summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2016-09-30 16:57:23 +0200
committerLars-Dominik Braun <lars@6xq.net>2016-09-30 16:59:06 +0200
commit724cc003460ec67eda269911da85c9f9e40aa6cf (patch)
tree14e27b45e04279516e4be546b15dcf6fafe17268
downloadeumel-src-724cc003460ec67eda269911da85c9f9e40aa6cf.tar.gz
eumel-src-724cc003460ec67eda269911da85c9f9e40aa6cf.tar.bz2
eumel-src-724cc003460ec67eda269911da85c9f9e40aa6cf.zip
Add extracted sources from floppy disk images
Some files have no textual representation (yet) and were added as raw dataspaces.
-rw-r--r--at/AT Generator135
-rw-r--r--at/AT Utilities1057
-rw-r--r--at/AT install93
-rw-r--r--basic/BASIC.Administration1886
-rw-r--r--basic/BASIC.Compiler2305
-rw-r--r--basic/BASIC.Runtime1571
-rw-r--r--basic/eumel coder 1.8.13086
-rw-r--r--basic/eumel0 codesbin0 -> 512 bytes
-rw-r--r--basic/gen.BASIC80
-rw-r--r--datatype/complex115
-rw-r--r--datatype/longint423
-rw-r--r--datatype/matrix482
-rw-r--r--datatype/vector213
-rw-r--r--dialog/ls-DIALOG 160
-rw-r--r--dialog/ls-DIALOG 277
-rw-r--r--dialog/ls-DIALOG 348
-rw-r--r--dialog/ls-DIALOG 471
-rw-r--r--dialog/ls-DIALOG 5118
-rw-r--r--dialog/ls-DIALOG 6102
-rw-r--r--dialog/ls-DIALOG 754
-rw-r--r--dialog/ls-DIALOG MENUKARTEN MANAGER28
-rw-r--r--dialog/ls-DIALOG MM-gen27
-rw-r--r--dialog/ls-DIALOG decompress150
-rw-r--r--dialog/ls-DIALOG-gen34
-rw-r--r--dialog/ls-MENUKARTE:Archivbin0 -> 40960 bytes
-rw-r--r--doc/basic/basic handbuch.11075
-rw-r--r--doc/basic/basic handbuch.22441
-rw-r--r--doc/basic/basic handbuch.3698
-rw-r--r--doc/basic/basic handbuch.index232
-rw-r--r--doc/dialog/gs-dialog handbuch.impressum89
-rw-r--r--doc/dialog/gs-dialog-1107
-rw-r--r--doc/dialog/gs-dialog-2215
-rw-r--r--doc/dialog/gs-dialog-3683
-rw-r--r--doc/dialog/gs-dialog-4672
-rw-r--r--doc/dialog/gs-dialog-5176
-rw-r--r--doc/dialog/gs-dialog-Inhaltsverzeichnis45
-rw-r--r--doc/dynamo/dynamo handbuch1826
-rw-r--r--doc/dynamo/dynamo handbuch.index69
-rw-r--r--doc/dynamo/dynamo handbuch.inhalt131
-rw-r--r--doc/eudas/abb.1-194
-rw-r--r--doc/eudas/abb.4-143
-rw-r--r--doc/eudas/abb.4-246
-rw-r--r--doc/eudas/abb.6-175
-rw-r--r--doc/eudas/abb.6-277
-rw-r--r--doc/eudas/abb.7-146
-rw-r--r--doc/eudas/abb.9-141
-rw-r--r--doc/eudas/abb.9-296
-rw-r--r--doc/eudas/abb.9-3113
-rw-r--r--doc/eudas/abb.9-498
-rw-r--r--doc/eudas/abb.9-551
-rw-r--r--doc/eudas/bildergenerator25
-rw-r--r--doc/eudas/eudas.hdb.1267
-rw-r--r--doc/eudas/eudas.hdb.10510
-rw-r--r--doc/eudas/eudas.hdb.11674
-rw-r--r--doc/eudas/eudas.hdb.12446
-rw-r--r--doc/eudas/eudas.hdb.13757
-rw-r--r--doc/eudas/eudas.hdb.14724
-rw-r--r--doc/eudas/eudas.hdb.15286
-rw-r--r--doc/eudas/eudas.hdb.16350
-rw-r--r--doc/eudas/eudas.hdb.2178
-rw-r--r--doc/eudas/eudas.hdb.3515
-rw-r--r--doc/eudas/eudas.hdb.5386
-rw-r--r--doc/eudas/eudas.hdb.6394
-rw-r--r--doc/eudas/eudas.hdb.7687
-rw-r--r--doc/eudas/eudas.hdb.8211
-rw-r--r--doc/eudas/eudas.hdb.9556
-rw-r--r--doc/eudas/eudas.hdb.inhalt133
-rw-r--r--doc/eudas/eudas.hdb.macros80
-rw-r--r--doc/eudas/eudas.hdb.titel99
-rw-r--r--doc/eudas/eudas.hdb.vorwort89
-rw-r--r--doc/eudas/eudas.ref.1326
-rw-r--r--doc/eudas/eudas.ref.10406
-rw-r--r--doc/eudas/eudas.ref.11347
-rw-r--r--doc/eudas/eudas.ref.2830
-rw-r--r--doc/eudas/eudas.ref.3270
-rw-r--r--doc/eudas/eudas.ref.4441
-rw-r--r--doc/eudas/eudas.ref.5432
-rw-r--r--doc/eudas/eudas.ref.6399
-rw-r--r--doc/eudas/eudas.ref.7447
-rw-r--r--doc/eudas/eudas.ref.8454
-rw-r--r--doc/eudas/eudas.ref.9194
-rw-r--r--doc/eudas/eudas.ref.fehler139
-rw-r--r--doc/eudas/eudas.ref.inhalt120
-rw-r--r--doc/eudas/eudas.ref.macros73
-rw-r--r--doc/eudas/eudas.ref.proz205
-rw-r--r--doc/eudas/eudas.ref.reg436
-rw-r--r--doc/eudas/eudas.ref.titel91
-rw-r--r--doc/eudas/eudas.ref.vorwort81
-rw-r--r--doc/eudas/ref.abb.1-142
-rw-r--r--doc/eudas/register490
-rw-r--r--doc/eudas/uedas.hdb.4686
-rw-r--r--doc/graphic/Altes Handbuch - Teil 10 - Graphik831
-rw-r--r--doc/graphic/GRAPHIK.book897
-rw-r--r--doc/graphic/graphik beschreibung661
-rw-r--r--doc/hamster/A5 - Doku: gs-Herbert und Robbi - Inhaltsverzeichnis45
-rw-r--r--doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 193
-rw-r--r--doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 2389
-rw-r--r--doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 3199
-rw-r--r--doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 41312
-rw-r--r--doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 5167
-rw-r--r--doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 673
-rw-r--r--doc/hamster/gs-Herbert und Robbi handbuch.impressum87
-rw-r--r--doc/lisp/lisp handbuch2260
-rw-r--r--doc/menugenerator/menu-generator handbuch.1100
-rw-r--r--doc/menugenerator/menu-generator handbuch.287
-rw-r--r--doc/menugenerator/menu-generator handbuch.3155
-rw-r--r--doc/menugenerator/menu-generator handbuch.4424
-rw-r--r--doc/menugenerator/menu-generator handbuch.5975
-rw-r--r--doc/menugenerator/menu-generator handbuch.6235
-rw-r--r--doc/menugenerator/menu-generator handbuch.7367
-rw-r--r--doc/menugenerator/menu-generator handbuch.81676
-rw-r--r--doc/menugenerator/menu-generator handbuch.impressum88
-rw-r--r--doc/menugenerator/menu-generator handbuch.index258
-rw-r--r--doc/menugenerator/menu-generator handbuch.inhalt72
-rw-r--r--doc/mp-bap/A5 - Doku: gs-MP BAP - Inhaltsverzeichnis50
-rw-r--r--doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1119
-rw-r--r--doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2302
-rw-r--r--doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3237
-rw-r--r--doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4638
-rw-r--r--doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5699
-rw-r--r--doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 653
-rw-r--r--doc/mp-bap/gs-MP BAP handbuch.impressum104
-rw-r--r--doc/programming/programmierhandbuch.1650
-rw-r--r--doc/programming/programmierhandbuch.2a1845
-rw-r--r--doc/programming/programmierhandbuch.2b1395
-rw-r--r--doc/programming/programmierhandbuch.3728
-rw-r--r--doc/programming/programmierhandbuch.41692
-rw-r--r--doc/programming/programmierhandbuch.51329
-rw-r--r--doc/programming/programmierhandbuch.5b1481
-rw-r--r--doc/programming/programmierhandbuch.61441
-rw-r--r--doc/programming/programmierhandbuch.index449
-rw-r--r--doc/programming/programmierhandbuch.inhalt249
-rw-r--r--doc/programming/programmierhandbuch.titel52
-rw-r--r--doc/prolog/prolog handbuch581
-rw-r--r--doc/prozess/Anhang Prozess92
-rw-r--r--doc/prozess/Inhalt Prozess84
-rw-r--r--doc/prozess/gs-Prozess handbuch.impressum104
-rw-r--r--doc/prozess/gs-Prozess-2255
-rw-r--r--doc/prozess/gs-Prozess-3346
-rw-r--r--doc/prozess/gs-Prozess-4173
-rw-r--r--doc/prozess/gs-prozess-199
-rw-r--r--doc/prozess/gs-prozess-5819
-rw-r--r--doc/prozess/gs-prozess-6641
-rw-r--r--doc/prozess/gs-prozess-71121
-rw-r--r--doc/prozess/gs-prozess-8377
-rw-r--r--doc/prozess/gs-prozess-9477
-rw-r--r--doc/system/systemhandbuch.11685
-rw-r--r--doc/system/systemhandbuch.21351
-rw-r--r--doc/system/systemhandbuch.31366
-rw-r--r--doc/system/systemhandbuch.41185
-rw-r--r--doc/user/benutzerhandbuch.1580
-rw-r--r--doc/user/benutzerhandbuch.2443
-rw-r--r--doc/user/benutzerhandbuch.32019
-rw-r--r--doc/user/benutzerhandbuch.42242
-rw-r--r--doc/user/benutzerhandbuch.5a1446
-rw-r--r--doc/user/benutzerhandbuch.5b1632
-rw-r--r--doc/user/benutzerhandbuch.5c711
-rw-r--r--doc/user/benutzerhandbuch.5d211
-rw-r--r--doc/user/benutzerhandbuch.5e223
-rw-r--r--doc/user/benutzerhandbuch.6474
-rw-r--r--doc/user/benutzerhandbuch.anhang484
-rw-r--r--doc/warenhaus/Anhang Warenhaus65
-rw-r--r--doc/warenhaus/Inhalt Warenhaus50
-rw-r--r--doc/warenhaus/gs-Warenhaus handbuch.impressum89
-rw-r--r--doc/warenhaus/gs-Warenhaus-1124
-rw-r--r--doc/warenhaus/gs-Warenhaus-272
-rw-r--r--doc/warenhaus/gs-Warenhaus-3309
-rw-r--r--doc/warenhaus/gs-Warenhaus-4378
-rw-r--r--doc/warenhaus/gs-Warenhaus-51468
-rw-r--r--doc/warenhaus/gs-Warenhaus-6589
-rw-r--r--doc/warenhaus/gs-Warenhaus-7235
-rw-r--r--dos/block i-o180
-rw-r--r--dos/dir.dos693
-rw-r--r--dos/disk descriptor.dos339
-rw-r--r--dos/dos hd inserter41
-rw-r--r--dos/dos inserter59
-rw-r--r--dos/dos-dat-handbuch650
-rw-r--r--dos/dump49
-rw-r--r--dos/eu disk descriptor107
-rw-r--r--dos/fat.dos369
-rw-r--r--dos/fetch371
-rw-r--r--dos/fetch save interface70
-rw-r--r--dos/get put interface.dos368
-rw-r--r--dos/insert.dos14
-rw-r--r--dos/konvert75
-rw-r--r--dos/manager-M.dos211
-rw-r--r--dos/manager-S.dos268
-rw-r--r--dos/name conversion.dos77
-rw-r--r--dos/open66
-rw-r--r--dos/save233
-rw-r--r--dos/shard interface20
-rw-r--r--dynamo/dyn.332073
-rw-r--r--dynamo/dyn.abnahme19
-rw-r--r--dynamo/dyn.bev50
-rw-r--r--dynamo/dyn.cob19
-rw-r--r--dynamo/dyn.delaytest8
-rw-r--r--dynamo/dyn.errors68
-rw-r--r--dynamo/dyn.forest47
-rw-r--r--dynamo/dyn.forst776
-rw-r--r--dynamo/dyn.gekoppeltependel19
-rw-r--r--dynamo/dyn.grashasenfuchs42
-rw-r--r--dynamo/dyn.help24
-rw-r--r--dynamo/dyn.inserter54
-rw-r--r--dynamo/dyn.mac44
-rw-r--r--dynamo/dyn.mehreredelays9
-rw-r--r--dynamo/dyn.natchez14
-rw-r--r--dynamo/dyn.oszillator26
-rw-r--r--dynamo/dyn.plot235
-rw-r--r--dynamo/dyn.plot+729
-rw-r--r--dynamo/dyn.print43
-rw-r--r--dynamo/dyn.proc160
-rw-r--r--dynamo/dyn.quadrat13
-rw-r--r--dynamo/dyn.rts376
-rw-r--r--dynamo/dyn.ruestungswettlauf32
-rw-r--r--dynamo/dyn.simon28
-rw-r--r--dynamo/dyn.std9
-rw-r--r--dynamo/dyn.steifedgl15
-rw-r--r--dynamo/dyn.tool217
-rw-r--r--dynamo/dyn.vec209
-rw-r--r--dynamo/dyn.wachstum19
-rw-r--r--dynamo/dyn.wasseröko64
-rw-r--r--dynamo/dyn.welt-forrester124
-rw-r--r--dynamo/dyn.wohnen105
-rw-r--r--dynamo/dyn.workfluc44
-rw-r--r--dynamo/dyn.wurzel14
-rw-r--r--dynamo/out.world43
-rw-r--r--eudas/Adressenbin0 -> 3584 bytes
-rw-r--r--eudas/dummy.text14
-rw-r--r--eudas/eudas.152
-rw-r--r--eudas/eudas.262
-rw-r--r--eudas/eudas.358
-rw-r--r--eudas/eudas.4150
-rw-r--r--eudas/eudas.generator86
-rw-r--r--eudas/eudas.init1463
-rw-r--r--eudas/pos.17319
-rw-r--r--graphic/Beispiel.Kreuz41
-rw-r--r--graphic/Beispiel.Sinus45
-rw-r--r--graphic/GRAPHIK.Picfile738
-rw-r--r--graphic/GRAPHIK.Plot285
-rw-r--r--graphic/GRAPHIK.Plotter247
-rw-r--r--graphic/GRAPHIK.Server97
-rw-r--r--graphic/GRAPHIK.Transform366
-rw-r--r--graphic/GRAPHIK.vektor plot506
-rw-r--r--graphic/HP7475.plot254
-rw-r--r--graphic/PC.plot758
-rw-r--r--graphic/ZEICHENSATZbin0 -> 11776 bytes
-rw-r--r--graphic/gen Graphik16
-rw-r--r--graphic/gen Plotter16
-rw-r--r--graphic/graphik editor324
-rw-r--r--hamster/ls-Herbert und Robbi 184
-rw-r--r--hamster/ls-Herbert und Robbi 231
-rw-r--r--hamster/ls-Herbert und Robbi 384
-rw-r--r--hamster/ls-Herbert und Robbi-gen33
-rw-r--r--hamster/ls-MENUKARTE:Herbert und Robbibin0 -> 94720 bytes
-rw-r--r--lisp/lisp.11306
-rw-r--r--lisp/lisp.2584
-rw-r--r--lisp/lisp.3767
-rw-r--r--lisp/lisp.4143
-rw-r--r--lisp/lisp.bootstrap118
-rw-r--r--menugenerator/Generatordatei: Archivmenu323
-rw-r--r--menugenerator/fonttab.ls-Menu-Generatorbin0 -> 2560 bytes
-rw-r--r--menugenerator/ls-MENUBASISTEXTEbin0 -> 17408 bytes
-rw-r--r--menugenerator/ls-Menu-Generator 147
-rw-r--r--menugenerator/ls-Menu-Generator 272
-rw-r--r--menugenerator/ls-Menu-Generator-gen30
-rw-r--r--mp-bap/ls-MENUKARTE:MP-BAPbin0 -> 79872 bytes
-rw-r--r--mp-bap/ls-MP BAP 1119
-rw-r--r--mp-bap/ls-MP BAP 2126
-rw-r--r--mp-bap/ls-MP BAP-gen30
-rw-r--r--net/basic net1148
-rw-r--r--net/net files-M5
-rw-r--r--net/net hardware interface389
-rw-r--r--net/net inserter145
-rw-r--r--net/net manager797
-rw-r--r--net/net report41
-rw-r--r--net/netz20
-rw-r--r--net/netzhandbuch2045
-rw-r--r--net/netzhandbuch.anhang58
-rw-r--r--net/netzhandbuch.index259
-rw-r--r--net/port server164
-rw-r--r--net/printer server99
-rw-r--r--net/spool cmd112
-rw-r--r--net/spool manager915
-rw-r--r--printer/dotmatrix24/beschreibungen2462
-rw-r--r--printer/dotmatrix24/fonttab.brotherbin0 -> 38400 bytes
-rw-r--r--printer/dotmatrix24/fonttab.epson.lq1500bin0 -> 35840 bytes
-rw-r--r--printer/dotmatrix24/fonttab.epson.lq850bin0 -> 38400 bytes
-rw-r--r--printer/dotmatrix24/fonttab.nec.p5bin0 -> 39936 bytes
-rw-r--r--printer/dotmatrix24/fonttab.nec.p5.newbin0 -> 39936 bytes
-rw-r--r--printer/dotmatrix24/fonttab.nec.p6+bin0 -> 48128 bytes
-rw-r--r--printer/dotmatrix24/fonttab.okibin0 -> 38400 bytes
-rw-r--r--printer/dotmatrix24/fonttab.toshiba.p321bin0 -> 15872 bytes
-rw-r--r--printer/dotmatrix24/inserter793
-rw-r--r--printer/dotmatrix24/module241554
-rw-r--r--printer/dotmatrix24/printer.24.nadel776
-rw-r--r--printer/dotmatrix24/readme320
-rw-r--r--printer/dotmatrix9/beschreibungen997
-rw-r--r--printer/dotmatrix9/fonttab.1bin0 -> 11264 bytes
-rw-r--r--printer/dotmatrix9/fonttab.10bin0 -> 15872 bytes
-rw-r--r--printer/dotmatrix9/fonttab.20bin0 -> 36864 bytes
-rw-r--r--printer/dotmatrix9/fonttab.20.lcbin0 -> 36864 bytes
-rw-r--r--printer/dotmatrix9/fonttab.20.lxbin0 -> 24576 bytes
-rw-r--r--printer/dotmatrix9/fonttab.7bin0 -> 46080 bytes
-rw-r--r--printer/dotmatrix9/fonttab.7.cxpbin0 -> 46080 bytes
-rw-r--r--printer/dotmatrix9/fonttab.7.fujbin0 -> 56832 bytes
-rw-r--r--printer/dotmatrix9/fonttab.7.mtbin0 -> 46080 bytes
-rw-r--r--printer/dotmatrix9/module91099
-rw-r--r--printer/dotmatrix9/printer.neun.nadel1129
-rw-r--r--printer/dotmatrix9/readme324
-rw-r--r--printer/laser/fonttab.apple.laserwriterbin0 -> 100864 bytes
-rw-r--r--printer/laser/fonttab.canon.lbp-8bin0 -> 58368 bytes
-rw-r--r--printer/laser/fonttab.epson.sqbin0 -> 29696 bytes
-rw-r--r--printer/laser/fonttab.hp.laserjetbin0 -> 24064 bytes
-rw-r--r--printer/laser/fonttab.kyocera.f-1010bin0 -> 71168 bytes
-rw-r--r--printer/laser/fonttab.nec.lc-08bin0 -> 38400 bytes
-rw-r--r--printer/laser/genfont.kyocera.f-1010.dynamic130
-rw-r--r--printer/laser/genfont.kyocera.f-1010.dynamic230
-rw-r--r--printer/laser/laser.inserter275
-rw-r--r--printer/laser/printer.apple.laserwriter770
-rw-r--r--printer/laser/printer.canon.lbp-8327
-rw-r--r--printer/laser/printer.epson.sq585
-rw-r--r--printer/laser/printer.hp.laserjet417
-rw-r--r--printer/laser/printer.kyocera.f-1010373
-rw-r--r--printer/laser/printer.nec.lc-08626
-rw-r--r--printer/laser/readme155
-rw-r--r--prolog/calc32
-rw-r--r--prolog/family29
-rw-r--r--prolog/permute15
-rw-r--r--prolog/prieks58
-rw-r--r--prolog/prolog2488
-rw-r--r--prolog/prolog installation117
-rw-r--r--prolog/puzzle24
-rw-r--r--prolog/quicksort14
-rw-r--r--prolog/standard35
-rw-r--r--prolog/sum13
-rw-r--r--prolog/thesaurus360
-rw-r--r--prolog/topographie59
-rw-r--r--prozess/ls-MENUKARTE:Prozessbin0 -> 62464 bytes
-rw-r--r--prozess/ls-Prozess 1 für AKTRONIC-Adapter57
-rw-r--r--prozess/ls-Prozess 1 für MUFI als Endgerät57
-rw-r--r--prozess/ls-Prozess 1 für MUFI im Terminalkanal55
-rw-r--r--prozess/ls-Prozess 239
-rw-r--r--prozess/ls-Prozess 326
-rw-r--r--prozess/ls-Prozess 461
-rw-r--r--prozess/ls-Prozess 584
-rw-r--r--prozess/ls-Prozess-gen146
-rw-r--r--system/crypt138
-rw-r--r--system/eumel printer.53473
-rw-r--r--system/eumelmeter131
-rw-r--r--system/font convertor 91095
-rw-r--r--system/free channel430
-rw-r--r--system/port server164
-rw-r--r--system/printer server99
-rw-r--r--system/purge85
-rw-r--r--system/referencer1077
-rw-r--r--system/reporter531
-rw-r--r--system/scheduler420
-rw-r--r--system/spool cmd178
-rw-r--r--system/spool manager1058
-rw-r--r--system/std analysator68
-rw-r--r--tecal/TeCal856
-rw-r--r--tecal/TeCal Auskunftbin0 -> 45056 bytes
-rw-r--r--tecal/TeCal.gen55
-rw-r--r--warenhaus/ls-MENUKARTE:Warenhausbin0 -> 60928 bytes
-rw-r--r--warenhaus/ls-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter36
-rw-r--r--warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endgerät36
-rw-r--r--warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal30
-rw-r--r--warenhaus/ls-Warenhaus 0: ohne Kartenleser27
-rw-r--r--warenhaus/ls-Warenhaus 137
-rw-r--r--warenhaus/ls-Warenhaus 2112
-rw-r--r--warenhaus/ls-Warenhaus 382
-rw-r--r--warenhaus/ls-Warenhaus 448
-rw-r--r--warenhaus/ls-Warenhaus 5103
-rw-r--r--warenhaus/ls-Warenhaus-gen29
374 files changed, 134225 insertions, 0 deletions
diff --git a/at/AT Generator b/at/AT Generator
new file mode 100644
index 0000000..d3bfd6d
--- /dev/null
+++ b/at/AT Generator
@@ -0,0 +1,135 @@
+(*************************************************************************)
+(*** Generiert Für IBM-AT einen neuen SYSUR-Zweig. ***)
+(*** Danach wird die eingebaute Hardwareuhr für die Systemzeit benutzt ***)
+(*** und andere Partitionen können mit neuem 'shutup' gebootet werden. ***)
+(*** ***)
+(*** Autor : W. Sauerwein Stand : 15.07.86 ***)
+(*************************************************************************)
+
+LET ack = 0,
+ nak = 1;
+
+cl eop (1, 4);
+erzeuge collector;
+erzeuge archive manager;
+erzeuge operator;
+erzeuge configurator;
+loesche collector;
+forget ("AT Generator", quiet);
+break.
+
+loesche collector :
+ end (/"colly");
+ put ("Collector gelöscht.");
+ line (2).
+
+erzeuge collector :
+ put line ("Generating 'Collector'...");
+ begin ("colly", PROC generate collector, t);
+ warte auf meldung;
+ IF answer = nak THEN end (/"colly");
+ errorstop (meldung)
+ FI.
+ TASK VAR t.
+
+erzeuge archive manager :
+ put line ("Generating 'ARCHIVE'...");
+ end (/"ARCHIVE");
+ begin ("ARCHIVE", PROC archive manager, t).
+
+erzeuge operator :
+ put line ("Generating 'OPERATOR'...");
+ end (/"OPERATOR");
+ begin ("OPERATOR", PROC monitor, t).
+
+erzeuge configurator :
+ put line ("Generating 'configurator'...");
+ end (/"configurator");
+ begin ("configurator", PROC generate configurator, t);
+ warte auf meldung;
+ IF answer = nak THEN errorstop (meldung) FI.
+
+warte auf meldung :
+ DATASPACE VAR ds; INT VAR answer;
+ wait (ds, answer, t);
+ BOUND TEXT VAR m := ds;
+ TEXT VAR meldung := m;
+ forget (ds).
+
+PROC generate collector :
+
+ disable stop;
+ fetch all (/"configurator");
+ DATASPACE VAR ds := nilspace;
+ BOUND TEXT VAR m := ds; m := "";
+ send (father, mess, ds);
+ forget (ds);
+ free global manager.
+
+mess : IF is error THEN m := error message;
+ nak
+ ELSE ack FI.
+
+END PROC generate collector;
+
+PROC generate configurator :
+
+ disable stop;
+ fetch all (/"colly");
+ DATASPACE VAR ds := nilspace;
+ BOUND TEXT VAR m := ds; m := "";
+ send (father, mess, ds);
+ forget (ds);
+ enable stop;
+ new configuration;
+ setup;
+ global manager (PROC ( DATASPACE VAR, INT CONST, INT CONST, TASK CONST)
+ configuration manager with time).
+
+mess : IF is error THEN m := error message;
+ nak
+ ELSE ack FI.
+
+END PROC generate configurator;
+
+TEXT PROC inverse (TEXT CONST t):
+ ""15"" + t + " " + ""14""
+END PROC inverse;
+
+PROC put center (TEXT CONST t):
+ put center (t, 80)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+ put center (zeile, t, 80)
+END PROC put center;
+
+PROC put center (TEXT CONST t, INT CONST gesamtbreite):
+ INT VAR cy;
+ get cursor (cy, cy);
+ put center (cy, t, gesamtbreite)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t, INT CONST gesamtbreite):
+ cursor ((gesamtbreite - length (t)) DIV 2, zeile);
+ put (t).
+END PROC put center;
+
+PROC cl eol:
+ out (""5"")
+END PROC cl eol;
+
+PROC cl eop:
+ out (""4"")
+END PROC cl eop;
+
+PROC cl eol (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eol
+END PROC cl eol;
+
+PROC cl eop (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eop
+END PROC cl eop;
+
diff --git a/at/AT Utilities b/at/AT Utilities
new file mode 100644
index 0000000..760e728
--- /dev/null
+++ b/at/AT Utilities
@@ -0,0 +1,1057 @@
+(*************************************************************************)
+(*** AT-spezifische Software, die zum Lesen der Hardwareuhr und ***)
+(*** Booten in anderen Partitionen benötigt wird. ***)
+(*** ***)
+(*** Zusammengestellt und geändert : Werner Sauerwein, GMD ***)
+(*** Stand : 31.10.86 ***)
+(*************************************************************************)
+
+PACKET splitting DEFINES low byte, (* Copyright (C) 1985 *)
+ high byte, (* Martin Schönbeck, Spenge *)
+ low word, (* Stand: 13.09.85 *)
+ high word:
+
+INT PROC high byte (INT CONST value):
+
+ TEXT VAR x := " ";
+ replace (x, 1, value);
+ code (x SUB 2)
+
+END PROC high byte;
+
+INT PROC low byte (INT CONST value):
+
+ TEXT VAR x := " ";
+ replace (x, 1, value);
+ code (x SUB 1)
+
+END PROC low byte;
+
+INT PROC high word (REAL CONST double precission int):
+
+ int (double precission int / 65536.0)
+
+END PROC high word;
+
+INT PROC low word (REAL CONST double precission int):
+
+ string of low bytes ISUB 1.
+
+string of low bytes:
+ code (int (double precission int MOD 256.0)) +
+ code (int ((double precission int MOD 65536.0) / 256.0)).
+
+END PROC low word;
+
+END PACKET splitting;
+
+
+PACKET basic block io DEFINES
+
+ read block,
+ write block:
+
+PROC read block (DATASPACE VAR ds,
+ INT CONST ds page no,
+ INT CONST block no,
+ INT VAR return code):
+ read block;
+ retry if read error.
+
+read block:
+ block in (ds, ds page no, 0, block no, return code).
+
+retry if read error:
+ INT VAR retry;
+ FOR retry FROM 1 UPTO 10 WHILE return code = 2 REP
+ reset to block 0 if fifth try;
+ read block
+ PER.
+
+reset to block 0 if fifth try:
+ IF retry = 5
+ THEN block in (ds, ds page no, 0, 0, return code)
+ FI.
+
+END PROC read block;
+
+PROC write block (DATASPACE CONST ds,
+ INT CONST ds page no,
+ INT CONST block no,
+ INT VAR return code):
+ write block;
+ retry if write error.
+
+write block:
+ block out (ds, ds page no, 0, block no, return code).
+
+retry if write error:
+ INT VAR retry;
+ FOR retry FROM 1 UPTO 10 WHILE return code = 2 REP
+ reset to block 0 if fifth try;
+ write block
+ PER.
+
+reset to block 0 if fifth try:
+ IF retry = 5
+ THEN disable stop;
+ DATASPACE VAR dummy ds := nilspace;
+ block in (dummy ds, 2, 0, 0, return code);
+ forget (dummy ds);
+ enable stop
+ FI.
+
+END PROC write block;
+
+PROC read block (DATASPACE VAR ds, INT CONST ds page,
+ REAL CONST archive block):
+
+ enable stop;
+ read block (ds, ds page, archive block, error);
+ INT VAR error;
+ SELECT error OF
+ CASE 0:
+ CASE 1: error stop ("Platte kann nicht gelesen werden");
+ CASE 2: error stop ("Lesefehler bei Block "+ text (archive block));
+ CASE 3: error stop ("Versorgungsfehler Archiv");
+ OTHERWISE error stop ("unbekannter Fehler auf Platte");
+ END SELECT;
+
+END PROC read block;
+
+PROC write block (DATASPACE CONST ds, INT CONST ds page,
+ REAL CONST archive block):
+
+ enable stop;
+ write block (ds, ds page, archive block, error);
+ INT VAR error;
+ SELECT error OF
+ CASE 0:
+ CASE 1: error stop ("Platte kann nicht geschrieben werden");
+ CASE 2: error stop ("Schreibfehler bei Block "+ text (archive block));
+ CASE 3: error stop ("Versorgungsfehler Archiv");
+ OTHERWISE error stop ("unbekannter Fehler auf Platte");
+ END SELECT;
+
+END PROC write block;
+
+PROC read block (DATASPACE VAR ds,
+ INT CONST ds page no,
+ REAL CONST block no,
+ INT VAR return code):
+ read block;
+ retry if read error.
+
+read block:
+ block in (ds, ds page no, high word (block no),
+ low word (block no), return code).
+
+retry if read error:
+ INT VAR retry;
+ FOR retry FROM 1 UPTO 10 WHILE return code = 2 REP
+ reset to block 0 if fifth try;
+ read block
+ PER.
+
+reset to block 0 if fifth try:
+ IF retry = 5
+ THEN block in (ds, ds page no, 0, 0, return code)
+ FI.
+
+END PROC read block;
+
+PROC write block (DATASPACE CONST ds,
+ INT CONST ds page no,
+ REAL CONST block no,
+ INT VAR return code):
+ write block;
+ retry if write error.
+
+write block:
+ block out (ds, ds page no, high word (block no),
+ low word (block no), return code).
+
+retry if write error:
+ INT VAR retry;
+ FOR retry FROM 1 UPTO 10 WHILE return code = 2 REP
+ reset to block 0 if fifth try;
+ write block
+ PER.
+
+reset to block 0 if fifth try:
+ IF retry = 5
+ THEN disable stop;
+ DATASPACE VAR dummy ds := nilspace;
+ block in (dummy ds, 2, 0, 0, return code);
+ forget (dummy ds);
+ enable stop
+ FI.
+
+END PROC write block;
+
+END PACKET basic block io;
+
+
+PACKET utilities DEFINES getchoice, cleol, cleop, inverse, put center:
+
+INT PROC get choice (INT CONST von, bis, TEXT VAR retchar):
+ get choice (von, bis, von, retchar)
+END PROC get choice;
+
+INT PROC get choice (INT CONST von, bis, zusatz, TEXT VAR retchar):
+ LET return = ""13"",
+ escape = ""27"",
+ left = ""8"";
+ TEXT VAR buffer;
+ INT VAR cx, cy;
+ get cursor (cx, cy); out (" " + left);
+ REP
+ REP
+ cursor (cx, cy); buffer := incharety;
+ UNTIL input ok OR buffer = escape PER;
+ IF buffer = escape THEN retchar := escape;
+ LEAVE get choice WITH 0
+ FI;
+ out (buffer);
+ leseschleife bis left or ret;
+ IF retchar = left THEN out (left + " ") FI;
+ IF retchar = escape THEN LEAVE get choice WITH 0 FI
+ UNTIL retchar = return OR retchar = escape PER;
+ int (buffer).
+
+input ok : (buffer >= text (von) AND buffer <= text (bis)) OR buffer = text (zusatz).
+
+leseschleife bis left or ret:
+ REP
+ inchar (retchar)
+ UNTIL retchar = return OR retchar = left OR retchar = escape PER.
+
+END PROC get choice;
+
+PROC cl eol (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eol
+END PROC cl eol;
+
+PROC cl eop (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eop
+END PROC cl eop;
+
+
+PROC cl eol:
+ out (""5"")
+END PROC cl eol;
+
+PROC cl eop:
+ out (""4"")
+END PROC cl eop;
+
+TEXT PROC inverse (TEXT CONST t):
+ ""15"" + t + " " + ""14""
+END PROC inverse;
+
+PROC put center (TEXT CONST t):
+ put center (t, 80)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+ put center (zeile, t, 80)
+END PROC put center;
+
+PROC put center (TEXT CONST t, INT CONST gesamtbreite):
+ INT VAR cy;
+ get cursor (cy, cy);
+ put center (cy, t, gesamtbreite)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t, INT CONST gesamtbreite):
+ cursor ((gesamtbreite - length (t)) DIV 2, zeile);
+ put (t).
+END PROC put center;
+
+END PACKET utilities
+
+
+PACKET part DEFINES activate, show actual partition table:
+ (* Copyright (C) 1985 *)
+ (* Martin Schönbeck, Spenge *)
+ (* Stand : 02.02.86 *)
+ (* Changed by : W.Sauerwein *)
+ (* I.Ley *)
+ (* Stand : 03.10.86 *)
+ LET fd channel = 28;
+
+ROW 256 INT VAR boot block;
+INT VAR boot block session := session - 1;
+
+PROC get boot block:
+ IF boot block session <> session
+ THEN hole aktuellen boot block
+ FI.
+
+hole aktuellen boot block:
+ disable stop;
+ DATASPACE VAR dummy ds := nilspace;
+ BOUND STRUCT (ALIGN dummy,
+ ROW 256 INT block) VAR partition table := dummy ds;
+ get external block (dummy ds, 2, 0, fd channel);
+ IF NOT is error
+ THEN transfer data to boot block
+ FI;
+ forget (dummy ds).
+
+transfer data to boot block:
+ IF not valid boot block
+ THEN try to get valid boot block from file
+ FI;
+ boot block := partition table. block;
+ boot block session := session.
+
+not valid boot block:
+ partition table. block [256] <> boot indicator OR
+ it is an old boot block of eumel.
+
+boot indicator: -21931.
+
+it is an old boot block of eumel:
+ partition table. block [1] = 1514.
+
+try to get valid boot block from file:
+ forget (dummy ds);
+ partition table := old ("bootblock");
+ IF is error THEN LEAVE transfer data to boot block FI.
+
+END PROC get boot block;
+
+PROC put boot block:
+ IF boot block ist uptodate
+ THEN schreibe block auf platte
+ ELSE errorstop ("boot block nicht uptodate")
+ FI.
+
+boot block ist uptodate:
+ boot block session = session.
+
+schreibe block auf platte:
+ disable stop;
+ DATASPACE VAR dummy ds := nilspace;
+ BOUND STRUCT (ALIGN dummy,
+ ROW 256 INT block) VAR partition table := dummy ds;
+ transfer data to dataspace;
+ put external block (dummy ds, 2, 0, fd channel);
+ forget (dummy ds).
+
+transfer data to dataspace:
+ partition table. block := boot block.
+
+END PROC put boot block;
+
+INT PROC partition type (INT CONST partition):
+ low byte (boot block [entry (partition) + 2])
+END PROC partition type;
+
+REAL PROC partition start (INT CONST partition):
+ unsigned low word + high word.
+
+unsigned low word:
+ real (low byte (boot block [entry (partition) + 4])) +
+ real (high byte (boot block [entry (partition) + 4])) * 256.0.
+
+high word:
+ real (boot block [entry (partition) + 5]).
+
+END PROC partition start;
+
+INT PROC partition word 0 (INT CONST partition):
+ boot block (entry (partition))
+END PROC partition word 0;
+
+INT PROC first track (INT CONST partition):
+ high byte (boot block [entry (partition) + 1])
+ + 4 * (low byte (boot block [entry (partition) + 1]) AND (128 + 64))
+END PROC first track;
+
+INT PROC last track (INT CONST partition):
+ high byte (boot block [entry (partition) + 3])
+ + 4 * (low byte (boot block [entry (partition) + 3]) AND (128 + 64))
+END PROC last track;
+
+BOOL PROC partition activ (INT CONST partition):
+ low byte (boot block [entry (partition)]) = 128
+END PROC partition activ;
+
+REAL PROC partition size (INT CONST partition):
+ unsigned low word + high word.
+
+unsigned low word:
+ real (low byte (boot block [entry (partition) + 6])) +
+ real (high byte (boot block [entry (partition) + 6])) * 256.0.
+
+high word:
+ real (boot block [entry (partition) + 7]).
+
+END PROC partition size;
+
+INT PROC tracks:
+ get value (-10, fd channel)
+END PROC tracks;
+
+PROC activate (INT CONST part type):
+ IF partition type exists AND is possible type
+ THEN deactivate all partitions and
+ activate desired partition
+ ELSE errorstop ("Gewünschte Partitionart gibt es nicht")
+ FI.
+
+is possible type:
+ part type > 0 AND
+ part type < 256.
+
+partition type exists:
+ INT VAR partition;
+ FOR partition FROM 1 UPTO 4 REP
+ IF partition type (partition) = part type
+ THEN LEAVE partition type exists WITH TRUE
+ FI;
+ PER;
+ FALSE.
+
+deactivate all partitions and activate desired partition:
+ FOR partition FROM 1 UPTO 4 REP
+ deactivate this partition;
+ IF partition type (partition) = part type
+ THEN activate partition
+ FI
+ PER;
+ put boot block.
+
+deactivate this partition:
+ set bit (boot block [entry (partition)], 7);
+ (* first setting needed, because reset bit does xor *)
+ reset bit (boot block [entry (partition)], 7).
+
+activate partition:
+ set bit (boot block [entry (partition)], 7)
+
+END PROC activate;
+
+INT PROC entry (INT CONST partition):
+ get boot block;
+ 256 - 5 * 8 + (partition * 8)
+END PROC entry;
+
+INT PROC get value (INT CONST control code, channel for value):
+ enable stop;
+ INT VAR old channel := channel;
+ continue (channel for value);
+ INT VAR value;
+ control (control code, 0, 0, value);
+ continue (old channel);
+ value
+END PROC get value;
+
+PROC get external block (DATASPACE VAR ds, INT CONST ds page,
+ archive block, get channel):
+ INT VAR old channel := channel;
+ continue (get channel);
+ disable stop;
+ read block (ds, ds page, archive block, error);
+ INT VAR error;
+ SELECT error OF
+ CASE 0:
+ CASE 1: error stop ("Platte kann nicht gelesen werden");
+ CASE 2: error stop ("Lesefehler bei Block "+ text (archive block));
+ CASE 3: error stop ("Versorgungsfehler Archiv");
+ OTHERWISE error stop ("unbekannter Fehler auf Platte");
+ END SELECT;
+ continue (old channel).
+END PROC get external block;
+
+PROC put external block (DATASPACE CONST ds, INT CONST ds page,
+ archive block, get channel):
+ INT VAR old channel := channel;
+ continue (get channel);
+ disable stop;
+ write block (ds, ds page, archive block, error);
+ INT VAR error;
+ SELECT error OF
+ CASE 0:
+ CASE 1: error stop ("Platte kann nicht geschrieben werden");
+ CASE 2: error stop ("Schreibfehler bei Block "+ text (archive block));
+ CASE 3: error stop ("Versorgungsfehler Archiv");
+ OTHERWISE error stop ("unbekannter Fehler auf Platte");
+ END SELECT;
+ continue (old channel).
+END PROC put external block;
+
+(**************************************************************************)
+
+ LET max partitions = 4;
+ ROW max partitions INT VAR part list;
+ ROW max partitions INT VAR part type, part active,
+ part first track, part last track;
+ ROW max partitions REAL VAR part start,
+ part size;
+ INT VAR zylinder,
+ startzeile tabelle :: 1,
+ active partition,
+ partitions,
+ partition, i, j, help;
+
+
+PROC get actual partition data :
+ get boot block;
+ zylinder := tracks;
+ FOR i FROM 1 UPTO max partitions REP
+ part type (i) := partition type (i);
+ part first track (i) := first track (i);
+ part last track (i) := last track (i);
+ part start (i) := partition start (i);
+ part size (i) := partition size (i);
+ part active (i) := partition word 0 (i);
+ IF partition activ (i) THEN active partition := i FI
+ PER;
+ get number of installed partitions;
+ generate part list.
+
+get number of installed partitions :
+ partitions := 0;
+ FOR i FROM 1 UPTO max partitions REP
+ IF part type (i) <> 0 THEN partitions INCR 1 FI
+ PER.
+
+generate part list :
+ FOR i FROM 1 UPTO max partitions REP
+ IF part type (i) <> 0 THEN part list (i) := i
+ ELSE part list (i) := 0
+ FI;
+ PER;
+ schiebe nullen nach hinten;
+ sort part list.
+
+schiebe nullen nach hinten :
+ i := 1; INT VAR k := 0;
+ REP k INCR 1;
+ IF part list (i) = 0 THEN circle
+ ELSE i INCR 1
+ FI
+ UNTIL k = max partitions - 1 PER.
+
+circle :
+ FOR j FROM i UPTO max partitions - 1 REP
+ part list (j) := part list (j + 1)
+ PER;
+ part list (max partitions) := 0.
+
+sort part list :
+ FOR i FROM 2 UPTO partitions REP
+ FOR j FROM 1 UPTO i - 1 REP
+ IF part first track (part list (i)) < part first track (part list (j))
+ THEN tausche FI
+ PER
+ PER.
+
+tausche :
+ help := part list (i);
+ part list (i) := part list (j);
+ part list (j) := help.
+
+END PROC get actual partition data;
+
+
+PROC show partition table :
+ headline;
+ devide table;
+ columns;
+ underlines;
+ rows;
+ footlines.
+
+head line :
+ cl eop (1, startzeile tabelle);
+ put center (inverse (" "
+ + "Aktuelle Partitions - Tabelle"
+ + " ")).
+
+devide table :
+ FOR i FROM 1 UPTO 8
+ REP
+ cursor (50, startzeile tabelle + i); out (inverse (""))
+ PER.
+
+columns :
+ cursor ( 1, startzeile tabelle + 2);
+ out (" Nr. System Typ-Nr. Zustand Größe Start Ende");
+ cursor (54, startzeile tabelle + 2);
+ out ("Plattengröße / Zylinder ").
+
+underlines :
+ cursor ( 1, startzeile tabelle + 3);
+ out ("-------------------------------------------------");
+ cursor (52, startzeile tabelle + 3);
+ out ("--------------------------").
+
+rows :
+ FOR i FROM 1 UPTO max partitions
+ REP cursor (2, startzeile tabelle + 3 + i);
+ put (text (i) + " :")
+ PER.
+
+footlines:
+ cursor (1, startzeile tabelle + 9);
+ put center (inverse (75 * " ")).
+
+END PROC show partition table;
+
+PROC update table :
+ get actual partition data;
+ FOR i FROM 1 UPTO partitions REP update partition PER;
+ FOR i FROM partitions + 1 UPTO max partitions REP rubout partition PER;
+ zeige plattengroesse.
+
+update partition :
+ partition := part list (i);
+ show partition.
+
+rubout partition :
+ cursor (6, startzeile tabelle + 3 + i);
+ out (" ").
+
+show partition :
+ cursor (6, startzeile tabelle + 3 + i);
+ put (name + type + zustand + groesse + startspur + endspur).
+
+name : subtext (subtext (part name, 1, 9)
+ + " ", 1, 10).
+
+type : text (part type (partition), 5) + " ".
+
+zustand : IF active partition = partition THEN (" aktiv ")
+ ELSE (" ")
+ FI.
+
+startspur : " " + text (part first track (partition), 5).
+endspur : text (part last track (partition), 6).
+groesse : text (part groesse, 5).
+
+zeige plattengroesse :
+ put gesamt;
+ put noch freie;
+ put maximaler zwischenraum.
+
+put maximaler zwischenraum :
+ cursor (54, startzeile tabelle + 6);
+ put ("max. zusammenh. : " + text (maximaler zwischenraum, 4)).
+
+put gesamt :
+ cursor (54, startzeile tabelle + 4);
+ put ("insgesamt : " + text (zylinder, 4)).
+
+put noch freie :
+ cursor (54, startzeile tabelle + 5);
+ put ("davon noch frei : " + text (freie zylinder, 4)).
+
+part groesse :
+ partition groesse (partition).
+
+part name :
+ SELECT part type (partition) OF
+ CASE 1 : "DOS"
+ CASE 69, 70, 71, 72 : "EUMEL"
+ OTHERWISE text (part type (partition))
+ END SELECT.
+
+freie zylinder :
+ zylinder - belegte zylinder.
+
+belegte zylinder :
+ help := 0;
+ FOR i FROM 1 UPTO partitions REP
+ help INCR partition groesse (part list (i))
+ PER;
+ help.
+
+END PROC update table;
+
+INT PROC maximaler zwischenraum :
+ IF partitions = 0 THEN zylinder
+ ELSE max (maximaler platz vor und zwischen den partitionen,
+ platz hinter letzter partition)
+ FI.
+
+maximaler platz vor und zwischen den partitionen :
+ help := platz vor erster partition;
+ FOR i FROM 1 UPTO partitions - 1
+ REP
+ help := max (help, begin of part i plus 1 - end of part i - 1)
+ PER;
+ help.
+
+platz vor erster partition :
+ part first track (part list (1)).
+
+platz hinter letzter partition :
+ zylinder - part last track (part list (partitions)) - 1.
+
+begin of part i plus 1 :
+ part first track (part list (i + 1)).
+
+end of part i :
+ part last track (part list (i)).
+
+END PROC maximaler zwischenraum;
+
+INT PROC partition groesse (INT CONST part) :
+ part last track (part) - part first track (part) + 1
+END PROC partition groesse;
+
+PROC show actual partition table:
+ show partition table;
+ update table;
+ line (4)
+END PROC show actual partition table;
+
+PROC show actual partition table (ROW max partitions INT VAR typnr):
+ show actual partition table;
+ FOR i FROM 1 UPTO max partitions REP
+ typnr (i) := partition type (part list (i))
+ PER;
+END PROC show actual partition table;
+
+END PACKET part;
+
+
+PACKET hw clock DEFINES hw clock: (* Copyright (C) 1985 *)
+ (* Martin Schönbeck, Spenge *)
+LET clock length = 7, (* Stand: 06.11.85 *)
+ clock command = 4;
+
+BOUND STRUCT (ALIGN dummy,
+ ROW clock length INT clock field) VAR clock data;
+
+REAL PROC hw clock:
+
+ disable stop;
+ get clock;
+ hw date + hw time.
+
+get clock:
+ DATASPACE VAR ds := nilspace;
+ clock data := ds;
+ INT VAR return code, actual channel := channel;
+ go to shard channel;
+ blockin (ds, 2, -clock command, 0, return code);
+ IF actual channel = 0 THEN break (quiet)
+ ELSE continue (actual channel)
+ FI;
+ IF return code <> 0
+ THEN errorstop ("Keine Hardware Uhr vorhanden");
+ FI;
+ put clock into text;
+ forget (ds).
+
+put clock into text:
+ TEXT VAR clock text := clock length * " ";
+ INT VAR i;
+ FOR i FROM 1 UPTO clock length REP
+ replace (clock text, i, clock data. clock field [i]);
+ PER.
+
+go to shard channel:
+ INT VAR retry;
+ FOR retry FROM 1 UPTO 20 REP
+ continue (32);
+ IF is error
+ THEN clear error;
+ pause (30)
+ FI;
+ UNTIL channel = 32 PER.
+
+hw date:
+ date (day + "." + month + "." + year).
+
+day: subtext (clock text, 7, 8).
+
+month: subtext (clock text, 5, 6).
+
+year: subtext (clock text, 1, 4).
+
+hw time:
+ time (hour + ":" + minute + ":" + second).
+
+hour: subtext (clock text, 9, 10).
+
+minute: subtext (clock text, 11, 12).
+
+second: subtext (clock text, 13, 14).
+
+END PROC hw clock;
+
+END PACKET hw clock
+
+
+PACKET old shutup DEFINES old shutup, (* Copyright (C) 1985 *)
+ old save system: (* Martin Schönbeck, Spenge *)
+ (* Stand: 06.11.85 *)
+PROC old shutup : shutup END PROC old shutup;
+
+PROC old save system : save system END PROC old save system;
+
+END PACKET old shutup;
+
+
+PACKET new shutup DEFINES shutup,
+ shutup dialog,
+ save system,
+ generate shutup manager,
+ generate shutup dialog manager:
+
+LET ack = 0;
+
+PROC shutup:
+
+ system down (PROC old shutup)
+
+END PROC shutup;
+
+PROC shutup (INT CONST new system):
+
+ IF new system <> 0
+ THEN prepare for new system
+ FI;
+ system down (PROC old shutup).
+
+prepare for new system:
+ activate (new system);
+ prepare for rebooting.
+
+prepare for rebooting:
+ INT VAR old channel := channel;
+ continue (32);
+ INT VAR dummy;
+ control (-5, 0, 0, dummy);
+ break (quiet);
+ continue (old channel).
+
+END PROC shutup;
+
+PROC save system:
+
+ IF yes ("Leere Floppy eingelegt")
+ THEN system down (PROC old save system)
+ FI
+
+END PROC save system;
+
+PROC system down (PROC operation):
+
+ BOOL VAR dialogue :: command dialogue;
+ command dialogue (FALSE);
+ operation;
+ command dialogue (dialogue);
+ IF command dialogue
+ THEN wait for configurator;
+ show date;
+ FI.
+
+show date:
+ page;
+ line (2);
+ put (" Heute ist der"); putline (date);
+ put (" Es ist"); put (time of day); putline ("Uhr");
+ line (2).
+
+END PROC system down;
+
+DATASPACE VAR ds := nilspace;
+
+PROC wait for configurator:
+
+ INT VAR i, receipt;
+ FOR i FROM 1 UPTO 20 WHILE configurator exists REP
+ pause (30);
+ forget (ds);
+ ds := nilspace;
+ ping pong (configurator, ack, ds, receipt)
+ UNTIL receipt >= 0 PER.
+
+configurator exists:
+ disable stop;
+ TASK VAR configurator := task ("configurator");
+ clear error;
+ NOT is niltask (configurator).
+
+END PROC wait for configurator;
+
+PROC generate shutup manager:
+
+ generate shutup manager ("shutup", 0);
+
+END PROC generate shutup manager;
+
+PROC generate shutup manager (TEXT CONST name, INT CONST new system):
+
+ TASK VAR son;
+ shutup question := name;
+ new system for manager := new system;
+ begin (name, PROC shutup manager, son)
+
+END PROC generate shutup manager;
+
+INT VAR new system for manager;
+TEXT VAR shutup question;
+
+PROC shutup manager:
+
+ disable stop;
+ command dialogue (TRUE);
+ REP
+ break;
+ line ;
+ IF yes (shutup question)
+ THEN clear error;
+ shutup (new system for manager);
+ pause (300);
+ FI;
+ PER
+
+END PROC shutup manager;
+
+PROC shutup dialog:
+ init;
+ show actual partition table (typnr);
+ REP
+ enter part number;
+ get cursor (cx, cy);
+ IF NOT escaped CAND yes (shutup question)
+ THEN message;
+ shutup (partition type);
+ LEAVE shutup dialog
+ FI;
+ PER.
+
+shutup question:
+ IF partition null
+ THEN "Shutup ausführen"
+ ELSE "Shutup nach Partition mit Typnummer " + text (typnr (partition)) + " ausführen"
+ FI.
+
+message:
+ cl eol (1, cy);
+ put line ("Bitte auf ENDE - Meldung warten !").
+
+partition type:
+ IF partition = 0
+ THEN 0
+ ELSE typnr (partition)
+ FI.
+
+init:
+ LET startzeile menu = 12,
+ escape = ""27"",
+ max partitions = 4;
+
+ ROW max partitions INT VAR typnr;
+ INT VAR partition, cx, cy;
+ TEXT VAR retchar.
+
+partition null:
+ partition = 0 COR typnr (partition) = 0.
+
+enter part number :
+ cl eop (1, startzeile menu);
+ cursor (54, startzeile menu ); put ("Abbruch mit <ESC>");
+ cursor (54, startzeile menu + 1); put ("Shutup ohne Wechsel mit <0>");
+ cursor ( 1, startzeile menu);
+ put ("Zu welcher Partition wollen Sie wechseln :");
+ get cursor (cx, cy);
+ REP
+ REP cursor (cx, cy);
+ partition := get choice (0, 4, retchar);
+ IF sure escaped THEN LEAVE shutup dialog FI;
+ UNTIL NOT escaped PER;
+ IF partition <> 0 CAND NOT partition exists
+ THEN fehler;
+ put ("Diese Partition gibt es nicht")
+ FI;
+ UNTIL partition = 0 OR partition exists PER;
+ cl eol (54, startzeile menu);
+ cl eol (54, startzeile menu + 1);
+ cl eop (1, cy + 2).
+
+partition exists:
+ typnr (partition) <> 0.
+
+escaped :
+ retchar = escape.
+
+sure escaped :
+ IF escaped THEN cl eop (1, 20); cursor (1, 22);
+ IF yes ("Shutup-Dialog abbrechen") THEN TRUE
+ ELSE cl eop (1, 20);
+ FALSE
+ FI
+ ELSE FALSE
+ FI.
+
+fehler :
+ cl eop (1, 20);
+ put (""7"" + inverse ("FEHLER :")); line (2).
+
+END PROC shutup dialog;
+
+PROC generate shutup dialog manager:
+ TASK VAR son;
+ begin ("shutup dialog", PROC shutup dialog manager, son)
+END PROC generate shutup dialog manager;
+
+PROC shutup dialog manager:
+ disable stop;
+ command dialogue (TRUE);
+ REP
+ break; line;
+ clear error;
+ INT VAR sess := session;
+ shutup dialog;
+ IF sess <> session THEN pause (300) FI;
+ PER;
+END PROC shutup dialog manager;
+
+END PACKET new shutup
+
+
+PACKET config manager with time DEFINES configuration manager ,
+ configuration manager with time :
+ (* Copyright (C) 1985 *)
+INT VAR old session := 0; (* Martin Schönbeck, Spenge *)
+ (* Stand: 06.11.85 *)
+PROC configuration manager:
+
+ configurate;
+ break;
+ global manager (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST)
+ configuration manager with time)
+
+END PROC configuration manager;
+
+PROC configuration manager with time (DATASPACE VAR ds, INT CONST order,
+ phase, TASK CONST order task):
+
+ IF old session <> session
+ THEN
+ disable stop;
+ set clock (hw clock);
+ set clock (hw clock); (* twice, to avoid all paging delay *)
+ IF is error THEN IF online THEN put error; clear error; pause (100)
+ ELSE clear error
+ FI FI;
+ old session := session;
+ set autonom;
+ FI;
+ configuration manager (ds, order, phase, order task);
+
+END PROC configuration manager with time;
+
+END PACKET config manager with time;
+
diff --git a/at/AT install b/at/AT install
new file mode 100644
index 0000000..11f9b55
--- /dev/null
+++ b/at/AT install
@@ -0,0 +1,93 @@
+(*************************************************************************)
+(*** Insertiert alle notwendigen Pakete, damit ein AT-System generiert ***)
+(*** werden kann, das die Hardwareuhr lesen und Partitionen bedienen ***)
+(*** kann. Startet den "AT Generator". ***)
+(*** ***)
+(*** Autor : W. Sauerwein Stand : 15.07.86 ***)
+(*************************************************************************)
+
+erste bildschirmmeldung;
+IF ich bin single THEN putline ("Die AT-spezifische Software ist nur auf Multi-User-Systemen benutzbar !")
+ ELSE hole dateien vom archiv;
+ insertiere alle pakete;
+ put line ("Running ""AT Generator""...");
+ run ("AT Generator")
+FI;
+forget ("AT install", quiet).
+
+ich bin single : (pcb (9) AND 255) <= 1.
+
+insertiere alle pakete :
+ insert and say ("AT Utilities").
+
+erste bildschirmmeldung :
+ page;
+ put center (" Generator für AT-spezifische Software gestartet."); line;
+ put center ("--------------------------------------------------");
+ line (2).
+
+hole dateien vom archiv :
+ TEXT VAR datei;
+ datei := "AT Utilities"; hole wenn noetig;
+ datei := "AT Generator"; hole wenn noetig;
+ release (archive);
+ line.
+
+hole wenn noetig :
+ IF NOT exists (datei) THEN
+ put line ("Loading """ + datei + """...");
+ fetch (datei, archive)
+ FI.
+
+PROC insert and say (TEXT CONST datei) :
+
+ INT VAR cx, cy;
+ put line ("Inserting """ + datei + """...");
+ get cursor (cx, cy);
+ insert (datei);
+ cl eop (cx, cy); line;
+ forget (datei, quiet).
+
+END PROC insert and say;
+
+TEXT PROC inverse (TEXT CONST t):
+ ""15"" + t + " " + ""14""
+END PROC inverse;
+
+PROC put center (TEXT CONST t):
+ put center (t, 80)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+ put center (zeile, t, 80)
+END PROC put center;
+
+PROC put center (TEXT CONST t, INT CONST gesamtbreite):
+ INT VAR cy;
+ get cursor (cy, cy);
+ put center (cy, t, gesamtbreite)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t, INT CONST gesamtbreite):
+ cursor ((gesamtbreite - length (t)) DIV 2, zeile);
+ put (t).
+END PROC put center;
+
+PROC cl eol:
+ out (""5"")
+END PROC cl eol;
+
+PROC cl eop:
+ out (""4"")
+END PROC cl eop;
+
+PROC cl eol (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eol
+END PROC cl eol;
+
+PROC cl eop (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eop
+END PROC cl eop;
+
diff --git a/basic/BASIC.Administration b/basic/BASIC.Administration
new file mode 100644
index 0000000..6df6854
--- /dev/null
+++ b/basic/BASIC.Administration
@@ -0,0 +1,1886 @@
+(***************************************************************************)
+(* *)
+(* Zweite von drei Dateien des EUMEL-BASIC-Systems *)
+(* *)
+(* Autor: Heiko Indenbirken *)
+(* Überarbeitet von: Rudolf Ruland und Michael Overdick *)
+(* *)
+(* Stand: 27.10.1987 *)
+(* *)
+(***************************************************************************)
+
+PACKET basic errors DEFINES basic error, (* Autor: Heiko Indenbirken *)
+ return error, (* Stand: 26.08.1987/rr/mo *)
+ basic warning:
+
+TEXT VAR erste zeile,
+ message;
+LET errorsize = 40;
+LET ERROR = STRUCT (INT no, TEXT msg);
+
+ROW errorsize ERROR CONST error msg :: ROW errorsize ERROR :
+(ERROR:( 1, "NEXT ohne FOR"),
+ ERROR:( 2, "Syntaxfehler:"),
+ ERROR:( 5, "Fehlerhafter Funktionsaufruf"),
+ ERROR:( 8, "Zeile mit dieser Nummer existiert nicht"),
+ ERROR:(10, "Das Feld ist bereits dimensioniert"),
+ ERROR:(13, "Falscher Typ:"),
+ ERROR:(15, "Text zu lang"),
+ ERROR:(18, "Undefinierte 'user function'"),
+ ERROR:(22, "Ausdruck erwartet"),
+ ERROR:(26, "FOR ohne NEXT"),
+ ERROR:(29, "WHILE ohne WEND"),
+ ERROR:(30, "WEND ohne WHILE"),
+ ERROR:(51, "Interner Fehler"),
+ ERROR:(80, "Fehlerhafte Zeilennummer"),
+ ERROR:(81, "Falsche Reihenfolge der Zeilennummern"),
+ ERROR:(82, "Falscher Typ des Operanden:"),
+ ERROR:(83, "Falscher Typ der Operanden:"),
+ ERROR:(84, "Falsche Felddimension:"),
+ ERROR:(85, "Rekursive Funktionsdefinition"),
+ ERROR:(86, "Fehlerhafte Laufvariable:"),
+ ERROR:(87, "Fehlerhafte Bereichsangabe:"),
+ ERROR:(88, "Fehlerhafte Dimensionierung:"),
+ ERROR:(89, "Parametervariable kommt mehrmals vor"),
+ ERROR:(90, "AS ohne NAME"),
+ ERROR:(91, "BASE ohne OPTION"),
+ ERROR:(92, "ELSE ohne IF"),
+ ERROR:(93, "STEP ohne FOR"),
+ ERROR:(94, "TAB ohne (L)PRINT"),
+ ERROR:(95, "THEN ohne IF"),
+ ERROR:(96, "TO ohne Zusammenhang"),
+ ERROR:(97, "USING ohne (L)PRINT"),
+ ERROR:(98, "Unbekannte Funktion,"),
+ ERROR:(99, "Unbekannte Prozedur,"),
+ ERROR:(100,"Nicht implementiert"),
+ ERROR:(101,"SUB ohne GO"),
+ ERROR:(102,"GO ohne TO oder SUB"),
+ ERROR:(103,"Accessrecht VAR erwartet, CONST gefunden"),
+ ERROR:(104,"Funktionsaufruf ohne Zusammenhang"),
+ ERROR:(105,"Nach OPTION BASE ist nur 0 oder 1 erlaubt"),
+ ERROR:(106,"Bei SWAP nur gleiche Variablentypen erlaubt"));
+
+TEXT PROC errortext (INT CONST no):
+ INT VAR i;
+ FOR i FROM 1 UPTO errorsize
+ REP IF errormsg [i].no = no
+ THEN LEAVE errortext WITH errormsg [i].msg FI
+ PER;
+ "Unbekannter BASIC-Fehler #" + text (no) .
+END PROC errortext;
+
+PROC basic error (TEXT CONST packet,
+ INT CONST error nr,
+ INT CONST line nr,
+ INT CONST statement nr,
+ TEXT CONST position, addition,
+ BOOL CONST leave statement):
+ erste zeile aufbauen;
+ einfache fehlermeldung aufbauen;
+ diese auf terminal ausgeben;
+ diese in sysout datei ausgeben wenn noetig; (* F20/rr *)
+ fehlermeldung in fehlerdatei ausgeben;
+ IF leave statement (* DEF/mo *)
+ THEN errorstop (101, packet + "-Fehler")
+ FI.
+
+erste zeile aufbauen:
+ IF line nr = 0 AND statement nr = 0
+ THEN erste zeile := "FEHLER"
+ ELSE erste zeile := "FEHLER (Dateizeile ";
+ erste zeile CAT text (line nr);
+ erste zeile CAT ") in Zeile ";
+ erste zeile CAT text (statement nr);
+ FI;
+
+ erste zeile CAT " bei >> ";
+ erste zeile CAT position;
+ erste zeile CAT " << : " .
+
+einfache fehlermeldung aufbauen:
+ message := " ";
+ message CAT error text (error nr);
+ message CAT " " .
+
+diese auf terminal ausgeben: (* F20/rr *)
+ display (""13""10"");
+ display (erste zeile);
+ display (""13""10"");
+ display (message + addition);
+ display (""13""10"") .
+
+diese in sysout datei ausgeben wenn noetig : (* F20/rr *)
+ IF sysout <> ""
+ THEN putline (erste zeile);
+ putline (message + addition);
+ line;
+ FI .
+
+fehlermeldung in fehlerdatei ausgeben:
+ note (erste zeile);
+ note line;
+ note (message);
+ note (addition);
+ note line .
+
+END PROC basic error;
+
+PROC basic warning (INT CONST line nr, (* mo *)
+ statement nr,
+ TEXT CONST warning text):
+generate warning;
+on screen;
+in sysout file;
+into the notebook.
+
+generate warning:
+ IF line nr = 0 AND statement nr = 0
+ THEN erste zeile := "WARNUNG"
+ ELSE erste zeile := "WARNUNG (Dateizeile ";
+ erste zeile CAT text (line nr);
+ erste zeile CAT ") in Zeile ";
+ erste zeile CAT text (statement nr);
+ FI;
+ erste zeile CAT ": ";
+ erste zeile CAT warning text.
+
+on screen:
+ display (""13""10"");
+ display (erste zeile);
+ display (""13""10"").
+
+in sysout file:
+ IF sysout <> ""
+ THEN putline (erste zeile);
+ line;
+ FI.
+
+into the notebook:
+ IF warnings
+ THEN note (erste zeile);
+ note line
+ FI.
+
+END PROC basic warning;
+
+PROC return error:
+ errorstop (1003, "RETURN ohne GOSUB")
+END PROC return error;
+
+END PACKET basic errors;
+
+PACKET basic types DEFINES symbol of, (* Autor: Heiko Indenbirken *)
+ type of, (* Stand: 07.09.1987/rr/mo *)
+ dim of,
+ shift, deshift,
+ reserved,
+ param list,
+ is bool op:
+
+LET (* S y m b o l T y p e n *)
+ any = 0, const = 1, var = 2, array = 3,
+ expr = 4, unused = 5, letter = 6, param = 7,
+ res word = 8, operator = 9, eos = 10, del = 11,
+ stat no = 12, eol = 13, eop = 14,
+ user fn = 20; (* DEF/mo *)
+(* Operatoren *)
+LET less equal = 28, unequal = 29, greater equal = 30;
+
+TEXT VAR dummy;
+
+TEXT PROC symbol of (INT CONST n) :
+ IF n < 0
+ THEN ""19"" + symbol of (-n)
+ ELSE SELECT n OF
+ CASE less equal : "<="
+ CASE unequal : "<>"
+ CASE greater equal : ">="
+
+ CASE eos : "EOS"
+ CASE eol : "EOL"
+ CASE eop : "EOF"
+ OTHERWISE : character END SELECT
+ FI .
+
+character :
+ IF n > 32 AND n < 128
+ THEN code (n)
+ ELIF n >= 128 AND n <= 255
+ THEN res word of (n)
+ ELSE "%" + subtext (text (n+1000), 2) + " " FI .
+
+END PROC symbol of;
+
+TEXT PROC type of (INT CONST n) :
+ SELECT n OF
+ CASE any : "ANY"
+ CASE const : "Konstante"
+ CASE var : "Variable"
+ CASE array : "Feld"
+ CASE expr : "Ausdruck"
+ CASE unused : " -?- "
+ CASE letter : "Buchstabe"
+ CASE param : "Parameter"
+ CASE res word : "reserviertes Wort"
+ CASE operator : "Operator"
+ CASE eos : "EOS"
+ CASE del : "Trennzeichen"
+ CASE stat no : "Zeilennumer"
+ CASE eol : "EOL"
+ CASE eop : "EOF"
+ CASE user fn : "'user function'" (* DEF/mo *)
+ OTHERWISE "?TYPE #" + text (n) ENDSELECT.
+END PROC type of;
+
+TEXT PROC dim of (TEXT CONST parameter):
+ IF parameter = ""
+ THEN ""
+ ELSE base limits and size FI .
+
+base limits and size:
+ INT CONST dimension :: (LENGTH parameter DIV 2) - 2;
+ TEXT VAR result :: text (parameter ISUB dimension+1);
+ INT VAR i;
+ result CAT ": [";
+ FOR i FROM 1 UPTO dimension-1
+ REP result CAT text (parameter ISUB i);
+ result CAT ", "
+ PER;
+ result CAT text (parameter ISUB dimension);
+ result CAT "] ";
+ result CAT text (parameter ISUB dimension+2);
+ result .
+
+END PROC dim of;
+
+TEXT PROC param list (INT CONST first, no):
+ IF no < first
+ THEN "keine"
+ ELSE parameter list FI .
+
+parameter list:
+ INT VAR i;
+ TEXT VAR result :: "(";
+ FOR i FROM first UPTO no
+ REP result CAT dump (dtype (i));
+ IF i = no
+ THEN result CAT ")"
+ ELSE result CAT ", " FI
+ PER;
+ result .
+
+END PROC param list;
+
+TEXT PROC shift (TEXT CONST word) :
+ INT VAR i;
+ dummy := word;
+ FOR i FROM 1 UPTO length (word)
+ REP shift char PER;
+ dummy .
+
+shift char:
+ INT VAR local letter :: code (dummy SUB i);
+ IF 97 <= local letter AND local letter <= 122
+ THEN replace (dummy, i, code (local letter - 32)) FI .
+
+END PROC shift;
+
+TEXT PROC deshift (TEXT CONST word) :
+ INT VAR i;
+ dummy := word;
+ FOR i FROM 1 UPTO length (word)
+ REP deshift char PER;
+ dummy .
+
+deshift char:
+ INT VAR local letter :: code (dummy SUB i);
+ IF 65 <= local letter AND local letter <= 90
+ THEN replace (dummy, i, code (local letter + 32)) FI;
+
+END PROC deshift;
+
+(* Verwaltung der Reservierten BASIC-Wörter *)
+LET first operator = 249, (* MOD NOT AND OR XOR EQV IMP *)
+ first bool op = 250; (* 249 250 251 252 253 254 255 *)
+
+INT VAR index;
+ROW 9 TEXT VAR res words :: ROW 9 TEXT :
+("",
+ ""129"as"163"go"167"if"188"on"217"to"252"or",
+ ""128"abs"130"asc"131"atn"141"cos"142"cvd"143"cvi"145"def"150"dim"152"end"153"eof"154"erl"155"err"157"exp"159"fix"160"for"161"fre"162"get"172"int"175"len"176"let"178"loc"179"log"191"out"192"pos"194"put"202"rnd"197"rem"204"sgn"205"sin"207"spc"208"sqr"214"tab"215"tan"221"val"227"cls"234"usr"235"sub"249"mod"250"not"251"and"253"xor"254"eqv"255"imp",
+ ""132"base"133"call"134"cdbl"136"chr$"137"cint"144"data"151"else"165"goto"166"hex$"173"kill"177"line"181"lset"182"mid$"183"mkd$"184"mki$"185"name"186"next"187"oct$"189"open"196"read"203"rset"209"step"210"stop"211"str$"213"swap"216"then"219"tron"222"wait"223"wend"228"erm$"230"lpos",
+ ""135"chain"138"clear"139"close"156"error"158"field"164"gosub"169"input"171"instr"174"left$"193"print"218"troff"220"using"224"while"225"width"226"write"231"time$"232"date$"233"timer",
+ ""140"common"146"defdbl"147"defint"148"defsng"149"defstr"168"inkey$"170"input$"180"lprint"190"option"199"resume"200"return"201"right$"206"space$"229"csrlin",
+ ""198"restore"212"string$",
+ "",
+ ""195"randomize");
+
+BOOL PROC reserved (TEXT CONST name, INT VAR no, type):
+ IF reserve is not possible COR not found within res words
+ THEN FALSE
+ ELSE no := code (this words SUB (index-1));
+ type := res word or op;
+ TRUE
+ FI .
+
+reserve is not possible:
+ INT CONST len :: length (name);
+ len < 2 OR len > 9 .
+
+not found within res words:
+ index := pos (this words, name);
+ index = 0 .
+
+this words:
+ res words [len] .
+
+res word or op:
+ IF no >= first operator
+ THEN operator
+ ELSE res word FI .
+
+END PROC reserved;
+
+INT PROC reserved (TEXT CONST name):
+ IF reserve is not possible COR not found within res words
+ THEN 0
+ ELSE code (this words SUB (index-1)) FI .
+
+reserve is not possible:
+ INT CONST len :: length (name);
+ len < 2 OR len > 9 .
+
+not found within res words:
+ index := pos (this words, name);
+ index = 0 .
+
+this words:
+ res words [len] .
+
+END PROC reserved;
+
+TEXT PROC res word of (INT CONST no):
+ INT VAR i;
+ FOR i FROM 2 UPTO 9
+ REP index := pos (res words [i], code (no));
+ IF index > 0
+ THEN LEAVE res word of WITH shift (this name) FI
+ PER;
+ "" .
+
+this name:
+ subtext (res words [i], index+1, next code) .
+
+next code:
+ INT VAR c := pos (res words [i], ""127"", ""255"", index+1);
+ IF c = 0
+ THEN length (res words [i])
+ ELSE c-1 FI .
+
+END PROC res word of;
+
+BOOL PROC is bool op (INT CONST no): (* mo *)
+ no >= first bool op
+END PROC is bool op;
+
+END PACKET basic types;
+
+PACKET basic table handling DEFINES init table, (* Autor: Heiko Indenbirken *)
+ put name, (* Stand: 13.08.1987/rr/mo *)
+ known, name of,
+ remember,
+ recognize,
+ table entries,
+ hash table, next table,
+ scope compulsory: (* DEF/mo *)
+
+LET hash length = 1024,
+ hash length minus one = 1023,
+ start of name table = 256,
+ table length = 4500;
+
+LET SYMBOL = STRUCT (INT type, ADDRESS adr, DTYPE data, TEXT dim);
+LET TABLE = STRUCT (INT entries,
+ ROW hash length INT hash table,
+ ROW table length INT next,
+ ROW table length TEXT name table,
+ ROW table length SYMBOL symbol table);
+
+DATASPACE VAR table space;
+BOUND TABLE VAR table;
+INITFLAG VAR tab := FALSE;
+SYMBOL CONST nilsymbol :: SYMBOL:(0, LOC 0, void type, "");
+INT VAR i;
+BOOL VAR compulsory with scope :: TRUE; (* DEF/mo *)
+
+PROC init table:
+ IF NOT initialized (tab)
+ THEN table space := nilspace;
+ table := table space;
+ FI;
+ table.entries := start of name table;
+ FOR i FROM 1 UPTO hash length
+ REP table.hash table [i] := 0 PER;
+ compulsory with scope := TRUE; (* DEF/mo *)
+
+END PROC init table;
+
+PROC put name (TEXT CONST scope, name, INT VAR pointer): (* DEF/mo *)
+ IF compulsory with scope
+ THEN put name (scope + name, pointer)
+ ELIF NOT in table
+ THEN put name (name, pointer)
+ FI.
+
+in table:
+ hash (scope + name, pointer);
+ pointer := hash table (pointer);
+ WHILE not end of chain
+ REP IF name is found THEN LEAVE in table WITH TRUE FI;
+ pointer := table. next (pointer);
+ PER;
+ FALSE .
+
+name is found:
+ table.name table [pointer] = scope + name.
+
+not end of chain:
+ pointer > 0 .
+
+END PROC put name;
+
+PROC put name (TEXT CONST name, INT VAR pointer):
+ IF no entry in hash table
+ THEN create a new chain
+ ELSE create a new entry in chain FI;
+ insert name in name table .
+
+no entry in hash table:
+ INT VAR hash index;
+ hash (name, hash index);
+ table.hash table [hash index] = 0 .
+
+create a new chain:
+ table.hash table [hash index] := table.entries .
+
+create a new entry in chain:
+ pointer := table.hash table [hash index];
+ REP IF name is found
+ THEN LEAVE put name
+ ELIF end of chain
+ THEN table.next [pointer] := table.entries;
+ LEAVE create a new entry in chain
+ ELSE pointer := next pointer FI
+ PER .
+
+name is found:
+ table.name table [pointer] = name.
+
+end of chain:
+ INT CONST next pointer := table.next [pointer];
+ next pointer = 0 .
+
+insert name in name table:
+ IF table.entries >= table length
+ THEN errorstop ("volle Namenstabelle") FI;
+
+ pointer := table.entries;
+ table.symbol table [pointer] := nilsymbol;
+ table.name table [pointer] := name;
+ table.next [pointer] := 0;
+ table.entries INCR 1 .
+
+END PROC put name;
+
+PROC hash (TEXT CONST name, INT VAR index) :
+ INT VAR j;
+ index := 0;
+ FOR j FROM 1 UPTO length (name)
+ REP addmult cyclic PER;
+ index INCR 1 .
+
+addmult cyclic :
+ index INCR index ;
+ IF index > hash length minus one
+ THEN wrap around FI;
+ index := (index + code (name SUB j)) MOD hash length minus one .
+
+wrap around:
+ index DECR hash length minus one .
+
+ENDPROC hash ;
+
+INT PROC table entries:
+ table.entries
+END PROC table entries;
+
+INT PROC hash table (INT CONST n):
+ table.hash table [n]
+END PROC hash table;
+
+INT PROC next table (INT CONST n):
+ table.next [n]
+END PROC next table;
+
+TEXT PROC name of (INT CONST index):
+ IF index < 0
+ THEN errorstop ("PROC name of: negativer Index"); ""
+ ELIF index < start of name table
+ THEN symbol of (index)
+ ELIF index <= table.entries
+ THEN table.name table (index)
+ ELSE errorstop ("PROC name of: Index größer als nametable");
+ ""
+ FI
+
+END PROC name of;
+
+PROC recognize (INT CONST symb, type, ADDRESS CONST adr, DTYPE CONST data, TEXT CONST dim):
+ symbol.type := type;
+ symbol.adr := adr;
+ symbol.data := data;
+ symbol.dim := dim .
+
+symbol: table.symboltable [symb] .
+END PROC recognize;
+
+PROC remember (INT CONST symb, INT VAR type, ADDRESS VAR adr, DTYPE VAR data, TEXT VAR dim):
+ SYMBOL CONST symbol := table.symboltable [symb];
+ type := symbol.type;
+ adr := symbol.adr;
+ data := symbol.data;
+ dim := symbol.dim
+END PROC remember;
+
+BOOL PROC known (INT CONST symb) :
+ table.symboltable [symb].type > 0
+END PROC known;
+
+PROC scope compulsory (BOOL CONST new state): (* DEF/mo *)
+ compulsory with scope := new state
+END PROC scope compulsory;
+
+END PACKET basic table handling;
+
+PACKET basic scanner DEFINES begin scanning, (* Autor: Heiko Indenbirken *)
+ next symbol, (* Stand: 27.10.1987/rr/mo *)
+ next data,
+ next statement,
+ define chars,
+ scan line,
+ scan line no, (* F29/rr *)
+ get data types of input vars, (* F25/rr *)
+ basic error,
+ basic warning,
+ basic list,
+ set scope,
+ scanner scope:
+
+
+LET (* S y m b o l T y p e n *)
+ any = 0, const = 1, var = 2, array = 3,
+ res word= 8, operator= 9, eos = 10, del =11,
+ stat no = 12, user fn = 20; (* DEF/mo *)
+
+LET (* S y m b o l z e i c h e n *)
+ less = 60, greater = 62,
+ less equal = 28, unequal = 29, greater equal = 30,
+ point = 46, eol = 13, eop = 14,
+ go = 163, gosub = 164, goto = 165,
+ sub = 235, to = 217;
+
+LET name chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.0123456789!#$%",
+ quote = """", open bracket = "(",
+ comma = ",", close bracket = ")",
+ colon = ":",
+ exponent chars= "dDeE";
+
+FILE VAR source file;
+TEXT VAR defint chars, defstr chars, record, letter,
+ scope, new name; (* DEF/mo *)
+REAL VAR r dummy;
+INT VAR act stat no, record no, rec len, scan pos, i dummy;
+BOOL VAR eol generated, at line begin, listing := FALSE;
+
+PROC define chars (TEXT CONST begin, end, DTYPE CONST data):
+ INT VAR i;
+ FOR i FROM code (begin) UPTO code (end)
+ REP IF data = int type
+ THEN defint chars CAT code (i)
+ ELIF data = text type
+ THEN defstr chars CAT code (i)
+ FI
+ PER .
+
+END PROC define chars;
+
+
+PROC scanline (TEXT VAR line, INT VAR col):
+ line := record;
+ col := scan pos
+END PROC scanline;
+
+INT PROC scan line no : record no END PROC scan line no;
+
+
+PROC get data types of input vars (ROW 100 DTYPE VAR input var data, (* F25/rr *)
+ INT VAR number input vars) :
+
+ TEXT VAR first var char;
+ INT VAR var pos := scan pos;
+ to begin of actual var;
+ REP get next input var;
+ skip brackets if necessary;
+ IF var char <> comma THEN LEAVE get data types of input vars FI;
+ skip comma;
+ PER;
+
+ . var char : record SUB var pos
+
+ . to begin of actual var :
+ WHILE pos (name chars, var char) <> 0 REP var pos DECR 1 PER;
+ var pos INCR 1;
+ number input vars := 0;
+
+ . get next input var :
+ first var char := deshift (var char);
+ WHILE pos (name chars, var char) <> 0 REP var pos INCR 1 PER;
+ var pos DECR 1;
+ number input vars INCR 1;
+ input var data (number input vars) := var datatype (first var char, var char);
+ var pos := pos (record, ""33"", ""255"", var pos + 1);
+
+ . skip brackets if necessary :
+ IF var char = open bracket
+ THEN INT VAR bracket counter := 1;
+ REP count bracket UNTIL bracket counter = 0 PER;
+ var pos := pos (record, ""33"", ""255"", var pos + 1);
+ FI;
+
+ . count bracket :
+ INT CONST open := pos (record, open bracket, var pos + 1),
+ close := pos (record, close bracket, var pos + 1);
+ IF open > 0
+ THEN IF close > 0
+ THEN IF open > close
+ THEN close bracket found
+ ELSE open bracket found
+ FI;
+ ELSE open bracket found
+ FI;
+ ELSE IF close > 0
+ THEN close bracket found
+ ELSE LEAVE get data types of input vars
+ FI;
+ FI;
+
+ . open bracket found :
+ bracket counter INCR 1;
+ var pos := open;
+
+ . close bracket found :
+ bracket counter DECR 1;
+ var pos := close;
+
+ . skip comma :
+ var pos := pos (record, ""33"", ""255"", var pos + 1);
+
+END PROC get data types of input vars;
+
+
+PROC begin scanning (FILE VAR basic file):
+ enable stop;
+ source file := basic file;
+ to first record (source file);
+ col (source file, 1);
+ IF eof (source file)
+ THEN errorstop ("Datei ist leer") FI;
+
+ defint chars := "";
+ defstr chars := "";
+ scope := ""; (* DEF/mo *)
+ act stat no := 0;
+ read record (source file, record);
+ rec len := length (record);
+ scan pos := 0;
+ record no := 1;
+ eol generated := FALSE;
+ at line begin := TRUE;
+ IF listing
+ THEN line;
+ putline (record);
+ IF sysout <> ""
+ THEN cout (record no)
+ FI
+ ELSE cout (record no)
+ FI.
+
+END PROC begin scanning;
+
+PROC next statement:
+ IF eof (source file)
+ THEN errorstop (99, "")
+ ELSE eol generated := FALSE;
+ at line begin := TRUE;
+ down (source file);
+ read record (source file, record);
+ rec len := length (record);
+ scan pos := 0;
+ record no INCR 1;
+ FI;
+ IF listing
+ THEN putline (record);
+ IF sysout <> ""
+ THEN cout (record no)
+ FI
+ ELSE cout (record no)
+ FI.
+
+END PROC next statement;
+
+PROC next symbol (TEXT VAR name, INT VAR no, type, DTYPE VAR data):
+ enable stop;
+ clear symbol;
+ IF eol generated
+ THEN next statement FI;
+
+ IF eol reached
+ THEN generate eol
+ ELIF at line begin CAND stat no found (* F15/rr *)
+ THEN generate stat no
+ ELSE generate chars FI .
+
+clear symbol:
+ name := "";
+ no := 0;
+ type := any;
+ data := void type .
+
+eol reached:
+ scan pos := pos (record, ""33"", ""255"", scan pos+1);
+ scan pos = 0 .
+
+generate eol :
+ IF eof (source file)
+ THEN name := "EOF"; no := eop; type := eos
+ ELSE name := "EOL"; no := eol; type := eos FI;
+ eol generated := TRUE .
+
+stat no found: (* F15/rr *)
+ at line begin := FALSE;
+ pos ("0123456789", act char) <> 0 .
+
+generate stat no: (* F15/rr *)
+ INT CONST next scan pos := last number pos;
+ name := subtext (record, scan pos, next scan pos);
+ act stat no := int (name);
+ scan pos := next scan pos;
+ no := act stat no; type := stat no .
+
+last number pos : (* F15/rr *)
+ INT CONST high := pos (record, ""058"", ""255"", scan pos),
+ low := pos (record, ""032"", ""047"", scan pos);
+ IF high > 0
+ THEN IF low > 0
+ THEN min (high, low) - 1
+ ELSE high - 1
+ FI
+ ELIF low > 0
+ THEN low - 1
+ ELSE LENGTH record
+ FI .
+
+generate chars:
+ SELECT code (act char) OF
+ CASE 32: next symbol (name, no, type, data) (* Space *)
+ CASE 34: generate text denoter (* " *)
+ CASE 39: generate eol (* ' *)
+ CASE 42, 43, 45, 47, 92, 94, 61: generate operator (* *,+,-,/,\,^,=*)
+ CASE 60: generate less op (*<, <=, <> *)
+ CASE 62: generate greater op (*>, >= *)
+ CASE 46: treat point (* . *)
+ CASE 48, 49, 50, 51, 52, 53, 54, 55, 56, 57:
+ generate numeric const (* 0 - 9 *)
+ CASE 58: generate eos (* : *)
+ CASE 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, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, (* small and large letters *)
+ generate res word or id
+ OTHERWISE generate delimiter END SELECT .
+
+generate text denoter:
+ get text const (name, data);
+ type := const .
+
+generate operator:
+ name := act char; no := code (name); type := operator .
+
+generate less op:
+ IF next char = "="
+ THEN name := "<="; no := less equal; skip char
+ ELIF next char = ">"
+ THEN name := "<>"; no := unequal; skip char
+ ELSE name := "<"; no := less FI;
+ type := operator .
+
+generate greater op:
+ IF next char = "="
+ THEN name := ">="; no := greater equal; skip char
+ ELSE name := ">"; no := greater; FI;
+ type := operator .
+
+treat point:
+ IF pos ("0123456789", next char) <> 0
+ THEN generate numeric const
+ ELSE name := ".";
+ no := point;
+ type := del
+ FI.
+
+generate numeric const:
+ get numeric const (name, data);
+ type := const .
+
+last name char:
+ name SUB LENGTH name .
+
+generate eos:
+ name := ":"; no := eos; type := eos .
+
+generate res word or id:
+ get name chars;
+ IF reserved (deshift name, no, type)
+ THEN IF type = res word AND no = go
+ THEN treat go
+ FI
+ ELSE IF function name
+ THEN data := ftn datatype;
+ type := user fn
+ ELSE data := var datatype (deshift (name) SUB 1, last name char);
+ type := var or array
+ FI;
+ put name (scope, deshift name, no)
+ FI.
+
+treat go:
+ next symbol (new name, no, type, data);
+ IF no = to AND type = res word
+ THEN name CAT new name;
+ no := goto
+ ELIF no = sub AND type = res word
+ THEN name CAT new name;
+ no := gosub
+ ELSE scan error (102, name, "")
+ FI.
+
+get name chars:
+ TEXT VAR deshift name :: "";
+ INT VAR begin of name :: scan pos;
+ FOR scan pos FROM scan pos UPTO rec len
+ WHILE name chars found
+ REP deshift name CAT deshifted char PER;
+ scan pos DECR 1;
+ name := subtext (record, begin of name, scan pos).
+
+name chars found:
+ pos (name chars, act char) > 0 .
+
+function name:
+ subtext (deshift name, 1, 2) = "fn" .
+
+ftn datatype:
+ IF last name char = "$"
+ THEN text type
+ ELIF last name char = "%"
+ THEN int type
+ ELSE real type FI .
+
+var or array:
+ IF array name
+ THEN name CAT "()";
+ deshift name CAT "()"; (* F30/rr *)
+ array
+ ELSE var FI .
+
+array name:
+ next scan char = "(" .
+
+deshifted char:
+ letter := act char;
+ IF letter >= "A" AND letter <= "Z"
+ THEN code (code (letter) + 32)
+ ELSE letter FI .
+
+generate delimiter:
+ name := act char; no := code (name); type := del .
+
+next scan char: record SUB pos (record, ""33"", ""255"", scan pos+1).
+next char: (record SUB scan pos + 1) .
+act char: record SUB scan pos .
+skip char: scan pos INCR 1 .
+END PROC next symbol;
+
+DTYPE PROC var datatype (TEXT CONST first name char, last name char) :
+
+ IF last name char = "!" OR last name char = "#"
+ THEN real type
+ ELIF last name char = "$"
+ THEN text type
+ ELIF last name char = "%"
+ THEN int type
+ ELIF pos (defint chars, first name char) > 0
+ THEN int type
+ ELIF pos (defstr chars, first name char) > 0
+ THEN text type
+ ELSE real type FI .
+
+END PROC var datatype;
+
+BOOL PROC next data (TEXT VAR data text, DTYPE VAR data type) : (* F17/rr *)
+
+ data type := void type;
+ IF no more data
+ THEN scan pos := rec len;
+ data text := "";
+ FALSE
+ ELIF quoted string
+ THEN get quoted string;
+ TRUE
+ ELSE get unquoted string;
+ TRUE
+ FI
+
+ . no more data :
+ scan pos := pos (record, ""33"", ""255"", scan pos+1);
+ scan pos = 0
+
+ . quoted string :
+ (record SUB scan pos) = quote
+
+ . get quoted string :
+ get text const (data text, data type);
+
+ . get unquoted string :
+ INT CONST comma or colon pos 1 := position of comma or colon minus one;
+ data text := compress (subtext (record, scan pos, comma or colon pos 1));
+ scan pos := comma or colon pos 1;
+
+ . position of comma or colon minus one :
+ INT CONST colon pos := pos (record, colon, scan pos),
+ comma pos := pos (record, comma, scan pos);
+ IF colon pos > 0
+ THEN IF comma pos > 0
+ THEN min (colon pos, comma pos) - 1
+ ELSE colon pos - 1
+ FI
+ ELSE IF comma pos > 0
+ THEN comma pos - 1
+ ELSE LENGTH record
+ FI
+ FI
+
+END PROC next data;
+
+PROC get numeric const (TEXT VAR value, DTYPE VAR data):
+ get sign;
+ get const;
+ check datatype .
+
+get sign:
+ IF act char = "-"
+ THEN value := "-";
+ scan pos INCR 1
+ ELIF act char = "+"
+ THEN value := "+";
+ scan pos INCR 1
+ ELSE value := "" FI .
+
+get const:
+ get digits;
+ get point;
+ get digits;
+ get exponent .
+
+get digits:
+ FOR scan pos FROM scan pos UPTO rec len
+ WHILE digit found
+ REP value CAT act char PER .
+
+get point:
+ IF act char = "."
+ THEN value CAT ".";
+ scan pos INCR 1
+ ELIF pos (exponent chars, act char) > 0
+ THEN value CAT ".0"
+ ELSE LEAVE get const FI .
+
+get exponent:
+ IF pos (exponent chars, act char) > 0 (* F1/rr *)
+ THEN value CAT "e";
+ scan pos INCR 1;
+ evtl get sign;
+ get digits
+ FI .
+
+evtl get sign:
+ IF act char = "+" OR act char = "-"
+ THEN value CAT act char;
+ scan pos INCR 1
+ FI .
+
+digit found:
+ "0" <= act char AND act char <= "9" .
+
+check datatype:
+ IF act char = "%"
+ THEN IF integer ok (value)
+ THEN data := int type
+ ELSE scan error (2, value, "INT-Konstante nicht korrekt") FI
+ ELIF act char = "!" OR act char = "#"
+ THEN IF real ok (value)
+ THEN data := real type
+ ELSE scan error (2, value, "REAL-Konstante nicht korrekt") FI
+ ELIF integer ok (value)
+ THEN scan pos DECR 1; data := int type
+ ELIF real ok (value)
+ THEN scan pos DECR 1;
+ data := real type
+ ELSE scan error (2, value, "Numerische Konstante nicht korrekt") FI .
+
+act char: record SUB scan pos .
+END PROC get numeric const;
+
+PROC get text const (TEXT VAR value, DTYPE VAR data):
+ INT CONST quote 1 := scan pos;
+ scan pos := pos (record, """", scan pos+1);
+ IF quote 1 < scan pos
+ THEN value := subtext (record, quote 1+1, scan pos-1);
+ data := text type
+ ELSE scan error (15, subtext (record, quote 1), "("" fehlt)") FI .
+
+END PROC get text const;
+
+BOOL PROC integer ok (TEXT VAR zahl):
+ disable stop;
+ i dummy := int (zahl);
+ IF is error
+ THEN clear error;
+ FALSE
+ ELIF last conversion ok
+ THEN zahl := ""0""0"";
+ replace (zahl, 1, i dummy);
+ TRUE
+ ELSE FALSE FI .
+
+END PROC integer ok;
+
+BOOL PROC real ok (TEXT VAR zahl):
+ disable stop;
+ r dummy := real (zahl);
+ IF is error
+ THEN clear error;
+ FALSE
+ ELIF last conversion ok
+ THEN zahl := ""0""0""0""0""0""0""0""0"";
+ replace (zahl, 1, r dummy);
+ TRUE
+ ELSE FALSE FI .
+
+END PROC real ok;
+
+PROC basic error (INT CONST no, TEXT CONST name, addition):
+ basic error ("Compiler", no, record no, act stat no, name, addition, TRUE)
+END PROC basic error;
+
+PROC basic error (INT CONST no, TEXT CONST name, addition, BOOL CONST leave statement):
+ basic error ("Compiler", no, record no, act stat no, name, addition, leave statement)
+END PROC basic error;
+
+PROC scan error (INT CONST no, TEXT CONST name, addition):
+ basic error ("Scanner", no, record no, act stat no, name, addition, TRUE)
+END PROC scan error;
+
+PROC basic warning (TEXT CONST warning text): (* mo *)
+ basic warning (record no, act stat no, warning text)
+END PROC basic warning;
+
+PROC basic list (BOOL CONST t):
+ listing := t
+END PROC basic list;
+
+BOOL PROC basic list:
+ listing
+END PROC basic list;
+
+PROC set scope (TEXT CONST new scope): (* DEF/mo *)
+ scope := new scope
+END PROC set scope;
+
+TEXT PROC scanner scope: (* DEF/mo *)
+ scope
+END PROC scanner scope;
+
+END PACKET basic scanner;
+
+
+PACKET basic stat no DEFINES init stat no, (* Autor: Heiko Indenbirken *)
+ stat no pos, (* Stand: 27.10.1987/rr/mo *)
+ label pos,
+ all stat no:
+
+LET nil = "";
+
+TEXT VAR found stat no :: nil;
+INT VAR i, akt stat no :: 0, found no :: 0;
+
+PROC init stat no (FILE VAR f, INT VAR error no): (* F21/rr *)
+(*Die Datei 'f' muß im 'modify-Mode' sein. *)
+ INT VAR line no;
+ akt stat no := -1; (* F28/rr *)
+ found no := 0;
+ found stat no := nil;
+ error no := 0; (* F21/rr *)
+ to first record (f);
+ col (f, 1);
+ disable stop;
+ FOR line no FROM 1 UPTO 4000
+ REP exec (PROC (TEXT CONST, INT CONST) check, f, line no);
+ IF is error THEN check error FI;
+ IF eof (f)
+ THEN LEAVE init stat no
+ ELSE down (f) FI
+ PER;
+
+. check error : (* F21/rr *)
+ IF error code = 100
+ THEN clear error;
+ error no INCR 1;
+ ELSE LEAVE init stat no;
+ FI;
+
+END PROC init stat no;
+
+PROC check (TEXT CONST record, INT CONST line no):
+ IF statement no vorhanden
+ THEN remember statement no FI .
+
+statement no vorhanden: (* F15/rr *)
+ INT CONST first number pos := pos (record, ""048"", ""057"", 1);
+ first number pos > 0 CAND first number pos = first non blank pos .
+
+first non blank pos : (* F15/rr *)
+ pos (record, ""033"", ""255"", 1) .
+
+remember statement no:
+ get statement no;
+ IF neue nummer ist groesser als vorherige
+ THEN akt stat no := neue nummer;
+ cout (neue nummer);
+ found no INCR 1;
+ found stat no CAT mki (neue nummer)
+ ELSE basic error ("Stat no", 81, line no, neue nummer, number,
+ "Letzte Zeilennummer davor: " + text (akt stat no), TRUE)
+ FI .
+
+get statement no : (* F15/rr *)
+ disable stop;
+ TEXT CONST number := subtext (record, first number pos, last number pos);
+ INT VAR neue nummer := int (number);
+ IF NOT last conversion ok OR is error
+ THEN clear error;
+ basic error ("Stat no", 80, line no, akt stat no, number,
+ "Die Zeilennummer muß im Bereich 0-32767 liegen", TRUE)
+ FI;
+ enable stop .
+
+last number pos : (* F15/rr *)
+ INT CONST high := pos (record, ""058"", ""255"", first number pos),
+ low := pos (record, ""032"", ""047"", first number pos);
+ IF high > 0
+ THEN IF low > 0
+ THEN min (high, low) - 1
+ ELSE high - 1
+ FI
+ ELIF low > 0
+ THEN low - 1
+ ELSE LENGTH record
+ FI .
+
+neue nummer ist groesser als vorherige:
+ neue nummer > akt stat no .
+
+END PROC check;
+
+INT PROC stat no pos (INT CONST stat no):
+ FOR i FROM found no DOWNTO 1
+ REP IF (found stat no ISUB i) = stat no
+ THEN LEAVE stat no pos WITH i FI
+ PER;
+ 0
+END PROC stat no pos;
+
+INT PROC label pos (INT CONST stat no):
+ FOR i FROM found no DOWNTO 1
+ REP IF (found stat no ISUB i) = stat no
+ THEN LEAVE label pos WITH i FI
+ PER;
+ basic error (8, text (stat no), nil); (* F16/rr *)
+ 0
+END PROC label pos;
+
+PROC all stat no (TEXT VAR stat no, INT VAR no):
+ stat no := found stat no;
+ no := found no
+END PROC all stat no;
+
+END PACKET basic stat no;
+
+PACKET basic storage DEFINES init storage, (* Autor: Heiko Indenbirken *)
+ next local adr, (* Stand: 12.06.86 *)
+ next ref,
+ local adr,
+ local storage,
+ type size,
+ quiet type:
+
+
+
+LET ref length = 2;
+
+INT VAR quiet size, quiet align;
+ADDRESS VAR loc adr, free loc adr;
+DTYPE VAR quiet value;
+identify ("QUIET", quiet size, quiet align, quiet value);
+
+PROC init storage:
+ free loc adr := LOC 0;
+ loc adr := LOC 0;
+
+END PROC init storage;
+
+(* Verwaltung der lokalen Addressen für Zwischenergebnisse *)
+ADDRESS PROC next local adr (DTYPE CONST type):
+ INT VAR type len :: type size (type);
+ loc adr := free loc adr;
+ adjust (loc adr, type len);
+ free loc adr := loc adr + type len;
+ loc adr .
+
+END PROC next local adr;
+
+ADDRESS PROC next ref:
+ loc adr := free loc adr;
+ adjust (loc adr, ref length);
+ free loc adr := loc adr + ref length;
+ loc adr .
+
+END PROC next ref;
+
+ADDRESS PROC local adr:
+ loc adr
+END PROC local adr;
+
+INT PROC local storage:
+ int (subtext (dump (free loc adr), 6))
+END PROC local storage;
+
+INT PROC type size (DTYPE CONST type):
+ IF type = int type OR type = bool type
+ THEN 1
+ ELIF type = row type
+ THEN 2
+ ELIF type = real type
+ THEN 4
+ ELIF type = text type
+ THEN 8
+ ELIF type = quiet value
+ THEN quiet size
+ ELSE errorstop ("Unbekannter DTYPE: " + dump (type)); 0 FI .
+
+END PROC type size;
+
+DTYPE PROC quiet type:
+ quiet value
+END PROC quiet type;
+
+END PACKET basic storage;
+
+PACKET basic identify DEFINES (* Autor: Heiko Indenbirken *)
+ (* Stand: 20.08.1987/rr/mo *)
+ identify,
+ convert paramfield,
+ dump ftn,
+ is basic function: (* mo *)
+
+LET nil = "";
+
+LET ENTRY = STRUCT (TEXT param, INT no, next, OPN opn, DTYPE result);
+
+ROW 256 ENTRY VAR ftn table;
+
+clear ftn table;
+init ftn names;
+init int operator;
+init real operator;
+init text operator;
+init predefined funktions;
+
+PROC dump ftn (INT CONST n, TEXT VAR param, INT VAR no, next,
+ OPN VAR opn, DTYPE VAR result):
+ param := ftn table [n].param;
+ no := ftn table [n].no;
+ next := ftn table [n].next;
+ opn := ftn table [n].opn;
+ result := ftn table [n].result
+
+END PROC dump ftn;
+
+PROC identify (INT CONST ftn no, first, params, OPN VAR operation, BOOL VAR found):
+ TEXT VAR param;
+ INT VAR pos :: min (ftn no, 256);
+ convert paramfield (first, params, param);
+ REP IF param = ftn table [pos].param AND ftn no = ftn table [pos].no
+ THEN declare (params+1, ftn table [pos].result);
+ declare (params+1, 1);
+ operation := ftn table [pos].opn;
+ found := TRUE;
+ LEAVE identify
+ ELSE pos := ftn table [pos].next FI
+ UNTIL pos <= 0 PER; (* F14/rr *)
+ operation := nop;
+ found := FALSE .
+
+END PROC identify;
+
+PROC next free entry (INT VAR free pos):
+ FOR free pos FROM 1 UPTO 256
+ REP IF ftn table [free pos].next < 0 AND ftn table [free pos].no = 0 (* mo *)
+ THEN LEAVE next free entry FI
+ PER;
+ errorstop ("Überlauf der Funktionstabelle") .
+
+END PROC next free entry;
+
+PROC convert paramfield (INT CONST first, params, TEXT VAR param):
+ INT VAR i;
+ param := nil;
+ FOR i FROM first UPTO params
+ REP param CAT datatype PER .
+
+datatype:
+ DTYPE CONST data :: dtype (i);
+ IF data = int type
+ THEN "I"
+ ELIF data = real type
+ THEN "R"
+ ELIF data = text type
+ THEN "T"
+ ELIF data = bool type
+ THEN "b"
+ ELSE errorstop ("Falscher DTYPE: " + dump (data));
+ nil
+ FI .
+
+END PROC convert paramfield;
+
+PROC convert paramfield (TEXT CONST params, INT CONST first):
+ INT VAR i;
+ FOR i FROM first UPTO first+length (params)-1
+ REP parameter (i, this type, 1, GLOB 0) PER .
+
+this type:
+ IF (params SUB i) = "I"
+ THEN int type
+ ELIF (params SUB i) = "R"
+ THEN real type
+ ELIF (params SUB i) = "T"
+ THEN text type
+ ELSE errorstop ("Unbekannter Typ: " + params);
+ undefined type
+ FI .
+
+END PROC convert paramfield;
+
+PROC init op (INT CONST ftn no, TEXT CONST param, ftn name):
+ IF elan opn found
+ THEN insert new opn in chain
+ ELSE errorstop ("PROC " + ftn name + " (" + param + ") nicht gefunden") FI .
+
+elan opn found:
+ OPN VAR opn;
+ BOOL VAR found;
+ convert paramfield (param, 1);
+ identify (ftn name, 1, length (param), opn, found);
+ found .
+
+insert new opn in chain:
+ INT VAR ftn pos :: ftn no;
+ REP IF end of chain found
+ THEN cat new entry in chain
+ ELIF free entry in chain found
+ THEN cover this entry
+ ELSE next entry FI
+ UNTIL ftn pos <= 0 PER .
+
+end of chain found:
+ act entry.next = 0 .
+
+cat new entry in chain:
+ INT VAR free pos;
+ next free entry (free pos);
+ act entry.next := free pos;
+ free entry := ENTRY:(param, ftn no, 0, opn, dtype (LENGTH param+1));
+ LEAVE insert new opn in chain .
+
+free entry in chain found:
+ act entry.next = -1 .
+
+cover this entry:
+ act entry := ENTRY:(param, ftn no, 0, opn, dtype (LENGTH param+1));
+ LEAVE insert new opn in chain .
+
+next entry:
+ ftn pos := act entry.next .
+
+act entry: ftn table [ftn pos] .
+free entry: ftn table [free pos] .
+
+END PROC init op;
+
+BOOL PROC is basic function (INT CONST ftn no): (* mo *)
+
+ pos (ftn names, code (ftn no)) <> 0
+
+END PROC is basic function;
+
+.
+clear ftn table:
+ INT VAR k;
+ FOR k FROM 1 UPTO 256
+ REP ftn table [k] := ENTRY:(nil, 0,-1, nop, undefined type) PER .
+
+init ftn names:
+ TEXT CONST ftn names :: "+-*/\^<=>"28""29""30""249""251""252""253""254"" +
+ ""128""130""131""134""136""137""141""143""142"" +
+ ""153""154""155""157""159""161""166""168""170""171""172"" +
+ ""174""175""178""179""182""184""183""187""192"" +
+ ""201""202""204""205""206""207""208""211""212"" +
+ ""215""221""228""229""230""231""232""233"";
+ FOR k FROM 1 UPTO length (ftn names)
+ REP ftn table [ftn pos] := ENTRY:(nil, ftn pos,-1, nop, void type) PER .
+
+ftn pos:
+ code (ftn names SUB k) .
+
+init int operator:
+ init op ( 43, "II", "+");
+ init op ( 45, "II", "-");
+ init op ( 42, "II", "*");
+ init op ( 47, "II", "/"); (* mo *)
+ init op ( 92, "II", "DIV"); (* mo *)
+ init op ( 94, "II", "^");
+ init op ( 61, "II", "EQU");
+ init op ( 29, "II", "UEQ");
+ init op ( 60, "II", "LES");
+ init op ( 28, "II", "LEQ");
+ init op ( 62, "II", "GRE");
+ init op ( 30, "II", "GEQ");
+ init op (249, "II", "MOD"); (* mo *)
+ init op (251, "II", "AND");
+ init op (252, "II", "OR");
+ init op (253, "II", "XOR");
+ init op (254, "II", "EQV");
+ init op (255, "II", "IMP").
+
+init real operator:
+ init op ( 43, "RR", "+");
+ init op ( 45, "RR", "-");
+ init op ( 42, "RR", "*");
+ init op ( 47, "RR", "/");
+ init op ( 92, "RR", "DIV"); (* mo *)
+ init op ( 94, "RR", "^");
+ init op ( 61, "RR", "EQU");
+ init op ( 29, "RR", "UEQ");
+ init op ( 60, "RR", "LES");
+ init op ( 28, "RR", "LEQ");
+ init op ( 62, "RR", "GRE");
+ init op ( 30, "RR", "GEQ");
+ init op (249, "RR", "realmod"). (* mo *)
+
+init text operator:
+ init op ( 43, "TT", "+");
+ init op ( 61, "TT", "EQU");
+ init op ( 29, "TT", "UEQ");
+ init op ( 60, "TT", "LES");
+ init op ( 28, "TT", "LEQ");
+ init op ( 62, "TT", "GRE");
+ init op ( 30, "TT", "GEQ") .
+
+init predefined funktions:
+ init op (128, "I", "abs");
+ init op (128, "R", "abs");
+ init op (130, "T", "asc");
+ init op (131, "R", "arctan");
+ init op (131, "I", "arctan");
+ init op (134, "I", "cdbl");
+ init op (134, "R", "cdbl");
+ init op (136, "I", "chr");
+ init op (136, "R", "chr");
+ init op (137, "R", "cint");
+ init op (137, "I", "cint");
+ init op (141, "R", "cos");
+ init op (141, "I", "cos");
+ init op (143, "T", "cvi");
+ init op (142, "T", "cvd");
+# init op (153, "", "eof");# (* File *)
+ init op (154, "", "errorline");
+ init op (155, "", "errorcode");
+ init op (157, "R", "exp");
+ init op (157, "I", "exp");
+ init op (159, "R", "floor");
+ init op (159, "I", "floor");
+ init op (161, "I", "fre");
+ init op (161, "R", "fre");
+ init op (161, "T", "fre");
+ init op (166, "I", "hex");
+ init op (166, "R", "hex");
+ init op (168, "", "incharety");
+ init op (170, "I", "inchars");
+ init op (170, "R", "inchars");
+ init op (171, "TT", "instr");
+ init op (171, "ITT", "instr");
+ init op (171, "RTT", "instr");
+ init op (172, "I", "ent");
+ init op (172, "R", "ent");
+ init op (174, "TI", "left");
+ init op (174, "TR", "left");
+ init op (175, "T", "length");
+# init op (178, "I", "line no");# (* File *)
+ init op (179, "R", "ln");
+ init op (179, "I", "ln");
+ init op (182, "TII", "mid");
+ init op (182, "TI", "mid");
+ init op (182, "TRR", "mid");
+ init op (182, "TR", "mid");
+ init op (183, "I", "mkd");
+ init op (183, "R", "mkd");
+ init op (187, "I", "oct");
+ init op (187, "R", "oct");
+ init op (192, "I", "pos");
+ init op (192, "R", "pos");
+ init op (201, "TI", "right");
+ init op (201, "TR", "right");
+ init op (202, "", "rnd"); (* F12/rr *)
+ init op (202, "I", "rnd");
+ init op (202, "R", "rnd");
+ init op (204, "I", "sign");
+ init op (204, "R", "sign");
+ init op (205, "R", "sin");
+ init op (205, "I", "sin");
+ init op (206, "I", "space");
+ init op (206, "R", "space");
+ init op (207, "I", "space");
+ init op (207, "R", "space");
+ init op (208, "R", "sqrt");
+ init op (208, "I", "sqrt");
+ init op (211, "I", "basictext");
+ init op (211, "R", "basictext");
+ init op (212, "IT", "string");
+ init op (212, "RT", "string");
+ init op (212, "II", "string");
+ init op (212, "RR", "string");
+ init op (212, "RI", "string");
+ init op (212, "IR", "string");
+ init op (215, "R", "tan");
+ init op (215, "I", "tan");
+ init op (221, "T", "val"); (* F18/rr *)
+ init op (228, "", "errormessage");
+ init op (229, "", "csrlin");
+ init op (230, "I", "lpos");
+ init op (230, "R", "lpos");
+ init op (231, "", "time");
+ init op (232, "", "date");
+ init op (233, "", "timer").
+
+END PACKET basic identify;
+
+PACKET basic data handling (* Autor: R. Ruland *)
+ (* Stand: 23.10.87/mo *)
+ DEFINES init data,
+ data line,
+ data, read,
+ restore,
+ next int,
+ next real,
+ next text:
+
+LET (* R e s u l t T y p e n *)
+ stat code = 0, stat char = ""0"",
+ data code = 1, data char = ""1"",
+ text code = 2, text char = ""2"",
+
+ int overflow = 4,
+ real overflow = 6;
+
+INT VAR type;
+TEXT VAR data text :: "", number text;
+
+PROC init data:
+
+ data text := ""
+
+END PROC init data;
+
+
+PROC init data (TEXT VAR data, INT VAR data pos):
+
+ data := data text;
+ data pos := 1
+
+END PROC init data;
+
+
+PROC restore (TEXT CONST data, INT VAR data pos, INT CONST line no):
+
+ INT CONST data length :: LENGTH data;
+ data pos := 1;
+ WHILE data pos < data length
+ REP type := code (data SUB data pos);
+ data pos INCR 1;
+ SELECT type OF
+ CASE stat code : IF int value (data, data pos) >= line no
+ THEN LEAVE restore FI
+ CASE data code, text code : data pos INCR int value (data, data pos)
+ OTHERWISE : errorstop (1051, "Fehlerhaften Dateneintrag gefunden: " + text (type))
+ ENDSELECT;
+ PER;
+ errorstop (1004, "RESTORE: Keine DATA-Anweisung in oder nach Zeile " + text (line no)
+ + " gefunden");
+
+END PROC restore;
+
+
+INT PROC next int (TEXT CONST data, INT VAR data pos):
+
+ number text := next text (data, data pos);
+ disable stop;
+ INT VAR result := int (number text);
+ IF is error
+ THEN IF error code = int overflow THEN handle overflow FI;
+ ELIF NOT last conversion ok CAND number text <> ""
+ THEN errorstop (1013, "READ: Falscher Datentyp, " + number text + " ist kein INT")
+ FI;
+ result
+
+ . handle overflow :
+ clear error;
+ result := result value;
+ IF cursor x pos <> 1 THEN next line FI;
+ basic out ("WARNUNG : INT-Überlauf bei READ, gefunden: " + number text);
+ next line;
+
+ . result value :
+ IF (number text SUB 1) = "-" THEN minint ELSE maxint FI
+
+END PROC next int;
+
+
+REAL PROC next real (TEXT CONST data, INT VAR data pos):
+
+ number text := next text (data, data pos);
+ disable stop;
+ REAL VAR result := val (number text);
+ IF is error
+ THEN IF error code = real overflow OR error code = int overflow (* <- wegen Fehler in REAL PROC real (T C) *)
+ THEN handle overflow or underflow
+ FI;
+ ELIF NOT last conversion ok CAND number text <> ""
+ THEN errorstop (1013, "READ: Falscher Datentyp, " + number text + " ist kein REAL")
+ FI;
+ result
+
+ . handle overflow or underflow : (* F23/rr *)
+ clear error;
+ IF cursor x pos <> 1 THEN next line FI;
+ basic out ("WARNUNG : " + overflow or underflow + " bei READ, gefunden: " + number text);
+ next line;
+
+ . overflow or underflow :
+ IF is overflow
+ THEN result := sign * (max real - 0.99999999999994e120); (* <- wegen Fehler in TEXT PROC text (R C) *)
+ "REAL-Überlauf"
+ ELSE result := 0.0;
+ "REAL-Unterlauf"
+ FI
+
+ . sign :
+ IF (number text SUB 1) = "-" THEN -1.0 ELSE 1.0 FI
+
+ . is overflow :
+ INT VAR exponent pos := pos (number text, "E");
+ IF exponent pos = 0 THEN exponent pos := pos (number text, "e") FI;
+ IF exponent pos = 0
+ THEN TRUE
+ ELSE (number text SUB (exponent pos + 1)) <> "-"
+ FI
+
+END PROC next real;
+
+
+TEXT PROC next text (TEXT CONST data, INT VAR data pos):
+
+ INT CONST len :: int value (data, data pos);
+ data pos INCR len;
+ subtext (data, data pos-len, data pos-1)
+
+END PROC next text;
+
+
+INT PROC int value (TEXT CONST data, INT VAR data pos):
+
+ data pos INCR 2;
+ subtext (data, data pos-2, data pos-1) ISUB 1
+
+END PROC int value;
+
+
+PROC data line (INT CONST line no):
+
+ data text CAT stat char;
+ data text CAT mki (line no)
+
+END PROC data line;
+
+
+PROC data (TEXT CONST string, DTYPE VAR data type) :
+
+ data text CAT data + mki (length (string));
+ data text CAT string;
+
+ . data :
+ IF data type = void type
+ THEN data char
+ ELIF data type = text type
+ THEN text char
+ ELSE errorstop (1051, "Unbekannter DTYPE: " + dump (data type)); ""
+ FI
+
+END PROC data;
+
+
+PROC read (TEXT CONST data, INT VAR data pos, INT VAR i):
+
+ type := code (data SUB data pos);
+ data pos INCR 1;
+ IF data pos >= LENGTH data
+ THEN errorstop (1004, "Keine Daten mehr für READ")
+ ELIF type = data code
+ THEN i := next int (data, data pos)
+ ELIF type = stat code
+ THEN data pos INCR 2;
+ read (data, data pos, i)
+ ELSE errorstop (1013, "READ: Falscher Datentyp, " + data string (data,data pos) + " ist kein INT")
+ FI;
+
+END PROC read;
+
+
+PROC read (TEXT CONST data, INT VAR data pos, REAL VAR r):
+
+ type := code (data SUB data pos);
+ data pos INCR 1;
+ IF data pos >= LENGTH data
+ THEN errorstop (1004, "Keine Daten mehr für READ")
+ ELIF type = data code
+ THEN r := next real (data, data pos)
+ ELIF type = stat code
+ THEN data pos INCR 2;
+ read (data, data pos, r)
+ ELSE errorstop (1013, "READ: Falscher Datentyp, " + data string (data,data pos) + " ist kein REAL")
+ FI;
+
+END PROC read;
+
+
+PROC read (TEXT CONST data, INT VAR data pos, TEXT VAR t):
+
+ type := code (data SUB data pos);
+ data pos INCR 1;
+ IF data pos >= LENGTH data
+ THEN errorstop (1004, "Keine Daten mehr für READ")
+ ELIF type = data code OR type = text code
+ THEN t := next text (data, data pos)
+ ELIF type = stat code
+ THEN data pos INCR 2;
+ read (data, data pos, t)
+ ELSE errorstop (1013, "READ: Falscher Datentyp, " + data string (data,data pos) + " ist kein TEXT")
+ FI;
+
+END PROC read;
+
+
+TEXT PROC data string (TEXT CONST data, INT VAR data pos):
+
+ IF type = text code
+ THEN """" + next text (data, data pos) + """"
+ ELSE "unbekannter DTYPE: " + text (type)
+ FI
+
+END PROC data string;
+
+END PACKET basic data handling;
+
+
+PACKET basic odds and ends DEFINES trace, (* Autor: Heiko Indenbirken *)
+ start basic, (* Stand: 26.10.1987/rr/mo *)
+ end basic,
+ loop end,
+ basic stop:
+
+(* Fehlerbehandlung *)
+
+PROC trace (INT CONST stat no):
+ basic out ("[" + text (stat no) + "]")
+
+END PROC trace;
+
+(*Laufzeitprozeduren *)
+PROC start basic:
+ set line nr (0);
+ initialize random (0.1); (* F26/rr *)
+ init output;
+ init input
+
+END PROC start basic;
+
+PROC end basic:
+ IF is error
+ THEN switch back to old sysout state
+ FI .
+
+END PROC end basic;
+
+(* Schleifenüberprüfung *)
+BOOL PROC loop end (REAL CONST x, max, step) :
+ IF step > 0.0
+ THEN x > max
+ ELSE x < max FI
+
+END PROC loop end;
+
+BOOL PROC loop end (INT CONST x, max, step) :
+ IF step > 0
+ THEN x > max
+ ELSE x < max FI
+
+END PROC loop end;
+
+PROC basic stop (INT CONST stat no):
+ basic out ("STOP beendet das Programm in Zeile " + text (stat no));
+ next line
+
+END PROC basic stop;
+
+END PACKET basic odds and ends
+
diff --git a/basic/BASIC.Compiler b/basic/BASIC.Compiler
new file mode 100644
index 0000000..d4e4c21
--- /dev/null
+++ b/basic/BASIC.Compiler
@@ -0,0 +1,2305 @@
+(***************************************************************************)
+(* *)
+(* Dritte von drei Dateien des EUMEL-BASIC-Systems *)
+(* *)
+(* Autor: Heiko Indenbirken *)
+(* Überarbeitet von: Rudolf Ruland und Michael Overdick *)
+(* *)
+(* Stand: 27.10.1987 *)
+(* *)
+(***************************************************************************)
+
+PACKET basic compiler DEFINES basic, (* Autor: Heiko Indenbirken *)
+ basic version: (* Stand: 27.10.1987/rr/mo *)
+
+PROC basic version :
+
+putline (""13" "15" BASIC - Compiler Version 1.1 (27.10.1987) "14"");
+
+END PROC basic version;
+
+LET compiler msg = " ******* ENDE DER UEBERSETZUNG *******",
+ compiler err msg = " Fehler entdeckt";
+
+LET (* S y m b o l T y p e n *)
+ any = 0, const = 1, var = 2, array = 3, denoter = 5,
+ res word= 8, operator= 9, eos = 10, del =11, stat no = 12,
+ result const = 13, (* F3/rr *)
+ user fn = 20; (* DEF/mo *)
+
+LET (* S y m b o l z e i c h e n *)
+ plus = 43, minus = 45, mult = 42,
+ div = 47, backslash = 92, exponent = 94,
+ equal = 61, semicolon = 59, comma = 44,
+ numbersign = 35, open bracket = 40, close bracket = 41,
+ eol = 13, eop = 14, mod op = 249;
+
+LET (* Reservierte Worte *)
+ as s = 129, base s = 132, call s = 133, chain s = 135,
+ clear s = 138, close s = 139, common s = 140, data s = 144,
+ def s = 145, defdbl s = 146, defint s = 147, defsng s = 148,
+ defstr s = 149, dim s = 150, else s = 151, end s = 152,
+ eof s = 153, error s = 156, field s = 158, for s = 160,
+ get s = 162, gosub s = 164, goto s = 165, if s = 167, (* F2/rr *)
+ input s = 169, kill s = 173, let s = 176, line in s = 177,
+ lprint s = 180, lset s = 181, mid s = 182, name s = 185,
+ next s = 186, on s = 188, open s = 189, option s = 190,
+ print s = 193, put s = 194, rand s = 195, read s = 196,
+ rem s = 197, restore s = 198, resume s = 199, return s = 200,
+ rset s = 203, step s = 209, stop s = 210, swap s = 213,
+ tab s = 214, then s = 216, to s = 217, troff s = 218,
+ tron s = 219, using s = 220, wait s = 222, wend s = 223,
+ while s = 224, width s = 225, write s = 226, not = 250,
+ cls s = 227, usr = 234, sub = 235; (* mo *)
+
+LET nil = "",
+ intern error = 51;
+
+LET SYMBOL = STRUCT (TEXT name, INT no, type, ADDRESS adr, DTYPE data);
+ADDRESS CONST niladr :: LOC -4;
+SYMBOL CONST nilsymbol :: SYMBOL : (nil, any, any, nil adr, void type);
+SYMBOL VAR symb;
+BOOL VAR found;
+OPN VAR opn;
+
+TEXT OP NAME (SYMBOL CONST val):
+ IF val.type = const
+ THEN constant value
+ ELIF val.type = stat no
+ THEN text (val.no)
+ ELSE val.name FI .
+
+constant value:
+ IF val.data = int type AND length (val.name) = 2
+ THEN text (val.name ISUB 1)
+ ELIF val.data = real type AND length (val.name) = 8
+ THEN text (val.name RSUB 1)
+ ELSE val.name FI .
+
+END OP NAME;
+
+PROC careful error (INT CONST no, TEXT CONST name, addition): (* DEF/mo *)
+ IF at end of statement
+ THEN basic error (no, name, addition)
+ ELSE basic error without leaving statement
+ FI.
+
+at end of statement:
+ symb.type = eos.
+
+basic error without leaving statement:
+ basic error (no, name, addition, FALSE);
+ error no INCR 1.
+
+END PROC careful error;
+
+(* P r e c o m p i l e r *)
+PROC next symbol:
+ symb.adr := niladr;
+ next symbol (symb.name, symb.no, symb.type, symb.data);
+
+ IF symb.no = end symbol AND symb.type = res word
+ THEN symb.no := -symb.no;
+ symb.type := eos;
+ FI
+END PROC next symbol;
+
+PROC skip (INT CONST symbol, type):
+ IF symb.type = type AND symb.no = symbol
+ THEN next symbol
+ ELSE basic error (2, NAME symb, name of (symbol) + " erwartet") FI .
+END PROC skip;
+
+PROC get letter (SYMBOL VAR symbol):
+ IF symb.type = var AND (LENGTH symb.name) = 1
+ THEN symbol := symb;
+ next symbol
+ ELSE basic error (2, NAME symb, "Buchstabe erwartet, " + type of (symb.type) + " gefunden") FI .
+
+END PROC get letter;
+
+PROC get var (SYMBOL VAR symbol):
+ IF symb.type = var
+ THEN variable (symbol)
+ ELIF symb.type = array
+ THEN array var (symbol)
+ ELSE basic error (2, NAME symb, "Variable erwartet, " + type of (symb.type) + " gefunden") FI .
+
+END PROC get var;
+
+PROC get expr (SYMBOL VAR symbol):
+ get expression (symbol, 0)
+END PROC get expr;
+
+PROC get const (SYMBOL VAR symbol, DTYPE CONST data):
+ IF symb.type = const
+ THEN symbol := symb;
+ declare const (symbol, data); (* F3/rr *)
+ next symbol
+ ELSE basic error (2, NAME symb, "Konstante erwartet, " + type of (symb.type) + " gefunden") FI .
+
+END PROC get const;
+
+PROC get var (SYMBOL VAR symbol, DTYPE CONST data):
+ get var (symbol);
+ convert (symbol, data)
+END PROC get var;
+
+PROC get expr (SYMBOL VAR symbol, DTYPE CONST data):
+ get expression (symbol, 0);
+ convert (symbol, data)
+END PROC get expr;
+
+PROC get expression (SYMBOL VAR result, INT CONST last prio):
+ get single result;
+ WHILE symb.type = operator AND higher priority
+ REP get dyadic operand;
+ gen dyadic operation
+ PER .
+
+get single result:
+ INT VAR prio;
+ SELECT symb.type OF
+ CASE var: variable (result)
+ CASE array: array var (result)
+ CASE const: get const
+ CASE operator: get monadic operator
+ CASE res word: basic function (result)
+ CASE user fn: user function (result) (* DEF/mo *)
+ OTHERWISE get bracket END SELECT .
+
+get const:
+ result := symb;
+ declare const (result, result. data); (* F3/rr *)
+ next symbol .
+
+get monadic operator:
+ get operator;
+ prio := monadic op prio; (* mo *)
+ get monadic operand;
+ generate monadic operator .
+
+monadic op prio: (* mo *)
+ IF op no = not
+ THEN 6
+ ELSE 12
+ FI.
+
+get monadic operand:
+ SYMBOL VAR operand;
+ next symbol;
+ get expression (operand, prio).
+
+generate monadic operator:
+(* Mögliche Ops: +, - und NOT *)
+ parameter (1, operand.data, const, operand.adr);
+ parameter (2, operand.data, var, next local adr (operand.data));
+ parameter (3, void type, const, nil adr);
+
+ IF op no = plus
+ THEN result := operand
+ ELIF op no = minus
+ THEN generate minus op
+ ELIF op no = not
+ THEN generate not op
+ ELSE basic error (2, op name, "Kein monadischer Operator") FI .
+
+generate minus op:
+ IF operand.data = int type
+ THEN apply (1, 2, int minus)
+ ELIF operand.data = real type
+ THEN apply (1, 2, real minus)
+ ELSE basic error (82, op name, NAME operand + " : " + dump (operand.data)) FI;
+ result := SYMBOL:(op name, 0, result const, local adr, operand.data) .
+
+generate not op:
+ IF operand.data = int type
+ THEN apply (1, 1, int not opn)
+ ELIF operand.data = real type
+ THEN apply (1, 1, real not opn)
+ ELSE basic error (82, op name, NAME operand + " : " + dump (operand.data)) FI;
+ result := SYMBOL:(op name, 0, result const, local adr, operand.data) .
+
+get operator:
+ INT CONST op no :: symb.no;
+ TEXT CONST op name :: symb.name .
+
+higher priority:
+ get operator;
+ prio := dyadic op prio;
+ prio > last prio .
+
+dyadic op prio:
+ IF is bool op (op no) THEN bool op prio
+ ELIF op no = plus OR op no = minus THEN 8
+ ELIF op no = mod op THEN 9
+ ELIF op no = backslash THEN 10
+ ELIF op no = mult OR op no = div THEN 11
+ ELIF op no = exponent THEN 13
+ ELSE (* relational operator *) 7
+ FI.
+
+bool op prio:
+ 256 - op no.
+
+get bracket:
+ IF symb.type = del AND symb.no = open bracket
+ THEN next symbol
+ ELSE basic error (22, NAME symb, "") FI;
+ get expression (result, 0);
+ skip (close bracket, del) .
+
+get dyadic operand:
+ next symbol;
+ get expression (operand, prio) .
+
+gen dyadic operation:
+ convert operands;
+ identify dyadic operator;
+ generate dyadic operator .
+
+convert operands:
+ DTYPE CONST op type :: type of operation;
+ convert (result, op type);
+ convert (operand, op type) .
+
+type of operation:
+ IF is bool op (op no)
+ THEN int type
+ ELIF result.data = operand.data
+ THEN result.data
+ ELSE real type FI .
+
+identify dyadic operator:
+ BOOL VAR local found;
+ OPN VAR local opn;
+ DTYPE VAR data;
+ parameter (1, result.data, const, result.adr);
+ parameter (2, operand.data, const, operand.adr);
+ identify (op no, 1, 2, local opn, local found);
+ IF NOT local found
+ THEN basic error (83, symbol of (op no),
+ NAME result + " : " + dump (result.data) + " und " +
+ NAME operand + " : " + dump (operand.data))
+ ELSE data := dtype (3) FI .
+
+generate dyadic operator:
+ declare (3, var);
+ define (3, next local adr (data));
+ apply (3, push);
+ apply (1, 2, local opn);
+ result := SYMBOL:(op name, 0, result const, local adr, data) .
+
+END PROC get expression;
+
+PROC variable (SYMBOL VAR symbol):
+ symbol := symb;
+ next symbol;
+ IF known (symbol.no)
+ THEN get adr from table
+ ELSE declare var (symbol, nil) FI .
+
+get adr from table:
+ TEXT VAR defined dim;
+ remember (symbol.no, symbol.type, symbol.adr, symbol.data, defined dim) .
+
+END PROC variable;
+
+PROC array var (SYMBOL VAR symbol field):
+(* Aufbau der Dimensionsangaben in der Symboltabelle *)
+(* limit 1 [limit 2]... Basis Elemente *)
+(* jeweils als 2 Byte Integer/Text *)
+(* Die Dimension ist dann DIM/2-2 *)
+ ROW 100 SYMBOL VAR indizes;
+ TEXT VAR limits;
+ INT VAR dim;
+
+ symbol field := symb; next symbol;
+ get paramfield (indizes, dim, int type);
+
+ IF known (symbol field.no)
+ THEN check field dim and data
+ ELSE declare new field FI;
+ generate field index .
+
+check field dim and data:
+ INT VAR type;
+ DTYPE VAR data;
+ remember (symbol field.no, type, symbol field.adr, data, limits);
+
+ IF old dim <> dim
+ THEN basic error (84, symbol field.name, "Dimensioniert in " + text (old dim) + " Dimensionen, gefundene Anzahl Indizes: " + text (dim))
+ ELIF NOT (symbol field.data = data)
+ THEN basic error (intern error, symbol field.name, dump (data) + " <=> " + dump (symbol field.data))
+ ELIF NOT (symbol field.type = type)
+ THEN basic error (intern error, symbol field.name, "Feld erwartet, " + type of (type) + " gefunden") FI .
+
+old dim: (length (limits) DIV 2) - 2 .
+
+declare new field:
+ limits := dim * ""10""0"" + mki (array base) +
+ mki ((10 - array base + 1)**dim);
+ declare var (symbol field, limits) .
+
+generate field index:
+ init field subscription;
+ FOR j FROM 1 UPTO dim
+ REP increase field index;
+ calc index length and limit;
+ calculate field pointer;
+ symbol field.adr := REF pointer
+ PER .
+
+init field subscription:
+ ADDRESS VAR pointer :: next local adr (row type),
+ index adr :: next local adr (int type);
+ INT VAR j, elem length :: (limits ISUB (dim+2)) * typesize (symbol field.data),
+ elem limit,
+ elem offset :: 1 - (limits ISUB (dim+1));
+ BOOL CONST base zero := elem offset = 1 .
+
+increase field index:
+ IF base zero
+ THEN parameter (1, int type, const, index.adr);
+ parameter (2, int type, const, one value);
+ parameter (3, int type, var, index adr);
+ parameter (4, void type, const, nil adr);
+ apply (1, 3, int add);
+ ELSE index adr := index.adr FI .
+
+index: indizes [j] .
+
+calc index length and limit:
+ elem limit := (limits ISUB j) + elem offset;
+ elem length := elem length DIV elem limit .
+
+calculate field pointer:
+ parameter (1, int type, const, symbol field.adr);
+ parameter (2, int type, const, index adr);
+ parameter (3, int type, elem length);
+ parameter (4, int type, elem limit);
+ parameter (5, int type, const, pointer);
+ parameter (6, void type, const, nil adr);
+ apply (1, 5, subscript);
+
+END PROC array var;
+
+PROC get paramfield (ROW 100 SYMBOL VAR params list, INT VAR no):
+ skip (open bracket, del);
+ FOR no FROM 1 UPTO 100
+ REP get expression (params list [no], 0);
+ IF symb.type = del AND symb.no = close bracket
+ THEN next symbol;
+ LEAVE get paramfield
+ ELSE skip (comma, del) FI
+ PER .
+
+END PROC get paramfield;
+
+PROC get paramfield (ROW 100 SYMBOL VAR params list, INT VAR no, DTYPE CONST data):
+ skip (open bracket, del);
+ FOR no FROM 1 UPTO 100
+ REP get expression (params list [no], 0);
+ convert (params list [no], data);
+ IF symb.type = del AND symb.no = close bracket
+ THEN next symbol;
+ LEAVE get paramfield
+ ELSE skip (comma, del) FI
+ PER .
+
+END PROC get paramfield;
+
+PROC examine access rights (ROW 100 SYMBOL VAR params list, INT CONST no):
+
+ INT VAR j;
+ FOR j FROM 1 UPTO no REP
+ IF params list [j].type = const OR params list [j].type = result const
+ THEN IF access (j) = 2
+ THEN basic error (103, NAME params list [j], "im " + text (j)
+ + ". Eintrag der Parameterliste")
+ FI
+ FI
+ PER
+
+END PROC examine access rights;
+
+PROC basic function (SYMBOL VAR ftn): (* Änd. 11.08.87, mo *)
+ init and check function;
+ IF symb.type = del AND symb.no = open bracket
+ THEN get paramfield (params list, number params);
+ FI;
+ apply function .
+
+init and check function:
+ ROW 100 SYMBOL VAR params list;
+ INT VAR number params :: 0;
+ BOOL CONST is usr :: symb.no = usr;
+ IF is usr
+ THEN check proc name
+ FI;
+ ftn := symb;
+ next symbol .
+
+check proc name:
+ next symbol;
+ IF symb.type = array
+ THEN symb.name := subtext (symb.name, 1, LENGTH symb.name-2)
+ ELIF symb.type <> var
+ THEN basic error (2, NAME symb, "Prozedurname erwartet")
+ FI.
+
+apply function:
+ OPN VAR ftn local opn;
+ BOOL VAR ftn found;
+ INT CONST result :: number params+1;
+
+ INT VAR j;
+ FOR j FROM 1 UPTO number params
+ REP parameter (j, params list [j].data, const, params list [j].adr) PER;
+ IF is usr
+ THEN identify proc;
+ examine access rights (params list, number params);
+ ELSE identify function
+ FI;
+
+ ftn.adr := next local adr (ftn.data);
+
+ declare (result, var);
+ define (result, ftn.adr);
+ apply (result, push);
+ apply (1, number params, ftn local opn).
+
+identify proc:
+ identify (deshift (ftn.name), 1, number params, ftn local opn, ftn found);
+ ftn.data := dtype (result);
+ IF NOT ftn found
+ THEN basic error (99, ftn.name, "Parameter angegeben: " + param list (1, number params))
+ ELIF ftn.data = void type
+ THEN basic error (5, ftn.name, "Die Prozedur liefert keinen Wert")
+ ELIF NOT (ftn.data = int type) AND NOT (ftn.data = real type) AND NOT (ftn.data = text type)
+ THEN basic error (5, ftn.name, "Der Typ des Resultats ist nicht erlaubt, gefunden: "
+ + dump (dtype (result)))
+ FI.
+
+identify function:
+ identify (ftn.no, 1, number params, ftn local opn, ftn found);
+ IF ftn found
+ THEN ftn.data := dtype (result)
+ ELIF is basic function (ftn.no)
+ THEN basic error (98, ftn.name, "Argument(e) angegeben: " + param list (1, number params))
+ ELSE basic error (22, ftn.name, "Anweisung(sbestandteil) gefunden")
+ FI.
+
+END PROC basic function;
+
+PROC user function (SYMBOL VAR result): (* DEF/mo *)
+ check if function defined;
+ get arguments if expected;
+ gosub (user function label);
+ copy result.
+
+check if function defined:
+ TEXT CONST scope :: name of (symb.no) + "?";
+ IF NOT known (symb.no)
+ THEN basic error (18, symb.name, "")
+ ELIF scanner scope = scope
+ THEN basic error (85, symb.name, "")
+ FI.
+
+get arguments if expected:
+ INT VAR param counter;
+ TEXT VAR dim text;
+ result := symb;
+ remember (symb.no, symb.type, result.adr, result.data, dim text);
+ INT VAR number of params :: LENGTH dim text DIV 2 - 1;
+ next symbol;
+ IF number of params > 0
+ THEN get all arguments
+ ELIF symb.no = open bracket AND symb.type = del
+ THEN basic error (5, symb.name, "Kein Argument erwartet")
+ FI.
+
+get all arguments:
+ IF symb.no <> open bracket OR symb.type <> del
+ THEN basic error (5, NAME symb, text (number of params) + " Argument(e) erwartet")
+ FI;
+ next symbol;
+ FOR param counter FROM 2 UPTO number of params REP
+ get one argument;
+ skip comma;
+ PER;
+ get one argument;
+ skip close bracket.
+
+get one argument:
+ SYMBOL VAR ftn param;
+ ftn param.no := dim text ISUB param counter;
+ remember (ftn param.no, ftn param.type, ftn param.adr, ftn param.data, ftn param.name);
+ IF ftn param.type <> var
+ THEN basic error (intern error, name of (ftn param.no), "Parametereintrag fehlerhaft")
+ FI;
+ SYMBOL VAR expr res;
+ get expr (expr res, ftn param.data);
+ apply move (ftn param.adr, expr res.adr, ftn param.data).
+
+skip comma:
+ IF symb.no = close bracket AND symb.type = del
+ THEN basic error (5, symb.name, text (number of params) + " Argumente erwartet")
+ ELIF symb.no <> comma OR symb.type <> del
+ THEN basic error (2, NAME symb, " , in Argumentenliste erwartet")
+ FI;
+ next symbol.
+
+skip close bracket:
+ IF symb.no = comma AND symb.type = del
+ THEN basic error (5, symb.name, "Nur " + text (number of params) + " Argument(e) erwartet")
+ ELIF symb.no <> close bracket OR symb.type <> del
+ THEN basic error (2, NAME symb, " ) nach Argumentenliste erwartet")
+ FI;
+ next symbol.
+
+user function label:
+ label list [dim text ISUB 1].
+
+copy result :
+ apply move (next local adr (result.data), result.adr, result.data);
+ result.adr := local adr.
+
+END PROC user function;
+
+PROC apply move (ADDRESS CONST dest adr, source adr, DTYPE CONST datype):
+ parameter (1, datype, var, dest adr);
+ parameter (2, datype, const, source adr);
+ parameter (3, void type, const, nil adr);
+
+ IF datype = int type
+ THEN apply (1, 2, int move)
+ ELIF datype = real type
+ THEN apply (1, 2, real move)
+ ELIF datype = text type
+ THEN apply (1, 2, text move)
+ ELSE basic error (2, "=", "Unbekannter Datentyp: " + dump (datype)) FI .
+
+END PROC apply move;
+
+PROC convert (SYMBOL VAR symbol, DTYPE CONST to data): (* F3/rr *)
+ IF to data = from data
+ THEN
+ ELIF symbol.type = const
+ THEN declare const (symbol, to data)
+ ELIF to data = int type
+ THEN make int
+ ELIF to data = real type
+ THEN make real
+ ELSE basic error (13, NAME symbol, dump (to data) + " erwartet, " + dump (from data) + " gefunden") FI .
+
+from data : symbol.data .
+
+make real :
+ IF symbol.data = int type
+ THEN parameter (1, symbol.data, const, symbol.adr);
+ parameter (2, real type, var, next local adr (real type));
+ parameter (3, void type, const, nil adr);
+ apply (1, 1, int to real);
+ symbol.adr := local adr;
+ symbol.data := real type
+ ELSE basic error (13, NAME symbol, dump (to data) + " erwartet, " + dump (from data) + " gefunden") FI .
+
+make int :
+ IF symbol.data = real type
+ THEN parameter (1, symbol.data, const, symbol.adr);
+ parameter (2, int type, var, next local adr (int type));
+ parameter (3, void type, const, nil adr);
+ apply (1, 1, real to int);
+ symbol.adr := local adr;
+ symbol.data := int type
+ ELSE basic error (13, NAME symbol, dump (to data) + " erwartet, " + dump (from data) + " gefunden") FI .
+
+END PROC convert;
+
+PROC declare const (SYMBOL VAR symbol constant, DTYPE CONST data):
+ convert symb value;
+ IF new constant
+ THEN declare this constant
+ ELSE get table entry FI .
+
+convert symb value:
+ IF data = symbol constant.data
+ THEN LEAVE convert symb value
+ ELIF data = int type AND symbol constant.data = real type
+ THEN symbol constant.name := mki (symbol constant.name RSUB 1);
+ ELIF data = real type AND symbol constant.data = int type
+ THEN symbol constant.name := mkd (symbol constant.name ISUB 1);
+ ELIF data = text type AND symbol constant.data = int type
+ THEN symbol constant.name := text (symbol constant.name ISUB 1)
+ ELIF data = text type AND symbol constant.data = real type
+ THEN symbol constant.name := text (symbol constant.name RSUB 1)
+ ELSE basic error (13, NAME symbol constant, dump (data) + " erwartet, "
+ + dump (symbol constant.data) + " gefunden") FI;
+ symbol constant.data := data .
+
+new constant:
+(* Konstanten werden wie folgt abgelegt: *)
+(* INT: § HL *)
+(* REAL: § MMMMMMME *)
+(* TEXT: § Text *)
+ put name ("§ " + symbol constant.name, symbol constant.no);
+ NOT known (symbol constant.no) .
+
+declare this constant:
+ IF data = int type
+ THEN allocate denoter (symbol constant.adr, symbol constant.name ISUB 1)
+ ELIF data = real type
+ THEN allocate denoter (symbol constant.adr, symbol constant.name RSUB 1)
+ ELIF data = text type
+ THEN allocate denoter (symbol constant.adr, symbol constant.name) FI;
+ recognize (symbol constant.no, const, symbol constant.adr, data, nil) .
+
+get table entry:
+ INT VAR table type;
+ TEXT VAR table dim;
+ remember (symbol constant.no, table type, symbol constant.adr, symbol constant.data, table dim);
+ IF table dim <> nil
+ THEN basic error (intern error, NAME symbol constant, "Dimension in Tabelle ungleich niltext")
+ ELIF NOT (symbol constant.data = data)
+ THEN basic error (intern error, NAME symbol constant, "Falscher DTYPE in Tabelle, erw: " + dump (data)
+ + ", gef: " + dump (symbol constant.data)) FI .
+
+END PROC declare const;
+
+PROC declare var (SYMBOL VAR symbol var, TEXT CONST dim): (* F4/rr *)
+ allocate variable;
+ recognize (symbol var.no, symbol var.type, symbol var.adr, symbol var.data, dim) .
+
+allocate variable :
+ symbol var.adr := next local adr (symbol var.data);
+ IF dim <> nil
+ THEN INT VAR index;
+ ADDRESS VAR dummy;
+ FOR index FROM 2 UPTO no of elements
+ REP dummy := next local adr (symbol var.data) PER;
+ FI .
+
+no of elements:
+ (dim ISUB (LENGTH dim DIV 2)) .
+END PROC declare var;
+
+PROC parameter (INT CONST p, DTYPE CONST d type, INT CONST value):
+ declare (p, d type);
+ declare (p, denoter);
+ define (p, value);
+END PROC parameter;
+
+PROC apply (INT CONST first, number params, TEXT CONST name):
+ identify (name, first, number params, opn, found);
+ IF NOT found
+ THEN errorstop (1051, "PROC " + name + ", Parameter: " + param list (first, number params) + ", nicht gefunden!") FI;
+ apply (first, number params, opn)
+
+END PROC apply;
+
+PROC clear local stack : (* F4/rr *)
+
+ define local variables;
+ clear index;
+ define (rep); index incr one;
+ if local storage less or equal index then goto end;
+ get cell address;
+ clear cell;
+ apply (rep);
+ define (end);
+ clear cell address;
+
+ . define local variables :
+ LABEL VAR rep, end;
+ ADDRESS VAR index;
+ declare (rep); declare (end);
+ allocate variable (index, type size (int type));
+
+ . clear index :
+ parameter (1, int type, var, index);
+ apply (1, 1, clear);
+
+ . index incr one :
+ parameter (1, int type, var, index);
+ apply (1, 1, incone);
+
+ . if local storage less or equal index then goto end :
+ parameter (1, int type, const, loc storage);
+ parameter (2, int type, const, index);
+ apply (1, 2, lsequ);
+ apply (end, TRUE);
+
+ . get cell address :
+ parameter (1, int type, const, LOC 2);
+ parameter (2, int type, const, index);
+ parameter (3, int type, 1);
+ parameter (4, int type, 16000);
+ parameter (5, int type, const, LOC 0);
+ apply (1, 5, subscript);
+
+ . clear cell :
+ parameter (1, int type, var, REF LOC 0);
+ apply (1, 1, clear);
+
+ . clear cell address :
+ parameter (1, int type, var, LOC 0);
+ apply (1, 1, clear);
+ parameter (1, int type, var, LOC 1);
+ apply (1, 1, clear);
+
+END PROC clear local stack;
+
+(* M a i n *)
+(* ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃ *)
+(* C o m p i l e r *)
+(* ***** G l o b a l e V a r i a b l en ***** *)
+INT VAR end symbol :: 0, error no :: 0, act stat no :: 0, array base :: 0;
+BOOL VAR basic trace, was warning;
+ADDRESS VAR data pos, data text;
+
+
+(* Globale Operationen *)
+OPN VAR basic init, basic frame, basic module, ret, equal op,
+ int minus, real minus, int not opn, real not opn,
+ trace op, ln op, push,
+ int incr, real incr, int add,
+ int move, real move, text move, test,
+ real to int, int to real, subscript,
+ clear, incone, lsequ, (* F4/rr *)
+ basic out text;
+
+(* Parameter VOID *)
+ init ("RTN", 1, 0, ret);
+
+(* Parameter INT *)
+ declare (1, int type);
+ init ("intnot", 1, 1, int not opn); (* mo *)
+ init ("PP", 1, 1, push);
+ init ("LN", 1, 1, ln op);
+ init ("real", 1, 1, int to real);
+ init ("TEST", 1, 1, test);
+ init ("CLEAR", 1, 1, clear);
+ init ("INCONE", 1, 1, incone);
+ init ("trace", 1, 1, trace op);
+
+(* Parameter INT INT *)
+ declare (2, int type);
+ init ("COMPLINT", 1, 2, int minus);
+ init ("MOVE", 1, 2, int move);
+ init ("INC", 1, 2, int incr);
+ init ("EQU", 1, 2, equal op);
+ init ("LSEQU", 1, 2, lsequ);
+
+(* Parameter INT INT INT *)
+ declare (3, int type);
+ init ("ADD", 1, 3, int add);
+
+(* Paramter REAL *)
+ declare (1, real type);
+ init ("realnot", 1, 1, real not opn); (* mo *)
+ init ("cint", 1, 1, real to int);
+
+(* Parameter REAL REAL *)
+ declare (2, real type);
+ init ("COMPLREAL", 1, 2, real minus);
+ init ("FMOVE", 1, 2, real move);
+ init ("INCR", 1, 2, real incr);
+
+(* Parameter TEXT *)
+ declare (1, text type);
+ init ("basicout", 1, 1, basic out text);
+
+(* Paramter TEXT TEXT *)
+ declare (2, text type);
+ init ("TMOVE", 1, 2, text move);
+
+(* Parameter ADDRESS INT DENOTER DENOTER ADDRESS *)
+ declare (3, denoter);
+ declare (4, denoter);
+ init ("SUBSCRIPT", 1, 5, subscript);
+
+PROC init (TEXT CONST name, INT CONST local from, number params, OPN VAR local opn):
+ identify (name, local from, number params, local opn, found);
+ IF NOT found
+ THEN errorstop (1051, "PROC init (TC, IC, IC, OPN VAR): OPN für """ + name + """ nicht gefunden") FI
+END PROC init;
+
+(* Runtime Konstanten *)
+ ADDRESS VAR true value, false value, niltext value,
+ zero value, one value, two value, three value,
+ comma value, int one value, real one value,
+ loc storage; (* F4/rr *)
+
+(* +++++ Globale Variablen +++++ *)
+ BOOL VAR proc found;
+ INT VAR deftype, field elems, i, params;
+ ROW 100 SYMBOL VAR param;
+ SYMBOL VAR base size, begin range, end range, expr result, field, filename,
+ from, len, image, label, old name, new name,
+ question, size, tab pos, var result;
+ TEXT VAR constant, field size, proc name;
+
+(* Label-Verwaltung *)
+LET label list size = 4100;
+BOUND ROW label list size LABEL VAR label list;
+DATASPACE VAR label ds;
+INITFLAG VAR label init :: FALSE;
+INT VAR last label no;
+
+(* ***** I n t e r f a c e P r o z d u r e n ***** *)
+PROC basic:
+ basic (last param)
+END PROC basic;
+
+PROC basic (TEXT CONST basic file name):
+ basic (basic file name, nil)
+END PROC basic;
+
+PROC basic (TEXT CONST basic file name, prog name):
+ IF NOT exists (basic file name)
+ THEN errorstop ("""" + basic file name + """ gibt es nicht")
+ ELSE FILE VAR basic file :: sequential file (modify, basic file name); (* F5/rr *)
+ headline (basic file, basic file name);
+ last param (basic file name);
+ basic (basic file, prog name)
+ FI;
+
+END PROC basic;
+
+PROC basic (FILE VAR source file, TEXT CONST prog name):
+ IF prog name <> nil CAND prog name is not a tag (* F5/rr *)
+ THEN errorstop ("unzulässiger Programmname : """ + prog name + """");
+ FI;
+ modify (source file); (* F5/rr *)
+ disable stop;
+ init label table;
+ store status;
+ coder on (data allocation by coder);
+ compile (source file, progname);
+ restore status;
+ start basic prog .
+
+prog name is not a tag : (* F5/rr *)
+ LET tag = 1;
+ INT VAR symbol type;
+ TEXT VAR symbol name;
+ scan (prog name);
+ next symbol (symbol name, symbol type);
+ symbol name <> prog name OR symbol type <> tag .
+
+init label table:
+ IF NOT initialized (label init)
+ THEN label ds := nilspace;
+ label list := label ds;
+ FI .
+
+store status:
+ INT CONST source line :: line no (source file),
+ source col :: col (source file);
+ BOOL CONST check status :: check;
+ check on .
+
+restore status:
+ to line (source file, source line);
+ col (source file, source col);
+ IF NOT check status
+ THEN check off FI .
+
+start basic prog:
+ IF error no > 0 OR is error
+ THEN basic error end
+ ELSE normal end
+ FI;
+ close (source file) .
+
+basic error end:
+ coder off (FALSE, FALSE, nop);
+ IF is error
+ THEN put error;
+ clear error
+ ELSE display (""13""10""10""); (* F20/rr *)
+ display (text (error no) + compiler err msg);
+ display (""13""10""10"");
+ display (compiler msg);
+ display (""13""10"");
+ IF sysout <> ""
+ THEN line (2);
+ put (text (error no) + compiler err msg);
+ line (2);
+ put (compiler msg);
+ line
+ FI
+ FI;
+ show file and error .
+
+show file and error: (* F20/rr *)
+ IF anything noted CAND command dialogue
+ THEN noteedit (source file);
+ FI;
+ errorstop (nil) .
+
+normal end:
+ IF prog name = nil
+ THEN run basic proc
+ ELSE insert basic proc FI;
+ IF warnings AND was warning
+ THEN show file and error
+ FI.
+
+run basic proc:
+ coder off (FALSE, TRUE, basic frame);
+ display (""13""10"") .
+
+insert basic proc:
+ coder off (TRUE, TRUE, basic frame);
+ coder on (data allocation by coder);
+ coder off (FALSE, FALSE, basic init);
+ display (""13""10"") .
+
+END PROC basic;
+
+PROC compile (FILE VAR source file, TEXT CONST progname):
+ enable stop;
+ init compiler;
+ init basic prog;
+
+ begin scanning (source file);
+ next symbol;
+ get statement group (eop);
+ end compiling .
+
+init compiler:
+ end symbol := 0;
+ error no := 0;
+ act stat no := 0;
+ array base := 0;
+ basic trace := FALSE;
+ was warning := FALSE;
+
+ init storage;
+ init label;
+ init data;
+ init table .
+
+init label:
+ TEXT VAR local stat no;
+ INT VAR stat nos;
+ init stat no (source file, error no); (* F21/rr *)
+ IF error no > 0 THEN LEAVE compile FI;
+ all stat no (local stat no, stat nos);
+ FOR i FROM 1 UPTO stat nos
+ REP declare (label list [i]) PER;
+ last label no := stat nos. (* DEF/mo *)
+
+init basic prog:
+ LIB VAR packet;
+ declare (basic packet name, packet);
+ define (packet);
+ parameter (1, void type, const, nil adr);
+ declare (basic init);
+ IF progname = nil
+ THEN declare (basic frame)
+ ELSE declare (progname, 1, 0, basic frame) FI;
+ declare (basic module);
+ declare runtime const;
+ declare basic init;
+ declare basic frame;
+ declare basic module .
+
+basic packet name:
+ IF progname <> ""
+ THEN "BASIC." + progname
+ ELSE "BASIC"
+ FI.
+
+declare runtime const:
+ allocate variable (data text, type size (text type));
+ allocate variable (data pos, type size (int type));
+ allocate variable (loc storage, type size (int type)); (* F4/rr *)
+
+ allocate denoter (true value, 0);
+ allocate denoter (false value, -1);
+ allocate denoter (niltext value, nil);
+ allocate denoter (one value, 1);
+ allocate denoter (two value, 2);
+ allocate denoter (three value, 3);
+ allocate denoter (real one value, 1.0);
+ allocate denoter (comma value, ",");
+
+ zero value := true value;
+ int one value := one value .
+
+declare basic init:
+ begin module;
+ define (basic init, 4);
+ parameter (1, text type, var, data text);
+ parameter (2, int type, var, data pos);
+ apply (1, 2, "initdata");
+ parameter (1, void type, const, nil adr);
+ apply (1, 0, ret);
+ end module .
+
+declare basic frame:
+ begin module;
+ define (basic frame, 4);
+
+ IF prog name = nil
+ THEN parameter (1, void type, const, nil adr);
+ apply (1, 0, basic init);
+ FI;
+
+ declare (1, int type);
+ declare (1, const);
+ define (1, 0);
+ parameter (2, void type, const, nil adr);
+ apply (1, 1, ln op);
+
+ apply (1, 0, "disablestop");
+ apply (1, 0, "startbasic");
+
+ parameter (1, int type, var, data pos);
+ parameter (2, int type, const, one value);
+ parameter (3, void type, const, nil adr);
+ apply (1, 2, int move);
+
+ parameter (1, void type, const, nil adr);
+ apply (1, 0, basic module);
+ apply (1, 0, "endbasic");
+ parameter (1, void type, const, nil adr);
+ apply (1, 0, ret);
+ end module .
+
+declare basic module:
+ LABEL VAR start lab;
+ begin module;
+ define (basic module);
+ declare (start lab);
+ apply (1, 0, "enablestop");
+ gosub (start lab);
+ parameter (1, void type, const, nil adr);
+ apply (1, 0, "returnerror"); (* mo *)
+ define (start lab);
+ clear local stack . (* F4/rr *)
+
+end compiling:
+ parameter (1, void type, const, nil adr);
+ apply (1, 0, ret);
+ define (loc storage, local storage - 1); (* F4/rr *)
+ set length of local storage (basic module, max (2, local storage)); (* F4/rr *)
+ IF error no = 0
+ THEN end module FI .
+
+END PROC compile;
+
+PROC get statement group (INT CONST new symbol):
+(* 'get statement group' compiliert das ganze Programm bis zum Auftreten *)
+(* von 'end symbol' *)
+ disable stop;
+ new end symbol;
+ get all basic lines;
+ old end symbol .
+
+new end symbol:
+ INT CONST old symbol :: end symbol;
+ end symbol := new symbol .
+
+old end symbol:
+ end symbol := old symbol .
+
+get all basic lines:
+ REP get basic line;
+
+ IF is error
+ THEN error handling
+ ELIF symb.type = eos
+ THEN check this eos FI
+ PER .
+
+error handling: (* F20/rr *)
+ IF error in basic program
+ THEN error no INCR 1
+ ELIF end of source file
+ THEN clear error;
+ LEAVE get all basic lines
+ ELIF halt from terminal
+ THEN LEAVE get statement group
+ ELSE error no INCR 1;
+ handle internal error;
+ LEAVE get statement group
+ FI;
+ clear error;
+ scope compulsory (TRUE); (* DEF/mo *)
+ set scope (""); (* DEF/mo *)
+ next statement;
+ next symbol .
+
+error in basic program:
+ errorcode = 101.
+
+end of source file:
+ errorcode = 99.
+
+halt from terminal:
+ errorcode = 1.
+
+handle internal error : (* F20/rr *)
+ TEXT VAR error :: "BASIC-Compiler ERROR";
+ IF errorcode <> 0
+ THEN error CAT " #" + text (errorcode) FI;
+ IF errorline > 0
+ THEN error CAT " at " + text (errorline) FI;
+ error CAT " : ";
+ error CAT errormessage;
+ IF sysout <> "" THEN putline (error) FI;
+ note (error);
+ noteline;
+ clear error;
+ errorstop (error).
+
+check this eos:
+ IF symb.no = eol
+ THEN next symbol
+ ELIF symb.no = -new symbol OR symb.no = eop
+ THEN LEAVE get all basic lines (* mo *)
+ ELSE basic error (intern error, NAME symb, "EOL erwartet, " +
+ type of (symb.type) + " gefunden")
+ FI .
+
+END PROC get statement group;
+
+PROC get basic line (INT CONST new symbol):
+(*Die Abbruchbedingungen werden neu gesetzt und bei Verlassen der *)
+(*Prozedur zurückgesetzt. *)
+ disable stop;
+ INT CONST old symbol :: end symbol;
+ end symbol := new symbol;
+ get basic line;
+ end symbol := old symbol .
+
+END PROC get basic line;
+
+PROC get basic line:
+(* 'get basic line' behandelt genau eine Zeile mit Zeilennummer. *)
+ enable stop;
+ IF symb.type = stat no
+ THEN gen stat no (symb.no) FI;
+
+ REP get one basic statement PER .
+
+get one basic statement:
+(* 'get one basic statement' behandelt genau ein Statement. *)
+ IF symb.type = eos
+ THEN get end of statement
+ ELIF symb.type = res word OR symb.type = var OR symb.type = array
+ THEN get one statement
+ ELSE basic error (2, NAME symb, type of (symb.type) + " ohne Zusammenhang") FI .
+
+get end of statement:
+ IF symb.no = eos
+ THEN next symbol
+ ELSE LEAVE get basic line FI .
+
+get one statement:
+ IF symb.type = res word
+ THEN get res word statement
+ ELIF symb.type = var OR symb.type = array
+ THEN let statement
+ FI;
+ skip comma if else expected;
+ IF symb.type <> eos
+ THEN basic error (2, NAME symb, "EOS erwartet, " + type of (symb.type) + " gefunden")
+ FI.
+
+skip comma if else expected:
+ IF end symbol = else s AND symb.type = del AND symb.no = comma
+ THEN next symbol;
+ IF symb.type <> eos OR symb.no <> -else s
+ THEN basic error (2, NAME symb, "ELSE erwartet")
+ FI
+ FI.
+
+get res word statement:
+ SELECT symb.no OF
+ CASE as s : basic error (90, symb.name, "")
+ CASE base s : basic error (91, symb.name, "")
+ CASE call s,
+ chain s : call statement
+ CASE clear s : not implemented
+ CASE close s : not implemented
+ CASE cls s : cls statement (* mo *)
+ CASE common s : not implemented
+ CASE data s : data statement
+ CASE def s : def statement (* mo *)
+ CASE defint s,
+ defdbl s,
+ defsng s,
+ defstr s : def type statement
+ CASE dim s : dim statement
+ CASE else s : basic error (92, symb.name, "")
+ CASE end s : end statement
+ CASE error s : error statement
+ CASE field s : not implemented
+ CASE for s : for statement
+ CASE get s : not implemented
+ CASE gosub s : gosub statement
+ CASE goto s : goto statement
+ CASE if s : if statement
+ CASE input s : input statement
+ CASE kill s : kill statement
+ CASE let s : let statement
+ CASE line in s: line statement
+ CASE lprint s : lprint statement (* mo *)
+ CASE l set s : l set statement
+ CASE mid s : mid statement
+ CASE name s : name statement
+ CASE next s : basic error (1, symb.name, "")
+ CASE on s : on statement
+ CASE open s : not implemented
+ CASE option s : option statement
+ CASE print s : print statement
+ CASE put s : not implemented
+ CASE rand s : randomize statement
+ CASE read s : read statement
+ CASE rem s : rem statement
+ CASE restore s: restore statement
+ CASE resume s : not implemented
+ CASE return s : return statement
+ CASE r set s : r set statement
+ CASE step s : basic error (93, symb.name, "")
+ CASE stop s : stop statement
+ CASE sub : basic error (101, symb.name, "")
+ CASE swap s : swap statement
+ CASE tab s : basic error (94, symb.name, "")
+ CASE then s : basic error (95, symb.name, "")
+ CASE to s : basic error (96, symb.name, "")
+ CASE troff s : troff statement
+ CASE tron s : tron statement
+ CASE using s : basic error (97, symb.name, "")
+ CASE wait s : not implemented
+ CASE wend s : basic error (30, symb.name, "")
+ CASE while s : while statement
+ CASE width s : width statement
+ CASE write s : write statement
+ OTHERWISE basic error (104, symb.name, "") END SELECT.
+
+not implemented:
+ basic error (100, symb.name, "").
+
+call statement:
+(*CALL <proc name> [(<argument list>)] *)
+ next symbol;
+ get proc name;
+ get proc parameter;
+ apply proc .
+
+get proc name:
+ proc name := symb.name;
+ IF symb.type = array
+ THEN proc name := subtext (proc name, 1, LENGTH proc name-2) FI;
+ next symbol .
+
+get proc parameter:
+ params := 0;
+ IF symb.type = del AND symb.no = open bracket
+ THEN get paramfield (param, params) FI .
+
+apply proc:
+ OPN VAR proc opn;
+ FOR i FROM 1 UPTO params
+ REP parameter (i, param [i].data, const, param [i].adr) PER;
+ identify (deshift (proc name), 1, params, proc opn, proc found);
+
+ IF NOT proc found
+ THEN basic error (99, proc name, "Parameter angegeben: " + param list (1, params))
+ ELIF result found
+ THEN basic error (5, proc name, "Kein Resultat erlaubt (gefunden: " + dump (result data) + ")")
+ FI;
+
+ examine access rights (param, params);
+
+ parameter (params+1, void type, const, nil adr);
+ apply (1, params, proc opn) .
+
+result found:
+ NOT (result data = void type) .
+
+result data:
+ dtype (params+1) .
+
+cls statement:
+(*CLS *)
+ next symbol;
+ apply (1, 0, "nextpage").
+
+data statement:
+(*DATA <list of constants> *)
+ DTYPE VAR const data;
+ data line (act stat no);
+ REP IF next data (constant, const data)
+ THEN data (constant, const data)
+ ELSE basic error (2, "EOL", "Daten fehlen !") FI;
+
+ next symbol;
+ IF symb.type = eos
+ THEN LEAVE data statement
+ ELIF symb.type <> del OR symb.no <> comma
+ THEN basic error (2, NAME symb, " , erwartet") FI
+ PER .
+
+def statement: (* DEF/mo *)
+(*DEF FN<name> [(parameter list)] = <function definition> *)
+ get function name;
+ store label of function;
+ get all params;
+ get function definition.
+
+get function name:
+ next symbol;
+ IF symb.type <> user fn
+ THEN treat wrong function name
+ ELIF LENGTH symb.name <= 2
+ THEN basic error (2, symb.name, "Unerlaubter Funktionsname")
+ ELIF known (symb.no)
+ THEN basic warning ("Die Funktion """ + symb.name + """ wurde bereits definiert");
+ was warning := TRUE
+ FI;
+ SYMBOL VAR function :: symb;
+ function.name := name of (function.no).
+
+treat wrong function name:
+ IF symb.type = var OR symb.type = array
+ THEN basic error (2, symb.name, "Funktionsname muß mit FN beginnen")
+ ELSE basic error (2, NAME symb, "Funktionsname erwartet")
+ FI.
+
+store label of function:
+ IF last label no < label list size
+ THEN last label no INCR 1
+ ELSE errorstop ("Zu viele Label")
+ FI;
+ declare (label list [last label no]);
+ TEXT VAR dim text :: "";
+ dim text CAT last label no;
+ recognize (function.no, user fn, niladr, function.data, dim text).
+
+get all params:
+ set scope (function.name + "?");
+ next symbol;
+ IF symb.type = del AND symb.no = open bracket
+ THEN REP
+ try to get a param;
+ try to get del
+ UNTIL symb.no = close bracket OR
+ (symb.type <> del AND symb.type <> var) PER;
+ skip close bracket
+ FI.
+
+try to get a param:
+ REP
+ IF symb.type <> var
+ THEN next symbol
+ FI;
+ IF symb.type <> var
+ THEN careful error (2, NAME symb, "Parametervariable erwartet");
+ IF symb.type <> del
+ THEN next symbol
+ FI
+ ELSE treat param
+ FI
+ UNTIL symb.type <> del OR symb.no = close bracket PER.
+
+treat param:
+ IF NOT known (symb.no)
+ THEN declare var (symb, nil);
+ ELIF already appeared in param list
+ THEN careful error (89, symb.name, "");
+ FI;
+ dim text CAT symb.no.
+
+already appeared in param list:
+ INT VAR param counter;
+ FOR param counter FROM 2 UPTO LENGTH dim text DIV 2 REP
+ IF (dim text ISUB param counter) = symb.no
+ THEN LEAVE already appeared in param list WITH TRUE
+ FI
+ PER;
+ FALSE.
+
+try to get del:
+ IF symb.type = var
+ THEN next symbol
+ FI;
+ IF symb.type = var OR (symb.type = del CAND (symb.no <> comma AND symb.no <> close bracket))
+ THEN careful error (2, symb.name, " , in Parameterliste erwartet")
+ FI.
+
+skip close bracket:
+ IF symb.type = del AND symb.no = close bracket
+ THEN next symbol
+ ELSE careful error (2, NAME symb, " ) nach Parameterliste erwartet")
+ FI.
+
+get function definition:
+ scope compulsory (FALSE);
+ skip (equal, operator);
+ generate forward jump;
+ define this label;
+ get expr (expr result, function.data);
+ recognize (function.no, user fn, expr result.adr, function.data, dim text);
+ goret;
+ define (behind);
+ scope compulsory (TRUE);
+ set scope ("").
+
+generate forward jump:
+ LABEL VAR behind;
+ declare (behind);
+ apply (behind).
+
+define this label:
+ define (label list [last label no]).
+
+
+def type statement:
+(*DEFINT/DBL/SNG/STR <range(s) of letters> *)
+ deftype := symb.no;
+ next symbol;
+ REP get letter (begin range);
+ IF symb.type = operator AND symb.no = minus
+ THEN next symbol;
+ get letter (end range)
+ ELSE end range := begin range FI;
+
+ IF name of (begin range.no) > name of (end range.no)
+ THEN basic error (87, begin range.name + "-" + end range.name, "")
+ ELSE define chars (name of (begin range.no), name of (end range.no), data type) FI;
+
+ IF symb.type = eos
+ THEN LEAVE def type statement
+ ELSE skip (comma, del) FI
+ PER .
+
+data type:
+ SELECT deftype OF
+ CASE defint s: int type
+ CASE defstr s: text type
+ OTHERWISE real type ENDSELECT .
+
+ dim statement:
+(*DIM <list of subscripted var results> *)
+ next symbol;
+ REP get field var;
+ get field size;
+ declare field;
+
+ IF symb.type = eos
+ THEN LEAVE dim statement
+ ELSE skip (comma, del) FI
+ PER .
+
+get field var:
+ IF symb.type = array
+ THEN IF known (symb.no)
+ THEN basic error (10, symb.name, "")
+ ELSE field := symb;
+ next symbol
+ FI
+ ELIF symb.type = var
+ THEN basic error (2, symb.name, "Dimensionsangabe fehlt")
+ ELSE basic error (2, NAME symb, "Feldname erwartet")
+ FI.
+
+get field size:
+ field size := "";
+ field elems := 1;
+ skip (open bracket, del);
+
+ REP get const (size, int type);
+ INT CONST field limit :: size.name ISUB 1;
+ IF field limit < array base
+ THEN basic error (88, NAME size, "Die Obergrenze muß >= " +
+ text (array base) + " sein")
+ ELSE field size CAT (mki (field limit));
+ field elems := field elems * (field limit + 1 - array base)
+ FI;
+
+ IF symb.type = del AND symb.no = close bracket
+ THEN next symbol;
+ LEAVE get field size
+ ELSE skip (comma, del) FI
+ PER .
+
+declare field:
+ field size CAT mki (array base);
+ field size CAT mki (field elems);
+ declare var (field, field size) .
+
+end statement:
+(*END *)
+ next symbol;
+ parameter (1, void type, const, nil adr);
+ apply (1, 0, ret) .
+
+error statement:
+(*ERROR <integer expr result> *)
+ next symbol;
+ get expr (expr result, int type);
+ parameter (1, int type, const, expr result.adr);
+ parameter (2, text type, const, niltext value);
+ apply (1, 2, "errorstop") .
+
+gosub statement:
+(*GOSUB <line number> *)
+ next symbol;
+ get const (label, int type);
+ gosub (this label) .
+
+goto statement :
+(*GOTO <line number> *)
+ next symbol;
+ get const (label, int type);
+ apply (this label) .
+
+this label: label list [label pos (label no)] .
+label no: label.name ISUB 1 .
+
+input statement:
+(*INPUT [;]["Anfrage" ;/,] Variable [, Variable] *)
+ ROW 100 DTYPE VAR input var data;
+ INT VAR number input vars;
+ LABEL VAR input lab;
+ next symbol;
+ declare (input lab);
+ define (input lab);
+ get semicolon for cr lf;
+ get question and question mark;
+ apply (1, 3, "readinput");
+ get input eof;
+ get data types of input vars (input var data, number input vars); (* F25/rr *)
+ check data types of input vars; (* F8/F25/rr *)
+ apply (1, 0, "inputok");
+ apply (input lab, FALSE);
+ assign list of input var . (* F8/F25/rr *)
+
+get semicolon for cr lf:
+ IF symb.type = del AND symb.no = semicolon
+ THEN next symbol;
+ parameter (1, bool type, const, false value)
+ ELSE parameter (1, bool type, const, true value) FI .
+
+get question and question mark:
+ IF symb.type = const AND symb.data = text type
+ THEN get const (question, text type);
+ parameter (2, text type, const, question.adr);
+ parameter (3, bool type, const, question mark value);
+ next symbol
+ ELSE parameter (2, text type, const, niltext value);
+ parameter (3, bool type, const, true value); (* F7/rr *)
+ FI .
+
+question mark value:
+ IF symb.type = del AND symb.no = semicolon
+ THEN true value
+ ELIF symb.type = del AND symb.no = comma
+ THEN false value
+ ELSE basic error (2, NAME symb, " ; oder , erwartet"); nil adr FI .
+
+get input eof:
+ IF symb.type = res word AND symb.no = eof s
+ THEN next symbol;
+ get const (label, int type);
+ apply (1, 0, "inputeof");
+ apply (this label, TRUE)
+ FI .
+
+check data types of input vars : (* F8/F25/rr *)
+ FOR i FROM 1 UPTO number input vars
+ REP parameter (1, int type, const, input data type);
+ apply (1, 1, "checkinput");
+ apply (input lab, FALSE);
+ PER .
+
+input data type : (* F8/F25/rr *)
+ IF input var data (i) = int type THEN one value
+ ELIF input var data (i) = real type THEN two value
+ ELIF input var data (i) = text type THEN three value
+ ELSE zero value
+ FI .
+
+assign list of input var : (* F8/F25/rr *)
+ REP get var (var result);
+ parameter (1, var result. data, var, var result. adr);
+ apply (1, 1, "assigninput");
+
+ IF symb.type = del AND symb.no = comma
+ THEN next symbol
+ ELSE LEAVE assign list of input var FI
+ PER .
+
+kill statement:
+(*KILL <filename> *)
+ next symbol;
+ get expr (filename, text type);
+
+ parameter (1, text type, const, filename.adr);
+ parameter (2, quiet type, const, next local adr (int type));
+ apply (2, 0, "quiet");
+ apply (1, 2, "forget") .
+
+let statement:
+(*[LET] <var> = <expression> *)
+ IF symb.type = res word AND symb.no = let s
+ THEN next symbol FI;
+ get var (var result);
+ skip (equal, operator);
+ get expr (expr result, var result.data);
+ apply move (var result.adr, expr result.adr, var result.data).
+
+line statement: (* F9/rr *)
+(*1. LINE INPUT [;][<"prompt string">;]<string var result> *)
+ next symbol;
+ skip (input s, res word);
+ get semicolon;
+ get prompt string;
+ apply (1, 3, "readinput");
+ assign string var result .
+
+get semicolon:
+ IF symb.type = del AND symb.no = semicolon
+ THEN next symbol;
+ parameter (1, bool type, const, false value)
+ ELSE parameter (1, bool type, const, true value) FI .
+
+get prompt string:
+ IF symb.type = const AND symb.data = text type
+ THEN get const (question, text type);
+ parameter (2, text type, const, question.adr);
+ skip (semicolon, del);
+ ELSE parameter (2, text type, const, niltext value);
+ FI;
+ parameter (3, bool type, const, false value) .
+
+assign string var result :
+ get var (var result, text type);
+ parameter (1, text type, var, var result.adr);
+ apply (1, 1, "assigninputline") .
+
+lprint statement:
+(*LPRINT (cf. PRINT) *)
+ apply (1, 0, "switchtoprintoutfile");
+ print statement;
+ apply (1, 0, "switchbacktooldsysoutstate").
+
+l set statement:
+(*LSET <string var> = <string expression> *)
+ next symbol;
+ get var (var result, text type);
+ skip (equal, operator);
+ get expr (expr result, text type);
+ parameter (1, text type, var, var result.adr);
+ parameter (2, text type, const, expr result.adr);
+ apply (1, 2, "lset") .
+
+mid statement:
+(*MID$ (<string var>, from [,len]) = <string expression> *)
+ next symbol;
+ skip (open bracket, del);
+ get var (var result, text type);
+ skip (comma, del);
+ get expr (from, int type);
+ IF symb.type = del AND symb.no = comma
+ THEN next symbol;
+ get expr (len, int type)
+ ELSE len := nilsymbol FI;
+ skip (close bracket, del);
+ skip (equal, operator);
+ get expr (expr result, text type);
+
+ parameter (1, text type, var, var result.adr);
+ parameter (2, int type, const, from.adr);
+ parameter (3, text type, const, expr result.adr);
+ IF len.data = int type
+ THEN parameter (4, int type, const, one value);
+ parameter (5, int type, const, len.adr);
+ parameter (6, text type, var, next local adr (text type));
+ apply (3, 3, "subtext");
+ parameter (3, text type, const, local adr);
+ FI;
+ apply (1, 3, "replace") .
+
+name statement:
+(*NAME <old filename> AS <new filename> *)
+ next symbol;
+ get expr (old name, text type);
+ skip (as s, res word);
+ get expr (new name, text type);
+ parameter (1, text type, const, old name.adr);
+ parameter (2, text type, const, new name.adr);
+ apply (1, 2, "rename") .
+
+option statement:
+(*OPTION BASE 0|1 *)
+ next symbol;
+ skip (base s, res word);
+ get const (base size, int type);
+ IF new array base > 1
+ THEN basic error (105, NAME base size, "")
+ ELSE array base := new array base
+ FI.
+
+new array base:
+ base size.name ISUB 1.
+
+randomize statement:
+(*RANDOMIZE [<expression>] *)
+ next symbol;
+ IF symb.type = eos
+ THEN apply (1, 0, "initrnd")
+ ELSE get expr (expr result, real type);
+ parameter (1, real type, const, expr result.adr);
+ apply (1, 1, "initrnd")
+ FI .
+
+read statement:
+(*READ <list of var> *)
+ next symbol;
+ REP get var (var result);
+ parameter (1, text type, const, data text);
+ parameter (2, int type, var, data pos);
+ parameter (3, var result.data, var, var result.adr);
+ apply (1, 3, "read");
+
+ IF symb.type = eos
+ THEN LEAVE read statement
+ ELSE skip (comma, del) FI
+ PER .
+
+rem statement:
+(*REM <remark> *)
+ next statement;
+ symb := SYMBOL : ("", eol, eos, LOC 0, void type);
+ LEAVE get basic line .
+
+restore statement:
+(*RESTORE [<line number>] *)
+ next symbol;
+ IF symb.type = eos
+ THEN parameter (1, int type, var, data pos);
+ parameter (2, int type, const, one value);
+ parameter (3, void type, const, nil adr);
+ apply (1, 2, int move);
+ ELSE get const (label, int type);
+ parameter (1, text type, const, data text);
+ parameter (2, int type, var, data pos);
+ parameter (3, int type, const, label.adr);
+ apply (1, 3, "restore")
+ FI .
+
+return statement :
+(*RETURN *)
+ next symbol;
+ goret .
+
+r set statement:
+(*RSET <string var> = <string expression> *)
+ next symbol;
+ get var (var result, text type);
+ skip (equal, operator);
+ get expr (expr result, text type);
+ parameter (1, text type, var, var result.adr);
+ parameter (2, text type, const, expr result.adr);
+ apply (1, 2, "rset") .
+
+stop statement:
+(*STOP *)
+ next symbol;
+ expr result := SYMBOL: (nil, any, const, nil adr, int type);
+ expr result.name CAT act stat no;
+ declare const (expr result, int type);
+ parameter (1, int type, const, expr result.adr);
+ apply (1, 1, "basicstop");
+ parameter (1, void type, const, nil adr);
+ apply (1, 0, ret) .
+
+swap statement:
+(*SWAP <var>,<var> *)
+ next symbol;
+ get var (var result);
+ parameter (1, var result.data, var, var result.adr);
+ DTYPE CONST first var result data :: var result.data;
+ skip (comma, del);
+ get var (var result);
+ IF first var result data = var result.data
+ THEN parameter (2, var result.data, var, var result.adr);
+ apply (1, 2, "swap")
+ ELSE basic error (106, var result.name, "gefunden: "
+ + dump (first var result data) + ", " + dump (var result.data))
+ FI.
+
+troff statement:
+(*TROFF *)
+ next symbol;
+ basic trace := FALSE .
+
+tron statement:
+(*TRON *)
+ next symbol;
+ basic trace := TRUE .
+
+width statement:
+(*WIDTH Größe *)
+ next symbol;
+ get expr (expr result, int type);
+ parameter (1, int type, const, expr result.adr);
+ apply (1, 1, "width") .
+
+write statement:
+(*WRITE [<list of expr results>] *)
+ next symbol;
+
+ IF symb.type = eos
+ THEN apply (1, 0, "nextline")
+ ELSE write list of expr results FI .
+
+write list of expr results:
+ REP get expr (expr result);
+ parameter (1, expr result.data, const, expr result.adr);
+ apply (1, 1, "basicwrite");
+
+ IF symb.type = eos
+ THEN apply (1, 0, "nextline");
+ LEAVE write list of expr results
+ ELSE skip (comma, del);
+ parameter (1, text type, const, comma value);
+ apply (1, 1, "basicout")
+ FI
+ PER .
+
+END PROC get basic line;
+
+PROC gen stat no (INT CONST local stat no):
+(* Die Zeilennummer wird als Label definiert *)
+(* Die Prozedur 'stat no' wird mit der Statementnummer aufgerufen *)
+ act stat no := local stat no;
+ define (label list [label pos (act stat no)]);
+
+ declare (1, int type);
+ declare (1, const);
+ define (1, act stat no);
+ parameter (2, void type, const, nil adr);
+ apply (1, 1, ln op);
+
+ IF basic trace
+ THEN expr result := SYMBOL: (nil, any, const, nil adr, int type);
+ expr result.name CAT act stat no;
+ declare const (expr result, int type);
+ parameter (1, int type, const, expr result.adr);
+ apply (1, 1, trace op)
+ FI;
+ next symbol .
+
+END PROC gen stat no;
+
+PROC for statement:
+(*FOR <var> = x TO y [STEP z] *)
+ SYMBOL VAR local var result, init val, limit val, step val;
+ LABEL VAR start loop, end loop;
+ INT CONST for stat no := act stat no, (* F29/rr *)
+ for scan line no := scan line no;
+ TEXT CONST for symb name := symb.name;
+ declare (start loop);
+ declare (end loop);
+
+ next symbol;
+ get loop var;
+ skip (equal, operator);
+ get expr (init val, local var result.data);
+ skip (to s, res word);
+ get expr (limit val, local var result.data);
+ get step val;
+
+ init loop var;
+ define (start loop);
+ gen check of variable;
+ get statement group (next s);
+
+ IF symb.type = eos AND symb.no = -next s
+ THEN next var statement
+ ELSE define (end loop);
+ basic error ("Compiler", 26, for scan line no, for stat no, for symb name, "", TRUE); (* F29/rr *)
+ FI .
+
+get loop var:
+ get var (local var result);
+ IF NOT (local var result.data = int type OR local var result.data = real type)
+ THEN basic error (2, NAME local var result, "INT oder REAL erwartet, "
+ + dump (local var result.data) + " gefunden")
+ FI .
+
+get step val:
+ IF symb.type = res word AND symb.no = step s
+ THEN next symbol;
+ get expr (step val, local var result.data)
+ ELIF local var result.data = int type
+ THEN step val.data := int type;
+ step val.adr := int one value
+ ELSE step val.data := real type;
+ step val.adr := real one value
+ FI .
+
+init loop var:
+ IF local var result.data = int type
+ THEN init int loop
+ ELSE init real loop FI .
+
+init int loop:
+ IF limit val.type = var
+ THEN parameter (1, int type, var, next local adr (int type));
+ parameter (2, int type, const, limit val.adr);
+ parameter (3, void type, const, nil adr);
+ apply (1, 2, int move);
+ limit val.adr := local adr;
+ FI;
+ IF step val.type = var
+ THEN parameter (1, int type, var, next local adr (int type));
+ parameter (2, int type, const, step val.adr);
+ parameter (3, void type, const, nil adr);
+ apply (1, 2, int move);
+ step val.adr := local adr;
+ FI;
+ IF NOT (init val.no = local var result.no)
+ THEN parameter (1, int type, var, local var result.adr);
+ parameter (2, int type, const, init val.adr);
+ parameter (3, void type, const, nil adr);
+ apply (1, 2, int move)
+ FI .
+
+init real loop:
+ IF limit val.type = var
+ THEN parameter (1, real type, var, next local adr (real type));
+ parameter (2, real type, const, limit val.adr);
+ parameter (3, void type, const, nil adr);
+ apply (1, 2, real move);
+ limit val.adr := local adr;
+ FI;
+ IF step val.type = var
+ THEN parameter (1, real type, var, next local adr (real type));
+ parameter (2, real type, const, step val.adr);
+ parameter (3, void type, const, nil adr);
+ apply (1, 2, real move);
+ step val.adr := local adr;
+ FI;
+ IF NOT (init val.no = local var result.no)
+ THEN parameter (1, real type, var, local var result.adr);
+ parameter (2, real type, const, init val.adr);
+ parameter (3, void type, const, nil adr);
+ apply (1, 2, real move)
+ FI .
+
+gen check of variable:
+ parameter (1, local var result.data, const, local var result.adr);
+ parameter (2, limit val.data, const, limit val.adr);
+ parameter (3, step val.data, const, step val.adr);
+ parameter (4, bool type, const, nil adr); apply (4, nop);
+(* In der nächsten Coder-Version ist eine PUSH-Angabe nop nicht nötig *)
+ apply (1, 3, "loopend");
+ apply (end loop, TRUE) .
+
+next var statement:
+(*NEXT [<var>][,<var>...] *)
+ next symbol;
+ generate loop end;
+ IF symb.type <> eos
+ THEN check next var result FI .
+
+check next var result:
+ IF symb.no = local var result.no
+ THEN next symbol;
+ IF symb.type = del AND symb.no = comma
+ THEN next for loop FI
+ ELSE basic error (86, NAME symb, local var result.name + " erwartet") FI .
+
+next for loop:
+ IF end symbol = next s
+ THEN symb := SYMBOL:("", -next s, eos, nil adr, void type)
+ ELSE basic error (1, symb.name, "") (* mo *)
+ FI.
+
+generate loop end:
+ parameter (1, local var result.data, var, local var result.adr);
+ parameter (2, step val.data, const, step val.adr);
+ parameter (3, void type, const, nil adr);
+ IF local var result.data = int type
+ THEN apply (1, 2, int incr)
+ ELSE apply (1, 2, real incr) FI;
+
+ apply (start loop);
+ define (end loop) .
+
+END PROC for statement;
+
+PROC if statement : (* Änd. 11.08.87, mo *)
+(* IF <expression> THEN <statement(s)>|<line number> *)
+(* [ELSE <statement(s)>|<line number>] *)
+(* IF <expression> GOTO <line number> *)
+(* [ELSE <statement(s)>|<line number>] *)
+ SYMBOL VAR local expr result;
+ next symbol;
+ get expr (local expr result, int type);
+ skip comma if there;
+ IF symb.type = res word AND (symb.no = then s OR symb.no = goto s)
+ THEN test expr result;
+ IF symb.no = goto s
+ THEN next symbol;
+ if goto statement
+ ELIF next symbol is stat no
+ THEN if goto statement
+ ELSE if then statement
+ FI
+ ELSE basic error (2, NAME symb, "THEN oder GOTO erwartet") FI .
+
+skip comma if there:
+ IF symb.no = comma AND symb.type = del
+ THEN next symbol
+ FI.
+
+test expr result:
+ parameter (1, int type, const, local expr result.adr);
+ parameter (2, bool type, var, nil adr); apply (2, nop);
+ apply (1, 1, test) .
+
+next symbol is stat no:
+ next symbol;
+ symb.type = const AND symb.data = int type.
+
+if goto statement:
+ SYMBOL VAR stat label;
+ get const (stat label, int type);
+ expect else if comma found;
+ IF symb.type = res word AND symb.no = else s
+ THEN apply (this label, FALSE);
+ treat else case
+ ELIF symb.type <> eos OR symb.no <> eol
+ THEN declare (else label);
+ apply (this label, FALSE);
+ apply (else label);
+ get basic line (else s);
+ IF symb.type = eos AND symb.no = -else s
+ THEN else statement
+ ELSE define (else label)
+ FI
+ ELSE apply (this label, FALSE)
+ FI.
+
+this label: label list [label pos (label no)] .
+label no: stat label.name ISUB 1 .
+
+expect else if comma found:
+ IF symb.type = del AND symb.no = comma
+ THEN next symbol;
+ IF symb.no <> else s OR symb.type <> res word
+ THEN basic error (2, NAME symb, "ELSE erwartet")
+ FI
+ FI.
+
+treat else case:
+ IF next symbol is stat no
+ THEN get const (stat label, int type);
+ apply (this label)
+ ELSE get basic line
+ FI.
+
+if then statement:
+ LABEL VAR fi label;
+ declare (else label);
+ apply (else label, TRUE);
+ get basic line (else s);
+
+ IF symb.type = eos AND symb.no = -else s
+ THEN declare (fi label);
+ apply (fi label);
+ else statement;
+ define (fi label)
+ ELSE define (else label) FI .
+
+
+else statement:
+ LABEL VAR else label;
+ define (else label);
+ treat else case.
+
+
+END PROC if statement;
+
+PROC on statement:
+(*2. ON <expression> GOSUB <list of line numbers> *)
+(*3. ON <expression> GOTO <list of line numbers> *)
+ LABEL VAR before case, after case, return case;
+ declare (before case);
+ declare (after case);
+ declare (return case);
+
+ next symbol;
+ IF symb.type = res word AND symb.no = error s
+ THEN basic error (100, symb.name, "")
+ FI;
+ get expr (expr result, int type);
+ IF on gosub statement
+ THEN gosub (before case);
+ apply (after case)
+ ELIF NOT on goto statement
+ THEN basic error (2, symb.name, "GOTO oder GOSUB erwartet") FI;
+
+ get case stat no;
+ define (before case);
+ gen case branches;
+ gen return case;
+ define (after case) .
+
+on gosub statement:
+ BOOL CONST gosub found := symb.type = res word AND symb.no = gosub s;
+ gosub found .
+
+on goto statement:
+ symb.type = res word AND symb.no = goto s.
+
+get case stat no:
+ TEXT VAR case stat no :: nil;
+ INT VAR case no :: 0;
+ next symbol;
+ REP get const (label, int type);
+ case no INCR 1;
+ case stat no CAT label.name;
+
+ IF symb.type = eos
+ THEN LEAVE get case stat no
+ ELSE skip (comma, del) FI
+ PER .
+
+gen case branches:
+ computedbranch (expr result.adr, case no + 1, otherwise lab); (* F6/rr *)
+ apply (otherwise lab);
+ FOR i FROM 1 UPTO case no
+ REP apply (label i) PER .
+
+gen return case:
+ IF gosub found
+ THEN define (return case);
+ goret
+ FI .
+
+otherwise lab:
+ IF gosub found
+ THEN return case
+ ELSE after case FI .
+
+label i:
+ label list [label pos (case stat no ISUB i)] .
+
+END PROC on statement;
+
+PROC print statement:
+(*PRINT [<list of expr results>] *)
+(*PRINT USING <string exp>;<list of expression> *)
+(*PRINT #<file number>,<list of expr results> *)
+(*PRINT #<file number>, USING <string exp>;<list of expression> *)
+ next symbol;
+ IF symb.type = del AND symb.no = numbersign
+ THEN print file statement
+ ELSE print display statement FI .
+
+print file statement:
+ basic error (100, symb.name, "") .
+
+print display statement:
+ get format string;
+ print list of expr results;
+ reset format string .
+
+get format string:
+ IF symb.type = res word AND symb.no = using s
+ THEN next symbol;
+ get expr (image, text type);
+ skip (semicolon, del);
+ parameter (1, text type, const, image.adr);
+ apply (1, 1, "using");
+ ELSE image := nilsymbol FI .
+
+reset format string:
+ IF image.type <> any
+ THEN apply (1, 0, "clearusing") FI .
+
+print list of expr results:
+ REP IF symb.type = res word AND symb.no = tab s
+ THEN get tabulation
+ ELIF symb.type = del AND symb.no = comma
+ THEN get next zone
+ ELIF symb.type = del AND symb.no = semicolon
+ THEN get next pos
+ ELIF symb.type = eos
+ THEN apply (1, 0, "nextline");
+ LEAVE print list of expr results
+ ELSE get print expr result FI;
+ PER .
+
+get tabulation:
+ next symbol;
+ skip (open bracket, del);
+ get expr (tab pos, int type);
+ skip (close bracket, del);
+ parameter (1, int type, const, tab pos.adr);
+ apply (1, 1, "tab") .
+
+get next zone:
+ next symbol;
+ IF image.type = any
+ THEN apply (1, 0, "nextzone") FI;
+ IF symb.type = eos
+ THEN LEAVE print list of expr results FI .
+
+get next pos:
+ next symbol;
+ IF symb.type = eos
+ THEN LEAVE print list of expr results FI .
+
+get print expr result:
+ get expr (expr result);
+ parameter (1, expr result.data, const, expr result.adr);
+ apply (1, 1, "basicout") .
+
+END PROC print statement;
+
+PROC while statement:
+(*WHILE <expression> *)
+ LABEL VAR while lab, wend lab;
+ SYMBOL VAR while expr result;
+ INT CONST while stat no := act stat no, (* F29/rr *)
+ while scan line no := scan line no;
+ TEXT CONST while symb name := symb.name;
+ next symbol;
+ declare (while lab);
+ declare (wend lab);
+
+ define (while lab);
+ get expr (while expr result, int type);
+ parameter (1, int type, const, while expr result.adr);
+ parameter (2, bool type, const, nil adr); apply (2, nop);
+ apply (1, 1, test);
+ apply (wend lab, TRUE); (* 'test' vergleicht mit 0 *)
+
+ get statement group (wend s);
+ IF symb.type = eos AND symb.no = -wend s
+ THEN wend statement
+ ELSE basic error ("Compiler", 29, while scan line no, while stat no, while symb name, "", TRUE) FI. (* F29/rr *)
+
+wend statement:
+(*WEND *)
+ apply (while lab);
+ define (wend lab);
+ next symbol .
+
+END PROC while statement;
+
+END PACKET basic compiler
+
diff --git a/basic/BASIC.Runtime b/basic/BASIC.Runtime
new file mode 100644
index 0000000..854002a
--- /dev/null
+++ b/basic/BASIC.Runtime
@@ -0,0 +1,1571 @@
+(***************************************************************************)
+(* *)
+(* Erste von drei Dateien des EUMEL-BASIC-Systems *)
+(* *)
+(* Autor: Heiko Indenbirken *)
+(* Überarbeitet von: Rudolf Ruland und Michael Overdick *)
+(* *)
+(* Stand: 27.10.1987 *)
+(* *)
+(***************************************************************************)
+
+PACKET basic std DEFINES EQU, UEQ, (* Autor: Heiko Indenbirken *)
+ LES, LEQ, (* Stand: 23.10.1987/rr/mo *)
+ GRE, GEQ,
+ EQV, IMP,
+ ^, swap,
+ val, asc, cdbl, chr,
+ cint, cvi, cvd, fre,
+ hex, inchars,
+ instr, ent, left,
+ mid, mki, mkd,
+ oct, right,
+ rnd, init rnd,
+ space, string,
+ l set, r set,
+ int not, real not,
+ /, DIV, real mod,
+ time, timer,
+ arctan, cos, sin, tan,
+ exp, ln, floor,
+ sqrt:
+
+
+INT CONST true := -1,
+ false := 0;
+
+LET real overflow = 6;
+
+
+(*BASIC-Integervergleiche *)
+INT OP EQU (INT CONST a, b):
+ IF a=b
+ THEN true
+ ELSE false FI
+END OP EQU;
+
+INT OP UEQ (INT CONST a, b):
+ IF a=b
+ THEN false
+ ELSE true FI
+END OP UEQ;
+
+INT OP LES (INT CONST a, b):
+ IF a<b
+ THEN true
+ ELSE false FI
+END OP LES;
+
+INT OP LEQ (INT CONST a, b):
+ IF a<=b
+ THEN true
+ ELSE false FI
+END OP LEQ;
+
+INT OP GRE (INT CONST a, b):
+ IF a>b
+ THEN true
+ ELSE false FI
+END OP GRE;
+
+INT OP GEQ (INT CONST a, b):
+ IF a>=b
+ THEN true
+ ELSE false FI
+END OP GEQ;
+
+(*BASIC-Realvergleiche *)
+INT OP EQU (REAL CONST a, b):
+ IF a=b
+ THEN true
+ ELSE false FI
+END OP EQU;
+
+INT OP UEQ (REAL CONST a, b):
+ IF a=b
+ THEN false
+ ELSE true FI
+END OP UEQ;
+
+INT OP LES (REAL CONST a, b):
+ IF a<b
+ THEN true
+ ELSE false FI
+END OP LES;
+
+INT OP LEQ (REAL CONST a, b):
+ IF a<=b
+ THEN true
+ ELSE false FI
+END OP LEQ;
+
+INT OP GRE (REAL CONST a, b):
+ IF a>b
+ THEN true
+ ELSE false FI
+END OP GRE;
+
+INT OP GEQ (REAL CONST a, b):
+ IF a>=b
+ THEN true
+ ELSE false FI
+END OP GEQ;
+
+(*BASIC-Tesxtvergleiche *)
+INT OP EQU (TEXT CONST a, b):
+ IF a=b
+ THEN true
+ ELSE false FI
+END OP EQU;
+
+INT OP UEQ (TEXT CONST a, b):
+ IF a=b
+ THEN false
+ ELSE true FI
+END OP UEQ;
+
+INT OP LES (TEXT CONST a, b):
+ IF a<b
+ THEN true
+ ELSE false FI
+END OP LES;
+
+INT OP LEQ (TEXT CONST a, b):
+ IF a<=b
+ THEN true
+ ELSE false FI
+END OP LEQ;
+
+INT OP GRE (TEXT CONST a, b):
+ IF a>b
+ THEN true
+ ELSE false FI
+END OP GRE;
+
+INT OP GEQ (TEXT CONST a, b):
+ IF a>=b
+ THEN true
+ ELSE false FI
+END OP GEQ;
+
+
+(*BASIC INTEGER / BOOL Operatoren *)
+REAL PROC real not (REAL CONST a): (* mo *)
+ real (int (a) XOR -1)
+END PROC real not;
+
+INT PROC int not (INT CONST a): (* mo *)
+ a XOR -1
+END PROC int not;
+
+INT OP EQV (INT CONST l, r):
+ int not (l XOR r)
+END OP EQV;
+
+INT OP IMP (INT CONST l, r):
+ (l EQV r) OR r
+END OP IMP;
+
+LET smallest significant = 5.0e-12;
+REAL OP ^ (REAL CONST x, y): (* F22/rr *)
+ IF x > 0.0
+ THEN x ** y
+ ELIF x = 0.0
+ THEN IF y > 0.0
+ THEN 0.0
+ ELIF y = 0.0
+ THEN 1.0
+ ELSE errorstop (real overflow, "");
+ max real
+ FI
+ ELSE REAL VAR floor y := floor (y + round value);
+ IF (abs (y - floor y) > smallest significant)
+ COR (floor y = 0.0 AND y <> 0.0)
+ THEN errorstop (1005, "bei " + text (x) +
+ " ^ " + text (y, 19) +
+ " : neg. Basis, gebr. Exponent");
+ 0.0
+ ELIF (floor y MOD 2.0) = 0.0
+ THEN (-x) ** floor y
+ ELSE - ( (-x) ** floor y )
+ FI
+ FI .
+
+ round value : IF y >= 0.0 THEN 0.5 ELSE -0.5 FI .
+
+END OP ^;
+
+REAL OP ^ (INT CONST x, y):
+ real (x) ** y
+END OP ^;
+
+REAL OP / (INT CONST l, r): (* mo *)
+ real (l) / real (r)
+END OP /;
+
+INT OP DIV (REAL CONST l, r): (* mo *)
+ cint (l) DIV cint (r)
+END OP DIV;
+
+REAL PROC real mod (REAL CONST l, r): (* mo *)
+ round (l, 0) MOD round (r, 0)
+END PROC real mod;
+
+(* Basic Arithmetik *)
+REAL VAR r swap;
+PROC swap (REAL VAR left, right):
+ r swap := left;
+ left := right;
+ right := r swap
+END PROC swap;
+
+INT VAR i swap;
+PROC swap (INT VAR left, right):
+ i swap := left;
+ left := right;
+ right := i swap
+END PROC swap;
+
+TEXT VAR t swap;
+PROC swap (TEXT VAR left, right):
+ t swap := left;
+ left := right;
+ right := t swap
+END PROC swap;
+
+(*Internkonvertierungen *)
+INT PROC cvi (TEXT CONST v):
+ v ISUB 1
+END PROC cvi;
+
+REAL PROC cvd (TEXT CONST v):
+ v RSUB 1
+END PROC cvd;
+
+TEXT VAR i text :: 2*""0"", r text :: 8*""0"";
+TEXT PROC mki (REAL CONST x):
+ mki (cint (x))
+END PROC mki;
+
+TEXT PROC mki (INT CONST i):
+ replace (i text, 1, i);
+ i text
+END PROC mki;
+
+TEXT PROC mkd (INT CONST i):
+ mkd (real (i))
+END PROC mkd;
+
+TEXT PROC mkd (REAL CONST r):
+ replace (r text, 1, r);
+ r text
+END PROC mkd;
+
+(*Textoperationen *)
+PROC l set (TEXT VAR left, TEXT CONST right):
+ replace (left, 1, right)
+END PROC l set;
+
+PROC r set (TEXT VAR left, TEXT CONST right):
+ replace (left, length (left)-length (right)+1, right)
+END PROC r set;
+
+TEXT PROC left (TEXT CONST string, REAL CONST no):
+ left (string, cint (no))
+END PROC left;
+
+TEXT PROC left (TEXT CONST string, INT CONST no):
+ subtext (string, 1, no)
+END PROC left;
+
+TEXT PROC right (TEXT CONST string, REAL CONST no):
+ right (string, cint (no))
+END PROC right;
+
+TEXT PROC right (TEXT CONST string, INT CONST no):
+ subtext (string, length (string)-no+1)
+END PROC right;
+
+TEXT PROC mid (TEXT CONST source, REAL CONST from):
+ mid (source, cint (from))
+END PROC mid;
+
+TEXT PROC mid (TEXT CONST source, INT CONST from):
+ subtext (source, from)
+END PROC mid;
+
+TEXT PROC mid (TEXT CONST source, REAL CONST from, length):
+ mid (source, cint (from), cint (length))
+END PROC mid;
+
+TEXT PROC mid (TEXT CONST source, INT CONST from, length):
+ subtext (source, from, from+length-1)
+END PROC mid;
+
+TEXT PROC string (REAL CONST x, y):
+ string (cint (x), cint (y))
+END PROC string;
+
+TEXT PROC string (INT CONST x, REAL CONST y):
+ string (x, cint (y))
+END PROC string;
+
+TEXT PROC string (REAL CONST x, INT CONST y):
+ string (cint (x), y)
+END PROC string;
+
+TEXT PROC string (INT CONST i, j):
+ i * code (j)
+END PROC string;
+
+TEXT PROC string (REAL CONST i, TEXT CONST x):
+ string (cint (i), x)
+END PROC string;
+
+TEXT PROC string (INT CONST i, TEXT CONST x):
+ i * (x SUB 1)
+END PROC string;
+
+(*Konvertierungen *)
+
+REAL PROC val (TEXT CONST text) : (* F18/rr *)
+
+ TEXT VAR buffer := text;
+ change (buffer, "d", "e");
+ change (buffer, "D", "e");
+ change (buffer, "E", "e");
+ real (buffer)
+
+END PROC val;
+
+REAL PROC asc (TEXT CONST text):
+ real (code (text SUB 1))
+END PROC asc;
+
+TEXT PROC chr (INT CONST n):
+ code (n)
+END PROC chr;
+
+TEXT PROC chr (REAL CONST n):
+ code (cint (n))
+END PROC chr;
+
+TEXT PROC hex (REAL CONST x):
+ hex (cint (x))
+END PROC hex;
+
+TEXT PROC hex (INT CONST x):
+ TEXT VAR value :: "12";
+ replace (value, 1, x);
+ high byte + low byte .
+
+low byte:
+ hexdigit (code (value SUB 1) DIV 16) + hexdigit (code (value SUB 1) MOD 16) .
+
+high byte:
+ IF (value SUB 2) = ""0""
+ THEN ""
+ ELSE hexdigit (code (value SUB 2) DIV 16) +
+ hexdigit (code (value SUB 2) MOD 16)
+ FI .
+
+END PROC hex;
+
+TEXT PROC oct (REAL CONST x):
+ oct (cint (x))
+END PROC oct;
+
+TEXT PROC oct (INT CONST x):
+ INT VAR number :: x AND maxint;
+ generate oct number;
+ IF x < 0
+ THEN "1" + oct number
+ ELSE subtext (oct number, pos (oct number, "1", "7", 1))
+ FI.
+
+generate oct number:
+ TEXT VAR oct number :: "";
+ INT VAR digit;
+ FOR digit FROM 1 UPTO 5 REP
+ oct number := hexdigit (number MOD 8) + oct number;
+ number := number DIV 8
+ PER.
+
+END PROC oct;
+
+TEXT PROC hexdigit (INT CONST digit):
+ IF 0 <= digit AND digit <= 9
+ THEN code (digit + 48)
+ ELIF 10 <= digit AND digit <= 15
+ THEN code (digit + 55)
+ ELSE errorstop (1051, "Hexziffer außerhalb des gültigen Bereichs"); "" FI
+END PROC hexdigit;
+
+TEXT PROC inchars (REAL CONST n):
+ inchars (cint (n))
+END PROC inchars;
+
+TEXT PROC inchars (INT CONST n):
+ TEXT VAR buffer :: "", char;
+ INT VAR i;
+ FOR i FROM 1 UPTO n
+ REP inchar (char);
+ buffer CAT char
+ PER;
+ buffer
+
+END PROC inchars;
+
+(*Mathematische Prozeduren *)
+REAL PROC ent (INT CONST r):
+ real (r)
+END PROC ent;
+
+REAL PROC ent (REAL CONST r):
+ IF r >= 0.0 OR frac (r) = 0.0
+ THEN floor (r)
+ ELSE floor (r-1.0) FI
+END PROC ent;
+
+REAL PROC cdbl (INT CONST r):
+ real (r)
+END PROC cdbl;
+
+REAL PROC cdbl (REAL CONST r):
+ r
+END PROC cdbl;
+
+INT PROC cint (INT CONST r):
+ r
+END PROC cint;
+
+INT PROC cint (REAL CONST r):
+ IF r >= 0.0
+ THEN int (r+0.5)
+ ELSE int (r-0.5) FI
+END PROC cint;
+
+REAL VAR last rnd :: rnd (1.0);
+REAL PROC rnd (INT CONST x):
+ rnd (real (x))
+END PROC rnd;
+
+REAL PROC rnd (REAL CONST x):
+ IF x > 0.0
+ THEN last rnd := random;
+ last rnd
+ ELIF x = 0.0
+ THEN last rnd
+ ELSE init rnd (x);
+ last rnd := random;
+ last rnd
+ FI
+
+END PROC rnd;
+
+REAL PROC rnd:
+ rnd (1.0)
+END PROC rnd;
+
+PROC init rnd (REAL CONST init value) :
+
+ REAL VAR init := init value;
+ IF init <= -1.0 OR 1.0 <= init
+ THEN set exp (- decimal exponent (init) - 1, init) FI;
+ initialize random (init)
+
+END PROC init rnd;
+
+
+REAL PROC fre (TEXT CONST dummy):
+ INT VAR f, u;
+ collect heap garbage;
+ storage (f, u);
+
+ real (f - u) * 1024.0
+END PROC fre;
+
+REAL PROC fre (REAL CONST dummy):
+ fre ("")
+END PROC fre;
+
+REAL PROC fre (INT CONST dummy):
+ fre ("")
+END PROC fre;
+
+(*Inputroutinenen *)
+INT PROC instr (TEXT CONST source, pattern):
+ pos (source, pattern)
+END PROC instr;
+
+INT PROC instr (REAL CONST from, TEXT CONST source, pattern):
+ instr (cint (from), source, pattern)
+END PROC instr;
+
+INT PROC instr (INT CONST from, TEXT CONST source, pattern):
+ pos (source, pattern, from)
+END PROC instr;
+
+TEXT PROC space (REAL CONST len):
+ space (cint (len))
+END PROC space;
+
+TEXT PROC space (INT CONST len):
+ len * " "
+END PROC space;
+
+TEXT PROC time: (* mo *)
+ subtext (time (clock (1) MOD day), 1, 8) (* hh:mm:ss *)
+END PROC time;
+
+REAL PROC timer:
+ clock (0)
+END PROC timer;
+
+REAL PROC arctan (INT CONST x):
+ arctan (real (x))
+END PROC arctan;
+
+REAL PROC cos (INT CONST x):
+ cos (real (x))
+END PROC cos;
+
+REAL PROC sin (INT CONST x):
+ sin (real (x))
+END PROC sin;
+
+REAL PROC tan (INT CONST x):
+ tan (real (x))
+END PROC tan;
+
+REAL PROC exp (INT CONST x):
+ exp (real (x))
+END PROC exp;
+
+REAL PROC ln (INT CONST x):
+ ln (real (x))
+END PROC ln;
+
+REAL PROC floor (INT CONST x):
+ real (x)
+END PROC floor;
+
+REAL PROC sqrt (INT CONST x):
+ sqrt (real (x))
+END PROC sqrt;
+
+END PACKET basic std;
+
+PACKET basic using DEFINES using, (* Autor: Heiko Indenbirken *)
+ clear using, (* Stand: 05.08.1987/rr/mo *)
+ basic text:
+
+
+LET exclamation point = "!",
+ backslash = "\",
+ comercial and = "&",
+ numbersign = "#",
+ plus = "+",
+ minus = "-",
+ asterisk dollar = "**$",
+ asterisk = "**",
+ dollarsign = "$$",
+ comma = ",",
+ point = ".",
+ caret = "^^^^",
+ underscore = "_",
+ blank = " ",
+ nil = "",
+
+ number format chars = "#+-*$.^",
+ format chars = "!\&#+-$*.";
+
+TEXT VAR result, using format :: "", pre format :: "";
+INT VAR using pos :: 0;
+BOOL VAR image used :: FALSE;
+
+PROC using (TEXT CONST format):
+ using format := format;
+ using pos := 0;
+ result := "";
+ image used := TRUE
+
+END PROC using;
+
+PROC clear using:
+ using format := "";
+ image used := FALSE
+END PROC clear using;
+
+TEXT PROC next format:
+ pre format := "";
+ IF using pos = 0
+ THEN ""
+ ELSE search rest of format FI .
+
+search rest of format:
+ WHILE using pos <= length (using format)
+ REP IF at underscore
+ THEN using pos INCR 1;
+ pre format CAT akt char
+ ELIF at format char
+ THEN LEAVE next format WITH pre format
+ ELSE pre format CAT akt char FI;
+ using pos INCR 1
+ PER;
+ using pos := 0;
+ pre format .
+
+at underscore:
+ akt char = underscore .
+
+at format char:
+ pos (format chars, akt char) > 0 CAND
+ evtl double asterisk CAND
+ evtl point with numbersign .
+
+evtl double asterisk:
+ akt char <> asterisk COR next char = asterisk .
+
+evtl point with numbersign:
+ akt char <> point COR next char = numbersign .
+
+akt char: using format SUB using pos .
+next char: using format SUB using pos+1 .
+END PROC next format;
+
+PROC init (TEXT VAR l result):
+ IF using pos = 0
+ THEN using pos := 1;
+ l result := next format;
+ IF using pos = 0
+ THEN errorstop (1005, "USING: kein Format gefunden") FI
+ ELSE l result := "" FI
+
+END PROC init;
+
+TEXT PROC basic text (TEXT CONST string):
+ IF image used
+ THEN using text
+ ELSE string FI .
+
+using text:
+ init (result);
+ result CAT format string;
+ using pos INCR 1;
+ result CAT next format;
+ result .
+
+format string:
+ IF akt char = exclamation point
+ THEN string SUB 1
+ ELIF akt char = backslash
+ THEN given length string
+ ELIF akt char = comercial and
+ THEN string
+ ELSE errorstop (1005, "USING-Format fehlerhaft: " + using format); "" FI .
+
+given length string:
+ INT VAR len :: 2;
+ FOR using pos FROM using pos+1 UPTO length (using format)
+ REP IF akt char = "\"
+ THEN LEAVE given length string WITH text (string, len) FI;
+ len INCR 1
+ UNTIL akt char <> " "PER;
+ errorstop (1005, "USING-Format fehlerhaft: " + using format);
+ "" .
+
+akt char: using format SUB using pos
+END PROC basic text;
+
+TEXT PROC basic text (INT CONST number):
+ IF image used
+ THEN basic text (real (number))
+ ELSE sign + text (number) FI .
+
+sign:
+ IF number >= 0
+ THEN " "
+ ELSE "" FI .
+
+END PROC basic text;
+
+TEXT PROC basic text (REAL CONST number):
+ IF image used
+ THEN using text
+ ELSE normal text FI .
+
+normal text:
+(* Bei Real Zahlen werden maximal 7 signifikante Stellen ausgegeben, *)
+(* führende und nachfolgende Nullen werden unterdrückt, *)
+(* der Dezimalpunkt wird im Normalformat unterdrückt *)
+ calculate sign;
+ REAL VAR mantissa := round (abs (number), 6-decimal exponent (number));
+ INT CONST exp :: decimal exponent (mantissa);
+
+ IF mantissa = 0.0
+ THEN result := " 0"
+ ELIF exp > 6 OR exp < -7 OR (exp < 0 AND more than 7 signifikant digits)
+ THEN scientific notation
+ ELIF exp < 0
+ THEN short negative notation
+ ELSE short positive notation FI;
+ result .
+
+more than 7 signifikant digits:
+ REAL VAR signifikant := mantissa;
+ set exp (7+exp, signifikant);
+ frac (signifikant) <> 0.0 .
+
+calculate sign:
+ IF number >= 0.0
+ THEN result := " "
+ ELSE result := "-" FI .
+
+scientific notation:
+ set exp (0, mantissa);
+ result CAT non zero (text (mantissa, 8, 6));
+
+ IF exp < 0
+ THEN result CAT "E-"
+ ELSE result CAT "E+" FI;
+
+ IF abs (exp) > 9
+ THEN result CAT text (abs (exp))
+ ELSE result CAT "0";
+ result CAT text (abs (exp))
+ FI .
+
+short positive notation:
+ result CAT non zero (text (mantissa, 8, 6-exp));
+ IF (result SUB LENGTH result) = "."
+ THEN delete char (result, LENGTH result) FI .
+
+short negative notation:
+ result CAT non zero (subtext (text (abs (mantissa), 9, 7), 2)).(* F13/rr *)
+
+using text:
+ init (result);
+ result CAT format number (subformat, number);
+ result CAT next format;
+ result .
+
+subformat:
+ INT VAR from :: using pos, to :: last format char;
+ subtext (using format, from, to) .
+
+last format char:
+ FOR using pos FROM using pos+1 UPTO length (using format)
+ REP IF non format char
+ THEN LEAVE last format char WITH using pos-1 FI
+ PER;
+ using pos := 0;
+ length (using format) .
+
+non format char:
+ IF (using format SUB using pos) = comma
+ THEN (using format SUB (using pos+1)) <> point
+ ELSE pos (numberformat chars, using format SUB using pos) = 0 FI .
+
+END PROC basic text;
+
+TEXT PROC non zero (TEXT CONST text):
+ INT VAR i;
+ FOR i FROM length (text) DOWNTO 2
+ REP UNTIL (text SUB i) <> "0" PER;
+ subtext (text, 1, i)
+END PROC non zero;
+
+TEXT PROC format number (TEXT CONST format, REAL CONST number):
+ IF no digit char
+ THEN errorstop (1005, "USING-Format fehlerhaft: " + using format); ""
+ ELIF exponent found
+ THEN exponent format
+ ELSE normal format FI .
+
+no digit char:
+ pos (format, numbersign) = 0 AND
+ pos (format, asterisk) = 0 AND
+ pos (format, dollarsign) = 0 .
+
+exponent found:
+ INT CONST exponent pos := pos (format, caret);
+ exponent pos > 0 .
+
+exponent format:
+ IF leading plus
+ THEN plus or minus + exponent field (subtext (format, 2), number, exponent pos-1)
+ ELIF trailing plus
+ THEN exponent field (format, number, exponent pos) + plus or minus
+ ELIF trailing minus
+ THEN exponent field (format, number, exponent pos) + nil or minus
+ ELSE blank or minus + exponent field (subtext (format, 2), number, exponent pos-1) FI .
+
+normal format:
+ IF leading numbersign
+ THEN number field (format, number, "", " ")
+ ELIF leading point
+ THEN number field (format, number, "", " ")
+ ELIF leading plus
+ THEN number field (format, abs (number), plus or minus, " ")
+ ELIF leading asterisk dollar
+ THEN number field (format, number, "$", "*")
+ ELIF leading asterisk
+ THEN number field (format, number, "", "*")
+ ELIF leading dollarsign
+ THEN number field (format, number, "$", " ")
+ ELSE errorstop (1005, "USING-Format fehlerhaft: " + using format); "" FI .
+
+leading numbersign: (format SUB 1) = numbersign .
+leading point: (format SUB 1) = point .
+leading plus: (format SUB 1) = plus .
+leading asterisk dollar: subtext (format, 1, 3) = asterisk dollar .
+leading asterisk: subtext (format, 1, 2) = asterisk .
+leading dollarsign: subtext (format, 1, 2) = dollarsign .
+
+trailing minus: (format SUB LENGTH format) = minus .
+trailing plus: (format SUB LENGTH format) = plus .
+
+plus or minus: IF number < 0.0 THEN minus ELSE plus FI .
+nil or minus: IF number < 0.0 THEN minus ELSE nil FI .
+blank or minus: IF number < 0.0 THEN minus ELSE blank FI .
+
+END PROC format number;
+
+TEXT PROC exponent field (TEXT CONST format, REAL CONST value, INT CONST exponent pos):
+ REAL VAR number := abs (value);
+ INT CONST point pos := pos (format, point);
+ calc leading and trailing;
+ INT CONST new exponent :: decimal exponent (value) - leading + 1;
+ IF abs (new exponent) >= 100
+ THEN "%" + mantissa + "E" + null text (new exponent, 4)
+ ELSE mantissa + exponent
+ FI.
+
+calc leading and trailing:
+ INT VAR leading, trailing;
+ IF point pos = 0
+ THEN leading := exponent pos-1;
+ trailing := 0
+ ELSE leading := point pos-1;
+ trailing := exponent pos-point pos-1
+ FI .
+
+mantissa:
+ set exp (leading - 1, number);
+ IF point pos = 0
+ THEN subtext (text (number, leading+1, 0), 1, leading)
+ ELSE subtext (text (number, leading+trailing+2, trailing), 2) FI .
+
+exponent:
+ "E" + null text (new exponent, 3) .
+
+END PROC exponent field;
+
+TEXT PROC number field (TEXT CONST format, REAL CONST value,
+ TEXT CONST pretext, lead char):
+ INT CONST point pos :: pos (format, point);
+ calc fraction;
+ calc digits;
+ calc commata if necessary;
+ fill with lead chars and sign .
+
+calc fraction:
+ INT VAR fraction :: 0, i;
+ FOR i FROM point pos+1 UPTO length (format)
+ WHILE (format SUB i) = numbersign
+ REP fraction INCR 1 PER .
+
+calc digits:
+ TEXT VAR valuetext;
+ IF point pos = 0
+ THEN valuetext := digits (abs (value), 0, TRUE);
+ delete char (valuetext, length (valuetext))
+ ELSE valuetext := digits (abs (value), fraction, point pos <> 1) FI .
+
+calc commata if necessary:
+ IF comma before point
+ THEN insert commata FI .
+
+comma before point:
+ point pos > 0 CAND (format SUB point pos-1) = comma .
+
+insert commata:
+ i := pos (valuetext, point)-3;
+ WHILE i > 1 CAND (valuetext SUB i) <> " "
+ REP insert char (valuetext, ",", i);
+ i DECR 3
+ PER .
+
+fill with lead chars and sign:
+ IF trailing minus
+ THEN fillby (pretext + valuetext, length (format)-1, lead char) + nil or minus
+ ELIF trailing plus
+ THEN fillby (pretext + valuetext, length (format)-1, lead char) + plus or minus
+ ELIF value < 0.0
+ THEN fillby (pretext + minus + valuetext, length (format), lead char)
+ ELSE fillby (pretext + valuetext, length (format), lead char) FI .
+
+
+plus or minus: IF value < 0.0 THEN minus ELSE plus FI .
+nil or minus: IF value < 0.0 THEN minus ELSE nil FI .
+trailing minus: (format SUB LENGTH format) = minus .
+trailing plus: (format SUB LENGTH format) = plus .
+END PROC numberfield;
+
+TEXT PROC null text (INT CONST n, digits):
+ TEXT VAR l result := text (abs (n), digits);
+ IF n < 0
+ THEN replace (l result, 1, "-")
+ ELSE replace (l result, 1, "+") FI;
+ change all (l result, " ", "0");
+ l result .
+END PROC null text;
+
+TEXT PROC fillby (TEXT CONST source, INT CONST format, TEXT CONST with):
+ IF differenz >= 0
+ THEN differenz * with + source
+ ELSE "%" + source FI .
+
+differenz: format - length (source) .
+END PROC fillby;
+
+TEXT PROC digits (REAL CONST value, INT CONST frac, BOOL CONST null):
+ IF decimal exponent (value) < 0
+ THEN TEXT VAR l result := text (value, frac+2, frac);
+
+ IF null AND first char <> "0"
+ THEN replace (l result, 1, "0");
+ l result
+ ELIF (NOT null AND first char = "0") OR first char = " "
+ THEN subtext (l result, 2)
+ ELSE l result FI
+ ELSE text (value, decimal exponent (value)+frac+2, frac) FI .
+
+first char:
+ (l result SUB 1) .
+
+END PROC digits;
+
+TEXT PROC right (TEXT CONST msg, INT CONST len):
+ IF length (msg) >= len
+ THEN subtext (msg, 1, len)
+ ELSE (len - length (msg)) * " " + msg FI
+
+END PROC right;
+
+END PACKET basic using;
+
+PACKET basic output (* Autor: R. Ruland *)
+ (* Stand: 28.08.1987/rr/mo *)
+ DEFINES basic page,
+ width,
+ init output,
+ basic out,
+ basic write,
+ tab,
+ next zone,
+ next line,
+ next page,
+ cursor x pos,
+ pos,
+ csrlin,
+ l pos,
+ switch to printout file,
+ switch back to old sysout state:
+
+LET zone width = 16; (* sd.ddddddEsdddb (s = sign, d = digit, b = blank) *)
+LET printfile name = "BASIC LPRINT OUTPUT";
+
+INT VAR screen width, x cursor, y cursor, line no;
+BOOL VAR paging := FALSE, first time,
+ in lprint; (* mo *)
+TEXT VAR buffer, output line, last sysout file, old sysout, char;
+
+PROC basic page (BOOL CONST status):
+
+ paging := status
+
+END PROC basic page;
+
+BOOL PROC basic page: paging END PROC basic page;
+
+
+PROC width (INT CONST max):
+
+ IF max < 0
+ THEN errorstop (1005, "WIDTH: negatives Angabe: " + text (max))
+ ELIF max = 0
+ THEN screen width := 1
+ ELSE screen width := max
+ FI;
+ last sysout file := "";
+
+END PROC width;
+
+INT PROC width : screen width END PROC width;
+
+
+PROC init output:
+
+ clear using;
+ width (max (1, x size));
+ line no := 1;
+ output line := "";
+ first time := TRUE;
+ in lprint := FALSE
+
+END PROC init output;
+
+
+PROC basic out (INT CONST i): bas out (basic text (i) + " ") END PROC basic out;
+
+PROC basic out (REAL CONST r): bas out (basic text (r) + " ") END PROC basic out;
+
+PROC basic out (TEXT CONST t): bas out (basic text (t)) END PROC basic out;
+
+PROC basic write (INT CONST i): bas out (basic text (i)) END PROC basic write;
+
+PROC basic write (REAL CONST r): bas out (basic text (r)) END PROC basic write;
+
+PROC basic write (TEXT CONST t): bas out (basic text ("""" + t + """")) END PROC basic write;
+
+
+PROC bas out (TEXT CONST msg):
+
+ get cursor;
+ IF length (msg) > free
+ THEN IF first time
+ THEN first time := FALSE;
+ next line;
+ bas out (msg);
+ ELSE buffer := subtext (msg, 1, free);
+ IF sysout = ""
+ THEN out (buffer)
+ ELSE sysout write (buffer)
+ FI;
+ next line;
+ buffer := subtext (msg, free + 1);
+ bas out (buffer);
+ FI;
+ ELSE first time := TRUE;
+ IF sysout = ""
+ THEN out (msg)
+ ELSE sysout write (msg)
+ FI;
+ FI;
+
+ . free : screen width - x cursor + 1
+
+END PROC bas out;
+
+
+PROC tab (INT CONST n):
+
+ get cursor;
+ IF n <= 0
+ THEN tab position out of range
+ ELIF n > screen width
+ THEN tab (n MOD screen width);
+ ELIF x cursor > n
+ THEN next line;
+ tab (n);
+ ELIF sysout = ""
+ THEN cursor (n, y cursor);
+ ELSE buffer := (n - x cursor) * " ";
+ sysout write (buffer)
+ FI;
+
+ . tab position out of range :
+ IF x cursor <> 1 THEN next line FI;
+ write ("WARNUNG : TAB-Position <= 0");
+ next line;
+
+END PROC tab;
+
+
+PROC next zone:
+
+ get cursor;
+ IF x cursor > screen width - zone width
+ THEN next line;
+ ELIF sysout = ""
+ THEN free TIMESOUT " ";
+ ELSE buffer := free * " ";
+ sysout write (buffer)
+ FI;
+
+ . free : ((x cursor - 1) DIV zone width + 1) * zone width - x cursor + 1
+
+END PROC next zone;
+
+
+PROC next line :
+
+ IF sysout = ""
+ THEN next line on screen
+ ELSE line;
+ write (""); (* generates new record *)
+ output line := "";
+ FI;
+
+ . next line on screen:
+ line no INCR 1;
+ IF paging CAND line no > y size
+ THEN IF in last line
+ THEN warte;
+ ELSE out (""13""10"");
+ line no := y cursor + 1;
+ FI;
+ ELIF NOT paging
+ THEN char := incharety;
+ IF char <> ""
+ THEN IF char = "+"
+ THEN paging := TRUE
+ ELSE type (char)
+ FI
+ FI;
+ out (""13""10"")
+ ELSE out (""13""10"")
+ FI
+
+ . in last line :
+ get cursor;
+ y cursor = y size
+
+ . warte :
+ cursor (x size - 2, y size);
+ out (">>");
+ inchar (char);
+ IF char = ""13""
+ THEN next page
+ ELIF char = ""10""
+ THEN out (""8""8" "13""10"")
+ ELIF char = ""27""
+ THEN clear editor buffer;
+ errorstop (1, "")
+ ELIF char = "-"
+ THEN out (""8""8" "13""10"");
+ line no := 1;
+ paging := FALSE;
+ ELSE out (""8""8" "13""10"");
+ line no := 1;
+ FI;
+
+ . clear editor buffer:
+ REP UNTIL get charety = "" PER;
+
+END PROC next line;
+
+
+PROC next page:
+
+ IF sysout = ""
+ THEN out (""1""4"")
+ ELSE line
+ FI;
+ clear using;
+ line no := 1;
+ output line := "";
+
+END PROC next page;
+
+
+INT PROC pos (REAL CONST dummy): (* mo *)
+
+ cursor x pos
+
+END PROC pos;
+
+
+INT PROC pos (INT CONST dummy): (* mo *)
+
+ cursor x pos
+
+END PROC pos;
+
+
+INT PROC cursor x pos :
+
+ get cursor;
+ x cursor
+
+END PROC cursor x pos;
+
+
+INT PROC csrlin: (* mo *)
+
+ get cursor;
+ y cursor
+
+END PROC csrlin;
+
+
+PROC get cursor :
+
+ IF sysout = ""
+ THEN get cursor (x cursor, y cursor);
+ ELSE x cursor := LENGTH output line + 1;
+ FI;
+
+END PROC get cursor;
+
+
+INT PROC l pos (REAL CONST dummy): (* mo *)
+
+ l pos (0)
+
+END PROC l pos;
+
+
+INT PROC l pos (INT CONST dummy): (* mo *)
+
+ INT VAR lprint position :: 1;
+ IF exists (printfile name)
+ THEN disable stop;
+ FILE VAR printfile :: sequential file (modify, printfile name);
+ IF lines (printfile) > 0
+ THEN to line (printfile, lines (printfile));
+ lprint position := len (printfile) + 1
+ FI;
+ output (printfile)
+ FI;
+ lprint position
+
+END PROC l pos;
+
+
+PROC switch to printout file: (* mo *)
+
+ in lprint := TRUE;
+ old sysout := sysout;
+ careful sysout (printfile name);
+
+END PROC switch to printout file;
+
+
+PROC switch back to old sysout state: (* mo *)
+
+ IF in lprint
+ THEN careful sysout (old sysout);
+ in lprint := FALSE
+ FI
+
+END PROC switch back to old sysout state;
+
+
+PROC sysout write (TEXT CONST string):
+ check sysout;
+ write (string);
+ output line CAT string.
+
+check sysout:
+ IF sysout <> last sysout file
+ THEN careful sysout (sysout)
+ FI.
+
+END PROC sysout write;
+
+
+PROC careful sysout (TEXT CONST new sysout): (* mo *)
+
+IF new sysout <> ""
+ THEN disable stop;
+ FILE VAR outfile :: sequential file (modify, new sysout);
+ max line length (outfile, screen width);
+ last sysout file := sysout;
+ IF lines (outfile) > 0
+ THEN to line (outfile, lines (outfile));
+ read record (outfile, output line);
+ delete record (outfile)
+ ELSE output line := ""
+ FI;
+ sysout (new sysout);
+ write (output line);
+ ELSE sysout ("")
+FI
+
+END PROC careful sysout;
+
+END PACKET basic output;
+
+
+PACKET basic input (* Autor: R. Ruland *)
+ (* Stand: 27.10.1987/rr/mo *)
+
+ DEFINES init input,
+ read input,
+ check input,
+ assign input,
+ assign input line,
+ input ok,
+ input eof:
+
+
+LET comma = ",",
+ quote = """",
+
+ wrong type = 1,
+ insufficient data = 2,
+ too much data = 3,
+ overflow = 4,
+
+ int overflow = 4,
+ real overflow = 6;
+
+INT VAR input line pos, input error no;
+BOOL VAR on terminal;
+TEXT VAR input line :: "", previous input line := "", input value;
+
+. first quote found : (input value SUB 1) = quote
+.;
+
+PROC init input :
+
+ input error no := 0;
+ input line pos := 0;
+ input line := "";
+ previous input line := "";
+
+END PROC init input;
+
+
+PROC read input (BOOL CONST cr lf, TEXT CONST msg, BOOL CONST question mark):
+
+ on terminal := sysout <> "" AND sysin = "";
+ check input error;
+ out string (msg);
+ IF question mark THEN out string ("? ") FI;
+ IF sysin <> ""
+ THEN getline (input line);
+ ELSE editget input line;
+ FI;
+ out string (input line);
+ IF crlf THEN out line FI;
+ input line pos := 0;
+ input error no := 0;
+
+ . check input error :
+ IF input error no = 0
+ THEN input line := "";
+ ELSE IF sysin = ""
+ THEN BOOL CONST old basic page := basic page;
+ basic page (FALSE);
+ IF cursor x pos <> 1 THEN next line FI;
+ basic out ("?Eingabe wiederholen ! (" + error text + ")");
+ next line;
+ basic page (old basic page);
+ ELSE errorstop (1080,"INPUT-Fehler (" + error text +
+ ") : >" + input line + "<");
+ FI;
+ FI;
+
+ . error text :
+ SELECT input error no OF
+ CASE wrong type : "falscher Typ"
+ CASE insufficient data : "zu wenig Daten"
+ CASE too much data : "zu viele Daten"
+ CASE overflow : "Überlauf"
+ OTHERWISE : ""
+ END SELECT
+
+ . editget input line :
+ TEXT VAR exit char;
+ INT VAR x, y;
+ get cursor (x, y);
+ REP IF width - x < 1
+ THEN out (""13""10"");
+ get cursor (x, y)
+ FI;
+ editget (input line, max text length, width - x, "", "k", exit char);
+ cursor (x, y);
+ IF exit char = ""27"k"
+ THEN input line := previous input line;
+ ELSE previous input line := input line;
+ LEAVE editget input line;
+ FI;
+ PER;
+
+END PROC read input;
+
+
+PROC out string (TEXT CONST string) :
+
+ basic out (string);
+ IF on terminal THEN out (string) FI;
+
+END PROC out string;
+
+
+PROC out line :
+
+ next line;
+ IF on terminal THEN out (""13""10"") FI;
+
+END PROC out line;
+
+
+BOOL PROC check input (INT CONST type) :
+
+ get next input value;
+ input value := compress (input value);
+ set conversion (TRUE);
+ SELECT type OF
+ CASE 1 : check int input
+ CASE 2 : check real input
+ CASE 3 : check text input
+ END SELECT;
+ IF NOT last conversion ok THEN input error no := wrong type FI;
+ input error no = 0
+
+ . check int input :
+ IF input value <> ""
+ THEN disable stop;
+ INT VAR help int value;
+ help int value := int (input value);
+ IF is error CAND error code = int overflow
+ THEN clear error;
+ input error no := overflow;
+ FI;
+ enable stop;
+ FI;
+
+ . check real input :
+ IF input value <> ""
+ THEN disable stop;
+ REAL VAR help real value;
+ help real value := val (input value);
+ IF is error CAND (error code = real overflow
+ OR error code = int overflow) (* <-- Aufgrund eines Fehlers in 'real' *)
+ THEN clear error;
+ input error no := overflow;
+ FI;
+ enable stop;
+ FI;
+
+ . check text input :
+ (* IF input value = "" THEN input error no := wrong type FI; *)
+ IF NOT is quoted string CAND quote found
+ THEN input error no := wrong type
+ FI;
+
+ . is quoted string :
+ first quote found CAND last quote found
+
+ . last quote found :
+ (input value SUB LENGTH input value) = quote
+
+ . quote found :
+ pos (input value, quote) > 0
+
+END PROC check input;
+
+
+PROC assign input (INT VAR int value) :
+
+ get next input value;
+ int value := int (input value);
+
+END PROC assign input;
+
+PROC assign input (REAL VAR real value) :
+
+ get next input value;
+ real value := val (input value);
+
+END PROC assign input;
+
+PROC assign input (TEXT VAR string value) :
+
+ get next input value;
+ input value := compress (input value);
+ IF first quote found
+ THEN string value := subtext (input value, 2, LENGTH input value -1)
+ ELSE string value := input value
+ FI;
+
+END PROC assign input;
+
+PROC assign input line (TEXT VAR string line) :
+
+ string line := input line;
+
+END PROC assign input line;
+
+
+PROC get next input value : (* F27/rr *)
+
+ IF input line pos > LENGTH input line
+ THEN input value := "";
+ input error no := insufficient data;
+ ELSE IF next non blank char = quote
+ THEN get quoted string
+ ELSE get unquoted string
+ FI;
+ FI;
+
+ . next non blank char :
+ INT CONST next non blank char pos := pos (input line, ""33"", ""255"", input line pos + 1);
+ input line SUB next non blank char pos
+
+ . get quoted string :
+ INT CONST quote pos := pos (input line, quote, next non blank char pos + 1);
+ IF quote pos = 0
+ THEN input value := subtext (input line, next non blank char pos);
+ input line pos := LENGTH input line + 1;
+ input error no := wrong type;
+ ELSE input value := subtext (input line, next non blank char pos, quote pos);
+ input line pos := pos (input line, ""33"", ""255"", quote pos + 1);
+ IF input line pos = 0
+ THEN input line pos := LENGTH input line + 1;
+ ELIF (input line SUB input line pos) <> comma
+ THEN input error no := wrong type;
+ input line pos DECR 1;
+ FI;
+ FI;
+
+ . get unquoted string :
+ INT VAR comma pos := pos (input line, comma, input line pos + 1);
+ IF comma pos = 0
+ THEN input value := subtext (input line, input line pos + 1);
+ input line pos := LENGTH input line + 1;
+ ELSE input value := subtext (input line, input line pos + 1, comma pos - 1);
+ input line pos := comma pos;
+ FI;
+
+END PROC get next input value;
+
+
+BOOL PROC input ok:
+
+ IF input line pos <= LENGTH input line
+ THEN input error no := too much data FI;
+ input line pos := 0;
+ input error no = 0
+
+END PROC input ok;
+
+BOOL PROC input eof: input line = "" END PROC input eof;
+
+
+END PACKET basic input;
+
+PACKET basic std using io (* Autor: R. Ruland *)
+ (* Stand: 26.10.87/rr/mo *)
+
+ DEFINES init rnd:
+
+
+PROC init rnd:
+
+ REAL VAR init;
+ REP read input (TRUE, "Startwert des Zufallszahlengenerators ? ", FALSE);
+ UNTIL check input (2) CAND input ok PER; (* F24/rr *)
+ assign input (init);
+ init rnd (init);
+
+END PROC init rnd;
+
+
+END PACKET basic std using io;
+
diff --git a/basic/eumel coder 1.8.1 b/basic/eumel coder 1.8.1
new file mode 100644
index 0000000..0047067
--- /dev/null
+++ b/basic/eumel coder 1.8.1
@@ -0,0 +1,3086 @@
+PACKET eumel coder (* Autor: U. Bartling *)
+ DEFINES coder on, coder off,
+ declare, define, apply, identify,
+ :=, =,
+ dump,
+
+ LIB,
+
+ LABEL,
+ gosub, goret,
+ computed branch,
+ complement condition code,
+
+ ADDRESS ,
+ GLOB, LOC, REF, DEREF,
+ ref length,
+ +,
+ adjust,
+ get base,
+ is global, is local, is ref,
+
+ DTYPE,
+ type class, type name,
+ void type, int type, real type, text type, bool type,
+ bool result type, dataspace type, undefined type,
+ row type, struct type, proc type, end type,
+
+ OPN,
+ set length of local storage,
+ begin module, end module,
+ is proc, is eumel 0 instruction,
+ address, operation,
+ nop,
+ mnemonic,
+
+ parameter,
+ next param,
+ NEXTPARAM,
+ access ,
+ dtype ,
+ param address,
+ same type ,
+
+ reserve storage,
+ allocate denoter ,
+ allocate variable,
+ data allocation by coder ,
+ data allocation by user,
+
+ run, run again,
+ insert,
+ prot, prot off,
+ check, check on, check off,
+
+ help, bulletin, packets,
+
+(**************************************************************************)
+(* *)
+(* E U M E L - C O D E R *)
+(* *)
+(* *)
+(* Zur Beschreibung des Coders siehe *)
+(* U.Bartling, J. Liedtke: EUMEL-Coder-Interface *)
+(* *)
+(* Stand der Dokumentation : 29.10.1986 *)
+(* Stand der Implementation : 03.09.1986 *)
+(* *)
+(* *)
+(**************************************************************************)
+
+#page#
+(**************************************************************************)
+(* *)
+(* 0. Datentyp DINT 03.09.1987 *)
+(* *)
+(* Definition des Datentyps *)
+(* arithmetischer Operationen *)
+(* und Konvertierungsprozeduren *)
+(* *)
+(**************************************************************************)
+
+
+ DINT,
+ -, *, DIV, MOD, <, <=,
+ AND, OR, XOR,
+ dput, dget, dmov,
+ ddec1, dinc1, dinc, ddec,
+ dadd, dsub,
+ dequ, dlseq,
+ INCR, DECR,
+ put, get, cout,
+ text, real, int, dint,
+ replace, DSUB :
+
+
+TYPE DINT = STRUCT (INT low, high) ;
+
+
+REAL VAR real value ; (* auch fuer Ausrichtung ! *)
+TEXT VAR convertion buffer ;
+
+DINT CONST dint0 :: dint(0) ;
+DINT VAR result :: dint 0 ;
+
+
+DINT PROC dint (INT CONST number) :
+ EXTERNAL 144
+ENDPROC dint ;
+
+INT PROC int (DINT CONST i) :
+ EXTERNAL 143
+ENDPROC int;
+
+REAL PROC real (DINT CONST number) :
+ real value := 65536.0 * real (number.high) ;
+
+ IF number.low >= 0
+ THEN real value INCR real (number.low)
+ ELSE real value INCR (real (number.low AND maxint) + 32768.0)
+ FI ;
+ real value
+ENDPROC real ;
+
+DINT PROC dint (REAL CONST number) :
+ real value := abs (number) ;
+ REAL CONST low := real value MOD 65536.0 ;
+
+ result.high := int(real value / 65536.0) ;
+ IF low < 32768.0
+ THEN result.low := int (low)
+ ELSE result.low := int (low-32768.0) OR minint
+ FI ;
+ IF number < 0.0 THEN dsub (dint0, result, result) FI ;
+ result
+ENDPROC dint ;
+
+TEXT PROC text (DINT CONST number) :
+ IF number.high = 0 THEN convert low part only
+ ELSE convert number
+ FI ;
+ convertion buffer .
+
+convert low part only :
+ IF number.low >= 0 THEN convertion buffer := text (number.low)
+ ELSE convertion buffer := text (real of low) ;
+ erase decimal point
+ FI .
+
+real of low :
+ real (number.low AND maxint) + 32768.0 .
+
+convert number :
+ convertion buffer := text (real(number)) ;
+ erase decimal point .
+
+erase decimal point :
+ convertion buffer := subtext (convertion buffer, 1, LENGTH convertion buffer-2)
+ENDPROC text;
+
+DINT PROC dint (TEXT CONST dint txt) :
+ convertion buffer := dint txt ;
+ INT CONST dot pos :: pos (convertion buffer, ".") ;
+ IF dot pos = 0 THEN convertion buffer CAT ".0" FI ;
+ dint (real(convertion buffer))
+ENDPROC dint ;
+
+PROC get (DINT VAR dest) :
+ REAL VAR number ;
+ get (number) ;
+ dest := dint (number)
+ENDPROC get ;
+
+PROC put (DINT CONST number) :
+ put (text (number));
+ENDPROC put ;
+
+PROC cout (DINT CONST number) :
+ EXTERNAL 61
+ENDPROC cout;
+
+OP := (DINT VAR a, DINT CONST b) :
+# INLINE ; #
+ dmov (b, a);
+ENDOP :=;
+
+OP INCR (DINT VAR a, DINT CONST b) :
+# INLINE ; #
+ dinc (b, a);
+ENDOP INCR;
+
+OP DECR (DINT VAR a, DINT CONST b) :
+# INLINE ; #
+ ddec (b, a);
+ENDOP DECR;
+
+BOOL OP = (DINT CONST a, b) :
+ EXTERNAL 137
+ENDOP =;
+
+BOOL OP <= (DINT CONST a, b) :
+ EXTERNAL 138
+ENDOP <=;
+
+BOOL OP < (DINT CONST a, b) :
+# INLINE ; #
+ NOT (b <= a)
+ENDOP <;
+
+BOOL PROC dequ (DINT CONST a, b) :
+ EXTERNAL 137
+ENDPROC dequ ;
+
+BOOL PROC dlseq (DINT CONST a, b) :
+ EXTERNAL 138
+ENDPROC dlseq ;
+
+PROC replace (TEXT VAR text, INT CONST index of dint, DINT CONST value) :
+ INT VAR subscript := index of dint * 2 ;
+ replace (text, subscript - 1,value.low);
+ replace (text, subscript, value.high);
+ENDPROC replace;
+
+DINT OP DSUB (TEXT CONST text, INT CONST index of dint) :
+ INT VAR subscript := index of dint * 2 ;
+ result.low := text ISUB subscript - 1;
+ result.high := text ISUB subscript;
+ result
+ENDOP DSUB;
+
+DINT OP + (DINT CONST a, b) :
+ EXTERNAL 135
+ENDOP + ;
+
+DINT OP - (DINT CONST a, b) :
+ EXTERNAL 136
+ENDOP - ;
+
+PROC dadd (DINT CONST a, b, DINT VAR res) :
+ EXTERNAL 135
+ENDPROC dadd ;
+
+PROC dsub (DINT CONST a, b, DINT VAR res) :
+ EXTERNAL 136
+ENDPROC dsub ;
+
+PROC dinc (DINT CONST source, DINT VAR dest) :
+ EXTERNAL 133
+ENDPROC dinc ;
+
+PROC ddec (DINT CONST source, DINT VAR dest) :
+ EXTERNAL 134
+ENDPROC ddec ;
+
+PROC dmov (DINT CONST source, DINT VAR dest) :
+ EXTERNAL 130
+ENDPROC dmov;
+
+DINT OP DIV (DINT CONST a,b) :
+ EXTERNAL 152
+ENDOP DIV ;
+
+DINT OP MOD (DINT CONST a,b) :
+ EXTERNAL 153
+ENDOP MOD ;
+
+DINT OP AND (DINT CONST a,b) :
+ result.low := a.low AND b.low ;
+ result.high := a.high AND b.high ;
+ result
+ENDOP AND ;
+
+DINT OP OR (DINT CONST a,b) :
+ result.low := a.low OR b.low ;
+ result.high := a.high OR b.high ;
+ result
+ENDOP OR ;
+
+DINT OP XOR (DINT CONST a,b) :
+ result.low := a.low XOR b.low ;
+ result.high := a.high XOR b.high ;
+ result
+ENDOP XOR ;
+
+PROC dput (ROW 32000 DINT VAR array, DINT CONST index, value) :
+ EXTERNAL 139
+ENDPROC dput ;
+
+PROC dget (ROW 32000 DINT VAR array, DINT CONST index, DINT VAR dest) :
+ EXTERNAL 140
+ENDPROC dget ;
+
+PROC dinc1 (DINT VAR dest) :
+ EXTERNAL 131
+ENDPROC dinc1 ;
+
+PROC ddec1 (DINT VAR dest) :
+ EXTERNAL 132
+ENDPROC ddec1 ;
+
+DINT OP * (DINT CONST a,b) :
+ EXTERNAL 151
+ENDOP * ;
+
+#page#
+ (***** Globale Variable *****)
+
+TEXT VAR object name;
+
+FILE VAR bulletin file;
+
+INT VAR memory management mode, global address offset, packet base,
+ hash table pointer, nt link, permanent pointer, param link,
+ packet link, index, mode, field pointer, word,
+ number of errors := 0 ;
+
+BOOL VAR found, end of params;
+
+#page#
+(**************************************************************************)
+(* *)
+(* 1. Interface zum ELAN-Compiler 13.11.1986 *)
+(* 1.8.1 *)
+(* *)
+(* Beschreibung der Tabellen (-groessen), *)
+(* internen Vercodung von Typen *)
+(* und Kennungen . *)
+(* Initialisieren und Beenden des Compilers, *)
+(* Lesen aus und Schreiben in Namens- bzw. Permanent-Tabelle *)
+(* *)
+(**************************************************************************)
+
+
+TYPE LIB = STRUCT (TEXT name, INT nt link, pt link, ADDRESS base) ;
+
+LET begin of hash table = 0 ,
+ end of hash table = 1023 ,
+
+ begin of permanent table = 22784 ,
+ before first pt entry = 22784 ,
+ first permanent entry = 22785 ,
+ end of permanent table = 32767 ,
+
+ wordlength = 1 , (* compile u n d run time *)
+ two word length = 2 ,
+ three word length = 3 ,
+ four word length = 4 ,
+
+ permanent param const = 10000 ,
+ permanent param var = 20000 ,
+ permanent proc op = 30000 ,
+ permanent type = 30000 ,
+ permanent row = 10 ,
+ permanent struct = 11 ,
+ permanent param proc = 12 ,
+ permanent param proc end marker = 0 ,
+ permanent type field = 0 ,
+
+ ptt limit = 10000 ,
+ begin of pt minus ptt limit = 12784 ,
+ begin of pt minus ptt limit 1 = 12785 , (* plus wordlength *)
+
+ void id = 0 ,
+ int id = 1 ,
+ real id = 2 ,
+ string id = 3 ,
+ bool id = 5 ,
+ bool result id = 6 ,
+ dataspace id = 7 ,
+ undefined id = 9 ,
+ row id = 10 ,
+ struct id = 11 ,
+ end id = 0 ,
+
+ const = 1 ,
+ var = 2 ,
+ proc id = 3 ,
+(* denoter = 5 , *)
+ bold = 2 ,
+
+ ins = TRUE ,
+ no ins = FALSE ,
+ no lst = FALSE ,
+ sermon = TRUE ,
+ no sermon = FALSE ,
+
+ run again mode = 0 ,
+ compile file mode = 1 ,
+ prep coder mode = 5 ,
+
+ warning message = 2 ,
+ error message = 4 ,
+
+ point line = "..............." ;
+
+INT CONST permanent packet := -2 ,
+ permanent end := -3 ;
+
+BOOL VAR coder active := FALSE ;
+
+INT VAR run again mod nr := 0 ;
+
+
+ (***** Start/Ende *****)
+
+LET coder not active = "CODER not active" ,
+ illegal define packet = "illegal define packet" ;
+
+PROC coder on (INT CONST data allocation mode) :
+ mark coder on ;
+ init opn section ;
+ init compiler ;
+ init memory management .
+
+mark coder on :
+ coder active := TRUE .
+
+init memory management :
+ memory management mode := data allocation mode .
+
+init compiler :
+ no do again ;
+ elan (prep coder mode, bulletin file, "", run again mod nr,
+ no ins, no lst, check option, no sermon)
+
+ENDPROC coder on;
+
+PROC coder off (BOOL CONST insert, sermon, OPN CONST start proc) :
+ IF coder active
+ THEN mark coder off ;
+ end coder (insert, sermon, start mod nr if no insert)
+ ELSE errorstop (coder not active)
+ FI .
+
+start mod nr if no insert :
+ IF insert THEN run again mod nr := 0
+ ELSE run again mod nr := start proc.mod nr
+ FI ;
+ run again mod nr .
+
+mark coder off :
+ reset memory management mode ;
+ init opn section ;
+ coder active := FALSE
+ENDPROC coder off ;
+
+PROC end coder (BOOL CONST insert wanted, sermon wanted, INT CONST mod) :
+ EXTERNAL 10021
+ENDPROC end coder ;
+
+PROC elan (INT CONST mode, FILE VAR source, TEXT CONST line,
+ INT VAR start module number, BOOL CONST ins, lst, rtc, ser) :
+ EXTERNAL 256
+ENDPROC elan ;
+
+PROC unsigned arithmetic :
+ EXTERNAL 92
+ENDPROC unsigned arithmetic ;
+
+
+ (***** Paket-Rahmen *****)
+
+PROC declare (TEXT CONST name, LIB VAR packet) :
+ packet.name := name
+ENDPROC declare ;
+
+PROC define (LIB VAR packet) :
+ check if definition possible ;
+ declare object (packet.name, packet.nt link, packet.pt link) ;
+ open packet (packet.nt link, global address offset, packet base) ;
+ set to actual base (packet) .
+
+check if definition possible :
+ IF NOT coder active THEN errorstop (coder not active) FI ;
+ IF module open THEN errorstop (illegal define packet) FI
+ENDPROC define ;
+
+PROC open packet (INT CONST nt link of packet name, INT VAR offset, base) :
+ EXTERNAL 10032
+ENDPROC open packet ;
+
+PROC identify (TEXT CONST name, LIB VAR packet, BOOL VAR packet exists) :
+ to packet (name) ;
+ packet exists := found ;
+ IF found THEN packet.name := name ;
+ packet.nt link := nt link ;
+ packet.pt link := packet link ;
+ get pbas (packet.base)
+ FI
+ENDPROC identify ;
+
+
+ (***** Hash/Namenstabelle *****)
+.
+next hash entry :
+ hash table pointer INCR wordlength .
+
+end of hash table reached :
+ hash table pointer > end of hash table .
+
+yet another nt entry :
+ nt link := cdb int (nt link) ;
+ nt link <> 0 . ;
+
+PROC declare object (TEXT CONST name, INT VAR nt link, pt pointer) :
+ EXTERNAL 10031
+ENDPROC declare object ;
+
+PROC to object (TEXT CONST searched object) :
+ hash ;
+ search nt entry .
+
+hash :
+ hash code := 0 ;
+ FOR index FROM 1 UPTO LENGTH searched object REP
+ addmult cyclic
+ ENDREP .
+
+addmult cyclic :
+ hash code INCR hash code ;
+ IF hash code > end of hash table THEN wrap around FI ;
+ hash code := (hash code + code (searched object SUB index)) MOD 1024 .
+
+wrap around :
+ hash code DECR end of hash table .
+
+hash code : nt link .
+
+search nt entry :
+ found := FALSE ;
+ WHILE yet another nt entry REP
+ read current entry ;
+ IF object name = searched object
+ THEN found := TRUE ;
+ LEAVE to object
+ FI
+ PER .
+
+read current entry :
+ permanent pointer := cdb int (nt link + wordlength) ;
+ object name := cdb text (nt link + two word length)
+ENDPROC to object ;
+
+
+ (***** Permanent Tabelle *****)
+.
+next procedure :
+ permanent pointer := cdb int (permanent pointer) . ;
+
+PROC next pt param :
+ mode := cdb int (param link) MOD ptt limit ;
+ param link INCR wordlength ;
+ IF mode = permanent row THEN skip over permanent row
+ ELIF mode = permanent struct THEN skip over permanent struct
+ FI ;
+ set end marker if end of list .
+
+skip over permanent row :
+ param link INCR wordlength ;
+ next pt param .
+
+skip over permanent struct :
+ REP
+ mode := cdb int (param link) ;
+ IF mode = permanent type field
+ THEN param link INCR wordlength ;
+ LEAVE skip over permanent struct
+ FI ;
+ next pt param
+ PER
+ENDPROC next pt param ;
+
+PROC set end marker if end of list :
+ mode := cdb int (param link) ;
+ end of params := mode >= permanent proc op OR mode <= 0
+ENDPROC set end marker if end of list ;
+
+PROC get type and mode (INT VAR type) :
+ mode := cdb int (param link) ;
+ IF mode < 0 THEN type := 2769 + (32767 + mode) ;
+ mode := 0
+ ELIF mode = permanent param proc THEN translate type
+ ELSE type := mode MOD ptt limit ;
+ mode DECR type ;
+ translate type if necessary ;
+ translate mode if necessary
+ FI .
+
+translate type if necessary :
+ IF permanent row or struct THEN translate type FI .
+
+translate type :
+ type := param link - begin of pt minus ptt limit .
+
+translate mode if necessary :
+ IF mode = permanent param const THEN mode := const
+ ELIF mode = permanent param var THEN mode := var
+ FI .
+
+permanent row or struct :
+ type = permanent row OR type = permanent struct
+ENDPROC get type and mode ;
+
+PROC put next permanent (INT CONST permanent value) :
+ EXTERNAL 10020
+ENDPROC put next permanent ;
+
+
+ (***** Allgemeine Zugriffsprozeduren *****)
+
+INT PROC cdb int (INT CONST index) :
+ EXTERNAL 116
+ENDPROC cdb int ;
+
+TEXT PROC cdb text (INT CONST index) :
+ EXTERNAL 117
+ENDPROC cdb text ;
+
+
+#page#
+(**************************************************************************)
+(* *)
+(* 2. Spruenge und Marken 07.10.1986 *)
+(* *)
+(* Definition des Datentyps LABEL *)
+(* *)
+(* Deklaration, Definition und Applikation von Marken *)
+(* *)
+(**************************************************************************)
+
+
+
+TYPE LABEL = INT ;
+
+BOOL VAR invers :: FALSE ;
+
+PROC declare (LABEL VAR label) :
+ CONCR (label) := 0
+ENDPROC declare ;
+
+PROC define (LABEL VAR label) :
+ EXTERNAL 10085
+ENDPROC define ;
+
+PROC complement condition code :
+ invers := NOT invers
+ENDPROC complement condition code ;
+
+PROC apply (LABEL VAR label) :
+ EXTERNAL 10151
+ENDPROC apply ;
+
+PROC apply (LABEL VAR label, BOOL CONST condition) :
+ IF condition xor invers THEN branch true (label)
+ ELSE branch false (label)
+ FI ;
+ invers := FALSE .
+
+condition xor invers :
+ IF condition THEN NOT invers
+ ELSE invers
+ FI
+ENDPROC apply ;
+
+OP := (LABEL VAR global label, local label) : (* EQUATE ! *)
+ EXTERNAL 10014
+ENDOP := ;
+
+TEXT PROC dump (LABEL CONST label) :
+ "LAB " + text (CONCR (label))
+ENDPROC dump ;
+
+PROC gosub (LABEL VAR label) :
+ EXTERNAL 10015
+ENDPROC gosub ;
+
+PROC goret :
+ s0 (q goret code)
+ENDPROC goret ;
+
+PROC branch true (LABEL VAR label) :
+ EXTERNAL 10028
+ENDPROC branch true ;
+
+PROC branch false (LABEL VAR label) :
+ EXTERNAL 10029
+ENDPROC branch false ;
+
+PROC computed branch (ADDRESS CONST switch, INT CONST limit, LABEL VAR out) :
+ s1 (q esc case, REPR switch) ;
+ s0 (limit) ;
+ branch false (out)
+ENDPROC computed branch ;
+
+
+#page#
+(**************************************************************************)
+(* *)
+(* 3. Datenaddressen 13.11.1986 *)
+(* *)
+(* Definition des Datentyps ADDRESS *)
+(* *)
+(* Aufbau von Datenaddressen (Vercodung) *)
+(* Fortschalten und Ausrichten von Adressen *)
+(* Behandlung von Paketbasis-Adressen *)
+(* Bereitstellen der Fehlermeldung "address overflow" (Coder-intern) *)
+(* *)
+(**************************************************************************)
+
+
+
+TYPE ADDRESS = STRUCT (INT kind, value) ;
+
+LET global = 0 ,
+ local = 1 ,
+ ref mask = 2 ,
+ global ref = 2 ,
+ local ref = 3 ,
+ module nr = 4 ,
+ immediate value = 5 ,
+ p base = 6 ,
+
+ eumel0 stack offset = 4 ,
+ local address limit = 16 384 ,
+ global address zero = 0 ,
+
+ illegal ref operation = "REF not allowed" ,
+ deref on non ref = "DEREF on non-ref address" ,
+ global ref not allowed = "GLOBAL REF not allowed" ,
+ unknown kind = "Unknown address kind" ,
+ address overflow = "Address Overflow" ,
+ illegal plus operation = "+ not allowed" ;
+
+ADDRESS VAR result addr;
+
+INT CONST ref length :: 2 ;
+
+OP := (ADDRESS VAR l, ADDRESS CONST r) :
+ CONCR (l) := CONCR (r)
+ENDOP := ;
+
+ADDRESS OP GLOB (INT CONST address level) :
+ result addr.kind := global ;
+ result addr.value := address level ;
+ IF memory management mode = data allocation by user
+ THEN result addr.value INCR global address offset
+ FI ;
+ result addr
+ENDOP GLOB ;
+
+ADDRESS OP LOC (INT CONST address level) :
+ result addr.kind := local ;
+ result addr.value := address level + eumel0 stack offset ;
+ result addr
+ENDOP LOC ;
+
+ADDRESS OP REF (ADDRESS CONST addr) :
+ CONCR (result addr) := CONCR (addr) ;
+ IF result addr.kind = local THEN result addr.kind INCR ref mask
+ ELIF result addr.kind = global THEN errorstop (global ref not allowed)
+ ELSE errorstop (illegal ref operation)
+ FI ;
+ result addr
+ENDOP REF ;
+
+ADDRESS OP DEREF (ADDRESS CONST ref address) :
+ CONCR (result addr) := CONCR (ref address) ;
+ IF is not local ref THEN errorstop (deref on non ref) FI ;
+ result addr.kind DECR ref mask ;
+ result addr .
+
+is not local ref :
+ result addr.kind <> local ref
+ENDOP DEREF ;
+
+INT OP REPR (ADDRESS CONST addr) :
+ CONCR (result addr) := CONCR (addr) ;
+ SELECT result addr.kind OF
+ CASE global :
+ CASE local : set bit (result addr.value, 15)
+ CASE global ref : errorstop (global ref not allowed)
+ CASE local ref : prep local ref
+ OTHERWISE errorstop (unknown kind)
+ ENDSELECT ;
+ result addr.value .
+
+prep local ref :
+ IF address limit exceeded THEN errorstop (address overflow) FI ;
+ set bit (result addr.value, 14) ;
+ set bit (result addr.value, 15) .
+
+address limit exceeded :
+ result addr.value < eumel0 stack offset OR
+ result addr.value > local address limit
+ENDOP REPR ;
+
+PROC get base (LIB CONST packet, ADDRESS VAR base) :
+ CONCR (base) := CONCR (packet.base)
+ENDPROC get base ;
+
+PROC set to actual base (LIB VAR packet) :
+ packet.base.kind := p base ;
+ packet.base.value := packet base
+ENDPROC set to actual base ;
+
+PROC get pbas (ADDRESS VAR base) :
+ base.kind := p base ;
+ base.value := cdbint (packet link + 2)
+ENDPROC get pbas ;
+
+BOOL OP = (ADDRESS CONST l,r) :
+ l.kind = r.kind AND l.value = r.value
+ENDOP = ;
+
+BOOL PROC is ref (ADDRESS CONST addr) :
+ addr.kind = local ref
+ENDPROC is ref ;
+
+BOOL PROC is global (ADDRESS CONST addr) :
+ addr.kind = global
+ENDPROC is global ;
+
+BOOL PROC is local (ADDRESS CONST addr) :
+ addr.kind = local
+ENDPROC is local ;
+
+ADDRESS OP + (ADDRESS CONST addr, INT CONST offset) :
+ CONCR (result addr) := CONCR (addr) ;
+ SELECT result addr.kind OF
+ CASE global : inc global
+ CASE local : inc local
+ OTHERWISE errorstop (illegal plus operation)
+ ENDSELECT ;
+ result addr .
+
+inc global :
+ result addr.value INCR offset ;
+ IF result addr.value < 0 THEN errorstop (address overflow) FI .
+
+inc local :
+ result addr.value INCR offset ;
+ IF result addr.value < eumel 0 stack offset OR
+ result addr.value > local address limit
+ THEN errorstop (address overflow)
+ FI
+ENDOP + ;
+
+PROC adjust (ADDRESS VAR addr, INT CONST adjust length) :
+ IF is local or global THEN adjust to length FI .
+
+is local or global :
+ addr.kind <= local .
+
+adjust to length :
+ mode := addr.value MOD adjust length ;
+ IF mode <> 0 THEN addr.value INCR (adjust length-mode) FI
+ENDPROC adjust ;
+
+TEXT PROC dump (ADDRESS CONST addr) :
+ kind + text (addr.value) .
+
+kind :
+ SELECT addr.kind OF
+ CASE global : "GLOBAL "
+ CASE local : "LOCAL "
+ CASE immediate value : "IMMEDIATE "
+ CASE module nr : "PARAM PROC "
+ CASE global ref : "GLOBAL REF "
+ CASE local ref : "LOCAL REF "
+ CASE p base : "PBAS "
+ OTHERWISE "undef. Addr: "
+ ENDSELECT
+ENDPROC dump;
+
+
+#page#
+(**************************************************************************)
+(* *)
+(* 4. Datentypen Teil I 08.09.1986 *)
+(* *)
+(* Definition des Datentyps DTYPE *)
+(* *)
+(* Interne Repraesentation der primitiven Datentypen *)
+(* Identifikation von DTYPEs *)
+(* *)
+(**************************************************************************)
+
+
+
+TYPE DTYPE = INT ;
+
+OP := (DTYPE VAR l, DTYPE CONST r) :
+ CONCR (l) := CONCR (r)
+ENDOP := ;
+
+BOOL OP = (DTYPE CONST l, r) :
+ CONCR (l) = CONCR (r)
+ENDOP = ;
+
+DTYPE PROC void type : DTYPE :(void id) ENDPROC void type ;
+
+DTYPE PROC int type : DTYPE :(int id) ENDPROC int type ;
+
+DTYPE PROC real type : DTYPE :(real id) ENDPROC real type ;
+
+DTYPE PROC text type : DTYPE :(string id) ENDPROC text type ;
+
+DTYPE PROC bool type : DTYPE :(bool id) ENDPROC bool type ;
+
+DTYPE PROC bool result type : DTYPE :(bool result id) ENDPROC bool result type;
+
+DTYPE PROC dataspace type : DTYPE :(dataspace id) ENDPROC dataspace type ;
+
+DTYPE PROC undefined type : DTYPE :(undefined id) ENDPROC undefined type ;
+
+DTYPE PROC row type : DTYPE :(row id) ENDPROC row type ;
+
+DTYPE PROC struct type : DTYPE :(struct id) ENDPROC struct type ;
+
+DTYPE PROC proc type : DTYPE :(permanent param proc) ENDPROC proc type ;
+
+DTYPE PROC end type : DTYPE :(end id) ENDPROC end type ;
+
+INT PROC type class (DTYPE CONST type) :
+ SELECT type id OF
+ CASE int id, real id, bool id, bool result id, string id,
+ dataspace id, undefined id : 1
+ CASE void id : 0
+ CASE row id : 3
+ CASE struct id : 4
+ CASE permanent param proc : 5
+ OTHERWISE pt type
+ ENDSELECT .
+
+pt type :
+ IF type id > ptt limit THEN permanent row or struct
+ ELSE abstract type
+ FI .
+
+abstract type : 2 .
+
+permanent row or struct :
+ unsigned arithmetic ;
+ mode := cdbint (type link into pt) MOD ptt limit ;
+ IF mode = struct id THEN 4
+ ELIF mode = row id THEN 3
+ ELIF mode = permanent param proc THEN 5
+ ELSE 2
+ FI .
+
+type link into pt :
+ type id + begin of pt minus ptt limit .
+
+type id : CONCR (type)
+ENDPROC type class ;
+
+PROC identify (TEXT CONST name,INT VAR size, align, DTYPE VAR type) :
+ SELECT type pos OF
+ CASE 1 : size := 0; align := 0; type id := void id
+ CASE 6 : size := 1; align := 1; type id := int id
+ CASE 10 : size := 4; align := 4; type id := real id
+ CASE 15 : size := 8; align := 4; type id := string id
+ CASE 20 : size := 1; align := 1; type id := bool id
+ CASE 25 : size := 1; align := 1; type id := dataspace id
+ OTHERWISE search for type in permanent table
+ ENDSELECT .
+
+type pos :
+ enclose in delimiters ;
+ pos (".VOID.INT.REAL.TEXT.BOOL.DATASPACE.", object name) .
+
+enclose in delimiters :
+ object name := "." ;
+ object name CAT name ;
+ object name CAT "." .
+
+search for type in permanent table :
+ to object (name) ;
+ IF not found THEN size := 0; align := 0; type id := undefined id
+ ELSE size := cdbint (permanent pointer + two wordlength) ;
+ type id := permanent pointer - begin of permanent table ;
+ IF size < two wordlength THEN align := 1
+ ELIF size < four wordlength THEN align := 2
+ ELSE align := 4
+ FI
+ FI .
+
+not found :
+ NOT found OR invalid entry .
+
+invalid entry :
+ permanent pointer = 0 OR
+ cdb int (permanent pointer + wordlength) <> permanent type .
+
+type id : CONCR (type)
+ENDPROC identify ;
+
+
+#page#
+(**************************************************************************)
+(* *)
+(* 5. Operationen Teil I 30.09.1986 *)
+(* *)
+(* Definition des Datentyps OPN *)
+(* Primitive Operationen (:= etc.) *)
+(* Initialisieren mit den externen Namen der EUMEL-0-Codes *)
+(* Bereitstellen dee Fehlermeldung 'proc op expected' (coder-intern) *)
+(* *)
+(**************************************************************************)
+
+
+TYPE OPN = STRUCT (INT kind, mod nr, top of stack) ;
+
+LET proc op = 0 ,
+ param proc = 1 ,
+ eumel 0 = 2 ,
+ nil = 3 ,
+
+ param proc at non ref = "PARAM PROC at non-ref address" ,
+ proc op expected = "PROC expected" ;
+
+OPN VAR eumel0 opn;
+eumel0 opn.kind := eumel0 ;
+eumel0 opn.top of stack := 0 ;
+
+eumel0 opn.mod nr := q pp ;
+OPN CONST pp :: eumel0 opn ,
+ nop code :: OPN :(nil, 0, 0) ;
+
+IF NOT exists ("eumel0 codes")
+ THEN IF yes ("Archive 'eumel coder' eingelegt")
+ THEN archive ("eumel coder") ;
+ fetch ("eumel0 codes", archive) ;
+ release (archive)
+ ELSE errorstop ("""eumel0 codes"" gibt es nicht")
+ FI
+FI ;
+BOUND THESAURUS VAR initial opcodes :: old ("eumel0 codes") ;
+THESAURUS VAR eumel 0 opcodes :: initial opcodes ;
+forget ("eumel0 codes") ;
+
+ADDRESS PROC address (OPN CONST opn) :
+ IF opn.kind <> proc op THEN errorstop (proc op expected) FI ;
+ result addr.kind := module nr ;
+ result addr.value := opn.mod nr ;
+ result addr
+ENDPROC address ;
+
+OPN PROC operation (ADDRESS CONST addr) :
+ IF addr.kind <> local ref THEN errorstop (param proc at non ref) FI ;
+ OPN VAR opn ;
+ opn.kind := param proc ;
+ opn.mod nr :=addr.value ;
+ opn.top of stack := 0 ;
+ opn
+ENDPROC operation ;
+
+TEXT PROC mnemonic (OPN CONST op code) :
+ name (eumel 0 opcodes, op code.mod nr)
+ENDPROC mnemonic ;
+
+OPN PROC nop :
+ nop code
+ENDPROC nop ;
+
+OP := (OPN VAR r, OPN CONST l) :
+ CONCR (r) := CONCR (l)
+ENDOP := ;
+
+BOOL PROC is proc (OPN CONST operation) :
+ operation.kind = proc op
+ENDPROC is proc ;
+
+BOOL PROC is eumel 0 instruction (TEXT CONST op code name) :
+ link (eumel 0 opcodes, op code name) <> 0
+ENDPROC is eumel 0 instruction ;
+
+BOOL PROC is eumel 0 instruction (OPN CONST operation) :
+ operation.kind = eumel0
+ENDPROC is eumel 0 instruction ;
+
+
+#page#
+(**************************************************************************)
+(* *)
+(* 6. Parameterfeld 10.04.1986 *)
+(* *)
+(* Bereitstellen des Parameterfeldes *)
+(* Schreiben und Lesen von Eintraegen im Parameterfeld *)
+(* Fortschalten von Zeigern in das Parameterfeld *)
+(* Bereitstellen der Konstanten 'size of param field' (Coder-intern) *)
+(* *)
+(**************************************************************************)
+
+
+
+LET PARAMDESCRIPTOR = STRUCT (DTYPE type, INT access,
+ ADDRESS addr, OPN push opn) ,
+
+ size of param field = 100 ,
+ param field exceeded = "Param Field Overflow",
+ param nr out of range = "Illegal Param Number" ;
+
+ROW size of param field PARAMDESCRIPTOR VAR param field ;
+
+
+ (***** Schreiben *****)
+
+PROC test param pos (INT CONST param nr) :
+ IF param nr < 1 OR param nr > size of param field
+ THEN errorstop (param nr out of range)
+ FI
+ENDPROC test param pos ;
+
+PROC declare (INT CONST param nr, DTYPE CONST type) :
+ test param pos (param nr) ;
+ enter type .
+
+enter type :
+ CONCR (param field [param nr].type) := CONCR (type)
+ENDPROC declare ;
+
+PROC declare (INT CONST param nr, access) :
+ test param pos (param nr) ;
+ enter access .
+
+enter access :
+ param field [param nr].access := access
+ENDPROC declare ;
+
+PROC define (INT CONST param nr, ADDRESS CONST addr) :
+ test param pos (param nr) ;
+ enter address .
+
+enter address :
+ CONCR (param field [param nr].addr) := CONCR (addr)
+ENDPROC define ;
+
+PROC define (INT CONST param nr, value) :
+ result addr.kind := immediate value ;
+ result addr.value := value ;
+ define (param nr, result addr)
+ENDPROC define ;
+
+PROC apply (INT CONST param nr, OPN CONST opn) :
+ test param pos (param nr) ;
+ enter push opn .
+
+enter push opn :
+ CONCR (param field [param nr].push opn) := CONCR (opn)
+ENDPROC apply ;
+
+PROC parameter (INT CONST param nr, DTYPE CONST type,
+ INT CONST access, ADDRESS CONST addr) :
+ test param pos (param nr) ;
+ enter type ;
+ enter access ;
+ enter address ;
+ enter pp as default .
+
+enter type :
+ CONCR (param field [param nr].type) := CONCR (type) .
+
+enter access :
+ param field [param nr].access := access .
+
+enter address :
+ CONCR (param field [param nr].addr) := CONCR (addr) .
+
+enter pp as default :
+ CONCR (param field [param nr].push opn) := CONCR (pp)
+ENDPROC parameter ;
+
+
+ (***** Lesen *****)
+
+ADDRESS PROC param address (INT CONST param nr) :
+ test param pos (param nr) ;
+ param field [param nr].addr
+ENDPROC param address ;
+
+DTYPE PROC dtype (INT CONST param nr) :
+ test param pos (param nr) ;
+ param field [param nr].type
+ENDPROC dtype ;
+
+INT PROC access (INT CONST param nr) :
+ test param pos (param nr) ;
+ param field [param nr].access
+ENDPROC access ;
+
+
+ (***** Fortschalten *****)
+
+OP NEXTPARAM (INT VAR param nr) :
+ test param pos (param nr) ;
+ INT CONST class :: type class (param field [param nr].type) ;
+ param nr INCR 1 ;
+ SELECT class OF
+ CASE 3 : NEXTPARAM param nr
+ CASE 4,5 : read until end
+ ENDSELECT .
+
+read until end :
+ WHILE NOT end marker read or end of field REP
+ NEXTPARAM param nr
+ PER ;
+ param nr INCR 1 .
+
+end marker read or end of field :
+ param nr > size of param field OR
+ CONCR (param field [param nr].type) = end id
+ENDOP NEXTPARAM ;
+
+INT PROC next param (INT CONST p) :
+ INT VAR index := p ;
+ NEXTPARAM index ;
+ index
+ENDPROC next param ;
+
+TEXT PROC dump (INT CONST p) :
+ IF p > 0 AND p <= 100 THEN dump entry (param field (p))
+ ELSE param nr out of range
+ FI
+ENDPROC dump ;
+
+TEXT PROC dump entry (PARAMDESCRIPTOR CONST id) :
+(* object name := dump (id.type) ; *)
+ object name := "TYPE " ; (* siehe *)
+ object name CAT dump (id.type) ; (* TEXT PROC dump (DTYPE d) *)
+ object name CAT text (id.access) ;
+ object name CAT dump (id.addr) ;
+ object name CAT dump (id.push opn) ;
+ object name
+ENDPROC dump entry ;
+
+
+#page#
+(**************************************************************************)
+(* *)
+(* 7. Datentypen Teil II 08.09.1986 *)
+(* *)
+(* Deklaration neuer Datentypen *)
+(* Vergleich von DTYPEs im Parameterfeld und in der Permanent-Tabelle *)
+(* *)
+(**************************************************************************)
+
+
+
+DTYPE VAR pt type ;
+
+PROC declare (TEXT CONST name, INT CONST size, align, DTYPE VAR type) :
+ entry into name table ;
+ put next permanent (permanent type) ;
+ put next permanent (size) ;
+ put next permanent (nt link) ;
+ mark no offsets of text elements .
+
+entry into name table :
+ declare object (name, nt link, CONCR (type)) ;
+ CONCR (type) DECR begin of permanent table .
+
+mark no offsets of text elements :
+ put next permanent (0)
+ENDPROC declare ;
+
+BOOL PROC same type (INT CONST param 1, param 2) :
+ INT CONST left type :: CONCR (param field [param 1].type) ;
+ IF left type = right type
+ THEN same fine structure if there is one
+ ELSE left type = undefined id OR right type = undefined id
+ FI .
+
+right type : CONCR (param field [param 2].type) .
+
+same fine structure if there is one :
+ IF left type = row id THEN compare row
+ ELIF left is struct or proc THEN compare struct
+ ELSE TRUE
+ FI .
+
+left is struct or proc :
+ left type = struct id OR left type = proc id .
+
+compare row :
+ equal sizes AND same type (param1 + 1, param2 + 1) .
+
+equal sizes :
+ param field [param1+1].access = param field [param2+1].access .
+
+compare struct :
+ INT VAR p1 :: param1+1, p2 :: param2+1 ;
+ WHILE same type (p1, p2) AND NOT end type found REP
+ NEXTPARAM p1 ;
+ NEXTPARAM p2
+ UNTIL end of field PER ;
+ FALSE .
+
+end type found :
+ CONCR (param field [p1].type) = end id .
+
+end of field :
+ p1 > size of param field OR p2 > size of param field
+ENDPROC same type ;
+
+BOOL PROC same type (INT CONST param nr, DTYPE CONST type) :
+ field pointer := param nr ;
+ CONCR (pt type) := CONCR (type) ;
+ equal types
+ENDPROC same type ;
+
+BOOL PROC equal types :
+ identical types OR one type is undefined .
+
+one type is undefined :
+ type of actual field = undefined id OR CONCR(pt type) = undefined id .
+
+identical types :
+ SELECT type class (pt type) OF
+ CASE 0, 1, 2 : type of actual field = CONCR (pt type)
+ CASE 3 : perhaps equal rows
+ CASE 4 : perhaps equal structs
+ CASE 5 : perhaps equal param procs
+ OTHERWISE FALSE
+ ENDSELECT .
+
+perhaps equal rows :
+ param link := CONCR (pt type) + begin of pt minus ptt limit ;
+ is row AND equal row sizes AND equal row types .
+
+is row :
+ type of actual field = row id .
+
+perhaps equal structs :
+ param link := CONCR (pt type) + begin of pt minus ptt limit ;
+ is struct AND same type fields .
+
+is struct :
+ type of actual field = struct id .
+
+equal row sizes :
+ pt row size = row size within param field .
+
+equal row types :
+ field pointer INCR 1 ;
+ param link INCR 2 ;
+ get type and mode (CONCR(pt type)) ;
+ equal types .
+
+pt row size :
+ cdb int (param link + 1) .
+
+row size within param field :
+ param field [field pointer + 1].access .
+
+same type fields :
+ REP
+ field pointer INCR 1 ;
+ param link INCR 1 ;
+ IF type of actual field = end id
+ THEN LEAVE same type fields WITH pt struct end reached
+ FI ;
+ get type and mode (CONCR(pt type)) ;
+ IF NOT equal types THEN LEAVE same type fields WITH FALSE FI
+ UNTIL end of field PER ;
+ FALSE .
+
+pt struct end reached :
+ cdbint (param link) = permanent type field .
+
+end of field :
+ field pointer > size of param field .
+
+type of actual field :
+ CONCR (param field [field pointer].type) .
+
+perhaps equal param procs :
+ param link := CONCR (pt type) + begin of pt minus ptt limit ;
+ is proc AND same param list .
+
+is proc : cdbint (param link) = permanent param proc .
+
+same param list :
+ param link INCR wordlength ;
+ DTYPE VAR proc result type ;
+ get type and mode (CONCR (proc result type)) ;
+ compare param list ;
+ check results .
+
+compare param list :
+ INT VAR last param := field pointer + 1 ;
+ REP
+ field pointer INCR 1 ;
+ param link INCR wordlength ;
+ IF pt param list exhausted THEN LEAVE compare param list FI ;
+ IF type of actual field = end id
+ THEN LEAVE equal types WITH FALSE
+ FI ;
+ get type and mode (CONCR(pt type)) ;
+ last param := field pointer ;
+ UNTIL NOT equal types OR end of field PER .
+
+check results :
+ pt param list exhausted AND equal result types .
+
+equal result types :
+ save param link ;
+ IF same type (last param, proc result type)
+ THEN restore ;
+ TRUE
+ ELSE FALSE
+ FI .
+
+pt param list exhausted :
+ cdbint (param link) = permanent param proc end marker .
+
+save param link :
+ INT CONST p :: param link .
+
+restore :
+ field pointer INCR 1 ;
+ param link := p
+
+ENDPROC equal types ;
+
+BOOL PROC is not void bool or undefined (DTYPE CONST dtype) :
+ type <> void id AND type <> bool result id AND type <> undefined id .
+
+type : CONCR (dtype)
+ENDPROC is not void bool or undefined ;
+
+
+#page#
+(**************************************************************************)
+(* *)
+(* 8. Operationen Teil II 08.09.1986 *)
+(* *)
+(* Definition der Opcodes *)
+(* Deklaration, Definition, Identifikation und Applikation *)
+(* Eroeffnen und Schliessen eines Moduls *)
+(* *)
+(**************************************************************************)
+
+
+
+LET module not opened = "Module not opened" ,
+ define missing = "DEFINE missing" ,
+ wrong nr of params = "Wrong Nr. of Params:" ,
+ illegal kind = "Opcode expected" ,
+ nested module = "Nested Modules" ,
+ no mod nr = "Param Proc expected" ,
+ no immediate value = "Value expected" ,
+ type error = "Type Error" ,
+
+ q ln = 1 ,
+ q move = 2 , q move code = 2 048 ,
+ q inc1 = 3 , q inc1 code = 3 072 ,
+ q dec1 = 4 , q dec1 code = 4 096 ,
+ q inc = 5 , q inc code = 5 120 ,
+ q dec = 6 , q dec code = 6 144 ,
+ q add = 7 , q add code = 7 168 ,
+ q sub = 8 , q sub code = 8 192 ,
+ q clear = 9 , q clear code = 9 216 ,
+ q test = 10 ,
+ q equ = 11 , q equ code = 11 264 ,
+ q lsequ = 12 , q lsequ code = 12 288 ,
+ q fmove = 13 , q fmove code = 13 312 ,
+ q fadd = 14 , q fadd code = 14 336 ,
+ q fsub = 15 , q fsub code = 15 360 ,
+ q fmult = 16 , q fmult code = 16 384 ,
+ q fdiv = 17 , q fdiv code = 17 408 ,
+ q flsequ = 18 , q flsequ code = 18 432 ,
+ q tmove = 19 , q tmove code = 19 456 ,
+ q tequ = 20 , q tequ code = 20 480 ,
+ q accds = 21 , q access ds code = 22 528 ,
+ q ref = 22 , q ref code = 23 552 ,
+ q subscript = 23 , q subscript code = 24 576 ,
+ q select = 24 , q select code = 25 600 ,
+ q ppv = 25 , q ppv code = 26 624 ,
+ q pp = 26 ,
+ q make false = 27 , (* q make false code = 65 513 *)
+ q movex = 28 ,
+(* q longa subs q longa subs code = 65 376 *)
+ q return = 29 , q return code = 32 512 ,
+ q true return = 30 , q true return code = 32 513 ,
+ q false return = 31 , q false return code = 32 514 ,
+ q goret code = 32 519 ,
+ q esc mult = 32 , q esc mult code = 32 553 ,
+ q esc div = 33 , q esc div code = 32 554 ,
+ q esc mod = 34 , q esc mod code = 32 555 ,
+ q pproc = 35 ,
+ q compl int = 36 , q compl int code = 32 551 ,
+ q compl real = 37 , q compl real code = 32 550 ,
+ q alias ds = 38 , q alias ds code = 32 546 ,
+ q movim = 39 , q esc movim code = 32 547 ,
+ q fequ = 40 , q fequ code = 32 548 ,
+ q tlsequ = 41 , q tlsequ code = 32 549 ,
+(* q case = 42 , *) q esc case = 32 544 ,
+ q plus = 43 ,
+ q minus = 44 ,
+ q mult = 45 ,
+ q int div = 46 ,
+ q real div = 47 ,
+ q equal = 48 ,
+ q lessequal = 49 ,
+ q ulseq = 50 , q ulseq code = 21 504 ,
+ q pdadd = 51 , q pdadd code = 32 653 ,
+ q ppsub = 52 , q ppsub code = 32 654 ,
+ q dimov = 53 , q dimov code = 32 655 ,
+ q idmov = 54 , q idmov code = 32 656 ;
+
+INT CONST q make false code :: - 1 022 ,
+ q longa subs code :: - 159 ,
+ q penter code :: - 511 ;
+
+
+ (***** Deklaration *****)
+
+PROC declare (OPN VAR operation) :
+ operation.kind := proc op ;
+ get module nr (operation.mod nr) ;
+ operation.top of stack := 0
+ENDPROC declare ;
+
+PROC declare (TEXT CONST name, INT CONST first, params, OPN VAR operation) :
+ declare (operation) ;
+ entry into name and pt table if necessary ;
+ enter params ;
+ enter result ;
+ enter module number .
+
+entry into name and pt table if necessary :
+ declare object (name, nt link, permanent pointer) .
+
+enter params :
+ field pointer := first ;
+ FOR index FROM 1 UPTO params REP
+ enter param (param field [field pointer]) ;
+ NEXTPARAM field pointer
+ PER .
+
+enter result :
+ enter param (param field[field pointer].type, permanent proc op) .
+
+enter module number :
+ put next permanent (operation.mod nr)
+ENDPROC declare ;
+
+PROC enter param (PARAMDESCRIPTOR CONST param) :
+ IF param.access = const
+ THEN enter param (param.type, permanent param const)
+ ELIF param.access = var
+ THEN enter param (param.type, permanent param var)
+ ELSE errorstop ("Unknown Access")
+ FI
+ENDPROC enter param ;
+
+PROC enter param (DTYPE CONST type, INT CONST permanent mode) :
+ unsigned arithmetic ;
+ SELECT type class (type) OF
+ CASE 0, 1, 2 : put next permanent (CONCR(type) + permanent mode)
+ OTHERWISE errorstop ("Illegal Type")
+ ENDSELECT
+ENDPROC enter param ;
+
+
+ (***** Definition *****)
+
+PROC define (OPN VAR opn) :
+ IF NOT module open THEN errorstop (module not opened)
+ ELSE proc head (opn.mod nr, opn.top of stack)
+ FI
+ENDPROC define ;
+
+PROC set length of local storage (OPN VAR opn, INT CONST size) :
+ IF size < 0 OR size > local address limit
+ THEN errorstop (address overflow)
+ ELIF opn.top of stack = 0
+ THEN errorstop (define missing)
+ ELIF opn.kind <> proc op
+ THEN errorstop (proc op expected)
+ FI ;
+ set length (opn.top of stack, size + eumel0 stack offset)
+ENDPROC set length of local storage ;
+
+PROC define (OPN VAR operation, INT CONST size) :
+ define (operation) ;
+ set length of local storage (operation, size)
+ENDPROC define ;
+
+
+ (***** Identifikation *****)
+
+INT VAR counter, result index, result type repr;
+
+PROC identify (TEXT CONST name, INT CONST first, params, OPN VAR operation,
+ BOOL VAR object exists) :
+ find result entry ;
+ to object (name) ;
+ IF found THEN first fit and leave if found FI ;
+ IF eumel0 THEN identify eumel0 instruction
+ ELSE yield undefined operation
+ FI .
+
+find result entry :
+ result index := first;
+ counter := 0 ;
+ WHILE counter < params REP
+ NEXTPARAM result index ;
+ counter INCR 1
+ PER ;
+ check on param field exceeded .
+
+check on param field exceeded :
+ IF result index > size of param field
+ THEN errorstop (param field exceeded)
+ FI .
+
+yield undefined operation :
+ declare (result index, undefined type) ;
+ apply (result index, nop) ;
+ object exists := FALSE .
+
+first fit and leave if found :
+ WHILE yet another procedure exists REP
+ check one procedure and leave if match ;
+ next procedure
+ PER .
+
+yet another procedure exists :
+ permanent pointer <> 0 .
+
+check one procedure and leave if match:
+ param link := permanent pointer + wordlength ;
+ set end marker if end of list ;
+ counter := params ;
+ field pointer := first ;
+ REP
+ IF end of params AND counter = 0
+ THEN procedure found
+ ELIF end of params OR counter = 0
+ THEN LEAVE check one procedure and leave if match
+ ELSE check next param
+ FI
+ PER .
+
+check next param :
+ get type and mode (CONCR(pt type)) ;
+ IF same types THEN set param mode ;
+ field pointer INCR 1 ;
+ param link INCR 1 ;
+ set end marker if end of list ;
+ counter DECR 1 ;
+ ELSE LEAVE check one procedure and leave if match
+ FI .
+
+same types : (* inline version ! *)
+ equal types .
+
+set param mode :
+ param field [field pointer].access := mode .
+
+procedure found :
+ get result ;
+ operation.kind := proc op ;
+ operation.mod nr := module number ;
+ operation.top of stack := 0 ;
+ object exists := TRUE ;
+ LEAVE identify .
+
+get result :
+ get type and mode (result type) ;
+ declare (result index, mode) .
+
+module number :
+ cdbint (param link + 1) .
+
+result type :
+ CONCR (param field [result index].type) .
+
+eumel0 :
+ eumel0 opn.mod nr := link (eumel 0 opcodes, name) ;
+ eumel0 opn.mod nr <> 0 .
+
+identify eumel 0 instruction :
+ init result type with void ;
+ CONCR (operation) := CONCR (eumel0 opn) ;
+ object exists := check params and set result ;
+ declare (result index, DTYPE:(result type repr)) ;
+ declare (result index, const) .
+
+init result type with void :
+ result type repr := void id .
+
+check params and set result :
+ SELECT operation.mod nr OF
+ CASE q return, q false return, q true return : no params
+ CASE q inc1, q dec1 : one int param yielding void
+ CASE q pproc, q pp, q ln : one param yielding void
+ CASE q test : one param yielding bool
+ CASE q clear, q ppv : one int or bool param yielding void
+ CASE q make false : one bool param yielding void
+ CASE q move : two int or bool params yielding void
+ CASE q compl int, q inc, q dec : two int params yielding void
+ CASE q compl real, q fmove : two real params yielding void
+ CASE q equ, q lsequ, q ulseq : two int params yielding bool
+ CASE q fequ, q flsequ : two real params yielding bool
+ CASE q tequ, q tlsequ : two text params yielding bool
+ CASE q tmove : two text params yielding void
+ CASE q accds, q ref, q movim,
+ q dimov, q idmov : two params yielding void
+ CASE q add, q sub, q esc mult,
+ q esc div, q esc mod : three int params yielding void
+ CASE q fadd, q fsub, q fmult, q fdiv : three real params yielding void
+ CASE q select, q movex, q alias ds,
+ q pdadd, q ppsub : three params
+ CASE q subscript : five params
+ CASE q plus, q mult : two intreals yielding intreal
+ CASE q minus : monadic or dyadic minus
+ CASE q int div : two int params yielding int
+ CASE q real div : two real params yielding real
+ CASE q equal, q lessequal : two intrealtexts yielding bool
+ OTHERWISE FALSE
+ ENDSELECT .
+
+no params :
+ params = 0 .
+
+one int param yielding void :
+ p1 void (int type, first, params) .
+
+one param yielding void :
+ params = 1 .
+
+one param yielding bool :
+ IF params = 1 THEN result type repr := bool id ;
+ TRUE
+ ELSE FALSE
+ FI .
+
+one int or bool param yielding void :
+ p1 void (int type, first, params) OR p1 void (bool type, first, params) .
+
+one bool param yielding void :
+ p1 void (bool type, first, params) .
+
+two int or bool params yielding void :
+ p2 (int type, first, params, void id) OR
+ p2 (bool type, first, params, void id) .
+
+two int params yielding void :
+ p2 (int type, first, params, void id) .
+
+two real params yielding void :
+ p2 (real type, first, params, void id) .
+
+two text params yielding void :
+ p2 (text type, first, params, void id) .
+
+two int params yielding bool :
+ p2 (int type, first, params, bool id) .
+
+two real params yielding bool :
+ p2 (real type, first, params, bool id) .
+
+two text params yielding bool :
+ p2 (text type, first, params, bool id) .
+
+two params yielding void :
+ params = 2 .
+
+three int params yielding void :
+ p3 void (int type, first, params) .
+
+three real params yielding void :
+ p3 void (real type, first, params) .
+
+three params :
+ params = 3 .
+
+five params :
+ params = 5 .
+
+two intreals yielding intreal :
+ two int params yielding int OR two real params yielding real .
+
+monadic or dyadic minus :
+ IF params = 2 THEN two intreals yielding intreal
+ ELIF params = 1 THEN monadic minus
+ ELSE FALSE
+ FI .
+
+monadic minus :
+ result type repr := CONCR (param field[first].type) ;
+ result type repr = int id OR result type repr = real id .
+
+two intrealtexts yielding bool :
+ two int params yielding bool OR two real params yielding bool OR
+ two text params yielding bool .
+
+two int params yielding int :
+ p2 (int type, first, params, int id) .
+
+two real params yielding real :
+ p2 (real type, first, params, real id)
+ENDPROC identify ;
+
+BOOL PROC p1 void (DTYPE CONST requested type, INT CONST first, param nr) :
+ param nr = 1 AND param type is requested plain type .
+
+param type is requested plain type :
+ CONCR (param field [first].type) = CONCR (requested type)
+
+ENDPROC p1 void ;
+
+BOOL PROC p2 (DTYPE CONST requested type, INT CONST first, param nr,
+ INT CONST result type) :
+ IF param nr = 2 AND param types equal requested plain type
+ THEN result type repr := result type ;
+ TRUE
+ ELSE FALSE
+ FI .
+
+param types equal requested plain type :
+ CONCR (param field [first] .type) = CONCR (requested type) AND
+ CONCR (param field [first+1].type) = CONCR (requested type)
+
+ENDPROC p2 ;
+
+BOOL PROC p3 void (DTYPE CONST requested type, INT CONST first, param nr) :
+ param nr = 3 AND param types ok .
+
+param types ok :
+ FOR index FROM first UPTO first+2 REP
+ IF different param types THEN LEAVE p3 void WITH FALSE FI
+ PER ;
+ TRUE .
+
+different param types :
+ CONCR (param field [index].type) <> CONCR (requested type)
+ENDPROC p3 void;
+
+
+ (***** Applikation *****)
+
+INT VAR address representation, left repr, right repr, result repr;
+
+PROC apply (INT CONST first, nr of params, OPN CONST opn) :
+ IF NOT module open THEN errorstop (module not opened) FI ;
+ SELECT opn.kind OF
+ CASE eumel 0 : generate eumel0 instruction
+ CASE proc op : call operation
+ CASE param proc : call param proc
+ CASE nil :
+ OTHERWISE errorstop (illegal kind)
+ ENDSELECT .
+
+call operation :
+ push params if necessary (first, nr of params, opn.mod nr) ;
+ call (opn.mod nr) .
+
+call param proc :
+ result addr.kind := local ref ;
+ result addr.value := opn.mod nr ;
+ INT CONST module nr := REPR result addr ;
+ push params if necessary (first, nr of params, module nr) ;
+ call param (module nr) .
+
+generate eumel0 instruction :
+ SELECT real nr of params OF
+ CASE 0 : p0 instruction
+ CASE 1 : apply p1 (opn, first addr)
+ CASE 2 : apply p2 (opn, first addr, second addr)
+ CASE 3 : apply p3 (opn, left type, first addr, second addr, third addr)
+ CASE 5 : subscript operation
+ OTHERWISE errorstop (wrong nr of params + text (nr of params))
+ ENDSELECT .
+
+real nr of params :
+ IF operator denotation THEN nr of params + 1
+ ELSE nr of params
+ FI .
+
+operator denotation :
+ opn.mod nr >= q plus AND opn.mod nr < q ulseq .
+
+p0 instruction :
+ IF opn.mod nr = q return THEN s0 (q return code)
+ ELIF opn.mod nr = q true return THEN s0 (q true return code)
+ ELIF opn.mod nr = q false return THEN s0 (q false return code)
+ ELSE errorstop (wrong nr of params +
+ mnemonic (opn))
+ FI .
+
+subscript operation :
+ IF opn.mod nr = q subscript
+ THEN subscription
+ ELSE errorstop (wrong nr of params + text (nr of params))
+ FI .
+
+subscription :
+ ADDRESS CONST element length :: param field [first+2].addr ,
+ limit :: param field [first+3].addr ;
+ check on immediates ;
+ IF element length.value < 1024
+ THEN s0 (q subscript code + element length.value)
+ ELSE s0 (q longa subs code) ;
+ s0 (element length.value)
+ FI ;
+ s3 (limit.value - 1, subs index, base addr, subs result) .
+
+check on immediates :
+ IF element length.kind <> immediate value OR
+ limit.kind <> immediate value
+ THEN errorstop (no immediate value)
+ FI .
+
+subs index : REPR param field [first+1].addr .
+
+base addr : REPR param field [first].addr .
+
+subs result : REPR param field [first+4].addr .
+
+first addr :
+ param field [first].addr .
+
+left type :
+ param field [first].type .
+
+second addr :
+ param field [nextparam (first)].addr .
+
+third addr :
+ param field [nextparam(nextparam(first))].addr
+ENDPROC apply ;
+
+PROC push params if necessary (INT CONST first, nr of params, mod nr) :
+ init param push (mod nr) ;
+ field pointer := first ;
+ IF nr of params > 0 THEN push params FI ;
+ push result if there is one .
+
+push params :
+ FOR index FROM 1 UPTO nr of params REP
+ apply p1 (push code, param addr) ;
+ NEXTPARAM field pointer
+ PER .
+
+push code :
+ param field [field pointer].push opn .
+
+param addr :
+ param field [field pointer].addr .
+
+push result if there is one :
+ IF push result necessary
+ THEN push result address (REPR param field [field pointer].addr)
+ FI .
+
+push result necessary :
+ param field [field pointer].push opn.kind <> nil AND
+ is not void bool or undefined (param field [field pointer].type)
+ENDPROC push params if necessary ;
+
+PROC apply p1 (OPN CONST opn, ADDRESS CONST addr) :
+ IF opn.mod nr = q ln THEN generate line number
+ ELIF opn.mod nr = q pproc THEN push module nr
+ ELSE gen p1 instruction
+ FI .
+
+gen p1 instruction :
+ address representation := REPR addr ;
+ SELECT opn.mod nr OF
+ CASE q inc1 : t1 (q inc1 code, address representation)
+ CASE q dec1 : t1 (q dec1 code, address representation)
+ CASE q clear : t1 (q clear code,address representation)
+ CASE q test : test bool object (address representation)
+ CASE q pp : push param (address representation)
+ CASE q ppv : s1 (q ppv code, address representation)
+ CASE q make false : s1 (q make false code, address representation)
+ OTHERWISE errorstop (wrong nr of params + mnemonic (opn))
+ ENDSELECT .
+
+generate line number :
+ IF addr.kind = immediate value THEN mark line (addr.value)
+ ELSE errorstop (no immediate value)
+ FI .
+
+push module nr :
+ IF addr.kind = module nr THEN push param proc (addr.value)
+ ELSE errorstop (no mod nr)
+ FI
+ENDPROC apply p1;
+
+PROC apply p2 (OPN CONST opn, ADDRESS CONST left addr, right addr):
+ left repr := REPR left addr ;
+ IF opn.mod nr = q movim THEN move immediate
+ ELSE gen p2 instruction
+ FI .
+
+gen p2 instruction :
+ right repr := REPR right addr ;
+ SELECT opn.mod nr OF
+ CASE q move : t2 (q move code, right repr, left repr)
+ CASE q inc : t2 (q inc code, right repr, left repr)
+ CASE q dec : t2 (q dec code, right repr, left repr)
+ CASE q equ : compare (q equ code, left repr, right repr)
+ CASE q lsequ : compare (q lsequ code, left repr, right repr)
+ CASE q ulseq : compare (q ulseq code, left repr, right repr)
+ CASE q fmove : t2 (q fmove code, right repr, left repr)
+ CASE q flsequ : compare (q flsequ code, left repr, right repr)
+ CASE q tmove : t2 (q tmove code, right repr, left repr)
+ CASE q tequ : compare (q tequ code, left repr, right repr)
+ CASE q compl int : s2 (q compl int code, left repr, right repr)
+ CASE q compl real : s2 (q compl real code, left repr, right repr)
+ CASE q fequ : compare (q fequ code, left repr, right repr)
+ CASE q tlsequ : compare (q tlsequ code, left repr, right repr)
+ CASE q accds : t2 (q access ds code, left repr, right repr)
+ CASE q ref : t2 (q ref code, left repr, right repr)
+ CASE q dimov : s2 (q dimov code, left repr, right repr)
+ CASE q idmov : s2 (q idmov code, left repr, right repr)
+ OTHERWISE errorstop (wrong nr of params + mnemonic (opn))
+ ENDSELECT .
+
+move immediate :
+ IF right addr.kind = immediate value
+ THEN s0 (q esc movim code) ;
+ s1 (right addr.value, left repr)
+ ELSE errorstop (no immediate value)
+ FI
+ENDPROC apply p2;
+
+PROC apply p3 (OPN CONST opn, DTYPE CONST left dtype,
+ ADDRESS CONST left addr, right addr, result addr ):
+ result repr := REPR result addr ;
+ IF opn.mod nr = q pdadd THEN select with dint; LEAVE apply p3
+ ELIF opn.mod nr = q select THEN gen select instruction; LEAVE apply p3 FI ;
+ left repr := REPR left addr ;
+ IF opn.mod nr = q movex THEN gen long move
+ ELIF opn.mod nr = q alias ds THEN alias dataspace
+ ELSE gen p3 instruction
+ FI .
+
+gen long move :
+ IF right addr.kind = immediate value
+ THEN long move (left repr, result repr, right addr.value)
+ ELSE errorstop (no immediate value)
+ FI .
+
+alias dataspace :
+ IF right addr.value = immediate value
+ THEN s0 (q alias ds code) ;
+ s2 (right addr.value, result repr, left repr)
+ ELSE errorstop (no immediate value)
+ FI .
+
+gen select instruction :
+ IF right addr.kind = immediate value
+ THEN IF different bases
+ THEN access external (left addr.value, right addr.value)
+ ELSE t1 (q select code, REPR left addr) ;
+ s1 (right addr.value, result repr)
+ FI
+ ELSE errorstop (no immediate value)
+ FI .
+
+select with dint :
+ right repr := REPR right addr ;
+ IF different bases THEN access external packet
+ ELSE simple access
+ FI .
+
+different bases :
+ left addr.kind = p base AND left addr.value <> packet base .
+
+simple access :
+ s3 (q pdadd code, REPR left addr, right repr, result repr) .
+
+access external packet :
+ access external (left addr.value, global address zero) ;
+ s3 (q pdadd code, REPR REF result addr, right repr, result repr) .
+
+gen p3 instruction :
+ right repr := REPR right addr ;
+ SELECT opn.mod nr OF
+ CASE q add : int add
+ CASE q sub : int sub
+ CASE q fadd : real add
+ CASE q fsub : real sub
+ CASE q fmult : real mult
+ CASE q fdiv, q real div : real div
+ CASE q esc mult : int mult
+ CASE q esc div, q int div : int div
+ CASE q esc mod : int mod
+ CASE q plus : int real add
+ CASE q minus : int real sub
+ CASE q mult : int real mult
+ CASE q equal, q lessequal : compare (comp code, left repr, right repr)
+ CASE q ppsub : distance between two objects
+ OTHERWISE errorstop (wrong nr of params + mnemonic (opn))
+ ENDSELECT .
+
+int add : compute (q add code, left repr, right repr, result repr) .
+
+int sub : compute (q sub code, left repr, right repr, result repr) .
+
+real add : compute (q fadd code, left repr, right repr, result repr) .
+
+real sub : compute (q fsub code, left repr, right repr, result repr) .
+
+real mult : compute (q fmult code, left repr, right repr, result repr) .
+
+real div : compute (q fdiv code, left repr, right repr, result repr) .
+
+int mult : s3 (q esc mult code, left repr, right repr, result repr) .
+
+int div : s3 (q esc div code, left repr, right repr, result repr) .
+
+int mod : s3 (q esc mod code, left repr, right repr, result repr) .
+
+int real add :
+ IF left type = int id THEN int add
+ ELSE real add
+ FI .
+
+int real sub :
+ IF left type = int id THEN int sub
+ ELSE real sub
+ FI .
+
+int real mult :
+ IF left type = int id THEN int mult
+ ELSE real mult
+ FI .
+
+comp code :
+ SELECT left type OF
+ CASE int id : IF opn.mod nr = q equal THEN q equ ELSE q lsequ FI
+ CASE real id : IF opn.mod nr = q equal THEN q fequ ELSE q flsequ FI
+ CASE string id : IF opn.mod nr = q equal THEN q tequ ELSE q tlsequ FI
+ OTHERWISE errorstop (type error); q equ
+ ENDSELECT .
+
+left type : CONCR (left dtype) .
+
+distance between two objects :
+ s3 (q ppsub code, left repr, right repr, result repr)
+
+ENDPROC apply p3;
+
+PROC access external (INT CONST old base, offset) :
+ s0 (q penter code + old base) ;
+ t2 (q ref code, offset, result repr) ;
+ s0 (q penter code + packet base)
+ENDPROC access external ;
+
+
+ (***** Modul *****)
+
+BOOL VAR module open ;
+
+.init opn section :
+ module open := FALSE .;
+
+PROC begin module :
+ IF module open THEN errorstop (nested module)
+ ELSE begin modul ;
+ module open := TRUE
+ FI
+ENDPROC begin module ;
+
+PROC end module :
+ IF NOT module open
+ THEN errorstop (module not opened)
+ ELSE end modul ;
+ module open := FALSE
+ FI
+ENDPROC end module ;
+
+TEXT PROC dump (OPN CONST operation) :
+ IF operation.kind = proc op THEN " PROC" + text (operation.mod nr, 5)
+ ELIF operation.kind = eumel 0 THEN " EUMEL0: " + mnemonic (operation)
+ ELSE " undef. Opn"
+ FI
+ENDPROC dump ;
+
+PROC begin modul :
+ EXTERNAL 10073
+ENDPROC begin modul ;
+
+PROC end modul :
+ EXTERNAL 10011
+ENDPROC end modul ;
+
+PROC proc head (INT VAR mod nr, top of stack) :
+ EXTERNAL 10012
+ENDPROC proc head ;
+
+PROC set length (INT CONST top of stack, size) :
+ EXTERNAL 10013
+ENDPROC set length ;
+
+PROC get module nr (INT VAR module nr) :
+ EXTERNAL 10016
+ENDPROC get module nr ;
+
+PROC compute (INT CONST op code, l addr, r addr, result address) :
+ EXTERNAL 10017
+ENDPROC compute ;
+
+PROC compare (INT CONST op code, l addr, r addr) :
+ EXTERNAL 10018
+ENDPROC compare ;
+
+PROC long move (INT CONST to, from, length) :
+ EXTERNAL 10019
+ENDPROC long move ;
+
+PROC call (INT CONST mod nr) :
+ EXTERNAL 10022
+ENDPROC call ;
+
+PROC call param (INT CONST mod nr) :
+ EXTERNAL 10023
+ENDPROC call param ;
+
+PROC push param (INT CONST addr) :
+ EXTERNAL 10024
+ENDPROC push param ;
+
+PROC push param proc (INT CONST mod nr) :
+ EXTERNAL 10025
+ENDPROC push param proc ;
+
+PROC init param push (INT CONST mod nr) :
+ EXTERNAL 10026
+ENDPROC init param push ;
+
+PROC push result address (INT CONST addr) :
+ EXTERNAL 10027
+ENDPROC push result address ;
+
+PROC test bool object (INT CONST addr) :
+ EXTERNAL 10192
+ENDPROC test bool object ;
+
+PROC mark line (INT CONST line number) :
+ EXTERNAL 10030
+ENDPROC mark line ;
+
+PROC s0 (INT CONST op code) :
+ EXTERNAL 10038
+ENDPROC s0 ;
+
+PROC s1 (INT CONST op code, addr) :
+ EXTERNAL 10039
+ENDPROC s1 ;
+
+PROC s2 (INT CONST op code , addr1, addr2) :
+ EXTERNAL 10040
+ENDPROC s2 ;
+
+PROC s3 (INT CONST op code, addr1, addr2, addr3) :
+ EXTERNAL 10041
+ENDPROC s3 ;
+
+PROC t1 (INT CONST op code, addr) :
+ EXTERNAL 10042
+ENDPROC t1 ;
+
+PROC t2 (INT CONST op code, addr1, addr2) :
+ EXTERNAL 10043
+ENDPROC t2 ;
+
+#page#
+(**************************************************************************)
+(* *)
+(* 9. Speicherverwaltung 03.06.1986 *)
+(* *)
+(* Ablage der Paketdaten *)
+(* *)
+(**************************************************************************)
+
+
+
+INT VAR address value;
+
+INT CONST data allocation by coder := 1 ,
+ data allocation by user := 2 ;
+
+LET not initialized = 0 ,
+ wrong mm mode = "Wrong MM Mode" ,
+ define on non global = "Define for GLOB only" ,
+ text too long = "TEXT too long" ;
+
+TEXT VAR const buffer :: point line ;
+
+.reset memory management mode :
+ memory management mode := not initialized . ;
+
+PROC reserve storage (INT CONST size) :
+ IF memory management mode <> data allocation by user
+ THEN errorstop (wrong mm mode)
+ FI ;
+ allocate var (address value, size) ;
+ memory management mode := not initialized
+ENDPROC reserve storage ;
+
+PROC allocate variable (ADDRESS VAR addr, INT CONST size) :
+ IF memory management mode <> data allocation by coder
+ THEN errorstop (wrong mm mode)
+ FI ;
+ allocate var (addr.value, size) ;
+ addr.kind := global
+ENDPROC allocate variable ;
+
+PROC allocate denoter (ADDRESS VAR addr, INT CONST value) :
+ IF memory management mode <> data allocation by coder
+ THEN errorstop (wrong mm mode)
+ FI ;
+ allocate int denoter (addr.value) ;
+ put data word (value, addr.value) ;
+ addr.kind := global
+ENDPROC allocate denoter ;
+
+PROC allocate denoter (ADDRESS VAR addr, REAL CONST value) :
+ IF memory management mode <> data allocation by coder
+ THEN errorstop (wrong mm mode)
+ FI ;
+ allocate real denoter (addr.value) ;
+ addr.kind := global ;
+ define (addr, value)
+ENDPROC allocate denoter ;
+
+PROC allocate denoter (ADDRESS VAR addr, TEXT CONST value) :
+ IF memory management mode <> data allocation by coder
+ THEN errorstop (wrong mm mode)
+ FI ;
+ allocate text denoter (addr.value, (LENGTH value+1) DIV 2 + 2) ;
+ addr.kind := global ;
+ skip heaplink;
+ define (addr, value) ;
+ reset heaplink .
+
+skip heaplink :
+ addr.value INCR 1 .
+
+reset heaplink :
+ addr.value DECR 1
+ENDPROC allocate denoter ;
+
+PROC allocate denoter (ADDRESS VAR addr, DINT CONST value) :
+ IF memory management mode <> data allocation by coder
+ THEN errorstop (wrong mm mode)
+ FI ;
+ allocate dint denoter (addr.value, value) ;
+ addr.kind := global
+ENDPROC allocate denoter ;
+
+PROC allocate dint denoter (INT VAR addr offset, DINT CONST value) :
+ adjust to an even address if necessary ;
+ put data word (value.low, addr offset) ;
+ allocate int denoter (address value) ;
+ put data word (value.high, address value) .
+
+adjust to an even address if necessary :
+ allocate int denoter (addr offset) ;
+ IF (addr offset AND 1) <> 0 THEN allocate int denoter (addr offset) FI
+ENDPROC allocate dint denoter ;
+
+PROC define (ADDRESS CONST addr, INT CONST value) :
+ IF addr.kind <> global
+ THEN errorstop (define on non global)
+ FI ;
+ put data word (value, addr.value)
+ENDPROC define ;
+
+PROC define (ADDRESS CONST addr, DINT CONST value) :
+ IF addr.kind <> global
+ THEN errorstop (define on non global)
+ FI ;
+ put data word (value.low , addr.value);
+ put data word (value.high, addr.value + 1)
+ENDPROC define ;
+
+PROC define (ADDRESS CONST addr, REAL CONST value) :
+ IF addr.kind <> global
+ THEN errorstop (define on non global)
+ FI ;
+ replace (const buffer, 1, value) ;
+ address value := addr.value ;
+ FOR index FROM 1 UPTO 4 REP
+ put data word (const buffer ISUB index, address value) ;
+ address value INCR 1
+ PER
+ENDPROC define ;
+
+PROC define (ADDRESS CONST addr, TEXT CONST value) :
+ IF addr.kind <> global THEN errorstop (define on non global)
+ ELIF LENGTH value > 255 THEN errorstop (text too long)
+ FI ;
+ address value := addr.value ;
+ const buffer := code (LENGTH value) ;
+ const buffer CAT value ;
+ const buffer CAT ""0"" ;
+ FOR index FROM 1 UPTO LENGTH const buffer DIV 2 REP
+ put data word (const buffer ISUB index, address value) ;
+ address value INCR 1
+ PER ;
+ const buffer := point line
+ENDPROC define ;
+
+PROC allocate var (INT VAR addr, INT CONST length) :
+ EXTERNAL 10033
+ENDPROC allocate var ;
+
+PROC allocate int denoter (INT VAR addr) :
+ EXTERNAL 10034
+ENDPROC allocate int denoter ;
+
+PROC allocate real denoter (INT VAR addr) :
+ EXTERNAL 10035
+ENDPROC allocate real denoter ;
+
+PROC allocate text denoter (INT VAR addr, INT CONST length) :
+ EXTERNAL 10036
+ENDPROC allocate text denoter ;
+
+PROC put data word (INT CONST value, INT CONST addr) :
+ EXTERNAL 10037
+ENDPROC put data word ;
+
+
+#page#
+(**************************************************************************)
+(* *)
+(* 10. Inspector 28.10.1987 *)
+(* *)
+(**************************************************************************)
+
+
+
+INT VAR line number, pattern length, begin of packet,
+ last packet entry, indentation;
+
+TEXT VAR bulletin name, type and mode, pattern, buffer, dummy name;
+
+DATASPACE VAR bulletin ds :: nilspace ;
+
+.packet name :
+ cdb text (cdb int(packet link + wordlength) + two word length) .
+
+.packet entry :
+ permanent pointer = 0 OR
+ cdbint (permanent pointer) = permanent packet OR
+ cdbint (permanent pointer + wordlength) = permanent packet .
+
+.within editor :
+ aktueller editor > 0 . ;
+
+TEXT PROC type name (DTYPE CONST type) :
+ type and mode := "" ;
+ IF CONCR (type) = void id THEN type and mode CAT "VOID"
+ ELSE name of type (CONCR (type))
+ FI ;
+ type and mode
+ENDPROC type name ;
+
+TEXT PROC dump (DTYPE CONST type) :
+(* type and mode := "TYPE " ;
+ name of type (CONCR (type)) ;
+ type and mode
+*)
+ type name (type) (* aus Kompatibilitätsgründen zum 1.9.2 Coder / rr *)
+ENDPROC dump ;
+
+PROC name of type (INT CONST type) :
+ SELECT type OF
+ CASE void id :
+ CASE int id : type and mode CAT "INT"
+ CASE real id : type and mode CAT "REAL"
+ CASE string id : type and mode CAT "TEXT"
+ CASE bool id, bool result id : type and mode CAT "BOOL"
+ CASE dataspace id : type and mode CAT "DATASPACE"
+ CASE row id : type and mode CAT "ROW "
+ CASE struct id : type and mode CAT "STRUCT"
+ OTHERWISE : complex type
+ ENDSELECT .
+
+complex type :
+ unsigned arithmetic ;
+ IF type > ptt limit THEN perhaps permanent struct or row
+ ELSE get complex type
+ FI .
+
+perhaps permanent struct or row :
+ index := type + begin of pt minus ptt limit ;
+ mode := cdb int (index) MOD ptt limit ;
+ IF mode = permanent row THEN get permanent row
+ ELIF mode = permanent struct THEN get permanent struct
+ ELSE type and mode CAT "-"
+ FI .
+
+get complex type :
+ index := type + begin of permanent table ;
+ IF is complex type THEN get name
+ ELSE type and mode CAT "-"
+ FI .
+
+is complex type :
+ permanent type definition mode = permanent type .
+
+get name :
+ type and mode CAT cdb text (link to type name + two word length) .
+
+link to type name :
+ cdb int (index + three word length) .
+
+permanent type definition mode :
+ cdb int (index + wordlength) .
+
+get permanent row :
+ INT VAR t;
+ type and mode CAT "ROW " ;
+ type and mode CAT text (cdb int (index + wordlength)) ;
+ type and mode CAT " " ;
+ param link := index + two wordlength ;
+ get type and mode (t) ;
+ name of type (t) .
+
+get permanent struct :
+ type and mode CAT "STRUCT ( ... )"
+ENDPROC name of type ;
+
+PROC help (TEXT CONST proc name) :
+ prep bulletin ;
+ prep help ;
+ scan (object name) ;
+ next symbol (pattern) ;
+ packet link := end of permanent table ;
+ IF function = 0 THEN standard help
+ ELSE asterisk help
+ FI .
+
+prep help :
+ object name := compress (proc name) ;
+ INT VAR function :: 0 ;
+ INT CONST l :: LENGTH object name ;
+ IF l > 1 AND object name <> "**"
+ THEN IF (object name SUB l) = "*"
+ THEN function INCR 2 ;
+ delete char (object name, l)
+ FI ;
+ IF (object name SUB 1) = "*"
+ THEN function INCR 1 ;
+ delete char (object name, 1)
+ FI ;
+ IF another asterisk THEN wrong function FI
+ FI.
+
+another asterisk :
+ pos (object name, "*") <> 0 .
+
+wrong function :
+ errorstop ("unzulaessige Sternfunktion") .
+
+standard help :
+ to object (pattern) ;
+ IF found THEN display
+ ELSE error stop ("unbekannt: " + proc name)
+ FI .
+
+display :
+ IF NOT packet entry
+ THEN WHILE permanent pointer <> 0 REP
+ put name of packet if necessary ;
+ put specifications (pattern) ;
+ next procedure
+ ENDREP ;
+ show bulletin file
+ FI .
+
+put name of packet if necessary :
+ IF new packet THEN packet link := permanent pointer ;
+ find begin of packet ;
+ writeline (2) ;
+ write packet name
+ FI .
+
+find begin of packet :
+ REP
+ packet link DECR wordlength
+ UNTIL begin of packet found PER .
+
+begin of packet found :
+ cdb int (packet link) = permanent packet .
+
+new packet :
+ permanent pointer < packet link .
+
+asterisk help :
+ hash table pointer := begin of hash table ;
+ pattern length := LENGTH pattern - 1 ;
+ REP
+ list all objects in current hash table chain ;
+ next hash entry
+ UNTIL end of hash table reached ENDREP ;
+ show bulletin file .
+
+list all objects in current hash table chain :
+ nt link := hash table pointer ;
+ WHILE yet another nt entry REP
+ permanent pointer := cdb int (nt link + wordlength) ;
+ object name := cdb text (nt link + two word length) ;
+ IF matching THEN into bulletin FI
+ PER .
+
+matching :
+ INT CONST p :: pos (object name, pattern) ;
+ SELECT function OF
+ CASE 1 : p <> 0 AND p = LENGTH object name - pattern length
+ CASE 2 : p = 1
+ CASE 3 : p <> 0
+ OTHERWISE FALSE
+ ENDSELECT .
+
+into bulletin :
+ object names into bulletin (BOOL PROC not end of chain)
+ENDPROC help ;
+
+BOOL PROC not end of chain :
+ permanent pointer <> 0
+ENDPROC not end of chain ;
+
+PROC write packet name :
+ indentation := 0 ;
+ write line ;
+ write bulletin line ("PACKET ") ;
+ indentation := 7 ;
+ object name := packet name ;
+ write bulletin line (object name) ;
+ write bulletin line (":") ;
+ writeline (2)
+ENDPROC write packet name ;
+
+PROC put specifications (TEXT CONST proc name) :
+ put obj name (proc name) ;
+ to first param ;
+ IF NOT end of params THEN put param list FI ;
+ put result ;
+ writeline .
+
+to first param :
+ param link := permanent pointer + word length ;
+ set end marker if end of list .
+
+put result :
+ INT VAR type;
+ get type and mode (type) ;
+ IF type <> void id THEN type and mode := " --> " ;
+ name of type (type) ;
+ write bulletin line (type and mode)
+ FI
+ENDPROC put specifications ;
+
+PROC put param list :
+ write bulletin line (" (") ;
+ REP
+ INT VAR type, param mode;
+ get type and mode (type) ;
+ param mode := mode ;
+ put type and mode ;
+ maybe param proc ;
+ next pt param ;
+ IF end of params THEN write bulletin line (")") ;
+ LEAVE put param list
+ FI ;
+ write bulletin line (", ") ;
+ PER .
+
+put type and mode :
+ type and mode := "" ;
+ name of type (type) ;
+ type and mode CAT name of mode ;
+ write bulletin line (type and mode) .
+
+name of mode :
+ IF param mode = const THEN " CONST"
+ ELIF param mode = var THEN " VAR"
+ ELSE " PROC"
+ FI .
+
+maybe param proc :
+ IF mode = permanent param proc THEN put virtual params FI .
+
+put virtual params :
+ skip over result type if complex type ;
+ IF NOT end of virtual params THEN put param list FI.
+
+skip over result type if complex type :
+ next pt param .
+
+end of virtual params :
+ end of params
+ENDPROC put param list ;
+
+PROC to packet (TEXT CONST packet name) :
+ to object ( packet name) ;
+ IF found THEN find start of packet objects FI .
+
+find start of packet objects :
+ last packet entry := 0 ;
+ packet link := before first pt entry ;
+ REP
+ packet link INCR wordlength ;
+ word := cdb int (packet link) ;
+ IF word < 0 THEN IF word = permanent packet THEN packet found
+ ELIF word = permanent end THEN return
+ FI
+ FI
+ ENDREP .
+
+packet found :
+ IF cdb int (packet link + wordlength) = nt link
+ THEN last packet entry := packet link FI .
+
+return :
+ IF last packet entry <> 0 THEN found := TRUE ;
+ packet link := last packet entry
+ ELSE found := FALSE
+ FI ;
+ LEAVE to packet
+ENDPROC to packet ;
+
+PROC next packet :
+ REP
+ packet link INCR wordlength ;
+ word := cdb int (packet link) ;
+ IF word = permanent packet THEN true return
+ ELIF end of permanents THEN false return
+ FI ;
+ ENDREP .
+
+true return :
+ found := TRUE ;
+ LEAVE next packet .
+
+false return :
+ found := FALSE ;
+ LEAVE next packet .
+
+end of permanents :
+ word = permanent end OR packet link > end of permanent table
+ENDPROC next packet ;
+
+PROC prep bulletin :
+ forget (bulletin ds) ;
+ bulletin ds := nilspace ;
+ bulletin file := sequential file (output, bulletin ds) ;
+ line number := 0 ;
+ buffer := ""
+ENDPROC prep bulletin ;
+
+PROC show bulletin file :
+ IF within editor THEN ueberschrift neu FI ;
+ DATASPACE VAR local ds :: bulletin ds ;
+ FILE VAR local file :: sequential file (modify, local ds) ;
+ show (local file) ;
+ forget (local ds)
+ENDPROC show bulletin file ;
+
+PROC write bulletin line (TEXT CONST line) :
+ IF LENGTH buffer + LENGTH line > 75 THEN writeline FI ;
+ buffer CAT line
+ENDPROC write bulletin line ;
+
+PROC writeline :
+ write (bulletin file, buffer) ;
+ line (bulletin file) ;
+ line number INCR 1 ;
+ cout (line number) ;
+ buffer := indentation * " "
+ENDPROC writeline ;
+
+PROC writeline (INT CONST times) :
+ IF LENGTH compress(buffer) <> 0 THEN index := times - 1 ;
+ writeline
+ ELSE index := times
+ FI ;
+ line (bulletin file, index) ;
+ line number INCR index;
+ indentation := 0 ;
+ cout (line number)
+ENDPROC writeline ;
+
+PROC bulletin (TEXT CONST packet name) :
+ prep bulletin ;
+ scan (packet name) ;
+ next symbol (pattern) ;
+ to packet (pattern) ;
+ IF found THEN list packet ;
+ show bulletin file
+ ELSE error stop (packet name + " ist kein Paketname")
+ FI .
+
+ENDPROC bulletin ;
+
+PROC list packet :
+ begin of packet := packet link + word length ;
+ write packet name ;
+ find end of packet ;
+ run through nametab and list all packet objects .
+
+find end of packet :
+ last packet entry := begin of packet ;
+ REP
+ last packet entry INCR wordlength ;
+ word := cdb int (last packet entry) ;
+ UNTIL end of packet entries PER .
+
+end of packet entries :
+ word = permanent packet OR word = permanent end .
+
+run through nametab and list all packet objects :
+ hashtable pointer := begin of hashtable ;
+ REP
+ nt link := hashtable pointer ;
+ list objects of current packet in this chain ;
+ next hash entry
+ UNTIL end of hashtable reached ENDREP .
+
+list objects of current packet in this chain :
+ WHILE yet another nt entry REP
+ permanent pointer := cdb int (nt link + wordlength) ;
+ put objects of this name
+ PER .
+
+put objects of this name :
+ IF there is an entry THEN into bulletin FI .
+
+there is an entry :
+ NOT packet entry AND
+ there is at least one object of this name in the current packet .
+
+there is at least one object of this name in the current packet :
+ REP
+ IF permanent pointer >= begin of packet AND
+ permanent pointer < last packet entry
+ THEN LEAVE there is at least one object of this name
+ in the current packet WITH TRUE FI ;
+ next procedure
+ UNTIL permanent pointer = 0 PER ;
+ FALSE .
+
+into bulletin :
+ object name := cdb text (nt link + two word length) ;
+ object names into bulletin (BOOL PROC within packet)
+ENDPROC list packet ;
+
+BOOL PROC within packet :
+ permanent pointer >= begin of packet AND
+ permanent pointer < last packet entry
+ENDPROC within packet ;
+
+PROC object names into bulletin (BOOL PROC link ok) :
+ scan (object name) ;
+ next symbol (dummy name, mode) ;
+ IF type definition THEN put type definition
+ ELSE put object definitions
+ FI .
+
+type definition :
+ mode = bold AND no params .
+
+no params :
+ cdb int (permanent pointer + word length) >= permanent type .
+
+put type definition :
+ put obj name (object name) ;
+ write bulletin line ("TYPE ") ;
+ writeline (1) .
+
+put object definitions :
+ WHILE link ok REP
+ put specifications (object name) ;
+ next procedure
+ ENDREP
+ENDPROC object names into bulletin ;
+
+PROC bulletin :
+ prep bulletin ;
+ packet link := first permanent entry ;
+ REP
+ list packet ;
+ write line (4) ;
+ next packet
+ UNTIL NOT found PER ;
+ show bulletin file
+ENDPROC bulletin ;
+
+PROC put obj name (TEXT CONST name) :
+ buffer := " " ;
+ bulletin name := point line ;
+ change (bulletin name, 1, end of line or name, name) ;
+ buffer CAT bulletin name ;
+ indentation := LENGTH buffer + 1 .
+
+end of line or name :
+ min (LENGTH name, LENGTH bulletin name)
+ENDPROC put obj name ;
+
+PROC packets :
+ prep bulletin ;
+ packet link := first permanent entry ;
+ REP
+ object name := packet name ;
+ put obj name (object name) ;
+ write line ;
+ next packet
+ UNTIL NOT found PER ;
+ show bulletin file
+ENDPROC packets ;
+
+#page#
+(**************************************************************************)
+(* *)
+(* 11. ELAN Run-Interface 04.08.1986 *)
+(* *)
+(* Uebersetzen von ELAN-Programmen *)
+(* Bereitstellen der Ausgabeprozeduren fuer den ELAN-Compiler *)
+(* *)
+(**************************************************************************)
+
+
+
+BOOL VAR list option := FALSE ,
+ check option := TRUE ,
+ warning option := FALSE ,
+ listing enabled := FALSE ;
+
+FILE VAR listing file ;
+
+TEXT VAR listing file name := "" ;
+
+
+PROC run (TEXT CONST file name) :
+ enable stop ;
+ IF NOT exists (file name)
+ THEN errorstop ("""" + file name + """ gibt es nicht")
+ FI ;
+ last param (file name) ;
+ run elan (file name, no ins)
+END PROC run;
+
+PROC run :
+ run (last param)
+ENDPROC run ;
+
+PROC run again :
+ IF run again mod nr <> 0
+ THEN elan (run again mode, bulletin file, "", run again mod nr,
+ no ins, no lst, check option, no sermon)
+ ELSE errorstop ("'run again' nicht moeglich")
+ FI
+ENDPROC run again ;
+
+PROC insert (TEXT CONST file name) :
+ enable stop ;
+ IF NOT exists (file name)
+ THEN errorstop ("""" + file name + """ gibt es nicht")
+ FI ;
+ last param (file name) ;
+ run elan (file name, ins)
+ENDPROC insert ;
+
+PROC insert :
+ insert (last param)
+ENDPROC insert ;
+
+PROC run elan (TEXT CONST file name, BOOL CONST insert option) :
+ FILE VAR source := sequential file (modify, file name) ;
+ IF listing enabled
+ THEN open listing file
+ FI ;
+
+ disable stop ;
+ no do again ;
+ elan (compile file mode, source, "" , run again mod nr,
+ insert option, list option, check option, sermon) ;
+
+ IF anything noted AND command dialogue
+ THEN ignore halt during compiling ;
+ note edit (source) ;
+ last param (file name) ;
+ errorstop ("")
+ FI .
+
+ignore halt during compiling :
+ IF is error
+ THEN put error ;
+ clear error ;
+ pause (5)
+ FI .
+
+open listing file :
+ listing file := sequential file (output, listing file name) ;
+ max line length (listing file, 130)
+
+ENDPROC run elan ;
+(*
+PROC out text (TEXT CONST text, INT CONST out type) :
+ INTERNAL 257 ;
+ IF online
+ THEN out (text)
+ FI ;
+ IF out type = error message OR (warning option AND out type = warning message)
+ THEN note (text) ;
+ FI ;
+ IF listing enabled
+ THEN write (listing file, text)
+ FI
+ENDPROC out text ;
+
+PROC out line (INT CONST out type) :
+ INTERNAL 258 ;
+ IF online
+ THEN out (""13""10"")
+ FI ;
+ IF out type = error message
+ OR (warning option AND out type = warning message)
+ THEN note line
+ ELIF listing enabled
+ THEN line (listing file)
+ FI
+ENDPROC out line ;
+*)
+PROC prot (TEXT CONST file name) :
+ list option := TRUE ;
+ listing file name := file name ;
+ listing enabled := TRUE
+ENDPROC prot ;
+
+PROC prot off :
+ list option := FALSE ;
+ listing enabled := FALSE
+ENDPROC prot off ;
+
+BOOL PROC prot :
+ list option
+ENDPROC prot ;
+
+PROC check on :
+ check option := TRUE
+ENDPROC check on ;
+
+PROC check off :
+ check option := FALSE
+ENDPROC check off ;
+
+BOOL PROC check :
+ check option
+ENDPROC check ;
+
+PROC warnings on :
+ warning option := TRUE
+ENDPROC warnings on ;
+
+PROC warnings off :
+ warning option := FALSE
+ENDPROC warnings off ;
+
+BOOL PROC warnings :
+ warning option
+ENDPROC warnings ;
+
+ENDPACKET eumel coder ;
+
+PACKET dint2 DEFINES dint type :
+
+INT VAR dummy ;
+DTYPE VAR d ;
+identify ("DINT", dummy, dummy, d) ;
+
+DTYPE CONST dint type := d
+
+ENDPACKET dint2 ;
+
diff --git a/basic/eumel0 codes b/basic/eumel0 codes
new file mode 100644
index 0000000..226014c
--- /dev/null
+++ b/basic/eumel0 codes
Binary files differ
diff --git a/basic/gen.BASIC b/basic/gen.BASIC
new file mode 100644
index 0000000..9690ae6
--- /dev/null
+++ b/basic/gen.BASIC
@@ -0,0 +1,80 @@
+(**************************************************************************)
+(* *)
+(* Generatorprogramm zur Installation des EUMEL-BASIC-Systems *)
+(* *)
+(* Autor: Heiko Indenbirken *)
+(* Überarbeitet von: Michael Overdick *)
+(* *)
+(* Stand: 27.08.1987 *)
+(* *)
+(**************************************************************************)
+
+LET coder name = "eumel coder 1.8.1";
+
+show headline;
+from archive ("BASIC.1", (coder name & "eumel0 codes") - all);
+from archive ("BASIC.2",
+ ("BASIC.Runtime" & "BASIC.Administration" & "BASIC.Compiler") - all);
+set status;
+insert ("eumel coder 1.8.1");
+insert ("BASIC.Runtime");
+insert ("BASIC.Administration");
+insert ("BASIC.Compiler");
+forget (coder name & "BASIC.Runtime"
+ & "BASIC.Administration" & "BASIC.Compiler" & "gen.BASIC");
+restore status;
+show end .
+
+show headline:
+ page;
+ putline (" "15"Einrichten des EUMEL-BASIC-Systems "14"");
+ line .
+
+set status:
+ BOOL VAR old check := check,
+ old warnings := warnings,
+ old command dialogue := command dialogue;
+ check off;
+ warnings off;
+ command dialogue (FALSE).
+
+restore status:
+ IF old check THEN do ("check on") ELSE do ("check off") FI;
+ IF old warnings THEN warnings on FI;
+ command dialogue (old command dialogue).
+
+show end:
+ line (2);
+ putline (" "15"BASIC-System installiert "14"");
+ line .
+
+PROC from archive (TEXT CONST name, THESAURUS CONST files):
+ IF highest entry (files) > 0
+ THEN ask for archive;
+ archive (name);
+ fetch (files, archive);
+ release (archive);
+ putline ("Archiv abgemeldet !")
+ FI .
+
+ask for archive:
+ line;
+ IF no ("Archiv """ + name + """ eingelegt")
+ THEN errorstop ("Archive nicht bereit") FI .
+
+END PROC from archive;
+
+THESAURUS OP & (TEXT CONST left, right):
+ THESAURUS VAR result := empty thesaurus;
+ insert (result, left);
+ insert (result, right);
+ result
+END OP &;
+
+THESAURUS OP & (THESAURUS CONST left, TEXT CONST right):
+ THESAURUS VAR result := left;
+ insert (result, right);
+ result
+END OP &;
+
+
diff --git a/datatype/complex b/datatype/complex
new file mode 100644
index 0000000..e2139d0
--- /dev/null
+++ b/datatype/complex
@@ -0,0 +1,115 @@
+
+PACKET complex DEFINES COMPLEX,:=,complex zero,complex one,complex i,
+ complex,realpart,imagpart,CONJ,+,-,*,/,=,<>,
+ put,get, ABS, sqrt, phi, dphi :
+
+TYPE COMPLEX = STRUCT(REAL re,im);
+COMPLEX PROC complex zero: COMPLEX :(0.0,0.0). END PROC complex zero;
+COMPLEX PROC complex one : COMPLEX :(1.0,0.0). END PROC complex one;
+COMPLEX PROC complex i : COMPLEX :(0.0,1.0). END PROC complex i;
+
+OP := (COMPLEX VAR dest, COMPLEX CONST source) :
+
+ CONCR (dest) := CONCR (source)
+
+ENDOP := ;
+
+COMPLEX PROC complex(REAL CONST re,im):
+ COMPLEX :(re,im).
+END PROC complex;
+
+REAL PROC realpart(COMPLEX CONST number):
+ number.re.
+END PROC realpart;
+
+REAL PROC imagpart(COMPLEX CONST number):
+ number.im.
+END PROC imagpart ;
+
+COMPLEX OP CONJ(COMPLEX CONST number):
+ COMPLEX :( number.re,- number.im).
+END OP CONJ;
+
+BOOL OP =(COMPLEX CONST a,b):
+ IF a.re=b.re
+ THEN a.im=b.im
+ ELSE FALSE
+ FI.
+END OP =;
+
+BOOL OP <>(COMPLEX CONST a,b):
+ IF a.re=b.re
+ THEN a.im<>b.im
+ ELSE TRUE
+ FI.
+END OP <>;
+
+COMPLEX OP +(COMPLEX CONST a,b):
+ COMPLEX :(a.re+b.re,a.im+b.im).
+END OP +;
+
+COMPLEX OP -(COMPLEX CONST a,b):
+ COMPLEX :(a.re-b.re,a.im-b.im).
+END OP -;
+
+COMPLEX OP *(COMPLEX CONST a,b):
+ REAL VAR re of a::a.re,im of a ::a.im,
+ re of b::b.re,im of b ::b.im;
+ COMPLEX :(re of a*re of b- im of a *im of b,
+ re of a*im of b+ im of a*re of b).
+END OP *;
+
+COMPLEX OP /(COMPLEX CONST a,b):
+ REAL VAR re of a::a.re,im of a::a.im,
+ re of b::b.re,im of b::b.im;
+ REAL VAR sqare sum of re and im ::b.re*b.re+b.im*b.im;
+ COMPLEX :( (re of a * re of b + im of a * im of b)/sqare sum of re and im,
+ (im of a *re of b - re of a*im of b)/sqare sum of re and im).
+END OP /;
+
+PROC get(COMPLEX VAR a):
+ REAL VAR realpart,imagpart;
+ get(realpart);get(imagpart);
+ a:= COMPLEX :(realpart,imagpart);
+END PROC get;
+
+PROC put(COMPLEX CONST a):
+ put(a.re);put(" ");put(a.im);
+END PROC put;
+
+REAL PROC dphi(COMPLEX CONST x):
+ IF imagpart(x)=0.0 THEN reell
+ ELIF realpart(x)=0.0 THEN imag
+ ELIF realpart(x)>0.0 THEN realpositiv
+ ELSE realnegativ
+ FI.
+reell: IF sign(realpart(x)) < 0 THEN 180.0 ELSE 0.0 FI.
+imag: IF imagpart(x)>0.0 THEN 90.0 ELSE 270.0 FI.
+realpositiv:IF imagpart(x)>0.0 THEN arctand(realpart(x)/imagpart(x))
+ ELSE
+arctand(realpart(x)/imagpart(x))+360.0 FI.
+realnegativ: arctand(realpart(x)/imagpart(x))+180.0.
+END PROC dphi;
+
+REAL PROC phi(COMPLEX CONST x):
+dphi(x)*3.141592653689793/180.0.
+END PROC phi;
+
+COMPLEX PROC sqrt(COMPLEX CONST x):
+IF x=complex zero THEN x
+ELIF realpart(x)<0.0 THEN
+complex(imagpart(x)/(2.0*real(sign(imagpart(x)))
+ *sqrt((ABSx-realpart(x))/2.0)),
+ real(sign(imagpart(x)))*sqrt((ABS x-realpart(x))/2.0))
+ELSE complex(sqrt((ABS x+realpart(x))/2.0),
+ imagpart(x)/(2.0*sqrt((ABS x+realpart(x))/2.0)))
+FI.
+
+END PROC sqrt;
+
+REAL OP ABS(COMPLEX CONST x):
+ sqrt(realpart(x)*realpart(x)+imagpart(x)*imagpart(x)).
+END OP ABS;
+
+END PACKET complex;
+
diff --git a/datatype/longint b/datatype/longint
new file mode 100644
index 0000000..e78bb52
--- /dev/null
+++ b/datatype/longint
@@ -0,0 +1,423 @@
+PACKET longint DEFINES LONGINT, (* Autoren: S.Baumann,A.Bentrup *)
+ :=, (* T.Sillke *)
+ <, (* Stand: 17.03.81 *)
+ >,
+ <=,
+ >=,
+ <>,
+ =,
+ -,
+ +,
+ *,
+ **,
+ ABS,
+ abs,
+ DECR,
+ DIV,
+ get,
+ INCR,
+ int,
+ (*last rest,*)
+ longint,
+ max,
+ max longint,
+ min,
+ MOD,
+ put,
+ random,
+ SIGN,
+ sign,
+ text,
+ zero:
+
+TYPE LONGINT = TEXT;
+
+LONGINT VAR result,aleft,aright;
+TEXT VAR ergebnis,x,y,z,h;
+INT VAR v byte,slr,sll;
+INT CONST snull :: code("0"), mtl :: 300 ;
+TEXT CONST negativ :: code(127),max digit :: code(99),null :: code(0),
+ overflow :: "LONGINT overflow",eins :: code(1);
+BOOL VAR vorl,vorr,vleft,vright;
+
+OP := (LONGINT VAR left, LONGINT CONST right) :
+ CONCR(left) := CONCR(right)
+END OP :=;
+
+BOOL OP < (LONGINT CONST left,right) :
+ slr := sign(right)*length(right);
+ sll := sign(left )*length(left );
+ IF slr <> sll THEN
+ IF slr > sll THEN TRUE ELSE FALSE FI
+ ELSE IF slr>0
+ THEN CONCR(left) < CONCR(right)
+ ELSE CONCR(left) > CONCR(right) FI
+ FI
+END OP < ;
+
+BOOL OP > (LONGINT CONST left,right) :
+ slr := sign(right)*length(right);
+ sll := sign(left )*length(left );
+ IF slr <> sll THEN
+ IF slr < sll THEN TRUE ELSE FALSE FI
+ ELSE IF slr>0
+ THEN CONCR(left) > CONCR(right)
+ ELSE CONCR(left) < CONCR(right) FI
+ FI
+END OP > ;
+
+BOOL OP <= (LONGINT CONST left,right) :
+ NOT (left > right)
+END OP <=;
+
+BOOL OP >= (LONGINT CONST left,right) :
+ NOT (left < right)
+END OP >=;
+
+BOOL OP <> (LONGINT CONST left,right) :
+ CONCR (left) <> CONCR (right)
+END OP <>;
+
+BOOL OP = (LONGINT CONST left,right) :
+ CONCR (left) = CONCR (right)
+END OP = ;
+
+LONGINT OP - (LONGINT CONST arg) :
+ SELECT code(CONCR(arg)SUB1) OF
+ CASE 0 : zero
+ CASE 127: LONGINT : (subtext(CONCR(arg),2))
+ OTHERWISE LONGINT : (negativ + CONCR(arg))
+ END SELECT
+END OP -;
+
+LONGINT OP + (LONGINT CONST arg) : arg END OP +;
+
+LONGINT OP - (LONGINT CONST left,right) :
+ IF CONCR(left ) = null THEN LEAVE - WITH -right
+ ELIF CONCR(right) = null THEN LEAVE - WITH left
+ ELIF sign(left) <> sign(right) THEN LEAVE - WITH left + (-right) FI;
+ betrag(left,right);
+ BOOL CONST betrag max :: aleft > aright;
+ IF betrag max
+ THEN result := LONGINT : (CONCR(aleft ) SUB CONCR(aright))
+ ELSE result := LONGINT : (CONCR(aright) SUB CONCR(aleft )) FI;
+ kuerze fuehrende nullen(CONCR(result),null);
+ IF vleft XOR betrag max THEN -result ELSE result FI
+END OP -;
+
+LONGINT OP + (LONGINT CONST left,right) :
+ IF sign(left) <> sign(right) THEN LEAVE + WITH left - (-right) FI;
+ betrag(left,right);
+ IF aleft > aright
+ THEN result := LONGINT : (CONCR(aleft ) ADD CONCR(aright))
+ ELSE result := LONGINT : (CONCR(aright) ADD CONCR(aleft )) FI;
+ IF vleft THEN result ELSE -result FI
+END OP +;
+
+LONGINT OP * (LONGINT CONST left,right) :
+ IF CONCR(left) = null OR CONCR(right) = null THEN LEAVE * WITH zero
+ ELIF length(left) + length(right) > mtl THEN errorstop (overflow) FI;
+ betrag(left,right);
+ IF aleft < aright
+ THEN result := LONGINT : (CONCR(aright) MUL CONCR(aleft ))
+ ELSE result := LONGINT : (CONCR(aleft ) MUL CONCR(aright)) FI;
+ IF length(CONCR(result)) = mtl THEN errorstop(overflow) FI;
+ IF vleft XOR vright THEN -result ELSE result FI
+END OP *;
+
+LONGINT OP ** (LONGINT CONST arg,exp) :
+ IF exp > longint(max int) THEN errorstop (overflow) FI;
+ arg ** int(exp)
+END OP **;
+
+LONGINT OP ** (LONGINT CONST arg,INT CONST exp) :
+ IF exp < 0 THEN errorstop ("LONGINT OP ** : negativ exp")
+ ELIF CONCR(arg)=null AND exp=0 THEN errorstop(text(0 ** 0)) FI;
+ IF exp = 0 THEN one
+ ELIF exp = 1 THEN arg
+ ELIF sign(arg) = -1 AND exp MOD 2 <> 0
+ THEN -LONGINT:(CONCR(abs(arg))EXPexp)
+ ELSE LONGINT:(CONCR(abs(arg))EXPexp) FI
+END OP **;
+
+LONGINT OP ABS (LONGINT CONST arg) : abs(arg) END OP ABS;
+
+LONGINT PROC abs (LONGINT CONST a) :
+ IF (CONCR(a)SUB1)=negativ THEN LONGINT:(subtext(CONCR(a),2)) ELSE a FI
+END PROC abs;
+
+OP DECR (LONGINT VAR result,LONGINT CONST ab) :
+ result := result - ab;
+END OP DECR;
+
+LONGINT OP DIV (LONGINT CONST left,right) :
+ IF CONCR(right) = null THEN error stop("LONGINT OP DIV by zero") FI;
+ betrag(left,right); h := CONCR(aright);
+ y := null + CONCR(aleft ); vorl := vleft;
+ z := null + CONCR(aright); vorr := vright;
+ IF aleft < aright THEN y:=CONCR(aleft); LEAVE DIV WITH zero FI;
+ INT VAR try,i,cr1 :: code(z SUB 2),cr2,cr3,zw;
+ BOOL VAR sh :: length(z) <> 2;
+ IF sh THEN cr3:=code(zSUB3); cr2:=10*cr1+cr3DIV10; cr3:=100*cr1+cr3 FI;
+ CONCR(result) := "";
+ FOR i FROM 0 UPTO length(y)-length(z) REP
+ laufe eine abschaetzung durch;
+ CONCR (result) CAT code(try)
+ PER; kuerze fuehrende nullen(y,null);
+ IF(CONCR(result)SUB1)=nullTHEN CONCR(result):=subtext(CONCR(result),2)FI;
+ IF vleft XOR vright THEN -result ELSE result FI.
+
+ laufe eine abschaetzung durch :
+ zw := 100*code(y SUB i+1) + code(y SUB i+2);
+ IF zw < 3276 AND sh THEN IF zw < 327
+ THEN try := min((100*zw + code(ySUBi+3)) DIV cr3, 99)
+ ELSE try := min(( 10*zw + code(ySUBi+3)DIV10)DIV cr2, 99) FI
+ ELSE try := min( zw DIV cr1, 99) FI;
+ x := z MUL code(try);
+ WHILE x > subtext(y,i+1,i+length(x)) REP
+ try DECR 1; x := x SUB z PER;
+ replace(y,i + 1,subtext(y,i + 1,i + length(x)) SUB x)
+END OP DIV;
+
+PROC get (LONGINT VAR result) :
+ get (ergebnis);
+ result := longint(ergebnis);
+END PROC get;
+
+PROC get (FILE VAR file,LONGINT VAR result) :
+ get(file,ergebnis);
+ result := longint(ergebnis);
+END PROC get;
+
+OP INCR (LONGINT VAR result,LONGINT CONST dazu) :
+ result := result + dazu;
+END OP INCR;
+
+INT PROC int (LONGINT CONST longint) :
+ IF length(longint) > 3
+ THEN max int + 1
+ ELSE ergebnis := (3-length(longint))*null + CONCR(abs(longint));
+ (code(ergebnis SUB 1) * 10000 +
+ code(ergebnis SUB 2) * 100 +
+ code(ergebnis SUB 3)) * sign(longint)
+ FI
+END PROC int;
+
+LONGINT PROC longint (INT CONST int) :
+ CONCR(result) := code( abs(int) DIV 10000) +
+ code((abs(int) MOD 10000) DIV 100) +
+ code( abs(int) MOD 100);
+ kuerze fuehrende nullen (CONCR(result),null);
+ IF int < 1 THEN -result ELSE result FI
+END PROC longint;
+
+LONGINT PROC longint (TEXT CONST text) :
+ INT VAR i;
+ ergebnis := compress(text);
+ BOOL VAR minus :: (ergebnisSUB1) = "-";
+ IF (ergebnisSUB1)="+" OR minus THEN ergebnis:=subtext(ergebnis,2) FI;
+ kuerze fuehrende nullen(ergebnis,"0");
+ kuerze die unzulaessigen zeichen aus ergebnis;
+ schreibe ergebnis im hundertersystem in result;
+ result mit vorzeichen.
+
+ kuerze die unzulaessigen zeichen aus ergebnis :
+ ergebnis := subtext(ergebnis,1,letztes zulaessiges zeichen).
+ letztes zulaessiges zeichen :
+ FOR i FROM 1 UPTO length(ergebnis) REP
+ UNTIL pos("0123456789", ergebnis SUB i) = 0 PER;
+ i - 1.
+ schreibe ergebnis im hundertersystem in result :
+ sll := length(ergebnis);
+ IF sll MOD 2 <> 0 THEN ergebnis := "0"+ergebnis; sll INCR 1 FI;
+ i := 1; CONCR(result) := "";
+ REP schreibe ein zeichen im hundertersystem in result;
+ i INCR 2
+ UNTIL i >= sll PER.
+ schreibe ein zeichen im hundertersystem in result :
+ CONCR(result) CAT code((code(ergebnis SUB i ) - snull) * 10 +
+ code(ergebnis SUB i + 1) - snull).
+ result mit vorzeichen :
+ IF ergebnis="" THEN zero ELIF minus THEN -result ELSE result FI
+END PROC longint;
+
+LONGINT PROC max (LONGINT CONST left,right) :
+ IF left > right THEN left ELSE right FI
+END PROC max;
+
+LONGINT PROC max longint :
+ LONGINT : ((mtl - 1) * max digit)
+END PROC max longint;
+
+LONGINT PROC min (LONGINT CONST left,right) :
+ IF left < right THEN left ELSE right FI
+END PROC min;
+
+LONGINT OP MOD (LONGINT CONST left,right) :
+ IF CONCR(right) = null THEN errorstop("LONGINT OP MOD by zero") FI;
+ result := left DIV right; last rest
+END OP MOD;
+
+PROC put (LONGINT CONST longint) :
+ INT VAR i :: 1,zwei ziffern;
+ IF sign(longint) = -1 THEN out("-"); i:=2 FI;
+ out(text(code(CONCR(longint) SUB i)));
+ FOR i FROM i + 1 UPTO length(CONCR(longint)) REP
+ zwei ziffern := code(CONCR(longint) SUB i);
+ out(code(zwei ziffern DIV 10 + snull));
+ out(code(zwei ziffern MOD 10 + snull));
+ PER;out(" ")
+END PROC put;
+
+PROC put (FILE VAR file,LONGINT CONST longint) :
+ put(file,text(longint));
+END PROC put;
+
+LONGINT PROC random (LONGINT CONST lower bound,upper bound) :
+ INT VAR i; x := CONCR(upper bound - lower bound - one); y := "";
+ FOR i FROM 1 UPTO length(x) REP y CAT code(random(0,99)) PER;
+ upper bound - (LONGINT : (y) MOD LONGINT : (x))
+END PROC random;
+
+INT OP SIGN (LONGINT CONST arg) : sign(arg) END OP SIGN;
+
+INT PROC sign (LONGINT CONST arg) :
+ SELECT code(CONCR(arg) SUB 1) OF
+ CASE 0 : 0
+ CASE 127 : -1
+ OTHERWISE 1
+ END SELECT
+END PROC sign;
+
+TEXT PROC text (LONGINT CONST longint) :
+ INT VAR i::1,zwei ziffern; ergebnis := "";
+ IF sign(longint) = -1 THEN ergebnis := "-"; i:=2 FI;
+ ergebnis CAT text (code (CONCR (longint) SUB i ) ) ;
+ FOR i FROM i+1 UPTO length(CONCR(longint)) REP
+ zwei ziffern := code(CONCR(longint) SUB i);
+ ergebnis CAT code(zwei ziffern DIV 10 + snull);
+ ergebnis CAT code(zwei ziffern MOD 10 + snull)
+ PER; ergebnis
+END PROC text;
+
+TEXT PROC text (LONGINT CONST longint,INT CONST length) :
+ x := text(longint); sll := LENGTH x;
+ IF sll > length THEN length * "*" ELSE (length - sll)*" " + x FI
+END PROC text;
+
+LONGINT PROC last rest :
+ IF y=null THEN LEAVE last rest WITH zero FI;
+ IF vorl XOR vorr THEN y := h SUB y; kuerze fuehrende nullen(y,null);
+ vorl := TRUE FI;
+ IF NOTvorr THEN y:=negativ+y; vorr := TRUE FI; LONGINT:(y)
+END PROC last rest;
+
+LONGINT PROC zero : LONGINT : (null) END PROC zero;
+LONGINT PROC one : LONGINT : (""1"") END PROC one;
+
+
+(* ----------------------- INTERNE HILFSPROZEDUREN ----------------------- *)
+
+TEXT OP ADD (TEXT CONST left,right) :
+ INT VAR carrybit :: 0,i,dif :: length(left) - length(right);
+ ergebnis := left;
+ FOR i FROM length(left) DOWNTO dif + 1 REP
+ replace(ergebnis,i,das result der addition)
+ PER;
+ IF carrybit = 1 THEN addiere den uebertrag FI;
+ ergebnis.
+
+ das result der addition :
+ v byte := (code(left SUB i) + code(right SUB i - dif) + carrybit);
+ IF v byte > 99
+ THEN carrybit := 1; code(v byte - 100)
+ ELSE carrybit := 0; code(v byte)
+ FI.
+ addiere den uebertrag :
+ FOR i FROM i DOWNTO 1
+ WHILE (ergebnis SUB i) >= max digit REP
+ replace(ergebnis,i,null)
+ PER;
+ IF (ergebnis SUB 1) = null OR dif = 0
+ THEN pruefe auf longint overflow
+ ELSE replace(ergebnis,i,code(code(ergebnis SUB i) + 1))
+ FI.
+ pruefe auf longint overflow :
+ IF length(ergebnis) = mtl - 1 THEN errorstop(overflow) FI;
+ ergebnis := eins + ergebnis
+END OP ADD;
+
+PROC betrag (LONGINT CONST a, b) :
+ vleft := (CONCR(a)SUB1)<>negativ; vright := (CONCR(b)SUB1)<>negativ;
+ IF vleft THEN aleft :=a ELSE CONCR(aleft ):=subtext(CONCR(a),2) FI;
+ IF vright THEN aright:=b ELSE CONCR(aright):=subtext(CONCR(b),2) FI
+END PROC betrag;
+
+TEXT OP EXP (TEXT CONST arg,INT CONST exp) :
+ INT VAR zaehler :: exp;
+ x := arg; z := eins;
+ REP IF zaehler MOD 2 = 1 THEN z := z MUL x FI;
+ zaehler := zaehler DIV 2; x := x MUL x
+ UNTIL zaehler = 1 PER;
+ x MUL z
+END OP EXP;
+
+PROC kuerze fuehrende nullen ( TEXT VAR text,TEXT CONST snull) :
+ INT VAR i;
+ text := subtext(text,erste nicht snull).
+
+ erste nicht snull :
+ FOR i FROM 1 UPTO length (text) - 1 REP
+ UNTIL (text SUB i) <> snull PER;
+ i
+END PROC kuerze fuehrende nullen;
+
+INT PROC length (LONGINT CONST a) :
+ IF (CONCR(a)SUB1)=negativ THEN length(CONCR(a))-1 ELSE length(CONCR(a)) FI
+END PROC length;
+
+TEXT OP MUL (TEXT CONST left,right) :
+ INT VAR i,j,carrybit,v,w;
+ ergebnis := (length(left) + length(right) - 1) * null;
+ FOR i FROM length(ergebnis) DOWNTO length(left) REP
+ v := i - length(left); w := length(right) - length(ergebnis) + i;
+ carrybit := 0;
+ FOR j FROM length(left) DOWNTO 1 REP
+ replace(ergebnis,v + j,result der addition)
+ PER;
+ replace(ergebnis,v,code(code(ergebnis SUB v) + carrybit));
+ PER;
+ IF carrybit = 0 THEN ergebnis ELSE code(carrybit) + ergebnis FI.
+
+ result der addition :
+ v byte := code(right SUB w) * code(left SUB j) + carrybit +
+ code(ergebnis SUB v + j);
+ carrybit := v byte DIV 100;
+ code(v byte MOD 100)
+END OP MUL;
+
+TEXT OP SUB (TEXT CONST left,right) :
+ INT VAR carrybit :: 0,i,dif :: length(left) - length(right);
+ ergebnis := left;
+ FOR i FROM length(left) DOWNTO dif + 1 REP
+ replace(ergebnis,i,das result der subtraktion);
+ PER;
+ IF carrybit = 1 THEN subtrahiere den uebertrag FI;
+ ergebnis.
+
+ das result der subtraktion :
+ v byte := (code(left SUB i) - code(right SUB i - dif) - carrybit);
+ IF v byte < 0
+ THEN carrybit := 1;code(v byte + 100)
+ ELSE carrybit := 0;code(v byte)
+ FI.
+ subtrahiere den uebertrag :
+ FOR i FROM i DOWNTO 2
+ WHILE (ergebnis SUB i) = null REP
+ replace(ergebnis,i,max digit)
+ PER;
+ replace(ergebnis,i,code(code(ergebnis SUB i) - 1))
+END OP SUB;
+
+END PACKET longint;
+
diff --git a/datatype/matrix b/datatype/matrix
new file mode 100644
index 0000000..d9de9fb
--- /dev/null
+++ b/datatype/matrix
@@ -0,0 +1,482 @@
+PACKET matrix DEFINES MATRIX, matrix, idn, (* Stand : 16.06.86 wk *)
+ :=, sub, (* Autor : H.Indenbirken *)
+ row, column,
+ COLUMNS,
+ ROWS,
+ DET,
+ INV,
+ TRANSP,
+ transp,
+ replace row, replace column,
+ replace element,
+ get, put,
+ =, <>,
+ +, -, * :
+
+TYPE MATRIX = STRUCT (INT rows, columns, VECTOR elems);
+TYPE INITMATRIX = STRUCT (INT rows, columns, REAL value, BOOL idn);
+
+MATRIX VAR a :: idn (1);
+INT VAR i;
+
+(****************************************************************************
+PROC dump (MATRIX CONST m) :
+ put line (text (m.rows) + " Reihen, " + text (m.columns) + " Spalten.");
+ dump (m.elems) .
+
+END PROC dump;
+****************************************************************************)
+
+OP := (MATRIX VAR l, MATRIX CONST r) :
+ CONCR (l) := CONCR (r);
+END OP :=;
+
+OP := (MATRIX VAR l, INITMATRIX CONST r) :
+ l.rows := r.rows;
+ l.columns := r.columns;
+ l.elems := vector (r.rows*r.columns, r.value);
+ IF r.idn
+ THEN idn FI .
+
+idn :
+ INT VAR i;
+ FOR i FROM 1 UPTO r.rows
+ REP replace (l.elems, calc pos (l.columns, i, i), 1.0) PER
+
+END OP :=;
+
+INITMATRIX PROC matrix (INT CONST rows, columns, REAL CONST value) :
+ IF rows <= 0
+ THEN errorstop ("PROC matrix : rows <= 0")
+ ELIF columns <= 0
+ THEN errorstop ("PROC matrix : columns <= 0") FI;
+
+ INITMATRIX : (rows, columns, value, FALSE)
+
+END PROC matrix;
+
+INITMATRIX PROC matrix (INT CONST rows, columns) :
+ matrix (rows, columns, 0.0)
+
+END PROC matrix;
+
+INITMATRIX PROC idn (INT CONST size) :
+ IF size <= 0
+ THEN errorstop ("MATRIX PROC idn : size <= 0") FI;
+
+ INITMATRIX : (size, size, 0.0, TRUE)
+
+END PROC idn;
+
+VECTOR PROC row (MATRIX CONST m, INT CONST i) :
+ VECTOR VAR v :: vector (m.columns);
+ INT VAR j, k :: 1, pos :: (i-1) * m.columns;
+ FOR j FROM pos+1 UPTO pos + m.columns
+ REP replace (v, k, m.elems SUB j);
+ k INCR 1
+ PER;
+ v
+
+END PROC row;
+
+VECTOR PROC column (MATRIX CONST m, INT CONST j) :
+ VECTOR VAR v :: vector (m.rows);
+ INT VAR i, k :: j;
+ FOR i FROM 1 UPTO m.rows
+ REP replace (v, i, m.elems SUB k);
+ k INCR m.columns
+ PER;
+ v
+
+END PROC column;
+
+INT OP COLUMNS (MATRIX CONST m) :
+ m.columns
+
+END OP COLUMNS;
+
+INT OP ROWS (MATRIX CONST m) :
+ m.rows
+
+END OP ROWS;
+
+REAL PROC sub (MATRIX CONST a, INT CONST row, column) :
+ a.elems SUB calc pos (a.columns, row, column)
+
+END PROC sub;
+
+PROC replace row (MATRIX VAR m, INT CONST rowindex, VECTOR CONST rowvalue) :
+ test ("PROC replace row : ", "LENGTH rowvalue", "COLUMNS m",
+ LENGTH rowvalue, m.columns);
+ test ("PROC replace row : row ", rowindex, m.rows);
+
+ INT VAR i, pos :: (rowindex-1) * m.columns;
+ FOR i FROM 1 UPTO m.columns
+ REP replace (m.elems, pos+i, rowvalue SUB i) PER
+
+END PROC replace row;
+
+PROC replace column (MATRIX VAR m, INT CONST columnindex,
+ VECTOR CONST columnvalue) :
+ test ("PROC replace column : ", "LENGTH columnvalue", "ROWS m",
+ LENGTH columnvalue, m.rows);
+ test ("PROC replace column : column ", columnindex, m.columns);
+
+ INT VAR i;
+ FOR i FROM 1 UPTO m.rows
+ REP replace (m.elems, calc pos (m.columns, i, columnindex),
+ columnvalue SUB i) PER
+
+END PROC replace column;
+
+PROC replace element (MATRIX VAR a, INT CONST row, column, REAL CONST x) :
+ test ("PROC replace element : row ", row, a.rows);
+ test ("PROC replace element : column ", column, a.columns);
+ replace (a.elems, calc pos (a.columns, row, column), x)
+
+END PROC replace element;
+
+BOOL OP = (MATRIX CONST l, r) :
+ IF l.rows <> r.rows
+ THEN FALSE
+ ELIF l.columns <> r.columns
+ THEN FALSE
+ ELSE l.elems = r.elems FI
+
+END OP =;
+
+BOOL OP <> (MATRIX CONST l, r) :
+ IF l.rows <> r.rows
+ THEN TRUE
+ ELIF l.columns <> r.columns
+ THEN TRUE
+ ELSE l.elems <> r.elems FI
+
+END OP <>;
+
+INT PROC calc pos (INT CONST columns, z, s) :
+ (z-1) * columns + s
+END PROC calc pos;
+
+MATRIX OP + (MATRIX CONST m) :
+ m
+
+END OP +;
+
+MATRIX OP + (MATRIX CONST l, r) :
+ test ("MATRIX OP + : ", "ROWS l", "ROWS r", l.rows, r.rows);
+ test ("MATRIX OP + : ", "COLUMNS l", "COLUMNS r", l.columns, r.columns);
+
+ a := l;
+ INT VAR i;
+ FOR i FROM 1 UPTO l.rows * l.columns
+ REP replace (a.elems, i, (l.elems SUB i) + (r.elems SUB i))
+ PER;
+ a
+
+END OP +;
+
+MATRIX OP - (MATRIX CONST m) :
+ a := m;
+ INT VAR i;
+ FOR i FROM 1 UPTO m.rows * m.columns
+ REP replace (a.elems, i, -a.elems SUB i)
+ PER;
+ a
+
+END OP -;
+
+MATRIX OP - (MATRIX CONST l, r) :
+ test ("MATRIX OP - : ", "ROWS l", "ROWS r", l.rows, r.rows);
+ test ("MATRIX OP - : ", "COLUMNS l", "COLUMNS r", l.columns, r.columns);
+
+ a := l;
+ INT VAR i;
+ FOR i FROM 1 UPTO l.rows * l.columns
+ REP replace (a.elems, i, (l.elems SUB i) - (r.elems SUB i))
+ PER;
+ a
+
+END OP -;
+
+MATRIX OP * (REAL CONST x, MATRIX CONST m) :
+ m*x
+
+END OP *;
+
+MATRIX OP * (MATRIX CONST m, REAL CONST x) :
+ a := m;
+ INT VAR i;
+ FOR i FROM 1 UPTO m.rows * m.columns
+ REP replace (a.elems, i, x*m.elems SUB i) PER;
+ a
+
+END OP *;
+
+VECTOR OP * (VECTOR CONST v, MATRIX CONST m) :
+ test ("VECTOR OP * : ", "LENGTH v", "ROWS m", LENGTH v, m.rows);
+ VECTOR VAR result :: vector (m.columns); (*wk*)
+ INT VAR i;
+ FOR i FROM 1 UPTO m.columns
+ REP replace (result, i, v * column (m, i)) PER;
+ result .
+
+END OP *;
+
+VECTOR OP * (MATRIX CONST m, VECTOR CONST v) :
+ test ("VECTOR OP * : ", "COLUMNS m", "LENGTH v", COLUMNS m, LENGTH v);
+ VECTOR VAR result :: vector (m.rows); (*wk*)
+ INT VAR i;
+ FOR i FROM 1 UPTO m.rows
+ REP replace (result, i, row (m, i) * v) PER;
+ result .
+
+END OP *;
+
+MATRIX OP * (MATRIX CONST l, r) :
+ test ("MATRIX OP * : ","COLUMNS l","ROWS r", l.columns, r.rows);
+
+ a.rows := l.rows;
+ a.columns := r.columns;
+ a.elems := vector (a.rows*a.columns)
+ INT VAR i, j;
+ FOR i FROM 1 UPTO a.rows
+ REP FOR j FROM 1 UPTO a.columns
+ REP VECTOR VAR rl :: row (l, i), cr :: column (r, j);
+ replace (a.elems, calc pos (a.columns, i, j), rl * cr)
+ PER
+ PER;
+ a .
+
+END OP *;
+
+PROC get (MATRIX VAR a, INT CONST rows, columns) :
+
+ a := matrix (rows,columns);
+ INT VAR i, j;
+ VECTOR VAR v;
+ FOR i FROM 1 UPTO rows
+ REP get (v, columns);
+ store row
+ PER .
+
+store row :
+ FOR j FROM 1 UPTO a.columns
+ REP replace (a.elems, calc pos (a.columns, i, j), v SUB j)
+ PER .
+
+END PROC get;
+
+PROC put (MATRIX CONST a, INT CONST length, fracs) :
+ INT VAR i, j;
+ FOR i FROM 1 UPTO a.rows
+ REP FOR j FROM 1 UPTO a.columns
+ REP put (text (sub (a, i, j), length, fracs)) PER;
+ line (2);
+ PER
+
+END PROC put;
+
+PROC put (MATRIX CONST a) :
+ INT VAR i, j;
+ FOR i FROM 1 UPTO a.rows
+ REP FOR j FROM 1 UPTO a.columns
+ REP TEXT CONST number :: " " + text (sub (a, i, j));
+ put (subtext (number, LENGTH number - 15))
+ PER;
+ line (2);
+ PER
+
+END PROC put;
+
+TEXT VAR error :: "";
+PROC test (TEXT CONST proc, l text, r text, INT CONST left, right) :
+ IF left <> right
+ THEN error := proc;
+ error CAT l text;
+ error CAT " (";
+ error CAT text (left);
+ error CAT ") <> ";
+ error CAT r text;
+ error CAT " (";
+ error CAT text (right);
+ error CAT ")";
+ errorstop (error)
+ FI .
+
+END PROC test;
+
+PROC test (TEXT CONST proc, INT CONST i, n) :
+ IF i < 1
+ THEN error := proc;
+ error CAT "subscript underflow (";
+ error CAT text (i);
+ error CAT ")";
+ errorstop (error)
+ ELIF i > n
+ THEN error := proc;
+ error CAT "subscript overflow (i=";
+ error CAT text (i);
+ error CAT ", max=";
+ IF n <= 0
+ THEN error CAT "undefined"
+ ELSE error CAT text (n) FI;
+ error CAT ")";
+ errorstop (error)
+ FI
+
+END PROC test;
+
+
+MATRIX OP TRANSP (MATRIX CONST m) :
+ MATRIX VAR a :: m;
+ transp (a);
+ a
+
+END OP TRANSP;
+
+PROC transp (MATRIX VAR m) :
+ INT VAR k :: 1, n :: m.rows*m.columns;
+ a := m;
+ FOR i FROM 2 UPTO n
+ REP replace (m.elems, i, a.elems SUB position) PER;
+ a := idn (1);
+ i := m.rows;
+ m.rows := m.columns;
+ m.columns := i .
+
+position :
+ k INCR m.columns;
+ IF k > n
+ THEN k DECR (n-1) FI;
+ k .
+END PROC transp;
+
+MATRIX OP INV (MATRIX CONST m) :
+ a := m;
+ ROW 32 INT VAR pivots;
+ INT VAR i, j, k :: ROWS a, n :: COLUMNS a, pos;
+
+ IF n <> k
+ THEN errorstop ("MATRIX OP INV : no square matrix") FI;
+
+ initialisiere die pivotpositionen;
+
+ FOR j FROM 1 UPTO n
+ REP pivotsuche (a, j, pos);
+ IF sub (a, pos, pos) = 0.0
+ THEN errorstop ("MATRIX OP INV : singular matrix") FI;
+ zeilentausch (a, j, pos);
+ merke dir die vertauschung;
+ transformiere die matrix
+ PER;
+
+ spaltentausch;
+ a .
+
+initialisiere die pivotpositionen :
+ FOR i FROM 1 UPTO n
+ REP pivots [i] := i PER .
+
+merke dir die vertauschung :
+ IF pos > j
+ THEN INT VAR hi :: pivots [j];
+ pivots [j] := pivots [pos];
+ pivots [pos] := hi
+ FI .
+
+transformiere die matrix :
+ REAL VAR h := 1.0/sub (a, j, j);
+
+ FOR k FROM 1 UPTO n
+ REP IF k <> j
+ THEN FOR i FROM 1 UPTO n
+ REP IF i <> j
+ THEN replace element (a, i, k, sub (a, i, k) -
+ sub (a, i, j)*sub (a, j, k)*h);
+ FI
+ PER;
+ FI
+ PER;
+
+ FOR k FROM 1 UPTO n
+ REP replace element (a, j, k, -h*sub (a, j, k));
+ replace element (a, k, j, h*sub (a, k, j))
+ PER;
+ replace element (a, j, j, h) .
+
+spaltentausch :
+ VECTOR VAR v :: vector (n);
+ FOR i FROM 1 UPTO n
+ REP FOR k FROM 1 UPTO n
+ REP replace (v, pivots [k], sub(a, i, k)) PER;
+ replace row (a, i, v)
+ PER .
+
+END OP INV;
+
+REAL OP DET (MATRIX CONST m) :
+ IF COLUMNS m <> ROWS m
+ THEN errorstop ("REAL OP DET : no square matrix") FI;
+
+ a := m;
+ INT VAR i, j, k, n :: COLUMNS m, pos;
+ REAL VAR merker := 1.0;
+ FOR j FROM 1 UPTO n
+ REP pivotsuche (a, j, pos);
+ IF j<> pos
+ THEN zeilentausch (a, j, pos);
+ zeilen tausch merken
+ FI;
+ transformiere die matrix
+ PER;
+ produkt der pivotelemente .
+
+transformiere die matrix :
+ REAL VAR hp := sub(a,j,j);
+ IF hp = 0.0
+ THEN LEAVE DET WITH 0.0
+ ELSE REAL VAR h := 1.0/hp;
+ FI;
+ FOR i FROM j+1 UPTO n
+ REP FOR k FROM j+1 UPTO n
+ REP replace element (a, i, k, sub (a, i, k) -
+ sub (a, i, j)*h*sub (a, j, k))
+ PER
+ PER .
+
+produkt der pivotelemente :
+ REAL VAR produkt :: sub (a, 1, 1);
+ FOR j FROM 2 UPTO n
+ REP produkt := produkt * sub (a, j, j) PER;
+ a := idn (1);
+ produkt * merker.
+
+zeilen tausch merken:
+ merker := merker * (-1.0).
+
+END OP DET;
+
+PROC pivotsuche (MATRIX CONST a, INT CONST start pos, INT VAR pos) :
+ REAL VAR max :: abs (sub (a, start pos, start pos));
+ INT VAR i;
+ pos := start pos;
+
+ FOR i FROM start pos+1 UPTO COLUMNS a
+ REP IF abs (sub (a, i, start pos)) > max
+ THEN max := abs (sub (a, i, start pos));
+ pos := i
+ FI
+ PER .
+
+END PROC pivotsuche;
+
+PROC zeilentausch (MATRIX VAR a, INT CONST old pos, pos) :
+ VECTOR VAR v := row (a, pos);
+ replace row (a, pos, row (a, old pos));
+ replace row (a, old pos, v) .
+
+END PROC zeilentausch;
+
+END PACKET matrix;
+
diff --git a/datatype/vector b/datatype/vector
new file mode 100644
index 0000000..5c9e896
--- /dev/null
+++ b/datatype/vector
@@ -0,0 +1,213 @@
+PACKET vector DEFINES VECTOR, :=, vector, (* Autor : H.Indenbirken *)
+ SUB, LENGTH, length, norm, (* Stand : 21.10.83 *)
+ nilvector, replace, =, <>,
+ +, -, *, /,
+ get, put :
+
+
+TYPE VECTOR = STRUCT (INT lng, TEXT elem);
+TYPE INITVECTOR = STRUCT (INT lng, REAL value);
+
+INT VAR i;
+TEXT VAR t :: "12345678";
+VECTOR VAR v :: nilvector;
+
+(****************************************************************************
+PROC dump (VECTOR CONST v) :
+ put line (text (v.lng) + " Elemente :");
+ FOR i FROM 1 UPTO v.lng
+ REP put line (text (i) + ": " + text (element i)) PER .
+
+element i :
+ v.elem RSUB i .
+
+END PROC dump;
+****************************************************************************)
+
+OP := (VECTOR VAR l, VECTOR CONST r) :
+ l.lng := r.lng;
+ l.elem := r.elem
+
+END OP :=;
+
+OP := (VECTOR VAR l, INITVECTOR CONST r) :
+ l.lng := r.lng;
+ replace (t, 1, r.value);
+ l.elem := r.lng * t
+
+END OP :=;
+
+INITVECTOR PROC nilvector :
+ vector (1, 0.0)
+
+END PROC nilvector;
+
+INITVECTOR PROC vector (INT CONST lng, REAL CONST value) :
+ IF lng <= 0
+ THEN errorstop ("PROC vector : lng <= 0") FI;
+ INITVECTOR : (lng, value)
+
+END PROC vector;
+
+INITVECTOR PROC vector (INT CONST lng) :
+ vector (lng, 0.0)
+
+END PROC vector;
+
+REAL OP SUB (VECTOR CONST v, INT CONST i) :
+ test ("REAL OP SUB : ", v, i);
+ v.elem RSUB i
+
+END OP SUB;
+
+INT OP LENGTH (VECTOR CONST v) :
+ v.lng
+
+END OP LENGTH;
+
+INT PROC length (VECTOR CONST v) :
+ v.lng
+
+END PROC length;
+
+REAL PROC norm (VECTOR CONST v) :
+ REAL VAR result :: 0.0;
+ FOR i FROM 1 UPTO v.lng
+ REP result INCR ((v.elem RSUB i)**2) PER;
+ sqrt (result) .
+
+END PROC norm;
+
+PROC replace (VECTOR VAR v, INT CONST i, REAL CONST r) :
+ test ("PROC replace : ", v, i);
+ replace (v.elem, i, r)
+
+END PROC replace;
+
+BOOL OP = (VECTOR CONST l, r) :
+ l.elem = r.elem
+END OP =;
+
+BOOL OP <> (VECTOR CONST l, r) :
+ l.elem <> r.elem
+END OP <>;
+
+VECTOR OP + (VECTOR CONST v) :
+ v
+END OP +;
+
+VECTOR OP + (VECTOR CONST l, r) :
+ test ("VECTOR OP + : ", l, r);
+ v := l;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, (l.elem RSUB i) + (r.elem RSUB i)) PER;
+ v
+
+END OP +;
+
+VECTOR OP - (VECTOR CONST a) :
+ v := a;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, - (a.elem RSUB i)) PER;
+ v
+
+END OP -;
+
+VECTOR OP - (VECTOR CONST l, r) :
+ test ("VECTOR OP - : ", l, r);
+ v := l;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, (l.elem RSUB i) - (r.elem RSUB i)) PER;
+ v
+END OP -;
+
+REAL OP * (VECTOR CONST l, r) :
+ test ("REAL OP * : ", l, r);
+ REAL VAR x :: 0.0;
+ FOR i FROM 1 UPTO l.lng
+ REP x INCR ((l.elem RSUB i) * (r.elem RSUB i)) PER;
+ x
+
+END OP *;
+
+VECTOR OP * (VECTOR CONST v, REAL CONST r) :
+ r*v
+
+END OP *;
+
+VECTOR OP * (REAL CONST r, VECTOR CONST a) :
+ v := a;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, r*(a.elem RSUB i)) PER;
+ v
+
+END OP *;
+
+VECTOR OP / (VECTOR CONST a, REAL CONST r) :
+ v := a;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, (a.elem RSUB i)/r) PER;
+ v
+
+END OP /;
+
+TEXT VAR error :: "";
+PROC test (TEXT CONST proc, VECTOR CONST v, INT CONST i) :
+ IF i > v.lng
+ THEN error := proc;
+ error CAT "subscript overflow (LENGTH v=";
+ error CAT text (v.lng);
+ error CAT ", i=";
+ error CAT text (i);
+ error CAT ")";
+ errorstop (error)
+ ELIF i < 1
+ THEN error := proc;
+ error CAT "subscript underflow (i = ";
+ error CAT text (i);
+ error CAT ")";
+ errorstop (error)
+ FI .
+
+END PROC test;
+
+PROC test (TEXT CONST proc, VECTOR CONST a, b) :
+ IF a.lng <> b.lng
+ THEN error := proc;
+ error CAT "LENGTH a (";
+ IF a.lng <= 0
+ THEN error CAT "undefined"
+ ELSE error CAT text (a.lng) FI;
+ error CAT ") <> LENGTH b (";
+ error CAT text (b.lng);
+ error CAT ")";
+ errorstop (error)
+ FI
+
+END PROC test;
+
+PROC get (VECTOR VAR v, INT CONST lng) :
+ v.lng := lng;
+ v.elem := lng * "12345678";
+ REAL VAR x;
+ FOR i FROM 1 UPTO lng
+ REP get (x);
+ replace (v.elem, i, x)
+ PER .
+
+END PROC get;
+
+PROC put (VECTOR CONST v, INT CONST length, fracs) :
+ FOR i FROM 1 UPTO v.lng
+ REP put (text (v.elem RSUB i, length, fracs)) PER
+
+END PROC put;
+
+PROC put (VECTOR CONST v) :
+ FOR i FROM 1 UPTO v.lng
+ REP put (text (v.elem RSUB i)) PER
+
+END PROC put;
+
+END PACKET vector;
+
diff --git a/dialog/ls-DIALOG 1 b/dialog/ls-DIALOG 1
new file mode 100644
index 0000000..974bcda
--- /dev/null
+++ b/dialog/ls-DIALOG 1
@@ -0,0 +1,60 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG 1 **
+ ** **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+PACKET ls dialog 1 DEFINES
+ ecke oben links, balken oben,{} ecke oben rechts, balken rechts,{} ecke unten links, balken links,{} ecke unten rechts, balken unten,{} waagerecht, senkrecht, kreuz,{} cursor on, cursor off,{} clear buffer, clear buffer and count,{} center, invers, page, page up,{} out frame, out menuframe, erase frame,{} std graphic char, ft20 graphic char,{} ibm graphic char, AREA, :=, fill,{} areax, areay, areaxsize, areaysize,{} cursor, get cursor, out, out invers,{}
+ out with beam, out invers with beam,{} erase, erase invers, erase with beam:{}TYPE AREA = STRUCT (INT x, y, xsize, ysize);{}LET blank = " ",{} mark ein = ""15"",{} mark aus = ""14"",{} cleol = ""5"";{}TEXT CONST fehlermeldung :: "Unzulässige Größen!";{}TEXT VAR eol := "+", eor := "+", eul := "+", eur := "+",{} bo := "+", br := "+", bl := "+", bu := "+",{} waa := "-", sen := "|", kr := "+",{} cursor sichtbar := "", cursor unsichtbar := "";{}
+TEXT PROC ecke oben links : eol END PROC ecke oben links ;{}TEXT PROC ecke oben rechts: eor END PROC ecke oben rechts ;{}TEXT PROC ecke unten links : eul END PROC ecke unten links ;{}TEXT PROC ecke unten rechts: eur END PROC ecke unten rechts ;{}TEXT PROC balken oben : bo END PROC balken oben ;{}TEXT PROC balken links : bl END PROC balken links ;{}TEXT PROC balken rechts : br END PROC balken rechts ;{}TEXT PROC balken unten : bu END PROC balken unten ;{}
+TEXT PROC waagerecht : waa END PROC waagerecht ;{}TEXT PROC senkrecht : sen END PROC senkrecht ;{}TEXT PROC kreuz : kr END PROC kreuz ;{}PROC ecke oben links (TEXT CONST t): eol := t END PROC ecke oben links ;{}PROC ecke oben rechts (TEXT CONST t): eor := t END PROC ecke oben rechts ;{}PROC ecke unten links (TEXT CONST t): eul := t END PROC ecke unten links ;{}PROC ecke unten rechts (TEXT CONST t): eur := t END PROC ecke unten rechts ;{}
+PROC balken oben (TEXT CONST t): bo := t END PROC balken oben ;{}PROC balken links (TEXT CONST t): bl := t END PROC balken links ;{}PROC balken rechts (TEXT CONST t): br := t END PROC balken rechts ;{}PROC balken unten (TEXT CONST t): bu := t END PROC balken unten ;{}PROC waagerecht (TEXT CONST t): waa := t END PROC waagerecht ;{}PROC senkrecht (TEXT CONST t): sen := t END PROC senkrecht ;{}PROC kreuz (TEXT CONST t): kr := t END PROC kreuz ;{}
+PROC std graphic char:{} ecke oben links ("+"); ecke oben rechts ("+");{} ecke unten links ("+"); ecke unten rechts ("+");{} balken oben ("+"); balken rechts ("+");{} balken links ("+"); balken unten ("+");{} waagerecht ("-"); senkrecht ("|");{} kreuz ("+");{} cursor sichtbar := ""; cursor unsichtbar := ""{}END PROC std graphic char;{}PROC ft20 graphic char:{} ecke oben links (""27"R�"27"S"); ecke oben rechts (""27"RD"27"S");{} ecke unten links (""27"RH"27"S"); ecke unten rechts (""27"RL"27"S");{}
+ balken oben (""27"RP"27"S"); balken rechts (""27"RT"27"S");{} balken links (""27"RX"27"S"); balken unten (""27"R\"27"S");{} waagerecht (""27"R`"27"S"); senkrecht (""27"Rd"27"S");{} kreuz (""27"Rh"27"S");{} cursor sichtbar := ""27"-1" ; cursor unsichtbar := ""27"-0" ;{} ft20 statuszeilen aus{}END PROC ft20 graphic char;{}PROC ft 20 statuszeilen aus: out (""27".A") END PROC ft 20 statuszeilen aus;{}PROC ft 20 statuszeilen an : out (""27".�") END PROC ft 20 statuszeilen an ;{}
+PROC ibm graphic char:{} ecke oben links (""201""); ecke oben rechts (""187"");{} ecke unten links (""200""); ecke unten rechts (""188"");{} balken oben (""203""); balken rechts (""185"");{} balken links (""204""); balken unten (""202"");{} waagerecht (""205""); senkrecht (""186"");{} kreuz (""206"");{} cursor sichtbar := "" ; cursor unsichtbar := ""{}END PROC ibm graphic char;{}PROC cursor on : out (cursor sichtbar ) END PROC cursor on ;{}
+PROC cursor off : out (cursor unsichtbar) END PROC cursor off;{}PROC cursor on (TEXT CONST t): cursor sichtbar := t END PROC cursor on ;{}PROC cursor off (TEXT CONST t): cursor unsichtbar := t END PROC cursor off;{}PROC clear buffer:{} REP UNTIL incharety = "" PER{}END PROC clear buffer;{}INT PROC clear buffer and count (TEXT CONST zeichen):{} INT VAR zaehler :: 0;{} TEXT VAR zeichenkette :: "", ch;{} IF zeichen = "" THEN clear buffer; LEAVE clear buffer and count WITH 0 FI;{}
+ ermittle die zeichenkette;{} untersuche auf vorhandene zeichen;{} zaehler.{} ermittle die zeichenkette:{} REP{} ch := incharety (1);{} zeichenkette CAT ch{} UNTIL ch = "" PER.{} untersuche auf vorhandene zeichen:{} INT VAR i;{} FOR i FROM 1 UPTO length (zeichenkette) REP{} IF pos (subtext (zeichenkette, i), zeichen) = 1{} THEN zaehler INCR 1{} FI{} PER.{}END PROC clear buffer and count;{}TEXT PROC center (INT CONST xsize, TEXT CONST t):{} TEXT VAR zeile :: compress (t);{}
+ zeile := ((xsize - length (zeile)) DIV 2) * blank + zeile;{} zeile CAT (xsize - length (zeile)) * blank;{} zeile{}END PROC center;{}TEXT PROC center (TEXT CONST t):{} center (79, t){}END PROC center;{}TEXT PROC invers (TEXT CONST t):{} TEXT VAR neu :: mark ein; neu CAT t; neu CAT " "; neu CAT mark aus;{} neu{}END PROC invers;{}PROC page (INT CONST x, y, xsize, ysize):{} INT VAR zeiger;{} IF x + xsize = 80{} THEN in einem streich{} ELSE putze vorsichtig{} FI;{} cursor (x, y).{}
+ in einem streich:{} FOR zeiger FROM y UPTO y + ysize - 1 REP{} cursor (x, zeiger); out (cleol){} PER.{} putze vorsichtig:{} FOR zeiger FROM y UPTO y + ysize - 1 REP{} cursor (x, zeiger); xsize TIMESOUT blank{} PER.{}END PROC page;{}PROC page (AREA CONST a):{} page (a.x, a.y, a.xsize, a.ysize){}END PROC page;{}PROC page up (INT CONST x, y, xsize, ysize):{} INT VAR zeiger;{} IF x + xsize = 80{} THEN in einem streich{} ELSE putze vorsichtig{}
+ FI.{} in einem streich:{} FOR zeiger FROM y + ysize - 1 DOWNTO y REP{} cursor (x, zeiger); out (cleol){} PER.{} putze vorsichtig:{} FOR zeiger FROM y + ysize - 1 DOWNTO y REP{} cursor (x, zeiger); xsize TIMESOUT blank{} PER.{}END PROC page up;{}PROC page up (AREA CONST a):{} page up (a.x, a.y, a.xsize, a.ysize){}END PROC page up;{}PROC out frame (INT CONST x, y, xsize, ysize):{} INT VAR zeiger;{} IF x < 1 COR y < 1 COR xsize < 8 COR ysize < 3 COR{} x + xsize > 80 COR y + ysize > 25{}
+ THEN LEAVE out frame{} FI;{} male oben;{} male seiten;{} male unten.{} male oben:{} cursor (x, y);{} out (ecke oben links);{} (xsize - 2) TIMESOUT waagerecht;{} out (ecke oben rechts).{} male seiten:{} FOR zeiger FROM 1 UPTO ysize - 2 REP{} cursor (x, y + zeiger); out (senkrecht);{} cursor (x + xsize - 1, y + zeiger); out (senkrecht){} PER.{} male unten:{} cursor (x, y + ysize - 1);{} out (ecke unten links);{} (xsize - 2) TIMESOUT waagerecht;{}
+ out (ecke unten rechts){}END PROC out frame;{}PROC out frame (AREA CONST a):{} IF a.x - 1 < 1 OR a.y - 1 < 1{} OR a.xsize + 2 > 79 OR a.ysize + 2 > 24{} OR a.x + a.xsize + 1 > 80{} OR a.y + a.ysize + 1 > 25{} THEN LEAVE out frame{} FI;{} out frame (a.x - 1, a.y - 1, a.xsize + 2, a.ysize + 2){}END PROC out frame;{}PROC out menuframe (INT CONST x, y, xsize, ysize):{} INT VAR i;{} untersuche angaben;{} schreibe rahmen.{} untersuche angaben:{} IF x < 0 COR y < 0 COR x + xsize > 81 COR y + ysize > 26{}
+ THEN LEAVE out menuframe{} FI.{} schreibe rahmen:{} IF x = 0 COR y = 0 COR xsize = 81 COR ysize = 26{} THEN zeichne reduzierten rahmen{} ELSE zeichne vollen rahmen{} FI.{} zeichne reduzierten rahmen:{} zeichne oberlinie;{} zeichne unterlinie.{} zeichne oberlinie:{} cursor (1, 2);{} 79 TIMESOUT waagerecht.{} zeichne unterlinie:{} cursor (1, 23);{} 79 TIMESOUT waagerecht.{} zeichne vollen rahmen:{} schreibe kopf; schreibe rumpf; schreibe fuss;{}
+ schreibe kopfleiste; schreibe fussleiste.{} schreibe kopf:{} cursor (x, y);{} out (ecke oben links);{} (xsize - 2) TIMESOUT waagerecht;{} out (ecke oben rechts).{} schreibe rumpf:{} FOR i FROM y + 1 UPTO y + ysize - 2 REP{} cursor (x, i); out (senkrecht);{} cursor (x + xsize - 1, i); out (senkrecht){} PER.{} schreibe fuss:{} cursor (x, y + ysize - 1);{} out (ecke unten links);{} (xsize - 2) TIMESOUT waagerecht;{} out (ecke unten rechts).{}
+ schreibe kopfleiste:{} cursor (x, y + 2 ); schreibe balkenlinie.{} schreibe fussleiste:{} cursor (x, y + ysize - 3); schreibe balkenlinie.{} schreibe balkenlinie:{} out (balken links); (xsize - 2) TIMESOUT waagerecht; out (balken rechts).{}END PROC out menuframe;{}PROC out menuframe (AREA CONST a):{} out menuframe (a.x - 1, a.y - 1, a.xsize + 2, a.ysize + 2){}END PROC out menuframe;{}PROC erase frame (INT CONST x, y, xsize, ysize):{} INT VAR zeiger;{} loesche oben; loesche seiten; loesche unten.{}
+ loesche oben:{} cursor (x, y); xsize TIMESOUT blank.{} loesche seiten:{} FOR zeiger FROM 1 UPTO ysize - 2 REP{} cursor (x, y + zeiger); out (blank);{} cursor (x + xsize - 1, y + zeiger); out (blank){} PER.{} loesche unten:{} cursor (x, y + ysize - 1); xsize TIMESOUT blank.{}END PROC erase frame;{}OP := (AREA VAR ziel, AREA CONST quelle):{} CONCR (ziel) := CONCR (quelle){}END OP :=;{}PROC fill (AREA VAR ziel, INT CONST a, b, c, d):{} IF a < 1 COR b < 1 COR a > 79 COR b > 24 COR c < 8 COR d < 3{}
+ COR c > 79 COR d > 24 COR a + c > 80 COR b + d > 25{} THEN errorstop (fehlermeldung){} FI;{} ziel.x := a; ziel.y := b; ziel.xsize := c; ziel.ysize := d{}END PROC fill;{}INT PROC areax (AREA CONST a): a.x END PROC areax;{}INT PROC areay (AREA CONST a): a.y END PROC areay;{}INT PROC areaxsize (AREA CONST a): a.xsize END PROC areaxsize;{}INT PROC areaysize (AREA CONST a): a.ysize END PROC areaysize;{}PROC out (TEXT CONST t, INT CONST breite):{} outtext (t, 1, breite){}
+END PROC out;{}PROC erase (INT CONST breite):{} breite TIMESOUT blank{}END PROC erase;{}PROC cursor (AREA CONST a, INT CONST spa, zei):{} cursor (a.x + spa - 1, a.y + zei - 1){}END PROC cursor;{}PROC get cursor (AREA CONST a, INT VAR spalte, zeile):{} INT VAR x, y;{} get cursor (x, y);{} spalte := x - a.x + 1; zeile := y - a.y + 1{}END PROC get cursor;{}PROC out (AREA CONST a, INT CONST spa, zei, TEXT CONST t):{} ueberpruefe cursorangaben; positioniere cursor;{} IF text ist zu lang{} THEN verkuerzte ausgabe{}
+ ELSE out (t){} FI.{} ueberpruefe cursorangaben:{} IF spa > xsize COR zei > a.ysize COR spa < 1 COR zei < 1{} THEN LEAVE out{} FI.{} positioniere cursor:{} cursor (a.x + spa - 1, a.y + zei - 1).{} text ist zu lang:{} length (t) > a.xsize - spa + 1.{} verkuerzte ausgabe:{} outsubtext (t, 1, a.xsize - spa + 1){}END PROC out;{}PROC out (AREA CONST a, INT CONST spa, zei, TEXT CONST t, INT CONST laenge):{} ueberpruefe cursorangaben; positioniere cursor;{} IF laenge ist zu gross{}
+ THEN verkuerzte ausgabe{} ELSE outtext (t, 1, laenge){} FI.{} ueberpruefe cursorangaben:{} IF spa > a.xsize COR zei > a.ysize COR spa < 1 COR zei < 1{} THEN LEAVE out{} FI.{} positioniere cursor:{} cursor (a.x + spa - 1, a.y + zei - 1).{} laenge ist zu gross:{} laenge > a.xsize - spa + 1.{} verkuerzte ausgabe:{} outtext (t, 1, a.xsize - spa + 1){}END PROC out;{}PROC erase (AREA CONST a, INT CONST spa, zei, INT CONST laenge):{} ueberpruefe cursorangaben; positioniere cursor;{}
+ IF laenge ist zu gross{} THEN verkuerzte ausgabe{} ELSE erase (laenge){} FI.{} ueberpruefe cursorangaben:{} IF spa > a.xsize COR zei > a.ysize COR spa < 1 COR zei < 1{} THEN LEAVE erase{} FI.{} positioniere cursor:{} cursor (a.x + spa - 1, a.y + zei - 1).{} laenge ist zu gross:{} laenge > a.xsize - spa + 1.{} verkuerzte ausgabe:{} erase (a.xsize - spa + 1){}END PROC erase;{}PROC out invers (AREA CONST a, INT CONST spa, zei, TEXT CONST t):{} ueberpruefe cursorangaben; positioniere cursor;{}
+ IF text ist zu lang{} THEN verkuerzte ausgabe{} ELSE out (mark ein); out (t); out (blank); out (mark aus){} FI.{} ueberpruefe cursorangaben:{} IF spa > (xsize - 4) COR zei > ysize COR spa < 2 COR zei < 1{} THEN LEAVE out invers{} FI.{} positioniere cursor:{} cursor (a.x + spa - 2, a.y + zei - 1).{} text ist zu lang:{} length (t) > a.xsize - spa - 1.{} verkuerzte ausgabe:{} out (mark ein); outsubtext (t, 1, a.xsize - spa - 1);{} out (blank); out (mark aus){}END PROC out invers;{}
+PROC out invers (AREA CONST a, INT CONST spa, zei,{} TEXT CONST t, INT CONST laenge):{} ueberpruefe cursorangaben; positioniere cursor;{} IF laenge ist zu gross{} THEN verkuerzte ausgabe{} ELSE out (mark ein); outtext (t, 1, laenge); out (blank); out (mark aus){} FI.{} ueberpruefe cursorangaben:{} IF spa > (a.xsize - 4) COR zei > a.ysize COR spa < 2 COR zei < 1{} THEN LEAVE out invers{} FI.{} positioniere cursor:{} cursor (a.x + spa - 2, a.y + zei - 1).{}
+ laenge ist zu gross:{} laenge > a.xsize - spa - 1.{} verkuerzte ausgabe:{} out (mark ein); outsubtext (t, 1, a.xsize - spa - 1);{} out (blank); out (mark aus){}END PROC out invers;{}PROC erase invers (AREA CONST a, INT CONST spa, zei, INT CONST laenge):{} ueberpruefe cursorangaben; positioniere cursor;{} IF laenge ist zu gross{} THEN verkuerzte ausgabe{} ELSE erase (laenge + 3){} FI.{} ueberpruefe cursorangaben:{} IF spa > (a.xsize - 4) COR zei > a.ysize COR spa < 2 COR zei < 1{}
+ THEN LEAVE erase invers{} FI.{} positioniere cursor:{} cursor (a.x + spa - 2, a.y + zei - 1).{} laenge ist zu gross:{} laenge > a.xsize - spa - 1.{} verkuerzte ausgabe:{} erase ( a.xsize - spa + 2).{}END PROC erase invers;{}PROC out with beam (AREA CONST a, INT CONST spa, zei, TEXT CONST t):{} ueberpruefe cursorangaben; positioniere cursor;{} IF text ist zu lang{} THEN verkuerzte ausgabe{} ELSE out (senkrecht); out (blank); out (blank);{} out (t);{} out (blank); out (blank); out (senkrecht){}
+ FI.{} ueberpruefe cursorangaben:{} IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{} THEN LEAVE out with beam{} FI.{} positioniere cursor:{} cursor (a.x + spa - 4, a.y + zei - 1).{} text ist zu lang:{} length (t) > a.xsize - spa - 2.{} verkuerzte ausgabe:{} out (senkrecht); out (blank); out (blank);{} outsubtext (t, 1, a.xsize - spa - 2);{} out (blank); out (blank); out (senkrecht){}END PROC out with beam;{}PROC out with beam (AREA CONST a, INT CONST spa, zei,{}
+ TEXT CONST t, INT CONST laenge):{} ueberpruefe cursorangaben; positioniere cursor;{} IF laenge ist zu gross{} THEN verkuerzte ausgabe{} ELSE out (senkrecht); out (blank); out (blank);{} outtext (t, 1,laenge);{} out (blank); out (blank); out (senkrecht){} FI.{} ueberpruefe cursorangaben:{} IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{} THEN LEAVE out with beam{} FI.{} positioniere cursor:{} cursor (a.x + spa - 4, a.y + zei - 1).{}
+ laenge ist zu gross:{} laenge > a.xsize - spa - 2.{} verkuerzte ausgabe:{} out (senkrecht); out (blank); out (blank);{} outsubtext (t, 1, a.xsize - spa - 2);{} out (blank); out (blank); out (senkrecht){}END PROC out with beam;{}PROC erase with beam (AREA CONST a, INT CONST spa, zei, INT CONST laenge):{} ueberpruefe cursorangaben; positioniere cursor;{} IF laenge ist zu gross{} THEN verkuerzte ausgabe{} ELSE erase (laenge + 6){} FI.{} ueberpruefe cursorangaben:{} IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{}
+ THEN LEAVE erase with beam{} FI.{} positioniere cursor:{} cursor (a.x + spa - 4, a.y + zei - 1).{} laenge ist zu gross:{} laenge > a.xsize - spa - 2.{} verkuerzte ausgabe:{} erase (a.xsize - spa + 4).{}END PROC erase with beam;{}PROC out invers with beam (AREA CONST a, INT CONST spa, zei, TEXT CONST t):{} ueberpruefe cursorangaben; positioniere cursor;{} IF text ist zu lang{} THEN verkuerzte ausgabe{} ELSE out (senkrecht); out (blank); out (mark ein);{} out (t);{}
+ out (blank); out (mark aus); out (senkrecht){} FI.{} ueberpruefe cursorangaben:{} IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{} THEN LEAVE out invers with beam{} FI.{} positioniere cursor:{} cursor (a.x + spa - 4, a.y + zei - 1).{} text ist zu lang:{} length (t) > a.xsize - spa - 2.{} verkuerzte ausgabe:{} out (senkrecht); out (blank); out (mark ein);{} outsubtext (t, 1, a.xsize - spa - 2);{} out (blank); out (mark aus); out (senkrecht){}
+END PROC out invers with beam;{}PROC out invers with beam (AREA CONST a, INT CONST spa, zei,{} TEXT CONST t, INT CONST laenge):{} ueberpruefe cursorangaben; positioniere cursor;{} IF laenge ist zu gross{} THEN verkuerzte ausgabe{} ELSE out (senkrecht); out (blank); out (mark ein);{} outtext (t, 1, laenge);{} out (blank); out (mark aus); out (senkrecht){} FI.{} ueberpruefe cursorangaben:{} IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{}
+ THEN LEAVE out invers with beam{} FI.{} positioniere cursor:{} cursor (a.x + spa - 4, a.y + zei - 1).{} laenge ist zu gross:{} laenge > a.xsize - spa - 2.{} verkuerzte ausgabe:{} out (senkrecht); out (blank); out (mark ein);{} outsubtext (t, 1, a.xsize - spa - 2);{} out (blank); out (mark aus); out (senkrecht){}END PROC out invers with beam;{}END PACKET ls dialog 1;{}
+
diff --git a/dialog/ls-DIALOG 2 b/dialog/ls-DIALOG 2
new file mode 100644
index 0000000..1750162
--- /dev/null
+++ b/dialog/ls-DIALOG 2
@@ -0,0 +1,77 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG 2 **
+ ** **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+PACKET ls dialog 2 DEFINES
+ some,{} one,{} infix namen,{} ohne praefix,{} not empty:{}LET maxentries = 200;{}LET zeichenstring = ""1""27""3""10""13""12"xo?",{} oben unten return rubout kreuz kringel = ""3""10""13""12"xo",{} q eins neun h = "q19h";{}LET zurueck = ""8"",{} piep = ""7"";{}LET hop = 1,{} esc = 2,{} oben = 3,{} unten = 4,{} return = 5,{} rubout = 6,{}
+ kreuz = 7,{} kringel = 8,{} frage = 9;{}LET punkt = ".",{} gleich = "=",{} blank = " ";{}INT VAR x,{} y,{} xsize,{} ysize,{} maxeintraege,{} anzahl,{} erste auswahlzeile,{} virtueller cursor,{} reeller cursor;{}TEXT VAR kennzeile 1,{} kennzeile 2,{} registrierkette :: "";{}BOOL VAR abbruch,{} auswahlende;{}BOUND ROW max entries TEXT VAR eintrag;{}ROW 2 TEXT CONST fehlermeldung :: ROW 2 TEXT : ({}
+ "Unzulässige Cursorwerte bei der Auswahl",{} "Fenster für Auswahl zu klein (x < 56 / y < 15)");{}ROW 24 TEXT CONST hinweis :: ROW 24 TEXT : ({} " Bitte warten... Ich sortiere und räume auf!",{} " Info: <?> Fertig: <ESC><q> Abbrechen: <ESC><h>",{} " Zum Weitermachen bitte irgendeine Taste tippen!",{} "Weitere Dateien!",{} "INFORMATIONEN: Auswahl mehrerer Dateien",{} "INFORMATIONEN: Auswahl einer Datei",{} " "15"Positionierungen: "14"",{} " hoch : zum vorausgehenden Namen",{}
+ " runter : zum folgenden Namen",{} " HOP hoch : auf den ersten Namen der Seite", (***********){} " HOP runter : auf den letzten Namen der Seite", (* bitte *){} " ESC 1 : auf den ersten Namen der Liste", (* diese *){} " ESC 9 : auf den letzten Namen der Liste", (* Länge *){} " "15"Auswahl treffen: "14"", (* nicht *){} " RETURN / x : diesen Namen ankreuzen ", (* über- *){}
+ " RUBOUT / o : Kreuz vor dem Namen loeschen", (* schrei-*){} " HOP RETURN / HOP x : alle folgende Namen ankreuzen", (* ten! *){} " HOP RUBOUT / HOP o : alle folgende Kreuze loeschen", (***********){} " "15"Auswahl verlassen: "14"",{} " ESC q : Auswahl verlassen",{} " ESC h : Auswahl abbrechen",{} " Auswahl m e h r e r e r Dateien durch Ankreuzen",{} " Auswahl e i n e r Datei durch Ankreuzen",{} " Bitte warten... Ich breche die Auswahl ab!"{}
+ );{}THESAURUS PROC auswahl (THESAURUS CONST t,{} BOOL CONST mehrere moeglich,{} TEXT CONST t1, t2):{} werte initialisieren;{} namen besorgen;{} bildschirm aufbauen;{} auswaehlen lassen;{} abgang vorbereiten.{} werte initialisieren:{} THESAURUS VAR ausgabe :: empty thesaurus;{} DATASPACE VAR ds := nilspace;{} eintrag := ds;{} kennzeile 1 := t1;{} kennzeile 2 := t2;{} abbruch := FALSE;{}
+ erste auswahlzeile := y + 7;{} anzahl := 0;{} maxeintraege := ysize - 11;{} virtueller cursor := 1;{} reeller cursor := 1.{} namen besorgen:{} fische die namen aus dem thesaurus;{} IF kein eintrag vorhanden{} THEN LEAVE auswahl WITH ausgabe{} FI.{} bildschirm aufbauen:{} schreibe kopfzeile;{} gib hinweis aus (kennzeile 1, kennzeile 2);{} gib erklaerungszeile aus (mehrere moeglich);{} baue bildschirm auf (1);{} footnote (x, y, xsize, ysize, hinweis [2]);{}
+ schreibe fusszeile;{} reellen cursor setzen .{} schreibe kopfzeile:{} cursor (x, y);{} out(ecke oben links);{} (xsize - 2) TIMESOUT waagerecht;{} out(ecke oben rechts).{} schreibe fusszeile:{} cursor (x, y + ysize - 1);{} out (ecke unten links);{} (xsize - 2) TIMESOUT waagerecht;{} out (ecke unten rechts).{} auswaehlen lassen:{} kreuze an (mehrere moeglich).{} abgang vorbereiten:{} IF abbruch{} THEN change footnote (x, y, xsize, ysize, hinweis [24]){}
+ ELSE change footnote (x, y, xsize, ysize, hinweis [ 1]){} FI;{} cursor (x + 1, y + ysize - 1);{} ausgabe erzeugen;{} forget (ds);{} ausgabe.{} fische die namen aus dem thesaurus:{} INT VAR zeiger;{} FOR zeiger FROM 1 UPTO highest entry (t) REP{} IF name (t, zeiger) <> ""{} THEN anzahl INCR 1;{} eintrag [anzahl] := name (t, zeiger){} FI{} PER.{} kein eintrag vorhanden:{} anzahl = 0.{} ausgabe erzeugen:{} TEXT VAR nummer;{} WHILE registrierkette <> "" REP{}
+ nummer := subtext (registrierkette, 1, 3);{} registrierkette := subtext (registrierkette, 5);{} insert (ausgabe, eintrag [ int (nummer)]){} PER.{}END PROC auswahl;{}PROC reellen cursor setzen:{} cursor (x + 1, erste auswahlzeile + reeller cursor - 1);{} out (marke (virtueller cursor, TRUE) + (8 * zurueck)){}END PROC reellen cursor setzen;{}PROC baue bildschirm auf (INT CONST anfang):{} gib kopfzeile aus;{} gib namenstabelle aus;{} gib fusszeile aus;{} loesche ggf restbereich.{}
+ gib kopfzeile aus:{} cursor (x, erste auswahlzeile - 1); out (senkrecht);{} IF reeller cursor = virtueller cursor{} THEN (xsize - 2) TIMESOUT punkt{} ELSE (xsize - length (hinweis [4]) - 5) TIMESOUT punkt;{} out (invers (hinweis [4])){} FI;{} out (senkrecht);{} line.{} gib namenstabelle aus:{} INT VAR zeiger, zaehler :: -1;{} FOR zeiger FROM anfang UPTO grenze REP{} zaehler INCR 1;{} cursor (x, erste auswahlzeile + zaehler);{} out (senkrecht); out (marke (zeiger, FALSE));{}
+ outtext (subtext (eintrag [zeiger], 1, xsize - 10), 1, xsize - 10);{} out (senkrecht);{} PER.{} gib fusszeile aus:{} cursor (x, erste auswahlzeile + zaehler + 1);{} out (senkrecht);{} IF NOT ((virtueller cursor + maxeintraege - reeller cursor) < anzahl){} THEN (xsize - 2) TIMESOUT punkt{} ELSE (xsize - length (hinweis [4]) - 5) TIMESOUT punkt;{} out (invers (hinweis [4])){} FI;{} out (senkrecht).{} loesche ggf restbereich:{} IF zaehler + 1 < maxeintraege{}
+ THEN loesche bildschirmrest{} FI.{} loesche bildschirmrest:{} FOR zeiger FROM restanfang UPTO restende REP{} cursor (x, zeiger); out (senkrecht);{} (xsize - 2) TIMESOUT blank;{} out (senkrecht){} PER.{} restanfang:{} erste auswahlzeile + zaehler + 2.{} restende:{} erste auswahlzeile + maxeintraege.{} grenze:{} min (anzahl, anfang + max eintraege - 1).{}END PROC baue bildschirm auf;{}TEXT PROC marke (INT CONST zeiger, BOOL CONST mit cursor):{}
+ INT VAR platz := nr (zeiger);{} IF platz = 0{} THEN leer{} ELSE mit zahl{} FI.{} mit zahl:{} IF mit cursor{} THEN "==>" + (3 - length (text (platz))) * blank + text (platz) + "x "{} ELSE " " + (3 - length (text (platz))) * blank + text (platz) + "x "{} FI.{} leer:{} IF mit cursor{} THEN "==> o "{} ELSE " o "{} FI.{}END PROC marke;{}INT PROC nr (INT CONST zeiger):{} IF pos (registrierkette, textstring (zeiger)) = 0{} THEN 0{} ELSE (pos (registrierkette, textstring (zeiger)) DIV 4) + 1{}
+ FI{}END PROC nr;{}TEXT PROC textstring (INT CONST nr):{} text (nr, 3) + "!"{}END PROC textstring;{}PROC info (BOOL CONST mehrere):{} notiere hinweisueberschrift;{} notiere positionierhinweise;{} IF noch platz vorhanden{} THEN notiere auswahlmoeglichkeiten auf alter seite{} ELSE wechsle auf naechste seite;{} notiere hinweisueberschrift;{} notiere auswahlmoeglichtkeiten auf neuer seite{} FI;{} stelle alten bildschirmzustand wieder her.{} notiere hinweisueberschrift:{}
+ cursor (x + 1, y + 1);{} IF mehrere{} THEN out (center(xsize - 2, invers (hinweis [5]))){} ELSE out (center(xsize - 2, invers (hinweis [6]))){} FI;{} cursor (x + 1, y + 2); out ("", xsize - 2).{} notiere positionierhinweise:{} cursor (x + 1, y + 3); out (hinweis [ 7], xsize - 2);{} cursor (x + 1, y + 4); out (hinweis [ 8], xsize - 2);{} cursor (x + 1, y + 5); out (hinweis [ 9], xsize - 2);{} cursor (x + 1, y + 6); out (hinweis [10], xsize - 2);{} cursor (x + 1, y + 7); out (hinweis [11], xsize - 2);{}
+ cursor (x + 1, y + 8); out (hinweis [12], xsize - 2);{} cursor (x + 1, y + 9); out (hinweis [13], xsize - 2).{} notiere auswahlmoeglichkeiten auf alter seite:{} cursor (x + 1, y + 10); out ("", xsize - 2);{} cursor (x + 1, y + 11); out (hinweis [14], xsize - 2);{} cursor (x + 1, y + 12); out (hinweis [15], xsize - 2);{} IF mehrere{} THEN gib alle auswahlmoeglichkeiten auf der alten seite an{} ELSE gib eine auswahlmoeglichkeit auf der alten seite an{} FI;{}
+ notiere verlassmoeglichkeiten auf der alten seite;{} loesche die restlichen zeilen;{} change footnote (x, y, xsize, ysize, hinweis [3]);{} cursor in ruhestellung;{} clear buffer.{} gib alle auswahlmoeglichkeiten auf der alten seite an:{} cursor (x + 1, y + 13); out (hinweis [16], xsize - 2);{} cursor (x + 1, y + 14); out (hinweis [17], xsize - 2);{} cursor (x + 1, y + 15); out (hinweis [18], xsize - 2).{} gib eine auswahlmoeglichkeit auf der alten seite an:{} cursor (x + 1, y + 13); out ("", xsize - 2);{}
+ cursor (x + 1, y + 14); out ("", xsize - 2);{} cursor (x + 1, y + 15); out ("", xsize - 2).{} notiere verlassmoeglichkeiten auf der alten seite:{} cursor (x + 1, y + 16); out ("", xsize - 2);{} cursor (x + 1, y + 17); out (hinweis [19], xsize - 2);{} cursor (x + 1, y + 18); out (hinweis [20], xsize - 2);{} cursor (x + 1, y + 19); out (hinweis [21], xsize - 2).{} loesche die restlichen zeilen:{} IF ysize = 24{} THEN cursor (x + 1, y + 20); out ("", xsize - 2){} FI.{}
+ wechsle auf naechste seite:{} loesche seitenrest;{} change footnote (x, y, xsize, ysize, hinweis [3]);{} cursor in ruhestellung;{} clear buffer;{} pause.{} loesche seitenrest:{} INT VAR zaehler;{} FOR zaehler FROM 10 UPTO ysize - 4 REP{} cursor (x + 1, y + zaehler); out ("", xsize - 2){} PER.{} notiere auswahlmoeglichtkeiten auf neuer seite:{} cursor (x + 1, y + 3); out (hinweis [14], xsize - 2);{} cursor (x + 1, y + 4); out (hinweis [15], xsize - 2);{} IF mehrere{}
+ THEN gib alle auswahlmoeglichkeiten auf der neuen seite an{} ELSE gib eine auswahlmoeglichkeit auf der neuen seite an{} FI;{} notiere verlassmoeglichkeiten auf der neuen seite.{} gib alle auswahlmoeglichkeiten auf der neuen seite an:{} cursor (x + 1, y + 5); out (hinweis [16], xsize - 2);{} cursor (x + 1, y + 6); out (hinweis [17], xsize - 2);{} cursor (x + 1, y + 7); out (hinweis [18], xsize - 2).{} gib eine auswahlmoeglichkeit auf der neuen seite an:{} cursor (x + 1, y + 5); out ("", xsize - 2);{}
+ cursor (x + 1, y + 6); out ("", xsize - 2);{} cursor (x + 1, y + 7); out ("", xsize - 2).{} notiere verlassmoeglichkeiten auf der neuen seite:{} cursor (x + 1, y + 8); out ("", xsize - 2);{} cursor (x + 1, y + 9); out (hinweis [19], xsize - 2);{} cursor (x + 1, y + 10); out (hinweis [20], xsize - 2);{} cursor (x + 1, y + 11); out (hinweis [21], xsize - 2);{} cursor in ruhestellung.{} cursor in ruhestellung:{} cursor (x + 1, y + ysize - 2).{} stelle alten bildschirmzustand wieder her:{}
+ clear buffer;{} pause;{} gib hinweis aus (kennzeile 1, kennzeile 2);{} gib erklaerungszeile aus (mehrere);{} virtueller cursor := 1;{} reeller cursor := 1;{} baue bildschirm auf (1);{} change footnote (x, y, xsize, ysize, hinweis [2]);{} reellen cursor setzen.{} noch platz vorhanden:{} (ysize - 4) > 18.{}END PROC info;{}PROC kreuze an (BOOL CONST mehrere):{} auswahlende := FALSE;{} REP{} zeichen lesen; zeichen interpretieren{} UNTIL auswahlende PER.{} zeichen lesen:{}
+ TEXT VAR zeichen;{} getchar (zeichen).{} zeichen interpretieren:{} SELECT pos (zeichenstring, zeichen) OF{} CASE hop : hop kommando verarbeiten (mehrere){} CASE esc : esc kommando verarbeiten{} CASE oben : nach oben{} CASE unten : nach unten{} CASE kreuz : ankreuzen; evtl aufhoeren{} CASE return : ankreuzen weiter; evtl aufhoeren{} CASE rubout : auskreuzen weiter{} CASE kringel : auskreuzen{} CASE frage : info (mehrere){}
+ OTHERWISE out (piep){} END SELECT.{} evtl aufhoeren:{} IF NOT mehrere{} THEN LEAVE kreuze an{} FI.{}END PROC kreuze an;{}PROC hop kommando verarbeiten (BOOL CONST mehrere):{} zweites zeichen lesen;{} zeichen interpretieren.{} zweites zeichen lesen:{} TEXT VAR zweites zeichen;{} getchar(zweites zeichen).{} zeichen interpretieren:{} SELECT pos (oben unten return rubout kreuz kringel, zweites zeichen) OF{} CASE 1 : hop nach oben{} CASE 2 : hop nach unten{}
+ CASE 3, 5 : IF mehrere THEN alle darunter ankreuzen FI{} CASE 4, 6 : IF mehrere THEN alle darunter loeschen FI{} OTHERWISE out (piep){} END SELECT.{} alle darunter ankreuzen:{} INT VAR i;{} FOR i FROM virtueller cursor UPTO anzahl REP{} IF nr (i) = 0{} THEN ankreuzen{} FI{} PER;{} bild aktualisieren ;{} reellen cursor setzen .{} ankreuzen:{} registrierkette CAT textstring (i).{} alle darunter loeschen:{} INT VAR j, position;{} FOR j FROM virtueller cursor UPTO anzahl REP{}
+ position := nr (j);{} IF position > 0{} THEN rausschmeissen;{} FI{} PER;{} bild aktualisieren;{} reellen cursor setzen.{} rausschmeissen:{} registrierkette := subtext (registrierkette, 1, (4 * position) - 4) +{} subtext (registrierkette, (4 * position) + 1).{} hop nach oben:{} IF ganz oben{} THEN out (piep){} ELIF oben auf der seite{} THEN raufblaettern{} ELSE top of page{} FI.{} ganz oben:{} virtueller cursor = 1.{}
+ oben auf der seite:{} reeller cursor = 1.{} raufblaettern:{} virtueller cursor DECR max eintraege;{} virtueller cursor := max (virtueller cursor, 1);{} baue bildschirm auf (virtueller cursor);{} reellen cursor setzen.{} top of page:{} loesche marke;{} virtueller cursor DECR (reeller cursor - 1);{} reeller cursor := 1;{} reellen cursor setzen.{} hop nach unten:{} IF ganz unten{} THEN out (piep){} ELIF unten auf der seite{} THEN runterblaettern{}
+ ELSE bottom of page{} FI.{} ganz unten:{} virtueller cursor = anzahl.{} unten auf der seite:{} reeller cursor > max eintraege - 1.{} runterblaettern:{} INT VAR alter virtueller cursor :: virtueller cursor;{} virtueller cursor INCR max eintraege;{} virtueller cursor := min (virtueller cursor, anzahl);{} reeller cursor := virtueller cursor - alter virtueller cursor;{} baue bildschirm auf (alter virtueller cursor + 1);{} reellen cursor setzen.{} bottom of page:{}
+ loesche marke;{} alter virtueller cursor := virtueller cursor;{} virtueller cursor INCR (max eintraege - reeller cursor);{} virtueller cursor := min (anzahl, virtueller cursor);{} reeller cursor INCR (virtueller cursor - alter virtueller cursor);{} reellen cursor setzen.{}END PROC hop kommando verarbeiten;{}PROC esc kommando verarbeiten:{} TEXT VAR zweites zeichen;{} getchar (zweites zeichen);{} SELECT pos (q eins neun h, zweites zeichen) OF{} CASE 1 : auswahlende := TRUE{}
+ CASE 2 : zeige anfang{} CASE 3 : zeige ende{} CASE 4 : abbruch := TRUE;{} auswahlende := TRUE;{} registrierkette := ""{} OTHERWISE out (piep){} END SELECT.{} zeige anfang:{} IF virtueller cursor = 1{} THEN out (piep){} ELIF virtueller cursor = reeller cursor{} THEN loesche marke;{} virtueller cursor := 1;{} reeller cursor := 1;{} reellen cursor setzen{} ELSE virtueller cursor := 1;{}
+ reeller cursor := 1;{} baue bildschirm auf (1);{} reellen cursor setzen{} FI.{} zeige ende:{} IF virtueller cursor = anzahl{} THEN out (piep){} ELIF ende auf bildschirm{} THEN loesche marke;{} reeller cursor INCR (anzahl - virtueller cursor);{} virtueller cursor := anzahl;{} reellen cursor setzen{} ELSE virtueller cursor := anzahl;{} reeller cursor := max eintraege;{}
+ baue bildschirm auf (anzahl - (max eintraege - 1));{} reellen cursor setzen{} FI.{} ende auf bildschirm:{} (reeller cursor + anzahl - virtueller cursor) < max eintraege + 1.{}END PROC esc kommando verarbeiten;{}PROC ankreuzen:{} INT VAR platz :: nr (virtueller cursor);{} IF platz <> 0{} THEN out (piep);{} LEAVE ankreuzen{} FI;{} registrierkette CAT textstring (virtueller cursor);{} reellen cursor setzen{}END PROC ankreuzen;{}PROC ankreuzen weiter:{}
+ INT VAR platz :: nr (virtueller cursor);{} IF platz <> 0{} THEN out (piep);{} LEAVE ankreuzen weiter{} FI;{} registrierkette CAT textstring (virtueller cursor);{} IF virtueller cursor < anzahl{} THEN nach unten{} FI;{} IF virtueller cursor = anzahl{} THEN reellen cursor setzen{} FI{}END PROC ankreuzen weiter;{}PROC auskreuzen weiter:{} INT VAR position :: nr (virtueller cursor);{} IF position = 0{} THEN out (piep);{} LEAVE auskreuzen weiter{} FI;{} rausschmeissen;{}
+ IF virtueller cursor < anzahl{} THEN nach unten{} ELSE loesche marke{} FI;{} bild aktualisieren;{} reellen cursor setzen.{} rausschmeissen:{} registrierkette := subtext (registrierkette, 1, 4 * position - 4) +{} subtext (registrierkette, 4 * position + 1).{}END PROC auskreuzen weiter;{}PROC auskreuzen:{} INT VAR position :: nr (virtueller cursor);{} IF position = 0{} THEN out (piep);{} LEAVE auskreuzen{} FI;{} rausschmeissen;{} loesche marke;{}
+ bild aktualisieren;{} reellen cursor setzen.{} rausschmeissen:{} registrierkette := subtext (registrierkette, 1, 4 * position - 4) +{} subtext (registrierkette, 4 * position + 1).{}END PROC auskreuzen;{}PROC bild aktualisieren:{} INT VAR ob, un, i, zaehler :: -1;{} ob := virtueller cursor - reeller cursor + 1;{} un := min (ob + max eintraege - 1, anzahl);{} FOR i FROM ob UPTO un REP{} zaehler INCR 1;{} cursor (x + 1, erste auswahlzeile + zaehler);{} out (marke (i,FALSE)) PER{}
+END PROC bild aktualisieren;{}PROC nach oben:{} IF noch nicht oben (*virtuell*){} THEN gehe nach oben{} ELSE out (piep){} FI.{} noch nicht oben:{} virtueller cursor > 1.{} gehe nach oben:{} IF reeller cursor = 1 THEN scroll down ELSE cursor up FI.{} scroll down:{} virtueller cursor DECR 1;{} baue bildschirm auf (virtueller cursor);{} reellen cursor setzen.{} cursor up:{} loesche marke;{} virtueller cursor DECR 1;{} reeller cursor DECR 1;{} reellen cursor setzen{}
+END PROC nach oben;{}PROC nach unten:{} IF noch nicht unten (*virtuell*){} THEN gehe nach unten{} ELSE out (piep){} FI.{} noch nicht unten:{} virtueller cursor < anzahl.{} gehe nach unten:{} IF reeller cursor > max eintraege - 1 THEN scroll up ELSE cursor down FI.{} scroll up:{} virtueller cursor INCR 1;{} baue bildschirm auf (virtueller cursor - (max eintraege - 1));{} reellen cursor setzen.{} cursor down:{} loesche marke;{} virtueller cursor INCR 1;{} reeller cursor INCR 1;{}
+ reellen cursor setzen{}END PROC nach unten;{}PROC loesche marke:{} out (marke (virtueller cursor, FALSE)){}END PROC loesche marke;{}PROC footnote (INT CONST x, y, xsize, ysize, TEXT CONST text):{} cursor (x, y + ysize - 3);{} out (balken links); (xsize - 2) TIMESOUT waagerecht; out (balken rechts);{} change footnote (x, y, xsize, ysize, text){}END PROC footnote;{}PROC change footnote (INT CONST x, y, xsize, ysize, TEXT CONST text):{} cursor (x, y + ysize - 2);{} out (senkrecht); outtext (text, 1, xsize - 2); out (senkrecht){}
+END PROC change footnote;{}PROC gib hinweis aus (TEXT CONST t1, t2):{} cursor (x, y + 1); out (senkrecht);{} out (center (xsize - 2, invers (t1)));{} out (senkrecht);{} cursor (x, y + 2); out (senkrecht);{} out ("", xsize - 2);{} out (senkrecht);{} cursor (x, y + 3); out (senkrecht);{} out (center (xsize - 2, t2));{} out (senkrecht){}END PROC gib hinweis aus;{}PROC gib erklaerungszeile aus (BOOL CONST mehrere):{}
+ cursor (x, y + 4); out (senkrecht);{} out ((xsize - 2) * gleich);{} out (senkrecht);{} cursor (x, y + 5); out (senkrecht);{} IF mehrere{} THEN out (erklaerungszeile mehrere){} ELSE out (erklaerungszeile eine){} FI;{} out (senkrecht).{} erklaerungszeile mehrere:{} invers (text 1 + (rest1 * blank)).{} erklaerungszeile eine:{} invers (text 2 + (rest2 * blank)).{}
+ text1:{} hinweis [22].{} text2:{} hinweis [23].{} rest1: (***************************){} xsize - length (text1) - 5. (* durch 'invers' wird ein *){} (* Blank angehängt und zu- *){} rest2: (* sätzlich noch durch *){} xsize - length (text2) - 5. (* 'relativcenter' - außer-*){}END PROC gib erklaerungszeile aus; (* dem nimmt die Markierung*){} (* selbst eine Position ein*){}
+ (***************************){}THESAURUS PROC infix namen (THESAURUS CONST t, TEXT CONST infix):{} THESAURUS VAR tt :: empty thesaurus;{} INT VAR i;{} FOR i FROM 1 UPTO highest entry (t) REP{} TEXT VAR eintrag :: name (t,i);{} IF eintrag enthaelt infix{} THEN insert (tt, eintrag){} FI{} PER;{} tt.{} eintrag enthaelt infix:{} pos (eintrag, infix) <> 0{}END PROC infix namen;{}THESAURUS PROC infix namen (THESAURUS CONST t, INT CONST dateityp):{}
+ THESAURUS VAR tt :: empty thesaurus;{} INT VAR i;{} FOR i FROM 1 UPTO highest entry (t) REP{} TEXT VAR eintrag :: name (t,i);{} IF eintrag enthaelt infix{} THEN insert (tt, eintrag){} FI{} PER;{} tt.{} eintrag enthaelt infix:{} type (old (eintrag)) = dateityp.{}END PROC infix namen;{}THESAURUS PROC infix namen (THESAURUS CONST t,{} TEXT CONST infix 1, INT CONST dateityp):{} THESAURUS VAR tt :: empty thesaurus;{} INT VAR i;{} FOR i FROM 1 UPTO highest entry (t) REP{}
+ TEXT VAR eintrag :: name (t,i);{} IF eintrag enthaelt infix{} THEN insert (tt, eintrag){} FI{} PER;{} tt.{} eintrag enthaelt infix:{} (pos (eintrag, infix 1) <> 0) AND (type (old (eintrag)) = dateityp).{}END PROC infix namen;{}THESAURUS PROC infix namen (THESAURUS CONST t,{} TEXT CONST infix 1, infix 2):{} THESAURUS VAR tt :: empty thesaurus;{} INT VAR i;{} FOR i FROM 1 UPTO highest entry (t) REP{} TEXT VAR eintrag :: name (t,i);{} IF eintrag enthaelt infix{}
+ THEN insert (tt, eintrag){} FI{} PER;{} tt.{} eintrag enthaelt infix:{} (pos (eintrag, infix 1) <> 0) OR (pos (eintrag, infix 2) <> 0){}END PROC infix namen;{}THESAURUS PROC infix namen (TEXT CONST infix):{} infix namen (ALL myself, infix){}END PROC infix namen;{}THESAURUS PROC infix namen (TEXT CONST infix 1, infix 2):{} infix namen (ALL myself, infix 1, infix 2){}END PROC infix namen;{}THESAURUS PROC ohne praefix (THESAURUS CONST thesaurus, TEXT CONST praefix):{} THESAURUS VAR t :: empty thesaurus;{}
+ INT VAR zaehler;{} FOR zaehler FROM 1 UPTO highest entry (thesaurus) REP{} IF name (thesaurus, zaehler) <> ""{} AND pos (name (thesaurus, zaehler), praefix) = 1{} THEN insert (t, subtext (name (thesaurus, zaehler),{} length (praefix) + 1)){} FI;{} PER;{} t{}END PROC ohne praefix;{}BOOL PROC not empty (THESAURUS CONST t):{} INT VAR i;{} FOR i FROM 1 UPTO highest entry (t) REP{} IF name (t, i) <> ""{} THEN LEAVE not empty WITH TRUE{}
+ FI{} PER;{} FALSE{}END PROC not empty;{}PROC untersuche bildschirmmasszahlen (TEXT CONST t1, t2):{} IF unzulaessige cursorwerte{} THEN errorstop (fehlermeldung [1]){} ELIF fenster ist zu klein{} THEN errorstop (fehlermeldung [2]){} FI.{} unzulaessige cursorwerte:{} (x + xsize) > 80 COR (y + ysize) > 25 COR x < 1 COR y < 1{} COR xsize > 79 COR ysize > 24.{} fenster ist zu klein:{} (xsize) < 56 COR (ysize) < 15{} COR length (t1) > (xsize - 5) COR length (t2) > (xsize - 5).{}
+END PROC untersuche bildschirmmasszahlen;{}TEXT PROC ggf gekuerzter text (TEXT CONST text):{} IF length (text) > (xsize - 5){} THEN subtext (text, 1, xsize - 7) + ".."{} ELSE text{} FI{}END PROC ggf gekuerzter text;{}THESAURUS PROC some (INT CONST spa, zei, breite, hoehe,{} THESAURUS CONST t,{} TEXT CONST t1, t2):{} TEXT VAR text 1, text 2;{} x := spa;{} y := zei;{} xsize := breite;{} ysize := hoehe;{} text 1 := ggf gekuerzter text (t1);{}
+ text 2 := ggf gekuerzter text (t2);{} untersuche bildschirmmasszahlen (text 1, text 2);{} auswahl (t, TRUE, text 1, text 2){}END PROC some;{}THESAURUS PROC some (INT CONST spa, zei,{} THESAURUS CONST t,{} TEXT CONST t1, t2):{} some (spa, zei, 79 - spa + 1, 24 - zei + 1, t, t1, t2){}END PROC some;{}THESAURUS PROC some (THESAURUS CONST t,{} TEXT CONST t1, t2):{} some (1, 1, 79, 24, t, t1, t2){}END PROC some;{}TEXT PROC one (INT CONST spa, zei, breite, hoehe,{}
+ THESAURUS CONST t,{} TEXT CONST t1, t2):{} TEXT VAR text 1, text 2;{} x := spa;{} y := zei;{} xsize := breite;{} ysize := hoehe;{} text 1 := ggf gekuerzter text (t1);{} text 2 := ggf gekuerzter text (t2);{} untersuche bildschirmmasszahlen (text 1, text 2);{} name (auswahl (t, FALSE, text 1, text 2), 1){}END PROC one;{}TEXT PROC one (INT CONST spa, zei,{} THESAURUS CONST t,{} TEXT CONST t1, t2):{} one (spa, zei, 79 - spa + 1, 24 - zei + 1, t, t1, t2){}
+END PROC one;{}TEXT PROC one (THESAURUS CONST t, TEXT CONST t1, t2):{} one (1, 1, 79, 24, t, t1, t2){}END PROC one;{}END PACKET ls dialog 2;{}
+
diff --git a/dialog/ls-DIALOG 3 b/dialog/ls-DIALOG 3
new file mode 100644
index 0000000..dce6507
--- /dev/null
+++ b/dialog/ls-DIALOG 3
@@ -0,0 +1,48 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG 3 **
+ ** **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls dialog 3 DEFINES{} WINDOW, :=, window,{} show, page, erase,{} line, remaining lines,{} cursor, get cursor,{} out frame, out menuframe,{} out, put, putline, editget,{} get, getline, yes, no,{} edit, center, stop,{} area, areax, areay,{} areaxsize, areaysize:{}LET piep = ""7"",{} cr = ""13"";{}LET janeinkette = "jJyYnN",{} blank = " ",{} niltext = "";{}TYPE WINDOW = STRUCT (AREA fenster,{}
+ INT cspalte, czeile, belegbare zeilen,{} BOOL fensterende erreicht);{}ROW 3 TEXT CONST aussage :: ROW 3 TEXT : ({} " 'Window' ungültig!",{} " (j/n) ?",{} " Zum Weitermachen bitte irgendeine Taste tippen!"{} );{}TEXT VAR number word, exit char;{}OP := (WINDOW VAR links, WINDOW CONST rechts):{} CONCR (links) := CONCR (rechts){}END OP :=;{}WINDOW PROC window (INT CONST x, y, xsize, ysize):{} WINDOW VAR w;{} fill (w.fenster, x, y, xsize, ysize);{} IF fenster ungueltig (w){}
+ THEN errorstop (aussage [1]){} FI;{} initialize (w);{} w{}END PROC window;{}PROC initialize (WINDOW VAR w):{} w.czeile := 1;{} w.cspalte := 1;{} w.fensterende erreicht := FALSE;{} w.belegbare zeilen := areaysize (w.fenster){}END PROC initialize;{}BOOL PROC fenster ungueltig (WINDOW CONST w):{} IF areax (w.fenster) < 1 COR areax (w.fenster) > 79{} COR areay (w.fenster) < 1 COR areay (w.fenster) > 24{} COR areaxsize (w.fenster) < 6 COR areaysize (w.fenster) < 3{}
+ COR areax (w.fenster) + areaxsize (w.fenster) > 80{} COR areay (w.fenster) + areaysize (w.fenster) > 25{} THEN TRUE{} ELSE FALSE{} FI.{}END PROC fenster ungueltig;{}PROC show (WINDOW VAR w):{} zeige rahmen;{} fenster putzen.{} zeige rahmen:{} out frame (w.fenster).{} fenster putzen:{} page (w).{}END PROC show;{}PROC page (WINDOW VAR w):{} initialize (w);{} page (w, FALSE){}END PROC page;{}PROC page (WINDOW CONST w, BOOL CONST mit rahmen ):{} IF areax (w) = 1 AND areay (w) = 1 AND{}
+ areaxsize (w) = 79 AND areaysize (w) = 24{} THEN page;{} ELSE loesche bereich{} FI.{} loesche bereich:{} IF mit rahmen{} THEN page (areax (w) - 1, areay (w) - 1,{} areaxsize (w) + 2, areaysize (w) + 2){} ELSE page (area (w)){} FI{}END PROC page;{}PROC erase (WINDOW VAR w):{} page (w, TRUE){}END PROC erase;{}PROC line (WINDOW VAR w):{} w.cspalte := 1;{} IF w.czeile < w.belegbare zeilen{} THEN w.czeile INCR 1;{} ELSE w.czeile := 1;{}
+ w.fensterende erreicht := TRUE{} FI;{} cursor (w, w.cspalte, w.czeile){}END PROC line;{}PROC line (WINDOW VAR w, INT CONST anzahl):{} INT VAR i; FOR i FROM 1 UPTO anzahl REP line (w) PER{}END PROC line;{}INT PROC remaining lines (WINDOW CONST w):{} INT VAR spalte, zeile;{} get cursor (w, spalte, zeile);{} IF spalte = 0 OR zeile = 0{} THEN 0{} ELSE w.belegbare zeilen - w.czeile{} FI{}END PROC remaining lines;{}PROC cursor (WINDOW VAR w, INT CONST spalte, zeile):{} IF spalte < 1 OR zeile < 1 OR spalte > areaxsize (w) OR zeile > areaysize (w){}
+ THEN page (w);{} ELSE w.cspalte := spalte; w.czeile := zeile;{} FI;{} cursor (w.fenster, w.cspalte, w.czeile){}END PROC cursor;{}PROC get cursor (WINDOW CONST w, INT VAR spalte, zeile):{} IF (w.cspalte < 1) OR (w.cspalte > areaxsize (w.fenster)){} OR{} (w.czeile < 1) OR (w.czeile > areaysize (w.fenster)){} THEN spalte := 0; zeile := 0{} ELSE spalte := w.cspalte; zeile := w.czeile{} FI{}END PROC get cursor;{}PROC out (WINDOW VAR w, TEXT CONST text):{}
+ INT VAR restlaenge;{} IF (w.cspalte >= 1) AND (w.cspalte <= areaxsize (w.fenster)){} AND{} (w.czeile >= 1) AND (w.czeile <= w.belegbare zeilen){} THEN putze ggf fenster;{} cursor (w.fenster, w.cspalte, w.czeile);{} outtext (text, 1, textende);{} setze fenstercursor neu;{} setze ausgabe ggf in naechster zeile fort{} FI.{} putze ggf fenster:{} IF w.fensterende erreicht{} THEN page (w);{} w.fensterende erreicht := FALSE{}
+ FI.{} textende:{} restlaenge := areaxsize (w.fenster) - w.cspalte + 1;{} min (length (text), restlaenge).{} setze fenstercursor neu:{} IF length (text) >= restlaenge{} THEN w.cspalte := 1;{} w.czeile INCR 1;{} schlage ggf neue seite auf{} ELSE w.cspalte INCR length (text){} FI.{} schlage ggf neue seite auf:{} IF w.czeile > w.belegbare zeilen{} THEN page (w);{} w.czeile := 1{} FI.{} setze ausgabe ggf in naechster zeile fort:{}
+ IF length (text) > restlaenge{} THEN out (w, subtext (text, restlaenge + 1)){} FI.{}END PROC out;{}PROC out frame (WINDOW VAR w):{} out frame (area (w)){}END PROC out frame;{}PROC out menuframe (WINDOW VAR w):{} out menu frame (area (w)){}END PROC out menuframe;{}PROC put (WINDOW VAR w, TEXT CONST word):{} out (w, word); out (w, blank){}END PROC put;{}PROC put (WINDOW VAR w, INT CONST number):{} put (w, text (number)){}END PROC put;{}PROC put (WINDOW VAR w, REAL VAR number):{} put (w, text (number)){}
+END PROC put;{}PROC putline (WINDOW VAR w, TEXT CONST textline):{} out (w, textline); line (w){}END PROC putline;{}PROC editget (WINDOW VAR w, TEXT VAR ausgabe,{} INT CONST max laenge, scroll,{} TEXT CONST sep, res, TEXT VAR exit char):{} INT VAR spalte, zeile;{} ggf zur naechsten zeile;{} get cursor (spalte, zeile); cursor on; cursor (spalte, zeile);{} editget (ausgabe, max laenge, min (scroll, restlaenge),{} sep, res, exitchar);{} get cursor (spalte, zeile); cursor off; cursor (spalte, zeile).{}
+ ggf zur naechsten zeile:{} IF restlaenge < 5 THEN line (w) FI.{} restlaenge:{} areaxsize (w.fenster) - w.cspalte - 1.{}END PROC editget;{}PROC editget (WINDOW VAR w, TEXT VAR ausgabe):{} TEXT VAR dummy;{} editget (w, ausgabe, 79, 79, "", "", dummy){}END PROC editget;{}PROC get (WINDOW VAR w, TEXT VAR word):{} INT VAR spa, zei;{} ggf zur naechsten zeile;{} get cursor (spa, zei); cursor on; cursor (spa, zei);{} REP{} word := "";{} editget (word, maxtextlength, restlaenge, " ", "", exit char);{}
+ out (w, subtext (word, 1, restlaenge));{} IF compress (word) <> ""{} THEN echoe exit char (w){} FI{} UNTIL word <> niltext AND word <> blank PER;{} get cursor (spa, zei); cursor off; cursor (spa, zei);{} delete leading blanks.{} ggf zur naechsten zeile:{} IF restlaenge < 5 THEN line (w) FI.{} restlaenge:{} areaxsize (w.fenster) - w.cspalte - 1.{} delete leading blanks:{} WHILE (word SUB 1) = blank REP word := subtext (word, 2) PER.{}END PROC get;{}PROC get (WINDOW VAR w, TEXT VAR word, TEXT CONST separator):{}
+ INT VAR spa, zei;{} ggf zur naechsten zeile;{} get cursor (spa, zei); cursor on; cursor (spa, zei);{} REP{} word := "";{} editget (word, maxtextlength, restlaenge, separator, "", exit char);{} out (w, subtext (word, 1, restlaenge));{} echoe exit char (w);{} UNTIL word <> niltext AND word <> blank PER;{} get cursor (spa, zei); cursor off; cursor (spa, zei).{} ggf zur naechsten zeile:{} IF restlaenge < 5 THEN line (w) FI.{} restlaenge:{} areaxsize (w.fenster) - w.cspalte - 1.{}
+END PROC get;{}PROC get (WINDOW VAR w, TEXT VAR word, INT CONST length):{} INT VAR spa, zei;{} ggf zur naechsten zeile;{} get cursor (spa, zei); cursor on; cursor (spa, zei);{} REP{} word := "";{} editget (word, maxtextlength, laenge, "", "", exit char);{} out (w, subtext (word, 1, laenge));{} echoe exit char (w){} UNTIL word <> niltext AND word <> blank PER;{} get cursor (spa, zei); cursor off; cursor (spa, zei).{} ggf zur naechsten zeile:{} IF restlaenge < 5 THEN line (w) FI.{}
+ restlaenge:{} areaxsize (w.fenster) - w.cspalte - 1.{} laenge:{} min (length, restlaenge).{}END PROC get;{}PROC get (WINDOW VAR w, INT VAR number):{} get (w, number word);{} number := int (number word){}END PROC get;{}PROC get (WINDOW VAR w, REAL VAR number):{} get (w, number word);{} number := real (number word){}END PROC get;{}PROC getline (WINDOW VAR w, TEXT VAR textline):{} INT VAR spa, zei;{} ggf zur naechsten zeile;{} get cursor (spa, zei); cursor on; cursor (spa, zei);{} REP{}
+ textline := "";{} editget (textline, maxtextlength, restlaenge, "", "", exit char);{} out (w, subtext (word, 1, restlaenge));{} echoe exit char (w);{} UNTIL textline <> niltext AND textline <> blank PER;{} get cursor (spa, zei); cursor off; cursor (spa, zei).{} ggf zur naechsten zeile:{} IF restlaenge < 5 THEN line (w) FI.{} restlaenge:{} areaxsize (w.fenster) - w.cspalte - 1.{}END PROC getline;{}PROC echoe exit char (WINDOW VAR fenster):{} IF exit char = cr{} THEN line (fenster){}
+ ELSE out (fenster, exit char){} FI{}END PROC echoe exit char;{}TEXT PROC center (WINDOW CONST w, TEXT CONST text):{} IF length (text) >= areaxsize (w.fenster){} THEN subtext (text, 1, areaxsize (w.fenster)){} ELSE center (areaxsize (w.fenster), text){} FI{}END PROC center;{}BOOL PROC yes (WINDOW VAR w, TEXT CONST frage):{} TEXT VAR zeichen, interne frage :: frage;{} interne frage CAT aussage [2];{} wechsel ggf auf neue seite;{} out (w, interne frage);{} hole eingabezeichen;{}
+ werte zeichen aus.{} wechsel ggf auf neue seite:{} IF remaining lines (w) < 1{} THEN page (w){} FI.{} hole eingabezeichen:{} cursor on; clear buffer;{} REP{} inchar (zeichen);{} piepse ggf{} UNTIL pos (janeinkette, zeichen) > 0 PER;{} out (w, blank + zeichen);{} cursor off; line (w).{} piepse ggf:{} IF pos (janeinkette, zeichen) = 0 THEN out (piep) FI.{} werte zeichen aus:{} IF pos (janeinkette, zeichen) < 5{} THEN TRUE{} ELSE FALSE{} FI.{}
+END PROC yes;{}PROC edit (WINDOW VAR w, FILE VAR f):{} out frame (w.fenster);{} loesche rechte spalten (w);{} cursor on;{} edit (f, areax (w.fenster), areay (w.fenster),{} areaxsize (w.fenster) - 1, areaysize (w.fenster));{} cursor off{}END PROC edit;{}PROC edit (WINDOW VAR w, TEXT CONST dateiname):{} FILE VAR f :: sequential file (modify, dateiname);{} to line (f, 1);{} edit (w, f){}END PROC edit;{}PROC show (WINDOW VAR w, FILE VAR f):{} out frame (w.fenster);{} loesche rechte spalten (w);{}
+ open editor (groesster editor + 1, f, FALSE,{} areax (w.fenster), areay (w.fenster),{} areaxsize (w.fenster) - 1, areaysize (w.fenster));{} cursor on;{} edit (groesster editor, "eqvw19dpgn"9"",{} PROC (TEXT CONST) std kommando interpreter);{} cursor off{}END PROC show;{}PROC show (WINDOW VAR w, TEXT CONST dateiname):{} FILE VAR f :: sequential file (modify, dateiname);{} to line (f, 1);{} show (w, f){}END PROC show;{}PROC loesche rechte spalten (WINDOW VAR w):{}
+ INT VAR i;{} FOR i FROM 1 UPTO areaysize (w.fenster) REP{} cursor (w, areaxsize (w.fenster) - 2, i); out (3 * blank){} PER{}END PROC loesche rechte spalten;{}BOOL PROC no (WINDOW VAR w, TEXT CONST frage):{} NOT yes (w, frage){}END PROC no;{}PROC stop (WINDOW VAR w):{} stop (w, 2){}END PROC stop;{}PROC stop (WINDOW VAR w, INT CONST zeilenzahl):{} INT VAR i; FOR i FROM 1 UPTO zeilenzahl REP line (w) PER;{} out (w, aussage [3]);{} pause{}END PROC stop;{}AREA PROC area (WINDOW CONST w):{}
+ w.fenster{}END PROC area;{}INT PROC areax (WINDOW CONST w):{} areax (w.fenster){}END PROC areax;{}INT PROC areay (WINDOW CONST w):{} areay (w.fenster){}END PROC areay;{}INT PROC areaxsize (WINDOW CONST w):{} areaxsize (w.fenster){}END PROC areaxsize;{}INT PROC areaysize (WINDOW CONST w):{} areaysize (w.fenster){}END PROC areaysize;{}END PACKET ls dialog 3;{}
+
diff --git a/dialog/ls-DIALOG 4 b/dialog/ls-DIALOG 4
new file mode 100644
index 0000000..7c9d9c4
--- /dev/null
+++ b/dialog/ls-DIALOG 4
@@ -0,0 +1,71 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG 4 **
+ ** **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls dialog 4 DEFINES{} boxinfo,{} boxnotice,{} boxalternative,{} boxyes,{} boxno,{} boxanswer,{} boxone,{} boxanswerone,{} boxsome,{} boxanswersome,{} out footnote,{} erase footnote:{}LET mark ein = ""15"",{} mark aus = ""14"",{} delimiter = ""13"",{} piep = ""7"",{} rechts links esc return = ""2""8""27""13"",{}
+ rechts links null return = ""2""8""0""13"" ,{} blank = " ",{} niltext = "",{} janeintasten = "jJyYnN";{}ROW 8 TEXT CONST aussage :: ROW 8 TEXT : ({}" Zum Weitermachen bitte irgendeine Taste tippen!",{}" Ändern: <Pfeile> Bestätigen: <RETURN> Abbruch: <ESC> <h>",{}" Ändern: <Pfeile> Bestätigen: <RETURN> Ja: <j> Nein: <n>",{}" Ändern: <Pfeile> Bestätigen: <RETURN>",{}" Fertig: <RETURN> Zeigen: <ESC><z> Abbruch: <ESC><h>",{}
+" Fertig: <RETURN> Abbruch: <ESC><h>",{}"Ja"13"Nein",{}" Eingabe: "{});{}PROC boxinfo (WINDOW VAR w, TEXT CONST t,{} INT CONST position, timelimit,{} INT VAR x, y, xsize, ysize):{} INT VAR spa, zei;{} get cursor (w, spa, zei);{} schreibe box (w, t, position, timelimit, x, y, xsize, ysize);{} cursor (w, spa, zei);{}END PROC boxinfo;{}PROC boxinfo (WINDOW VAR w, TEXT CONST t, INT CONST position,{} timelimit, BOOL CONST trennlinie weg):{} INT VAR x, y, xsize, ysize, spa, zei;{}
+ get cursor (w, spa, zei);{} schreibe box (w, t, position, timelimit, x, y, xsize, ysize);{} page up (x, y, xsize, ysize);{} IF trennlinie weg{} THEN erase footnote (w, TRUE){} ELSE erase footnote (w, FALSE){} FI;{} cursor (w, spa, zei){}END PROC boxinfo;{}PROC boxinfo (WINDOW VAR w, TEXT CONST t, INT CONST position, timelimit):{} boxinfo (w, t, position, timelimit, TRUE){}END PROC boxinfo;{}PROC boxinfo (WINDOW VAR w, TEXT CONST t):{} boxinfo (w, t, 5, maxint, TRUE){}END PROC boxinfo;{}
+PROC boxnotice (WINDOW VAR w, TEXT CONST t, INT CONST position,{} INT VAR x, y, xsize, ysize):{} INT VAR spa, zei;{} get cursor (w, spa, zei);{} schreibe notiz (w, t, position, x, y, xsize, ysize);{} cursor (w, spa, zei){}END PROC boxnotice;{}INT PROC boxalternative (WINDOW VAR w, TEXT CONST t,{} auswahlliste, zusatztasten,{} INT CONST position, BOOL CONST mit abbruch,{} INT VAR x, y, xsize, ysize):{}
+ INT VAR ergebnis, spa, zei;{} get cursor (w, spa, zei);{} schreibe alternativen (w, t, auswahlliste, zusatztasten, position,{} mit abbruch, x, y, xsize, ysize, ergebnis);{} cursor (w, spa, zei);{} ergebnis{}END PROC boxalternative;{}INT PROC boxalternative (WINDOW VAR w, TEXT CONST t, auswahlliste,{} zusatztasten, INT CONST position,{} BOOL CONST mit abbruch, trennlinie weg):{} INT VAR x, y, xsize, ysize, ergebnis, spa, zei;{}
+ get cursor (w, spa, zei);{} ergebnis := boxalternative (w, t, auswahlliste, zusatztasten, position,{} mit abbruch, x, y, xsize, ysize);{} page up (x, y, xsize, ysize);{} IF trennlinie weg{} THEN erase footnote (w, TRUE){} ELSE erase footnote (w, FALSE){} FI;{} cursor (w, spa, zei);{} ergebnis{}END PROC boxalternative;{}INT PROC boxalternative (WINDOW VAR w, TEXT CONST t,{} auswahlliste, zusatztasten,{} INT CONST position, BOOL CONST mit abbruch):{}
+ boxalternative (w, t, auswahlliste, zusatztasten,{} position, mit abbruch, TRUE){}END PROC boxalternative;{}BOOL PROC boxyes (WINDOW VAR w, TEXT CONST t, INT CONST position,{} INT VAR x, y, xsize, ysize):{} INT VAR spa, zei;{} get cursor (w, spa, zei);{} BOOL CONST wert :: ja (w, t, position, x, y, xsize, ysize);{} cursor (w, spa, zei);{} wert{}END PROC boxyes;{}BOOL PROC boxyes (WINDOW VAR w, TEXT CONST t,{} INT CONST position, BOOL CONST trennlinie weg):{}
+ INT VAR x, y, xsize, ysize, spa, zei;{} get cursor (w, spa, zei);{} BOOL VAR wert :: ja (w, t, position, x, y, xsize, ysize);{} page up (x, y, xsize, ysize);{} IF trennlinie weg{} THEN erase footnote (w, TRUE){} ELSE erase footnote (w, FALSE);{} FI;{} cursor (w, spa, zei);{} wert{}END PROC boxyes;{}BOOL PROC boxyes (WINDOW VAR w, TEXT CONST t, INT CONST position):{} boxyes (w, t, position, TRUE){}END PROC boxyes;{}BOOL PROC boxno (WINDOW VAR w, TEXT CONST t, INT CONST position,{}
+ INT VAR x, y, xsize, ysize):{} NOT boxyes (w, t, position, x, y, xsize, ysize){}END PROC boxno;{}BOOL PROC boxno (WINDOW VAR w, TEXT CONST t,{} INT CONST position, BOOL CONST trennlinie weg):{} NOT boxyes (w, t, position, trennlinie weg){}END PROC boxno;{}BOOL PROC boxno (WINDOW VAR w, TEXT CONST t, INT CONST position):{} boxno (w, t, position){}END PROC boxno;{}TEXT PROC boxanswer (WINDOW VAR w, TEXT CONST t, vorgabe,{} INT CONST position, INT VAR x, y, xsize, ysize):{}
+ INT VAR spa, zei;{} TEXT VAR wert;{} get cursor (w, spa, zei);{} wert := hole antwort (w, t, vorgabe, position, FALSE, x, y, xsize, ysize);{} cursor (spa, zei);{} wert{}END PROC boxanswer;{}TEXT PROC boxanswer (WINDOW VAR w, TEXT CONST t, vorgabe,{} INT CONST position, BOOL CONST trennlinie weg):{} INT VAR x, y, xsize, ysize, spa, zei;{} get cursor (w, spa, zei);{} TEXT VAR wert := hole antwort (w, t, vorgabe, position, FALSE,{} x, y, xsize, ysize);{}
+ page up (x, y, xsize, ysize);{} IF trennlinie weg{} THEN erase footnote (w, TRUE){} ELSE erase footnote (w, FALSE){} FI;{} cursor (w, spa, zei);{} wert{}END PROC boxanswer;{}TEXT PROC boxanswer (WINDOW VAR w, TEXT CONST t, vorgabe,{} INT CONST position):{} boxanswer (w, t, vorgabe, position, TRUE){}END PROC boxanswer;{}TEXT PROC boxone (WINDOW VAR w, THESAURUS CONST thesaurus,{} TEXT CONST text1, text2, BOOL CONST mit reinigung):{}
+ INT VAR spa, zei;{} get cursor (w, spa, zei);{} TEXT VAR wert :: one (areax (w) + 2, areay (w) + 2,{} areaxsize (w) - 4, areaysize (w) - 2,{} thesaurus, text1, text2);{} IF mit reinigung{} THEN page up (areax (w) + 2, areay (w) + 2,{} areaxsize (w) - 4, areaysize (w) - 2);{} erase footnote (w){} FI;{} cursor (w, spa, zei);{} wert{}END PROC boxone;{}TEXT PROC boxanswerone (WINDOW VAR w, TEXT CONST text, vorgabe,{}
+ THESAURUS CONST thesaurus, TEXT CONST t1, t2,{} BOOL CONST mit reinigung, trennlinie weg):{} INT VAR x,y, xsize, ysize, spa, zei;{} get cursor (w, spa, zei);{} TEXT VAR wert := hole antwort (w, text, vorgabe, 5, TRUE,{} x, y, xsize, ysize);{} IF wert = ""27"z"{} THEN lasse auswaehlen{} ELSE uebernimm den wert{} FI;{} cursor (w, spa, zei);{} wert.{} lasse auswaehlen:{} IF mit reinigung{} THEN wert := boxone (w, thesaurus, t1, t2, TRUE ){}
+ ELSE wert := boxone (w, thesaurus, t1, t2, FALSE){} FI.{} uebernimm den wert:{} IF mit reinigung{} THEN page up (x, y, xsize, ysize);{} entferne ggf die trennlinie{} FI.{} entferne ggf die trennlinie:{} IF trennlinie weg{} THEN erase footnote (w, TRUE){} ELSE erase footnote (w, FALSE){} FI.{}END PROC boxanswer one;{}TEXT PROC boxanswerone (WINDOW VAR w, TEXT CONST text, vorgabe,{} THESAURUS CONST thesaurus, TEXT CONST t1, t2,{}
+ BOOL CONST mit reinigung):{} boxanswerone (w, text, vorgabe, thesaurus, t1, t2, mit reinigung, TRUE){}END PROC boxanswer one;{}THESAURUS PROC boxsome (WINDOW VAR w, THESAURUS CONST thesaurus,{} TEXT CONST text1, text2,{} BOOL CONST mit reinigung):{} INT VAR spa, zei;{} get cursor (w, spa, zei);{} THESAURUS VAR wert :: some (areax (w) + 2, areay (w) + 2,{} areaxsize (w) - 4, areaysize (w) - 2,{}
+ thesaurus, text1, text2);{} IF mit reinigung{} THEN page up (areax (w) + 2, areay (w) + 2,{} areaxsize (w) - 4, areaysize (w) - 2);{} erase footnote (w){} FI;{} cursor (w, spa, zei);{} wert{}END PROC boxsome;{}THESAURUS PROC boxanswersome (WINDOW VAR w, TEXT CONST text, vorgabe,{} THESAURUS CONST thesaurus,{} TEXT CONST t1, t2,{} BOOL CONST mit reinigung, trennlinie weg):{}
+ THESAURUS VAR ergebnis :: empty thesaurus;{} INT VAR x, y, xsize, ysize, spa, zei;{} get cursor (w, spa, zei);{} TEXT VAR wert := hole antwort (w, text, vorgabe, 5, TRUE,{} x, y, xsize, ysize);{} IF wert = ""27"z"{} THEN lasse auswaehlen{} ELSE uebernimm den wert{} FI;{} cursor (w, spa, zei);{} ergebnis.{} lasse auswaehlen:{} IF mit reinigung{} THEN ergebnis := boxsome (w, thesaurus, t1, t2, TRUE ){} ELSE ergebnis := boxsome (w, thesaurus, t1, t2, FALSE){}
+ FI.{} uebernimm den wert:{} IF wert <> niltext{} THEN insert (ergebnis, wert){} FI;{} IF mit reinigung{} THEN page up (x, y, xsize, ysize);{} entferne ggf die trennlinie{} FI.{} entferne ggf die trennlinie:{} IF trennlinie weg{} THEN erase footnote (w, TRUE){} ELSE erase footnote (w, FALSE){} FI.{}END PROC boxanswer some;{}THESAURUS PROC boxanswersome (WINDOW VAR w, TEXT CONST text, vorgabe,{} THESAURUS CONST thesaurus,{}
+ TEXT CONST t1, t2,{} BOOL CONST mit reinigung):{} boxanswersome (w, text, vorgabe, thesaurus, t1, t2, mit reinigung, TRUE){}END PROC boxanswersome;{}PROC out footnote (WINDOW VAR w, BOOL CONST mit trennlinie, TEXT CONST text):{} INT VAR spa, zei;{} get cursor (w, spa, zei);{} IF mit trennlinie{} THEN cursor (w, 1, areaysize (w) - 1);{} areaxsize (w) TIMESOUT waagerecht{} FI;{} cursor (w, 1, areaysize (w));{} outtext (text, 1, areaxsize (w));{}
+ cursor (w, spa, zei){}END PROC out footnote;{}PROC out footnote (WINDOW VAR w, TEXT CONST t):{} out footnote (w, TRUE, t){}END PROC out footnote;{}PROC erase footnote (WINDOW VAR w, BOOL CONST auch trennlinie):{} INT VAR spa, zei;{} get cursor (w, spa, zei);{} IF auch trennlinie{} THEN cursor (w, 1, areaysize (w) - 1);{} outtext ("", 1, areaxsize (w)){} FI;{} cursor (w, 1, areaysize (w));{} outtext ("", 1, areaxsize (w));{} cursor (w, spa, zei){}END PROC erase footnote;{}PROC erase footnote (WINDOW VAR w):{}
+ erase footnote (w, TRUE){}END PROC erase footnote;{}PROC schreibe boxtext (WINDOW VAR w, TEXT CONST t,{} INT CONST position, zusatzlaenge,{} mindestbreite, mindesthoehe,{} INT VAR x, y, xsize, ysize):{} ermittle boxbreite und boxhoehe;{} ermittle rahmenwerte;{} schreibe boxkopf;{} schreibe boxrumpf.{} ermittle boxbreite und boxhoehe:{} TEXT VAR intern :: t + delimiter;{} entferne fuehrende delimiter;{} INT VAR anfang :: 1,{}
+ ende :: pos (intern, delimiter, anfang) - 1;{} xsize := 0;{} ysize := 0;{} WHILE ende > 0 REP{} ysize INCR 1;{} lege ggf boxbreite fest;{} bestimme neue positionen{} PER.{} entferne fuehrende delimiter:{} WHILE (intern SUB 1) = delimiter REP{} intern := subtext (intern, 2){} PER.{} lege ggf boxbreite fest:{} IF length (subtext (intern, anfang, ende)) > xsize{} THEN xsize := length (subtext (intern, anfang, ende)){} FI.{} bestimme neue positionen:{}
+ anfang := ende + 2;{} ende := pos (intern, delimiter, anfang) - 1.{} ermittle rahmenwerte:{} schlage notwendige groessen auf;{} kill ueberlaengen;{} lege bildschirmpositionen fest.{} schlage notwendige groessen auf:{} IF xsize < mindestbreite{} THEN xsize := mindestbreite{} FI;{} IF ysize < mindesthoehe{} THEN ysize := mindesthoehe{} FI;{} ysize INCR zusatzlaenge;{} ysize INCR 2; (* Für den Rahmen *){} xsize INCR 2. (* Für den Rahmen *){} kill ueberlaengen:{}
+ IF ysize > (areaysize (w) - 4){} THEN ysize := areaysize (w) - 4{} FI;{} IF xsize > (areaxsize (w) - 4){} THEN xsize := areaxsize (w) - 4{} FI.{} lege bildschirmpositionen fest:{} SELECT position OF{} CASE 1: plazierung links oben{} CASE 2: plazierung rechts oben{} CASE 3: plazierung links unten{} CASE 4: plazierung rechts unten{} OTHERWISE plazierung im zentrum{} END SELECT.{} plazierung links oben:{} x := areax (w) + 2;{} y := areay (w) + 2.{}
+ plazierung rechts oben:{} x := areax (w) + areaxsize (w) - xsize - 2;{} y := areay (w) + 2.{} plazierung links unten:{} x := areax (w) + 2;{} y := areay (w) + areaysize (w) - ysize - 2.{} plazierung rechts unten:{} x := areax (w) + areaxsize (w) - xsize - 2;{} y := areay (w) + areaysize (w) - ysize - 2.{} plazierung im zentrum:{} x := areax (w) + ((areaxsize (w) - (xsize + 2)) DIV 2) + 1;{} y := areay (w) + ((areaysize (w) - ysize) DIV 2).{} schreibe boxkopf:{}
+ cursor (x, y);{} out (ecke oben links);{} (xsize - 2) TIMESOUT waagerecht;{} out (ecke oben rechts).{} schreibe boxrumpf:{} INT VAR i;{} intern := t + delimiter;{} entferne fuehrende delimiter;{} anfang := 1;{} ende := pos (intern, delimiter, anfang) - 1;{} FOR i FROM y + 1 UPTO y + ysize - zusatzlaenge - 2 REP{} cursor (x, i);{} out (senkrecht);{} outtext (subtext (intern, anfang, ende), 1, xsize - 2);{} out (senkrecht);{} anfang := ende + 2;{}
+ ende := pos (intern, delimiter, anfang) - 1{} PER{}END PROC schreibe boxtext;{}PROC schreibe boxfuss (WINDOW VAR w,{} INT CONST x, y, xsize, ysize, limit):{} schreibe abschlusszeile;{} out footnote (w, aussage [1]);{} cursor in position und warten.{} schreibe abschlusszeile:{} cursor (x, y + ysize - 1);{} out (ecke unten links);{} (xsize - 2) TIMESOUT waagerecht;{} out (ecke unten rechts).{} cursor in position und warten:{} cursor parken (w);{}
+ clear buffer;{} pause (limit){}END PROC schreibe boxfuss;{}PROC cursor parken (WINDOW VAR w):{} cursor (w, 1, 2){}END PROC cursor parken;{}PROC schreibe box (WINDOW VAR w, TEXT CONST t,{} INT CONST position, timelimit,{} INT VAR x, y, xsize, ysize):{} schreibe boxtext (w, t, position, 0, 0, 0, x, y, xsize, ysize);{} schreibe boxfuss (w, x, y, xsize, ysize, timelimit){}END PROC schreibe box;{}PROC schreibe notizfuss (WINDOW VAR w, INT CONST x, y, xsize, ysize):{}
+ schreibe abschlusszeile;{} cursor parken (w).{} schreibe abschlusszeile:{} cursor (x, y + ysize - 1);{} out (ecke unten links);{} (xsize - 2) TIMESOUT waagerecht;{} out (ecke unten rechts).{}END PROC schreibe notizfuss;{}PROC schreibe notiz (WINDOW VAR w, TEXT CONST t, INT CONST position,{} INT VAR x, y, xsize, ysize):{} schreibe boxtext (w, t, position, 0, 0, 0, x, y, xsize, ysize);{} schreibe notizfuss (w, x, y, xsize, ysize){}END PROC schreibe notiz;{}PROC schreibe alternativen (WINDOW VAR w, TEXT CONST t, altzeile, sonst,{}
+ INT CONST position, BOOL CONST mit abbruch,{} INT VAR x, y, xsize, ysize, ergebnis):{} ROW 10 STRUCT (TEXT alternat, INT anfang, laenge) VAR altliste;{} normiere alternativen;{} untersuche alternativen;{} schreibe boxtext (w, textintern, position, 2, altbreite,{} 0, x, y, xsize, ysize);{} schreibe alternativenfuss;{} lasse auswaehlen;{} liefere ergebnis.{} textintern:{} IF sonst = janeintasten{} THEN TEXT VAR zwischen;{}
+ zwischen := t;{} kuerze um folgende blanks;{} zwischen + "? "{} ELSE t{} FI.{} kuerze um folgende blanks:{} WHILE (zwischen SUB (length (zwischen))) = blank REP{} zwischen := subtext (zwischen , 1, length (zwischen) - 1){} PER.{} normiere alternativen:{} TEXT VAR altintern :: altzeile;{} altintern CAT delimiter.{} untersuche alternativen:{} INT VAR altanzahl :: 1, altbreite, first :: - 2, anfang :: 1,{} ende :: pos (altintern, delimiter, anfang) - 1;{}
+ WHILE ende > 0 AND altanzahl <= 10 REP{} trage alternative ein;{} trage alternativenanfang ein;{} trage alternativenlaenge ein;{} setze neue positionen fest{} PER;{} ermittle gesamtalternativenbreite.{} trage alternative ein:{} altliste [altanzahl].alternat :={} compress (subtext (altintern, anfang, ende)).{} trage alternativenanfang ein:{} first INCR 3;{} altliste [altanzahl].anfang := first.{} trage alternativenlaenge ein:{}
+ altliste [altanzahl].laenge := length (altliste [altanzahl].alternat);{} first INCR altliste [altanzahl].laenge.{} setze neue positionen fest:{} anfang := ende + 2;{} ende := pos (altintern, delimiter, anfang) - 1;{} altanzahl INCR 1.{} ermittle gesamtalternativenbreite:{} altanzahl DECR 1;{} altbreite := altliste [altanzahl].anfang;{} altbreite INCR (altliste [altanzahl].laenge + 3);{} IF altbreite > areaxsize (w) - 6{} THEN LEAVE schreibe alternativen{}
+ FI.{} schreibe alternativenfuss:{} schreibe leerzeile;{} schreibe antwortmoeglichkeiten;{} schreibe abschlusszeile;{} IF mit abbruch{} THEN out footnote (w, aussage [2]){} ELSE beruecksichtige ja nein hinweis{} FI.{} schreibe leerzeile:{} cursor (x, y + ysize - 3);{} out (senkrecht);{} (xsize - 2) TIMESOUT blank;{} out (senkrecht).{} schreibe antwortmoeglichkeiten:{} cursor (x, y + ysize - 2);{} out (senkrecht);{} einrueckbreite TIMESOUT blank;{}
+ out (antwortleiste);{} rest TIMESOUT blank;{} out (senkrecht).{} einrueckbreite:{} (xsize - 2 - length (antwortleiste)) DIV 2.{} antwortleiste:{} INT VAR zeiger; TEXT VAR ausgabe :: "";{} FOR zeiger FROM 1 UPTO altanzahl REP{} ausgabe CAT altliste [zeiger].alternat;{} ausgabe CAT " "{} PER;{} compress (ausgabe).{} rest:{} xsize - 2 - einrueckbreite - length (antwortleiste).{} schreibe abschlusszeile:{} cursor (x, y + ysize - 1);{} out (ecke unten links);{}
+ (xsize - 2) TIMESOUT waagerecht;{} out (ecke unten rechts).{} beruecksichtige ja nein hinweis:{} IF sonst = janeintasten{} THEN out footnote (w, aussage [3]){} ELSE out footnote (w, aussage [4]){} FI.{} lasse auswaehlen:{} INT VAR altzeiger :: 1;{} stelle erste alternative invers dar;{} REP{} hole eingabe;{} werte eingabe aus und reagiere{} UNTIL alternative gefunden PER.{} stelle erste alternative invers dar:{} cursor (x + einrueckbreite, y + ysize - 2);{}
+ out (mark ein);{} out (altliste [altzeiger].alternat); out (blank);{} out (mark aus);{} cursor (x + einrueckbreite, y + ysize - 2).{} hole eingabe:{} TEXT VAR moegliche, eingabe;{} IF mit abbruch{} THEN moegliche := rechts links esc return + sonst{} ELSE moegliche := rechts links null return + sonst{} FI;{} clear buffer;{} REP{} inchar (eingabe);{} piepse bei unzulaessiger eingabe{} UNTIL pos (moegliche, eingabe) > 0 PER.{} piepse bei unzulaessiger eingabe:{}
+ IF pos (moegliche, eingabe) = 0 THEN out (piep) FI.{} werte eingabe aus und reagiere:{} SELECT pos (moegliche, eingabe) OF{} CASE 1: zur naechsten alternative{} CASE 2: zur vorausgehenden alternative{} CASE 3: esc kommando verarbeiten{} END SELECT.{} zur naechsten alternative:{} loesche aktuelle alternative;{} ermittle rechte alternative;{} stelle neue alternative invers dar.{} zur vorausgehenden alternative:{} loesche aktuelle alternative;{} ermittle linke alternative;{}
+ stelle neue alternative invers dar.{} loesche aktuelle alternative:{} cursor (alternativenanfang - 1, y + ysize - 2);{} out (blank);{} out (altliste [altzeiger].alternat);{} out (2 * blank).{} alternativenanfang:{} x + einrueckbreite + altliste [altzeiger].anfang.{} ermittle rechte alternative:{} IF altzeiger = altanzahl{} THEN altzeiger := 1{} ELSE altzeiger INCR 1{} FI.{} ermittle linke alternative:{} IF altzeiger = 1{} THEN altzeiger := altanzahl{}
+ ELSE altzeiger DECR 1{} FI.{} stelle neue alternative invers dar:{} cursor (alternativenanfang - 1, y + ysize - 2);{} out (mark ein);{} out (altliste [altzeiger].alternat); out (blank);{} out (mark aus);{} cursor (alternativenanfang - 1, y + ysize - 2).{} esc kommando verarbeiten:{} inchar (eingabe);{} IF eingabe = "h"{} THEN ergebnis := 0;{} LEAVE schreibe alternativen{} ELSE out (piep); eingabe := ""{} FI.{} alternative gefunden:{} pos (moegliche, eingabe) > 3.{}
+ liefere ergebnis:{} IF pos (moegliche, eingabe) = 4{} THEN ergebnis := altzeiger{} ELSE ergebnis := 100 + pos (sonst, eingabe){} FI.{}END PROC schreibe alternativen;{}BOOL PROC ja (WINDOW VAR w, TEXT CONST t, INT CONST position,{} INT VAR x, y, xsize, ysize):{} INT VAR ergebnis;{} schreibe alternativen (w, t, aussage [7], janeintasten, position,{} FALSE, x, y, xsize, ysize, ergebnis);{} SELECT ergebnis OF{} CASE 2, 105, 106: FALSE{} OTHERWISE TRUE{}
+ END SELECT.{}END PROC ja;{}TEXT PROC hole antwort (WINDOW VAR w, TEXT CONST t, vorgabe,{} INT CONST position, BOOL CONST mit auswahl,{} INT VAR x, y, xsize, ysize):{} TEXT VAR eingabe :: compress (vorgabe);{} schreibe boxtext (w, t, position, 2, length (aussage [8]) + 12, 2,{} x, y, xsize, ysize);{} schreibe antwortfuss;{} clear buffer;{} REP{} IF eingabe = "break"{} THEN eingabe := ""{} FI;{} lasse eintragen{}
+ UNTIL eingabe <> "break" PER;{} liefere ergebnis.{} schreibe antwortfuss:{} schreibe leerzeile;{} schreibe eingabezeile;{} schreibe abschlusszeile;{} IF mit auswahl{} THEN out footnote (w, aussage [5]){} ELSE out footnote (w, aussage [6]){} FI.{} schreibe leerzeile:{} cursor (x, y + ysize - 3);{} out (senkrecht);{} (xsize - 2) TIMESOUT blank;{} out (senkrecht).{} schreibe eingabezeile:{} cursor (x, y + ysize - 2);{} out (senkrecht);{} out (aussage [8]);{}
+ (xsize - 2 - length (aussage [8])) TIMESOUT blank;{} out (senkrecht).{} schreibe abschlusszeile:{} cursor (x, y + ysize - 1);{} out (ecke unten links);{} (xsize - 2) TIMESOUT waagerecht;{} out (ecke unten rechts).{} lasse eintragen:{} TEXT VAR exit :: "";{} cursor on;{} cursor (x + length (aussage [8]) + 1, y + ysize - 2);{} IF mit auswahl{} THEN editget (eingabe, maxtextlength, textlaenge, "", "hz", exit){} ELSE editget (eingabe, maxtextlength, textlaenge, "", "h", exit){}
+ FI;{} cursor off;{} IF exit = ""27"h"{} THEN eingabe := ""{} ELIF mit auswahl AND (exit = ""27"z"){} THEN eingabe := ""27"z"{} ELSE eingabe := compress (eingabe){} FI.{} textlaenge:{} xsize - 2 - length (aussage [8]).{} liefere ergebnis:{} eingabe.{}END PROC hole antwort;{}END PACKET ls dialog 4;{}
+
diff --git a/dialog/ls-DIALOG 5 b/dialog/ls-DIALOG 5
new file mode 100644
index 0000000..1772b99
--- /dev/null
+++ b/dialog/ls-DIALOG 5
@@ -0,0 +1,118 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG 5 **
+ ** **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls dialog 5 DEFINES{} menufootnote, old menufootnote,{} menuinfo,menualternative,{} menuyes, menuno, menuone,{} menusome,menuanswer,{} menuanswerone, menuanswersome,{} install menu, handle menu,{} refresh submenu, deactivate,{} regenerate menuscreen, activate,{} write menunotice, erase menunotice,{} menubasistext, anwendungstext,{} show menuwindow, menuwindowpage,{} menuwindowout, menuwindowget,{} menuwindoweditget, menuwindowedit,{}
+ menuwindowshow, menuwindowline,{} menuwindowyes, menuwindowno,{} menuwindowcursor, get menuwindowcursor,{} remaining menuwindowlines,{} menuwindowcenter, menuwindowstop,{} editorinformationen,stdinfoedit,{} menukartenname, current menuwindow,{} reset dialog, only intern, ausstieg,{} direktstart:{}LET systemkuerzel = "ls-DIALOG",{} menutafeltaskname = "ls-MENUKARTEN",{} menutafeltype = 1954,{} menutafelpraefix = "ls-MENUKARTE:",{}
+ stdmenukartenname = "ls-MENUKARTE:Archiv",{} versionsnummer = "1.1",{} copyright1 = " (C) 1987/88 Eva Latta-Weber",{} copyright2 = " (C) 1988 ERGOS GmbH";{}LET maxmenus = 6,{} maxmenutexte = 300,{} maxinfotexte = 2000,{} maxhauptmenupunkte = 10,{} maxuntermenupunkte = 15,{} erste untermenuzeile = 3;{}LET blank = " ",{} piep = ""7"",{}
+ cleol = ""5"",{} cleop = ""4"",{} trennzeilensymbol = "###",{} bleibt leer symbol = "***",{} hauptmenuluecke = " ";{}LET auswahlstring1 = ""8""2""10""3""13""27"?";{}TYPE MENUPUNKT = STRUCT (TEXT punktkuerzel,{} punktname,{} procname,{} boxtext,{} BOOL aktiv,{} angewaehlt),{}
+ EINZELMENU = STRUCT (INT belegt,{} TEXT ueberschrift,{} INT anfangsposition,{} maxlaenge,{} ROW maxuntermenupunkte MENUPUNKT menupunkt,{} INT aktueller untermenupunkt,{} TEXT startprozedurname,{} leaveprozedurname),{} MENU = STRUCT (TEXT menuname,{} INT anzahl hauptmenupunkte,{}
+ ROW maxhauptmenupunkte EINZELMENU einzelmenu,{} TEXT menueingangsprozedur,{} menuausgangsprozedur,{} menuinfo,{} lizenznummer,{} versionsnummer,{} INT hauptmenuzeiger,{} untermenuanfang,{} untermenuzeiger),{} INFOTEXT = STRUCT (INT anzahl infotexte,{}
+ ROW maxinfotexte TEXT stelle),{} MENUTEXT = STRUCT (INT anzahl menutexte,{} ROW maxmenutexte TEXT platz),{} MENULEISTE = STRUCT (INT belegt, zeigeraktuell, zeigerhintergrund,{} ROW maxmenus MENU menu,{} MENUTEXT menutext,{} INFOTEXT infotext);{}BOUND MENULEISTE VAR menuleiste;{}DATASPACE VAR ds;{}WINDOW VAR menuwindow, schreibfenster, editorinfofenster;{}
+INITFLAG VAR in this task :: FALSE;{}INT VAR anzahl offener menus :: 0;{}INT VAR menunotizx, menunotizxsize,{} menunotizy, menunotizysize,{} menunotizposition;{}TEXT VAR angekoppelte menutafel :: "",{} permanent footnote :: "",{} menunotiztext;{}BOOL VAR menunotiz ist gesetzt :: FALSE,{} nur interne verwendung :: FALSE,{} mit ausstieg :: FALSE;{}REAL VAR zeitpunkt :: clock (1);{}
+ROW 13 TEXT CONST fehlermeldung :: ROW 13 TEXT : ({}"Die Task '" + menutafeltaskname + "' existiert nicht!",{}"Die Menukarte '",{}"' existiert nicht in der Task '" + menutafeltaskname + "'!",{}"' hat falschen Typ/Bezeichnung (keine 'MENUKARTE')!",{}"Das Menu '",{}"' ist nicht in der angekoppelten Menukarte!",{}"Zu viele geoeffnete Menus ( > 2 )!",{}"Kein Menu geoeffnet!",{}"Menu enthaelt keine Menupunkte!",{}"Menupunkt ist nicht im Menu enthalten!",{}"Kein Text vorhanden!",{}"Zugriff unmöglich!",{}
+"Einschränkung unzulässig!"{});{}ROW 1 TEXT CONST vergleichstext :: ROW 1 TEXT : ({}"gibt es nicht"{});{}ROW 3 TEXT CONST hinweis :: ROW 3 TEXT : ({}"Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>",{}" Zum Weitermachen bitte irgendeine Taste tippen!",{}"Bitte warten ... Ich räume auf!"{});{}ROW 3 TEXT CONST infotext :: ROW 3 TEXT : ({}" Für diesen Menupunkt ist (noch) keine "13""13" Funktion eingetragen!",{}" Möchten Sie dieses Menu tatsächlich verlassen",{}" Leider ist zu diesem Menupunkt "13""13" kein Info - Text eingetragen!"{}
+ );{}PROC install menu (TEXT CONST menutafelname):{} installmenu (menutafelname, TRUE){}END PROC install menu;{}PROC install menu (TEXT CONST menutafelname, BOOL CONST mit kennung):{} TEXT VAR letzter parameter;{} IF mit kennung{} THEN zeige menukennung{} FI;{} initialisiere menu ggf;{} IF menutafel noch nicht angekoppelt{} THEN letzter parameter := std;{} hole menutafel;{} kopple menutafel an;{} last param (letzter parameter){} FI.{} initialisiere menu ggf:{}
+ IF NOT initialized (in this task){} THEN angekoppelte menutafel := "";{} anzahl offener menus := 0;{} menunotiz ist gesetzt := FALSE;{} nur interne verwendung := FALSE{} FI.{} menutafel noch nicht angekoppelt:{} menutafelname <> angekoppelte menutafel.{} hole menutafel:{} IF NOT exists task (menutafeltaskname){} THEN bereinige situation; cursor on;{} errorstop (fehlermeldung [1]){} FI;{} disable stop;{} fetch (menutafelname, /menutafeltaskname);{}
+ IF is error AND pos (errormessage, vergleichstext [1]) > 0{} THEN clear error; enable stop;{} bereinige situation; cursor on;{} errorstop (fehlermeldung [2] + menutafelname +{} fehlermeldung [3]){} ELIF is error{} THEN clear error; enable stop;{} bereinige situation; cursor on;{} errorstop (errormessage){} ELSE enable stop{} FI.{} kopple menutafel an:{} IF type (old (menutafelname)) = menutafeltype{}
+ AND pos (menutafelname,menutafelpraefix) = 1{} THEN forget (ds);{} ds := old (menutafelname);{} menuleiste := ds;{} angekoppelte menutafel := menutafelname;{} forget (menutafelname, quiet){} ELSE bereinige situation; cursor on;{} errorstop ("'" + menutafelname + fehlermeldung [4]){} FI.{}END PROC install menu;{}PROC only intern (BOOL CONST wert):{} nur interne verwendung := wert{}END PROC only intern;{}
+PROC ausstieg (BOOL CONST wert):{} mit ausstieg := wert{}END PROC ausstieg;{}TEXT PROC menukartenname:{} IF NOT initialized (in this task){} THEN angekoppelte menutafel := "";{} anzahl offener menus := 0;{} menunotiz ist gesetzt := FALSE;{} FI;{} angekoppelte menutafel{}END PROC menukartenname;{}PROC handle menu (TEXT CONST menuname):{} nur interne verwendung := FALSE;{} mit ausstieg := TRUE;{} handle menu (menuname, ""){}END PROC handle menu;{}
+PROC handle menu (TEXT CONST menuname, ausstiegsproc):{} cursor off;{} IF nur interne verwendung{} THEN oeffne menu (menuname){} ELSE biete menu an{} FI;{} lasse menupunkte auswaehlen;{} IF nur interne verwendung{} THEN do (ausstiegsproc);{} anzahl offener menus DECR 1;{} IF anzahl offener menus < 1 THEN erase menunotice FI;{} menuleiste.zeigeraktuell := menuleiste.zeigerhintergrund;{} menuwindow := window (1,1,79, 24);{} nur interne verwendung := FALSE;{}
+ mit ausstieg := TRUE;{} cursor on{} ELSE schliesse menu;{} leere ggf den bildschirm{} FI.{} biete menu an:{} REAL VAR zwischenzeit :: clock (1) - zeitpunkt;{} IF zwischenzeit < 2.0{} THEN pause (20 - int (10.0 * zwischenzeit)){} FI;{} oeffne menu (menuname).{} leere ggf den bildschirm:{} IF anzahl offener menus < 1{} THEN erase menunotice;{} page; cursor on{} FI.{} lasse menupunkte auswaehlen:{} TEXT VAR kuerzelkette :: "";{}
+ starte aktuelle untermenuoperationen;{} REP{} cursor in warteposition;{} ermittle aktuelle kuerzelkette;{} nimm zeichen auf;{} interpretiere zeichen;{} UNTIL menu verlassen gewuenscht PER.{} nimm zeichen auf:{} TEXT CONST erlaubte zeichen ::auswahlstring1 + kuerzelkette;{} TEXT VAR eingabezeichen;{} INT VAR zeichenposition;{} REP{} inchar (eingabezeichen);{} zeichenposition := pos (erlaubte zeichen, eingabezeichen);{} piepse ggf{} UNTIL zeichenposition > 0 PER.{}
+ piepse ggf:{} IF zeichenposition = 0 THEN out (piep) FI.{} menu verlassen gewuenscht:{} zeichenposition = 6 AND (zweites zeichen = "q").{} interpretiere zeichen:{} SELECT zeichenposition OF{} CASE 1: gehe einen hauptmenupunkt nach links{} CASE 2: gehe einen hauptmenupunkt nach rechts{} CASE 3: gehe einen untermenupunkt nach unten{} CASE 4: gehe einen untermenupunkt nach oben{} CASE 5: fuehre aktuellen menupunkt aus{} CASE 6: hole esc sequenz{} CASE 7: zeige erklaerungstext im menu an{}
+ OTHERWISE werte kuerzeleingabe aus{} END SELECT.{} gehe einen hauptmenupunkt nach links:{} INT VAR anzahl schritte :: 1;{} beende aktuelle untermenuoperationen;{} loesche aktuelles untermenu auf bildschirm;{} loesche alte hauptmenumarkierung;{} anzahl schritte INCR clear buffer and count (""8"");{} ermittle linke menuposition;{} stelle aktuellen hauptmenupunkt invers dar;{} starte aktuelle untermenuoperationen;{} schreibe aktuelles untermenu auf bildschirm.{} gehe einen hauptmenupunkt nach rechts:{}
+ anzahl schritte := 1;{} beende aktuelle untermenuoperationen;{} loesche aktuelles untermenu auf bildschirm;{} loesche alte hauptmenumarkierung;{} anzahl schritte INCR clear buffer and count (""2"");{} ermittle rechte menuposition;{} stelle aktuellen hauptmenupunkt invers dar;{} starte aktuelle untermenuoperationen;{} schreibe aktuelles untermenu auf bildschirm.{} loesche alte hauptmenumarkierung:{} erase invers (area (menuwindow), startpos, 1, ueberschriftlaenge);{}
+ out (area (menuwindow), startpos, 1, ueberschrifttext).{} startpos:{} aktuelles untermenu.anfangsposition.{} ueberschriftlaenge:{} length (ueberschrifttext).{} ueberschrifttext:{} aktuelles untermenu.ueberschrift.{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} ermittle linke menuposition:{} INT VAR positionszaehler;{} FOR positionszaehler FROM 1 UPTO anzahl schritte REP{}
+ drehe die menuposition um einen wert runter{} PER.{} ermittle rechte menuposition:{} FOR positionszaehler FROM 1 UPTO anzahl schritte REP{} drehe die menuposition um einen wert hoch{} PER.{} drehe die menuposition um einen wert runter:{} IF aktuelles menu.hauptmenuzeiger > 1{} THEN aktuelles menu.hauptmenuzeiger DECR 1{} ELSE aktuelles menu.hauptmenuzeiger{} := aktuelles menu.anzahl hauptmenupunkte{} FI.{} drehe die menuposition um einen wert hoch:{}
+ IF aktuelles menu.hauptmenuzeiger{} < aktuelles menu.anzahl hauptmenupunkte{} THEN aktuelles menu.hauptmenuzeiger INCR 1{} ELSE aktuelles menu.hauptmenuzeiger := 1{} FI.{} gehe einen untermenupunkt nach unten:{} INT VAR naechster aktiver := folgender aktiver untermenupunkt;{} nimm ummarkierung vor.{} gehe einen untermenupunkt nach oben:{} naechster aktiver := vorausgehender aktiver untermenupunkt;{} nimm ummarkierung vor.{} nimm ummarkierung vor:{} IF ueberhaupt aktive menupunkte vorhanden{}
+ THEN demarkiere aktuellen untermenupunkt;{} gehe zum folgenden untermenupunkt;{} markiere aktuellen untermenupunkt{} FI.{} ueberhaupt aktive menupunkte vorhanden:{} (aktuelles untermenu.belegt > 0) CAND (naechster aktiver > 0).{} gehe zum folgenden untermenupunkt:{} aktuelles menu.untermenuzeiger := naechster aktiver.{} stelle aktuellen hauptmenupunkt invers dar:{} out invers (area (menuwindow), startpos, 1, ueberschrifttext).{} fuehre aktuellen menupunkt aus:{}
+ IF nur interne verwendung AND mit ausstieg{} THEN kennzeichne als angetickt;{} disable stop;{} do (ausstiegsproc);{} do (menuanweisung);{} aktueller menupunkt.angewaehlt := FALSE;{} IF is error THEN put error; clear error FI;{} enable stop;{} anzahl offener menus DECR 1;{} menuleiste.zeigeraktuell := menuleiste.zeigerhintergrund;{} menuwindow := window (1,1,79, 24);{} nur interne verwendung := FALSE;{}
+ cursor on;{} LEAVE handle menu{} ELSE kennzeichne als angetickt;{} fuehre operation aus (menuanweisung);{} nimm kennzeichnung zurueck{} FI.{} kennzeichne als angetickt:{} aktueller menupunkt.angewaehlt := TRUE;{} markiere aktuellen untermenupunkt.{} nimm kennzeichnung zurueck:{} aktueller menupunkt.angewaehlt := FALSE;{} markiere aktuellen untermenupunkt.{} menuanweisung:{} compress (aktueller menupunkt.procname).{} aktueller menupunkt:{}
+ aktuelles untermenu.menupunkt [aktuelles menu.untermenuzeiger].{} hole esc sequenz:{} TEXT VAR zweites zeichen;{} inchar (zweites zeichen);{} SELECT pos ("q?$", zweites zeichen) OF{} CASE 1: erfrage abbruch{} CASE 2: zeige menubedienhinweise{} CASE 3: gib info aus{} OTHERWISE out (piep){} END SELECT.{} erfrage abbruch:{} IF menuno (infotext [2], 5){} THEN zweites zeichen := "n" (* gleichgültig, nur nicht 'q' *){} FI.{} zeige menubedienhinweise:{}
+ INT VAR gewaehlt;{} REP{} gewaehlt := menualternative ( alttext, altwahl, altzusatz, 5, FALSE);{} erfuelle den wunsch{} UNTIL ausstieg aus bedienhinweisen gewuenscht PER.{} alttext:{} menuleiste.menutext.platz [1].{} altwahl:{} menuleiste.menutext.platz [2].{} altzusatz:{} menuleiste.menutext.platz [3].{} erfuelle den wunsch:{} SELECT gewaehlt OF{} CASE 1,101,106: menuinfo (menuleiste.menutext.platz [4], 5, maxint){} CASE 2,102,107: menuinfo (menuleiste.menutext.platz [5], 5, maxint){}
+ CASE 3,103,108: menuinfo (menuleiste.menutext.platz [6], 5, maxint){} CASE 4,104,109: menuinfo (menuleiste.menutext.platz [7], 5, maxint){} END SELECT.{} ausstieg aus bedienhinweisen gewuenscht:{} gewaehlt = 5 OR gewaehlt = 105 OR gewaehlt = 110.{} gib info aus:{} menuinfo (menuleiste.menutext.platz [20]).{} zeige erklaerungstext im menu an:{} IF compress (erklaerungstext) = ""{} THEN menuinfo (infotext [3]){} ELSE menuinfo (erklaerungstext){} FI.{} erklaerungstext:{}
+ aktueller menupunkt.boxtext.{} werte kuerzeleingabe aus:{} naechster aktiver := pos (kuerzelkette, eingabezeichen);{} nimm ummarkierung vor;{} fuehre aktuellen menupunkt aus.{} starte aktuelle untermenuoperationen:{} ermittle aktuelle kuerzelkette;{} IF startoperation <> ""{} THEN fuehre operation aus (startoperation){} FI.{} startoperation:{} compress (aktuelles untermenu.startprozedurname).{} ermittle aktuelle kuerzelkette:{} kuerzelkette := "";{} INT VAR kuerzelzeiger;{}
+ FOR kuerzelzeiger FROM 1 UPTO aktuelles untermenu.belegt REP{} IF compress (aktuelles punktkuerzel) = ""{} THEN kuerzelkette CAT ""0"" { beliebiger Code der Länge 1 }{} ELSE haenge ggf kuerzel an{} FI{} PER.{} aktuelles punktkuerzel:{} aktuelles untermenu.menupunkt [kuerzelzeiger].punktkuerzel.{} haenge ggf kuerzel an:{} IF betrachteter punkt ist aktiv{} THEN kuerzelkette CAT aktuelles punktkuerzel{} ELSE kuerzelkette CAT ""0""{} FI.{} betrachteter punkt ist aktiv:{}
+ aktuelles untermenu.menupunkt [kuerzelzeiger].aktiv.{} beende aktuelle untermenuoperationen:{} kuerzelkette := "".{}END PROC handle menu;{}PROC oeffne menu (TEXT CONST menuname):{} cursor off;{} suche eingestelltes menu;{} IF menu existiert nicht{} THEN cursor on;{} page;{} errorstop (fehlermeldung [5] + menuname + fehlermeldung [6]){} FI;{} anzahl offener menus INCR 1;{} ggf neue seite aufschlagen;{} ueberpruefe anzahl offener menus;{} lege ggf aktuelles menu auf eis;{}
+ initialisiere den menubildschirm;{} IF NOT nur interne verwendung{} THEN aktuelles menu.hauptmenuzeiger := 1;{} aktuelles menu.untermenuzeiger := 0;{} aktuelles menu.untermenuanfang := 0;{} FI;{} show menu;{} fuehre ggf menueingangsprozedur aus;{} zeige ggf menukenndaten an.{} suche eingestelltes menu:{} INT VAR i, suchzeiger;{} BOOL VAR gefunden :: FALSE;{} FOR i FROM 1 UPTO menuleiste.belegt REP{} IF menuleiste.menu [i].menuname = menuname{}
+ THEN gefunden := TRUE;{} suchzeiger := i;{} FI{} UNTIL menuleiste.menu [i].menuname = menuname PER.{} menu existiert nicht:{} NOT gefunden.{} ueberpruefe anzahl offener menus:{} IF anzahl offener menus > 2{} THEN anzahl offener menus := 0; cursor on;{} errorstop (fehlermeldung [7]){} FI.{} lege ggf aktuelles menu auf eis:{} IF anzahl offener menus = 2{} THEN menuleiste.zeigerhintergrund := menuleiste.zeigeraktuell{} FI;{} menuleiste.zeigeraktuell := suchzeiger.{}
+ initialisiere den menubildschirm:{} IF anzahl offener menus = 2{} THEN menuwindow := window (6, 4, 73, 20){} ELSE menuwindow := window (1, 1, 79, 24);{} FI.{} fuehre ggf menueingangsprozedur aus:{} IF aktuelles menu.menueingangsprozedur <> ""{} THEN fuehre operation aus (aktuelles menu.menueingangsprozedur){} FI.{} ggf neue seite aufschlagen:{} IF anzahl offener menus = 1 THEN page FI.{} zeige ggf menukenndaten an:{} IF anzahl offener menus = 1 AND aktuelles menu.menuinfo <> bleibt leer symbol{}
+ THEN write menunotice (vollstaendiger infotext, 4);{} pause (100);{} erase menunotice{} FI.{} vollstaendiger infotext:{} aktuelles menu.menuinfo +{} aktuelles menu.lizenznummer +{} aktuelles menu.versionsnummer.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{}END PROC oeffne menu;{}PROC show menu:{} ueberpruefe menudaten;{} stelle hauptmenuleiste zusammen;{} zeige hauptmenu an;{} stelle aktuellen hauptmenupunkt invers dar;{} schreibe aktuelles untermenu auf bildschirm;{}
+ zeige informationszeile an.{} ueberpruefe menudaten:{} IF anzahl offener menus = 0{} THEN errorstop (fehlermeldung [8]){} ELIF aktuelles menu.anzahl hauptmenupunkte < 1{} THEN errorstop (fehlermeldung [9]){} FI.{} stelle hauptmenuleiste zusammen:{} TEXT VAR hauptmenuzeile :: "";{} INT VAR zeiger;{} hauptmenuzeile CAT aktuelles menu.menuname;{} hauptmenuzeile CAT ":";{} FOR zeiger FROM 1 UPTO aktuelles menu.anzahl hauptmenupunkte REP{} haenge hauptmenupunkt an{}
+ PER.{} haenge hauptmenupunkt an:{} hauptmenuzeile CAT hauptmenuluecke;{} hauptmenuzeile CAT hauptmenupunktname.{} hauptmenupunktname:{} aktuelles menu.einzelmenu [zeiger].ueberschrift.{} zeige hauptmenu an:{} page (menuwindow, TRUE);{} out menuframe (area (menuwindow));{} cursor (menuwindow, 1, 1);{} out (menuwindow, hauptmenuzeile).{} stelle aktuellen hauptmenupunkt invers dar:{} cursor (menuwindow, startposition, 1);{} out (menuwindow, invers (ueberschrifttext)).{}
+ startposition:{} aktuelles untermenu.anfangsposition - 1.{} ueberschrifttext:{} aktuelles untermenu.ueberschrift.{} zeige informationszeile an:{} write permanent footnote (hinweis [1]).{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC show menu;{}PROC schreibe aktuelles untermenu auf bildschirm:{} ermittle linke obere ecke des untermenukastens;{} wirf untermenu aus;{}
+ show menunotice;{} cursor in warteposition.{} ermittle linke obere ecke des untermenukastens:{} aktuelles menu.untermenuanfang := menumitte - halbe menubreite;{} achte auf randextrema.{} menumitte:{} startposition + (length (ueberschrifttext) DIV 2) - 1.{} startposition:{} aktuelles untermenu.anfangsposition.{} ueberschrifttext:{} aktuelles untermenu.ueberschrift.{} halbe menubreite:{} aktuelles untermenu.maxlaenge DIV 2.{} achte auf randextrema:{} gleiche ggf linken rand aus;{}
+ gleiche ggf rechten rand aus.{} gleiche ggf linken rand aus:{} IF aktuelles menu.untermenuanfang < 4{} THEN aktuelles menu.untermenuanfang := 4{} FI.{} gleiche ggf rechten rand aus:{} IF (aktuelles menu.untermenuanfang + aktuelles untermenu.maxlaenge) >{} (areaxsize (menuwindow) - 3){} THEN aktuelles menu.untermenuanfang{} := areaxsize (menuwindow) - aktuelles untermenu.maxlaenge - 3{} FI.{} wirf untermenu aus:{} IF aktuelles menu.untermenuzeiger = 0{}
+ THEN aktuelles menu.untermenuzeiger := folgender aktiver untermenupunkt{} FI;{} wirf untermenukopfzeile aus;{} wirf untermenurumpf aus;{} wirf untermenufusszeile aus;{} markiere aktuellen untermenupunkt.{} wirf untermenukopfzeile aus:{} cursor (menuwindow, spalte, anfangszeile);{} out (balken oben); striche; out (balken oben).{} wirf untermenufusszeile aus:{} cursor (menuwindow, spalte, endezeile);{} out (ecke unten links); striche; out (ecke unten rechts).{} spalte:{}
+ aktuelles menu.untermenuanfang - 3.{} anfangszeile:{} erste untermenuzeile - 1.{} endezeile:{} erste untermenuzeile + aktuelles untermenu.belegt.{} striche:{} (aktuelles untermenu.maxlaenge + 5) TIMESOUT waagerecht.{} wirf untermenurumpf aus:{} INT VAR laufvar;{} INT CONST aktuelle punktlaenge :: aktuelles untermenu.maxlaenge + 1;{} FOR laufvar FROM 1 UPTO aktuelles untermenu.belegt REP{} wirf eine einzelne menuzeile aus{} PER.{} wirf eine einzelne menuzeile aus:{}
+ out with beam (area (menuwindow), menuspalte, menuzeile,{} aktueller punktname, laenge).{} menuspalte:{} aktuelles menu.untermenuanfang.{} menuzeile:{} erste untermenuzeile + laufvar - 1.{} aktueller punktname:{} untermenubezeichnung (laufvar).{} laenge:{} aktuelle punktlaenge.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC schreibe aktuelles untermenu auf bildschirm;{}
+PROC loesche aktuelles untermenu auf bildschirm:{} beende aktuelle untermenuoperationen;{} loesche untermenu auf bildschirm;{} schreibe balken wieder hin;{} aktuelles menu.untermenuzeiger := 1.{} beende aktuelle untermenuoperationen:{} IF leaveoperation <> ""{} THEN fuehre operation aus (leaveoperation){} FI.{} leaveoperation:{} compress (aktuelles untermenu.leaveprozedurname).{} loesche untermenu auf bildschirm:{} INT VAR laufvar;{} FOR laufvar FROM aktuelles untermenu.belegt + 1 DOWNTO 1 REP{}
+ loesche eine einzelne menuzeile{} PER.{} loesche eine einzelne menuzeile:{} erase with beam (area (menuwindow), menuspalte, menuzeile, laenge).{} menuspalte:{} aktuelles menu.untermenuanfang.{} menuzeile:{} erste untermenuzeile + laufvar - 1.{} laenge:{} aktuelles untermenu.maxlaenge + 1.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{} schreibe balken wieder hin:{}
+ cursor (menuwindow, spalte, anfangszeile);{} (aktuelles untermenu.maxlaenge + 7) TIMESOUT waagerecht.{} spalte:{} aktuelles menu.untermenuanfang - 3.{} anfangszeile:{} erste untermenuzeile - 1.{}END PROC loesche aktuelles untermenu auf bildschirm;{}PROC markiere aktuellen untermenupunkt:{} IF aktuelles menu.untermenuzeiger <> 0{} THEN laufe ggf zum naechsten aktiven menupunkt;{} out invers with beam (area (menuwindow), menuspalte, menuzeile,{} aktueller punktname, laenge){}
+ FI.{} laufe ggf zum naechsten aktiven menupunkt:{} IF NOT aktuelles untermenu.menupunkt [aktuelles menu.untermenuzeiger].aktiv{} THEN aktuelles menu.untermenuzeiger := folgender aktiver untermenupunkt{} FI.{} menuspalte:{} aktuelles menu.untermenuanfang.{} menuzeile:{} erste untermenuzeile - 1 + aktuelles menu.untermenuzeiger.{} aktueller punktname:{} untermenubezeichnung (aktuelles menu.untermenuzeiger).{} laenge:{} aktuelles untermenu.maxlaenge + 1.{} aktuelles menu:{}
+ menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC markiere aktuellen untermenupunkt;{}PROC demarkiere aktuellen untermenupunkt:{} IF aktuelles menu.untermenuzeiger <> 0{} THEN erase invers (area (menuwindow), menuspalte, menuzeile, laenge);{} out (area (menuwindow), menuspalte, menuzeile,{} aktueller punktname, laenge){} FI.{} menuspalte:{} aktuelles menu.untermenuanfang.{}
+ menuzeile:{} erste untermenuzeile - 1 + aktuelles menu.untermenuzeiger.{} aktueller punktname:{} untermenubezeichnung (aktuelles menu.untermenuzeiger).{} laenge:{} aktuelles untermenu.maxlaenge + 1.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC demarkiere aktuellen untermenupunkt;{}INT PROC folgender aktiver untermenupunkt:{} INT VAR anzahl aktiver menupunkte :: 0;{}
+ untersuche anzahl aktiver menupunkte;{} IF kein aktiver menupunkt vorhanden{} THEN 0{} ELIF nur ein aktiver menupunkt vorhanden{} THEN liefere einzigen aktiven menupunkt{} ELSE liefere naechsten aktiven menupunkt{} FI.{} untersuche anzahl aktiver menupunkte:{} INT VAR zaehler, position;{} FOR zaehler FROM 1 UPTO aktuelles untermenu.belegt REP{} IF aktuelles untermenu.menupunkt [zaehler].aktiv{} THEN anzahl aktiver menupunkte INCR 1;{} position := zaehler{}
+ FI{} UNTIL anzahl aktiver menupunkte > 1 PER.{} kein aktiver menupunkt vorhanden:{} anzahl aktiver menupunkte = 0.{} nur ein aktiver menupunkt vorhanden:{} anzahl aktiver menupunkte = 1.{} liefere einzigen aktiven menupunkt:{} position.{} liefere naechsten aktiven menupunkt:{} INT VAR interner zeiger;{} stelle internen zeiger auf den naechsten menupunkt;{} WHILE NOT punkt ist aktiv REP{} untersuche naechsten menupunkt{} PER;{} ergebnis.{} stelle internen zeiger auf den naechsten menupunkt:{}
+ IF aktuelles menu.untermenuzeiger = letzter untermenupunkt{} THEN interner zeiger := 1{} ELSE interner zeiger := aktuelles menu.untermenuzeiger + 1{} FI.{} letzter untermenupunkt:{} aktuelles untermenu.belegt.{} punkt ist aktiv:{} aktuelles untermenu.menupunkt [interner zeiger].aktiv.{} untersuche naechsten menupunkt:{} IF interner zeiger = letzter untermenupunkt{} THEN interner zeiger := 1{} ELSE interner zeiger INCR 1{} FI.{}
+ ergebnis:{} interner zeiger.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC folgender aktiver untermenupunkt;{}INT PROC vorausgehender aktiver untermenupunkt:{} INT VAR anzahl aktiver menupunkte :: 0;{} untersuche anzahl aktiver menupunkte;{} IF kein aktiver menupunkt vorhanden{} THEN 0{} ELIF nur ein aktiver menupunkt vorhanden{} THEN liefere einzigen aktiven menupunkt{}
+ ELSE liefere vorausgehenden aktiven menupunkt{} FI.{} untersuche anzahl aktiver menupunkte:{} INT VAR zaehler, position;{} FOR zaehler FROM 1 UPTO aktuelles untermenu.belegt REP{} IF aktuelles untermenu.menupunkt [zaehler].aktiv{} THEN anzahl aktiver menupunkte INCR 1;{} position := zaehler{} FI{} UNTIL anzahl aktiver menupunkte > 1 PER.{} kein aktiver menupunkt vorhanden:{} anzahl aktiver menupunkte = 0.{} nur ein aktiver menupunkt vorhanden:{} anzahl aktiver menupunkte = 1.{}
+ liefere einzigen aktiven menupunkt:{} position.{} liefere vorausgehenden aktiven menupunkt:{} INT VAR interner zeiger;{} stelle internen zeiger auf vorausgehenden menupunkt;{} WHILE NOT punkt ist aktiv REP{} untersuche vorausgehenden menupunkt{} PER;{} ergebnis.{} stelle internen zeiger auf vorausgehenden menupunkt:{} IF aktuelles menu.untermenuzeiger <= 1{} THEN interner zeiger := letzter untermenupunkt{} ELSE interner zeiger := aktuelles menu.untermenuzeiger - 1{}
+ FI.{} letzter untermenupunkt:{} aktuelles untermenu.belegt.{} punkt ist aktiv:{} aktuelles untermenu.menupunkt [interner zeiger].aktiv.{} untersuche vorausgehenden menupunkt:{} IF interner zeiger = 1{} THEN interner zeiger := letzter untermenupunkt{} ELSE interner zeiger DECR 1{} FI.{} ergebnis:{} interner zeiger.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}
+END PROC vorausgehender aktiver untermenupunkt;{}PROC cursor in warteposition:{} cursor (areax (menuwindow), areay (menuwindow) + 1){}END PROC cursor in warteposition;{}TEXT PROC untermenubezeichnung (INT CONST position):{} TEXT VAR bezeichnung :: "";{} bezeichnung CAT kennzeichnung;{} bezeichnung CAT punktkennung;{} bezeichnung.{} kennzeichnung:{} IF aktueller menupunkt.aktiv{} AND aktueller menupunkt.angewaehlt{} THEN "*"{} ELIF aktueller menupunkt.aktiv{}
+ AND aktueller menupunkt.punktkuerzel <> ""{} THEN aktueller menupunkt.punktkuerzel{} ELIF aktueller menupunkt.aktiv{} AND aktueller menupunkt.punktkuerzel = ""{} THEN blank{} ELSE "-"{} FI.{} punktkennung:{} IF menupunkt ist trennzeile{} THEN strichellinie{} ELSE aktueller menupunkt.punktname{} FI.{} menupunkt ist trennzeile:{} aktueller menupunkt.punktname = (blank + trennzeilensymbol).{} strichellinie:{}
+ (aktuelles untermenu.maxlaenge + 1) * "-".{} aktueller menupunkt:{} aktuelles untermenu.menupunkt [position].{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC untermenubezeichnung;{}PROC fuehre operation aus (TEXT CONST operation):{} disable stop;{} IF operation = ""{} THEN menuinfo (infotext [1]);{} LEAVE fuehre operation aus{} FI;{} do (operation);{}
+ IF is error{} THEN menuinfo (errormessage, 5);{} clear error{} FI;{} old menufootnote;{} enable stop;{} cursor off{}END PROC fuehre operation aus;{}PROC veraendere aktivierung (TEXT CONST unterpunkt, BOOL CONST eintrag):{} INT VAR unterpunktposition :: 0, zeiger;{} suche unterpunkt;{} aendere aktivierung.{} suche unterpunkt:{} FOR zeiger FROM 1 UPTO untermenuende REP{} IF untermenupunkt = blank + compress (unterpunkt){} THEN unterpunktposition := zeiger;{} LEAVE suche unterpunkt{}
+ FI{} PER;{} LEAVE veraendere aktivierung.{} untermenuende:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].belegt.{} untermenupunkt:{} aktuelles untermenu.menupunkt [zeiger].punktname.{} aendere aktivierung:{} aktuelles untermenu.menupunkt [unterpunktposition].aktiv := eintrag.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC veraendere aktivierung;{}
+PROC veraendere aktivierung (INT CONST punktnummer, BOOL CONST eintrag):{} IF punktnummer >= 1 AND punktnummer <= untermenuende{} THEN aktuelles untermenu.menupunkt [punktnummer].aktiv := eintrag{} FI.{} untermenuende:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].belegt.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC veraendere aktivierung;{}PROC veraendere anwahl (TEXT CONST unterpunkt, BOOL CONST eintrag):{}
+ INT VAR unterpunktposition :: 0, zeiger;{} suche unterpunkt;{} aendere anwahl.{} suche unterpunkt:{} FOR zeiger FROM 1 UPTO untermenuende REP{} IF untermenupunkt = blank + compress (unterpunkt){} THEN unterpunktposition := zeiger;{} LEAVE suche unterpunkt{} FI{} PER;{} enable stop;{} errorstop (fehlermeldung [10]).{} untermenuende:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].belegt.{} untermenupunkt:{} aktuelles untermenu.menupunkt [zeiger].punktname.{}
+ aendere anwahl:{} aktuelles untermenu.menupunkt [unterpunktposition].angewaehlt := eintrag.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC veraendere anwahl;{}PROC activate (TEXT CONST unterpunkt):{} enable stop;{} veraendere aktivierung (unterpunkt, TRUE){}END PROC activate;{}PROC activate (INT CONST punktnummer):{} enable stop;{} veraendere aktivierung (punktnummer, TRUE){}
+END PROC activate;{}PROC deactivate (TEXT CONST unterpunkt):{} enable stop;{} veraendere aktivierung (unterpunkt, FALSE){}END PROC deactivate;{}PROC deactivate (INT CONST punktnummer):{} enable stop;{} veraendere aktivierung (punktnummer, FALSE){}END PROC deactivate;{}PROC select (TEXT CONST unterpunkt):{} enable stop;{} veraendere anwahl (unterpunkt, TRUE){}END PROC select;{}PROC deselect (TEXT CONST unterpunkt):{} enable stop;{} veraendere anwahl (unterpunkt, FALSE){}END PROC deselect;{}
+PROC schliesse menu:{} IF aktuelles menu.menuausgangsprozedur <> ""{} THEN menufootnote (hinweis [3]);{} fuehre operation aus (aktuelles menu.menuausgangsprozedur){} FI;{} anzahl offener menus DECR 1;{} IF anzahl offener menus = 1{} THEN aktiviere das auf eis gelegte menu{} FI.{} aktiviere das auf eis gelegte menu:{} menuleiste.zeigeraktuell := menuleiste.zeigerhintergrund;{} menuwindow := window (1, 1, 79, 24);{} show menu.{} aktuelles menu:{} menuleiste.menu [menuleiste.zeigeraktuell].{}
+END PROC schliesse menu;{}PROC refresh submenu:{} schreibe aktuelles untermenu auf bildschirm;{} show menunotice;{}END PROC refresh submenu;{}PROC regenerate menuscreen:{} IF anzahl offener menus = 0{} THEN errorstop (fehlermeldung [8]){} ELIF anzahl offener menus = 1{} THEN page;{} show menu;{} show menunotice{} ELSE zeige erstes menu an;{} zeige zweites menu an;{} show menunotice{} FI.{} zeige erstes menu an:{} INT VAR menuzeiger :: menuleiste.zeigeraktuell;{}
+ menuleiste.zeigeraktuell := menuleiste.zeigerhintergrund;{} menuwindow := window (1, 1, 79, 24);{} anzahl offener menus := 1;{} show menu.{} zeige zweites menu an:{} menuleiste.zeigeraktuell := menuzeiger;{} menuwindow := window (6, 4, 73, 20);{} anzahl offener menus := 2;{} show menu.{}END PROC regenerate menuscreen;{}PROC menuinfo (TEXT CONST t, INT CONST position, timelimit):{} boxinfo (menuwindow, t, position, timelimit, FALSE);{} schreibe aktuelles untermenu auf bildschirm;{}
+ old menufootnote{}END PROC menuinfo;{}PROC menuinfo (TEXT CONST t, INT CONST position):{} menuinfo (t, position, maxint){}END PROC menuinfo;{}PROC menuinfo (TEXT CONST t):{} menuinfo (t, 5, maxint){}END PROC menuinfo;{}INT PROC menualternative (TEXT CONST t, auswahlliste, zusatztasten,{} INT CONST position, BOOL CONST mit abbruch):{} INT VAR ergebnis := boxalternative (menuwindow, t, auswahlliste,{} zusatztasten, position, mit abbruch, FALSE);{}
+ schreibe aktuelles untermenu auf bildschirm;{} old menufootnote;{} ergebnis{}END PROC menualternative;{}BOOL PROC menuyes (TEXT CONST frage, INT CONST position):{} BOOL VAR wert := boxyes (menuwindow, frage, position, FALSE);{} schreibe aktuelles untermenu auf bildschirm;{} old menufootnote;{} wert{}END PROC menuyes;{}BOOL PROC menuno (TEXT CONST frage, INT CONST position):{} NOT menuyes (frage, position){}END PROC menuno;{}TEXT PROC menuone (THESAURUS CONST thes, TEXT CONST t1, t2,{} BOOL CONST mit reinigung):{}
+ TEXT CONST wert :: boxone (menuwindow, thes, t1, t2, mit reinigung);{} IF mit reinigung{} THEN schreibe aktuelles untermenu auf bildschirm;{} old menufootnote{} FI;{} wert{}END PROC menuone;{}THESAURUS PROC menusome (THESAURUS CONST thes, TEXT CONST t1, t2,{} BOOL CONST mit reinigung):{} THESAURUS CONST thesaurus :: boxsome (menuwindow, thes, t1, t2,{} mit reinigung);{} IF mit reinigung{} THEN schreibe aktuelles untermenu auf bildschirm;{}
+ old menufootnote{} FI;{} thesaurus{}END PROC menusome;{}TEXT PROC menuanswer (TEXT CONST t, vorgabe, INT CONST position):{} TEXT VAR wert :: boxanswer (menuwindow, t, vorgabe, position, FALSE);{} schreibe aktuelles untermenu auf bildschirm;{} old menufootnote;{} wert{}END PROC menuanswer;{}TEXT PROC menuanswerone (TEXT CONST t, vorgabe, THESAURUS CONST thes,{} TEXT CONST t1, t2, BOOL CONST mit reinigung):{} TEXT VAR wert :: boxanswerone (menuwindow, t, vorgabe, thes, t1, t2,{}
+ mit reinigung, FALSE){} IF mit reinigung{} THEN schreibe aktuelles untermenu auf bildschirm;{} old menufootnote{} FI;{} wert{}END PROC menuanswer one;{}THESAURUS PROC menuanswersome (TEXT CONST t, vorgabe, THESAURUS CONST thes,{} TEXT CONST t1, t2, BOOL CONST mit reinigung):{} THESAURUS VAR wert :: boxanswersome (menuwindow, t, vorgabe,{} thes, t1, t2, mit reinigung, FALSE){}
+ IF mit reinigung{} THEN schreibe aktuelles untermenu auf bildschirm;{} old menufootnote{} FI;{} wert{}END PROC menuanswersome;{}PROC menufootnote (TEXT CONST t):{} cursor (menuwindow, 1, areaysize (menuwindow) - 1);{} areaxsize (menuwindow) TIMESOUT waagerecht;{} cursor (menuwindow, 1, areaysize (menuwindow));{} outtext (t, 1, areaxsize (menuwindow)){}END PROC menufootnote;{}PROC old menufootnote:{} menufootnote (permanent footnote){}END PROC old menufootnote;{}TEXT PROC menubasistext (INT CONST nummer):{}
+ IF nummer <= 20{} THEN fehlermeldung [12]{} ELIF nummer > menuleiste.menutext.anzahl menutexte{} THEN fehlermeldung [11]{} ELSE menuleiste.menutext.platz [nummer]{} FI{}END PROC menubasistext;{}TEXT PROC anwendungstext (INT CONST nummer):{} IF nummer > menuleiste.infotext.anzahl infotexte{} THEN fehlermeldung [11]{} ELSE menuleiste.infotext.stelle [nummer]{} FI{}END PROC anwendungstext;{}PROC zeige menukennung:{} IF anzahl offener menus = 0{} THEN zeige angaben und emblem;{}
+ FI.{} zeige angaben und emblem:{} ROW 5 WINDOW VAR w;{} w [ 1] := window (40, 3, 30, 9);{} w [ 2] := window (36, 5, 30, 9);{} w [ 3] := window (30, 7, 30, 9);{} w [ 4] := window (22, 9, 30, 9);{} w [ 5] := window (12, 11, 30, 9);{} page;{} show (w [1]); out (w [1], center (w [1], invers (systemkuerzel)));{} show (w [2]); out (w [2], " Version " + versionsnummer);{} show (w [3]); out (w [3], copyright1);{} show (w [4]); out (w [4], copyright2);{} show (w [5]);{}
+ cursor (w [5], 1, 2);out (w [5], " lll sssssssss ");{} cursor (w [5], 1, 3);out (w [5], " lll sss sss ");{} cursor (w [5], 1, 4);out (w [5], " lll sss ");{} cursor (w [5], 1, 5);out (w [5], " lll sssssssss ");{} cursor (w [5], 1, 6);out (w [5], " lll sss ");{} cursor (w [5], 1, 7);out (w [5], " lll latta soft sss ");{} cursor (w [5], 1, 8);out (w [5], " lllllllll sssssssss ");{} cursor (79, 24);{}
+ zeitpunkt := clock (1);{}END PROC zeige menukennung;{}PROC reset dialog:{} angekoppelte menutafel := "";{} anzahl offener menus := 0{}END PROC reset dialog;{}PROC write permanent footnote (TEXT CONST t):{} permanent footnote := t;{} cursor (menuwindow, 1, areaysize (menuwindow));{} outtext (t, 1, areaxsize (menuwindow)){}END PROC write permanent footnote;{}PROC write menunotice (TEXT CONST t, INT CONST position):{} erase menunotice;{} boxnotice (menuwindow, t, position, menunotizx, menunotizy,{}
+ menunotizxsize, menunotizysize);{} menunotiztext := t;{} menunotizposition := position;{} menunotiz ist gesetzt := TRUE{}END PROC write menunotice;{}PROC show menunotice:{} IF menunotiz ist gesetzt{} THEN boxnotice (menuwindow, menunotiztext, menunotizposition,{} menunotizx, menunotizy, menunotizxsize, menunotizysize);{} FI{}END PROC show menunotice;{}PROC erase menunotice:{} INT VAR spa, zei;{} get cursor (spa, zei);{}
+ IF menunotiz ist gesetzt{} THEN page up (menunotizx, menunotizy, menunotizxsize, menunotizysize);{} menunotiz ist gesetzt := FALSE;{} cursor (spa, zei){} FI{}END PROC erase menunotice;{}PROC initialize menuwindow:{} schreibfenster := window (areax (menuwindow) + 1,{} areay (menuwindow) + 3,{} areaxsize (menuwindow) - 2,{} areaysize (menuwindow) - 4){}END PROC initialize menuwindow;{}
+PROC show menuwindow:{} initialize menuwindow;{} show (schreibfenster);{}END PROC show menuwindow;{}PROC menuwindow page:{} initialize menuwindow;{} page (schreibfenster){}END PROC menuwindow page;{}PROC menuwindowout (TEXT CONST text):{} out (schreibfenster, text){}END PROC menuwindow out;{}PROC menuwindowget (TEXT VAR text):{} get (schreibfenster, text){}END PROC menuwindowget;{}PROC menuwindoweditget (TEXT VAR text):{} editget (schreibfenster, text){}END PROC menuwindoweditget;{}PROC menuwindowedit (TEXT CONST dateiname):{}
+ initialize menuwindow;{} edit (schreibfenster, dateiname){}END PROC menuwindowedit;{}PROC menuwindowedit (FILE VAR f):{} initialize menuwindow;{} edit (schreibfenster, f){}END PROC menuwindowedit;{}PROC menuwindowshow (TEXT CONST dateiname):{} initialize menuwindow;{} show (schreibfenster, dateiname){}END PROC menuwindowshow;{}PROC menuwindowshow (FILE VAR f):{} initialize menuwindow;{} show (schreibfenster, f){}END PROC menuwindowshow;{}BOOL PROC menuwindowyes (TEXT CONST frage):{} yes (schreibfenster, frage){}
+END PROC menuwindowyes;{}BOOL PROC menuwindowno (TEXT CONST frage):{} no (schreibfenster, frage){}END PROC menuwindowno;{}PROC menuwindowline:{} menuwindowline (1){}END PROC menuwindowline;{}PROC menuwindowline (INT CONST anzahl):{} line (schreibfenster, anzahl){}END PROC menuwindowline;{}PROC menuwindowcursor (INT CONST spa, zei):{} cursor (schreibfenster, spa, zei){}END PROC menuwindowcursor;{}PROC get menuwindowcursor (INT VAR spa, zei):{} get cursor (schreibfenster, spa, zei){}END PROC get menuwindowcursor;{}
+INT PROC remaining menuwindowlines:{} remaining lines (schreibfenster){}END PROC remaining menuwindowlines;{}TEXT PROC menuwindowcenter (TEXT CONST t):{} center (schreibfenster, t){}END PROC menuwindowcenter;{}PROC menuwindowstop:{} menuwindowstop (2){}END PROC menuwindowstop;{}PROC menuwindowstop (INT CONST anzahl):{} stop (schreibfenster, anzahl){}END PROC menuwindowstop;{}WINDOW PROC current menuwindow:{} initialize menuwindow;{} schreibfenster{}END PROC current menuwindow;{}PROC stdinfoedit (FILE VAR f, INT CONST oberste zeile):{}
+ IF oberste zeile < 1 OR oberste zeile > 3{} THEN errorstop (fehlermeldung [13]);{} FI;{} garantiere menukarte;{} cursor (1, oberste zeile); out (cleop);{} cursor (1, 23); out(79 * waagerecht);{} cursor (1, 24); outtext (menubasistext (141), 1, 79);{} editorinfofenster := window (1, oberste zeile + 1, 79, 24 - oberste zeile);{} kommando auf taste legen ("?", "editorinformationen");{} command dialogue (FALSE);{} cursor on; edit (f, 1, oberste zeile, 79, 23 - oberste zeile);{} command dialogue (TRUE);{}
+ kommando auf taste legen ("?", "").{} garantiere menukarte:{} TEXT VAR name := compress (menukartenname);{} IF name = ""{} THEN install menu (stdmenukartenname, FALSE){} FI.{}END PROC stdinfoedit;{}PROC stdinfoedit (FILE VAR f):{} stdinfoedit (f, 1){}END PROC stdinfoedit;{}PROC stdinfoedit (TEXT CONST dateiname, INT CONST oberste zeile):{} FILE VAR f :: sequential file (modify, dateiname);{} stdinfoedit (f, oberste zeile);{}END PROC stdinfoedit;{}PROC stdinfoedit (TEXT CONST dateiname):{}
+ stdinfoedit (dateiname, 1){}END PROC stdinfoedit;{}PROC editorinformationen:{} BOOL VAR ende gewuenscht :: FALSE; INT VAR z;{} FOR z FROM startwert UPTO 22 REP{} cursor (1, z); out (cleol);{} PER;{} REP{} INT VAR erg := boxalternative (editorinfofenster,{} menubasistext (149),{} menubasistext (150),{} menubasistext (151),{} 5, FALSE, FALSE);{} erfuelle den wunsch{}
+ UNTIL ende gewuenscht PER;{} cursor (2, 23); 77 TIMESOUT waagerecht;{} cursor (1, 24); outtext (menubasistext (141), 1, 79).{} startwert:{} areay (editorinfofenster) + 1.{} erfuelle den wunsch:{} SELECT erg OF{} CASE 1, 101, 109: boxinfo (editorinfofenster, menubasistext (142), 5, maxint, FALSE){} CASE 2, 102, 110: boxinfo (editorinfofenster, menubasistext (143), 5, maxint, FALSE){} CASE 3, 103, 111: boxinfo (editorinfofenster, menubasistext (144), 5, maxint, FALSE){} CASE 4, 104, 112: boxinfo (editorinfofenster, menubasistext (145), 5, maxint, FALSE){}
+ CASE 5, 105, 113: boxinfo (editorinfofenster, menubasistext (146), 5, maxint, FALSE){} CASE 6, 106, 114: boxinfo (editorinfofenster, menubasistext (147), 5, maxint, FALSE){} CASE 7, 107, 115: boxinfo (editorinfofenster, menubasistext (148), 5, maxint, FALSE){} CASE 8, 108, 116: ende gewuenscht := TRUE{} OTHERWISE (*tue nichts*){} END SELECT{}END PROC editorinformationen;{}PROC bereinige situation:{} page;{} forget (ds);{} reset dialog{}END PROC bereinige situation;{}
+PROC direktstart (TEXT CONST procname, BOOL CONST autoloeschen):{} TEXT VAR datname := "Selbststartergenerierungsdatei", letzter := std;{} kopple archivmenukarte an;{} schreibe programm;{} insertiere programm;{} abkoppeln.{} kopple archivmenukarte an:{} install menu (stdmenukartenname, FALSE).{} schreibe programm:{} forget (datname, quiet);{} FILE VAR f :: sequential file (output, datname);{} putline (f, menubasistext (191));{} putline (f, "do (""reset dialog; erase menunotice; " + procname + """);");{}
+ putline (f, menubasistext (192));{} IF autoloeschen{} THEN putline (f, menubasistext (193)){} ELSE putline (f, menubasistext (194)){} FI;{} putline (f, menubasistext (195));{} putline (f, menubasistext (196)).{} insertiere programm:{} TEXT VAR t := "insert (""" + datname + """)"; do (t).{} abkoppeln:{} forget (datname, quiet); last param (letzter);{} reset dialog;{} global manager.{}END PROC direktstart;{}END PACKET ls dialog 5;{}
+
diff --git a/dialog/ls-DIALOG 6 b/dialog/ls-DIALOG 6
new file mode 100644
index 0000000..b27eae2
--- /dev/null
+++ b/dialog/ls-DIALOG 6
@@ -0,0 +1,102 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG 6 **
+ ** Archiv-/Taskhandling **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls dialog 6 DEFINES{} menu archiv notizort setzen,{} menu archiv grundeinstellung,{} menu archiv zieltask einstellen,{} menu archiv zieltask aendern,{} menu archiv reservieren,{} menu archiv neue diskette,{} menu archiv schreiben,{} menu archiv checken,{} menu archiv schreibcheck,{} menu archiv holen,{} menu archiv loeschen,{} menu archiv verzeichnis,{} menu archiv verzeichnis drucken,{} menu archiv initialisieren,{}
+ menu archiv reservierung aufgeben,{} archiv:{}LET menukartenname = "ls-MENUKARTE:Archiv";{}LET ack = 0,{} schreiben = 1,{} checken = 2,{} schreibcheck = 3,{} holen = 4,{} loeschen = 5,{} list code = 15,{} reserve code = 19;{}BOOL VAR zieltask ist archivmanager :: TRUE,{} archiv gehoert mir :: FALSE,{} fehlerfall :: FALSE,{} kontakt mit zieltask erfolgt :: FALSE;{}
+TEXT VAR zieltaskname :: "ARCHIVE",{} aktueller archivname :: "";{}INT VAR stationsnummer :: station (myself),{} letzte funktion :: 11,{} notizort :: 3;{}PROC archiv:{} install menu (menukartenname, FALSE);{} handle menu ("ARCHIV"){}END PROC archiv;{}PROC melde zieltaskerror (TEXT CONST meldung):{} IF meldung = menubasistext (47){} THEN menuinfo (menubasistext (123)){} ELIF meldung = menubasistext (46){}
+ THEN menuinfo (menubasistext (124)){} ELIF pos (meldung, "inkonsistent") > 0{} THEN menuinfo (menubasistext (125)){} ELIF pos (meldung, "Lesen unmoeglich") > 0{} COR pos (meldung, "Schreiben unmoeglich") > 0{} THEN menuinfo (menubasistext (126)){} ELIF pos (meldung, "Archiv heisst") > 0 AND pos (meldung, "?????") > 0{} THEN menuinfo (menubasistext (127)){} ELIF pos (meldung, "Archiv heisst") > 0{} THEN menuinfo (menubasistext (128)){} ELIF pos (meldung, "Schreibfehler") > 0 CAND pos (meldung, "Archiv") > 0{}
+ THEN menuinfo (menubasistext (129)){} ELIF pos (meldung, "Lesefehler") > 0{} THEN menuinfo (menubasistext (130)){} ELIF pos (meldung, "Kommando") > 0 AND pos (meldung, "unbekannt") > 0{} THEN menuinfo (menubasistext (131)){} ELIF pos (meldung, "falscher Auftrag fuer Task") > 0{} THEN menuinfo (menubasistext (132)){} ELIF meldung = menubasistext (41){} THEN menuinfo (menubasistext (133)){} ELIF meldung = menubasistext (42){} THEN menuinfo (menubasistext (134)){}
+ ELIF pos (meldung, "Collector") > 0 AND pos(meldung, "fehlt") > 0{} THEN menuinfo (menubasistext (135)){} ELIF pos (meldung, "kein Zugriffsrecht auf Task") > 0{} THEN menuinfo (menubasistext (132)){} ELIF pos (meldung, "nicht initialisiert") > 0{} THEN menuinfo (menubasistext (136)){} ELIF pos (meldung, "ungueltiger Format-Code") > 0{} THEN menuinfo (menubasistext (137)){} ELSE menuinfo (invers (meldung)){} FI{}END PROC melde zieltaskerror;{}PROC menu archiv notizort setzen (INT CONST wert):{}
+ SELECT wert OF{} CASE 1,2,3,4,5 : notizort := wert{} OTHERWISE notizort := 3{} END SELECT{}END PROC menu archiv notizort setzen;{}PROC menu archiv grundeinstellung (INT CONST ort):{} menu archiv zieltask aendern ("ARCHIVE", station (myself), TRUE);{} menu archiv notizort setzen (ort);{} zieltask anzeigen{}END PROC menu archiv grundeinstellung;{}PROC menu archiv zieltask einstellen:{} TEXT VAR taskname :: "";{} INT VAR stationsnr, auswahl;{} BOOL VAR ist amanager;{} erfrage daten;{}
+ kontrolliere daten;{} menu archiv zieltask aendern (taskname, stationsnr, ist amanager);{} refresh submenu;{} zieltask anzeigen.{} erfrage daten:{} auswahl := menualternative (menubasistext (51), menubasistext (52),{} menubasistext (53), 5, TRUE);{} SELECT auswahl OF{} CASE 1, 101 : menu archiv zieltask aendern{} ("ARCHIVE", station (myself), TRUE );{} ausstieg{} CASE 2, 102 : menu archiv zieltask aendern{}
+ (name (father), station (myself), FALSE);{} ausstieg{} CASE 3, 103 : menu archiv zieltask aendern{} ("PUBLIC", station (myself), FALSE);{} ausstieg{} CASE 4, 104 : handeinstellung{} OTHERWISE ausstieg{} END SELECT.{} ausstieg:{} refresh submenu;{} zieltask anzeigen;{} LEAVE menu archiv zieltask einstellen.{} handeinstellung:{} taskname := menuanswer (menubasistext (81), zieltaskname, 5);{}
+ stationsnr := int (menuanswer (menubasistext (82),{} text (station (myself)), 5));{} ist amanager := menuyes (menubasistext (83), 5).{} kontrolliere daten:{} IF compress (taskname) = ""{} OR compress (taskname) = "-"{} OR taskname = name (myself){} THEN menuinfo (menubasistext (64));{} LEAVE menu archiv zieltask einstellen{} FI.{}END PROC menu archiv zieltask einstellen;{}PROC menu archiv zieltask aendern (TEXT CONST taskname,{}
+ INT CONST stationsnr,{} BOOL CONST ist archivmanager):{} menufootnote (menubasistext (21) + menubasistext (23));{} gib ggf archiv frei;{} IF ist archivmanager{} THEN archivmanager einstellen{} ELSE sonstige task einstellen{} FI;{} aktiviere gueltige archivmenupunkte.{} gib ggf archiv frei:{} IF archiv gehoert mir{} THEN archivreservierung aufgeben{} FI.{} archivmanager einstellen:{} zieltask ist archivmanager := TRUE;{}
+ zieltaskname := taskname;{} stationsnummer := stationsnr;{} kontakt mit zieltask erfolgt := FALSE;{} aktueller archivname := "";{} archiv gehoert mir := FALSE;{} letzte funktion := 11.{} sonstige task einstellen:{} zieltask ist archivmanager := FALSE;{} zieltaskname := taskname;{} stationsnummer := stationsnr;{} aktueller archivname := "";{} archiv gehoert mir := FALSE;{}
+ letzte funktion := 6.{}END PROC menu archiv zieltask aendern;{}PROC menu archiv reservieren:{} TEXT VAR archivname :: "", meldung :: "";{} kontrolliere einstellung;{} menufootnote (menubasistext (21) + menubasistext (24));{} versuche archiv zu reservieren (meldung);{} werte meldung aus;{} archiv anmelden (archivname, meldung, TRUE);{} IF archivname = ""{} THEN behandle archivfehler{} ELSE aktueller archivname := archivname{} FI;{} aktiviere gueltige archivmenupunkte;{}
+ refresh submenu;{} zieltask anzeigen.{} kontrolliere einstellung:{} IF NOT zieltask ist archivmanager{} THEN aktiviere gueltige archivmenupunkte;{} refresh submenu;{} LEAVE menu archiv reservieren{} ELIF NOT kontakt mit zieltask erfolgt{} THEN versuche kontakt herzustellen{} FI.{} versuche kontakt herzustellen:{} TEXT VAR fehler :: "";{} IF NOT task ist kommunikativ (fehler){} THEN melde zieltaskerror (fehler);{} melde rigoros ab;{}
+ LEAVE menu archiv reservieren{} ELSE kontakt mit zieltask erfolgt := TRUE{} FI.{} werte meldung aus:{} IF meldung <> ""{} THEN melde zieltaskerror (meldung);{} melde rigoros ab;{} LEAVE menu archiv reservieren{} FI.{} behandle archivfehler:{} melde zieltaskerror (meldung);{} archivreservierung aufgeben;{} melde rigoros ab{}END PROC menu archiv reservieren;{}PROC melde rigoros ab:{} aktueller archivname := "";{} archiv gehoert mir := FALSE;{}
+ kontakt mit zieltask erfolgt := FALSE{}END PROC melde rigoros ab;{}PROC versuche archiv zu reservieren (TEXT VAR fehler):{} IF NOT kontakt mit zieltask erfolgt{} THEN fehler := menubasistext (44);{} archiv gehoert mir := FALSE;{} LEAVE versuche archiv zu reservieren{} FI;{} disable stop;{} IF eigene station{} THEN reserve ("beknackter archivename",/zieltaskname ){} ELSE reserve ("beknackter archivename", stationsnummer/zieltaskname){} FI;{} IF is error{} THEN fehler := errormessage;{}
+ melde rigoros ab;{} clear error{} ELSE archiv gehoert mir := TRUE;{} fehler := "";{} FI;{} enable stop{}END PROC versuche archiv zu reservieren;{}PROC archiv anmelden (TEXT VAR archivname, fehler, BOOL CONST mit anfrage):{} ueberpruefe archivbesitz;{} fuehre archivanmeldung aus.{} ueberpruefe archivbesitz:{} IF NOT archiv gehoert mir OR NOT kontakt mit zieltask erfolgt{} THEN fehler := menubasistext (45);{} melde rigoros ab;{} LEAVE archiv anmelden{}
+ FI.{} fuehre archivanmeldung aus:{} IF mit anfrage{} THEN frage nach eingelegter diskette und melde an{} ELSE melde archiv unter richtigem namen an{} FI.{} frage nach eingelegter diskette und melde an:{} IF menuyes (menubasistext (84), 5){} THEN menufootnote (menubasistext (21) + menubasistext (25));{} melde archiv unter richtigem namen an{} ELSE fehler := menubasistext (46);{} aktueller archivname := "";{} LEAVE archiv anmelden{}
+ FI.{} melde archiv unter richtigem namen an:{} disable stop;{} IF eigene station{} THEN reserve ("beknackter archivename",/zieltaskname);{} list (/zieltaskname);{} ELSE reserve ("beknackter archivename", stationsnummer/zieltaskname);{} list (stationsnummer/zieltaskname){} FI;{} IF is error{} THEN fehler := errormessage;{} behandle die fehlermeldung{} ELSE archivname := "beknackter archivename";{} fehler := "";{} enable stop{}
+ FI.{} behandle die fehlermeldung:{} IF subtext (fehler, 1, 14) = menubasistext (61){} CAND subtext (fehler, 16, 20) <> menubasistext (62){} THEN clear error; enable stop;{} archivname := subtext (fehler, 16, length (fehler) - 1);{} melde archiv nun wirklich richtig an;{} fehler := "";{} enable stop{} ELIF subtext (fehler, 1, 14) = menubasistext (61){} CAND subtext (fehler, 16, 20) = menubasistext (62){} THEN clear error; enable stop;{}
+ archivname := "";{} fehler := menubasistext (62){} ELSE clear error; enable stop;{} archivname := ""{} FI.{} melde archiv nun wirklich richtig an:{} IF eigene station{} THEN reserve (archivname,/zieltaskname);{} ELSE reserve (archivname, stationsnummer/zieltaskname){} FI.{}END PROC archiv anmelden;{}PROC menu archiv neue diskette:{} ueberpruefe reservierung;{} melde neue diskette an.{} ueberpruefe reservierung:{} IF NOT (archiv gehoert mir AND kontakt mit zieltask erfolgt){}
+ THEN melde zieltaskerror (menubasistext (47));{} LEAVE menu archiv neue diskette{} FI.{} melde neue diskette an:{} TEXT VAR archivname :: "", meldung :: "";{} menufootnote (menubasistext (21) + menubasistext (26));{} archiv anmelden (archivname, meldung, FALSE);{} IF archivname = ""{} THEN behandle archivfehler{} ELSE aktueller archivname := archivname{} FI;{} zieltask anzeigen.{} behandle archivfehler:{} melde zieltaskerror (meldung);{} aktueller archivname := "".{}
+END PROC menu archiv neue diskette;{}PROC menu archiv schreiben:{} dateioperation mit zieltask (schreiben);{} regenerate menuscreen{}END PROC menu archiv schreiben;{}PROC menu archiv checken:{} dateioperation mit zieltask (checken);{} regenerate menuscreen{}END PROC menu archiv checken;{}PROC menu archiv schreibcheck:{} dateioperation mit zieltask (schreibcheck);{} regenerate menuscreen{}END PROC menu archiv schreibcheck;{}PROC menu archiv holen:{} dateioperation mit zieltask (holen);{} regenerate menuscreen{}
+END PROC menu archiv holen;{}PROC menu archiv loeschen:{} dateioperation mit zieltask (loeschen);{} regenerate menuscreen{}END PROC menu archiv loeschen;{}PROC dateioperation mit zieltask (INT CONST wahl):{} ueberpruefe kommunikationsbasis und sinnhaftigkeit;{} lasse dateien auswaehlen;{} operiere mit ausgewaehlten dateien.{} ueberpruefe kommunikationsbasis und sinnhaftigkeit:{} IF unzulaessiger zieltaskname{} THEN LEAVE dateioperation mit zieltask{} ELIF zieltaskname = name (myself){}
+ THEN melde zieltaskerror (menubasistext (48));{} LEAVE dateioperation mit zieltask{} ELIF zieltask ist archivmanager AND NOT archiv gehoert mir{} THEN melde zieltaskerror (menubasistext (47));{} LEAVE dateioperation mit zieltask{} ELIF NOT zieltask ist archivmanager{} AND (wahl = checken OR wahl = schreibcheck){} THEN gib hinweis auf unmoeglich;{} LEAVE dateioperation mit zieltask{} ELIF NOT zieltask ist archivmanager{}
+ THEN stelle kontakt mit zieltask her{} ELIF wahl < schreiben OR wahl > loeschen{} THEN LEAVE dateioperation mit zieltask{} FI.{} stelle kontakt mit zieltask her:{} TEXT VAR fehler :: "";{} IF task ist kommunikativ (fehler){} THEN kontakt mit zieltask erfolgt := TRUE{} ELSE melde zieltaskerror (fehler);{} LEAVE dateioperation mit zieltask{} FI.{} gib hinweis auf unmoeglich:{} menuinfo (menubasistext (121) + taskname + menubasistext (122)).{}
+ taskname:{} IF eigene station{} THEN zieltaskname{} ELSE text (stationsnummer) + "/" + zieltaskname{} FI.{} lasse dateien auswaehlen:{} THESAURUS VAR angekreuzte;{} disable stop;{} IF wahl = schreiben OR wahl = schreibcheck{} THEN angekreuzte := menusome (ALL myself, operationshinweis,{} ankreuzhinweis, FALSE){} ELSE angekreuzte := menusome (zieltaskthesaurus, operationshinweis,{} ankreuzhinweis, FALSE){}
+ FI;{} fehlerbehandlung.{} zieltaskthesaurus:{} IF eigene station{} THEN ALL /zieltaskname{} ELSE ALL (stationsnummer/zieltaskname){} FI.{} ankreuzhinweis:{} menubasistext (91) + operationskennzeichnung (wahl) + menubasistext (92).{} operationshinweis:{} operationsbezeichnung (wahl) + zieltaskhinweis.{} operiere mit ausgewaehlten dateien:{} bereite bildschirm vor;{} steige ggf bei leerem thesaurus aus;{} IF wahl = schreiben OR wahl = schreibcheck{} THEN zuerst loeschen{}
+ FI;{} IF wahl = schreibcheck{} THEN fehlerfall := FALSE;{} dateioperation ausfuehren (angekreuzte, schreiben, FALSE);{} IF NOT fehlerfall{} THEN dateioperation ausfuehren (angekreuzte, checken, TRUE){} FI{} ELSE dateioperation ausfuehren (angekreuzte, wahl, TRUE){} FI.{} bereite bildschirm vor:{} show menuwindow.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (angekreuzte){} THEN menuwindowline (2);{} menuwindowout (menubasistext (94));{}
+ menuwindowstop;{} LEAVE dateioperation mit zieltask{} FI.{} zuerst loeschen:{} menuwindowout (menuwindowcenter (menubasistext (21) + menubasistext (31)));{} menuwindowline;{} IF not empty (angekreuzte){} THEN disable stop;{} THESAURUS CONST zu loeschende ::{} angekreuzte / zieltaskthesaurus;{} fehlerbehandlung;{} biete ggf dateien zum loeschen an{} ELSE menuwindowpage{} FI.{} biete ggf dateien zum loeschen an:{}
+ IF not empty (zu loeschende){} THEN menuwindowout (menuwindowcenter (invers (menubasistext (108))));{} menuwindowline;{} menuwindowout (menuwindowcenter (menubasistext (109)));{} menuwindowline (2);{} dateien rausschmeissen{} ELSE menuwindowpage{} FI.{} dateien rausschmeissen:{} command dialogue (FALSE);{} biete dateien einzeln zum loeschen an;{} menuwindowpage;{} command dialogue (TRUE).{} biete dateien einzeln zum loeschen an:{}
+ INT VAR z, index;{} FOR z FROM 1 UPTO highest entry (zu loeschende) REP{} disable stop;{} IF name (zu loeschende, z) <> ""{} THEN stelle frage und fuehre aus{} FI;{} fehlerbehandlung{} PER.{} stelle frage und fuehre aus:{} IF menuwindowyes ("'" + name (zu loeschende, z) + "' "{} + menubasistext (111)){} THEN erase (name (zu loeschende, z), task (zieltaskname)){} ELSE menuwindowout (menubasistext (110));{} menuwindowline;{}
+ delete (angekreuzte, name (zu loeschende, z), index);{} pause (20){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} melde zieltaskerror (errormessage);{} clear error; enable stop;{} LEAVE dateioperation mit zieltask{} FI.{}END PROC dateioperation mit zieltask;{}PROC dateioperation ausfuehren (THESAURUS CONST angekreuzte,{} INT CONST wahl,{} BOOL CONST mit schlussbemerkung):{}
+ INT VAR spalte :: 1, zeile :: 3, k, anzahl :: 0;{} menuwindowout (menuwindowcenter (invers (operationsbezeichnung (wahl){} + zieltaskhinweis)));{} command dialogue (FALSE);{} fuehre einzelne operationen aus;{} command dialogue (TRUE);{} IF mit schlussbemerkung{} THEN schreibe schlussbemerkung{} ELSE menuwindowpage{} FI.{} fuehre einzelne operationen aus:{} FOR k FROM 1 UPTO highest entry (angekreuzte) REP{} IF name (angekreuzte, k) <> ""{}
+ THEN disable stop;{} bildschirmausgabe;{} operation ausfuehren;{} anzahl INCR 1;{} fehlerbehandlung{} FI{} PER.{} bildschirmausgabe:{} spalte := 1;{} IF remaining menuwindowlines < 2{} THEN menuwindowpage; zeile := 1{} ELSE zeile INCR 1{} FI;{} menuwindowcursor (spalte, zeile);{} ergaenzter dateiname.{} ergaenzter dateiname:{} INT VAR windowcolumn, windowrow;{} SELECT wahl OF{} CASE schreiben : menuwindowout (menubasistext (105) + dateiname){}
+ CASE checken : get menuwindowcursor (windowcolumn, windowrow);{} menuwindowout (dateiname + menubasistext (106));{} menuwindowcursor (windowcolumn, windowrow);{} CASE holen : menuwindowout (menubasistext (107) + dateiname){} END SELECT.{} dateiname:{} " """ + name (angekreuzte, k) + """ ".{} operation ausfuehren:{} IF eigene station{} THEN fuehre eigenstationoperation aus{} ELSE fuehre fremdstationoperation aus{} FI.{}
+ fuehre eigenstationoperation aus:{} SELECT wahl OF{} CASE schreiben : save (name (angekreuzte, k), /zieltaskname){} CASE checken : check (name (angekreuzte, k), /zieltaskname);{} bestaetige{} CASE holen : ueberschreiben erfragen eigene station{} CASE loeschen : loeschen erfragen eigene station{} END SELECT.{} ueberschreiben erfragen eigene station:{} IF exists (name (angekreuzte, k)){} THEN menuwindowline;{} IF menuwindowyes (dateiname + menubasistext (112)){}
+ THEN zeile INCR 2;{} menuwindowline;{} forget (name (angekreuzte, k), quiet);{} fetch (name (angekreuzte, k), /zieltaskname){} FI{} ELSE fetch (name (angekreuzte, k), /zieltaskname){} FI.{} loeschen erfragen eigene station:{} IF menuwindowyes (dateiname + menubasistext (111)){} THEN erase (name (angekreuzte, k), /zieltaskname){} FI.{} fuehre fremdstationoperation aus:{} SELECT wahl OF{} CASE schreiben : save (name (angekreuzte, k), ziel){}
+ CASE checken : check (name (angekreuzte, k), ziel); bestaetige{} CASE holen : ueberschreiben erfragen fremde station{} CASE loeschen : loeschen erfragen fremde station{} END SELECT.{} ueberschreiben erfragen fremde station:{} IF exists (name (angekreuzte, k)){} THEN menuwindowline;{} IF menuwindowyes (dateiname + menubasistext (112)){} THEN zeile INCR 2;{} menuwindowline;{} forget (name (angekreuzte, k), quiet);{}
+ fetch (name (angekreuzte, k), ziel){} FI{} ELSE fetch (name (angekreuzte, k), ziel){} FI.{} loeschen erfragen fremde station:{} IF menuwindowyes (dateiname + menubasistext (111)){} THEN erase (name (angekreuzte, k), ziel){} FI.{} ziel:{} stationsnummer/zieltaskname.{} bestaetige:{} IF NOT is error{} THEN menuwindowout (dateiname + menubasistext (114)){} FI.{} schreibe schlussbemerkung:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{}
+ ELSE menuwindowline (2){} FI;{} IF anzahl > 0{} THEN menuwindowout (menubasistext (93) +{} operationskennzeichnung (wahl)){} ELSE menuwindowout (menubasistext (94)){} FI;{} menuwindowstop.{} fehlerbehandlung:{} IF is error{} THEN fehlerfall := TRUE;{} regenerate menuscreen;{} melde zieltaskerror (errormessage);{} clear error; enable stop;{} LEAVE dateioperation ausfuehren{} FI.{}END PROC dateioperation ausfuehren;{}
+TEXT PROC operationsbezeichnung (INT CONST nr):{} SELECT nr OF{} CASE schreiben : menubasistext (95){} CASE checken : menubasistext (97){} CASE schreibcheck : menubasistext (99){} CASE holen : menubasistext (101){} CASE loeschen : menubasistext (103){} OTHERWISE ""{} END SELECT{}END PROC operationsbezeichnung;{}TEXT PROC operationskennzeichnung (INT CONST nr):{} SELECT nr OF{} CASE schreiben : menubasistext (96){} CASE checken : menubasistext (98){}
+ CASE schreibcheck : menubasistext (100){} CASE holen : menubasistext (102){} CASE loeschen : menubasistext (104){} OTHERWISE ""{} END SELECT{}END PROC operationskennzeichnung;{}BOOL PROC not empty (THESAURUS CONST t):{} INT VAR i;{} FOR i FROM 1 UPTO highest entry (t) REP{} IF name (t, i) <> ""{} THEN LEAVE not empty WITH TRUE{} FI{} PER;{} FALSE{}END PROC not empty;{}TEXT PROC zieltaskhinweis:{} IF zieltaskname = "ARCHIVE"{} THEN "(" + menubasistext (78) + ")"{}
+ ELIF zieltaskname = name (father){} THEN "(" + menubasistext (79) + ")"{} ELSE menubasistext (80) + zieltaskname + ")"{} FI{}END PROC zieltaskhinweis;{}PROC menu archiv verzeichnis:{} forget("Interne Dateiliste bei Archivoperation", quiet);{} ueberpruefe kommunikationsbasis;{} liste dateien der zieltask auf;{} regenerate menuscreen.{} ueberpruefe kommunikationsbasis:{} IF unzulaessiger zieltaskname{} THEN LEAVE menu archiv verzeichnis{} ELIF zieltaskname = name (myself){}
+ THEN LEAVE ueberpruefe kommunikationsbasis{} ELIF zieltask ist archivmanager AND NOT archiv gehoert mir{} THEN melde zieltaskerror (menubasistext (47));{} LEAVE menu archiv verzeichnis{} ELIF NOT zieltask ist archivmanager{} THEN stelle kontakt mit zieltask her{} FI.{} stelle kontakt mit zieltask her:{} TEXT VAR fehler :: "";{} IF task ist kommunikativ (fehler){} THEN kontakt mit zieltask erfolgt := TRUE{} ELSE melde zieltaskerror (fehler);{}
+ LEAVE menu archiv verzeichnis{} FI.{} liste dateien der zieltask auf:{} erstelle liste;{} gib liste aus;{} forget ("Interne Dateiliste bei Archivoperation", quiet).{} erstelle liste:{} menufootnote (menubasistext (21) + menubasistext (28));{} FILE VAR f :: sequential file (output, "Interne Dateiliste bei Archivoperation");{} disable stop;{} IF eigene station{} THEN list (f, /zieltaskname){} ELSE list (f, stationsnummer/zieltaskname){} FI;{} IF is error{}
+ THEN melde zieltaskerror (errormessage);{} forget ("Interne Dateiliste bei Archivoperation", quiet);{} clear error; enable stop;{} LEAVE menu archiv verzeichnis{} FI;{} enable stop.{} gib liste aus:{} modify (f);{} IF NOT (zieltaskname = name (myself)){} THEN to line (f, 1);{} insert record (f);{} notiere kopfzeile;{} headline (f, menubasistext (43));{} ELSE entferne eigenen namen aus der liste{} FI;{}
+ to line (f, 1);{} cursor on; menuwindowshow (f); cursor off.{} notiere kopfzeile:{} IF zieltask ist archivmanager{} THEN write record (f, headline (f));{} ELSE write record (f, zieltaskbezeichnung){} FI.{} entferne eigenen namen aus der liste:{} TEXT VAR zeile :: ""; INT VAR i;{} FOR i FROM lines (f) DOWNTO 1 REP{} to line (f, i);{} read record (f, zeile);{} IF pos (zeile, "Interne Dateiliste bei Archivoperation") > 0{} THEN delete record (f);{}
+ LEAVE entferne eigenen namen aus der liste{} FI{} PER{}END PROC menu archiv verzeichnis;{}PROC menu archiv verzeichnis drucken:{} forget ("Interne Dateiliste bei Archivoperation", quiet);{} ueberpruefe kommunikationsbasis;{} erstelle listing;{} drucke listing aus.{} ueberpruefe kommunikationsbasis:{} IF unzulaessiger zieltaskname{} THEN LEAVE menu archiv verzeichnis drucken{} ELIF zieltaskname = name (myself){} THEN LEAVE ueberpruefe kommunikationsbasis{}
+ ELIF zieltask ist archivmanager AND NOT archiv gehoert mir{} THEN melde zieltaskerror (menubasistext (47));{} LEAVE menu archiv verzeichnis drucken{} ELIF NOT zieltask ist archivmanager{} THEN stelle kontakt mit zieltask her{} FI.{} stelle kontakt mit zieltask her:{} TEXT VAR fehler :: "";{} IF task ist kommunikativ (fehler){} THEN kontakt mit zieltask erfolgt := TRUE{} ELSE melde zieltaskerror (fehler);{} LEAVE menu archiv verzeichnis drucken{}
+ FI.{} erstelle listing:{} LET dummy name pos = 18;{} FILE VAR listfile; INT VAR i; TEXT VAR record :: "";{} TEXT CONST head :: 70 * "=", end :: 70 * "-";{} IF menuno (menubasistext (90), 5){} THEN LEAVE menu archiv verzeichnis drucken{} FI;{} menufootnote (menubasistext (21) + menubasistext (29));{} disable stop;{} listfile := sequential file (output, "Interne Dateiliste bei Archivoperation");{} IF eigene station{} THEN list (listfile, /zieltaskname){} ELSE list (listfile, stationsnummer/zieltaskname){}
+ FI;{} IF is error{} THEN melde zieltaskerror (errormessage);{} forget ("Interne Dateiliste bei Archivoperation", quiet);{} clear error; enable stop;{} LEAVE menu archiv verzeichnis drucken{} FI;{} enable stop.{} drucke listing aus:{} schreibe dateikopf;{} loesche dummy names;{} schreibe fuss;{} drucke und loesche listing.{} schreibe dateikopf:{} modify (listfile);{} to line (listfile, 1);{} FOR i FROM 1 UPTO 6 REP insert record (listfile) PER;{}
+ to line (listfile, 1);{} write record (listfile, "#type (""elanlist"")#"); down (listfile);{} write record (listfile, "#start (2.5,0.0)##limit (20,5)#"{} + "#pagelength (26.0)#"); down (listfile);{} write record (listfile, head); down (listfile);{} schreibe erkennungszeile; down (listfile);{} write record (listfile, " Listing vom " + date + ", "{} + time of day + " Uhr"); down (listfile);{} write record (listfile, head).{}
+ schreibe erkennungszeile:{} IF zieltask ist archivmanager{} THEN write record (listfile, "Archiv: " + headline (listfile)){} ELSE write record (listfile, "Task : " + taskbezeichnung){} FI.{} taskbezeichnung:{} IF eigene station{} THEN zieltaskname{} ELSE text (stationsnummer) + "/" + zieltaskname{} FI.{} loesche dummy names:{} to line (listfile, 8);{} WHILE NOT eof (listfile) REP{} read record (listfile, record);{} IF (record SUB dummy name pos) = "-"{}
+ OR pos (record, "Interne Dateiliste bei Archivoperation") > 0{} THEN delete record (listfile){} ELSE down (listfile){} FI{} PER.{} schreibe fuss:{} output (listfile);{} putline (listfile, end).{} drucke und loesche listing:{} menufootnote (menubasistext (21) + menubasistext (30));{} disable stop;{} print ("Interne Dateiliste bei Archivoperation");{} IF is error{} THEN melde zieltaskerror (errormessage);{} clear error; enable stop;{}
+ forget ("Interne Dateiliste bei Archivoperation", quiet);{} LEAVE menu archiv verzeichnis drucken{} FI;{} enable stop;{} forget ("Interne Dateiliste bei Archivoperation", quiet){}END PROC menu archiv verzeichnis drucken;{}TEXT PROC zieltaskbezeichnung:{} IF eigene station{} THEN menubasistext (77) + taskbezeichnung{} ELSE menubasistext (76) + text (stationsnummer) + " " +{} menubasistext (77) + zieltaskname{} FI.{} taskbezeichnung:{} IF zieltaskname = "ARCHIVE"{}
+ THEN menubasistext (78){} ELIF zieltaskname = name (father){} THEN menubasistext (79) + " (" + zieltaskname + ")"{} ELSE zieltaskname{} FI{}END PROC zieltaskbezeichnung;{}BOOL PROC unzulaessiger zieltaskname:{} IF compress (zieltaskname) = "" OR compress (zieltaskname) = "-"{} THEN TRUE{} ELSE FALSE{} FI{}END PROC unzulaessiger zieltaskname;{}PROC menu archiv initialisieren:{} TEXT VAR archivname :: "", meldung :: "";{} klaere zieltaskart;{} formatiere ggf;{}
+ initialisiere ggf.{} klaere zieltaskart:{} IF NOT zieltask ist archivmanager{} THEN menuinfo (menubasistext (121) + zieltaskname +{} menubasistext (122));{} LEAVE menu archiv initialisieren{} FI.{} formatiere ggf:{} IF menuyes (menubasistext (85), 5){} THEN nimm archiv in beschlag;{} fuehre formatierung aus{} FI.{} nimm archiv in beschlag:{} stelle archivbesitz sicher;{} IF aktueller archivname <> ""{} THEN archivname := aktueller archivname{}
+ ELSE archivname := menubasistext (75){} FI;{} IF eigene station{} THEN reserve (archivname,/zieltaskname){} ELSE reserve (archivname, stationsnummer/zieltaskname){} FI;{} aktueller archivname := archivname;{} archiv gehoert mir := TRUE;{} zieltask anzeigen.{} stelle archivbesitz sicher:{} IF NOT archiv gehoert mir OR NOT kontakt mit zieltask erfolgt{} THEN versuche kommunikation;{} versuche archiv zu reservieren (meldung);{} werte meldung aus{}
+ FI.{} versuche kommunikation:{} TEXT VAR fehler :: "";{} IF NOT task ist kommunikativ (fehler){} THEN melde zieltaskerror (fehler);{} melde rigoros ab;{} LEAVE menu archiv initialisieren{} ELSE kontakt mit zieltask erfolgt := TRUE{} FI.{} werte meldung aus:{} IF meldung <> ""{} THEN melde zieltaskerror (meldung);{} aktueller archivname := "";{} zieltask anzeigen;{} LEAVE menu archiv initialisieren{} FI.{}
+ fuehre formatierung aus:{} INT VAR auswahl :: menualternative (menubasistext (54),{} menubasistext (55),{} menubasistext (56), 5, TRUE);{} IF auswahl = 0{} THEN LEAVE fuehre formatierung aus{} FI;{} IF auswahl > 100{} THEN auswahl DECR 100{} FI;{} command dialogue (FALSE);{} disable stop;{} menufootnote (menubasistext (21) + menubasistext (27));{} IF eigene station{} THEN formatiere auf eigener station{}
+ ELSE formatiere auf fremder station{} FI;{} IF is error{} THEN melde zieltaskerror (errormessage);{} clear error; enable stop;{} command dialogue (TRUE);{} LEAVE formatiere ggf{} ELSE enable stop;{} command dialogue (TRUE);{} aktiviere gueltige archivmenupunkte;{} refresh submenu;{} zieltask anzeigen{} FI.{} formatiere auf eigener station:{} IF auswahl < 5{} THEN format (auswahl, /zieltaskname){}
+ ELSE format (/zieltaskname){} FI.{} formatiere auf fremder station:{} IF auswahl < 5{} THEN format (auswahl, stationsnummer/zieltaskname){} ELSE format (stationsnummer/zieltaskname){} FI.{} initialisiere ggf:{} stelle archivbesitz sicher;{} archiv anmelden (archivname, meldung, FALSE);{} IF archivname <> ""{} THEN aktueller archivname := archivname;{} archiv gehoert mir := TRUE;{} aktiviere gueltige archivmenupunkte;{} refresh submenu;{}
+ zieltask anzeigen;{} frage nach ueberschreiben{} ELIF meldung = menubasistext (63) OR meldung = menubasistext (62){} THEN frage nach initialisieren{} ELSE melde zieltaskerror (meldung);{} aktueller archivname := "";{} zieltask anzeigen;{} LEAVE menu archiv initialisieren{} FI.{} frage nach ueberschreiben:{} IF menuyes (menubasistext (86) + archivname + menubasistext (87), 5){} THEN erfrage neuen namen und initialisiere{}
+ ELSE LEAVE menu archiv initialisieren{} FI.{} frage nach initialisieren:{} IF menuyes (menubasistext (88), 5){} THEN erfrage neuen namen und initialisiere{} ELSE LEAVE menu archiv initialisieren{} FI.{} erfrage neuen namen und initialisiere:{} TEXT VAR neuer name := compress(menuanswer (menubasistext (89),{} aktueller archivname, 5));{} IF neuer name <> ""{} THEN archivname := neuer name{} ELIF neuer name = "" AND archivname = ""{}
+ THEN archivname := menubasistext (75){} FI;{} command dialogue (FALSE);{} disable stop;{} IF eigene station{} THEN reserve (archivname, /zieltaskname);{} clear (/zieltaskname){} ELSE reserve (archivname, stationsnummer/zieltaskname);{} clear (stationsnummer/zieltaskname){} FI;{} IF is error{} THEN melde zieltaskerror (errormessage);{} clear error; enable stop;{} command dialogue (TRUE);{} melde rigoros ab;{}
+ archivreservierung aufgeben;{} aktiviere gueltige archivmenupunkte;{} refresh submenu;{} zieltask anzeigen;{} LEAVE menu archiv initialisieren{} ELSE enable stop; command dialogue (TRUE);{} aktueller archivname := archivname;{} archiv gehoert mir := TRUE;{} aktiviere gueltige archivmenupunkte;{} refresh submenu;{} zieltask anzeigen{} FI{}END PROC menu archiv initialisieren;{}PROC archive (TEXT CONST archive name,task, INT CONST station):{}
+ call (reserve code, archive name, station/task){}END PROC archive;{}PROC menu archiv reservierung aufgeben:{} IF archiv gehoert mir{} THEN menufootnote (menubasistext (21) + menubasistext (22));{} archivreservierung aufgeben;{} FI;{} erase menunotice;{} old menufootnote{}END PROC menu archiv reservierung aufgeben;{}PROC archivreservierung aufgeben:{} command dialogue (FALSE);{} disable stop;{} IF eigene station{} THEN release (/zieltaskname){} ELSE release (stationsnummer/zieltaskname);{}
+ FI;{} IF is error{} THEN clear error{} FI;{} enable stop;{} command dialogue (TRUE);{} archiv gehoert mir := FALSE;{} aktueller archivname := ""{}END PROC archivreservierung aufgeben;{}BOOL PROC eigene station:{} IF stationsnummer = 0 OR stationsnummer = station (myself){} THEN TRUE{} ELSE FALSE{} FI{}END PROC eigene station;{}PROC aktiviere gueltige archivmenupunkte:{} IF zieltask ist archivmanager AND NOT archiv gehoert mir{} THEN aktiviere nur grundfunktionen{}
+ ELSE aktiviere alle momentan gueltigen punkte{} FI.{} aktiviere alle momentan gueltigen punkte:{} IF letzte funktion = 11{} THEN activate (1); activate (2);{} activate (4); activate (5); activate (6); activate (7); activate (8);{} activate (10); activate (11);{} activate (13); activate (14);{} ELIF letzte funktion = 6{} THEN deactivate (1); deactivate (2);{} activate (4); deactivate (5); deactivate (6); activate (7); activate (8);{}
+ activate (10); activate (11);{} deactivate (13); activate (14);{} FI.{} aktiviere nur grundfunktionen:{} activate (1); deactivate (2);{} deactivate (4); deactivate (5); deactivate (6); deactivate (7); deactivate (8);{} deactivate (10); deactivate (11);{} activate (13); activate (14).{}END PROC aktiviere gueltige archivmenupunkte;{}PROC zieltask anzeigen:{} IF zieltask ist archivmanager{} THEN schreibe taskname und archivname{} ELSE schreibe taskname{}
+ FI.{} schreibe taskname:{} write menunotice (menubasistext (59) + ""13"" + name der task, notizort).{} schreibe taskname und archivname:{} write menunotice (menubasistext (59) + ""13"" + name der task +{} ""13"" + menubasistext (60) + ""13"" + archivname,{} notizort).{} name der task:{} IF zieltaskname = "ARCHIVE" AND eigene station{} THEN " " + menubasistext (71){} ELIF zieltaskname = "PUBLIC" AND eigene station{} THEN " " + menubasistext (72){}
+ ELIF zieltaskname = name (father){} THEN " " + menubasistext (73){} ELSE " " + ggf gekuerzter zieltaskname{} FI.{} ggf gekuerzter zieltaskname:{} TEXT VAR interner name;{} IF eigene station{} THEN interner name := zieltaskname;{} ELSE interner name := text (stationsnummer) + "/" + zieltaskname{} FI;{} IF length (interner name) < 20{} THEN ""15"" + interner name + " "14""{} ELSE ""15"" + subtext (interner name, 1 , 18) + ".." + " "14""{} FI.{}
+ archivname:{} IF NOT archiv gehoert mir OR aktueller archivname = ""{} THEN " " + menubasistext (74){} ELSE " "15"" + ggf gekuerzter archivname + " "14""{} FI.{} ggf gekuerzter archivname:{} IF eigene station AND length (aktueller archivname) > 20{} THEN subtext (aktueller archivname, 1, 18) + ".."{} ELIF NOT eigene station AND length (aktueller archivname) > 17{} THEN subtext (aktueller archivname, 1, 15) + ".."{} ELSE aktueller archivname{} FI.{}
+END PROC zieltask anzeigen;{}BOOL PROC task ist kommunikativ (TEXT VAR fehler):{} INT VAR antwort;{} DATASPACE VAR dummy space := nilspace;{} IF zieltask ist archivmanager{} THEN schicke reservierungscode{} ELSE schicke listcode{} FI.{} schicke reservierungscode:{} disable stop;{} IF eigene station{} THEN pingpong (/zieltaskname, reserve code, dummy space, antwort);{} ELSE pingpong (stationsnummer/zieltaskname, reserve code,{} dummy space, antwort){}
+ FI;{} werte antwort aus.{} schicke listcode:{} disable stop;{} IF eigene station{} THEN pingpong (/zieltaskname, list code, dummy space, antwort);{} ELSE pingpong (stationsnummer/zieltaskname, list code,{} dummy space, antwort){} FI;{} werte antwort aus.{} werte antwort aus:{} IF is error{} THEN clear error{} FI;{} BOUND TEXT VAR inhalt := dummy space;{} enable stop;{} IF antwort = 0 THEN fehler := ""{} ELIF antwort = -1 THEN fehler := menubasistext (41){}
+ ELIF antwort = -2 THEN fehler := menubasistext (42){} ELSE fehler := inhalt{} FI;{} forget (dummy space);{} IF antwort = ack{} THEN kontakt mit zieltask erfolgt := TRUE; TRUE{} ELSE kontakt mit zieltask erfolgt := FALSE; FALSE{} FI{}END PROC task ist kommunikativ;{}END PACKET ls dialog 6;{}
+
diff --git a/dialog/ls-DIALOG 7 b/dialog/ls-DIALOG 7
new file mode 100644
index 0000000..467f531
--- /dev/null
+++ b/dialog/ls-DIALOG 7
@@ -0,0 +1,54 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG 7 **
+ ** Dateihandling **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls dialog 7 DEFINES{} menu dateien verzeichnis,{} menu dateien loeschen,{} menu dateien drucken,{} menu dateien kopieren,{} menu dateien umbenennen,{} menu dateien speicherplatz,{} menu dateien aufraeumen:{}LET filetype = 1003,{} maxlaenge = 60,{} breite = 40,{} niltext = "";{}TEXT CONST dateibez :: "Dateiliste bei internen Operationen";{}PROC menu dateien verzeichnis:{} forget (dateibez, quiet);{} liste dateien auf;{}
+ regenerate menuscreen.{} liste dateien auf:{} erstelle liste;{} gib liste aus;{} forget (dateibez, quiet).{} erstelle liste:{} menufootnote (menubasistext (21) + menubasistext (28));{} FILE VAR f :: sequential file (output, dateibez);{} list (f); modify (f);{} headline (f, menubasistext (43));{} to line (f, 1); insert record (f);{} write record (f, menubasistext (161));{} entferne eigenen namen aus der liste.{} entferne eigenen namen aus der liste:{} TEXT VAR zeile :: ""; INT VAR i;{}
+ FOR i FROM lines (f) DOWNTO 1 REP{} to line (f, i); read record (f, zeile);{} IF pos (zeile, dateibez) > 0{} THEN delete record (f);{} LEAVE entferne eigenen namen aus der liste{} FI{} PER.{} gib liste aus:{} to line (f, 1); cursor on; menuwindowshow (f); cursor off{}END PROC menu dateien verzeichnis;{}PROC menu dateien loeschen:{} lasse dateien auswaehlen;{} loesche ausgewaehlte dateien;{} regenerate menuscreen.{} lasse dateien auswaehlen:{} IF NOT not empty (ALL myself){}
+ THEN noch keine datei;{} LEAVE menu dateien loeschen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} THESAURUS VAR angekreuzte :={} menuanswersome ( center (breite, invers (menubasistext(162))) +{} menubasistext (163), "", ALL myself,{} menubasistext (162), menubasistext (91) +{} menubasistext (104) + menubasistext (92), FALSE).{} loesche ausgewaehlte dateien:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{}
+ menuwindowout (menuwindowcenter (invers (menubasistext (162))));{} menuwindowline (2);{} command dialogue (FALSE);{} fuehre einzelne operation aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (menubasistext (93) + menubasistext (104));{} menuwindowstop.{} fuehre einzelne operation aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (angekreuzte) REP{} IF name (angekreuzte, k) = niltext{} THEN LEAVE fuehre einzelne operation aus{}
+ ELIF NOT exists (name (angekreuzte, k)){} THEN menuwindowout (" """ + name (angekreuzte, k) + """");{} menuwindowline;{} menuwindowout (menubasistext (188)); menuwindowline;{} LEAVE fuehre einzelne operation aus{} ELSE disable stop;{} IF menuwindowyes (" """ + name (angekreuzte, k) + """ "{} + menubasistext (111)){} THEN forget (name (angekreuzte, k), quiet){} FI;{}
+ fehlerbehandlung{} FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (angekreuzte){} THEN menuwindowline (2);{} menuwindowout (menubasistext (94));{} menuwindowstop;{} regenerate menuscreen;{} LEAVE menu dateien loeschen{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{}
+ THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{} clear error; enable stop;{} LEAVE menu dateien loeschen{} FI{}END PROC menu dateien loeschen;{}PROC menu dateien drucken:{} lasse programme auswaehlen;{} drucke programme;{} regenerate menuscreen.{} lasse programme auswaehlen:{} IF NOT not empty (ALL myself){} THEN noch keine datei;{} LEAVE menu dateien drucken{} ELSE biete auswahl an{} FI.{} biete auswahl an:{}
+ THESAURUS VAR angekreuzte :={} menuanswersome ( center (breite, invers (menubasistext(164))) +{} menubasistext (163), "", ALL myself,{} menubasistext (164), menubasistext (91) +{} menubasistext (165) + menubasistext (92), FALSE).{} drucke programme:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers (menubasistext (164))));{} menuwindowline (2);{} command dialogue (FALSE);{}
+ fuehre einzelne operation aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (menubasistext (93) + menubasistext (165));{} menuwindowstop.{} fuehre einzelne operation aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (angekreuzte) REP{} IF name (angekreuzte, k) = niltext{} THEN LEAVE fuehre einzelne operation aus{} ELIF NOT exists (name (angekreuzte, k)){} THEN menuwindowout (" """ + name (angekreuzte, k) + """");{}
+ menuwindowline;{} menuwindowout (menubasistext (188)); menuwindowline;{} LEAVE fuehre einzelne operation aus{} ELSE disable stop;{} menuwindowout ( " """ + name (angekreuzte, k) + """ "{} + menubasistext (166));{} menuwindowline;{} print (name (angekreuzte, k));{} fehlerbehandlung{} FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (angekreuzte){}
+ THEN menuwindowline (2);{} menuwindowout (menubasistext (94));{} menuwindowstop;{} regenerate menuscreen;{} LEAVE menu dateien drucken{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{} clear error; enable stop;{}
+ LEAVE menu dateien drucken{} FI.{}END PROC menu dateien drucken;{}PROC menu dateien kopieren:{} ermittle alten dateinamen;{} erfrage neuen dateinamen;{} kopiere ggf die datei.{} ermittle alten dateinamen:{} IF NOT not empty (ALL myself){} THEN noch keine datei;{} LEAVE menu dateien kopieren{} ELSE hole den namen{} FI.{} hole den namen:{} TEXT VAR alter name :={} menuanswerone ( center (breite, invers (menubasistext(167))) +{} menubasistext (163), "", ALL myself,{}
+ menubasistext (167), menubasistext (168) +{} menubasistext (169) + menubasistext (170), TRUE);{} IF alter name = niltext{} THEN LEAVE menu dateien kopieren{} ELIF NOT exists (alter name){} THEN menuinfo (menubasistext (188));{} LEAVE menu dateien kopieren{} FI.{} erfrage neuen dateinamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + menubasistext (171) + bisheriger name{}
+ + menubasistext (172).{} ueberschrift:{} center (maxlaenge, invers (menubasistext (167))) + ""13""13"".{} bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{} kopiere ggf die datei:{} IF neuer name = niltext{} THEN menuinfo (invers (menubasistext (173)));{} LEAVE menu dateien kopieren{} ELIF exists (neuer name){} THEN mache vorwurf;{} LEAVE menu dateien kopieren{} ELSE copy (alter name, neuer name){}
+ FI.{} mache vorwurf:{} menuinfo (menubasistext (174)).{}END PROC menu dateien kopieren;{}PROC menu dateien umbenennen:{} ermittle alten dateinamen;{} erfrage neuen dateinamen;{} benenne ggf die datei um.{} ermittle alten dateinamen:{} IF NOT not empty (ALL myself){} THEN noch keine datei;{} LEAVE menu dateien umbenennen{} ELSE hole den namen{} FI.{} hole den namen:{} TEXT VAR alter name :={} menuanswerone ( center (breite, invers (menubasistext(175))) +{}
+ menubasistext (163), "", ALL myself,{} menubasistext (175), menubasistext (168) +{} menubasistext (176) + menubasistext (170), TRUE);{} IF alter name = niltext{} THEN LEAVE menu dateien umbenennen{} ELIF NOT exists (alter name){} THEN menuinfo (menubasistext (188));{} LEAVE menu dateien umbenennen{} FI.{} erfrage neuen dateinamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{}
+ ueberschrift + menubasistext (171) + bisheriger name{} + menubasistext (177).{} ueberschrift:{} center (maxlaenge, invers (menubasistext (175))) + ""13""13"".{} bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{} benenne ggf die datei um:{} IF neuer name = niltext{} THEN menuinfo (invers (menubasistext (173)));{} LEAVE menu dateien umbenennen{} ELIF exists (neuer name){} THEN mache vorwurf;{} LEAVE menu dateien umbenennen{}
+ ELSE rename (alter name, neuer name){} FI.{} mache vorwurf:{} menuinfo (menubasistext (174)).{}END PROC menu dateien umbenennen;{}PROC menu dateien speicherplatz:{} lasse dateinamen auswaehlen;{} ermittle den speicherplatz;{} regenerate menuscreen.{} lasse dateinamen auswaehlen:{} IF NOT not empty (ALL myself){} THEN noch keine datei;{} LEAVE menu dateien speicherplatz{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} THESAURUS VAR angekreuzte :={}
+ menuanswersome ( center (breite, invers (menubasistext(178))) +{} menubasistext (163), "", ALL myself,{} menubasistext (178), menubasistext (179), FALSE).{} ermittle den speicherplatz:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers (menubasistext (178))));{} menuwindowline (2);{} command dialogue (FALSE);{} fuehre einzelne operation aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{}
+ menuwindowout (menubasistext (180));{} menuwindowstop.{} fuehre einzelne operation aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (angekreuzte) REP{} IF name (angekreuzte, k) = niltext{} THEN LEAVE fuehre einzelne operation aus{} ELIF NOT exists (name (angekreuzte, k)){} THEN menuwindowout (" """ + name (angekreuzte, k) + """");{} menuwindowline;{} menuwindowout (menubasistext (188)); menuwindowline;{} LEAVE fuehre einzelne operation aus{}
+ ELSE disable stop;{} menuwindowout ( " """ + name (angekreuzte, k) + """ "{} + menubasistext (181){} + speicherplatz (name (angekreuzte, k)));{} menuwindowline;{} fehlerbehandlung{} FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (angekreuzte){} THEN menuwindowline (2);{} menuwindowout (menubasistext (94));{} menuwindowstop;{} regenerate menuscreen;{}
+ LEAVE menu dateien speicherplatz{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{} clear error; enable stop;{} LEAVE menu dateien speicherplatz{} FI.{}END PROC menu dateien speicherplatz;{}TEXT PROC speicherplatz (TEXT CONST dateiname):{}
+ DATASPACE VAR ds :: old (dateiname);{} INT CONST platz :: storage (ds);{} forget (ds);{} " " + text (platz) + menubasistext (182){}END PROC speicherplatz;{}PROC menu dateien aufraeumen:{} lasse dateinamen auswaehlen;{} raeume die dateien auf;{} regenerate menuscreen.{} lasse dateinamen auswaehlen:{} IF NOT not empty (ALL myself){} THEN noch keine datei;{} LEAVE menu dateien aufraeumen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} THESAURUS VAR angekreuzte :={}
+ menuanswersome ( center (breite, invers (menubasistext(183))) +{} menubasistext (163), "", ALL myself,{} menubasistext (183), menubasistext (91) +{} menubasistext (184) + menubasistext (92), FALSE).{} raeume die dateien auf:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers (menubasistext (183))));{} menuwindowline (2);{} command dialogue (FALSE);{} fuehre einzelne operation aus;{}
+ command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (menubasistext (93) + menubasistext (184));{} menuwindowstop.{} fuehre einzelne operation aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (angekreuzte) REP{} IF name (angekreuzte, k) = niltext{} THEN LEAVE fuehre einzelne operation aus{} ELIF NOT exists (name (angekreuzte, k)){} THEN menuwindowout (" """ + name (angekreuzte, k) + """");{} menuwindowline;{} menuwindowout (menubasistext (188)); menuwindowline;{}
+ LEAVE fuehre einzelne operation aus{} ELIF dateityp ist ok{} THEN disable stop;{} menuwindowline;{} menuwindowout ( " """ + name (angekreuzte, k) + """ "{} + menubasistext (185) );{} menuwindowline; menuwindowout (" ");{} reorganize (name (angekreuzte, k));{} fehlerbehandlung{} ELSE menuwindowout ( " """ + name (angekreuzte, k) + """ "{} + menubasistext (186)){}
+ FI{} PER.{} dateityp ist ok:{} type (old (name (angekreuzte, k))) = filetype.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (angekreuzte){} THEN menuwindowline (2);{} menuwindowout (menubasistext (94));{} menuwindowstop;{} regenerate menuscreen;{} LEAVE menu dateien aufraeumen{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){}
+ FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{} clear error; enable stop;{} LEAVE menu dateien aufraeumen{} FI.{}END PROC menu dateien aufraeumen;{}PROC noch keine datei:{} menuinfo (menubasistext ( 187)){}END PROC noch keine datei;{}END PACKET ls dialog 7;{}
+
diff --git a/dialog/ls-DIALOG MENUKARTEN MANAGER b/dialog/ls-DIALOG MENUKARTEN MANAGER
new file mode 100644
index 0000000..67799ea
--- /dev/null
+++ b/dialog/ls-DIALOG MENUKARTEN MANAGER
@@ -0,0 +1,28 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG **
+ ** MENUKARTEN-MANAGER **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls dialog manager DEFINES{} ls dialog manager:{}LET fetch code = 11,{} save code = 12,{} exists code = 13,{} list code = 15,{} continue code = 100;{}LET mm taskname = "ls-MENUKARTEN",{} gibt es schon = "Die Task 'ls-MENUKARTEN' existiert schon!",{} verweis = "Unzulässiger Zugriff auf die Task 'ls-MENUKARTEN'!";{}PROC ls dialog manager:{} stelle richtigen tasknamen ein;{} global manager{} (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST) ls dialog manager){}
+END PROC ls dialog manager;{}PROC stelle richtigen tasknamen ein:{} IF name (myself) <> mm taskname{} THEN nimm umbenennung vor{} FI.{} nimm umbenennung vor:{} IF NOT exists task (mm taskname){} THEN rename myself (mm taskname){} ELSE errorstop (gibt es schon){} FI.{}END PROC stelle richtigen tasknamen ein;{}PROC ls dialog manager (DATASPACE VAR ds, INT CONST order, phase,{} TASK CONST order task):{} IF order task = supervisor{} OR order = fetch code{}
+ OR order = save code{} OR order = exists code{} OR order = list code{} OR order = continue code{} THEN free manager (ds, order, phase, order task){} ELSE errorstop (verweis){} FI{}END PROC ls dialog manager;{}END PACKET ls dialog manager;{}
+
diff --git a/dialog/ls-DIALOG MM-gen b/dialog/ls-DIALOG MM-gen
new file mode 100644
index 0000000..ef05853
--- /dev/null
+++ b/dialog/ls-DIALOG MM-gen
@@ -0,0 +1,27 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG **
+ ** MENUKARTEN MANAGER **
+ ** Generator-Programm **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+LET dateiname = "ls-DIALOG MENUKARTEN MANAGER",{} archivname = "gs-dialog";{}gib bildschirmhinweis;{}hole generatordatei vom archiv;{}insertiere die datei;{}do ("ls dialog manager").{}gib bildschirmhinweis:{} page;{} putline (" "15"ls-DIALOG MENUKARTEN MANAGER - Generierung "14"").{}hole generatordatei vom archiv:{} IF NOT exists (dateiname){} THEN cursor (1, 5); out (""4"");{} putline ("Bitte warten... Ich hole eine Datei von der Diskette!");{} archive (archivname);{}
+ fetch (dateiname, archive);{} release (archive){} FI.{}insertiere die datei:{} cursor (1, 5); out (""4"");{} putline ("Bitte warten... Ich insertiere!");{} check off; insert (dateiname); check on;{} forget ("ls-DIALOG MM/gen", quiet);{} forget (dateiname, quiet).{}
+
diff --git a/dialog/ls-DIALOG decompress b/dialog/ls-DIALOG decompress
new file mode 100644
index 0000000..96d9340
--- /dev/null
+++ b/dialog/ls-DIALOG decompress
@@ -0,0 +1,150 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG - DECOMPRESS **
+ ** **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+PACKET ls dialog decompress DEFINES
+
+ komprimiere,
+ dekomprimiere:
+
+LET verweis = "Angegebene Datei existiert nicht!",
+ falscher typ = "Angegebenen Datei hat falschen Typ!",
+ filetype = 1003;
+
+PROC komprimiere (TEXT CONST dateiname):
+ INT VAR zeiger;
+ ueberpruefe existenz;
+ ueberpruefe dateityp;
+ initialisiere;
+ FOR zeiger FROM 1 UPTO 24 REP
+ getline (ein, eingabezeile);
+ putline (aus, eingabezeile);
+ PER;
+ WHILE NOT eof (ein) REP
+ getline (ein, eingabezeile);
+ zaehler INCR 1; cout (zaehler);
+ zwischenzeile := abgeschnitten (eingabezeile);
+ haenge zeilentrenner an;
+ haenge zwischenzeile an ausgabezeile;
+ schreibe ausgabezeile ggf weg
+ PER;
+ schreibe ausgabezeile weg;
+ mache ausgabedatei zur eingabedatei.
+
+ ueberpruefe existenz:
+ IF NOT exists (dateiname)
+ THEN errorstop (verweis);
+ FI.
+
+ ueberpruefe dateityp:
+ IF type (old (dateiname)) <> filetype
+ THEN errorstop (falscher typ)
+ FI.
+
+ initialisiere:
+ FILE VAR ein := sequential file (input, dateiname);
+ FILE VAR aus := sequential file (output, "KOMPRIM");
+ maxlinelength (aus, 600);
+ INT VAR zaehler :: 1;
+ TEXT VAR eingabezeile :: "", zwischenzeile :: "", ausgabezeile :: "".
+
+ haenge zeilentrenner an:
+ IF zwischenzeile <> ""
+ THEN zwischenzeile CAT "{}"
+ FI.
+
+ haenge zwischenzeile an ausgabezeile:
+ ausgabezeile CAT zwischenzeile.
+
+ schreibe ausgabezeile ggf weg:
+ IF length (ausgabezeile) > 500
+ THEN schreibe ausgabezeile weg
+ FI.
+
+ schreibe ausgabezeile weg:
+ IF ausgabezeile <> ""
+ THEN putline (aus, ausgabezeile);
+ ausgabezeile := ""
+ FI.
+
+mache ausgabedatei zur eingabedatei:
+ forget (dateiname, quiet);
+ rename ("KOMPRIM", dateiname).
+END PROC komprimiere;
+
+TEXT PROC abgeschnitten (TEXT CONST zeile):
+ TEXT VAR t :: zeile;
+ WHILE (t SUB length (t)) = " " REP
+ t := subtext (t, 1, length (t) - 1)
+ PER;
+ t
+END PROC abgeschnitten;
+
+PROC dekomprimiere (TEXT CONST dateiname):
+ INT VAR zeiger;
+ ueberpruefe existenz;
+ ueberpruefe dateityp;
+ initialisiere;
+ FOR zeiger FROM 1 UPTO 24 REP
+ getline (ein, eingabezeile);
+ putline (aus, eingabezeile);
+ PER;
+ WHILE NOT eof (ein) REP
+ getline (ein, eingabezeile);
+ zerlege zeile
+ PER;
+ forget (dateiname, quiet);
+ rename ("DEKOMPRIM", dateiname).
+
+ ueberpruefe existenz:
+ IF NOT exists (dateiname)
+ THEN errorstop (verweis)
+ FI.
+
+ ueberpruefe dateityp:
+ IF type (old (dateiname)) <> filetype
+ THEN errorstop (falscher typ)
+ FI.
+
+ initialisiere:
+ FILE VAR ein := sequential file (input, dateiname);
+ FILE VAR aus := sequential file (output, "DEKOMPRIM");
+ INT VAR zaehler :: 1;
+ TEXT VAR eingabezeile :: "", ausgabezeile :: "".
+
+ zerlege zeile:
+ WHILE eingabezeile <> "" REP
+ nimm das erste stueck und schreibe es weg;
+ entferne den zeilentrenner
+ PER.
+
+ nimm das erste stueck und schreibe es weg:
+ ausgabezeile := subtext (eingabezeile, 1, pos (eingabezeile, "{}") - 1);
+ putline (aus, ausgabezeile);
+ zaehler INCR 1;
+ cout (zaehler).
+
+ entferne den zeilentrenner:
+ eingabezeile := subtext (eingabezeile, pos (eingabezeile, "{}") + 2).
+END PROC dekomprimiere;
+END PACKET ls dialog decompress;
+
diff --git a/dialog/ls-DIALOG-gen b/dialog/ls-DIALOG-gen
new file mode 100644
index 0000000..e085616
--- /dev/null
+++ b/dialog/ls-DIALOG-gen
@@ -0,0 +1,34 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-DIALOG **
+ ** GENERATORPROGRAMM **
+ ** Version 1.2 **
+ ** **
+ ** (Stand: 04.11.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+LET mm taskname = "ls-MENUKARTEN",{} datei 1 = "ls-DIALOG 1",{} datei 2 = "ls-DIALOG 2",{} datei 3 = "ls-DIALOG 3",{} datei 4 = "ls-DIALOG 4",{} datei 5 = "ls-DIALOG 5",{} datei 6 = "ls-DIALOG 6",{} datei 7 = "ls-DIALOG 7",{} menukarte = "ls-MENUKARTE:Archiv";{}PROC stelle existenz des mm sicher:{} cursor (1, 5); out (""4"");{} IF NOT exists (task (mm taskname)){} THEN errorstop ("Unbedingt erst den 'MENUKARTEN-MANAGER' generieren!");{} FI{}
+END PROC stelle existenz des mm sicher;{}PROC vom archiv (TEXT CONST datei):{} cursor (1,5); out (""4"");{} out (" """); out (datei); putline (""" wird geholt.");{} fetch (datei, archive){}END PROC vom archiv;{}PROC hole (TEXT CONST datei):{} IF NOT exists (datei) THEN vom archiv (datei) FI{}END PROC hole;{}PROC in (TEXT CONST datei):{} hole (datei);{} cursor (1, 5); out (""4"");{} out (" """); out (datei); out (""" wird übersetzt: ");{} insert (datei);{} forget (datei, quiet);{}END PROC in;{}
+PROC schicke (TEXT CONST datei):{} cursor (1, 5); out (""4"");{} out (" """); out(datei);{} out (""" wird zum MENUKARTEN-MANAGER geschickt!");{} command dialogue (FALSE);{} save (datei, task (mm taskname));{} command dialogue (TRUE);{} forget (datei, quiet){}END PROC schicke;{}INT VAR size, used;{}BOOL VAR einzeln;{}storage (size, used);{}einzeln := size - used < 500;{}forget ("ls-DIALOG/gen", quiet);{}wirf kopfzeile aus;{}stelle existenz des mm sicher;{}hole die dateien;{}insertiere die dateien;{}
+mache global manager aus der task.{}wirf kopfzeile aus:{} page;{} putline (" "15"ls-DIALOG - Automatische Generierung "14"").{}hole die dateien:{} IF NOT exists (datei 1) COR NOT exists (datei 2){} COR NOT exists (datei 3) COR NOT exists (datei 4){} COR NOT exists (datei 5) COR NOT exists (datei 6){} COR NOT exists (datei 7) COR NOT exists (menukarte){} THEN hole dateien vom archiv{} FI.{}hole dateien vom archiv:{} cursor (1,3);{} IF yes ("Ist das Archiv angemeldet und die 'ls-DIALOG' - Diskette eingelegt"){}
+ THEN lese ein{} ELSE line (2);{} errorstop ("Ohne die Diskette kann ich das System nicht generieren!"){} FI.{}lese ein:{} cursor (1, 3); out (""4"");{} out (" "15"Bitte die Diskette eingelegt lassen! "14"");{} IF NOT einzeln{} THEN hole (datei 1);{} hole (datei 2);{} hole (datei 3);{} hole (datei 4);{} hole (datei 5);{} hole (datei 6);{} hole (datei 7);{} hole (menukarte);{} cursor (1, 3); out(""4"");{}
+ out (" "15"Die Diskette wird nicht mehr benötigt! "14"");{} release (archive){} FI.{}insertiere die dateien:{} check off;{} in (datei 1);{} in (datei 2);{} in (datei 3);{} in (datei 4);{} in (datei 5);{} in (datei 6);{} in (datei 7);{} schicke (menukarte);{} IF einzeln THEN release (archive) FI;{} check on.{}mache global manager aus der task:{} global manager.{}
+
+
+
+
diff --git a/dialog/ls-MENUKARTE:Archiv b/dialog/ls-MENUKARTE:Archiv
new file mode 100644
index 0000000..c859d22
--- /dev/null
+++ b/dialog/ls-MENUKARTE:Archiv
Binary files differ
diff --git a/doc/basic/basic handbuch.1 b/doc/basic/basic handbuch.1
new file mode 100644
index 0000000..2e604cb
--- /dev/null
+++ b/doc/basic/basic handbuch.1
@@ -0,0 +1,1075 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#Basic
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#page nr ("%", 1)#
+#head#
+EUMEL-BASIC-Compiler Inhalt %
+#end#
+
+Inhalt
+
+1 Einleitung 3
+
+2 Installation des BASIC-Compilers 4
+
+3 Aufruf und Steuerung des BASIC-Compilers 5
+
+4 Umgang mit dem BASIC-Compiler 7
+4.1 Erläuterungen zur Syntax 7
+4.2 Datentypen und Konstanten 10
+4.3 Variablen und Felder 12
+4.4 Operatoren 14
+4.5 Funktionen 19
+4.6 Typanpassung 22
+4.7 Aufruf von EUMEL-Prozeduren in BASIC-Programmen 23
+
+5 Steuerung der Bildschirmausgaben 25
+
+6 Grenzen des Compilers 26
+
+7 Fehlerbehandlung 28
+7.1 Fehler zur Übersetzungszeit 28
+7.2 Fehler zur Laufzeit 30
+
+8 Übersicht über die Anweisungen und Funktionen 31
+
+9 Anpassung von Programmen an den EUMEL-BASIC-Compiler 96
+9.1 Unterschiede zwischen BASIC-Interpretern
+ und dem EUMEL-BASIC-Compiler 96
+9.2 Abweichungen von ISO 6373-1984 (Minimal-BASIC) 97
+9.3 Anpassung von Microsoft-BASIC Programmen
+ an den EUMEL-BASIC-Compiler 98
+
+Anhang A: Reservierte Wörter 100
+Anhang B: Vom Scanner erkannte Symboltypen 103
+Anhang C: Übersicht über die Fehlermeldungen 106
+Anhang D: ELAN-Prozeduren des Compilers 113
+#page#
+
+
+#page nr ("%", 3)#
+#head#
+EUMEL-BASIC-Compiler 1. Einleitung %
+
+#end#
+
+1. Einleitung
+
+
+BASIC entspricht heute nicht mehr den Vorstellungen von einer modernen Program­
+miersprache. Dennoch wurde für das EUMEL-Betriebssystem ein Compiler für BASIC
+entwickelt. Er soll vor allem dazu dienen, schon bestehende BASIC-Programme -
+gegebenenfalls nach entsprechender Anpassung - auch unter EUMEL verfügbar zu
+machen.
+Der Compiler ist weitgehend an die ISO-Norm 6373 für Minimal-BASIC angelehnt.
+Die Syntax und Bedeutung der Anweisungen orientiert sich in den meisten Fällen an
+Microsoft-BASIC. Anweichungen treten insbesondere an den Stellen auf, an denen
+Prinzipien des Betriebssystems EUMEL verletzt würden.
+Verglichen mit dem ELAN-Compiler des EUMEL-Systems ist der BASIC-Compiler
+beim Übersetzen recht langsam. Auch aus diesem Grund scheint es nicht sinnvoll,
+den BASIC-Compiler zur Neuentwicklung größerer Programme einzusetzen.
+
+Sinn dieses Handbuchs ist es vor allem, Kenntnisse über den Umgang mit dem
+EUMEL-BASIC-Compiler zu vermitteln. Das Handbuch ist auf keinen Fall als Ein­
+führung in die Programmiersprache BASIC gedacht, sondern es soll dem Benutzer mit
+BASIC-Erfahrung die Arbeit mit dem EUMEL-BASIC-Compiler ermöglichen und
+erleichtern. Neben Erfahrung in BASIC setzt dieses Buch an einigen Stellen auch
+Grundkenntnisse über das EUMEL-System voraus.
+
+
+
+Zur #ib(4)#Notation#ie(4)# in dieser Beschreibung
+
+Bei der Beschreibung der Anweisungen und Funktionen und auch an anderen Stellen
+werden in dieser Beschreibung Syntaxregeln für BASIC-Programme oder Teile davon
+angegeben. Dabei werden folgende Zeichen mit besonderer Bedeutung verwendet:
+
+[ ] optionale Angabe
+[...] beliebig häufige Wiederholung der letzten optionalen Angabe
+| alternative Angabe, d.h. entweder die letzte links stehende Angabe oder
+ die nächste rechts stehende Angabe, aber nicht beide
+< > in spitzen Klammern stehende Begriffe sind entweder definiert (z.B. <Va­
+ riable>) oder werden hinter der Syntaxregel erläutert
+
+Die Notation der exportierten ELAN-Prozeduren des Compilers (besonders in An­
+hangD) entspricht der in den EUMEL-Handbüchern üblichen Prozedurkopf-
+Schreibweise.
+#page#
+#head#
+EUMEL-BASIC-Compiler 2. Installation des BASIC-Compilers %
+
+#end#
+
+2. #ib(3)#Installation des BASIC-Compilers#ie(3)#
+
+
+Der EUMEL-BASIC-Compiler wird auf zwei Disketten mit jeweils 360 KByte
+Speicherkapazität ausgeliefert.
+Auf der Diskette "BASIC.1" befindet sich das #ib(3)#Generatorprogramm#ie(3)#("gen.BASIC") zur
+Installation des EUMEL-BASIC-Systems.
+Legen Sie diese Diskette in das Laufwerk ihres Rechners ein und geben Sie in der
+Task, in der das BASIC-System installiert werden soll, folgende Zeile nach 'gib
+kommando :' (oder 'maintenance :') ein:
+
+archive ("BASIC.1"); fetch ("gen.BASIC", archive); run
+
+Lassen Sie die Diskette 'BASIC.1' im Laufwerk und antworten Sie auf die Frage
+"Archiv "BASIC.1" eingelegt(j/n)?" mit "j". Das Generatorprogramm holt nun einige
+Dateien von der Diskette. Nach Zugriff auf das Archiv erscheint die Meldung "Archiv
+abgemeldet!" und die Frage "Archiv 'BASIC.2' eingelegt(j/n)?". Legen Sie nun statt
+des Archivs 'BASIC.1' das Archiv 'BASIC.2' in das Laufwerk ein und drücken Sie bitte
+wiederum "j". Nach weiteren Archivoperationen erscheint dann wieder die Meldung
+"Archiv abgemeldet". Sie können nun die Diskette "BASIC.2" aus dem Laufwerk
+entnehmen.
+Das Generatorprogramm insertiert nun alle Programme des BASIC-Systems in der
+Task. Dieser Vorgang nimmt einige Zeit in Anspruch. Zum Abschluß erscheint die
+Meldung "BASIC-System installiert".
+Der EUMEL-BASIC-Compiler steht Ihnen nun in der Task (und in nachfolgend
+eingerichteten Söhnen) zur Verfügung.
+#page#
+#head#
+EUMEL-BASIC-Compiler 3. Aufruf und Steuerung des BASIC-Compilers %
+
+#end#
+
+3. #ib(4)#Aufruf und #ib(3)#Steuerung des BASIC-Compilers#ie(3)##ie(4)#
+
+
+
+
+Übersetzen von BASIC-Programmen
+
+Ein BASIC-Programm, das vom Compiler übersetzt werden soll, muß sich dazu in
+einer EUMEL-Textdatei befinden (Syntax vgl. Kap. 4.). Steht das BASIC-Programm
+zum Beispiel in der Datei "Programm.17+4", so wird der Compiler mit
+
+ #ib(3)#basic#ie(3)# ("Programm.17+4")
+
+zum Übersetzen dieses Programms aufgerufen.
+In einem Vordurchlauf werden die Zeilennummern des Programms auf Richtigkeit
+überprüft. Beim eigentlichen Compilerdurchlauf wird das BASIC-Programm dann mit
+Hilfe des EUMEL-Coders in einen von der EUMEL-0-Maschine ausführbaren Code
+übersetzt.
+
+Das Programm wird mit 'check on' (Zeilennummergenerierung) übersetzt.
+Ein 'runagain' wie bei ELAN-Programmen ist bei BASIC-Programmen zur Zeit
+leider nicht möglich.
+
+
+
+Insertieren von BASIC-Programmen
+
+Der BASIC-Compiler kann BASIC-Programme auch insertieren. Das ganze Pro­
+gramm bildet dabei eine Prozedur, die nach dem Insertieren wie eine 'normale'
+ELAN-Prozedur aufgerufen werden kann.
+Zum Insertieren wird der Compiler mit einem zusätzlichen Text-Parameter aufge­
+rufen:
+
+ #ib(3)#basic#ie(3)# ("Programm.17+4", "blackjack")
+
+Das Programm wird übersetzt und, falls keine Fehler gefunden wurden, fest einge­
+tragen ('insertiert'). Gestartet wird das Programm aber nicht.
+"blackjack" ist nun der Prozedurname, unter dem das BASIC-Programm nach erfolg­
+reichem Insertieren aufgerufen werden kann.
+Bei 'packets' erscheint jetzt der Eintrag 'BASIC.blackjack' in der Liste der insertierten
+Pakete, und ein 'help ("blackjack")' zeigt, daß eine Prozedur 'blackjack' nun tatsäch­
+lich in der Task bekannt ist. Die Prozedur 'bulletin' funktioniert für insertierte
+BASIC-Programme nicht. Sie ist aber auch nicht nötig, da das 'Paket' mit dem
+BASIC-Programm ohnehin nur eine Prozedur enthält und ihr Name ja schon aus
+dem Namen des Paketes hervorgeht.
+
+#on ("b")#
+Beachten Sie:
+ - Der Prozedurname muß der Syntax für ELAN-Prozedurnamen entsprechen, darf
+ aber #on ("b")#keine Leerzeichen enthalten.
+ - Die BASIC-Programme können über den Prozedurnamen nur aufgerufen wer­
+ den; die Übergabe von Parametern ist ebenso wie Wertlieferung nicht möglich.
+ - Jedes Insertieren belegt Speicherplatz im Codebereich der Task. Weil der Coder
+ und der Compiler ebenfalls recht viel Code belegen, kann es (vor allem, wenn
+ die BASIC-Programme lang sind) schnell zu einem Code-Überlauf kommen
+ (Compiler Error 305). Es sollten daher nur die Programme insertiert werden, für
+ die dies wirklich nötig ist.
+ - Achten Sie bei der Wahl des Namens für die gelieferte Prozedur darauf, daß sie
+ nicht ungewollt Prozeduren des Betriebssystems überdecken. (Der Aufruf 'ba­
+ sic("tadellos","help")' wäre z.B. gar nicht tadellos, denn 'help' wäre nach dem
+ Insertieren überdeckt).
+ - Auch beim Insertieren werden die BASIC-Programme mit 'check on' übersetzt.
+#off ("b")#
+
+
+Ausgabe der übersetzten Zeilen während des
+Compilierens
+Mit '#ib(3)#basic list#ie(3)# (TRUE)' wird der Compiler so eingestellt, daß beim Übersetzen die
+aktuelle Programmzeile ausgegeben wird. Diese Ausgabe kann auch mit '#ib(3)#sysout#ie(3)#'
+umgeleitet werden. Zum Beispiel:
+
+ sysout ("Fehlerprotokoll"); basic ("Programm.17+4")
+
+Dies kann beim #ib(3)#Debugging#ie(3)# von BASIC-Programmen eine wertvolle Hilfe sein, da in
+der Ausgabedatei die Fehler sofort hinter der betreffenden Programmzeile vermerkt
+werden. Das 'sysout' muß in Monitortasks ('gib kommando:') direkt vor dem Aufruf
+des Compilers gegeben werden, weil der Monitor 'sysout' sonst wieder zurücksetzt.
+
+Mit 'basic list (FALSE)' kann die Ausgabe der Programmzeilen beim Übersetzen
+wieder ausgeschaltet werden.
+
+#page#
+#head#
+EUMEL-BASIC-Compiler 4. Umgang mit dem BASIC-Compiler %
+
+#end#
+
+4. Umgang mit dem BASIC-Compiler
+
+
+
+4.1. Erläuterungen zur #ib(3)#Syntax#ie(3)#
+
+
+Ein zu übersetzendes Programm muß dem BASIC-Compiler in Form einer
+#ib(3)#EUMEL-Textdatei#ie(3)# übergeben werden. (Es gelten somit auch die für EUMEL-Text­
+dateien üblichen Begrenzungen, z.B. höchstens 32000 Zeichen pro Zeile und höch­
+stens 4075 Dateizeilen pro Datei.)
+BASIC-Programme setzen sich aus Programmzeilen zusammen; jede Dateizeile der
+#ib(3)#Programmdatei#ie(3)# bildet eine BASIC-Programmzeile. Die Syntax für ein Programm sieht
+damit so aus:
+
+
+<Programmzeile>[<Programmzeile>][...]EOF
+
+Dabei bedeutet #ib(3)#EOF (end of file)#ie(3)# das Ende der Programmdatei.
+
+Eine #ib(3)#Programmzeile#ie(3)# hat folgende Syntax:
+
+
+[<Zeilennummer>][<Anweisung>][:<Anweisung>][...][:]EOL
+
+Die #ib(3)#Zeilennummer#ie(3)# dient unter anderem als Sprungadresse an den Anfang der Pro­
+grammzeile während der Laufzeit des Programms (vgl. 'GOTO' und 'GOSUB'). Sie ist
+fakultativ (d.h. sie muß nicht geschrieben werden). Durch sparsame Verwendung von
+Zeilennummern (nämlich nur da, wo sie benötigt werden) kann eine gewisse Steige­
+rung der #ib(3)#Übersichtlichkeit von BASIC-Programmen#ie(3)# erreicht werden. Hat eine Pro­
+grammzeile keine Zeilennummer, so wird bei Fehlermeldungen (sowohl während der
+Übersetzung als auch zur Laufzeit des Programms) die letzte Zeilennummer mit
+angegeben, die davor auftrat.
+Zeilennummern dürfen im Bereich von 1 bis 32767 liegen und müssen unbedingt in
+aufsteigender Reihenfolge vergeben werden. Zeilennummern dürfen keine Leerzeichen
+enthalten und müssen mit einem Leerzeichen abgeschlossen werden. Um spätere
+Ergänzungen zu ermöglichen, ist eine Numerierung im Abstand zehn empfehlenswert.
+
+Hier ein Beispiel, wie ein BASIC-Programm in einer EUMEL-Datei aussehen
+könnte:
+
+
+...........................Einmaleins............................
+10 CLS: PRINT "Kleines Einmaleins"
+ FOR zahl% = 1 TO 10
+ PRINT
+ 'Erzeugung einer Zeile
+ FOR faktor% = 1 TO 10
+ PRINT TAB (faktor% * 5);
+ PRINT USING "\#\#\#"; faktor% * zahl%;
+ NEXT faktor%
+ NEXT zahl%
+
+
+
+
+Die Syntax der Anweisungen, die vom EUMEL-BASIC-Compiler übersetzt werden
+können, ist ausführlich im Kapitel 8 beschrieben.
+
+Der #ib(3)#Doppelpunkt#ie(3)# dient als Trennzeichen zwischen Anweisungen. Ihm muß nicht
+unbedingt eine Anweisung folgen. Er kann somit als explizites "Ende der
+Anweisung"-Symbol aufgefaßt werden (#ib(3)#EOS, "end of statement"#ie(3)#).
+
+#ib(3)#EOL (end of line)#ie(3)# ist das Ende einer Dateizeile. (Dieses "Zeichen" ist ebenso wie
+EOF beim Editieren der Datei nicht sichtbar.)
+Das #ib(3)#Hochkomma#ie(3)# ("'", Code 39) wird vom Compiler ebenfalls als EOL interpretiert.
+Alle dem Hochkomma in der Dateizeile folgenden Zeichen werden überlesen. Dies
+ermöglicht das Schreiben von Kommentaren ohne Verwendung der
+'REM'-Anweisung.
+
+Es sei hier bereits bemerkt, daß sich durch die Realisierung des Übersetzers als
+#on ("b")#Compiler gewisse Unterschiede gegenüber Interpretern #off ("b")#ergeben (siehe hierzu Kap. 9).
+Der wesentliche Unterschied ist, daß der Interpreter dem Programmtext analog zum
+Programmablauf folgt, der Compiler das Programm aber von vorne bis hinten Zeile für
+Zeile übersetzt. Dies hat zur Folge, daß z.B. die Dimensionierungen von Feldvariablen
+#on ("b")#textuell vor der Verwendung der Variablen stattfinden müssen#off ("b")# und nicht, wie bei
+Interpretern, nur im Ablauf des Programms vorher ausgeführt werden müssen.
+
+
+
+Weitere Schreibregeln
+
+#on ("b")#
+1. #ib(3)#Groß-/Kleinschreibung#ie(3)##off ("b")#
+Für den BASIC-Compiler bestehen zwischen kleinen und großen Buchstaben keiner­
+lei Unterschiede, es sei denn es handelt sich um Textdenoter (Textkonstanten).
+Daher können alle #ib(3)#Schlüsselwörter#ie(3)# und #ib(3)#Variablennamen#ie(3)# mit kleinen oder großen
+Buchstaben geschrieben werden. Aus der Tatsache, daß zwischen großen und kleinen
+Buchstaben nicht unterschieden wird, folgt aber bespielsweise auch, daß die Variab­
+lennamen (vgl. 4.3.) 'hallo' und 'HALLO' ein und dieselbe Variable bezeichnen.
+
+#on ("b")#
+2. #ib(3)#Reservierte Wörter#ie(3)##off ("b")#
+Der BASIC-Compiler erkennt eine ganze Reihe #on("i")#reservierter Wörter#off("i")#. Es handelt sich
+hierbei im wesentlichen um die Namen der Anweisungen und Funktionen. Sie sollten
+im eigenen Interesse darauf achten, daß sich sowohl vor als auch hinter reservier­
+ten Wörtern stets mindestens ein #on ("b")##ib(3)#Leerzeichen#ie(3)##off ("b")# (Blank) befindet. Der #ib(3)#Scanner#ie(3)# (ver­
+gleiche AnhangB) erkennt zwar manchmal die reservierten Wörter auch ohne Leer­
+zeichen, aber unter bestimmten Umständen kann es auch zu erkannten oder - noch
+schlimmer - vom Compiler unerkannten Fehlern kommen.
+Hierzu zwei Beispiele:
+Die Anweisung 'IF a > b THENPRINT "größer"' führt beim Compilieren zur Fehler­
+meldung "Syntaxfehler: THEN oder GOTO erwartet".
+Wesentlich gefährlicher ist da schon die Programmzeile
+ "LEThallo = 3 : PRINT hallo",
+denn die unerwartete Wirkung ist die Ausgabe von "0" auf dem Bildschirm. Der Wert
+"3" wurde nämlich nicht der Variablen mit dem Namen "hallo" zugewiesen, sondern
+einer Variablen namens "LEThallo".
+
+#on ("b")#
+3. Bedeutung der #ib(3)#Leerstelle#ie(3)# ("Blank") für den Compiler#off("b")#
+Wie schon aus dem vorhergehenden Punkt ersichtlich kann das Fehlen von trennen­
+den Leerstellen unschöne Effekte haben, denn der #ib(3)#Scanner#ie(3)# (vgl. AnhangB) des
+BASIC-Compilers erkennt anhand der Leerstelle (Code 32) beim Durchlauf durch das
+Programm, daß ein #ib(3)#Symbol#ie(3)# zu Ende ist.
+Es kommt somit immer dann zu Fehlern, wenn zwei Symbole (z.B. reservierte Wörter,
+Konstanten, Variablen etc.) nicht durch Leerzeichen getrennt sind, und der Scanner
+sie als ein Symbol "versteht".
+Beispiel:
+ "a = 3 : b = 4 : PRINT a b" erzeugt die Ausgabe "34".
+ "a = 3 : b = 4 : PRINT ab" erzeugt hingegen die Ausgabe "0", denn der
+Compiler sieht "ab" als #on ("b")#einen Variablennamen an. #off ("b")#
+
+
+
+4.2. #ib(3)#Datentypen#ie(3)# und #ib(3)#Konstanten#ie(3)#
+
+
+Der EUMEL-BASIC-Compiler unterscheidet grundsätzlich zwischen zwei Daten­
+typen, nämlich zwischen #ib(3)#Texte#ie(3)#n und #ib(3)#Zahlen#ie(3)#.
+
+#on ("b")#
+#ib(3)#Datentyp TEXT#ie(3)# #off ("b")#
+Texte dürfen alle Zeichen enthalten (Codes 0 bis 255) und bis zu 32000 Zeichen lang
+sein.
+Die zugehörigen Konstanten werden von #ib(3)#Anführungszeichen#ie(3)# begrenzt, z.B.:
+ "Anzahl Einträge: "
+ "2.32 DM"
+ "General-Musik-Direktor"
+Anführungszeichen (Code 34) dürfen #on("i")#innerhalb#off("i")# von Text-Konstanten nicht vor­
+kommen.
+
+Bei Zahlen unterscheidet der Compiler noch zwischen #ib(3)#INTs#ie(3)# (#ib(3)#Ganzzahlen#ie(3)#) und REALs
+(#ib(3)#Gleitkommazahlen#ie(3)#). Diese entsprechen im Hinblick auf den Wertebereich genau den
+in ELAN bekannten INTs und REALs.
+
+#on ("b")#
+#ib(3)#Datentyp INT#ie(3)# #off ("b")#
+INT-Werte dürfen zwischen -32768 und 32767 liegen. INT-Konstanten dürfen aber
+#on("i")#nur#off("i")# aus Ziffern und einem optionalen '%'-Zeichen am Ende bestehen. Das bedeutet,
+daß die INT-Konstanten im Bereich von 0 bis 32767 liegen können.
+Ein nachgestelltes '%'-Zeichen kennzeichnet eine Konstante nochmals explizit als
+INT. (Diese Option wurde aus Kompatibilitätsgründen implementiert.)
+
+#on ("b")#
+#ib(3)#Datentyp REAL#ie(3)# #off ("b")#
+REALs können Werte zwischen -9.999999999999*10#u#126#e# und
+9.999999999999*10#u#126#e# annehmen.
+Die kleinste positive von Null verschiedene Zahl ist 9.999999999999*10#u#-126#e#.
+Der kleinste REAL-Wert mit x + 1.0 > 1.0 ist gleich 10#u#-12#e#.
+REAL-Konstanten werden gebildet aus Vorkommastellen, Dezimalpunkt, Nachkom­
+mastellen, Zeichen "E" oder "D" (jeweils auch klein) für den #ib(3)#Exponent#ie(3)#en gefolgt vom
+Vorzeichen und den Ziffern des Exponenten.
+Dabei müssen nicht für jede REAL-Konstante alle diese Elemente benutzt werden.
+Unverzichtbar sind #on("i")#entweder#off("i")# der Dezimalpunkt #on("i")#oder#off("i")# der Exponent. Ebenso müssen
+zumindest entweder Vor- oder Nachkommastellen vorhanden sein.
+
+Beispiele für gültige REAL-Konstanten sind:
+ 0.
+ .01
+ 1E-17
+ 2.9979D8
+ .3e-102
+ 100.e+7
+
+Nicht erlaubt sind dagegen folgende Schreibweisen für REAL-Konstanten:
+ e12 (#ib(3)#Mantisse#ie(3)# fehlt)
+ 100 (ist INT-Konstante)
+ . (weder Vor- noch Nachkommastellen)
+ .E-12 (dito)
+ 1exp-3 ('exp' nicht erlaubt)
+ -1.99e30 (Mantisse hat Vorzeichen)
+
+Das letzte Beispiel zeigt, daß auch vor REAL-Konstanten keine #ib(3)#Vorzeichen#ie(3)# erlaubt
+sind. Da normalerweise keine REAL-Konstanten, sondern vielmehr numerische
+Ausdrücke verlangt werden, können durch Voranstellen des Operators '-' (vgl. 4.4.)
+auch #ib(3)#negative Zahlenwerte#ie(3)# leicht erzeugt werden.
+
+An REAL-Konstanten darf eines der Zeichen "!" und "\#" angehängt werden. Diese
+Option wurde aus Kompatibilitätsgründen eingebaut. Wird ein "!" oder "\#" an eine
+INT-Konstante angehängt, so verwandelt es diese in eine REAL-Konstante.
+Beispiel: 10000! oder 10000\# entspricht 10000. oder 1E4
+
+
+#page#
+
+4.3. Variablen und Felder
+
+
+Variablen
+
+Der BASIC-Compiler stellt für die in 4.2. vorgestellten Datentypen TEXT, INT und
+REAL auch Variablen zur Verfügung.
+Die #ib(3)#Variablennamen#ie(3)# müssen folgenden Bedingungen genügen:
+- Ein Variablenname muß mit einem Buchstaben beginnen.
+- Variablennamen dürfen ab der zweiten Stelle außer Buchstaben auch Ziffern, Dezi­
+ malpunkte sowie die Zeichen "!", "\#", "$" und "%" enthalten. Leerzeichen dürfen
+ in Variablennamen dagegen nicht vorkommen.
+- Variablennamen dürfen nicht mit FN beginnen (vgl. 4.5. benutzer-definierte Funk­
+ tionen).
+- #ib(3)#Reservierte Wörter#ie(3)# (siehe Anhang A) dürfen kein Variablenname sein. Als Teiltexte
+ dürfen reservierte Wörter aber in Variablennamen enthalten sein (auch am Anfang).
+
+Variablennamen dürfen beliebig lang sein, und alle Zeichen eines Variablennamens
+sind signifikant.
+
+Welchen Typ eine Variable hat, entscheidet der Compiler nach folgenden #ib(3)#Kriterien#ie(3, " für den Typ einer Variablen")# (in
+der Reihenfolge ihrer Beachtung):
+- Ist das letzte Zeichen des Namens ein "!" oder "\#", so bezeichnet er eine
+ REAL-Variable.
+- Ist das letzte Zeichen ein "%", so handelt es sich um eine INT-Variable.
+- Ist das letzte Zeichen des Namens ein "$", so ist die Variable vom Typ TEXT.
+- Liegt das erste Zeichen des Namens im Bereich der mit einer #ib(3)#DEFINT#ie(3)#-Anweisung
+ (vgl. Kap. 8) festgelegten Buchstaben, so ist die Variable eine INT-Variable.
+- Liegt das erste Zeichen im Bereich der mit einer #ib(3)#DEFSTR#ie(3)#-Anweisung (vgl. Kap. 8)
+ festgelegten Buchstaben, so handelt es sich um eine TEXT-Variable.
+- Wenn keine der obigen Bedingungen erfüllt ist, dann bezeichnet der Name eine
+ Variable des Datentyps REAL.
+
+Variablen, denen noch kein Wert zugewiesen wurde, haben den Inhalt null (bei INT
+und REAL) beziehungsweise Leertext (bei TEXT).
+
+
+
+Felder (#ib(4)#Arrays#ie(4)#)
+
+Ein Feld (Array) ist eine Ansammlung von mehreren Variablen gleichen Typs. Jedes
+Feld hat einen Namen. Für die #ib(3)#Feldnamen#ie(3)# gelten die gleichen Regeln wie für die
+Namen von normalen Variablen. Auch die Datentypen werden nach den gleichen
+Kriterien bestimmt wie bei einfachen Variablen.
+In einem Feld können die Elemente in bis zu 100 #ib(3)#Dimensionen#ie(3)# abgelegt werden. Auf
+ein Element eines Feldes wird über den Feldnamen und den Index / die #ib(3)#Indizes#ie(3)# des
+Elements zugegriffen. Beim Zugriff auf das Element müssen so viele Indizes ange­
+geben werden, wie das Feld Dimensionen hat.
+Beispiel:
+Das Feld 'tabelle' habe zwei Dimensionen. Mit 'tabelle (3, 5)' wird auf das Element
+mit dem Index 3 in der ersten Dimension und dem Index 5 in der zweiten Dimension
+zugegriffen.
+
+Beim ersten Zugriff auf ein Element eines Feldes wird anhand der Zahl der Indizes
+die Anzahl der Dimensionen festgestellt und das Feld so eingerichtet, daß in jeder
+Dimension der größte Index zehn ist.
+Soll ein Feld mit anderen größten Indizes eingerichtet werden, so muß hierzu die
+#ib(3)#DIM#ie(3)#-Anweisung verwendet werden (siehe Kapitel 8).
+
+Der kleinste Index ist voreingestellt auf null, kann aber mit der #ib(3)#OPTION BASE#ie(3)#-
+Anweisung (vgl. Kap. 8) auch auf eins eingestellt werden.
+
+Die Elemente eines Feldes sind, wie auch die einfachen Variablen, mit den Werten
+null (INT und REAL) beziehungsweise Leertext (TEXT) vorbesetzt, sofern ihnen noch
+nichts zugewiesen wurde.
+
+#page#
+
+4.4. Operatoren
+
+Nachfolgend sind alle Operatoren aufgelistet, die vom EUMEL-BASIC-Compiler
+übersetzt werden.
+
+
+Arithmetische #ib(4)#Operatoren#ie(4, ", arithmetische")#
+
+#ib(3)##ie(3, "+")##ib(3)##ie(3, "-")##ib(3)##ie(3, "*")##ib(3)##ie(3, "/")#
+#ib(3)##ie(3, "\")##ib(3)##ie(3, "MOD")##ib(3)##ie(3, "^")#
+
+ Operand(en) Zweck Ergebnistyp
+
+ + INT positives Vorzeichen INT
+ REAL positives Vorzeichen REAL
+
+ INT, INT INT-Addition INT
+ REAL, REAL REAL-Addition REAL
+
+ - INT negatives Vorzeichen INT
+ REAL negatives Vorzeichen REAL
+
+ INT, INT INT-Subtraktion INT
+ REAL, REAL REAL-Subtraktion REAL
+
+ * INT, INT INT-Multiplikation INT
+ REAL, REAL REAL-Multiplikation REAL
+
+ / (INT, INT) #linefeed (0.5)#
+ REAL-Division REAL
+ REAL, REAL #linefeed (1.0)#
+
+ \ INT, INT #linefeed (0.5)#
+ INT-Division INT
+ (REAL, REAL) #linefeed (1.0)#
+
+MOD INT, INT INT-Divisionsrest INT
+ REAL, REAL Divisionsrest nach REAL
+ Runden auf Ganzzahl (nicht INT)
+
+ ^ (INT, INT) #linefeed (0.5)#
+ Potenzierung REAL
+ REAL, REAL #linefeed (1.0)#
+
+
+#on ("b")#
+Hinweis: #off ("b")#
+Wird ein Operator mit numerischen Operanden unterschiedlichen Typs (also INT und
+REAL) aufgerufen, so wird der INT-Operand nach REAL konvertiert und der Operator
+mit den beiden REAL-Operanden aufgerufen.
+Sind die Operandtypen in Klammern angegeben, so werden vor Ausführung der Ope­
+ration die Operanden zu den nicht eingeklammerten Typen konvertiert.
+Da jede #ib(3)#Konvertierung#ie(3)# Zeit benötigt, sollte der Benutzer darauf achten, daß möglichst
+wenig konvertiert werden muß.
+Hierzu ein (etwas extremes, aber nicht seltenes) Beispiel:
+Der Aufruf a%\b bewirkt zunächst eine Konvertierung von a% nach REAL:
+CDBL(a%)\b. Intern wird die Berechnung dann aber wieder mit INTs ausgeführt:
+CINT(CDBL(a%))\CINT(b). Das Ergebnis wird also erst nach drei Konvertierungen
+geliefert. Schreibt man dagegen sofort a%\CINT(b), dann reicht eine Konvertierung
+aus.
+
+Es muß außerdem bei den Operatoren +, - und * für INTs darauf geachtet werden,
+daß das Ergebnis innerhalb des INT-Wertebereichs liegen muß, da es sonst zu
+einem #ib(3)#INT-Überlauf#ie(3)# kommt.
+
+
+
+Text-Operator #ib(4)#+#ie(4)#
+
+#ib(3)##ie(3, "Operatoren, Text-")#
+Für Text-Manipulationen wird der Operator '+' mit zwei TEXT-Operanden zur
+Verfügung gestellt. Mit '+' werden zwei Texte aneinandergehängt (konkateniert).
+
+
+
+Vergleichsoperatoren#ib(4)##ie(4, "Operatoren, Vergleichs-")#
+
+Im EUMEL-BASIC gibt es folgende Vergleichsoperatoren:
+
+#ib(3)#=#ie(3)# gleich
+#ib(3)#<>#ie(3)# ungleich
+#ib(3)#<#ie(3)# kleiner
+#ib(3)#>#ie(3)# größer
+#ib(3)#<=#ie(3)# kleiner oder gleich
+#ib(3)#>=#ie(3)# größer oder gleich
+
+Bei den numerischen Datentypen werden mit den Vergleichsoperatoren die Zahlen­
+werte verglichen.
+Sollen ein INT und ein REAL verglichen werden, dann wird der INT vorher nach
+REAL konvertiert und ein REAL-Vergleich vorgenommen.
+
+Bei Texten dienen die Vergleichsoperatoren zum Vergleich der Zeichencodes. Dies
+ermöglicht zum Beispiel ein alphabetisches Sortieren von Wörtern, mit der Einschrän­
+kung, daß Groß- und Kleinbuchstaben unterschiedliche Zeichencodes haben (ver­
+gleiche EUMEL-Zeichensatz-Tabelle im Benutzerhandbuch) und somit verschieden
+eingeordnet werden.
+Es gilt a$ < b$, wenn die Zeichenkette in a$ codemäßig vor der Zeichenkette in b$
+ steht: "a" < "b" (TRUE) "aa"< "a" (FALSE)
+
+
+Die Vergleichsoperatoren liefern, je nachdem ob die Aussage wahr oder falsch ist, die
+INT-Werte 0 (falsch) oder -1 (wahr).
+Anhand des Ergebnisses einer Vergleichsoperation kann zum Beispiel der Programm­
+ablauf gesteuert werden (siehe Kapitel 8, IF-Anweisung).
+
+
+
+Logische Operatoren
+
+#ib(3)##ie(3, "Operatoren, logische")#
+Die logischen Operatoren haben zwei Aufgaben:
+1. logische (Boolsche) Verknüpfung von #ib(3)#Wahrheitswerte#ie(3)#n, die zum Beispiel von
+ Vergleichsoperationen geliefert werden und
+2. bitweise Ausführung von logischen Verknüpfungen auf den internen (Zweierkom­
+ plement-) Darstellungen von INT-Werten.
+
+Da für beide Aufgaben die gleichen Operatoren benutzt werden, wurden für die Wahr­
+heitswerte die INT-Werte 0 für falsch (Bitmuster: 0000000000000000) und -1 für
+wahr (Bitmuster: 1111111111111111) gewählt.
+
+ Operand(en) Zweck insbesondere gilt
+
+#ib(3)#NOT#ie(3)# INT #linefeed (0.5)# NOT0->-1
+ #ib(3)#Negation#ie(3)#
+ (REAL) #linefeed (1.0)# NOT-1->0
+
+#ib(3)#AND#ie(3)# INT, INT #ib(3)#UND-Verknüpfung#ie(3)# 0AND0->0
+ 0AND-1->0
+ -1AND0->0
+ -1AND-1->-1
+
+ #ib(3)#OR#ie(3)# INT, INT #ib(3)#ODER-Verknüpfung#ie(3)# 0OR0->0
+ 0OR-1->-1
+ -1OR0->-1
+ -1OR-1->-1
+
+#ib(3)#XOR#ie(3)# INT, INT #ib(3)#Exklusiv-ODER-Verknüpfung#ie(3)# 0XOR0->0
+ 0XOR-1->-1
+ -1XOR0->-1
+ -1XOR-1->0
+
+#ib(3)#EQV#ie(3)# INT, INT #ib(3)#Äquivalenz-Verknüpfung#ie(3)# 0EQV0->-1
+ 0EQV-1->0
+ -1EQV0->0
+ -1EQV-1->-1
+
+#ib(3)#IMP#ie(3)# INT, INT #ib(3)#Implikations-Verknüpfung#ie(3)# 0IMP0->-1
+ 0IMP-1->-1
+ -1IMP0->0
+ -1IMP-1->-1
+
+
+
+Prioritäten der Operanden
+
+
+Hier die Übersicht über alle Operatoren in der Reihenfolge ihrer Ausführung
+
+
+ Operator Priorität
+
+ ^ Potenzierung 13
+ +, - positives/negatives Vorzeichen 12
+ *, / Multiplikation, REAL-Division 11
+ \ INT-Division 10
+ MOD Divisionsrest- (MOD-) Operation 9
+ +, - Addition, Subtraktion 8
+ =, <>, <, >, <=, >= Vergleichsoperatoren 7
+ NOT Negation 6
+ AND UND-Verknüpfung 5
+ OR ODER-Verknüpfung 4
+ XOR Exklusiv-ODER-Verknüpfung 3
+ EQV Äquivalenz-Verknüpfung 2
+ IMP Implikations-Verknüpfung 1
+
+
+Die Reihenfolge der Auswertung von Ausdrücken kann durch Klammern geändert
+werden.
+
+Beachten Sie, daß der Operator '=' in BASIC die Funktion eines Vergleichsoperators
+und des #ib(3)#Zuweisungsoperators#ie(3)##ib(3)##ie(3, "Operator, Zuweisungs-")# (siehe Kapitel 8, LET-Anweisung) hat.
+
+#page#
+
+4.5. #ib(3)#Funktionen#ie(3)#
+
+
+
+Standard-Funktionen
+
+Der EUMEL-BASIC-Compiler unterstützt eine ganze Reihe von Funktionen. Diese
+Funktionen liefern Werte und können in Ausdrücken zusammen mit Konstanten,
+Variablen und Operatoren verwendet werden.
+Viele der eingebauten Funktionen arbeiten mit Argumenten, das heißt es werden den
+Funktionen Werte übergeben.
+In Kapitel 8 dieses Handbuches sind alle Funktionen ausführlich beschrieben.
+Beispiele für #ib(3)#Funktionsaufrufe#ie(3)#:
+ SQR (17) Dieser Ausdruck liefert die Wurzel von 17 als REAL.
+ RIGHT$ (text$, 5) Dieser Ausdruck liefert die letzten fünf Textzeichen
+#right#aus 'text$' als TEXT.
+
+
+
+Benutzer-definierte Funktionen
+
+Neben der Verwendung der standardmäßig verfügbaren Funktionen besteht für den
+Benutzer die Möglichkeit, selbst Funktionen innerhalb eines Programms zu definieren.
+
+#on ("b")#
+#ib(3)#Definition benutzer-definierter Funktionen#ie(3)# #off ("b")#
+Hierzu dient die #ib(3)#DEF FN#ie(3)#-Anweisung (vergleiche Kapitel 8).
+Die Syntax der DEF FN-Anweisung lautet:
+
+DEFFN<Name>[(<Parameter>[,<Parameter>][...])]=
+#right#<Funktionsdefinition>
+
+<Name>: Zeichenfolge, die der Syntax für Variablennamen ent­
+ sprechen muß.
+ FN<Name> bilden zusammen den Namen der neuen
+ Funktion.
+<#ib(3)#Parameter#ie(3)#>: Zeichenfolge, die der Syntax für Variablennamen ent­
+ sprechen muß.
+<Funktionsdefinition>: Ausdruck, der Konstanten, Variablen, die Parameter der
+ Funktion und Aufrufe anderer Funktionen enthalten
+ darf.
+
+- Die benutzer-definierten Funktionen ("user functions") liefern, genau wie die
+ Standard-Funktionen, Werte.
+- Das letzte Zeichen des Funktionsnamens gibt den Typ des Wertes an, den die
+ Funktion liefert. Soll die Funktion einen TEXT liefern, so muß der Name mit "$"
+ enden. Soll ein INT geliefert werden, muß der Name mit "%" enden. Für alle
+ anderen Endungen wird eine REAL-liefernde Funktion eingetragen.
+- Die Syntax der Parameternamen entspricht der Syntax für die Namen von einfachen
+ Variablen.
+- Die Parameter haben nur bei der Definition Gültigkeit. Hierbei 'überdecken' sie (für
+ diese Zeile) eventuell im BASIC-Programm vorhandene gleichnamige Variablen.
+- Jeder Parameter darf in der Parameterliste nur einmal vorkommen.
+- Bezeichnet der Funktionsname eine TEXT-liefernde Funktion, so muß auch die
+ Funktionsdefinition ein Ergebnis vom Typ TEXT liefern. Zwischen INTs und REALs
+ findet eine Typanpassung statt.
+- Eine Funktion darf nicht in ihrer eigenen Definition erscheinen.
+- Eine Funktion ist allein durch ihren Namen gekennzeichnet. Generische Funktionen
+ (gleicher Name, aber unterschiedliche Parameter) können somit nicht definiert wer­
+ den.
+
+Beispiele für gültige Funktionsdefinitionen:
+ DEF FNPI = 3.1415927
+ DEF FNumfang (radius) = 2.0 * FNPI * radius (Enthält Aufruf von FNPI)
+ DEF FNhallo$ (dummy$) = "Hallo " + name$ (name$ kommt im
+ #right#BASIC-Programm vor)
+ DEF FNheavyside% (x) = ABS (SGN (x) = 1)
+
+Beispiele für ungültige Funktionsdefinitionen:
+ DEF FNfunct (a, b, a) = a ^ 2 + b (a kommt zweimal als Parameter vor)
+ DEF FNfr (x) = x * FNfr (x - 1) (rekursive Definition)
+
+
+#on ("b")#
+#ib(3)#Aufruf benutzer-definierter Funktionen#ie(3)# #off ("b")#
+
+FN<Name> [ ( <Argument> [, <Argument>] [...] ) ]
+
+<#ib(3)#Argument#ie(3)#> : Ausdruck, der für den entsprechenden Parameter bei der Evaluation
+ (Auswertung) der Funktion eingesetzt werden soll
+
+- Beim Funktionsaufruf werden die Argumente in der Reihenfolge ihres Auftretens für
+ die Parameter eingesetzt. Für TEXT-Parameter müssen die Argumente ebenfalls
+ TEXTe liefern. Zwischen INTs und REALs findet eine Typanpassung statt.
+- Die Anzahl der Argumente muß genau mit der Anzahl der Parameter übereinstim­
+ men.
+- Für in der Funktionsdefinition vorkommende Variablen wird der zum Zeitpunkt des
+ Funktionsaufruf gültige Wert eingesetzt.
+- Die Definition der Funktion muß dem ersten Aufruf der Funktion textuell voraus­
+ gehen.
+- Eine Definition gilt für alle textuell folgenden Aufrufe, bis die Funktion wieder neu
+ definiert wird.
+
+Beispiele für korrekte Funktionsaufrufe (bezogen auf obige Beispiel-Definitionen):
+ PRINT FNPI / 2.0 (Ausgabe: 1.570796)
+ PRINT FNumfang (20) (Ausgabe: 125.6637)
+ LET name$ = "Purzelbär":PRINT FNhallo$ ("") (Ausgabe: Hallo Purzelbär)
+ PRINT heavyside% (-17.3) (Ausgabe: 0)
+
+Beispiele für falsche Funktionsaufrufe (bezogen auf obige Beispiel-Definitionen):
+ PRINT FNPI (10) (kein Argument erwartet)
+ PRINT FNumfang (Argument erwartet)
+ PRINT FNhallo$ (zahl%) (Falscher Typ des Arguments)
+ PRINT FNheavyside (17.4, -12.3) (Zu viele Argumente)
+
+
+#page#
+
+4.6. #ib(3)#Typanpassung#ie(3)#
+
+
+In BASIC wird, im Gegensatz zu ELAN, nicht sehr streng zwischen den numerischen
+Datentypen unterschieden, sondern es finden häufig automatische Typanpassungen
+statt. Zu solchen Typanpassungen kommt es vor allem bei der Zuweisung, bei Opera­
+toren und bei Funktionen, aber auch bei einigen Anweisungen.
+Die automatische Typanpassung hat zwei Nachteile:
+1. Die Typkonvertierung von INT nach REAL und umgekehrt kostet Zeit während der
+ Programmausführung.
+2. Es kann zu sehr unangenehmen Laufzeitfehlern kommen, wenn eine REAL-
+ INT-#ib(3)#Konvertierung#ie(3)# mit Fehler abbricht, weil der REAL-Wert außerhalb des
+ INT-Wertebereichs liegt.
+
+Allgemein gilt also, daß sich der Programmierer auch in BASIC über die Typen der
+verwendeten Objekte im klaren sein sollte. Außerdem ist zu beachten, daß bei Konver­
+tierungen von REAL nach INT immer gerundet wird.
+
+Genaueres zur Typanpassung bei der Zuweisung finden Sie in Kapitel 8 bei der
+LET-Anweisung.
+Über Typkonvertierung bei Operatoren informiert Kapitel 4.4.
+Informationen über die Funktionen betreffenden Typkonvertierungen befinden sich am
+Anfang von Kapitel 8 und direkt bei der Beschreibung der jeweiligen Funktionen
+(ebenfalls in Kapitel 8).
+
+#page#
+
+4.7. Aufruf von EUMEL-Prozeduren in
+ BASIC-Programmen
+
+
+
+Der EUMEL-BASIC-Compiler bietet die Möglichkeit, insertierte ELAN-Prozeduren
+(und auch insertierte BASIC-Programme) in BASIC-Programmen aufzurufen. Hierzu
+werden die beiden Anweisungen #ib(3)#CALL#ie(3)# und #ib(3)#CHAIN#ie(3)# (identisch) sowie die Funktion
+#ib(3)#USR#ie(3)# zur Verfügung gestellt.
+Mit der CALL-Anweisung (siehe auch Kapitel 8) können Prozeduren aufgerufen
+werden, die keinen Wert liefern und nur die BASIC-Datentypen INT, REAL und/oder
+TEXT als Parameter benötigen.
+Beispiele:
+ CALL list
+ CALL taskstatus ("PUBLIC")
+ CALL cursor (10, 21)
+ CALL getcursor (x%, y%)
+
+Das letzte Beispiel zeigt, daß auch #ib(3)#VAR-Parameter#ie(3)# im ELAN-Sinne übergeben
+werden können.
+
+Die Funktion USR dient im Gegensatz zu CALL zum Aufruf von #ib(3)#wertliefernden Pro­
+zeduren#ie(3)#. Die Prozeduren dürfen allerdings nur einen der BASIC-Datentypen INT,
+REAL oder TEXT liefern. Es gilt auch bei USR, wie bei CALL, daß die aufgerufenen
+Prozeduren nur Parameter der Typen INT, REAL oder TEXT haben dürfen.
+Beispiele:
+ PRINT USR e (Ausgabe: 2.718282)
+ PRINT USR compress (" EUMEL ") (Ausgabe: EUMEL)
+
+#on ("b")#
+Wichtige Hinweise zu CALL, CHAIN und USR: #off ("b")#
+1. Bei den Parametern finden keinerlei Typkonvertierungen statt (ELAN-
+ Prozeduren werden ja gerade anhand der Typen ihrer Parameter eindeutig identifi­
+ ziert).
+2. Die Prozedurnamen nach CALL, CHAIN und USR dürfen keine Leerzeichen ent­
+ halten, weil die Prozedur sonst nicht identifiziert werden kann.
+ Beispiel: CALLlernsequenzauftastelegen(...) statt
+ CALLlernsequenzauftastelegen(...)
+3. Die Prozedurnamen können (nach BASIC-Konvention) auch Großbuchstaben
+ enthalten.
+ Beispiel: CALLcursor(17,4) ist äquivalent zu
+ CALLCURSOR(17,4)
+
+
+Wie in Kapitel 3 erläutert kann ein BASIC-Programm auch insertiert werden. Somit
+können mit der CALL-Anweisung auch andere (vorher insertierte) BASIC-
+Programme aufgerufen werden.
+Beispiel:
+CALL blackjack ('blackjack' sei der Prozedurname, unter dem ein BASIC-
+ Programm zuvor insertiert wurde.)
+
+Die sonst in einigen BASIC-Dialekten vorhandene Möglichkeit, Programme oder
+#ib(3)#Programmsegmente#ie(3)# nachzuladen, kann so durch Aufrufe von insertierten Programmen
+nachgebildet werden.
+#page#
+#head#
+EUMEL-BASIC-Compiler 5. Steuerung der Bildschirmausgaben %
+
+#end#
+
+5. #ib(4)#Steuerung der #ib(3)#Bildschirmausgaben#ie(3)##ie(4)#
+
+
+
+Die Ausgaben von BASIC-Programmen ('PRINT' und 'WRITE') werden im Paket
+'basic output' behandelt. Dieses Paket ermöglicht unter anderem, daß die Ausgabe
+auf das Terminal mit der Prozedur
+
+ PROC #ib(3)#basic page#ie(3)# (BOOL CONST status)
+
+gesteuert werden können. Wird dabei 'TRUE' eingestellt, so wartet die Ausgabe bei
+Erreichen der letzten Terminalzeile auf die Eingabe eines Zeichens, bevor sie fortfährt.
+Das Eingabezeichen wird nach Ausgabe von ">>" in der rechten unteren Ecke des
+Bildschirms erwartet und wie folgt interpretiert:
+
+#linefeed (1.5)#
+ Löschen des Bildschirms und Ausgabe der nächsten Bildschirmseite
+ Ausgabe der nächsten Zeile
+ Abbruch des Programms mit der Fehlermeldung "'halt' vom Terminal"
+ 'basic page' wird auf 'FALSE' gesetzt #linefeed (1.0)#und mit der normalen Ausgabe
+ weitergemacht
+
+Alle anderen Tasten bewirken eine Ausgabe der nächste Bildschirmseite (#ib(3)#Scrolling#ie(3)#).
+
+Ist 'basic page' auf 'FALSE' gesetzt, so kann durch Eingabe von vor einem Zei­
+lenwechsel 'basic page' auf 'TRUE' gesetzt werden.
+#page#
+#head#
+EUMEL-BASIC-Compiler 6. Grenzen des Compilers %
+
+#end#
+
+6. #ib(3)#Grenzen des Compilers#ie(3)#
+
+
+Es gibt verschiedene Grenzen, die bei der Benutzung des BASIC-Compilers erreicht
+werden können.
+
+#on ("b")#
+Grenzen des #ib(3)#EUMEL-Coder#ie(3)#s #off ("b")#
+Da ein BASIC-Programm vom Compiler als eine Prozedur im Coder eingetragen
+wird, darf der Code für ein BASIC-Programm die #ib(3)#Modulgrenze#ie(3)# von 7500 Byte Code
+nicht überschreiten.
+Sollte dies doch einmal der Fall sein (#ib(3)#Compiler Error 308#ie(3)#), so gibt es folgende
+Abhilfe-Möglichkeiten:
+- Zerlegen des BASIC-Programms in mehrere BASIC-Programme, wobei ein
+ Programm das andere während der Ausführung aufrufen kann (vgl.4.7.).
+ Bei dieser Methode können die Teilprogramme aber nicht mit gemeinsamen Variab­
+ len arbeiten.
+- Auslagerung von Programmteilen (z.B. Unterprogrammen) in ELAN-Prozeduren,
+ die insertiert und vom BASIC-Programm aufgerufen werden können (vgl.4.7.).
+ Dieses Verfahren bietet die Möglichkeit, Variablen zwischen BASIC-Programm und
+ ELAN-Prozedur über die Prozedurschnittstelle auszutauschen.
+
+Neben der Begrenzung des Codes ist auch die Größe des Datenspeicherbereichs pro
+BASIC-Programm begrenzt. Insgesamt dürfen die Datenobjekte eines BASIC-
+Programms nicht mehr als 32 KByte Speicherplatz belegen. Andernfalls kommt es
+zum #ib(3)#Compiler Error 307#ie(3)#.
+
+Eine weitere Grenze des EUMEL-Coders stellt die maximal zulässige Anzahl der
+#ib(3)#Labels#ie(3)# (interne Sprungadressen) dar. Es können nur höchstens 2000 Labels vom
+Coder verwaltet werden. Der BASIC-Compiler vergibt für jede gefundene Zeile mit
+Zeilennummer ein Label und benötigt auch bei Schleifen (FOR-NEXT, WHILE-
+WEND), Fallunterscheidungen (IF-Anweisung), Unterprogramm-Aufrufen (GOSUB)
+und bei der Definition von benutzer-definierten Funktionen (DEF) Labels.
+Beim Auftreten des #ib(3)#Compiler Errors 304#ie(3)# (zu viele Label) ist Abhilfe relativ leicht
+dadurch möglich, daß Zeilennummern nur den Zeilen vergeben werden, die tatsächlich
+angesprungen werden (d.h. zu denen es GOTOs oder GOSUBs gibt).
+
+#on ("b")#
+Grenzen des BASIC-Compilers #off ("b")#
+Die interne #ib(3)#Namenstabelle#ie(3)# des BASIC-Compilers kann etwa 4240 Einträge aufneh­
+men. Ein Eintrag in dieser Tabelle wird für jede Variable, für jedes Feld, für jede
+benutzer-definierte Funktion und für jeden Parameter einer benutzer-definierten
+Funktion sowie für jede Konstante erzeugt. Numerische Konstanten erhalten, sofern
+sie konvertiert werden müssen, sogar zwei Einträge in der Namenstabelle.
+Bei Auftreten des seltenen Fehlers "volle Namenstabelle" kann durch eine Aufteilung
+des BASIC-Programms in Teilprogramme oder eine Auslagerung von Unterprogram­
+men in ELAN-Prozeduren Abhilfe geschaffen werden.
+
+#on ("b")#
+Sonstige EUMEL-Grenzen #off ("b")#
+Außer den bisher genannten Begrenzungen sei nochmals auf die Begrenzung des
+#ib(3)#Codebereichs pro Task#ie(3)# hingewiesen (maximal 256 KByte Code).
+Da der EUMEL-Coder und der BASIC-Compiler recht viel Code belegen, sollte
+"vorsichtig" insertiert werden, also nur das, was wirklich benötigt wird.
+Auch die übrigen Grenzen des EUMEL-Systems sind zu beachten (vergleiche hierzu
+die Aufstellung der möglichen Compiler Errors im EUMEL-Benutzerhandbuch)!
+
+#page#
+#head#
+EUMEL-BASIC-Compiler 7. Fehlerbehandlung %
+
+#end#
+
+7. #ib(3)#Fehlerbehandlung#ie(3)#
+
+
+7.1. #ib(3)#Fehler zur Übersetzungszeit#ie(3)#
+
+Endeckt der BASIC-Compiler bei der Übersetzung eines BASIC-Programms Fehler,
+so werden diese auf dem Bildschirm angezeigt und ins #ib(3)#Notebook#ie(3)# eingetragen.
+Nur (syntaktisch) fehlerfreie Programme werden zur Ausführung gebracht beziehungs­
+weise insertiert.
+Im #ib(3)#Vordurchlauf#ie(3)# werden die Zeilennummern auf Richtigkeit überprüft. Falls bereits
+hiebei Fehler festgestellt werden, bricht der Compiler die Übersetzung nach dem
+Vordurchlauf ab.
+Im #ib(3)#Hauptdurchlauf#ie(3)# wird das Programm Zeile für Zeile auf syntaktische Richtigkeit
+überprüft und gleichzeitig übersetzt. Wird dabei in einer Programmzeile ein Fehler
+entdeckt, so wird er angezeigt und die Übersetzung des Programms #on("i")#in der nächsten
+Programmzeile#off("i")# fortgesetzt. Eine Ausnahme von dieser Regel bildet nur die #ib(3)#DEF FN#ie(3)#-
+Anweisung, bei der bei gewissen Fehlern die Übersetzung fortgesetzt wird. (Der
+Grund hierfür liegt darin, daß die Folgefehlerzahl besonders bei der DEF FN-
+Anweisung sehr groß wäre, wenn beim Auftreten eines Fehlers die Übersetzung der
+Zeile sofort abgebrochen würde. Die Parameter würden dann nämlich nicht oder
+falsch abgelegt, und bei jedem Aufruf der Funktion würde ein Fehler gemeldet.)
+
+Eine Übersicht über alle verwendeten Fehlermeldungen zur Übersetzungszeit befindet
+sich im AnhangC.
+
+
+
+Interne Compilerfehler
+
+Neben den "normalen" Fehlern (siehe oben) kann es in seltenen Fällen möglicher­
+weise auch zu internen Fehlern kommen.
+Es gibt zwei verschiedene Sorten von internen Fehlern:
+1. interne Fehler, die das Compilerprogramm selbst feststellt.
+ Solche Fehler bewirken die Meldung "Interner Fehler !" (meist mit näherer Erläu­
+ terung) und die Fortsetzung der Übersetzung in der nächsten Programmzeile.
+2. Fehler, die in anderen Paketen des BASIC-Systems oder des EUMELs (z.B. im
+ EUMEL-Coder) während der Übersetzungszeit ausgelöst werden (siehe auch
+ Kapitel 6: "Grenzen des Compilers").
+ Solche Fehler werden mit "#ib(3)#BASIC-Compiler ERROR#ie(3)#" und eventuell näheren
+ Angaben gemeldet. Beim Auftreten eines solchen Fehlers wird die Übersetzung
+ des gesamten Programms abgebrochen.
+
+Sollten bei Ihrer Arbeit mit dem EUMEL-BASIC-Compiler interne Fehler auftreten,
+die nicht auf das Überschreiten von Compilergrenzen zurückzuführen sind, dann
+wären wir Ihnen für eine Meldung der Fehler dankbar. Bitte senden Sie eine Fehler­
+beschreibung an:
+
+ Gesellschaft für Mathematik und Datenverarbeitung
+ Schloß Birlinghoven
+ Postfach 1240
+ 5205 Sankt Augustin 1
+
+Die Fehlerbeschreibung sollte nach Möglichkeit folgende Informationen enthalten:
+- verwendete Hardware
+- Urlader-Version
+- EUMEL-Version
+- Programmtext des Programms, das den Fehler auftreten ließ
+- genaue Angabe der ausgegebenen Fehlermeldung
+
+
+#page#
+
+7.2. #ib(3)#Fehler zur Laufzeit#ie(3)#
+
+Treten während der Laufzeit eines BASIC-Programms Fehler auf, so wird die Ausfüh­
+rung des Programms mit einer entsprechenden Fehlermeldung abgebrochen.
+Da die meisten Laufzeit-Fehlermeldungen durch Prozeduren des EUMEL-Systems
+(und nicht des BASIC-Systems) erzeugt werden, entsprechen sie oft nicht der
+BASIC-Terminologie. (Beispielsweise führt ein zu großer Feldindex zu der Fehlermel­
+dung "Ueberlauf bei Subskription".)
+
+Die bei Laufzeitfehlern gemeldete #ib(3)#Fehlerzeile#ie(3)# bezieht sich nicht (wie bei ELAN-Pro­
+grammen) auf die Nummer der Dateizeile, sondern auf die letzte der Programmzeile
+vorangegangene BASIC-Zeilennummer.
+
+Fast alle ausgelösten Laufzeitfehler erzeugen auch #ib(3)#Fehlercodes#ie(3)#. Dabei liefern Fehler
+aus EUMEL-Betriebssystem-Prozeduren die EUMEL-Standard-Fehlercodes (vgl.
+Systemhandbuch), zum Beispiel wird beim Fehler "INT-Ueberlauf" der Fehlercode 4
+geliefert.
+Laufzeitfehler, die in Prozeduren des BASIC-Systems ausgelöst werden, liefern dage­
+gen den in Microsoft-BASIC üblichen Fehlercode plus 1000. So liefert die Meldung
+"Keine Daten mehr für READ" den Fehlercode 1004 (MS-BASIC: "Out of data",
+Fehlercode 4).
+Es läßt sich so anhand des gelieferten Fehlercodes ermitteln, ob der Fehler im
+BASIC-System oder an einer anderen Stelle des EUMEL-Systems ausgelöst wurde.
+
+Eine Übersicht über die innerhalb des BASIC-Systems erzeugten Fehlermeldungen
+enthält Anhang C.
+
diff --git a/doc/basic/basic handbuch.2 b/doc/basic/basic handbuch.2
new file mode 100644
index 0000000..1379e9e
--- /dev/null
+++ b/doc/basic/basic handbuch.2
@@ -0,0 +1,2441 @@
+#page nr ("%", 31)#
+#head#
+EUMEL-BASIC-Compiler 8. Übersicht über die Befehle und Funktionen %
+
+#end#
+
+8. Übersicht über die Anweisungen und Funktionen
+
+
+
+In diesem Kapitel sind alle Anweisungen und Funktionen des vom Compiler übersetz­
+baren BASIC-Sprachumfangs in alphabetischer Reihenfolge aufgeführt.
+Auch die Anweisungsbestandteile (z.B. ELSE und TO) sind mit einem Hinweis auf die
+zugehörige Anweisung eingeordnet.
+Sind bei Funktionen INT- oder REAL-Ausdrücke als Argumente angegeben, so ist
+dies als Hinweis auf den Sinn der Funktion zu verstehen. Es können auch Ausdrücke
+des jeweils anderen Datentyps eingesetzt werden. Wird statt eines INT-Ausdrucks
+ein REAL-Ausdruck angegeben, so darf dessen Wert aber nur innerhalb des
+Wertebereichs für INTs liegen, da der REAL-Wert bei der Ausführung der Funktion
+in einen INT-Wert konvertiert wird.
+
+
+
+Funktion : ABS
+
+Zweck : Berechnung des Betrages (Absolutwertes) einer Zahl
+
+Syntax : ABS (<num. Ausdruck>)
+
+Erklärung : Liefert den Betrag des numerischen Ausdrucks.
+ Das Ergebnis ist vom gleichen Typ wie das Argument.
+
+
+Beispiel : 10 a = -12.74
+ 20 PRINT ABS (a)
+ Ausgabe: 12.74
+
+Vergleiche : SGN-Funktion
+
+
+
+Operator : AND
+
+Siehe Kapitel 4.4. (Operatoren)
+
+
+
+Anweisungsbestandteil : AS
+
+Siehe NAME-Anweisung
+
+
+
+Funktion : ASC
+
+Zweck : Ermittlung des ASCII-Codes eines Textzeichens
+
+Syntax : ASC (<TEXT-Ausdruck>)
+
+Erklärung : Die Funktion liefert den ASCII-Code des ersten Zeichens des
+ TEXT-Ausdrucks.
+ Der Code wird als INT geliefert.
+
+
+Beispiel : 10 a$ = "Guten Tag !"
+ 20 PRINT ASC (a$)
+ Ausgabe: 71
+
+Vergleiche : CHR$-Funktion (Komplementärfunktion)
+
+
+
+Funktion : ATN
+
+Zweck : Berechnung des Arcustangens
+
+Syntax : ATN (<num. Ausdruck>)
+
+Erklärung : Die Funktion liefert den Arcustangens des
+ numerischen Ausdrucks in Radiant.
+
+
+Beispiel : 10 LET x = 4
+ 20 PRINT ATN (x)
+ Ausgabe: 1.325818
+
+Vergleiche : TAN-Funktion (Komplementärfunktion), SIN, COS
+
+
+
+Anweisungsbestandteil : BASE
+
+Siehe OPTION BASE-Anweisung
+
+
+
+Anweisung : CALL
+
+Zweck : Aufruf einer insertierten Prozedur
+
+Syntax : CALL <Prozedurname> #right#[ (<Parameter> [, <Parameter>] [...] ) ]
+
+Erklärung : <Prozedurname>: Folge aus Zeichen, die für Prozeduren im
+ EUMEL-System zugelassen sind (also Buchstaben und - ab der
+ zweiten Stelle - Zahlen), aber keine Leerzeichen.
+
+ <Parameter>: <CONST-Parameter> | <VAR-Parameter>
+
+ <CONST-Parameter>: Ausdruck (genau des von der Prozedur
+ benötigten Typs)
+ <VAR-Parameter>: Variable (genau des von der Prozedur benö­
+ tigten Typs)
+
+ Die Prozedur mit dem angegebenen <Prozedurnamen> wird mit den
+ angegebenen Parametern aufgerufen.
+ Die aufgerufene Prozedur darf keinen Wert liefern (vgl. USR-Funk­
+ tion).
+
+ Mögliche Fehlerfälle:
+ - Eine Prozedur mit dem Namen <Prozedurnamen> und den an­
+ gegebenen Parametern gibt es nicht.
+ - Die Prozedur liefert einen Wert.
+ - Die Prozedur benötigt Parametertypen, die in BASIC nicht bekannt
+ sind (z.B. BOOL, FILE, TASK, QUIET).
+ - Ein Parameter ist CONST, es wird aber ein VAR-Parameter ver­
+ langt.
+
+ Weitere Informationen finden Sie in Kapitel 4.7.
+
+Hinweis : 1. Bei den Parametern wird keine Typkonvertierung vorgenommen.
+ 2. Der Prozedurname muß (entgegen der ELAN-Gewohnheit) ohne
+ Leerzeichen angegeben werden.
+ 3. Statt des Anweisungswortes CALL kann auch CHAIN geschrieben
+ werden. CALL und CHAIN werden im EUMEL-BASIC nicht wie
+ in Microsoft-BASIC benutzt.
+
+
+Beispiel : 10 CALL sysout ("Meine Datei")
+ 20 PRINT "Dieser Text geht nun in die Datei"
+ 30 CALL sysout ("")
+ 40 PRINT "Wieder auf den Bildschirm"
+
+
+Vergleiche : USR-Funktion
+
+
+
+Funktion : CDBL
+
+Zweck : Konvertierung in den Datentyp REAL
+
+Syntax : CDBL (<num. Ausdruck>)
+
+Erklärung : Das Ergebnis des numerischen Ausdrucks wird als REAL geliefert.
+
+
+Beispiel : 10 LET a! = 17
+ 20 PRINT USR max (CDBL (a!), 152.3)
+ 30 REM max benötigt zwei REALs als Parameter
+
+
+Vergleiche : CINT-Funktion
+
+
+
+Anweisung : CHAIN
+
+Vollkommen identisch mit der CALL-Anweisung (Erklärung siehe dort !)
+
+
+
+Funktion : CHR$
+
+Zweck : Erzeugung eines Textzeichens mit einem bestimmten ASCII-Code
+
+Syntax : CHR$ (<INT-Ausdruck>)
+
+Erklärung : Die Funktion liefert das Zeichen mit dem ASCII-Code, den der
+ INT-Ausdruck angibt.
+ Das Zeichen wird als TEXT geliefert.
+ Die Leistung der Funktion ist nur für Werte im Bereich 0 bis 255
+ definiert.
+
+
+Beispiel : 10 PRINT CHR$ (61)
+ Ausgabe: =
+
+Vergleiche : ASC-Funktion (Komplementärfunktion)
+
+
+
+Funktion : CINT
+
+Zweck : Konvertierung in den Datentyp INT
+
+Syntax : CINT (<num. Ausdruck>)
+
+Erklärung : Das Ergebnis des numerischen Ausdrucks wird als INT geliefert.
+ REALs werden gerundet. Werte außerhalb des INT-Bereichs führen
+ zu einem INT-Überlauf.
+
+
+Beispiel : 10 LET a = 17.625
+ 20 PRINT CINT (a); CINT (-a)
+ Ausgabe: 18 -18
+
+Vergleiche : CDBL-, FIX-, INT-Funktionen
+
+
+
+Anweisung : CLS
+
+Zweck : Löschen des Bildschirms
+
+Syntax : CLS
+
+Erklärung : Löscht den Bildschirm und positioniert den Cursor in die linke obere
+ Bildschirmecke (Position 1, 1).
+
+
+Beispiel : 10 CLS
+ 20 PRINT "PROGRAMMBEGINN"
+
+
+
+
+Funktion : COS
+
+Zweck : Berechnung des Cosinus eines Radiantwertes
+
+Syntax : COS (<Winkel>)
+
+Erklärung : <Winkel>: REAL-Ausdruck, der den Winkel in Radiant angibt.
+ Die Funktion liefert den Cosinus des Winkels als REAL.
+
+
+Beispiel : 10 PI = 3.141593
+ 20 PRINT COS (PI/4)
+ Ausgabe: .7071067
+
+Vergleiche : SIN-, TAN-Funktionen
+
+
+
+Funktion : CSRLIN
+
+Zweck : Ermittlung der aktuellen Cursorzeile
+
+Syntax : CSRLIN
+
+Erklärung : Geliefert wird die Nummer der Zeile (als INT), in der sich der Cursor
+ auf dem Bildschirm befindet. Die oberste Zeile hat die Nummer 1.
+
+
+Beispiel : 10 CLS
+ 20 PRINT
+ 30 PRINT CSRLIN
+ Ausgabe: 2
+
+Vergleiche : POS-Funktion
+
+
+
+Funktion : CVD, CVI
+
+Zweck : Decodierung von in Texten verschlüsselten Zahlenwerten
+
+Syntax : CVD (<TEXT-Ausdruck>)
+ CVI (<TEXT-Ausdruck>)
+
+Erklärung : INTs und REALs können (mit MKI$ und MKD$) zu Texten codiert
+ werden.
+ CVD decodiert einen in 8 TEXT-Zeichen codierten REAL-Wert.
+ CVI decodiert einen in 2 TEXT-Zeichen codierten INT-Wert.
+ Es wird beim ersten Zeichen des TEXT-Ausdrucks mit der Dekodie­
+ rung begonnen.
+ Ist der TEXT zu kurz, so wird mit der Meldung "Ueberlauf bei Subs­
+ kription" abgebrochen.
+
+
+Beispiel : 10 zahl$ = MKD$ (3.1415)
+ 20 PRINT CVD (zahl$)
+ Ausgabe: 3.1415
+
+Vergleiche : MKD$-, MKI$- Funktionen (Komplementärfunktionen)
+
+
+
+Anweisung : DATA
+
+Zweck : Ablegen von Konstanten
+
+Syntax : DATA [<string>] [, [<string>]] [...]
+
+Erklärung : <string> : <quoted string> | <unquoted string>
+ <quoted string> : von Anführungszeichen umschlossene Zeichen­
+ folge, die alle Zeichen außer Anführungs­
+ zeichen enthalten darf
+ <unquoted string>: Zeichenfolge, die alle Zeichen außer Komma
+ und Doppelpunkt enthalten darf
+
+ Eine DATA-Anweisung stellt einen Datenspeicher dar, der mit READ
+ (s.d.) ausgelesen werden kann.
+ In der DATA-Anweisung können "quoted strings" oder "unquo­
+ ted strings" angegeben werden. "quoted strings" können später nur
+ noch als Texte ausgelesen werden.
+ Bei "unquoted strings" wird der Datentyp in der DATA-Anweisung
+ dagegen nicht festgelegt. Sie können also als INTs, REALs oder
+ TEXTe ausgelesen werden. Sollen "unquoted strings" Zahlenwerte
+ darstellen, so müssen sie den in BASIC üblichen Schreibregeln für
+ die numerischen Konstanten des jeweiligen Typs genügen. Es sind
+ allerdings zusätzlich noch Vorzeichen erlaubt.
+ Wenn die <strings> nicht angegeben sind, so wird ein "nil-Datum"
+ abgelegt. Dieses bewirkt bei einem READ mit numerischer Variable
+ die Lieferung des Wertes null und bei einem READ mit TEXT-Vari­
+ able die Lieferung eines Leertextes.
+
+ Die DATA-Anweisungen können an beliebiger Stelle im Programm
+ (vor oder hinter den zugehörigen READ-Anweisungen) stehen.
+
+ Alle DATA-Anweisungen eines Programms bilden zusammen einen
+ großen sequentiellen Speicher, auf den mit READ der Reihe nach
+ zugegriffen wird. Intern wird ein sogenannter READ-DATA-Zeiger
+ geführt, der immer auf das nächste auszulesende Element zeigt.
+ Die RESTORE-Anweisung (s.d.) ermöglicht es, den READ-
+ DATA-Zeiger auf das erste Element einer bestimmten DATA-Zeile
+ zu setzen.
+
+
+Beispiel : 2020 PRINT "Stadt", "Land", "Fluß"
+ 2030 READ stadt$, land$, fluß$
+ 2040 PRINT stadt$, land$, fluß$
+ .
+ 5000 DATA Paris, Frankreich, Seine
+
+
+Vergleiche : READ-, RESTORE-Anweisungen
+
+
+
+Funktion : DATE$
+
+Zweck : Abrufen des aktuellen Tagesdatums
+
+Syntax : DATE$
+
+Erklärung : Das Tagesdatum wird als Text in der Form TT.MM.JJ geliefert.
+
+
+Beispiel : 10 PRINT "Heute ist der " + DATE$
+ Ausgabe (z.B.): Heute ist der 28.08.87
+
+Vergleiche : TIME$-Funktion
+
+
+
+Anweisung : DEFDBL, DEFINT, DEFSNG, DEFSTR
+
+Zweck : Definition von Anfangsbuchstaben zur Kennzeichnung bestimmter
+ Variablentypen
+
+Syntax : DEFDBL <Buchstabe1> [ - <Buchstabe2>]
+ #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...]
+ DEFINT <Buchstabe1> [ - <Buchstabe2>]
+ #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...]
+ DEFSNG <Buchstabe1> [ - <Buchstabe2>]
+ #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...]
+ DEFSTR <Buchstabe1> [ - <Buchstabe2>]
+ #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...]
+
+
+Erklärung : Mit den aufgeführten Anweisungen ist es möglich, bestimmte Buch­
+ staben festzulegen, die, wenn sie als Anfangsbuchstaben eines
+ Variablennamens verwendet werden, der Variablen einen bestimmten
+ Typ zuordnen.
+
+ Die Typfestlegung durch Kennzeichnung mit den Zeichen '!', '\#', '%'
+ oder '$' hat jedoch Vorrang vor den festgelegten Anfangsbuchstaben.
+ Eine genaue Erläuterung, nach welchen Kriterien der BASIC-Compi­
+ ler den Typ einer Variablen feststellt, befindet sich in Kapitel 4.3.
+
+ Die DEFINT-Anweisung legt Anfangsbuchstaben für INT-Variablen
+ fest.
+ Mit der DEFSTR-Anweisung werden Anfangsbuchstaben von
+ TEXT-Variablen festgelegt.
+ Die Anweisungen DEFDBL- und DEFSNG- wurden nur aus Kom­
+ patibilitätsgründen implementiert. Sie werden zwar auf syntaktische
+ Richtigkeit überprüft, aber ansonsten vom Compiler nicht beachtet.
+
+ Werden bei den Anweisungen ganze Buchstabenbereiche angegeben,
+ so muß der Buchstabe vor dem Bindestrich auch im Alphabet vor
+ dem Buchstaben hinter dem Bindestrich stehen.
+
+Hinweis : 1. Die oben beschriebenen Anweisungen gelten stets erst für die im
+ weiteren Text neu benutzten (also neu eingerichteten) Variablen.
+ 2. Die beschriebenen Anweisungen dürfen auch mehr als einmal in
+ einem Programm vorkommen. Die Buchstaben, die in der zweiten
+ und in den folgenden Anweisungen festgelegt werden, werden
+ #on("izusätzlich#off("i zu den in der ersten Anweisung festgelegten Buchsta­
+ ben als Kennzeichen für den betreffenden Datentyp vom Compiler
+ vermerkt.
+ 3. Der Compiler überprüft nicht, ob gleiche Buchstaben als Kennzei­
+ chen für mehr als einen Variablentyp angegeben werden (siehe
+ Kapitel 4.3.). Der Benutzer ist also selbst dafür verantwortlich, daß
+ solche Überschneidungen nicht vorkommen.
+
+
+Beispiel : 10 DEFSTR s - z
+ 20 DEFINT a - h, n
+ 30 DIM tabelle (17) 'TEXT-Feld
+ 40 LET c = 4 'INT-Variable
+ 50 LET nummer = 17 'INT-Variable
+ 60 LET ueberschrift = "Willkommen" 'TEXT-Variable
+ 70 LET reellezahl = 19.563 'REAL-Variable
+ 80 LET aha\# = -1.36E17 'REAL-Variable
+
+
+
+
+Anweisung : DEF FN
+
+Zweck : Definition einer benutzer-definierten Funktion
+
+Syntax : DEF FN<Name> [ ( <Parameter> [, <Parameter>] #right# [...] ) ] = <Funktionsdefinition>
+
+Erklärung : <Name> : Zeichenfolge, die der Syntax für Variablennamen
+ entsprechen muß
+ FN<Name> bilden zusammen den Namen der
+ neuen Funktion
+ <Parameter>: Zeichenfolge, die der Syntax für Variablennamen
+ entsprechen muß
+ <Funktionsdefinition>: Ausdruck, der Konstanten, Variablen, die
+ Parameter der Funktion und Aufrufe
+ anderer Funktionen enthalten darf
+
+ Mit der DEF FN-Anweisung wird eine benutzer-definierte Funktion
+ ("user function") mit dem Funktionsnamen FN<Name> definiert
+ (vergleiche hierzu auch Kapitel 4.5.).
+ Die benutzer-definierte Funktion liefert, genau wie die standard­
+ mäßig eingebauten Funktionen, einen Wert, der sich aus der Auswer­
+ tung des unter <Funktionsdefinition> angegebenen Ausdrucks
+ ergibt.
+ Das letzte Zeichen des Funktionsnamens gibt den Typ des Wertes
+ an, den die Funktion liefert. Soll die Funktion einen TEXT liefern, so
+ muß der Name mit "$" enden. Soll ein INT geliefert werden, muß der
+ Name mit "%" enden. Für alle anderen Endungen wird eine REAL-
+ liefernde Funktion eingetragen.
+ Bezeichnet der Funktionsname eine TEXT-liefernde Funktion, so
+ muß auch die Funktionsdefinition ein Ergebnis vom Typ TEXT liefern.
+ Zwischen INTs und REALs findet eine Typanpassung statt.
+
+ Die Parameter stehen für die beim Aufruf der Funktion übergebenen
+ Argumente.
+ Sie haben nur bei der Definition Gültigkeit. Hierbei 'überdecken' sie
+ (für diese Zeile) eventuell im BASIC-Programm vorhandene gleich­
+ namige Variablen.
+ Die Syntax der Parameternamen entspricht der Syntax der Namen
+ von einfachen Variablen.
+ Jeder Parameter darf in der Parameterliste nur einmal vorkommen.
+
+ In der Definition dürfen auch Aufrufe von zuvor definierten anderen
+ "user functions" erscheinen, nicht aber die zu definierende Funktion
+ selbst (rekursive Definition).
+
+ Die Funktionen sind allein durch ihre Namen gekennzeichnet. Gene­
+ rische Funktionen (gleicher Name, aber unterschiedliche Parameter)
+ können somit nicht definiert werden.
+
+Hinweis : 1. Die Definition einer "user function" muß ihrem ersten Aufruf
+ immer textuell vorausgehen.
+ 2. "user functions" können auch mehrfach definiert werden. Der
+ Compiler gibt in einem solchen Fall aber eine Warnung aus, da
+ die neue Definition nur für die textuell folgenden Aufrufe gültig ist.
+
+
+Beispiel : 10 LET pi = 3.1415927
+ 20 DEF FNkreisflaeche (radius)
+ #right#= 4.0 * pi * radius * radius
+ 1010 PRINT FNkreisflaeche (1.75)
+ Ausgabe: 38.48451
+
+
+
+Anweisung : DIM
+
+Zweck : Dimensionierung eines Feldes
+
+Syntax : DIM <Felddeklaration> [, <Felddeklaration>] [...]
+
+Erklärung : <Felddeklaration>: <Feldvariable> (<INT-Konstante>
+ #right#[, <INT-Konstante>] [...] )
+ <Feldvariable>: Name des Feldes (Syntax wie Name von einfachen
+ Variablen, vgl. 4.3.)
+
+ Mit der DIM-Anweisung wird ein Feld dimensioniert, das heißt die
+ Anzahl seiner Dimensionen sowie der kleinste und größte Index in
+ jeder Dimension werden festgelegt und der Speicherplatz für seine
+ Elemente (siehe 4.3.) wird reserviert.
+
+ Der kleinste Index in allen Dimensionen richtet sich nach der letzten
+ vorausgegangenen OPTION BASE-Anweisung.
+ Geht der Dimensionierung die Anweisung OPTION BASE 0 textuell
+ voraus oder ist keine OPTION BASE-Anweisung vor der Dimensio­
+ nierung vorhanden, so ist der kleinste Index in allen Dimensionen
+ null.
+ Wenn der Dimensionierung aber eine OPTION BASE 1-Anweisung
+ vorausgeht, dann ist der kleinste Index in allen Dimensionen eins.
+
+ Der größte Feldindex wird für jede Dimension durch die in Klammern
+ stehenden INT-Konstanten angegeben. Die Anzahl dieser INT-Kon­
+ stanten bestimmt auch, wie viele Dimensionen das dimensionierte
+ Feld hat.
+
+ Wird auf ein Element einer Feldvariablen zugegriffen, ohne daß die
+ Feldvariable vorher dimensioniert wurde, dann wird das Feld automa­
+ tisch dimensioniert, wobei die Anzahl der Dimensionen anhand der
+ Anzahl der Indizes beim Aufruf ermittelt wird. Der größte Feldindex
+ wird bei dieser automatischen Dimensionierung in jeder Dimension
+ auf zehn gesetzt. Der kleinste Index richtet sich nach den vorausge­
+ gangenen OPTION BASE-Anweisungen (siehe oben).
+
+ Fehlerfälle bei der Dimensionierung:
+ - "Das Feld ist bereits dimensioniert":
+ Das Feld wurde bereits explizit, oder automatisch durch den Zugriff
+ auf ein Feldelement dimensioniert .
+ - "Die Obergrenze muß >= 1 sein":
+ Es wurde versucht, 0 als größten Index in einer Dimension festzu­
+ legen, obwohl mit OPTION BASE der kleinste Index auf eins fest­
+ gelegt wurde.
+
+ Fehlerfälle beim Zugriff auf ein Feldelement:
+ - "Dimensioniert in ... Dimensionen, gefundene Anzahl Indizes ...":
+ Beim Zugriff wurde eine Anzahl von Indizes gefunden, die nicht mit
+ der Anzahl der Dimensionen übereinstimmt (Fehler zur Über­
+ setzungszeit).
+ - "Ueberlauf bei Subskription" oder "Unterlauf bei Subskription":
+ Der Index ist zu groß beziehungsweise zu klein (Fehler zur Lauf­
+ zeit).
+
+
+Beispiel : 10 DIM a% (20, 10), text$ (30, 40)
+ 20 DIM tabelle (5, 7, 25)
+ 30 LET element = matrix (1, 7)
+
+ Zeile 30 führt eine automatische Dimensionierung durch, die einem
+ DIM matrix (10, 10) entspricht.
+
+
+
+Anweisungsbestandteil : ELSE
+
+Siehe IF-Anweisung
+
+
+
+Anweisung : END
+
+Zweck : Beenden der Programmausführung eines BASIC-Programms
+
+Syntax : END
+
+Erklärung : END beendet die Programmausführung des BASIC-Programms ohne
+ eine Meldung (im Gegensatz zu STOP, s.d.).
+ END-Anweisungen dürfen im Programm an beliebiger Stelle stehen,
+ und es darf auch mehr als eine END-Anweisung in einem
+ Programm vorkommen.
+ Der Compiler übersetzt ein Programm auch nach Erreichen einer
+ END-Anweisung weiter.
+ Nach der letzten Anweisung eines Programms muß kein END stehen.
+
+
+Beispiel : 2020 PRINT "Das war's !"
+ 2030 REM Hiernach hört's auf
+ 2040 END
+
+
+Vergleiche : STOP-Anweisung
+
+
+
+Anweisungsbestandteil : EOF
+
+Siehe INPUT-Anweisung
+
+
+
+
+Operator : EQV
+
+Siehe Kapitel 4.4. (Operatoren)
+
+
+
+Funktion : ERL
+
+Zweck : Ermittlung der letzten Fehlerzeile
+
+Syntax : ERL
+
+Erklärung : Die Nummer der Zeile, in der der letzte Fehler auftrat, wird als INT
+ geliefert.
+
+Hinweis : ERL ist realisiert durch Aufruf der Prozedur 'errorline' des Betriebs­
+ systems.
+ Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü­
+ gung steht, ist diese Funktion nicht im üblichen BASIC-Sinne
+ brauchbar.
+
+Vergleiche : ERM$, ERR-Funktionen, ERROR-Anweisung
+
+
+
+Funktion : ERM$
+
+Zweck : Ermittlung der letzten Fehlermeldung
+
+Syntax : ERM$
+
+Erklärung : Die letzte Fehlermeldung wird als TEXT geliefert.
+
+Hinweis : ERM$ ist realisiert durch Aufruf der Prozedur 'errormessage' des
+ Betriebssystems.
+ Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü­
+ gung steht, ist diese Funktion nicht im üblichen BASIC-Sinne
+ brauchbar.
+
+Vergleiche : ERL-, ERR-Funktionen, ERROR-Anweisung
+
+
+
+Funktion : ERR
+
+Zweck : Ermittlung des letzten Fehlercodes
+
+Syntax : ERR
+
+Erklärung : Der Code des letzten aufgetretenen Fehlers wird als INT geliefert.
+
+Hinweis : ERR ist realisiert durch Aufruf der Prozedur 'errorcode' des Betriebs­
+ systems.
+ Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü­
+ gung steht, ist diese Funktion nicht im üblichen BASIC-Sinne
+ brauchbar.
+
+Vergleiche : ERL-, ERM$-Funktionen, ERROR-Anweisung
+
+
+
+Anweisung : ERROR
+
+Zweck : Auslösen eines Fehlers mit bestimmtem Fehlercode
+
+Syntax : ERROR <INT-Ausdruck>
+
+Erklärung : Es wird ein Fehler mit dem durch den INT-Ausdruck bestimmten
+ Fehlercode ausgelöst.
+
+Hinweis : ERROR ist realisiert durch Aufruf der Prozedur 'errorstop' des Be­
+ triebssystems.
+ Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü­
+ gung steht, ist diese Anweisung nicht im üblichen BASIC-Sinne
+ brauchbar.
+
+Vergleiche : ERL-, ERM$-, ERR-Funktionen
+
+
+
+Funktion : EXP
+
+Zweck : Berechnung einer Potenz der Eulerschen Zahl
+
+Syntax : EXP (<REAL-Ausdruck>)
+
+Erklärung : Die Funktion liefert e (die Basis des natürlichen Logarithmus) poten­
+ ziert mit dem Wert des REAL-Ausdrucks.
+ Bei zu großen Werten kommt es zum Fehler 'REAL-Ueberlauf'.
+ Das Ergebnis der Funktion wird als REAL geliefert.
+
+
+Beispiel : 10 PRINT EXP (10.0)
+ Ausgabe: 22026.47
+
+Vergleiche : LOG-Funktion (Komplementärfunktion)
+
+
+
+Funktion : FIX
+
+Zweck : Ermittlung der Vorkommastellen einer REAL-Zahl
+
+Syntax : FIX (<REAL-Ausdruck>)
+
+Erklärung : Die Funktion schneidet die Nachkommastellen ab und liefert nur die
+ Vorkommastellen des REAL-Ausdrucks.
+ Die Vorkommastellen werden ebenfalls als REALs geliefert.
+
+
+Beispiel : 10 zahl = 1.2345E2
+ 20 PRINT FIX (zahl)
+ Ausgabe: 123
+
+Vergleiche : CINT-, INT-Funktionen
+
+
+
+Anweisung : FOR
+
+Zweck : Beginn einer Zählschleife
+
+Syntax : FOR <num. Variable> = <Anfangswert> #ib(3)#TO#ie(3)# <Endwert>
+ #right#[ #ib(3)#STEP#ie(3)# <Schrittweite> ]
+ <Schleifenrumpf>
+
+
+Erklärung : <num. Variable> : INT- oder REAL-Variable
+ <Anfangswert> : numerischer Ausdruck
+ <Endwert> : numerischer Ausdruck
+ <Schrittweite> : numerischer Ausdruck
+ <Schleifenrumpf>: Folge von Programmzeilen
+
+ Die FOR-Anweisung erlaubt die komfortable Programmierung von
+ automatischen Zählschleifen (sogenannten FOR-NEXT-Schleifen).
+ Gelangt das Programm während der Ausführung an eine FOR-An­
+ weisung, so werden zunächst die Ausdrücke <Anfangswert>,
+ <Endwert> sowie gegebenenfalls <Schrittweite> ausgewertet. Der
+ Anfangswert wird dann der Variablen zugewiesen.
+ Wenn der Wert der Variablen größer ist als der Endwert (bzw. kleiner
+ als der Endwert bei negativer Schrittweite), dann wird das Programm
+ mit der nach dem korrespondierenden NEXT (s.d.) folgenden
+ Anweisung fortgesetzt.
+ Ist dies jedoch nicht der Fall, werden die Anweisungen des <Schlei­
+ fenrumpfs> ausgeführt. Erreicht das Programm nun die zum FOR
+ gehörige NEXT-Anweisung (gleiche Variable), so wird der Wert der
+ Variablen um die Schrittweite erhöht beziehungsweise erniedrigt (je
+ nach Vorzeichen), und wieder an den Anfang der Schleife verzweigt.
+ Hier findet dann wieder der Vergleich des Variableninhalts mit dem
+ Endwert statt (siehe oben).
+
+ Die Laufvariable darf innerhalb der Schleife in Ausdrücken vorkom­
+ men. Sie darf sogar verändert werden (, was aber zu unübersichtli­
+ chen Effekten führen kann). Auch eine Schachtelung mehrerer
+ Schleifen mit der gleichen Laufvariable ist syntaktisch möglich, sollte
+ aber #on("iunter allen Umständen#off("i vermieden werden.
+
+ FOR-NEXT-Schleifen dürfen (auch mit WHILE-WEND-Schleifen,
+ s.d.) geschachtelt werden. Überschneidungen von FOR-NEXT-
+ Schleifen und WHILE-WEND-Schleifen sind aber nicht zulässig.
+
+
+Beispiel : 10 DIM name$ (5)
+ 20 FOR i = 1 TO 5
+ 30 PRINT "Bitte geben Sie den " + STR$ (i)
+ #right#+ ". Namen ein:";
+ 40 INPUT name$ (i)
+ 50 NEXT i
+
+
+ Es werden die fünf Elemente des Feldes 'name$' eingelesen.
+
+Vergleiche : NEXT-, WHILE-, IF-Anweisungen
+
+
+
+Funktion : FRE
+
+Zweck : Ermittlung des verfügbaren Speicherplatzes
+
+Syntax : FRE (<num. Ausdruck>)
+ FRE (<TEXT-Ausdruck>)
+
+Erklärung : Die Funktion liefert die Anzahl der freien Bytes.
+ FRE veranlaßt außerdem ein 'collect heap garbage' (EUMEL-
+ Systemprozedur).
+
+ Das Ergebnis der Funktion wird als REAL geliefert.
+ Der Argument-Ausdruck ist ein Dummy-Argument (hat keinen
+ Einfluß auf den gelieferten Wert).
+
+Hinweis : Bei der EUMEL M+ Version wird ein korrektes Ergebnis geliefert
+ (vgl.'storage info').
+
+
+Beispiel : 10 PRINT FRE (0)
+ Ausgabe (z.B.): 5324800
+
+
+
+Anweisungsbestandteil : GO
+
+Siehe GOSUB und GOTO
+
+
+
+Anweisung : GOSUB
+
+Zweck : Unterprogramm-Aufruf
+
+Syntax : GOSUB <Zeilennummer>
+
+Erklärung : <Zeilennummer>: INT-Konstante
+ Statt GOSUB darf auch GO #ib(3)#SUB#ie(3)# geschrieben werden.
+
+ Die Programmausführung wird in der Zeile mit der angegebenen
+ Zeilennummer fortgesetzt. Die Zeile mit der Zeilennummer muß im
+ Programm existieren.
+ Wird im weiteren Programmablauf die Anweisung RETURN gefunden,
+ so wird hinter dem letzten abgearbeiteten GOSUB die Programm­
+ ausführung fortgesetzt.
+ GOSUB dient zum Aufruf von #on("iUnterprogrammen#off("i, die von mehr als
+ einer Stelle im Programm (und auch in anderen Unterprogrammen)
+ aufgerufen werden können.
+
+Hinweis : Es wird empfohlen, Unterprogramme im Programm deutlich als solche
+ zu kennzeichnen und (durch END, STOP oder GOTO) sicherzustel­
+ len, daß nur mit GOSUB zu ihnen verzweigt wird, da es sonst leicht
+ zu der (Laufzeit-) Fehlermeldung "RETURN ohne GOSUB" kommen
+ kann.
+
+
+Beispiel : 140 GOSUB 10000 'Zeige Uhrzeit
+ .
+ .
+ 370 GOSUB 10000 'Zeige Uhrzeit
+ 9990 END
+ 10000 REM Unterprogramm Zeige Uhrzeit
+ 10010 PRINT "Es ist " + TIME$ + " Uhr"
+ 10020 RETURN
+
+
+Vergleiche : RETURN-, ON-, GOTO- Anweisungen
+
+
+
+Anweisung : GOTO
+
+Zweck : Sprung zu einer angegebenen Zeile
+
+Syntax : GOTO <Zeilennummer>
+
+Erklärung : <Zeilennummer>: INT-Konstante
+ Statt GOTO darf auch GO #ib(3)#TO#ie(3)# geschrieben werden.
+
+ Die Programmausführung wird in der Zeile mit der angegebenen
+ Zeilennummer fortgesetzt. Die Zeile mit der Zeilennummer muß im
+ Programm existieren.
+
+
+Beispiel : 10 INPUT "Monat (1-12)", monat%
+ 20 IF monat% < 1 OR monat% > 12 THEN GOTO 10
+
+
+Vergleiche : ON-, IF-, GOSUB- Anweisungen
+
+
+
+Funktion : HEX$
+
+Zweck : Erzeugung der hexadezimalen Darstellung einer Zahl als Text
+
+Syntax : HEX$ (<INT-Ausdruck>)
+
+Erklärung : Die Funktion liefert die hexadezimale (Zweierkomplement-) Darstel­
+ lung der Zahl, die sich aus dem INT-Ausdruck ergibt.
+
+
+Beispiel : 10 PRINT HEX$ (10000)
+ Ausgabe: 2710
+
+Vergleiche : OCT$-Funktion
+
+
+
+Anweisung : IF
+
+Zweck : Sprung zu einer angegebenen Zeile
+
+Syntax : IF <Bedingung>
+ #right#[,] #ib(3)#THEN#ie(3)# <Anweisung(en)>|<Zeilennummer>
+ #right#[ [,] #ib(3)#ELSE#ie(3)# <Anweisung(en)>|<Zeilennummer>]
+ IF <Bedingung> [,] GOTO <Zeilennummer>
+ #right#[ [,] ELSE <Anweisung(en)>|<Zeilennummer>]
+
+Erklärung : <Bedingung> : numerischer Ausdruck
+ <Anweisung(en)>: Eine oder mehrere BASIC-Anweisungen, wobei
+ mehrere wie gewohnt durch ':' zu trennen sind
+ <Zeilennummer> : INT-Konstante
+ Statt GOTO darf auch GO TO geschrieben werden.
+
+ Anhand der Bedingung wird entschieden, ob die Abarbeitung des
+ Programms mit dem THEN- oder ELSE-Zweig fortgesetzt werden
+ soll. Mit dem THEN-Zweig wird das Programm fortgesetzt, wenn die
+ Bedingung erfüllt ist (, d.h. der numerische Ausdruck ungleich null
+ ist). Im anderen Fall (Bedingung nicht erfüllt, numerischer Ausdruck
+ gleich null) wird das Programm mit dem ELSE-Teil fortgesetzt. Ist
+ kein ELSE-Teil angegeben, so wird die Abarbeitung des
+ Programmes in der folgenden #on("iZeile#off("i (nicht nach ':') fortgesetzt.
+
+ Sind statt Anweisungen Zeilennummern nach THEN oder ELSE
+ angegeben, so entspricht dies einem GOTO (s.d.) zu diesen Zeilen­
+ nummern.
+
+
+Hinweis : Auch eine IF-Anweisung muß in #on("ieiner#off("i Programmzeile stehen.
+
+
+Beispiel : 10 IF a >= b THEN IF a > b THEN
+ #right#PRINT "a größer b" ELSE PRINT "a gleich b"
+ #right#ELSE PRINT "a kleiner b"
+
+
+ Das Beispiel zeigt, daß bei geschachtelten IF-Anweisungen die
+ ELSE-Teile immer auf das letzte vorhergehende IF bezogen werden,
+ für das noch kein ELSE-Teil gefunden wurde.
+
+
+
+Vergleiche : GOTO-, GOSUB-, ON-Anweisungen
+
+
+
+Operator : IMP
+
+Siehe Kapitel 4.4. (Operatoren)
+
+
+
+Funktion : INKEY$
+
+Zweck : Holen eines Zeichens von der Tastatur
+
+Syntax : INKEY$
+
+Erklärung : Die Funktion liefert ein Textzeichen aus dem Tastaturzeichenpuffer.
+ Wurde kein Zeichen eingegeben, so wird ein Leertext (niltext) gelie­
+ fert.
+ Die gelieferten Zeichen erscheinen nicht auf dem Bildschirm.
+
+
+Beispiel : 10 REM Schreibmaschine
+ 20 LET a$ = INKEY$
+ 30 IF ASC (a$) = 27 THEN STOP
+ 40 PRINT a$;
+ 50 GOTO 20
+
+
+ Die eingegebenen Zeichen werden ausgegeben. Abbruch mit ESC.
+
+Vergleiche : INPUT$-Funktion, INPUT-Anweisung
+
+
+
+Anweisung : INPUT
+
+Zweck : Einlesen von Daten von der Tastatur
+
+Syntax : INPUT [;] [<Eingabeaufforderung> ,|; ][ #ib(3)#EOF#ie(3)#
+ <Zeilennummer>]
+ #right#<Variable> [, <Variable> ] [...]
+
+Erklärung : <Eingabeaufforderung>: TEXT-Konstante
+ <Zeilennummer>: INT-Konstante
+ <Variable>: Variable, der der eingelesene Werte
+ zugewiesen werden soll
+
+ Mit der INPUT-Anweisung werden Daten zur Laufzeit des
+ Programms von der Tastatur in Variablen eingelesen.
+
+ Folgt dem INPUT-Statement ein Semikolon, so wird nach
+ Beendigung der Eingabe kein Zeilenwechsel vorgenommen.
+
+ Fehlt die <Eingabeaufforderung>, so wird "? " als Eingabe­
+ aufforderung ausgegeben.
+ Folgt der ein Semikolon, so wird "? " noch zusätzlich ausge­
+ geben. Bei einem Komma wird dieser Standard-Prompt unter­
+ drückt.
+
+ Folgt der <Eingabeaufforderung> die Zeichenfolge 'EOF', so wird
+ bei Eingabe eines Leertextes zu der nach 'EOF' angegebenen
+ Zeilennumer verzweigt.
+
+ Sollen mehrere Variablen eingelesen werden, so muß der Benutzer
+ auch entsprechend viele Daten (durch Kommata getrennt) zur Verfü­
+ gung stellen.
+
+ Wird nichts eingegeben beziehungsweise nur die richtige Anzahl von
+ Kommata, so wird den entsprechenden Variablen 0, 0.0 bzw. 'niltext'
+ zugewiesen.
+
+ Bei der Eingabe für eine Textvariable können alle Zeichen (außer
+ Steuerzeichen) eingegeben werden. Beginnt eine Eingabe mit dem
+ Anführungszeichen oder endet sie damit, dann muß sie auch damit
+ enden beziehungsweise beginnen. Diese beiden Anführungszeichen
+ werden nicht mit zugewiesen. Innerhalb dieser Texteingabe dürfen
+ Anführungszeichen stehen, aber keine Kommata.
+
+ Eingaben für numerische Variablen müssen in der für Konstanten
+ üblichen Schreibweise erfolgen. Vorzeichen sind allerdings zusätzlich
+ erlaubt.
+
+ Vor Zuweisung der eingegebenen Werte an die Variablen werden
+ Anzahl und Typ(en) und die Anzahl überprüft.
+ Dabei können folgende Fehlerfälle auftreten:
+ - "falscher Typ":
+ Es wurde ein Text statt einer Zahl eingegeben, es wurde ein REAL
+ statt eines INTs eingegeben oder eine Texteingabe ist fehlerhaft.
+ - "zu wenig Daten"
+ - "zu viele Daten"
+ - "Überlauf":
+ Es wurde eine zu große (oder zu kleine) Zahl eingegeben.
+
+ Kommt es zu einem Fehler, dann wird nach der Meldung "?Eingabe
+ wiederholen ! (<Fehlerbeschreibung>)" die Eingabe zum Editieren
+ angeboten.
+
+Hinweis : Bei Eingabe von 'ESC k' kann die letzte Eingabezeile zum Editieren
+ zurückgeholt werden.
+
+ Die Eingabe kann mit der Systemprozedur 'sysin' aus einer Datei
+ erfolgen. Aus der Eingabedatei wird für jedes INPUT-Statement eine
+ Zeile eingelesen. Die Ausgabe der Eingabeaufforderung und der
+ Zeilenwechsel nach der Eingabe werden unterdrückt. Sind die
+ Eingabedaten fehlerhaft, so wird das Programm mit 'errorstop'
+ abgebrochen.
+
+ Wird die Ausgabe mit 'sysout' umgeleitet, so werden die Eingabe­
+ aufforderung, die Eingabezeichenfolge und der Zeilenwechsel nach
+ der Eingabe auf den Bildschirm und in die Ausgabedatei ausgegeben,
+ auch dann, wenn der Text der Eingabe aus einer Datei eingelesen
+ wurde.
+
+
+Beispiel : 1990 INPUT "Name, Vorname, Alter";
+ #right#name$, vorname$, alter%
+
+
+Vergleiche : INKEY$-, INPUT$-Funktionen
+
+
+
+Funktion : INPUT$
+
+Zweck : Holen einer Zeichenfolge von der Tastatur
+
+Syntax : INPUT$ (<Anzahl Zeichen>)
+
+Erklärung : <Anzahl Zeichen>: INT-Ausdruck
+
+ Die Funktion liefert eine Folge von <Anzahl Zeichen> Textzeichen
+ aus dem Tastaturzeichenpuffer. Enthält der Puffer nicht alle ge­
+ wünschten Zeichen, so wird auf weitere Zeichen von der Tastatur
+ gewartet.
+ Die gelieferten Zeichen erscheinen nicht auf dem Bildschirm.
+
+
+Beispiel : 10 PRINT "Bitte drei Zeichen eingeben !"
+ 20 LET a$ = INPUT$ (3)
+ 30 PRINT "Danke schön !"
+
+
+Vergleiche : INKEY$-Funktion, INPUT-Anweisung
+
+
+
+Funktion : INSTR
+
+Zweck : Suchen einer Zeichenfolge in einer anderen
+
+Syntax : INSTR ( [<Startposition>,] <TEXT-Ausdruck1>,
+ #right#<TEXT-Ausdruck 2>)
+
+Erklärung : <Startposition>: INT-Ausdruck
+
+ Die Funktion liefert die Position, ab der der TEXT-Ausdruck 2 das
+ erste Mal im TEXT-Ausdruck 1 vorkommt.
+ Die Position wird als INT geliefert.
+
+
+Beispiel : 10 LET a$ = "hallihallo"
+ 20 LET b$ = "all"
+ 30 PRINT INSTR (a$, b$); INSTR (5, a$, b$)
+ Ausgabe: 2 7
+
+
+
+Funktion : INT
+
+Zweck : Ermittlung der nächstkleineren ganzen Zahl
+
+Syntax : INT (<REAL-Ausdruck>)
+
+Erklärung : Die Funktion liefert die größte ganze Zahl, für die gilt:
+ n kleiner gleich <REAL-Ausdruck>.
+ Bei positiven Werten bedeutet das, daß die Nachkommastellen abge­
+ schnitten werden.
+ Das Ergebnis wird als REAL geliefert.
+
+
+Beispiel : 10 PRINT INT (11.74); INT (-11.74)
+ Ausgabe: 11 -12
+
+Vergleiche : CINT-, FIX-Funktionen
+
+
+
+Anweisung : KILL
+
+Zweck : Löschen einer Datei in der Task
+
+Syntax : KILL <Dateiname>
+
+Erklärung : <Dateiname>: TEXT-Ausdruck
+ Die Datei <Dateiname> wird (ohne Nachfrage) gelöscht.
+
+
+Beispiel : 2110 KILL "Scratchdatei"
+
+
+
+
+Funktion : LEFT$
+
+Zweck : Erzeugung eines Teiltextes aus einem anderen Text
+
+Syntax : LEFT$ (<TEXT-Ausdruck>, <Anzahl Zeichen>)
+
+Erklärung : <Anzahl Zeichen>: INT-Ausdruck
+
+ Die Funktion liefert die ersten <Anzahl Zeichen> Textzeichen des
+ TEXT-Ausdrucks.
+
+
+Beispiel : 10 LET a$ = "hallihallo"
+ 20 PRINT LEFT$ (a$, 4)
+ Ausgabe: hall
+
+Vergleiche : MID$-, RIGHT$-Funktionen, LSET-, MID$-, RSET-
+ Anweisungen
+
+
+
+Funktion : LEN
+
+Zweck : Ermittlung der Länge eines Textes
+
+Syntax : LEN (<TEXT-Ausdruck>)
+
+Erklärung : Die Funktion liefert die Anzahl der im TEXT-Ausdruck enthaltenen
+ Zeichen (also die Länge des Textes). Die Länge wird als INT
+ geliefert.
+ Ein Leertext (niltext, "") hat die Länge null.
+
+
+Beispiel : 10 LET a$ = "hallihallo"
+ 20 PRINT LEN (a$)
+ Ausgabe: 10
+
+
+
+Anweisung : LET
+
+Zweck : Zuweisung eines Wertes an eine Variable
+
+Syntax : [LET] <Variable> = <Ausdruck>
+
+Erklärung : Die LET-Anweisung ermöglicht das Zuweisen von Werten an Variab­
+ len (dazu gehören auch die Elemente von Feldern).
+
+ Das Schlüsselwort LET ist optional, d.h. eine Zuweisung wird auch
+ ohne dieses Schlüsselwort erkannt.
+
+ #on("iZuweisung an TEXT-Variablen:#off("i
+ LET <TEXT-Variable> = <TEXT-Ausdruck> oder <num.
+ Konstante>
+ Die numerische Konstante wird automatisch in einen TEXT umge­
+ wandelt (vgl. STR$-Funktion)
+
+ #on("iZuweisung an INT-Variablen:#off("i
+ LET <INT-Variable> = <num. Ausdruck>
+ Ist der numerische Ausdruck ein REAL-Ausdruck, so wird automa­
+ tisch nach INT konvertiert (vgl. CINT-Funktion).
+
+ #on("iZuweisung an REAL-Variablen:#off("i
+ LET <REAL-Variable> = <num. Ausdruck>
+ Ist der numerische Ausdruck ein INT-Ausdruck, so wird automatisch
+ nach REAL konvertiert (vgl. CDBL-Funktion).
+
+
+Beispiel : 10 LET t$ = "murmel marmel"
+ 20 LET t$ = 1245.3 'wie "1245.3"
+ 30 LET i% = 852
+ 40 LET i% = 12.73 'aufgerundet: 13
+ 50 LET r = 564 'wie 564.
+ 60 LET r = 157.36
+
+
+
+
+Anweisung : LINE INPUT
+
+Zweck : Einlesen einer Eingabe von der Tastatur in eine TEXT-Variable
+
+Syntax : LINE INPUT [;] [<Eingabeaufforderung>;]
+ #right#<TEXT-Variable>
+
+Erklärung : Die LINE INPUT-Anweisung ermöglicht das Einlesen von Eingaben
+ in TEXT-Variablen, aber im Gegensatz zu INPUT ohne Beachtung
+ von Trennzeichen (z.B. ",").
+
+ Steht direkt nach LINE INPUT ein Semikolon, so wird nach Beendi­
+ gung der Eingabe der Zeilenwechsel unterdrückt.
+
+ Der eingegebene Text wird (bis auf das CR-Zeichen) der TEXT-
+ Variablen zugewiesen.
+
+
+Beispiel : 2110 LINE INPUT "Name: ";name$
+
+
+ Der Benutzer könnte nun auch folgendes eingeben:
+ Neumann, Alfred E.
+
+Vergleiche : INPUT-Anweisung
+
+
+
+Funktion : LOG
+
+Zweck : Berechnung des natürlichen Logarithmus einer Zahl
+
+Syntax : LOG (<REAL-Ausdruck>)
+
+Erklärung : Die Funktion liefert den natürlichen Logarithmus des Wertes des
+ REAL-Ausdrucks.
+ Bei nicht-positiven Werten kommt es zu einem Fehler in der
+ EUMEL-Prozedur 'log2'.
+ Das Ergebnis der Funktion wird als REAL geliefert.
+
+
+Beispiel : 10 PRINT LOG (10.0)
+ Ausgabe: 2.302585
+
+Vergleiche : EXP-Funktion (Komplementärfunktion)
+
+
+
+Funktion : LPOS
+
+Zweck : Ermittlung der aktuellen Druckspalte
+
+Syntax : LPOS (<num. Ausdruck>)
+
+Erklärung : Geliefert wird die Nummer der Spalte (als INT), in die das nächste
+ nächste Zeichen mit LPRINT ausgegeben wird. Die Spalte ganz links
+ hat die Nummer 1.
+ Der Argument-Ausdruck ist ein Dummy-Argument (hat keinen
+ Einfluß auf den gelieferten Wert).
+
+
+Beispiel : 3010 IF LPOS (0) > 65 THEN LPRINT
+ 3020 LPRINT name$
+
+
+ Falls die Druckposition hinter Spalte 65 liegt, wird eine neue Druck­
+ zeile begonnen.
+
+Vergleiche : LPRINT-Anweisung, TAB-, POS-Funktion
+
+
+
+Anweisung : LPRINT
+
+Zweck : Ausgabe in eine Druckdatei
+
+Syntax : LPRINT [#ib(3)#USING#ie(3)# <Format> ;]
+ #right#[ #ib(3)#TAB#ie(3)# (<Spalte>) | , | ; | <Ausdruck> ] [...]
+
+Erklärung : <Format> : TEXT-Ausdruck für USING (vgl. PRINT)
+ <Spalte> : INT-Ausdruck (vgl. PRINT)
+ <Ausdruck>: TEXT-Ausdruck oder numerischer Ausdruck
+
+ Die LPRINT-Anweisung arbeitet wie PRINT (siehe dort), mit dem
+ Unterschied, daß LPRINT die Zeichen nicht auf den Bildschirm, son­
+ dern in eine Datei mit dem Namen "BASIC LPRINT OUTPUT"
+ ausgibt. Diese Datei wird automatisch eingerichtet, falls sie noch
+ nicht existiert. Ist sie schon vorhanden, so werden die auszugeben­
+ den Zeichen am Ende der Datei angefügt.
+ Nach oder bei Ablauf des Programms kann die Datei (evtl. nach
+ vorheriger Aufbereitung durch Textverarbeitungsprogramme) mit
+ 'print', wie im EUMEL-System üblich, an den Drucker geschickt
+ werden. Der Benutzer ist selbst dafür verantwortlich, daß er die
+ Druckdatei, sofern die Daten nicht mehr benötigt werden, vor einem
+ neuen Programmlauf leert oder löscht. Versäumt er dies, so bleiben
+ die alten Daten in der Druckdatei, und die neuen Ausgaben werden
+ hinten angefügt. Das Löschen der Druckdatei kann zum Beispiel
+ durch das BASIC-Programm mit der KILL-Anweisung erreicht
+ werden.
+
+ Die Art der Ausgabe und die Syntax ist sonst analog zur PRINT-
+ Anweisung (siehe Erläuterungen dort).
+
+
+Beispiel : 2110 LPRINT "Dieser Text geht in die Druckdatei"
+ 2120 LPRINT TAB (12); "Datum: " DATE$
+ 2130 LPRINT 1, 2, 3
+
+
+Vergleiche : PRINT-Anweisung, LPOS-Funktion
+
+
+
+Anweisung : LSET
+
+Zweck : Ersetzen von Zeichen eines Textes von links her
+
+Syntax : LSET <TEXT-Variable> = <TEXT-Ausdruck>
+
+Erklärung : Das Ergebnis des TEXT-Ausdrucks wird, links beginnend, in der
+ TEXT-Variablen eingesetzt. Es werden höchstens so viele Zeichen
+ ersetzt, wie bisher schon in der Variablen vorhanden waren, das heißt
+ die Länge des Textes in der Variablen ändert sich nicht.
+
+
+Beispiel : 210 LET a$ = "12345"
+ 220 LSET a$ = "ABCDEFG"
+ 230 PRINT a$,
+ 240 LSET a$ = "abc"
+ 250 PRINT a$
+ Ausgabe: ABCDE abcDE
+
+Vergleiche : MID$-, RSET-Anweisungen, LEFT$-, MID$-, RIGHT$-Funk­
+ tionen
+
+
+
+Anweisung : MID$
+
+Zweck : Ersetzen von Zeichen innnerhalb eines Textes
+
+Syntax : MID$ (<TEXT-Variable>, <Startposition>
+ #right#[, <Anzahl Zeichen>] ) = <TEXT-Ausdruck>
+
+Erklärung : <Startposition> : INT-Ausdruck
+ <Anzahl Zeichen>: INT-Ausdruck
+
+ Das Ergebnis des TEXT-Ausdrucks wird, bei <Startposition>
+ beginnend, in der TEXT-Variablen eingesetzt. Es werden höch­
+ stens LEN <TEXT-Variable> Textzeichen ersetzt. Ist keine
+ <Anzahl Zeichen> angegeben, so werden so viele Zeichen des
+ TEXT-Ausdrucks wie möglich in der TEXT-Variablen eingetragen.
+ Außerdem gilt: Es wird nicht über das bisherige Ende des Variablen­
+ inhalts ersetzt, das heißt die Länge des Textes in der Variablen
+ ändert sich nicht.
+
+
+Beispiel : 210 LET a$ = "12345"
+ 220 MID$ (a$, 3) = "ABCDEFG"
+ 230 PRINT a$,
+ 240 MID$ (a$, 2, 1) = "abc"
+ 250 PRINT a$
+ Ausgabe: 12ABC 1aABC
+
+Vergleiche : LEFT$-, MID$-, RIGHT$-Funktionen, LSET-, RSET-
+ Anweisungen
+
+
+
+Funktion : MID$
+
+Zweck : Erzeugung eines Teiltextes aus einem anderen Text
+
+Syntax : MID$ (<TEXT-Ausdruck>,
+ #right#<Startposition> [, <Anzahl Zeichen>])
+
+Erklärung : <Startposition> : INT-Ausdruck
+ <Anzahl Zeichen>: INT-Ausdruck
+
+ Die Funktion liefert höchstens <Anzahl Zeichen> Textzeichen des
+ TEXT-Ausdrucks von Position <Startposition> an.
+ Wird <Anzahl Zeichen> nicht angegeben, so werden alle Zeichen
+ ab Startposition geliefert.
+ Werden rechts von <Startposition> keine Zeichen mehr gefunden
+ oder ist <Anzahl Zeichen> gleich null, so wird ein Leertext geliefert.
+
+
+Beispiel : 10 LET a$ = "hallihallo"
+ 20 PRINT MID$ (a$, 4, 4),
+ 30 PRINT MID$ (a$, 6)
+ Ausgabe: liha hallo
+
+Vergleiche : LEFT$-, RIGHT$-Funktionen, LSET-, MID$-, RSET-
+ Anweisungen
+
+
+
+Funktion : MKD$, MKI$
+
+Zweck : Codierung von Zahlenwerten in Texte
+
+Syntax : MKD$ (<REAL-Ausdruck>)
+ MKI$ (<INT-Ausdruck>)
+
+Erklärung : Mit MKD$ und MKI$ können INTs und REALs zu Texten codiert
+ werden.
+
+ Die Funktion MKD$ liefert einen 8 Zeichen langen TEXT, der den
+ Wert des REAL-Ausdrucks codiert enthält.
+ Vergleichbar arbeitet MKI$, das einen 2 Zeichen langen TEXT liefert,
+ der den Wert des INT-Ausdrucks darstellt.
+
+ Mit MKD$ und MKI$ codierte Werte können mit CVD und CVI (s.d.)
+ wieder decodiert werden.
+
+
+Beispiel : 10 zahl$ = MKD$ (3.1415)
+ 20 PRINT CVD (zahl$)
+ Ausgabe: 3.1415
+
+Vergleiche : CVD-, CVI-Funktionen
+
+
+
+Operator : MOD
+
+Siehe Kapitel 4.4. (Operatoren)
+
+
+
+Anweisung : NAME
+
+Zweck : Umbenennen einer Datei
+
+Syntax : NAME <alter Name> AS <neuer Name>
+
+Erklärung : <alter Name>: TEXT-Ausdruck
+ <alter Name>: TEXT-Ausdruck
+
+ NAME benennt die Datei <alter Name> in <neuer Name> um.
+
+
+Beispiel : 10 NAME "Käufer" AS "Kunden"
+
+
+
+
+Anweisung : NEXT
+
+Zweck : Markierung des Endes einer FOR-Schleife
+
+Syntax : NEXT [<num. Variable>] [, <num. Variable>] [...]
+
+Erklärung : NEXT markiert das Ende einer FOR-Schleife (vergleiche FOR-
+ Anweisung).
+
+ Wird keine Variable angegeben, so bezieht sich das NEXT auf das
+ letzte textuell vorhergehende FOR.
+ Wird eine Laufvariable angegeben, so muß sie mit der im letzten
+ FOR verwendeten Laufvariable übereinstimmen.
+ Werden mehrere Variablen angegeben, so werden durch die
+ NEXT-Anweisung mehrere FOR-Schleifen abgeschlossen.
+ Beachten Sie, daß FOR-Schleifen sich nicht überschneiden dürfen,
+ sondern nur Schachtelungen zulässig sind. Es kommt daher auf die
+ Reihenfolge der Variablen bei den NEXT-Anweisungen an. Die
+ letzte (innerste) FOR-Schleife muß als erste wieder mit dem zuge­
+ hörigen NEXT abgeschlossen werden.
+
+Vergleiche : FOR-, WHILE-Anweisungen
+
+
+
+Operator : NOT
+
+Siehe Kapitel 4.4. (Operatoren)
+
+
+
+Funktion : OCT$
+
+Zweck : Erzeugung der oktalen Darstellung einer Zahl als Text
+
+Syntax : OCT$ (<INT-Ausdruck>)
+
+Erklärung : Die Funktion liefert die oktale (Zweierkomplement-) Darstellung der
+ Zahl, die sich aus dem INT-Ausdruck ergibt.
+
+
+Beispiel : 10 PRINT OCT$ (10000)
+ Ausgabe: 23420
+
+Vergleiche : OCT$-Funktion
+
+
+
+Anweisung : ON
+
+Zweck : Ausführung eines "berechneten" Sprungs oder Unterprogramm-
+ Aufrufs
+
+Syntax : ON <Sprungziel Nr.> GOTO | GOSUB
+ #right#<Zeilennummer> [, <Zeilennummer>] [...]
+
+Erklärung : <Sprungziel Nr.>: INT-Ausdruck
+ <Zeilennummer> : INT-Konstante
+
+ ON ermöglicht die Verzweigung des Programms an eine von mehre­
+ ren Stellen abhängig vom Ergebnis eines INT-Ausdrucks.
+ Gelangt das Programm an eine ON-Anweisung, dann wird zunächst
+ der Wert des INT-Ausdrucks berechnet. Dieses Ergebnis bildet dann
+ die Nummer n des Sprungziels. Danach wird zur n-ten Zeilen­
+ nummer, die nach GOTO beziehungsweise GOSUB steht, verzweigt.
+ Die maximale Anzahl von Zeilennummern, die nach GOTO oder
+ GOSUB angegeben werden dürfen, ist 512.
+ Nimmt <Sprungziel Nr.> einen Wert an, zu dem keine Zeile in der
+ Liste gefunden wird (z.B. Werte kleiner gleich null oder Werte größer
+ als die Anzahl der angegebenen Zeilennummern), so wird das Pro­
+ gramm mit der der ON-Anweisung folgenden Programmzeile fortge­
+ setzt.
+
+ Statt GOTO und GOSUB darf auch GO TO beziehungsweise
+ GO SUB geschrieben werden.
+
+Hinweis : Die ON-Anweisung muß in #on("ieiner#off("i Programmzeile stehen.
+
+
+Beispiel : 260 INPUT "Menüpunkt 1, 2 oder 3", a
+ 270 ON VAL (a) GOTO 300, 400, 500
+ 280 GOTO 260
+ 300 PRINT "Menüpunkt 1"
+ .
+ .
+ 400 PRINT "Menüpunkt 2"
+ .
+ .
+ 500 PRINT "Menüpunkt 3"
+
+
+ Entsprechend der Eingabe wird nach 300, 400 oder 500 verzweigt.
+ Bei Fehleingaben wird Zeile 280 ausgeführt.
+
+Vergleiche : GOSUB-, GOTO-, IF-Anweisungen
+
+
+
+Anweisung : OPTION BASE
+
+Zweck : Festlegung des kleinsten Wertes für Feldindizes
+
+Syntax : OPTION BASE 0|1
+
+Erklärung : OPTION BASE legt fest, ob die nachfolgend dimensionierten Felder
+ Elemente mit dem Index 0 erhalten, oder ob der niedrigste Index 1
+ ist. Voreingestellt ist OPTION BASE 0.
+
+Hinweis : Der niedrigste Feldindex kann für jedes Feld individuell eingestellt
+ werden. Die OPTION BASE-Anweisung gilt für alle Felder, deren
+ Dimensionierung ihr textuell nachfolgen. Eine erneute OPTION
+ BASE-Anweisung kann dann die Untergrenze für die #on("iihr#off("i folgenden
+ Dimensionierungen festlegen.
+
+
+Beispiel : 10 DIM a (100) 'Indizes 0-100
+ 20 OPTION BASE 1
+ 30 b$ (3) = "hallo" 'Indizes 1-10
+ 40 DIM a% (5) 'Indizes 1-5
+ 50 OPTION BASE 0
+ 60 DIM c% (9) 'Indizes 0-9
+ 70 LET d (4) = 12.3 'Indizes 0-10
+
+
+Vergleiche : DIM-Anweisung
+
+
+
+Operator : OR
+
+Siehe Kapitel 4.4. (Operatoren)
+
+
+
+Funktion : POS
+
+Zweck : Ermittlung der aktuellen Cursorspalte
+
+Syntax : POS (<num. Ausdruck>)
+
+Erklärung : Geliefert wird die Nummer der Spalte (als INT), in der sich der Cursor
+ auf dem Bildschirm befindet. Die Spalte ganz links hat die Num­
+ mer 1.
+ Der Argument-Ausdruck ist ein Dummy-Argument (hat keinen
+ Einfluß auf den gelieferten Wert).
+
+
+Beispiel : 10 CLS
+ 20 PRINT "testtext";
+ 30 PRINT POS (0)
+ Ausgabe: testtext 9
+
+
+Vergleiche : CSRLIN-, LPOS-Funktionen
+
+
+
+Anweisung : PRINT
+
+Zweck : Ausgabe auf den Bildschirm
+
+Syntax : PRINT [#ib(3)#USING#ie(3)# <Format> ;]
+ #right#[ #ib(3)#TAB#ie(3)# (<Spalte>) | , | ; | <Ausdruck> ] [...]
+
+Erklärung : <Format> : TEXT-Ausdruck für USING (s. u.)
+ <Spalte> : INT-Ausdruck (s. u.)
+ <Ausdruck>: TEXT-Ausdruck oder numerischer Ausdruck, der
+ ausgegeben werden soll.
+
+ PRINT dient der Ausgabe von Zeichen auf dem Bildschirm.
+ Numerische Werte werden mit sieben signifikanten Ziffer ausgege­
+ ben. Bei Exponentendarstellung werden für den Exponent maximal 3
+ Ziffern ausgegeben. Hinter allen numerischen Werten und vor posi­
+ tiven numerischen Werten wird jeweils ein Leerzeichen ausgegeben.
+
+ TAB bewirkt eine Positionierung des Cursors auf die angegebene
+ Spalte (die Spalte ganz links hat die Nummer 1). Ist die Spaltenzahl
+ größer als die mit WIDTH eingestellte Ausgabebreite, so wird auf die
+ Spalte mit der Nummer Spalte MODULO Ausgabebreite positioniert.
+ Eine Spaltennummer kleiner gleich null bewirkt eine entsprechende
+ Warnung.
+ Ist die Spalte mit der angegebenen Nummer in der aktuellen Zeile
+ bereits überschritten, dann wird auf die nächste Zeile positioniert.
+
+ Ein Semikolon bewirkt, daß der Cursor an der gerade erreichten
+ Position bleibt.
+
+ Ein Komma bewirkt die Positionierung auf die nächste gültige Spal­
+ te, für deren Nummer gilt: Nummer MODULO 16 ist 1.
+ Das Komma dient also der Ausgabe in 16 Zeichen breiten Zonen.
+
+ Endet die PRINT-Anweisung mit TAB (<Spalte>), einem Komma
+ oder einem Semikolon, dann wird kein Zeilenvorschub ausgelöst.
+
+ #onbold#USING
+ Der EUMEL-BASIC-Compiler unterstützt auch die PRINT
+ USING-Anweisung für formatierte Ausgaben.
+ Der nach dem Wort USING angegebene TEXT-Ausdruck spezifi­
+ ziert das Ausgabeformat für eine PRINT USING-Anweisung.
+
+ Formatierung von Texten:
+ "!": Nur das erste Zeichen einer Zeichenfolge wird ausgegeben
+ "\n Leerzeichen\": Es werden die 2 + n ersten Zeichen einer
+ Zeichenfolge ausgegeben
+ "&": Alle Zeichen einer Zeichenfolge werden ausgegeben
+
+ Formatierung von Zahlen:
+ "\#": bezeichnet eine Ziffernposition
+ ".": Position des Dezimalpunkts
+ "+": (vor oder nach Zahlen) Ausgabe des Vorzeichens
+ "-": (nach Zahlen) gegebenenfalls Ausgabe von "-" hinter der
+ Zahl
+ "**": Führende Leerstellen werden mit Sternchen aufgefüllt; wirkt
+ außerdem wie "\#\#".
+ "$$": Es wird ein Dollarzeichen links vor der formatierten Zahl ausgegeben;
+ wirkt außerdem wie "\#\#".
+ "**$": Führende Leerstellen werden mit Sternchen ausgefüllt und direkt vor
+ der formatierten Zahl wird ein Dollarzeichen ausgegeben; wirkt
+ außerdem wie "\#\#\#".
+ ",": (vor Dezimalpunkt) Unterteilung der Vorkommastellen in Dreier­
+ gruppen mittels Komma
+ "^^^^": Position des Exponenten
+ "_": Ein Zeichen, das einem Unterstreichungsstrich folgt, wird unverändert
+ ausgegeben
+
+ Ist der Format-Ausdruck fehlerhaft, so kommt es zum Fehler "USING-
+ Format fehlerhaft".
+ Überschreitet eine auszugebende Zahl in irgendeiner Hinsicht die im
+ Format-Ausdruck für sie vorgesehene Stellenzahl, so wird das Zeichen "%"
+ ausgegeben, um den Fehler anzuzeigen.
+
+
+Hinweis : 1. PRINT (und PRINT USING) richtet sich bei allen Ausgaben nach
+ der mit WIDTH eingestellten Ausgabebreite.
+ 2. Alle Ausgaben von PRINT können mit der Systemprozedur
+ 'sysout' in eine Datei umgeleitet werden. Dann wird nichts auf
+ das Terminal ausgegeben.
+ 3. Das Verhalten beim Erreichen der letzten Bildschirmzeile kann
+ mit der Prozedur 'basic page' gesteuert werden. Vergleiche
+ hierzu Kapitel 5, "Steuerung der Bildschirmausgabe".
+
+
+Beispiel : 10 PRINT "hallo", 2 ^ 32 TAB (33) "Ende";
+
+ Ausgabe: hallo 4.294967E+09 Ende
+ Position: 1234567890123456789012345678901234567890
+
+
+Vergleiche : WRITE-, LPRINT-Anweisungen, POS-, CSRLIN-, SPC-
+ Funktionen
+
+
+
+Anweisung : RANDOMIZE
+
+Zweck : Festlegung eines Anfangswertes für den Zufallszahlengenerator
+
+Syntax : RANDOMIZE [<num. Ausdruck>]
+
+Erklärung : Mit RANDOMIZE erhält der Zufallszahlengenerator einen bestimmten
+ Startwert.
+ Ist kein numerischer Ausdruck angegeben, so wird während des
+ Programmlaufs die Meldung "Startwert des Zufallszahlen­
+ generators ?" ausgegeben und ein Startwert eingelesen.
+
+ Wird der Zufallszahlengenerator immer mit dem gleichen Wert gestar­
+ tet, so liefert er auch immer die gleichen Zufallszahlen. Soll er immer
+ verschiedene Werte liefern, so kann er zum Beispiel mit der System­
+ uhr auf zufällige Startwerte gesetzt werden (RANDOMIZE TIMER).
+
+
+Beispiel : 10 RANDOMIZE 4711
+ 20 FOR i = 1 TO 5
+ 30 PRINT INT (RND * 10);
+ 40 NEXT i
+ Ausgabe: 5 6 2 9 6
+
+Vergleiche : RND-Funktion
+
+
+
+Anweisung : READ
+
+Zweck : Auslesen von Daten aus DATA-Anweisungen
+
+Syntax : READ <Variable> [, <Variable>] [...]
+
+Erklärung : <Variable>: numerische Variable oder TEXT-Variable
+
+ Die READ-Anweisung liest die nächsten Elemente aus der aktuellen
+ DATA-Anweisung (s.d.) in die angegebenen Variablen ein.
+
+ In TEXT-Variablen können sowohl "quoted strings" als auch "un­
+ quoted strings" (vgl. DATA-Anweisung) eingelesen werden.
+ In numerische Variablen können dagegen nur "unquoted strings"
+ eingelesen werden. Außerdem müssen die Zeichen des "unquoted
+ string" eine gültige Darstellung einer numerischen Konstanten (even­
+ tuell mit Vorzeichen) sein. Sind diese Bedingungen nicht erfüllt, so
+ kommt es bei der Ausführung des Programms zu entsprechenden
+ Fehlern.
+
+ Eine READ-Anweisung kann Daten aus vorangehenden und nach­
+ folgenden DATA-Anweisungen lesen.
+ Alle DATA-Anweisungen eines Programms bilden zusammen einen
+ großen sequentiellen Speicher, auf den mit READ der Reihe nach
+ zugegriffen wird. Intern wird ein sogenannter READ-DATA-Zeiger
+ geführt, der immer auf das nächste auszulesende Element zeigt.
+
+ Die RESTORE-Anweisung (s.d.) ermöglicht es, den READ-DATA-
+ Zeiger auf das erste Element einer bestimmten DATA-Zeile zu
+ setzen.
+
+ Sind keine Daten mehr für READ vorhanden, so wird die Ausführung
+ des Programms mit der Fehlermeldung "Keine Daten mehr für
+ READ" abgebrochen.
+
+
+Beispiel : 2020 PRINT "Stadt", "Land", "Fluß"
+ 2030 READ stadt$, land$, fluß$
+ 2040 PRINT stadt$, land$, fluß$
+ .
+ 5000 DATA Köln, Bundesrepublik Deutschland, Rhein
+
+
+Vergleiche : DATA-, RESTORE-Anweisungen
+
+
+
+Anweisung : REM
+
+Zweck : Ermöglicht das Einfügen von Kommentaren in ein Programm
+
+Syntax : REM <Zeichenfolge>
+
+Erklärung : <Zeichenfolge>: Beliebige Folge von Zeichen
+
+ Wird eine REM-Anweisung gefunden, so wird der Rest der Pro­
+ grammzeile nicht weiter beachtet. Die Compilierung wird in der fol­
+ genden Zeile fortgesetzt.
+ Es empfielt sich, von Kommentarzeilen möglichst oft Gebrauch zu
+ machen, weil sie den Programmtext dokumentieren und strukturieren.
+
+Hinweis : Nach REM können keine weiteren Anweisungen mehr in einer Pro­
+ grammzeile stehen, da sie nicht übersetzt werden. Auch der Doppel­
+ punkt wird nach REM nicht beachtet.
+
+
+Beispiel : 1000 REM Ausgabe des Feldes
+ 1010 FOR i = 1 TO feldgroesse%
+ 1020 PRINT "Eintrag"; i; feld (i)
+ 1030 NEXT i
+
+
+
+Anweisung : RESTORE
+
+Zweck : Setzen des READ-DATA-Zeigers auf den Anfang einer angegebe­
+ nen Zeile
+
+Syntax : RESTORE [<Zeilennummer>]
+
+Erklärung : <Zeilennummer>: INT-Konstante
+
+ Der READ-DATA-Zeiger (vgl. DATA-Anweisung) wird auf die Zeile
+ <Zeilennummer> gesetzt.
+ Wird keine Zeilennummer angegeben, so wird für <Zeilennummer>
+ 1 eingesetzt.
+
+ Existiert die Programmzeile <Zeilennummer> nicht oder ist in ihr
+ keine DATA-Anweisung vorhanden, so wird der Zeiger auf die
+ nächste textuell folgende DATA-Anweisung gesetzt.
+ Folgt der angegebenen Zeilennummer im Programm keine DATA-
+ Anweisung mehr, kommt es zu der Fehlermeldung "RESTORE: Keine
+ DATA-Anweisung in oder nach Zeile <Zeilennummer> gefunden !"
+
+
+Beispiel : 10 READ a, b, c
+ 20 RESTORE
+ 30 READ d, e, f
+ 40 DATA 2, 3, 5
+ 50 PRINT a; b; c; d; e; f
+ Ausgabe: 2 3 5 2 3 5
+
+Vergleiche : DATA-, READ-Anweisungen
+
+
+
+Anweisung : RETURN
+
+Zweck : Rücksprung aus einem Unterprogramm
+
+Syntax : RETURN
+
+Erklärung : RETURN bewirkt einen Rücksprung aus dem Unterprogramm hinter
+ die aufrufende GOSUB-Anweisung.
+
+ Es dürfen auch mehrere RETURN-Anweisungen in einem Unterpro­
+ gramm vorkommen, um es an verschiedenen Stellen zu verlassen.
+
+ Wird ein RETURN gefunden, ohne daß ein GOSUB durchlaufen
+ wurde, so wird mit der Fehlermeldung "RETURN ohne GOSUB"
+ abgebrochen.
+
+
+Beispiel : 140 GOSUB 10000 'Zeige Uhrzeit
+ .
+ .
+ 370 GOSUB 10000 'Zeige Uhrzeit
+ 9990 END
+ 10000 REM Unterprogramm Zeige Uhrzeit
+ 10010 PRINT "Es ist " + TIME$ + " Uhr"
+ 10020 RETURN
+
+
+Vergleiche : GOSUB-, ON-Anweisungen
+
+
+
+Funktion : RIGHT$
+
+Zweck : Erzeugung eines Teiltextes aus einem anderen Text
+
+Syntax : RIGHT$ (<TEXT-Ausdruck>, <Anzahl Zeichen>)
+Erklärung : <Anzahl Zeichen>: INT-Ausdruck
+
+ Die Funktion liefert die letzten <Anzahl Zeichen> Textzeichen des
+ TEXT-Ausdrucks.
+ Ist <Anzahl Zeichen> größer gleich der Länge des TEXT-
+ Ausdrucks, so wird der gesamte Ausdruck geliefert.
+
+
+Beispiel : 10 LET a$ = "hallihallo"
+ 20 PRINT RIGHT$ (a$, 5)
+ Ausgabe: hallo
+
+Vergleiche : LEFT$-, MID$-Funktionen, LSET-, MID$-, RSET-Anweisungen
+
+
+
+Funktion : RND
+
+Zweck : Erzeugung von Zufallszahlen
+
+Syntax : RND [<num. Ausdruck>]
+
+Erklärung : Wird kein Argument angegeben, so wird ein Wert größer null für den
+ Ausdruck angenommen.
+
+ RND (x) liefert
+
+ für x > 0:
+ eine neue Zufallszahl. Es gilt immer: 0 <= RND < 1. Der Betrag
+ des Arguments hat keinen Einfluß auf das Ergebnis.
+
+ für x = 0:
+ die letzte gelieferte Zufallszahl noch einmal.
+
+ für x < 0:
+ eine neue Zufallszahl. Vorher wird aber RANDOMIZE x (s.d.) ausge­
+ führt.
+
+ Die Zufallszahlen werden als REALs geliefert.
+ Der Zufallszahlengenerator kann mit der RANDOMIZE-Anweisung
+ auf bestimmte Startwerte eingestellt werden.
+
+
+Beispiel : 10 FOR i = 1 TO 5
+ 20 PRINT INT (RND * 10)
+ 30 NEXT i
+ Ausgabe (z.B.): 7 9 9 5 0
+
+Vergleiche : RANDOMIZE-Anweisung
+
+
+
+Anweisung : RSET
+
+Zweck : Ersetzen von Zeichen eines Textes von rechts her
+
+Syntax : RSET <TEXT-Variable> = <TEXT-Ausdruck>
+
+Erklärung : Das Ergebnis des TEXT-Ausdrucks wird, rechts beginnend, in der
+ TEXT-Variablen eingesetzt. Es werden höchstens so viele Zeichen
+ ersetzt, wie bisher schon in der Variablen vorhanden waren, das heißt
+ die Länge des Textes in der Variablen ändert sich nicht.
+ Soll ein Text eingesetzt werden, der länger ist als der Text in der
+ Variablen, so wird die Variable nicht verändert.
+
+
+Beispiel : 210 LET a$ = "ABCDEFG"
+ 220 RSET a$ = "12345"
+ 230 PRINT a$,
+ 240 RSET a$ = "abc"
+ 250 PRINT a$
+ Ausgabe: AB12345 AB12abc
+
+Vergleiche : LSET-, MID$-Anweisungen, LEFT$-, MID$-, RIGHT$-Funk­
+ tionen
+
+
+
+Funktion : SGN
+
+Zweck : Ermittlung des Vorzeichens einer Zahl
+
+Syntax : SGN (<num. Ausdruck>)
+
+Erklärung : SGN (x) liefert
+ für x > 0: 1
+ für x = 0: 0
+ für x < 0: -1 .
+
+
+Beispiel : 10 a = -12.74
+ 20 PRINT SGN (a); SGN (-a); SGN (0 * a)
+ Ausgabe: -1 1 0
+
+Vergleiche : ABS-Funktion
+
+
+
+Funktion : SIN
+
+Zweck : Berechnung des Sinus eines Radiantwertes
+
+Syntax : SIN (<Winkel>)
+
+Erklärung : <Winkel>: REAL-Ausdruck, der den Winkel in Radiant angibt.
+ Die Funktion liefert den Sinus des Winkels als REAL.
+
+
+Beispiel : 10 PI = 3.141593
+ 20 PRINT SIN (PI/4)
+ Ausgabe: .7071068
+
+Vergleiche : COS-, TAN-Funktionen
+
+
+
+Funktion : SPACE$
+
+Zweck : Erzeugung einer bestimmten Anzahl von Leerzeichen
+
+Syntax : SPACE$ (<INT-Ausdruck>)
+
+Erklärung : Die SPACE$-Funktion liefert einen TEXT, der aus so vielen Leerzei­
+ chen (Code 32) besteht, wie der Wert des INT-Ausdrucks angibt.
+
+
+Beispiel : 10 PRINT "123456789"
+ 20 PRINT "^" + SPACE$ (7) + "^"
+
+ Ausgabe: 123456789
+ ^ ^
+
+
+Vergleiche : STRING$-Funktion
+
+
+
+Funktion : SPC
+
+Diese Funktion entspricht exakt der SPACE$-Funktion und wurde nur aus Kompatibi­
+litätsgründen implementiert.
+
+
+
+Funktion : SQR
+
+Zweck : Berechnung der Quadratwurzel einer Zahl
+
+Syntax : SQR (<num. Ausdruck>)
+
+Erklärung : SQR (x) liefert die Quadratwurzel des durch den numerischen Aus­
+ druck angegebenen Wertes.
+ Das Ergebnis wird als REAL geliefert.
+
+
+Beispiel : 10 PRINT SQR (100);
+ 20 PRINT SQR (2);
+ 30 PRINT SQR (17.453)
+ Ausgabe: 10 1.414214 4.177679
+
+
+
+Anweisungsbestandteil : STEP
+
+Siehe FOR-Anweisung
+
+
+
+Anweisung : STOP
+
+Zweck : Beenden der Programmausführung eines BASIC-Programms mit
+ Meldung
+
+Syntax : STOP
+
+Erklärung : STOP beendet die Programmausführung des BASIC-Programms.
+ Im Gegensatz zu END (s.d.) erzeugt STOP dabei die Meldung "STOP
+ beendet das Programm in Zeile ...".
+
+ STOP-Anweisungen dürfen im Programm an beliebiger Stelle
+ stehen, und es darf auch mehr als eine STOP-Anweisung in einem
+ Programm vorkommen.
+ Der Compiler übersetzt ein Programm auch nach Erreichen einer
+ STOP-Anweisung weiter.
+
+
+Beispiel : 3220 IF eingabe$ = "Ende" THEN STOP
+
+
+Vergleiche : END-Anweisung
+
+
+
+Funktion : STR$
+
+Zweck : Konvertierung einer Zahl in einen Text
+
+Syntax : STR$ (<num. Ausdruck>)
+
+Erklärung : Die Funktion liefert die Darstellung des Wertes des numerischen
+ Ausdrucks als TEXT.
+ Die Zahlen werden so als Text geliefert, wie sie bei einer PRINT-
+ Anweisung auf dem Bildschirm erscheinen würden.
+
+
+Beispiel : 10 LET zahl$ = STR$ (1e6)
+ 20 PRINT zahl$; LEN (zahl$)
+ Ausgabe: 1000000 7
+
+Vergleiche : VAL-Funktion (Komplementärfunktion)
+
+
+
+Funktion : STRING$
+
+Zweck : Erzeugung eines Textes mit mehreren gleichen Zeichen
+
+Syntax : STRING$ (<Anzahl>, <Code>|<TEXT-Ausdruck>)
+
+Erklärung : <Anzahl>: INT-Ausdruck
+ <Code> : INT-Ausdruck (Wert im Bereich 0 bis 255)
+
+ Die Funktion liefert <Anzahl> mal das Zeichen,
+ - das den ASCII-Code <Code> hat oder
+ - das am Anfang vom Ergebnis des TEXT-Ausdrucks steht.
+
+
+Beispiel : 10 LET pfeil$ = STRING$ (10, "=") + ">"
+ 20 PRINT pfeil$;" ";STRING$ (5, 35) '35 entspr. \#
+ Ausgabe: ==========> \#\#\#\#\#
+
+Vergleiche : SPACE$-Funktion
+
+
+
+Anweisungsbestandteil : SUB
+
+Siehe GOSUB-Anweisung
+
+
+
+Anweisung : SWAP
+
+Zweck : Tauschen der Inhalte zweier Variablen
+
+Syntax : SWAP <Variable1>, <Variable2>
+
+Erklärung : SWAP tauscht die Inhalte der beiden Variablen.
+
+ Die beiden Variablen müssen vom gleichen Typ sein.
+
+
+Beispiel : 3220 LET a = 10
+ 3230 LET b = 20
+ 3240 SWAP a, b
+ 3250 PRINT a; b
+ Ausgabe: 20 10
+
+
+
+Anweisungsbestandteil : TAB
+
+Siehe PRINT- und LPRINT-Anweisung
+
+
+
+Funktion : TAN
+
+Zweck : Berechnung des Tangens eines Radiantwertes
+
+Syntax : TAN (<Winkel>)
+
+Erklärung : <Winkel>: REAL-Ausdruck, der den Winkel in Radiant angibt.
+ Die Funktion liefert den Tangens des Winkels als REAL.
+
+
+Beispiel : 10 PI = 3.141593
+ 20 PRINT TAN (PI/4)
+ Ausgabe: 1
+
+Vergleiche : COS-, SIN-Funktionen
+
+
+
+Anweisungsbestandteil : THEN
+
+Siehe IF-Anweisung
+
+
+
+Funktion : TIMER
+
+Zweck : Lesen der Systemuhr (CPU-Zeit der Task)
+
+Syntax : TIMER
+
+Erklärung : Die bisher von der Task verbrauchte CPU-Zeit (in Sekunden) wird
+ als REAL geliefert.
+
+ TIMER eignet sich auch zum Starten des Zufallszahlengenerators
+ (vgl. RANDOMIZE-Anweisung).
+
+
+Beispiel : 2010 LET starttime = TIMER
+ .
+ .
+ 2620 PRINT "Verbrauchte CPU-Zeit:";
+ 2630 PRINT TIMER - starttime; "Sekunden"
+
+
+Vergleiche : TIME$-Funktion
+
+
+
+Funktion : TIME$
+
+Zweck : Abrufen der aktuellen Tageszeit
+
+Syntax : TIME$
+
+Erklärung : Die Tageszeit wird als Text in der Form HH.MM.SS geliefert.
+
+
+Beispiel : 10 PRINT "Es ist jetzt "; TIME$; " Uhr"
+ Ausgabe (z.B.): Es ist jetzt 10:51:17 Uhr
+
+Vergleiche : DATE$-, TIMER-Funktionen
+
+
+
+Anweisungsbestandteil : TO
+
+Siehe FOR- und GOTO-Anweisungen
+
+
+
+Anweisung : TRON / TROFF
+
+Zweck : Ein- und Ausschalten der TRACE-Funktion
+
+Syntax : TRON
+ TROFF
+
+Erklärung : Der TRACE-Modus dient der Suche nach logischen Fehlern bei der
+ Entwicklung von BASIC-Programmen.
+
+ TRON schaltet den TRACE-Modus für die nachfolgend übersetzten
+ Programmzeilen ein.
+
+ Ist der TRACE-Modus eingeschaltet, so wird für jede gefundene
+ Zeilennummer die Ausgabe dieser Zeilennummer in eckigen
+ Klammern mit in den erzeugten Code aufgenommen. Dies hat dann
+ während des Laufens den Effekt, daß immer bei Abarbeitung der im
+ TRACE-Modus übersetzten Zeilen die aktuelle Zeilennummer aus­
+ gegeben wird. Es ist so leicht zu verfolgen, in welcher Reihenfolge
+ die Zeilen des Programms ausgeführt werden.
+
+ TROFF schaltet den TRACE-Modus für die textuell folgenden Pro­
+ grammzeilen wieder aus.
+
+
+Beispiel : 5220 TRON
+ 5230 REM hier beginnt die kritische
+ 5240 REM Programmstelle
+ .
+ .
+ .
+ 5970 TROFF
+
+
+ Die Zeilen 5230 bis 5970 werden im TRACE-Modus übersetzt.
+
+
+
+Anweisungsbestandteil : USING
+
+Siehe PRINT-Anweisung
+
+
+
+Funktion : USR
+
+Zweck : Aufruf einer wertliefernden insertierten Prozedur
+
+Syntax : USR <Prozedurname>
+ #right#[ (<Parameter> [, <Parameter>] [...] ) ]
+
+Erklärung : <Prozedurname>: Folge aus Zeichen, die für Prozeduren im
+ EUMEL-System zugelassen sind (also Buchstaben und - ab der
+ zweiten Stelle - Zahlen), jedoch keine Leerzeichen.
+
+ <Parameter>: <CONST-Parameter> | <VAR-Parameter>
+
+ <CONST-Parameter>: Ausdruck (genau des von der Prozedur
+ benötigten Typs)
+ <VAR-Parameter>: Variable (genau des von der Prozedur benö­
+ tigten Typs)
+
+ Die Prozedur mit dem angegebenen <Prozedurnamen> und den
+ angegebenen Parametern wird aufgerufen.
+ Die USR-Funktion liefert nach Ausführung der Prozedur das von der
+ Prozedur übergebene Ergebnis (Typ INT, REAL oder TEXT).
+
+ Mögliche Fehlerfälle:
+ - Eine Prozedur mit dem Namen <Prozedurnamen> und den ange­
+ gebenen Parametern gibt es nicht.
+ - Die Prozedur liefert keinen Wert.
+ - Die Prozedur liefert einen Typ, der in BASIC unbekannt ist (zum
+ Beispiel BOOL).
+ - Die Prozedur benötigt Parametertypen, die in BASIC nicht bekannt
+ sind (z.B. BOOL, FILE, TASK, QUIET).
+ - Ein Parameter ist CONST, es wird aber ein VAR-Parameter ver­
+ langt.
+
+ Weitere Informationen finden Sie in Kapitel 4.7.
+
+Hinweis : 1. Bei den Parametern wird keine Typkonvertierung vorgenommen.
+ 2. Der Prozedurname muß (entgegen der ELAN-Gewohnheit) ohne
+ Leerzeichen angegeben werden.
+ 3. USR ist die einzige Funktion, bei der das Argument (nämlich der
+ Prozeduraufruf) nicht in Klammern stehen darf.
+
+
+Beispiel : 10 LET euler = USR e
+ 20 PRINT euler
+ Ausgabe: 2.718282
+
+Vergleiche : CALL-, CHAIN-Anweisungen
+
+
+
+Funktion : VAL
+
+Zweck : Konvertierung eines Texts in eine Zahl
+
+Syntax : VAL (<TEXT-Ausdruck>)
+
+Erklärung : Die Funktion liefert den Wert der Zahl, deren Darstellung in dem
+ übergebenen TEXT-Ausdruck enthalten ist. Führende Leerstellen
+ werden dabei überlesen.
+ Sobald ein nicht wandelbares Zeichen festgestellt wird, wird der bis
+ dahin ermittelte Wert (am Anfang null) geliefert.
+
+
+Beispiel : 10 LET zahl$ = "-1.256E-63"
+ 20 PRINT VAL (zahl$)
+ Ausgabe: -1.256E-63
+
+Vergleiche : STR$-Funktion (Komplementärfunktion)
+
+
+
+Anweisung : WEND
+
+Zweck : Markierung des Endes einer WHILE-Schleife
+
+Syntax : WEND
+
+Erklärung : WEND markiert das Ende einer WHILE-Schleife (vergleiche
+ WHILE-Anweisung).
+
+Vergleiche : WHILE-, FOR-Anweisungen
+
+
+
+Anweisung : WHILE
+
+Zweck : Beginn einer abweisenden Schleife
+
+Syntax : WHILE <Bedingung>
+ <Schleifenrumpf>
+
+Erklärung : <Bedingung> : numerischer Ausdruck
+ <Schleifenrumpf>: Folge von Programmzeilen
+
+ Die WHILE-Anweisung erlaubt die komfortable Programmierung von
+ abweisenden Schleifen (sogenannten WHILE-WEND-Schleifen) in
+ BASIC.
+ Gelangt das Programm während der Ausführung an eine WHILE-
+ Anweisung, so wird zunächst der Bedingungs-Ausdruck ausge­
+ wertet. Ist die Bedingung nicht erfüllt (falsch, Wert gleich null), so
+ wird das Programm mit der nächsten Anweisung hinter der korres­
+ pondierenden WEND-Anweisung fortgesetzt.
+ Ist die Bedingung dagegen erfüllt (wahr, Wert ungleich null), so
+ werden die Anweisungen des Schleifenrumpfs abgearbeitet. Beim
+ Erreichen der WEND-Anweisung springt das Programm wieder zur
+ WHILE-Anweisung zurück, die Bedingung wird erneut überprüft und,
+ je nach Ergebnis, wird der Schleifenrumpf oder die Anweisung nach
+ WEND ausgeführt.
+
+ WHILE-WEND-Schleifen dürfen (auch mit FOR-NEXT-Schleifen,
+ s.d.) geschachtelt werden. Überschneidungen von WHILE-WEND-
+ Schleifen und FOR-NEXT-Schleifen sind jedoch nicht zulässig.
+
+
+Beispiel : 10 LET weiter$ = "j"
+ 20 WHILE LEFT$ (weiter$, 1) = "j"
+ 30 REM Hier beginnt das eigentliche Programm
+ .
+ .
+ 1650 INPUT "Weiter ? (j/n)", weiter$
+ 1660 WEND
+
+
+ Das eigentliche Programm wird so lange ausgeführt, bis der Benutzer
+ etwas anderes als "j" an der ersten Stelle von 'weiter$' eingibt.
+
+Vergleiche : FOR-, IF-Anweisungen
+
+
+
+Anweisung : WIDTH
+
+Zweck : Einstellung der Bildschirmbreite
+
+Syntax : WIDTH <Zeichen pro Zeile>
+
+Erklärung : <Zeichen pro Zeile> : INT-Ausdruck
+
+ Mit der WIDTH-Anweisung wird festgelegt, wie viele Zeichen pro
+ Zeile bei Ausgaben auf den Bildschirm oder in Dateien pro Zeile
+ ausgegeben werden sollen.
+ Soll für die Druckdatei eine andere Anzahl von Zeichen pro Zeile
+ gelten als für den Bildschirm, dann muß vor jeder Sequenz von
+ LPRINT-Anweisungen die gewünschte Anzahl mit WIDTH einge­
+ stellt werden.
+ WIDTH gilt auch für Ausgaben in 'sysout'-Dateien.
+ Insbesondere bei der Ausgabe in Dateien kann ein Wert von mehr als
+ 80 Zeichen pro Zeile sinnvoll sein.
+
+
+Beispiel : 10 REM es sollen nur 45 Zeichen pro Zeile
+ 20 REM ausgegeben werden
+ 30 WIDTH 45
+
+
+Vergleiche : PRINT-, LPRINT-, WRITE-Anweisungen
+
+
+
+Anweisung : WRITE
+
+Zweck : Ausgabe von Zahlen und Texten auf dem Bildschirm
+
+Syntax : WRITE [<Ausdruck>] [, <Ausdruck>] [...]
+
+Erklärung : <Ausdruck>: numerischer Ausdruck oder TEXT-Ausdruck
+
+ Die WRITE-Anweisung erlaubt die Ausgabe von Daten auf dem
+ Bildschirm. Die angegebenen Ausdrücke werden ausgewertet und
+ ausgegeben. Dabei werden numerische Werte im gleichen Format
+ wie bei der PRINT-Anweisung (s.d.) ausgegeben, mit der Einschrän­
+ kung, daß den Zahlen keine Leerstelle folgt.
+ Die Ergebnisse von Text-Ausdrücken werden von Anführungszei­
+ chen umschlossen ausgegeben.
+ Alle Einzelausgaben werden durch Kommata voneinander getrennt.
+
+ Nach Ausgabe aller angegebenen Ausdrücke wird der Cursor an den
+ Anfang der nächsten Zeile positioniert.
+
+
+Beispiel : 10 LET a = 10.7: b = 20
+ 20 LET c$ = "Testtext"
+ 30 WRITE a, b, c$
+ Ausgabe: 10.7, 20,"Testtext"
+
+Vergleiche : PRINT-, LPRINT-, WIDTH-Anweisungen
+
+
+
+Operator : XOR
+
+Siehe Kapitel 4.4. (Operatoren)
+
diff --git a/doc/basic/basic handbuch.3 b/doc/basic/basic handbuch.3
new file mode 100644
index 0000000..14cb499
--- /dev/null
+++ b/doc/basic/basic handbuch.3
@@ -0,0 +1,698 @@
+#page nr ("%",97)#
+#head#
+EUMEL-BASIC-Compiler 9. Anpassung von Programmen an den EUMEL-BASIC-Compiler %
+
+#end#
+
+9. Anpassung von Programmen an den EUMEL-BASIC-Compiler
+
+
+9.1. Unterschiede zwischen BASIC-Inter­
+ pretern und dem EUMEL-BASIC-
+ Compiler
+
+Bei der Anpassung von Programmen für BASIC-Interpreter an den EUMEL-
+BASIC-Compiler gibt es einige Besonderheiten zu beachten, die auf den unterschied­
+lichen Arbeitsweisen von Compilern gegenüber Interpretern beruhen.
+Bei Interpretern fällt die Übersetzung und Ausführung des Quellprogramms zeitlich
+zusammen (genau genommen gibt es ja gar keine Übersetzung, sondern das Quell­
+programm wird #on("i")#interpretiert#off("i")#). Dies hat zur Folge, daß auch nicht zur Ausführung
+bestimmte Anweisungen (z.B. Dimensionierungen, Typfestlegungen etc.) erst während
+der Ausführung des Programms erkannt und ausgewertet werden.
+Bei Compilern hingegen muß deutlich zwischen der Übersetzungszeit (Compiletime)
+und der Laufzeit (Runtime) eines Programms unterschieden werden.
+Der wesentliche Unterschied zwischen Compilern und Interpretern liegt nun in der
+Reihenfolge der Kenntnisnahme von den Anweisungen. Während der Interpreter von
+den Anweisungen in der Reihenfolge ihres Auftretens entlang des Programmablaufs
+Kenntnis nimmt, werden die Anweisungen vom Compiler in der Reihenfolge ihres
+textuellen Auftretens zur Kenntnis genommen.
+Da es sich bei dem EUMEL-BASIC-Compiler um einen One-Pass-Compiler
+handelt, ist es zwingend notwendig, daß
+- DIM-Anweisungen vor dem ersten Zugriff auf das zu dimensionierende Feld
+ stehen.
+- OPTION BASE-Anweisungen vor den betreffenden Dimensionierungen stehen.
+- DEF FN-Anweisungen vor dem ersten Aufruf der zu definierenden Funktion ste­
+ hen.
+- DEFINT- beziehungsweise DEFSTR-Anweisungen vor der ersten Verwendung der
+ betreffenden Variablen erscheinen.
+
+Einige Interpreter lassen sogar den Abschluß von FOR-NEXT- und WHILE-
+WEND-Schleifen an mehreren Stellen im Programm zu (z.B. mehrere NEXT-
+Anweisungen zu einer FOR-Anweisung). Auch solche "Kunstgriffe" gestattet der
+EUMEL-BASIC-Compiler (aus den oben geschilderten Gründen) nicht.
+
+
+
+
+9.2. Abweichungen von ISO 6373-1984
+ (Minimal-BASIC)
+
+
+
+Der EUMEL-BASIC-Compiler weicht in folgenden Punkten von der ISO-Norm
+6373-1984 für Minimal-BASIC ab:
+- Treten bei der Auswertung von numerischen Ausdrücken Überläufe auf, so wird
+ nicht, wie im Standard vorgesehen, eine Warnung ausgegeben und mit bestimmten
+ Höchstwerten weitergerechnet, sondern die Ausführung des BASIC-Programms
+ wird mit einer entsprechenden Fehlermeldung abgebrochen.
+- Nimmt die Sprungziel-Nummer bei der ON-Anweisung einen fehlerhaften Wert an
+ (Nummer < 1 oder Nummer > Anzahl Sprungziele), dann wird nicht, wie im
+ Standard empfohlen, mit einer Fehlermeldung abgebrochen, sondern es wird (wie
+ auch in Microsoft-BASIC üblich) das Programm mit der der ON-Anweisung fol­
+ genden Anweisung fortgesetzt.
+- Bei der DATA-Anweisung müssen nicht unbedingt Zeichenfolgen angegeben
+ werden. Werden sie weggelassen, dann wird bei Ausführung der READ-
+ Anweisung null beziehungsweise Leertext geliefert (vergleiche Kapitel 8, DATA-
+ Anweisung).
+- Bei den Eingaben für eine INPUT-Anweisung können ebenfalls die Daten wegge­
+ lassen werden. Auch hier wird null beziehungsweise Leertext geliefert (vergleiche
+ Kapitel 8, INPUT-Anweisung)
+
+
+Die Erweiterungen gegenüber ISO 6373 sollen hier nicht im einzelnen aufgeführt
+werden. Bitte vergleichen Sie in Zweifelsfällen die Normungsschrift mit dieser Doku­
+mentation!
+
+
+
+
+9.3. Anpassung von Microsoft-BASIC Pro­
+ grammen an den EUMEL-BASIC-
+ Compiler
+
+
+
+Bei der Entwicklung des EUMEL-BASIC-Compilers wurde zwar auf Übereinstim­
+mung mit Microsoft-BASIC Wert gelegt, von einer echten Kompatibilität kann aber
+aufgrund einer ganzen Reihe fehlender Anweisungen und Funktionen nicht gespro­
+chen werden.
+Gegenüber Microsoft-BASIC fehlen vor allem:
+- alle "Direkt-Kommandos" (RUN, LIST, LOAD, SAVE, MERGE usw.). Die Aufgaben
+ dieser Anweisungen werden von den Prozeduren des EUMEL-Systems über­
+ nommen.
+- im weiteren Sinne "hardware-nahe" oder an Maschinensprache orientierte Anwei­
+ sungen und Funktionen (CALL, PEEK, POKE, USR, WAIT usw.)
+- die ERROR-Handling Anweisungen (ON ERROR, RESUME)
+- die Dateiverarbeitungs-Anweisungen und -Funktion (INPUT\#, PRINT\# u.a.; die
+ INPUT- und PRINT-Anweisungen wurden aber auf Zusammenarbeit mit 'sysin'
+ und 'sysout' abgestimmt.)
+- die Single-Precision-Variablen (Single- und Double-Precision-Variablen wer­
+ den beide auf den Datentyp REAL abgebildet.)
+- die hexadezimalen und oktalen Konstanten
+
+Anweisungen und Funktionen, die sich abweichend vom Microsoft-Standard verhal­
+ten, sind vor allem:
+- CALL, CHAIN, USR
+- ERROR, ERR, ERL
+- LSET, RSET
+
+Wichtige Erweiterungen gegenüber Microsoft-BASIC sind:
+- Möglichkeit des Aufrufs von ELAN-Prozeduren
+- Maximale Anzahl von Zeichen pro Zeile: 32000
+- Maximale Anzahl von Zeichen pro TEXT-Objekt: 32000
+- OPTION BASE wirkt auf einzelne Felder (und nicht unbedingt auf ein ganzes
+ Programm)
+
+#on ("b")#
+Hinweis zur Verwendung von MS-BASIC-Programmen im EUMEL-System#off ("b")#
+Sollen Microsoft-BASIC-Programme in das EUMEL-Systemm übernommen wer­
+den, so ist dabei so vorzugehen:
+1. Speichern Sie das Programm von MS-BASIC aus mit der ASCII-SAVE-Option
+ ab.
+ Beispiel: SAVE "PROGRAMM.BAS",A
+2. Lesen Sie das Programm mittels "DOSDAT" (Programm zum Lesen von MS-
+ DOS-Dateien) im "file ascii"-Modus ein:
+
+ reserve ("file ascii", /"DOS"); fetch ("PROGRAMM.BAS", /"DOS")
+
+Danach steht ihnen das BASIC-Program in der EUMEL-Textdatei
+"PROGRAMM.BAS" zur Verfügung.
+
+#page#
+#head#
+EUMEL-BASIC-Compiler Anhang A: Reservierte Wörter %
+
+#end#
+
+Anhang A: #ib(4)#Reservierte Wörter#ie(4)#
+Dieser Anhang enthält eine Übersicht über alle vom EUMEL-BASIC-Compiler
+erkannten reservierten Wörter.
+
+ABS Funktion
+AND Operator
+AS Anweisungsbestandteil
+ASC Funktion
+ATN Funktion
+BASE Anweisungsbestandteil
+CALL Anweisung
+CDBL Funktion
+CHAIN Anweisung
+CHR$ Funktion
+CINT Funktion
+CLEAR nicht implementiert
+CLOSE nicht implementiert
+CLS Anweisung
+COMMON nicht implementiert
+FIELD nicht implementiert
+COS Funktion
+CSRLIN Funktion
+CVD Funktion
+CVI Funktion
+DATA Anweisung
+DATE$ Funktion
+DEF Anweisung
+DEFDBL Anweisung
+DEFINT Anweisung
+DEFSNG Anweisung
+DEFSTR Anweisung
+DIM Anweisung
+ELSE Anweisungsbestandteil
+END Anweisung
+EOF Anweisungsbestandteil
+EQV Operator
+ERL Funktion
+ERM$ Funktion
+ERR Funktion
+ERROR Anweisung
+EXP Funktion
+FIX Funktion
+FOR Anweisung
+FRE Funktion
+GET nicht implementiert
+GO Anweisungsbestandteil
+GOSUB Anweisung
+GOTO Anweisung
+HEX$ Funktion
+IF Anweisung
+IMP Operator
+INKEY$ Funktion
+INPUT Anweisung
+INPUT$ Funktion
+INSTR Funktion
+INT Funktion
+KILL Anweisung
+LEFT$ Funktion
+LEN Funktion
+LET Anweisung
+LINE Anweisungsbestandteil
+LOC nicht implementiert
+LOG Funktion
+LPOS Funktion
+LPRINT Anweisung
+LSET Anweisung
+MID$ Anweisung/Funktion
+MKD$ Funktion
+MKI$ Funktion
+MOD Operator
+NAME Anweisung
+NEXT Anweisung
+NOT Operator
+OCT$ Funktion
+ON Anweisung
+OPEN nicht implementiert
+OPTION Anweisung
+OR Operator
+OUT nicht implementiert
+POS Funktion
+PRINT Anweisung
+PUT nicht implementiert
+RANDOMIZE Anweisung
+READ Anweisung
+REM Anweisung
+RESTORE Anweisung
+RESUME nicht implementiert
+RETURN Anweisung
+RIGHT$ Funktion
+RND Funktion
+RSET Anweisung
+SGN Funktion
+SIN Funktion
+SPACE$ Funktion
+SPC Funktion
+SQR Funktion
+STEP Anweisungsbestandteil
+STOP Anweisung
+STR$ Funktion
+STRING$ Funktion
+SUB Anweisungsbestandteil
+SWAP Anweisung
+TAB Anweisungsbestandteil
+TAN Funktion
+THEN Anweisungsbestandteil
+TIME$ Funktion
+TIMER Funktion
+TO Anweisungsbestandteil
+TROFF Anweisung
+TRON Anweisung
+USING Anweisungsbestandteil
+USR Funktion
+VAL Funktion
+WAIT nicht implementiert
+WEND Anweisung
+WHILE Anweisung
+WIDTH Anweisung
+WRITE Anweisung
+XOR Operator
+#page#
+#head#
+EUMEL-BASIC-Compiler Anhang B: Vom Scanner erkannte Symboltypen %
+
+#end#
+
+Anhang B: Vom #ib(3)#Scanner#ie(3)# erkannte #ib(3)#Symbol­
+typen#ie(3)#
+
+ Der Scanner (ein Paket des EUMEL-BASIC-Systems) hat die Aufgabe, den Pro­
+grammtext Zeichen für Zeichen durchzugehen und auszulesen ('scannen'). Dabei
+werden die Zeichen immer zu logischen Gruppen, sogenannten #on("i")#Symbolen#off("i")# zusammen­
+gefaßt. Diese Symbole werden dann dem eigentlichen Compilerprogramm geliefert.
+Der Scanner entscheidet nach recht komplizierten Regeln, welche Zeichen aus der
+Quelldatei zu einem Symbol zusammengefaßt werden. Dennoch soll in diesem An­
+hang der Begriff des Symbols etwas näher erklärt werden, da der Anwender (vor allem
+bei den Fehlermeldungen) mit Symboltypen konfrontiert wird.
+
+
+
+Reservierte Wörter
+#on ("b")#
+Anfangszeichen:#off ("b")# Buchstaben
+#on ("b")#
+Folgezeichen:#off ("b")# Buchstaben
+#on ("b")#
+Beispiele:#off ("b")# PRINT, VAL, TAB, SUB, TO
+#on ("b")#
+Vergleiche:#off ("b")# Anhang A
+
+
+
+Operatoren
++ - * / \ ^ MOD
+NOT AND OR XOR EQV IMP
+< > = <= >= <>
+
+#on ("b")#
+Vergleiche:#off ("b")# Kapitel 4.4.
+
+
+
+numerische Konstanten
+#on ("b")#
+Anfangszeichen:#off ("b")# Ziffern 0 bis 9, Dezimalpunkt '.'
+#on ("b")#
+Folgezeichen:#off ("b")# zusätzlich: 'd', 'D', 'e' oder 'E', am Schluß auch '%', '!' oder '\#'
+#on ("b")#
+Beispiele:#off ("b")# 1.0, 1.256d123, 12!
+#on ("b")#
+Vergleiche:#off ("b")# Kapitel 4.2.
+
+
+
+TEXT-Konstanten
+#on ("b")#
+Anfangszeichen:#off ("b")# Anführungszeichen
+#on ("b")#
+Folgezeichen:#off ("b")# Alle Zeichen, sogar Doppelpunkte, Apostrophe und Steuerzei­
+ chen. Anführungszeichen dürfen #on("i")#innerhalb#off("i")# von
+ TEXT-Konstanten nicht vorkommen. Eine
+ TEXT-Konstante #on("i")#muß#off("i")# aber mit einem Anfüh­
+ rungszeichen enden.
+#on ("b")#
+Beispiele:#off ("b")# "tadellos", "!?': alles mögliche"
+#on ("b")#
+Vergleiche:#off ("b")# Kapitel 4.2.
+
+
+
+Variablen
+#on ("b")#
+Anfangszeichen:#off ("b")# Buchstaben
+#on ("b")#
+Folgezeichen:#off ("b")# zusätzlich: Punkt '.', Ziffern 0 bis 9, Zeichen '$', '%', '!' und '\#'
+#on ("b")#
+Beispiele:#off ("b")# zeiger, A$, Zahl!, n%, var\#4.3%
+#on ("b")#
+Vergleiche:#off ("b")# Kapitel 4.3.
+
+
+
+Felder/Feldelemente
+wie Variablen, jedoch gefolgt von '(', den Indexangaben und ')'
+#on ("b")#
+Beispiele:#off ("b")# zeiger (3), A$ (pointer), Zahl! (7), n% (a, b, c + d)
+#on ("b")#
+Vergleiche:#off ("b")# Kapitel 4.3.
+
+
+
+Benutzer-definierte Funktionen
+#on ("b")#
+Anfangszeichen:#off ("b")# FN
+#on ("b")#
+Folgezeichen:#off ("b")# Buchstaben, Punkt '.', Ziffern 0 bis 9,
+ Zeichen '$', '%', '!' und '\#'
+#on ("b")#
+Beispiele:#off ("b")# FNfunct, FNgauss%, FNf!4.5.6d\#
+#on ("b")#
+Vergleiche:#off ("b")# Kapitel 4.5.
+
+
+
+EOS (End of Statement, Anweisungsende)
+Doppelpunkt ':'
+
+#on ("b")#
+Vergleiche:#off ("b")# Kapitel 4.1.
+
+
+
+EOL (End of Line, Zeilenende)
+Apostrophzeichen ' oder Ende der Dateizeile
+EOL bedeutet gleichzeitig auch EOS
+
+#on ("b")#
+Vergleiche:#off ("b")# Kapitel 4.1.
+
+
+
+EOF (End of File, Dateiende)
+Ende der Quelldatei
+EOF bedeutet gleichzeitig auch EOL (und somit auch EOS)
+
+#on ("b")#
+Vergleiche:#off ("b")# Kapitel 4.1.
+
+
+
+Trennzeichen
+Alle bisher nicht genannten Zeichen werden vom Scanner als Trennzeichen behan­
+delt. In BASIC benötigte Trennzeichen sind das Komma (','), das Semikolon (';') sowie
+die beiden runden Klammern '(' und ')'.
+Zeichen mit Codes kleiner als 32 (Steuerzeichen) werden vom Scanner überlesen.
+#page#
+#head#
+EUMEL-BASIC-Compiler Anhang C: Übersicht über die Fehlermeldungen %
+
+#end#
+
+Anhang C: Übersicht über die Fehlermeldungen
+
+
+Übersicht über die verwendeten Fehlermeldungen zur
+Übersetzungszeit
+Diese Übersicht enthält alle zur Übersetzungszeit möglichen Fehler, mit Ausnahme
+der internen Fehler.
+Die Erläuterungen geben die üblichen Ursachen für die Fehlermeldung an. Es wird
+empfohlen, sich im Falle eines Fehlers außerdem in Kapitel 8 über die genaue Syntax
+der betreffenden Anweisung beziehungsweise Funktion zu informieren.
+
+
+#on ("b")#AS ohne NAME#off ("b")#
+AS darf nur in NAME-Anweisungen vorkommen.
+
+#on ("b")#Accessrecht VAR erwartet, CONST gefunden#off ("b")#
+Beim Aufruf einer ELAN-Prozedur (CALL, CHAIN oder USR) wurde ein VAR-Para­
+meter verlangt. Angegeben wurde aber ein CONST-Parameter (zum Beispiel ein
+Ausdruck).
+
+#on ("b")#Ausdruck erwartet#off ("b")#
+Es wurde ein numerischer oder TEXT-Ausdruck erwartet. Diese Fehlermeldung
+erscheint zum Beispiel, wenn nach einem Operator kein Ausdruck mehr gefunden
+wird.
+
+#on ("b")#BASE ohne OPTION#off ("b")#
+BASE darf nur in OPTION BASE-Anweisungen vorkommen.
+
+#on ("b")#Bei SWAP nur gleiche Variablentypen erlaubt#off ("b")#
+Mit SWAP können nur Variablen von genau dem gleichen Typ bearbeitet werden.
+
+#on ("b")#Das Feld ist bereits dimensioniert#off ("b")#
+Diese Fehlermeldung erscheint bei DIM-Anweisungen, wenn das Feld vorher schon
+explizit oder automatisch dimensioniert wurde.
+
+#on ("b")#ELSE ohne IF#off ("b")#
+ELSE darf nur in IF-Anweisungen vorkommen. ELSE muß in der gleichen Zeile
+stehen wie die zugehörige IF-Anweisung.
+
+#on ("b")#Falsche Felddimension:
+Dimensioniert in ... Dimensionen, gefundene Anzahl Indizes: ...#off ("b")#
+Beim Zugriff auf ein Feldelement wurden zu viele oder zu wenig Indizes angegeben.
+
+#on ("b")#FOR ohne NEXT#off ("b")#
+Diese Fehlermeldung erscheint, wenn am Programmende für eine FOR-Anweisung
+kein korrespondierendes NEXT gefunden wurde.
+
+#on ("b")#Falsche Reihenfolge der Zeilennummern#off ("b")#
+Die Zeilennummern wurden nicht in aufsteigender Reihenfolge angegeben.
+
+#on ("b")#Falscher Typ#off ("b")#
+Es wurde ein anderer Datentyp erwartet als angegeben, und es konnte keine automa­
+tische Konvertierung vorgenommen werden.
+
+#on ("b")#Falscher Typ der Operanden#off ("b")#
+Bei einem dyadischen Operator wurden Operanden angegeben, für deren Typen
+dieser Operator nicht definiert ist (vergleiche Kapitel 4.4.).
+
+#on ("b")#Falscher Typ des Operanden#off ("b")#
+Bei einem monadischen Operator wurde ein Operand angegeben, für dessen Typ
+dieser Operator nicht definiert ist (vergleiche Kapitel 4.4.).
+
+#on ("b")#Fehlerhafte Bereichsangabe#off ("b")#
+Diese Fehlermeldung kann bei den Anweisungen DEFDBL, DEFINT, DEFSNG und
+DEFSTR auftreten, wenn bei einer Bereichsangabe der Buchstabe vor dem Binde­
+strich im Alphabet nach dem Buchstaben hinter dem Bindestrich steht.
+
+#on ("b")#Fehlerhafte Dimensionierung: Die Obergrenze muß >= 1 sein#off ("b")#
+Es wurde versucht, ein Feld mit dem größten Index null in einer Dimension zu
+dimensionieren, obwohl die Index-Untergrenze mit OPTION BASE auf eins einge­
+stellt war.
+
+#on ("b")#Fehlerhafte Laufvariable#off ("b")#
+Nach einer NEXT-Anweisung wurde eine Laufvariable gefunden, die nicht zur letzten
+anhängigen FOR-Anweisung gehört. Der Fehler tritt auf, wenn Schleifen geschachtelt
+wurden.
+
+#on ("b")#Fehlerhafte Zeilennummer#off ("b")#
+Die Zeilennumer entspricht nicht der Syntax für Zeilennumern.
+
+#on ("b")#Fehlerhafter Funktionsaufruf#off ("b")#
+- Die Prozedur liefert keinen Wert
+ Es wurde versucht, eine Prozedur mit USR aufzurufen, die keinen Wert liefert.
+- Der Typ des Resultats ist nicht erlaubt, gefunden: ...
+ Es wurde versucht, eine Prozedur mit USR aufzurufen, die ein Objekt liefert,
+ dessen Datentyp in BASIC nicht bekannt ist.
+- Kein Argument erwartet
+ Es wurde versucht, eine benutzer-definierte Funktion, die ohne Parameter definiert
+ wurde, mit Argument(en) aufzurufen.
+- ... Argument(e) erwartet
+ Die Anzahl der angegebenen Argumente ist kleiner als die Anzahl der bei der
+ Funktionsdefinition angegebenen Parameter.
+- Nur ... Argument(e) erwartet
+ Die Anzahl der angegebenen Argumente ist größer als die Anzahl der bei der Funk­
+ tionsdefinition angegebenen Parameter.
+- Kein Resultat erlaubt (gefunden: ...)
+ Bei CALL oder CHAIN wurde versucht, eine wertliefernde Prozedur aufzurufen.
+
+#on ("b")#Funktionsaufruf ohne Zusammenhang#off ("b")#
+Es wurde ein Funktionsaufruf angegeben, wo eine Anweisung erwartet wurde.
+
+#on ("b")#GO ohne TO oder SUB#off ("b")#
+Das reservierte Wort GO kann nur in GO SUB oder GO TO auftreten.
+
+#on ("b")#Interner Fehler#off ("b")#
+Bei der Übersetzung wurde innerhalb des Compilerprogramms ein interner Fehler
+ausgelöst. (vergleiche Kapitel 7.1.)
+
+#on ("b")#Nach OPTION BASE ist nur 0 oder 1 erlaubt#off ("b")#
+Es wurde versucht, eine Zahl > 1 nach OPTION BASE anzugeben.
+
+#on ("b")#NEXT ohne FOR#off ("b")#
+Es wurde eine NEXT-Anweisung gefunden, die keiner FOR-Anweisung zuzuordnen
+ist, da keine "offenen" FOR-Schleifen mehr anhängig sind.
+
+#on ("b")#Nicht implementiert#off ("b")#
+Einige reservierte Wörter werden vom BASIC-Compiler erkannt, obwohl die zugehö­
+rigen Anweisungen oder Funktionen nicht implementiert sind (vgl. Anhang A).
+
+#on ("b")#Parametervariable kommt mehrmals vor#off ("b")#
+Bei der Definition einer "user function" kommt ein Parameter in der Parameterliste
+mehr als einmal vor.
+
+#on ("b")#Rekursive Funktionsdefinition#off ("b")#
+Es wurde versucht, in der Definition einer "user function" die zu definierende Funk­
+tion aufzurufen.
+
+#on ("b")#STEP ohne FOR#off ("b")#
+STEP darf nur in FOR-Anweisungen vorkommen.
+
+#on ("b")#SUB ohne GO#off ("b")#
+SUB darf nur in GOSUB vorkommen.
+
+#on ("b")#Syntaxfehler: <nähere Fehlerangabe>#off ("b")#
+Wenn dieser Fehler erscheint, wurde vom Compiler eine Angabe gefunden, die nach
+den Syntaxregeln dort nicht erwartet wurde oder fehlerhaft ist.
+
+#on ("b")#TAB ohne (L)PRINT#off ("b")#
+TAB darf nur in PRINT- und LPRINT-Anweisungen vorkommen.
+
+#on ("b")#THEN ohne IF#off ("b")#
+THEN darf nur in IF-Anweisungen vorkommen. THEN muß in der gleichen Zeile
+stehen wie die zugehörige IF-Anweisung.
+
+#on ("b")#TO ohne Zusammenhang#off ("b")#
+TO darf nur in FOR-Anweisungen oder in GO TO vorkommen.
+
+#on ("b")#Text zu lang#off ("b")#
+Dieser Fehler erscheint, wenn ein Anführungszeichen fehlt beziehungsweise ein
+Anführungszeichen zu viel gefunden wird.
+
+#on ("b")#Unbekannte Funktion, Argument(e) angegeben: ...#off ("b")#
+Es wurde versucht, eine Funktion mit einem Argument aufzurufen, für dessen Typ die
+Funktion nicht definiert ist.
+
+#on ("b")#Unbekannte Prozedur, Parameter angegeben: ...#off ("b")#
+Die angegebene Prozedur konnte mit den angegebenen Parametertypen nicht gefun­
+den werden.
+
+#on ("b")#Undefinierte 'user function'#off ("b")#
+Es wurde versucht, eine benutzer-definierte Funktion aufzurufen, die (noch) nicht
+definiert wurde.
+
+#on ("b")#USING ohne (L)PRINT#off ("b")#
+USING darf nur in PRINT- und LPRINT-Anweisungen vorkommen.
+
+#on ("b")#WEND ohne WHILE#off ("b")#
+Es wurde eine WEND-Anweisung gefunden, die keiner WHILE-Anweisung zuzuord­
+nen ist, da keine "offenen" WHILE-Schleifen mehr anhängig sind.
+
+#on ("b")#WHILE ohne WEND#off ("b")#
+Diese Fehlermeldung erscheint, wenn am Programmende für eine WHILE-Anweisung
+kein korrespondierendes WEND gefunden wurde.
+
+#on ("b")#Zeile mit dieser Nummer existiert nicht#off ("b")#
+Es wurde versucht, mit GOTO oder GOSUB zu einer Zeilennumer zu verzweigen, die
+im Programm nicht angegeben wurde.
+
+
+
+
+Übersicht über die innerhalb des BASIC-Systems
+ausgelösten Laufzeitfehler
+Die meisten Laufzeitfehler werden auch bei BASIC-Programmen im EUMEL-System
+erzeugt (vergleiche Kapitel 7.2.). Einige werden aber innerhalb des BASIC-Systems
+erzeugt. Die nachfolgende Übersicht enthält die innerhalb des BASIC-Systems aus­
+gelösten Fehler mit Angabe des gelieferten Fehlercodes und der Fehlermeldung.
+
+#on ("b")#Fehlercode:#off ("b")# 1003
+#on ("b")#Fehlermeldung:#off ("b")# RETURN ohne GOSUB
+Eine RETURN-Anweisung wurde gefunden, obwohl keine GOSUB-Anweisung mehr
+anhängig war.
+
+
+#on ("b")#Fehlercode:#off ("b")# 1004
+#on ("b")#Fehlermeldung:#off ("b")# RESTORE: Keine DATA-Anweisung in oder nach
+#right#Zeile ... gefunden
+Eine RESTORE-Anweisung konnte nicht ausgeführt werden, weil in oder nach der in
+der Anweisung angegebenen Zeilennummer keine DATA-Anweisung mehr steht.
+
+
+#on ("b")#Fehlercode:#off ("b")# 1005
+#on ("b")#Fehlermeldung:#off ("b")# bei ^: negative Basis, gebrochener Exponent: ...
+Es wurde versucht, eine negative Zahl mit einer gebrochenen Zahl zu potenzieren.
+
+
+#on ("b")#Fehlercode:#off ("b")# 1005
+#on ("b")#Fehlermeldung:#off ("b")# USING: kein Format gefunden
+Bei einer PRINT USING-Anweisung wurde kein Format für die Ausgabe angegeben
+oder die Formatzeichenkette enthält keine Formatzeichen.
+
+
+#on ("b")#Fehlercode:#off ("b")# 1005
+#on ("b")#Fehlermeldung:#off ("b")# USING-Format fehlerhaft: ...
+Bei einer PRINT USING-Anweisung wurde ein fehlerhaftes Format angegeben.
+
+
+#on ("b")#Fehlercode:#off ("b")# 1004
+#on ("b")#Fehlermeldung:#off ("b")# Keine Daten mehr für READ
+Es stehen keine Daten mehr für die READ-Anweisung zur Verfügung; der READ-
+DATA-Zeiger zeigt hinter das Ende der letzten DATA-Anweisung.
+
+
+#on ("b")#Fehlercode:#off ("b")# 1005
+#on ("b")#Fehlermeldung:#off ("b")# WIDTH: negative Angabe: ...
+Nach WIDTH wurde eine negative Zahl gefunden.
+
+
+#on ("b")#Fehlercode:#off ("b")# 1013
+#on ("b")#Fehlermeldung:#off ("b")# READ: Falscher Datentyp, ... ist kein INT
+Einer INT-Variablen konnte kein Wert zugewiesen werden, da das aktuelle Objekt
+aus der DATA-Liste keine gültige Darstellung eines INT-Wertes war oder ein
+"quoted string" gefunden wurde.
+
+
+#on ("b")#Fehlercode:#off ("b")# 1013
+#on ("b")#Fehlermeldung:#off ("b")# READ: Falscher Datentyp, ... ist kein REAL
+Einer REAL-Variablen konnte kein Wert zugewiesen werden, da das aktuelle Objekt
+aus der DATA-Liste keine gültige Darstellung eines REAL-Wertes war oder ein
+"quoted string" gefunden wurde.
+
+
+#on ("b")#Fehlercode:#off ("b")# 1051 (interner Fehler)
+#on ("b")#Fehlermeldung:#off ("b")# variierend
+Bei der Ausführung des Programms trat in einer Prozedur des BASIC-Systems ein
+interner Fehler auf. (Vergleiche Kapitel 7.)
+
+
+#on ("b")#Fehlercode:#off ("b")# 1080
+#on ("b")#Fehlermeldung:#off ("b")# INPUT-Fehler ( Fehlerart ) : > Eingabezeile <
+Bei einer INPUT-Anweisung, die auf eine mit 'sysin' eingestellte Datei wirken sollte,
+kam es zu einem Fehler der angegebenen Fehlerart. Nach dem Doppelpunkt wird die
+Eingabezeile aus der Eingabedatei ausgegeben.
+#page#
+#head#
+EUMEL-BASIC-Compiler Anhang D: ELAN-Prozeduren des Compilers %
+
+#end#
+
+Anhang D: ELAN-Prozeduren des Compilers
+
+ #on ("b")#PROC #ib(3)#basic#ie(3)# (TEXT CONST dateiname)#off ("b")#
+ Das in der Datei 'dateiname' enthaltene BASIC-Programm wird dem BASIC-
+ Compiler zur Übersetzung übergeben. Werden keine Fehler gefunden, so wird das
+ Programm direkt nach der Übersetzung ausgeführt.
+ Beispiel:
+
+ basic ("Mein liebstes BASIC-Programm")#off ("b")#
+
+
+ #on ("b")#PROC basic (TEXT CONST dateiname, prozedurname)#off ("b")#
+ Das in der Datei 'dateiname' enthaltene BASIC-Programm wird dem BASIC-
+ Compiler zur Übersetzung übergeben. Werden keine Fehler gefunden, dann wird
+ das Programm unter dem Namen 'prozedurname' dauerhaft eingetragen (inser­
+ tiert).
+ Das Programm wird nicht ausgeführt. Beachten Sie, daß der Prozedurname den
+ Vorschriften für ELAN-Prozedurnamen entsprechen muß und außerdem #on ("b")#keine
+ Leerzeichen#off ("b")# enthalten darf. (Zur Namenswahl siehe auch Kapitel 3.)
+ Beispiel:
+
+ basic ("Mein liebstes BASIC-Programm", "liebstesprogramm")#off ("b")#
+
+
+
+ #on ("b")#PROC #ib(3)#basic list#ie(3)# (BOOL CONST status)#off ("b")#
+ Mit der Prozedur 'basic list' kann eingestellt werden, ob die gerade vom Compiler
+ übersetzten Programmzeilen angezeigt werden sollen oder nicht (vergleiche Kapitel
+ 3.).
+
+ basic list (TRUE)#off ("b")#: Die übersetzten Zeile werden angezeigt
+ basic list (FALSE)#off ("b")#: Die übersetzten Zeile werden nicht angezeigt
+
+
+ #on ("b")#PROC #ib(3)#basic page#ie(3)# (BOOL CONST status)#off ("b")#
+ Mit der Prozedur 'basic page' kann eingestellt werden, wie die Ausgaben von
+ BASIC-Programmen behandelt werden, wenn der Bildschirm voll ist (vergleiche
+ Kapitel 5, Steuerung der Bildschirmausgaben).
+
+ basic page (TRUE): Beim Erreichen des Bildschirmendes wird auf einen
+ Tastendruck gewartet (vgl. Kap. 5.)
+ basic page (FALSE): Beim Erreichen des Bildschirmendes wird 'gescrollt'.
+
diff --git a/doc/basic/basic handbuch.index b/doc/basic/basic handbuch.index
new file mode 100644
index 0000000..4ac7e16
--- /dev/null
+++ b/doc/basic/basic handbuch.index
@@ -0,0 +1,232 @@
+#page nr ("%",115)#
+#head#
+EUMEL-BASIC-Compiler Stichwortverzeichnis %
+
+#end#
+
+Stichwortverzeichnis
+
+>= 15
+\ 14
+- 14
++ 14
++ 15
+<= 15
+* 14
+/ 14
+= 15
+> 15
+< 15
+<> 15
+^ 14
+ABS 31
+AND 16
+Anführungszeichen 10
+Argument 21
+Arithmetische Operatoren 14
+Arrays 13
+ASC 32
+ATN 32
+Äquivalenz-Verknüpfung 17
+Aufruf benutzer-definierter Funktionen 21
+Aufruf und Steuerung des BASIC-Compilers 5
+basic 5, 113
+BASIC-Compiler ERROR 28
+basic list 6, 113
+basic page 25, 114
+benutzer-definierte Funktionen 19, 104
+Bildschirmausgaben 25
+CALL 23, 33
+CDBL 35
+CHAIN 23, 35
+CHR$ 35
+CINT 36
+CLS 36
+Codebereichs pro Task 27
+Compiler Error 304 26
+Compiler Error 307 26
+Compiler Error 308 26
+COS 37
+CSRLIN 37
+CVD, CVI 38
+DATA 38
+DATE$ 40
+Datentypen 10
+Datentyp INT 10
+Datentyp REAL 10
+Datentyp TEXT 10
+Debugging 6
+DEFDBL, DEFINT, DEFSNG, DEFSTR 40
+DEF FN 19, 28, 42
+Definition benutzer-definierter Funktionen 19
+DEFINT 12
+DEFSTR 12
+DIM 13, 43
+Dimensionen 13
+Doppelpunkt 8
+ELSE 54
+END 45
+EOF 56
+EOF (End of File, Dateiende) 7, 105
+EOL (End of Line, Zeilenende) 8, 105
+EOS (End of Statement, Anweisungsende) 8, 105
+EQV 17
+ERL 46
+ERM$ 47
+ERR 47
+ERROR 48
+EUMEL-Coder 26
+EUMEL-Textdatei 7
+Exklusiv-ODER-Verknüpfung 17
+EXP 49
+Exponent 10
+Fehlerbehandlung 28
+Fehlercodes 30
+Fehlerzeile 30
+Fehler zur Laufzeit 30, 111
+Fehler zur Übersetzungszeit 28, 106
+Felder (Arrays) 13
+Felder/Feldelemente 104
+Feldnamen 13
+FIX 49
+FOR 50
+FRE 51
+Funktionen 19
+Funktionsaufrufe 19
+Ganzzahlen 10
+Generatorprogramm 4
+Gleitkommazahlen 10
+GOSUB 52
+GOTO 53
+Grenzen des Compilers 26
+Groß-/Kleinschreibung 9
+Hauptdurchlauf 28
+HEX$ 54
+Hochkomma 8
+IF 54
+IMP 17
+Implikations-Verknüpfung 17
+Indizes 13
+INKEY$ 56
+INPUT$ 58
+INPUT 56
+Insertieren von BASIC-Programmen 5
+Installation des BASIC-Compilers 4
+INSTR 59
+INT 59
+Interne Compilerfehler 28
+INTs 10
+INT-Überlauf 15
+KILL 60
+Konstanten 10
+Konvertierung 15, 22
+Kriterien für den Typ einer Variablen 12
+Labels 26
+Leerzeichen 9
+LEFT$ 60
+LEN 61
+LET 61
+LINE INPUT 62
+LOG 63
+Logische Operatoren 16
+LPOS 63
+LPRINT 64
+LSET 65
+Mantisse 11
+MID$ 65, 66
+MKD$, MKI$ 67
+MOD 14
+Modulgrenze 26
+NAME 68
+Namenstabelle 27
+Negation 16
+negative Zahlenwerte 11
+NEXT 50, 68
+NOT 16
+Notation 3
+Notebook 28
+numerische Konstanten 103
+OCT$ 69
+ODER-Verknüpfung 17
+ON 69
+Operatoren 103
+Operatoren, arithmetische 14
+Operatoren, logische 16
+Operatoren, Text- 15
+Operatoren, Vergleichs- 15
+Operator, Zuweisungs- 18
+OPTION BASE 13, 71
+OR 17
+Parameter 19
+POS 72
+PRINT 72
+Prioritäten der Operanden 18
+Programmdatei 7
+Programmsegmente 24
+Programmzeile 7
+RANDOMIZE 75
+READ 75
+REM 77
+Reservierte Wörter 9, 12, 100, 103
+RESTORE 77
+RETURN 78
+RIGHT$ 79
+RND 80
+RSET 81
+Scanner 9, 103
+Schlüsselwörter 9
+Scrolling 25
+SGN 81
+SIN 82
+SPACE$ 82
+SPC 83
+SQR 83
+Standard-Funktionen 19
+STEP 50
+Steuerung der Bildschirmausgaben 25
+Steuerung des BASIC-Compilers 5
+STOP 84
+STR$ 84
+STRING$ 85
+SUB 52
+SWAP 86
+Symbol 9
+Symboltypen 103
+Syntax 7
+sysout 6
+TAB 64, 72
+TAN 86
+Texte 10
+TEXT-Konstanten 104
+Text-Operator + 15
+THEN 54
+TIME$ 88
+TIMER 87
+TO 50, 53
+Trennzeichen 105
+TRON / TROFF 88
+Typanpassung 22
+UND-Verknüpfung 16
+USING 64, 72
+USR 23, 90
+Übersetzen von BASIC-Programmen 5
+Übersichtlichkeit von BASIC-Programmen 7
+VAL 91
+Variablen 12, 104
+Variablennamen 9, 12
+VAR-Parameter 23
+Vergleichsoperatoren 15
+Vordurchlauf 28
+Vorzeichen 11
+Wahrheitswerte 16
+Weitere Schreibregeln 9
+WEND 92
+wertliefernden Prozeduren 23
+WHILE 92
+WIDTH 93
+WRITE 94
+XOR 17
+Zahlen 10
+Zeilennummer 7
+Zuweisungsoperator 18
+
diff --git a/doc/dialog/gs-dialog handbuch.impressum b/doc/dialog/gs-dialog handbuch.impressum
new file mode 100644
index 0000000..b470fe4
--- /dev/null
+++ b/doc/dialog/gs-dialog handbuch.impressum
@@ -0,0 +1,89 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#gs-Dialog
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+
+#free (4.0)##on("b")#
+#center#gs-Dialog
+
+
+#center#Benutzerhandbuch
+
+
+#center#Version 1.0
+
+
+#off("b")##center#copyright
+#center#Eva Latta-Weber
+#center#Software- und Hardware-Systeme, 1988
+#center#ERGOS GmbH, 1990
+#page#
+#block#
+#center#____________________________________________________________________________
+
+
+Copyright:  ERGOS GmbH   März 1990
+
+ Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+ maschinenlesbare Form sowie das Speichern in Informations­
+ systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+ der ERGOS GmbH gestattet.
+
+
+#center#____________________________________________________________________________
+
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender.
+
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden.
+
+Texterstellung :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+ erstellt und aufbereitet und auf einem Kyocera Laser­
+ drucker gedruckt.
+
+
+
+
+#center#___________________________________________________________________________
+
+
+
+Ergonomic Office Software GmbH
+
+Bergstr. 7 Telefon: (02241) 63075
+5200 Siegburg Teletex: 2627-2241413=ERGOS
+ Telefax: (02241) 63078
+
+
+#center#____________________________________________________________________________
+
+
diff --git a/doc/dialog/gs-dialog-1 b/doc/dialog/gs-dialog-1
new file mode 100644
index 0000000..59b98c3
--- /dev/null
+++ b/doc/dialog/gs-dialog-1
@@ -0,0 +1,107 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (3)#
+#headodd#
+#center#gs-DIALOG#right#%
+
+#end#
+#headeven#
+%#center#gs-DIALOG
+
+#end#
+
+#center#1
+
+#center#Was kann gs-DIALOG?
+
+
+
+ In diesem Kapitel wollen wir Ihnen erläutern, was
+#on("b")#gs-DIALOG#off("b")# Ihnen für Vorteile bringen soll. Sie haben
+sicher schon mit einem Computer gearbeitet und sich
+mehrfach darüber geärgert, daß Sie mit jedem neuen Pro­
+gramm auch eine neue Bedienung erlernen müssen. Zwar
+sind Sie als EUMEL-Anwender schon sehr verwöhnt, da das
+System sehr homogen ist und bestimmte Systemelemente,
+wie z.B. der Editor, mit immer gleicher Bedienung immer
+wieder auftauchen. Für die jeweiligen Anwendungspro­
+gramme aber gibt es eine Reihe von Kommandos und Tasten­
+folgen, die Sie sich für die Bedienung merken müssen.
+Brauchen Sie Informationen zu den einzelnen Programm­
+teilen, so müssen Sie zumeist in (den gerade nicht griff­
+bereiten) Handbüchern nachschlagen.
+ Und der Anfänger? Er ist am härtesten betroffen! Er
+muß sich nicht nur mit der neuen Maschine auseinander­
+setzen, die technische Handhabung erlernen - von ihm
+erwartet man, daß er sich innerhalb kurzer Zeit eine Rei­
+he von Kommandos einprägt, die für die Bedienung des
+Grundsystems notwendig sind - und darüber hinaus noch
+die Kommandos für die verschiedenen Anwendungsprogram­
+me. Viele resignieren nach den ersten Gehversuchen.
+ Und der Programmierer? Viele Anwender haben keine
+Vorstellung davon, welche Arbeit in einem Programm
+steckt. Einen großen Teil seiner Arbeit verwendet der
+Programmierer darauf, die Benutzerschnittstelle zu ge­
+stalten - den Teil des Programms, mit dem der Anwender in
+Kontakt kommt, über den er mit dem Programm kommuni­
+ziert, einen Dialog führt. Die Gestaltung und Pflege der
+Benutzerschnittstelle kann dabei bis zu 50% der Gesamt­
+arbeit an einem Programm ausmachen.
+
+ #on("b")#gs-DIALOG#off("b")# ist entwickelt worden, um diese Nachteile zu
+beheben bzw. zumindest zu verringern. Grundelemente von
+#on("b")#gs-DIALOG#off("b")# sind die Pull-Down-Menus (Klappmenus), in de­
+nen die zur Verfügung stehenden Funktionen übersicht­
+lich zur Auswahl angeboten werden. So ist es möglich, daß
+eine Vielzahl von Funktionen verwaltet werden - ohne
+daß der Anwender den Überblick verliert. Dabei können zu
+jeder angebotenen Funktion noch Informationen abge­
+rufen werden, so daß ein Blättern in Handbüchern sich
+zumeist erübrigt.
+ Zunächst einmal ist #on("b")#gs-DIALOG#off("b")# gar kein eigenständiges
+Programm. Es ist vielmehr ein Baukastensystem, auf das
+andere Programme zugreifen können. Davon können sowohl
+der Programmierer und erst recht der Anwender profi­
+tieren:
+ Der Programmierer wird bei seiner Arbeit - insbeson­
+dere bei der Gestaltung der Benutzerschnittstelle we­
+sentlich entlastet, da er auf vorgefertigte Komponenten
+zurückgreifen kann. Er kann sich mehr auf die inhalt­
+liche Ausgestaltung seiner Programme konzentrieren.
+ Sie als Anwender profitieren von der #on("u")#einfachen#off("u")# und
+#on("u")#immer einheitlichen Bedienung#off("u")# solcher Programme. Aus
+den Menupunkten können Sie auf einfache Weise auswählen
+und den gewünschten Teil des Programms zur Ausführung
+bringen. Durch diese Bedienung wird der Aufwand, sich in
+ein neues Programmsystem einzuarbeiten, erheblich redu­
+ziert. Die zur Verfügung stehenden Programmfunktionen
+können effektiver ausgenutzt werden, da sie jederzeit
+offensichtlich sind. Informationen zu den einzelnen Pro­
+grammpunkten können Sie jederzeit abrufen, d.h. zumeist
+können Sie auf ein Nachschlagen in den Handbüchern ver­
+zichten.
+ #on("b")#gs-DIALOG#off("b")# ist aber nicht nur ein Baukastensystem, auf
+das andere Programme zugreifen können. Bei nahezu jeder
+Anwendung ist es notwendig, Dateien auf das Archiv zu
+schreiben oder von dort zu holen. Aus diesem Grunde ist
+eine leistungsfähige, komfortable Archivbehandlung in
+das Programmsystem integriert.
+ Ein Austausch von Dateien ist aber nicht nur mit dem
+Archiv möglich. Sie können auch mit anderen Tasks inner­
+halb Ihres Systems (z.B. mit der Vatertask) oder sogar -
+sofern installiert - mit einer Task irgendwo innerhalb
+des EUMEL-Netzes Dateien austauschen. Daneben werden
+noch Funktionen angeboten, die den Umgang mit den Da­
+teien vereinfachen (Verzeichnis, Umbenennen, Kopieren,
+Löschen, Aufräumen etc.).
+ Diese Funktionen stehen Ihnen unabhängig von ande­
+ren Programmen zu Verfügung, sobald Sie #on("b")#gs-DIALOG#off("b")# in­
+stalliert haben. Andererseits finden Sie diese Funktionen
+in immer gleicher Form auch in den meisten Programmen,
+die auf der Basis von #on("b")#gs-DIALOG#off("b")# entwickelt worden sind
+und entwickelt werden.
+
+
+
+
+
diff --git a/doc/dialog/gs-dialog-2 b/doc/dialog/gs-dialog-2
new file mode 100644
index 0000000..a25d35d
--- /dev/null
+++ b/doc/dialog/gs-dialog-2
@@ -0,0 +1,215 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (6)#
+#headodd#
+#center#gs-DIALOG#right#%
+
+#end#
+#headeven#
+%#center#gs-DIALOG
+
+#end#
+
+#center#2
+
+#center#Installation von gs-DIALOG
+
+
+
+ Bevor Sie #on("b")#gs-DIALOG#off("b")# auf Ihrem System benutzen kön­
+nen, müssen Sie das Programm zunächst installieren. Wenn
+#on("b")#gs-DIALOG#off("b")# auf Ihrem System schon zur Verfügung steht,
+können Sie dieses Kapitel ruhig überspringen.
+
+
+2.1 Voraussetzungen:
+
+ Um #on("b")#gs-DIALOG#off("b")# auf Ihrem Computer betreiben zu können,
+muß das EUMEL-Betriebssystem installiert sein. #on("b")#gs-DIALOG#off("b")#
+setzt die Multi-User-Version voraus und ist lauffähig ab
+Version 1.7.5.
+
+
+2.2 Lieferumfang
+
+ #on("b")#gs-DIALOG#off("b")# wird auf einer Diskette geliefert, die alle
+notwendigen Programme enthält. Um den Inhalt der Dis­
+kette feststellen zu können, starten Sie Ihr System und
+bringen es dazu, daß 'gib kommando:' erscheint. Dann legen
+Sie die Diskette ein und geben das Kommando:
+
+ archive ("gs-DIALOG"); list (archive);
+ release (archive) <RETURN>
+
+ Anschließend erscheint eine Übersicht der auf dem
+Archiv vorhandenen Programme. Folgende Programme soll­
+ten sich in der Übersicht befinden:
+
+ "gs-DIALOG MENUKARTEN MANAGER"
+ "gs-DIALOG MM/gen"
+ "gs-DIALOG 1"
+ "gs-DIALOG 2"
+ "gs-DIALOG 3"
+ "gs-DIALOG 4"
+ "gs-DIALOG 5"
+ "gs-DIALOG 6"
+ "gs-DIALOG 7"
+ "gs-MENUKARTE:Archiv"
+ "gs-DIALOG/gen"
+
+ Eventuell können noch weitere Namen auf der Diskette
+vorhanden sein. Wenn Sie den Inhalt der Diskette kon­
+trolliert haben und diese Programme auf der Diskette
+vorhanden sind, können Sie #on("b")#gs-DIALOG#off("b")# installieren.
+ Sollten Sie statt der Übersicht eine Fehlermeldung
+erhalten, überprüfen Sie bitte, ob die Diskette das rich­
+tige Format besitzt oder ob ihr Diskettenlaufwerk Pro­
+bleme macht. Sollten dagegen Programme fehlen, so rekla­
+mieren Sie die Diskette.
+
+
+2.3 Installation
+
+Die Installation erfolgt in #on("u")#zwei Schritten#off("u")#:
+ #on("u")#Zunächst#off("u")# muß eine Task eingerichtet werden, in der
+später alle Menukarten aufbewahrt werden. Diese Menu­
+karten enthalten alle Informationen, die #on("b")#gs-DIALOG#off("b")# für
+den Aufbau und den Umgang mit den Menus benötigt. #on("u")#Der
+Name dieser Task ist vorgegeben#off("u")# ('gs-MENUKARTEN'), da
+#on("b")#gs-DIALOG#off("b")# später auf diese Task zugreift. Sollten Sie
+hier einen anderen Namen wählen, so wird die Task vom
+Generierungsprogramm automatisch umbenannt, um die
+Funktionsfähigkeit von #on("b")#gs-DIALOG#off("b")# zu garantieren!
+ #on("u")#Anschließend#off("u")# kann das Programmsystem selbst in einer
+anderen Task installiert werden. Wie nehmen hier an, daß
+die Task den Namen 'MENU' erhalten soll. (Sie können für
+diese Task auch einen beliebigen anderen Namen wählen.)
+
+
+1) #on("u")#Einrichten der 'Menukarten - Task'#off("u")#
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+#off("b")#
+
+ --> gib supervisor kommando:
+
+#on("b")#
+ begin ("gs-MENUKARTEN") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+
+
+ (Arbeiten mehrere Personen mit dem Computer, dann ist
+es sinnvoll, diese Task vor unbefugtem Zugriff durch ein
+Passwort zu schützen. Wie das gemacht wird, können Sie in
+Ihrem EUMEL-Benutzerhandbuch erfahren.)
+ Legen Sie dann die Archivdiskette ein, auf der sich
+#on("b")#gs-DIALOG#off("b")# befindet, und geben Sie die folgenden Komman­
+dos:
+
+#on("b")#
+ archive("gs-DIALOG") <RETURN>
+
+ fetch("gs-DIALOG MM/gen",archive) <RETURN>
+
+ run <RETURN>
+#off("b")#
+
+ Sie haben damit das Generatorprogramm gestartet; die
+Installation wird automatisch durchgeführt. Lassen Sie
+während des gesamten Vorgangs die Archivdiskette einge­
+legt. Die Generierung ist beendet, wenn der EUMEL-
+Eingangsbildschirm erscheint.
+
+2) #on("u")#Installation des Programmsystems#off("u")#
+
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+#off("b")#
+
+ --> gib supervisor kommando:
+
+#on("b")#
+ begin ("MENU") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+
+
+ (Sichern Sie, wenn gewünscht, auch diese Task durch
+ein Passwort vor unbefugtem Zugriff.)
+ Legen Sie die #on("b")#gs-DIALOG#off("b")#-Archivdiskette ein und geben
+Sie die folgenden Kommandos:
+
+#on("b")#
+ archive("gs-DIALOG") <RETURN>
+
+ fetch("gs-DIALOG/gen",archive) <RETURN>
+
+ run <RETURN>
+#off("b")#
+
+ Sie haben damit das Generatorprogramm gestartet. Die
+Generierung benötigt jetzt aber wesentlich mehr Zeit als
+die zuvor! Lassen Sie während des gesamten Vorgangs die
+Archivdiskette eingelegt. Die Generierung ist beendet,
+wenn der EUMEL-Eingangsbildschirm erscheint. Die Task,
+in der die Generierung stattfindet, wird automatisch zur
+Managertask, das heißt, daß Söhne von ihr eingerichtet
+werden können. Damit ist die Installation von #on("b")#gs-DIALOG#off("b")#
+abgeschlossen - in allen Sohn- und Enkeltasks können
+Sie nun mit dem Kommando:
+
+#on("b")#
+ archiv <RETURN>
+#off("b")#
+
+die Archivverwaltung aufrufen.
+
+
+2.4 Nutzung der 'Semi-Graphik-Zeichen'
+
+ #on("b")#gs-DIALOG#off("b")# verwendet beim Aufbau der Rahmen inner­
+halb der Menus nur solche Zeichen, die auf jedem Computer
+zur Verfügung stehen. Die meisten Computer/Terminals
+verfügen aber über einen Zeichensatz, der es erlaubt,
+solche Rahmen "schöner" darzustellen. #on("b")#gs-DIALOG#off("b")# ist dar­
+auf vorbereitet, diese Eigenschaften auszunutzen.
+ Allerdings ist der Aufruf dieser Graphikzeichen nicht
+einheitlich festgelegt. Verfügen Sie über einen Computer,
+der 'IBM - kompatibel' ist, oder über ein Terminal 'Beehive
+FT20', dann können Sie die Graphikzeichen ganz einfach
+nutzen, denn dafür sind im Programm bereits Befehle vor­
+bereitet.
+
+ibm  graphic char <RETURN> - Mit diesem Befehl stel­
+ len Sie für #on("b")#gs-DIALOG#off("b")#
+ den 'IBM - Graphikzei­
+ chensatz' ein.
+
+ft20 graphic char <RETURN> - Mit diesem Befehl stel­
+ len Sie für #on("b")#gs-DIALOG#off("b")#
+ den 'Beehive FT20 -
+ Graphikzeichensatz'
+ ein.
+
+std  graphic char <RETURN> - Mit diesem Befehl stel­
+ len Sie wieder den
+ 'Standard - Graphik­
+ zeichensatz' ein.
+
+ Nehmen Sie eine solche Einstellung in einer Task vor,
+so erben alle Sohn- und Enkeltasks diese Einstellung. Sie
+können auch in verschiedenen Task unterschiedliche Ein­
+stellungen wählen.
+
+ Verfügen Sie über andere Computer- oder Terminalty­
+pen, die Grapikzeichen darstellen können, so können Sie
+diese ebenfalls nutzen. Sie müßten sich allerdings ein
+kleines ELAN-Programm schreiben. Aber auch das ist ganz
+einfach, da #on("b")#gs-DIALOG#off("b")# auch darauf vorbereitet ist. Wie
+das gemacht wird, wird aber erst in Kapitel 5 erläutert.
+
diff --git a/doc/dialog/gs-dialog-3 b/doc/dialog/gs-dialog-3
new file mode 100644
index 0000000..044720b
--- /dev/null
+++ b/doc/dialog/gs-dialog-3
@@ -0,0 +1,683 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (12)#
+#headodd#
+#center#gs-DIALOG#right#%
+
+#end#
+#headeven#
+%#center#gs-DIALOG
+
+#end#
+
+#center#3
+
+#center#Umgang mit den Menus
+
+
+#center#Eine Beispielsitzung
+
+
+ Wie schon oben erwähnt, ist in #on("b")#gs-DIALOG#off("b")# eine Archiv­
+verwaltung integriert. Anhand dieses Programms möchten
+wir den Umgang mit und die Arbeitsweise von #on("b")#gs-DIALOG#off("b")#
+vorstellen. Als Beispiel wollen wir eine Datei von einer
+Ihrer Archivdisketten ins System holen.
+ Zunächst zu den Begriffen: Die Disketten, die Sie in den
+Rechner einlegen können, um z.B. Dateien (und Programme)
+von anderen Computern übernehmen zu können, bezeichnet
+man als #on("u")#Archiv#off("u")#. Das Archiv (die Diskette) wird benutzt, um
+Daten und Programme vor Beschädigung und Verlust zu
+sichern. Es ist sehr wichtig, daß Sie Ihre Programme und
+Daten auf Archivdisketten sichern, denn ein einziger
+Hardwarefehler könnte die Arbeit von vielen Stunden
+zunichte machen.
+ Da man diese Operationen, d.h. Programme und Daten
+auf Disketten zu sichern und wieder von dort zu holen,
+sehr häufig benötigt, ist die Archivbehandlung fest in
+das #on("b")#gs-DIALOG#off("b")#-Programmsystem integriert und Bestandteil
+nahezu jeden Programms, das unter #on("b")#gs-DIALOG#off("b")# entwickelt
+wird. Unabhängig von anderen Programmen kann die
+Archivbehandlung aber auch benutzt werden, sobald
+#on("b")#gs-DIALOG#off("b")# installiert ist. Das wollen wir jetzt auspro­
+bieren.
+
+
+3.1 Aufruf der Archivverwaltung:
+
+ Richten Sie eine Task als Sohn der Task ein, in der Sie
+#on("b")#gs-DIALOG#off("b")# installiert haben. Nehmen wir hier an, die neue
+Task soll den Namen 'TEST' erhalten - die Task, in der
+#on("b")#gs-DIALOG#off("b")# installiert ist, habe den Namen 'MENU'.
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+#off("b")#
+ --> gib supervisor kommando:
+#on("b")#
+ begin ("TEST","MENU") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+#on("b")#
+ archiv <RETURN>
+#off("b")#
+
+ Mit dem Befehl 'archiv' können Sie jederzeit die Archiv­
+behandlung aufrufen - es erscheint dann folgendes Menu:
+
+
+#on("b")#
+ARCHIV: Dateien Archiv
+-+-------------------+----------------------------------------------------
+ | v Verzeichnis |
+ | --------------- |
+ | l Löschen |
+ | d Drucken |
+ | --------------- |
+ | k Kopieren |
+ | u Umbenennen |
+ | --------------- |
+ | s Speicherplatz |
+ | a Aufräumen |
+ +-------------------+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+
+3.2 Bedienung des Menusystems
+
+- Aufbau der Menus (Bildschirmaufbau)
+
+ Ein Menu ist ein Angebot von Funktionen, die ein Pro­
+gramm ausführen kann. Aus diesem Angebot kann der Pro­
+grammbenutzer auswählen. In diesem Sinne ist ein solches
+Menu durchaus vergleichbar mit einer Speisenkarte in
+einem Restaurant.
+ Jedes Menu unter #on("b")#gs-DIALOG#off("b")# besitzt eine 'Kopfzeile'
+und eine 'Fußzeile'. In der Kopfzeile ist ganz links der
+Name des Programms angegeben, mit dem Sie gerade arbei­
+ten. Daneben enthält die Kopfzeile die 'Oberbegriffe', mit
+denen die einzelnen Untermenus angesprochen werden
+können. Maximal können hier zehn Oberbegriffe auftau­
+chen - in unserem Beispiel sind es nur zwei.
+ Besondere Bedeutung für die Bedienung der Menus
+kommt der Fußzeile zu. Einerseits wird hier jeweils ange­
+zeigt, welche Tasten Sie zum jeweiligen Zeitpunkt benut­
+zen können, andererseits erhalten Sie über diese Fußzeile
+auch Informationen, wenn #on("b")#gs-DIALOG#off("b")# "mit sich selbst be­
+schäftigt ist", d.h. Operationen ausführt. Wissen Sie also
+nicht mehr weiter, so schauen Sie zuerst auf die Fußzeile
+und beachten Sie die hier stehenden Informationen.
+ Im Bereich zwischen der Kopf- und Fußzeile werden die
+Untermenus ausgegeben. Dieser Bereich wird auch dazu
+benutzt, um Informationen an den Benutzer einzublenden,
+Fragen an ihn zu richten, ihn aus einem Angebot (z.B. von
+Dateien) auswählen zu lassen und vieles mehr.
+ Treiben wir den Vergleich mit der Speisenkarte in ei­
+nem Restaurant noch ein wenig weiter. Bei einem großen
+Angebot kann eine Speisenkarte recht umfangreich wer­
+den. Denken Sie beispielsweise an eine Speisenkarte in
+einem chinesischen Restaurant. Dazu sind neben den an­
+gebotenen Gerichten oft noch Zusatzinformationen (Zube­
+reitungsart, Zutaten etc.) angegeben. Um dem Gast die Aus­
+wahl zu erleichtern, ist die Speisenkarte aber zumeist
+untergliedert; man findet Suppen, warme Vorspeisen, kalte
+Vorspeisen, Gerichte mit Schweinefleisch, mit Rindfleisch,
+mit Geflügel, mit Fisch etc.
+ Ein Computerprogramm kann, ebenso wie ein Restau­
+rant, dem Benutzer ein großes Angebot (an Programmfunk­
+tionen) machen. Von großem Nachteil ist allerdings, daß
+ein Computerbildschirm - im Gegensatz zu einer umfang­
+reichen Speisenkarte - viel zu klein ist, um alle Angebote
+und Informationen gleichzeitig darstellen zu können.
+Außerdem würde ein nahezu vollständig beschriebener
+Bildschirm sehr unübersichtlich sein.
+ Aus diesem Grunde haben wir uns entschlossen, immer
+nur einen Teil des vorhandenen Angebotes an Funktionen
+und der vorhandenen Informationen anzuzeigen - immer
+nur soviel, daß Sie sich auf dem Bildschirm orientieren
+können und den Überblick nicht verlieren. Dazu haben Sie
+die Möglichkeit, jeweils zu bestimmen, auf welche Infor­
+mationen Sie Ihre Aufmerksamkeit richten wollen, was Sie
+angezeigt bekommen möchten.
+
+
+- Auswahl der Menupunkte
+
+ Zu jedem Oberbegriff in der Kopfzeile gehört eine
+Liste von Funktionen, die das Programm dazu zur Auswahl
+anbietet. Allerdings ist immer nur eine Liste (ein Unter­
+menu) sichtbar. Das sichtbare Untermenu gehört immer zu
+dem Oberbegriff in der Kopfzeile, der invers dargestellt
+ist. Wir wollen uns zunächst das Untermenu zum zweiten
+Oberbegriff ('Archiv') anzeigen lassen. Zum Wechsel zwi­
+schen den Oberbegriffen in der Kopfzeile benutzt man die
+Pfeiltasten <links> oder <rechts>. Probieren Sie es einmal
+aus. Es erscheint das folgende Bild auf dem Bildschirm:
+
+
+#on("b")#
+ARCHIV: Dateien Archiv
+-------+-------------------------+----------------------------------------
+ | r Reservieren |
+ | - Neue Diskette |
+ | --------------------- |
+ | - Schreiben |
+ | - Checken |
+ | - Kombination |
+ | - Holen/Lesen |
+ | - Löschen |
+ | --------------------- |
+ | - Verzeichnis |
+ | - Drucken |
+ | --------------------- |
+ | i Initialisieren |
+ | z Zieltask einstellen |
+ +-------------------------+ +---------------------+
+ | Dateiaustausch mit: |
+ | Archiv |
+ | Archivname: |
+ | --- |
+ +---------------------+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+
+ Sie können jetzt sehen, daß ein anderer Oberbegriff in
+der Kopfzeile aktiviert, d.h. invers dargestellt ist. Dane­
+ben wurde noch das sichtbare Untermenu "eingeklappt"
+und ein anderes "ausgeklappt". Man könnte die Unterme­
+nus deshalb auch als 'Klappmenus' bezeichnen - gebräuch­
+lich ist allerdings die Bezeichnung 'Pull-Down-Menus', an
+die wir uns auch halten wollen.
+
+ Sicher haben Sie bemerkt, daß es einen Augenblick
+gedauert hat, bis das Pull-Down-Menu unter dem Menu­
+punkt 'Archiv' erschien. Das hat auch seine Ursache, denn
+#on("b")#gs-DIALOG#off("b")# muß einige Einstellungen vornehmen, die etwas
+Zeit in Anspruch nehmen. Neben dem Pull-Down-Menu ist
+unten rechts auf dem Bildschirm noch ein 'Kasten' sicht­
+bar geworden. Er dient Ihnen zur Information. Da
+#on("b")#gs-DIALOG#off("b")# nicht nur den Austausch von Dateien mit dem
+Archiv, sondern auch mit anderen Tasks ermöglicht, wird
+hier immer angezeigt, mit welcher Task der Dateiaus­
+tausch zur Zeit erfolgt. Ist das Archiv eingestellt, so
+wird auch noch der Name der Diskette angezeigt - aber
+erst wenn das Archiv angemeldet worden ist, was ja mo­
+mentan noch nicht der Fall ist. Deshalb werden nur drei
+Striche ausgegeben.
+ Sicher ist Ihnen das Grundprinzip der Menubehand­
+lung schon klar geworden: Sie müssen sich zuerst inner­
+halb der Kopfzeile für einen Oberbegriff entscheiden.
+Zum gewählten Oberbegriff wird dann jeweils das Angebot
+an zugehörigen Programmfunktionen im darunterstehen­
+den Pull-Down-Menu angezeigt. Dieses Vorgehen hat den
+Vorteil, daß man den kleinen Bildschirm im Prinzip "mehr­
+fach nutzen kann". Die Pull-Down-Menus können sich ja
+ruhig überlappen. Sie merken es gar nicht, da ja nicht
+alle gleichzeitig angezeigt werden.
+ Noch ein Vorteil ist da, Sie können sich auf den Teil
+konzentrieren, für den Sie sich gerade interessieren und
+werden nicht durch andere Informationen abgelenkt. An­
+dererseits können Sie jederzeit auch an die Funktionen
+und Informationen gelangen, die gerade nicht sichtbar
+sind.
+ Sie haben sicher bemerkt, daß nicht nur innerhalb der
+Kopfzeile ein Begriff invers dargestellt ist, sondern
+auch einer innerhalb jedes Pull-Down-Menus. Nachdem man
+sich für einen Oberbegriff entschieden hat, kann man
+nämlich noch zwischen den Funktionen innerhalb des
+Pull-Down-Menus wählen.
+ Da das Pull-Down-Menu zum Oberbegriff 'Archiv' noch
+einige Besonderheiten aufweist, wollen wir uns die Funk­
+tionsweise zuerst am Pull-Down-Menu unter dem Oberbe­
+griff 'Dateien' verdeutlichen. Bitte wechseln Sie deshalb
+durch Betätigung der Pfeiltaste <links> oder <rechts> zum
+ersten Pull-Down-Menu zurück.
+ Ähnlich wie in der Kopfzeile, können Sie auch inner­
+halb des Pull-Down-Menus zu einem anderen Punkt wech­
+seln. Das geschieht durch die Pfeiltasten <hoch> und
+<runter>. Dabei werden 'Trennlinien' innerhalb des Pull-
+Down-Menus, die nur der Untergliederung dienen, über­
+sprungen. Vom obersten Menupunkt gelangt man direkt
+zum untersten und umgekehrt. Probieren Sie es einmal
+aus.
+
+
+- Informationen zu einem Menupunkt.
+
+ Zu jedem Punkt eines Pull-Down-Menus können Sie In­
+formationen abrufen. Das ist ganz einfach, denn Sie
+brauchen sich nur auf den gewünschten Menupunkt zu
+begeben (die Pfeiltasten so betätigen, bis der betreffende
+Menupunkt im Pull-Down-Menu invers dargestellt wird).
+Anschließend betätigen Sie die Fragezeichentaste (<?>).
+ Auf dem Bildschirm erscheint ein Kasten in den die
+Informationen zum Menupunkt eingetragen sind. Zwar wird
+dadurch ein Teil des Bildschirms überschrieben, doch kei­
+ne Angst - sobald Sie auf irgendeine Taste tippen, wird
+der alte Bildschirmzustand wieder hergestellt! Ebenso wie
+die Pull-Down-Menus sind diese Informationen normaler­
+weise verborgen. Auf Anforderung werden sie aber sicht­
+bar - ja es wäre gar nicht möglich alle vorhandenen In­
+formationen gleichzeitig auf dem Bildschirm darzustel­
+len. Es wäre auch unsinnig, denn man benötigt diese In­
+formationen zumeist nur, wenn man sich in das Programm
+einarbeitet. Später, wenn Ihnen der Umgang mit dem Pro­
+gramm vertraut ist, sind diese Informationen überflüssig
+und würden, wenn sie immer sichtbar wären, nur stören.
+
+
+- Informationen zur Bedienung des Menus
+
+ Alles das, was hier ausführlich beschrieben ist, kön­
+nen Sie auch in Kurzform auf dem Bildschirm erfahren,
+denn auch die Informationen, wie das Menu bedient wird,
+sind jeweils im Menu vorhanden. Möchten Sie diese Infor­
+mationen auf dem Bildschirm sehen, so tippen Sie die
+Tastenfolge <ESC><?>, d.h. erst die Taste 'ESC' und dann die
+Fragezeichentaste. Danach erscheint folgender Kasten
+auf dem Bildschirm:
+
+#on("b")#
+ +---------------------------------------+
+ | gs-DIALOG |
+ | |
+ | e ... Erläuterungen (allgemein) |
+ | w ... Wahl eines Menupunktes |
+ | a ... Aktivieren des Menupunktes |
+ | b ... Besondere Tasten / Menuende |
+ | |
+ | z ... Zurück in das Menu |
+ | |
+ | e w a b z |
+ +---------------------------------------+
+#off("b")#
+
+ Wenngleich die Informationen kurz gefaßt sind, so
+haben sie doch nicht alle gleichzeitig auf dem Bildschirm
+Platz. Aus diesem Grunde werden Sie aufgefordert, sich
+weiter zu entscheiden, welche Informationen Sie haben
+möchten. Sie können zwischen mehreren Alternativen wäh­
+len. Die Reihenfolge spielt keine Rolle; Sie können auch
+Informationen mehrmals aufrufen.
+ Der Aufruf kann auf zweierlei Weise erfolgen: Entwe­
+der Sie bewegen mit den Pfeiltasten <links> oder <rechts>
+die Markierung in der letzten Zeile des Kastens auf den
+Buchstaben, der vor dem von Ihnen gewünschten Punkt
+steht und tippen anschließend auf die <RETURN>-Taste
+oder Sie tippen direkt die entsprechende Buchstabentaste
+(z.B. <e>). Beide Vorgehensweisen sind zulässig und haben
+die gleiche Wirkung.
+ Daraufhin werden die gewünschten Informationen
+sichtbar. Durch Tippen irgendeiner Taste verschwinden
+die Informationen wieder vom Bildschirm und sichtbar
+wird wieder der oben abgebildete 'Verteiler'. Erst wenn
+man den Punkt 'z ... Zurück in das Menu' wählt, verschwin­
+det auch dieser Kasten und man gelangt zurück in das
+Menu.
+
+
+- Aktivierbare und nicht aktivierbare Menupunkte
+
+ Wir wollen jetzt endlich unserer Absicht nachgehen,
+eine Datei vom Archiv zu holen. Dazu wechseln wir zuerst
+wieder zum Oberbegriff 'Archiv' in der Kopfzeile. Nach
+kurzer Zeit erscheint das Ihnen schon bekannte Pull-
+Down-Menu. Wenn Sie hier versuchen, die einzelnen Menu­
+punkte innerhalb des Pull-Down-Menus anzusteuern, so
+werden Sie feststellen, daß das nicht möglich ist. Alle
+Menupunkte, die ein Minuszeichen ('-') vor der Bezeichnung
+haben, können nicht angewählt werden. Diese Menupunkte
+sind zur Zeit nicht aktivierbar. Solche Menupunkte kön­
+nen in Menus häufiger auftreten.
+ Das kann mehrere Ursachen haben: Einerseits könnte
+auf diese Weise ein Programmierer ein komplettes Menu
+entwerfen, das schon alle Funktionen zeigt, wenn auch die
+zugehörigen Programme dazu noch nicht fertig sind. Das
+ist aber in unserem Falle nicht so. Hier ist die Ursache
+eine andere: Bevor man im EUMEL-System auf das Archiv­
+laufwerk zugreifen kann, muß man es erst für sich re­
+servieren. Dadurch wird sichergestellt, daß nicht gleich­
+zeitig mehrere Benutzer auf eine Archivdiskette zugrei­
+fen und ggf. Dateien unbeabsichtigt zerstören. Erst wenn
+das Laufwerk reserviert worden ist, kann man auf die
+Diskette zugreifen. Das wird im Menu durch die nicht ak­
+tivierbaren Punkte zum Ausdruck gebracht.
+
+
+- Aktivieren von Menupunkten
+
+ Wir müssen also zuerst das Archiv reservieren. Auch
+hier gibt es (zumeist) zwei Möglichkeiten, den gewünsch­
+ten Menupunkt zu aktivieren. Entweder Sie sorgen durch
+Bedienung der Pfeiltasten dafür, daß der gewünschte
+Menupunkt invers dargestellt wird und betätigen an­
+schließend die <RETURN>-Taste oder - sofern vor dem Me­
+nupunkt ein einzelner Buchstabe oder eine Ziffer aufge­
+listet ist - tippen Sie einfach auf die zugehörige Buch­
+staben- oder Zifferntaste. Tippen Sie hier die Taste <r>.
+ Warten Sie einen Moment, denn es wird überprüft, ob
+das Laufwerk von einer anderen Task benutzt wird. Ist
+dies der Fall, erhalten Sie darüber auf dem Bildschirm
+eine Meldung. Ansonsten wird an Sie die Frage gerichtet,
+ob die Diskette eingelegt ist. Wenn diese Frage erscheint,
+befindet sich das Laufwerk schon "in Ihrem Besitz". Erst
+jetzt ist es sinnvoll, wenn auch andere auf das Laufwerk
+zugreifen können, die Diskette in das Laufwerk zu legen.
+Erst wenn die Frage auf dem Bildschirm erscheint, können
+Sie sicher sein, daß keine andere Task mehr auf das Lauf­
+werk zugreifen kann. Legen Sie also beim Erscheinen der
+Frage eine Ihrer EUMEL-Archivdisketten in das Laufwerk
+und bejahen Sie anschließend die gestellte Frage, indem
+Sie die Taste <j> tippen. (Sie können aber auch - wie schon
+in vorausgehenden Situationen - die Inversdarstellung
+innerhalb des Kastens, in dem die Frage auf dem Bild­
+schirm dargestellt wird, auf das 'Ja' positionieren und
+anschließend die <RETURN>-Taste tippen.)
+ #on("b")#gs-DIALOG#off("b")# ermittelt jetzt den Namen der eingelegten
+Diskette und zeigt diesen im Kasten rechts unten auf dem
+Bildschirm an. Außerdem werden die zuvor nicht aktiver­
+baren Punkte aktivierbar gemacht. Das kann man daran
+erkennen, daß auf dem Bildschirm die Minuszeichen vor
+den betreffenden Menupunkten verschwinden (und Buch­
+staben sichtbar werden).
+ Lassen Sie sich zunächst ein Inhaltsverzeichnis der
+Diskette anzeigen. Dazu brauchen Sie nur den Menupunkt
+'v Verzeichnis' wählen. Wie das gemacht wird wissen Sie ja
+schon. Sie können dabei beobachten, daß vor dem Menu­
+punkt das bisherige Zeichen verschwindet und ein Stern
+(*) sichtbar wird. Daran kann man erkennen, daß #on("b")#gs-DIALOG#off("b")#
+den Auftrag bereits ausführt.
+ Es dauert einen Moment, bis das Verzeichnis erstellt
+ist - anschließend wird es auf dem Bildschirm ausgegeben.
+Paßt das Verzeichnis nicht vollständig auf den Bild­
+schirm, so können Sie sich darin bewegen, blättern etc.,
+wie Sie es aus dem Editor gewohnt sind. Ebenso wird das
+Verzeichnis auch wie der Editor verlassen - durch die
+Tastenfolge <ESC><q> (das wird übrigens auch auf dem
+Bildschirm angezeigt!).
+
+
+- Dateiauswahl
+
+ Sie sollen jetzt eine Datei von der Archivdiskette in
+das System holen, d.h. genauer gesagt von der Diskette
+kopieren. Aktivieren Sie also auf gewohnte Weise den
+Menupunkt 'h Holen/Lesen'. Warten Sie anschließend einen
+Moment, denn #on("b")#gs-DIALOG#off("b")# erstellt eine Liste aller vorhan­
+denen Dateien auf der Diskette und bietet Sie Ihnen an­
+schließend so an, daß Sie komfortabel eine Auswahl tref­
+fen können.
+ Haben Sie die #on("b")#gs-DIALOG#off("b")#-Archivdiskette eingelegt, so
+zeigt sich etwa der folgende Bildschirm:
+
+
+#on("b")#
+ARCHIV: Dateien Archiv
+-------+-------------------------+--------------------------------------
+ +--------------------------------------------------------------------+
+ | Dateien holen/lesen (Archiv) |
+ | |
+ | Bitte alle Dateien ankreuzen, die 'geholt' werden sollen! |
+ |====================================================================|
+ | Auswahl m e h r e r e r Dateien durch Ankreuzen |
+ |....................................................................|
+ |==> o gs-DIALOG MENUKARTEN MANAGER" |
+ | o gs-DIALOG MM/gen |
+ | o gs-DIALOG 1 |
+ | o gs-DIALOG 2 |
+ | o gs-DIALOG 3 |
+ | o gs-DIALOG 4 |
+ | o gs-DIALOG 5 |
+ | o gs-DIALOG 6 |
+ | o gs-DIALOG 7 |
+ | o gs-MENUKARTE:Archiv |
+ |..................................................Weitere Dateien!..|
+ +--------------------------------------------------------------------+
+--|Info: <?> Fertig: <ESC><q> Abbrechen: <ESC><h> |
+In+--------------------------------------------------------------------+
+#off("b")#
+
+
+ Auf dem Archiv sind mehrere Dateien vorhanden. Alle
+werden Ihnen zur Auswahl angeboten. In der obersten
+Zeile wird zur Kontrolle die Funktion angezeigt, die Sie
+gerade gewählt haben. Sie können jetzt die Dateien, auf
+die sich die Operation beziehen sollen, in beliebiger Rei­
+henfolge ankreuzen. Wenn Sie abschließend die Auswahl
+verlassen, werden die Dateien in der Ankreuzreihenfolge
+bearbeitet (hier in die Task geholt).
+ Die Handhabung der Dateiauswahl ist ganz einfach. Der
+Pfeil gibt jeweils an, welche Datei aktuell behandelt
+wird. Zunächst wird vor den Namen jeweils nur ein 'o' aus­
+gegeben. Mit den Pfeiltasten <hoch> und <runter> können
+Sie nun mit dem Pfeil vor den Namen fahren, den Sie an­
+kreuzen möchten. Tippen Sie dann die Taste <x> oder
+<RETURN>, so erscheint in der Anzeige ein 'x' vor dem Na­
+men und eine Zahl, die angibt, die wievielte Datei Sie an­
+gekreuzt haben. Haben Sie sich versehen, so können Sie
+das Kreuz auch wieder löschen. Dazu fahren Sie einfach
+erneut vor den betreffenden Namen, wo ja jetzt ein 'x'
+steht, und tippen die Taste <o> (kleines 'o') oder <RUBOUT>.
+Dadurch wird das Kreuz entfernt und gegebenenfalls eine
+Umnumerierung der schon angekreuzten Dateinamen vor­
+genommen. Verlassen Sie jetzt die Auswahl mit der Tasten­
+folge <ESC><q>, so werden die Dateien nacheinander in der
+von Ihnen angekreuzten Reihenfolge in die Task kopiert.
+ Neben dieser Auswahl, in der #on("u")#m e h r e r e#off("u")# Dateien an­
+gekreuzt (ausgewählt) werden können, gibt es auch eine
+Auswahl, in der nur jeweils #on("u")#e i n e#off("u")# Datei angekreuzt wer­
+den darf. Das ist durch die entsprechende Beschriftung
+auf dem Bildschirm kenntlich gemacht. In einem solchen
+Fall wird die Auswahl nach Ankreuzen eines Namens #on("u")#auto­
+matisch#off("u")# verlassen, d.h. man braucht nicht <ESC><q> zu tip­
+pen!.
+ In einer Dateiauswahl können bis zu 200 Dateien ver­
+waltet werden. Da aber nicht alle Namen gleichzeitig auf
+dem Bildschirm angezeigt werden können, wird jeweils in
+der gepunkteten Zeile angezeigt, ob noch #on("u")#weitere Dateien#off("u")#
+in der Liste vorausgehen oder folgen. In unserem Beispiel
+geht als keine Datei voraus, es folgen aber noch weitere
+Dateien hinter der zuletzt angezeigten Datei.
+ Damit Sie noch komfortabler mit dieser Dateiauswahl
+arbeiten können, gibt es weitere Tastenfolgen die nütz­
+lich sein können. Wenn Sie die Fragezeichentaste (<?>) tip­
+pen, werden Sie auf dem Bildschirm angezeigt. Durch Tip­
+pen irgendeiner weiteren Taste können Sie weiterblättern
+bzw. in die Auswahl zurückgelangen. Folgende Tastenkom­
+mandos stehen Ihnen zur Verfügung:
+
+
+ Positionierungen:
+
+ hoch : zum vorausgehenden Namen
+ runter : zum folgenden Namen
+ HOP hoch : auf den ersten Namen der Seite
+ HOP runter : auf den letzten Namen der Seite
+ ESC 1 : auf den ersten Namen der Liste
+ ESC 9 : auf den letzten Namen der Liste
+
+
+ Auswahl treffen:
+
+ RETURN / x : diesen Namen ankreuzen
+(RUBOUT / o : Kreuz vor dem Namen löschen )
+(HOP RETURN/HOP x: alle folgenden Namen ankreuzen)
+(HOP RUBOUT/HOP o: alle folgenden Namen löschen )
+
+
+ Auswahl verlassen:
+
+ ESC q : Auswahl verlassen
+ ESC h : Auswahl abbrechen
+
+
+
+ Die in Klammern gesetzten Tastenfunktionen kann man
+nur verwenden, wenn die Auswahl #on("u")#mehrerer#off("u")# Dateien zuge­
+lassen ist.
+ Wie Sie sehen, orientiert sich die Bedienung an den
+Tastenfunktionen, die Ihnen schon aus dem Editor be­
+kannt sind. Haben Sie aus Versehen einen Menupunkt ge­
+wählt, so daß Ihnen eine solche Auswahl angeboten wird,
+so können Sie die Auswahl durch <ESC><h> (für 'halt') ab­
+brechen.
+
+
+- Ja/Nein - Fragen
+
+ An verschiedenen Stellen werden Fragen an Sie ge­
+richtet, die Sie mit 'ja' oder 'nein' beantworten müssen.
+Tippen Sie dazu entsprechend je nach Entscheidung die
+Taste <j> (für 'ja') bzw. <n> (für 'nein').
+
+
+- Eingaben
+
+ An einigen Stellen werden Sie aufgefordert, eine Ein­
+gabe zu machen (z.B. einen Dateinamen einzugeben). Sofern
+möglich wird Ihnen auch ein Vorschlag für die Eingabe
+gemacht (z.B. wenn Sie Dateien kopieren oder umbenennen
+wollen). Wenn Sie den gemachten Vorschlag akzeptieren,
+dann brauchen Sie zur Bestätigung nur die <RETURN>-
+Taste zu tippen.
+ Gefällt Ihnen der Vorschlag nicht oder wird Ihnen
+kein Vorschlag gemacht, so machen Sie bitte die ge­
+wünschte Angabe. Zum Schreiben stehen Ihnen alle aus dem
+Editor bekannten Funktionen zur Verfügung. Mit der
+Taste <RUBOUT> können Sie Buchstaben löschen, mit
+<RUBIN> einfügen. Die Eingabe wird durch Tippen der
+<RETURN>-Taste abgeschlossen.
+ Ist der von Ihnen gewünschte Name schon in Ihrer Task
+vorhanden und steht in der Fußzeile der Hinweis 'Zeigen:
+<ESC><z>', dann können Sie sich auch alle vorhandenen
+Namen zur Auswahl anbieten lassen und durch Ankreuzen
+den beabsichtigten Namen auswählen.
+
+
+- Alternativen
+
+ Ihnen können auch mehrere Alternativen angeboten
+werden, zwischen denen Sie wählen müssen. In der unter­
+sten Zeile eines solchen Kastens, in denen Ihnen die Al­
+ternativen auf dem Bildschirm eingeblendet werden, sind
+die Möglichkeiten aufgeführt, die darüber beschreiben
+sind. Mit den Pfeiltasten können sie die Markierung auf
+die gewünschte Alternative positionieren und dann durch
+die <RETURN>-Taste zur Ausführung bringen. (Manchmal
+ist das auch durch Tippen der den Alternativen vorange­
+stellten Buchstaben oder Ziffern möglich).
+
+
+- Verlassen des Menus
+
+ Das Menu kann insgesamt mit der Tastenfolge <ESC><q>
+verlassen werden. Damit das nicht versehentlich ge­
+schieht, wird zur Sicherheit die Frage gestellt, ob Sie das
+Menu tatsächlich verlassen wollen. Verneinen Sie die
+Frage, verbleiben Sie im Menu, ansonsten gelangen Sie
+zurück in die 'gib kommando:' - Ebene.
+
+ Mit dieser Beispielsitzung haben Sie jetzt schon fast
+alle Arten des Umgangs mit #on("b")#gs-DIALOG#off("b")# kennengelernt.
+Sicher ist dies beim ersten Mal sehr verwirrend. Mit den
+folgenden vier grundsätzlichen Regeln können Sie
+#on("b")#gs-DIALOG#off("b")# aber immer bedienen:
+
+ 1. Achten Sie darauf, welche Tastenkombinationen in
+ der Fußzeile angegeben sind. Halten Sie sich daran!
+
+ 2. Rufen Sie - sofern vorhanden - die Hilfsfunktio­
+ nen mit <?> oder <ESC><?> auf. Damit erhalten Sie
+ weitere Informationen.
+
+ 3. Funktioniert eine Tastenkombination nicht (geben
+ Sie dem Rechner eine kurze Zeit zum Reagieren),
+ versuchen Sie die Tastenkombination <ESC><q> (Ver­
+ lassen) oder <ESC><h> (Abbruch). Falls sich darauf­
+ hin etwas ändert, verfahren Sie wie unter 1).
+
+ 4. Erfolgt noch immer keine Reaktion, tippen Sie die
+ <SV>-Taste und versuchen Sie das Programm mit
+ 'halt' zu stoppen. Führt auch das nicht zum Erfolg,
+ hat sich der Rechner "aufgehängt". Wenn Sie keine
+ Erfahrungen mit einer solchen Situation haben,
+ wenden Sie sich an Ihren Systembetreuer.
+
+
+3.3 Zusammenfassung/Kurzbeschreibung
+
+Menu: Sie können jede (aktive) Funktion inner­
+ halb eines Pull-Down-Menus mit den
+ Pfeiltasten anwählen und durch Tippen
+ der <RETURN>-Taste zur Ausführung
+ bringen. (Ersatzweise kann - sofern vor
+ dem Menupunkt ein Buchstabe oder eine
+ Ziffer angegeben ist - die Funktion
+ durch Tippen der entsprechenden Taste
+ direkt zur Ausführung gebracht werden.)
+ Zu jeder Funktion kann durch Tippen der
+ Fragezeichentaste eine Hilfestellung
+ angefordert werden. Gibt man die Tasten­
+ folge <ESC><?>, so wird die Bedienung des
+ Menus auf dem Bildschirm kurz erläutert.
+ Mit der Tastenfolge <ESC><q> wird das
+ Menu (nach einer Sicherheitsabfrage)
+ verlassen.
+
+Dateiauswahl: Hier können Sie die gewünschten Namen
+ mit <x> ankreuzen und das Kreuz mit <o>
+ wieder entfernen. Die Auswahl - sofern
+ mehrere Dateien ausgewählt werden kön­
+ nen - wird durch die Tastenfolge
+ <ESC><q> verlassen. Alle Möglichkeiten
+ der Bedienung werden angezeigt, wenn die
+ Fragezeichentaste getippt wird. Die Aus­
+ wahl wird abgebrochen (ohne Kreuze!),
+ wenn die Tastenfolge <ESC><h> eingege­
+ ben wird.
+
+Eingabe: Hier können Sie eine Zeile eingeben oder
+ eine Vorgabe ändern (wie im Editor). Ein­
+ fügen und Löschen mit RUBIN und RUBOUT.
+ Ist in der Fußzeile die Tastenfolge
+ '<ESC><z>: Zeigen' angegeben, so können
+ Sie darüber auch eine Auswahl anfor­
+ dern, in der Sie bereits vorhandene Na­
+ men nur anzukreuzen brauchen. Zumeist
+ ist auch ein Abbruch der Eingabe durch
+ die Tastenfolge <ESC><h> möglich.
+
+Frage: Beantworten Sie die an Sie gerichtete
+ Frage mit <j> oder <n>. Sie können auch
+ auf dem Bildschirm die Markierung auf
+ die gewünschte Antwort setzten und an­
+ schließend die <RETURN>-Taste tippen.
+
+Alternativen: Aus den angegebenen Möglichkeiten kön­
+ nen Sie eine auswählen, indem Sie entwe­
+ der die der Alternative vorangestellte
+ Taste tippen oder in der letzten Zeile des
+ Kastens die Markierung auf die ge­
+ wünschte Kennzeichnung positionieren
+ und anschließend die <RETURN>-Taste
+ tippen.
+
+Fehler: Die Meldung muß durch Tippen einer be­
+ liebigen Taste quittiert werden.
+
+Bitte warten: Der Rechner ist beschäftigt - keine
+ Taste tippen!
+
+
diff --git a/doc/dialog/gs-dialog-4 b/doc/dialog/gs-dialog-4
new file mode 100644
index 0000000..03d8dc4
--- /dev/null
+++ b/doc/dialog/gs-dialog-4
@@ -0,0 +1,672 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (30)#
+#headodd#
+#center#gs-DIALOG#right#%
+
+#end#
+#headeven#
+%#center#gs-DIALOG
+
+#end#
+#center#4
+
+#center#Beschreibung der Menufunktionen
+
+
+4.1 Menufunktionen zum Oberbegriff 'Dateien'
+
+ In diesem Kapitel werden alle die Menufunktionen be­
+schrieben, die Ihnen unter dem Obergeriff 'Dateien' im
+Menu angeboten werden.
+
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich einen Über­
+ blick über die in Ihrer Task vorhandenen Dateien ver­
+ schaffen.
+ Nach Aufruf dieser Funktion wird eine Liste der
+ Dateien auf dem Bildschirm ausgegeben, die sich in
+ Ihrer Task befinden. Da die Liste selbst eine Datei ist,
+ kann sie mit der Tastenkombination <ESC><q> verlassen
+ werden - hierauf wird auch in der Kopfzeile der Datei
+ hingewiesen. Falls nicht alle Dateien auf den Bild­
+ schirm passen, können Sie das Fenster mit <HOP><hoch>
+ bzw. <HOP><runter> rollen.
+
+#on("u")##on("b")#l Löschen#off("b")##off("u")#
+ Mit dieser Funktion können Sie Dateien, die Sie
+ nicht mehr benötigen, die unnötig Platz belegen, lö­
+ schen. Aber Vorsicht! Die Dateien verschwinden durch
+ diese Funktion unwiederbringlich!
+ Zunächst wird der Dateiname der Datei erfragt, die
+ gelöscht werden soll. Hier können Sie direkt den be­
+ treffenden Namen eingeben und die Eingabe mit
+ <RETURN> abschließen. Sie können sich aber auch durch
+ die Tastenfolge <ESC><z> (für 'zeigen') alle in der Task
+ vorhandenen Dateien zur Auswahl anbieten lassen und
+ dort einfach einen Namen ankreuzen.
+ Für jede einzelne Datei wird noch einmal zur
+ Sicherheit angefragt, ob diese auch tatsächlich ge­
+ löscht werden soll. Zur Bestätigung tippen Sie bitte
+ die Taste <j> ('ja') - zur Verhinderung die Taste <n>
+ ('nein').
+
+ Fehlerfälle:
+ - Eine Datei mit dem angegebenen Namen existiert
+ nicht.
+
+#on("u")##on("b")#d Drucken#off("b")##off("u")#
+ Mit dieser Funktion können Sie Dateien über einen
+ angeschlossenen Drucker ausdrucken lassen.
+ Zunächst wird der Dateiname der Datei erfragt, die
+ gedruckt werden soll. Hier können Sie direkt den be­
+ treffenden Namen eingeben und die Eingabe mit
+ <RETURN> abschließen. Sie können sich aber auch durch
+ die Tastenfolge <ESC><z> (für 'zeigen') alle in der Task
+ vorhandenen Dateien zur Auswahl anbieten lassen und
+ dort einfach einen Namen ankreuzen.
+ Die Datei(en) wird/werden anschließend zum Drucker
+ geschickt. Der Vorgang wird auf dem Bildschirm proto­
+ kolliert.
+
+ Fehlerfälle:
+ - Eine Datei mit dem angegebenen Namen existiert
+ nicht.
+ - Die Druckdatei hat einen falschen Typ zum Drucken
+ (ist nicht editierbar).
+ - Der Drucker ist nicht funktionsbereit.
+ - Der Drucker wird nicht über die Task 'PRINTER' be­
+ trieben.
+ - Auf Ihrem System werden die Druckkosten abge­
+ rechnet. Sie müssen sich mit einer Codenummer
+ identifizieren.
+
+#on("u")##on("b")#k Kopieren#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich eine (logische)
+ Kopie einer bereits im System vorhandenen Datei anle­
+ gen. Das ist z.B. dann sinnvoll, wenn Sie sich einen
+ bestimmten Stand einer Datei aufbewahren wollen.
+ Zunächst wird der Dateiname der Datei erfragt, die
+ kopiert werden soll. Hier können Sie direkt den be­
+ treffenden Namen eingeben und die Eingabe mit
+ <RETURN> abschließen. Sie können sich aber auch durch
+ die Tastenfolge <ESC><z> (für 'zeigen') alle in der Task
+ vorhandenen Dateien zur Auswahl anbieten lassen und
+ dort einfach einen Namen ankreuzen.
+ Anschließend wird dieser Name angezeigt und der
+ Name für die Kopie erfragt. Es muß ein Name eingetra­
+ gen werden, der in dieser Task noch nicht für eine
+ Datei vergeben wurde; ansonsten erfolgt ein Hinweis
+ darauf und es wird nicht kopiert!
+ Da man aber oft für die Kopie einen ähnlichen Na­
+ men wie für das Original wählt, wird der 'alte' Name
+ vorgeschlagen. Aus genannten Gründen muß er aber
+ verändert werden. Sie können diesen Namen mit den
+ üblichen Editierfunktionen verändern oder mit
+ <HOP><RUBOUT> löschen und ganz neu eingeben. Auf
+ diese Weise sparen Sie aber eine Menge Tipparbeit,
+ wenn Sie einen langen Namen nur an einer Stelle än­
+ dern wollen.
+
+ Fehlerfälle:
+ - Eine Datei mit dem angegebenen Namen existiert
+ nicht.
+ - Eine Datei mit dem gewünschten Namen existiert
+ bereits in der Task.
+
+#on("u")##on("b")#u Umbenennen#off("b")##off("u")#
+ Mit dieser Funktion können Sie einer bereits vor­
+ handenen Datei einen neuen Namen geben.
+ Zunächst wird der Dateiname der Datei erfragt, die
+ umbenannt werden soll. Hier können Sie direkt den
+ betreffenden Namen eingeben und die Eingabe mit
+ <RETURN> abschließen. Sie können sich aber auch durch
+ die Tastenfolge <ESC><z> (für 'zeigen') alle in der Task
+ vorhandenen Dateien zur Auswahl anbieten lassen und
+ dort einfach einen Namen ankreuzen.
+ Anschließend wird dieser Name angezeigt und der
+ zukünftige Name für die Datei erfragt. Es muß ein
+ Name eingetragen werden, der in dieser Task noch
+ nicht für eine Datei vergeben wurde; ansonsten er­
+ folgt ein Hinweis darauf und die Datei wird nicht
+ umbenannt!
+ Da man aber oft den 'neuen' Namen in Anlehnung an
+ den 'alten' Namen wählt, wird der 'alte' Name vorge­
+ schlagen. Aus genannten Gründen muß er aber verän­
+ dert werden. Sie können diesen Namen mit den üblichen
+ Editierfunktionen verändern oder mit <HOP><RUBOUT>
+ löschen und ganz neu eingeben. Auf diese Weise sparen
+ Sie aber eine Menge Tipparbeit, wenn Sie einen langen
+ Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Datei mit dem angegebenen Namen existiert
+ nicht.
+ - Eine Datei mit dem gewünschten Namen existiert
+ bereits in der Task.
+
+#on("u")##on("b")#s Speicherplatz#off("b")##off("u")#
+ Mit dieser Funktionen können Sie sich zu Ihrer
+ Information den Speicherbedarf anzeigen lassen, den
+ eine Datei auf dem Speichermedium einnimmt.
+ Zunächst wird der Dateiname der Datei erfragt,
+ deren Speicherplatz ermittelt werden soll. Hier kön­
+ nen Sie direkt den betreffenden Namen eingeben und
+ die Eingabe mit <RETURN> abschließen. Sie können sich
+ aber auch durch die Tastenfolge <ESC><z> (für 'zeigen')
+ alle in der Task vorhandenen Dateien zur Auswahl
+ anbieten lassen und dort einfach einen Namen ankreu­
+ zen.
+ Anschließend wird der belegte Speicherplatz der
+ ausgewählten Datei(en) auf dem Bildschirm angezeigt.
+ Die Größe wird in KB (Kilobyte) angegeben. Ein KB ent­
+ spricht etwa 1000 Zeichen, also einer halb vollge­
+ schriebenen Bildschirmseite.
+
+ Fehlerfälle:
+ - Eine Datei mit dem angegebenen Namen existiert
+ nicht.
+
+#on("u")##on("b")#a Aufräumen#off("b")##off("u")#
+ Wenn in einer Datei viel geändert wurde, wird der
+ Platzbedarf dieser Datei erheblich vergrößert ("Text­
+ leichen"). Dies tritt vor allem dann auf, wenn sehr
+ häufig eingefügt wurde. Da der Platzbedarf der Datei
+ zunimmt, sind mehr Speicherzugriffe notwendig, als es
+ dem Inhalt entspricht. Zudem führt die interne Orga­
+ nisation einer solchen Datei zu Einbußen bei der Bear­
+ beitungsgeschwindigkeit.
+ Mit dieser Funktion wird die Datei in eine "fri­
+ sche" Datei gewandelt. Diesen Vorgang nennt man 'Re­
+ organisieren' (Aufräumen). Anschließend belegt die
+ Datei zumeist (erheblich) weniger Speicherplatz als
+ zuvor.
+ Diese Funktion ist allerdings nur mit einer Ein­
+ schränkung nutzbar. Sie läßt sich nur auf Textdateien
+ anwenden, nicht auf andere Dateitypen. Das System
+ nimmt aber die Unterscheidung in Dateitypen automa­
+ tisch vor - allerdings kann es vorkommen, daß Sie den
+ Hinweis erhalten: "... kann nicht aufgeräumt werden!".
+ Zunächst wird der Dateiname der Datei erfragt, die
+ aufgeräumt (reorganisiert werden soll. Hier können
+ Sie direkt den betreffenden Namen eingeben und die
+ Eingabe mit <RETURN> abschließen. Sie können sich
+ aber auch durch die Tastenfolge <ESC><z> (für 'zeigen')
+ alle in der Task vorhandenen Dateien zur Auswahl
+ anbieten lassen und dort einfach einen Namen ankreu­
+ zen.
+ Anschließend wird/werden die ausgewählte(n) Da­
+ tei(en) aufgeräumt (reorganisert). #on("u")#Achtung! Die Funk­
+ tion ist zeitaufwendig!#off("u")#
+
+ Fehlerfälle:
+ - Eine Datei mit dem angegebenen Namen existiert
+ nicht.
+#page#
+4.2 Menufunktionen zum Oberbegriff 'Archiv'
+
+ In diesem Kapitel werden alle die Menufunktionen be­
+schrieben, die Ihnen unter dem Oberbegriff 'Archiv' im
+Menu angeboten werden. Mit den Funktionen in diesem
+Menu können Sie aber nicht nur Dateien auf dem Archiv
+behandeln, sondern auch in anderen Tasks im Multi-
+User-System oder über das EUMEL-Netz sogar auf anderen
+Rechnern!
+ Wenn Sie das Pull-Down-Menu (siehe Seite 12) gerade
+aufgeschlagen haben, sind nicht alle Funktionen akti­
+vierbar! Um weitere Funktionen zu aktivieren, muß erst
+einer der aktivierbaren Menupunkte ausgeführt werden.
+
+#on("u")##on("b")#r Reservieren#off("b")##off("u")# (des Archivlaufwerks)
+ Im EUMEL-Multi-User-System haben normalerweise
+ mehrere Personen das Zugriffsrecht auf das Archiv­
+ laufwerk. Allerdings muß der Zugriff so geregelt wer­
+ den, daß sich die Beteiligten dabei nicht gegenseitig
+ "in die Quere kommen". Ein Zugriff auf das Archiv­
+ laufwerk erfordert zunächst eine Anmeldung. Ist diese
+ Anmeldung erfolgt, kann von den anderen Beteiligten
+ nicht mehr auf das Laufwerk zugegriffen werden - bis
+ es wieder freigegeben worden ist.
+ Diese Anmeldung des Archivlaufwerkes erfolgt
+ über die Menufunktion 'r Reservieren'. Greift bereits
+ eine andere Task auf das Laufwerk zu, so erhalten Sie
+ darüber einen Hinweis auf dem Bildschirm. Ansonsten
+ wird an Sie die Frage gestellt, ob die Diskette einge­
+ legt und das Laufwerk geschlossen ist.
+ Erst zu diesem Zeitpunkt ist sichergestellt, daß Sie
+ den alleinigen Zugriff auf das Laufwerk haben. Des­
+ halb sollten Sie, wenn Sie mit mehreren Personen am
+ Computer arbeiten, erst zum Zeitpunkt der Fragestel­
+ lung die Diskette ins Laufwerk einlegen.
+ Nachdem Sie die Diskette eingelegt und die Frage
+ bejaht haben, ermittelt das System selbständig den
+ Namen der eingelegten Diskette, zeigt den Namen auf
+ dem Bildschirm (im kleinen Kasten rechts unten) an und
+ aktiviert die anderen Menupunkte des Pull-Down-
+ Menus.
+ #on("u")#Beim Verlassen des Pull-Down-Menus, wenn eine
+ andere Zieltask eingestellt wird oder wenn das Menu
+ gänzlich verlassen wird, wird die Reservierung auto­
+ matisch aufgehoben!#off("u")#
+
+ Fehlerfälle:
+ - Das Laufwerk ist von einer anderen Task belegt.
+ - Die Diskette ist falsch eingelegt oder das Lauf­
+ werk ist nicht richtig geschlossen.
+ - Die Diskette ist nicht formatiert bzw. initiali­
+ siert.
+ - Die Diskette kann nicht gelesen werden (keine
+ EUMEL-Diskette, Diskette hat ein falsches Format,
+ Diskette ist verschmutzt...).
+
+#on("u")##on("b")#n Neue Diskette#off("b")##off("u")# (anmelden)
+ Der Dateiaustausch mit einer Diskette ist nur dann
+ möglich, wenn der im System eingestellte Diskettenna­
+ me (auf dem Bildschirm im kleinen Kasten unten rechts
+ sichtbar) mit dem tatsächlichen Namen der Diskette
+ übereinstimmt. Nach einem Diskettenwechsel ist das
+ aber in der Regel nicht mehr der Fall. Greift man dann
+ auf die neu eingelegte Diskette zu, so erscheint die
+ Fehlermeldung: 'Falscher Archivname! Bitte neue Dis­
+ kette anmelden!'.
+ Das Anmelden einer neuen Diskette - ohne einen
+ neuen Reserviervorgang - wird durch diese Menufunk­
+ tion ermöglicht. Nach Aktivieren dieses Menupunktes
+ wird der Name der eingelegten Diskette ermittelt, im
+ System eingestellt und auf dem Bildschirm angezeigt.
+ Im Gegensatz zur Menufunktion 'r Reservieren'
+ greift #on("b")#gs-DIALOG#off("b")# ohne Anfrage an den Benutzer auf
+ das Archivlaufwerk zu (die Reservierung bleibt ja
+ bestehen). Ist das Archivlaufwerk reserviert, so ist
+ die Neuanmeldung einer Diskette über diese Menufunk­
+ tion weniger zeitaufwendig.
+
+ Fehlerfälle:
+ - wie unter 'r Reservieren'
+
+#on("u")##on("b")#s Schreiben#off("b")##off("u")# (Kopieren)
+ Alle Dateien der eigenen Task werden zur Auswahl
+ angeboten. Wenn Sie die Auswahl durch die Tastenfolge
+ <ESC><q> verlassen, überprüft #on("b")#gs-DIALOG#off("b")# zunächst, ob
+ die Dateien in der eingestellten Zietask schon vor­
+ handen sind. Ist das der Fall, erfragt #on("b")#gs-DIALOG#off("b")#, ob
+ die dort vorhandenen Dateien überschrieben, d.h. ge­
+ löscht werden dürfen (s.u.). Anschließend werden alle
+ angekreuzten Dateien in der Reihenfolge, in der Sie
+ sie angekreuzt haben, in die eingestellte Zieltask
+ kopiert. Der Vorgang wird auf dem Bildschirm proto­
+ kolliert. Die Originaldateien in der eigenen Task
+ bleiben dabei erhalten.
+ Wenn in der Zieltask schon eine Datei existiert, die
+ den gleichen Namen hat wie eine Datei, die Sie dorthin
+ kopieren möchten, so wird angefragt, ob die vorher
+ schon existierende Datei überschrieben (gelöscht!)
+ werden soll. Bejahen Sie diese Frage, so wird die be­
+ reits in der Zieltask existierende Datei (unwieder­
+ bringlich) gelöscht und die gewünschte Datei dorthin
+ transportiert. Ein Überschreiben aus Versehen ist
+ nicht möglich, wenn Sie die an Sie gestellte Frage
+ sorgfältig beantworten.
+ Verneinen Sie die Frage, so wird die Datei auch
+ nicht hinübertransportiert! Sie können die Datei aber
+ umbenennen (Menufunktion 'u Umbenennen' unter dem
+ Oberbegriff 'Dateien') und anschließend mit anderem
+ Namen hinüberschreiben.
+ Beachten Sie, daß beim Überschreiben einer Datei
+ auf einer Archivdiskette der Speicherplatz der alten
+ (überschriebenen) Version im allgemeinen nicht wie­
+ derverwendet werden kann. In einem solchen Fall
+ könnte die Diskette voll geschrieben werden, obwohl
+ eigentlich genügend Platz vorhanden wäre. Zur Opti­
+ mierung überprüft #on("b")#gs-DIALOG#off("b")# deshalb zuerst, ob die
+ angekreuzten Dateien schon in der Zieltask vorhanden
+ sind und löscht diese, wenn Sie Ihr Einverständnis
+ geben. Erst anschließend werden die Dateien insgesamt
+ kopiert.
+ Normalerweise ist als Zieltask das Archivlaufwerk
+ der eigenen Station eingestellt. Mit der Menufunktion
+ 'z Zieltask einstellen' kann diese Einstellung aber
+ verändert werden.
+
+ Fehlerfälle:
+ - Die Diskette ist falsch eingelegt oder beschädigt.
+ - Die Diskette kann nicht beschrieben werden
+ (Schreibfehler)
+ - Die Diskette ist voll.
+ - Sehen Sie auch unter 'r Reservieren'
+ 'z Zieltask einstellen'
+
+#on("u")##on("b")#c Checken#off("b")##off("u")#
+ Diese Menufunktion kann nur ausgeführt werden,
+ wenn der Dateiaustausch mit einem Archiv(manager)
+ erfolgt - ansonsten ist diese Menufunktion auch
+ nicht aktivierbar. Die Menufunktion dient dazu, auf
+ Diskette geschriebene Dateien auf Lesefehler hin zu
+ prüfen. Es empfiehlt sich, diese Prüfroutine auf neu
+ auf die Diskette geschriebene Dateien anzuwenden.
+ Sehen Sie dazu auch 'k Kombination'
+ Alle Dateien der eingestellten Zieltask (Archiv)
+ werden zur Auswahl angeboten. Wenn Sie die Auswahl
+ durch die Tastenfolge <ESC><q> verlassen, werden alle
+ angekreuzten Dateien in der Reihenfolge, in der Sie
+ sie angekreuzt haben, "gecheckt", d.h. auf Lesefehler
+ hin überprüft. Der Vorgang wird auf dem Bildschirm
+ protokolliert.
+
+ Fehlerfälle:
+ - Lesefehler auf dem Archiv
+ - Sehen Sie auch unter 'r Reservieren'
+
+#on("u")##on("b")#k Kombination#off("b")##off("u")#
+ Diese Menufunktion ist eine Kombination aus den
+ beiden Menufunktionen 's Schreiben' und 'c Checken'
+ (Sehen Sie weitere Informationen auch dort!).
+ Alle Dateien der eigenen Task werden zur Auswahl
+ angeboten. Wenn Sie die Auswahl durch die Tastenfolge
+ <ESC><q> verlassen, werden alle angekreuzten Dateien
+ in der Reihenfolge, in der Sie sie angekreuzt haben,
+ in die eingestellte Zieltask kopiert (gegebenenfalls
+ müssen bereits vorhandene Dateien gleichen Namens in
+ der Zieltask gelöscht werden). Anschließend werden
+ alle Dateien, die gerade geschrieben wurden, gecheckt,
+ d.h. auf Lesefehler hin untersucht. Beide Vorgänge
+ werden auf dem Bildschirm protokolliert.
+ Da die 'Check' - Operation nur bei Archivmanagern
+ zulässig ist, ist diese Menufunktion ebenfalls nur bei
+ Archivmanagern aktivierbar. Zur Erläuterung sehen
+ Sie bitte auch unter 'z Zieltask einstellen'.
+
+#on("u")##on("b")#h Holen/Lesen#off("b")##off("u")#
+ Die Menufunktion dient dazu, Dateien, die bereits
+ auf einer Archivdiskette oder in einer anderen Task
+ existieren, in die eigene Task zu kopieren.
+ Alle Dateien der eingestellten Zieltask werden zur
+ Auswahl angeboten. Anschließend werden Kopien der
+ angekreuzten Dateien in der Reihenfolge des Ankreu­
+ zens in die eigene Task geholt. Das Original in der
+ Zieltask bleibt dabei unverändert! Der Vorgang wird
+ auf dem Bildschirm protokolliert.
+ Sind in der eigenen Task schon Dateien mit glei­
+ chem Namen vorhanden, so wird gefragt, ob die 'alten'
+ Dateien überschrieben (gelöscht) werden dürfen. Nur
+ wenn Sie zustimmen, werden die in Ihrer Task existie­
+ renden Dateien (unwiederbringlich!) gelöscht und Ko­
+ pien der gleichnamigen Dateien aus der Zieltask ange­
+ fertigt.
+ Stimmen Sie dem Löschvorgang nicht zu, dann blei­
+ ben die bisherigen Dateien in Ihrer Task erhalten -
+ die Dateien aus der Zieltask werden dann aber auch
+ nicht in Ihre Task kopiert! Um dennoch die Kopien zu
+ erhalten, können Sie die namensgleichen Dateien in
+ Ihrer Task umbenennen und dann erst die Dateien aus
+ der anderen Task anfordern.
+ Normalerweise werden die Dateien vom Archiv der
+ eigenen Station geholt. Mit dem Menupunkt 'z Zieltask
+ einstellen' kann diese Einstellung verändert werden.
+
+ Fehlerfälle:
+ - Lesefehler auf dem Archiv
+ - Sehen Sie auch unter 'r Reservieren'
+ 's Schreiben'
+ 'z Zieltask einstellen'
+
+#on("u")##on("b")#l Löschen#off("b")##off("u")#
+ Die Menufunktion dient dazu, Dateien in der Ziel­
+ task (unwiederbringlich!) zu löschen. Dazu werden alle
+ Dateien der eingestellten Zieltask zur Auswahl ange­
+ boten. Anschließend werden die angekreuzten Dateien
+ in der Reihenfolge ihres Ankreuzens gelöscht. Zur
+ Sicherheit muß noch einmal für jede einzelne Datei
+ bestätigt werden, daß sie auch tatsächlich gelöscht
+ werden soll.
+ Beachten Sie, daß beim Löschen einer Datei auf ei­
+ ner Archivdiskette der Speicherplatz im allgemeinen
+ nicht wieder verwendet werden kann. In einem solchen
+ Fall könnte die Diskette voll geschrieben werden,
+ obwohl eigentlich genügend Platz vorhanden wäre.
+ Diese Probleme treten bei anderen Tasks, die keine
+ Archivmanager sind, nicht auf, da deren Speicherplatz
+ intelligenter verwaltet wird.
+ Normalerweise ist als Zieltask das Archiv der eige­
+ nen Station eingestellt. Mit dem Menupunkt 'z Zieltask
+ einstellen' kann diese Einstellung verändert werden.
+
+ Fehlerfälle:
+ - Sehen Sie auch unter 'r Reservieren'
+ 's Schreiben'
+ 'z Zieltask einstellen'
+
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie sich einen
+ Überblick über die in der Zieltask (z.B. auf dem Archiv)
+ vorhandenen Dateien verschaffen.
+ Nach Aufruf der Funktion wird eine Liste der Da­
+ teien auf dem Bildschirm ausgegeben, die sich in der
+ Zieltask (z.B. auf dem Archiv) befinden. Ist die Zieltask
+ ein Archiv(manager), so wird auch angezeigt, wieviel
+ Platz auf der Diskette belegt ist. Da die Liste selbst
+ eine Datei ist, kann sie mit der Tastenkombination
+ <ESC><q> verlassen werden. Falls nicht alle Dateinamen
+ auf den Bildschirm passen, können Sie das Fenster mit
+ <HOP><hoch> und <HOP><runter> rollen.
+
+ Fehlerfälle:
+ - Sehen Sie unter 'z Zieltask einstellen'
+
+#on("u")##on("b")#d Drucken#off("b")##off("u")#
+ Das Verzeichnis der Dateien in der Zieltask, das
+ man mit der Menufunktion 'v Verzeichnis' auf dem Bild­
+ schirm angezeigt bekommt, kann mit dieser Menufunk­
+ tion ausgedruckt werden.
+ Zur Sicherheit fragt #on("b")#gs-DIALOG#off("b")# an, ob wirklich ein
+ solches Dateiverzeichnis der Zieltask gedruckt werden
+ soll. Bejaht man die Frage, so wird ein Dateiverzeich­
+ nis erstellt und zum Drucker geschickt.
+
+ Fehlerfälle:
+ - Der Drucker ist nicht funktionsbereit.
+ - Der Drucker wird nicht über die Task 'PRINTER' be­
+ trieben.
+ - Auf Ihrem System werden die Druckkosten abge­
+ rechnet. Sie müssen sich mit einer Codenummer
+ identifizieren.
+
+#on("u")##on("b")#i Initialisieren#off("b")##off("u")#
+ Diese Menufunktion gestattet es, frische Disketten
+ zu formatieren, zu initialisieren bzw. beschriebene
+ Disketten vollständig zu löschen und ggf. dabei umzu­
+ benennen. Bei Aufruf dieser Menufunktion wird - so­
+ fern noch nicht geschehen - das Archivlaufwerk auto­
+ matisch reserviert.
+ Wenn Sie eine fabrikneue Diskette aus der Verpak­
+ kung nehmen, müssen Sie diese zunächst #on("u")#formatieren#off("u")#.
+ Dabei wird die Diskette auf ein festgelegtes physika­
+ lisches Format eingestellt. Ohne daß diese Operation
+ vorausgegangen ist, kann eine Diskette weder be­
+ schrieben noch gelesen werden.
+ Prinzipiell braucht eine Diskette nur ein einziges
+ Mal formatiert zu werden. Sie können Sie jedoch jeder­
+ zeit wieder formatieren - z.B. wenn Sie Disketten ha­
+ ben, von denen Sie nicht genau wissen, für welche
+ Zwecke sie zuvor verwendet wurden.
+ Wenn Sie diese Menufunktion aktivieren, werden Sie
+ zunächst gefragt, ob Sie die Diskette auch formatie­
+ ren wollen. Bejahen Sie die Frage, so werden Ihnen
+ mehrere Formate zur Auswahl angeboten:
+
+#on ("b")#
+ +------------------------------------+
+ | Formatieren einer Diskette |
+ | |
+ | Dies sind die möglichen Formate: |
+ | |
+ | 1 ..... 40 Spur - 360 KB |
+ | 2 ..... 80 Spur - 720 KB |
+ | 3 ..... 5 1/4" - 1,2 MB |
+ | 4 ..... 3 1/2" - 1,4 MB |
+ | s ..... Standard - Format |
+ | |
+ | 1 2 3 4 s |
+ +------------------------------------+
+#off("b")#
+
+ Erkundigen Sie sich bei Ihrem Händler, welches
+ Format Sie bei Ihrem Rechner und den von Ihnen ver­
+ wendeten Disketten einstellen müssen. Manche Rechner
+ unterstützen diese Operation innerhalb des EUMEL-
+ Systems auch gar nicht, das Formatieren muß dann ir­
+ gendwie anders außerhalb des EUMEL-Systems gesche­
+ hen.
+ Wenn Sie die Formatierung abgeschlossen oder auch
+ übersprungen haben, beginnt die eigentliche Initiali­
+ sierung der Diskette. Dabei wird als erstes der Ar­
+ chivname auf die Diskette geschrieben. Alle alten Da­
+ ten, die sich ggf. auf der Diskette befinden, werden
+ auch bei diesem Vorgang unwiederbringlich (!) ge­
+ löscht.
+ Zur Sicherheit überprüft #on("b")#gs-DIALOG#off("b")# in jedem Falle,
+ ob es sich um eine EUMEL - Diskette handelt, und er­
+ fragt Ihr Einverständnis, ob die Diskette wirklich
+ initialisiert werden soll. Geben Sie hierzu Ihr Ein­
+ verständnis, dann erfragt #on("b")#gs-DIALOG#off("b")# noch den (neuen)
+ Archivnamen. Hatte die Diskette schon einen Namen,
+ dann wird dieser zum Überschreiben angeboten. Wollen
+ Sie den alten Archivnamen beibehalten, so brauchen
+ Sie nur die <RETURN>-Taste zu tippen, ansonsten kön­
+ nen Sie den Namen auch zuvor verändern oder einen
+ ganz neuen Namen hinschreiben. Anhand des ausgege­
+ benen Namens können Sie auch überprüfen, ob Sie die
+ richtige Diskette eingelegt haben.
+ Das Initialisieren funktioniert natürlich nur,
+ wenn Sie als Zieltask einen Archivmanager eingestellt
+ haben - ansonsten ist diese Menufunktion gesperrt
+ (nicht aktivierbar!).
+
+ Fehlerfälle:
+ - Formatieren ist nicht auf dem System möglich
+ - Sehen Sie auch unter 'r Reservieren'
+ 'z Zieltask einstellen'
+
+#on("u")##on("b")#z Zieltask einstellen#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie festlegen, mit
+ welcher Zieltask Sie kommunizieren, d.h. z.B. Dateien
+ austauschen möchten. Normalerweise ist hier das Archiv
+ am eigenen Rechner eingestellt. Das wird auch nach
+ Aufklappen des Pull-Down-Menus im Kasten rechts
+ unten angezeigt.
+ Sie können aber auch eine andere Task einstellen
+ (z.B. die Vatertask oder die Task 'PUBLIC'), um mit diesen
+ Dateien auszutauschen oder um sich auch nur einen
+ Überblick über die dort vorhandenen Dateien zu ver­
+ schaffen. Wenn Sie mit Ihrem Rechner in ein EUMEL-Netz
+ integriert sind, können Sie auch auf Tasks anderer
+ Rechner zugreifen oder auch Disketten von Laufwerken
+ anderer Rechner einlesen (z.B. wenn Sie Disketten ande­
+ rer Formate haben, die von Ihrem Rechner nicht gelesen
+ werden können).
+ Dabei werden zwei Anforderungen an die Zieltask
+ gestellt: Sie muß existieren und bereit für den Datei­
+ austausch sein, d.h es muß eine Managertask sein, auf
+ die Sie Zugriff haben. Versuchen Sie auf andere Tasks
+ zuzugreifen, so erhalten Sie entsprechende (Fehler-)­
+ Meldungen.
+ Zu beachten ist noch, daß es im EUMEL-System ver­
+ schiedene Arten von Managertasks gibt - Archivmana­
+ ger und normale Dateimanager. Der Unterschied besteht
+ darin, daß ein Archivmanager vom Benutzer vor dem
+ Zugriff reserviert werden muß - anschließend hat nur
+ dieser Benutzer (bis zur Aufgabe der Reservierung) ein
+ Zugriffsrechts auf den Manager. Normale Dateimanager
+ können dagegen von mehreren Benutzern in beliebiger
+ Reihenfolge angesprochen werden.
+ Ein Archivmanager kann auch auf bestimmte Disket­
+ tenformate spezialisert sein (z.B. auf das Lesen von
+ DOS-Disketten). Manche Rechner haben auch mehrere
+ Archivmanager für verschiedene Laufwerke etc. Durch
+ Einstellen unterschiedlicher Archivmanager können
+ Sie dann auf verschiedenen Laufwerken archivieren.
+ Nach Aktivieren dieses Menupunktes werden Ihnen
+ die folgenden Alternativen angeboten:
+
+#on ("b")#
+ +-------------------------------------------+
+ | Dateiaustausch gewünscht mit: |
+ | |
+ | a ... Archiv (Eigene Station) |
+ | |
+ | v ... Vatertask |
+ | |
+ | p ... 'PUBLIC' (Eigene Station) |
+ | |
+ | s ... Sonstige Task |
+ | |
+ | |
+ | Archiv Vatertask PUBLIC Sonstige |
+ +-------------------------------------------+
+#off("b")#
+
+ Da der Dateiaustausch mit dem Standardarchiv der
+ eigenen Station (Task: 'ARCHIVE'), mit der Vatertask
+ und der Task 'PUBLIC' recht häufig in Anspruch genom­
+ men wird, sind diese drei Optionen unter den Alterna­
+ tiven direkt angegeben. Entscheiden Sie sich für eine
+ dieser drei Tasks, so nimmt #on("b")#gs-DIALOG#off("b")# alle notwendi­
+ gen Einstellungen vor. Möchten Sie dagegen in Kon­
+ takt mit einer anderen Task treten, so wählen Sie die
+ Alternative 's ... Sonstige Task'.
+
+ In diesem Falle haben Sie noch 3 Angaben zu machen:
+
+ - Zunächst werden Sie nach dem Namen der Zieltask
+ gefragt. Geben Sie den Namen der Zieltask - ohne
+ Anführungsstriche (!) - ein und schließen Sie die
+ Eingabe mit der <RETURN>-Taste ab. (Den ausgegebe­
+ nen Namen der z.Z. eingestellten Task können Sie
+ dabei verändern bzw. überschreiben.)
+ - Dann wird die Nummer der Station im EUMEL-Netz
+ erfragt, auf der sich die Zieltask befindet. Die
+ Nummer Ihrer Station wird als Vorschlag ausgege­
+ ben. Wollen Sie mit einer Task auf Ihrem Rechner
+ kommunizieren, so brauchen Sie diesen Vorschlag
+ nur durch Drücken der <RETURN>-Taste zu bestäti­
+ gen; ansonsten tragen Sie zuvor die entsprechende
+ Stationsnummer ein. Ist Ihr Rechner nicht in ein
+ EUMEL-Netz integriert, so wird die Stationsnummer
+ 0 (Null) ausgegeben. Bitte bestätigen Sie diese Sta­
+ tionsnummer durch Tippen der <RETURN>-Taste.
+ - Zum Abschluß müssen Sie noch angeben, ob die ein­
+ gestellte Zieltask ein Archivmanager ist oder
+ nicht.
+
+ #on("b")#gs-DIALOG#off("b")# versucht dann den Kontakt herzustellen.
+ Je nachdem, welche Einstellung Sie vorgenommen ha­
+ ben, sind bestimmte Funktionen innerhalb des Menus
+ nicht aktivierbar. #on("b")#gs-DIALOG#off("b")# läßt nur die Funktionen
+ zu, die aufgrund Ihrer Einstellungen zulässig sind.
+ Im Kasten rechts unten auf dem Bildschirm wird
+ jeweils angezeigt, welche Zieltask eingestellt ist.
+ Erscheint in diesem Kasten auch ein Hinweis auf den
+ Archivnamen, so haben Sie einen Archivmanager einge­
+ stellt. Ist dagegen vor dem Namen der Zieltask noch
+ eine Zahl und ein Schrägstrich angegeben, so haben
+ Sie eine Zieltask auf einem anderen Rechner einge­
+ stellt.
+ Bedenken Sie, daß Operationen mit Tasks auf ande­
+ ren Stationen länger andauern können - werden Sie
+ nicht ungeduldig!
+ Sie können die Einstellung der Zieltask jederzeit
+ wieder verändern!
+
+ Fehlerfälle:
+ - Die eingestellte Zieltask existiert nicht.
+ - Die eingestellte Zieltask existiert zwar, ist aber
+ nicht empfangsbereit, d.h. ein Zugriff von Ihrer
+ Task aus ist nicht möglich!
+ - Das Netz ist nicht funktionsbereit (Collector-Task
+ fehlt).
+ - Die Kommunikation war nicht erfolgreich.
+ - Die gewünschte Operation kann mit der eingestell­
+ ten Zieltask nicht ausgeführt werden (Zieltask ist
+ z.B. gar kein Archivmanager - Sie aber versuchen,
+ das Laufwerk zu reservieren)
+
diff --git a/doc/dialog/gs-dialog-5 b/doc/dialog/gs-dialog-5
new file mode 100644
index 0000000..f2b17cf
--- /dev/null
+++ b/doc/dialog/gs-dialog-5
@@ -0,0 +1,176 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (49)#
+#headodd#
+#center#gs-DIALOG#right#%
+
+#end#
+#headeven#
+%#center#gs-DIALOG
+
+#end#
+#center#5
+
+#center#Informationen für Lehrer/Programmierer
+
+
+5.1 "Verschlüsselung" der Dateien auf der Diskette
+
+ Wenn Sie sich die Inhalte der Dateien angesehen haben,
+in denen die Programme für #on("b")#gs-DIALOG#off("b")# enthalten sind,
+werden Sie festgestellt haben, daß der Code dicht gepackt
+ist. Das war notwendig, um die gesamten Programme auf
+einer Diskette unterzubringen.
+ Allerdings ist der Code #on("u")#nicht#off("u")# verschlüsselt - nur
+dichter gepackt. Auf der gelieferten Diskette befindet
+sich eine Datei mit Namen "gs-DIALOG decompress". In die­
+ser Datei ist das (einfache) Komprimier- und Dekompri­
+mierprogramm enthalten. Insertieren Sie dieses Programm
+in einer Task. Anschließend stehen Ihnen zwei Befehle zur
+Verfügung:
+
+PROC komprimiere (TEXT CONST dateiname):
+ Die angegebene Datei wird komprimiert; die Datei steht
+ anschließend unter gleichem Namen zur Verfügung.
+
+PROC dekomprimiere (TEXT CONST dateiname):
+ Eine zuvor mit 'komprimiere' bearbeitete Datei wird -
+ bis auf die Leerzeilen - in den Ursprungszustand über­
+ führt. Die Datei steht anschließend wieder unter glei­
+ chem Namen zur Verfügung.
+
+ Dieser 'Service' ist vornehmlich für Lehrer gedacht.
+So können Programmteile im Unterricht Gegenstand von
+Betrachtungen sein; Schüler können nach optimaleren
+Algorithmen für Teillösungen suchen - ggf. Anregungen
+geben. Sinnvoll ist es, das eigentliche Programm nicht zu
+verändern, um die Lauffähigkeit der unter #on("b")#gs-DIALOG#off("b")#
+entwickelten Software nicht zu gefährden.
+
+
+5.2 Nutzung der Graphikzeichen auf anderen Rechnern/
+Terminals
+
+ Wie schon unter "2.4 Nutzung der 'Semi - Graphik -
+Zeichen'" erwähnt, ist #on("b")#gs-DIALOG#off("b")# darauf vorbereitet, für
+'IBM - kompatible Rechner' und für Terminals 'Beehive
+FT20' die Umrahmungen der Kästen als durchgezogene Li­
+nien auszugeben - dadurch gewinnt die Bildschirmdar­
+stellung.
+ #on("b")#gs-DIALOG#off("b")# ist aber hinsichtlich der Graphikzeichen
+nur für diese Endgeräte vorbereitet und benutzt in allen
+anderen Fällen Zeichen des normalen Zeichensatzes.
+ Sie können sich aber, sofern Ihr Rechner/Terminal
+über solche Semi - Graphikzeichen verfügt, leicht selbst
+eine Anpassung dafür erstellen. Auch darauf ist
+#on("b")#gs-DIALOG#off("b")# schon vorbereitet. Keine Angst, versuchen Sie
+es ruhig einmal. Sie können nichts falsch machen; denn
+sollte es Ihnen nicht gelingen, so können Sie jederzeit
+mit dem Befehl 'std graphic char' und einem anschließen­
+den <RETURN> die Standardeinstellung wieder vornehmen.
+ Informieren Sie sich in Ihrer Terminal-/Rechner­
+beschreibung, welche Codes ausgegeben werden müssen, um
+die Grahpikzeichen darzustellen. Folgende Zeichen werden
+benötigt:
+
+ Ecke oben links : ω (f)
+ Ecke oben rechts : � (g)
+ Ecke unten links : � (e)
+ Ecke unten rechts : � (h)
+
+ Balken oben : � (n)
+ Balken unten : ̂ (o)
+ Balken links : ̄ (m)
+ Balken rechts : ̃ (l)
+ Kreuz : ̗ (i)
+
+ waagerechte Linie : ̇ (k)
+ senkrechte Linie : � (j)
+
+ ---------------------------------------------
+
+ ( Cursor sichtbar : ( ESC . 1 ) )
+ ( Cursor unsichtbar : ( ESC . 0 ) )
+
+
+ #on("b")#gs-DIALOG#off("b")# müssen nun die speziellen Codes Ihres Rech­
+ners/Terminals mitgeteilt werden. Dafür stehen die fol­
+genden Prozeduren zur Verfügung:
+
+PROC ecke oben links (TEXT CONST zeichenkette);
+PROC ecke oben rechts (TEXT CONST zeichenkette);
+PROC ecke unten links (TEXT CONST zeichenkette);
+PROC ecke unten rechts (TEXT CONST zeichenkette);
+PROC balken oben (TEXT CONST zeichenkette);
+PROC balken unten (TEXT CONST zeichenkette);
+PROC balken links (TEXT CONST zeichenkette);
+PROC balken rechts (TEXT CONST zeichenkette);
+PROC waagerecht (TEXT CONST zeichenkette);
+PROC senkrecht (TEXT CONST zeichenkette);
+PROC kreuz (TEXT CONST zeichenkette);
+
+PROC cursor on (TEXT CONST zeichenkette);
+PROC cursor off (TEXT CONST zeichenkette);
+
+ Sofern möglich, kann auch noch ein Code eingegeben
+werden, damit der Cursor auf dem Bildschirm sichtbar bzw.
+unsichtbar ist.
+ Wie man sich selbst eine Anpassung schreiben kann,
+wollen wir hier an einem Beispiel aufzeigen. Wir schrei­
+ben dazu eine Anpassung für das Terminal 'Ampex 210+'.
+ In der Terminalbeschreibung ist angegeben, wie das
+Terminal konfiguriert sein muß - diese Konfiguartion
+haben wir eingestellt. Weiterhin ist angegeben, daß auf
+die Grapikzeichen durch die Zeichenfolge 'ESC $' umge­
+schaltet und durch die Zeichenfolge 'ESC %' auf den nor­
+malen Zeichensatz zurückgeschaltet wird. Für die jeweils
+speziellen Graphikzeichen sind bestimmte Buchstaben an­
+zugeben (z.B. für die 'Ecke oben links' der Buchstabe 'f').
+Die Zeichen für dieses Terminal sind oben hinter den Gra­
+phikzeichen in Klammern angegeben. Für 'ESC' muß der Code
+'27' ausgegeben werden.
+
+PACKET eigene graphikanpassung DEFINES
+
+ private graphic char:
+
+PROC private graphic char:
+ ecke oben links (""27"$f"27"%");
+ ecke oben rechts (""27"$g"27"%");
+ ecke unten links (""27"$e"27"%");
+ ecke unten rechts (""27"$h"27"%");
+ balken oben (""27"$n"27"%");
+ balken rechts (""27"$l"27"%");
+ balken links (""27"$m"27"%");
+ balken unten (""27"$o"27"%");
+ waagerecht (""27"$k"27"%");
+ senkrecht (""27"$j"27"%");
+ kreuz (""27"$i"27"%");
+ cursor on (""27".1");
+ cursor off (""27".0");
+END PROC private graphic char;
+
+END PACKET eigene graphikanpassung;
+
+ Nachdem das Programm insertiert und der Befehl
+'private graphic char' gegeben ist, steht in dieser Task
+und allen Söhnen davon die Graphikanpassung für das
+Terminal 'Ampex 210+' zur Verfügung.
+
+
+5.3 Fehlerbehandlung
+
+ Haben Sie z.B. das Menu durch Tippen der <SV>-Taste
+verlassen, so kann es vorkommen, daß anschließend das
+Menu auf dem Bildschirm nicht ordnungsgemäß aufgebaut
+wird. Verlassen Sie dann die Menuebene durch die Tasten­
+folge <ESC><q>.
+
+Wenn 'gib kommando:' erscheint, geben Sie den Befehl
+
+ reset dialog <RETURN>
+
+ Dadurch wird das Menusystem in den Anfangszustand
+gesetzt. Anschließend können Sie das von Ihnen ge­
+wünschte Programm (wieder) aufrufen.
+
diff --git a/doc/dialog/gs-dialog-Inhaltsverzeichnis b/doc/dialog/gs-dialog-Inhaltsverzeichnis
new file mode 100644
index 0000000..741744f
--- /dev/null
+++ b/doc/dialog/gs-dialog-Inhaltsverzeichnis
@@ -0,0 +1,45 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+Inhaltsverzeichnis
+
+
+1 Was kann gs-DIALOG 3
+
+2 Installation von gs-DIALOG 6
+2.1 Voraussetzungen 6
+2.2 Lieferumfang 6
+2.3 Installation 6
+2.4 Nutzung der 'Semi-Graphik-Zeichen' 10
+
+3 Umgang mit den Menus; Eine Beispielsitzung 12
+3.1 Aufruf der Archivverwaltung 12
+3.2 Bedienung des Menusystems 14
+ - Aufbau der Menus (Bildschirmaufbau) 14
+ - Auswahl der Menupunkte 15
+ - Informationen zu einem Menupunkt 18
+ - Informationen zur Bedienung des Menus 19
+ - Aktivierbare und nicht aktivierbare
+ Menupunkte 20
+ - Aktivieren von Menupunkten 21
+ - Dateiauswahl 22
+ - Ja/Nein - Fragen 26
+ - Eingaben 26
+ - Alternativen 26
+ - Verlassen des Menus 27
+3.3 Zusammenfassung/Kurzbeschreibung 28
+
+4 Beschreibung der Menufunktionen 30
+4.1 Menufunktionen zum Oberbegriff 'Dateien' 30
+4.2 Menufunktionen zum Oberbegriff 'Archiv' 36
+
+5 Informationen für Lehrer/Programmierer 49
+5.1 "Verschlüsselung" der Dateien auf der
+ Diskette 49
+5.2 Nutzung der Graphikzeichen auf andere
+ Rechnern/Terminals 50
+5.3 Fehlerbehandlung 53
+
+
+
+
+
diff --git a/doc/dynamo/dynamo handbuch b/doc/dynamo/dynamo handbuch
new file mode 100644
index 0000000..4012973
--- /dev/null
+++ b/doc/dynamo/dynamo handbuch
@@ -0,0 +1,1826 @@
+#block##pageblock##page (2)##setcount (1)##count per page#
+#head#
+#center#DYNAMO-Compiler
+#center#____________________________________________________________
+
+#end#
+#bottom odd#
+#center#____________________________________________________________
+GMD #right#DYNAMO - %
+#end#
+#bottom even#
+#center#____________________________________________________________
+DYNAMO - % #right#GMD
+#end#
+
+#ib#1. Einleitung#ie#
+
+
+
+Diese Handbuch beschreibt die Funktion des EUMEL-DYNAMO-Compilers in der
+Version 3.3+ und seine Einschränkungen oder Änderungen gegenüber dem
+DYNAMO-Sprachstandard. In keiner Weise kann diese Beschreibung eine Einfüh­
+rung in die Programmiersprache DYNAMO ersetzen!
+
+Die beschriebene Compilerversion enthält nun auch ein Modul zur Unterstützung von
+hochauflösender Grafik durch die häufig in IBM-PC/AT-Kompatiblen eingesetzte
+CGA-Grafikkarte. Dennoch ist es einfach möglich, diesen Grafikmodus auszuschal­
+ten, und somit die alte, zeichenorientierte Grafik weiter zu verwenden.
+
+Der DYNAMO-Compiler wurde 1983 von Robert Keil und Torsten Fröhlich (Helm­
+holtz-Gymnasium, Bonn) im Rahmen des MIKROS-Projektes am Informatik-Kolleg
+der GMD entwickelt. Für Spezifikation und Betreuung der Entwicklung war Dr. Diether
+Craemer verantwortlich, software-technische Unterstützung kam von Prof. John
+Henize, Dr. Peter Heyderhoff, Rudolf Legde und Dipl.- Math. Lothar Oppor. Die
+Grafik wurde von D.Giffeler beigesteuert.
+
+
+
+
+#ib#1.1. Referenzliteratur#ie#
+
+
+
+
+ [1] Craemer, Diether
+ "Mathematisches Modellieren dynamischer Vorgänge"
+ e. Einf. in die Programmiersprache DYNAMO
+ Stuttgart, Teuber, 1985
+ ISBN 3-519-02477-2
+
+ [2] Craemer, Diether
+ "Fluß und Zustand - Simulation dynamischer Vorgänge in DYNAMO"
+ in: LOGIN 5 (1985), Heft 1, S. 20-23
+
+ [3] Pugh, Alexander L.
+ "DYNAMO II User's Manual"
+ Cambridge, London 1973: MIT-Press
+ ISBN 0-262-66018-0
+#page#
+
+#ib#1.2. Die Programmiersprache DYNAMO#ie#
+
+
+
+DYNAMO wurde von einer Gruppe um Jay FORRESTER am Massachusetts Institute
+of Technology (MIT) um 1960 entwickelt. Die Sprache basiert auf der #on ("i")# System
+Dynamic#off ("i")# von FORRESTER.
+
+In DYNAMO (#on ("u")##on ("b")#Dyna#off ("b")##off ("u")#mic #on ("u")##on ("b")#Mo#off ("b")##off ("u")#delling Language) können Systeme, in denen Veränderun­
+gen kontinuierlich geschehen, modelliert und simuliert werden.
+
+Kontinuierliche Veränderungen von Größen werden über deren Veränderungsrate im
+Wesentlichen nach folgender Gleichung berechnet
+
+Größe jetzt = Größe früher + DT * Veränderungsrate,
+
+dabei ist DT die Länge des Zeitintervalls von "früher" bis "jetzt".
+
+Außer diesen Gleichungen für Größen braucht man Gleichungen für die Verände­
+rungsraten, für Hilfsgrößen, zur Initialisierung von Größen, zur Definition von Konstan­
+ten und Tabellen, zu Angaben von Simulationsläufen und zur Wiedergabe von Ergeb­
+nissen in Zahlentabellen oder Diagrammen.
+
+Alle diese Gleichungen können einfach in der Form, wie man sie aus dem Mathema­
+tik-Unterricht der Sekundarstufe kennt, hingeschrieben werden, ohne sich Gedanken
+über den Ablauf des Programms machen zu müssen.
+
+#on ("b")#
+DYNAMO ist also eine einfache funktional-applikative, nicht-prozedurale Sprache.#off ("b")#
+
+Das macht ihren Reiz und ihre Leistungsfähigkeit aus, die zur Formulierung der be­
+kannten Weltmodelle von FORRESTER, MEADOWS ("Die Grenzen des Wachstums"),
+PESTEL, MESAROVIC u.a. in dieser Sprache führten.
+
+Anwendungsgebiete der Sprache sind ökologische, gesellschaftliche, wirtschaftliche
+und technische Systeme, deren dynamisches Verhalten der Modellbildner nachbilden
+und studieren möchte.
+
+Im Allgemeinen verfolgt der Modellbildner mit seinem Modell einen Zweck (Verhaltens­
+änderung des nachgebildeten Systems), so daß auch neben gesicherten Fakten die
+Wertvorstellungen des Modellbildners in das Modell eingehen.
+
+
+
+
+#ib#1.3 Kurz-Einführung in die DYNAMO-
+Schreibweise#ie#
+
+
+
+Die System Dynamic Methode benutzt als Analogie-Bild den Archetyp des Flusses:
+
+ - Wasser fließt durch das Flußbett, kann in Seen gestaut und in der Ge­
+ schwindigkeit durch Schleusen und Wehre reguliert werden.
+
+ - Analog dazu "fließt" Geld auf dem Überweisungsweg, wird in Konten gestaut,
+ und die Liquidität kann durch Zinssätze reguliert werden.
+
+ - Gedanken "fließen" auf Nervenbahnen, werden im Gehirn gespeichert, und
+ Gedankenströme werden über Synapsen reguliert.
+
+ - Autos "fließen" über Straßen, werden auf Parkplätzen gestaut, und der Ver­
+ kehrsfluß wird über Ampeln reguliert.
+
+ - Menschen "fließen" über Wanderwege, halten sich in Wohnorten auf, und die
+ Bevölkerungsdynamik wird durch ein komplexes, rückgekoppeltes Zusammen­
+ spiel von Ein- und Auswanderungsraten sowie Geburts- und Sterberaten
+ reguliert.
+
+Am letzten Beispiel wird deutlich, daß sich ein soziales Phänomen nur im Zusam­
+menwirken vieler netzartig miteinander verbundener Variablen beschreiben läßt (wenn
+überhaupt).
+
+Solange jedoch einigen Variablen ZUSTANDS-CHARAKTER ("Wasserstand") und
+anderen VERÄNDERUNGS-CHARAKTER ("Flußgeschwindigkeit") zugeordnet
+werden kann, können die Größen für Berechnungen folgender Art verwendet werden:
+
+
+ Wasserstand jetzt = Wasserstand früher + vergangene Zeit *
+ (Zuflußrate - Abflußrate)
+
+
+analog:
+
+ Bevölkerung jetzt = Bevölkerung früher + vergangene Zeit *
+ (Geburtsrate - Sterberate)
+
+
+Diese Schreibweise kann praktisch so in ein Computerprogramm übernommen wer­
+den. Mit geringfügigen Änderungen handelt es sich bei diesen Gleichungen schon um
+gültige Zeilen in der Programmiersprache DYNAMO.
+
+In DYNAMO wird er Zeitpunkt "jetzt" durch das Anhängsel .K, der Zeitpunkt "früher"
+durch das Anhängsel .J, die Zeitspanne von jetzt bis später durch das Anhängsel .KL,
+die Zeitspanne von früher bis jetzt durch das Anhänsel .JK und die vergangene Zeit
+mit DT (wie "Delta Tempus": Zeitdifferenz) bezeichnet. Die Variablen mit Zustands-
+Charakter heißen LEVELS (Niveaus) und die Veränderungs-Charakter heißen RATES
+(Veränderungsraten, Geschwindigkeiten). Die entsprechenden Gleichungen werden mit
+L bzw. R gekennzeichnet. Es gib weitere Kennzeichnungen:
+
+ C für Konstantendefinition (constant)
+ T für Tabellendefintion (table)
+ A für Hilfsgrößen (auxiliaries)
+ N für Anfangswerte (initial)
+ X für Folgezeile (extension)
+ PRINT für Ausgabe von Zahlen
+ PLOT für Ausgabe von Diagrammen
+
+Ein einfaches Bevölkerungsmodell könnte z.B. so geschriben werden:
+
+
+ L BEVÖLKERUNG.K=BEVÖLKERUNG.J+DT*(GEBURTENRATE.JK
+ X -STERBERATE.JK)
+ R STERBERATE.KL=5
+ R GEBURTENRATE.KL=20
+ N BEVÖLKERUNG=1000
+ C DT=1 (jedes Jahr wird neu berechnet)
+ C LENGTH=60 (60 Jahre werden simuliert)
+ PRINT BEVÖLKERUNG
+
+
+Für eine tiefere Einführung in DYNAMO sollte man die Referenzliteratur zu Rate
+ziehen.
+
+
+
+
+#ib#1.4 Eine erste, kleine Sitzung mit dem
+DYNAMO-System#ie#
+
+
+
+Wir gehen davon aus, daß das DYNAMO-System in ihrer Task generiert worden ist
+(siehe 2.).
+
+ 1. Tippen Sie das obrige Programm mittels des EUMEL-Editors ab.
+
+ 2. Verlassen Sie den Editor mit <ESC><q> und starten Sie den DYNAMO-
+ Compiler durch die Eingabe des Befehls "dynamo".
+
+ 3. Nach erfolgreichem Übersetzen sollte Ihnen nun das DYNAMO-Runtime-
+ System zur Verfügung stehen. Durch den Befehl 'run' wird das Programm aus­
+ geführt und Sie erhalten eine Zahlenkolonne, die die Entwicklung der Bevöl­
+ kerung in den zu untersuchenden 60 Jahren angibt. Falls Ihnen beim Abtippen
+ des Programms Fehler unterlaufen sein sollten, so kann das Programm nicht
+ fehlerfrei übersetzt werden. Fehlermeldunggen zur Compile-Zeit des
+ DYNAMO-Compilers werden im Paralleleditor angezeigt; das Programm kann
+ im oberen der beiden Editorfenster (in diesem befinden Sie sich auch nach
+ Fehlern) korrigiert werden. Danach können Sie erneut wie nach Punkt 2 ver­
+ fahren.
+#page#
+
+
+
+#ib#2. Generierung des DYNAMO-Compilers#ie#
+
+
+
+Der DYNAMO-Compiler, seine Funktionen und die Beispielprogramme werden auf
+zwei Archiv-Disketten a#b#' 360 KB ausgeliefert.
+
+Zum Generieren des DYNAMO-Systems legen Sie bitte die erste Diskette in das
+Dikettenlaufwerk Ihres Rechners und durch folgende Kommandozeile lesen Sie den
+Generator vom Archiv und starten ihn:
+
+
+ archive ("dynamo"); fetch ("dyn.inserter", archive); run
+
+
+Danach holt der Generator alle benötigten Dateien vom eingelegten Archiv bzw. von
+dem zweiten Archiv (nachdem er Sie zum Wechseln der Diskette aufgefordert hat).
+Anschließend wird der DYNAMO-Compiler insertiert. Am Ende der Generierung
+werden Sie gefragt werden, ob Sie den Compiler mit Grafik#u##count ("Grafik")##e# oder ohne benutzen
+wollen. Nach der Meldung "dynamo system generiert" können Sie den Compiler#foot#
+#u##value ("Grafik")##e# Es kann z.Zt. nur eine CGA-Grafikkarte betrieben werden
+#end#
+nutzen.
+#page#
+
+
+
+#ib#3. Der EUMEL-DYNAMO-Compiler#ie#
+
+
+
+Der im EUMEL-System implementierte DYNAMO-Compiler ist ein 2-Pass-
+Compiler, der die DYNAMO-Programme zunächst in ELAN übersetzt. Der Vorteil
+dieser Methode besteht darin, daß es möglich ist, übersetzte Programme unabhängig
+vom DYNAMO-Compiler zur Ausführung bringen zu können.
+
+Die Notation der im folgenden aufgeführten ELAN-Prozeduren des Compilers ent­
+spricht der in den EUMEL-Handbüchern üblichen Prozedurkopf-Schreibweise.
+
+Als Beispiel:
+
+
+ dynamo ("dyn.grasshasenfuchs")
+
+
+ein Beispiel für den Aufruf der Prozedur mit der Prozedurkopf-Schreibweise
+
+ PROC dynamo (TEXT CONST filename)
+
+auf der Kommando-Ebene des Betriebssystems EUMEL.
+
+Der Prozedur 'dynamo' wird beim Aufruf der Dateiname (TEXT) 'filename' übergeben
+und dadurch der Compiler auf die Datei mit dem Namen 'filename' angewendet.
+
+
+
+
+#ib#3.1. Benutzung des DYNAMO-Compiler#ie#
+
+
+
+Um ein DYNAMO-Programm zu Übersetzen, gibt es grundsätzlich zwei Möglichkei­
+ten. Erst einmal kann man ein DYNAMO-Programm in ein ELAN-Programm um­
+wandeln, jedoch ohne es dabei zur Ausführung zu bringen. Dieses ELAN-Programm
+kann man nun unabhängig vom eingentlichen Compiler starten. Die zweite, wohl öfter
+angewendete Methode ist, ein DYNAMO-Programm in ein ELAN-Programm zu
+compilieren, wobei es danach direkt ausgeführt wird. Ob danach ein ELAN-
+Programm zur Verfügung stehen soll, kann der Benutzer selbst entscheiden.
+
+
+PROC dynamo
+
+ Zweck: Aufruf des DYNAMO-Compilers mit 'quelldatei' = 'last param', d.h. das
+ zu übersetzende Programm steht in der zuletzt bearbeiteten Datei.
+
+
+PROC dynamo (TEXT CONST quelldatei)
+
+ Zweck: Ruft den DYNAMO-Compiler für die Datei 'quelldatei' auf. Anmerkung:
+ Gleichbedeutend mit 'dynamo (quelltext, quelltext + ".elan", TRUE)', s.
+ nächste Prozedur.
+
+ Beispiel:
+
+
+ dynamo ("dyn.grashasenfuchs")
+
+
+ Der DYNAMO-Compiler wird auf die Datei "dyn.grashasenfuchs" ange­
+ wendet.
+
+
+PROC dynamo (TEXT CONST quelldatei, zieldatei,
+ BOOL CONST pass2 ausfuehren)
+
+ Zweck: Diese Prozedur startet den DYNAMO-Compiler. 'quelldatei' gibt den
+ Namen der Datei an, in welcher der DYNAMO-Quelltext enthalten ist,
+ 'zieldatei' ist der Name der Datei, die das erzeugte ELAN-Programm
+ beinhalten soll. Wenn 'pass2 ausfuehren' = TRUE, dann wird dieses auch
+ durch den ELAN-Compiler weiterverarbeitet (das Programm wird zur
+ Ausführung gebracht).
+
+ Beispiel:
+
+
+ dynamo ("dyn.grashasenfuchs",
+ "grashasenfuchs.elanprogramm", FALSE)
+
+
+ Im obigen Beispiel wird der in der Datei "dyn.grashasenfuchs" enthaltene
+ DYNAMO-Quelltext in die Datei "grashasenfuchs.elanprogramm" als
+ ELAN-Programm geschrieben. Das ELAN-Programm wird nicht ausge­
+ führt.
+
+
+PROC erase (BOOL CONST erase option)
+
+ Zweck: Wenn 'erase option' = TRUE, so werden die erzeugten ELAN-Programme
+ nach Beendigung der Ausführung gelöscht, bei 'erase option' = FALSE
+ bleiben sie erhalten (Voreinstellung: 'erase option' = FALSE).
+
+
+PROC error listing (TEXT CONST fehlerdatei)
+
+ Zweck: Falls gewünscht ist, die Fehlermeldungen, die ggf. beim Übersetzen ein­
+ treten, auch in eine Datei zu schreiben, so können Sie hier unter 'fehler­
+ datei' einen Dateinamen angeben. Bei der Angabe von "" wird die Umlei­
+ tung in die Datei ausgeschaltet werden (Voreingestellt ist 'fehlerdatei' =
+ "").
+
+
+PROC graphic (BOOL CONST graphic option)
+
+ Zweck: Mit dieser Prozedur läßt sich einstellen, ob bei der DYNAMO-Anweisung
+ PLOT die hochauflösende Grafik ('graphic option' = TRUE) oder die zei­
+ chenorientierte Grafik ('grafik option' = FALSE) verwendet werden soll. Die
+ Voreinstellung wird bei der Installation des Compilers erfragt.
+
+
+PROC protokoll (BOOL CONST protokoll option)
+
+ Zweck: Bei 'protokoll option' = TRUE werden alle Textausgaben, die bei der
+ Laufzeit des DYNAMO-Programmes auftreten, nicht nur auf dem Bild­
+ schirm dargestellt, sondern auch in eine Datei mit dem Namen "dyn.out"
+ protokolliert (voreingestellt ist 'protokoll option' = FALSE). Die Datei
+ "dyn.out" enthält auch Seitenvorschubbefehle ('\#page\#') und sollte nur mit
+ einem EUMEL-Printer ausgedruckt werden.
+
+
+
+
+#ib#3.2. Abweichungen gegenüber dem
+ Sprachstandard#ie#
+
+
+
+ - Die Länge der Namen ist nicht auf 7 Zeichen festgelegt, sondern praktisch be­
+ liebig (32000). Dies ist eine Erweiterung; wer seine Programme auch auf ande­
+ ren DYNAMO-Compilern laufen lassen will, sollte sich aber auf 7 Zeichen be­
+ schränken.
+
+ - Zahlen werden intern mit einer Mantisse von 13 Stellen abgespeichert, von denen
+ nur die ersten 7 bei der Ausgabe dargestellt werden. Die größte darstellbare Zahl
+ ist daher 9.999999999999e126.
+
+ - Die maximale Anzahl der Gleichungen ist auf 950 festgelegt.
+
+ - Der Compiler akzeptiert aus Gründen der besseren Lesbarkeit auch Programme,
+ die in Kleinschrift geschrieben sind. Dabei ist es sinnvoll, die Quellprogramme
+ konsistent zu halten (d.h. Groß- und Kleinschrift nicht zu vermischen). Man
+ sollte grundsätzlich Kleinschrift vorziehen, da diese vom Compiler auch effizienter
+ verarbeitet werden kann.
+
+ - Quellprogramme dürfen eine beliebige Zahl von Leerzeilen enthalten. X - Befeh­
+ le (Fortschreibungszeilen) werden davon nicht beeinflußt.
+
+ - In der augenblicklichen Version 3.3 des Compilers gelten folgende Einschränkun­
+ gen :
+
+ 1. Bei der Verarbeitung von Array-Gleichungen werden Compilerseitig keine
+ Semantik-Überprüfungen auf eventuell unzureichende Initialisierung oder
+ Überlappung (d.h. mehrfaches Setzen desselben Elements) durchgeführt.
+ Defaultmäßig bekommen alle Elemente einer Array-Gleichung bei der Initiali­
+ sierung den Wert '0.0' zugewiesen.
+
+ 2. Die maximale Größe von Tables und Array-Gleichungen ist durch Verwen­
+ dung des Vector-Pakets auf 4000 Elemente festgelegt. Da pro Table-Ele­
+ ment aber zur Zeit eine Zeile im Zielprogramm generiert wird, sollte man dies
+ besser nicht ausnutzen.
+
+ 3. Supplementary-Gleichungen werden aus Kompatibilitäts-Gründen korrekt
+ übersetzt, aber sonst wie Auxiliary-Gleichungen behandelt.
+
+ 4. Print ('prtper')- und Plotperiode ('pltper') werden nur als Konstanten verarbei­
+ tet. Falls Gleichungen für 'prtper' oder 'pltper' angegeben werden, so bewirken
+ diese keine Veränderung.
+
+ 5. Array-Gleichungen dürfen nicht mehr als eine Dimension besitzen.
+
+ 6. Für Gleichungen, die Makro-Aufrufe enthalten, sollten Initialisierungs (N)-
+ Gleichungen angegeben werden.
+
+
+
+#ib#3.3. Das DYNAMO Runtime-System#ie#
+
+
+
+Nach erfolgreicher Übersetzung wird vom Zielprogramm das Runtime-System aufge­
+rufen. In diesem Modus (das DYNAMO-Runtime-System meldet sich mit "dynamo
+runtime system :") ist es möglich, Konstanten zu ändern und DynamoProgramme zur
+Ausführung zu bringen.
+
+Im DYNAMO-Runtime-System stehen folgende Kommandos zur Verfügung (näheres
+zur Notation siehe Kapitel 4, S. #to page ("Anweisungen und Funktionen")#).
+
+
+ run
+
+ Zweck: Ausführen des übersetzten Programms
+
+
+ run <name>
+
+ Zweck: Ausführen des übersetzten Programms und retten des Konstantendaten­
+ raums in des Datenraum mit dem Namen "<name>.const". Existiert der
+ Datenraum bereits, werden die Konstanten aus dem Datenraum in den
+ Lauf übernommen. Somit ermöglicht der Compiler, Konstantenwerte aus
+ einem früheren Lauf wieder zu verwenden.
+
+
+ c <Konstantenname>=Wert [/<Konstantenname>=Wert [...]]
+
+ Zweck: Änderung einer oder mehrerer Konstanten
+
+
+ ?
+
+ Zweck: Anzeigen der Konstanten und ihrer Werte
+
+
+ quit
+
+ Zweck: Verlassen des Runtime-Systems
+
+
+ help
+
+ Zweck: Zeigt eine kurze Erklärung
+
+
+Bei PRINT- und PLOT-Ausgaben sind folgende Kommandos möglich:
+
+ + Nächster Bildschirm
+ o (Off), keine Unterbrechung der Ausgabe (nicht möglich bei hochauflösen­
+ der Grafik)
+ e (End), Zurück zum Runtime System
+ p Phasendiagramm (nur bei hochauflösender Grafik möglich)
+
+
+
+#ib#3.4. Fehlermeldungen des
+ DYNAMO-Compilers#ie#
+
+
+
+Falls der Compiler einen Fehler im DYNAMO-Programm entdeckt, gibt er eine Feh­
+lermeldung nach dem folgenden Muster aus:
+"Fehler in Zeile <zeilennummer> bei >> <symbol> << : <fehlertext>.
+
+Im folgenden sind alle Fehlermeldungen und Möglichkeiten zur Abhilfe aufgelistet,
+sofern diese nicht klar ersichtlich sind:
+
+ 1 GLEICHUNG DOPPELT DEFINIERT
+
+ 2 DOPPELTE INITIALISIERUNG
+
+ 3 FALSCHER ZEILENTYP
+ -> Erlaubt sind : a, c, l, n, r, s, print, plot, note, spec, *, x, macro, mend,
+ for, noise, run.
+
+ 4 VERSCHACHTELTE MAKRO-DEFINITION
+ -> 'mend' - Befehl fehlt.
+
+ 5 MAKRO-NAME ERWARTET
+
+ 6 '(' ERWARTET
+
+ 7 FORMALER PARAMETER ERWARTET
+
+ 8 ')' NACH PARAMETERLISTE ERWARTET
+
+ 9 BEI AUXILIARIES NUR SUBSKRIPTION MIT '.K' ERLAUBT
+
+10 BEI KONSTANTEN-DEFINITION NAME ERWARTET
+
+11 BEI LEVELS NUR SUBSKRIPTION MIT '.K' ERLAUBT
+
+12 BEI RATES NUR SUBSKRIPTTION MIT '.KL' ERLAUBT
+
+13 BEI TABLE-DEFINITIONEN KEINE SUBSKRIPTION ERLAUBT
+
+14 X - BEFEHL HIER NICHT ERLAUBT
+
+15 BEI FOR-DEFINITION NAME ERWARTET
+
+16 '=' NACH FOR-VARIABLE ERWARTET
+
+17 BEREICHSANGABE ERWARTET
+
+18 ',' ERWARTET
+
+19 LOKALE GLEICHUNG NUR IN MAKRO ERLAUBT
+
+20 BEI DEFINITION NAME ERWARTET
+
+21 '=' ERWARTET
+
+22 INDEX NICHT KORREKT
+ -> Als Index ist nur erlaubt : <for variable> !,
+ <add op> <ganze zahl>!.
+ <add op> ::= "+"; "-".
+
+23 ')' NACH INDIZIERUNG ERWARTET
+
+24 PRTPER NICHT DEFINIERT
+ -> Wenn das Programm einen Print-Befehl enthält, muß 'prtper' (Printperiode)
+ als Konstante definiert werden.
+
+25 PLTPER NICHT DEFINIERT
+ -> Wenn das Programm einen Plot-Befehl enthält, muß 'pltper' (Plotperiode)
+ als Konstante definiert werden.
+
+26 '/' ODER ',' BEI PLOT ERWARTET
+
+27 NAME ALS PLOTPARAMETER ERWARTET
+
+28 DOPPELTE SCALE - ANGABE IN EINER GRUPPE
+ -> Wenn mehrere Plotparameter mit ',' getrennt werden (also die gleiche Ska­
+ lierung erhalten), dürfen nicht mehrere feste Skalierungen angegeben wer­
+ den.
+
+29 ERSTE SCALE - ANGABE ERWARTET
+
+30 ZWEITE SCALE - ANGABE ERWARTET
+
+31 ')' NACH SCALE - ANGABE FEHLT
+
+32 PRINTPARAMETER NICHT DEFINIERT
+
+33 PRINTPARAMETER ERWARTET
+
+34 TIME DARF NUR INITIALISIERT WERDEN
+
+35 DT NICHT DEFINIERT
+
+36 LENGTH NICHT DEFINIERT
+
+37 BEI KONSTANTEN - DEFINITION ZAHL ERWARTET
+
+38 BEI INITIALISIERUNG KONSTANTE ERWARTET
+
+39 LEVELS MUESSEN INITIALISIERT WERDEN
+
+40 KONSTANTE BEI TABLE ERWARTET
+
+41 '/' ODER "," ERWARTET
+
+42 TABLE - DEFINITION OHNE BENUTZUNG
+
+43 SIMULTANE GLEICHUNGEN
+ -> Bei dem Versuch, A, R, oder N - Gleichungen zu sortieren, trat eine
+ direkte oder indirekte Rekursion auf.
+
+44 FAKTOR ERWARTET
+ -> Erwartet : <zahl>;
+ <funktions aufruf>;
+ <macro aufruf>;
+ <gleichungs name>;
+ '(', <ausdruck>, ')';
+ <monadischer operator>, <faktor>.
+ <monadischer operator> ::= '+'; '-'.
+
+45 TIME MUSS MIT '.J' ODER '.K' SUBSKRIBIERT WERDEN
+
+46 SYMBOL NICHT DEFINIERT
+
+47 FUNKTION NICHT DEFINIERT
+
+48 UNZULAESSIGE INDIZIERUNG
+ -> Die Indices auf beiden Seiten der Gleichung müssen immer gleich sein.
+
+49 FALSCHE PARAMETERANZAHL
+
+50 FALSCHES TRENNSYMBOL ZWISCHEN PARAMETERN
+
+51 ALS PARAMETER TABLE ERWARTET
+
+52 FALSCHER PARAMETER IN TABLEFUNKTION
+
+53 ZU VIELE AKTUELLE PARAMETER
+
+54 ')' NACH MAKROAUFRUF FEHLT
+
+55 REKURSIVER MAKROAUFRUF
+
+56 BEI N - GLEICHUNG KEINE SUBSKRIPTION ERLAUBT
+
+57 FALSCHE SUBSKRIPTION IN AUXILIARY - GLEICHUNG
+
+58 ')' ERWARTET
+
+59 FALSCHE SUBSKRIPTION IN LEVEL - GLEICHUNG
+
+60 FALSCHE SUBSKRIPTION IN RATE - GLEICHUNG
+
+61 FOR - VARIABLE NICHT DEFINIERT
+ -> Eine FOR - Variable muß vor der ersten Benutzung definiert werden.
+
+62 KONSTANTE ERWARTET
+
+63 FALSCHES REAL - FORMAT
+ -> Exponent fehlt
+
+64 GLOBALE GLEICHUNG IN MACRO NICHT ERLAUBT
+
+65 DOPPELTE DEFINITION BEI MEHRFACHEM MAKROAFRUF
+
+66 ALS NOISE - PARAMETER ZAHL ERWARTET
+#page#
+
+#ib#4. Anweisungen und Funktionen des
+ EUMEL-DYNAMO-Compilers#ie#
+#goal page ("Anweisungen und Funktionen")#
+
+
+Dieses Kapitel gibt eine alphabetische Übersicht über die im EUMEL-DYNAMO-
+Compiler realisierten Anweisungen und Funktionen (wertliefernde Algorithmen).
+
+Die Beschreibung der Anweisungen und Funktionen ist nach der DYNAMO-
+Syntaxregel angegeben, wobei folgende Zeichen mit besonderer Bedeutung verwendet
+werden:
+
+ [] optionale Angabe
+ [...] beliebig häufige Wiederholung der letzten optionalen Angabe
+ < > in spitzen Klammern stehende Namen sind Variablen- bzw. Konstan­
+ tennamen
+ <Name> steht für einen beliebigen Bezeichner gemäß der DYNAMO-Syntax
+ <Zahl> bezeichnet einen beliebigen Wert (also auch eine Ausdruck)
+ {} Alternative Angabe
+
+ X DYNAMO Anweisung, kennzeichnet eine Fortsetzungsszeile der
+ vorhergegangenen Anweiung (S. #to page ("X")#)
+
+Alle Anweisungen und Funktionen werden nach dem gleichen Schema dargestellt:
+
+
+
+Funktionsname#right#Typ (Funkt. oder Anweisung)
+
+
+Zweck: Schlagwort zur Wirkung
+
+Format: Beschreibung des Formates (spezielle Zeichen s.o.)
+
+Erklärung: kurze Beschreibung der Anweisung/Funktion
+
+Beispiel: Anwendung der Anweisung/Funktion
+
+Programm: Beispielprogramm, in welchem die Anweisung/Funktion angewendet wird.
+
+Referenz: Verweis auf ähnliche oder äquivalente Anweisungen/Funktionen im
+ Format '<Funktions- bzw. Anweisungsname>, Seitennummer'.
+
+
+Eine oder mehrere dieser Felder können fehlen (z.B. wenn es keine Referenz oder
+kein Beispielprogramm gibt).
+#page#
+
+
+
+#ib#4.1. Übersicht über die Anweisungen und
+ Funktionen#ie#
+
+
+
+#goal page ("A")##ib (2)#A#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Auxiliary-Gleichung (A-Gleichung, Hilfsgleichung)
+
+Format: A <Auxiliary-Name>.K=<Ausdruck>#u##count ("Ausdruck")##e#
+#foot#
+#u##value ("Ausdruck")##e# genaueres über die Definition eines Ausdruckes siehe [1], S. 93
+#end#
+
+Erklärung: Mit Hilfe von Auxiliary-Gleichungen werden Level- und Hilfsgrößen
+ (Auxiliaries) zum selben Zeitpunkt verknüpft.
+
+Beispiel: A JM.K=MM.K/MEJ
+
+Programm: "dyn.workfluc"
+
+
+
+#ib (2)#ABS#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Absolutbetrag
+
+Format: ABS(<Zahl>)
+
+Erklärung: Liefert den Absolutbetrag
+
+
+ IF <Zahl> >= 0 THEN
+ <Zahl>
+ ELSE
+ - <Zahl>
+ END IF
+
+Beispiel: N X=ABS(A*2.0)
+
+
+
+#goal page ("ARCTAN")#ARCTAN#on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Berechnung der trigonometrischen Funktion Arcustangens
+
+Format: ARCTAN(<Zahl>)
+
+Erklärung: Berechnet den Arcustangens von <Zahl>; Ergebnis im Bogenmaß.
+
+Beispiel: N X=ARCTAN(TAN(1.3)) (X = 1.3)
+
+
+Referenz: COSD, S. #to page ("COSD")#
+ SIN, S. #to page ("SIN")#
+ SIND, S. #to page ("SIND")#
+ TAN, S. #to page ("TAN")#
+ TAND, S. #to page ("TAND")#
+ ARCTAND, S. #to page ("ARCTAN")#
+ COS, S. #to page ("COS")#
+
+
+
+#goal page ("ARCTAND")##ib (2)#ARCTAND#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Berechnung der trigonometrischen Funktion Arcustangens
+
+Format: ARCTAND(<Zahl>)
+
+Erklärung: Berechnet den Arcustangens von <Zahl>; Ergebnis im Gradmaß
+
+Beispiel: N X=ARCTAND(TAND(45.0)) (X = 45.0)
+
+
+Referenz: COSD, S. #to page ("COSD")#
+ SIN, S. #to page ("SIN")#
+ SIND, S. #to page ("SIND")#
+ TAN, S. #to page ("TAN")#
+ TAND, S. #to page ("TAND")#
+ COS, S. #to page ("COS")#
+ ARCTAN, S. #to page ("ARCTAND")#
+
+
+
+#goalpage ("C")##ib (2)#C#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Konstantendefinition
+
+Format: C <Name>=<Zahl>
+
+Erklärung: Werte, die während eines Simulationslaufes gleich bleiben, können durch
+ die Konstantendefintion benannt werden (s. auch 'c' im Runtime-
+ System).
+
+Beispiel: C POPI=30.3
+
+Programm: "dyn.wohnen"
+
+
+
+#goal page ("CLIP")##ib (2)#CLIP#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Wert nach Bedingung
+
+Format: CLIP(<Zahl1>,<Zahl2>,<Zahl3>,<Zahl4>)
+
+Erklärung: Liefert den Wert des ersten Argumentes, wenn das dritte Argument
+ größer oder gleich dem vierten Argument ist. Andernfalls wird der Wert
+ des zweiten Argumentes geliefert.
+
+
+ IF <Zahl3> >= <Zahl4> THEN
+ <Zahl1>
+ ELSE
+ <Zahl2>
+ END IF
+
+Beispiel: N X=CLIP(1.0,2.0,3.0,4.0) (X = 2.0)
+
+
+Programm: "dyn.welt/forrester"
+
+Referenz: FIFGE, S. #to page ("FIFGE")# (äquivalente Funktion)
+
+
+
+#goalpage ("COS")#COS#on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Berechnung der trigonometrischen Funktion Cosinus
+
+Format: COS(<Zahl>)
+
+Erklärung: Es wird der Cosinus des Wertes <Zahl>, welcher im Bogenmaß vorlie­
+ gen muß, geliefert.
+
+Beispiel: N X=COS(1.6)
+
+Referenz: COSD, S. #to page ("COSD")#
+ SIN, S. #to page ("SIN")#
+ SIND, S. #to page ("SIND")#
+ TAN, S. #to page ("TAN")#
+ TAND, S. #to page ("TAND")#
+ ARCTAN, S. #to page ("ARCTAN")#
+ ARCTAND, S. #to page ("ARCTAND")#
+
+
+
+#goal page ("COSD")##ib (2)#COSD#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Berechnung der trigonometrischen Funktion Cosinus
+
+Format: COSD(<Zahl>)
+
+Erklärung: Es wird der Cosinus des Wertes <Zahl>, welcher im Gradmaß vorliegen
+ muß, geliefert.
+
+Beispiel: N X=COSD(33.5)
+
+Referenz: COS, S. #to page ("COS")#
+ SIN, S. #to page ("SIN")#
+ SIND, S. #to page ("SIND")#
+ TAN, S. #to page ("TAN")#
+ TAND, S. #to page ("TAND")#
+ ARCTAN, S. #to page ("ARCTAN")#
+ ARCTAND, S. #to page ("ARCTAND")#
+
+
+
+#goal page ("EXP")##ib (2)#EXP#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Exponentialfunktion zur Basis e
+
+Format: EXP(<Zahl>)
+
+Erklärung: Liefert e#u#<Zahl>#e#
+
+Beispiel: N X=EXP(1.0) (X = 2.71 = e)
+
+
+Referenz: LN, S. #to page ("LN")# (Umkehrfunktion)
+
+
+
+#goal page ("FIFGE")##ib (2)#FIFGE#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Wert nach Bedingung (#on ("u")#f#off ("u")#irst #on ("u")#if#off ("u")# #on ("u")#g#off ("u")#reater or #on ("u")#e#off ("u")#qual)
+
+Format: FIFGE(<Zahl1>,<Zahl2>,<Zahl3>,<Zahl4>)
+
+Erklärung: Liefert den Wert des ersten Argumentes, wenn das dritte Argument
+ größer oder gleich dem vierten Argument ist. Andernfalls wird der Wert
+ des zweiten Argumentes geliefert.
+
+
+ IF <Zahl3> >= <Zahl4> THEN
+ <Zahl1>
+ ELSE
+ <Zahl2>
+ END IF
+
+Beispiel: N X=FIFGE(1.0,2.0,3.0,4.0) (X = 2.0)
+
+
+Referenz: CLIP, S. #to page ("CLIP")# (äquivalente Funktion)
+
+
+
+#goal page ("FIFZE")##ib (2)#FIFZE#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Wert nach Bedingung (#on ("u")#f#off ("u")#irst #on ("u")#if#off ("u")# #on ("u")#ze#off ("u")#ro)
+
+Format: FIFZE(<Zahl1>,<Zahl2>,<Zahl3>)
+
+Erklärung: Wenn der Parameter <Zahl3> den Wert 0 hat, so wird <Zahl1>
+ geliefert, andernfalls <Zahl2>
+
+
+ IF <Zahl3> = 0 THEN
+ <Zahl1>
+ ELSE
+ <Zahl2>
+ END IF
+
+Beispiel: N X=FIFZE(1.0,2.0,3.0) (X = 2.0)
+
+
+Referenz: SWITCH, S. #to page ("SWITCH")#
+
+
+
+#goal page ("FLOOR")##ib (2)#FLOOR#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Vorkommastellen
+
+Format: FLOOR(<Zahl>)
+
+Erklärung: Liefert die Vorkommastellen von <Zahl>
+
+Beipiel: N X=FLOOR(3.14) (X = 3.0)
+
+
+Referenz: FRAC, S. #to page ("FRAC")#
+
+
+
+#ib (2)#FOR#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Schleifen-Definition
+
+Format: FOR <Name>=<Zahl1>,<Zahl2>
+
+Erklärung: <Name> bezeichnet eine Schleifenvariable, die von <Zahl1> bis
+ <Zahl2> hochgezählt wird. Somit ist es möglich, gleiche Berechnungen
+ für die verschiedenen Werte einer Tabelle durchzuführen.
+
+Beispiel: FOR BERECHNUNGSZEITRAUM=1900,2100
+
+
+Programm: "dyn.bev"
+
+
+
+#goal page ("FRAC")##ib (2)#FRAC#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Nachkommastellen
+
+Format: FRAC(<Zahl>)
+
+Erklärung: Liefert die Nachkommastellen von <Zahl>
+
+Beispiel: N X=FRAC(3.14) (X = 0.14)
+
+
+Referenz: FLOOR, S. #to page ("FLOOR")#
+
+
+
+#goal page ("L")##ib (2)#L#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Level-Gleichung
+
+Format: L <Level-Name>.K=<Level-Name>.J+
+ <Vergangenheitsausdruck>
+
+Erklärung: Die Level-Gleichung stellt einen gegenwärtigen Wert in Bezug zu
+ seinem Wert in der Vergangenheit und seiner Veränderungsrate in der
+ bis dahin vergangenen Zeit (Vergangenheitsausdruck s. [1], S. 96).
+
+Beispiel: L HASEN.K=CLIP(HASEN.J+DT*(HGRATE.JK
+ X -HSRATE.JK),0,HASEN.J,0)
+
+Programm: "dyn.grashasenfuchs"
+
+
+
+#goal page ("LN")##ib (2)#LN#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Logarithmus-Funktion
+
+Format: LN(<Zahl>)
+
+Erklärung: Berechnet den natürlichen Logarithmus von <Zahl>
+
+Beispiel: N X=LN(1.0) (X = 0.0)
+
+
+Programm: "dyn.wasseröko"
+
+Referenz: LOG2, S. #to page ("LOG2")#
+ LOG10, S. #to page ("LOG10")#
+ EXP, S. #to page ("EXP")#
+
+
+
+#goal page ("LOG2")##ib (2)#LOG2#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Logarithmus-Funktion
+
+Format: LOG2(<Zahl>)
+
+Erklärung: Berechnet den Logarithmus von <Zahl> zur Basis 2
+
+Beispiel: N X=LOG2(8.0) (X = 3.0)
+
+
+Referenz: LN, S. #to page ("LN")#
+ LOG10, S. #to page ("LOG10")#
+
+
+
+#goal page ("LOG10")##ib (2)#LOG10#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Logarithmus-Funktion
+
+Format: LOG10(<Zahl>)
+
+Erklärung: Berechnet den Logarithmus von <Zahl> zur Basis 10
+
+Beispiel: N X=LOG10(100.0) (X = 2.0)
+
+
+Referenz: LOG2, S. #to page ("LOG2")#
+ LN, S. #to page ("LN")#
+ EXP, S. #to page ("EXP")#
+
+
+
+#goal page ("MACRO")##ib (2)#MACRO#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Macro-Definition
+
+Format: MACRO <Name>(<Ausdruck>[,<Ausdruck>[...]])
+
+Erklärung: Durch die Verwendung der MACRO-Anweisung können Sie einer oder
+ mehreren DYNAMO-Gleichungen einen Namen geben (<Name>).
+ Macros müssen durch MEND abgeschloßen werden und dürfen #on ("u")#nicht#off ("u")#
+ rekursiv aufgerufen werden (vergl. Refinements in ELAN).
+
+Beispiel: MACRO SMOOTH(IN,DEL)
+ L SMOOTH.K=SMOOTH.J+DT*(IN.J-SMOOTH.J)/DEL
+ N SMOOTH=IN
+ MEND
+
+Programm: "dyn.mac" (diese Datei enthält alle bisherigen Makros)
+
+Referenz: MEND, S. #to page ("MEND")#
+
+
+
+#goal page ("MAX")##ib (2)#MAX#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Maximum zweier Größen
+
+Format: MAX(<Zahl1>,<Zahl2>)
+
+Erklärung: Liefert die größere Zahl aus <Zahl1> und <Zahl2>
+
+
+ IF <Zahl1> > <Zahl2> THEN
+ <Zahl1>
+ ELSE
+ <Zahl2>
+ END IF
+
+Beispiel: N X=MAX(1.0,2.0) (X = 2.0)
+
+
+Referenz: MIN, S. #to page ("MIN")#
+
+
+
+#goal page ("MEND")##ib (2)#MEND#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Macro-Definition
+
+Format: MEND
+
+Erklärung: MEND beendet eine Macro-Definition
+
+Beispiel: MACRO SMOOTH(IN,DEL)
+ L SMOOTH.K=SMOOTH.J+DT*(IN.J-SMOOTH.J)
+ X /DEL
+ N SMOOTH=IN
+ MEND
+
+Programm: "dyn.mac" (diese Datei enthält alle bisherigen Makros)
+
+Referenz: MACRO, S. #to page ("MACRO")#
+
+
+
+#goal page ("MIN")##ib (2)#MIN#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Minimum zweier Größen
+
+Format: MIN(<Zahl1>,<Zahl2>)
+
+Erklärung: Liefert die kleinere Zahl aus <Zahl1> und <Zahl2>
+
+Beispiel: N X=MIN(1.0,2.0) (X = 1.0)
+
+
+Programm: "dyn.forst7"
+
+Referenz: MAX, S. #to page ("MAX")#
+
+
+
+#goal page ("N")##ib (2)#N#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Initialisierungsgleichung
+
+Format: N <Name>=<Zahl>
+
+Erklärung: Initialisert eine Variable mit dem Bezeichner <Name> auf den Wert
+ <Zahl>, d.h. es wird ihr ein Startwert zugewiesen.
+
+Beispiel: N X=1900
+
+Programm: "dyn.grashasenfuchs"
+
+
+
+#goal page ("NOISE")##ib (2)#NOISE#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Pseudo-Zufallszahlen-Generator
+
+Format: NOISE(<Zahl>)
+
+Erklärung: Diese Funktion liefert eine Pseudo-Zufallszahl zwischen -0.5 und +0.5
+ und setzt einen neuen Startwert für den Generator fest. Der Parameter
+ <Zahl> wird nicht ausgewertet.
+
+Beispiel: N X=NOISE(0)
+
+Referenz: NORMRN, S. #to page ("NORMRN")#
+
+
+
+#goal page ("NORMRN")##ib (2)#NORMRN#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Pseudo-Zufallszahlen-Generator
+
+Format: NORM(<Zahl1>,<Zahl2>)
+
+Erklärung: Liefert einen Wert zwischen <Zahl1> - <Zahl2> * 2.4 und <Zahl1>
+ + <Zahl2> * 2.4.
+
+Beispiel: N X=NORM(1.0,10.0)
+
+Referenz: NOISE, S. #to page ("NOISE")#
+
+
+
+#ib (2)#NOTE#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Kommentar
+
+Format: NOTE <Kommentarzeile>
+
+Erklärung: Die Zeilen, die mit NOTE gekennzeichnet sind, werden vom Compiler als
+ Kommentarzeilen erkannt und nicht beachtet. NOTE-Zeilen haben nur
+ dokumentierenden Charakter und sind für den Programmlauf ohne jede
+ Bedeutung. Dennoch sollte man, wenn immer möglich, Kommentare in
+ sein DYNAMO-Programm einfügen, denn sie sind in DYNAMO an­
+ nähernd die einzige Möglichkeit, ein Programm lesbar zu machen, damit
+ es auch nach längerer Zeit noch korrigiert werden kann.
+
+Beispiel: NOTE Dies ist eine Kommentarzeile
+
+Programm: "dyn.welt/forrester"
+
+
+
+#goal page ("PLOT")##ib (2)#PLOT#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Darstellen der Ergebnisse in Diagrammform
+
+Format: PLOT <Name>[=<Druckzeichen>][(<Skalenbegin>,
+ <Skalenende>)][/...][,...]
+
+Erklärung: Durch diese Anweisung werden die Größen nach PLTPER Zeiteinheiten
+ in einem Diagramm ausgegeben. Die Angabe eines Druckzeichens ist
+ nur bei zeichenorientierten Grafik erforderlich, denn bei hochauflösender
+ Grafik werden die Graphen der verschiedenen Größen durch unterschied­
+ liche Linientypen gezeichnet; fehlt bei der zeichenorientierten Grafik das
+ Druckzeichen, so werden die Graphen durch die Zahlen von 0...9 darge­
+ stellt. Bei "/" werden verschiedene, bei "," gleiche Skalen benutzt.
+
+Beispiel: PLOT GRAS=G(995,1005)/HASEN=H(85,115)
+ X /FUECHS=F(15,35)
+
+Programm: "dyn.grashasenfuchs"
+
+Referenz: PRINT, S. #to page ("PRINT")#
+
+
+
+#goal page ("POWER")##ib (2)#POWER#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Potenzfunktion
+
+Format: POWER(<Zahl1>,<Zahl2>)
+
+Erklärung: Liefert <Zahl1>#u#<Zahl2>#e#
+
+Beipiel: N X=POWER(2, 2) (X = 4)
+
+
+Referenz: SQRT, S. #to page ("SQRT")#
+
+
+
+#goal page ("PRINT")##ib (2)#PRINT#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Darstellung der Ergebnisse in Tabellenform
+
+Format: PRINT <Name>[/...][,...]
+
+Erklärung: Durch diese Anweisung werden die Werte (<Name>) nach PRTPER
+ Zeiteinheiten in einer Tabelle ausgegeben. Die Ausgabe kann umgeleitet
+ werden (s. 'protokoll').
+
+Beispiel: PRINT GBEV,BEV(1),BEV(40),BEV(60),BEV(63)
+ X ,BEV(65),ZBEV,PRENT
+
+Programm: "dyn.bev"
+
+Referenz: PLOT, S. #to page ("PLOT")#
+
+
+
+#goal page ("R")##ib (2)#R#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Rate-Gleichung
+
+Format: R<Rate-Name>.KL=<Gegenwartsausdruck>
+
+Erklärung: Eine Rate-Gleichung stellt die Veränderungsrate in Bezug zu den aktu­
+ ellen Level-Größen.
+
+Beispiel: R FGRATE.KL=FGK*HASEN*FUECHS.K
+
+
+Programm: "dyn.grashasenfuchs"
+
+Referenz: A, S. #to page ("A")#
+ C, S. #to page ("C")#
+ L, S. #to page ("L")#
+
+
+
+#ib (2)#RAMP#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Wert nach Bedingung
+
+Format: RAMP(<Zahl1>,<Zahl2>)
+
+Erklärung: Wenn TIME kleiner <Zahl2>, dann liefert RAMP 0, andernfalls wird
+ <Zahl1> * (TIME - <Zahl2>) geliefert.
+
+
+ IF TIME < <Zahl2> THEN
+ 0
+ ELSE
+ <Zahl1> * (TIME - <Zahl2>)
+ END IF
+
+
+
+#goal page ("RUN")##ib (2)#RUN#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Überschrift
+
+Format: RUN <Überschrift>
+
+Erklärung: Gibt dem aktuellen Lauf eine Überschrift. Gleichzeitig ist
+ "<Überschrift>.const" der Name eines Datenraums, in dem die Kon­
+ stanten dieses Laufs aufgehoben werden (s. 'run' im Runtime-System).
+
+Beispiel: RUN Überschrift
+
+Referenz: *, S. #to page ("*")#
+
+
+
+#ib (2)#S#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Supplementary-Gleichung
+
+Format: S <Name>.K=<Vergangenheitsausdruck>
+
+Erklärung: Gleichungen für Hilfsgrößen werden durch Supplementary-Gleichungen
+ ausgedrückt.
+
+Beispiel: S SCHADSTOFFVERHÄLTNIS.K=COZWEI.K/OZWEI.K
+
+
+
+
+#ib (2)#SCLPRD#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Skalarprodukt
+
+Format: SCLPRD(<Tabelle1>,<Zahl1>,<Zahl2>,<Tabelle2>,<Zahl3>)
+
+Erklärung: Liefert das Skalarprokukt der Tabellen <Tabelle1> und <Tabelle2>,
+ wobei <Zahl1> und <Zahl2> den Ausschnitt aus der ersten Tabelle
+ angeben und <Zahl3> den Startindex für den Vektor in der zweiten
+ Tabelle angibt.
+
+Beispiel: GB.K=SCLPRD(BEV.K,15,44,GR,1)/2
+
+
+Programm: "dyn.bev"
+
+
+
+#goal page ("SIN")##ib (2)#SIN#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Berechnung der trigonometrischen Funktion Sinus
+
+Format: SIN(<Zahl>)
+
+Erklärung: Berechnet den Sinus von <Zahl>, welche im Bogenmaß angegeben
+ wird.
+
+Beispiel: N X=SIN(0.5)
+
+Referenz: COS, S. #to page ("COS")#
+ COSD, S. #to page ("COSD")#
+ SIND, S. #to page ("SIND")#
+ TAN, S. #to page ("TAN")#
+ TAND, S. #to page ("TAND")#
+ ARCTAN, S. #to page ("ARCTAN")#
+ ARCTAND, S. #to page ("ARCTAND")#
+
+
+
+#goal page ("SIND")##ib (2)#SIND#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Berechnung der trigonometrischen Funktion Sinus
+
+Format: SIND(<Zahl>)
+
+Erklärung: Berechnet den Sinus von <Zahl>, welche im Gradmaß angegeben wird.
+
+Beispiel: N X=SIND(45.0)
+
+Referenz: COS, S. #to page ("COS")#
+ SIN, S. #to page ("SIN")#
+ COSD, S. #to page ("COSD")#
+ TAN, S. #to page ("TAN")#
+ TAND, S. #to page ("TAND")#
+ ARCTAN, S. #to page ("ARCTAN")#
+ ARCTAND, S. #to page ("ARCTAND")#
+
+
+
+#ib (2)#SPEC#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Lauf-Anweisung
+
+ DT=<Zahl1>
+Format: SPEC { LENGTH=<Zahl2> }[/...]
+ PLTPER=<Zahl3>
+ PRTPER=<Zahl4>
+
+Erklärung: Durch die Lauf-Anweisung werden die Systemkonstanten festgesetzt.
+ Sie darf pro Lauf nur einmal benutzt werden.
+
+Beispiel: SPEC DT=1/PLTPER=1/PRTPER=1/LENGTH=2000
+
+
+Referenz: C, S. #to page ("C")# (SPEC kann durch C-Def. ersetzt werden)
+
+
+
+#goal page ("SQRT")##ib (2)#SQRT#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Quadratwurzel
+
+Format: SQRT(<Zahl>)
+
+Erklärung: Berechnet die Quadratwurzel aus <Zahl>
+
+Beispiel: N X=SQRT(4.0) (X = 2.0)
+
+
+Referenz: POWER, S. #to page ("POWER")#
+
+
+
+#ib (2)#STEP#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+Zweck: Wert nach Bedingung
+
+Format: STEP(<Zahl1>,<Zahl2>)
+
+Erklärung: Ist TIME kleiner <Zahl2>, so wird 0 geliefert, ansonsten <Zahl1>
+
+
+ IF TIME < <Zahl2> THEN
+ 0.0
+ ELSE
+ <Zahl1>
+ END IF
+
+Beispiel: N X=STEP(12.0,12.0)
+
+
+
+#goal page ("SUM")##ib (2)#SUM#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Summierung einer Tabelle
+
+Format: SUM(<Tabelle>)
+
+Erklärung: Liefert die Summe der Einträge in einer Tabelle
+
+Beispiel: A GESAMTBEV.K=SUM(BEV.K)
+
+Programm: "dyn.bev"
+
+Referenz: SUMV, S. #to page ("SUMV")#
+
+
+
+#goal page ("SUMV")##ib (2)#SUMV#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Summierung einer Tabelle
+
+Format: SUMV(<Tabelle>,<Zahl1>,<Zahl2>)
+
+Erklärung: Summierung der Einträge in der Tabelle von Element <Zahl1> bis
+ Element <Zahl2>
+
+Beispiel: A ZBEV.K=SUMV(BEV.K,16,59) Teilbevölkerung
+
+
+Programm: "dyn.bev"
+
+Referenz: SUM, S. #to page ("SUM")#
+
+
+
+#goal page ("SWITCH")##ib (2)#SWITCH#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Wert nach Bedingung
+
+Format: SWITCH(<Zahl1>,<Zahl2>,<Zahl3>)
+
+Erklärung: Wenn der Parameter <Zahl3> den Wert 0 hat, so wird <Zahl1>
+ geliefert, andernfalls <Zahl2> (gleichbedeutend mit FIFZE).
+
+
+ IF <Zahl3> = 0 THEN
+ <Zahl1>
+ ELSE
+ <Zahl2>
+ END IF
+
+Beispiel: N X=SWITCH(1.0,2.0,3.0) (X = 2.0)
+
+
+Referenz: FIFZE, S. #to page ("FIFZE")#
+
+
+
+#goal page ("T")##ib (2)#T#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Tabellen-Definition
+
+Format: T <Name>=<Zahl1>[/<Zahl2>[....]]
+
+Erklärung: Durch die T-Anweisung wird eine Tabelle definiert, die Elemente wer­
+ den durch "/" getrennt hintereinander angegeben.
+
+Beispiel: T TABELLE=1/2/3/4/5/6/8/9/10/11/12
+
+
+Programm: "dyn.bev"
+
+Referenz: TABLE, S. #to page ("TABLE")#
+ TABHL, S. #to page ("TABHL")#
+
+
+
+#goal page ("TABHL")##ib (2)#TABHL#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Tabellenfunktion
+
+Format: TABHL(<Tabelle>,<Zahl1>,<Zahl2>,<Zahl3>)
+
+Erklärung: IF <Zahl1> < <Zahl2> THEN
+ <Tabelle> (<Zahl2>)
+ ELIF <Zahl2> <= <Zahl1> AND <Zahl1> <= <Zahl3> THEN
+ TABLE (<Tabelle>, <Zahl1>, <Zahl2>, <Zahl3>)
+ ELSE
+ <Tabelle> (<Zahl3>)
+ END IF
+
+Beispiel: A BRMM.K=TABHL(BRMMT,MSL.K,0,5,1)
+
+
+Programm: "dyn.welt/forrester"
+
+Referenz: T, S. #to page ("T")#
+ TABLE, S. #to page ("TABLE")#
+
+
+
+#goal page ("TABLE")##ib (2)#TABLE#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Tabellenfunktion
+
+Format: TABLE(<Tabelle>,<Zahl1>,<Zahl2>,<Zahl3>,<Zahl4>)
+
+Erklärung: Verknüpft die Werte aus <Tabelle> mit <Zahl1>, wobei <Zahl2> den
+ ersten und <Zahl3> den letzten Tabelleneintrag angibt. <Zahl4> stellt
+ die Schrittweite dar.
+
+Beispiel: T TABELLE=1/2/3/4/5
+ A BEISP.K=TABLE(TABELLE,X.K,2,4,1)
+
+Programm: "dyn.welt/forrester"
+
+Referenz: T, S. #to page ("T")#
+ TABHL, S. #to page ("TABHL")#
+
+
+
+#goal page ("TAN")##ib (2)#TAN#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Berechnung der trigonometrischen Funktion Tangens
+
+Format: TAN(<Zahl>)
+
+Erklärung: Berechnet den Tangens von <Zahl>, welche im Bogenmaß angegeben
+ wird.
+
+Beispiel: N X=TAN(0.5)
+
+Referenz: COS, S. #to page ("COS")#
+ SIN, S. #to page ("SIN")#
+ COSD, S. #to page ("COSD")#
+ SIND, S. #to page ("TAN")#
+ TAND, S. #to page ("TAND")#
+ ARCTAN, S. #to page ("ARCTAN")#
+ ARCTAND, S. #to page ("ARCTAND")#
+
+
+
+#goal page ("TAND")##ib (2)#TAND#ie (2)##on ("i")##right#Funktion#off ("i")#
+
+
+Zweck: Berechnung der trigonometrischen Funktion Tangens
+
+Format: TAND(<Zahl>)
+
+Erklärung: Berechnet den Tangens von <Zahl>, welche im Gradmaß angegeben
+ wird.
+
+Beispiel: N X=TAND(45.0)
+
+Referenz: COS, S. #to page ("COS")#
+ SIN, S. #to page ("SIN")#
+ COSD, S. #to page ("COSD")#
+ TAN, S. #to page ("TAN")#
+ SIND, S. #to page ("SIND")#
+ ARCTAN, S. #to page ("ARCTAN")#
+ ARCTAND, S. #to page ("ARCTAND")#
+
+
+
+#goalpage ("X")##ib (2)#X#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Fortsetzungszeile
+
+Format: X <Fortsetzungszeile>
+
+Erklärung: Eine in der vorangegangenen Zeile nicht beendete Anweisung wird nach
+ einer X-Anweisung fortgesetzt (Es können beliebig viele X-Anweisun­
+ gen nacheinander folgen).
+
+Beispiel: T TABELLE=1/2/3/4/5/6/7/8/9/10/11/12/13/14
+ X /15/16/17/18/19
+
+Programm: "dyn.bev"
+
+
+
+#goal page ("*")##ib (2)#*#ie (2)##on ("i")##right#Anweisung#off ("i")#
+
+
+Zweck: Überschrift
+
+Format: * <Überschrift>
+
+Erklärung: Gibt dem aktuellen Lauf eine Überschrift
+
+Beispiel: * Überschrift
+
+Referenz: RUN, S. #to page ("RUN")#
+#page#
+
+#ib#5. Makros in DYNAMO#ie#
+
+
+
+
+Der DYNAMO-Compiler bietet die Möglichkeit, benutzereigene Funktionen zu definie­
+ren. Makros werden ähnlich wie Refinements in ELAN in das DYNAMO-Programm
+eingesetzt. Beim EUMEL-DYNAMO-Compiler werden mit "zz" beginnende Namen
+generiert, so daß Sie es vermeiden sollten, eigene Namen mit "zz" beginnen zu
+lassen. Weiterhin sollte man als Namen der aktuellen Parameter nicht die Namen der
+formellen Parameter verwenden.
+
+Folgende Makros werden standardmäßig vom DYNAMO-Compiler zur Verfügung
+gestellt:
+
+ macro delay1 (in, del) Verzögerung erster Ordnung
+
+ macro delay3 (in, del) Verzögerung dritter Ordnung
+ Material
+
+ macro delay3p (in, del, ppl) Verzögerung dritter Ordnung mit
+ Pipeline
+
+ macro delinf3 (in, del) Verzögerung dritter Ordnung für
+ Information
+
+ macro smooth (in, del) Verzögerung erster Ordnung für
+ Information
+
+
+
+
+#ib#5.1. Insertieren von Makros#ie#
+
+
+
+
+Makros werden durch folgende Prozedur in die Compilertabelle eingetragen:
+
+
+PROC insert macro (TEXT CONST filename):
+
+ Zweck: Fügt die in der Datei 'filename' enthaltenen Makros in die Makrotabelle ein.
+ Die Datei sollte zweckmäßigerweise nur Makrodefinitionen enthalten. Es ist
+ - im Gegensatz zu normalen DYNAMO-Programmen - nicht nötig, die
+ Systemkonstanten zu definieren (die Standard-Makros sind in der Datei
+ "dyn.mac" enthalten; diese Datei kann beliebig ergänzt werden).
+
+
+
+
+#ib#5.2. Aufbau eines Makros#ie#
+
+
+
+
+Makros beginnen in DYNAMO immer mit der Anweisung MACRO (s. auch Seite #to page ("MACRO")#)
+und enden mit MEND (s. Seite #to page ("MEND")#). Dazwischen steht ein Makrorumpf, bestehend
+aus einer oder mehreren DYNAMO-Gleichungen. Beim Makroaufruf können, soweit
+vorher definiert, Parameter angegeben werden, jedoch rekursiv aufrufen kann man
+Makros nicht.
+
+Beispiel: MACRO SMOOTH (IN, DEL)
+ L SMOOTH.K = SMOOTH.J + DT * (IN.J - SMOOTH.J)
+ X /DEL
+ N SMOOTH = IN
+ MEND
+
+Lokale Variablen in Makros beginnen mit einem $-Zeichen. Der Makro-Expandierer
+ersetzt das $-Zeichen durch "zz" gefolgt von einer Zahl. Aus diesem Grund sollen
+eigene Namen nicht mit "zz" beginnen.
+
+Falls Sie eine Fehlermeldung bekommen, die sich auf einen mit "zz" beginnenden
+Namen bezieht, sollten Sie den Fehler in dem entsprechenden Makro suchen.
+
+#on ("b")#
+Achtung: #off ("b")#Makros sollten nur von fortgeschrittenden DYNAMO-Programmieren
+ verwendet werden, da Makros Eigenschaften von Refinements (textuelle
+ Ersetzung) und Prozeduren (Parameterübergabe) vereinigen. Der daraus
+ folgende Effekt ist nicht ganz einfach zu durchschauen.
+#page#
+
+
+
+#ib#6. Erweiterung des Sprachumfangs#ie#
+
+
+
+
+Während Makros in DYNAMO geschrieben werden, ist es ferner möglich, die Menge
+der Funktionen mittels der Sprache ELAN zu erweitern.
+
+Hierbei geht man wie folgt vor:
+
+ 1. Schreiben einer Funktion in ELAN (näheres siehe unten)
+
+ 2. Einbinden der Funktion in die Tabellen des DYNAMO-Compilers
+
+ 2.1. Einschreiben des Namens der Funktion, gefolgt von den Typen der Ein­
+ gabeparameter in die bestehende Datei "dyn.std", wobei folgende Typen
+ existieren:
+
+ r real (Datentyp REAL)
+ t table (Datentyp TAB)
+
+ Abgeschlossen wird die "dyn.std"-Datei durch die Zeichensequenz "/*".
+
+ Beispiele:
+
+ power rr table trrrr /*
+
+
+ 2.2. Laden der Funktion(en) mittels der Prozedur 'init std ("dyn.std")'
+
+
+Eine zur Einbindung in den DYNAMO-Compiler vorgesehene ELAN-Funktion wird
+unter Beachtung gewisser Regeln erstellt:
+
+ 1. Die deklarierten ELAN-Prozeduren dürfen nur Parameter vom Typ REAL oder
+ TAB besitzen oder gänzlich ohne Parameter sein.
+
+ 2. Der Typ des Resultaten muß vom Typ REAL sein.
+
+Zur Manipulation von Tabellen wurde der Datentyp TAB geschaffen, auf welchen man
+wie auf das Standard-Vektorpaket zugreifen kann.
+
+Beispiel:
+
+ REAL PROC abs (REAL CONST a):
+ IF a < 0.0 THEN
+ -a
+ ELSE
+ a
+ END IF
+ END PROC abs;
+
+ PROC sumv (TAB CONST tab, REAL CONST erstes, letztes):
+ REAL VAR summe := 0.0;
+ INT VAR i;
+ FOR i FROM int (erstes) UPTO int (letztes) REPEAT
+ summe INCR wert (tab, i)
+ END REPEAT;
+ summe
+ END PROC sumv
+
+
+
+
+#ib#6.1. Für fortgeschrittende ELAN-Program­
+ mierer#ie#
+
+
+
+Der Quellcode des EUMEL-DYNAMO-Compilers wird mit ausgeliefert. Daher
+können Einschränkungen (s. 3.2 Abweichungen gegenüber dem Sprachstandard)
+leicht beseitigt werden. Wem z.B. die Anzahl der Gleichungen (950) zu wenig ist, der
+kann im Quelltext des Compilers diesen Wert (annähernd) beliebig nach oben hin
+erhöhen.
+
diff --git a/doc/dynamo/dynamo handbuch.index b/doc/dynamo/dynamo handbuch.index
new file mode 100644
index 0000000..af77d79
--- /dev/null
+++ b/doc/dynamo/dynamo handbuch.index
@@ -0,0 +1,69 @@
+#block##pageblock##page (52)#
+#head#
+#center#DYNAMO-Compiler
+#center#____________________________________________________________
+
+#end#
+#bottom odd#
+#center#____________________________________________________________
+GMD #right#DYNAMO - %
+#end#
+#bottom even#
+#center#____________________________________________________________
+DYNAMO - % #right#GMD
+#end#
+Anhang - Übersicht über Anweisungen und
+Funktionen
+
+
+#clear pos##l pos (0.0)##r pos (10.0)##fillchar (" ")#
+#table#
+A 21
+ABS 21
+ARCTAND 22
+C 23
+CLIP 23
+COSD 24
+EXP 25
+FIFGE 25
+FIFZE 26
+FLOOR 26
+FOR 27
+FRAC 27
+L 28
+LN 28
+LOG2 29
+LOG10 29
+MACRO 30
+MAX 31
+MEND 31
+MIN 32
+N 32
+NOISE 33
+NORMRN 33
+NOTE 34
+PLOT 35
+POWER 35
+PRINT 36
+R 36
+RAMP 37
+RUN 37
+S 38
+SCLPRD 38
+SIN 39
+SIND 39
+SPEC 40
+SQRT 40
+STEP 41
+SUM 41
+SUMV 42
+SWITCH 42
+T 43
+TABHL 43
+TABLE 44
+TAN 44
+TAND 45
+X 45
+* 46
+#table end#
+
diff --git a/doc/dynamo/dynamo handbuch.inhalt b/doc/dynamo/dynamo handbuch.inhalt
new file mode 100644
index 0000000..2d1b1f3
--- /dev/null
+++ b/doc/dynamo/dynamo handbuch.inhalt
@@ -0,0 +1,131 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#DYNAMO
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#block#
+#center#____________________________________________________________________________
+
+ Copyright 1988
+
+ Selbstverlag GMD
+ Alle Rechte vorbehalten.
+ Insbesondere ist die Überführung in maschinenlesbare
+ Form, sowie das Speichern in Informationssystemen, auch
+ auszugsweise, nur mit schriftlicher Genehmigung der
+ GMD gestattet.
+#center#____________________________________________________________________________
+
+
+ Herausgeber:
+
+ Gesellschaft für Mathematik und Datenverarbeitung mbH
+
+ Postfach 1240, Schloß Birlinghoven
+ D-5205 Sankt Augustin 1
+ Telefon(02241) 14-1, Telex 8 89 469 gmd d
+ Telefax(02241) 14 28 89, BTX *43900\#
+ Teletex 2627-224135=GMDVV
+
+
+Autor:
+
+ Christian Szymanski
+
+nach Anregungen von:
+
+ Diether Craemer, Robert Keil
+
+überarbeitet von:
+
+ Thomas Müller
+
+Texterstellung:
+
+ Dieser Text wurde mit der EUMEL-Textverarbeitung erstellt und aufbereitet und
+ mit dem Agfa Laserdrucksystem P400 gedruckt.
+
+
+
+ Hinweis:
+
+#on("italics")#
+ Diese Dokumentation wurde mit größtmöglicher Sorgfalt erstellt. Dennoch wird
+ für die Korrektheit und Vollständigkeit der gemachten Angaben keine Gewähr
+ übernommen. Bei vermuteten Fehlern der Software oder der Dokumentation
+ bitten wir um baldige Meldung, damit eine Korrektur möglichst rasch erfolgen
+ kann. Anregungen und Kritik sind jederzeit willkommen.#off("italics")#
+#page#
+#pagenr ("%", 1")##setcount (1)##block##pageblock##count per page#
+#head#
+#center#DYNAMO-Compiler
+#center#____________________________________________________________
+
+#end#
+#bottom odd#
+#center#____________________________________________________________
+GMD #right#DYNAMO - %
+#end#
+#bottom even#
+#center#____________________________________________________________
+DYNAMO - % #right#GMD
+#end#
+
+Inhalt
+
+
+
+#clear pos##lpos (0.0)##r pos (10.0)##fillchar (" ")#
+#table#
+1. Einleitung 2
+ 1.1. Referenzliteratur 2
+ 1.2. Die Programmiersprache DYNAMO 3
+ 1.3. Kurz-Einführung in die DYNAMO-Schreibweise 4
+ 1.4. Eine erste, kleine Sitzung mit dem DYNAMO-System 6
+
+2. Generierung des DYNAMO-Compilers 7
+
+3. Der EUMEL-DYNAMO-Compiler 8
+ 3.1. Benutzung des DYNAMO-Compiler 8
+ 3.2. Abweichungen gegenüber dem Sprachstandard 11
+ 3.3. Das DYNAMO Runtime-System 12
+ 3.4. Fehlermeldungen des DYNAMO-Compilers 14
+
+4. Anweisungen und Funktionen des EUMEL-DYNAMO-Compilers 19
+ 4.1. Übersicht über die Anweisungen und Funktionen 21
+
+5. Makros in DYNAMO 47
+ 5.1. Insertieren von Makros 48
+ 5.2. Aufbau eines Makros 48
+
+6. Erweiterung des Sprachumfangs 50
+ 6.1. Für fortgeschrittende ELAN-Programmierer 51
+
+Anhang - Übersicht über Anweisungen unf Funktionen 52
+#table end#
+
diff --git a/doc/eudas/abb.1-1 b/doc/eudas/abb.1-1
new file mode 100644
index 0000000..06c27fd
--- /dev/null
+++ b/doc/eudas/abb.1-1
@@ -0,0 +1,94 @@
+init dgs;
+window (0.0, 0.0, 13.5, 7.1); (*viewport (0.0,0.0,13.5,7.1); *)
+scale (1.0,1.0,0.0,0.0);
+(*clear pixels;*)
+
+karteikasten (1.0, 3.5, "Kartei A", "Wegner", "Herbert");
+karteikasten (5.0, 0.5, "Kartei B", "Regmann", "Karin");
+
+LET myname = "abb.1-1";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (10000);
+*)
+PROC karteikasten (REAL CONST x, y, TEXT CONST name, t name, t vorname) :
+
+ move (x - 0.1, y);
+ draw (x + 3.6, y);
+ draw (x + 3.6, y + 1.0);
+ draw (x - 0.1, y + 1.0);
+ draw (x - 0.1, y);
+
+ move (x + 0.1, y + 1.1);
+ draw (x + 0.5, y + 1.5);
+ move (x + 0.1, y + 1.1);
+ draw (x + 3.6, y + 1.1);
+ move (x - 0.1, y + 1.0);
+ draw (x + 0.5, y + 1.6);
+
+ move (x + 3.6, y);
+ draw (x + 5.2, y + 1.6);
+ draw (x + 5.2, y + 2.6);
+ draw (x + 3.6, y + 1.0);
+ move (x + 3.6, y + 1.1); draw (x + 5.0, y + 2.5);
+ move (x + 5.2, y + 2.6); draw (x + 5.0, y + 2.6);
+
+ move (x + 0.5, y + 1.1);
+ draw (x + 0.5, y + 2.5);
+ draw (x + 4.0, y + 2.5);
+ draw (x + 4.0, y + 1.5);
+ move (x + 0.5, y + 2.5);
+ draw (x + 1.5, y + 3.5);
+ draw (x + 5.0, y + 3.5);
+ draw (x + 5.0, y + 2.5);
+ move (x + 5.0, y + 3.5);
+ draw (x + 4.0, y + 2.5);
+ REAL VAR x off := 0.1;
+ WHILE x off < 1.0 REP
+ move (x + 0.5 + xoff, y + 2.5 + x off);
+ draw (x + 4.0 + xoff, y + 2.5 + xoff);
+ draw (x + 4.0 + xoff, y + 1.5 + xoff);
+ x off INCR 0.1
+ END REP;
+ font size (0.5);
+ font expansion (1.5);
+ move (x + 0.5, y + 0.2); draw (name);
+ font size (0.25);
+ move (x + 0.7, y + 2.10); draw ("Name");
+ move (x + 0.7, y + 1.65); draw ("Vorname");
+ move (x + 0.7, y + 1.20); draw ("Strasse");
+ move (x + 2.1, y + 2.10); draw (": " + t name);
+ move (x + 2.1, y + 1.65); draw (": " + t vorname);
+ move (x + 2.1, y + 1.20); draw (":");
+
+END PROC karteikasten;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/eudas/abb.4-1 b/doc/eudas/abb.4-1
new file mode 100644
index 0000000..439e052
--- /dev/null
+++ b/doc/eudas/abb.4-1
@@ -0,0 +1,43 @@
+init dgs;
+window (0.0, 0.0, 13.5, 3.2); viewport (0.0,0.0,13.5,3.2);
+(* scale (2.0,2.0,0.0,0.0); *)
+(*clear pixels;*)
+
+font size (0.25);
+font expansion (1.5);
+
+INT VAR i;
+FOR i FROM 0 UPTO 4 REP
+ move (2.0, real (i) * 0.5);
+ draw (10.0, real (i) * 0.5);
+ move (2.1, real (i) * 0.5 + 0.1);
+ draw ("Feld " + code (code ("E") - i));
+END REP;
+move (2.0, 2.5);
+draw (10.0, 2.5);
+move (2.0, 2.5);
+draw (2.0, 0.0);
+move (3.5, 3.0);
+draw (10.0, 3.0);
+FOR i FROM 1 UPTO 4 REP
+ move (2.0 + real (i) * 1.5, 3.0);
+ draw (2.0 + real (i) * 1.5, 0.0);
+ move (2.2 + real (i) * 1.5, 2.6);
+ draw ("Satz " + text (i))
+END REP;
+move (9.5, 3.0);
+draw (9.5, 0.0);
+(*
+pause (1000);
+*)
+
+LET myname = "abb.4-1";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+
+
diff --git a/doc/eudas/abb.4-2 b/doc/eudas/abb.4-2
new file mode 100644
index 0000000..a836def
--- /dev/null
+++ b/doc/eudas/abb.4-2
@@ -0,0 +1,46 @@
+init dgs;
+window (0.0, 0.0, 13.5, 2.0); viewport (0.0,0.0,13.5,2.0);
+(*scale (1.7,1.7,-1.6,0.0);*)
+(*
+clear pixels;
+*)
+
+kasten (1.0, 0.0, 3.0, 1.5);
+kasten (7.0, 0.0, 3.0, 1.5);
+font size (0.4); font expansion (1.5);
+move (1.8, 0.6); draw ("Menü");
+move (7.9, 0.6); draw ("Hilfe");
+move (4.5, 1.0); draw (6.5, 1.0);
+ draw (6.25, 1.25); move (6.5, 1.0); draw (6.25, 0.75);
+move (6.5, 0.5); draw (4.5, 0.5);
+ draw (4.75, 0.75); move (4.5, 0.5); draw (4.75, 0.25);
+font size (0.25);
+move (5.0, 1.1); draw ("ESC '?'");
+move (5.0, 0.6); draw ("ESC 'q'");
+move (10.5, 1.0); draw (11.5, 1.0); draw (11.5, 0.5); draw (10.5, 0.5);
+ draw (10.75, 0.75); move (10.5, 0.5); draw (10.75, 0.25);
+move (11.8, 0.9); draw ("ESC 'w'");
+move (11.8, 0.4); draw ("ESC 'z'");
+
+
+LET myname = "abb.4-2";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (9000);
+*)
+PROC kasten (REAL CONST x anf, y anf, x l, y l) :
+
+ move (x anf, y anf);
+ draw (x anf, y anf + y l);
+ draw (x anf + x l, y anf + y l);
+ draw (x anf + x l, y anf);
+ draw (x anf, y anf)
+
+END PROC kasten;
+
diff --git a/doc/eudas/abb.6-1 b/doc/eudas/abb.6-1
new file mode 100644
index 0000000..fb83242
--- /dev/null
+++ b/doc/eudas/abb.6-1
@@ -0,0 +1,75 @@
+init dgs;
+window (0.0, 0.0, 13.5, 4.0); viewport (0.0,0.0,13.5,4.0);
+(*scale (1.0,1.0, 0.0,0.0);*)
+(*
+clear pixels;
+*)
+
+move (2.25, 1.0); draw (4.75, 1.0);
+move (2.25, 3.0); draw (4.75, 3.0);
+ move (2.5, 1.0); draw (2.5, 3.3);
+ move (3.0, 1.0); draw (3.0, 3.3);
+ move (3.5, 1.0); draw (3.5, 3.3);
+ move (4.0, 1.0); draw (4.0, 3.3);
+ move (4.5, 1.0); draw (4.5, 3.3);
+font size (0.30); font expansion (1.5);
+move (2.6, 3.1); draw ("4");
+move (2.6, 2.0); draw ("M");
+move (3.1, 3.1); draw ("5");
+move (3.1, 2.0); draw ("N");
+move (3.6, 3.1); draw ("6");
+move (3.6, 2.0); draw ("O");
+move (4.1, 3.1); draw ("7");
+move (4.1, 2.0); draw ("P");
+ pfeil (3.75, 0.75);
+
+move (5.0, 2.0); draw (7.0, 2.0); draw (6.75, 2.25);
+ move (7.0, 2.0); draw (6.75, 1.75);
+move (5.0, 2.1); draw ("Einfügen");
+
+move (7.25, 1.0); draw (8.5, 1.0); move (9.0, 1.0); draw (10.25, 1.0);
+move (7.25, 3.0); draw (8.5, 3.0); move (9.0, 3.0); draw (10.25, 3.0);
+ move (7.5, 1.0); draw (7.5, 3.3);
+ move (8.0, 1.0); draw (8.0, 3.3);
+ move (8.5, 1.0); draw (8.5, 3.3);
+ move (9.0, 1.0); draw (9.0, 3.3);
+ move (9.5, 1.0); draw (9.5, 3.3);
+ move (10.0, 1.0); draw (10.0, 3.3);
+move (7.6, 3.1); draw ("4");
+move (7.6, 2.0); draw ("M");
+move (8.1, 3.1); draw ("5");
+move (8.1, 2.0); draw ("N");
+move (8.6, 3.1); draw ("6");
+move (9.1, 3.1); draw ("7");
+move (9.1, 2.0); draw ("O");
+move (9.6, 3.1); draw ("8");
+move (9.6, 2.0); draw ("P");
+
+pfeil (8.75, 0.75);
+
+PROC pfeil (REAL CONST x spitze, y spitze) :
+
+ move (x spitze, y spitze);
+ draw (x spitze + 0.25, y spitze - 0.25);
+ draw (x spitze + 0.1, y spitze - 0.25);
+ draw (x spitze + 0.1, y spitze - 0.5);
+ draw (x spitze - 0.1, y spitze - 0.5);
+ draw (x spitze - 0.1, y spitze - 0.25);
+ draw (x spitze - 0.25, y spitze - 0.25);
+ draw (x spitze, y spitze)
+
+END PROC pfeil;
+
+
+LET myname = "abb.6-1";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (9000)
+*)
+
diff --git a/doc/eudas/abb.6-2 b/doc/eudas/abb.6-2
new file mode 100644
index 0000000..7771a29
--- /dev/null
+++ b/doc/eudas/abb.6-2
@@ -0,0 +1,77 @@
+init dgs;
+window (0.0, 0.0, 13.5, 5.0); viewport (0.0,0.0,13.5,5.0);
+(*scale (1.4,1.4, 0.0,0.0);*)
+(*clear pixels;*)
+
+move (2.5, 4.5); draw (12.4, 4.5); draw (12.4, 4.0); draw (11.0, 4.0);
+ draw (11.0, 3.5); move (10.5, 3.5); draw (10.5, 4.0); draw (2.5, 4.0);
+move (13.5, 4.5); draw (12.5, 4.5); draw (12.5, 3.5); move (13.0, 3.5);
+ draw (13.0, 4.0); draw (13.5, 4.0);
+move (2.5, 3.5); draw (13.5, 3.5); move (13.5, 3.0); draw (10.0, 3.0);
+ draw (10.0, 2.5); move (9.5, 2.5); draw (9.5, 3.0); draw (2.5, 3.0);
+move (10.5, 3.0); draw (10.5, 2.5); move (11.0, 2.5); draw (11.0, 3.0);
+move (12.5, 2.5); draw (12.5, 3.0); move (13.0, 3.0); draw (13.0, 2.5);
+move (2.5, 2.5); draw (6.4, 2.5); draw (6.4, 2.0); draw (4.0, 2.0);
+ draw (4.0, 1.5); draw (6.5, 1.5); draw (6.5, 2.5); draw (13.5, 2.5);
+ move (13.5, 2.0); draw (7.0, 2.0); draw (7.0, 1.5); draw (9.0, 1.5);
+ draw (9.0, 1.0); draw (3.5, 1.0); draw (3.5, 2.0); draw (2.5, 2.0);
+move (9.5, 2.0); draw (9.5, 1.0); draw (10.4, 1.0); draw (10.4, 1.5);
+ draw (10.0, 1.5); draw (10.0, 2.0);
+move (10.5, 2.0); draw (10.5, 1.0); draw (13.0, 1.0); draw (13.0, 2.0);
+ move (11.0, 2.0); draw (11.0, 1.5); draw (12.5, 1.5); draw (12.5, 2.0);
+move (4.5, 1.5); draw (4.75, 1.25); draw (4.5, 1.0);
+move (5.5, 1.5); draw (5.75, 1.25); draw (5.5, 1.0);
+move (7.5, 1.5); draw (7.75, 1.25); draw (7.5, 1.0);
+move (11.5, 1.5); draw (11.75, 1.25); draw (11.5, 1.0);
+
+font size (0.25); font expansion (1.4);
+move (2.5, 4.1); draw ("K0");
+move (2.5, 3.1); draw ("N0");
+move (2.5, 2.1); draw ("A0");
+
+move (0.0, 4.1); draw ("'Kalender'");
+move (0.0, 3.1); draw ("'Namen'");
+move (0.0, 2.1); draw ("'Adressen'");
+move (0.0, 1.1); draw ("Arbeitskopie");
+
+move (4.9, 1.1); draw ("A1");
+move (5.9, 1.1); draw ("A2");
+move (7.9, 1.1); draw ("A3");
+move (11.9, 1.1); draw ("K1");
+
+x alignment (right);
+move (13.5, 4.1); draw ("K1");
+move (13.5, 3.1); draw ("N0");
+move (13.5, 2.1); draw ("A2");
+
+x alignment (normal);
+font size (0.2);
+INT VAR i;
+FOR i FROM 0 UPTO 10 REP
+ time (2.5 + real (i) * 1.0, i)
+END REP;
+
+PROC time (REAL CONST x pos, INT CONST nr) :
+
+ move (x pos, 4.9); draw (x pos, 4.6);
+ move (x pos, 3.9); draw (x pos, 3.6);
+ move (x pos, 2.9); draw (x pos, 2.6);
+ move (x pos, 1.9); draw (x pos, 1.6);
+ move (x pos, 0.9); draw (x pos, 0.6);
+ move (x pos + 0.1, 0.6); draw (text (nr))
+
+END PROC time;
+
+
+LET myname = "abb.6-2";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (9000);
+*)
+
diff --git a/doc/eudas/abb.7-1 b/doc/eudas/abb.7-1
new file mode 100644
index 0000000..3536ad9
--- /dev/null
+++ b/doc/eudas/abb.7-1
@@ -0,0 +1,46 @@
+init dgs;
+window (0.0, 0.0, 13.5, 6.0); viewport (0.0,0.0,13.5,6.0);
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+
+kasten (5.0, 4.5, 3.0, 1.0);
+kasten (5.0, 1.5, 3.0, 1.0);
+kasten (1.5, 3.0, 3.0, 1.0);
+font size (0.35); font expansion (1.5);
+x alignment (center);
+move (6.5, 4.8); draw ("Druckmuster");
+move (6.5, 1.8); draw ("Druckdatei");
+move (3.0, 3.3); draw ("EUDAS-Datei");
+move (6.5, 0.0); draw ("Drucker");
+
+move (6.5, 4.25); draw (6.5, 2.75); draw (6.25, 3.0);
+ move (6.5, 2.75); draw (6.75, 3.0);
+move (4.75, 3.5); draw (6.25, 3.5); draw (6.0, 3.75);
+ move (6.25, 3.5); draw (6.0, 3.25);
+move (6.5, 1.25); draw (6.5, 0.5); draw (6.75, 0.75);
+ move (6.5, 0.5); draw (6.25, 0.75);
+
+
+PROC kasten (REAL CONST x anf, y anf, x l, y l) :
+
+ move (x anf, y anf);
+ draw (x anf, y anf + y l);
+ draw (x anf + x l, y anf + y l);
+ draw (x anf + x l, y anf);
+ draw (x anf, y anf)
+
+END PROC kasten;
+
+
+LET myname = "abb.7-1";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (9000);
+*)
+
diff --git a/doc/eudas/abb.9-1 b/doc/eudas/abb.9-1
new file mode 100644
index 0000000..774b78b
--- /dev/null
+++ b/doc/eudas/abb.9-1
@@ -0,0 +1,41 @@
+init dgs;
+window (0.0, 0.0, 13.5, 4.0); viewport (0.0,0.0,13.5,4.0);
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+
+move (1.5, 1.0); draw (8.75, 1.0);
+move (1.5, 3.5); draw (8.75, 3.5);
+INT VAR i;
+FOR i FROM 0 UPTO 9 REP
+ move (1.75 + real (i) * 0.75, 3.7);
+ draw (1.75 + real (i) * 0.75, 1.0);
+END REP;
+
+move (4.7, 3.7); draw (4.7, 1.0);
+
+font size (0.25); font expansion (1.5);
+x alignment (center);
+FOR i FROM 0 UPTO 8 REP
+ move (2.125 + real (i) * 0.75, 3.6); draw (text (i + 110))
+END REP;
+FOR i FROM 1 UPTO 5 REP
+ move (2.125 + real (i + 3) * 0.75, 0.6); draw ("(" + text (i) + ")")
+END REP;
+
+font size (0.35); x alignment (left);
+move (2.0, 0.0); draw ("Datei A");
+move (5.0, 0.0); draw ("Datei B");
+
+
+LET myname = "abb.9-1";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (9000)
+*)
+
diff --git a/doc/eudas/abb.9-2 b/doc/eudas/abb.9-2
new file mode 100644
index 0000000..4e9444d
--- /dev/null
+++ b/doc/eudas/abb.9-2
@@ -0,0 +1,96 @@
+init dgs;
+window (0.0, 0.0, 13.5, 6.5); viewport (0.0,0.0,13.5,6.5);
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+
+INT VAR i;
+move (4.0, 0.0); draw (4.0, 2.0);
+move (5.5, 0.0); draw (5.5, 2.0);
+FOR i FROM 0 UPTO 4 REP
+ move (4.0, real (i) * 0.5);
+ draw (5.5, real (i) * 0.5)
+END REP;
+
+move (4.0, 3.0); draw (4.0, 6.0);
+move (5.5, 3.0); draw (5.5, 6.0);
+FOR i FROM 0 UPTO 6 REP
+ move (4.0, real (i) * 0.5 + 3.0);
+ draw (5.5, real (i) * 0.5 + 3.0)
+END REP;
+
+move (7.5, 2.0); draw (7.5, 6.0);
+move (9.0, 2.0); draw (9.0, 6.0);
+FOR i FROM 0 UPTO 8 REP
+ move (7.5, real (i) * 0.5 + 2.0);
+ draw (9.0, real (i) * 0.5 + 2.0)
+END REP;
+
+strichel (5.5, 6.0, 7.5, 6.0);
+strichel (5.5, 3.0, 7.5, 3.0);
+strichel (5.5, 1.0, 7.5, 3.0);
+strichel (5.5, 0.0, 7.5, 2.0);
+
+move (5.5, 4.75); draw (6.0, 4.75);
+ draw (6.0, 1.75); draw (5.5, 1.75);
+move (4.0, 3.75); draw (3.5, 3.75);
+ draw (3.5, 1.25); draw (4.0, 1.25);
+
+font size (0.4); font expansion (1.5);
+move (0.0, 0.8); draw ("Koppeldatei");
+move (0.0, 4.3); draw ("Hauptdatei");
+move (10.0, 4.3); draw ("virtuelle");
+move (10.0, 3.4); draw ("Datei");
+
+font size (0.3);
+move (4.5, 0.1); draw ("H2");
+move (4.5, 0.6); draw ("H1");
+move (4.5, 1.1); draw ("B");
+move (4.5, 1.6); draw ("A");
+move (4.5, 3.1); draw ("F4");
+move (4.5, 3.6); draw ("B");
+move (4.5, 4.1); draw ("F3");
+move (4.5, 4.6); draw ("A");
+move (4.5, 5.1); draw ("F2");
+move (4.5, 5.6); draw ("F1");
+move (8.0, 5.6); draw ("F1");
+move (8.0, 5.1); draw ("F2");
+move (8.0, 4.6); draw ("A");
+move (8.0, 4.1); draw ("F3");
+move (8.0, 3.6); draw ("B");
+move (8.0, 3.1); draw ("F4");
+move (8.0, 2.6); draw ("H1");
+move (8.0, 2.1); draw ("H2");
+
+PROC strichel (REAL CONST x anf, y anf, x end, y end) :
+
+ REAL VAR laenge := x end - x anf;
+ INT VAR teile := int (abstand/ 0.4);
+ REAL VAR verhaeltnis := (y end - y anf) / laenge;
+ laenge := laenge / (real (2 * teile + 1));
+ INT VAR i;
+ FOR i FROM 0 UPTO teile REP
+ move (x anf + real (i + i) * laenge,
+ y anf + verhaeltnis * real (i + i) * laenge);
+ draw (x anf + real (i + i + 1) * laenge,
+ y anf + verhaeltnis * real (i + i + 1) * laenge)
+ END REP .
+
+abstand :
+ sqrt ((y end - y anf) + (y end - y anf) +
+ (x end - x anf) * (x end - x anf)) .
+
+END PROC strichel;
+
+
+LET myname = "abb.9-2";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (9000);
+*)
+
diff --git a/doc/eudas/abb.9-3 b/doc/eudas/abb.9-3
new file mode 100644
index 0000000..9b190ab
--- /dev/null
+++ b/doc/eudas/abb.9-3
@@ -0,0 +1,113 @@
+init dgs;
+window (0.0, 0.0, 13.5, 7.0); viewport (0.0,0.0,13.5,7.0);
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+
+x alignment (center);
+font size (0.3); font expansion (1.2);
+kasten (1.5, 5.0, 2.0, 1.5);
+move (2.5, 5.9); draw ("EUDAS-");
+move (2.5, 5.3); draw ("Datei 1");
+move (3.5, 5.75); draw (4.0, 5.75);
+kasten (4.0, 5.0, 2.0, 1.5);
+move (5.0, 5.9); draw ("gekettete");
+move (5.0, 5.3); draw ("Datei A");
+move (6.0, 5.75); draw (6.5, 5.75);
+kasten (6.5, 5.0, 2.0, 1.5);
+move (7.5, 5.9); draw ("gekettete");
+move (7.5, 5.3); draw ("Datei B");
+kasten (1.5, 2.0, 2.0, 1.5);
+move (2.5, 2.9); draw ("gekoppelte");
+move (2.5, 2.3); draw ("Datei C");
+kasten (4.0, 0.0, 2.0, 1.5);
+move (5.0, 0.9); draw ("gekoppelte");
+move (5.0, 0.3); draw ("Datei D");
+
+punkt (9.0, 5.75);
+punkt (9.25, 5.75);
+punkt (9.5, 5.75);
+
+strichel (1.0, 4.5, 10.0, 4.5);
+strichel (1.0, 7.0, 10.0, 7.0);
+strichel (1.0, 4.5, 1.0, 7.0);
+x alignment (right); font size (0.4);
+move (10.0, 3.9);
+draw ("Hauptdatei");
+
+punkt (2.5, 3.75);
+punkt (2.5, 4.0);
+punkt (2.5, 4.25);
+
+punkt (5.0, 1.75);
+punkt (5.0, 2.0);
+punkt (5.0, 2.25);
+punkt (5.0, 2.5);
+punkt (5.0, 2.75);
+punkt (5.0, 3.0);
+punkt (5.0, 3.25);
+punkt (5.0, 3.5);
+punkt (5.0, 3.75);
+punkt (5.0, 4.0);
+punkt (5.0, 4.25);
+
+PROC punkt (REAL CONST x pos, y pos) :
+
+ LET p size = 0.025;
+ move (x pos, y pos + p size);
+ draw (x pos + p size, y pos);
+ draw (x pos, y pos - p size);
+ draw (x pos - p size, y pos);
+ draw (x pos, y pos + p size)
+
+END PROC punkt;
+
+
+PROC strichel (REAL CONST x anf, y anf, x end, y end) :
+
+ REAL VAR laenge := x end - x anf;
+ INT VAR teile := int (abstand/ 0.4);
+ REAL VAR senkrecht, verhaeltnis;
+ IF laenge <> 0.0 THEN
+ verhaeltnis := (y end - y anf) / laenge; senkrecht := 1.0
+ ELSE
+ verhaeltnis := 1.0; senkrecht := 0.0 ;
+ laenge := y end - y anf
+ END IF;
+ laenge := laenge / (real (2 * teile + 1));
+ INT VAR i;
+ FOR i FROM 0 UPTO teile REP
+ move (x anf + real (i + i) * laenge * senkrecht,
+ y anf + verhaeltnis * real (i + i) * laenge);
+ draw (x anf + real (i + i + 1) * laenge * senkrecht,
+ y anf + verhaeltnis * real (i + i + 1) * laenge)
+ END REP .
+
+abstand :
+ sqrt ((y end - y anf) * (y end - y anf) +
+ (x end - x anf) * (x end - x anf)) .
+
+END PROC strichel;
+
+PROC kasten (REAL CONST x anf, y anf, x l, y l) :
+
+ move (x anf, y anf);
+ draw (x anf, y anf + y l);
+ draw (x anf + x l, y anf + y l);
+ draw (x anf + x l, y anf);
+ draw (x anf, y anf)
+
+END PROC kasten;
+
+
+LET myname = "abb.9-3";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (9000)
+*)
+
diff --git a/doc/eudas/abb.9-4 b/doc/eudas/abb.9-4
new file mode 100644
index 0000000..e243265
--- /dev/null
+++ b/doc/eudas/abb.9-4
@@ -0,0 +1,98 @@
+init dgs;
+window (0.0, 0.0, 13.5, 6.0); viewport (0.0,0.0,13.5,6.0);
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+
+kasten (2.0, 1.0, 1.4, 2.0);
+kasten (3.5, 1.0, 1.4, 2.0);
+kasten (6.5, 1.0, 1.4, 2.0);
+kasten (2.0, 3.4, 1.4, 2.0);
+kasten (5.0, 3.4, 1.4, 2.0);
+kasten (6.5, 3.4, 1.4, 2.0);
+ strichel (3.5, 3.4, 3.5, 5.4);
+ strichel (3.5, 5.4, 4.9, 5.4);
+ strichel (4.9, 5.4, 4.9, 3.4);
+ strichel (4.9, 3.4, 3.5, 3.4);
+move (1.9, 2.7); draw (1.5, 2.7);
+draw (1.5, 4.6); draw (1.9, 4.6);
+
+x alignment (center);
+font size (0.3); font expansion (1.4);
+
+move (2.7, 5.6); draw ("22-1");
+move (2.7, 4.9); draw ("X");
+move (2.7, 4.4); draw ("K");
+move (2.7, 2.5); draw ("K");
+move (2.7, 2.0); draw ("N1");
+move (2.7, 0.4); draw ("(114)");
+
+move (4.2, 5.6); draw ("22-2");
+move (4.2, 4.9); draw ("X");
+move (4.2, 4.4); draw ("K");
+move (4.2, 2.5); draw ("K");
+move (4.2, 2.0); draw ("N2");
+move (4.2, 0.4); draw ("(209)");
+
+move (5.7, 5.6); draw ("23-1");
+move (5.7, 4.9); draw ("Y");
+move (5.7, 4.4); draw ("L");
+
+move (7.2, 5.6); draw ("24-1");
+move (7.2, 4.9); draw ("Z");
+move (7.2, 4.4); draw ("M");
+move (7.2, 2.5); draw ("M");
+move (7.2, 0.4); draw ("(17)");
+
+font size (0.4); x alignment (normal);
+move (8.5, 2.0); draw ("Koppeldatei");
+move (8.5, 4.4); draw ("Hauptdatei");
+
+PROC strichel (REAL CONST x anf, y anf, x end, y end) :
+
+ REAL VAR laenge := x end - x anf;
+ INT VAR teile := int (abstand/ 0.4);
+ REAL VAR senkrecht, verhaeltnis;
+ IF laenge <> 0.0 THEN
+ verhaeltnis := (y end - y anf) / laenge; senkrecht := 1.0
+ ELSE
+ verhaeltnis := 1.0; senkrecht := 0.0 ;
+ laenge := y end - y anf
+ END IF;
+ laenge := laenge / (real (2 * teile + 1));
+ INT VAR i;
+ FOR i FROM 0 UPTO teile REP
+ move (x anf + real (i + i) * laenge * senkrecht,
+ y anf + verhaeltnis * real (i + i) * laenge);
+ draw (x anf + real (i + i + 1) * laenge * senkrecht,
+ y anf + verhaeltnis * real (i + i + 1) * laenge)
+ END REP .
+
+abstand :
+ sqrt ((y end - y anf) * (y end - y anf) +
+ (x end - x anf) * (x end - x anf)) .
+
+END PROC strichel;
+
+PROC kasten (REAL CONST x anf, y anf, x l, y l) :
+
+ move (x anf, y anf);
+ draw (x anf, y anf + y l);
+ draw (x anf + x l, y anf + y l);
+ draw (x anf + x l, y anf);
+ draw (x anf, y anf)
+
+END PROC kasten;
+
+
+LET myname = "abb.9-4";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (9000)
+*)
+
diff --git a/doc/eudas/abb.9-5 b/doc/eudas/abb.9-5
new file mode 100644
index 0000000..c00655c
--- /dev/null
+++ b/doc/eudas/abb.9-5
@@ -0,0 +1,51 @@
+init dgs;
+window (0.0, 0.0, 13.5, 7.0); viewport (0.0,0.0,13.5,7.0);
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+
+kasten (1.5, 0.0, 3.5, 2.0);
+kasten (7.0, 0.0, 3.5, 2.0);
+kasten (4.0, 4.0, 4.0, 3.0);
+ kasten (5.0, 5.5, 2.0, 1.0);
+
+move (3.25, 2.25); draw (4.75, 3.75);
+ draw (4.5, 3.75); move (4.75, 3.75); draw (4.75, 3.5);
+ move (3.25, 2.25); draw (3.5, 2.25);
+ move (3.25, 2.25); draw (3.25, 2.5);
+move (8.75, 2.25); draw (7.25, 3.75);
+ draw (7.5, 3.75); move (7.25, 3.75); draw (7.25, 3.5);
+ move (8.75, 2.25); draw (8.5, 2.25);
+ move (8.75, 2.25); draw (8.75, 2.5);
+
+x alignment (center);
+font size (0.4); font expansion (1.4);
+
+move (3.25, 0.2); draw ("Benutzer A");
+move (8.75, 0.2); draw ("Benutzer B");
+move (6.0, 4.3); draw ("Manager");
+font size (0.3);
+move (6.0, 5.6); draw ("Kunden");
+
+PROC kasten (REAL CONST x anf, y anf, x l, y l) :
+
+ move (x anf, y anf);
+ draw (x anf, y anf + y l);
+ draw (x anf + x l, y anf + y l);
+ draw (x anf + x l, y anf);
+ draw (x anf, y anf)
+
+END PROC kasten;
+
+
+LET myname = "abb.9-5";
+save pixels (myname + ".p");
+FILE VAR f := sequential file (modify, myname + ".p");
+to line (f, 1); insert record (f);
+write record (f, "#linefeed (0.8)#");
+insert record (f); write record (f, myname);
+to eof (f); insert record (f); write record (f, myname);
+to line (f, 1);
+(*
+pause (9000)
+*)
+
diff --git a/doc/eudas/bildergenerator b/doc/eudas/bildergenerator
new file mode 100644
index 0000000..8129476
--- /dev/null
+++ b/doc/eudas/bildergenerator
@@ -0,0 +1,25 @@
+PROC starten :
+
+ command dialogue (FALSE);
+ disable stop;
+ fetch (name, /"DGS NEC");
+ run (name);
+ save (name + ".p", /"DGS NEC");
+ end (myself)
+
+END PROC starten;
+
+TEXT VAR name;
+
+PROC gen (TEXT CONST t) :
+
+ name := t;
+ begin ("p", PROC starten, a);
+ TASK VAR a;
+ WHILE exists (a) REP pause (100) END REP
+
+END PROC gen;
+
+gen ("abb.4-2");
+gen ("abb.6-1");
+
diff --git a/doc/eudas/eudas.hdb.1 b/doc/eudas/eudas.hdb.1
new file mode 100644
index 0000000..40b5a84
--- /dev/null
+++ b/doc/eudas/eudas.hdb.1
@@ -0,0 +1,267 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (3)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+#center##on("b")#"Was kann EUDAS ?
+
+
+
+In diesem Kapitel wollen wir Ihnen erklären, was EUDAS Ihnen ei­
+gentlich bringen soll. Sie arbeiten sicher nicht nur aus Spaß am
+Computer, sondern wollen ihn für bestimmte Aufgaben einsetzen. Ein
+Computer kann bestimmte Aufgaben nur dann bearbeiten, wenn er
+dafür programmiert worden ist.
+ EUDAS ist nun ein Programm, das allgemein Aufgaben der Da­
+tenverwaltung lösen kann. Zunächst wollen wir Ihnen erläutern,
+wodurch dieses Anwendungsgebiet genau charakterisiert wird.
+
+
+1.1 Textverarbeitung und Datenverwaltung
+
+Es gibt zwei Einsatzbereiche des Computers, die von fast jedem An­
+wender benötigt werden, egal auf welchem Spezialgebiet er tätig ist:
+nämlich die #on("i")#Textverarbeitung#off("i")# und die #on("i")#Datenverwaltung#off("i")#. Durch die
+Unterscheidung dieser beiden Bereiche werden die charakteristi­
+schen Merkmale der Datenverwaltung abgegrenzt.
+
+#on("b")#Textverarbeitung#off("b")# Die Textverarbeitung befaßt sich damit,
+einen beliebigen Text auf einem Rechner zu erfassen und anschließend
+über einen Drucker wieder auszugeben. Der Sinn dieser Arbeit liegt
+darin, daß man einen einmal eingegebenen Text sehr einfach ändern
+kann. Außerdem kann der Computer einige unangenehme Aufgaben
+übernehmen, die beim Schreiben von Texten auftreten: die Auftei­
+lung auf Zeilen und Seiten, die Seitennumerierung und vieles mehr.
+ Charakteristisch für die Textverarbeitung ist, daß der Einfluß
+des Computers sich auf kosmetische Details beschränkt. Die Spei­
+cherung und eventuelle Aufbereitung zum Drucken haben praktisch
+nichts mit dem Inhalt des Textes zu tun. Dies wäre für den Rechner
+auch sehr schwierig, da die im Text enthaltenen Informationen in
+menschlicher Sprache vorliegen, die für einen Rechner nicht ver­
+ständlich ist.
+
+#on("b")#Datenverwaltung#off("b")# Bei der Datenverwaltung werden ebenfalls
+textuelle Informationen gespeichert, diese liegen aber in einer aufberei­
+teten Form vor, die einen Teil des Inhalts für den Computer ver­
+ständlich macht. Bei der Datenverwaltung werden Objekte betrach­
+tet, die verschiedene Eigenschaften haben können. Ein solches
+Objekt kann z.B. eine Person sein. Als Eigenschaften werden mit
+dieser Person zusammenhängende Informationen betrachetet, die für
+die jeweilige Anwendung wichtig sind.
+ Ein Beispiel für eine solche Betrachtungsweise ist der Arbeit­
+nehmer im Betrieb. Einige der typischerweise erfaßten Daten sind
+Name, Adresse, Telefon, Geburtsdatum und Geschlecht. Alle diese
+Daten sind Eigenschaften oder #on("i")#Attribute#off("i")#, die einem bestimmten
+Menschen mehr oder weniger fest zugeordnet sind.
+ Die Betonung inhaltlicher Beziehungen erleichtert es dem Com­
+puter, die gespeicherten Daten in verschiedenen Variationen aus­
+zuwerten.
+
+#on("b")#Beispiel#off("b")# Um die Unterscheidung zwischen Textverarbeitung
+und
+Datenverwaltung deutlicher zu machen, werden im folgenden Bei­
+spiel die Informationen über eine Person in zwei unterschiedlichen
+Formen dargeboten, die für den Menschen die gleiche Aussagekraft
+haben:
+
+ 1. Frau Magdalene Kant, geb. Hagedorn, wurde am 12. Januar
+ 1946 geboren. Sie wohnt in Bonn in der Meckenheimer Allee
+ 112. Seit 1977 arbeitet sie in unserer Firma. Sie ist tele­
+ fonisch erreichbar unter der Nummer 0228/356782.
+
+ 2. Name: Magdalene
+ Vorname: Kant
+ Geburtsname: Hagedorn
+ Geburtsdatum: 12.01.46
+ Geschlecht: weiblich
+ Strasse: Meckenheimer Allee 112
+ PLZ: 5200
+ Wohnort: Bonn 1
+ Vorwahl: 0228
+ Telefon: 356782
+ beschäftigt seit: 1977
+
+Die Form der Darstellung wie in der ersten Alternative eignet sich
+nur für den Menschen, da die gleiche Information auf viele ver­
+schiedene Weisen ausgedrückt werden könnte (z.B. unterschiedlicher
+Satzbau). Die zweite Alternative beschränkt sich auf die für die
+bestimmte Anwendung wesentlichen Zusammenhänge; der Computer
+kann die Aufteilung der Information in einzelne Attribute ausnut­
+zen.
+ In dieser zweiten Form können Sie Daten mit EUDAS erfassen
+und auch auswerten. Die Attribute können Sie jeweils passend zu
+den erfaßten Daten selbst bestimmen.
+ Für Daten in der ersten Form steht Ihnen die EUMEL-Textver­
+arbeitung zur Verfügung. EUDAS wurde so entwickelt, daß Sie auch
+Daten an die Textverarbeitung übergeben können.
+ Es ist nämlich möglich, einen freien Text aus der Attributdar­
+stellung automatisch zu erzeugen, indem Sie dem Computer den
+Satzbau mit entsprechenden Platzhaltern vorgeben. Der Rechner
+setzt die einzelnen Attribute dann an die angegebenen Stellen.
+Diese Funktion ist ein Kernstück von EUDAS und wird in Abschnitt
+1.3 näher erläutert.
+
+
+1.2 EUDAS als Karteikasten
+
+Wie Sie vielleicht schon bemerkt haben, ähnelt die zweite Form der
+Darstellung einer Karteikarte, auf der Platz für bestimmte Einträge
+freigehalten wird. Anhand dieses Modells können Sie sich in vielen
+Fällen die Arbeitsweise von EUDAS veranschaulichen. Sie sollten die
+Analogie allerdings nicht zu weit treiben: EUDAS schaufelt ja nicht
+wirklich mit Karteikarten herum. Manche Funktionen sind eben
+computerspezifisch und ließen sich mit Karteikarten gar nicht
+durchführen.
+ Mit EUDAS können Sie die möglichen Einträge auf den Karteikar­
+ten (also die Attribute) völlig frei bestimmen; die einzige Beschrän­
+kung besteht darin, daß Sie in einem Karteikasten nur Karten mit
+völlig gleichem Aufbau verwenden können. Wenn Sie eine neue Kar­
+teikarte entwerfen wollen, brauchen Sie nur Namen für die einzel­
+nen Einträge anzugeben. EUDAS zeigt Ihnen dann quasi eine Karte
+am Bildschirm, in der diese Einträge aufgeführt sind.
+ Sie können nun am Bildschirm Daten auf diese Karteikarten
+schreiben. Dabei dürfen die Einträge fast beliebig lang sein; wenn
+der Platz auf dem Bildschirm nicht reicht, können Sie sich Ihre
+überdimensionale Karteikarte in Ausschnitten ansehen.
+ Die einmal eingegebenen Daten bleiben nun so lange gespei­
+chert, wie Sie wollen (bzw. bis Ihr Rechner zusammenfällt). Haben
+Sie beim Eintragen Fehler gemacht, können Sie diese jederzeit kor­
+rigieren oder später noch weitere Informationen ergänzen.
+
+#free (7.5)#
+
+#center#Abb. 1-1 EUDAS als Karteikasten
+
+
+#on("b")#Anwendungen#off("b")# Mit den gespeicherten Daten können Sie nun
+ver­
+schiedene Dinge anstellen (bzw. vom Rechner anstellen lassen). Das
+Einfachste ist natürlich das, was Sie mit einer Kartei auch machen
+würden, sich nämlich einzelne Karteikarten anzuschauen.
+ Um eine bestimmte Karteikarte herauszufinden, geben Sie
+EUDAS einfach den Inhalt vor, nach dem gesucht werden soll. Hier
+zeigt sich bereits der erste Vorteil eines Computers: Die Suche in
+der EUDAS-Kartei ist viel schneller, als Sie es von Hand könnten.
+Außerdem kann der Rechner keine Karte zufällig übersehen.
+ EUDAS zeigt sich auch dann überlegen, wenn Sie einen ganz
+bestimmten Teil der Kartei durchforsten müssen. Eine Bücherei muß
+z.B. regelmäßig alle Bücher heraussuchen, deren Leihfrist über­
+schritten ist. Der Computer durchsucht in solchen Fällen ermü­
+dungsfrei auch große Datenmengen.
+ Wenn Sie die Karteikarten in einer bestimmten Reihenfolge
+haben wollen, kann EUDAS auch das Sortieren übernehmen. Weitere
+automatische Vorgänge betreffen z.B. das Rauswerfen überflüssiger
+oder veralteter Karten. Die Einträge können auch nach einer be­
+stimmten Vorschrift alle geändert werden. Solche Aufgaben treten
+z.B. in der Schule auf, wo die Schüler jedes Jahr versetzt werden
+müssen (natürlich bis auf Ausnahmen).
+ Auch Beziehungen zwischen verschiedenen Karteien kann
+EUDAS herstellen. Dies kann man noch einmal an dem Beispiel der
+Bücherei illustrieren. Wenn ein Buch gefunden wurde, dessen Leih­
+frist überschritten ist, muß der zugehörige Ausleiher gefunden und
+angeschrieben werden. Das Heraussuchen beider Karten kann EUDAS
+in einem Arbeitsgang durchführen.
+
+
+1.3 Drucken
+
+Eine besondere Stärke von EUDAS ist die Möglichkeit, die gespei­
+cherten Daten in schriftlicher Form auszuwerten. Dadurch, daß die
+Daten in einer Form gespeichert sind, die den Inhalt widerspiegelt,
+können die gleichen Daten in vielen verschiedenen Formen auf
+Papier ausgegeben werden.
+
+
+
+
+ Karl Eudas
+ An Poltersdorf
+ XXXXXXXXXXX
+ XXXXXXXXXXX
+
+ XXXX XXXXXXXXXXXX
+
+ Lieber XXXXXXX !
+
+ Dies ist ein Beispiel für ein
+ Druckmuster.
+
+ Viele Grüße
+
+
+
+#center#Abb. 1-2 Muster für die Druckausgabe
+
+
+Zu diesem Zweck geben Sie EUDAS ein Muster des gewünschten Aus­
+drucks vor. Der Rechner setzt dann an entsprechend markierten
+Leerstellen die gespeicherten Informationen ein und druckt das
+Ergebnis aus. Auf diese Weise ersparen Sie sich die umfangreiche
+Schreibarbeit, die anfällt, wenn die Informationen auf den Kartei­
+karten in anderer Form benötigt werden.
+ Natürlich müssen Sie zum Entwerfen des Formulars kein ge­
+wiefter Programmierer sein. Wenn Sie einen Rundbrief verschicken
+wollen, schreiben Sie den Brief, als wollten Sie Ihn nur einmal
+schicken. Lediglich im Adressfeld müssen Sie Platzhalter an den
+Stellen vorsehen, an denen später die wirklichen Adressen stehen
+sollen.
+
+#on("b")#Verwendungsmöglichkeiten#off("b")# Die Möglichkeiten für solche
+Formulare
+sind unbegrenzt. Beispiele sind Briefe, Adreßaufkleber, Überwei­
+sungsaufträge und sortierte Listen. Mit den Inhalten einer Kartei
+können Sie beliebig viele verschiedene Ausgaben erzeugen. Bei dem
+obigen Beispiel der Leihbücherei könnten Sie EUDAS dazu einsetzen,
+nicht nur die säumigen Ausleiher herauszufinden, sondern die Mah­
+nung gleich fertig für einen Fensterbriefumschlag herzustellen. Für
+den Bediener bliebe die einzige Tätigkeit, diesen Vorgang anzuwer­
+fen.
+ Wie weiter oben schon erwähnt, können Sie diese Ausgaben von
+EUDAS auch zur Textverarbeitung übernehmen. So können Sie zum
+Beispiel die Literaturliste für ein Buch mit EUDAS führen und Aus­
+züge später jeweils an die passenden Stellen einfügen.
+
+#on("b")#Berechnungen#off("b")# Die Druckfunktion von EUDAS kann jedoch nicht
+nur
+zum Ausfüllen von Formularen verwendet werden. Wenn Sie Berech­
+nungen anstellen oder Auswertungen vornehmen wollen, können Sie
+im Druckmuster auch Anweisungen der Sprache ELAN verwenden.
+Damit haben Sie eine komplette Programmiersprache für Ihre Muster
+zur Verfügung.
+ Ehe Sie einen Schreck bekommen: Selbst für komplizierte Muster
+brauchen Sie nur einen ganz kleinen Teil von ELAN zu beherrschen,
+da die meiste Arbeit immer von EUDAS übernommen wird (Sie müssen
+also nicht etwa selber ein ganzes Programm schreiben).
+ Anwendungen für diese Möglichkeit gibt es genug. Angefangen
+von einfachen Zählungen bis hin zu statistischen Auswertungen,
+von einfachen Summen bis zum kompletten Rechnungsschreiben.
+Immer nimmt Ihnen EUDAS alles das ab, was automatisch ablaufen
+kann. Sie versorgen EUDAS nur noch mit den passenden Formeln für
+Ihre Anwendung.
+
+
+1.4 Grenzen
+
+Natürlich können Sie nicht alle Probleme mit EUDAS gleichermaßen
+gut lösen. EUDAS verwendet ein einfaches Modell (Karteikasten) und
+versucht, mit möglichst wenig Informationen von Ihrer Seite auszu­
+kommen. Kompliziertere Sachverhalte verlangen auch kompliziertere
+Strukturen, die Sie dann selbst entwerfen müssen. Eine einfache
+Lösung mit EUDAS kann in solchen Fällen zu langsam oder zu um­
+ständlich sein.
+ Wenn Sie jedoch die wenigen Strukturprinzipien von EUDAS
+verstanden haben, werden Sie sehr schnell viele Probleme mit
+EUDAS lösen können. Zuerst erfassen Sie einfach alle Daten, die Sie
+brauchen und überlegen sich erst dann, in welcher Form Sie diese
+Daten haben wollen. Auch nachträglich können Sie jederzeit noch
+neue Daten und Formulare hinzufügen, so daß Sie mit der Zeit
+EUDAS gewinnbringend für viele Routineaufgaben benutzen werden.
+
diff --git a/doc/eudas/eudas.hdb.10 b/doc/eudas/eudas.hdb.10
new file mode 100644
index 0000000..442f575
--- /dev/null
+++ b/doc/eudas/eudas.hdb.10
@@ -0,0 +1,510 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (97)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+10 Datenabfrage am Bildschirm
+
+
+
+10.1 Feldauswahl
+
+Da die Anzahl der möglichen Felder bei EUDAS-Dateien viel größer
+ist als die Anzahl der zur Verfügung stehenden Zeilen auf dem
+Bildschirm (255 gegenüber 22), muß es eine Möglichkeit geben, auch
+die übrigen Felder anzusehen.
+
+#on("b")#Rollen#off("b")# Dazu kann man den Bildschirmausschnitt in
+vertikaler
+Richtung #on("i")#rollen#off("i")#. Sie müssen sich die Bildschirmanzeige als einen
+Ausschnitt des wirklichen Satzes vorstellen. Um weitere Inhalte des
+Satzes zu sehen, verschieben Sie den Ausschnitt einfach.
+ Dazu dienen die beiden Tastenkombinationen ESC OBEN und ESC
+UNTEN. Diese Kombinationen wirken nur im Menü "Einzelsatz". An
+der Bildschirmanzeige ändert sich natürlich nur dann etwas, wenn
+es noch weitere Felder zum Anzeigen gibt.
+ Ob dies der Fall ist, können Sie an zwei Indikatoren ablesen.
+Zum einen wird hinter dem letzten Feld eine markierte Abschluß­
+zeile ausgegeben. Ist diese nicht sichtbar, gibt es noch Felder, die
+Sie mit ESC UNTEN hochholen können. Zum anderen steht die Num­
+mer der ersten Zeile in der Überschrift. Ist diese Nummer größer als
+1, können Sie mit ESC OBEN noch Felder sichtbar machen.
+ Das Rollen ist oft auch dann notwendig, wenn sich ein Feld
+über mehrere Zeilen erstreckt. In diesem Fall kann es passieren,
+daß die erste Zeile des Feldes nicht mehr sichtbar ist, da sie ober­
+halb des Anzeigebereichs liegen würde.
+
+#on("b")#Feldauswahl#off("b")# Eine weitere Möglichkeit bei zu vielen Feldern
+be­
+steht darin, nur die interessanten Felder zur Anzeige auszuwählen.
+Dies geschieht mit der Funktion
+#free (0.2)#
+
+ F Feldauswahl
+
+#free (0.2)#
+Ihnen werden alle Felder zur Auswahl angeboten. Kreuzen Sie die
+Felder an, die Sie sehen wollen und denken Sie daran, daß die Rei­
+henfolge des Ankreuzens beachtet wird. Anschließend werden Ihnen
+nur die ausgewählten Felder angezeigt. Falls Sie kein Feld ankreu­
+zen, bleibt die alte Feldauswahl bestehen.
+ Wollen Sie wieder alle Felder sehen, müssen Sie diese nicht alle
+einzeln ankreuzen. Mit HOP 'x' in der Auswahl werden alle Felder
+angekreuzt (die noch nicht angekreuzt waren). Diese Tastenkombi­
+nation können Sie allgemein bei einer Auswahl verwenden. Sie
+können die Kreuzchen mit 'o' auch wieder löschen, um zum Beispiel
+"alle außer einem" auszuwählen.
+ Beachten Sie, daß die Auswahl der anzuzeigenden Felder nichts
+mit der eigentlichen Dateistruktur zu tun hat, sondern nur für die
+Anzeige gilt. Den Verarbeitungsfunktionen (zum Beispiel Drucken)
+stehen natürlich nach wie vor alle Felder zur Verfügung.
+ Unvermutete Effekte können dann entstehen, wenn Sie bei
+einer eingestellten Feldauswahl ändern oder einfügen. Die nicht
+ausgewählten Felder werden beim Ändern natürlich nicht geändert
+und beim Einfügen einfach leer gelassen.
+
+
+10.2 Satzeditor
+
+An dieser Stelle sollen noch einige weitere Funktionen des Satz­
+editors vorgestellt werden, die Sie noch nicht kennengelernt haben.
+
+#on("b")#Rollen im Satzeditor#off("b")# Sie können auch rollen, wenn Sie sich
+im
+Satzeditor befinden (also beim Suchen, Einfügen und Ändern). Den­
+ken Sie daran, daß Sie die Einzelsatzanzeige immer mit ESC OBEN
+und ESC UNTEN rollen, während sonst (Editor, Auswahl von Datei­
+namen) immer mit HOP OBEN und HOP UNTEN gerollt wird.
+ Diese Diskrepanz hat technische Gründe und läßt sich leider
+nicht vermeiden. Wie Sie sich vielleicht erinnern, führt das Blättern
+mit HOP OBEN und HOP UNTEN im Satzeditor dazu, daß die Korre­
+spondenz zwischen Feldnamen und Feldinhalt verlorengeht. Daher
+muß an dieser Stelle mit ESC statt HOP gearbeitet werden.
+
+#on("b")#Ähnliche Sätze#off("b")# Wenn Sie mehrere ähnliche Sätze eintragen
+müssen,
+bietet Ihnen EUDAS eine Erleichterung an. Sie können nämlich beim
+Einfügen die Daten eines anderen Satzes übernehmen.
+ Dazu müssen Sie beim Ändern oder Einfügen des anderen Satzes
+ESC 'p' drücken. Der Inhalt des Satzes wird dann in einen Zwischen­
+speicher gebracht. Beachten Sie, daß im Gegensatz zum EUMEL-
+Editor kein Text markiert sein muß, sondern immer der ganze Satz
+transportiert wird.
+ Beim Einfügen eines neuen Satzes können Sie diesen Satz dann
+mit ESC 'g' in den Satzeditor übernehmen. Alle vorherigen Inhalte
+werden überschrieben. Anschließend können Sie die Daten nach
+Wunsch abändern.
+ Der Inhalt des Zwischenspeichers kann beliebig oft auf diese
+Weise kopiert werden. Der Inhalt des Zwischenspeichers wird bei
+Ändern der Feldauswahl oder beim Öffnen einer neuen Datei ge­
+löscht.
+
+#on("b")#Tagesdatum#off("b")# Im Satzeditor können Sie mit ESC 'D' das
+aktuelle
+Tagesdatum abfragen. Es wird an der aktuellen Cursorposition ein­
+getragen, als ob Sie es selbst getippt hätten.
+ Auf diese Weise können Sie Sätze einfach mit Datum versehen
+oder nach Sätzen suchen, die mit dem Tagesdatum in Beziehung
+stehen (zum Beispiel 'Fälligkeit = Heute').
+
+
+10.3 Suchmuster
+
+Die bisher genannten Möglichkeiten des Suchmusters sind noch
+etwas beschränkt. Eine Bedingung in unserer Adressendatei, die wir
+im Suchmuster noch nicht ausdrücken können, wäre zum Beispiel:
+Suche alle Adressen der Personen, die Wegner oder Simmern heißen.
+ Diese Alternative, Wegner ODER Simmern, kann nun in EUDAS
+durch ein Komma ausgedrückt werden:
+
+
+ Name Wegner,Simmern
+ Vorname
+
+
+Beachten Sie, daß hinter dem Komma kein Leerzeichen folgen darf,
+wie Sie es vielleicht gewohnt sind, in einem Text zu schreiben.
+EUDAS kann nämlich nicht unterscheiden, ob Sie das Leerzeichen
+nur aus optischen Gründen geschrieben haben, oder ob Sie danach
+suchen wollen.
+
+#on("b")#Lokale Alternative#off("b")# Die eben beschriebene
+Konstruktionsmethode
+heißt #on("i")#lokale Alternative#off("i")#. Lokal deshalb, weil Sie nur innerhalb
+eines Feldes gilt. Was das bedeuten soll, sehen Sie, wenn Sie die
+Bedingung mit einer weiteren Bedingung für ein anderes Feld kom­
+binieren:
+
+
+ Name Wegner,Simmern
+ Vorname
+ Strasse
+ PLZ 5*
+ Ort
+
+
+Dieses Muster hat die Bedeutung: Wähle alle Personen namens Weg­
+ner oder Simmern aus, die im PLZ-Bereich 5 wohnen. Die beiden
+Bedingungen für den Namen sind mit der Bedingung für die PLZ mit
+UND verknüpft - das heißt, eine der beiden ersten Bedingungen muß
+zutreffen #on("i")#und#off("i")# die untere Bedingung. Dieses UND ist global, da es
+Bedingungen für verschiedene Felder miteinander verbindet.
+ Natürlich können Sie für mehrere Felder gleichzeitig lokale
+Alternativen angeben. Eine anderes Suchmuster könnte zum Beispiel
+so aussehen:
+
+
+ Name Wegner,Simmern
+ Vorname
+ Strasse
+ PLZ 5,5000
+ Ort
+
+
+In diesem Fall muß eine ausgewählte Person Wegner oder Simmern
+heißen und in Köln wohnen.
+
+#on("b")#Globale Alternative#off("b")# Es wird nun aber für bestimmte
+Situationen
+noch eine andere Art von Alternativen benötigt. Als Beispiel soll
+ein Suchmuster dienen, das folgende Bedingung ausdrückt. Gesucht
+ist eine weibliche Person mit Namen Simmern oder eine männliche
+Person mit Namen Wegner.
+ Dieser Fall läßt sich mit unseren bisherigen Mitteln nicht lö­
+sen. Es wird nämlich eine Alternative zwischen zwei zusammen­
+gesetzten Bedingungen gefordert. Als Ausweg bietet sich an, prak­
+tisch mehrere Suchmuster anzugeben, die dann mit ODER verknüpft
+werden.
+ Um diese verschiedenen Suchmuster optisch am Bildschirm zu
+kennzeichnen, wird ein Semikolon als sogenannte #on("i")#globale Alternati­
+ve#off("i")# verwendet. Das Semikolon trennt das Suchmuster quasi in ver­
+schiedene Spalten auf, die jeweils eine eigene Bedingung enthalten
+können. Unser gewünschtes Suchmuster würde also so aussehen:
+
+
+ Name Wegner;Simmern
+ Vorname
+ Strasse
+ PLZ
+ Ort
+ m/w m;w
+
+
+Ebenso wie bei lokalen Alternativen darf hinter dem Semikolon kein
+Leerzeichen folgen. Daher kann das zweite Semikolon auch nicht
+direkt unter dem ersten stehen. Die Spalten werden also einfach nur
+durchgezählt: nach dem ersten Semikolon beginnt die zweite Spal­
+te, nach dem zweiten Semikolon die dritte usw.
+ In Zeilen, in denen keine Bedingungen stehen, kann auch das
+Semikolon weggelassen werden. Es kann ebenfalls weggelassen wer­
+den, wenn die weiteren Spalten leer sind. Steht ein Semikolon direkt
+am Anfang der Zeile, so ist die erste Spalte leer.
+ Um dies zu illustrieren, sei hier noch ein weiteres Beispiel
+angegeben:
+
+
+ Name Wegner
+ Vorname ;Anna-Maria
+ Strasse
+
+
+In diesem Fall muß eine ausgewählte Person mit Nachnamen Wegner
+oder mit Vornamen Anna-Maria heißen.
+
+#on("b")#Stern#off("b")# Bis jetzt haben Sie hauptsächlich Bedingungen
+betrachtet,
+die exakt zutreffen mußten. Sie wissen aber bereits, daß man auch
+Bedingungen angeben kann, bei denen nur ein Teil des zu suchen­
+den Feldes bekannt ist, nämlich indem der unbekannte Teil mit
+einem Stern markiert wird.
+ In Kapitel 5 haben Sie gelernt, daß der Stern nur am Anfang
+und Ende des Musters stehen kann. Dies trifft nicht ganz zu, denn
+Sie können den Stern auch inmitten eines Textes anwenden. So
+trifft die Bedingung 'Si*n' auf alle Namen zu, die mit 'Si' beginnen
+und mit 'n' enden.
+ Beachten Sie hier das "und" in der Formulierung der Bedingung.
+Das Muster ist eigentlich eine Schreibweise für zwei Bedingungen
+für ein Feld, die mit UND verknüpft sind.
+ Sie können auch noch weitere Sterne in das Muster aufnehmen.
+Dabei gibt es jedoch eine Kleinigkeit zu beachten. Das Muster
+'*x*y*' bedeutet: das Feld muß ein 'x' und ein 'y' enthalten. Über
+die Reihenfolge der beiden Zeichen ist jedoch in dieser Bedingung
+nichts gesagt, obwohl es vielleicht vom Aussehen suggeriert wird.
+ Denken Sie daran, keine zwei Sterne nebeneinander zu schrei­
+ben - eine solche Bedingung hätte keinen Sinn.
+ Es gibt eine weitere spezielle Bedingung, die mit Hilfe des
+Sterns formuliert wird. Ein einzelner Stern bedeutet nämlich: Das
+Feld ist nicht leer. Beachten Sie den kleinen Unterschied: ein Stern
+in einem Muster kann für einen beliebigen Text stehen, der auch
+leer sein kann. Ein einzelner Stern jedoch steht für einen beliebigen
+Text, der nicht leer ist.
+ Damit Sie ein Gefühl für die Verwendung des Sterns bekommen,
+hier noch ein paar Beispiele:
+
+
+Mei*r*
+
+ Der Name beginnt mit 'Mei' und enthält ein 'r'. Trifft zu auf
+ 'Meier', 'Meiring', aber nicht auf 'Meiling' oder 'Merzei'.
+
+
+Donau*dampf*schiff*schaft
+
+ Feld beginnt mit 'Donau', endet mit 'schaft' und enthält
+ 'dampf' und 'schiff'. Trifft zu auf 'Donaudampfschiffahrtsge­
+ sellschaft', aber auch auf 'Donaugesellschiffdampffahrtschaft'.
+
+
+Roller*erfahren
+
+ Dieses Muster muß man ganz genau interpretieren. Es bedeutet:
+ der Inhalt beginnt mit 'Roller' und endet mit 'erfahren'. Das
+ Muster trifft nicht nur auf 'Roller erfahren' sondern auch auf
+ 'Rollerfahren' zu. Der Stern verliert also in diesem Fall seine
+ symbolische Bedeutung als Platzhalter für einen bestimmten
+ Text.
+
+#on("b")#Vergleiche#off("b")# Es gibt in EUDAS noch weitere Muster, die
+einen gan­
+zen Bereich von Werten auswählen. Diese betreffen Bedingungen der
+Art "größer als" und "kleiner als". Solche Vergleichsbeziehungen
+werden durch zwei Punkte dargestellt.
+ So wählt das Muster 'K..' alle Felder aus, die in der alphabe­
+tischen Reihenfolge hinter 'K' liegen, wobei das 'K' selbst mit ein­
+geschlossen ist. Umgekehrt trifft '..K' auf alle Felder zu, die davor
+liegen.
+ Sie können beide Bedingungen auch kombinieren. So trifft die
+Bedingung 'A..K' auf alle Felder zu, die im Lexikon unter 'A' bis
+'J' erscheinen (die Felder mit 'K' sind hier ausgeschlossen). Beach­
+ten Sie, daß die direkte Kombination wieder die Verknüpfung zweier
+einzelner Bedingungen mit UND darstellt.
+
+#on("b")#Negation#off("b")# Um den Bereich möglicher Suchmuster noch zu
+erweitern,
+können Sie einzelne Bedingungen auch noch verneinen. Dies ge­
+schieht durch Voranstellen zweier Minuszeichen. So bedeutet das
+Muster '--Meier', daß alle Personen ausgewählt werden, die nicht
+Meier heißen.
+ Die Verneinung bezieht sich immer auf das unmittelbar folgende
+Muster (bis zum nächsten Komma, Semikolon oder dem Zeilenende)
+und nicht etwa auf eine ganze Zeile. Sie umfaßt jedoch die UND-
+Verknüpfung der kombinierten Bedingungen. So sind zum Beispiel die
+Muster '--E..M', '--E..,--..M' und '..E,M..' völlig gleichbedeu­
+tend.
+
+#on("b")#Feldvergleich#off("b")# Als letztes haben Sie im Suchmuster auch
+noch die
+Möglichkeit, ein Feld mit anderen Feldern des gleichen Satzes zu
+vergleichen. Bisher hatten Sie ein Feld ja immer nur mit konstanten
+Texten verglichen.
+ Um dies zu erreichen, geben Sie statt eines Vergleichstextes
+den Feldnamen des Feldes an, mit dem Sie vergleichen wollen. Zur
+Kennzeichnung müssen Sie dem Namen noch ein '&' voranstellen.
+Diese Konstruktion funktioniert mit allen bisher besprochenen Ver­
+gleichen. Beispielsweise trifft
+
+
+ Feld1 ..&Feld2
+
+
+auf alle Sätze zu, in denen der Inhalt von Feld1 kleiner ist als der
+Inhalt von Feld2.
+ Im Gegensatz zum Druckmuster dürfen in den Feldnamen zwar
+Leerzeichen enthalten sein, nicht jedoch
+#free (0.2)#
+
+ .. * , ;
+
+#free (0.2)#
+da diese Zeichen als reservierte Zeichen gelten und jeweils als
+Begrenzer wirken. Die gleiche Beschränkung gilt dementsprechend
+auch für konstante Vergleichstexte.
+ Beachten Sie, daß hinter dem '&' bis zum nächsten Begrenzer­
+zeichen ein gültiger (vorhandener) Feldname stehen muß. Anderen­
+falls wird der Text als konstantes Muster betrachtet.
+ Wie schon oben gesagt, kann der Feldvergleich mit allen Ver­
+gleichen verwendet werden. Auch gemischte Konstruktionen sind
+zulässig, beispielsweise
+
+
+ Feld1 A..&Feld3,*&Feld9*
+
+
+Diese Bedingung trifft zu, wenn Feld1 größer oder gleich 'A', aber
+kleiner als der Inhalt von Feld3 ist, oder wenn der Inhalt von Feld9
+darin vorkommt.
+
+#on("b")#Optimierung#off("b")# Hier noch eine Bemerkung zur Geschwindigkeit
+des
+Suchens. Je mehr Bedingungen Sie angeben, desto mehr Vergleiche
+müssen beim Suchen angestellt werden und desto länger dauert es.
+ Das erste Feld einer Datei erfährt jedoch eine Sonderbehand­
+lung. Wenn Sie für dieses Feld ein Muster für Übereinstimmung
+angeben, kann der Suchvorgang enorm beschleunigt werden, da das
+erste Feld einer Datei intern speziell verwaltet wird. Damit das
+Verfahren funktioniert, dürfen keine globalen Alternativen oder
+lokale Alternativen für das erste Feld verwendet werden.
+ Diese Suchoptimierung sollten Sie bereits beim Einrichten einer
+Datei berücksichtigen. Geben Sie als erstes Feld das an, nach dem
+am ehesten direkt gesucht wird. Typisches Beispiel hierfür ist der
+Nachname, aber auch Artikelnummern sind sinnvoll. Wichtig ist, daß
+das erste Feld nicht zu oft identisch ist und auch mehr als zwei
+Buchstaben enthält, damit die Optimierung ihre volle Wirksamkeit
+entfaltet.
+ Denken Sie daran, daß durch die Feldauswahl ein beliebiges
+Feld als erstes auf dem Bildschirm stehen kann. Für die Optimierung
+wird jedoch immer das Feld betrachtet, das beim Einrichten der
+Datei als erstes angegeben wurde.
+
+
+10.4 Markieren
+
+Manchmal entsteht die Situation, daß Sie eine Reihe von Sätzen
+bearbeiten wollen, aber keine Suchbedingung formulieren können,
+die auf alle diese Sätze zutrifft. In diesem Fall bietet EUDAS Ihnen
+die Möglichkeit, solche Sätze von Hand zu markieren.
+ Ein Beispiel: Sie haben eine ganze Reihe von Sätzen geändert
+und wollen diese Änderungen als Protokoll ausdrucken. Es läßt sich
+aber nicht mit Hilfe eines Suchmusters feststellen, welche Sätze
+geändert wurden.
+ Als Abhilfe wählen Sie bei jedem geänderten Satz die Funktion
+#free (0.2)#
+
+ M Markierung
+
+#free (0.2)#
+Dadurch wird der bisher unmarkierte Satz markiert. Dies wird
+kenntlich an der Anzeige 'MARK+' in der Überschrift. Sobald Sie den
+ersten Satz markiert haben, erscheint bei jedem Satz, ob er markiert
+ist oder nicht.
+ Haben Sie einen Satz irrtümlich markiert, können Sie die Mar­
+kierung mit der gleichen Funktion auch wieder entfernen.
+ Alle Funktionen, die bisher die durch das Suchmuster ausge­
+wählten Sätze bearbeitet haben, arbeiten nun nur noch auf den
+markierten Sätzen. Somit können Sie anschließend mit der Druck­
+funktion die gewünschten Sätze drucken. Die Markierung hat also
+Priorität über die eingestellte Suchbedingung. Lediglich die Bewe­
+gung am Bildschirm beachtet immer nur die Suchbedingung.
+ Sie können alle Markierungen der Datei mit der Funktion
+#free (0.2)#
+
+ Alle Markier.
+ L Löschen
+
+#free (0.2)#
+im Menü 'Gesamtdatei' wieder entfernen. Anschließend wird beim
+Drucken wieder das Suchmuster beachtet. Die Markierungen ver­
+schwinden auch, wenn eine neue Datei geöffnet wird. Die Markie­
+rungen sind also nicht permanent in einer Datei gespeichert, son­
+dern existieren nur, während die Datei geöffnet ist.
+ Bei Koppeldateien können Sie aus technischen Gründen immer
+nur alle Kombinationen auf einmal markieren. Die Markierung einer
+Kombination markiert auch alle anderen Kombinationen des gleichen
+Satzes.
+
+
+10.5 Übersicht
+
+Wie Sie bisher gesehen haben, zeigte EUDAS immer einen einzigen
+Satz in dem Standardformular auf dem Bildschirm. Es gibt jedoch
+auch eine Möglichkeit, mehrere Sätze gleichzeitig zu betrachten.
+Dazu dient die Funktion
+#free (0.2)#
+
+ U Übersicht
+
+#free (0.2)#
+im Menü 'Gesamtdatei'.
+ In der Übersicht nimmt jeder Satz nur eine Bildschirmzeile in
+Anspruch. Die Feldinhalte werden, durch Komma getrennt, in der
+Zeile nacheinander aufgezählt, bis kein Platz mehr vorhanden ist.
+Am Anfang jeder Zeile steht die Satznummer und ob der jeweilige
+Satz markiert ist (entweder '+' für markiert oder '-'). In der Über­
+schrift stehen in gleicher Weise die Feldnamen angegeben.
+ Der aktuelle Satz wird innerhalb der Übersichtsanzeige immer
+durch eine inverse Satznummer dargestellt. Es werden nur die durch
+das eingestellte Suchmuster ausgewählten Sätze gezeigt. Trifft die
+Selektionsbedingung nicht auf den aktuellen Satz zu, wird an seiner
+Stelle zur Information ein leerer Platzhalter angezeigt. Hinter dem
+letzten Satz wird auch das Dateiende als besonders gekennzeichne­
+ter Satz angegeben.
+
+___________________________________________________________________________________________
+
+ ÜBERSICHT: Blättern: HOP OBEN, HOP UNTEN Ende: ESC q Hilfe: ESC ?
+ Satznr. Name, Vorname, PLZ, Ort, Strasse, m/w,
+ 1 - Wegner, Herbert, Krämergasse 12, 5000, Köln, m,
+ 2 - Sandmann, Helga, Willicher Weg 109, 5300, Bonn 1, w,
+ 3 - Katani, Albert, Lindenstr. 3, 5210, Troisdorf, m,
+ 4 - Ulmen, Peter, Mozartstraße 17, 5, Köln 60, m,
+ 5 - Regmann, Karin, Grengelweg 44, 5000, Köln 90, w,
+ 6 - Arken, Hubert, Talweg 12, 5200, Siegburg, m,
+ 7 - Simmern, Anna-Maria, Platanenweg 67, 5, Köln 3, w,
+ 8 - Kaufmann-Drescher, Angelika, Hauptstr. 123, 53, Bonn 2, w,
+ 9 - Fuhrmann, Harald, Glockengasse 44, 5000, Köln 1, m,
+ 10 - Seefeld, Friedrich, Kabelgasse, 5000, Köln-Ehrenfeld, m,
+ 11 - << DATEIENDE >>
+
+___________________________________________________________________________________________
+
+
+#center#Abb. 10-1 Übersicht
+
+
+#on("b")#Feldauswahl#off("b")# Wenn Sie die Funktion aufrufen, haben Sie
+zuerst
+noch die Möglichkeit, nur einen Teil der vorhandenen Felder zur
+Anzeige auszuwählen. Dazu bejahen Sie die Frage und können dann
+die Felder in der gewünschten Reihenfolge ankreuzen. Analog zur
+Funktion 'Feldauswahl' wird auch hier die zuletzt für die Übersicht
+verwendete Feldauswahl beibehalten, wenn Sie die Frage verneinen
+oder kein Feld ankreuzen. Die Feldauswahl für die Übersicht ist
+unabhängig von der Feldauswahl für die normale Satzanzeige.
+ Von der Möglichkeit zur Feldauswahl sollten Sie Gebrauch ma­
+chen, denn durch die komprimierte Darstellung der Übersicht kann
+meistens nur ein kleiner Teil eines Satzes dargestellt werden.
+
+#on("b")#Rollen#off("b")# Nachdem die Sätze auf dem Bildschirm erschienen
+sind,
+haben Sie wieder die Möglichkeit, die Darstellung zu rollen. Dazu
+können Sie die Pfeiltasten OBEN und UNTEN sowie die Tastenkombi­
+nationen HOP OBEN und HOP UNTEN verwenden. Diese Funktionen
+verschieben den invers dargestellten aktuellen Satz und funktio­
+nieren wie im Editor. Beachten Sie auch hier wieder den Unterschied
+zum Rollen in der Einzelsatzanzeige.
+ Das Rollen wirkt wie ein Positionieren mit 'Weiter' oder 'Zu­
+rück'. Nach der Rückkehr aus der Übersicht können Sie sich also an
+einer ganz anderen Stelle in der Datei befinden.
+ Es stehen Ihnen zum Rollen auch noch die folgenden Tasten­
+kombinationen zur Verfügung (wie im Editor): HOP RETURN macht
+den aktuellen Satz zum ersten auf der Seite. ESC '1' zeigt den er­
+sten Satz der Datei, ESC '9' analog dazu den letzten.
+ Wenn Sie eine komplizierte Suchbedingung eingestellt haben
+und EUDAS viele Sätze erfolglos überprüfen muß, dauert der Bild­
+aufbau natürlich entsprechend lange. EUDAS gibt zu Ihrer Informa­
+tion aber immer die Nummer des Satzes aus, der gerade überprüft
+wird. Außerdem werden Tastenbefehle nach jeder Zeile angenommen,
+so daß Sie schon weiterblättern können, wenn Sie den ersten Satz
+gesehen haben.
+
+#on("b")#Markieren#off("b")# In der Übersicht können Sie auch Sätze
+markieren. Mit
+'+' markieren Sie den aktuellen Satz; mit '-' entfernen Sie die Mar­
+kierung wieder. So können Sie einfach die Sätze ankreuzen, die Sie
+später bearbeiten wollen.
+
+#on("b")#Verlassen#off("b")# Mit ESC 'q' können Sie die Übersicht wieder
+verlassen,
+auch mitten beim Aufbau des Bildes. Haben Sie erkannt, daß EUDAS
+sinnlos mit einer falschen Suchbedingung sucht, können Sie die
+Funktion auch mit ESC 'h' (Halt) abbrechen und gegebenenfalls ein
+neues Suchmuster einstellen.
+
diff --git a/doc/eudas/eudas.hdb.11 b/doc/eudas/eudas.hdb.11
new file mode 100644
index 0000000..6a59847
--- /dev/null
+++ b/doc/eudas/eudas.hdb.11
@@ -0,0 +1,674 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (109)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+11 Funktionen zur Bearbeitung
+
+
+
+11.1 Sortieren
+
+Wenn Sie die Sätze in Ihrer EUDAS-Datei in einer bestimmten Rei­
+henfolge haben wollen (dies wird in vielen Fällen zum Drucken
+verlangt), müssen Sie die Datei sortieren. Sie können EUDAS ange­
+ben, in welcher Reihenfolge die Sortierung erfolgen soll. Um die
+aktuelle Datei zu sortieren, rufen Sie die Funktion
+#free (0.2)#
+
+ Akt. Datei
+ S Sortieren
+
+#free (0.2)#
+auf. Falls die Datei noch nie sortiert wurde, wird Ihnen auf jeden
+Fall die Sortierreihenfolge zum Auswählen angeboten. Anderenfalls
+werden Sie gefragt, ob Sie die vorherige Sortierreihenfolge ändern
+wollen.
+ Das Sortieren wird als Veränderung betrachtet und nur auf der
+Arbeitskopie durchgeführt!
+
+#on("b")#Sortierreihenfolge#off("b")# Die Sortierreihenfolge gibt an, welche
+Felder in
+welcher Reihenfolge beim Vergleichen zweier Sätze benutzt werden
+sollen. Zuerst wird das an erster Stelle angegebene Feld verglichen.
+Sind die Inhalte hier unterschiedlich, wird die Einordnung der Sätze
+nach diesem Feld bestimmt.
+ Sind die Inhalte in diesem Feld aber gleich, so wird nach dem
+nächsten Feld verglichen. Ist kein weiteres Feld in der Sortierrei­
+henfolge angegeben, wird der Vergleich an dieser Stelle mit einem
+zufälligen Ergebnis abgebrochen, das heißt, es kann nicht vorher­
+gesagt werden, welcher der beiden Sätze zuerst kommt.
+ Die Sortierreihenfolge können Sie in einer Menüauswahl einge­
+ben. Kreuzen Sie die Felder an, die Sie vergleichen wollen und ach­
+ten Sie auf die richtige Reihenfolge. Die eingegebene Reihenfolge
+wird in der Datei gespeichert, um beim nächsten Sortiervorgang
+wiederverwendet zu werden.
+ Nachdem Sie alle bei der Sortierung zu berücksichtigenden
+angekreuzt haben, werden Sie für jedes dieser Felder gefragt, ob
+nach dem Feld aufsteigend oder absteigend sortiert werden soll.
+
+#on("b")#Ablauf#off("b")# Der Ablauf des Sortierens wird durch Ausgabe von
+Satz­
+nummern dargestellt. Bis zur ausgegebenen Satznummer sind alle
+Sätze richtig sortiert. Bei Bedarf kann der Vorgang durch SV und
+dann 'halt' abgebrochen werden. Die Datei bleibt dabei auf jeden
+Fall intakt.
+
+#on("b")#Optimierung#off("b")# Die gespeicherte Sortierreihenfolge wird auch
+noch zu
+einer weiteren Optimierung benutzt. Wenn eine Datei sortiert war
+und nur wenige Änderungen stattgefunden haben, brauchen beim
+nächsten Sortiervorgang nur die wenigen veränderten Sätze einzeln
+einsortiert zu werden. Das funktioniert natürlich nur unter der
+Voraussetzung, daß die gleiche Sortierreihenfolge gewählt wird. Das
+Sortieren braucht in diesem Fall erheblich weniger Zeit.
+
+#on("b")#Probleme#off("b")# Normalerweise werden die einzelnen Felder nach
+dem
+EUMEL-Zeichencode verglichen. Das bedeutet, daß sich die Reihen­
+folge der Zeichen nach dem EUMEL-Zeichencode richtet. Ein Zeichen
+mit einem höheren Code wird also vor einem Zeichen mit einem
+niedrigeren Code einsortiert.
+ In manchen Fällen ergeben sich mit diesem Vergleichsverfahren
+aber auch Schwierigkeiten. Wenn in einem Feld Zahlen oder DM-
+Beträge stehen, führt die Methode zu falschen Ergebnissen. Die '10'
+wird zum Beispiel vor der '2' einsortiert. Warum? Texte werden
+immer linksbündig geschrieben und verglichen. Bei Zahlen richtet
+sich die Wertigkeit jedoch nach dem Abstand vom Komma.
+ Da bei Texten zuerst das erste Zeichen verglichen wird, ent­
+steht hier durch Vergleich von '1' und '2' der Eindruck, die '10'
+käme vor der '2'. Korrigieren könnte man dies, indem man ein Leer­
+zeichen vor die '2' schreibt. Wenn also die (nicht geschriebenen)
+Dezimalkommata direkt untereinanderstehen, werden Zahlen richtig
+verglichen.
+
+#on("b")#Typ ZAHL#off("b")# EUDAS hat jedoch eine bequemere Art, dieses
+Problem zu
+behandeln. Ein Feld, das Zahlen enthalten soll, bekommt einen spe­
+ziellen Typ ZAHL zugewiesen, der zu einer richtigen Sortierung
+führt.
+ Bei Feldern vom Typ ZAHL ignoriert EUDAS bei Vergleichen alle
+nichtnumerischen Zeichen und vergleicht den Wert der Zahl. So
+können Sie zum Beispiel in einem Satz '2,50 DM' und im anderen
+Satz '10 DM' eintragen - EUDAS kann jetzt die richtige Reihenfolge
+feststellen.
+ Übrigens: falls Sie numerische Werte lieber mit einem Dezi­
+malpunkt statt einem Dezimalkomma schreiben, können Sie EUDAS
+das mit dem ELAN-Kommando
+
+
+ dezimalkomma (".")
+
+
+mitteilen. Wenn Sie ein solches Kommando eingeben wollen, können
+Sie im EUDAS-Menü ESC ESC drücken. In der Statuszeile erscheint
+dann die Aufforderung:
+
+
+ Gib Kommando:
+
+
+Hier können Sie wie im Editor oder im EUMEL-Monitor ein beliebiges
+Kommando eingeben und ausführen.
+ Die Normaleinstellung für das Dezimalkomma erreichen Sie
+wieder durch das Kommando
+
+
+ dezimalkomma (",")
+
+
+
+#on("b")#Typ ändern#off("b")# Die Feldtypen sind eine permanente Eigenschaft
+einer
+EUDAS-Datei. Beim Einrichten einer neuen Datei wird zunächst der
+Standardtyp für alle Felder genommen. Sie erhalten jedoch Gelegen­
+heit, abweichende Feldtypen zu vergeben, wenn Sie die Frage
+
+___________________________________________________________________________________________
+
+ Feldnamen oder Feldtypen ändern (j/n) ?
+___________________________________________________________________________________________
+
+
+bejahen.
+ Auch nachträglich können Sie die Feldtypen noch ändern. Dies
+geschieht mit der Funktion
+#free (0.2)#
+
+ F Feldstrukt.
+
+#free (0.2)#
+im Menü 'Öffnen'. Zunächst werden Sie gefragt, ob Sie noch weitere
+Feldnamen anfügen wollen. So könnten Sie die Datei um weitere
+Felder ergänzen, die bei allen Sätzen zunächst leer sind. Die neuen
+Felder müssen Sie wie beim Einrichten der Datei untereinander im
+Editor schreiben.
+ Als zweites erscheint dann die gleiche Frage wie oben. Wenn
+Sie diese bejahen, wird Ihnen eine Auswahl der zu ändernden Fel­
+der mit Feldnamen und den zugehörigen Feldtypen angeboten. Kreu­
+zen Sie hier die Felder an, deren Feldtypen Sie ändern möchten.
+ Da Sie mit dieser Funktion sowohl Feldnamen als auch Feld­
+typen verändern können, wird Ihnen für jedes Feld zunächst der
+Name zum Ändern angeboten. Sie können den Namen korrigieren oder
+überschreiben. Die Namensänderung hat jedoch keine Auswirkung
+auf den Feldinhalt!
+ Wenn Sie den Namen nicht ändern wollen, drücken Sie einfach
+RETURN. Anschließend können Sie für das Feld den neuen Feldtyp
+angeben. Tippen Sie einen der vier Feldtypen als Text ein und
+drücken Sie RETURN. Anschließend hat das Feld einen neuen Typ.
+Die verschiedenen möglichen Typen werden jetzt genau erklärt.
+
+#on("b")#Feldtypen#off("b")# TEXT ist der Standardtyp, der die Feldinhalte
+nach
+EUMEL-Zeichencode vergleicht. Den Typ ZAHL hatten wir schon
+weiter oben kennengelernt. Daneben gibt es noch den Typ DATUM.
+ Dieser Typ vergleicht Daten der Form 'tt.mm.jj'. Soll ein sol­
+ches Datum richtig einsortiert werden, müßte es anderenfalls in der
+Reihenfolge umgedreht werden (also 'jj.mm.tt'). Dies ist aber nicht
+nötig, wenn das Feld den Typ DATUM bekommt. Beachten Sie, daß
+alle Inhalte, die nicht die beschriebene Form haben, als gleich be­
+trachtet werden.
+ Der letzte Typ ist DIN. Dabei werden Texte nach DIN 5007 ver­
+glichen. Das bedeutet, daß Groß- und Kleinbuchstaben als gleich
+angesehen werden, daß alle nichtalphabetischen Zeichen ignoriert
+werden und die Umlaute ihren richtigen Platz bekommen (Umlaute
+werden in normalen Texten hinter allen anderen Zeichen einsor­
+tiert). Da hierfür ein relativ großer Zeitaufwand notwendig ist,
+sollte dieser Typ nur dann gewählt werden, wenn er erforderlich ist.
+Den schnellsten Vergleich ermöglicht der Typ TEXT.
+
+#on("b")#Hinweis#off("b")# Beachten Sie, daß mit der Vergabe von Feldtypen
+keine
+Überprüfung der Eingabe verbunden ist. Insbesondere beim Datum
+wird nicht geprüft, ob die Form 'tt.mm.jj' eingehalten wurde. Wollen
+Sie solche Überprüfungen vornehmen, lesen Sie bitte Abschnitt 11.3.
+
+
+11.2 Kopieren
+
+In diesem Abschnitt sollen Sie erfahren, wie Sie eine EUDAS-Datei
+#on("i")#kopieren#off("i")# können. Diese Funktion kann nicht nur ein inhaltsgleiches
+Duplikat einer EUDAS-Datei herstellen (dies könnten Sie einfacher
+durch eine logische Kopie bewerkstelligen, s. 16.1), sondern auch
+komplizierte Umstrukturierungen vornehmen.
+
+#on("b")#Kopiermuster#off("b")# Der Schlüssel zu dieser Leistungsfähigkeit
+ist das
+#on("i")#Kopiermuster#off("i")#. Wie beim Druckmuster legen Sie dadurch die genauen
+Auswirkungen der Funktion fest.
+ Für jedes Feld in der Zieldatei, in die kopiert werden soll,
+enthält das Kopiermuster die Angabe, woraus der Inhalt dieses
+Feldes entstehen soll. Durch Auswahl und Reihenfolge dieser Anga­
+ben bestimmen Sie die Struktur der Zieldatei.
+ Im einfachsten Fall sieht die Kopieranweisung für ein Feld wie
+folgt aus:
+
+
+ "Feldname" K f ("Feldname");
+
+
+Das 'K' dient zur Festlegung der Kopierfunktion. Auf der linken
+Seite steht in Anführungsstrichen der Name des Zielfeldes. Der
+Ausdruck auf der rechten Seite gibt den zukünftigen Inhalt des
+Feldes an. Der Ausdruck im obigen Beispiel steht einfach für den
+Inhalt des Feldes 'Feldname' in der aktuellen Datei. Das Semikolon
+am Ende dient zur Abgrenzung, da der ganze Ausdruck auch mehrere
+Zeilen lang sein darf.
+ In der oben genannten Form würde das Feld 'Feldname' iden­
+tisch in die Zieldatei kopiert. Weitere Möglichkeiten besprechen wir
+später.
+
+#on("b")#Feldreihenfolge#off("b")# Zunächst wollen wir uns damit befassen,
+wie Sie
+die Feldreihenfolge in der Zieldatei beeinflussen können. Dies ge­
+schieht einfach dadurch, daß Sie die Kopieranweisungen in der ge­
+wünschten Reihenfolge aufschreiben. Damit können wir bereits ein
+erstes komplettes Beispiel betrachten:
+
+
+ "Name" K f ("Name");
+ "Vorname" K f ("Vorname");
+ "PLZ" K f ("PLZ");
+ "Ort" K f ("Ort");
+ "Strasse" K f ("Strasse");
+ "m/w" K f ("m/w");
+
+
+Dieses Kopiermuster würde die bereits beschriebene Adressendatei
+identisch kopieren, da alle Felder in der gleichen Reihenfolge vor­
+kommen.
+ Wenn Sie jedoch die Feldreihenfolge ändern wollen (um zum
+Beispiel ein anderes Feld als erstes zu optimieren), brauchen Sie
+bloß die Reihenfolge im Kopiermuster zu verändern:
+
+
+ "Ort" K f ("Ort");
+ "Name" K f ("Name");
+ "Vorname" K f ("Vorname");
+ "PLZ" K f ("PLZ");
+ "Strasse" K f ("Strasse");
+ "m/w" K f ("m/w");
+
+
+Im Gegensatz zur Auswahl der Feldreihenfolge für die Anzeige än­
+dern Sie so die Feldreihenfolge für die Zieldatei permanent.
+
+#on("b")#Felder anfügen#off("b")# Die beiden angegebenen Kopiermuster haben
+jedoch
+nur dann die beschriebene Wirkung, wenn die Zieldatei noch nicht
+existert. Bei einer existierenden Datei kann die Feldreihenfolge
+nicht mehr geändert werden; daher hat die Reihenfolge der Kopier­
+anweisungen dann keine Wirkung.
+ Sie können jedoch zu einer existierenden Zieldatei noch Felder
+hinzufügen. EUDAS verwendet nämlich folgende einfache Vorschrift:
+
+#limit (12.0)#
+ Wenn als Zielfeld in einer Kopieranweisung ein Feld
+ genannt wird, das in der Zieldatei noch nicht vorkommt,
+ wird es als weiteres Feld der Zieldatei hinzugefügt.
+#limit (13.5)#
+
+Diese Strategie hat im Fall der nicht existierenden Datei zur Folge,
+daß alle Felder neu sind und in der Reihenfolge ihres Auftretens
+eingerichtet werden. Existiert die Datei schon, werden zusätzliche
+Felder am Ende angefügt.
+ Beachten Sie, daß zusätzliche Felder für eine existierende
+Datei nur in den neu hinzukopierten Sätzen gefüllt sind. In den
+alten Sätzen bleiben alle neuen Felder einfach leer.
+
+#on("b")#Satzauswahl#off("b")# An dieser Stelle sollte erwähnt werden, daß
+wie bei
+allen Funktionen, die die gesamte Datei betreffen, nur die durch die
+Suchbedingung ausgewählten Sätze kopiert werden. Ist mindestens
+ein Satz markiert, werden nur die markierten Sätze kopiert und die
+Suchbedingung ignoriert.
+
+#on("b")#Teildatei#off("b")# Jetzt können Sie auch die zweite wichtige
+Aufgabe des
+Kopierens verstehen. Sie können aus einer Datei einen Teil der
+Sätze und einen Teil der Felder #on("i")#herausziehen#off("i")#. Danach haben Sie
+unter Umständen eine wesentlich kleinere Datei, die sich auch
+schneller bearbeiten läßt. Gerade wenn Sie nicht den allerneuesten
+64-Bit-Supercomputer haben, können Sie so viel Zeit sparen, wenn
+Sie wiederholt nur mit einem Teil der Datei arbeiten müssen.
+ Die Auswahl der Sätze für einen solchen Zweck erfolgt über ein
+Suchmuster; im Kopiermuster geben Sie dann nur die gewünschten
+Felder an.
+
+#on("b")#Aufruf#off("b")# An dieser Stelle wollen wir jetzt endlich
+behandeln, wie
+Sie die Kopierfunktion aufrufen. Dazu gibt es die Auswahl
+#free (0.2)#
+
+ Satzauswahl
+ K Kopieren
+
+#free (0.2)#
+im Menü "Gesamtdatei". Als erstes werden Sie nach dem Namen der
+Zieldatei gefragt. Existiert die Zieldatei schon und war sie vorher
+sortiert, werden Sie gefragt, ob Sie die Datei zum Schluß wieder
+sortieren wollen. Wie immer beim Sortieren werden auch hier gege­
+benenfalls nur die neu hinzugekommenen Sätze einsortiert.
+ Als nächstes müssen Sie den Namen des Kopiermusters angeben.
+Da das Kopiermuster eine normale Textdatei ist, können Sie sich
+einen beliebigen Namen ausdenken, unter dem das Muster dann
+gespeichert wird.
+ Wollen Sie das Kopiermuster nicht aufbewahren, sondern nur
+einmal verwenden, brauchen Sie keinen Namen anzugeben. Drücken
+Sie einfach RETURN und für die Dauer des Kopierens wird das
+Kopiermuster als unbenannte Datei eingerichtet.
+ Nachdem Sie den Namen des Kopiermusters eingegeben haben,
+gelangen Sie in den Editor, wo Sie das Muster ändern können. Damit
+Sie beim ersten Mal nicht so viel tippen müssen, bietet EUDAS Ihnen
+bei einer neuen Musterdatei ein #on("i")#Standard-Kopiermuster#off("i")# zum Ändern
+an. Das Aussehen des Standard-Kopiermusters richtet sich danach,
+ob die Zieldatei schon existiert oder nicht.
+ Existiert die Zieldatei noch nicht, so werden im Standard-
+Kopiermuster alle Felder der Ausgangsdatei in ihrer originalen Rei­
+henfolge angegeben. Wenn Sie dieses Muster nicht noch ändern, wird
+die aktuelle Datei identisch kopiert.
+ Sie können jedoch die Feldreihenfolge verändern oder Felder
+weglassen, indem Sie einfach die entsprechenden Zeilen vertauschen
+oder löschen. Für Umbenennungen überschreiben Sie einfach den
+Namen auf der linken Seite der Kopieranweisung. So können Sie das
+Kopiermuster mit geringstem Aufwand erstellen.
+ Existiert die Zieldatei jedoch schon, werden Ihnen im Kopier­
+muster alle Felder der Zieldatei angeboten. Bei Feldern, die in der
+aktuellen Datei nicht vorkommen, erscheint folgende Anweisung:
+
+
+ "Anrede" K "";
+
+
+Obwohl die Anweisung in diesem Fall keine Wirkung hat (wenn man
+sie wegließe, würde das Feld ebenfalls leer bleiben), ist sie dennoch
+aufgeführt, damit Sie auf der rechten Seite einen entsprechenden
+Ausdruck einsetzen können.
+ Bei den angebotenen Anweisungen hat eine Änderung der Rei­
+henfolge oder eines Feldnamens keinen Sinn, da diese Felder ja alle
+bereits existieren. Jedoch können Sie die Ausdrücke auf der rechten
+Seite variieren und neue Anweisungen (Felder) hinzufügen.
+
+#on("b")#Ablauf#off("b")# Wenn Sie die Eingabe des Kopiermusters mit ESC 'q'
+verlas­
+sen, wird das Kopiermuster übersetzt. Dabei können Fehlermeldun­
+gen auftreten. Sie können dann die Fehler korrigieren, wobei Sie die
+Fehlermeldungen gleichzeitig auf dem Bildschirm sehen können. War
+das Kopiermuster korrekt, werden alle ausgewählten (bzw. markier­
+ten) Sätze der aktuellen Datei in die Zieldatei kopiert und diese
+anschließend gegebenenfalls noch sortiert.
+ Die kopierten Sätze werden jeweils am Ende der Zieldatei ange­
+fügt. War die Zieldatei vorher schon sortiert, können Sie angeben,
+daß die neuen Sätze zum Schluß noch einsortiert werden. Anderen­
+falls können Sie die Datei anschließend mit der Funktion 'Sortieren'
+sortieren.
+
+#on("b")#ELAN-Ausdrücke#off("b")# Wenn Sie schon einmal programmiert haben,
+wird
+Ihnen vielleicht aufgefallen sein, daß ein Kopiermuster einem
+ELAN-Programm verdächtig ähnlich sieht. Diese Vermutung trügt Sie
+nicht. Dies läßt den Schluß zu, daß Sie noch mehr ELAN hier an­
+bringen können.
+ Haben Sie noch nie programmiert, sollten Sie jetzt nicht in
+Panik geraten, denn das Wichtigste dieses Abschnitts haben Sie
+bereits gelernt. Vielleicht sind Ihnen die folgenden Beispiele bereits
+ganz nützlich. Um alle Möglichkeiten auszunutzen, sollten Sie sich
+aber irgendwann (später!) mit den Kapiteln 14 und 15 befassen, in
+denen Sie Genaueres erfahren.
+ Zunächst sei festgestellt, daß der rechte Teil einer Kopieran­
+weisung ein beliebiger ELAN-Ausdruck sein kann, der einen TEXT
+liefert. Den wichtigsten Ausdruck kennen Sie bereits:
+
+
+ f ("Feldname")
+
+
+liefert den Inhalt des Feldes 'Feldname' des aktuellen Satzes der
+aktuellen Datei. Gibt es das Feld nicht, erscheint eine Fehlermel­
+dung bei der Ausführung.
+ Sie können jedoch auch einen konstanten Text angeben, der
+dann für alle Sätze gleich ist. Dazu schließen Sie den Text einfach
+in Anführungsstriche ein. Die folgende Kopieranweisung dient dazu,
+ein neues Feld einzurichten, das aber vorläufig noch leer bleiben
+soll:
+
+
+ "Feldname" K "";
+
+
+Ebenso können Sie mehrere Felder zu einem neuen verbinden, zum
+Beispiel:
+
+
+ "Wohnort" K f ("PLZ") + " " + f ("Ort");
+
+
+Das Pluszeichen kennzeichnet die Aneinanderreihung von zwei Tex­
+ten. Denken Sie auch immer an das Semikolon am Ende. In gleicher
+Weise können Sie viele andere Textfunktionen verwenden, die in
+Kapitel 14 beschrieben sind.
+ Prinzipiell können Sie auch Bedingungen mit IF abfragen, wie
+zum Beispiel in der folgenden Übersetzung:
+
+
+ IF f ("m/w") = "w" THEN
+ "Anrede" K "Frau"
+ ELSE
+ "Anrede" K "Herr"
+ END IF;
+
+
+Auf diese Weise können Sie Kodierungen verschiedenster Art auto­
+matisch umsetzen. Sie müssen hierbei jedoch unbedingt darauf ach­
+ten, daß innerhalb der IF-Konstruktion immer eine Kopieranweisung
+ausgeführt wird. Falls nämlich kein Fall zutrifft und für ein Feld
+keine Kopieranweisung ausgeführt wird, wird das Feld bei einer
+neuen Datei auch nicht richtig eingerichtet.
+
+
+11.3 Tragen
+
+In Kapitel 6 hatten Sie gesehen, wie man einzelne Sätze aus der
+aktuellen Datei in eine andere trägt, und auch, wie man sie wieder
+zurückholen kann. Diese Funktion diente im wesentlichen dazu,
+nicht mehr benötigte Sätze zu entfernen.
+ Sie haben aber auch die Möglichkeit, eine ganze Reihe von
+Sätzen in einem Arbeitsgang zu tragen, nämlich alle durch das
+Suchmuster ausgewählten beziehungsweise alle markierten Sätze.
+Diese Funktion dient ebenfalls dazu, Sätze zu entfernen, beispiels­
+weise alle Sätze, die vor einem gewissen Stichtag liegen. Als wei­
+tere Anwendung können Sie beim Tragen aber auch Bedingungen
+überprüfen.
+ Diese #on("i")#Prüfbedingungen#off("i")# sollen sicherstellen, daß die Daten in
+einer Datei ganz bestimmten Richtlinien entsprechen. Zum Beispiel
+kann geprüft werden, ob ein eingegebenen Datum stimmen kann, ob
+ein Satz doppelt aufgenommen wurde oder ob eine Artikelnummer die
+richtige Anzahl von Stellen hat.
+ Die Prüfbedingungen werden einer Datei fest zugeordnet. Sie
+können mit der Funktion
+#free (0.2)#
+
+ P Prüfbed.
+
+#free (0.2)#
+im Menü 'Öffnen' eingegeben oder geändert werden. Die Prüfbedin­
+gungen werden als Text im Editor geschrieben.
+
+#on("b")#Ablauf#off("b")# Das ganze Verfahren läuft nun so ab: Sie fügen neue
+Sätze
+immer erst in eine Zwischendatei ein, die die gleiche Struktur wie
+die eigentliche Datei hat. Wenn Sie alle Sätze fertig eingegeben
+haben, tragen Sie diese Datei komplett in die gewünschte Datei.
+Dabei werden die Prüfbedingungen getestet.
+ Erfüllt ein Satz die Bedingungen, wird er anstandslos getragen.
+Trifft eine Bedingung aber nicht zu, bleibt der Satz in der Zwi­
+schendatei und eine entsprechende Meldung wird ausgegeben. Die
+Meldungen werden gespeichert, um Sie später nochmal abrufen zu
+können.
+ Sie müssen jetzt in der Zwischendatei die notwendigen Ände­
+rungen durchführen, damit die Prüfbedingungen erfüllt werden. Beim
+Aufruf der Funktion
+#free (0.2)#
+
+ A Ändern
+
+#free (0.2)#
+können Sie mit Hilfe der Tastenkombination ESC 'P' (großes P) die
+Datei mit den Fehlermeldungen in einem kleinen Teilfenster editie­
+ren. Anhand dieser Hinweise können Sie dann den Satz korrigieren.
+Die Meldungen bleiben bis zum nächsten Öffnen oder Tragen erhal­
+ten.
+ Nach der Korrektur können Sie den gleichen Vorgang erneut
+aufrufen - es sind ja nur noch die zuerst fehlerhaften Sätze in der
+Zwischendatei. Bei Bedarf können Sie diesen Vorgang wiederholen,
+bis alle Sätze korrekt übernommen worden sind.
+
+#on("b")#Aufruf#off("b")# Das Tragen wird aufgerufen durch die Funktion
+#free (0.2)#
+
+ Satzauswahl
+ T Tragen
+
+#free (0.2)#
+Nach Eingabe des Zieldateinamens müssen Sie noch angeben, ob Sie
+die Prüfbedingungen testen wollen.
+
+#on("b")#Prüfbedingungen#off("b")# Zu diskutieren bleibt noch die Form der
+Prüfbe­
+dingungen. Diese stellen ein kleines ELAN-Programm dar, in dem
+einige spezielle Prozeduren zum Prüfen enthalten sind. Wenn Sie
+nicht ELAN programmieren können, sollte Sie diese Bemerkung nicht
+erschrecken: die Prüfbedingungen sind einfach genug.
+ Sie schreiben also die Prüfbedingungen jeweils untereinander.
+Eine mögliche Bedingung ist
+
+
+ wertemenge ("Feldname", "Wert1,Wert2,Wert3,Wert4");
+
+
+Diese Bedingung gibt an, daß das Feld einen der angegebenen Werte
+haben muß. Die Werte werden untereinander durch Komma getrennt.
+Es gibt jedoch keine Möglichkeit, Werte mit Komma darzustellen, da
+das Komma immer als Trennung wirkt. Leerzeichen dürfen in den
+Werten vorkommen, sie müssen dann aber auch genau so im Feld
+stehen.
+ Wir könnten zum Beispiel eine Bedingung für unser Feld 'm/w'
+wie folgt formulieren
+
+
+ wertemenge ("m/w", "m,w");
+
+
+EUDAS würde sich dann beschweren, wenn das Feld leer wäre (ir­
+gendein Geschlecht muß die Person ja wohl haben). Wenn das Feld
+auch leer sein darf, geben Sie einfach zwei Kommata hintereinander
+oder ein Komma am Anfang an:
+
+
+ wertemenge ("m/w", ",m,w");
+
+
+Eine andere Möglichkeit der Prüfbedingung besteht darin, eine
+Maske für ein Feld zu definieren. Diese Maske gibt an, daß an be­
+stimmten Stellen des Feldes nur bestimmte Zeichen stehen dürfen.
+So könnte man zum Beispiel folgende Maske für ein Datumsfeld
+angeben:
+
+
+ feldmaske ("Datum", "99.99.99");
+
+
+Die Neunen haben hier eine spezielle Bedeutung und und stehen für
+eine beliebige Ziffer. Es gibt noch einige weitere Zeichen, die eine
+reservierte Bedeutung haben, nämlich:
+
+
+ '9' für jede Ziffer (wie schon erwähnt)
+ 'X' für jedes Zeichen
+ 'A' für jeden Großbuchstaben
+ 'a' für jeden Kleinbuchstaben
+ '*' für eine Folge beliebiger Zeichen
+
+
+Alle anderen Zeichen im Muster stehen für sich selbst. Eine Sonder­
+stellung besitzt der Stern; er sollte sparsam verwendet werden, da
+seine Benutzung etwas aufwendiger ist. Der Stern kann auch für
+eine leere Zeichenfolge stehen. Als weiteres Beispiel könnte man
+definieren
+
+
+ feldmaske ("Name", "A*");
+
+
+damit immer ein Name angegeben ist, der noch dazu mit einem Groß­
+buchstaben beginnt.
+ Für Bedingungen, die sich nicht mit diesen beiden Prozeduren
+formulieren lassen, gibt es noch
+
+
+ pruefe ("Feldname", Bedingung);
+
+
+Diese Prozedur erhält einen logischen (booleschen) Wert als Parame­
+ter, der einen Vergleich darstellt. Ist dieser Parameter falsch
+(FALSE), wird eine entsprechende Fehlermeldung protokolliert. So
+könnte man folgende Bedingung angeben:
+
+
+ pruefe ("Alter", wert ("Alter") > 18.0);
+
+
+Diese Bedingung würde sicherstellen, daß alle Personen in der Datei
+volljährig sind ('wert' ist eine von EUDAS definierte Funktion, die
+den Inhalt eines Feldes als REAL-Zahl liefert - denken Sie auch
+daran, daß der ELAN-Compiler Zahlen mit Dezimalpunkt geschrieben
+haben möchte).
+ Da die Prüfbedingungen ein ELAN-Programm sind, können Sie
+natürlich sämtliche ELAN-Anweisungen verwenden.
+ Weiterhin haben Sie die Möglichkeit, Doppeleinträge zu verhin­
+dern. Dazu geben Sie mit Hilfe der Prozedur
+
+
+ eindeutige felder (n);
+
+
+wieviele Felder vom ersten an eindeutig sein sollen. Ein zu tragen­
+der Satz, der mit irgendeinem anderen Satz in diesen Feldern über­
+einstimmt, wird als fehlerhaft zurückgewiesen. In unserer Adressen­
+datei könnte man
+
+
+ eindeutige felder (2);
+
+
+angeben. Damit würde ein neuer Satz mit bereits vorhandenem Na­
+men und Vornamen abgelehnt.
+
+#on("b")#Limit#off("b")# Aus technischen Gründen können die Prüfbedingungen
+einer
+Datei nur 2000 Zeichen umfassen. Wollen Sie aufwendigere Bedin­
+gungen konstruieren, sollten Sie sich diese als Prozedur definieren
+und insertieren. In den Prüfbedingungen müssen Sie dann nur diese
+Prozedur aufrufen.
+
+
+11.4 Automatische Änderungen
+
+Mit EUDAS können Sie die geöffnete Datei nicht nur satzweise von
+Hand ändern, sondern auch automatisch die ganze Datei. Dazu müs­
+sen Sie dem Rechner eine Vorschrift geben, nach der er handeln
+kann. Ein solches #on("i")#Änderungsmuster#off("i")# stellt im Prinzip schon ein klei­
+nes Programm dar. Der Änderungsvorgang wird durch die Auswahl
+#free (0.2)#
+
+ V Verändern
+
+#free (0.2)#
+aufgerufen. Dabei wird der Name des Änderungsmusters erfragt. Dies
+ist eine normale Textdatei. Existiert das Muster noch nicht, können
+Sie den Inhalt an dieser Stelle im Editor angeben. Anschließend
+werden alle ausgewählten Sätze nach der Vorschrift bearbeitet.
+Dabei wird jeweils die aktuelle Satznummer ausgegeben.
+
+#on("b")#Änderungsmuster#off("b")# Da auch ein Kopiermuster ein Programm ist,
+ist
+es nicht erstaunlich, daß Änderungsmuster ganz ähnlich aussehen.
+Eine typische Zeile sieht etwa so aus:
+
+
+ "Feldname" V "neuer Inhalt";
+
+
+Diese Zeile bedeutet: Ersetze den Inhalt des Feldes 'Feldname'
+durch den Text 'neuer Inhalt'. Anstelle des neuen Textes kann
+wieder ein beliebiger ELAN-Ausdruck stehen. Ein Beispiel, in dem
+ein Feld einen Stern angehängt bekommt, sieht dann so aus:
+
+
+ "Feldname" V f ("Feldname") + "*";
+
+
+Beachten Sie, daß Sie den Ausdruck auf der rechten Seite eventuell
+in Klammern setzen müssen (obwohl der Operator 'V' die niedrigste
+Priorität hat). Wenn Sie sich nicht sicher sind, können Sie den Aus­
+druck immer in Klammern einschließen.
+ Ebenso wie im Kopiermuster können Sie hier beliebige ELAN-
+Ausdrücke verwenden. Auch IF-Abfragen und ähnliche Konstruktio­
+nen sind möglich, im Gegensatz zum Kopiermuster sogar ohne Be­
+schränkungen.
+ Im Vergleich zu einem separat geschriebenen ELAN-Programm
+hat das Änderungsmuster den Vorteil, daß Sie nur die eigentlichen
+Veränderungsanweisungen kodieren müssen. Die wiederholte Anwen­
+dung auf die ausgewählten Sätze erledigt EUDAS automatisch. Wol­
+len Sie eine solche Änderungsanweisung fest insertieren, so brau­
+chen Sie das Muster nur in eine Prozedur zu verpacken und EUDAS
+zu übergeben (Näheres s. Referenzhandbuch).
+
diff --git a/doc/eudas/eudas.hdb.12 b/doc/eudas/eudas.hdb.12
new file mode 100644
index 0000000..fba5ca5
--- /dev/null
+++ b/doc/eudas/eudas.hdb.12
@@ -0,0 +1,446 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (123)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+12 Weitere Möglichkeiten zum Drucken
+
+
+
+12.1 Anschluß an die Textverarbeitung
+
+Auf zweierlei Art und Weise kann der EUDAS-Druckgenerator mit
+den Programmen der EUMEL-Textverarbeitung zusammenarbeiten.
+Zum ersten können Ausgabedateien des Druckprozesses anschließend
+mit den Textkosmetik-Werkzeugen bearbeitet werden. Zum anderen
+kann EUDAS im Editor direkt Daten aus einer EUDAS-Datei in die
+editierte Datei importieren.
+
+#on("b")#Druckrichtung#off("b")# Wie Sie schon in Kapitel 7 gesehen haben,
+kann
+man die Ausgabe des Druckgenerators statt auf den Drucker in eine
+Datei umleiten. Die Datei erhält dann einen automatisch generierten
+Namen. Sie können jedoch auch festlegen, daß die Ausgabe in eine
+ganz bestimmte Datei geschrieben werden soll. Dazu wählen Sie die
+Funktion
+
+
+ Ausgabe
+ R Richtung
+
+
+im Druckmenü. Es erscheint die Frage
+
+___________________________________________________________________________________________
+
+ Ausgabe automatisch zum Drucker (j/n) ?
+___________________________________________________________________________________________
+
+
+Verneinen Sie die Frage und es erscheint
+
+___________________________________________________________________________________________
+
+ Ausgabe in bestimmte Datei (j/n) ?
+___________________________________________________________________________________________
+
+
+Wenn Sie diese Frage auch verneinen, erhält die Ausgabedatei einen
+automatisch generierten Namen. Wenn Sie die Frage aber bejahen,
+können Sie anschließend den Namen der Ausgabedatei angeben.
+ Existiert die angegebene Datei schon, wird der Ausdruck am
+Ende der Datei angefügt. Anderenfalls wird die Datei neu eingerich­
+tet.
+ Die Angabe der Ausgabedatei gilt jedoch nur für den folgenden
+Druckvorgang. Wenn Sie mehrmals in die gleiche Datei drucken wol­
+len, müssen Sie den Namen immer wieder neu angeben. Falls Sie dies
+vergessen, wird die folgenden Male wieder ein Name automatisch
+generiert.
+
+#on("b")#Begrenzung der Dateigröße#off("b")# Für kleinere Systeme ist es
+vorteilhaft,
+wenn die Druckausgabe nicht in einer großen Datei gesammelt wird,
+sondern sich auf mehrere kleine Dateien verteilt. Da die Ausgabe­
+datei nach dem Drucken gelöscht wird, kann man auf diese Weise
+einen Hintergrundengpaß vermeiden. Es besteht die Möglichkeit, die
+maximale Größe der Ausgabedatei mit dem ELAN-Kommando
+
+
+ maxdruckzeilen (1000)
+
+
+auf eine bestimmte Zeilenzahl (maximal 4000) zu beschränken. Wenn
+der Druckgenerator nach der Bearbeitung eines Satzes feststellt,
+daß diese Maximalzahl überschritten wurde, wird die Ausgabedatei
+direkt gedruckt (falls durch 'Richtung' eingestellt) und eine neue
+Ausgabedatei eröffnet.
+
+#on("b")#Initialisierungsteil#off("b")# Dabei ist jedoch zu beachten, daß
+Drucker­
+steuerungsanweisungen, die im Vorspann eingestellt wurden, jetzt in
+der neuen Datei nicht mehr vorhanden sind. In einem solchen Fall
+würden die folgenden Teile der Ausgabe mit einer anderen Einstel­
+lung gedruckt.
+ Um dies zu vermeiden, können Sie solche Anweisungen in den
+#on("i")#Initialisierungsteil#off("i")# schreiben. Der Initialisierungsteil umfaßt alle
+Zeilen des Druckmusters bis zum ersten Abschnitt, also bis zur
+ersten Anweisung. Zeilen im Initialisierungsteil werden beim Eröff­
+nen einer neuen Ausgabedatei an den Anfang dieser Datei ge­
+schrieben.
+ Druckersteuerungsanweisungen, die ein bestimmtes Schriftbild
+der Ausgabe erzeugen ('type', 'limit', 'linefeed', 'start' usw.), sollten
+also in den Initialisierungsteil vor Beginn aller Abschnitte ge­
+schrieben werden.
+
+#on("b")#Nachbearbeitung#off("b")# Wenn Sie in der Druckausgabe verschiedene
+Schriften oder Proportionalschrift verwenden wollen, sollten Sie die
+folgenden Hinweise beachten. Da EUDAS keine Informationen über
+die Schriftbreiten und -größen hat, werden alle Schrifttypen gleich
+behandelt. Dies gilt insbesondere für die Zeilenbreite, die ja durch
+das Dateilimit des Druckmusters festgelegt ist.
+ So kann es passieren, daß Zeilen mit kleinen Schrifttypen zu
+früh abgeschnitten werden, während Zeilen mit großen Schriften
+nicht mehr auf das Blatt passen. Für diesen Fall sollten Sie das
+größte benötigte Limit einstellen (zum Beispiel 135 bei Schmal­
+schrift auf DIN A 4) und die Ausgabedatei anschließend mit 'line­
+form' bearbeiten.
+ 'lineform' verteilt zu langen Text auf mehrere Zeilen. Außerdem
+werden gegebenenfalls Trennungen durchgeführt.
+ 'lineform' benötigt zur Information Absatzmarken. Fehlt an
+einer Zeile die Absatzmarke, wird die nächste Zeile so weit wie
+möglich direkt angehängt. Die Absatzmarken in der Ausgabedatei
+werden direkt aus dem Druckmuster übernommen (es ist nicht mög­
+lich, Absatzzeilen durch eingesetzte Leerzeichen zu erzeugen). Im
+Normalfall sollten alle Zeilen im Druckmuster eine Absatzmarke
+haben.
+ Wenn Sie seitenorientierte Überschriften haben möchten, kön­
+nen Sie auch 'pageform' einsetzen. Die gewünschten Überschrift­
+anweisungen können Sie im Initialisierungsteil angeben.
+ Die beiden Funktionen wählen Sie über den Menüpunkt
+
+
+ N Nachbearb.
+
+
+im Druckmenü. Dort können Sie den Namen der Ausgabedatei ange­
+ben, die Sie bearbeiten möchten. Es wird jeweils gefragt, ob Sie
+'lineform' und 'pageform' anwenden wollen. Das Ergebnis der Bear­
+beitung können Sie danach ausdrucken.
+
+#on("b")#EUDAS im Editor#off("b")# Wenn Sie sich im Editor zum Zweck der
+Textver­
+arbeitung befinden, können Sie Daten aus einer EUDAS-Datei direkt
+in die editierte Datei übernehmen. Dazu wählen Sie zunächst die
+gewünschten Sätze aus - danach geben Sie den Namen eines Druck­
+musters an. EUDAS druckt die gewählten Sätze unter Beachtung des
+Druckmusters direkt in die editierte Datei.
+ Wenn Sie das Kommando
+
+
+ eudas
+
+
+im Editor geben (nach ESC ESC), gelangen Sie in ein spezielles
+Kurzprogramm, das alle notwendigen Information von Ihnen erfragt.
+ Zunächst müssen Sie den Namen der gewünschten EUDAS-Datei
+angeben. Diese Datei wird dann automatisch geöffnet. Vorher geöff­
+nete Dateien werden nach Anfrage gesichert. Beachten Sie, daß
+keine Datei mehr geöffnet ist, wenn Sie später EUDAS wieder normal
+aufrufen.
+ Danach wird Ihnen eine Übersicht aller Sätze gezeigt - in einer
+Form, die Sie aus der Funktion 'Übersicht' bereits kennen. Wie dort
+wird Ihnen zunächst eine Auswahl der Felder angeboten, um die
+Anzeige übersichtlich zu halten. Anschließend können Sie noch ein
+Suchmuster angeben.
+ In der Übersicht können Sie sich dann zu einem bestimmten
+Satz bewegen oder mehrere Sätze markieren. Nach dem Verlassen der
+Übersicht können Sie den aktuellen Satz oder alle ausgewählten
+(bzw. markierten) Sätze drucken. Natürlich können Sie auch beide
+Fragen verneinen.
+ Zum Drucken wird der Name des Druckmusters erfragt. Dieses
+muß bereits existieren. Die Ausgabe wird an der Stelle eingefügt, an
+der der Cursor in der editierten Datei steht - die Zeile wird bei
+Bedarf aufgesplittet.
+ Nach dem Drucken können Sie den Vorgang wiederholen, wenn
+Sie zum Beispiel einen weiteren Satz drucken wollen. Dazu können
+Sie auch ein neues Suchmuster angeben. Markierungen von Sätzen
+werden nach dem Drucken gelöscht.
+
+
+12.2 Spaltendruck
+
+Für manche Anwendungen reicht es nicht aus, wenn die bearbeite­
+ten Sätze jeweils untereinander in der Ausgabe erscheinen. Häufig­
+stes Beispiel dafür ist der Etikettendruck. Hierfür werden vielfach
+mehrbahnige Formulare eingesetzt.
+ In diesem Fall müssen die Sätze bis zur gewünschten Anzahl
+von Spalten nebeneinander gesetzt werden - erst danach wird die
+nächste Reihe angefangen.
+ EUDAS unterstützt diese Anwendung. Dazu wird hinter der
+'%WIEDERHOLUNG'-Anweisung die Anzahl der Spalten als Parameter
+geschrieben (durch Leerzeichen getrennt). Der Wiederholungsteil
+wird dann mit der angegebenen Anzahl von Spalten gedruckt. Zu
+beachten ist, daß Vorspann und Nachspann diese Spaltenanordnung
+durchbrechen, also immer hinter dem bisher Gedruckten beginnen.
+ Die Spaltenbreite wird vom Dateilimit des Druckmusters be­
+stimmt. Die Zeilen eines Wiederholungsteils werden bis zum Limit
+mit Leerzeichen aufgefüllt, wenn der nächste Wiederholungsteil
+danebengesetzt wird.
+ Alternativ kann die Spaltenbreite in Zeichen auch als zweiter
+Parameter angegeben werden. Der Wert gilt jedoch nur für den Wie­
+derholungsteil - Vor- und Nachspann richten sich immer nur nach
+dem Dateilimit.
+ Es spielt keine Rolle, ob die nebeneinandergesetzten Wieder­
+holungsteile unterschiedliche Längen haben. Die kürzeren Teile
+werden einfach bei Bedarf durch Leerzeilen ergänzt. Es ist jedoch zu
+beachten, daß sich auf diese Weise unterschiedliche Längen für die
+einzelnen Reihen ergeben können.
+ Beispiel: Das Ergebnis für Satz 1, 3, 4 und 5 sei vier Zeilen
+lang, für Satz 2 aber fünf Zeilen. Bei zweispaltigem Druck wird die
+erste Reihe eine Zeile länger als die folgenden (s. dazu Abb. 12-1).
+
+
+ Satz 1 Satz 2
+ braucht braucht
+ vier Zeilen. ausnahmsweise
+ ---------------- fünf Zeilen.
+ ----------------
+ Satz 3 Satz 4
+ braucht braucht
+ vier Zeilen. vier Zeilen.
+ ---------------- ----------------
+ Satz 5
+ braucht
+ vier Zeilen.
+ ----------------
+
+#center#Abb. 12-1 Seitenaufteilung beim Spaltendruck
+
+
+#on("b")#Beispiel#off("b")# Zum Abschluß noch als Beispiel ein Druckmuster
+für ein
+dreibahniges Etikettenformular. Die Spaltenbreite und die Länge des
+Wiederholungsteils richten sich natürlich nach dem verwendeten
+Formular und müssen im Einzelfall ausprobiert werden.
+
+
+ % VORSPANN
+ \#start (1.0, 0.8)\#
+ % WIEDERHOLUNG 3 40
+
+ &Vorname %Name
+ &Strasse
+
+ &PLZ %Ort
+ \#free (1.693)\#
+
+
+
+12.3 Modi
+
+Gesetzt der Fall, Sie wollen eine Tabelle drucken, deren Einträge
+auf jeden Fall in voller Länge erscheinen sollen, auch wenn sie die
+Spaltenbreite überschreiten. Dies würde bedeuten, daß Tabellenein­
+träge nach rechts geschoben werden, wenn vorhergehende Einträge
+länger sind. Für diesen Fall können also nur Feldmuster variabler
+Position (mit '%') eingesetzt werden. Diese werden jedoch auch nach
+links geschoben, wenn vorher kürzere Inhalte auftreten.
+
+#on("b")#Tabellenmodus#off("b")# Um dieses Linksschieben zu unterdrücken,
+können
+Sie mit folgender Anweisung im Musterteil in den #on("i")#Tabellenmodus#off("i")#
+umschalten:
+
+
+ % MODUS 2
+
+
+Der so eingestellte Modus gilt bis zum Ende des jeweiligen Ab­
+schnitts. Zu Beginn eines Abschnitts ist der Modus 1 (Normalmodus)
+eingestellt.
+
+#on("b")#Beispiel#off("b")# Um diese Anweisung auszuprobieren, sollten Sie
+folgendes Druckmuster auf unsere Beispieldatei anwenden:
+
+
+ % WIEDERHOLUNG
+ % MODUS 2
+ &Vorname %Name
+
+
+In der Ausgabe können Sie sehen, daß der Nachname nicht nach
+links geschoben wird, so daß eine Tabelle entsteht. Ist der Vorname
+jedoch zu lang, wird die Tabelleneinteilung durchbrochen und der
+Nachname nach rechts geschoben, um den Vornamen nicht abschnei­
+den zu müssen:
+
+
+ Herbert Wegner
+ Helga Sandmann
+ Albert Katani
+ Peter Ulmen
+ Karin Regmann
+ Hubert Arken
+ Anna-Maria Simmern
+ Angelika Kaufmann-Drescher
+ Harald Fuhrmann
+ Friedrich Seefeld
+
+
+#on("b")#Zeilenfortsetzung#off("b")# Eine weitere Möglichkeit, überlange
+Feldinhalte
+einzusetzen, besteht darin, daß der Rest des Inhaltes, der nicht
+mehr in den reservierten Raum paßt, in der nächsten Zeile fortge­
+setzt wird. Dies wird im Modus 3 erreicht. Falls ein Feldinhalt ab­
+geschnitten werden müßte, wird in diesem Modus die gleiche Mu­
+sterzeile nochmal mit den restlichen Inhalten gedruckt. Dies wird
+fortgesetzt, bis alle Inhalte abgearbeitet sind.
+ Damit die Fortsetzung sinnvoll ist, wird das letzte Wort ganz in
+die nächste Zeile übernommen, falls es zerschnitten würde (ähnlich
+wie im Editor). Der dadurch freiwerdende Raum in der vorigen Zeile
+wird mit Leerzeichen gefüllt. Ist rechtsbündiges Einsetzen verlangt,
+werden die einzelnen Teile jeweils rechtsbündig in ihrem reservier­
+ten Platz justiert.
+ Dieser Modus ist besonders interessant, wenn Sie längere Kom­
+mentare in eine EUDAS-Datei eintragen, die Sie dann natürlich auch
+wieder drucken wollen. Den Text tragen Sie bereits in mehreren
+Zeilen in die EUDAS-Datei ein. Beachten Sie, daß der Umbruch des
+Textes im Druck nicht mit dem Umbruch des Textes am Bildschirm
+übereinstimmt. Wollen Sie dies verhindern, müssen Sie jeden Absatz
+des Textes in ein eigenes Feld schreiben.
+ Wie zu Anfang des Kapitels bereits angedeutet, kann der Um­
+bruch bei Proportionalschrift nicht korrekt sein, da EUDAS die Zei­
+chenbreiten nicht kennt. Um die nachfolgende Bearbeitung mit
+'lineform' zu ermöglichen, werden bei fortgesetzten Feldern grund­
+sätzlich keine Absatzmarken an die Zeilen geschrieben. Lediglich die
+letzte Fortsetzungszeile erhält eine Absatzmarke.
+ In den Fortsetzungszeilen, werden die Feldmuster, deren Inhalte
+bereits abgearbeitet sind, leer eingesetzt. Die Mustertexte zwischen
+den Feldmustern werden in den Fortsetzungszeilen durch Leerzei­
+chen ersetzt.
+ Die Anzahl der Fortsetzungszeilen kann durch die Anweisung
+
+
+ % MEHR n
+
+
+auf eine bestimmte Zahl 'n' festgelegt werden. Wenn alle Inhalte
+abgearbeitet wurden, aber die Anzahl der Zeilen noch nicht erreicht
+ist, werden entsprechend viele Zeilen mit leeren Inhalten erzeugt.
+ Die Zeilenwiederholung kann auch mit dem Tabellenmodus kom­
+biniert werden. Dies wird im Modus 4 erreicht. Felder variabler
+Position werden auch in diesem Modus nicht nach links geschoben.
+Außerdem werden aber in Fortsetzungszeilen die Mustertexte zwi­
+schen den Feldmustern wiederholt, um z.B. Tabellenbegrenzungen zu
+erzeugen.
+
+#on("b")#Beispiele#off("b")# Zur Verdeutlichung hier noch einige Beispiele.
+Das folgende Druckmuster:
+
+
+ % WIEDERHOLUNG
+ % MODUS 3
+ Kommentar: &Kommentar
+ ----------
+
+
+könnte folgende Ausgabe bewirken:
+
+
+ Kommentar: Dies ist ein längerer Kommentar aus
+ einer EUDAS-Datei, der zum Drucken
+ auf eine Breite von 48 Zeichen
+ umbrochen worden ist. Nur die letzte
+ Zeile hat eine Absatzmarke.
+ ----------
+
+
+Soll die Anzahl der Zeilen immer gleich bleiben, könnte man folgen­
+des Druckmuster verwenden:
+
+
+ % WIEDERHOLUNG
+ % MODUS 3
+ % MEHR 5
+ Kommentar: &Kommentar
+ ----------
+
+
+Mit einem kürzeren Text ergäbe sich folgendes Bild:
+
+
+ Kommentar: Nur ein kurzer Text.
+
+
+
+
+ ----------
+
+
+Für eine Tabelle würde man den Modus 4 benutzen:
+
+
+ % VORSPANN
+ --------------------------------------------------------
+ ! Abk. ! Kommentar !
+ !---------+--------------------------------------------!
+ % WIEDERHOLUNG
+ % MODUS 4
+ ! &abk ! &Kommentar&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& !
+ ----------+---------------------------------------------
+
+
+Als Ausgabe könnte folgender Text erscheinen:
+
+
+ --------------------------------------------------------
+ ! Abk. ! Kommentar !
+ !---------+--------------------------------------------!
+ ! MA11 ! Dieser Kurs hat eine Menge an besonderen !
+ ! ! Eigenschaften, die ihn für jüngere !
+ ! ! Teilnehmer geeignet erscheinen lassen. !
+ !---------+--------------------------------------------!
+ ! TD04 ! Stellt keine besonderen Anforderungen. !
+ !---------+--------------------------------------------!
+ ! PM01 ! Seit dem 01.01. eingerichtet und noch !
+ ! ! nicht voll besetzt. !
+ ----------+---------------------------------------------
+
+
+Beachten Sie hier, daß Tabelleneinträge hier nicht wie im Modus 2
+geschoben, sondern auf weitere Zeilen verteilt werden, wenn sie zu
+lang sind. Außerdem werden die Tabellenbegrenzungen mit wieder­
+holt. Das Feldmuster für Kommentar muß jedoch mit fester Länge
+angegeben werden, da sonst die rechte Tabellenbegrenzung bis zum
+Dateilimit geschoben würde.
+
+#on("b")#Zusammenfassung#off("b")# Zum Abschluß dieses Abschnitts eine
+Zusammenfassung aller möglichen Modi:
+
+ Modus Effekt
+
+ 1 Normalmodus.
+ '%'-Feldmuster werden auch nach links geschoben.
+ Keine Zeilenwiederholung.
+
+ 2 Tabellenmodus.
+ '%'-Feldmuster werden nicht nach links geschoben.
+ Keine Zeilenwiederholung.
+
+ 3 Normalmodus mit Zeilenwiederholung.
+ '%'-Feldmuster werden auch nach links geschoben.
+ Zeilenwiederholung ohne Zwischentexte.
+
+ 4 Tabellenmodus mit Zeilenwiederholung.
+ '%'-Feldmuster werden nicht nach links geschoben.
+ Zeilenwiederholung mit Zwischentexten.
+
+
diff --git a/doc/eudas/eudas.hdb.13 b/doc/eudas/eudas.hdb.13
new file mode 100644
index 0000000..435fbfc
--- /dev/null
+++ b/doc/eudas/eudas.hdb.13
@@ -0,0 +1,757 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (133)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+13 Programmierung von Druckmustern
+
+
+
+13.1 Abkürzungen
+
+In den vorigen Kapiteln haben Sie erfahren, daß man Feldmuster
+von ganz bestimmter Länge definieren kann, deren Inhalt in genau
+dieser Länge eingesetzt und bei Bedarf abgeschnitten wird. Bei der
+Angabe dieser Länge spielt jedoch die Länge des Feldnamens eine
+ganz entscheidende Rolle. Das kürzeste Feldmuster fester Länge, das
+Sie definieren können, ist nämlich zwei Zeichen länger als der Feld­
+name (ein Musterzeichen vorher und eins nachher).
+ Hätte das Feld 'PLZ' den Namen 'Postleitzahl' bekommen, so
+müßte ein solches Feldmuster mindestens eine Länge von 14 Zeichen
+haben. Damit Sie mit diesem Feldnamen auch ein Feldmuster der
+Länge 4 bekommen können (Postleitzahlen haben in den seltensten
+Fällen mehr als 4 Stellen), haben Sie die Möglichkeit, den Namen
+'Postleitzahl' für die Verwendung im Druckmuster geeignet abzu­
+kürzen.
+ Abkürzungen haben jedoch noch eine viel weitreichendere
+Bedeutung. Mit ihnen ist es möglich, nicht nur die Feldinhalte einer
+EUDAS-Datei einzusetzen, sondern auch jeden anderen Text, den Sie
+mit einem ELAN-Programm erzeugen können.
+ Die einfachsten zusätzlichen Daten, die Sie verwenden können,
+sind z.B. Datum und Uhrzeit. Für weitergehende Zwecke können Sie
+die Inhalte der EUDAS-Datei auch für Berechnungen verwenden und
+damit so umfangreiche Probleme wie das Schreiben von Rechnungen
+oder statistische Auswertungen unter Verwendung eines Druck­
+musters lösen.
+
+#on("b")#Abkürzungsteil#off("b")# Abkürzungen werden in einem speziellen
+Abkür­
+zungsteil am Ende eines Abschnittes angegeben. Der Abkürzungsteil
+wird durch die Anweisung
+
+
+ % ABKUERZUNGEN
+
+
+eingeleitet. Eine Abkürzungsdefinition hat eine ähnliche Form wie
+ein Refinement (Falls Sie nicht wissen, was das ist, vergessen Sie
+es). Zu Beginn steht der Name der Abkürzung in Form eines Feld­
+musters, beginnend in der ersten Spalte. Danach folgt, durch Leer­
+zeichen getrennt, ein Doppelpunkt in der gleichen Zeile. Daran
+schließt sich ein beliebiger ELAN-Ausdruck an, der sich in freiem
+Format über beliebig viele Zeilen erstrecken kann und mit einem
+Punkt abgeschlossen werden muß. Dieser ELAN-Ausdruck muß ein
+TEXT-Objekt liefern.
+
+#on("b")#Feldinhalt#off("b")# Für die Abfrage von Inhalten aus einer
+EUDAS-Datei ist der Ausdruck
+
+
+ f ("Feldname")
+
+
+vordefiniert. Die Abkürzung des Feldes 'Postleitzahl' würde also als
+Ausschnitt folgendermaßen aussehen:
+
+
+ % ABKUERZUNGEN
+ &p : f ("Postleitzahl") .
+
+
+Mit dieser Definition kann man im Muster so verfahren, als ob das
+Feld 'Postleitzahl' auch 'p' hieße. Diese einfachste Form der Ab­
+kürzung können Sie natürlich variieren, indem Sie für 'p' und
+'Postleitzahl' Ihre eigenen Namen einsetzen.
+
+#on("b")#Übersetzung#off("b")# Beachten Sie, daß das Druckmuster in ein
+ELAN-Pro­
+gramm umgeformt werden muß, da ELAN-Ausdrücke in ihm vorkom­
+men. Das automatisch erzeugte ELAN-Programm wird dann vom
+ELAN-Compiler übersetzt und ausgeführt. Fehler in den ELAN-Aus­
+drücken im Abkürzungsteil können erst vom ELAN-Compiler ent­
+deckt werden. Dieser kennt jedoch das Druckmuster nicht und mel­
+det die Fehler anhand des generierten Programms. Sie müssen in
+einem solchen Fall aufpassen, daß Sie die Fehlerquelle an der rich­
+tigen Stelle im Druckmuster lokalisieren (Hilfestellungen dazu sind
+im Kapitel über die Übersetzung von Druckmustern zu finden).
+
+#on("b")#Beispiel#off("b")# Um die Verwendung von Abkürzungen zu
+demonstrieren, wollen wir folgendes Druckmuster betrachten:
+
+
+ % VORSPANN
+ Adressenliste als Beispiel für Abkürzungen
+ Stand: &Datum
+ ------------------------------------------
+ % ABKUERZUNGEN
+ &Datum : date .
+
+ % WIEDERHOLUNG
+ &&l : &Vorname %Name
+ &Strasse
+ &&p& &Ort
+ ------------------------------------------
+ % ABKUERZUNGEN
+ &l : lfd nr .
+ &p : f ("PLZ") .
+
+ % NACHSPANN
+ &l Adressen gedruckt.
+
+
+Dieses Beispiel enthält eine ganze Reihe interessanter Details. Als
+erstes sollten Sie registrieren, daß auch im Vorspann oder Nach­
+spann Feldmuster verwendet werden können. Soll in diesem Fall ein
+Feldinhalt aus der EUDAS-Datei eingesetzt werden, so werden beim
+Vorspann die Inhalte des ersten und beim Nachspann die Inhalte des
+letzten durch Suchmuster ausgewählten Satzes verwendet. Daher
+kann auch jeder Abschnitt einen Abkürzungsteil haben. Abkürzun­
+gen gelten jedoch für alle Abschnitte (s. '&l'); die Aufteilung in
+mehrere Abkürzungsteile fördert im wesentlichen die Übersichtlich­
+keit.
+ Versuchen Sie, an diesem Beispiel die wichtigsten Unterschiede
+zwischen dem #on("i")#Musterteil#off("i")# und dem #on("i")#Abkürzungsteil#off("i")# eines Abschnittes
+zu verstehen. Das Format des Musterteiles soll in die Ausgabe
+übernommen werden; daher ist dort die Stellung jedes Wortes wich­
+tig. Im Abkürzungsteil definieren Sie Abkürzungen ohne bestimm­
+tes Format - mit der einzigen Ausnahme, daß eine Abkürzungs­
+definition mit einem '&' in der ersten Spalte anfangen und ein
+Leerzeichen vor dem Doppelpunkt haben muß. Wie Sie sehen, dürfen
+dort Leerzeilen zur besseren Lesbarkeit eingefügt werden.
+Sie sollten bei unserem Beispiel folgende Ausgabe erhalten:
+
+
+ Adressenliste als Beispiel für Abkürzungen
+ Stand: 28.12.84
+ ------------------------------------------
+ 1 : Herbert Wegner
+ Krämergasse 12
+ 5000 Köln
+ ------------------------------------------
+ 2 : Helga Sandmann
+ Willicher Weg 109
+ 5300 Bonn 1
+ ------------------------------------------
+ 3 : Albert Katani
+ Lindenstr. 3
+ 5210 Troisdorf
+ ------------------------------------------
+ 4 : Peter Ulmen
+ Mozartstraße 17
+ 5 Köln 60
+ ------------------------------------------
+ 5 : Karin Regmann
+ Grengelweg 44
+ 5000 Köln 90
+ ------------------------------------------
+ 6 : Hubert Arken
+ Talweg 12
+ 5200 Siegburg
+ ------------------------------------------
+ 7 : Anna-Maria Simmern
+ Platanenweg 67
+ 5 Köln 3
+ ------------------------------------------
+ 8 : Angelika Kaufmann-Drescher
+ Hauptstr. 123
+ 53 Bonn 2
+ ------------------------------------------
+ 9 : Harald Fuhrmann
+ Glockengasse 44
+ 5000 Köln 1
+ ------------------------------------------
+ 10 : Friedrich Seefeld
+ Kabelgasse
+ 5000 Köln-Ehrenfeld
+ ------------------------------------------
+ 10 Adressen gedruckt.
+
+
+Nun zu den Abkürzungen im einzelnen. Das Feld 'PLZ' muß abge­
+kürzt werden, damit es rechtsbündig vor den Ort gedruckt werden
+kann. Die Abkürzung 'p' benutzt die im vorigen Kapitel beschriebe­
+ne Form zur Abfrage des Feldinhaltes.
+ 'Datum' wird als Abkürzung für das aktuelle Datum definiert,
+ein häufig benötigter Fall. 'date' ist der ELAN-Ausdruck, der das
+Datum liefert. (Bemerkung für ELAN-Programmierer: der Name der
+Abkürzung gehorcht nicht der ELAN-Syntax für Bezeichner).
+ Eine für Tabellen sinnvolle Funktion wird bei der Definition
+von 'l' verwendet. Der von EUDAS definierte Ausdruck 'lfd nr' lie­
+fert die laufende Nummer des gerade gedruckten Satzes als Text.
+Dabei ist zu beachten, daß die laufende Nummer nicht mit der Satz­
+nummer übereinstimmt, sondern nur während des Druckvorganges
+von 1 an bei jedem gedruckten Satz hochgezählt wird. Diese Funk­
+tion dient dazu, die Sätze in der Liste durchzunumerieren.
+ Die laufende Nummer soll in der Liste rechtsbündig mit Doppel­
+punkt vor dem Namen stehen. Dazu wird das Feldmuster '&&l' be­
+nutzt, eine Form, die eigentlich keinen Sinn hat (die Kombination
+'variable Länge' und 'rechtsbündig' gibt es nicht). Um ein möglichst
+kurzes Feldmuster schreiben zu können, wird in diesem Fall jedoch
+feste Länge unterstellt (auch ohne folgendes '&'). Damit hat das
+kürzeste Feldmuster fester Länge drei Zeichen sowohl im linksbün­
+digen ('&l&') wie auch im rechtsbündigen Fall ('&&l').
+
+#on("b")#Auswertungen#off("b")# Die Verwendung der Abkürzung 'l' im Nachspann
+kann als erstes Beispiel für eine Auswertungsfunktion gelten. Da
+für den Nachspann die Daten des letzten Satzes verwendet werden,
+erscheint hier die laufende Nummer des letzten Satzes und somit die
+Anzahl der Sätze, die gedruckt wurden. Das kann dazu benutzt
+werden, die Sätze zu zählen, die eine bestimmte Suchbedingung
+erfüllen. Folgendes Druckmuster zählt die Anzahl der Frauen oder
+Männer in der Datei:
+
+
+ % NACHSPANN
+ &l Personen mit dem Geschlecht '%<m/w>' vorhanden.
+ % ABKUERZUNGEN
+ &l : lfd nr .
+
+
+Wenn Sie vor dem Drucken jetzt die Suchbedingung 'm' für das Feld
+'m/w' einstellen, werden alle Männer ausgewählt. Das Drucken be­
+steht in diesem Fall nur aus dem Hochzählen der laufenden Nummer
+für jeden Mann. Im Nachspann kann das Ergebnis dann ausgegeben
+werden; zugleich soll der aktuelle Wert des Feldes 'm/w' gedruckt
+werden, damit das Druckmuster auch für das Zählen der Frauen
+verwendet werden kann.
+ Die beiden möglichen Ausgaben würden dann so aussehen:
+
+
+ 6 Personen mit dem Geschlecht 'm' vorhanden.
+
+ 4 Personen mit dem Geschlecht 'w' vorhanden.
+
+
+#on("b")#Zusammenfassung#off("b")# Wir können die Erkenntnisse dieses
+Abschnittes wie folgt zusammenfassen:
+
+* Feldmuster können auch im Vorspann und Nachspann verwendet
+ werden. Im Vorspann werden die Daten des ersten, im Nachspann
+ die Daten des letzten ausgewählten Satzes verwendet.
+
+* Der Musterteil eines Abschnittes definiert ein Format; der Ab­
+ kürzungsteil ist formatfrei.
+
+* 'lfd nr' dient zum Durchnumerieren aller gedruckten Sätze.
+
+* Ein rechtsbündiges Feldmuster hat immer auch feste Länge.
+
+#on("b")#Komplexe Abkürzungen#off("b")# Mit Hilfe von Abkürzungen können wir
+jetzt auch bessere Musterbriefe schreiben. Ein Problem, das bereits
+angesprochen wurde, besteht darin, daß in der Anrede je nach Ge­
+schlecht 'Herr' oder 'Frau' stehen soll. Um dieses Problem zu lösen,
+wird der Inhalt des Feldes 'm/w' benötigt.
+ Da in einer Abkürzung jede ELAN-Anweisung erlaubt ist, die
+einen Text liefert, können natürlich auch #on("i")#IF-Anweisungen#off("i")# verwen­
+det werden. Mit diesen Informationen können wir jetzt die Abkür­
+zung 'Anrede' definieren:
+
+
+ % ABKUERZUNGEN
+ &Anrede :
+ IF f ("m/w") = "w" THEN
+ "Frau"
+ ELSE
+ "Herr"
+ END IF .
+
+
+Für Nicht-Programmierer: Die IF-Anweisung besteht aus einer Ab­
+frage und zwei Alternativen. Die Abfrage steht zwischen dem IF und
+dem THEN und besteht in der Regel aus einer Abfrage, ob zwei
+Dinge gleich oder ungleich (<>), größer oder kleiner sind. Außerdem
+können mehrere Abfragen mit AND (und) und OR (oder) kombiniert
+werden. Näheres dazu im Kapitel 14.
+ Die Alternative hinter dem THEN wird ausgewählt, wenn die
+Abfrage zutrifft. An dieser Stelle sind wieder beliebige Ausdrücke
+erlaubt, die einen Text liefern, einschließlich erneuter IF-Anwei­
+sungen (Schachtelung). Die Alternative zwischen ELSE und END IF
+wird ausgewählt, wenn die Abfrage nicht zutrifft.
+
+#on("b")#Textkonstanten#off("b")# Bisher wurden nur ELAN-Funktionen als
+Textlie­
+feranten betrachtet ('date', 'lfd nr', 'f'). In unserem Fall werden
+aber #on("i")#Textkonstanten#off("i")# in den Alternativen der IF-Anweisung benö­
+tigt. Textkonstanten werden in ELAN in Anführungsstriche einge­
+schlossen, die aber nicht zum Text gehören. Innerhalb einer Text­
+konstanten werden Leerzeichen wie alle anderen Zeichen angesehen
+(erscheinen also auch nachher in der Ausgabe).
+ Bei solchen Abkürzungen, die längere Anweisungen umfassen,
+sollten Sie das freie Format ausnutzen und eine möglichst über­
+sichtliche Darstellung wählen. Wie Sie sehen, muß nur der Doppel­
+punkt noch in der ersten Zeile stehen, der Rest kann sich beliebig
+auf die folgenden Zeilen erstrecken.
+
+#on("b")#Beispiel#off("b")# Ein typischer Einsatz einer IF-Anweisung für die
+Anrede sieht so aus:
+
+
+ % WIEDERHOLUNG
+
+ Sehr geehrte&Anrede %<Name>!
+
+ ...
+ % ABKUERZUNGEN
+ &Anrede :
+ IF f ("m/w") = "m" THEN
+ "r Herr"
+ ELSE
+ " Frau"
+ END IF .
+
+
+Sie sollten jetzt diese Konstruktion in einen Musterbrief einfügen
+können. Probieren Sie ihn dann als Beispiel aus !
+
+#on("b")#Weitere Möglichkeiten#off("b")# Durch Verwendung von Abkürzungen ist
+es
+auch möglich, rechtsbündige Felder mit einer Länge von weniger als
+3 Zeichen zu simulieren. Dies geschieht mit Hilfe der Textoperatio­
+nen von ELAN. Ohne ELAN-Vorkenntnisse können Sie dieses Bei­
+spiel überlesen. In unserer Liste im obigen Beispiel sind die laufen­
+den Nummern höchstens zweistellig und sollten deshalb auch nur
+zwei Stellen belegen. Dies würde folgende Abkürzung ermöglichen:
+
+
+ % ABKUERZUNGEN
+ &l : text (lfd nr als zahl, 2) .
+ lfd nr als zahl : int (lfd nr) .
+
+
+Die Prozedur 'text' wird dazu benutzt, eine Zahl rechtsbündig auf
+zwei Stellen zu formatieren (s. EUMEL-Benutzerhandbuch). Da die
+Abkürzung immer eine Länge von zwei Zeichen hat, kann sie auch in
+einem Feldmuster variabler Länge eingesetzt werden. Die Attribute
+'feste Länge' und 'rechtsbündig' werden in diesem Fall also nicht
+durch das Feldmuster, sondern durch die Abkürzung selbst erzeugt.
+ Um die Prozedur 'text' anwenden zu können, muß die laufende
+Nummer als Zahl (sprich: INT-Objekt) vorliegen. Diese Umwandlung
+wird mit der Prozedur 'int' vorgenommen, die einen Text in eine
+Zahl umwandelt. Obwohl man 'int (lfd nr)' direkt in den Aufruf von
+'text' hätte schreiben können, wird hier als Demonstration dafür ein
+Refinement verwendet.
+ Refinements können in einem Abkürzungsteil neben Abkürzun­
+gen stehen und von allen Abkürzungen benutzt werden. Sie werden
+ähnlich geschrieben wie Abkürzungen, nur ihr Name muß in Klein­
+buchstaben geschrieben werden, dafür muß er nicht in der ersten
+Spalte anfangen und kann Leerzeichen enthalten. Bei komplizierte­
+ren Ausdrücken sollten Refinements zur besseren Lesbarkeit einge­
+setzt werden.
+ Sie können die IF-Anweisung auch mit beliebig vielen ELIF-
+Teilen versehen. Achten Sie jedoch darauf, daß die IF-Anweisung
+#on("i")#immer#off("i")# irgendeinen Wert liefern muß. Sie dürfen also den ELSE-Teil
+nicht weglassen. Statt einer IF-Anweisung können Sie natürlich
+auch eine SELECT-Anweisung verwenden. Es stehen Ihnen im Prin­
+zip alle werteliefernden Anweisungen von ELAN zur Verfügung.
+ Die Programmiersprache ELAN bietet Ihnen noch weit mehr
+Möglichkeiten, als hier beschrieben werden können. So können Sie
+sich eigene Prozeduren definieren und diese dann in Abkürzungen
+verwenden. In Kapitel 14 und 15 finden Sie eine Einführung in die
+wichtigsten Konstrukte, die für EUDAS gebraucht werden.
+
+
+13.2 Bedingte Musterteile
+
+Wenn größere Teile des Druckmusters in Abhängigkeit von bestimm­
+ten Daten unterschiedlich ausfallen sollen, werden die dazu benö­
+tigten Abkürzungen sehr umfangreich. Für solche Fälle kann man
+IF-Anweisungen auch im Musterteil eines Abschnitts verwenden. In
+diesem Fall werden die Alternativen der IF-Anweisung durch
+Musterzeilen dargestellt.
+ Im Musterteil müssen jedoch die Zeilen, die Teil der IF-An­
+weisung sind, von den Musterzeilen unterschieden werden. Deshalb
+werden die Anweisungszeilen durch ein '%'-Zeichen in der ersten
+#on("i")#und#off("i")# zweiten Spalte gekennzeichnet. Das zweite '%'-Zeichen dient
+zur Unterscheidung von Anweisungen an den Druckgenerator, die
+nicht an den ELAN-Compiler übergeben werden sollen.
+ Mit einer IF-Anweisung im Musterteil kann man das Anredepro­
+blem auch folgendermaßen lösen:
+
+
+ % WIEDERHOLUNG
+ %% IF f ("m/w") = "w" THEN
+ Sehr geehrte Frau &<Name>!
+ %% ELSE
+ Sehr geehrter Herr &<Name>!
+ %% END IF;
+
+
+Beachten Sie den Unterschied, daß die IF-Anweisung hier mit einem
+Semikolon abgeschlossen werden muß - in Abkürzungen mußte ja ein
+Punkt danach folgen. Außerdem darf hier der ELSE-Teil (die zweite
+Alternative) fehlen, während in einer Abkürzung in jeder Alternati­
+ve etwas stehen muß (zumindest der leere Text "").
+ Falls sich der IF-THEN-Teil über mehr als eine Zeile erstrek­
+ken soll, muß jede dieser Zeilen mit '%%' beginnen, da die Folgezei­
+len sonst als Musterzeilen gedruckt würden. Benutzen Sie in einem
+solchen Fall jedoch besser ein Refinement, das Sie im Abkürzungs­
+teil definieren müssen.
+ Sie können im Musterteil auch andere ELAN-Anweisungen
+verwenden. Der Unterschied zu Abkürzungen liegt darin, daß die
+Musterzeilen nicht als Werte angesehen werden, die die Anweisung
+liefern muß, sondern als Anweisungen, die dort aufgeführten Mu­
+sterzeilen einzusetzen und zu drucken. Daher kann im Musterteil
+auch eine FOR-Schleife sinnvoll sein, wenn in Abhängigkeit eines
+Wertes eine bestimmte Anzahl von Zeilen gedruckt werden soll.
+
+
+13.3 Übersetzung
+
+Wenn Sie bis jetzt auch als ELAN-Programmierer immer noch nicht
+ganz durchblicken, wie Sie welche ELAN-Anweisungen verwenden
+können, dann ist das noch kein Anlaß zur Sorge. Es ist kaum mög­
+lich, die genauen Auswirkungen beliebiger Anweisungen zu be­
+schreiben, ohne den Übersetzungsprozeß zu schildern, der diese
+Anweisungen zu einem ELAN-Programm zusammenbindet. Daher soll
+diese Übersetzung jetzt genauer erklärt werden.
+
+#on("b")#Übersetzungsmechanismus#off("b")# Alle Zeilen eines Abkürzungsteils
+wer­
+den direkt in das Programm übernommen, wobei der Name einer Ab­
+kürzung durch einen beliebig gewählten Refinementnamen ersetzt
+wird ('abk' + eine laufende Nummer). Alle Abkürzungen und Re­
+finements werden als globale Refinements definiert, also außerhalb
+von Prozeduren. Dadurch wird erreicht, daß sie an jeder Stelle
+verwendet werden können.
+ Damit eine Abkürzung richtig als Refinement übersetzt wird,
+muß sie ein TEXT-Objekt als Wert liefern. Die anderen Refinements
+sind beliebig, da Sie nur in selbstdefinierten Anweisungen verwen­
+det werden. Die Refinements der Abkürzungen werden in einer Zu­
+weisung an eine TEXT-Variable verwendet, damit der Druckgenera­
+tor auf den entsprechenden Wert zugreifen kann.
+ Jeder Abschnitt wird dagegen als eine Prozedur übersetzt. Jede
+Folge von Musterzeilen wird in eine Anweisung übersetzt, diese
+Musterzeilen einzusetzen und zu drucken. Jede '%%'-Anweisung
+wird einfach unverändert dazwischen geschrieben. Die Vorspann-
+Prozedur wird einmal zu Anfang aufgerufen, die Prozedur für den
+Wiederholungsteil einmal für jeden ausgewählten Satz und die Nach­
+spann-Prozedur einmal am Schluß.
+ Bei Fehlern im ELAN-Teil zeigt der Compiler das erzeugte Pro­
+gramm zusammen mit seinen Fehlermeldungen im Paralleleditor. Sie
+müssen nun die Fehlermeldung lokalisieren und anhand der eben
+gegebenen Hinweise in das ursprüngliche Druckmuster zurücküber­
+setzen, damit Sie dort den Fehler korrigieren können.
+
+#on("b")#Beispiel#off("b")# Nun müßten Sie genug Informationen haben, um
+beliebige
+ELAN-Anweisungen in das Druckmuster einfügen zu können. Als
+Beispiel wollen wir versuchen, alle Männer und Frauen in der
+Adressendatei zu zählen, ohne ein Suchmuster einstellen zu müssen
+und ohne den Druckvorgang zweimal ablaufen zu lassen (wie dies
+bei dem obigen Beispiel der Fall war). Ein erster Versuch könnte so
+aussehen:
+
+
+ % VORSPANN
+ %% INT VAR maenner, frauen;
+ %% maenner := 0;
+ %% frauen := 0;
+ % WIEDERHOLUNG
+ %% IF f ("m/w") = "m" THEN
+ %% maenner INCR 1
+ %% ELSE
+ %% frauen INCR 1
+ %% END IF
+ % NACHSPANN
+ &maenner Männer und %frauen Frauen vorhanden.
+
+
+Aber Vorsicht! In diesem Beispiel sind mehrere Fehler eingebaut.
+Finden Sie sie!
+
+#on("b")#Fehler im Beispiel#off("b")# Der erste Fehler befindet sich im
+Nachspann.
+Hier wird versucht, die Namen der beiden Variablen 'maenner' und
+'frauen' direkt in einem Feldmuster zu verwenden. Diese beiden
+Namen sind dem Druckgenerator nicht bekannt, sondern nur dem
+ELAN-Compiler. Um die Werte der beiden Variablen einsetzen zu
+können, müssen Sie also zwei geeignete Abkürzungen definieren.
+ Der zweite Fehler ist schwieriger zu finden. Wie oben gesagt,
+wird jeder Abschnitt in eine Prozedur übersetzt. Die in einem Ab­
+schnitt definierten Variablen können also nur in diesem Abschnitt
+verwendet werden (sie sind lokal) und auch nicht im Abkürzungs­
+teil, da dieser wieder global vereinbart wird. Die beiden im Vor­
+spann definierten Variablen stehen also im Wiederholungsteil und im
+Nachspann nicht zur Verfügung.
+
+#on("b")#Anweisungen im Initialisierungsteil#off("b")# Für diesen Fall gibt
+es die
+Möglichkeit, ELAN-Anweisungen vor allen Abschnitten im Initiali­
+sierungsteil zu definieren. Diese Anweisungen sind dann ebenfalls
+global. Das richtige Druckmuster finden Sie auf der nächsten Seite.
+ Natürlich könnten Sie die Initialisierung der beiden Variablen
+auch noch aus dem Vorspann herausnehmen. Denken Sie daran, daß
+Sie aus INT-Variablen erst einen Text machen müssen, ehe Sie sie
+in eine Musterzeile einsetzen können. Beachten Sie Schreibweise der
+Variablen: in ELAN können die Umlaute nicht in Bezeichnern ver­
+wendet werden, daher muß die Variable mit 'ae' geschrieben wer­
+den. Im Mustertext und in Abkürzungs- und Feldnamen können die
+Umlaute jedoch frei verwendet werden.
+
+
+ %% INT VAR maenner, frauen;
+ % VORSPANN
+ %% maenner := 0;
+ %% frauen := 0;
+ % WIEDERHOLUNG
+ %% IF f ("m/w") = "m" THEN
+ %% maenner INCR 1
+ %% ELSE
+ %% frauen INCR 1
+ %% END IF
+ % NACHSPANN
+ &m Männer und %f Frauen vorhanden .
+ % ABKUERZUNGEN
+ &m : text (maenner) .
+ &f : text (frauen) .
+
+
+
+13.4 Gruppen
+
+Der Druckgenerator bietet die Möglichkeit, Vorspann und Nachspann
+nicht nur am Anfang und am Ende, sondern auch an bestimmten
+Stellen zwischen Sätzen zu drucken. Diese Stellen sind dadurch
+bestimmt, daß ein bestimmtes Merkmal (z.B. ein Feldinhalt) seinen
+Wert ändert. Ein solches Merkmal wird im Druckmuster #on("i")#Gruppe#off("i")# ge­
+nannt.
+ Ein Beispiel für die Verwendung von Gruppen ist eine Schüler­
+datei, die nach Klassen geordnet ist. Definiert man das Feld 'Klas­
+se' als Gruppe, so wird jeweils am Ende einer Klasse ein Nachspann
+und am Beginn einer Klasse ein Vorspann gedruckt.
+ Dieses Verfahren ist eine Erweiterung der bisher beschriebenen
+Methode, indem eine Datei quasi in mehrere Dateien untergliedert
+wird, die jedoch in einem Arbeitsgang gedruckt werden können.
+Voraussetzung dafür ist jedoch, daß die Datei nach dem Gruppen­
+merkmal geordnet ist - der Druckgenerator sammelt nicht erst alle
+Schüler einer Klasse aus der Datei, sondern erwartet sie hinter­
+einander.
+
+#on("b")#Gruppendefinition#off("b")# Eine Gruppe wird im Initialisierungsteil
+des
+Druckmusters (also vor allen Abschnitten) definiert. Notwendige
+Daten sind eine Nummer zur Identifizierung und das Merkmal. Die
+Nummer sollte am sinnvollsten von 1 an vergeben werden; die mög­
+lichen Werte sind nach oben hin beschränkt. Das Merkmal ist ein
+beliebiger ELAN-Ausdruck, der einen Text liefert. Sinnvollerweise
+wird er den Inhalt eines Feldes enthalten.
+ Gruppendefinitionen müssen nach allen ELAN-Anweisungen im
+Initialisierungsteil folgen, und zwar, weil die Gruppendefinitionen
+alle in einer Prozedur zusammengefaßt werden, die bei jedem neuen
+Satz auf Gruppenwechsel testet.
+ Unter der Annahme, daß die oben erwähnte Schülerdatei ein
+Feld 'Klasse' besitzt, würde die Gruppe wie folgt definiert:
+
+
+ % GRUPPE 1 f ("Klasse")
+
+
+Nach der Anweisung 'GRUPPE' folgt die Gruppennummer und dann
+ein ELAN-Ausdruck. Die ganze Definition muß in einer Zeile stehen;
+reicht der Platz nicht aus, müssen Sie in einem Abkürzungsteil ein
+Refinement definieren.
+
+#on("b")#Klassenliste#off("b")# Das komplette Druckmuster für die
+Klassenliste könn­
+te folgendes Aussehen haben, wenn außer 'Klasse' auch noch die
+Felder 'Name' und 'Vorname' vorhanden sind:
+
+
+ % GRUPPE 1 f ("Klasse")
+ % VORSPANN
+ Klassenliste für Klasse &Klasse
+ ----------------------------
+ % WIEDERHOLUNG
+ &Vorname %Name
+ % NACHSPANN
+ \#page\#
+
+
+Wenn eine Gruppe definiert ist, werden im Nachspann immer die
+Feldinhalte des letzten Satzes vor dem Gruppenwechsel gedruckt, im
+Vorspann die Inhalte des ersten Satzes nach dem Wechsel. Daher
+kann hier im Vorspann die Klasse gedruckt werden, da sie sich erst
+ändert, wenn schon wieder der nächste Vorspann gedruckt wird.
+
+#on("b")#Mehrere Gruppen#off("b")# Wie die Identifikation über eine
+Gruppennummer
+vermuten läßt, können Sie mehrere Gruppen definieren. Nachspann
+und Vorspann werden jeweils gedruckt, wenn sich das Merkmal ir­
+gendeiner Gruppe ändert. Ob eine bestimmte Gruppe gewechselt hat,
+kann mit der Abfrage
+
+
+ BOOL PROC gruppenwechsel (INT CONST gruppennummer)
+
+
+in einer IF-Anweisung ermittelt werden. Vor dem ersten und nach
+dem letzten Satz wechseln automatisch alle Gruppen.
+ Die ganze Datei bildet eine Quasi-Gruppe mit der Nummer 0.
+Sie ist immer definiert und wechselt nur vor dem ersten und nach
+dem letzten Satz. Sie ist es, die bewirkt, daß Vorspann und Nach­
+spann in ihrer normalen Weise gedruckt werden.
+
+#on("b")#Anwendungsbeispiel#off("b")# Um einige der Möglichkeiten zu
+illustrieren,
+die durch Gruppen geschaffen werden, wollen wir als Beispiel eine
+Anwendung betrachten, die neue Wege für die Benutzung von EUDAS
+aufzeigt.
+ Aus einer Datei, in der für jede Bestellung der Kunde, der Ar­
+tikel, die bestellte Menge und der Einzelpreis des Artikels einge­
+tragen werden, sollen anschließend Rechnungen gedruckt werden.
+Die Datei soll folgende Felder haben:
+
+
+ 'Kundennummer'
+ 'Artikelnummer'
+ 'Einzelpreis'
+ 'Menge'
+
+
+Als Voraussetzung müssen die Bestellungen in der Datei jeweils
+nach Kunden geordnet vorliegen. Die Kundennummer wird als Gruppe
+definiert, so daß die Bestellungen eines Kunden zu einer Rechnung
+zusammengefaßt werden können. Das Druckmuster rechnet dann die
+einzelnen Preise zusammen und gibt eine Endsumme aus.
+ Damit in der Rechnung Name und Adresse des Kunden auftau­
+chen können, wird zu der Bestellungsdatei die Kundendatei gekop­
+pelt, die folgende Felder haben soll:
+
+
+ 'Kundennummer'
+ 'Name'
+ 'Vorname'
+ 'Strasse'
+ 'PLZ'
+ 'Ort'
+
+
+Stellen Sie sich zum Ausprobieren des folgenden Druckmusters ge­
+gebenenfalls eigene Daten zusammen. Hier nun das Druckmuster:
+
+
+ %% REAL VAR gesamtpreis, summe;
+ % GRUPPE 1 f ("Kundennummer")
+ % VORSPANN
+ %% summe := 0.0;
+ Fa. Kraus & Sohn
+ Schotterstr. 10
+
+ 5000 Köln 1
+ &Vorname %Name
+ &Strasse
+
+ &PLZ &Ort &Datum
+
+ R E C H N U N G
+ ===============
+
+ Menge Artikelnr. Einzelpreis Gesamtpreis
+ ------------------------------------------------
+ % ABKUERZUNGEN
+ &Datum : date .
+
+ % WIEDERHOLUNG
+ %% gesamtpreis := round
+ %% (wert ("Einzelpreis") * wert ("Menge"), 2);
+ %% summe INCR gesamtpreis;
+ &Menge &Artikelnummer &&&&epr&& &&&&gpr&&
+ % ABKUERZUNGEN
+ &epr : f ("Einzelpreis") .
+ &gpr : zahltext (gesamtpreis, 2) .
+
+ % NACHSPANN
+ ------------------------------------------------
+ Summe: &&&&sum&&
+ + 14% MWSt. &&&Mwst&&
+ =========
+ Endbetrag &&&&end&&
+ \#page\#
+ % ABKUERZUNGEN
+ &sum : zahltext (summe, 2) .
+ &Mwst : zahltext (mwst, 2) .
+ &end : zahltext (summe + mwst, 2) .
+ mwst : round (summe * 0.14, 2) .
+
+
+Im Initialisierungsteil dieses Druckmusters wird die Kundennummer
+als Gruppe definiert. Dies hat zur Folge, daß für jeden neuen Kun­
+den eine neue Rechnung begonnen wird, nachdem vorher im Nach­
+spann die Rechnungssumme des vorherigen Kunden berechnet und
+ausgedruckt wurde. Vor dieser Gruppendefinition sind 'gesamtpreis'
+und 'summe' definiert, die später als globale Variablen zur Verfü­
+gung stehen sollen. Diese Zeile darf nicht nach der Gruppendefini­
+tion stehen.
+ Im Vorspann wird der Kopf der Rechnung angegeben. Dieser
+enthält neben den Daten des Kunden (aus der gekoppelten Kun­
+dendatei) noch das Datum. Die Kundennummer wird nur zum Kop­
+peln und als Gruppenmerkmal benötigt, erscheint also nicht auf der
+Rechnung.
+ Es fällt auf, daß im Firmennamen ein '&'-Zeichen auftaucht,
+das doch für die Markierung von Feldmustern reserviert ist. Die
+beiden Musterzeichen können jedoch im normalen Text auftauchen,
+wenn ihnen direkt ein Leerzeichen folgt. In diesem Fall werden Sie
+nicht als Beginn eines Feldmusters interpretiert, sondern unverän­
+dert gedruckt. Der gleiche Fall taucht noch mit '%' im Nachspann
+auf.
+ Im Wiederholungsteil wird zunächst aus dem Einzelpreis und der
+Menge des jeweiligen Artikels der Gesamtpreis für diesen Artikel
+berechnet. Für die Abfrage der Feldinhalte wird die Funktion 'wert'
+verwendet, die wie 'f' funktioniert, jedoch gleich einen REAL-Wert
+liefert.
+ Zu beachten ist, daß 'wert' wie beim Sortieren von Zahl alle
+Sonderzeichen ignoriert. Weiterhin müssen die Zahlen mit dem ein­
+gestellten Dezimalkomma geschrieben werden (also normalerweise
+mit Komma), damit ihr Wert richtig erkannt wird. Anderenfalls soll­
+ten Sie den Dezimalpunkt einstellen (s. 11.1).
+ Damit kaufmännisch richtig gerechnet wird, wird der Gesamt­
+preis auf 2 Nachkommastellen gerundet und erst dann aufsummiert.
+Würde der Gesamtpreis nur zum Einsetzen gerundet, könnten bei der
+anschließenden Addition der nicht gerundeten Werte eine falsche
+Gesamtsumme entstehen.
+ Erst nach diesen Berechnungen kann die Musterzeile folgen, in
+die die Werte dann eingesetzt werden. Um eine Ausgabe mit zwei
+Nachkommastellen zu erzeugen, wird die von EUDAS definierte
+Funktion 'zahltext' benutzt. Diese erzeugt aus einem REAL-Wert
+einen Text mit der angegebenen Anzahl von Kommastellen und setzt
+das korrekte Dezimalkomma ein. Das Ergebnis dieser Funktion wird
+dann rechtsbündig eingesetzt.
+ Im Nachspann wird dann der summierte Wert mit aufgeschlage­
+ner Mehrwertsteuer gedruckt. Die Mehrwertsteuer muß ebenfalls auf
+zwei Nachkommastellen gerundet werden.
+
+#on("b")#Erweiterung#off("b")# Zur Erweiterung könnten Sie die Bestelldatei
+noch mit
+einer Artikeldatei koppeln, die etwa folgende Struktur haben würde:
+
+
+ 'Artikelnummer'
+ 'Bezeichnung'
+ 'Einzelpreis'
+
+
+In diesem Fall könnten Sie noch jeweils die Artikelbezeichnung in
+eine Rechnungszeile drucken. Außerdem würde der Preis zentral
+gespeichert. Eine entsprechende Änderung des Druckmusters sollte
+Ihnen keine Schwierigkeiten bereiten.
+
+
+
diff --git a/doc/eudas/eudas.hdb.14 b/doc/eudas/eudas.hdb.14
new file mode 100644
index 0000000..1aa3c87
--- /dev/null
+++ b/doc/eudas/eudas.hdb.14
@@ -0,0 +1,724 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (151)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+14 Ausdrücke in ELAN
+
+
+
+14.1 Was sind Ausdrücke ?
+
+In diesem Kapitel wollen wir uns mit ELAN-Ausdrücken beschäfti­
+gen, wie sie für EUDAS gebraucht werden. Natürlich kann dies keine
+ernsthafte Einführung für ELAN-Programmierer sein - mit solchen
+Ambitionen halten Sie sich am besten an die entsprechende ELAN-
+Literatur.
+ Dieser Text richtet sich eher an den Benutzer, der kaum Erfah­
+rung mit ELAN hat, aber die Möglichkeiten von EUDAS optimal nut­
+zen will. Viele fortgeschrittene Fähigkeiten von EUDAS laufen ja
+über ELAN-Programme.
+
+#on("b")#Vorkommen#off("b")# Sie haben ELAN-Ausdrücke bereits an
+verschiedenen
+Stellen eingesetzt, wenn Sie sich mit den vorhergehenden Kapiteln
+befaßt haben. ELAN-Ausdrücke werden in nahezu allen Verarbei­
+tungsfunktionen benötigt.
+ Im Druckmuster dienen sie dazu, den Inhalt eines Feldmusters
+festzulegen. Die Definition einer Abkürzung besteht immer aus dem
+Namen der Abkürzung und einem Ausdruck. Ebenso wird in einer
+Gruppendefinition ein Ausdruck angegeben.
+ Beim Kopiermuster und beim Änderungsmuster besteht jeweils
+die rechte Seite einer Anweisung aus einem Ausdruck. Weiterhin
+werden Ausdrücke auch in anderen ELAN-Konstruktionen benötigt,
+wie zum Beispiel direkt am Anfang einer IF-Anweisung.
+
+#on("b")#Bedeutung#off("b")# Ein Ausdruck steht allgemein für einen Wert. Im
+ein­
+fachsten Fall kann dies eine Konstante sein, der Wert des Aus­
+drucks ändert sich also nicht. Anderenfalls spricht man von einem
+zusammengesetzten Ausdruck. Dessen Wert ergibt sich dann durch
+die Ausführung der im Ausdruck angegebenen Operationen. Dieser
+Wert kann je nach dem aktuellen Zustand des Systems verschieden
+sein, da er jedes Mal neu berechnet wird, wenn er gebraucht wird.
+ Ein Beispiel für einen zusammengesetzten Ausdruck ist 2+2
+Dieser Ausdruck steht für den Wert 4.
+ Der Wert eines Ausdrucks ist das, was uns eigentlich interes­
+siert. Beim Druckvorgang wird dieser Wert dann gedruckt, beim
+Kopieren und Verändern in ein Feld eingetragen.
+
+#on("b")#Zusammensetzung#off("b")# Ausdrücke lassen sich aus verschiedenen
+Ele­
+menten zusammensetzen. Grundlage bilden die Konstanten. Konstan­
+ten können durch #on("i")#Operatoren#off("i")# miteinander verknüpft werden. So ist
+in dem Ausdruck 2+3 das '+' ein Operator, der die Konstanten 2
+und 3 verknüpft. Das Ergebnis der Verknüpfung hängt natürlich vom
+jeweiligen Operator ab.
+ Wie Sie schon in der Schule gelernt haben ("Punktrechnung vor
+Strichrechnung"), muß man die Reihenfolge der Operatoren festlegen,
+wenn mehrere Operatoren im Spiel sind. Ähnliche Regeln gibt es für
+alle Operatoren in ELAN.
+ Wenn eine andere Reihenfolge der Operatoren erwünscht ist,
+können Sie diese durch Einsatz von Klammern verändern. Auch dies
+dürfte Ihnen aus der Schule noch in Erinnerung sein. Der Unter­
+schied in ELAN ist lediglich, daß es dort einige zusätzliche Opera­
+toren gibt, die Ihnen nicht aus der Mathematik vertraut sind.
+ Ein weiteres Konstruktionselement von Ausdrücken sind #on("i")#Funk­
+tionen#off("i")#. Auch diese kennen Sie aus der Schule. Lediglich die
+Schreibweise muß für den "dummen" Computer etwas ausführlicher
+gehalten werden (Beispiel: sin (3.14 * x)).
+ Die Argumente der Funktion hinter dem Funktionsnamen müssen
+auf jeden Fall in Klammern stehen. In der Terminologie der Pro­
+grammiersprachen spricht man von #on("i")#Parametern#off("i")#. Parameter können
+wieder komplexe Ausdrücke sein. Bei Funktionen mit mehreren
+Parametern werden diese durch Komma getrennt:
+
+
+ min (2.5 * x, x + 1.25)
+
+
+
+14.2 Datentypen
+
+Bevor wir beginnen, konkrete Ausdrücke zu behandeln, müssen wir
+erst das Konzept der #on("i")#Datentypen#off("i")# einführen. Grundidee dabei ist,
+daß es verschiedene Klassen von Werten gibt, die nicht einfach
+untereinander gemischt werden können.
+ So gibt es in ELAN einen grundlegenden Unterschied zwischen
+#on("i")#Zahlen#off("i")# und #on("i")#Texten#off("i")#. Texte bestehen aus einer beliebigen Aneinan­
+derreihung von Zeichen, die im Normalfall nur für den betrachten­
+den Menschen eine Bedeutung haben. Mit Zahlen kann man dagegen
+Berechnungen anstellen.
+ Der tiefere Grund für die Trennung in verschiedene Typen ist
+also, daß für jeden Typ gewisse Operationen definiert snd, die nur
+für diesen Typ sinnvoll sind. So ist zum Beispiel die Addition der
+beiden Texte "abc" und "-/-" völlig sinnlos.
+ Aber nicht nur die Operationen sind verschieden, sondern auch
+die interne Darstellung im Rechner. So werden der Text "1234" und
+die Zahl 1234 völlig anders gespeichert, obwohl man ihnen die glei­
+che Bedeutung beimessen könnte.
+
+#on("b")#Grundtypen#off("b")# In ELAN gibt es vier verschiedene Grundtypen,
+die für
+uns wichtig sind. Sie können sich in ELAN auch eigene Typen
+schaffen, dies geht jedoch weit über unsere Bedürfnisse hinaus.
+ Der in EUDAS am meisten verwendete Typ heißt #on("i")#TEXT#off("i")#. TEXT-
+Objekte bestehen aus einer Folge von 0 bis 32000 Zeichen. Die Zei­
+chen entstammen einem Satz von 256 verschiedenen Symbolen, die
+jeweils eine andere Darstellung haben. Einige der Zeichen lassen
+sich überhaupt nicht darstellen, sondern führen bestimmte Funktio­
+nen aus (zum Beispiel Bildschirm löschen).
+ Sämtliche Feldinhalte einer EUDAS-Datei sind TEXTe, ebenso
+die Zeilen von Textdateien. Auch Datei- und Feldnamen sind
+TEXTe. Von daher besteht eigentlich kein Grund, warum Sie sich
+außer zur Programmierung noch mit anderen Datentypen beschäfti­
+gen sollten.
+ Neben den Texten gibt es noch die Zahlen. Diese sind in ihrer
+internen Darstellung so beschaffen, daß ein effizientes Rechnen mit
+ihnen möglich ist. Andererseits können sie nicht mehr beliebige
+Informationen darstellen, sondern haben eine sehr eingeschränkte
+Bedeutung.
+ Um unterschiedichen Bedürfnissen gerecht zu werden, gibt es in
+ELAN zwei verschiedene Zahltypen. Der Typ #on("i")#INT#off("i")# umfaßt nur ganze
+Zahlen ohne Kommastellen. Damit die Zahl möglichst wenig Spei­
+cherplatz belegt, ist der Wertebereich bei den meisten Rechnern auf
+-32768..32767 beschränkt (die krummen Zahlen ergeben sich wegen
+der Binärarithmetik des Rechners). Dieser Typ eignet sich am besten
+zum Abzählen und zum Auswählen aus einer festen Anzahl von
+Objekten (zum Beispiel Feld 1 bis Feld 255).
+ Zum eigentlichen Rechnen gibt es den Typ #on("i")#REAL#off("i")#. Dieser umfaßt
+auch Kommazahlen. Genauigkeit, Wertebereich und Darstellung sind
+nahezu identisch mit den Möglichkeiten eines Taschenrechners. der
+Typ REAL wird immer dann verwendet, wenn mit realen Größen
+(Geldbeträge, physikalische Werte) gerechnet werden muß.
+ Zuletzt gibt es noch den Typ #on("i")#BOOL#off("i")#. Er hat nur zwei mögliche
+Werte, nämlich TRUE (wahr) und FALSE (falsch). Er wird dazu benö­
+tigt, Ausdrücke zu schreiben, die den Zweig einer IF-Anweisung
+bestimmen.
+
+#on("b")#Denotation#off("b")# ELAN verfügt über einen strengen Typenschutz;
+das
+heißt, Objekte verschiedenen Typs dürfen nicht gemischt werden.
+Daher muß schon bei der Schreibweise der Konstanten festgelegt
+sein, welchen Typ die Konstante hat.
+ Bei Texten geschieht dies durch den Einschluß in Anführungs­
+striche. Die Anführungsstriche sorgen gleichzeitig auch für eine
+Abgrenzung der Zeichen des Textes und des umgebenden Programms.
+Sie kennen diese Schreibweise bereits von vielen Stellen in EUDAS.
+ Ebenfalls keine Probleme bereitet der Typ BOOL, da die
+Schreibweise der beiden möglichen Werte TRUE und FALSE eindeutig
+ist.
+ Problematisch wird es bei den Zahlen. Da die ganzen Zahlen in
+den rationalen Zahlen enthalten sind, muß für die ganzen Zahlen
+durch die Schreibweise festgelegt werden, zu welchem der beiden
+Typen sie gehören. Man hat festgelegt, daß REAL-Zahlen immer mit
+Komma geschrieben werden müssen, während Zahlen ohne Komma den
+Typ INT haben (das Komma wird in ELAN bei den REAL-Zahlen in
+internationaler Schreibweise als Punkt notiert).
+ So ist 4 eine INT-Zahl, während 4.0 den Typ REAL besitzt.
+Denken Sie in Zukunft immer daran, welcher Zahltyp jeweils ver­
+langt wird und richten Sie die Schreibweise danach.
+
+#on("b")#Unterschied zu Feldtypen#off("b")# Verwechseln Sie die hier
+vorgestellten
+Datentypen nicht mit den Feldtypen einer EUDAS-Datei. Die Feld­
+typen beziehen sich immer auf den gleichen Datentyp, nämlich
+TEXT. Die Feldtypen bestimmen lediglich die spezielle Behandlung
+des Feldes beim Suchen und Sortieren, während Datentypen tat­
+sächlich Unterschiede in der Speicherung und den anwendbaren
+Operationen bedeuten.
+ Daher können Sie Feldtypen auch nach Bedarf ändern, während
+der Datentyp eines Objekts ein für alle Mal feststeht. Merken Sie
+sich, daß Feldinhalte in EUDAS immer den Typ TEXT haben.
+
+#on("b")#Umwandlungen#off("b")# Obwohl verschiedene Datentypen nicht
+miteinander
+gemischt werden dürfen, können sie mit speziellen Funktionen in­
+einander umgewandelt werden. So ist zum Beispiel die Addition von
+1 und 1.5 verboten, aber der folgende Ausdruck
+
+
+ real (1) + 1.5
+
+
+liefert den Wert 2.5 mit dem Typ REAL. Umgekehrt geht die Um­
+wandlung mit der Funktion 'int', dabei werden jedoch die Nachkom­
+mastellen abgeschnitten. Weitere Hinweise dazu erhalten Sie im
+Abschnitt 14.4.
+ Wichtiger jedoch ist die Umwandlung von Zahlen in TEXT-Ob­
+jekte. Was Sie auf Ihrem Bildschirm oder Ausdruck sehen, sind ja
+immer nur Zeichenfolgen und damit Texte. Zahlen (INT oder REAL)
+in ihrer internen Darstellung können Sie prinzipiell nicht sehen. Sie
+müssen zur Darstellung immer in Texte umgewandelt werden.
+ Auch beim Rechnen mit Werten aus EUDAS-Dateien müssen
+mehrere Umwandlungen stattfinden. Der Feldinhalt, der ja ein TEXT
+ist, muß zunächst in eine Zahl umgewandelt werden. Dann wird mit
+dieser Zahl gerechnet. Wenn das Ergebnis wieder in ein Feld einge­
+tragen oder gedruckt werden soll, muß eine Rückumwandlung in
+einen Text vorgenommen werden.
+ Die zum Umwandeln benötigten Funktionen werden ebenfalls im
+Abschnitt 14.4 besprochen.
+
+#on("b")#Funktionsbeschreibung#off("b")# In den zwei folgenden Abschnitten
+sollen
+die wichtigsten Funktionen und Operatoren anhand von Beispielen
+beschrieben werden. Da jede Funktion nur auf bestimmte Datentypen
+angewendet werden kann, gibt es eine Notation, die genau die Form
+eines Funktionsaufrufs festlegt.
+
+
+ INT PROC min (INT CONST a, b)
+
+
+Die obige Schreibweise hat folgende Bedeutung: Spezifiziert wird die
+Funktion 'min', die als Ergebnis einen INT-Wert liefert (das INT
+ganz links). Die Bezeichnung PROC gibt an, daß es sich um eine
+Funktion handelt. In Klammern ist dann angegeben, welche Parame­
+ter verwendet werden müssen. Die Funktion hat zwei Parameter,
+beide vom Typ INT. Die Bezeichnung CONST gibt an, daß auch Kon­
+stanten verwendet werden dürfen (Normalfall).
+ Zu beachten ist, daß bei jedem Aufruf beide Parameter vorhan­
+den und vom Typ INT sein müssen. Anderenfalls gibt es eine Feh­
+lermeldung.
+ Die gleiche Schreibweise wird auch zur Spezifikation von Ope­
+ratoren verwendet:
+
+
+ INT OP + (INT CONST a, b)
+
+
+Jedoch dürfen Operatoren nicht mit Parametern in Klammern ge­
+schrieben werden, sondern der Operator wird zwischen die Parameter
+geschrieben.
+ Eine Besonderheit von ELAN ist es, daß es verschiedene Opera­
+toren und Funktionen mit gleichem Namen geben kann. Die Funktio­
+nen werden nur unterschieden nach dem Typ ihrer Parameter. So
+gibt es nicht nur den oben genannten Operator '+', sondern auch
+den folgenden:
+
+
+ REAL OP + (REAL CONST a, b)
+
+
+Obwohl im Aussehen gleich, handelt es sich doch um verschiedene
+Operatoren mit möglicherweise völlig verschiedener Wirkung. Dies
+sieht man an diesem Beispiel:
+
+
+ TEXT OP + (TEXT CONST a, b)
+
+
+Dieser Operator führt nun keine Addition aus, sondern eine #on("i")#Verket­
+tung#off("i")# zweier Texte. Je nach Typ der Parameter wird der entspre­
+chende Operator ausgesucht.
+
+
+14.3 TEXT-Funktionen
+
+In diesem Abschnitt wollen wir die wichtigsten Funktionen und
+Operatoren zur Behandlung von Texten beschreiben. Wie Sie noch
+sehen werden, spielt dabei aber auch der Typ INT eine gewisse
+Rolle.
+
+#on("b")#EUDAS-Abfragen#off("b")# Die wichtigste Funktion zur Abfrage von
+Inhal­
+ten der aktuellen Datei sollten Sie bereits kennen:
+
+
+ TEXT PROC f (TEXT CONST feldname)
+
+
+Neu ist eigentlich nur die Schreibweise der Spezifikation. Sie sollten
+aber in der Lage sein, daraus einen konkreten Ausdruck zu kon­
+struieren. Bisher haben wir immer die Schreibweise
+
+
+ f ("Feldname")
+
+
+verwendet. Dies ist jedoch nur ein Beispiel. Die korrekte Angabe
+finden Sie oben.
+ Die Funktion 'f' darf natürlich nicht angewendet werden, wenn
+keine Datei geöffnet ist. In die Verlegenheit kommen Sie aber nur
+beim Ausprobieren, denn alle gefährlichen EUDAS-Funktionen sind
+sonst gesperrt.
+ Falls das angegebene Feld nicht existiert, wird mit einer Feh­
+lermeldung abgebrochen. Beachten Sie, daß dies immer erst bei der
+Ausführung festgestellt werden kann. Bei der Eingabe, zum Beispiel
+eines Druckmusters, kann dies noch nicht überprüft werden.
+ Eine weitere Abfrage, die EUDAS während des Druckens ermög­
+licht, ist die Funktion
+
+
+ TEXT PROC lfd nr
+
+
+Diese hat keine Parameter und liefert die laufende Nummer des
+gedruckten Satzes.
+ Diese beiden Funktionen können als Ausgangsbasis dienen zur
+Manipulation mit weiteren Funktionen.
+
+#on("b")#Verkettung#off("b")# Zur Verkettung von Teiltexten gibt es den oben
+schon
+beschriebenen Operator '+'. Wenn Sie mehr als zwei Texte verketten
+wollen, können Sie den Operator beliebig hintereinander verwenden:
+
+
+ f ("PLZ") + " " + f ("Ort")
+
+
+Wie in diesem Beispiel können Sie sowohl Konstanten als auch Tex­
+te, die von anderen Funktionen geliefert werden, verketten. Beach­
+ten Sie, daß die Texte immer ohne Zwischenraum aneinandergehängt
+werden; daher wird im obigen Beispiel ein Leerzeichen extra ange­
+geben.
+ Wenn Sie eine bestimmte Anzahl von gleichen Zeichen haben
+möchten (zum Beispiel für horizontale Linien oder große Zwischen­
+räume), können Sie dafür folgenden Operator verwenden:
+
+
+ TEXT OP * (INT CONST anzahl, TEXT CONST einzeltext)
+
+
+Hier sehen Sie als Beispiel einen Operator, der mit verschiedenen
+Datentypen arbeitet. Sie müssen die Parameter jedoch immer in der
+angegebenen Reihenfolge benutzen. Das folgende Beispiel ist kor­
+rekt:
+
+
+ 20 * "-"
+
+
+während dies nicht erlaubt ist:
+
+
+ "-" * 20
+
+
+Wieder können Sie diesen Operator mit anderen Funktionen verknü­
+pfen:
+
+
+ "!" + 10 * " " + "!" + 5 * "-" + "!"
+
+
+Da der Multiplikationsoperator Vorrang vor der Addition hat, kom­
+men Sie hier sogar ohne Klammern aus (überlegen Sie sich, wo ein
+Fehler auftreten würde, wenn dies nicht so wäre). Als Ergebnis
+dieses komplexen Ausdrucks ergäbe sich der folgende Text:
+
+
+ "! !-----!"
+
+
+#on("b")#Teiltexte#off("b")# Um auch Teile von Texten bearbeiten zu können,
+werden
+die Zeichen eines Textes von 1 an (mit INT-Zahlen) durchnumeriert.
+Anhand dieser Positionen können Sie Teiltexte extrahieren.
+ Damit Sie die Position des letztes Zeichens (und damit die An­
+zahl der Zeichen) erfragen können, gibt es die Funktion
+
+
+ INT PROC length (TEXT CONST text)
+
+
+Wieviel Zeichen in einem Feld stehen, können Sie also mit
+
+
+ length (f ("Feldname"))
+
+
+erfahren.
+ Einen Teiltext bekommen Sie mit der Funktion 'subtext'. Diese
+gibt es in zwei Ausführungen.
+
+
+ TEXT PROC subtext (TEXT CONST text, INT CONST anfang)
+
+
+liefert den Teiltext von einer bestimmten Position an (einschließ­
+lich) bis zum Textende. Mit
+
+
+ TEXT PROC subtext (TEXT CONST t, INT CONST anf, ende)
+
+
+können Sie auch die Position des letzten Zeichens (einschließlich)
+angeben. Daher würden die beiden folgenden Aufrufe
+
+
+ subtext (f ("Feldname"), 1)
+ subtext (f ("Feldname"), 1, length (f ("Feldname")))
+
+
+den Feldinhalt unverändert liefern. Ein weiteres Beispiel:
+
+
+ subtext ("Ein Text als Beispiel", 5, 8)
+
+
+liefert als Ergebnis "Text".
+ Es gibt noch den Operator 'SUB', der jeweils nur ein Zeichen
+aus dem Text liefert:
+
+
+ TEXT OP SUB (TEXT CONST text, INT CONST stelle)
+
+
+Der Aufruf ist gleichwertig zu einem Aufruf von 'subtext', in dem
+beide Stellen gleich sind.
+ Bei beiden Funktionen wird nicht vorhandener Text einfach
+ignoriert. So liefert
+
+
+ subtext ("Hallo", 4, 8)
+
+
+das Ergebnis "lo" und
+
+
+ "Hallo" SUB 10
+
+
+den leeren Text "".
+
+#on("b")#Verschachtelte Ausdrücke#off("b")# Wie Sie bereits gesehen haben,
+kann
+man Ausdrücke ineinander verschachteln. Dies ist in unserem Fall
+sehr nützlich, wenn Teiltexte bestimmt werden sollen, deren Posi­
+tion nicht konstant ist. Ein Beispiel, in dem 'length' bei der Fest­
+legung der Endposition verwendet wird, haben Sie weiter oben
+bereits gesehen.
+ Als weitere Möglichkeit können Sie mit Positionen, die ja INT-
+Zahlen sind, ganz normal rechnen. Folgender Ausdruck liefert zum
+Beispiel die letzten drei Zeichen eines Feldes:
+
+
+ subtext (f ("Feldname"), length (f ("Feldname")) - 2)
+
+
+Wichtig ist, daß ein Ausdruck, der wieder als Parameter für einen
+anderen Ausdruck verwendet werden soll, den richtigen Typ hat,
+der von dem anderen Ausdruck verlangt wird.
+ In dem obigen Beispiel muß als Position ein INT verwendet
+werden. Diese Position wird vom Operator '-' berechnet. Es gibt
+aber nur einen Subtraktionsoperator, der einen INT liefert, nämlich
+den, der wiederum zwei INTs subtrahiert. Glücklicherweise sind
+sowohl 'length' als auch die 2 vom Typ INT, anderenfalls wäre der
+Ausdruck fehlerhaft. 'length' wiederum benötigt einen TEXT als
+Parameter, der von der Funktion 'f' stammt, die als Parameter eben­
+falls einen TEXT verlangt.
+ Wie Sie sehen, kann es durchaus verwickelt zugehen, wenn ein
+Ausdruck aus den verschiedensten Teilausdrücken unterschiedlichen
+Typs zusammengesetzt ist. Die gleiche Überprüfung wie eben ge­
+schildert sollten Sie bei jedem Ausdruck vornehmen, damit keine
+Fehlermeldung erscheint.
+
+#on("b")#Variable Positionen#off("b")# Zur Berechnung von Positionen gibt es
+noch eine weitere nützliche Prozedur, nämlich
+
+
+ INT PROC pos (TEXT CONST text, teiltext)
+
+
+Sie liefert die Position, an der der angegebene Teiltext zum ersten
+Mal in dem Text vorkommt, oder 0, wenn der Teiltext nicht darin
+vorkommt. So ist
+
+
+ pos ("Hallo", "l") = 3
+
+
+und
+
+
+ pos ("Hallo", "lo") = 4
+
+
+und
+
+
+ pos ("Hallo", "xx") = 0
+
+
+Diese Funktion kann zum Beispiel dazu verwendet werden, ein Feld
+in mehrere Teile aufzuspalten. Sind zum Beispiel Name und Vorname
+in einem Feld durch Leerzeichen getrennt hintereinandergeschrie­
+ben, liefert
+
+
+ subtext (f ("Name"), 1, pos (f ("Name"), " ") - 1)
+
+
+den Vornamen und entsprechend
+
+
+ subtext (f ("Name"), pos (f ("Name"), " ") + 1)
+
+
+den Nachnamen. Soll die Position erst ab einer gewissen Stelle ge­
+sucht werden, gibt es noch die folgende Variation der Funktion:
+
+
+ INT PROC pos (TEXT CONST text, teiltext, INT CONST ab)
+
+
+Bei dieser Funktion wird erst ab der angegebenen Stelle einschließ­
+lich gesucht.
+
+
+14.4 Rechenfunktionen
+
+#on("b")#Umwandlungen#off("b")# Bevor mit dem Inhalt eines Feldes gerechnet
+wer­
+den kann (auch wenn das Feld den Feldtyp ZAHL hat), muß der Wert
+des Feldinhaltes als REAL-Zahl berechnet werden. Dazu gibt es die
+Funktion
+
+
+ REAL PROC wert (TEXT CONST feldname)
+
+
+Die Funktion 'wert' ignoriert alle Sonderzeichen in dem Feld außer
+dem Minuszeichen (als Vorzeichen) und dem eingestellten Dezimal­
+komma. Wenn das Feld 'Summe' beispielsweise "-***20,09 DM" ent­
+hält, ergibt sich
+
+
+ wert ("Summe") = 20.09
+
+
+Zum kaufmännischen Rechnen ist es manchmal erforderlich, den Wert
+auf eine bestimmte Anzahl von Nachkommastellen zu runden. Diese
+Anzahl kann man bei einer Variante von 'wert' als Parameter ange­
+ben:
+
+
+ REAL PROC wert (TEXT CONST feldname,
+ INT CONST kommastellen)
+
+
+Mit den so erhaltenen Werten können Sie dann die weiter unten
+beschriebenen Berechnungen durchführen. Bevor Sie das Ergebnis
+jedoch drucken oder in ein Feld eintragen können, müssen Sie den
+REAL-Wert wieder in einen TEXT verwandeln. Dazu dient die Funk­
+tion
+
+
+ TEXT PROC zahltext (REAL CONST wert,
+ INT CONST kommastellen)
+
+
+Der übergebene Wert wird mit der gewünschten Anzahl von Komma­
+stellen als Text formatiert. Dazu wird der Wert gerundet. Außerdem
+wird statt eines Punktes das eingestellte Dezimalkomma eingesetzt.
+Die Länge des Textes richtet sich nach der Anzahl von benötigten
+Stellen, es werden also keine führenden Nullen oder Leerzeichen
+eingesetzt (dafür kann man den Text beim Drucken ja rechtsbündig
+einsetzen).
+ Wird 0 als Kommastellen angegeben, wird auch kein Dezimal­
+komma erzeugt (Darstellung wie ein INT). Als Abkürzung können Sie
+auch
+
+
+ TEXT PROC zahltext (TEXT CONST feldname,
+ INT CONST kommastellen)
+
+
+als Ersatz für
+
+
+ zahltext (wert ("Feldname"), kommastellen)
+
+
+verwenden. So kann ein Feld einheitlich zum Drucken formatiert
+werden.
+
+#on("b")#Arithmetik#off("b")# Sowohl mit INT- als auch mit REAL-Zahlen
+(jedoch
+nicht gemischt) können Sie die üblichen Rechenoperatoren '+', '-'
+und '*' verwenden. Auch Minimum ('min') und Maximum ('max') sind
+für zwei Parameter dieser Typen definiert.
+ Lediglich die Division wird bei beiden Typen unterschiedlich
+gehandhabt. Für REAL-Zahlen gibt es den Operator '/' für die
+übliche Division. Da die ganzzahlige Division eine andere Bedeutung
+hat, wird dafür der Operator 'DIV' verwendet. Den Rest der ganz­
+zahligen Division liefert 'MOD'.
+ 'abs' liefert den Wert eines REAL oder INT ohne das Vorzeichen.
+Die Umwandlungsfunktionen 'int' und 'real' hatten wir ja bereits
+weiter oben erwähnt.
+ Für REAL-Zahlen gibt es noch weitere mathematische Funktio­
+nen (Exponentialfunktion, Trigonometrie), die Sie am besten im
+EUMEL-Benutzerhandbuch nachschlagen, wenn Bedarf dafür besteht.
+
+
+14.5 Abfragen
+
+#on("b")#IF-Abfragen#off("b")# Wie Sie schon im vorigen Kapitel gesehen
+haben,
+kann man in Druckmustern auch IF-Abfragen als Ausdrücke ver­
+wenden. Die IF-Abfragen können zwar auch ineinander verschach­
+telt werden, sie dürfen jedoch nicht mehr innerhalb eines normalen
+Ausdrucks angewendet werden.
+ Eine IF-Abfrage enthält 3 Teilausdrücke in folgender Form:
+
+
+ IF 'BOOL-Ausdruck' THEN
+ 'Ausdruck1'
+ ELSE
+ 'Ausdruck2'
+ END IF
+
+
+Der erste Ausdruck muß einen Wert vom Typ BOOL liefern, der ent­
+scheidet, welcher der beiden Teilausdrücke ausgewertet wird. Wir
+werden gleich noch sehen, was für Möglichkeiten es da gibt.
+ Die beiden Teilausdrücke dürfen auch wieder IF-Abfragen sein,
+sind sie es jedoch nicht, dürfen in ihnen dann keine IF-Abfragen
+mehr vorkommen. Die IF-Abfragen liegen also immer auf der äußer­
+sten Ebene.
+ Die beiden Teilausdrücke dürfen einen beliebigen Typ haben, er
+muß jedoch für beide gleich sein.
+ Als Ergebnis der IF-Abfrage wird 'Ausdruck1' geliefert, wenn
+der BOOL-Ausdruck wahr ist, sonst 'Ausdruck2'.
+
+#on("b")#Vergleiche#off("b")# Die wesentlichen Operationen, die boolesche
+Ausdrücke
+zur Verwendung in IF-Abfragen bilden, sind die Vergleichsoperato­
+ren:
+
+
+ = <> <= >= < >
+
+
+Sie vergleichen jeweils zwei Elemente vom Typ TEXT, INT oder REAL
+und liefern TRUE (wahr) oder FALSE (falsch). Selbstverständlich
+können auch sie zwei zusammengesetzte Teilausdrücke vergleichen.
+ Eine Anwendung ist zum Beispiel der Test, ob ein Text in einem
+anderen enthalten ist:
+
+
+ IF pos (f ("Betrag"), "DM") > 0 THEN
+ "deutsches Geld"
+ ELSE
+ "ausländisches Geld"
+ END IF
+
+
+Die Funktion 'pos' wird hier dazu benutzt, festzustellen, ob es sich
+um deutsches oder ausländisches Geld handelt.
+ Oft müssen jedoch mehrere Vergleiche miteinander kombiniert
+werden. Zu diesem Zweck gibt es die beiden Operatoren AND (und)
+und OR (oder). Damit AND das Ergebnis TRUE liefert, müssen beide
+Vergleiche wahr sein, bei OR muß mindestens einer der beiden wahl
+sein.
+ Die Reihenfolge aller dieser Operatoren ist so gewählt, daß
+normalerweise keine Klammern benötigt werden. Funktionen haben
+immer Vorrang vor Operatoren, bei den Operatoren kommt die Multi­
+plikation vor der Addition, dann kommen die Vergleiche, danach das
+AND und danach das OR. Alle anderen Operatoren (#on("i")#insbesondere
+SUB#off("i")#) teilen sich den letzten Rang.
+ Wenn Sie also in einem Ausdruck mehrere Vergleiche mit AND
+und OR verknüpfen, und das OR soll stärker binden als das AND,
+müssen Sie dies durch Klammern ausdrücken.
+ Den oben besprochenen Operator SUB sollten Sie immer in
+Klammern setzen, wenn Sie ihn in einem Vergleich benutzen. Da er
+die niedrigste Priorität hat, gäbe es sonst mit Sicherheit Fehler:
+
+
+ IF (f ("Name") SUB 1) = "M" THEN
+ "vielleicht Müller"
+ ELSE
+ "bestimmt nicht"
+ END IF
+
+
+#on("b")#Refinements#off("b")# Bisher hatten wir gesagt, daß IF-Abfragen
+nicht
+innerhalb von anderen Ausdrücken verwendet werden dürfen. Diese
+Einschränkung kann man umgehen, indem man #on("i")#Refinements#off("i")# verwen­
+det.
+ Ein Refinement hat im Druckmuster eine ähnliche Wirkung wie
+eine Abkürzung, lediglich der Name darf nur mit Kleinbuchstaben
+und Ziffern geschrieben sein und kann nicht als Feldmuster ver­
+wendet werden.
+
+
+ &abk :
+ subtext (f ("Name"), namensanfang) .
+ namensanfang :
+ IF pos (f ("Name"), " ") > 0 THEN
+ pos (f ("Name"), " ") + 1
+ ELSE
+ length (f ("Name"))
+ END IF .
+
+
+Innerhalb von Refinements dürfen auch wieder andere Refinements
+verwendet werden.
+ Auch in Kopier- und Änderungsmustern können Sie Refinements
+verwenden. Hier müssen Sie jedoch darauf achten, daß alle Refine­
+ments am Ende gesammelt werden und vor dem ersten Refinement
+ein Punkt stehen muß. Ebenso müssen die Refinements wie im
+Druckmuster durch Punkte voneinander getrennt sein:
+
+
+ "Anrede" K anrede;
+ .
+ anrede :
+ IF f ("m/w") = "w" THEN
+ "Frau"
+ ELSE
+ "Herr"
+ END IF .
+
+
+
diff --git a/doc/eudas/eudas.hdb.15 b/doc/eudas/eudas.hdb.15
new file mode 100644
index 0000000..c0a22cf
--- /dev/null
+++ b/doc/eudas/eudas.hdb.15
@@ -0,0 +1,286 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (165)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+15 Anweisungen in ELAN
+
+
+
+15.1 Variablen und Zuweisungen
+
+Im vorigen Kapitel haben wir Ausdrücke in ELAN kennengelernt. Der
+Wert eines Ausdrucks wird bei jeder Verwendung erneut berechnet.
+Wenn wir den Wert eines Ausdrucks aufbewahren wollen, müssen wir
+ihn schon in eine EUDAS-Datei schreiben.
+ Oft tritt jedoch die Notwendigkeit auf, Werte zu merken, ohne
+sie in einer Datei zu speichern. Beispiel dafür ist ein Zählvorgang im
+Druckmuster. In jedem Wiederholungsteil muß der dazukommende
+Wert zum bisherigen, aufsummierten und aufbewahrten Wert addiert
+werden. Das Zwischenergebnis der Zählung muß also irgendwo ge­
+speichert werden.
+
+#on("b")#Variablen#off("b")# Zu diesem Zweck gibt es Variablen. Sie sind
+ähnlich wie
+Felder in einer Datei. Ihre Existenz ist jedoch unabhängig von einer
+Datei. Außerdem sind sie zu Anfang nicht einfach leer, sondern
+haben einen undefinierten Wert.
+ Variablen müssen im Programm definiert werden. Sie existieren
+dann während der Ausführung dieses Programms und gehen an­
+schließend verloren. Zu Beginn des Programms sind sie, wie schon
+gesagt, undefiniert.
+ Eine Variable muß immer einen Typ haben. Dieser Typ ist für
+die Lebensdauer der Variable unveränderlich. Die Variable kann
+natürlich nur Werte dieses Typs annehmen.
+ Eine Variablendefinition (oder auch -deklaration) besteht aus
+der Angabe eines Typs, dem Schlüsselwort VAR und einem freige­
+wählten Namen. Wie schon bei den Refinements darf ein solcher
+Name nur aus Kleinbuchstaben (keine Umlaute) und eventuell Zif­
+fern bestehen. Dagegen darf der Name Leerzeichen enthalten.
+Beispiel:
+
+
+ INT VAR zaehler;
+ TEXT VAR feldname;
+ REAL VAR mein ergebnis 1;
+
+
+Das Semikolon am Ende beschließt die Definition.
+ Die Lebensdauer einer Variablen hängt davon ab, an welcher
+Stelle sie definiert ist. Eine Variable, die im Druckmuster im Initia­
+lisierungsteil definiert ist, behält ihren Wert für die gesamte Dauer
+des Druckvorgangs. Eine Variable in einem Abschnitt lebt dagegen
+nur für eine Abarbeitung dieses Abschnitts. Bei der nächsten Abar­
+beitung ist sie wieder undefiniert.
+ Das gleiche gilt für Kopier- und Änderungsmuster. Auch hier
+sind Variablen nur für die Dauer der Bearbeitung eines Satzes
+gültig.
+
+#on("b")#Zuweisung#off("b")# Um einer Variablen einen Wert zu geben, führt
+man eine
+#on ("i")#Zuweisung#off("i")# aus. Die Zuweisung wird durch Doppelpunkt und Gleich­
+heitszeichen aneinandergeschrieben gekennzeichnet. Auf der linken
+Seite steht die Variable, auf der rechten Seite eine Ausdruck:
+
+
+ zaehler := 1;
+
+
+Wie oben schließt das Semikolon die Anweisung ab. Nach der Aus­
+führung hat die Variable den Wert 1. Der Wert vorher ist für die
+Zuweisung egal, er kann definiert oder undefiniert sein.
+ Eine Variable kann in einem Ausdruck verwendet werden, indem
+man einfach den Namen hinschreibt. Der Ausdruck
+
+
+ zaehler + 1
+
+
+hat nach der obigen Zuweisung den Wert 2. Eine Variable muß bei
+der Verwendung definiert sein, sonst können beliebige Fehler ent­
+stehen. Es muß also vor der ersten Verwendung ausdrücklich eine
+Zuweisung erfolgt sein.
+ Da Variablen in Ausdrücken verwendet werden können und
+Ausdrücke auf der rechten Seite einer Zuweisung stehen, ist folgen­
+de Konstruktion möglich:
+
+
+ zaehler := zaehler + 1;
+
+
+Diese Zeile bewirkt, daß der Wert der Variable um 1 erhöht wird.
+Zuerst wird bei der Zuweisung der Wert des Ausdrucks auf der rech­
+ten Seite bestimmt. Zu diesem Zeitpunkt habe die Variable bei­
+spielsweise den Wert 1. Der Ausdruck hat dann den Wert 2 (1+1).
+Dieser Wert wird der neue Wert der Variablen.
+ Bei der nächsten Ausführung würde sich der gleiche Vorgang
+wiederholen, so daß die Variable anschließend den Wert 3 hat.
+ Auch bei der Zuweisung gilt natürlich, daß die Variable auf der
+linken Seite den gleichen Datentyp haben muß wie der Ausdruck auf
+der rechten Seite.
+
+#on("b")#Initialisierung#off("b")# Sie können Variablendeklaration und
+Zuweisung
+auch miteinander verknüpfen, so daß die Variable gleich zu Anfang
+einen Wert erhält:
+
+
+ INT VAR zaehler := 0;
+
+
+Dieses Verfahren ist eine gute Vorsichtsmaßregel, damit Sie keine
+undefinierten Variablen verwenden.
+
+#on("b")#Inkrement#off("b")# Da der Fall so häufig auftritt, daß der Wert
+einer Vari­
+ablen um einen bestimmten Wert erhöht wird (bei allen Zählvorgän­
+gen), gibt es auch dafür eine Abkürzung, und zwar die beiden Ope­
+ratoren INCR und DECR.
+
+
+ zaehler INCR 1;
+ mein ergebnis 1 DECR 24.4;
+
+
+Die Operatoren sind für REALs und INTs definiert. INCR erhöht um
+einen Betrag, DECR erniedrigt. Auf der rechten Seite darf wieder ein
+beliebiger Ausdruck stehen.
+ Für TEXTe gibt es eine ähnliche Abkürzung, allerdings nur für
+die Addition (Verkettung). Hier heißt der Operator CAT. Die beiden
+folgenden Zeilen haben die gleiche Bedeutung:
+
+
+ feldname := feldname + ".";
+ feldname CAT ".";
+
+
+
+15.2 Weitere Konstruktionen
+
+#on("b")#IF#off("b")# Die Ihnen bereits bekannte IF-Konstruktion dient nicht
+nur
+dazu, Werte zu liefern, sondern steuert auch die Abarbeitung von
+beliebigen Anweisungen. Diese Anweisungen können Kopier- und
+Änderungsanweisungen sein (s. Kapitel 11), oder die oben beschrie­
+benen Zuweisungen.
+ In einem Teil der IF-Konstruktion können auch mehrere Anwei­
+sungen stehen. Diese müssen dann jedoch unbedingt durch Semiko­
+lon getrennt sein. Mehrere Anweisungen hintereinander haben ein­
+fach die Bedeutung der Ausführung in der notierten Reihenfolge.
+ Als drittes kann auch der ELSE-Teil weggelassen, da nicht in
+jedem Fall ein Ergebnis erwartet wird. Falls die Bedingung nicht
+zutrifft, muß nicht unbedingt etwas ausgeführt werden.
+
+
+ IF zaehler > 0 THEN
+ zaehler DECR 1;
+ mein ergebnis 1 INCR wert ("zaehlfeld")
+ END IF;
+
+
+Auch diese IF-Konstruktion kann wieder geschachtelt werden. Für
+viele Fälle gibt es jedoch einen ELIF-Teil, der die Verschachtelung
+erspart:
+
+
+ IF f ("m/w") = "m" THEN
+ maenner INCR 1
+ ELIF f ("m/w") = "w" THEN
+ frauen INCR 1
+ ELSE
+ zweifelhaft INCR 1
+ END IF;
+
+
+Der ELIF-Teil beinhaltet noch einmal einen Test. Dieser Test wird
+jedoch nur dann durchgeführt, wenn die erste Bedingung falsch war.
+Gibt es noch mehr Wahlmöglichkeiten, können Sie beliebig viele
+ELIF-Teile benutzen.
+ Beachten Sie, daß die letzte Anweisung in einem Teil der IF-
+Konstruktion nicht unbedingt ein folgendes Semikolon haben muß
+(das Semikolon soll nur trennen). Ein Semikolon an dieser Stelle
+kann aber auch nicht schaden.
+
+#on("b")#Werteliefernde Programme#off("b")# Nicht nur Ausdrücke können Werte
+lie­
+fern, sondern auch ganze Anweisungsfolgen. Dies ist eine Erweite­
+rung der werteliefernden IF-Konstruktion. Sie können dies für Ab­
+kürzungen oder Refinements ausnutzen.
+
+
+ endergebnis :
+ gesammelte zeichen CAT ".";
+ gesammelte zeichen .
+
+
+In diesem Beispiel werden in einer Textvariable bestimmte Zeichen
+gesammelt. Zum Schluß soll ein Punkt angefügt werden und dieser
+Text dann als Ergebnis des Refinements geliefert werden.
+ Damit eine Anweisungsfolge einen Wert liefert, muß am Ende
+der Anweisungsfolge ein Ausdruck stehen. Der Wert des Ausdrucks
+nach Abarbeitung der Anweisungen ist dann der Wert der Anwei­
+sungsfolge.
+ Allerdings kann man den gleichen Wert oft verschieden aus­
+drücken. Folgendes Refinement hat die gleiche Wirkung wie oben:
+
+
+ endergebnis :
+ gesammelte zeichen + "." .
+
+
+In manchen Fällen ist eine Formulierung als werteliefernde Anwei­
+sungsfolge jedoch übersichtlicher.
+
+#on("b")#Beispiel#off("b")# Zum Abschluß dieses Kapitels wollen wir als
+Beispiel eine
+statistische Auswertung einer Zahlenreihe als Druckmuster formu­
+lieren.
+ Gegeben sei eine Datei mit folgenden Feldern:
+
+
+ "Meßwert 1"
+ "Meßwert 2"
+
+
+Wir wollen als Ergebnis Mittelwert und Standardabweichung der
+beiden Meßwerte ausdrucken. Dazu dient das Druckmuster auf der
+folgenden Seite.
+ Im Initialisierungsteil des Druckmusters werden die notwendi­
+gen Variablen definiert und initialisiert. Beachten Sie hier, daß in
+einer Definition mehrere Variablen durch Komma getrennt aufgeführt
+werden können, wenn sie den gleichen Typ haben.
+ Im Wiederholungsteil müssen dann jeweils die Zwischensummen
+aktualisiert werden. Da mit der Funktion 'wert' eine relativ auf­
+wendige Umwandlung verbunden ist, wird der Wert des jeweiligen
+Feldes erst einmal in einer Variable zwischengespeichert, da er
+mehrmals benötigt wird. Diese Zwischenspeicherungsvariable muß
+nicht initialisiert werden
+ Im Nachspann werden dann die Ergebnisse gedruckt. Die Formeln
+sind jeweils als Abkürzungen definiert. Die Funktion 'zahltext' sorgt
+dafür, daß die Werte mit drei Nachkommastellen (gerundet) aufge­
+führt werden.
+ Da die Formeln relativ komplex sind, werden sie auf mehrere
+Zeilen verteilt (in ELAN hat das Zeilenende keine Bedeutung).
+
+
+ %% REAL VAR
+ %% messwert,
+ %% summe 1 := 0.0, quadratsumme 1 := 0.0,
+ %% summe 2 := 0.0, quadratsumme 2 := 0.0;
+ %% INT VAR anzahl := 0;
+ % WIEDERHOLUNG
+ %% anzahl INCR 1;
+ %% messwert := wert ("Meßwert 1");
+ %% summe 1 INCR messwert;
+ %% quadratsumme 1 INCR messwert * messwert;
+ %% messwert := wert ("Meßwert 2");
+ %% summe 2 INCR messwert;
+ %% quadratsumme 2 INCR messwert * messwert;
+ % NACHSPANN
+ &anz Meßwerte.
+ Meßwert 1 Meßwert 2
+ Mittelwert &&mw1&&&& &&mw2&&&&
+ Standardabweichung &&st1&&&& &&st2&&&&
+ % ABKUERZUNGEN
+ &mw1 : zahltext (summe 1 / real (anzahl), 3) .
+ &mw2 : zahltext (summe 2 / real (anzahl), 3) .
+ &st1 : zahltext
+ (sqrt ((quadratsumme 1 - summe 1 * summe 1 /
+ real (anzahl)) / real (anzahl - 1)), 3) .
+ &st2 : zahltext
+ (sqrt ((quadratsumme 2 - summe 2 * summe 2 /
+ real (anzahl)) / real (anzahl - 1)), 3) .
+
+
+Mit entsprechenden Formeln können Sie dieses Beispiel für Ihre
+eigenen Statistiken erweitern. Die Beispiele der letzten beiden Ka­
+pitel sollten Ihnen genügend Anregungen dafür gegeben haben.
+
diff --git a/doc/eudas/eudas.hdb.16 b/doc/eudas/eudas.hdb.16
new file mode 100644
index 0000000..5f5d575
--- /dev/null
+++ b/doc/eudas/eudas.hdb.16
@@ -0,0 +1,350 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (171)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+16 Dateiverwaltung mit EUDAS
+
+
+
+16.1 Dateien im System
+
+Zum Bearbeiten von Dateien innerhalb des Systems gibt es das Menü
+'Dateien', das Sie bereits in Kapitel 4 kurz kennengelernt haben.
+An dieser Stelle sollen die übrigen Funktionen dieses Menüs be­
+sprochen werden.
+
+
+ --------------
+ Dateien System
+ U Übersicht
+ --------------
+ Datei
+ L Löschen
+ N Umbenennen
+ K Kopieren
+ P Platzbedarf
+ A Aufräumen
+ --------------
+
+#center#Abb. 16-1 Menü 'Dateien'
+
+
+Beachten Sie, daß alle Funktionen in diesem Menü mit Dateien
+beliebiger Struktur arbeiten können, also sowohl mit Textdateien
+als auch EUDAS-Dateien (und anderen). Dies liegt daran, daß
+Dateien an dieser Stelle einfach als "schwarze Kästen" mit beliebi­
+gem Inhalt betrachtet werden.
+
+#on("b")#Übersicht#off("b")# Die Funktion 'Übersicht' haben Sie bereits
+ausprobiert.
+Sie zeigt in einem Editorfenster an der rechten Seite alle Dateien,
+die sich in Ihrer Task befinden. Falls nicht alle Dateien auf den
+Bildschirm passen, können Sie das Fenster mit HOP OBEN und HOP
+UNTEN rollen. Sie verlassen die Übersicht wie üblich mit ESC 'q'.
+
+#on("b")#Löschen#off("b")# Auch die Funktion 'Löschen' sollten Sie schon
+kennen.
+Mit dieser Funktion verschwindet eine Datei auf Nimmerwieder­
+sehen. Daher werden Sie sicherheitshalber immer gefragt, ob Sie die
+Datei wirklich löschen wollen. Sie können in einer Auswahl auch
+alle zu löschenden Dateien ankreuzen (dann wird trotzdem nochmal
+gefragt).
+ Eine EUDAS-Datei, die gerade geöffnet ist, können Sie nicht
+löschen (sonst würde EUDAS zumindest durcheinanderkommen). Sie
+müssen die Datei zuerst sichern - oder nicht sichern, aber die
+Arbeitskopien löschen.
+
+#on("b")#Umbenennen#off("b")# Mit der Funktion 'Umbenennen' können Sie einer
+Datei
+einen neuen Namen geben. Sie werden zuerst aufgefordert, den alten
+Namen der Datei einzugeben. Alternativ können Sie hier wieder die
+umzubenennenden Dateien auswählen. Danach wird Ihnen (für jede
+ausgewählte Datei) der alte Dateiname zum Überschreiben angebo­
+ten.
+ Sie können diesen Namen mit den üblichen Editierfunktionen
+verändern oder mit HOP RUBOUT löschen und ganz neu eingeben.
+Auf diese Weise sparen Sie sich erheblichen Tippaufwand, wenn Sie
+einen langen Dateinamen an nur einer Stelle verändern wollen.
+
+#on("b")#Kopieren#off("b")# Wie in Abschnitt 11.2 bereits angedeutet, gibt es
+eine
+Funktion zum logischen Kopieren von Dateien. Dies ist eine Funk­
+tion, die sich auf spezielle Eigenschaften des EUMEL-Systems
+stützt. Wenn Sie eine Datei #on("i")#logisch#off("i")# kopieren, wird lediglich ein
+Verweis kopiert. Die Daten werden zunächst nur einmal für beide
+Dateien gespeichert.
+ Natürlich hätte das Ganze wenig Sinn, wenn danach bei Ände­
+rungen immer beide Dateien geändert würden. Bei Änderungen an
+einer Datei werden jedoch nur die geänderten Daten getrennt ange­
+legt, der Rest wird weiterhin gemeinsam benutzt. Die beiden Dateien
+sind also nach außen hin komplett unabhängig, intern werden je­
+doch gemeinsame Daten so weit wie möglich geteilt. Auf diese Weise
+wird sowohl Zeit als auch Speicherplatz gespart.
+ Dieses Verfahren ist besonders dann sinnvoll, wenn Sie sich
+einen bestimmten Stand einer Datei aufbewahren wollen. In diesem
+Fall stellen Sie sich eine logische Kopie her und arbeiten mit dem
+Original weiter. Es werden dann nur die Daten zusätzlich angelegt,
+die Sie seit der Kopie verändert haben.
+ EUDAS benutzt die gleiche Funktion auch für die Arbeitskopie.
+Die Arbeitskopie teilt ebenfalls ihre Daten mit dem Original. Ande­
+renfalls wäre es ja auch zeitlich gar nicht möglich, beim Öffnen eine
+Arbeitskopie anzufertigen.
+ Beim Aufruf der Funktion 'Kopieren' werden Sie zunächst nach
+dem Namen der Datei gefragt (wie üblich mit Auswahlmöglichkeit).
+Dann können Sie einen neuen Namen für die Kopie angeben. Dieser
+neue Name darf jedoch nicht für eine andere Datei vergeben sein.
+Wollen Sie eine andere Datei überkopieren, müssen Sie diese zu­
+nächst löschen.
+ Denken Sie daran, daß die hier beschriebene Funktion sich
+wesentlich vom Kopieren im Menü 'Gesamtdatei' unterscheidet. Dort
+wird nämlich eine tatsächliche Kopie durchgeführt, dafür können Sie
+sich dann auch selektiv bestimmte Daten herausgreifen. Außerdem
+gilt die dortige Funktion nur für EUDAS-Dateien.
+
+#on("b")#Platzbedarf#off("b")# Zu Ihrer Information können Sie sich auch den
+Platz­
+bedarf anzeigen lassen, den eine Datei auf dem Speichermedium hat.
+Wenn Sie den Namen der Datei angegeben haben, wird Ihnen die
+Größe in "Kilobyte" (KB) angegeben. Ein KB entspricht etwa 1000
+Zeichen, also einer halben vollgeschriebenen Bildschirmseite.
+ Bei logisch kopierten Dateien wird für jede Datei der benötigte
+Platz separat angegeben. Sie können die Zahlen also nicht einfach
+addieren, um den Gesamtspeicherbedarf zu ermitteln, da Sie dann
+die gemeinsam benutzten Bereiche doppelt zählen würden.
+
+#on("b")#Aufräumen#off("b")# Wenn eine Datei viel geändert wurde, führen zwei
+Effekte zu einer langsameren Verarbeitung dieser Datei. Zum einen
+wird durch Textleichen der Platzbedarf größer. Dies tritt vor allem
+dann auf, wenn zu einzelnen Sätzen immer etwas hinzugefügt wurde
+(eine Folge der Flexibilität, mit variablen Textlängen operieren zu
+dürfen).
+ Da der Platzbedarf der Datei also wächst, sind mehr Speicher­
+zugriffe notwendig, als es dem Inhalt entspricht. Doch nicht nur der
+Platz, sondern auch die Verteilung der Sätze machen sich unange­
+nehm bemerkbar. Da vergrößerte Sätze intern am Ende der Datei
+gespeichert werden, werden logisch aufeinanderfolgende Sätze phy­
+sikalisch weit verstreut.
+ Der gleiche Effekt ensteht auch durch Umsortieren oder Ein­
+fügen von Sätzen. Um die Datei sequentiell zu bearbeiten, sind also
+ständig wechselnde Speicherzugriffe erforderlich.
+ Die beiden beschriebenen Effekte führen zur Geschwindigkeits­
+verringerung. Dies kann verhindert werden, indem die Datei in eine
+frische Datei umkopiert wird. Diesen Vorgang nennt man #on("i")#Reorgani­
+sieren#off("i")#. Dafür gibt es die Funktion 'Aufräumen'.
+ Während des Umkopierens werden die Satznummern ausgegeben.
+Achten Sie darauf, daß zum Reorganisieren genügend Platz auf dem
+System vorhanden ist, um eine komplette Kopie der zu reorganisie­
+renden Datei aufzunehmen.
+ Zum Reorganisieren muß nämlich tatsächlich eine physikalische
+Kopie angefertigt werden. Eine logische Kopie oder das Schreiben
+auf das Archiv reorganisieren eine Datei dagegen nicht, wohl aber
+die Funktion 'Kopieren' im Menü 'Gesamtdatei'.
+ Da der Inhalt gelesen werden muß, funktioniert die Funktion
+'Aufräumen' im Gegensatz zu den oben gemachten Versprechungen
+nur für Textdateien oder EUDAS-Dateien, nicht aber für andere
+Dateitypen. Die Unterscheidung der Dateitypen wird automatisch
+vorgenommen.
+
+
+16.2 Dateien auf dem Archiv
+
+Mit den Funktionen im Menü 'Archiv' können Sie nicht nur Dateien
+auf dem Archiv behandeln, sondern auch in anderen Tasks oder per
+EUMEL-Netz sogar auf anderen Rechnern.
+
+
+ --------------
+ Dateien Archiv
+ U Übersicht
+ D Üb. Drucken
+ --------------
+ Datei
+ K Kopieren
+ vom Archiv
+ S Schreiben
+ auf Archiv
+ L Löschen
+ auf Archiv
+ --------------
+ Archivdiskette
+ I Init
+ --------------
+ Z Zielarchiv
+ P Paßwort
+ R Reservieren
+ --------------
+
+#center#Abb. 16-2 Menue 'Archiv'
+
+
+#on("b")#Zielarchiv#off("b")# Dazu können Sie die Task einstellen, mit der
+Sie arbei­
+ten möchten. Normaleinstellung ist die Task 'ARCHIVE', die Ihre
+Archivdiskette bedient. Dies wird auch in der untersten Bildschirm­
+zeile angezeigt.
+ Die Task stellen Sie mit der Funktion 'Zielarchiv' ein. Sie
+werden dann nach dem Namen der Task gefragt. Diese Task muß
+eine Managertask sein (also unabhängig vom Bildschirm arbeiten)
+und sie muß bereits existieren.
+ Wenn Sie auf Ihrem Rechner das EUMEL-Netz installiert haben,
+werden Sie auch nach der Nummer der Zielstation gefragt, also der
+Nummer des Rechners, auf dem die gewünschte Task arbeitet. Durch
+Drücken von RETURN wird automatisch Ihre eigene Stationsnummer
+verwendet.
+ Nun gibt es zwei Arten von Managertasks, mit denen EUDAS
+zusammenarbeiten kann, #on("i")#Archivmanager#off("i")# und normale Dateimanager.
+Der Unterschied besteht darin, daß ein Archivmanager für einen
+Benutzer reserviert werden muß, damit man nicht auf Disketten
+eines anderen Benutzers zugreifen kann. Normale Dateimanager
+können und sollen dagegen von mehreren Benutzern in beliebiger
+Reihenfolge angesprochen werden.
+ Manche Rechner haben mehrere Archivmanager für mehrere
+Diskettenlaufwerke. Durch das Einstellen des Zielarchivs können Sie
+auf verschiedenen Laufwerken archivieren. Ein Archivmanager kann
+sich natürlich auch auf einem anderen Rechner befinden. Sie benut­
+zen dann dessen Diskettenlaufwerk.
+ Beim Einstellen des Zielarchivs wird als letztes gefragt, ob die
+Zieltask ein Archivmanager ist oder nicht. Im Normalfall sollten Sie
+die Frage bejahen, wenn Sie 'ARCHIVE' einstellen, und ansonsten
+verneinen (s. die obigen Ausnahmefälle).
+ Das eingestellte Zielarchiv wird jeweils in der untersten Bild­
+schirmzeile angezeigt.
+ Die Reservierung eines Archivmanagers findet beim ersten Zu­
+griff statt. Beim Umschalten des Zielarchivs oder Verlassen des
+Menüs wird die Reservierung automatisch wieder aufgehoben.
+
+#on("b")#Übersicht#off("b")# Mit der Funktion 'Übersicht' können Sie eine
+Auflistung
+aller Dateien abrufen, die sich auf der Archivdiskette (bzw. in dem
+eingestellten Manager) befinden. Wie die Dateiübersicht im System
+können Sie die Darstellung wie im Editor rollen und mit ESC 'q'
+verlassen.
+ Wollen Sie die Übersicht gedruckt haben, rufen Sie die Funktion
+'Übersicht drucken' auf. Die Übersicht wird dann nochmals zusam­
+mengestellt und gleich gedruckt.
+
+#on("b")#Schreiben und Lesen#off("b")# Mit den Funktionen 'Kopieren vom
+Archiv'
+und 'Schreiben auf Archiv' können Sie Dateien zwischen dem Archiv
+und Ihrer Task hin und her transportieren. Es wird jeweils eine
+Kopie angefertigt, das heißt das Original auf der Diskette oder in
+Ihrer Task wird nicht verändert.
+ Wenn die transportierte Datei an ihrem Ziel schon existiert,
+wird gefragt, ob die vorher existierende Datei gelöscht (überschrie­
+ben) werden soll. Überschreiben aus Versehen ist nicht möglich,
+wenn Sie die Frage sorgfältig beantworten.
+ Beim Aufruf der Funktionen können Sie den gewünschten Da­
+teinamen angeben oder in der Auswahl ankreuzen. Die Auswahl ist
+hier besonders sinnvoll, wenn Sie mehrere Dateien (eventuell sogar
+in einer bestimmten Reihenfolge) sichern müssen. Außerdem können
+Sie ja keine Datei transportieren, die nicht existiert; alle Möglich­
+keiten werden Ihnen also durch Ankreuzen angeboten.
+ Beachten Sie, daß beim Überschreiben einer Datei auf einer
+Archivdiskette der Speicherplatz der alten (überschriebenen) Ver­
+sion im allgemeinen nicht wiederverwendet werden kann. In diesem
+Fall kann das Archiv voll werden, obwohl eigentlich genügend Platz
+da wäre.
+
+#on("b")#Löschen#off("b")# Das gleiche Problem tritt auf beim Löschen einer
+Datei
+auf dem Archiv. Mit der Funktion 'Löschen auf Archiv' können Sie
+zwar die Datei auf der Diskette ungültig machen, der Platz wird
+jedoch nur dann wiederverwendet, wenn es die letzte Datei auf der
+Diskette war. Anderenfalls bleiben "Leichen" übrig, die Sie in der
+Archivübersicht als Striche erkennen können.
+ Diese Probleme treten jedoch mit anderen Managern nicht auf,
+da diese Ihren Speicherplatz intelligenter verwalten können.
+
+#on("b")#Initialisieren#off("b")# Als Abhilfe bei einem übergelaufenen Archiv
+müssen
+Sie das ganze Archiv initialisieren und neu beschreiben. Dazu gibt
+es die Funktion 'Init'.
+ Diese Funktion müssen Sie auch dann verwenden, wenn Sie eine
+Archivdiskette zum ersten Mal verwenden. Auf dem Archiv muß
+nämlich als erstes der Archivname eingetragen werden, ehe es be­
+nutzt werden kann. Diesen Namen müssen Sie hier angeben.
+ Alle alten Daten des Archivs werden komplett gelöscht. Daher
+müssen Sie vorher die noch gültigen Daten vom Archiv ins System
+kopiert haben. Wenn das Archiv vorher schon beschrieben war,
+werden Sie anhand des Namens gefragt, ob Sie die richtige Diskette
+zum Überschreiben eingelegt haben.
+ Wenn Sie eine fabrikneue Diskette aus der Verpackung nehmen,
+müssen Sie diese vor der Initialisierung #on("i")#formatieren#off("i")#. Dabei wird die
+Diskette auf ein bestimmtes physikalisches Format eingestellt. Ohne
+diese Operation ist weder Schreiben noch Lesen überhaupt möglich.
+ In der Regel muß eine Diskette nur einmal formatiert werden.
+Sie können sie jedoch jederzeit wieder formatieren (wenn Sie zum
+Beispiel nicht wissen, was Ihnen da für eine alte Diskette in die
+Finger geraten ist).
+ Am Anfang des Initialisierens werden Sie gefragt, ob Sie die
+Diskette formatieren wollen. Manche Rechner unterstützen diese
+Operation innerhalb des EUMEL-Systems nicht. In diesem Fall (und
+natürlich auch sonst normalerweise) müssen Sie die Frage vernei­
+nen. Das Formatieren muß dann vorher irgendwie außerhalb des
+Systems geschehen sein.
+ Das Initialisieren funktioniert natürlich nur bei Archivmana­
+gern. Bei einer anderen Zieltask ist diese Funktion gesperrt.
+
+#on("b")#Paßwort#off("b")# Dateien in einem allgemeinen Dateimanager (nicht
+jedoch
+auf dem Archiv) können Sie mit einem Paßwort gegen unbefugten
+Zugriff sichern. Sinnvolle Voraussetzung dafür ist, daß der Datei­
+manager selbst mit einem anderen Paßwort gegen Betreten gesichert
+ist.
+ Das von Ihnen verwendete Paßwort geben Sie mit der Funktion
+'Paßwort' ein. Damit Ihnen niemand über die Schulter schauen
+kann, werden alle Zeichen auf dem Bildschirm als Punkte darge­
+stellt. Anschließend müssen Sie das Paßwort noch einmal eingeben,
+damit sich kein unbemerkter Schreibfehler eingeschlichen hat.
+ Das Paßwort wird dann bei allen Transport- und Löschopera­
+tionen abgefragt. Eine Datei im Manager erhält Ihr Paßwort zuge­
+wiesen, wenn Sie sie das erste Mal im Manager ablegen. Bei allen
+folgenden Zugriffen muß das gleiche Paßwort eingestellt sein, sonst
+wird der Zugriff verweigert.
+ Natürlich können Sie für verschiedene Dateien verschiedene
+Paßwörter einstellen. Trotz Einstellung eines Paßworts können auch
+andere Benutzer ihre Dateien im gleichen Manager ablegen.
+ Sie können auch für Schreiben (und Löschen) sowie Lesen
+unterschiedliche Paßwörter einstellen. Dazu benutzen Sie einfach
+einen Trennstrich in der Form
+
+
+ Schreibpaßwort/Lesepaßwort
+
+
+Soll eine Datei überhaupt nicht überschrieben oder gelöscht werden
+können, können Sie '-' als Schreibpaßwort verwenden:
+
+
+ -/Lesepaßwort
+
+
+Die Datei kann dann nur beim direkten Betreten der Managertask
+verändert werden.
+ Wollen Sie die Paßworteinstellung wieder aufheben, drücken Sie
+bei der Paßworteingabe nur RETURN, da der leere Text als "kein
+Paßwort" interpretiert wird.
+
+#on("b")#Reservieren#off("b")# Wollen Sie eine Task als Zieltask verwenden,
+die zwar
+kein Archivmanager ist, aber reserviert werden muß (zum Beispiel
+'DOS' zum Ansprechen fremder Diskettenformate) müssen Sie die
+Reservierung mit der Funktion 'Reservieren' selbst vornehmen. Die
+Zieltask darf nicht als Archivmanager gekennzeichnet sein (dann ist
+die Funktion 'Reservieren' nämlich gesperrt).
+ Bei der Reservierung müssen Sie den Reservierungsparameter
+(abhängig von der Art der Zieltask - bei 'DOS' beispielsweise den
+Modus) als Text eingeben. Nach der Reservierung können Sie die
+anderen Funktionen des Archivmenüs verwenden.
+ Die Freigabe der Zieltask erfolgt automatisch beim Verlassen
+des Menüs oder beim Einstellen einer neuen Zieltask.
+
diff --git a/doc/eudas/eudas.hdb.2 b/doc/eudas/eudas.hdb.2
new file mode 100644
index 0000000..f3f14e1
--- /dev/null
+++ b/doc/eudas/eudas.hdb.2
@@ -0,0 +1,178 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (11)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+2 Installation des Programms
+
+
+
+Bevor Sie EUDAS auf Ihrem System benutzen können, müssen Sie das
+Programm zuvor installieren. Wenn EUDAS schon auf Ihrem System
+zur Verfügung steht, können Sie dieses Kapitel getrost überlesen.
+
+
+2.1 Lieferumfang
+
+EUDAS wird auf einer Diskette geliefert, die alle notwendigen Pro­
+gramme enthält. Um den Inhalt der Diskette feststellen zu können,
+starten Sie Ihr System und bringen es dazu, daß 'gib kommando:'
+erscheint. Dann legen Sie die Diskette ein und geben das Kommando
+
+
+ archive ("EUDAS"); list (archive); release (archive)
+
+
+Anschließend erscheint eine Übersicht der auf dem Archiv vorhan­
+denen Programmteile. Folgende Namen sollten sich in dieser Über­
+sicht wiederfinden:
+
+
+ "eudas.1"
+ "eudas.2"
+ "eudas.3"
+ "eudas.4"
+ "eudas.init"
+ "eudas.generator"
+ "Adressen"
+
+
+Eventuell können noch weitere Namen in der Übersicht auftauchen.
+Sollte einer der angegebenen Namen nicht vorhanden sein, rekla­
+mieren Sie die Diskette. Falls Sie statt der Übersicht eine Fehler­
+meldung erhalten, sollten Sie überprüfen, ob die Diskette das rich­
+tige Format besitzt oder Ihr Diskettenlaufwerk Probleme bereitet.
+ Wenn Sie so den Inhalt der Diskette kontrolliert haben, können
+Sie EUDAS installieren. Je nachdem, ob Sie ein Single-User oder ein
+Multi-User System benutzen, sind die Anweisungen unterschiedlich.
+Sie brauchen nur den Sie betreffenden der beiden folgenden Ab­
+schnitte zu lesen. Falls Sie nicht wissen, welches System Sie benut­
+zen: ein Multi-User System wird auf der Systemdiskette und am
+Bildschirm durch die Kennzeichnung 'EUMEL x.y.z/M' identifiziert,
+bei einem Single-User System steht als letztes Zeichen ein 'S'.
+
+
+2.2 Single-User
+
+Dieser Abschnitt betrifft Sie nur, wenn Sie EUDAS auf einem
+Single-User System installieren wollen.
+ Sie können EUDAS immer nur auf einer bestimmten Hinter­
+grunddiskette installieren. Auf dieser Diskette sollten noch min­
+destens 250 KB frei sein (stellen Sie dies durch das Kommando
+'storage info' sicher). EUDAS kann anschließend auch nur auf dieser
+Diskette verwendet werden.
+ Starten Sie nun die gewünschte Diskette. Dann legen Sie die
+Diskette, auf der EUDAS sich befindet, in das Archivlaufwerk. Geben
+Sie dann das Kommando
+
+
+ archive ("EUDAS"); fetch ("eudas.generator", archive); run
+
+
+Sie haben damit das Generatorprogramm gestartet, das die Installa­
+tion automatisch durchführt. Lassen Sie während dieses Vorganges
+das EUDAS-Archiv eingelegt. Sie werden benachrichtigt, wenn die
+Generierung abgeschlossen ist.
+ Wenn Sie EUDAS auf allen Ihren Hintergrunddisketten haben
+möchten, können Sie das so erzeugte System als Muttersystem
+sichern. Mit dem Kommando 'save system' können Sie den Hinter­
+grund komprimiert auf eine leere Archivdiskette schreiben. Mit
+dieser Sicherung können Sie dann jederzeit neue Systemdisketten
+wie von Ihrem Originalsystem herstellen.
+
+#on("b")#Einschränkungen#off("b")# Aus Platzgründen hat die
+Single-User-Version von EUDAS folgende Einschränkungen:
+#free (0.2)#
+ Sie können die Funktionen Ketten und Koppeln nicht verwenden.
+#free (0.2)#
+ Sie können im Druckmuster keine ELAN-Anweisungen und -Aus­
+ drücke verwenden.
+#free (0.2)#
+ Es stehen nur einige allgemeine Hilfstexte zur Verfügung.
+#free (0.2)#
+ Funktionen, die mehrere Tasks vorausssetzen, sind ebenfalls
+ gesperrt.
+#free (0.2)#
+Die betreffenden Funktionen sind zwar gegebenenfalls im Menü
+enthalten, lassen sich aber nicht aufrufen.
+
+
+2.3 Multi-User
+
+Dieser Abschnitt betrifft Sie nur, wenn Sie EUDAS auf einem Mul­
+ti-User System installieren wollen.
+ EUDAS muß in einer bestimmten Task installiert werden. Alle
+neuen Söhne und Enkel dieser Task können dann EUDAS aufrufen.
+Im Normalfall wird diese Task 'PUBLIC' sein.
+ Zum Installieren müssen Sie in diese Task gehen (in diesem
+Beispiel 'PUBLIC'). Dazu rufen Sie durch Tippen der SV-Taste den
+Supervisor und geben das Kommando
+
+
+ continue ("PUBLIC")
+
+
+Stelle Sie mit Hilfe des 'storage info'-Kommandos fest, ob auf Ihrem
+Hintergrund noch mindestens 300 KB frei sind (dieser Platz wird zur
+Generierung benötigt). Dann legen Sie die EUDAS-Archivdiskette ein
+und geben folgendes Kommando
+
+
+ archive ("EUDAS"); fetch ("eudas.generator", archive); run
+
+
+Falls die Task 'PUBLIC' Söhne besitzt, werden Sie gefragt, ob Sie
+diese löschen wollen. EUDAS steht nämlich nur in den Söhnen zur
+Verfügung, die #on("i")#nach#off("i")# der Installation eingerichtet wurden. Antworten
+Sie auf die Frage durch einfaches Tippen von 'j' oder 'n'. wenn Sie
+die Frage verneinen, können Sie die Generierung zu diesem Zeit­
+punkt auch noch abbrechen und zunächst die Söhne aufräumen.
+ Es erscheint die Frage
+
+
+ Ausführliche Hilfstexte installieren ? (j/n)
+
+
+Verneinen Sie die Frage, wenn in Ihrem System der Speicherplatz
+kritisch ist (zum Beispiel wenn Sie keine Festplatte haben). Es
+werden dann nur die wichtigsten allgemeinen Hilfstexte installiert
+(Ersparnis etwa 40 KByte).
+ Anschließend wird die automatische Generierung gestartet.
+Lassen Sie die EUDAS-Archivdiskette eingelegt. Die Generierung ist
+beendet, wenn das EUMEL-Bild erscheint. Die Task, in der die
+Generierung stattfindet, wird automatisch zu einer Managertask, das
+heißt, daß man von ihr Söhne einrichten kann.
+ Sie können das so erweiterte System auch mit 'save system' auf
+einer oder mehreren Archivdiskette sichern. Lesen Sie dazu die
+Hinweise zur Systemsicherung im EUMEL-Systemhandbuch.
+
+#on("b")#Korrekturversionen#off("b")# Falls Sie später einmal eine
+Korrekturversion
+von EUDAS bekommen, sollten Sie vor der neuen Generierung die
+Task, in der EUDAS vorher generiert war, löschen (Vorsicht: alle
+Söhne werden mitgelöscht) und wieder neu einrichten. Anderenfalls
+bleibt die alte Version als unzugängliche "Leiche" auf Ihrem System
+liegen.
+ In diesem Fall und auch, wenn Sie mehrere Programme in der
+gleichen Task installieren, kann es zum Überlauf der internen Über­
+setzertabellen kommen. Für größere Installationen oder wenn Sie
+viele verschiedene Programme benutzen, empfiehlt es sich, zur
+Generierung eine eigene Task 'EUDAS' als Sohn von 'PUBLIC' zu
+verwenden. Sie dürfen dann aber in 'PUBLIC' nicht zu viel insertie­
+ren, da 'EUDAS' ja alle Programme von 'PUBLIC' erbt. Denken Sie
+daran, daß Sie EUDAS nur in Tasks benutzen können, die unter der
+Task 'EUDAS' eingerichtet wurden.
+
+
+
+
+
+
diff --git a/doc/eudas/eudas.hdb.3 b/doc/eudas/eudas.hdb.3
new file mode 100644
index 0000000..e89ff4f
--- /dev/null
+++ b/doc/eudas/eudas.hdb.3
@@ -0,0 +1,515 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (15)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+3 Ein Beispiel zum Ausprobieren
+
+
+
+Bevor Sie in die tieferen Geheimnisse von EUDAS einsteigen, sollen
+Sie in diesem Kapitel erst einige Erfahrungen mit der Bedienung
+sammeln. Dadurch erhalten Sie Sicherheit im Umgang mit dem Pro­
+gramm und haben bereits einen Eindruck dessen, was Sie anschlie­
+ßend erwartet.
+ Das Durchlesen dieses Kapitels ist nur dann sinnvoll, wenn Sie
+die Anweisungen selbst am Rechner ausprobieren. Anderenfalls
+beginnen Sie besser mit dem nächsten Kapitel.
+ Im folgenden sind die Eingaben, die Sie machen sollen, kursiv
+gedruckt, während Ausgaben des Rechners normal erscheinen.
+Außerdem erscheinen spezielle Tasten in spitzen Klammern:
+
+
+ <RET>
+
+
+Bitte tippen Sie nicht die eckigen Klammern oder Großbuchstaben,
+sondern die entsprechende Taste. Oft haben die Sondertasten auch
+etwas andere Bezeichnungen (die obige zum Beispiel 'CR', 'Carriage
+Return', 'RETURN', 'ENTER'). Bitte fragen Sie bei Unklarheiten Ihren
+Systemlieferanten oder -betreuer.
+
+
+3.1 Start
+
+Die Anweisungen zum Starten von EUDAS sind unterschiedlich, je
+nachdem wie Ihr System eingerichtet ist. Bitte beachten Sie daher
+die verschiedenen Fälle.
+
+1. Falls Sie EUDAS nicht selbst installiert haben, fragen Sie am
+ besten Ihren Systembetreuer. Ansonsten verhalten Sie sich wie
+ unter 2.
+
+2. Falls Sie EUDAS nach den Anweisungen von Kapitel 2 in einem
+ Multi-User-System eingerichtet haben, müssen Sie zunächst eine
+ Arbeitstask (Arbeitsbereich) einrichten. Dazu tippen Sie die
+ SV-Taste (diese trägt häufig die unterschiedlichsten Bezeich­
+ nungen). Es erscheint
+
+
+ EUMEL x.y.z/M
+
+ gib supervisor kommando :
+
+
+ Sie tippen nun folgendes Kommando:
+
+
+ #on("i")#begin ("arbeit")#off("i")#<RET>
+
+
+ Vergessen Sie nicht die RETURN-Taste am Schluß. Machen Sie
+ jetzt weiter bei Punkt 4.
+
+3. Falls Sie ein Single-User-System besitzen, starten Sie die
+ Systemdiskette und geben das Datum ein. Dann machen Sie wei­
+ ter mit Punkt 4.
+
+4. Danach erscheint:
+
+
+ gib kommando :
+
+
+ und Sie tippen:
+
+
+ #on("i")#eudas#off("i")#<RET>
+
+
+ Als Ergebnis wird das EUDAS-Eingangsmenü angezeigt (s. Abb.
+ 3-1 auf der nächsten Seite).
+
+
+3.2 Daten eintragen
+
+Als Beispiel sollen Sie eine kleine Adressenkartei einrichten. Der
+Fachausdruck für eine elektronische Kartei ist #on("i")#Datei#off("i")#.
+
+___________________________________________________________________________________________
+
+ EUDAS: Öffnen Einzelsatz Gesamtdatei Drucken Dateien Archiv
+ --------------:
+ EUDAS-Datei :
+ O Öffnen :
+ - Ketten :
+ - Koppeln : EEEEE U U DDDD A SSSS
+ --------------: E U U D D A A S
+ Arbeitskopie : EEE U U D D AAAAA SSS
+ - Sichern : E U U D D A A S
+ --------------: EEEEE UUU DDDD A A SSSS
+ Aktuelle Datei:
+ - Notizen : Version 4.3
+ - Feldstrukt. : Stand: 14.07.87
+ - Prüfbeding. :
+ --------------: (C) Copyright
+ Mehrbenutzer : Thomas Berlage
+ M Manager : Software-Systeme
+ --------------:
+ :
+ :
+ :
+ :
+ :
+ Akt.Datei: Manager: Datum: 22.07.87
+___________________________________________________________________________________________
+
+
+#center#Abb. 3-1 EUDAS-Eingangsmenü
+
+
+ Zunächst müssen Sie eine neue Datei einrichten. Dazu tippen
+Sie die Leertaste. Dadurch wird die invers dargestellte Funktion
+'Öffnen' ausgeführt. Folgen Sie bitte dem nachstehenden Dialog auf
+der rechten Bildschirmseite:
+
+
+ Name der Datei: #on ("i")#Mitglieder#off("i")#<RET>
+ "Mitglieder" neu einrichten ? (j/n) #on("i")#j#off("i")#
+
+
+Unter der Überschrift 'Neue Feldnamen' tippen Sie jetzt folgendes
+(bitte keine Leerstellen vor den Namen tippen):
+
+
+ #on("i")#Name#off("i")#<RET>
+ #on("i")#Vorname#off("i")#<RET>
+ #on("i")#PLZ#off("i")#<RET>
+ #on("i")#Ort#off("i")#<RET>
+ #on("i")#Strasse#off("i")#<RET>
+ #on("i")#m/w#off("i")#<ESC>#on("i")#q#off("i")#
+
+
+Zum Schluß beantworten Sie noch eine Frage:
+
+
+ Feldnamen oder Feldtypen aendern ? (j/n) #on("i")#n#off("i")#
+
+
+Damit ist die neue Datei eingerichtet.
+ Nun tippen Sie die Pfeiltaste <RECHTS>. Es erscheint ein neues
+Menübild (s. Abb. 3-2).
+
+___________________________________________________________________________________________
+
+ EUDAS: Öffnen Einzelsatz Gesamtdatei Drucken Dateien Archiv
+ --------------: Satz 1 .........ENDE... Mitglieder .......... Feld 1
+ Positionieren : Name
+ W Weiter : Vorname
+ Z Zurück : PLZ
+ N Satz.Nr : Ort
+ --------------: Strasse
+ Suchbedingung : m/w
+ S Setzen : ...........................................................
+ L Löschen :
+ M Markierung :
+ --------------:
+ Datensatz :
+ E Einfügen :
+ A Ändern :
+ T Tragen :
+ H Holen :
+ --------------:
+ F Feldauswahl :
+ --------------:
+ :
+ :
+ :
+
+___________________________________________________________________________________________
+
+
+#center#Abb. 3-2 Menü 'Einzelsatz'
+
+
+Nun tippen Sie so lange die Pfeiltaste <UNTEN>, bis die Funktion
+'Einfügen' invers markiert ist. Dann tippen Sie die Leertaste zum Aus­
+führen dieser Funktion. Die Schreibmarke springt nach rechts ins
+Datenfeld zum Eingeben. Geben Sie jetzt den ersten Datensatz wie
+folgt ein:
+
+
+ #on("i")#Wegner#off("i")#<RET>
+ #on("i")#Herbert#off("i")#<RET>
+ #on("i")#5000#off("i")#<RET>
+ #on("i")#Köln#off("i")#<RET>
+ #on("i")#Krämergasse 12#off("i")#<RET>
+ #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")#
+
+
+Anschließend wird das Datenfeld wieder freigemacht, so daß Sie
+gleich den zweiten Datensatz eingeben können. Dies tun Sie auf die
+gleiche Weise, nur mit anderen Daten:
+
+
+ #on("i")#Sandmann#off("i")#<RET>
+ #on("i")#Helga#off("i")#<RET>
+ #on("i")#5300#off("i")#<RET>
+ #on("i")#Bonn 1#off("i")#<RET>
+ #on("i")#Willicher Weg 109#off("i")#<RET>
+ #on("i")#w#off("i")#<ESC>#on("i")#w#off("i")#
+
+
+Ebenso verfahren Sie dann weiter mit den folgenden Daten. Falls Sie
+sich vertippt haben, können Sie mit den vier Pfeiltasten an die
+entsprechende Stelle gehen und die falschen Buchstaben über­
+schreiben.
+
+
+ #on("i")#Katani#off("i")#<RET>
+ #on("i")#Albert#off("i")#<RET>
+ #on("i")#5210#off("i")#<RET>
+ #on("i")#Troisdorf#off("i")#<RET>
+ #on("i")#Lindenstr. 3#off("i")#<RET>
+ #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")#
+
+ #on("i")#Ulmen#off("i")#<RET>
+ #on("i")#Peter#off("i")#<RET>
+ #on("i")#5#off("i")#<RET>
+ #on("i")#Köln 60#off("i")#<RET>
+ #on("i")#Mozartstraße 17#off("i")#<RET>
+ #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")#
+
+ #on("i")#Regmann#off("i")#<RET>
+ #on("i")#Karin#off("i")#<RET>
+ #on("i")#5000#off("i")#<RET>
+ #on("i")#Köln 90#off("i")#<RET>
+ #on("i")#Grengelweg 44#off("i")#<RET>
+ #on("i")#w#off("i")#<ESC>#on("i")#w#off("i")#
+
+ #on("i")#Arken#off("i")#<RET>
+ #on("i")#Hubert#off("i")#<RET>
+ #on("i")#5200#off("i")#<RET>
+ #on("i")#Siegburg#off("i")#<RET>
+ #on("i")#Talweg 12#off("i")#<RET>
+ #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")#
+
+ #on("i")#Simmern#off("i")#<RET>
+ #on("i")#Anna-Maria#off("i")#<RET>
+ #on("i")#5#off("i")#<RET>
+ #on("i")#Köln 3#off("i")#<RET>
+ #on("i")#Platanenweg 67#off("i")#<RET>
+ #on("i")#w#off("i")#<ESC>#on("i")#w#off("i")#
+
+ #on("i")#Kaufmann-Drescher#off("i")#<RET>
+ #on("i")#Angelika#off("i")#<RET>
+ #on("i")#53#off("i")#<RET>
+ #on("i")#Bonn#off("i")#<RET>
+ #on("i")#Hauptstr. 123#off("i")#<RET>
+ #on("i")#w#off("i")#<ESC>#on("i")#w#off("i")#
+
+ #on("i")#Fuhrmann#off("i")#<RET>
+ #on("i")#Harald#off("i")#<RET>
+ #on("i")#5000#off("i")#<RET>
+ #on("i")#Köln 1#off("i")#<RET>
+ #on("i")#Glockengasse 44#off("i")#<RET>
+ #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")#
+
+
+Bei der letzten Adresse ist die letzte Taste unterschiedlich, da Sie
+keine weiteren Daten mehr eintragen wollen. Bitte beachten Sie dies.
+
+
+ #on("i")#Seefeld#off("i")#<RET>
+ #on("i")#Friedrich#off("i")#<RET>
+ #on("i")#5000#off("i")#<RET>
+ #on("i")#Köln-Ehrenfeld#off("i")#<RET>
+ #on("i")#Kabelgasse#off("i")#<RET>
+ #on("i")#m#off("i")#<ESC>#on("i")#q#off("i")#
+
+
+Damit die neu eingetragenen Daten permanent gespeichert sind,
+müssen Sie sie #on("i")#sichern#off("i")#. Dazu kehren Sie durch Tippen von <LINKS>
+in das erste Menü zurück. Dort tippen Sie wieder so lange <UNTEN>,
+bis die Funktion 'Sichern' markiert ist. Tippen Sie dann die Leer­
+taste zum Ausführen und folgen dem nachstehenden Dialog:
+
+
+ Arbeitskopie "Mitglieder" veraendert! Sichern ? (j/n) #on("i")#j#off("i")#
+ Alte Version ueberschreiben ? (j/n) #on("i")#j#off("i")#
+ Interne Arbeitskopien loeschen ? (j/n) #on("i")#j#off("i")#
+
+
+Damit steht Ihnen nun eine Mitgliederdatei mit 10 Einträgen zur
+weiteren Verfügung.
+
+
+3.3 Daten abfragen
+
+Um Daten abzufragen, müssen Sie die Datei zunächst wieder öffnen.
+Dazu bewegen Sie die inverse Markierung durch mehrmaliges Tippen
+von <OBEN> nach oben bis zur Funktion 'Öffnen' und tippen Sie die
+Leertaste. Danach ergibt sich folgender Dialog:
+
+
+ Name der Datei: #on("i")#Mitglieder#off("i")#<RET>
+ Wollen Sie etwas aendern (eine Arbeitskopie einrichten)
+ ? (j/n) #on("i")#n#off("i")#
+
+
+Danach gehen Sie durch Tippen von <RECHTS> in das zweite Menü.
+Dort erscheint jetzt die zehnte Adresse.
+ Zunächst sollen Sie an den Anfang gehen. Dazu schieben Sie
+die Markierung auf die Funktion 'Satz.Nr' mit Hilfe der Pfeiltasten
+und tippen dann die Leertaste. Nach folgender Angabe
+
+
+ Neue Satznummer: #on("i")#1#off("i")#<RET>
+
+
+erscheint die erste Adresse. Nun sollen Sie nach der Adresse von
+Harald Fuhrmann suchen. Dazu bringen Sie die Markierung auf die
+Funktion 'Suchbedingung Setzen' und tippen die Leertaste. Die
+Schreibmarke springt wieder in das Datenfeld. Dort geben Sie ein:
+
+
+ #on("i")#Fuhrmann#off("i")#<ESC>#on("i")#q#off("i")#
+
+
+In der markierten Überschrift erscheint 'SUCH-' zum Zeichen, daß
+eine Suchbedingung eingestellt ist. Dann schieben Sie die Markie­
+rung auf die Funktion 'Weiter' und tippen die Leertaste. Kurz da­
+nach erscheint die Adresse von Herrn Fuhrmann mit dem Hinweis
+'SUCH+' (gefunden).
+ Führen Sie dann die Funktion 'Zurück' aus (Verschieben der
+Markierung und Tippen der Leertaste). Es erscheint wieder die erste
+Adresse mit dem Hinweis 'SUCH-' (kein weiterer Fuhrmann gefun­
+den). Führen Sie dann die Funktion `Suchbedingung Löschen' aus.
+Der 'SUCH'-Hinweis verschwindet wieder.
+ Als nächstes sollen Sie die Daten nach allen weiblichen Mit­
+gliedern durchsuchen. Dazu führen Sie wieder die Funktion 'Such­
+bedingung Setzen' aus. Diesmal tippen Sie im Datenfeld fünfmal die
+Pfeiltaste <UNTEN>, bis die Schreibmarke neben der Bezeichnung
+'m/w' steht. Dort tippen Sie
+
+
+ #on("i")#w#off("i")#<ESC>#on("i")#q#off("i")#
+
+
+Wenn Sie jetzt die Funktion 'Weiter' ausführen, erscheint das erste
+weibliche Mitglied, Frau Sandmann. Da aber noch weitere Frauen in
+der Datei vorkommen, führen Sie erneut 'Weiter' aus und es erschei­
+nen die nächsten weiblichen Mitglieder.
+ Wenn kein gesuchtes Mitglied mehr gefunden wurde, erscheint
+ein leeres Datenfeld mit den Bezeichnungen 'ENDE' und 'SUCH-' in
+der Überschrift. Durch mehrmaliges Ausführen von 'Zurück' können
+Sie die weiblichen Mitglieder wieder in der umgekehrten Reihenfolge
+ansehen, bis Sie an den Anfang der Datei kommen.
+ Bitte lassen Sie die Suchbedingung eingestellt, denn im näch­
+sten Abschnitt wollen wir alle weiblichen Mitglieder ausdrucken.
+
+
+3.4 Drucken
+
+Zuerst begeben Sie sich durch zweimaliges Tippen von <RECHTS> in
+das Druckmenü, das in Abb. 3-3 gezeigt wird.
+
+___________________________________________________________________________________________
+
+ EUDAS: Öffnen Einzelsatz Gesamtdatei Drucken Dateien Archiv
+ --------------:
+ Satzauswahl :
+ D Drucken :
+ --------------:
+ Druckausgabe :
+ R Richtung :
+ --------------:
+ Textdatei :
+ E Editieren :
+ A Ausdrucken :
+ N Nachbearb. :
+ --------------:
+ :
+ :
+ :
+ :
+ :
+ :
+ :
+ :
+ :
+ :
+ Akt.Datei: "Mitglieder" Datum: 22.07.87
+___________________________________________________________________________________________
+
+
+#center#Abb. 3-3 Menü 'Drucken'
+
+
+Zunächst müssen Sie ein Druckmuster erstellen, das angibt, wie der
+Druck aussehen soll. Dazu führen Sie die Funktion 'Textdatei Edi­
+tieren' aus. Es erscheint die Aufforderung:
+
+
+ Name der Datei: #on("i")#liste#off("i")#<RET>
+
+
+Dann wird der Bildschirm gelöscht und Sie können folgendes einge­
+ben:
+
+
+ #on("i")#% VORSPANN#off ("i")#<RET>
+ #on("i")#Liste der weiblichen Mitglieder#off ("i")#<RET>
+ #on("i")#-------------------------------#off ("i")#<RET>
+ #on("i")#% WIEDERHOLUNG#off ("i")#<RET>
+ #on("i")#&Vorname %Name#off ("i")#<ESC>#on("i")#q#off("i")#
+
+
+Ebenso wie beim Eingeben von Daten können Sie hier mit den Pfeil­
+tasten auf fehlerhafte Stellen zurückgehen und dort korrigieren.
+ Nun sollten Sie sich vergewissern, ob Ihr Drucker eingeschaltet
+und bereit (Ready) ist. Falls Sie keinen Drucker haben, folgen Sie
+bitte den Anweisungen unter 2. Anderenfalls gehen Sie wie folgt
+vor.
+
+1. Rufen Sie die Funktion 'Richtung' auf und beantworten Sie
+ folgende Frage:
+
+
+ Ausgabe automatisch zum Drucker ? (j/n) #on("i")#j#off("i")#
+
+
+ Dann rufen Sie die Funktion 'Drucken' auf und geben den Namen
+ des Druckmusters an:
+
+
+ Name des Druckmusters: #on("i")#liste#off ("i")#<RET>
+
+
+ Als Ergebnis sollte folgende Liste auf Ihrem Drucker erscheinen:
+
+
+ Liste der weiblichen Mitglieder
+ -------------------------------
+ Helga Sandmann
+ Karin Regmann
+ Anna-Maria Simmern
+ Angelika Kaufmann-Drescher
+
+
+2. Rufen Sie die Funktion 'Richtung' auf und beantworten Sie
+ folgende Fragen:
+
+
+ Ausgabe automatisch zum Drucker ? (j/n) #on("i")#n#off("i")#
+ Ausgabe in bestimmte Datei ? (j/n) #on("i")#n#off("i")#
+
+
+ Dann rufen Sie die Funktion 'Drucken' auf und geben den Namen
+ des Druckmusters an:
+
+
+ Name des Druckmusters: #on("i")#liste#off ("i")#<RET>
+
+
+ Nach dem Ende des Druckprozesses (wenn das Sternchen vor
+ 'Drucken' wieder durch ein 'D' ersetzt worden ist), rufen Sie
+ wieder die Funktion 'Textdatei Editieren' auf und geben folgen­
+ den Namen an:
+
+
+ Name der Datei: #on("i")#liste.a$1#off("i")#<RET>
+
+
+ Es erscheint die gleiche Ausgabe wie unter 1 beschrieben auf
+ dem Bildschirm. Wenn Sie die Ausgabe genug gesehen haben,
+ kehren Sie durch
+
+
+ <ESC>#on("i")#q#off("i")#
+
+
+ wieder in das Menü zurück.
+
+
+3.5 Ergebnis
+
+Da Sie sich wieder im Menü befinden, könne Sie EUDAS durch
+
+ <ESC>#on("i")#q#off("i")#
+
+wieder verlassen. Danach können Sie Ihre Sitzung beenden, etwas
+Anderes tun oder EUDAS erneut aufrufen.
+
+ Sie haben nun selbst ausprobiert, wie Sie unter EUDAS Daten
+eingeben können, wie Sie diese Daten abrufen und in ihnen suchen
+können. Sie haben die Daten auch schon ausgedruckt.
+ Damit Sie besser verstehen, was Sie soeben gemacht haben,
+werden Sie in den folgenden vier Kapiteln die Grundfunktionen von
+EUDAS mit den dazugehörigen Erläuterungen kennenlernen.
+ Danach können Sie dann selber Ihre eigene Anwendung entwer­
+fen und EUDAS zu Ihrer Arbeitserleichterung einsetzen.
+
+
+
+
+
+
diff --git a/doc/eudas/eudas.hdb.5 b/doc/eudas/eudas.hdb.5
new file mode 100644
index 0000000..b5927ea
--- /dev/null
+++ b/doc/eudas/eudas.hdb.5
@@ -0,0 +1,386 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (43)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+5 Gespeicherte Daten abfragen
+
+
+
+5.1 Öffnen
+
+Als letzte Vorbereitung, bevor Sie mit der Adreßdatei spielen kön­
+nen, müssen Sie die Datei wie einen Karteikasten #on("i")#öffnen#off("i")#. Nach dem
+Öffnen beziehen sich alle weiteren Funktionen auf die gerade ge­
+öffnete Datei. Aus diesem Grund darf auch immer nur eine einzige
+Datei geöffnet sein - als hätte auf Ihrem Schreibtisch nur ein Kar­
+teikasten Platz.
+ Dazu wählen Sie jetzt wieder das erste Menü an. Dort finden
+Sie die Funktion
+#free (0.2)#
+
+ O Öffnen
+
+#free (0.2)#
+Wählen Sie diese Funktion aus. Dann drücken Sie die Leertaste, um
+die Funktion auszuführen. Als erstes erscheint im unteren Teil des
+Bildschirms eine Frage:
+
+___________________________________________________________________________________________
+
+ Wollen Sie etwas aendern (eine Arbeitskopie anlegen) (j/n) ?
+___________________________________________________________________________________________
+
+
+Der Cursor bleibt hinter der Frage stehen. Sie kennen diesen Frage­
+zustand ja schon.
+ In diesem Fall wollen Sie an der Spieldatei nichts verändern,
+Sie beantworten die Frage also mit einem 'n'. Als nächstes werden
+Sie nach dem Namen gefragt (Beachten Sie auch hier wieder die
+Statuszeile).
+ Tippen Sie nun 'Adressen' und beenden Sie die Eingabe mit
+RETURN. EUDAS öffnet die Datei und kehrt zum Menü zurück. Alter­
+nativ können Sie die Datei auch in einer Auswahl ankreuzen, wenn
+Sie ESC 'z' tippen.
+
+#on("b")#Fußzeile#off("b")# Nach der Ausführung dieser Funktion sollten Sie
+Ihre
+Aufmerksamkeit auf die letzte Zeile des Bildschirms richten. Hier
+finden Sie jetzt folgendes vor:
+
+___________________________________________________________________________________________
+
+ Akt.Datei: "Adressen" Manager: Datum: 22.07.87
+___________________________________________________________________________________________
+
+
+Neben dem Datum und dem eingestellten Manager (dies kommt viel
+später) sehen Sie hier, welche Datei Sie geöffnet haben und nun
+bearbeiten können. Diese Fußzeile finden Sie auch in den ande­
+ren Menüs. Lediglich die mittlere Angabe ändert sich bei den ande­
+ren Menüs (eine Erläuterung dazu finden Sie in späteren Kapiteln).
+
+#on("b")#Anzeige#off("b")# Zum Anzeigen der Daten in der Adreßdatei müssen Sie
+das
+zweite Menü 'Einzelsatz' anwählen (durch Drücken der Pfeiltaste
+RECHTS). Am linken Rand erscheint das neue Menü mit den Anzei­
+gefunktionen. Der Rest des Bildschirms enthält das Formular für die
+Adreßdatei mit den Daten des ersten Satzes. Abbildung 5-1 zeigt
+das Bild, das sich dann ergibt.
+
+___________________________________________________________________________________________
+
+ EUDAS: Öffnen Einzelsatz Gesamtdatei Drucken Dateien Archiv
+ --------------: Satz 1 ................... Adressen ....... Zeile 1
+ Positionieren : Name Wegner
+ W Weiter : Vorname Herbert
+ Z Zurück : PLZ 5000
+ N Satz.Nr : Ort Köln
+ --------------: Strasse Krämergasse 12
+ Suchbedingung : m/w m
+ S Setzen : ...........................................................
+ L Löschen :
+ M Markierung :
+ --------------:
+ Datensatz :
+ - Einfügen :
+ - Ändern :
+ - Tragen :
+ - Holen :
+ --------------:
+ F Feldauswahl :
+ --------------:
+ :
+ :
+ :
+
+___________________________________________________________________________________________
+
+
+#center#Abb. 5-1 Menü 'Einzelsatz'
+
+
+Das automatisch generierte Formular zeigt immer genau einen Satz.
+Das Formular besteht aus drei Teilen: der Überschrift, dem Feldteil
+und der Abschlußzeile. In der #on("i")#Überschrift#off("i")# steht der Name der Datei
+("Adressen"), die Satznummer (1) und die Nummer der ersten ange­
+zeigten Zeile (immer 1, außer wenn die Datei mehr Felder hat, als
+auf den Bildschirm passen). In manchen Fällen können auch noch
+weitere Informationen dort auftauchen, wie wir später sehen wer­
+den.
+ Im #on("i")#Feldteil#off("i")# befindet sich der eigentliche Inhalt, und zwar sind
+links markiert die Feldnamen zu sehen, während rechts die zugehö­
+rigen Inhalte des betreffenden Satzes stehen. Dieses Bild ähnelt
+einer Karteikarte mit einem festen Format.
+ Die #on("i")#Abschlußzeile#off("i")# am Ende gibt an, daß für diesen Satz keine
+weiteren Informationen mehr vorhanden sind. Wir werden aber spä­
+ter noch sehen, wie man anderenfalls die restlichen Informatio­
+nen sichtbar machen kann.
+
+
+5.2 Bewegen
+
+Nun wollen Sie nicht immer nur einen Satz betrachten (das wäre ja
+furchtbar langweilig). Daher müssen Sie die Möglichkeit haben, sich
+in der Datei zu "bewegen". Dies geschieht mit Hilfe der beiden
+Funktionen
+#free (0.2)#
+
+ W Weiter
+
+#free (0.2)#
+und
+#free (0.2)#
+
+ Z Zurück
+
+#free (0.2)#
+Sie haben die Wirkung, daß der Satz mit der nächsthöheren bzw.
+nächstniedrigeren Satznummer angezeigt wird. Natürlich funktioniert
+dies nur, wenn noch ein Satz vorhanden ist: am Anfang (Satz 1)
+können Sie nicht zurückgehen. In diesem Fall ignoriert EUDAS Ihren
+Befehl einfach.
+ Wenn Sie bis zum Ende der Datei gehen (keine Angst - diese
+Datei enthält nur 10 Sätze), werden Sie feststellen, daß zum Schluß
+ein ganz leerer Satz erscheint. Dieser Satz ist eine Art Endemarkie­
+rung; er informiert Sie, daß keine weiteren Sätze vorhanden sind.
+Dieser Satz ist aber kein richtiger Satz, daher wird in der Über­
+schrift 'ENDE' angezeigt. (Wenn Ihnen diese Art Endemarkierung
+merkwürdig erscheint: sie hat schon einen triftigen Grund, s.6.2).
+ Um einen Satz mit bekannter Satznummer gezielt anzuwählen,
+können Sie die Funktion
+#free (0.2)#
+
+ N Satz.Nr
+
+#free (0.2)#
+verwenden. Sie müssen anschließend die Satznummer eingeben (Bitte
+mit RETURN beenden). Ist der Satz vorhanden, erscheint dieser,
+ansonsten stehen Sie am Ende der Datei.
+
+#on("b")#Aufruf über Buchstaben#off("b")# Vielleicht ist Ihnen inzwischen
+schon
+aufgefallen, daß vor jeder Funktion in einem Menü ein Buchstabe
+steht. Damit hat es folgendes auf sich: da das Positionieren des
+Cursors zum Auswählen einer Funktion mehrere Tastendrücke erfor­
+dern kann, haben Sie die Möglichkeit, jede Funktion auch über
+einen Buchstaben auszuführen.
+ Dies ist besonders dann sinnvoll, wenn Sie mit den eben be­
+sprochenen Funktionen schnell in der Datei "blättern" wollen. An­
+dererseits müssen Sie sich aber für eine schnelle Reaktion auch
+einige der Tasten merken. Für die Praxis empfiehlt sich folgender
+Kompromiß: die meistgebrauchten Funktionen über Buchstaben und
+der Rest durch Positionieren im Menü.
+
+
+5.3 Suchen
+
+Stellen Sie sich vor, die Datei wäre größer und Sie müßten eine
+bestimmte Adresse heraussuchen. Dazu würden Sie durch die ganze
+Datei durchgehen, bis die gewünschte Adresse erscheint. Das wäre
+natürlich bei vielen Adressen eine ungeheuer mühselige Arbeit, die
+mit einem Karteikasten wahrscheinlich schneller zu erledigen wäre.
+ EUDAS bietet Ihnen jedoch die Möglichkeit, nach bestimmten
+Sätzen zu suchen. Dazu müssen Sie angeben, wonach gesucht werden
+soll. Als Beispiel wollen wir die Adresse von Frau Simmern su­
+chen. Bewegen Sie sich zunächst zurück bis auf den ersten Satz.
+Dann wählen Sie die Funktion
+#free (0.2)#
+
+ Suchbedingung
+ S Setzen
+
+#free (0.2)#
+Auf dem Bildschirm verschwinden die Feldinhalte und der Cursor
+steht hinter dem ersten Feldnamen. Dies bedeutet, daß Sie neben
+die Feldnamen etwas schreiben können. Auch in der Statuszeile
+erscheint statt der Anzeige der Menünamen ein Hinweis auf die
+Eingabemöglichkeit (s. Abb. 5-2). Sie befinden sich jetzt in einem
+Zustand, in dem Sie hinter die Feldnamen etwas schreiben können
+(dem sogenannten #on("i")#Satzeditor#off("i")#).
+ Als Angabe, was gesucht werden soll, schreiben Sie jetzt in der
+ersten Zeile neben 'Name' die Bedingung 'Simmern'. Sie haben jetzt
+ein einfaches #on("i")#Suchmuster#off("i")# angegeben. Ein Suchmuster besteht aus
+Bedingungen, die neben die Feldnamen geschrieben werden. Unser
+einfaches Suchmuster lautet übersetzt:
+
+ Wähle alle Sätze aus, bei denen 'Simmern' im Feld 'Name'
+ steht.
+
+Beenden Sie die Eingabe des Suchmusters mit ESC 'q'. Es erscheint
+wieder das vorherige Bild, mit dem Unterschied, daß jetzt in der
+Überschrift ein 'SUCH-' auftaucht. EUDAS steht immer noch auf dem
+ersten Satz.
+ Die Anzeige 'SUCH' gibt an, daß ein Suchmuster eingestellt
+wurde. Das Minuszeichen bedeutet, daß der aktuelle Satz die Such­
+bedingung jedoch #on("i")#nicht#off("i")# erfüllt.
+
+___________________________________________________________________________________________
+
+ SUCHMUSTER EINGEBEN: Abbruch: ESC h Beenden: ESC q Hilfe: ESC ?
+ --------------: Satz 1 .................... ............... Zeile 1
+ Positionieren : Name Simmern
+ W Weiter : Vorname
+ Z Zurück : PLZ
+ N Satz.Nr : Ort
+ --------------: Strasse
+ Suchbedingung : m/w
+ * Setzen : ...........................................................
+ L Löschen :
+ M Markierung :
+ --------------:
+ Datensatz :
+ - Einfügen :
+ - Ändern :
+ - Tragen :
+ - Holen :
+ --------------:
+ F Feldauswahl :
+ --------------:
+ :
+ :
+___________________________________________________________________________________________
+
+
+#center#Abb. 5-2 Eingabe eines Suchmusters
+
+
+#on("b")#Positionierung#off("b")# Das Suchen beginnt erst, wenn Sie sich in
+der Datei
+bewegen. In diesem Fall erhalten die Funktionen 'Satz weiter' und
+'Satz zurück' eine etwas geänderte Bedeutung. Sie gehen nämlich
+nicht einfach zum nächsten bzw. vorigen Satz, sondern zum näch­
+sten bzw. vorigen Satz.
+ Als Indikator, daß Sie sich auf dem gesuchten Satz befinden,
+dient die Anzeige 'SUCH+'. Probieren Sie dies jetzt aus, indem Sie
+weitergehen. Als nächster Satz erscheint der gewünschte Satz 7. Die
+nicht ausgewählten Sätze wurden also übersprungen. Das gleiche
+passiert, wenn Sie noch weiter gehen. Da kein passender Satz mehr
+vorhanden ist, erscheint der leere Endesatz.
+
+#limit (12.0)#
+ Denken Sie daran, daß das Einstellen der Suchbedingung
+ noch keine Suche bewirkt. Diese müssen Sie selbst
+ durch Positionieren mit 'Weiter' oder 'Zurück' auslösen.
+#limit (13.5)#
+
+Sollten Sie sich nicht am Anfang der Datei befinden, wenn Sie eine
+Suchbedingung einstellen, kann es sein, daß sich der gesuchte Satz
+vor oder hinter der aktuellen Position befindet. In diesem Fall
+müssen Sie entscheiden, ob Sie vorwärts oder rückwärts gehen.
+Wenn Sie rückwärts gehen und der Satz ist nicht in diesem Ab­
+schnitt, erscheint der erste Satz mit der Anzeige 'SUCH-'. Gehen Sie
+dann wieder vorwärts, finden Sie den Satz auf jeden Fall.
+ Die Funktion 'Satz.Nr' richtet sich natürlich nicht nach der
+eingestellten Bedingung, da Sie ja eine bestimmte Satznummer wün­
+schen. Aus der 'SUCH'-Anzeige können Sie jedoch entnehmen, ob
+die Suchbedingung auf diesen Satz zutrifft.
+
+#on("b")#Suchbedingung löschen#off("b")# Wollen Sie wieder alle Sätze sehen,
+müssen Sie die Funktion
+#free (0.2)#
+
+ Suchbedingung
+ L Löschen
+
+#free (0.2)#
+auswählen. Die Anzeige 'SUCH' verschwindet wieder, um anzudeu­
+ten, daß keine Suchbedingung mehr eingestellt ist.
+
+#on("b")#Beispiel#off("b")# Um den Charakter einer Selektion nochmal deutlich
+zu
+machen, sollen Sie jetzt eine Bedingung einstellen, die auf mehrere
+Sätze zutrifft. Dies hätte uns auch eben passieren können, wenn es
+mehrere Simmern gegeben hätte. Wir können zum Beispiel alle weib­
+lichen Personen auswählen.
+ Als erstes löschen Sie die alte Suchbedingung. Tun Sie dies
+nicht, wird Ihnen beim nächsten Eingeben das alte Suchmuster zum
+Ändern angeboten. Dies ist praktisch, wenn ein Suchmuster nicht
+den erhofften Erfolg brachte und Sie es modifizieren wollen.
+ Danach wählen Sie erneut die Funktion 'Suchbedingung setzen'.
+Nun bewegen Sie den Cursor mit der Pfeiltaste UNTEN neben den
+Feldnamen 'm/w'. Dort tragen Sie die Bedingung 'w' ein. Verlassen
+Sie die Eingabe mit ESC 'q'.
+ Wenn Sie sich jetzt in der Datei bewegen, sehen Sie, daß immer
+nur weibliche Personen angezeigt werden - die männlichen werden
+unterdrückt (in Umkehrung der Realität).
+
+
+ ! 1 ! ! 3 ! 4 ! ! 6 !
+ +-----+-----+-----+-----+-----+-----+-----+
+ !Name ! .. ! ! .. ! .. ! ! .. !
+ ! ! ! ! ! ! ! !
+ : : : : :
+ ! ! ! ! ! ! ! !
+ !m/w ! w ! ! w ! w ! ! w !
+ +-----+-----+ +-----+-----+ +-----+
+
+#center#Abb. 5-3 Wirkung einer Selektion
+
+
+
+5.4 Suchbedingungen
+
+Im letzten Abschnitt haben Sie gesehen, wie das Einstellen einer
+Suchbedingung funktioniert. In diesem Abschnitt sollen Sie weitere
+Möglichkeiten zur Formulierung von Suchmustern kennenlernen.
+ Die erste Möglichkeit kennen Sie schon. Wenn neben einen
+Feldnamen ein Text geschrieben wird, bedeutet dies, daß ausge­
+wählte Sätze im Inhalt dieses Feldes mit dem Text übereinstimmen
+müssen.
+
+#on("b")#Kombination#off("b")# Nun kann es sein, daß mehrere Bedingungen
+gelten
+müssen. Im ersten Beispiel des vorigen Abschnitts hätten wir zum
+Beispiel auch noch den Vornamen 'Anna-Maria' angeben können, um
+bei mehreren Simmern die richtige auszuwählen. Wird also in mehre­
+re Felder eine Bedingung geschrieben, müssen alle diese Bedingun­
+gen gleichzeitig zutreffen.
+ Würden Sie in unserem Beispiel noch als dritte Bedingung 'm'
+für das Feld 'm/w' angeben, würde gar kein Satz mehr ausgewählt,
+da Anna-Maria Simmern natürlich nicht männlich ist. Auch das
+kann also passieren.
+
+
+ Name Simmern
+ Vorname Anna-Maria
+ ..
+ ..
+ m/w m
+
+#center#Abb. 5-4 Kombination von Bedingungen
+
+
+#on("b")#Stern#off("b")# Die Bedingungen, die wir bis jetzt kennengelernt
+haben,
+müssen alle ganz exakt zutreffen. Häufig tritt aber der Fall auf,
+daß der gesuchte Name nicht genau bekannt ist. In diesem Fall
+kann der Name im Suchmuster auch teilweise eingegeben werden.
+Der unbekannte Teil am Anfang oder am Ende wird einfach durch
+einen Stern markiert.
+ Wenn Sie also als Bedingung 'Sim*' für den Namen angeben, so
+würde dies auf den Namen Simmern zutreffen, aber zum Beispiel
+auch auf Simmerath oder Simon. Die Bedingung '*mern' würde nicht
+nur auf Simmern zutreffen, sondern auch auf Pommern.
+ Der Stern kann aber auch für einen leeren Text stehen. So
+trifft 'Simmern*' auf Simmern zu, aber auch auf Doppelnamen. die
+mit Simmern beginnen. Wissen Sie jetzt nicht, ob Simmern in dem
+Doppelnamen vorne oder hinten erscheint, können Sie auch an bei­
+den Seiten einen Stern machen. Die Bedingung '*Simmern*' trifft
+nicht nur auf Simmern, sondern sowohl auf Deckerath-Simmern als
+auch auf Simmern-Jakob zu.
+ Es gibt noch eine Reihe von weiteren Möglichkeiten, Bedingun­
+gen im Suchmuster zu formulieren. Auch komplexe Kombinationen
+von Bedingungen sind möglich. Mit dem bisher Besprochenen sollten
+Sie aber in vielen Fällen auskommen. Die übrigen Möglichkeiten
+werden in Abschnitt 10.2 erklärt. Schauen Sie bei Bedarf dort nach.
+
+
diff --git a/doc/eudas/eudas.hdb.6 b/doc/eudas/eudas.hdb.6
new file mode 100644
index 0000000..e617881
--- /dev/null
+++ b/doc/eudas/eudas.hdb.6
@@ -0,0 +1,394 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (51)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+6 Daten eingeben und ändern
+
+
+
+6.1 Neue Datei einrichten
+
+Nachdem Sie sich bis jetzt an einer existierenden Datei erprobt
+haben, können Sie nun dazu übergehen, eine eigene neue Datei
+einzurichten. Als Beispiel sollen Sie ein kleines Telefonregister
+erstellen.
+ Dazu gehen Sie wieder in das Menü 'Öffnen' zurück und wäh­
+len erneut die Funktion
+#free (0.2)#
+
+ O Öffnen
+
+#free (0.2)#
+indem Sie mehrmals OBEN tippen, bis die Funktion markiert. Dann
+tippen Sie die Lerrtaste zum Ausführen. Als Dateinamen geben Sie
+'Telefonnummern' an.
+ Da die Datei 'Telefonnummern' noch nicht existiert, werden Sie
+gefragt:
+
+
+ "Telefonnummern" neu einrichten ? (j/n) #on("i")#j#off("i")#
+
+
+Es kann ja sein, daß Sie sich vertippt haben und eine andere,
+existierende Datei meinten. In unserem Fall wird die Datei aber
+wirklich neu eingerichtet, daher bejahen Sie die Frage.
+
+#on("b")#Feldnamen eingeben#off("b")# Wenn Sie beim Öffnen eine Datei neu
+einrich­
+ten, müssen Sie zuerst die Feldnamen festlegen, zum Beispiel diese:
+
+
+ 'Name'
+ 'Vorname'
+ 'Strasse'
+ 'PLZ'
+ 'Ort'
+ 'Telefon'
+ 'Bemerkungen'
+
+
+Ihnen wird jetzt Gelegenheit gegeben, die Feldnamen untereinander
+einzugeben. Zur Korrektur können Sie die gleichen Tasten verwen­
+den wie im Editor (beachten Sie dazu die Statuszeile am oberen
+Bildschirmrand.
+ Geben Sie die Namen in dieser Reihenfolge ein. Tippen Sie nach
+jedem Namen die RETURN-Taste, damit der nächste Name in eine
+neue Zeile kommt. Beenden Sie die Eingabe mit ESC 'q'.
+ Die folgende Frage ermöglicht es Ihnen, noch weitere Eigen­
+schaften der Felder festzulegen. Dies ist jedoch im Normalfall nicht
+nötig. Beantworten Sie also die Frage mit 'n'. Ihre Datei ist nun
+eingerichtet.
+ Wie Sie sehen, besteht das Einrichten einer Datei eigentlich
+nur aus der Eingabe der Feldnamen. Wenn Sie später noch Felder
+anfügen wollen, ist dies ohne weiteres möglich.
+
+
+6.2 Sätze Einfügen
+
+Nachdem die Datei nun eingerichtet worden ist, sollen Sie zunächst
+einige Sätze eingeben. Wenn Sie wieder das Menü 'Einzelsatz' an­
+wählen, sehen Sie nur den leeren Satz mit der Anzeige 'ENDE', der
+das Dateiende markiert. Um neue Sätze aufzunehmen, gibt es die
+Funktion
+#free (0.2)#
+
+ E Einfügen
+
+#free (0.2)#
+Wenn Sie diese Funktion aufrufen, geschieht etwas Ähnliches wie
+beim Eingeben des Suchmusters. Der Cursor wandert wieder hinter
+den ersten Feldnamen und in der Statuszeile erscheint die Auffor­
+derung
+
+___________________________________________________________________________________________
+
+ SATZ EINFUEGEN: Abbruch: ESC h Beenden: ESC q Hilfe: ESC ?
+___________________________________________________________________________________________
+
+
+Sie können nun die Feldinhalte der einzelnen Felder neben die
+entsprechenden Feldnamen schreiben. Mit der RETURN-Taste schlie­
+ßen Sie eine Zeile ab und gelangen in die nächste.
+ Um eventuelle falsche Eingaben zu korrigieren, können Sie
+ähnlich wie im Editor mit den Pfeiltasten herumfahren und falsche
+Eingaben überschreiben. Die Taste RUBOUT löscht falsche Zeichen.
+Sie beenden die Eingabe mit ESC 'q'. Anschließend ist der neue Satz
+vorhanden.
+
+
+#free (4.5)#
+
+#center#Abb. 6-1 Einfügen
+
+
+#on("b")#Wirkung#off("b")# Die Wirkungsweise der Funktion 'Einfügen'
+verdeutlicht
+die Abb. 6-1. Dargestellt ist ein Ausschnitt aus einer Datei mit den
+Sätzen 4 bis 7 und durch Buchstaben dargestellten, beliebigen In­
+halten. Satz 6 sei der aktuelle Satz.
+ Beim Einfügen wird nun vor dem aktuellen Satz eine Lücke für
+den neuen Satz geschaffen, die zunächst noch leer ist und dann von
+Ihnen ausgefüllt werden muß. Die Satznummern aller folgenden Sätze
+erhöhen sich um 1.
+ Die Leerstelle bleibt nur dann erhalten, wenn Sie Daten für den
+neuen Satz eingeben. Anderenfalls wird nach ESC 'q' wieder der alte
+Zustand hergestellt.
+ Dieses Verfahren erklärt auch, warum das Ende der Datei ein
+leerer Pseudosatz ist. Um nämlich am Ende der Datei einen neuen
+Satz anzufügen, muß man vor dem Endesatz einen Satz einfügen.
+ Nachdem Sie also jetzt den ersten Satz eingegeben haben,
+müssen Sie sich wieder zum Ende bewegen, damit der nächste Satz
+hinter dem ersten steht. Für diesen häufig benötigten Vorgang gibt
+es eine Abkürzung: Wenn Sie die Eingabe mit ESC 'w' (Weiter) statt
+ESC 'q' beenden, geht EUDAS nach dem Einfügen des Satzes weiter
+zum nächsten und fügt dort wieder einen Satz ein.
+ Auf diese Weise können Sie also schnell eine ganze Reihe von
+Sätzen nacheinander eingeben. Nachdem Sie einen Satz eingegeben
+haben, tippen Sie ESC 'w' und können gleich anschließend schon mit
+der Eingabe des nächsten Satzes beginnen. Alle so eingegebenen
+Sätze erscheinen nachher in der Reihenfolge der Eingabe.
+
+#on("b")#Satzeditor#off("b")# Bei der Eingabe eines neuen Satzes haben Sie
+nahezu
+alle Möglichkeiten, die auch der EUMEL-Editor bietet. Der be­
+schreibbare Bereich ist jedoch kleiner. Er umfaßt das ganze Gebiet,
+in dem sonst die Feldinhalte erscheinen.
+ Wie beim Editor können Sie den Cursor mit den Cursortasten
+(Pfeiltasten) bewegen. Mit der Taste RUBOUT können Sie ein Zeichen
+löschen. Die restlichen Zeichen der Zeile rücken dann nach. Mit
+RUBIN dagegen schalten Sie in einen Einfügemodus um. Alle einge­
+gebenen Zeichen werden dann eingefügt - der Rest der Zeile rückt
+entsprechend nach rechts. Nochmaliges Tippen von RUBIN schaltet
+wieder in den alten Modus. Welcher Modus eingeschaltet ist, steht
+in der Überschriftzeile.
+ Mit der Kombination ESC RUBOUT können Sie den Rest einer
+Zeile ab der Cursorposition löschen. Steht der Cursor in der ersten
+Spalte, wird dementsprechend die ganze Zeile gelöscht. Im Unter­
+schied zum EUMEL-Editor rücken die folgenden Zeilen jedoch nicht
+herauf.
+ Entsprechend fügen Sie mit der Funktion ESC RUBIN eine neue
+Zeile ein. Dies ist immer dann erforderlich, wenn ein Feldinhalt
+nicht auf eine Zeile paßt. Der Teil der Zeile, der hinter dem Cursor
+steht, wird bei ESC RUBIN in die neue Zeile mitgenommen.
+ Normalerweise tippen Sie ESC RUBIN, wenn Sie an das Ende
+einer Zeile kommen. Wenn Sie aber weiterschreiben, wird die Zeile
+einfach gerollt. Dies ist nicht weiter schlimm, aber Sie können den
+ganzen Feldinhalt nicht auf einmal sehen.
+ In der normalen Anzeige wird ein überlanger Inhalt auf jeden
+Fall auf mehrere Zeilen verteilt.
+
+#on("b")#Warnung#off("b")# Ein Hinweis für alle, die sich mit der
+Editorbedienung
+schon auskennen: EUDAS benutzt den Editor als Unterprogramm.
+Jedoch haben einige Editorfunktionen unliebsame Auswirkungen.
+Besonders gefährlich sind hier HOP RUBOUT und HOP RUBIN. Diese
+Funktion zerstören die Korrespondenz zwischen Feldnamen und
+Feldinhalten, das heißt der Feldinhalt steht nicht mehr neben dem
+Feldnamen.
+ Weiterhin können Sie das Editorbild rollen, ohne daß die Feld­
+namen mitrollen (zum Beispiel wenn Sie in der untersten Zeile
+RETURN drücken). In diesem Fall ist die Korrespondenz auch nicht
+erhalten, das heißt die Inhalte stehen falsch, sind aber eigentlich
+richtig.
+ In solchen Fällen erscheint am oberen oder unteren Rand der
+Hinweis "Bitte ESC '1' druecken". Wenn das Editorbild nur gerollt
+wurde, verschwindet durch ESC '1' der Hinweis wieder und das Bild
+ist in Ordnung. Wenn jedoch Zeilen gelöscht oder eingefügt wurden,
+müssen Sie diese Änderungen von Hand wieder rückgängig machen,
+bis der Hinweis verschwindet. Sie sollten also HOP RUBOUT und HOP
+RUBIN im Satzeditor nicht verwenden.
+ Im Zweifelsfall, wenn Sie meinen, den Satz durcheinanderge­
+bracht zu haben, können Sie immer mit ESC 'h' abbrechen. Es steht
+dann der vorherige Zustand für einen neuen Versuch zur Verfügung.
+
+
+6.3 Daten ändern
+
+Wenn Sie nachträglich noch eingegebene Daten ändern wollen, kön­
+nen Sie die Funktion
+#free (0.2)#
+
+ A Ändern
+
+#free (0.2)#
+verwenden. Sie haben anschließend wie beim Einfügen Gelegenheit,
+neue Daten einzugeben. Allerdings werden Ihnen die bisherigen
+Daten gleich mit angeboten, so daß Sie nur die Änderungen ein­
+geben müssen. Alles andere kann unverändert bleiben. Auch diese
+Funktion wird mit ESC 'q' verlassen. ESC 'w' funktioniert beim
+Ändern ebenfalls (der nächste Satz wird zum Ändern angeboten).
+ Stellen Sie beim Ändern oder Einfügen fest, daß Sie irgendeinen
+krassen Fehler gemacht haben, können Sie die Operation mit ESC 'h'
+abbrechen. Beim Ändern bleibt dann der alte Zustand unverändert,
+beim Einfügen wird kein Satz eingefügt.
+
+#on("b")#Löschen#off("b")# Für den Fall, daß Sie einen Satz wieder ganz aus
+der
+Datei löschen wollen, hat EUDAS eine besondere Vorsichtsmaßnahme
+vorgesehen. Damit der Satz nicht gleich unwiederbringlich verloren­
+geht, müssen Sie ihn zunächst in eine andere Datei #on("i")#tragen#off("i")#. Falls
+das Löschen ein Irrtum war, können Sie den Satz von dort noch
+wiederholen. In vielen Fällen besteht ohnehin die Anforderung, daß
+auch die nicht mehr aktuellen Daten noch eine gewisse Zeit aufge­
+hoben werden müssen.
+ Zum Tragen gibt es die Funktion
+
+
+ Datensatz
+ T Tragen
+
+
+Sie werden nach einem Dateinamen gefragt. Geben Sie hier zum
+Beispiel 'müll' an. Da diese Datei noch nicht existiert, werden Sie
+gefragt, ob Sie sie neu einrichten wollen (falls Sie sich vielleicht
+verschrieben haben). Danach wird der aktuelle Satz in die Datei
+'müll' transportiert. Am Bildschirm erscheint der nächste Satz. Der
+getragene Satz kommt an das Ende der Zieldatei.
+ Eine Bedingung beim Tragen ist, daß die Zieldatei immer die
+gleichen Felder haben muß wie die aktuelle Datei. Sie können also
+nicht aus verschieden strukturierten Dateien in die gleiche Datei
+tragen.
+ Zum Zurückholen eines Satzes benutzen Sie die Funktion
+
+
+ Datensatz
+ H Holen
+
+
+Der letzte Satz der Datei, die Sie angeben, wird vor dem aktuellen
+Satz eingefügt. Dadurch wird der Effekt des letzten Tragens wieder
+aufgehoben.
+ Um die getragenen Sätze endgültig zu vernichten, müssen Sie
+die Zieldatei als Ganzes löschen. Die dazu notwendige Funktion aus
+dem Menü 'Dateien' haben Sie bereits in Abschnitt 4.4 kennenge­
+lernt.
+
+
+6.4 Arbeitskopie sichern
+
+Wenn Sie eine Datei zum Ändern öffnen oder sie gerade neu einge­
+richtet haben, wird von dieser Datei intern eine Arbeitskopie ange­
+legt, die dann geändert wird. Sie müssen diese Arbeitskopie nach
+den Änderungen sichern, damit die Änderungen wirksam werden.
+ In unserem Beispiel ist die Datei "Telefonnummern" immer noch
+leer. Die Änderungen sind momentan nur in der internen Kopie
+vorhanden. Wenn Sie die Datei zum Beispiel auf eine Archivdiskette
+schreiben wollten, würden Sie eine leere Datei auf der Diskette
+haben.
+ Zum Sichern rufen Sie die Funktion
+#free (0.2)#
+
+ S Sichern
+
+#free (0.2)#
+im ersten Menü auf. Es erscheint dann folgende Frage:
+
+___________________________________________________________________________________________
+
+ Arbeitskopie "Telefonnummern" veraendert! Sichern (j/n) ?
+___________________________________________________________________________________________
+
+
+Beantworten Sie diese Frage mit 'j'. Als nächstes wird gefragt:
+
+___________________________________________________________________________________________
+
+ Alte Version überschreiben (j/n) ?
+___________________________________________________________________________________________
+
+
+Beantworten Sie auch diese Frage mit 'j'. Die Arbeitskopie über­
+schreibt dann die (leere) Version vor dem Ändern.
+ Wenn Sie die Frage verneint hätten, könnten Sie anschließend
+einen neuen Namen für die Arbeitskopie angeben. Dies wäre dann
+sinnvoll, wenn Sie den Stand vor den Änderungen noch aufbewahren
+wollen. In diesem Fall ist es jedoch nutzlos, die alte leere Datei
+noch behalten zu wollen.
+ Abschließend wird gefragt, ob Sie die Arbeitskopien löschen
+wollen. Wenn Sie noch weiter mit der Datei arbeiten wollen, vernei­
+nen Sie diese Frage. Die Datei bleibt dann geöffnet. Anderenfalls
+müßten Sie die Datei neu öffnen, wenn Sie sie wieder ansehen wol­
+len.
+
+#on("b")#Arbeitskopien#off("b")# Es ist sehr wichtig, daß Sie sich die
+Funktionsweise
+mit der Arbeitskopie immer vor Augen halten, damit Sie später bei
+der Arbeit mit EUDAS nicht überrascht werden.
+ Eine Arbeitskopie wird immer dann angelegt, wenn Sie beim
+Öffnen einer EUDAS-Datei angeben, daß Sie diese Datei ändern
+wollen. In dem Beispiel haben Sie eine neue Datei eingerichtet.
+EUDAS nimmt dann automatisch an, daß Sie ändern wollen. Öffnen
+Sie eine existierende Datei, werden Sie gefragt
+
+___________________________________________________________________________________________
+
+ Wollen Sie etwas ändern (Arbeitskopie anlegen) (j/n) ?
+___________________________________________________________________________________________
+
+
+Wenn Sie diese Frage verneinen, wird keine Arbeitskopie angelegt;
+alle Änderungsfunktionen werden jedoch gesperrt. Daran können Sie
+auch erkennen, daß keine Arbeitskopie vorliegt.
+ Die Arbeitskopie, die EUDAS sich anlegt, ist anonym. Wenn Sie
+sich also im Menü 'Dateien' eine Übersicht zeigen lassen, erscheint
+nur das Original. Bevor Sie mit diesem Original etwas anstellen
+(zum Beispiel auf Archiv schreiben), sollten Sie sich vergewissern,
+daß Sie die Arbeitskopie gesichert haben, da das Original sonst
+nicht auf dem neuesten Stand ist.
+ Um Sie in diesem Fall zu warnen, erscheint vor einer geöffneten
+Datei in einer Dateiauswahl das Symbol <!>, zum Beispiel:
+
+
+ o <!> "Telefonnummern"
+ o "Mitglieder"
+
+
+Wenn Sie dieses Symbol sehen, sollten Sie die Datei lieber erst
+sichern, bevor Sie etwas mit ihr anstellen.
+
+#on("b")#Beispiel#off("b")# Um die Arbeitsweise von EUDAS noch besser zu
+verstehen,
+betrachten Sie das Beispiel in Abb. 6-2. Nehmen Sie an, Sie haben
+drei EUDAS-Dateien 'Kalender', 'Namen' und 'Adressen' mit ihren
+Anfangsinhalten K0, N0 und A0 (symbolisch). In dem Diagramm sind
+die Vorgänge zu den Zeitpunkten 0 bis 10 mit ihren Auswirkungen
+auf die Inhalte der Dateien und der Arbeitskopie dargestellt.
+
+
+#free (5.5)#
+#center#Abb. 6-2 Beispiel zur Arbeitskopie
+
+
+Zu den einzelnen Zeitpunkten passiere folgendes:
+
+0: Anfangszustand. Es wurde noch keine Datei geöffnet, also ist
+ keine Arbeitskopie vorhanden. Es könnte aber auch eine
+ beliebige Datei ohne Änderungserlaubnis geöffnet sein.
+#free (0.2)#
+1: Die Datei 'Adressen' wird geöffnet zum Ändern. Der momen­
+ tane Zustand der Datei wird als Arbeitskopie übernommen.
+#free (0.2)#
+2: Es wird eine Änderung vorgenommen (zum Beispiel) ein Satz
+ eingefügt). Diese Änderung betrifft aber nur die Kopie - die
+ Datei 'Adressen' als Original bleibt unverändert.
+#free (0.2)#
+3: Eine weitere Änderung führt zum Inhalt A2 der Arbeitsko­
+ pie.
+#free (0.2)#
+4: Aufruf von 'Sichern'. Die alte Version von 'Adressen' wird
+ überschrieben und durch den Inhalt A2 ersetzt. Die Frage
+ nach dem Löschen der Arbeitskopie wird verneint; daher bleibt
+ die Kopie auch erhalten.
+#free (0.2)#
+5: Die Kopie wird erneut verändert.
+#free (0.2)#
+6: Aufruf von 'Sichern'. Die Frage, ob die Kopie gesichert wer­
+ den soll, wird verneint. Die Arbeitskopie soll jedoch gelöscht
+ werden. Als Ergebnis geht die Änderung A3 verloren (viel­
+ leicht war diese Änderung ein Irrtum). Die Datei 'Adressen'
+ wird nicht verändert. Es ist keine Arbeitskopie mehr vor­
+ handen.
+#free (0.2)#
+7: Die Datei 'Namen' wird zum Ändern geöffnet.
+#free (0.2)#
+8: Die Datei 'Kalender' wird zum Ändern geöffnet. Da an der
+ vorigen Arbeitskopie keine Änderungen vorgenommen wurden,
+ kann die Kopie einfach überschrieben werden. Anderenfalls
+ wäre an dieser Stelle die Möglichkeit zum Sichern angeboten
+ worden.
+#free (0.2)#
+9: Es wird eine Änderung durchgeführt.
+#free (0.2)#
+10: Die geänderte Arbeitskopie wird gesichert, das Original über­
+ schrieben und die Arbeitskopie gelöscht (Normalfall).
+
+
diff --git a/doc/eudas/eudas.hdb.7 b/doc/eudas/eudas.hdb.7
new file mode 100644
index 0000000..d6f1bf3
--- /dev/null
+++ b/doc/eudas/eudas.hdb.7
@@ -0,0 +1,687 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (61)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+7 Ausdrucken der Daten
+
+
+
+7.1 Druckmuster
+
+Nachdem Sie sich die Inhalte der EUDAS-Datei ausgiebig am Bild­
+schirm angesehen haben, möchten Sie die gespeicherten Daten sicher
+auch in gedruckter Form auf Papier sehen. Sie können eine
+EUDAS-Datei jedoch nicht ohne weiteres ausdrucken, da sie eine
+andere Struktur als normale Textdateien hat.
+ Vor dem Drucken müssen also die Inhalte der EUDAS-Datei
+zunächst in lesbarer Form in eine Textdatei geschrieben werden.
+EUDAS kann diese Aufgabe jedoch ohne Ihre Hilfe nicht alleine be­
+wältigen.
+ Es taucht nämlich das Problem auf, daß die Dateiinhalte in
+vielen verschiedenen Formen dargestellt werden können (Sie erin­
+nern sich sicher noch an das erste Kapitel). Vielleicht wollen Sie
+bestimmte Überschriften haben oder die Daten müssen auf ein be­
+stimmtes Formular passen.
+ Um die Ausgabe nach Ihren Wünschen zu gestalten, müssen Sie
+also dem Rechner genau angeben, an welcher Stelle welche Felder
+gedruckt werden sollen usw. Dies geht am einfachsten, indem Sie
+dem Rechner ein Muster vorsetzen, nach dem er dann die richtigen
+Ausdrucke erstellen kann. Dieses Muster schreiben Sie in eine eige­
+ne Textdatei, die #on("i")#Druckmuster#off("i")# genannt wird. Aus den Daten der
+EUDAS-Datei und der Form, die im Druckmuster angegeben ist, wird
+dann eine weitere Textdatei erzeugt, die die Daten in der ge­
+wünschten Form enthält und die anschließend automatisch gedruckt
+werden kann.
+ Durch ein Druckmuster erhalten Sie fast völlige Freiheit in der
+Gestaltung Ihrer Ausdrucke. Zum Beispiel können aus einer einzigen
+Adressendatei einfache Listen, Einladungskarten oder Rundbriefe
+erzeugt werden. Für eine einfache Adressenliste entspricht das
+Druckmuster einer Zeile der Liste, wobei angegeben wird, in welche
+Spalten die Inhalte gedruckt werden. Zum Drucken von Einladungs­
+karten wird als Druckmuster eine Einladungskarte verwendet, in der
+die Stellen markiert sind, an denen die Adresse erscheinen soll. Das
+gleiche kann man mit einem Brief machen, der dann mit jeder
+Adresse einmal ausgedruckt wird.
+
+#on("b")#Druckverfahren#off("b")# Man kann sich diesen Druckprozeß wie folgt
+vorstellen:
+
+
+#free (6.5)#
+
+#center#Abb. 7-1 Druckverfahren
+
+
+Vereinfacht gesagt (das genaue Verfahren wird später beschrieben)
+wird für jeden Satz der EUDAS-Datei das Druckmuster einmal in die
+Druckdatei übernommen. Dabei werden die Inhalte aus der EUDAS-
+Datei in einer noch anzugebenden Weise an den gewünschten Stellen
+eingefügt.
+ Im weiteren sollen Sie erfahren, wie ein Druckmuster genau
+aussieht und wie daraus ein Ausdruck entsteht.
+
+#on("b")#Beispiel#off("b")# Im folgenden sollen Sie zur Demonstration die
+bereits in
+Kapitel 3 und 4 beschriebene Beispieldatei verwenden. Nach Mög­
+lichkeit sollten Sie die angegebenen Beispiele mit dieser Datei
+selbst am Rechner ausprobieren.
+
+Folgende Sätze befinden sich in der Datei:
+
+
+ Vorname Name, Strasse, PLZ Ort, m/w
+ -------------------------------------------------------
+ Herbert Wegner, Krämergasse 12, 5000 Köln, m
+ Helga Sandmann, Willicher Weg 109, 5300 Bonn 1, w
+ Albert Katani, Lindenstr. 3, 5210 Troisdorf, m
+ Peter Ulmen, Mozartstraße 17, 5 Köln 60, m
+ Karin Regmann, Grengelweg 44, 5000 Köln 90, w
+ Hubert Arken, Talweg 12, 5200 Siegburg, m
+ Anna-Maria Simmern, Platanenweg 67, 5 Köln 3, w
+ Angelika Kaufmann-Drescher, Hauptstr. 123, 53 Bonn 2, w
+ Harald Fuhrmann, Glockengasse 44, 5000 Köln 1, m
+ Friedrich Seefeld, Kabelgasse, 5000 Köln-Ehrenfeld, m
+
+
+Wie Sie sehen, wurde die Reihenfolge der Felder gegenüber der Datei
+teilweise verändert und Name und Vorname ohne Komma hinterein­
+andergeschrieben, während die anderen Feldinhalte durch Komma
+getrennt sind. Diese Liste wurde unter Verwendung eines Druck­
+musters erzeugt.
+ Da dieses Druckmuster jedoch vorerst noch zu kompliziert ist,
+sollen Sie erst einmal ein einfacheres Druckmuster erstellen und
+versuchen, nur die Namen aus der Datei in Tabellenform auszuge­
+ben.
+ Das dafür nötige Druckmuster hat folgendes Aussehen:
+
+
+ % WIEDERHOLUNG
+ ! &Name ! &Vorname !
+
+
+Das Druckmuster besteht nur aus zwei Zeilen, von der die zwei­
+te das eigentliche Muster darstellt. Die erste Zeile ist eine #on("i")# Anwei­
+sung#off("i")# an den Druckgenerator. 'WIEDERHOLUNG' gibt an, daß die
+folgenden Zeilen für jeden Satz wiederholt werden sollen (warum
+diese Angabe notwendig ist, werden Sie später einsehen). Das Pro­
+zentzeichen kennzeichnet eine Anweisung und muß unbedingt in der
+ersten Spalte des Druckmusters stehen, also ganz am linken Rand.
+ In der zweiten Zeile ist zu sehen, daß das Zeichen '&' dazu
+benutzt wird, die Stellen zu markieren, an denen nachher Feldin­
+halte eingesetzt werden sollen. Hinter dem '&'-Zeichen folgt der
+Name des Feldes, das an dieser Stelle eingesetzt werden soll. Eine
+solche Konstruktion wird #on("i")#Feldmuster#off("i")# genannt. Beachten Sie, daß
+Feldnamen hier immer ohne Anführungsstriche geschrieben werden
+müssen. Die Ausrufungszeichen bilden den eigentlichen Mustertext
+und werden unverändert als Tabellenbegrenzung in die Ausgabe
+übernommen.
+ Als Ergebnis des Druckprozesses sollte folgende Ausgabe auf
+dem Drucker erscheinen:
+
+
+ ! Wegner ! Herbert !
+ ! Sandmann ! Helga !
+ ! Katani ! Albert !
+ ! Ulmen ! Peter !
+ ! Regmann ! Karin !
+ ! Arken ! Hubert !
+ ! Simmern ! Anna-Maria !
+ ! Kaufmann-Drescher ! Angelika !
+ ! Fuhrmann ! Harald !
+ ! Seefeld ! Friedrich !
+
+
+Sie können erkennen, daß die Feldmuster in der Ausgabe jeweils
+durch den Inhalt des zugehörigen Feldes ersetzt worden sind. Der
+übrige Text in der Musterzeile ist unverändert geblieben. Beachten
+Sie, daß das '&' ein reserviertes Zeichen ist, das ein Feldmuster im
+umgebenden Text kennzeichnet und daher (vorerst) nicht gedruckt
+werden kann.
+
+
+7.2 Aufruf
+
+In diesem Abschnitt sollen Sie erfahren, wie Sie diese Ausgabe
+selbst erzeugen können. Damit der Druckgenerator arbeiten kann,
+müssen Sie die Datei 'Adressen' erst einmal öffnen. Anschließend
+wählen Sie das Menü 'Drucken' an.
+
+#on("b")#Druckmuster erstellen#off("b")# Als nächstes müssen Sie das
+Druckmuster erstellen. Hierfür gibt es die Funktion
+#free (0.2)#
+
+ Textdatei
+ E Editieren
+
+#free (0.2)#
+da das Druckmuster eine normale Textdatei ist.
+ Wählen Sie diese Funktion. Sie werden dann nach einem Namen
+für das Druckmuster gefragt. Wir wollen das Druckmuster 'Namens­
+liste' nennen - Sie können aber auch einen beliebigen anderen
+Namen wählen. Denken Sie daran, die Anführungsstriche nicht mit
+einzugeben.
+ Es erscheint anschließend das gewohnte Editorbild mit einer
+entsprechenden Statuszeile. Geben Sie die zwei Zeilen des Druck­
+musters ein und beenden Sie den Editor mit ESC 'q'. Damit ist das
+Druckmuster fertig.
+
+ Die hier beschriebene Funktion können Sie nicht nur zum Er­
+stellen, sondern auch zum Ändern und einfachen Ansehen eines
+Druckmusters bzw. einer Textdatei allgemein verwenden. Es wird
+Ihnen immer der jeweilige Inhalt präsentiert, den Sie dann nach
+Belieben abändern können oder nicht.
+
+___________________________________________________________________________________________
+
+ EUDAS: Öffnen Einzelsatz Gesamtdatei Drucken Dateien Archiv
+ --------------:
+ Satzauswahl :
+ D Drucken :
+ --------------:
+ Druckausgabe :
+ R Richtung :
+ --------------:
+ Textdatei :
+ E Editieren :
+ A Ausdrucken :
+ N Nachbearb. :
+ --------------:
+
+___________________________________________________________________________________________
+
+#center#Abb. 7-2 Menü "Drucken"
+
+
+#on("b")#Ausgaberichtung#off("b")# Bevor Sie jetzt weitermachen, sollten Sie
+über­
+prüfen, ob an Ihrem System ein Drucker angeschlossen ist. Der
+Drucker sollte bei den folgenden Versuchen betriebsbereit sein.
+ Ist kein Drucker angeschlossen oder wollen Sie kein Papier
+verschwenden, haben Sie die Möglichkeit, den Ausdruck als Text­
+datei zu erhalten. Dazu wählen Sie die Funktion
+#free (0.2)#
+
+ Ausgabe
+ R Richtung
+
+#free (0.2)#
+an. Beantworten Sie beide Fragen, die Ihnen gestellt werden, mit
+'n'. Die Ausgaben stehen dann nachher in Dateien mit einem Namen
+der Form
+#free (0.2)#
+
+ Namensliste.a$n
+
+#free (0.2)#
+die Sie sich mit der oben beschriebenen Funktion dann genau wie
+ein Druckmuster anschauen können. Der Name besteht also aus dem
+Namen des Druckmusters, dem ein '.a$' angehängt wird. Die Nummer
+'n' dient zur Unterscheidung bei mehreren aufeinanderfolgenden
+Ausgaben. Um Verwirrung zu vermeiden, sollten Sie die Datei nach
+dem Anschauen löschen (im Menü 'Dateien').
+
+#on("b")#Druckaufruf#off("b")# Wenn Sie diese Hinweise beachtet haben, können
+Sie den Druckvorgang mit der Auswahl
+#free (0.2)#
+
+ Satzauswahl
+ D Drucken
+
+#free (0.2)#
+starten. Sie werden hier nach dem Namen des Druckmusters gefragt,
+das Sie verwenden wollen (Sie können ja durchaus eine ganze Reihe
+von verschiedenen Druckmustern haben).
+ Sie können den Ablauf des Druckvorganges daran verfolgen,
+daß jeweils die Nummer des Satzes ausgegeben wird, der gerade
+bearbeitet wird. Probieren Sie eventuell auch kleine Abwandlungen
+des Druckmusters aus, indem Sie die Tabellenspalten schmaler oder
+breiter machen oder die Ausrufungszeichen durch ein anderes Zei­
+chen ersetzen (je nach Geschmack).
+
+#on("b")#Ausgabedatei#off("b")# Wollen Sie die erzeugte Ausgabe (die in der
+Datei
+'Namensliste.a$1' steht) irgendwann tatsächlich ausdrucken, ver­
+wenden Sie die Funktion
+#free (0.2)#
+
+ A Ausdrucken
+
+#free (0.2)#
+Sie werden dann nach dem Namen der Textdatei gefragt. Beachten
+Sie, daß Sie diese Funktion #on("i")#nicht#off("i")# zum Drucken von EUDAS-Dateien
+verwenden können, da aus einer EUDAS-Datei erst eine Druckdatei
+erzeugt werden muß.
+ Auch wenn Sie angegeben haben, daß die Ausgabe des Druck­
+prozesses direkt ausgedruckt werden soll, startet Ihr Drucker erst,
+wenn EUDAS die ganze Datei durchgegangen ist und der Vorgang für
+Sie beendet ist. Dies liegt am EUMEL-System, das nur vollständige
+Druckaufträge entgegennimmt, damit sich mehrere Benutzer nicht in
+die Quere kommen können. In einem Multi-User-System können Sie
+weiterarbeiten, während der Drucker beschäftig ist.
+
+#on("b")#Fehler#off("b")# Bevor der eigentliche Druckprozeß gestartet wird,
+wird das
+Druckmuster auf unsinnige oder unverständliche Konstruktionen
+überprüft. Ist dem Druckgenerator etwas suspekt, gibt er eine Feh­
+lermeldung aus, in der die fragliche Situation von seiner Seite aus
+beschrieben wird. Er kann natürlich nicht Ihren Fehler "verstehen".
+Daher müssen Sie unter Umständen eine Fehlermeldung erst inter­
+pretieren, ehe Sie die wahre Ursache erkennen können.
+ Damit Sie einen aufgetretenen Fehler gleich korrigieren können,
+werden Ihnen das Druckmuster und die Fehlermeldungen parallel auf
+dem Bildschirm zum Ändern und Anschauen angeboten. Sie können
+mit dem Editor das Druckmuster ändern und in den Fehlermeldungen
+blättern. Diese Konfiguration wird Paralleleditor genannt. Mit ESC
+'w' wechseln Sie zwischen den beiden Bildschirmhälften.
+
+#on("b")#Suchbedingung#off("b")# Wollen Sie nicht alle Namen ausdrucken, so
+können
+Sie vorher ein Suchmuster einstellen, das nur auf die gewünschten
+Namen zutrifft (wie im Kapitel 5 beschrieben). Der Druckgenerator
+richtet sich immer nach dem aktuell eingestellten Suchmuster und
+druckt nur die ausgewählten Sätze. Wenn Sie zum Beispiel die Na­
+men aller Frauen ausdrucken wollen, stellen Sie im Tastenmodus ein
+Suchmuster ein (das sollten Sie können), das für das Feld 'm/w' die
+Bedingung 'w' enthält. Danach können Sie den Druckgenerator auf­
+rufen. Vergessen Sie nicht, das Suchmuster anschließend wieder zu
+löschen.
+
+#on("b")#Feldnamen abfragen#off("b")# Wenn Sie selber ein Druckmuster
+erstellen,
+wird es häufiger vorkommen, daß Sie die genaue Schreibweise der
+Feldnamen nicht im Kopf haben. Für diesen Zweck definiert EUDAS
+im Editor eine spezielle Tastenkombination.
+ Wenn Sie dort ESC 'F' tippen (großes 'F'), erhalten Sie eine
+Auswahl aller Felder der gerade geöffneten Datei. Sie können sich
+die Namen einfach ansehen, aber auch direkt in den Text des
+Druckmusters übernehmen.
+ Wenn Sie nämlich vor dem Verlassen der Auswahl mit ESC 'q'
+ein Feld ankreuzen, wird anschließend der Name in Anführungs­
+strichen an die Position geschrieben, an der vor dem Aufruf der
+Cursor stand. Auf diese Weise können Sie sich auch das Tippen
+langer Feldnamen vereinfachen.
+ Beachten Sie, daß Sie im Normalfall im Druckmuster die Anfüh­
+rungsstriche wieder entfernen müssen. Die Anführungsstriche dienen
+zur Abgrenzung, wie weit der Feldname geht. Falls der Name Leer­
+zeichen enthält, beachten Sie bitte den Absatz 'Abgrenzung der
+Feldnamen' in Abschnitt 7.4.
+
+
+7.3 Abschnitte
+
+Die Tabellen, die Sie bis jetzt erzeugen können, sehen optisch noch
+nicht sehr gut aus. Es fehlt auf jeden Fall eine vernünftige Über­
+schrift. Um eine Überschrift zu erzeugen, können Sie im Druckmuster
+einen #on("i")#Vorspann#off("i")# definieren, der ganz zu Anfang einmal gedruckt
+wird.
+ Dieser Vorspann wird durch die Anweisung
+
+
+ % VORSPANN
+
+
+eingeleitet (bitte nicht vergessen, daß das '%'-Zeichen für eine
+Anweisung in der ersten Spalte stehen muß). Die folgenden Zeilen
+bis zur 'WIEDERHOLUNG'-Anweisung gehören zum Vorspann. Ein
+Druckmuster für unsere Namensliste mit Überschrift könnte dann so
+aussehen:
+
+
+ % VORSPANN
+ Alle Namen aus der EUDAS-Datei 'adressen'
+ -----------------------------------------
+ % WIEDERHOLUNG
+ ! &Name ! &Vorname !
+
+
+Der Druckgenerator erzeugt mit diesem Druckmuster die gewünschte
+Liste mit Überschrift. Sie können als Vorspann natürlich auch einen
+beliebigen anderen Text verwenden.
+ In einer analogen Weise können Sie die Liste noch durch eine
+waagerechte Linie abschließen, indem Sie einen #on("i")#Nachspann#off("i")# definie­
+ren. Die dafür notwendige Anweisung heißt
+
+
+ % NACHSPANN
+
+
+Die Zeilen nach dieser Anweisung werden gedruckt, nachdem alle
+Sätze bearbeitet worden sind. Das folgende Druckmuster erzeugt
+schon eine sehr schöne Liste:
+
+
+ % VORSPANN
+ Alle Namen aus der EUDAS-Datei 'adressen'
+ -----------------------------------------
+ % WIEDERHOLUNG
+ ! &Name ! &Vorname !
+ % NACHSPANN
+ -----------------------------------------
+
+
+nämlich:
+
+
+ Alle Namen aus der EUDAS-Datei 'adressen'
+ -----------------------------------------
+ ! Wegner ! Herbert !
+ ! Sandmann ! Helga !
+ ! Katani ! Albert !
+ ! Ulmen ! Peter !
+ ! Regmann ! Karin !
+ ! Arken ! Hubert !
+ ! Simmern ! Anna-Maria !
+ ! Kaufmann-Drescher ! Angelika !
+ ! Fuhrmann ! Harald !
+ ! Seefeld ! Friedrich !
+ -----------------------------------------
+
+
+Die drei Teile, aus denen ein Druckmuster bestehen kann (Vorspann,
+Nachspann und Wiederholungsteil), werden #on("i")#Abschnitte#off("i")# genannt. Wie
+Sie später noch sehen werden, haben Abschnitte eine Reihe von
+gemeinsamen Eigenschaften. Ein Abschnitt wird durch eine eigene
+Anweisung eingeleitet und endet, wenn ein anderer Abschnitt be­
+ginnt oder das Druckmuster zu Ende ist. Alle Abschnitte können
+auch weggelassen werden, irgendein Abschnitt muß aber immer
+vorhanden sein. So ist es zum Beispiel möglich, ein Druckmuster zu
+bauen, das nur aus einem Nachspann besteht (Sie werden allerdings
+jetzt noch nicht verstehen können, warum so etwas sinnvoll sein
+kann).
+ Zum Abschluß dieses Kapitels hier noch einmal eine Übersicht
+der bisher vorgestellten Anweisungen:
+
+
+ Anweisung ! Bedeutung
+ ---------------+----------------------------------
+ % VORSPANN ! leitet Vorspann ein
+ % WIEDERHOLUNG ! leitet Wiederholungsteil ein
+ % NACHSPANN ! leitet Nachspann ein
+
+
+
+7.4 Feldmuster
+
+Mit den bis jetzt beschriebenen Möglichkeiten des Druckgenerators
+können Sie schon sehr viel anfangen. Es fehlt aber noch die Mög­
+lichkeit, mehrere Feldinhalte direkt hintereinander zu schreiben,
+egal wie lang diese Inhalte sind. Diese Fähigkeit wird zum Beispiel
+für die anfangs vorgestellte Liste benötigt.
+
+#on("b")#Variable Position#off("b")# Die Feldmuster, die Sie bis jetzt
+kennen, begin­
+nen mit einem '&'-Zeichen und werden immer genau an der Stelle
+gedruckt, an der sie stehen (feste Position). Sie können ein Feld­
+muster aber auch mit '%' beginnen lassen. In diesem Fall kann der
+Inhalt verschoben werden (variable Position), je nachdem, ob vorhe­
+rige Inhalte kürzer oder länger sind.
+ '%' ist wie '&' ein reserviertes Zeichen, kann also nicht direkt
+gedruckt werden. Da '&' und '%' Feldmuster einleiten, heißen sie
+#on("i")#Musterzeichen#off("i")#.
+ Um Feldmuster variabler Position einmal auszuprobieren, soll­
+ten Sie unser bisheriges Druckmuster in der folgenden Weise um­
+schreiben:
+
+
+ % WIEDERHOLUNG
+ &Vorname %Name
+
+
+(Vorspann und Nachspann der Einfachheit halber mal weggelassen).
+Als Ergebnis erhalten wir:
+
+
+ Herbert Wegner
+ Helga Sandmann
+ Albert Katani
+ Peter Ulmen
+ Karin Regmann
+ Hubert Arken
+ Anna-Maria Simmern
+ Angelika Kaufmann-Drescher
+ Harald Fuhrmann
+ Friedrich Seefeld
+
+
+Das Feldmuster '%Name' ist also entsprechend der Länge des Vor­
+namens nach links oder nach rechts gerutscht. Zu beachten ist, daß
+ein Feldmuster mit '%' nicht in der ersten Spalte stehen darf, denn
+dann würde die Zeile als Anweisung angesehen. Ein Feldmuster
+variabler Position wäre ja auch in der ersten Spalte wenig sinnvoll.
+
+#on("b")#Feste Länge#off("b")# Außer den beiden bisher besprochenen einfachen
+Arten (mit '&' oder '%') gibt es noch weitere Ausprägungen von
+Feldmustern für besondere Fälle. Wird ein Feldmuster noch von
+weiteren Musterzeichen gefolgt, dann wird dieses Feldmuster immer
+in der reservierten Länge eingesetzt. Die reservierte Länge reicht
+vom ersten bis zum letzten Musterzeichen. Durch die zusätzlichen
+Musterzeichen wird also ein bestimmter Platz freigehalten.
+ Ersetzt man im obigen Druckmuster '&Vorname' durch
+'&Vorname&&', wird der Effekt des folgenden '%'-Feldes wieder
+aufgehoben, da jetzt für alle Vornamen die gleiche Länge verwendet
+wird (Probieren Sie dies aus).
+ Bei einem solchen Feldmuster mit fester Länge wird der Inhalt
+abgeschnitten, falls er diese Länge überschreitet; ist der Inhalt
+kürzer, wird rechts mit Leerstellen aufgefüllt. Aber auch bei Feld­
+mustern mit variabler Länge (also ohne folgende Musterzeichen)
+kann abgeschnitten werden, nämlich genau dann, wenn der Inhalt so
+lang ist, daß ein folgendes Feld mit fester Position (mit '&' anfan­
+gend) überschrieben würde. Hätten wir also in unserem ersten
+Druckmuster nicht genügend Platz für die Spalten vorgesehen,
+wären einige Namen abgeschnitten worden (probieren Sie es nochmal
+aus, falls es Ihnen nicht schon passiert ist).
+ In einem weiteren Fall werden Feldmuster variabler Länge
+abgeschnitten, nämlich wenn die generierte Zeile die maximale
+Zeilenlänge überschreitet. Die maximale Zeilenlänge richtet sich
+nach dem Dateilimit, das für das Druckmuster eingestellt ist. Nor­
+malerweise ist dies 77, so daß Sie in Normalschrift die Zeilenbreite
+auf einem DIN A4-Blatt nicht überschreiten.
+ Benutzen Sie jedoch breites Papier oder eine schmale Schrift,
+sollten Sie während der Eingabe des Druckmusters ESC ESC tippen
+und das Kommando
+
+
+ limit (135)
+
+
+eingeben. EUDAS nutzt dann die volle Zeilenbreite aus.
+
+#on("b")#Rechtsbündig#off("b")# Sie sind jetzt aber noch nicht zu Ende mit
+den
+Feldmustervariationen. Eine letzte Möglichkeit besteht darin, den
+Inhalt rechtsbündig in ein Feldmuster einzusetzen. Dies hat natür­
+lich nur Sinn bei fester Länge. Man erreicht dies dadurch, daß man
+das Feldmuster mit mehreren Musterzeichen beginnen läßt. So ist
+
+
+ %%Vorname%
+
+
+die rechtsbündige Version von
+
+
+ %Vorname%%
+
+
+Beide Feldmuster sind gleich lang, beim ersten wird jedoch am lin­
+ken Rand aufgefüllt oder abgeschnitten, beim zweiten dagegen am
+rechten Rand.
+
+#on("b")#Zusammenfassung#off("b")# Hier noch einmal eine Zusammenstellung
+aller möglichen Feldmustertypen:
+
+
+ Typ ! Beispiel ! Position ! Länge ! bündig
+ ----+-----------+------------------------------
+ 1 ! &Name ! fest ! variabel ! links
+ 2 ! %Name ! variabel ! variabel ! links
+ 3 ! &Name&&& ! fest ! fest ! links
+ 4 ! %Name%%% ! variabel ! fest ! links
+ 5 ! &&&Name& ! fest ! fest ! rechts
+ 6 ! %%%Name% ! variabel ! fest ! rechts
+
+
+Wir können zusammenfassen:
+#free (0.2)#
+* Feldmuster dienen im Druckmuster dazu, Stellen zu markieren, an
+ denen Inhalte eingesetzt werden sollen.
+#free (0.2)#
+* Feldmuster beginnen mit einem Musterzeichen ('&' oder '%');
+ darauf folgt der Feldname.
+#free (0.2)#
+* Durch '&' wird feste und durch '%' variable Position festgelegt.
+#free (0.2)#
+* Durch zusätzliche Musterzeichen kann eine feste Länge angege­
+ ben werden; mehrere Musterzeichen am Anfang führen zu rechts­
+ bündigem Einsetzen.
+
+#on("b")#Abgrenzung der Feldnamen#off("b")# Als nächstes sollen Sie den Fall
+be­
+trachten, daß Sie einen Namen in der oft auftretenden Form
+
+
+ Name, Vorname
+
+
+schreiben wollen. Die Schwierigkeit liegt in dem Komma, das direkt
+hinter dem Namen folgen soll. Sie könnten versuchen, diese Situa­
+tion im Druckmuster folgendermaßen darzustellen:
+
+
+ % WIEDERHOLUNG
+ &Name, %Vorname
+
+
+In diesem Fall erhalten Sie aber die Fehlermeldung
+
+
+ FEHLER in Zeile 2 bei >>Name,<<
+ diese Abkuerzung ist nicht definiert
+
+
+Wenn Sie sich nicht genau vorstellen können, wie der Druckgenera­
+tor ein Feldmuster liest, wird Ihnen dieser Fehler mysteriös er­
+scheinen, denn 'Name' ist doch als Feld definiert (was eine Abkür­
+zung ist, werden Sie in Kapitel 13 lernen). Den entscheidenden
+Hinweis liefert jedoch das Komma. Offensichtlich hat der Druck­
+generator das Komma als Teil des Feldnamens angesehen.
+ Dies liegt daran, daß ja irgendwann der Feldname in einem
+Feldmuster beendet sein muß. Normalerweise interpretiert der
+Druckgenerator ein Leerzeichen oder Musterzeichen als Ende des
+Namens, alle vorherigen Zeichen gehören mit zum Feldnamen. Wenn
+nun aber nach dem Feldmuster kein Leerzeichen folgen soll (wie in
+unserem Beispiel) oder der Feldname selbst Leerzeichen enthält
+(dies ist ja erlaubt, könnte aber im Druckmuster nie erkannt wer­
+den), muß noch eine zusätzliche Angabe erfolgen.
+ In solchen Fällen kann der Feldname in spitze Klammern einge­
+schlossen werden. Der Druckgenerator sieht den Feldnamen dann bei
+der ersten schließenden Klammer als beendet an, wobei die Klam­
+mern natürlich nicht zum Feldnamen gehören, aber auch nicht ge­
+druckt werden.
+ Das obige Beispiel müßte also richtig so formuliert werden:
+
+
+ % WIEDERHOLUNG
+ &<Name>, %Vorname
+
+
+Wenn Sie dieses Druckmuster ausprobieren, werden Sie sehen, daß
+die Namen tatsächlich in der gewünschten Form erscheinen.
+
+#on("b")#Leerautomatik#off("b")# Es gibt noch eine trickreiche Automatik in
+EUDAS,
+die in manchen Fällen ganz nützlich ist - und zwar in Fällen, in
+denen Sie mehrere Felder als Aufzählung durch Leerzeichen ge­
+trennt drucken wollen. Nehmen wir an, unsere Adreßdatei hätte
+noch ein Feld 'Titel', in das Sie bei Bedarf 'Dr.' oder 'Prof. Dr.'
+eintragen. In der Adresse würden Sie dann angeben:
+
+
+ &Titel %Vorname %Name
+
+
+Wenn der Titel jedoch leer ist, würde ein störendes Leerzeichen vor
+dem Namen bleiben. In einem solchen Fall entfernt EUDAS das Leer­
+zeichen automatisch. Vorbedingung für diese Automatik ist, daß es
+sich um ein Feld variabler Länge handelt und vor dem Feld noch ein
+Leerzeichen steht (außer in Spalte 1).
+
+#on("b")#Aufgabe#off("b")# Sie sollten jetzt die Möglichkeiten des
+Druckgenerators
+soweit kennengelernt haben, daß Sie ein Druckmuster für die zu
+Anfang des Kapitels erwähnte Liste aller Dateiinhalte erstellen
+können. Versuchen Sie dies zunächst allein, ehe Sie die Lösung
+nachschauen.
+
+
+Hier nun die Lösung:
+
+
+ % VORSPANN
+ Vorname Name, Strasse, PLZ Ort, m/w
+ -------------------------------------------------------
+ % WIEDERHOLUNG
+ &Vorname %<Name>, %<Strasse>, %PLZ %<Ort>, %m/w
+
+
+Beachten Sie die spitzen Klammern, die nötig sind, um das Kom­
+ma ohne Zwischenraum anzuschließen.
+
+#on("b")#Beispiel#off("b")# Als letztes Beispiel sollen Sie einen Fall
+betrachten, bei
+dem pro Satz mehr als eine einzelne Listenzeile gedruckt werden
+soll, und zwar sollen Sie einen Brief schreiben, in den der Druck­
+generator die Adressen verschiedener Leute einfügen soll. Die Er­
+stellung von Formbriefen ist eine sehr häufige Anwendung von
+EUDAS. Mit den bisher beschriebenen Konstrukten kann man etwa
+folgendes Druckmuster schreiben:
+
+
+ % WIEDERHOLUNG
+ &Vorname %Name
+ &Strasse
+ &PLZ %Ort
+
+ Lieber &Vorname !
+
+ Ich lade Dich mit diesem Brief zu
+ meiner nächsten Party ein.
+ Bring gute Laune und was zu Essen mit.
+
+ Viele Grüße
+ \#page\#
+
+
+Die letzte Zeile zeigt eine Möglichkeit, von der Sie wahrscheinlich
+öfter Gebrauch machen werden, nämlich Druckersteuerungsanwei­
+sungen in das Druckmuster einzufügen. Die Anweisung '\#page\#'
+wird an den Drucker weitergereicht und bewirkt, daß nach jedem
+Brief eine neue Seite angefangen wird (Sie wollen sicher nicht
+mehrere Briefe auf ein Blatt drucken). Sie können auch andere An­
+weisungen verwenden, z.B. neue Schrifttypen einstellen. Informieren
+Sie sich gegebenenfalls, welche Anweisungen die Textkosmetik zur
+Verfügung stellt.
+
+#on("b")#Ausblick#off("b")# Sie kennen jetzt bereits einen großen Teil der
+Möglich­
+keiten des Druckgenerators. Einige wünschenswerte Fähigkeiten
+fehlen jedoch noch. So wäre es vorteilhaft, wenn abhängig vom
+Inhalt des Feldes 'm/w' die Anrede 'Sehr geehrter Herr' oder 'Sehr
+geehrte Frau' erzeugt werden könnte. Außerdem könnte das im
+Rechner vorhandene Datum automatisch in den Brief übernommen
+werden. Diese Möglichkeiten werden den Kapiteln 12 und 13 be­
+schrieben.
+ Sie sollten diese jedoch erst dann durchlesen, wenn Sie eine
+gewisse Sicherheit im Umgang mit Druckmustern erlangt haben.
+Zuvor sollten Sie die Inhalte dieses Kapitels beherrschen, damit Sie
+EUDAS gut nutzen können.
+
diff --git a/doc/eudas/eudas.hdb.8 b/doc/eudas/eudas.hdb.8
new file mode 100644
index 0000000..83246e9
--- /dev/null
+++ b/doc/eudas/eudas.hdb.8
@@ -0,0 +1,211 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (75)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+8 Was war und was noch kommt
+
+
+
+8.1 Rückblick
+
+So! Wenn Sie bis hierhin gut mitgearbeitet haben, haben Sie die
+erste und wichtigste Etappe beim Erlernen von EUDAS schon ge­
+schafft. Bevor Sie kennenlernen, was für Möglichkeiten Ihnen EUDAS
+sonst noch bietet, wollen wir die wichtigsten Dinge rekapitulieren,
+die Sie gelernt haben sollten.
+
+#on("b")#EUDAS-Dateien#off("b")# Sie sollten wissen, wie EUDAS-Dateien
+aussehen,
+und daß sie sich von normalen Textdateien unterscheiden. Diese
+Unterscheidung sollten Sie immer beachten, denn es gibt Funktio­
+nen, die nur EUDAS-Dateien annehmen (zum Beispiel 'Öffnen'),
+andere, die nur Textdateien annehmen (zum Beispiel 'Textdatei
+erstellen') und solche, die mit beliebigen Arten von Dateien "ohne
+Ansehen der Person" funktionieren (zum Beispiel 'Kopieren vom
+Archiv').
+
+#on("b")#Bedienung#off("b")# Sie sollten wissen, wie man eine Funktion im
+Menü
+aufruft; wie Sie EUDAS die notwendigen Informationen (zum Beispiel
+Dateinamen) mitgeben und wie Sie in besonderen Situationen (Feh­
+ler, Abbruch) reagieren können. Zur problemlosen Bedienung sollten
+Sie auch die jeweilige Statuszeile interpretieren können.
+
+#on("b")#Dateiverwaltung#off("b")# Sie sollten wissen, wie Sie Dateien von
+Archiv­
+disketten holen und dort auch wieder abspeichern können. Dazu ist
+die Dateiauswahl durch Ankreuzen sehr hilfreich. Sie sollten von
+Anfang an darauf achten, daß Sie Ihre Dateien regelmäßig auf dem
+Archiv sichern, damit Sie bei etwaigen Problemen mit Ihrem Rechner
+die Daten nicht verlieren.
+
+#on("b")#Öffnen#off("b")# Sie sollten wissen, daß Sie eine EUDAS-Datei vor
+dem
+Bearbeiten erst öffnen müssen. Weiterhin sollten Sie mit der Ar­
+beitskopie umgehen können, die EUDAS bei Änderungen anlegt.
+Denken Sie daran, Ihre Datei nach Änderungen zu sichern. Sie soll­
+ten auch neue EUDAS-Dateien mit eigener Struktur anlegen können.
+
+#on("b")#Ansehen und Ändern#off("b")# Sie sollten wissen, wie Sie die Daten
+Ihrer
+EUDAS-Dateien am Bildschirm abrufen können - entweder manuell
+oder mit Hilfe eines Suchmusters. Sie sollten Änderungen und Ein­
+fügungen durchführen können.
+
+#on("b")#Drucken#off("b")# Sie sollten wissen, wie Sie die Daten einer
+EUDAS-Datei
+mit Hilfe eines Druckmusters ausdrucken können. Denken Sie daran,
+daß dies ein zweistufiger Vorgang ist (Generierung der Druckdatei -
+Ausgeben an Drucker), den Sie an verschiedenen Stellen beeinflus­
+sen können.
+
+Lesen Sie das entsprechende Kapitel erneut durch, wenn Sie sich bei
+einem Punkt dieser Aufzählung nicht sicher sind. Wichtig ist auch,
+daß Sie die bschriebenen Funktionen selbst am Rechner ausprobiert
+haben.
+ Wenn Sie dies alles geduldig absolviert haben, sind Sie in der
+Lage, EUDAS sinnvoll für Ihre eigenen Probleme einzusetzen. Sie
+sollten jetzt ruhig versuchen, eigene Lösungen zu realisieren. Sicher
+werden Sie dabei erkennen, daß Ihnen noch einige Möglichkeiten
+fehlen. Die Chancen sind aber gut, daß EUDAS Ihnen diese Möglich­
+keiten bietet.
+ Im nächsten Abschnitt erhalten Sie einen Überblick darüber,
+was EUDAS noch zur Verfügung stellt. Dort können Sie sich orien­
+tieren, welche Kapitel Sie lesen sollten, wenn Sie bestimmte Fragen
+haben.
+
+
+8.2 Ausblick
+
+Im zweiten Teil dieses Handbuchs erwarten Sie eine ganze Reihe
+interessanter Themen. Dort werden Erweiterungen und Verallgemei­
+nerungen von Funktionen beschreiben, die Sie bereits kennen. Viele
+Funktionen sind jedoch ganz neu und manchmal auch nicht ganz
+einfach zu beherrschen.
+
+#on("b")#Kapitel 9#off("b")# Das neunte Kapitel befaßt sich mit der
+grundsätzlichen
+Struktur der geöffneten Datei. Sie erfahren, daß Sie mehr als eine
+Datei gleichzeitig öffnen und bearbeiten können. Zum einen können
+Sie gleichartige Dateien verketten oder Dateien über Beziehungen
+koppeln. Insbesondere das Koppeln ist eine wichtige Grundlage für
+viele fortgeschrittene Anwendungen von EUDAS.
+ In diesem Kapitel wird auch beschrieben, wie Sie auf einem
+Mehrplatzsystem von mehreren Plätzen aus auf die gleichen EUDAS-
+Dateien zugreifen können. Die Fähigkeiten von EUDAS auf diesem
+Gebiet erreichen nicht das Niveau von großen Datenbanksystemen,
+sind jedoch einfach anzuwenden und in vielen Fällen nützlich.
+
+#on("b")#Kapitel 10#off("b")# Im zehnten Kapitel erfahren Sie, wie Sie den
+Bildschirm
+übersichtlicher gestalten können, wenn Sie Dateien mit zahlreichen
+Feldern benötigen. Sie können bestimmte Felder auswählen, aber
+auch die Sätze einfach ausschnittweise ansehen.
+ Das Suchmuster besitzt noch viele Fähigkeiten, die im ersten
+Teil nicht zur Sprache gekommen sind. Sie können mehrere Bedin­
+gungen auf verschiedene Weisen miteinander kombinieren. Auch
+einige neue Vergleiche treten auf. Außerdem können Sie mehrere
+Felder eines Satzes miteinander vergleichen.
+ Zum schnellen Überblick steht Ihnen eine Funktion bereit, die
+jeweils einen Satz pro Bildschirmzeile anzeigt. In dieser Übersicht
+können Sie blättern und auch Sätze markieren (ankreuzen), um Sie
+später zu bearbeiten.
+
+#on("b")#Kapitel 11#off("b")# Das elfte Kapitel ist den Funktionen zur
+Bearbeitung
+gewidmet. Dort erfahren Sie, wie Sie eine Datei sortieren können.
+Außerdem können Sie eine Datei ausschnittweise kopieren, wobei Sie
+noch eine Vielzahl von Manipulationsmöglichkeiten haben.
+ Auch das Tragen von mehreren Sätzen in einem Arbeitsgang ist
+möglich. Dabei können Konsistenzbedingungen einer Datei überprüft
+werden.
+ Als letztes erfahren Sie, wie man eine EUDAS-Datei automa­
+tisch nach einer beliebigen Vorschrift ändern kann. Hier, wie bei
+den vorherigen Funktionen, werden Sie zum ersten Mal erkennen,
+wieviel man mit der Programmiersprache ELAN innerhalb von EUDAS
+ohne viel Aufwand machen kann.
+
+#on("b")#Kapitel 12#off("b")# Das nächste Kapitel zeigt Ihnen weitere
+Möglichkeiten
+zum Drucken. Sie können die Druckausgabe vor dem Drucken noch
+mit den Programmen der EUMEL-Textverarbeitung aufbereiten. Auch
+innerhalb der EUMEL-Textverarbeitung können Sie EUDAS aufrufen,
+um Daten aus einer EUDAS-Datei in den Text einzufügen.
+ EUDAS kann auch in mehreren Spalten drucken (zum Beispiel
+für Etiketten). Schließlich wird noch beschrieben, wie Sie lange
+Felder auf mehrere Zeilen aufteilen können und welche speziellen
+Möglichkeiten Sie zur Erzeugung von Tabellen haben.
+
+#on("b")#Kapitel 13#off("b")# Ab hier beginnt die Beschreibung dessen, was
+die
+Ausgabe des Druckgenerators so ungeheuer anpassungsfähig macht:
+die Verwendung der Programmiersprache ELAN.
+ Mit einfachsten ELAN-Elementen können Sie komplizierte For­
+matierungswünsche erfüllen. Dazu können Sie den Inhalt von Feld­
+mustern durch vorherige Bearbeitung und durch die Abfrage von
+Bedingungen manipulieren. Ganze Musterteile können in Abhängig­
+keit von Bedingungen variabel gestaltet werden.
+ Auch der Ablauf von Druckvorgängen kann von Bedingungen
+abhängig gemacht werden. So lassen sich gesteuert Vorspann und
+Nachspann innerhalb des Ausdrucks einfügen und Zwischenüber­
+schriften oder -summen bilden (Gruppenverarbeitung).
+
+#on("b")#Kapitel 14 und 15#off("b")# Für denjenigen, der noch nie mit ELAN zu
+tun
+hatte, werden diese Möglichkeiten sicher nicht ganz einfach zu
+verstehen sein. Obwohl die vorherigen Kapitel viele benutzbare
+Beispiele enthalten, ist zur vollen Ausnutzung ein gewisses Ver­
+ständnis von ELAN notwendig.
+ Dies soll in den Kapitel 14 und 15 vermittelt werden, und zwar
+in dem Umfang, in dem es in EUDAS nötig ist (Sie sollen hier nicht
+zum ELAN-Programmierer ausgebildet werden). Für den ELAN-
+Kenner bieten diese Kapitel sicher nichts Neues, aber sie enthalten
+viele Beispiele und Beschreibungen der Funktionen, die für EUDAS
+wichtig sind.
+ Dabei geht Kapitel 15 weiter auf die Sprachmittel für Zählvor­
+gänge, Auswertungen und statistische Anwendungen ein, während in
+Kapitel 14 die grundlegenden Ausdrücke zur Formulierung von
+Manipulationen besprochen werden.
+
+#on("b")#Kapitel 16#off("b")# Im letzten Kapitel geht es dann wieder
+harmloser zu.
+Hier werden die Funktionen beschrieben, die unter EUDAS zur
+allgemeinen Dateiverwaltung zur Verfügung stehen. Im Grunde sind
+dies alles Funktionen, die vom EUMEL-System zur Verfügung ge­
+stellt werden. EUDAS integriert sie lediglich in ein Menüsystem,
+damit Sie als Benutzer die Funktionen möglichst einfach aufrufen
+können.
+ Aber auch dem erfahrenen EUMEL-Benutzer bieten die Funktio­
+nen einen zusätzlichen Komfort, da auch hier die praktische Aus­
+wahl durch Ankreuzen in allen Funktionen vertreten ist. Außerdem
+wird die Anzahl von Tastendrücken zum Erreichen eines Ziels ver­
+ringert. Daher besteht auch für den "Profi" keine Notwendigkeit,
+grundsätzlich mit einer Kommandoschnittstelle weiterzuarbeiten.
+
+#on("b")#Referenzhandbuch#off("b")# Im Referenzhandbuch sind alle hier
+besproche­
+nen Funktionen noch einmal in einer sehr kurzen, zusammenfassen­
+den und abstrakten Form aufgeführt. Dort sollen Sie nachschlagen,
+wenn Sie eine ganz bestimmte Information suchen und sich mit
+EUDAS bereits auskennen.
+ Sie können jedoch auch ohne das Referenzhandbuch auskommen,
+denn alles, was Sie wissen müssen, steht auch hier im Benutzer­
+handbuch.
+ Das Referenzhandbuch enthält auch einen Teil, der sich spe­
+ziell an den ELAN-Programmierer wendet, der besondere Anwendun­
+gen mit EUDAS realisieren will. Allerdings sollten alle dort be­
+schriebenen Möglichkeiten mit Vorsicht betrachtet werden, da sie im
+Normalfall nicht so abgesichert sind, wie die hier beschriebenen
+Fähigkeiten. Auch sollten Sie mit den Einsatzmöglichkeiten von
+ELAN, wie sie in den Kapitel 11 und 13 beschrieben sind, wirklich
+alle praktischen Probleme erledigen können.
+
diff --git a/doc/eudas/eudas.hdb.9 b/doc/eudas/eudas.hdb.9
new file mode 100644
index 0000000..341feca
--- /dev/null
+++ b/doc/eudas/eudas.hdb.9
@@ -0,0 +1,556 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (83)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+9 Das virtuelle Dateikonzept
+
+
+
+9.1 Konzept
+
+Bisher haben Sie zu einem Zeitpunkt immer nur eine EUDAS-Datei
+bearbeiten können. Wenn Sie zu einer anderen Datei wechseln woll­
+ten, mußten Sie die eine Datei sichern und die andere Datei wieder
+öffnen. Es gibt jedoch Fälle, in denen Beziehungen zwischen mehre­
+ren Dateien bestehen. Daher kann EUDAS auch mit mehreren Dateien
+gleichzeitig umgehen.
+ Es hat jedoch Vorteile, wenn man nur mit einer Datei arbeitet.
+Sie müssen dann nicht immer den Namen der gewünschten Datei
+angeben, wenn Sie eine Funktion ausführen. Dies brauchen Sie nur
+einmal beim Öffnen zu tun - danach ist eindeutig festgelegt, wel­
+che Datei gemeint ist.
+ EUDAS versucht diese Vorteile auch bei mehreren Dateien zu
+erhalten. Die verschiedenen Dateien werden so kombiniert, daß eine
+neue Datei entsteht. Sie arbeiten dann nur mit dieser Datei, die alle
+Daten der Einzeldateien enthält.
+ Damit Sie aber nicht so lange warten müssen, geschieht dieser
+Kombinationsvorgang erst beim Ansehen. Die kombinierte Datei ist
+also nicht wirklich vorhanden, sondern ihre Einzelsätze werden nur
+bei Bedarf erzeugt. Daher heißt diese Gesamtdatei auch #on("i")#virtuelle#off("i")#
+(scheinbare) Datei.
+ Eine Kombination von Dateien ist auf zwei Arten möglich. Sie
+können gleichartige Dateien hintereinander#on("i")#ketten#off("i")#, oder Sie können
+Dateien über gemeinsame Felder #on("i")#koppeln#off("i")#. Beide Methoden können
+auch kombiniert werden.
+
+#on("b")#Änderungen#off("b")# Die virtuelle Datei kann auch verändert werden.
+Die
+Veränderungen werden dann in den entsprechenden Ursprungsda­
+teien vorgenommen. Es ist jedoch nicht immer eindeutig, wie diese
+Änderungen aussehen sollen. Achten Sie daher auf die speziellen
+Regeln, die bei solchen Änderungen gelten, damit Sie die Auswir­
+kungen einer Änderung abschätzen können.
+ Wenn Sie Veränderungen vorgenommen haben, müssen Sie die
+Arbeitskopien anschließend wieder sichern. Denken Sie daran, daß
+EUDAS immer auf unbenannten Kopien arbeitet, wenn Sie ändern
+wollen. Beim Sichern von mehreren Dateien wird Ihnen zu jeder
+Datei einzeln angezeigt, ob sie tatsächlich verändert wurde. Sie
+können dann ebenfalls einzeln entscheiden, ob Sie die Datei sichern
+wollen oder nicht.
+
+
+9.2 Ketten
+
+Wenn Sie einmal EUDAS-Dateien mit mehreren tausend Sätzen er­
+stellen, werden Sie feststellen, daß deren Handhabung recht um­
+ständlich sein kann. Da die Datei sehr groß ist, dauern zum Beispiel
+Kopiervorgänge aufs Archiv viel länger als bei kleinen Dateien.
+ Wenn Sie nun auch noch für jede kleine Änderung die Datei
+vom Archiv holen und anschließend wieder zurückschreiben müssen,
+werden Sie einen Weg suchen, diese Arbeit zu erleichtern. Die ein­
+fachste Möglichkeit wäre, einen schnelleren Rechner zu kaufen. Dies
+ist gleichzeitig aber auch die teuerste.
+
+
+#free (4.5)#
+
+#center#Abb. 9-1 Verkettung von A und B
+
+
+EUDAS ermöglicht es Ihnen nun, die große Datei in mehrere kleine
+aufzuspalten. In der Regel gibt es bei solch großen Dateien ein
+Kriterium, nach dem die Sätze in verschiedene Dateien verteilt
+werden können. Jede einzelne Datei kann nun bequem geändert
+werden.
+ Ein Problem entsteht jedoch, wenn alle Dateien zusammen ver­
+arbeitet werden müssen (zum Beispiel beim Drucken). Für einen
+solchen Vorgang können Sie die kleineren Dateien logisch aneinan­
+derketten.
+ Dies bedeutet für Sie, daß alle kleinen Dateien wie eine große
+Datei wirken. Wenn Sie beim Bewegen in der Datei das Ende einer
+einzelnen Datei erreichen, kommen Sie automatisch an den Anfang
+der nächsten Datei.
+
+#on("b")#Aufruf#off("b")# Damit dies funktioniert, müssen die Dateien
+natürlich
+gleiche Feldstruktur haben. Außerdem ist die Zahl der verkettbaren
+Dateien aus technischen Gründen auf 10 beschränkt.
+ Sie können die Dateien verketten, indem Sie die Funktion
+#free (0.2)#
+
+ K Ketten
+
+#free (0.2)#
+im Menü 'Öffnen' aufrufen.
+
+#on("b")#Änderungen#off("b")# In der virtuellen Datei ist sowohl Einfügen als
+auch
+Ändern erlaubt. Beim Einfügen ist jedoch zu beachten, daß am Ende
+einer Datei nicht angefügt werden kann. Dies liegt daran, daß Sie
+entweder vor dem letzten Satz der einen Datei oder vor dem ersten
+Satz der anderen Datei einfügen. Der Endesatz der einen Datei, der
+normalerweise sichtbar wäre, wird übersprungen.
+ Am Ende der letzten Datei können Sie natürlich anfügen, da
+deren Endemarkierung als Ende der ganzen Datei ja wieder sichtbar
+ist.
+
+
+9.3 Koppeln
+
+Nachdem das Verketten von Dateien noch ganz einfach zu verstehen
+war, kommt jetzt eine Funktion auf Sie zu, die kompliziertere Mög­
+lichkeiten in sich birgt: nämlich das Koppeln.
+ Es kommt häufiger vor, daß sich ein Feld einer Datei auf einen
+bestimmten Satz in einer anderen Datei bezieht. So könnten zum
+Beispiel die Ausleihen einer Bücherei in folgender Datei gespeichert
+sein:
+
+
+ 'Name'
+ 'Vorname'
+ 'Datum'
+ 'Buch-Nr.'
+
+
+Wenn jetzt ein Ausleiher sein Rückgabedatum überschritten hat,
+möchte die Bücherei dem Kunden ein Mahnschreiben schicken. Auf
+diesem Schreiben soll aber nicht die Buch-Nr. erscheinen, sondern
+Autor und Titel des Buches.
+ Diese Sekundärinformationen sind in einer anderen Datei ge­
+speichert, der Bestandskartei:
+
+
+ 'Buch-Nr.'
+ 'Autor'
+ 'Titel'
+ 'Verlag'
+
+
+Alle Dateistrukturen hier sind natürlich zwecks größerer Übersicht­
+lichkeit vereinfacht. Um jetzt dem Kunden das Mahnschreiben zu
+schicken, müssen die Informationen in den beiden Dateien korreliert
+werden.
+
+#on("b")#Aufruf#off("b")# Zuerst wird die Ausleihdatei normal geöffnet. Dazu
+wird dann die Bestandsdatei mit Hilfe der Funktion
+#free (0.2)#
+
+ K Koppeln
+
+#free (0.2)#
+gekoppelt. Dies hat folgenden Effekt:
+ Die Sätze erscheinen normal so, wie sie in der Ausleihdatei
+auftauchen, also für jede Ausleihe genau ein Satz. Dazu erscheint
+aber jeweils die Beschreibung des ausgeliehenen Buches aus der
+Bestandsdatei: die beiden Dateien wurden über das Feld "Buch-Nr."
+gekoppelt.
+ Als Struktur ergibt sich für die kombinierte Datei:
+
+
+ 'Name'
+ 'Vorname'
+ 'Datum'
+ 'Buch-Nr.'
+ 'Titel'
+ 'Autor'
+ 'Verlag'
+
+
+Die Felder der Koppeldatei wurden also noch hinzugefügt.
+
+#on("b")#Koppelfelder#off("b")# Zwei Dinge sind in diesem Zusammenhang
+wichtig:
+Damit der Koppelvorgang ohne allzuviele Vorgaben auskommen kann,
+müssen Felder, über die gekoppelt wird, den gleichen Namen haben
+- und zwar exakt Zeichen für Zeichen. Zum zweiten muß ein solches
+#on("i")#Koppelfeld#off("i")# am Anfang der gekoppelten Datei (in unserem Fall der
+Bestandsdatei) stehen. Dies ist aus technischen Gründen notwendig,
+damit der Koppelvorgang in vernünftiger Geschwindigkeit ablaufen
+kann.
+
+
+#free (7.0)#
+
+#center#Abb. 9-2 Schema des Koppelvorgangs
+
+
+#on("b")#Mehrere Dateien#off("b")# Genau wie beim Ketten ist die Kombination
+der
+Dateien nicht physikalisch, sondern nur scheinbar vollzogen worden.
+Bis zum Limit der maximal geöffneten Dateien (10) können Sie auch
+weitere Dateien dazukoppeln. Die Koppelfelder dieser Dateien kön­
+nen sich jedoch immer nur auf die erste Datei beziehen, also nicht
+auf eine andere Koppeldatei.
+ Dies könnte man in unserem Beispiel ausnutzen. Die Bücherei
+hat sicher auch eine Datei ihrer Mitglieder. Diese könnte etwa so
+aussehen:
+
+
+ 'Name'
+ 'Vorname'
+ 'm/w'
+ 'Strasse'
+ 'PLZ'
+ 'Ort'
+
+
+Diese Datei können wir ebenfalls zur Ausleihdatei dazukoppeln.
+Damit haben wir auch gleich die Quelle gewonnen, aus der wir die
+Anschrift für das Mahnschreiben gewinnen können.
+ Die Kopplung geschieht in diesem Fall über zwei Felder, näm­
+lich 'Name' und 'Vorname'. Damit ein Mitglied eindeutig identifi­
+ziert wird, werden beide Namen gebraucht. Dies berücksichtigt auch
+das Koppelverfahren. Wiederum müssen die Namen exakt mit Namen
+der ersten Datei übereinstimmen.
+ Wenn mehrere Koppelfelder für eine Koppeldatei notwendig sind,
+müssen Sie alle hintereinander stehen. Wäre die Struktur der Mit­
+gliederdatei etwa
+
+
+ 'Name'
+ 'Titel'
+ 'Vorname'
+ 'm/w'
+ 'Strasse'
+ 'PLZ'
+ 'Ort'
+
+
+würde nur über 'Name' gekoppelt, da 'Titel' in der ersten Datei
+nicht vorkommt. Alle weiteren Felder können dann keine Koppelfel­
+der mehr werden. Durch Umstellen der Feldreihenfolge der Koppel­
+datei (durch Umkopieren) oder durch entsprechende Benennung von
+Feldern können Sie immer den gewünschten Effekt erzielen.
+
+
+#free (8.0)#
+
+#center#Abb. 9-3 Aufbau der virtuellen Datei
+
+
+#on("b")#Zusammenfassung#off("b")# An dieser Stelle wollen wir die Ergebnisse
+dieses Abschnitts als Regel zusammenfassen:
+
+#limit (12.0)#
+ Die ersten Felder der Koppeldatei, die wörtlich an be­
+ liebiger Stelle auch in der ersten Datei auftauchen,
+ werden Koppelfelder genannt. Zu einem Satz der ersten
+ Datei wird ein Satz der Koppeldatei gezeigt, der im In­
+ halt der Koppelfelder übereinstimmt.
+#limit (13.5)#
+
+Übersetzt in unser Beispiel heißt dies: 'Buch-Nr.' bzw. 'Name' und
+'Vorname' sind Koppelfelder. Zu einer bestimmten Ausleihe erschei­
+nen die Daten des Buches mit der angegebenen Buch-Nr. bzw. die
+Adresse des Mitgliedes mit den angegebenen Namen.
+
+
+9.4 Auswirkungen des Koppelns
+
+Nachdem Sie nun das Grundprinzip des Koppelns kennen, sollen Sie
+einige Auswirkungen dieses Verfahrens kennenlernen.
+ Ein Beispiel dazu finden Sie in Abb. 9-4. Dargestellt sind je­
+weils die Satznummern und einige Inhalte. Die zweite Zeile in der
+Hauptdatei und die erste in der Koppeldatei stellen das Koppelfeld
+dar.
+
+
+#free (6.5)#
+
+#center#Abb. 9-4 Kombinationen
+
+
+#on("b")#Kombinationen#off("b")# Zuerst muß geklärt werden, was passiert,
+wenn es
+keinen passenden Satz in der Koppeldatei gibt. Zum Beispiel könnte
+eine Buchnummer eingegeben worden sein, die in der Bestandsdatei
+nicht existiert. In diesem Fall zeigt EUDAS für die Felder der Kop­
+peldatei einfach einen leeren Inhalt an (siehe Satz 23 der Haupt­
+datei, es gibt keinen Satz mit 'L' in der Koppeldatei).
+ Wenn umgekehrt zu einem bestimmten Buch keine Ausleihe
+existiert, macht das natürlich nichts - das Buch erscheint nur
+dann, wenn Sie die Bestandsdatei alleine öffnen.
+ Weiterhin kann es passieren, daß es zwei passende Sätze in der
+Koppeldatei gibt. Dies kommt dann vor, wenn zwei Mitglieder glei­
+chen Namen und gleichen Vornamen haben (was gar nicht so selten
+ist). In diesem Fall zeigt EUDAS beide Kombinationen an (siehe
+Satz 23 der Hauptdatei). Die Ausleihe erscheint also zweimal, je­
+weils mit einem anderen Mitglied.
+ Damit man diesen Fall ohne weiteres erkennen kann, führt
+EUDAS bei Kopplungen zwei Nummern: zum einen die normale Satz­
+nummer und zum anderen eine Kombinationsnummer. In dem eben
+besprochenen Fall würde die Satznummer gleichbleiben, die Kombi­
+nationsnummer aber hochgezählt werden. Am Bildschirm wird die
+Kombinationsnummer durch Bindestrich getrennt hinter die Satz­
+nummer geschrieben, wenn Sie Dateien koppeln.
+ Das Durchgehen aller Kombinationen zu einem Satz der Haupt­
+datei passiert aber nur dann, wenn Sie sich mit der Funktion 'Satz
+weiter' in der Datei bewegen. Wenn Sie rückwärts gehen oder auf
+einen bestimmten Satz positionieren, wird immer nur die erste Kom­
+bination angezeigt (Dies hat zum Teil technische Gründe). Beim
+Zurückgehen von Satz 23-1 in dem Beispiel würde also auf Satz
+22-1 positioniert und die Kombination 22-2 übersprungen.
+
+#on("b")#Änderungen#off("b")# Auch wenn Sie Dateien gekoppelt haben, können
+Sie
+immer noch Sätze ändern und einfügen (wenn Sie dies beim Öffnen
+erlaubt haben). Die Auswirkungen der Veränderungen sind jedoch
+nicht mehr ganz so einfach wie bei geketteten Dateien, wo sich die
+Änderungen ja einfach auf den aktuellen Satz bezogen.
+ Als Grundregel gilt, daß Änderungen möglichst wenig Auswir­
+kungen auf die Koppeldateien haben sollen. Das führt dazu, daß
+beim Einfügen eines neuen Satzes oder beim Entfernen eines Satzes
+durch Tragen keine Aktion in der Koppeldatei durchgeführt wird.
+Dies ist auch nicht nötig, denn wenn zum Beispiel ein neuer (zu­
+nächst leerer) Satz eingefügt wird, existiert sowieso noch kein
+passender Satz in der Koppeldatei und die entsprechenden Felder
+bleiben leer. Hingegen darf beim Entfernen eines Satzes der Satz in
+der Koppeldatei nicht entfernt werden, da er ja noch zu einem an­
+deren Satz gehören könnte.
+ Änderungen an den Koppelfeldern können nun zu drei verschie­
+denen Reaktionen führen:
+
+1. Es wird kein Satz der Koppeldatei geändert, sondern nur ein
+ neuer passender Satz gesucht. Dies geschieht immer dann, wenn
+ außer den Koppelfeldern nur leere Inhalte für die Felder der
+ Koppeldatei angegeben sind. Nach dem Ändern oder Einfügen
+ werden dann die Inhalte des neuen Koppelsatzes angezeigt.
+
+ Beispiel: Bei einer Ausleihe geben Sie Name und Vorname des
+ Ausleihers an, nicht aber seine Adresse. Wenn Sie den Satzedi­
+ tor beim Einfügen mit ESC 'q' verlassen, wird die zugehörige
+ Adresse angezeigt (falls der entsprechende Name in der Kop­
+ peldatei vorhanden ist).
+
+2. Es wird ein neuer Satz in der Koppeldatei angefügt. Dies ge­
+ schieht immer dann, wenn die Koppelfelder verändert wurden
+ und die anderen Felder der Koppeldatei nicht leer sind. Da­
+ durch soll verhindert werden, daß die Koppelfelder in einem
+ Satz verändert werden, der vielleicht noch zu einem anderen
+ Satz paßt.
+
+ Beispiel: Sie geben bei einer Ausleihe auch die Adresse mit
+ an. Wenn eine Person mit gleichem Namen und Vornamen bereits
+ existiert, wird die dort gespeicherte Adresse nicht überschrie­
+ ben. Stattdessen wird die zweite Adresse auch in die Koppel­
+ datei eingetragen. Beim nächsten Ansehen bekommen Sie dann
+ zwei Adressen angezeigt. So wird verhindert, daß Sie ungewollt
+ die erste Adresse vernichten.
+
+3. Der Satz in der Koppeldatei wird verändert. Dies geschieht nur
+ dann, wenn die Koppelfelder unverändert geblieben sind, der
+ Rest sich aber geändert hat.
+
+ Beispiel: Sie ändern eine Ausleihe mit der zugehörigen
+ Adresse. Sie geben nur eine neue Straße an und lassen Name
+ und Vorname unverändert. Der Satz in der Koppeldatei enthält
+ anschließend die neue Straße.
+
+Da Koppeldateien keine Sortierung besitzen müssen, werden neue
+Sätze der Koppeldatei immer am Ende angefügt. Dies ist zu beach­
+ten, wenn die Koppeldatei auch allein verwendet werden soll. Ge­
+gebenenfalls müssen Sie die Koppeldatei dann erst sortieren.
+
+
+9.5 Umschalten auf Koppeldatei
+
+Häufig kommt es vor, daß Sie beim Einfügen eines neuen Satzes mit
+gekoppelten Dateien die Verbindung mit einem existierenden Satz
+der Koppeldatei erreichen wollen, aber den notwendigen Inhalt der
+Koppelfelder nicht auswendig wissen.
+ So wollen Sie beim Eingeben einer Ausleihe Name und Vorname
+des Entleihers nicht immer wieder abtippen. Dabei ist auch die
+Gefahr von Eingabefehlern sehr groß. Stattdessen wollen Sie lieber
+erst den Entleiher in der Mitgliederdatei suchen und dessen Namen
+dann automatisch in den Entleihsatz übernehmen.
+ Hierfür bietet Ihnen EUDAS eine Unterstützung an.
+
+#on("b")#Ausführung#off("b")# Während Sie sich in der virtuellen Datei
+befinden,
+können Sie auf eine bestimmte Koppeldatei umschalten, die Sie dann
+wie eine Einzeldatei bearbeiten können. Beim Zurückschalten haben
+Sie dann die Möglichkeit, die Koppelfelder des gefundenen Satzes zu
+übernehmen.
+ Das Umschalten bewirken Sie durch die Tastenkombination ESC
+'K' (großes K) nur im Menü 'Einzelsatz' sowie im Satzeditor beim
+Einfügen und Ändern. An anderen Stellen hat dieser Befehl keine
+Wirkung. Bei mehreren Koppeldateien werden Ihnen die Dateien der
+Reihenfolge nach angeboten. Durch Verneinung aller Fragen können
+Sie die Funktion ohne Wirkung beenden.
+ Haben Sie nun umgeschaltet, wird Ihnen die Koppeldatei dar­
+geboten, als hätten Sie sie allein geöffnet. Sie können die Datei
+auch beliebig ändern (wenn Sie dies beim Öffnen angegeben haben).
+Nur die Anzeige <KOPPEL> in der Bildüberschrift zeigt an, daß Sie
+sich in einer Koppeldatei befinden. Sie können auch Funktionen in
+anderen Menüs aufrufen.
+ Das Zurückschalten geschieht im Menü 'Einzelsatz' mit der
+gleichen Tastenkombination. Alle Einstellungen der virtuellen Datei
+von vorher bis auf die Feldauswahl bleiben erhalten.
+ Wenn Sie nicht im Menü, sondern im Satzeditor (also beim
+Ändern oder Einfügen) umschalten, werden Sie zunächst wieder aus
+dem Satzeditor rausgeworfen. Sie können dann in der Koppeldatei
+den gewünschten Satz aufsuchen (oder neu eintragen). Beim Zurück­
+schalten werden Sie gefragt, ob Sie die Koppelfelder übernehmen
+wollen oder nicht. Danach kehren Sie automatisch wieder in den
+Satzeditor zurück, wobei jetzt die Koppelfelder gegebenenfalls aus­
+gefüllt oder überschrieben sind.
+ Durch erneutes Umschalten können Sie den Vorgang auch für
+weitere Koppeldateien wiederholen.
+ Die Position, die Sie beim Umschalten in der Koppeldatei einge­
+nommen haben, wird bis zum nächsten Umschalten gespeichert. Sie
+kommen dann zunächst wieder auf den gleichen Satz. So können Sie
+die gleichen Koppelfelder wie beim letzten Mal übernehmen, indem
+Sie einfach zweimal ESC 'K' tippen.
+
+#on("b")#Beispiel#off("b")# Der typische Vorgang beim Entleihen würde dann
+wie folgt
+aussehen. Zunächst öffnen Sie die Entleihdatei mit Änderungser­
+laubnis; dann koppeln Sie die Mitgliederdatei und die Bestandsdatei
+dazu.
+ Für eine neue Ausleihe rufen Sie zunächst die Funktion 'Ein­
+fügen' auf. Dann tippen Sie ESC 'K' und schalten auf die Mitglie­
+derdatei um. Dort suchen Sie das Mitglied und schalten wieder zu­
+rück. Existierte das Mitglied noch nicht, können Sie es gleich ein­
+tragen. Beim Zurückschalten übernehmen Sie den Namen des Mit­
+glieds.
+ Dann tragen Sie die Nummer des Buches ein (die müssen Sie nur
+dann suchen, wenn Sie nicht auf dem Buch steht). Das Entleihdatum
+erhalten Sie mit Hilfe der Tastenkombination ESC 'D' (wird im näch­
+sten Kapitel beschrieben).
+ Wollen Sie mehrere Ausleihen für ein Mitglied eintragen, so
+tippen Sie beim nächsten Einfügen einfach zweimal ESC 'K', ohne
+dazwischen eine Positionierung vorzunehmen.
+
+
+9.6 Mehrfachbenutzung
+
+EUDAS ermöglicht es mehreren Benutzern an einem Rechner, mit den
+gleichen Dateien zu arbeiten. Dies ist eigentlich nichts Besonderes,
+denn das EUMEL-System ist ja bereits von Haus aus dazu geeignet.
+Es müssen jedoch einige Schutzvorkehrungen getroffen werden,
+damit dadurch keine Probleme entstehen.
+ Als Grundvoraussetzung für die Mehrfachbenutzung müssen
+EUDAS-Dateien in einer unabhängigen #on("i")#Managertask#off("i")# gespeichert
+sein. Eine Managertask kann man sich durch das Kommando 'global
+manager' einrichten. In dieser Task sollte dann nicht mehr gearbei­
+tet werden.
+ Stattdessen kann sich der Benutzer Dateien aus dieser Mana­
+gertask kopieren und auch wieder dorthin zurückschreiben. Wie Sie
+dies im EUDAS-Menü bewerkstelligen können, wird im Kapitel 16
+beschrieben. Es sei nochmal betont, daß dies eine Methode ist, die
+Sie für beliebige Dateien verwenden können.
+ Im Kapitel 16 ist weiterhin auch beschrieben, wie Sie solche
+Dateien mit #on("i")#Passworten#off("i")# schützen können, so daß sie nicht jeder
+benutzen kann. Schauen Sie bei Bedarf dort nach.
+
+
+#free (7.7)#
+
+#center#Abb. 9-5 Mehrfachbenutzung
+
+
+#on("b")#Konflikte#off("b")# Wir wollen uns jedoch jetzt um ein Problem
+kümmern, das
+bei dieser Art von Mehrfachbenutzung auftritt. Nehmen wir an,
+unsere Bücherei habe zwei Plätze, an denen Entleihen durchgeführt
+werden können. Beide Plätze sollen mit der gleichen Entleihdatei
+arbeiten (wie Sie gleich noch sehen werden und aus anderen Grün­
+den würde man EUDAS für eine solche Bücherei nicht einsetzen -
+wir wollen hier nur das Prinzip illustrieren).
+ Der Ablauf wäre dann folgendermaßen. Jeder Platz kopiert sich
+für eine Entleihe die gemeinsame Datei aus der Managertask, öffnet
+sie, trägt die Entleihe ein und sichert die Datei wieder. Dann wird
+die Datei in die Managertask zurückgeschrieben, wo sie die alte
+Entleihdatei ersetzt.
+ Abgesehen von dem viel zu hohen manuellen Aufwand kann der
+Fall eintreten, daß beide gleichzeitig eine Entleihe bearbeiten.
+Nehmen wir an, beide benutzen die Entleihdatei mit dem symboli­
+schen Inhalt A. Auf Platz 1 kommt noch die Entleihe B, auf Platz 2
+die Entleihe C dazu. Platz 1 will anschließend den Inhalt AB zu­
+rückschreiben, Platz 2 den Inhalt AC.
+ Je nach der zeitlichen Reihenfolge wird nur eine der beiden
+Versionen übrigbleiben, da derjenige, der später zurücksichert, die
+vorherige Version überschreibt. Richtig sollte die endgültige Version
+ABC herauskommen. Unser Beispiel führt jedoch auf jeden Fall zu
+einer fehlerhaften Datei.
+ Grund dafür ist, daß beim Zurückschreiben der ganzen Datei ein
+Platz gesperrt werden muß, während der andere Platz eine Datei
+zum Ändern angefordert hat. Man könnte auch dazu übergehen, nur
+einzelne Sätze zu übertragen; diese Methode wird jedoch von EUDAS
+wegen des hohen Aufwandes nicht unterstützt (daher würde man
+EUDAS eben auch nicht für eine Mehrplatz-Bücherei nehmen).
+ In vielen Fällen reicht das Sperren ganzer Dateien jedoch aus,
+besonders, wenn nicht ganz so häufig an einzelnen Sätzen geändert
+wird. EUDAS bietet dafür neben der notwendigen Sperre auch noch
+eine automatische Versendung der Dateien an.
+
+#on("b")#Manager#off("b")# Es bietet sich an, dieses Kopieren der Dateien
+beim Öff­
+nen (auch Koppeln und Ketten) und Sichern automatisch durchzu­
+führen. Als Voraussetzung dafür müssen Sie EUDAS angeben, mit
+welcher Managertask Sie arbeiten wollen. Dazu dient die Funktion
+#free (0.2)#
+
+ M Manager
+
+#free (0.2)#
+im Menü 'Öffnen'. Sie werden dann nach dem Namen der Task ge­
+fragt. Geben Sie keinen Namen an, wird der Managermodus wieder
+ausgeschaltet. Welche Task als Manager eingestellt ist, sehen Sie in
+der untersten Bildschirmzeile.
+ In der Task, die Sie angeben, muß EUDAS insertiert sein (oder
+in einem Vater), da sonst die Sperre nicht funktioniert.
+ Wenn Sie nun einen solchen Manager angegeben haben, können
+Sie beim Öffnen Dateinamen aus dieser Task angeben. Auch bei ESC
+'z' werden Ihnen alle Namen aus dem Manager mit angeboten. Wenn
+Sie einen solchen Namen angeben, der nicht aus Ihrer eigenen Task
+stammt, wird die Datei vor dem Öffnen automatisch kopiert. Wenn
+Sie angegeben haben, daß Sie die Datei verändern wollen, wird in
+der Managertask eine entsprechende Sperre gesetzt.
+ Wenn Sie die Datei nach Änderungen dann sichern, wird die
+geänderte Kopie zurückgeschrieben. Die Sperre wird jedoch erst
+dann aufgehoben, wenn Sie die Arbeitskopien endgültig löschen.
+ Möchte nun ein anderer Benutzer diese Datei öffnen, während
+Sie sie ändern, kann er dies nur, wenn er sie nicht ändern will.
+Natürlich wird die Datei dann auch nicht wieder zurückgeschickt.
+Will er sie ändern, erhält er eine Fehlermeldung und kann den
+Versuch später wiederholen.
+
+#on("b")#Vorsichtsmaßregeln#off("b")# Bedenken Sie, daß der Schutz nur
+wirksam sein
+kann, wenn Sie diesen Vorgang nicht unter Umgehung der Menü­
+steuerung ausführen. Würden Sie sich zum Beispiel eine Datei vom
+Manager holen (s. Kapitel 16), ohne daß Sie ein Änderungsvorhaben
+anmelden können, können Sie diese Datei ja trotzdem ändern und
+wieder zurückschicken. In diesem Fall hat EUDAS keine Kontrolle
+mehr über die Datei.
+ Aus dem gleichen Grund sollten Sie sich die Managertask auch
+nicht an Ihren Bildschirm holen, denn auch dann könnten Sie ohne
+Kontrolle Änderungen durchführen (zudem kann der Manager wäh­
+rend dieser Zeit nicht auf andere Benutzer reagieren).
+ Nur wenn Sie eine neue Datei im Manager anlegen, müssen Sie
+dies von Hand tun. Dazu erstellen Sie die Datei ganz normal und
+schreiben Sie mit der in Kapitel 16 beschriebenen Funktion zum
+Manager. Sie sollten jedoch darauf achten, daß dort nicht schon
+eine Datei gleichen Namens liegt (EUDAS fragt ja dann, ob über­
+schrieben werden soll).
+
diff --git a/doc/eudas/eudas.hdb.inhalt b/doc/eudas/eudas.hdb.inhalt
new file mode 100644
index 0000000..62134f8
--- /dev/null
+++ b/doc/eudas/eudas.hdb.inhalt
@@ -0,0 +1,133 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+Inhalt
+
+
+
+ Vorwort . . . . . . . . . . . . . . . . . . . i
+ Inhalt . . . . . . . . . . . . . . . . . . . . iii
+
+
+I. Die ersten Schritte
+
+#on("b")#1 Was kann EUDAS ?#off("b")#
+#free (0.2)#
+1.1 Textverarbeitung und Datenverwaltung . . . . . 3
+1.2 EUDAS als Karteikasten . . . . . . . . . . . . 5
+1.3 Drucken . . . . . . . . . . . . . . . . . . . 7
+1.4 Grenzen . . . . . . . . . . . . . . . . . . . 9
+
+#on("b")#2 Installation#off("b")#
+#free (0.2)#
+2.1 Lieferumfang . . . . . . . . . . . . . . . . . 11
+2.2 Single-User . . . . . . . . . . . . . . . . . 12
+2.3 Multi-User . . . . . . . . . . . . . . . . . . 13
+
+#on("b")#3 Ein Beispiel zum Ausprobieren#off("b")#
+#free (0.2)#
+3.1 Start . . . . . . . . . . . . . . . . . . . . 15
+3.2 Daten eintragen . . . . . . . . . . . . . . . 16
+3.3 Daten abfragen . . . . . . . . . . . . . . . . 21
+3.4 Drucken . . . . . . . . . . . . . . . . . . . 22
+3.5 Ergebnis . . . . . . . . . . . . . . . . . . . 24
+
+
+II. Einführung in die Benutzung
+
+#on("b")#4 Umgang mit Dateien und Menüs#off("b")#
+#free (0.2)#
+4.1 EUDAS-Dateien . . . . . . . . . . . . . . . . 27
+4.2 EUDAS-Menüs . . . . . . . . . . . . . . . . . 29
+4.3 Archivmenü . . . . . . . . . . . . . . . . . . 32
+4.4 Dateiverwaltung . . . . . . . . . . . . . . . 37
+4.5 Bedienungsregeln . . . . . . . . . . . . . . . 39
+
+#on("b")#5 Gespeicherte Daten abfragen#off("b")#
+#free (0.2)#
+5.1 Öffnen . . . . . . . . . . . . . . . . . . . . 43
+5.2 Bewegen . . . . . . . . . . . . . . . . . . . 45
+5.3 Suchen . . . . . . . . . . . . . . . . . . . . 46
+5.4 Suchbedingungen . . . . . . . . . . . . . . . 49
+
+#on("b")#6 Daten eingeben und ändern#off("b")#
+#free (0.2)#
+6.1 Neue Datei einrichten . . . . . . . . . . . . 51
+6.2 Sätze einfügen . . . . . . . . . . . . . . . . 52
+6.3 Daten ändern . . . . . . . . . . . . . . . . . 55
+6.4 Arbeitskopie sichern . . . . . . . . . . . . . 56
+
+#on("b")#7 Ausdrucken der Daten#off("b")#
+#free (0.2)#
+7.1 Druckmuster . . . . . . . . . . . . . . . . . 61
+7.2 Aufruf . . . . . . . . . . . . . . . . . . . . 64
+7.3 Abschnitte . . . . . . . . . . . . . . . . . . 67
+7.4 Feldmuster . . . . . . . . . . . . . . . . . . 69
+
+#on("b")#8 Was war und was noch kommt#off("b")#
+#free (0.2)#
+8.1 Rückblick . . . . . . . . . . . . . . . . . . 75
+8.2 Ausblick . . . . . . . . . . . . . . . . . . . 76
+
+
+III. Weitere Möglichkeiten
+
+#on("b")#9 Das virtuelle Dateikonzept#off("b")#
+#free (0.2)#
+9.1 Konzept . . . . . . . . . . . . . . . . . . . 83
+9.2 Ketten . . . . . . . . . . . . . . . . . . . . 84
+9.3 Koppeln . . . . . . . . . . . . . . . . . . . 85
+9.4 Auswirkungen des Koppelns . . . . . . . . . . 89
+9.5 Umschalten auf Koppeldatei . . . . . . . . . . 92
+9.6 Mehrfachbenutzung . . . . . . . . . . . . . . 93
+
+#on("b")#10 Datenabfrage am Bildschirm#off("b")#
+#free (0.2)#
+10.1 Feldauswahl . . . . . . . . . . . . . . . . . 97
+10.2 Satzeditor . . . . . . . . . . . . . . . . . . 98
+10.3 Suchmuster . . . . . . . . . . . . . . . . . . 99
+10.4 Markieren . . . . . . . . . . . . . . . . . . 104
+10.5 Übersicht . . . . . . . . . . . . . . . . . . 105
+
+#on("b")#11 Funktionen zur Bearbeitung#off("b")#
+#free (0.2)#
+11.1 Sortieren . . . . . . . . . . . . . . . . . . 109
+11.2 Kopieren . . . . . . . . . . . . . . . . . . . 112
+11.3 Tragen . . . . . . . . . . . . . . . . . . . . 118
+11.4 Automatische Änderungen . . . . . . . . . . . 121
+
+#on("b")#12 Weitere Möglichkeiten zum Drucken#off("b")#
+#free (0.2)#
+12.1 Anschluß an die Textverarbeitung . . . . . . . 123
+12.2 Spaltendruck . . . . . . . . . . . . . . . . . 126
+12.3 Modi . . . . . . . . . . . . . . . . . . . . . 128
+
+#on("b")#13 Programmierung von Druckmustern#off("b")#
+#free (0.2)#
+13.1 Abkürzungen . . . . . . . . . . . . . . . . . 133
+13.2 Bedingte Musterteile . . . . . . . . . . . . . 141
+13.3 Übersetzung . . . . . . . . . . . . . . . . . 142
+13.4 Gruppen . . . . . . . . . . . . . . . . . . . 144
+
+#on("b")#14 Ausdrücke in ELAN#off("b")#
+#free (0.2)#
+14.1 Was sind Ausdrücke ? . . . . . . . . . . . . . 151
+14.2 Datentypen . . . . . . . . . . . . . . . . . . 152
+14.3 TEXT-Funktionen . . . . . . . . . . . . . . . 156
+14.4 Rechenfunktionen . . . . . . . . . . . . . . . 160
+14.5 Abfragen . . . . . . . . . . . . . . . . . . . 161
+
+#on("b")#15 Anweisungen in ELAN#off("b")#
+#free (0.2)#
+15.1 Variablen und Zuweisungen . . . . . . . . . . 165
+15.2 Weitere Konstruktionen . . . . . . . . . . . . 168
+
+#on("b")#16 Dateiverwaltung mit EUDAS#off("b")#
+#free (0.2)#
+16.1 Dateien im System . . . . . . . . . . . . . . 171
+16.2 Dateien auf dem Archiv . . . . . . . . . . . . 174
+
+
+IV. Anhang
+
+ Register . . . . . . . . . . . . . . . . . . . 181
+
diff --git a/doc/eudas/eudas.hdb.macros b/doc/eudas/eudas.hdb.macros
new file mode 100644
index 0000000..d06e6d1
--- /dev/null
+++ b/doc/eudas/eudas.hdb.macros
@@ -0,0 +1,80 @@
+#*format#
+#limit (13.5)##start (3.5,2.5)##pagelength (21.0)##block#
+#:firsthead (false)#
+#linefeed (1.07)#
+#*macro end#
+#*text#
+#type ("prop10")#
+#linefeed (1.07)#
+#*macro end#
+#*beispiel#
+#type ("12")#
+#linefeed (0.97)#
+#*macro end#
+#*bildschirm#
+#type ("17")#
+#linefeed(0.83)#
+#*macro end#
+#*proc#
+#type ("12")#
+#*macro end#
+#*endproc#
+#free (0.1)#
+#type ("prop10")#
+#linefeed (1.0)#
+#*macro end#
+#*abschnitt ($1,$2,$3)#
+#headodd#
+#on("b")#$1#right#$3 %#off("b")#
+#free (1.0)#
+#end#
+#on("b")##ib(9)#$1#ie(9,"   $3")# $2#off("b")#
+#*macro end#
+#*char($1)#
+$1
+#*macro end#
+#*kapitel ($1,$2,$3,$4)#
+#free (1.3)#
+#"nlq"#
+#type("roman.24")#
+#on("b")##center#$1#off("b")#
+#free (0.2)#
+#type ("roman.18")#
+#on("b")##center#$2 #off("b")#
+#on("b")##center# $3#off("b")#
+#on("b")##center#$4#off("b")#
+#type ("prop10")#
+#free (0.6)#
+#headeven#
+#on("b")#% $2 $3 $4#off("b")#
+#free (1.0)#
+#end#
+#headodd#
+#right##on("b")#%#off("b")#
+#free (1.0)#
+#end#
+#*macro end#
+#*f2#
+#free (0.2)#
+#*macro end#
+#*a ($1)#
+#on("b")#$1.#off("b")# 
+#*macro end#
+#*bsp ($1)#
+#type("12")#$1#type("prop")#
+#*macro end#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/eudas/eudas.hdb.titel b/doc/eudas/eudas.hdb.titel
new file mode 100644
index 0000000..b8cc805
--- /dev/null
+++ b/doc/eudas/eudas.hdb.titel
@@ -0,0 +1,99 @@
+#limit (14.0)#
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#E U D A S
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+
+#free (6.0)#
+#on("b")#EUDAS#off("b")#
+#free (1.0)#
+#on("b")#Anwender-#off("b")#
+#on("b")#Datenverwaltungssystem#off("b")#
+#free (2.0)#
+#on ("b")#VERSION 4#off("b")#
+#free(1.0)#
+#on("u")#                                                    #off("u")#
+#free (0.5)#
+#on("b")#BENUTZERHANDBUCH#off("b")#
+#block#
+#page#
+#free (12.0)#
+Ausgabe Juli 1987
+
+Dieses Handbuch und das zugehörige Programm sind urheberrechtlich
+geschützt. Die dadurch begründeten Rechte, insbesondere der Ver­
+vielfältigung in irgendeiner Form, bleiben dem Autor vorbehalten.
+
+Es kann keine Garantie dafür übernommen werden, daß das Pro­
+gramm für eine bestimmte Anwendung geeignet ist. Die Verantwor­
+tung dafür liegt beim Kunden.
+
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrekt­
+heit und Vollständigkeit der Angaben wird aber keine Gewähr über­
+nommen. Das Handbuch kann jederzeit ohne Ankündigung geändert
+werden.
+
+(c) Copyright 1987 Thomas Berlage
+ Software-Systeme
+ Im alten Keller 3
+#free (0.1)#
+ D-5205 Sankt Augustin 1
+#page#
+#free (7.0)#
+#center##on("b")#I.#off("b")#
+#free (1.0)#
+#center##on("b")#DIE#off("b")#
+#center##on("b")#ERSTEN#off ("b")#
+#center##on("b")#SCHRITTE#off("b")#
+#page#
+#free (7.0)#
+#center##on("b")#II.#off("b")#
+#free (1.0)#
+#center##on("b")#EINFÜHRUNG#off("b")#
+#center##on("b")#IN DIE#off ("b")#
+#center##on("b")#BENUTZUNG#off("b")#
+#page#
+#free (7.0)#
+#center##on("b")#III.#off("b")#
+#free (1.0)#
+#center##on("b")#WEITERE#off("b")#
+#center##on("b")#MÖGLICHKEITEN#off("b")#
+#page#
+#free (7.0)#
+#center##on("b")#IV.#off("b")#
+#free (1.0)#
+#center##on("b")#ANHANG#off("b")#
+
+
+
+
+
+
+
+
diff --git a/doc/eudas/eudas.hdb.vorwort b/doc/eudas/eudas.hdb.vorwort
new file mode 100644
index 0000000..6f7f17c
--- /dev/null
+++ b/doc/eudas/eudas.hdb.vorwort
@@ -0,0 +1,89 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#EUDAS
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+Vorwort
+
+
+
+Lieber EUDAS-Benutzer !
+
+Dieses Handbuch soll Sie bei Ihrer Arbeit mit EUDAS begleiten. Ob­
+wohl EUDAS nicht schwierig zu bedienen ist, gibt es doch eine Reihe
+von Dingen zu lernen, ehe Sie ein EUDAS-Spezialist geworden sind.
+ Um Ihnen diesen Weg möglichst einfach zu machen, ist die
+EUDAS-Dokumentation in zwei Handbücher aufgeteilt. Dies ist das
+#on("b")#Benutzerhandbuch#off("b")#, das Ihnen eine gut lesbare Einführung in alle
+Fähigkeiten von EUDAS bieten soll. Außerdem gibt es noch das
+#on("b")#Referenzhandbuch#off("b")#, das Ihnen zum Nachschlagen und als Hilfe beim
+Programmieren dienen soll.
+
+ Bis Sie EUDAS gut beherrschen, sollten Sie sich also mit dem
+Benutzerhandbuch beschäftigen. Das Benutzerhandbuch ist nochmal
+in drei Teile aufgeteilt, um Ihnen das Lernen zu erleichtern. In
+jedem Teil werden die vorher behandelten Dinge zyklisch wieder
+aufgenommen und auf höherem Niveau erweitert.
+ Der allererste Teil des Handbuchs umfaßt nur drei Kapitel und
+soll Ihnen über den ersten Tag mit EUDAS hinweghelfen. Dort finden
+Sie eine Übersicht, was Sie mit EUDAS anfangen können, wie Sie das
+Programm auf Ihrem Rechner installieren und ein kurzes Beispiel
+zum Ausprobieren.
+ Im zweiten Teil lernen Sie dann die Grundkonzepte von EUDAS
+anhand von zahlreichen Beispielen kennen. Sie sollten die Beispiele
+am Rechner ausprobieren und ihre Bedeutung verstehen. Nach dem
+Durcharbeiten dieses Teils (was höchstens wenige Tage in Anspruch
+nimmt) sind Sie dann in der Lage, EUDAS für eigene Zwecke anzu­
+wenden.
+ Wenn Ihre Ansprüche dann wachsen, sollten Sie sich mit dem
+dritten Teil befassen. Hier erhalten Sie Einblick in weitergehende
+Möglichkeiten von EUDAS. Die einzelnen Kapitel sind relativ unab­
+hängig voneinander, so daß Sie nur die für Sie interessanten
+genauer durchlesen müssen.
+ In Kapitel 8 finden Sie als Orientierung nicht nur eine Wieder­
+holung dessen, was Sie im zweiten Teil gelernt haben sollten, son­
+dern auch eine Übersicht, welche weiteren Möglichkeiten im dritten
+Teil noch beschrieben werden.
+
+ Im Referenzhandbuch finden Sie später, wenn Sie einige Erfah­
+rung gesammelt haben, eine genaue Beschreibung der Wirkungsweise
+aller Funktionen. Um diese zu verstehen, sollten Sie jedoch bereits
+eine grobe Ahnung der Wirkungsweise haben.
+ Als zweites finden Sie im Referenzhandbuch Informationen für
+Programmierer, die EUDAS-Funktionen in eigenen Programmen ver­
+wenden wollen. Dies sollte jedoch in den meisten Fällen nicht not­
+wendig sein, so daß dieser Teil für Spezialisten reserviert bleibt.
+
+ Trotz größter Bemühungen kann das Handbuch natürlich nicht
+frei von Unklarheiten und Fehlern sein. Anregungen und Kritik sind
+daher dringend erwünscht, um diese Dokumentation zu verbessern.
+
+Und nun viel Spaß bei Ihrer Arbeit mit EUDAS !
+
diff --git a/doc/eudas/eudas.ref.1 b/doc/eudas/eudas.ref.1
new file mode 100644
index 0000000..7c66368
--- /dev/null
+++ b/doc/eudas/eudas.ref.1
@@ -0,0 +1,326 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (3)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+Zustände und Bedienung
+
+
+
+1.1 Zustände
+
+EUDAS befindet sich zu jeder Zeit in einem von 11 verschiedenen
+Zuständen. Für jeden Zustand ist festgelegt, welche Eingabetasten
+benutzt werden können und welche Wirkung sie haben. Bestimmte
+Tastenfunktionen führen in einen anderen Zustand. Obwohl für
+jeden Zustand andere Tastenkombinationen gültig sind, wird für die
+gleiche Funktion in jedem Zustand auch die gleiche Taste oder
+Tastenkombination verwendet.
+ Die wichtigsten Tastenfunktionen eines Zustandes werden in
+der #on("i")#Statuszeile#off("i")# am oberen Bildschirmrand angezeigt.
+ Im folgenden sind alle möglichen Zustände als Übersicht be­
+schrieben. Eine Übersicht der Zustandsübergänge enthält Abb. 1-1.
+ Zu jedem Zustand wird die entsprechende Statuszeile darge­
+stellt sowie alle möglichen Tastenfunktionen und ihre Bedeutung.
+
+EUDAS: Öffnen Einzelsatz Gesamtdatei Drucken Dateien Archiv
+
+_____________________________________________________
+
+OBEN Anwahl der nächsthöheren Funktion
+UNTEN Anwahl der nächsttieferen Funktion
+RECHTS Anwahl des nächsten Menüs zur Rechten
+LINKS Anwahl des nächsten Menüs zur Linken
+HOP OBEN Anwahl der ersten Funktion
+HOP UNTEN Anwahl der letzten Funktion
+'1' .. '6' Anwahl des entsprechenden Menüs
+LEER Ausführen der gewählten Funktion
+'Buchstabe' Ausführen der Funktion mit 'Buchstabe' davor
+ESC '?' Hilfestellung zur gewählten Funktion
+ESC ESC Eingabe von ELAN-Kommandos
+
+
+HILFE: Beenden: ESC q Seite weiter: ESC w Seite zurueck: ESC z
+
+_____________________________________________________
+
+ESC 'w' Blättern zur nächsten Seite
+ESC 'z' Blättern zur vorigen Seite
+ESC 'q' Verlassen (Rückkehr in alten Zustand)
+
+
+AUSWAHL: Ankreuzen: 'x' Durchstreichen: 'o' Beenden: ESC q Hilfe: ESC ?
+
+_____________________________________________________
+
+'x' Auswahl ankreuzen
+'o' Ankreuzen rückgängig machen
+LEER Ankreuzen und Auswahl sofort verlassen
+OBEN Zur nächsten Auswahl nach oben
+UNTEN Zur nächsten Auswahl nach unten
+HOP OBEN Zur obersten Auswahl bzw. eine Seite zurück
+HOP UNTEN Zur untersten Auswahl bzw. eine Seite weiter
+HOP RETURN Aktuelle Auswahl wird erste auf der Seite
+ESC '1' zur ersten Auswahl
+ESC '9' zur letzten Auswahl
+ESC 'q' Auswahl verlassen und weitermachen
+ESC '?' Hilfe zur Auswahl
+HOP 'x' alle freien Wahlen ankreuzen
+HOP 'o' alle Kreuze entfernen
+ESC 'h' Auswahl und Funktion abbrechen
+
+
+EINGABE: Bestätigen: RETURN Zeigen: ESC z Abbrechen: ESC h Hilfe: ESC ?
+
+_____________________________________________________
+
+RECHTS zum nächsten Zeichen
+LINKS zum vorigen Zeichen
+HOP RECHTS zum letzten Zeichen
+HOP LINKS zum ersten Zeichen
+RUBOUT Zeichen löschen
+RUBIN Einfügemodus umschalten
+HOP RUBOUT Rest der Zeile löschen
+'Zeichen' Zeichen überschreiben oder einfügen
+RETURN Eingabe abschließen und weitermachen
+ESC '?' Hilfe zur Eingabe
+ESC 'h' Eingabe und Funktion abbrechen
+ESC 'z' Auswahl zeigen (falls in Statuszeile aufgeführt)
+
+
+FRAGE: Bejahen: j,J Verneinen: n,N Abbrechen: ESC h Hilfe: ESC ?
+
+_____________________________________________________
+
+'j', 'J' Frage bejahen
+'n', 'N' Frage verneinen
+ESC '?' Hilfe zur Frage
+ESC 'h' Frage und Funktion abbrechen
+
+
+!!! FEHLER !!! Quittieren: ESC q Hilfe zur Meldung: ESC ?
+
+_____________________________________________________
+
+ESC '?' Hilfe zum Fehler
+ESC 'Taste' Fehler quittieren
+'Taste' Fehler quittieren
+
+
+SATZ ÄNDERN: Abbruch: ESC h Beenden: ESC q Hilfe: ESC ?
+SATZ EINFÜGEN: Abbruch: ESC h Beenden: ESC q Hilfe: ESC ?
+SUCHMUSTER EINGEBEN: Abbruch: ESC h Beenden: ESC q Hilfe: ESC ?
+
+_____________________________________________________
+
+ESC OBEN eine Seite zurück blättern
+ESC UNTEN eine Seite vor blättern
+ESC '?' Hilfe zum Satzeditor
+ESC 'p' ganzen Satz merken (nicht bei Suchmuster)
+ESC 'g' Satz durch gemerkten ersetzen (nicht bei Such­
+ muster)
+ESC 'h' Abbruch der Funktion
+ESC 'D' Tagesdatum schreiben
+ESC 'F' Prüffehler nach Tragen editieren
+ESC 'w' Verlassen und mit nächstem Satz erneut aufrufen
+ (nicht im Suchmuster)
+ESC 'z' Verlassen und mit vorigem Satz erneut aufrufen
+ (nicht im Suchmuster)
+ESC RUBIN Rest der Zeile in neue Zeile umbrechen
+ESC RUBOUT Rest der Zeile löschen
+HOP RUBIN nicht verwenden!
+HOP RUBOUT nicht verwenden!
+
+Weitere Tasten siehe EUMEL-Benutzerhandbuch (Editor).
+
+
+Bitte warten..
+
+_____________________________________________________
+
+keine Tasten erlaubt (außer SV)
+
+
+ZEIGEN: Blättern: HOP OBEN, HOP UNTEN Ende: ESC q Hilfe: ESC ?
+
+_____________________________________________________
+
+HOP OBEN auf erste Zeile bzw. eine Seite zurück
+HOP UNTEN auf letzte Zeile bzw. eine Seite vor
+ESC '?' Hilfe zur Übersicht
+ESC 'h' Abbruch der Funktion
+ESC 'q' Verlassen
+
+
+EDITIEREN: Abbruch: ESC h Verlassen: ESC q Hilfe: ESC ?
+
+_____________________________________________________
+
+ESC 'F' Feldnamen anzeigen und auswählen
+ESC 'h' Abbruch der Funktion
+
+Weitere Tasten siehe EUMEL-Benutzerhandbuch (Editor).
+
+
+Gib Kommando:
+
+_____________________________________________________
+
+Tasten siehe EINGABE.
+
+
+#free (18.5)#
+
+#center#Abb. 1-1 Zustandsübergänge
+
+
+
+
+1.2 Menüs
+
+Menüs dienen zur Auswahl von Funktionen. Sie werden am linken
+Rand des Bildschirms angezeigt. Welches Menü aktiv ist, wird durch
+Markierung des Menünamens in der obersten Bildschirmzeile unter
+allen zur Verfügung stehenden Menüs angezeigt. In jedem Menü ist
+die zuletzt ausgeführte Funktion ebenfalls markiert.
+
+#on("b")#Ausführen von Funktionen#off("b")# Zum Ausführen einer bestimmten
+Funk­
+tion wird mit Hilfe der Cursortasten ein bestimmtes Menü und die
+gewünschte Funktion angewählt. Die Funktion wird dann durch
+Drücken der Leertaste ausgeführt. Alternativ kann auch der vor der
+Funktion stehende Buchstabe gedrückt werden.
+ Die einzelnen Menüs können auch durch Nummern (1 bis 6)
+angewählt werden (absolute Positionierung).
+ Soll eine andere Taste als die Leertaste zum Ausführen ver­
+wendet werden, so kann dies durch die Prozedur 'ausfuehrtaste'
+angegeben werden (s. Abschnitt 10.3).
+ Funktionen, deren Ausführung augenblicklich nicht möglich
+oder nicht sinnvoll ist, werden durch ein vorangestelltes Minuszei­
+chen gekennzeichnet. Sie können zwar angewählt, nicht aber ausge­
+führt werden.
+ Durch ESC '?' wird ein erläuternder Hilfstext zur gerade ange­
+wählten Funktion angezeigt. Näheres dazu s. Abschnitt 1.4.
+ Durch ESC ESC kann ein beliebiges ELAN-Kommando eingegeben
+und ausgeführt werden. Die Eingabe des Kommandos erfolgt in der
+Statuszeile.
+
+
+1.3 Auswahl
+
+Die Auswahlfunktion dient dazu, aus vorhandenen Datei- oder
+Feldnamen in bestimmter Reihenfolge auszuwählen. Die einzelnen
+Namen werden untereinander aufgelistet.
+ Vor jedem Namen ist ein 'o' zum Ankreuzen angegeben. Mit den
+Cursortasten kann der Cursor vor einen bestimmten Namen positio­
+niert werden. Mit 'x' kann dieser Name dann angekreuzt werden. Das
+Ankreuzen kann durch 'o' wieder rückgängig gemacht werden.
+ Die Reihenfolge des Ankreuzens wird durch vorangestellte
+Nummern gekennzeichnet. Die Namen werden von der entsprechenden
+Funktion später in genau dieser Reihenfolge verwendet.
+ Wenn nicht alle Namen auf den Bildschirm passen, kann die
+Darstellung gerollt werden. Ein Teil der Überschrift bleibt dabei
+stehen; am Anfang und am Ende wird jeweils eine Abschlußzeile zur
+Kennzeichnung mitgerollt.
+ Mit ESC '?' kann eine Hilfestellung abgerufen werden. Mit ESC
+'q' wird die Auswahl beendet. Mit ESC 'h' können die Auswahl und
+die in Ausführung befindliche Operation abgebrochen werden.
+
+
+1.4 Hilfe und Dialog
+
+In den meisten Situationen kann durch ESC '?' eine spezifische
+Hilfestellung abgerufen werden. Die Anzeige der Hilfsinformation
+geschieht im rechten Bildschirmteil.
+ Die Texte sind seitenweise aufgebaut. Es wird immer eine Seite
+angezeigt. Mit ESC 'w' bzw. ESC 'z' kann auf die nächste bzw, vorige
+Seite umgeblättert werden. Mit ESC 'q' wird die Hilfestellung wieder
+verlassen und die Situation wiederhergestellt, in der die Hilfe auf­
+gerufen wurde.
+
+#on("b")#Fragen#off("b")# Die meisten Funktionen wickeln zur Eingabe von
+zusätz­
+lichen Parametern oder zum Stellen von Fragen einen Dialog in der
+unteren Schirmhälfte ab. Es gibt zwei Möglichkeiten des Dialogs:
+eine Frage oder die Eingabe eines Textes.
+ Bei einer Frage kann man mit 'j' oder 'n' antworten. Sowohl
+große als auch kleine Buchstaben werden akzeptiert. Mit ESC '?'
+kann eine Hilfsinformation zu der Frage abgerufen werden. ESC 'h'
+bricht die fragende Funktion ab.
+
+#on("b")#Eingabe#off("b")# Bei der Eingabe eines Textes können die üblichen
+Opera­
+tionen zum Editieren in einer Zeile verwendet werden. Die Eingabe
+wird durch RETURN beendet. Auch hier kann durch ESC '?' eine
+Hilfsinformation abgerufen werden. ESC 'h' bricht ebenfalls die fra­
+gende Funktion ab. In einigen Fällen (ersichtlich aus der Statuszei­
+le) kann durch ESC 'z' eine Auswahl der verfügbaren Namen abgeru­
+fen werden.
+
+
+1.5 Editor
+
+Der EUMEL-Editor wird in EUDAS auf zweierlei Weise aufgerufen.
+Zum einen dient er im Satzformular zum Eingeben von Daten und
+Suchmustern. Dort wird er als #on("i")#Satzeditor#off("i")# bezeichnet. Da hier die
+Feldnamen mit berücksichtigt werden müssen, gibt es einige Unter­
+schiede zum normalen Editor.
+ An anderen Stellen wird der Editor ohne Änderungen eingesetzt
+zum Eingeben von Feldnamen oder Mustern. In diesem Fall finden
+Sie die Bedienungshinweise im EUMEL-Benutzerhandbuch.
+
+#on("b")#Satzeditor#off("b")# Beim Ändern, Einfügen und Eingeben des
+Suchmusters
+wird im EUDAS-Formular der Editor aufgerufen. Das Editorfenster
+beschränkt sich auf den rechten Teil des Formulars, der einen Teil
+der Überschrift und die Feldinhalte umfaßt. Im Satzeditor können
+dann die entsprechenden Inhalte eingegeben bzw. verändert werden.
+ Rollen unter Beibehaltung der Korrespondenz ist durch ESC
+OBEN und ESC UNTEN möglich. Diese Funktionen wirken wie bei der
+Anzeige - das Editorfenster wird ebenfalls entsprechend mitgerollt.
+Mit ESC '1' kann wie üblich auf die erste, mit ESC '9' auf die letzte
+Zeile gesprungen werden. Auch diese Funktionen passen die Feld­
+namen entsprechend an.
+ Falls die für ein Feld vorgesehenen Zeilen nicht für den Inhalt
+ausreichen, kann durch ESC RUBIN eine weitere Zeile für dieses Feld
+bereitgestellt werden. ESC RUBIN wirkt wie zweimal HOP RUBIN, die
+Korrespondenz mit den Feldnamen bleibt jedoch gewahrt.
+ Zum Löschen steht ESC RUBOUT zur Verfügung. Es löscht eine
+ganze Zeile, aber nur, wenn für dieses Feld noch andere Zeilen zur
+Verfügung stehen, wird die Zeile tatsächlich vom Bildschirm ent­
+fernt. Im Normalfall bleibt sonst eine Leerzeile für dieses Feld ste­
+hen.
+ Ist die Information für ein Feld auf mehrere Zeilen verteilt, so
+werden diese Zeilen zur Verarbeitung aneinandergehängt. Gegebe­
+nenfalls wird zwischen zwei Zeilen noch ein Leerzeichen eingefügt.
+ Der Editor kann wie üblich mit ESC 'q' verlassen werden. ESC
+'h' bricht die Funktion ab, ohne die erfolgten Änderungen und Ein­
+gaben zu berücksichtigen. Mit ESC 'w' und ESC 'z' kann das Bearbei­
+ten von mehreren Sätzen beschleunigt werden. Durch diese Tasten­
+kombinationen wird der Editor verlassen und die gleiche Operation
+(Ändern/Einfügen) beim nächsten bzw. vorigen Satz wiederholt.
+
+#on("b")#Hinweis#off("b")# Aus technischen Gründen kann das Editorfenster
+gegen­
+über den Feldnamen verschoben werden (durch Rollen mit HOP
+UNTEN zum Beispiel). Dabei geht die sichtbare Korrespondenz zwi­
+schen Feldnamen und Feldinhalten verloren. Ein solcher Fall wird
+durch einen markierten Balken mit entsprechender Meldung ange­
+zeigt. Durch ESC '1' wird das Fenster aber wieder zurechtgerückt.
+ Aus diesem Grund sollte im Satzeditor auf HOP OBEN und HOP
+UNTEN sowie auf RETURN am Ende des Fensters verzichtet werden.
+Auch HOP RUBIN und HOP RUBOUT sollten nicht verwendet werden,
+weil auf diese Weise die Anzahl der Zeilen verändert wird. Eine
+solche Störung kann nicht durch ESC '1' beseitigt werden. Von Hand
+müssen die entsprechenden Zeilen wieder gelöscht oder eingefügt
+werden.
+
+
diff --git a/doc/eudas/eudas.ref.10 b/doc/eudas/eudas.ref.10
new file mode 100644
index 0000000..fbfcf7e
--- /dev/null
+++ b/doc/eudas/eudas.ref.10
@@ -0,0 +1,406 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (97)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+10 Programmierung der Menüs
+
+
+
+10.1 Menüformat
+
+EUDAS verwendet drei verschiedene Strukturen zur Benutzerunter­
+stützung: Menü, Auswahl und Hilfestellung. Ein Menü dient zur
+Auswahl von Funktionen, eine Auswahl bietet Feld- oder Datei­
+namen an und eine Hilfestellung zeigt einen Informationstext.
+ Alle diese Strukturen werden aus einer Initialisierungsdatei
+eingelesen. Die Initialisierungsdatei ist eine normale Textdatei. Ihr
+Format soll in diesem Abschnitt beschrieben werden.
+ Die Strukturen können in beliebiger Reihenfolge in der Initiali­
+sierungsdatei stehen. Jede Struktur wird durch eine spezielle
+Anweisung eingeleitet. Anweisungen beginnen ähnlich wie im
+Druckmuster mit einem Prozentzeichen. Dementsprechend gibt es die
+drei Anweisungen
+
+
+ % MENUE "Name"
+ % AUSWAHL "Name"
+ % HILFE "Gebiet/Name"
+
+
+die jeweils eine Struktur einleiten. Beendet wird eine Definition
+immer mit
+
+
+ % ENDE
+
+
+#on("b")#Menü#off("b")# Für ein Menü wird noch der Text angegeben, der auf
+dem
+Bildschirm erscheinen soll. Er wird durch die Anweisung
+
+
+ % BILD
+
+
+eingeleitet. Danach folgen Zeilen mit dem Bildschirminhalt in der
+gewünschten Größe (die tatsächliche Anzeigegröße wird erst beim
+Aufruf angegeben). Dabei werden die Auswahlpositionen, auf denen
+der Cursor sich bewegen kann, durch ein geschütztes Leerzeichen in
+Spalte 2 festgelegt.
+ Nach der Angabe des Bildes muß für jede mögliche Auswahl­
+position noch eine weitere Angabe gemacht werden. Die Auswahl­
+positionen (oder Felder) werden dabei von oben nach unten durch­
+gezählt. Begonnen wird mit der Nummer 1.
+ Eine Felddefinition hat das Format
+
+
+ % FELD nr "Hilfstext" "Tasten"
+
+
+Die Nummer identifiziert das Feld. Der Hilfstext gibt den Namen der
+Hilfestellung an, die gezeigt werden soll, wenn auf diesem Feld ESC
+'?' gedrückt wird. Die Tasten sind alle Zeichen, die gedrückt werden
+können, um dieses Feld direkt auszuführen.
+ Anschließend an die Felddefinition kann in weiteren Zeilen
+noch ein ELAN-Programm folgen, das bei Auswahl des Feldes aus­
+geführt wird.
+
+#on("b")#Auswahl#off("b")# Für eine Auswahl muß zuerst ein Vorspann angegeben
+werden, der immer in den ersten Bildschirmzeilen der Auswahl an­
+gezeigt wird. Dieser wird durch
+
+
+ % VORSPANN
+
+
+eingeleitet. Danach folgt das Bild. Das Bild setzt sich aus drei Tei­
+len zusammen. Die erste Zeile, in der ein geschütztes Leerzeichen
+vorkommt, bildet den Wiederholungsteil. Diese Zeile wird nachher so
+oft wie nötig mit entsprechenden Inhalten wiederholt, wobei das
+geschützte Leerzeichen als Bindestrich dargestellt wird, auf dem
+sich der Cursor bewegen kann. Die Teile davor und danach werden
+jeweils bei Bedarf mitgerollt.
+ Die Wiederholungszeile darf mehrere geschützte Leerzeichen
+enthalten. Die Inhalte werden dann in mehreren Spalten angezeigt.
+Zu beachten ist, daß vor einem Trennstrich noch mindestens fünf
+Zeichen Platz für eine laufende Nummer bleiben müssen.
+
+#on("b")#Hilfe#off("b")# Der Name einer Hilfestellung setzt sich aus zwei
+Teilen
+zusammen, die durch einen Schrägstrich getrennt werden. Der erste
+Name gibt die Kategorie der Hilfestellung an, der zweite Name den
+Einzeltext. Dies dient dazu, die relativ große Zahl der Hilfstexte
+überschaubar zu machen. Als Beispiel
+
+
+ % HILFE "JA/Allgemein"
+
+
+Eine Hilfestellung besteht einfach aus mehreren Seiten Text. Jede
+Seite wird durch die AnweisungQ
+
+
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q
+
+
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q
+
+
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q
+
+
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈estellung, wobei die Seiten einfach von 1 an durch­
+gezählt werden. Anschließend darf für diese Seite natürlich kein
+Text folgen.
+
+
+10.2 Verwaltung der Menüs
+
+Alle Menüdaten werden intern in Datenräumen gehalten. Dabei sind
+die einzelnen Strukturen getrennt. Mit 'menuedaten einlesen' kön­
+nen Menüdaten aus einer Struktur gelesen und abgespeichert wer­
+den. Existierende Strukturen werden dabei überschrieben, neue
+hinzugefügt.
+ Mit 'menuenamen' können die vorhandenen Strukturen abgefragt
+werden. Mit 'menue loeschen' werden einzelne Strukturen oder alle
+Menüdaten gelöscht. Damit die Datenräume mit den Menüdaten auch
+an Söhne übergeben werden, ist der 'global manager' entsprechend
+geändert. Dies wird im einzelnen durch 'menue manager' bewirkt.
+Der neue Global Manager akzeptiert auch Anfragen von Tasks, die
+nicht Söhne oder Enkel sind.
+
+
+PROC menuedaten einlesen (TEXT CONST dateiname)
+
+ Die in der Datei enthaltenen Strukturen werden eingelesen und
+ abgespeichert. Treten bei diesem Prozeß Fehler auf, so wird
+ eine entsprechende Meldung ins EUMEL-Notizbuch geschrieben
+ und nachher im Paralleleditor angezeigt.
+
+
+THESAURUS PROC menuenamen (INT CONST index)
+
+ Liefert die Namen der Strukturen. Der Index hat folgende Be­
+ deutung:
+ 1: Hilfskategorien
+ 2: Menüs
+ 3: Auswahlen
+ Ist der Index negativ, so werden die Hilfsnamen der entspre­
+ chenden Hilfskategorie geliefert, die im Thesaurus den Index
+ mit umgekehrtem Vorzeichen hat.
+
+
+PROC menue loeschen (TEXT CONST name, INT CONST index)
+
+ Löscht den Namen in dem Thesaurus mit dem angegebenen In­
+ dex, falls dort der Name vorhanden ist.
+
+
+PROC menue loeschen (BOOL CONST hilfen reduzieren)
+
+ Löscht alle Menüdaten. Ist 'hilfen reduzieren' verlangt, wird
+ beim späteren Einlesen der Hilfstexte jeweils nur der erste
+ Text einer Kategorie gespeichert, um Platz zu sparen.
+
+
+PROC global manager
+
+ Geänderter Manager, der die Menüdatenräume in Söhne trans­
+ portiert und Sperren setzen kann. Ersetzt den normalen 'free
+ global manager'. Nur im Multi-User-System vorhanden.
+
+
+PROC menue manager (DATASPACE VAR ds,
+ INT CONST order, phase,
+ TASK CONST order task)
+
+ Eigentliche Manager-Routine. Kann dazu dienen, Managererwei­
+ terungen vorzunehmen. Nur im Multi-User-System vorhanden.
+ Beispiel: der Manager soll nur Aufträge von Söhnen annehmen.
+
+
+ PROC new manager (DATASPACE VAR ds,
+ INT CONST order, phase,
+ TASK CONST order task):
+
+ LET begin code = 4;
+ IF order task < myself OR order = begin code OR
+ order task = supervisor THEN
+ menue manager (ds, order, phase, order task)
+ ELSE
+ errorstop ("kein Sohn")
+ END IF
+
+ END PROC new manager;
+
+ global manager (PROC new manager)
+ (* startet den Manager *)
+
+
+
+10.3 Aufruf
+
+Menüs werden mit der Prozedur 'menue anbieten' aufgerufen. Dabei
+muß neben den Namen ein Fenster übergeben werden, in dem die
+Menüs dann angezeigt werden. Es ist darauf zu achten, daß das
+Fenster groß genug ist, um wenigstens die Auswahlpositionen im
+Bild zu haben.
+ Außerdem muß eine Prozedur übergeben werden, die die einzel­
+nen Funktionen ausführt. Diese Prozedur erhält als Parameter die
+Nummer der ausgewählten Funktion.
+ Mit 'waehlbar' können Auswahlen gesperrt werden. Diese Anga­
+be kann jedoch nicht vor Aufruf von 'menue anbieten' erfolgen, da
+dann alle Sperren erstmal gelöscht werden. Zum Setzen der Sperren
+beim Betreten eines Menüs dient ein besonderer Code, mit dem die
+übergebene Prozedur aufgerufen wird.
+ Eine Auswahl wird mit der Prozedur 'auswahl anbieten' aufge­
+rufen. Diese bekommt ebenfalls ein Fenster übergeben, außerdem
+den Namen einer Hilfestellung, die bei Bedarf aufgerufen werden
+kann. Weiterhin muß eine Prozedur übergeben werden, die die aus­
+zuwählenden Texte erzeugt. Die gewählten Texte können anschlie­
+ßend mit der Prozedur 'wahl' abgefragt werden.
+ Eine Hilfestellung wird durch die Prozedur 'hilfe anbieten'
+ausgegeben. Dabei muß außer dem Namen auch noch ein Fenster
+übergeben werden.
+ Mit 'status anzeigen' kann ein Text in der Statuszeile ausge­
+geben werden. Die Menüprogramme tun dies für ihren Bereich jedoch
+selbst.
+
+
+PROC menue anbieten (ROW 6 TEXT CONST menuenamen,
+ FENSTER VAR f,
+ BOOL CONST esc erlaubt,
+ PROC (INT CONST, INT CONST) interpreter)
+
+ Die angegebenen Menüs werden in dem Fenster 'f' angezeigt.
+ Das Fenster wird nach Beendigung des Menüs als verändert
+ gekennzeichnet. Die Namen der 6 Menüs werden in die Titelzeile
+ aufgenommen. Die Menünamen sollten mit einer Menüidentifika­
+ tion versehen sein, zum Beispiel "EUDAS.Öffnen". Der Text vor
+ dem Punkt wird an den Anfang der Titelzeile gestellt und bei
+ den einzelnen Menünamen unterdrückt. Nicht benötigte Menüs
+ müssen als "" angegeben werden.
+
+ 'esc erlaubt' gibt an, ob mit ESC ESC ein Kommandodialog ge­
+ führt werden kann. Die übergebene Prozedur muß die einzelnen
+ Funktionen ausführen, die als Zahl übergeben werden. Der
+ Interpreter wird im 'disable stop' aufgerufen, daher ist in der
+ Regel ein 'enable stop' erforderlich.
+
+ Die Parameter für 'interpreter' haben folgende Bedeutung:
+ Par. 1: 0 Aufruf zur Initialisierung der Sperren
+ oder anderen Initialisierungen zu Beginn
+ 1..6 Angabe des aktuellen Menüs
+ Par. 2: 1..23 Aufruf der entsprechenden Funktion
+ 0 Eintritt in ein neues Menü (wird vor der
+ Ausgabe dieses Menüs aufgerufen)
+ -1 Verlassen des Menüs
+ -2 Bildschirmupdate (nach Eintritt in das
+ Menü, wenn das Menü ganz ausgegeben ist,
+ oder wenn der Bildschirm nach 'Gib
+ Kommando:' zerstört worden ist)
+
+ FEHLER:
+
+ #on("i")#"Name" existiert nicht.#off("i")#
+ Das angegebene Menü ist nicht vorhanden.
+
+
+PROC waehlbar (INT CONST menuenr, funktionsnr
+ BOOL CONST moeglich)
+
+ Setzt die Funktionssperre der angegebenen Funktion. Muß in­
+ nerhalb von 'menue anbieten' aufgerufen werden. Zu Beginn von
+ 'menue anbieten' sind jeweils alle Funktionen erlaubt.
+
+
+PROC ausfuehrtaste (TEXT CONST taste)
+
+ Setzt die Taste, die Funktionen ausführt. Ist standardmäßig die
+ Leertaste.
+
+ FEHLER:
+
+ #on("i")#falsche Ausfuehrtaste#off("i")#
+ Es muß ein einzelnes Zeichen angegeben werden, das nicht
+ bereits anderweitig verwendet wird.
+
+
+PROC auswahl anbieten (TEXT CONST name, FENSTER CONST f,
+ TEXT CONST hilfe,
+ PROC (TEXT VAR, INT CONST) inhalt)
+
+ Ruft die Auswahl in dem angegebenen Fenster auf. 'hilfe' wird
+ als Hilfestellung verwendet. Die Prozedur 'inhalt' liefert den
+ Text, der an der n-ten Position stehen soll. Wenn keine wei­
+ teren Texte vorhanden sind, muß für alle weiteren Positionen
+ "" geliefert werden.
+
+ FEHLER:
+
+ #on("i")#"Name" existiert nicht.#off("i")#
+ Die angegebene Auswahl ist nicht vorhanden.
+
+
+INT PROC wahl (INT CONST stelle)
+
+ Liefert die Nummer des Textes, der an der n-ten Stelle ausge­
+ wählt wurde. Wurde kein weiterer Text mehr gewählt, so wird 0
+ geliefert.
+
+
+PROC hilfe anbieten (TEXT CONST name, FENSTER CONST f)
+
+ Bietet den Hilfstext in dem angegebenen Fenster an. Existiert
+ die Hilfe innerhalb der angegebenen Kategorie nicht, wird die
+ erste Hilfe der Kategorie angezeigt.
+
+ FEHLER:
+
+ #on("i")#Hilfe existiert nicht#off("i")#
+ Die angegebene Hilfskategorie ist nicht vorhanden.
+
+
+PROC status anzeigen (TEXT CONST zeile)
+
+ Zeigt den angegebenen Text in der obersten Bildschirmzeile an.
+
+
+10.4 Dialog
+
+EUDAS führt den Benutzerdialog in einem Fenster, dessen Größe
+durch 'dialogfenster' eingestellt wird. Das Dialogfenster wird zei­
+lenweise belegt. 'dialog' reserviert eine neue Zeile für eine beliebi­
+ge Ausgabe. Wenn das Fenster voll ist oder überschrieben wurde,
+wird in der ersten Zeile wieder angefangen. Den gleichen Effekt
+kann man mit 'neuer dialog' erreichen.
+ Mit 'ja' kann man im Dialogfenster eine Frage stellen. Als Ant­
+wort kann auch eine Hilfestellung angefordert werden oder die
+Funktion abgebrochen werden. Mit 'editget' kann man nach Auffor­
+derung einen Text eingeben lassen. Dabei stehen die gleichen
+zusätzlichen Möglichkeiten zur Verfügung.
+ Mit 'fehler ausgeben' kann eine durch 'errorstop' erzeugte Feh­
+lermeldung im Dialogfenster angezeigt werden. Der Benutzer muß
+erst eine Taste drücken, ehe er weitermachen kann. Auch hier kann
+eine Hilfestellung zu der Fehlermeldung abgerufen werden.
+
+
+PROC dialogfenster (INT CONST x, y, xl, yl)
+
+ Gibt die Fenstergröße und -position des Dialogfensters an. Für
+ den ganzen Bildschirm müßte (1, 1, 79, 24) angegeben werden.
+
+
+PROC dialog
+
+ Positioniert den Cursor auf die nächste Dialogzeile im Dialog­
+ fenster. Wurde das Fenster verändert, wird das Fenster ge­
+ löscht und auf die erste Zeile positioniert.
+
+
+PROC neuer dialog
+
+ Sorgt dafür, daß der nächste Aufruf von 'dialog' wieder in
+ einem leeren Fenster beginnt.
+
+
+BOOL PROC ja (TEXT CONST frage, hilfe)
+
+ Stellt die angegebene Frage. Es kann die angegebene Hilfsin­
+ formation abgerufen werden. Außerdem wird durch ESC 'h' ein
+ Abbruch (errorstop ("")) erzeugt.
+
+
+PROC editget (TEXT CONST prompt, TEXT VAR eingabe,
+ TEXT CONST res, hilfe)
+
+ Gibt den Text 'prompt' aus und editiert dahinter 'eingabe'. Es
+ kann die angegebene Hilfsinformation abgerufen werden. 'res'
+ gibt an, bei welchen ESC-Folgetasten das Editieren beendet
+ werden soll. In einem solchen Fall wird als Eingabe (ESC + die
+ gedrückte Taste) zurückgeliefert.
+
+
+PROC fehler ausgeben
+
+ Im Dialogfenster wird die letzte Fehlermeldung ausgegeben.
+ Gleichzeitig wird der Fehlerzustand gelöscht. Der Benutzer muß
+ eine Taste drücken, um weiterzumachen. Alternativ kann die
+ Hilfsinformation "FEHLER/" + text (errorcode) abgerufen wer­
+ den.
+
+
diff --git a/doc/eudas/eudas.ref.11 b/doc/eudas/eudas.ref.11
new file mode 100644
index 0000000..48d36c3
--- /dev/null
+++ b/doc/eudas/eudas.ref.11
@@ -0,0 +1,347 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (105)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+11 Programmierung von Anwendungen
+
+
+
+Zur Realisierung eigener EUDAS-Anwendungen mit Hilfe von ELAN-
+Programmen gibt es mehrere Möglichkeiten mit zunehmender Lei­
+stungsfähigkeit, aber auch steigender Komplexität und Fehleranfäl­
+ligkeit. In den folgenden Abschnitten werden die drei wesentlichen
+Methoden vorgestellt. Sie sollten erst dann eine kompliziertere
+Methode in Angriff nehmen, wenn Sie die einfachere beherrschen.
+
+
+11.1 Musterprogramme
+
+Die bevorzugte Methode zur Erstellung eigener Anwendungen unter
+EUDAS ist die Programmierung von Mustern. EUDAS läßt dies bei
+Druckmustern, Kopiermustern und Änderungsmustern zu.
+ In diesem Fall steuert EUDAS den Ablauf des Programms im
+groben automatisch. Die jeweils unterschiedlichen Anweisungen, was
+im einzelnen zu tun ist, werden in ELAN programmiert. Aus dem
+Muster mit diesen zusätzlichen Anweisungen generiert EUDAS dann
+das Programm und führt es mit Hilfe des ELAN-Compilers aus.
+
+#on("b")#Vorteile#off("b")# Diese Methode hat den Vorteil, daß nur die
+minimal not­
+wendigen Anweisungen tatsächlich selbst programmiert werden
+müssen. Dafür reichen bereits geringe ELAN-Kenntnisse vollkommen
+aus. Ein Muster kann relativ schnell erstellt und getestet werden.
+Durch den einfachen Aufbau ist auch die Fehlerwahrscheinlichkeit
+beim Entwickeln geringer als bei anderen Methoden.
+ Daneben lassen sich die Musterprogramme jeweils bequem im
+Menü durch Angabe des Namens oder durch Ankreuzen ausführen,
+also auch durch unbedarfte Benutzer.
+
+#on("b")#Nachteile#off("b")# Nachteil dieser Methode ist, daß jeweils beim
+Aufruf das
+Programm nochmal neu erzeugt und übersetzt werden muß, da die
+Übersetzung auch von der gerade geöffneten Datei abhängt. Dies
+stört besonders bei umfangreichen Druckmustern (auf langsamen
+Rechnern).
+ Zum zweiten wird ein umfangreiches Druckmuster auch bald
+unübersichtlich, da Strukturierungshilfen für größere Programme
+fehlen. Der eigentliche Mustertext ist dann schwer von den zahlrei­
+chen Abkürzungen zu trennen.
+ Als Abhilfe für diese beiden Nachteile bietet es sich an, um­
+fangreichere Abkürzungen bzw. Ausdrücke eingebettet in ein
+ELAN-Paket aus dem Muster herauszunehmen und vorher zu in­
+sertieren.
+ Dadurch fällt zum einen die ständige Neuübersetzung dieser
+Ausdrücke weg, zum anderen ist das eigentliche Muster wieder
+überschaubar. Voraussetzung zur Anwendung eines solchen Musters
+ist dann jedoch, daß das zugehörige Paket in der jeweiligen Task
+bereits vorher übersetzt wurde.
+ Die nachfolgenden Beispiele zeigen, wie dieses Verfahren in der
+Realität aussehen kann.
+
+#on("b")#Beispiel 1#off("b")# In der Schulverwaltung soll ein Kopier- oder
+Ände­
+rungsmuster erstellt werden, das die Versetzung am Schuljahresende
+realisiert. Angenommen wird eine Datei, die alle Schüler enthält.
+Schüler, die nicht versetzt werden, sind vorher im Feld 'Versetzung'
+mit einem beliebigen Text gekennzeichnet worden (zum Beispiel
+'Nachprüfung' o.ä.).
+ Die Versetzung kann auf zweierlei Weise erfolgen: zum einen
+durch automatische Änderung, wenn die alte Version noch auf einer
+Archivdiskette aufgehoben wird, oder durch Kopieren in eine neue
+Datei.
+ Bei beiden Mustern ist die einzige Änderung die Angabe der
+neuen Klasse. Daher bietet es sich an, eine Prozedur 'neue klasse'
+zu definieren, die als Ergebnis die neue Klasse eines Schülers lie­
+fert. Diese Prozedur kann dann im Änderungsmuster wie folgt ver­
+wendet werden:
+
+
+ "Klasse" V neue klasse;
+
+
+Entsprechend läuft die Verwendung im Kopiermuster:
+
+
+ "Name" K f ("Name");
+ "Vorname" K f ("Vorname");
+ "Klasse" K neue klasse;
+ ...
+
+
+Die Prozedur 'neue klasse' muß dann in einem Paket definiert wer­
+den, das etwa folgendes Aussehen haben könnte (spezifische Ände­
+rungen natürlich möglich):
+
+
+ PACKET klassenwechsel DEFINES neue klasse:
+
+ TEXT PROC neue klasse :
+
+ IF f ("Versetzung") = "" THEN
+ klasse um 1 erhoeht
+ ELSE
+ alte klasse ohne zusatz
+ END IF .
+
+ klasse um 1 erhoeht :
+ INT CONST alte klasse := int (f ("Klasse"));
+ IF alte klasse < 9 THEN
+ "0" + text (alte klasse + 1) + zusatz
+ ELSE
+ text (alte klasse + 1) + zusatz
+ END IF .
+
+ zusatz :
+ f ("Klasse") SUB 3.
+
+ alte klasse ohne zusatz :
+ subtext (f ("Klasse"), 1, 2) .
+
+ END PROC neue klasse;
+
+ END PACKET klassenwechsel;
+
+
+Schüler, die versetzt werden, erhalten ihre neue Jahrgangsstufe mit
+dem alten Klassenzusatz zugeteilt. Dabei ist darauf zu achten, daß
+die Klassen 5 bis 9 eine '0' vorangestellt bekommen, damit die
+Sortierung funktioniert.
+ Schüler, die nicht versetzt werden, behalten ihre alte Jahr­
+gangsstufe, allerdings ohne einen Klassenzusatz, der ihnen an­
+schließend manuell zugewiesen werden muß.
+ Zur Benutzung muß das oben angegebene Paket in eine Text­
+datei geschrieben und mit dem Kommando 'insert' fest insertiert
+werden.
+
+#on("b")#Beispiel 2#off("b")# Aus einer Datei mit bibliographischen Einträgen
+sollen
+bestimmte Literaturhinweise gedruckt werden. Der Literaturhinweis
+soll jeweils als Endlostext umbrochen werden. Dafür müssen in einer
+Abkürzung alle Daten verkettet werden. Es sei das folgende ein­
+fache Druckmuster vorgegeben:
+
+
+ % WIEDERHOLUNG
+ % MODUS 3
+ [&<krz>] &titel
+
+ % ABKUERZUNGEN
+ &krz : f ("Kurzbez") . (* z.B. "Lew84" *)
+ &titel : titel lang .
+
+
+Die Prozedur 'titel lang' wird in folgendem Paket definiert:
+
+
+ PACKET bibliographie DEFINES titel lang :
+
+ TEXT VAR puffer; (* verringert Heap-Belastung *)
+
+ TEXT PROC titel lang :
+
+ puffer := f ("Name 1");
+ puffer CAT ", ";
+ puffer CAT f ("Vorname 1");
+ ggf weitere namen;
+ titel kursiv;
+ enthalten in;
+ erscheinungsort und jahr;
+ puffer .
+
+ ggf weitere namen:
+ IF f ("Name 2") <> "" THEN
+ puffer CAT "; ";
+ puffer CAT f ("Name 2")
+ END IF .
+
+ titel kursiv :
+ puffer CAT " \#on (""i"")\#";
+ puffer CAT f ("Titel");
+ puffer CAT "\#off (""i"")\#, " .
+
+ enthalten in :
+ IF f ("in") <> "" THEN
+ puffer CAT " in: ";
+ puffer CAT f ("in");
+ puffer CAT ", "
+ END IF .
+
+ erscheinungsort und jahr :
+ puffer CAT f ("Ort");
+ puffer CAT ", ";
+ puffer CAT f ("Jahr") .
+
+ END PROC titel lang;
+
+ END PACKET bibliographie;
+
+
+Die Puffervariable wird verwendet, um die bei Verwendung des
+Operators '+' entstehende Heapbelastung zu verringern. An diese
+Variable werden nacheinander alle notwendigen Daten mit den ent­
+sprechenden Trennzeichen angehängt.
+ Im Druckmuster wird dieser lange Text dann im Modus 3 auf
+mehrere Zeilen umbrochen, wobei die Einrückung erhalten bleibt. Die
+Druckausgabe kann dann bei Bedarf noch mit 'lineform' bearbeitet
+werden, um einen noch besseren Umbruch zu erzielen.
+
+
+11.2 Dateianwendungen
+
+Die zweite Möglichkeit der Programmierung unter EUDAS besteht
+darin, ELAN-Programme zu schreiben, die EUDAS-Dateien mit Hilfe
+des in Kapitel 6 beschriebenen Datentyps EUDAT manipulieren. Die
+Programmierung gestaltet sich ähnlich wie mit FILEs.
+
+#on("b")#Vorteile#off("b")# Durch dieses Verfahren haben Sie volle Freiheit
+der Pro­
+grammierung. Da lediglich die Struktur der EUDAS-Dateien als
+Datenspeicher verwendet wird, sind sehr viele Anwendungen denk­
+bar.
+ Außerdem können so beliebig viele Dateien gleichzeitig bear­
+beitet werden. Da die Programme nicht auf die virtuelle Datei zu­
+greifen, ist ein Konflikt mit dem aktuellen Zustand von EUDAS
+nahezu ausgeschlossen.
+
+#on("b")#Nachteile#off("b")# Der Nachteil dieses Verfahrens ist, daß viele
+Dinge
+selbst programmiert werden müssen, so zum Beispiel das Durchgehen
+einer Datei. Auch die Hilfsmittel der virtuellen Datei wie Such­
+muster, Koppeln und alle Anwendungen, die auf die virtuelle Datei
+zugreifen, stehen nicht zur Verfügung.
+
+#on("b")#Beispiel 1#off("b")# Die in Abschnitt 6.6 vorgestellte Anwendung als
+Asso­
+ziativspeicher kann als Beispiel für diese Methode dienen.
+
+#on("b")#Beispiel 2#off("b")# Eine EUDAS-Datei (zum Beispiel eine
+Schülerdatei) soll
+in mehrere Dateien aufgespalten werden (zum Beispiel klassen­
+weise). Dies kann durch das folgende Beispielprogramm bewirkt
+werden:
+
+
+ LET
+ klassenfeld = 3,
+ quellname = "Schüler",
+ zielname = "Jahrgang ";
+ ROW 9 EUDAT VAR ziel;
+ EUDAT VAR quelle;
+ SATZ VAR feldnamen;
+
+ quelle oeffnen;
+ zieldateien einrichten;
+ auf satz (quelle, 1);
+ WHILE NOT dateiende (quelle) REP
+ aktuellen satz kopieren;
+ weiter (quelle)
+ END REP .
+
+ quelle oeffnen :
+ oeffne (quelle, quellname);
+ feldnamen lesen (quelle, feldnamen) .
+
+ zieldateien einrichten :
+ INT VAR i;
+ FOR i FROM 1 UPTO 9 REP
+ oeffne (ziel (i), zielname + text (i + 4));
+ feldnamen aendern (ziel (i), feldnamen)
+ END REP .
+
+ aktuellen satz kopieren :
+ SATZ VAR satz;
+ satz lesen (quelle, satz);
+ satz einfuegen (ziel (stufe), satz);
+ weiter (ziel (stufe)) .
+
+ stufe :
+ TEXT VAR klasse;
+ feld lesen (satz, klassenfeld, klasse);
+ int (klasse) - 4 .
+
+
+
+11.3 Integrierte Anwendungen
+
+Die schwierigste Möglichkeit, Anwendungen unter EUDAS zu reali­
+sieren, ist ihre Integration. Ein solches Programm greift selbst auf
+die virtuelle Datei zu, nutzt die Funktionen von EUDAS so weit wie
+möglich und definiert vielleicht sogar ein eigenes Menü.
+
+#on("b")#Vorteile#off("b")# Auf diese Weise können natürlich alle
+Möglichkeiten
+ausgeschöpft werden. Sie können Programme erstellen, die als eine
+natürliche Erweiterung von EUDAS wirken oder EUDAS ganz erset­
+zen.
+
+#on("b")#Nachteile#off("b")# Eine solche Integration ist aber besonders
+schwierig,
+wenn EUDAS und die Erweiterung nebeneinander benutzt werden
+sollen. In diesem Fall hat EUDAS keine komplette Kontrolle der
+Interaktion, so daß leicht undefinierte Zustände möglich sind.
+ Weniger Probleme treten auf, wenn sichergestellt ist, daß nur
+die Anwendung selbst verwendet wird. Auch in diesem Fall ist zu
+beachten, daß EUDAS nicht als Programmierumgebung für Anwen­
+dungssysteme konzipiert wurde und daher nicht immer leicht zu
+benutzen ist.
+ Am einfachsten ist es noch, nur eigene Menüs für eine andere
+Anwendung zu verwenden, da die Menüprozeduren relativ unabhän­
+gig vom Rest sind.
+
+#on("b")#Richtlinien#off("b")# Bei Erweiterungen von EUDAS sind folgende
+Richtlinien zu beachten:
+
+1. Ein Programm, das selber Dateien für die virtuelle Datei öffnen
+ will, sollte vorher prüfen, ob noch eine Datei geöffnet ist und in
+ diesem Fall abbrechen. Beim Multi-User-Betrieb ist nämlich
+ sonst nicht gewährleistet, daß alle Sperren wieder entfernt
+ werden.
+
+2. Ein solches Programm sollte seine eigenen Dateien vor dem
+ Wechsel zu EUDAS selbst wieder sichern und die Arbeitskopien
+ löschen, damit der Ausgangszustand zu Beginn des Programms
+ wiederhergestellt wird.
+
+3. Programme, die Menüs benutzen, sollten nicht unter EUDAS auf­
+ gerufen werden, da sonst eine Beeinflussung der EUDAS-Menüs
+ möglich ist.
+
+An dieser Stelle soll noch einmal von der Erstellung integrierter
+Anwendungen abgeraten werden, wenn es auch andere Möglichkeiten
+gibt, das gegebene Problem mit EUDAS zu lösen. Der hohe Aufwand
+dieser Methode rechtfertigt sich nur in wenigen Fällen.
+ Experimentierfreudige Anwender werden sich durch diese War­
+nung sowieso nicht abhalten lassen. Ihnen sollte aber bewußt sein,
+daß ein solches Vorgehen auf eigene Gefahr stattfindet und kein
+Anspruch auf Beratung oder Fehlerbeseitigung in einem solchen Fall
+besteht.
+
diff --git a/doc/eudas/eudas.ref.2 b/doc/eudas/eudas.ref.2
new file mode 100644
index 0000000..2447897
--- /dev/null
+++ b/doc/eudas/eudas.ref.2
@@ -0,0 +1,830 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (13)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+2 Zusammenstellung der Funktionen
+
+
+
+Im folgenden finden Sie eine Übersicht über alle Menüfunktionen. Zu
+jeder Funktion ist aufgeführt, welche Parameter angegeben werden
+müssen. Die Parameter werden als Text erfragt. Bei einigen Funk­
+tionen können alle möglichen Parameterwerte mit ESC 'z' (Zeigen)
+als Auswahl abgerufen werden. Bei manchen können in der Auswahl
+mehrere Werte angekreuzt werden, die dann nacheinander abgear­
+beitet werden. Welcher Fall zutrifft, ist jeweils aufgeführt.
+
+
+2.1 Menü 'Öffnen'
+
+
+#linefeed (0.5)#
+#on ("b")#O EUDAS-Datei Öffnen#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: EUDAS-Dateiname, mit Zeigen, eine Wahl
+
+Zweck: Stellt eine EUDAS-Datei als aktuelle Arbeitsdatei ein.
+ Falls eine vorher geöffnete Datei verändert wurde,
+ wird sie nach Anfrage gesichert. Falls die zu öffnende
+ Datei noch nicht existiert, kann sie nach Anfrage
+ eingerichtet werden. Dabei müssen dann die Feld­
+ namen angegeben werden.
+
+ Es wird gefragt, ob die Datei geändert werden soll. In
+ diesem Fall wird eine Arbeitskopie hergestellt. Fast
+ alle EUDAS-Funktionen beziehen sich nachher auf die
+ so eingestellte Datei.
+
+ Ist ein Mehrbenutzer-Manager eingestellt, kann auch
+ eine Datei aus dieser Managertask als Parameter
+ angegeben werden. Die Datei wird dann automatisch
+ von dort kopiert und eine Sperre im Manager gesetzt,
+ falls Änderungen vorgenommen werden sollen.
+
+Verweise: Abschnitt 3.2
+ Benutzerhandbuch Abschnitt 5.1 und 9.1
+
+
+#linefeed (0.5)#
+#on("b")#E EUDAS-Datei Ketten#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: EUDAS-Dateiname, mit Zeigen, mehrfache Wahl
+
+Zweck: Falls bereits eine EUDAS-Datei geöffnet ist, kann eine
+ weitere Datei gleicher Struktur logisch angekettet
+ werden. Bei der Bearbeitung werden dann beide Datei­
+ en wie eine zusammenhängende Datei behandelt.
+
+ Die gekettete Datei kann ebenfalls verändert werden,
+ wenn dies beim Öffnen der ersten Datei angegeben
+ wurde. Die angegebene Datei kann auch aus einem
+ Manager stammen.
+
+Verweise: Abschnitt 3.2
+ Benutzerhandbuch Abschnitt 9.2
+
+
+#linefeed (0.5)#
+#on("b")#K EUDAS-Datei Koppeln#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: EUDAS-Dateiname, mit Zeigen, mehrfache Wahl
+
+Zweck: Falls bereits eine Datei geöffnet ist, kann eine andere
+ EUDAS-Datei dazugekoppelt werden. Dazu muß min­
+ destens das erste Feld der zu koppelnden Datei in der
+ bereits geöffneten Datei vorkommen.
+
+ Nach dem Koppeln erscheinen beide Dateien wie eine
+ Datei. Zu jedem Satz der ersten Datei erscheinen je­
+ weils alle Sätze der Koppeldatei, die in dem Koppelfeld
+ übereinstimmen.
+
+ Die gekoppelte Datei kann ebenfalls verändert werden,
+ wenn dies beim Öffnen der ersten Datei angegeben
+ wurde. Die angegebene Datei kann auch aus einem
+ Manager stammen.
+
+Verweise: Abschnitt 3.3
+ Benutzerhandbuch Abschnitt 9.3 und 9.4
+
+
+#linefeed (0.5)#
+#on("b")#S Arbeitskopie Sichern#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Wurde eine EUDAS-Datei geöffnet und verändert, muß
+ zum Schluß die veränderte Arbeitskopie wieder ge­
+ sichert werden. Die Arbeitskopie kann entweder ge­
+ löscht werden, die alte Version ersetzen oder unter
+ einem neuen Namen registriert werden.
+
+ Für jede veränderte Datei wird zunächst erfragt, ob
+ die alte Version überschrieben werden soll. Dies ist
+ der Normalfall. Bei Verneinung dieser Frage muß ein
+ neuer Name für die Arbeitskopie angegeben werden.
+
+ Zum Schluß wird erfragt, ob alle Arbeitskopien ge­
+ löscht werden sollen (Normalfall: ja). Anderenfalls
+ bleiben die Dateien weiter geöffnet.
+
+Verweise: Abschnitt 3.5
+ Benutzerhandbuch Abschnitt 6.4
+
+
+#linefeed (0.5)#
+#on("b")#N Notizen ansehen/ändern#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Zu jeder EUDAS-Datei kann als Notiz ein beliebiger
+ Text gespeichert werden. Dieser Text der aktuellen
+ Datei wird mit dieser Funktion im Editor angezeigt
+ und kann verändert werden, wenn eine Arbeitskopie
+ angelegt wurde. Anderenfalls werden etwaige Verän­
+ derungen einfach ignoriert.
+
+Verweise: Abschnitt 3.1
+
+
+#linefeed (0.5)#
+#on("b")#F Feldstruktur ändern#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Mit dieser Funktion können neue Felder an die aktu­
+ elle Datei angefügt werden. Außerdem lassen sich
+ Feldnamen und Feldtypen ändern. Die Feldtypen be­
+ stimmen die Behandlung eines Feldes beim Suchen oder
+ Sortieren (z.B. von Zahlen).
+
+ Zunächst wird erfragt, ob neue Feldnamen angefügt
+ werden sollen. Diese können dann im Editor eingege­
+ ben werden. Danach wird gefragt, ob Feldnamen oder
+ Feldtypen geändert werden sollen (neu angefügte
+ Felder erhalten erst einmal den Typ TEXT). Falls die
+ Frage bejaht wird, können in einer Auswahl die zu
+ ändernden Felder angekreuzt werden. Für jedes ange­
+ kreuzte Feld werden dann der Name und der Typ zum
+ Überschreiben angeboten.
+
+Verweise: Abschnitt 3.1
+ Benutzerhandbuch Abschnitt 11.1
+
+
+#linefeed (0.5)#
+#on("b")#P Prüfbedingungen ansehen/ändern#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Beim Tragen in eine EUDAS-Datei können Bedingungen
+ für die zu tragenden Sätze überprüft werden. Diese
+ Bedingungen für die aktuelle Datei können mit dieser
+ Funktion angezeigt und, falls erlaubt, auch geändert
+ werden.
+
+Verweise: Abschnitt 3.1 und 4.4
+ Benutzerhandbuch Abschnitt 11.3
+
+
+#linefeed (0.5)#
+#on("b")#M Mehrbenutzer Manager einstellen#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Managertaskname, kein Zeigen
+
+Zweck: EUDAS kann beim Öffnen eine Datei von einer anderen
+ Task des Systems kopieren. Dadurch können mehrere
+ Benutzer kontrolliert auf die gleiche Datei zugreifen.
+ Wenn diese Möglichkeit verwendet werden soll, muß
+ mit dieser Funktion zunächst die in Frage kommende
+ Managertask angegeben werden.
+
+Verweise: Abschnitt 3.7
+ Benutzerhandbuch Abschnitt 9.6
+
+
+2.2 Menü 'Einzelsatz'
+
+
+#linefeed (0.5)#
+#on("b")#W Weiter#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Geht einen Satz weiter in der aktuellen Datei - falls
+ eine Suchbedingung eingestellt ist, weiter zum näch­
+ sten ausgewählten Satz.
+
+Verweise: Abschnitt 4.2
+ Benutzerhandbuch Abschnitt 5.2
+
+
+#linefeed (0.5)#
+#on("b")#Z Zurück#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Geht einen Satz zurück in der aktuellen Datei - falls
+ eine Suchbedingung eingestellt ist, zurück zum vori­
+ gen ausgewählten Satz.
+
+Verweise: Abschnitt 4.2
+ Benutzerhandbuch Abschnitt 5.2
+
+
+#linefeed (0.5)#
+#on("b")#N Auf Satz Nr. ..#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Positioniert auf einen bestimmten Satz der aktuellen
+ Datei, dessen Satznummer eingegeben werden muß, und
+ zwar unabhängig, ob der Satz durch die Suchbedingung
+ ausgewählt wird oder nicht. Trifft die eingestellte
+ Suchbedingung nicht auf den Satz zu, erscheint
+ 'SUCH-' in der Überschrift. Existiert die eingegebene
+ Satznummer nicht, positioniert EUDAS hinter den
+ letzten Satz der Datei.
+
+Verweise: Benutzerhandbuch Abschnitt 5.2
+
+
+#linefeed (0.5)#
+#on("b")#S Suchbedingung Setzen#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Es kann eine neue Suchbedingung für die aktuelle
+ Datei eingegeben werden, bzw. eine vorher eingestellte
+ Suchbedingung wird zum Ändern angeboten. Die Such­
+ bedingung wird in Form eines Suchmusters in das
+ Satzformular geschrieben.
+
+ Die eingestellte Suchbedingung wird beim Positionieren
+ und bei allen Bearbeitungsfunktionen beachtet.
+
+Verweise: Abschnitt 4.2
+ Benutzerhandbuch Abschnitt 5.3, 5.4 und 10.3
+
+
+#linefeed (0.5)#
+#on("b")#L Suchbedingung Löschen#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Die eingestellte Suchbedingung wird wieder gelöscht.
+
+Verweise: Abschnitt 4.2
+ Benutzerhandbuch Abschnitt 5.3
+
+
+#linefeed (0.5)#
+#on ("b")#M Markierung umkehren#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Mit dieser Funktion können einzelne Sätze zur späte­
+ ren Bearbeitung markiert werden. Falls der aktuelle
+ Satz bereits markiert ist, wird die Markierung wieder
+ entfernt, ansonsten wird er markiert.
+
+ Wenn mindestens ein Satz markiert ist, beachten die
+ Bearbeitungsfunktionen nur die markierten Sätze. So
+ kann eine manuelle Auswahl durchgeführt werden. Die
+ Markierung bleibt nur bis zum Sichern bestehen. Sie
+ ist keine permanente Eigenschaft einer EUDAS-Datei.
+
+Verweise: Abschnitt 4.2
+ Benutzerhandbuch Abschnitt 10.4
+
+
+#linefeed (0.5)#
+#on ("b")#E Datensatz Einfügen#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Mit dieser Funktion wird vor dem aktuellen Satz ein
+ leerer Satz eingefügt, für den anschließend die Feld­
+ inhalte im Satzformular eingetragen werden können.
+
+Verweise: Abschnitt 3.4
+ Benutzerhandbuch Abschnitt 6.2 und 10.2
+
+
+#linefeed (0.5)#
+#on ("b")#A Datensatz Ändern#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Die Inhalte des aktuellen Satzes werden im Satzformu­
+ lar zum Ändern angeboten.
+
+Verweise: Abschnitt 3.4
+ Benutzerhandbuch Abschnitt 6.3 und 10.2
+
+
+#linefeed (0.5)#
+#on ("b")#T Datensatz Tragen#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: EUDAS-Dateiname, mit Zeigen, eine Wahl
+
+Zweck: Mit dieser Funktion kann der aktuelle Satz in eine
+ anderen EUDAS-Datei gleicher Struktur transportiert
+ werden. In der Zieldatei wird er am Ende angefügt.
+
+Verweise: Abschnitt 4.4
+ Benutzerhandbuch Abschnitt 6.3
+
+
+#linefeed (0.5)#
+#on ("b")#H Datensatz Holen#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: EUDAS-Dateiname, mit Zeigen, eine Wahl
+
+Zweck: Mit dieser Funktion kann der letzte Satz einer ande­
+ ren Datei vor dem aktuellen Satz eingefügt werden,
+ sofern die Struktur gleich ist. Damit kann ein vorher­
+ gegangenes Tragen rückgängig gemacht werden.
+
+Verweise: Abschnitt 4.4
+ Benutzerhandbuch Abschnitt 6.3
+
+
+#linefeed (0.5)#
+#on ("b")#F Feldauswahl#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Die Felder der aktuellen Datei werden in einer Aus­
+ wahl angeboten. Am Bildschirm werden danach nur die
+ ausgewählten Felder in der gewählten Reihenfolge
+ dargestellt. Die Auswahl hat jedoch nur Auswirkung
+ auf die Darstellung am Bildschirm, anderen Funktionen
+ stehen nach wie vor alle Felder zur Verfügung. Die
+ Auswahl gilt bis zum Sichern, sie wird also nicht mit
+ der Datei abgespeichert.
+
+Verweise: Abschnitt 4.1
+ Benutzerhandbuch Abschnitt 10.1
+
+
+2.3 Menü 'Gesamtdatei'
+
+
+#linefeed (0.5)#
+#on ("b")#K Satzauswahl Kopieren#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: EUDAS-Dateiname, mit Zeigen, eine Wahl
+ Name Kopiermuster, ohne Zeigen
+
+Zweck: Mit dieser Funktion werden die ausgewählten bzw.
+ markierten Sätze der aktuellen Datei in eine andere
+ Datei kopiert. Welche Felder kopiert werden sollen und
+ in welcher Reihenfolge, wird durch ein Kopiermuster
+ festgelegt. Dieses Kopiermuster kann benannt werden
+ oder unbenannt nur für ein Mal erstellt werden. Wird
+ das Kopiermuster neu erstellt, wird ein Standard-
+ Kopiermuster zum Ändern angeboten.
+
+Verweise: Abschnitt 4.4
+ Benutzerhandbuch Abschnitt 11.2
+
+
+#linefeed (0.5)#
+#on ("b")#T Satzauswahl Tragen#off("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: EUDAS-Dateiname, mit Zeigen, eine Wahl
+
+Zweck: Transportieren der ausgewählten bzw. markierten
+ Sätze in eine andere Datei gleicher Struktur. Die Sätze
+ werden in der Zieldatei am Ende eingefügt.
+
+Verweise: Abschnitt 4.4
+ Benutzerhandbuch Abschnitt 11.3
+
+
+#linefeed (0.5)#
+#on ("b")#V Satzauswahl Verändern#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Name Änderungsmuster, mit Zeigen, mehrfache Wahl
+
+Zweck: Bearbeiten der ausgewählten bzw. markierten Sätze
+ der aktuellen Datei nach Vorgabe einer Änderungs­
+ vorschrift.
+
+Verweise: Abschnitt 4.4
+ Benutzerhandbuch Abschnitt 11.4
+
+
+#linefeed (0.5)#
+#on ("b")#U Übersicht Satzauswahl#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Anzeige aller ausgewählten Sätze in einem Über­
+ sichtsformat mit einem Satz pro Bildschirmzeile. Die
+ Felder, die in der Übersicht angezeigt werden sollen,
+ können vorher ausgewählt werden. In der Übersicht ist
+ Blättern und Markieren von Sätzen möglich.
+
+Verweise: Abschnitt 4.1
+ Benutzerhandbuch Abschnitt 10.5
+
+
+#linefeed (0.5)#
+#on ("b")#S Aktuelle Datei Sortieren#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Sortieren der aktuellen Datei in beliebiger Reihenfolge
+ auf- oder absteigend. Zum Sortieren muß eine Ar­
+ beitskopie angelegt sein. Die Feldreihenfolge, in der
+ sortiert werden soll, wird vorher erfragt.
+
+Verweise: Abschnitt 4.3
+ Benutzerhandbuch Abschnitt 11.1
+
+
+#linefeed (0.5)#
+#on ("b")#L Alle Markierungen Löschen#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Löschen aller Markierungen der aktuellen Datei.
+
+Verweise: Abschnitt 4.2
+ Benutzerhandbuch Abschnitt 10.4
+
+
+2.4 Menü 'Drucken'
+
+
+#linefeed (0.5)#
+#on ("b")#D Satzauswahl Drucken#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Name Druckmuster, mit Zeigen, mehrfache Wahl
+
+Zweck: Ausdruck des Inhalts der ausgewählten oder markier­
+ ten Sätze in druckbarer Form nach Vorgabe eines
+ Druckmusters. Die Ausgabe kann automatisch zum
+ Drucker geschickt werden oder erst in einer Datei
+ zwischengespeichert werden.
+
+Verweise: Kapitel 5
+ Benutzerhandbuch Abschnitt 7.1 und 7.2
+
+
+#linefeed (0.5)#
+#on ("b")#R Richtung Druckausgabe#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Mit dieser Funktion kann festgelegt werden, ob die
+ Druckausgabe automatisch zum Drucker geschickt wird,
+ in eine bestimmte Datei oder in eine automatisch
+ eingerichtete Datei geschrieben wird.
+
+ Die Angabe einer bestimmten Datei gilt nur für den
+ nächsten Druckvorgang. Sie muß also gegebenenfalls
+ wieder neu eingestellt werden.
+
+Verweise: Abschnitt 5.2
+ Benutzerhandbuch Abschnitt 7.2 und 12.1
+
+
+#linefeed (0.5)#
+#on ("b")#E Textdatei Editieren#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Name Textdatei, mit Zeigen, mehrfache Wahl
+
+Zweck: Aufruf des EUMEL-Editors zum Erstellen und Ändern
+ von Druckmustern und Änderungsmustern sowie zum
+ Ansehen der Druckausgabe.
+
+Verweise: Benutzerhandbuch Abschnitt 7.2
+
+
+#linefeed (0.5)#
+#on ("b")#A Textdatei Ausdrucken#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Name Textdatei, mit Zeigen, mehrfache Wahl
+
+Zweck: Mit dieser Funktion kann eine Textdatei oder die
+ zwischengespeicherte Ausgabe des Druckens einer
+ EUDAS-Datei zum Drucker geschickt werden.
+
+Verweise: Benutzerhandbuch Abschnitt 7.2
+
+
+#linefeed (0.5)#
+#on ("b")#N Textdatei Nachbearbeiten#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Name Textdatei, mit Zeigen, mehrfache Wahl
+
+Zweck: Mit dieser Funktion kann die zwischengespeicherte
+ Ausgabe des Druckens einer EUDAS-Datei mit den
+ Textkosmetikprogrammen 'lineform' und 'pageform'
+ bearbeitet werden.
+
+Verweise: Benutzerhandbuch Abschnitt 12.1
+
+
+2.5 Menü 'Dateien'
+
+
+#linefeed (0.5)#
+#on ("b")#U Übersicht Dateien System#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Übersicht über die Dateien im System in der aktuellen
+ Benutzertask.
+
+Verweise: Benutzerhandbuch Abschnitt 16.1
+
+
+#linefeed (0.5)#
+#on ("b")#L Datei Löschen#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Dateiname, mit Zeigen, mehrfache Wahl
+
+Zweck: Löschen einer beliebigen Datei in der aktuellen Be­
+ nutzertask nach Anfrage.
+
+Verweise: Benutzerhandbuch Abschnitt 16.1
+
+
+#linefeed (0.5)#
+#on ("b")#N Datei Umbenennen#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Dateiname, mit Zeigen, mehrfache Wahl
+ Neuer Name, ohne Zeigen
+
+Zweck: Umbenennen einer beliebigen Datei in der aktuellen
+ Benutzertask.
+
+Verweise: Benutzerhandbuch Abschnitt 16.1
+
+
+#linefeed (0.5)#
+#on ("b")#K Datei Kopieren#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Dateiname, mit Zeigen, mehrfache Wahl
+ Zieldateiname, ohne Zeigen
+
+Zweck: Anfertigen einer logischen Kopie einer beliebigen
+ Datei in der aktuellen Benutzertask.
+
+Verweise: Benutzerhandbuch Abschnitt 16.1
+
+
+#linefeed (0.5)#
+#on ("b")#P Platzbedarf einer Datei#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Dateiname, mit Zeigen, mehrfache Wahl
+
+Zweck: Zeigt den belegten Speicherplatz einer beliebigen
+ Datei in der aktuellen Benutzertask.
+
+Verweise: Benutzerhandbuch Abschnitt 16.1
+
+
+#linefeed (0.5)#
+#on ("b")#A Datei Aufräumen#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Dateiname, mit Zeigen, mehrfache Wahl
+
+Zweck: Reorganisieren einer Textdatei oder einer EUDAS-
+ Datei, um Platz zu sparen oder den Zugriff zu be­
+ schleunigen. Empfiehlt sich bei stark veränderten
+ oder umsortierten Dateien.
+
+Verweise: Benutzerhandbuch Abschnitt 16.1
+
+
+2.6 Menü 'Archiv'
+
+
+#linefeed (0.5)#
+#on ("b")#U Übersicht Dateien Archiv#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Übersicht aller Dateien auf der eingelegten Archivdis­
+ kette.
+
+Verweise: Benutzerhandbuch Abschnitt 16.2
+
+
+#linefeed (0.5)#
+#on ("b")#D Archivübersicht Drucken#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Die Archivübersicht wird direkt zum Drucker ge­
+ schickt.
+
+Verweise: Benutzerhandbuch Abschnitt 16.2
+
+
+#linefeed (0.5)#
+#on ("b")#K Datei Kopieren vom Archiv#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Dateiname, mit Zeigen, mehrfache Wahl
+
+Zweck: Eine Datei auf der Archivdiskette wird in die aktuelle
+ Benutzertask kopiert.
+
+Verweise: Benutzerhandbuch Abschnitt 16.2
+
+
+#linefeed (0.5)#
+#on ("b")#S Datei Schreiben auf Archiv#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Archivname
+ Dateiname, mit Zeigen, mehrfache Wahl
+
+Zweck: Eine Datei aus der aktuellen Benutzertask wird auf
+ die eingelegte Archivdiskette geschrieben.
+
+Verweise: Benutzerhandbuch Abschnitt 16.2
+
+
+#linefeed (0.5)#
+#on ("b")#L Datei Löschen auf Archiv#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Archivname
+ Dateiname, mit Zeigen, mehrfache Wahl
+
+Zweck: Löschen einer Datei auf der eingelegten Archivdisket­
+ te. Der Platz kann jedoch nicht immer wiederverwendet
+ werden.
+
+Verweis: Benutzerhandbuch Abschnitt 16.2
+
+
+#linefeed (0.5)#
+#on ("b")#I Archivdiskette Initialisieren#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: keine
+
+Zweck: Mit dieser Funktion kann eine Archivdiskette komplett
+ gelöscht werden. Die Diskette kann dabei auch gleich­
+ zeitig formatiert werden, falls der Rechner dies zu­
+ läßt. Das Initialisieren ist notwendig, bevor eine neue
+ Diskette als Archiv verwendet werden kann.
+
+Verweise: Benutzerhandbuch Abschnitt 16.2
+
+
+#linefeed (0.5)#
+#on ("b")#Z Zielarchiv einstellen#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Managertaskname, ohne Zeigen
+
+Zweck: Mit dieser Funktion kann eine Managertask angegeben
+ werden, die als Ziel der Archivoperationen dient.
+ Damit können Dateien auch in beliebigen Managertasks
+ oder über das EUMEL-Netz gesichert werden.
+
+ Es wird erfragt, ob die angegebene Task ein Archiv­
+ manager oder ein gewöhnlicher Dateimanager ist.
+
+Verweise: Benutzerhandbuch Abschnitt 16.2
+
+
+#linefeed (0.5)#
+#on ("b")#P Paßwort einstellen#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Paßwort
+
+Zweck: Mit dieser Funktion kann ein Paßwort eingestellt
+ werden, das bei der Kommunikation mit allgemeinen
+ Managertasks überprüft wird.
+
+Verweise: Benutzerhandbuch Abschnitt 16.2
+
+
+#linefeed (0.5)#
+#on ("b")#R Archivmanager Reservieren#off ("b")#
+#linefeed (1.07)#
+_____________________________________________________
+
+Parameter: Reservierungstext
+
+Zweck: Falls als Zielarchiv eine Managertask eingestellt ist,
+ die zwar kein Archivmanager ist, aber reserviert
+ werden muß (z.B. 'DOS'), kann die Reservierung mit
+ dieser Funktion ausgeführt werden. Die Freigabe
+ erfolgt automatisch beim Verlassen des Menüs.
+
+Verweise: Benutzerhandbuch Abschnitt 16.2
+
+
+
+2.7 Kurzabfrage
+
+Wird 'eudas' innerhalb des EUMEL-Editors aufgerufen, so wird eine
+spezielle Kurzabfrage gestartet. Diese ermöglicht die Übernahme von
+Druckdaten direkt in die editierte Datei.
+ Zunächst wird der Dateiname der zu verwendenden EUDAS-
+Datei erfragt. Diese Datei wird dann geöffnet. Vorher geöffnete und
+veränderte Dateien werden nach Anfrage gesichert.
+ Als nächstes kann für die folgende Übersicht eine Feldauswahl
+eingestellt werden, damit die relevanten Felder auch auf dem Bild­
+schirm erscheinen.
+ Danach beginnt ein wiederholbarer Prozeß mit der Eingabe
+eines Suchmusters nach Anfrage. Die ausgewählten Sätze werden
+dann in einer Übersicht gezeigt. In der Übersicht können auch Sätze
+markiert werden.
+ Nach Verlassen der Übersicht bestehen drei Möglichkeiten zum
+Drucken: Falls mindestens ein Satz markiert wurde, können nach
+Anfrage alle markierten Sätze gedruckt werden. Wurde kein Satz
+markiert, können nach Anfrage alle ausgewählten (bzw. vorher
+angezeigten) Sätze gedruckt werden. Wird diese Frage jeweils ver­
+neint, kann nach Anfrage auch der aktuelle Satz als einziger ge­
+druckt werden.
+ Wurde eine der Fragen bejaht, wird der Name des Druckmusters
+erfragt, das bereits existieren muß. Das Ergebnis der Druckausgabe
+wird dann an der aktuellen Cursorposition in der editierten Datei
+eingefügt.
+ Der Prozeß kann danach mit einem anderen Suchmuster wieder­
+holt werden. Dabei werden alle Markierungen wieder gelöscht.
+
diff --git a/doc/eudas/eudas.ref.3 b/doc/eudas/eudas.ref.3
new file mode 100644
index 0000000..9b58b9b
--- /dev/null
+++ b/doc/eudas/eudas.ref.3
@@ -0,0 +1,270 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (31)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+3 Das virtuelle Dateimodell
+
+
+
+3.1 Dateistruktur
+
+Eine EUDAS-Datei hat folgende Bestandteile:
+
+- 0 bis 5000 #on("i")#Sätze#off("i")#, von 1 an durchnumeriert. Jeder Satz enthält für
+ jedes Feld einen variabel langen Text als Inhalt, der standard­
+ mäßig leer ist.
+
+- 1 bis 256 #on("i")#Felder#off("i")#, die die Sätze aufteilen. Jedes Feld besitzt einen
+ #on("i")#Feldnamen#off("i")# als Text und einen von vier #on("i")#Feldtypen#off("i")# (TEXT, ZAHL,
+ DATUM oder DIN). Der Feldname dient zur Identifizierung des
+ Feldes, der Feldtyp spezifiziert die Art der Behandlung beim Ver­
+ gleichen von Feldern.
+
+- Drei Zusatztexte. Der erste nimmt die #on("i")#Prüfbedingungen#off("i")# auf, der
+ zweite speichert das Datum der letzten Veränderung und der
+ dritte kann allgemeine #on("i")#Notizen#off("i")# aufnehmen.
+
+- Einen #on("i")#Satzzeiger#off("i")#, der einen bestimmten Satz als aktuellen Satz
+ auszeichnet. Der Satzzeiger kann durch Positionierungsoperatio­
+ nen verändert werden.
+
+- Eine #on("i")#Sortierreihenfolge#off("i")#, die angibt, in welcher Feldreihenfolge die
+ Datei zuletzt sortiert worden ist. Dazu für jeden Satz eine Anga­
+ be, ob er entsprechend dieser Reihenfolge an der richtigen Posi­
+ tion steht.
+
+- Eine interne Datenstruktur, die beschleunigten Zugriff auf eine
+ Satz nach dem Inhalt des ersten Feldes ermöglicht. Diese Struktur
+ steht ganz unter Kontrolle von EUDAS und kann nicht von außen
+ manipuliert werden.
+
+
+3.2 Öffnen
+
+#on("b")#Virtuelle Datei#off("b")# Die meisten EUDAS-Funktionen arbeiten
+nicht
+direkt auf einer EUDAS-Datei, sondern auf der sogenannten #on("i")#vir­
+tuellen Datei#off("i")#, die aus mehreren realen Dateien bestehen kann. Die
+virtuelle Datei erscheint nach außen hin wie eine einzelne
+EUDAS-Datei. Die Operationen auf der virtuellen Datei werden je­
+weils auf die einzelnen Bestandteile abgebildet.
+ Damit eine EUDAS-Datei Bestandteil der virtuellen Datei wird,
+muß sie geöffnet werden. Dieses Öffnen kann auf dreierlei Art und
+Weise geschehen.
+ Das Öffnen der ersten Datei stellt eine neue virtuelle Datei
+her. Die Feldnamen und Feldeigenschaften der ersten Datei werden
+in der virtuellen Datei übernommen. Dies ist der Normalfall, in dem
+sich die virtuelle Datei noch nicht von der zugrundeliegenden Datei
+unterscheidet.
+ Bei diesem ersten Öffnen muß angegeben werden, ob die vir­
+tuelle Datei verändert werden soll oder nicht. Falls die virtuelle
+Datei verändert werden soll, wird eine Arbeitskopie aller geöffneten
+Dateien angelegt. Die Ursprungsdateien können erst am Ende der
+Arbeit mit den geänderten Kopien überschrieben werden.
+
+#on("b")#Weitere Dateien#off("b")# Weitere Dateien können gekettet oder
+gekoppelt
+werden. Gekettete Dateien werden logisch an die zuerst geöffnete
+Datei angehängt. Ihre Dateistruktur wird ignoriert, sollte aber mit
+der ersten Datei übereinstimmen. Die Folge aneinander geketteter
+EUDAS-Dateien wird als #on("i")#Hauptdatei#off("i")# bezeichnet.
+ In der Hauptdatei werden die Sätze von 1 an durchnumeriert;
+die Aufeinanderfolge der Sätze wird durch die Anordnung der Sätze
+in den einzelnen Dateien und die Reihenfolge bestimmt, in der die
+Dateien gekettet wurden.
+ Die gekoppelten Dateien werden der Hauptdatei untergeordnet.
+Die in ihnen enthaltenen Informationen werden nur angezeigt, wenn
+sie mit einem Satzinhalt der Hauptdatei korrespondieren. Der
+Mechanismus dieser Satzkopplung wird im nächsten Abschnitt
+beschrieben.
+
+
+#free (8.0)#
+
+#center#Abb. 3-1 Schematischer Aufbau der virtuellen Datei
+
+
+
+3.3 Koppeln
+
+ Die Sätze der gekoppelten Dateien werden in Relation zu den
+Sätzen in der Hauptdatei gesetzt. Zu jedem Satz in der Hauptdatei
+kann eine Anzahl von Sätzen aus jeder Koppeldatei gehören. Diese
+Sätze müssen in den Inhalten der sogenannten #on("i")#Koppelfelder#off("i")# über­
+einstimmen.
+ Welche Felder Koppelfelder sind, richtet sich nach den Feld­
+namen. Die ersten Felder der Koppeldatei, die auch in der Haupt­
+datei vorhanden sind, werden als Koppelfelder betrachtet. Die Kop­
+pelfelder müssen also bei der Koppeldatei am Anfang stehen - in
+der Hauptdatei kann jedes beliebige Feld ein Koppelfeld sein.
+ Wenn eine Datei zur virtuellen Datei gekoppelt wird, werden
+alle Felder, die nicht Koppelfelder sind, in die virtuelle Datei auf­
+genommen. Die Koppelfelder brauchen nicht noch mal wiederholt zu
+werden, da ihr Inhalt ja immer identisch ist.
+ Zu beachten ist, daß bei diesem Verfahren auch Namenskonflik­
+te entstehen können, wenn nach den Koppelfeldern später wieder
+ein Feldname vorkommt, der auch in der Hauptdatei vorhanden ist.
+In den Fällen, in denen Felder durch ihren Namen angesprochen
+werden, ist dann das zweite Feld gleichen Namens nicht verfügbar.
+
+
+#free (7.0)#
+
+#center#Abb. 3-2 Schema des Koppelvorgangs
+
+
+#on("b")#Kombinationen#off("b")# Beim Vorwärtsgehen in der virtuellen Datei
+werden
+zu jedem Satz der Hauptdatei nacheinander alle möglichen Kombina­
+tionen der zugehörigen Koppelsätze angezeigt, denn es können
+mehrere passende Koppelsätze vorhanden sein. Die Satznummer
+bleibt dabei gleich; die einzelnen Kombinationen werden von 1 an
+durchgezählt. Beim Rückwärtsgehen wird aus technischen Gründen
+immer nur die erste Kombination angezeigt.
+ Existiert zu einem Satz kein passender Koppelsatz, so bleiben
+die entsprechenden Felder leer. Die Koppelsätze müssen in der
+ganzen Koppeldatei gesucht werden, daher ist bei großen Koppel­
+dateien die Suchzeit zu berücksichtigen.
+
+
+3.4 Änderungen
+
+In der virtuellen Datei kann auch geändert werden. Dabei ist jedoch
+Vorsicht angebracht. Es muß festgelegt sein, wie Änderungen der
+einzelnen Felder auf die beteiligten Dateien abgebildet werden.
+ Falls die virtuelle Datei keine Koppeldateien enthält, werden
+Änderungen am aktuellen Satz an der zugehörigen Datei durchge­
+führt. Das Löschen eines Satzes wird auch direkt in der Datei
+durchgeführt. Ein neuer Satz wird immer in der Datei eingefügt, zu
+der der aktuelle Satz gehört - am Ende der ersten Datei kann also
+kein Satz eingefügt werden, wenn noch weitere Dateien folgen.
+ Enthält die virtuelle Datei Koppeldateien, werden die Änderun­
+gen in der Hauptdatei wie oben beschrieben durchgeführt. Änderun­
+gen, die Felder in den Koppeldateien betreffen, werden nach folgen­
+der Entscheidungstabelle behandelt:
+
+ 1 2 3 4 5
+ ---------------
+ Koppelfelder verändert N J J N N
+ Übrige Felder verändert N - - J J
+ Übrige Felder leer - J N - N
+ Vorher Koppelsatz vorhanden - - - J N
+ ---------------
+ Neuen Satz einfügen x x
+ Koppelsatz ändern x
+ Kopplung aktualisieren x
+
+Fall 1: Es wurden keine Veränderungen an den Feldern des Kop­
+ pelsatzes vorgenommen, daher ist auch keine Aktion not­
+ wendig.
+
+Fall 2: Eines der Koppelfelder wurde verändert. Die Änderung wird
+ in der Hauptdatei durchgeführt. Die übrigen Felder des
+ Koppelsatzes sind jedoch als leer angegeben. In diesem Fall
+ wird der Koppelsatz nicht verändert, sondern nur eine
+ neue Korrespondenz gesucht.
+
+Fall 3: Eines der Koppelfelder wurde verändert, gleichzeitig ent­
+ halten aber auch die anderen Felder Informationen. In
+ diesem Fall wird ein neuer Satz in der Koppeldatei ange­
+ fügt, der die neuen Inhalte enthält. So wird vermieden,
+ daß an anderer Stelle plötzlich kein passender Koppelsatz
+ mehr vorhanden ist.
+
+Fall 4: Nur Felder der Koppeldatei, die nicht Koppelfelder sind,
+ wurden verändert, außerdem existierte ein korrespondie­
+ render Satz in der Koppeldatei. In diesem Fall werden die
+ Informationen im Koppelsatz abgeändert.
+
+Fall 5: Wie 4, nur war vorher noch kein Koppelsatz vorhanden
+ (Felder waren leer). In diesem Fall muß ein neuer Satz in
+ die Koppeldatei eingefügt werden. Einfügungen in die
+ Koppeldatei geschehen immer am Dateiende.
+
+#on("b")#Einfügen/Löschen#off("b")# Beim Löschen eines Satzes der virtuellen
+Datei
+durch Tragen bleiben die Koppeldateien unverändert. Nach dem
+Einfügen eines neuen Satzes wird nur dann ein Satz in einer Kop­
+peldatei eingefügt, wenn dieser Satz nicht nur Koppelfelder enthal­
+ten würde. Falls beim Einfügen nur die Koppelfelder angegeben
+werden, wird ein korrespondierender Satz in der Koppeldatei ge­
+sucht. Vergleichen Sie hierzu die Regeln beim Ändern.
+
+
+3.5 Sichern
+
+Falls Änderungen der virtuellen Datei erlaubt sind, arbeitet EUDAS
+immer auf Sicherheitskopien der beteiligten Dateien. Eine Datei, die
+wirklich verändert wurde, muß vor dem Aufbau einer neuen virtuel­
+len Datei gesichert oder explizit gelöscht werden.
+ Für jede einzelne Datei kann festgelegt werden, ob sie gesi­
+chert werden soll oder nicht. Als Hilfe wird dazu für jede Datei
+angegeben, ob sie tatsächlich verändert wurde oder nicht. Die
+Arbeitskopie kann beim Sichern die alte Version überschreiben oder
+unter einem neuen Namen gesichert werden.
+ Am Ende des Sicherns können die Arbeitskopien gelöscht wer­
+den. Anderenfalls werden die Dateien so betrachtet, als ob sie di­
+rekt nach dem Sichern wieder geöffnet worden wären und stehen
+weiterhin zur Verfügung.
+ Falls alle Dateien entweder gesichert oder nicht verändert
+sind, werden beim nächsten Öffnen einer neuen virtuellen Datei die
+vorherigen Arbeitskopien gelöscht.
+
+
+3.6 Umschalten auf Koppeldatei
+
+Falls eine Datei gekoppelt ist, kann man die virtuelle Datei auf
+diese Koppeldatei umschalten. Dadurch verhält sich die virtuelle
+Datei so, als ob nur diese Koppeldatei geöffnet wäre. Die Einstel­
+lungen der Hauptdatei wie Markierungen und Suchbedingung bleiben
+jedoch erhalten und stehen beim Zurückschalten wieder zur Verfü­
+gung.
+ Die Satzposition der Koppeldatei beim letzten Umschalten wird
+ebenfalls gespeichert und wird beim nächsten Umschalten wieder
+eingenommen, unabhängig von der tatsächlichen Satzposition der
+Koppeldatei zu diesem Zeitpunkt.
+ Für die Koppeldatei können eigene Markierungen vergeben
+werden, die auch nach dem Umschalten gespeichert bleiben. Auch
+ein Suchmuster kann für die Koppeldatei eingestellt werden, dies
+geht jedoch beim Zurückschalten wieder verloren. Die eingestellte
+Feldauswahl für die Bildschirmanzeige geht leider bei jedem Um­
+schalten verloren.
+ Das Umschalten kann entweder im Menü 'Einzelsatz' oder beim
+Einfügen und Ändern durch ESC 'K' bewirkt werden, ebenso das
+Zurückschalten nur im Menü 'Einzelsatz'. Beim Umschalten aus Ein­
+fügen oder Ändern erfolgt beim Zurückschalten eine Rückkehr in
+diesen Zustand. Dabei können nach Anfrage die Koppelfelder des
+aktuellen Satzes der Koppeldatei in die Hauptdatei übernommen und
+damit eine bestimmte Kopplung bewirkt werden.
+
+
+3.7 Mehrbenutzerbetrieb
+
+Durch Einstellen einer Managertask für den Mehrbenutzerbetrieb
+können auch Dateien dieser Managertask beim Öffnen direkt ver­
+wendet werden. Die Datei wird automatisch aus der Managertask
+kopiert und geöffnet.
+ Falls die Datei geändert werden soll, wird eine Sperre in der
+Managertask gesetzt, die verhindert, daß auch ein anderer Benutzer
+diese Datei zum Ändern öffnet. Beim Sichern erfolgt dann ein Rück­
+schreiben der Arbeitskopie. Die Sperre wird jedoch erst dann zu­
+rückgesetzt, wenn alle Arbeitskopien gelöscht werden, da erst dann
+keine Möglichkeit des Rückschreibens mehr besteht.
+ Alle Dateien der Managertask werden bei der Dateiauswahl zum
+Öffnen mit angeboten. Falls eine Datei in beiden Tasks existiert,
+wird die Datei in der Managertask genommen, die Datei der eigenen
+Task jedoch erst nach Anfrage überschrieben.
+ Damit die Sperre funktionieren kann, muß EUDAS in der Mana­
+gertask zur Verfügung stehen und die Task muß #on("i")#nach#off("i")# dem Insertie­
+ren von EUDAS als 'global manager' definiert werden (nicht 'free
+global manager' verwenden).
+
diff --git a/doc/eudas/eudas.ref.4 b/doc/eudas/eudas.ref.4
new file mode 100644
index 0000000..cfd6daf
--- /dev/null
+++ b/doc/eudas/eudas.ref.4
@@ -0,0 +1,441 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (39)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+4 Ansehen und Bearbeiten
+
+
+
+4.1 Anzeige
+
+Die Anzeige und Eingabe von Einzelsätzen sowie die Eingabe von
+Suchmustern geschieht in einem Standardformular in einem recht­
+eckigen Fenster. Dieses Fenster befindet sich in der rechten Bild­
+schirmhälfte.
+ Das Formular besteht aus vier Teilen: der Überschrift, den
+Feldnamen, den Feldinhalten und der Abschlußzeile (s. Abbildung).
+
+ Überschrift
+#free (0.3)#
+ Satz 33 ..SUCH+..MARK-... datei ............... Feld 1
+ Feld 1
+ Feld 2
+ Feld 3 Feldinhalte
+
+ Feld 4
+ ..............................................................
+#free (0.3)#
+ Feldnamen Abschlußzeile
+
+
+
+#on("b")#Überschrift#off("b")# Die Überschrift zeigt folgende Informationen
+an:
+
+ Satz n[-m]
+ Die Satznummer des aktuellen Satzes, bei gekoppelten Dateien
+ auch die Satzkombination.
+
+ SUCH+/-
+ Zeigt an, ob der aktuelle Satz die eingestellte Suchbedingung
+ erfüllt oder nicht (wird während Eintragungen nicht angezeigt).
+ Wenn keine Suchbedingung eingestellt ist, erscheint diese An­
+ zeige nicht.
+
+ MARK+/-
+ Zeigt an, ob der aktuelle Satz markiert ist oder nicht (Wird
+ während Eintragungen nicht angezeigt). Wenn kein Satz mar­
+ kiert ist, erscheint diese Anzeige nicht.
+
+ ENDE
+ Wird hinter dem letzten Satz der Datei als Kennzeichnung des
+ Endesatzes ausgegeben.
+
+ 'Dateiname'
+ Gibt den Namen der ersten geöffneten Datei an.
+
+ <KOPPPEL>
+ Erscheint statt des Dateinamens, wenn auf eine Koppeldatei
+ umgeschaltet wurde.
+
+ Feld n/Zeile n
+ Zeilennummer des obersten angezeigten Feldes (bei Anzeige)
+ bzw. der aktuellen Cursorzeile (während Eintragungen).
+
+#on("b")#Feldteil#off("b")# Die Feldnamen sind zur Unterscheidung von den
+Feld­
+inhalten invers dargestellt. Die Breite der Feldnamen richtet sich
+nach der Länge des längsten Feldnamens. Ist dieser zu lang, um
+noch eine ordentliche Anzeige zu ermöglichen, wird bei einer be­
+stimmten Länge der Rest des Namens abgeschnitten.
+ Zwischen dem Feldnamen an der linken Seite und dem dane­
+benstehenden Feldinhalt besteht immer eine Korrespondenz, d.h. der
+Inhalt eines Feldes wird direkt neben dem Namen dargestellt. In der
+Regel wird pro Feld eine Bildschirmzeile reserviert. Kann der Feld­
+inhalt jedoch nicht mehr in einer Zeile untergebracht werden, wer­
+den weitere Zeilen zur Darstellung dieses Feldes herangezogen. In
+diesen Zeilen steht statt des Feldnamens nur ein markierter Leer­
+raum.
+ Alle folgenden Zeilen ohne Namen gehören zu dem gleichen
+Feld. Der Inhalt wird auf diese Zeilen umbrochen, d.h. wenn ein
+Wort nicht mehr auf die Zeile paßt, wird es komplett in die nächste
+Zeile geschrieben (wie beim Editor). Wörter werden nur dann zer­
+schnitten, wenn sie nicht als Ganzes auf eine Zeile passen. Wörter
+werden untereinander durch Leerzeichen getrennt.
+ Aus Effizienzgründen werden in bestimmten Fällen auch mehr
+Folgezeilen als nötig angezeigt. Hat nämlich ein neuer Satz einen
+kürzeren Inhalt als der vorige, so werden die Feldnamen nur dann
+wieder zusammengerückt, wenn das ganze Bild neugeschrieben wer­
+den muß. Anderenfalls werden nur die Feldinhalte aktualisiert.
+ Die Bildausgabe wird unterbrochen, wenn 'w' oder 'z' gedrückt
+wurde, da dann die Inhalte des aktuellen Satzes nicht mehr inter­
+essieren.
+
+#on("b")#Rollen#off("b")# Da nicht alle Felder auf den Bildschirm passen
+müssen, kann das Bild gerollt werden.
+ Mit ESC UNTEN wird um eine Seite nach unten geblättert, mit
+ESC OBEN wieder zurück. Hinter dem letzten Feld erscheint ein
+markierter Balken als Abschlußzeile. Weiter als bis zum Erscheinen
+dieses Balken kann nicht gerollt werden. Mit ESC '1' wird ganz an
+den Anfang gerollt, mit ESC '9' ganz ans Ende.
+ Bei Feldern, die sich über mehrere Zeilen erstrecken, kann es
+passieren, daß nach dem Rollen die erste Bildschirmzeile nicht die
+erste Zeile eines Feldes ist, also der erste Teil eines Feldes nicht
+dargestellt wird. Trotzdem wird in diesem Fall in der ersten Anzei­
+gezeile der Feldname angezeigt.
+
+#on("b")#Feldauswahl#off("b")# Man kann auswählen, welche Felder in welcher
+Rei­
+henfolge angezeigt werden sollen. Dies dient der besseren Übersicht.
+Von der Anzeige werden nur die ausgewählten Felder behandelt, die
+anderen Felder bleiben leer, werden nicht verändert oder berück­
+sichtigt. Die Anzeigeauswahl ändert jedoch nichts an der Datei­
+struktur.
+ Die Feldauswahl ist keine permanente Eigenschaft einer
+EUDAS-Datei. Sie geht daher bei einem neuen Öffnen oder beim
+Umschalten auf eine Koppeldatei verloren.
+
+#on("b")#Übersicht#off("b")# Im Gegensatz zur normalen Anzeige, bei der ein
+Satz pro
+Bildschirm dargestellt wird, können in der Übersicht mehrere Sätze
+gleichzeitig überschaut werden. Dabei wird jeder Satz in einer Zeile
+untergebracht. Die Auswahl der Felder, die in der Übersicht er­
+scheinen sollen, wird vor Beginn der Funktion erfragt.
+ In jeder Zeile steht die Nummer des jeweiligen Satzes, eine
+Anzeige, ob er markiert ist (+) oder nicht (-) und die Feldinhalte
+in der gewählten Reihenfolge und Auswahl, jeweils duch Komma und
+Leerzeichen getrennt. Inhalte, die nicht mehr auf die Zeile passen,
+werden abgeschnitten.
+ Es werden nur durch das Suchmuster ausgewählte Sätze ange­
+zeigt. Ist der aktuelle Satz nicht ausgewählt, so erscheint an seiner
+Stelle '<< >>' als Hinweis. In der Überschrift sind die Feldnamen
+angegeben - durch Komma getrennt, so viele wie hinpassen.
+ Die Satznummer des aktuellen Satzes ist jeweils markiert. In
+der Übersicht kann geblättert werden. HOP OBEN und HOP UNTEN,
+OBEN und UNTEN wirken wie im Editor.
+ Durch '+' oder '-' kann auch die Markierung des aktuellen
+Satzes verändert werden.
+
+
+4.2 Satzauswahl
+
+Die Auswahl der Sätze, die gedruckt oder mit den Funktionen aus
+Abschnitt 4.4 bearbeitet werden sollen, kann entweder durch eine
+Suchbedingung oder durch Markierung vorgenommen werden. Wenn
+mindestens ein Satz markiert ist, werden von den Bearbeitungs­
+funktionen nur die markierten Sätze behandelt. Anderenfalls wird
+die eingestellte Suchbedingung beachtet.
+ Die Bildschirmanzeige richtet sich immer nur nach der einge­
+stellten Suchbedingung.
+
+#on("b")#Suchmuster#off("b")# Ein Suchmuster gibt für jedes Feld bestimmte
+Bedin­
+gungen an. Es wird im Standardformular mit Hilfe des Satzeditors
+eingegeben. Dabei stehen neben jedem Feld die Bedingungen für
+dieses Feld in einer intuitiv verständlichen Form. Folgende Einzel­
+bedingungen sind möglich:
+
+ Muster Inhalt ist gleich Muster
+ Muster.. Inhalt ist größergleich Muster
+ ..Muster Inhalt ist kleiner Muster
+ Muster1..Muster2 Inhalt liegt dazwischen
+ *Muster Inhalt endet mit Muster
+ Muster* Inhalt beginnt mit Muster
+ *Muster* Inhalt enthält Muster
+ * Inhalt ist nicht leer
+ ++ Satz markiert (unabhängig vom Feldinhalt)
+
+Die ersten vier Einzelbedingungen beachten auch den Typ eines
+Feldes (wie er bei der Feldstruktur eingegeben werden kann und
+beim Sortieren beachtet wird). So werden z.B. bei der Gleichheit von
+Zahlen alle nicht-numerischen Zeichen ignoriert (s. Sortieren).
+ Die drei Bedingungen mit Stern können auch miteinander ver­
+knüpft werden. Die Einzelbedingungen müssen dann alle zutreffen,
+damit der Satz ausgewählt wird. So bedeutet zum Beispiel das
+Muster 'M1*M2*M3*M4', daß das Feld mit 'M1' beginnen und mit 'M4'
+enden muß. Außerdem muß es 'M2' und 'M3' enthalten, jedoch nicht
+unbedingt in der angegebenen Reihenfolge.
+ Wird der Mustertext durch '&' und einen gültigen Feldnamen der
+aktuellen Datei ersetzt, findet der Vergleich nicht mit einem
+Mustertext, sondern mit dem Inhalt des angegebenen Feldes statt.
+Als Feldtyp für den Vergleich wird in diesem Fall der Typ des Fel­
+des genommen, in dem der Vergleich steht.
+
+#on("b")#Verknüpfung#off("b")# Einzelbedingungen können durch Voranstellen
+von
+'--' verneint werden. Einzelbedingungen für verschiedene Felder
+werden mit UND verknüpft.
+ Es gibt zwei Arten der ODER-Verknüpfung: die lokale und die
+globale. Die lokale ODER-Verknüpfung wird durch ein Komma zwi­
+schen Einzelbedingungen realisiert. Sie hat eine höhere Priorität als
+das UND zwischen verschiedenen Feldern. So hat folgendes Such­
+muster
+
+
+ Feld1 Bed1,Bed2
+ Feld2 Bed3
+
+
+die Bedeutung
+
+
+ ( Bed1 (Feld1) ODER Bed2 (Feld2) ) UND Bed3 (Feld3)
+
+
+Die globale ODER-Verknüpfung wird durch ein Semikolon repräsen­
+tiert. Alle Einzelbedingungen nach dem n-ten Semikolon aller Zeilen
+werden zu einer Alternative zusammengefaßt. Damit hat das Such­
+muster
+
+
+ Feld1 Bed1;Bed2
+ Feld2 Bed3
+
+
+die Bedeutung
+
+
+ ( Bed1 (Feld1) UND Bed3 (Feld2) ) ODER Bed2 (Feld1)
+
+
+Damit ergibt sich für die Priorität der einzelnen Konstruktionen
+folgende Reihenfolge:
+
+ höchste Einzelbedingung
+ Verkettung von Einzelbedingungen (UND)
+ Verneinung
+ lokales ODER
+ UND zwischen Feldern
+ niedrigste globales ODER
+
+#on("b")#Optimierung#off("b")# Wenn für das erste Feld einer Datei eine
+Gleich-
+Bedingung angegeben wurde und keine globale Alternative vorhan­
+den ist, kann der Suchvorgang wegen der Dateistruktur optimiert
+werden, indem nur Sätze untersucht werden müssen, die im ersten
+Feld den gesuchten Text enthalten.
+
+#on("b")#Reservierte Zeichen#off("b")# Im Rahmen der Analyse einer
+Musterzeile
+wirken folgende Zeichenfolgen als unbeschränkt reservierte Zeichen:
+
+
+ , ; .. *
+
+
+Sie dürfen daher in keinem Mustertext oder Feldnamen vorkommen,
+da sie als Separator wirken. Die beiden folgenden Zeichenfolgen
+werden nur zu Anfang eines durch die vorstehenden Separatoren
+gebildeten Abschnitts erkannt:
+
+
+ -- & ++
+
+
+Sie dürfen daher prinzipiell an weiterer Stelle vorkommen, ohne als
+Sonderzeichen erkannt zu werden. Alle anderen Zeichen in der Zeile
+werden dem Mustertext bzw. Feldnamen ohne weitere Interpretation
+zugeordnet.
+
+
+4.3 Sortieren und Reorganisieren
+
+Eine EUDAS-Datei kann in einer beliebigen Feldreihenfolge sortiert
+werden. Mit dieser Angabe kann man bestimmen, welche Felder beim
+Vergleich zweier Sätze berücksichtigt werden sollen und in welcher
+Reihenfolge.
+ Die Sortierreihenfolge wird in der Datei gespeichert und wird
+anschließend immer wieder verwendet, wenn keine anderen Angaben
+gemacht wurden.
+ Der Sortierzustand einer Datei wird ebenfalls gespeichert. Wenn
+nur wenige Sätze seit der letzten Sortierung verändert wurden,
+müssen auch nur diese Sätze einsortiert werden.
+
+#on("b")#Feldtypen#off("b")# Um eine korrekte Sortierung auch von Zahlen oder
+Daten sicherzustellen, wird jedem Feld einer EUDAS-Datei ein Feld­
+typ zugeordnet, der beim Sortieren (und auch beim Suchen) berück­
+sichtigt wird.
+ Es gibt folgende Feldtypen (als Standard wird der Typ TEXT
+verwendet):
+
+ TEXT Vergleich von Texten nach dem EUMEL-Code der einzel­
+ nen Zeichen. Dies ist Standard und sorgt für schnellst­
+ möglichen Vergleich. Die weiteren Typen brauchen erheb­
+ lich mehr Zeit.
+
+ DIN Vergleich nach DIN 5007 (s. EUMEL-Benutzerhandbuch).
+ Umlaute werden korrekt eingeordnet, Groß- und Klein­
+ buchstaben werden gleichbehandelt, Sonderzeichen werden
+ ignoriert.
+
+ ZAHL Der Wert einer Zahl wird verglichen. Außer den Ziffern,
+ dem Dezimalkomma und dem Minuszeichen vor der ersten
+ Ziffer werden alle anderen Zeichen ignoriert. Das Dezi­
+ malkomma ist standardmäßig auf ',' eingestellt, kann aber
+ verändert werden (s. Abschnitt 6.5). Die nicht ignorierten
+ Zeichen werden in eine REAL-Zahl umgewandelt und dann
+ verglichen.
+
+ DATUM Es werden Daten der Form 'tt.mm.jj' verglichen. In diesem
+ Fall werden Tag und Jahr vertauscht und dann vergli­
+ chen. Texte mit einer anderen Länge als 8 werden alle
+ als gleich betrachtet.
+
+#on("b")#Reorganisieren#off("b")# Wenn viele Änderungen an einer EUDAS-Datei
+vorgenommen worden sind, steigt ihr Platzbedarf durch viele Text­
+leichen an. In diesem Fall empfiehlt es sich, die Datei zu reorgani­
+sieren. Auch wenn beim Sortieren viele Sätze vertauscht wurden,
+sollte die Datei reorganisiert werden, da beim Sortieren die physi­
+kalische Reihenfolge der Sätze nicht verändert wird. In diesem Fall
+ergibt sich nach dem Reorganisieren ein Geschwindigkeitsvorteil.
+
+
+4.4 Bearbeiten
+
+#on("b")#Kopieren#off("b")# Durch Kopieren kann ein Ausschnitt aus der
+virtuellen
+Datei in eine andere EUDAS-Datei kopiert werden. Es werden alle
+ausgewählten Sätze kopiert. Wenn mindestens ein Satz markiert ist,
+werden alle markierten Sätze als ausgewählt betrachtet, ansonsten
+alle, die durch die Suchbedingung angegeben sind. Die kopierten
+Sätze werden am Ende der Zieldatei angefügt.
+ Welche Felder kopiert werden sollen, wird durch das Kopier­
+muster angegeben. Hierbei können auch mehrere Felder zu einem
+verschmolzen werden. Allgemein ergeben sich die Felder der Ziel­
+datei aus einem beliebigen ELAN-Ausdruck.
+ Das Kopiermuster ist ein ELAN-Programm und enthält im we­
+sentlichen Ausdrücke der Form
+
+
+ "Feldname" K Ausdruck ;
+
+
+Durch diese Anweisung wird der Ausdruck in das Feld der Zieldatei
+mit dem angegebenen Namen kopiert. Existiert dieses Feld in der
+Zieldatei noch nicht, so wird es als letztes angefügt. Falls die
+Zieldatei noch nicht existiert, wird sie eingerichtet. In diesem Fall
+bestimmt also die Reihenfolge der 'K'-Ausdrücke die Reihenfolge der
+Feldnamen in der Zieldatei.
+ Da die Reihenfolge der 'K'-Ausdrücke wichtig ist, dürfen diese
+nicht in einer IF-Anweisung stehen, sondern müssen für jeden Satz
+komplett in der gleichen Reihenfolge ausgeführt werden.
+
+#on("b")#Standard-Kopiermuster#off("b")# Vor dem Kopieren wird ein Standard-
+Kopiermuster zum Editieren angeboten, das sich nach der Zieldatei
+richtet. Existiert die Zieldatei noch nicht, wird das Muster so kon­
+struiert, daß alle Felder der virtuellen Datei unverändert kopiert
+werden. Wollen Sie einige Felder nicht kopieren, brauchen Sie nur
+die entsprechenden Zeilen zu löschen; wollen Sie die Felder in eine
+andere Reihenfolge bringen, müssen Sie die Zeilen umordnen.
+ Existiert die Zieldatei bereits, gibt das Standard-Kopiermuster
+an, daß alle Felder der Zieldatei einen Wert erhalten. Ist ein Feld
+der Zieldatei in der virtuellen Datei enthalten, so wird dieses ko­
+piert, ansonsten erhält das Feld einen leeren Inhalt. Sie können in
+diesem Fall weitere Felder angeben oder für die leeren Felder Aus­
+drücke formulieren.
+
+#on("b")#Tragen#off("b")# Durch Tragen werden alle ausgewählten Sätze der
+virtuel­
+len Datei in eine andere Datei transportiert. Sie sind in der vir­
+tuellen Datei dann nicht mehr vorhanden. Damit bei diesem Vorgang
+keine Informationen verlorengehen können, muß die Zieldatei so
+viele Felder haben wie die virtuelle Datei. Normalerweise sollte sie
+in der Feldstruktur mit der virtuellen Datei übereinstimmen.
+ Die getragenen Sätze werden jeweils am Ende der Datei ange­
+fügt.
+ Beim Tragen können zusätzlich noch Konsistenzbedingungen
+überprüft werden. Die Prüfbedingungen sind in der Zieldatei gespei­
+chert und können beim Ändern der Feldstruktur angegeben werden.
+ Die Prüfbedingung ist ein ELAN-Programm, das vor dem Tragen
+des jeweiligen Satzes ausgeführt wird. Durch spezielle Testprozedu­
+ren kann das Tragen des Satzes verhindert werden, wenn diese
+Prozeduren ein negatives Ergebnis liefern. Gleichzeitig wird eine
+Meldung in eine Protokolldatei geschrieben, die dann zur Identifi­
+zierung der fehlerhaften Sätze dienen kann.
+ Folgende Prüfprozeduren stehen zur Verfügung (siehe auch
+Abschnitt 8.3):
+
+
+ pruefe ("Feldname", Bedingung)
+
+ Hiermit kann eine beliebige Bedingung (BOOL-Ausdruck in
+ ELAN) überprüft werden.
+
+
+ wertemenge ("Feldname", "Wert1,Wert2,...,Wertn")
+
+ Das Feld muß einen in der angegebenen Liste enthaltenen
+ Werte annehmen.
+
+
+ feldmaske ("Feldname", "Maske")
+
+ Das Feld wird auf Übereinstimmung mit der Maske geprüft.
+ Fünf spezielle Zeichen in der Maske können dabei auf
+ mehrere Zeichen zutreffen:
+ '9' alle Ziffern
+ 'a' alle Kleinbuchstaben, Umlaute, 'ß'
+ 'A' alle Großbuchstaben, Umlaute
+ 'X' alle Zeichen
+ '*' Folge von beliebigen Zeichen
+ Der Stern sollte sparsam angewendet werden, da er verar­
+ beitungsaufwendig ist.
+
+
+ eindeutige felder (n)
+
+ Die Zahl 'n' gibt an, die wieviel ersten Felder der Zieldatei
+ eindeutig sein müssen. Stimmt der zu tragende Satz mit
+ einem Satz der Zieldatei in diesen Feldern überein, wird
+ eine Fehlermeldung erzeugt.
+
+Es können auch einzelne Sätze manuell getragen werden. In diesem
+Fall wird die Prüfbedingung nicht getestet. Ebenso kann der Satz
+wieder zurückgeholt und in der aktuellen Datei eingefügt werden.
+
+#on("b")#Nach Vorschrift ändern#off("b")# Die ausgewählten Sätze der
+virtuellen
+Datei können automatisch nach einer Verarbeitungsvorchrift geän­
+dert werden. Die Verarbeitungsvorschrift ist ein ELAN-Programm, in
+dem mit Hilfe des Operators 'V' Änderungen angegeben werden:
+
+
+ "Feldname" V TEXT-Ausdruck ;
+
+
+Das angegebene Feld erhält den Inhalt, der durch den Ausdruck
+angegeben ist. Änderungen an Koppeldateien werden wie im Dialog
+behandelt (s. Abschnitt 3.4).
+
+
+
+
diff --git a/doc/eudas/eudas.ref.5 b/doc/eudas/eudas.ref.5
new file mode 100644
index 0000000..02971ea
--- /dev/null
+++ b/doc/eudas/eudas.ref.5
@@ -0,0 +1,432 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (49)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+5 Drucken und Druckmuster
+
+
+
+5.1 Druckmustersyntax
+
+Ein Druckmuster ist eine Beschreibung für die Form, in der die In­
+halte einer EUDAS-Datei ausgedruckt werden sollen. Der syntakti­
+sche Aufbau des Druckmusters ist zeilenorientiert und gehorcht
+folgender Syntax:
+
+ Druckmuster :
+ [ Initialisierungsteil ]
+ [ Vorspann ]
+ [ Wiederholungsteil ]
+ [ Nachspann ]
+
+ Initialisierungsteil :
+ ( Kommandozeile #char (""124"")# Textzeile )*
+ ( GRUPPE-Anweisung #char(""124"")# Textzeile )*
+
+ Vorspann :
+ VORSPANN-Anweisung Abschnitt
+
+ Wiederholungsteil :
+ WIEDERHOLUNG-Anweisung Abschnitt
+
+ Nachspann :
+ NACHSPANN-Anweisung Abschnitt
+
+ Abschnitt :
+ Musterteil
+ [ ABKUERZUNGEN-Anweisung Abkürzungsteil ]
+
+ Musterteil :
+ ( Musterzeile #char(""124"")# Kommandozeile #char(""124"")#
+ MODUS-Anweisung #char (""124"")# MEHR-Anweisung )*
+
+Zur Notation: [] bedeutet optional, ()* beliebig häufige Wiederho­
+lung, #char(""124"")# Alternative und keine Angabe einfache Aneinanderreihung.
+Die verschiedenen Zeilentypen werden weiter unten beschrieben.
+ Zusätzlich gilt die Bedingung, daß von Vorspann, Wiederho­
+lungsteil und Nachspann mindestens einer vorhanden sein muß.
+
+#on("b")#Zeilentypen#off("b")# Im Druckmuster gibt es 6 verschiedene
+Zeilentypen:
+
+#on("i")#Kommandozeilen#off("i")#
+ Eine Kommandozeile beginnt mit '%%' in der ersten und zweiten
+ Spalte. Der Inhalt der Zeile ab Spalte 3 wird dem ELAN-Compi­
+ ler übergeben. Die Bedeutung dieser Zeilen ergibt sich aus dem
+ in 5.4 beschriebenen Übersetzungsmechanismus.
+
+#on("i")#Anweisungen#off("i")#
+ Anweisungen beginnen mit '%' in der ersten Spalte und dienen
+ zur Steuerung des Druckgenerators. Der Name der Anweisung
+ muß in Großbuchstaben und ohne Leerzeichen geschrieben
+ werden. Davor dürfen sich noch Leerzeichen befinden. An­
+ schließend können noch Parameter folgen, die nur durch Leer­
+ zeichen getrennt aneinander gereiht werden. Die Syntax einer
+ Anweisung ähnelt der eines Operators in ELAN.
+
+#on("i")#Textzeilen#off("i")#
+ Textzeilen sind die nicht anderweitig markierten Zeilen im
+ Initialisierungsteil. Sie werden unverändert an den Anfang
+ jeder Druckdatei gestellt.
+
+#on("i")#Musterzeilen#off("i")#
+ Musterzeilen sind nicht besonders gekennzeichnete Zeilen im
+ Musterteil. Sie enthalten Feldmuster und werden nach dem
+ Einsetzen von Inhalten in die Ausgabedatei übernommen. Die
+ Interpretation der Musterzeilen wird in Abschnitt 5.3 beschrie­
+ ben.
+
+#on("i")#Abkürzungszeilen#off("i")#
+ Abkürzungszeilen markieren den Beginn einer Abkürzung im
+ Abkürzungsteil eines Abschnittes. Sie werden durch '&' in der
+ ersten Spalte gekennzeichnet. Darauf folgt ohne Zwischenraum
+ der Name einer Abkürzung (ohne Leerzeichen) und danach
+ durch Leerzeichen getrennt ein Semikolon. Der Name der Ab­
+ kürzung wird bei der Übersetzung durch einen Refinementnamen
+ ersetzt und die Zeile dem ELAN-Compiler übergeben. Der Rest
+ der Zeile kann also den Beginn eines werteliefernden Refine­
+ ments enthalten.
+
+#on("i")#Programmzeilen#off("i")#
+ Programmzeilen sind die nicht durch '&' markierten Zeilen im
+ Abkürzungsteil. Sie werden unverändert an den ELAN-Compiler
+ übergeben. Der erlaubte Inhalt richtet sich nach dem Überset­
+ zungsmechanismus (5.4).
+
+
+5.2 Der Druckvorgang
+
+Der Druckvorgang besteht im wesentlichen darin, daß für alle zu
+bearbeitenden Sätze der Wiederholungsteil einmal interpretiert wird
+und das Ergebnis in eine Ausgabedatei geschrieben wird, die dann
+gedruckt werden kann. Wenn mindestens ein Satz markiert ist, wer­
+den alle markierten Sätze der virtuellen Datei bearbeitet, ansonsten
+alle durch die Suchbedingung erfaßten.
+
+#on("b")#Gruppen#off("b")# Eine #on("i")#Gruppe#off("i")# ist eine Folge von Sätzen, die in einem be­
+stimmten Merkmal übereinstimmen. Durch eine GRUPPE-Anweisung
+der Form
+
+
+ % GRUPPE n Ausdruck
+
+
+werden aufeinanderfolgende Sätze mit gleichem Wert des angegebe­
+nen Ausdrucks gruppiert. Über die Nummer 'n' kann festgestellt
+werden, ob sich das angegebene Merkmal verändert hat. Dies ge­
+schieht mit der Prozedur
+
+
+ BOOL PROC gruppenwechsel (INT CONST gruppennr)
+
+
+Immer wenn zwischen zwei Sätzen ein Gruppenwechsel stattfindet,
+wird beim vorigen Satz der Nachspann und beim folgenden Satz der
+Vorspann einmal interpretiert. Dies führt dazu, daß entsprechende
+Vorspann- bzw. Nachspannzeilen gedruckt werden.
+ Vor dem ersten und nach dem letzten zu bearbeitenden Satz
+wechseln alle Gruppen, d.h. dort wird immer ein Vorspann bzw.
+Nachspann erzeugt.
+ Ist ein zu interpretierender Abschnitt nicht vorhanden, so wird
+an dieser Stelle keine Ausgabe erzeugt. Die Textzeilen des Initali­
+sierungsteils werden auf jeden Fall bei Beginn des Druckvorganges
+in die Ausgabedatei geschrieben. Falls die Ausgabedatei voll ist,
+wird eine neue Datei angefangen und die Zeilen des Initialisie­
+rungsteils erneut an den Anfang gestellt.
+
+
+ Satz- Gruppen- Ausgabe
+ nummer merkmal
+#free (0.1)#
+ Initialisierungsteil
+ -------------------------------------------------
+ 1 x Vorspann
+ WDH-Teil
+ 2 x WDH-Teil
+ Nachspann
+ -------------------------------------------------
+ 3 y Vorspann
+ WDH-Teil
+ 4 y WDH-Teil
+ 5 y WDH-Teil
+ Nachspann
+ -------------------------------------------------
+ ENDE
+
+#center#Abb. 5-1 Ablauf des Druckvorganges mit Gruppen
+
+
+#on("b")#Spaltendruck#off("b")# Normalerweise werden die Ausgaben der
+einzelnen
+Abschnitte hintereinander in der Ausgabedatei plaziert. Durch An­
+gabe einer Nummer als Parameter in der WIEDERHOLUNG-Anweisung
+können auch soviel Spalten wie angegeben nebeneinander gedruckt
+werden. Die Spaltenbreite wird dabei durch das Dateilimit (Komman­
+do 'limit' im Editor) festgelegt. Alternativ kann die Spaltenbreite
+auch als zweiter Parameter durch Leerzeichen getrennt angegeben
+werden.
+ Vorspann und Nachspann werden jedoch auf jeden Fall wieder
+in eine eigene Zeile geschrieben, der Spaltendruck also unterbro­
+chen.
+
+
+5.3 Interpretation von Musterzeilen
+
+Musterzeilen können Feldmuster enthalten, die bei der Interpreta­
+tion durch entsprechende Inhalte ersetzt werden, ehe die Muster­
+zeile in die Ausgabedatei übernommen wird. Der Beginn eines Feld­
+musters wird durch ein Musterzeichen ('&' oder '%') markiert. Wo
+und wie der Inhalt eingesetzt wird, kann durch folgende Variationen
+angegeben werden:
+
+
+ Typ ! Beispiel ! Position ! Länge ! bündig
+ ----+-----------+------------------------------
+ 1 ! &Name ! fest ! variabel ! links
+ 2 ! %Name ! variabel ! variabel ! links
+ 3 ! &Name&&& ! fest ! fest ! links
+ 4 ! %Name%%% ! variabel ! fest ! links
+ 5 ! &&&Name& ! fest ! fest ! rechts
+ 6 ! %%%Name% ! variabel ! fest ! rechts
+
+
+Der in dem Feldmuster angegebene Name muß Name einer Abkür­
+zung in irgendeinem Abkürzungsteil oder eines Feldes sein. Der
+Name darf kein Leerzeichen oder Musterzeichen enthalten. Falls dies
+doch der Fall ist, muß der Name in spitze Klammern eingeschlossen
+werden.
+ Bei fester Länge wird bei zu kurzem Inhalt mit Leerzeichen
+aufgefüllt, bei zu langem Inhalt abgeschnitten. Bei linksbündigem
+Einsetzen geschieht dies an der rechten, sonst an der linken Seite.
+ Feldmuster variabler Länge können je nach Inhalt dazu führen,
+daß der folgende Teil der Musterzeile verschoben wird. Für diesen
+Einsetzprozeß gelten die folgenden Regeln:
+
+#on("b")#Position#off("b")# Feldmuster fester Position (mit '&' beginnend)
+werden
+immer in der Position eingesetzt, in der sie stehen. Feldmuster
+variabler Position (mit '%' beginnen) können nach rechts verschoben
+werden, wenn vorherige Inhalte länger als ihre Muster sind, und
+nach links, wenn Modus 1 oder 3 eingestellt ist und vorherige In­
+halte kürzer sind.
+
+#on("b")#Länge#off("b")# Feldmuster variabler Länge erhalten auf jeden Fall
+den
+Platz, der durch die Länge des Feldmusters reserviert ist. Sind die
+Inhalte kürzer, kann der gewonnene Platz als Reserve für andere
+Feldmuster verwendet werden; sind die Inhalte länger, so wird der
+Inhalt so weit eingesetzt, wie noch Reserve vorhanden ist und der
+Rest abgeschnitten.
+ Muß in ein Feldmuster variabler Länge ein leerer Inhalt einge­
+setzt werden, so werden beim Drucken auch die auf das Feldmuster
+folgenden Leerzeichen unterdrückt, falls vor dem Feldmuster noch
+ein Leerzeichen steht oder das Feldmuster in Spalte 1 beginnt.
+ Feldmuster fester Länge werden immer in ihrer reservierten
+Länge eingesetzt. Sie werden im folgenden behandelt wie Feldmuster
+variabler Länge, deren Inhalt so lang ist wie das Feldmuster.
+
+#on("b")#Verteilung#off("b")# Die Verteilung der verschiebbaren Feldmuster
+auf der
+Zeile geschieht jeweils in dem Abschnitt zwischen zwei Feldmustern
+fester Position bzw. Zeilenanfang oder Zeilenende. Für jeden Ab­
+schnitt wird festgestellt, wieviel Stellen die Inhalte insgesamt mehr
+oder weniger als ihre Muster benötigen.
+ Der Längenausgleich geschieht zwischen dem letzten Feldmuster
+und dem Ende des Abschnitts. Dort wird ein Pufferplatz bestimmt,
+der bei Überlänge bis auf ein Leerzeichen verkleinert werden kann
+und an dem bei Unterlänge zusätzliche Leerzeichen eingefügt wer­
+den.
+ Außer am Pufferplatz wird an keinem Mustertext des Abschnitts
+etwas geändert. Zwischentexte zwischen den Feldmustern werden
+unverändert übertragen und mit den umgebenden Feldmustern ver­
+schoben.
+ Als Pufferplatz wird die erste Lücke hinter dem letzten Feld­
+muster eines Abschnittes verwendet, die mehr als ein Leerzeichen
+enthält. Ist keine solche Lücke vorhanden, wird das Ende des Ab­
+schnitts verwendet, falls dort ein Leerzeichen steht, und sonst das
+Ende des letzten Feldmusters.
+ Die durch den Pufferplatz und kürzere Inhalte gewonnene Re­
+serve wird von links an die Feldmuster mit Überlänge verteilt, bis
+die Reserve verbraucht ist.
+
+#on("b")#Zeilende#off("b")# Das Zeilenende wird als ein Quasi-Feldmuster mit
+fester
+Position aufgefaßt, das am Limit der Druckmusterdatei steht. Es
+sind also keine Einsetzungen möglich, die über das Limit der Datei
+hinausgehen. Als Pufferplatz wird hier jedoch die erste Blanklücke
+vom Zeilenende her verwendet, damit Mustertexte am Zeilenende
+gegebenenfalls stehenbleiben. Ist keine solche Lücke vorhanden, so
+wird das Zeilenende als Pufferplatz verwendet.
+ Obwohl nicht als Pufferplatz ausgewiesen, kann der Raum zwi­
+schen Zeilenende und Dateilimit als Reserve verwendet werden.
+
+#on("b")#Modi#off("b")# Der Einsetzmechanismus kann durch die MODUS-Anweisung
+mit einem Parameter verändert werden. Folgende Modi stehen zur
+Verfügung:
+
+
+ Modus ! Effekt
+ ------+----------------------------------------
+ 1 ! Normalmodus.
+ ! '%'-Feldmuster werden auch
+ ! nach links geschoben.
+ ! Keine Zeilenwiederholung.
+ ------+----------------------------------------
+ 2 ! Tabellenmodus.
+ ! '%'-Feldmuster werden nicht
+ ! nach links geschoben.
+ ! Keine Zeilenwiederholung.
+ ------+----------------------------------------
+ 3 ! Normalmodus mit Zeilenwiederholung.
+ ! '%'-Feldmuster werden auch
+ ! nach links geschoben.
+ ! Zeilenwiederholung ohne Zwischentexte.
+ ------+----------------------------------------
+ 4 ! Tabellenmodus mit Zeilenwiederholung.
+ ! '%'-Feldmuster werden nicht
+ ! nach links geschoben.
+ ! Zeilenwiederholung mit Zwischentexten.
+ ------+----------------------------------------
+
+
+Bei Zeilenwiederholung werden Inhalte in einer folgenden Zeile
+fortgesetzt, falls sie in der ersten Zeile nicht untergebracht werden
+konnten. Dazu wird die Musterzeile mit den Restinhalten erneut
+interpretiert. Je nach Modus werden auch die Zwischentexte noch
+wiederholt. Der Restinhalt umfaßt immer noch das ganze letzte Wort,
+das nicht mehr auf die vorige Zeile paßte. Es findet also ein Um­
+bruch statt. Die Positionen, die in der vorigen Zeile vom Anfang des
+Wortes eingenommen würden, werden durch Leerzeichen ersetzt.
+ Durch die MEHR-Anweisung mit einem Parameter kann die Zahl
+der Zeilenwiederholungen für die nächste Musterzeile festgesetzt
+werden. Dies hat jedoch nur eine Auswirkung, falls Zeilenwieder­
+holung zugelassen ist. Stehen zur Interpretation keine Restinhalte
+mehr zur Verfügung, wird mit leeren Inhalten weitergearbeitet. Kann
+ein Inhalt bei der vorgegebenen Anzahl von Zeilen nicht ganz dar­
+gestellt werden, wird der Rest nicht ausgegeben.
+
+
+5.4 Anschluß zum ELAN-Compiler
+
+Falls in einem Druckmuster Abkürzungen, Kommandozeilen oder
+Gruppendefinitionen vorkommen, wird das Druckmuster in ein
+ELAN-Programm umgewandelt, das dann vom ELAN-Compiler über­
+setzt wird.
+ Alle Zeilen eines Abkürzungsteils werden direkt in das Pro­
+gramm übernommen, wobei der Name einer Abkürzung durch einen
+beliebig gewählten Refinementnamen ersetzt wird ('abk' + eine lau­
+fende Nummer). Alle Abkürzungen und Refinements werden als glo­
+bale Refinements definiert, also außerhalb von Prozeduren. Dadurch
+wird erreicht, daß sie an jeder Stelle verwendet werden können.
+ Damit eine Abkürzung richtig als Refinement übersetzt wird,
+muß sie ein TEXT-Objekt als Wert liefern. Die anderen Refinements
+sind beliebig, da sie nur in selbstdefinierten Anweisungen verwen­
+det werden. Die Refinements der Abkürzungen werden in einer Zu­
+weisung an eine TEXT-Variable verwendet, damit der Druckgenera­
+tor auf den entsprechenden Wert zugreifen kann.
+ Jeder Abschnitt wird dagegen als eine Prozedur übersetzt. Eine
+Folge von Musterzeilen wird in eine Anweisung übersetzt, diese
+Musterzeilen einzusetzen und zu drucken. Eine '%%'-Anweisung wird
+einfach unverändert dazwischengeschrieben. Die Prozedur für den
+Wiederholungsteil wird einmal für jeden ausgewählten Satz aufgeru­
+fen, die Vorspann- und die Nachspann-Prozedur einmal bei jedem
+Gruppenwechsel.
+ Anweisungen im Initialisierungsteil werden an den Anfang des
+Programms als globale Definitionen gestellt.
+
+#on("b")#Fehler#off("b")# Findet sich in dem erzeugten ELAN-Programm ein
+Fehler,
+der durch den Druckgenerator nicht erkannt werden konnte (z.B.
+eine Abkürzung liefert keinen Wert), so muß der ELAN-Compiler
+diesen Fehler erkennen. Anschließend zeigt er das erzeugte Pro­
+gramm zusammen mit seinen Fehlermeldungen im Paralleleditor. Sie
+müssen nun die Fehlermeldung lokalisieren und anhand der eben
+gegebenen Hinweise in das ursprüngliche Druckmuster zurücküber­
+setzen, damit Sie dort den Fehler korrigieren können.
+
+
+5.5 Fehlermeldungen
+
+Folgende Fehlermeldungen können bei der Übersetzung eines Druck­
+musters auftreten:
+
+#on("i")#keine schliessende Klammer in Feldmuster#off("i")#
+ Wenn der Name in einem Feldmuster in spitze Klammern einge­
+ schlossen werden soll, muß noch in der gleichen Zeile eine
+ schließende Klammer vorhanden sein.
+
+#on("i")#kein Kommando in Kommandozeile#off("i")#
+ Eine Zeile, die mit '%' beginnt, enthält keinen weiteren Text.
+
+#on("i")#unbekanntes Kommando#off("i")#
+ Das erste Wort in einer Kommandozeile ist kein bekanntes Kom­
+ mando.
+
+#on("i")#kein % WIEDERHOLUNG gefunden#off("i")#
+ Das Druckmuster enthält keine Anweisung, die den Beginn eines
+ Abschnittes markiert. Es muß aber mindestens ein Abschnitt
+ vorhanden sein.
+
+#on("i")#nur GRUPPE-Anweisung erlaubt#off("i")#
+ Im Initialisierungsteil ist nur die GRUPPE-Anweisung erlaubt.
+
+#on("i")#keine ELAN-Anweisung im Initialisierungsteil nach Gruppen­
+definition#off("i")#
+ Sobald im Initialisierungsteil eine GRUPPE-Anweisung aufgetreten
+ ist, ist keine Kommandozeile mehr möglich.
+
+#on("i")#illegale Gruppennummer#off("i")#
+ In einer GRUPPE-Anweisung wurde eine zu große Nummer angege­
+ ben. Gruppen sollten von 1 an durchnumeriert werden.
+
+#on("i")#diese Gruppe wurde schon definiert#off("i")#
+ Eine Gruppennummer wurde mehrfach verwendet.
+
+#on("i")#diese Abkürzung ist nicht definiert#off("i")#
+ Ein Name in einem Feldmuster tritt nicht als Feld-oder Abkür­
+ zungsname auf. Eventuell enthält er ein Leerzeichen!
+
+#on("i")#dieser Abschnitt wurde schon einmal definiert#off("i")#
+ Kein Abschnitt kann mehrmals angegeben werden.
+
+#on("i")#falscher Modus#off("i")#
+ In einer MODUS-Anweisung wurde ein nicht definierter Modus als
+ Parameter angegeben.
+
+#on("i")#diese Anweisung darf im Musterteil nicht vorkommen#off("i")#
+
+#on("i")#im Abkürzungsteil darf keine Anweisung auftreten#off("i")#
+
+#on("i")#in dieser Zeile stehen zu viele Feldmuster#off("i")#
+ Es können maximal 24 Feldmuster in einer Zeile stehen. Abhilfe:
+ mehrere Feldmuster durch eine Abkürzung zusammenfassen.
+
+#on("i")#das Druckmuster enthält zu viele Feldmuster#off("i")#
+ Die Gesamtanzahl der Feldmuster ist begrenzt. Abhilfe: mehrere
+ Feldmuster durch eine Abkürzung zusammenfassen.
+
+#on("i")#nach dem "&" soll direkt der Name einer Abkürzung folgen#off("i")#
+ In einer Abkürzungszeile stehen Leerzeichen hinter dem '&'.
+
+#on("i")#kein Doppelpunkt nach Abkürzung#off("i")#
+ Nach dem Abkürzungsnamen in einer Abkürzungszeile muß durch
+ ein Leerzeichen getrennt ein Doppelpunkt folgen.
+
+#on("i")#Abkürzung mehrfach definiert#off("i")#
+ Die Abkürzung wurde unter dem gleichen Namen schon einmal,
+ vielleicht in einem anderen Abschnitt, definiert.
+
+#on("i")#das Druckmuster enthält zu viele Abkürzungen#off("i")#
+ Abhilfe: mehrere Abkürzungen zu einem Ausdruck zusammenfas­
+ sen.
+
+
diff --git a/doc/eudas/eudas.ref.6 b/doc/eudas/eudas.ref.6
new file mode 100644
index 0000000..7c8ada6
--- /dev/null
+++ b/doc/eudas/eudas.ref.6
@@ -0,0 +1,399 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (61)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+6 Struktur von EUDAS-Dateien
+
+
+
+EUDAS-Dateien können unabhängig von EUDAS über den Daten­
+typ EUDAT manipuliert werden. Die zur Verfügung stehenden Zu­
+griffsoperationen sind in diesem Kapitel beschrieben.
+ Der Datentyp EUDAT ist analog zum Datentyp FILE. Jede
+EUDAT-Variable kann an eine EUDAS-Datei angekoppelt werden.
+Dadurch lassen sich beliebig viele EUDAS-Dateien gleichzeitig be­
+arbeiten. Wie der Abschnitt 6.6 zeigt, sind so auch ganz andere
+Anwendungen realisierbar.
+ Die wesentlichen EUDAS-Funktionen (Ansehen, Suchen, Druk­
+ken) können jedoch nicht direkt auf EUDAT-Variablen angewendet
+werden, sondern greifen auf die virtuelle Datei zu, die im nächsten
+Kapitel beschreiben wird.
+
+
+6.1 Der Datentyp SATZ
+
+Der Datentyp SATZ stellt einen einzelnen EUDAS-Satz dar, der
+intern als TEXT realisiert ist. Ein SATZ besteht aus bis zu 256
+Feldern, die jeweils einen TEXT enthalten können. Nach dem Initi­
+alisieren sind alle Felder mit "" vorbelegt. Die Felder können über
+Nummern von 1 bis 256 angesprochen werden.
+ Damit kann man sich einen SATZ als dynamisches ROW n TEXT
+vorstellen, das bis zu 256 Elemente haben kann. Anders als ein
+entsprechendes ROW belegt ein leerer SATZ praktisch keinen Spei­
+cherplatz.
+ Folgende Zugriffsprozeduren stehen zur Verfügung:
+
+TYPE SATZ
+
+OP := (SATZ VAR, SATZ CONST)
+
+PROC satz initialisieren (SATZ VAR)
+ Jeder SATZ muß vor Benutzung initialisiert werden.
+
+INT PROC felderzahl (SATZ CONST)
+ Liefert die Nummer des höchsten belegten Feldes.
+
+PROC feld lesen (SATZ CONST, INT CONST feldnr,
+ TEXT VAR inhalt)
+ Liest den Inhalt des Feldes 'feldnr' in 'inhalt'.
+
+ FEHLER:
+
+ #on("i")#n ist keine Feldnummer#off("i")#
+ 'n' liegt außerhalb des Bereiches 1..256.
+
+PROC feld bearbeiten (SATZ CONST, INT CONST feldnr,
+ PROC (TEXT CONST, INT CONST, INT CONST) bearbeite)
+ Ruft 'bearbeite' auf, wobei 'bearbeite' ein Text und zwei Posi­
+ tionen in diesem Text übergeben werden. Die Positionen geben
+ das erste und das letzte Zeichen des durch 'feldnr' ausgewähl­
+ ten Feldes an. Ist der Anfang größer als das Ende, so ist das
+ Feld leer.
+
+ FEHLER:
+
+ #on("i")#n ist keine Feldnummer#off("i")#
+ 'n' liegt außerhalb des Bereiches 1..256.
+
+PROC feld aendern (SATZ VAR, INT CONST feldnr,
+ TEXT CONST inhalt)
+ Schreibt 'inhalt' in das Feld mit der Nummer 'feldnr'
+
+ FEHLER:
+
+ #on("i")#n ist keine Feldnummer#off("i")#
+ 'n' liegt außerhalb des Bereiches 1..256.
+
+INT PROC feldindex (SATZ CONST, TEXT CONST muster)
+ Falls eines der Felder 'muster' enthält, wird die Nummer dieses
+ Feldes geliefert, sonst 0.
+
+
+6.2 Der Datentyp EUDAT
+
+Der Datentyp EUDAT muß ähnlich wie ein FILE an einen benann­
+ten oder unbenannten Datenraum angekoppelt werden. Der Daten­
+raum hat anschließend den Typ 3243. Weitere Zugriffe auf eine
+EUDAT-Variable sind erst nach erfolgtem Ankoppeln zulässig. An­
+derenfalls können undefinierte Fehler entstehen.
+
+TYPE EUDAT
+
+PROC oeffne (EUDAT VAR, TEXT CONST dateiname)
+ Koppelt die EUDAT-Variable an die EUDAS-Datei mit dem
+ Namen 'dateiname' an. Die Datei wird eingerichtet, falls sie
+ noch nicht existiert.
+
+ FEHLER:
+
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Die angegebene Datei hat nicht den Typ 3243.
+
+PROC oeffne (EUDAT VAR, DATASPACE CONST ds)
+ Koppelt die EUDAT-Variable an den Datenraum 'ds'.
+
+ FEHLER:
+
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Der Datenraum wurde bereits verwendet und hat nicht den Typ
+ 3243.
+
+Eine EUDAS-Datei ist in Felder und Sätze unterteilt. Die Felder
+werden beim Zugriff über Nummern angesprochen. Jedem Feld ist
+jedoch zur Identifikation ein TEXT als Feldname zugeordnet. Die
+Feldnamen werden als SATZ gespeichert, wobei jedes Feld seinen
+zugeordneten Namen enthält.
+
+INT PROC felderzahl (EUDAT CONST)
+ Liefert Anzahl der benannten Felder. Ist zu Anfang 0.
+
+PROC feldnamen aendern (EUDAT VAR,
+ SATZ CONST neue namen)
+ Setzt die Feldnamen einer Datei. Ist 'felderzahl (neue namen)'
+ größer als die Felderzahl der Datei, so wird die Felderzahl der
+ Datei entsprechend heraufgesetzt.
+
+PROC feldnamen lesen (EUDAT CONST, SATZ VAR namen)
+ Liefert alle Feldnamen in einer SATZ-Variablen.
+
+Eine EUDAS-Datei enthält drei zusätzliche Notiztexte. Zwei davon
+sind bereits reserviert, und zwar:
+#free (0.2)#
+ 1: Prüfbedingungen
+ 2: Datum der letzten Änderung
+
+Der dritte kann für freie Notizen verwendet werden.
+
+PROC notizen lesen (EUDAT CONST, INT CONST notiz nr,
+ TEXT VAR notizen)
+ Schreibt die Notizen der EUDAS-Datei in 'notizen' ('notiz nr' =
+ 1,2,3).
+
+PROC notizen aendern (EUDAT VAR, INT CONST notiz nr,
+ TEXT CONST notizen)
+ Ändert die Notizen. Alte Notizen werden dabei überschrieben
+ ('notiz nr' = 1,2,3).
+
+
+6.3 Satzposition
+
+Eine EUDAS-Datei läßt sich sequentiell vorwärts und rückwärts
+bearbeiten. Dazu gibt es eine aktuelle Satzposition. Ein bestimmter
+Satz kann auch direkt angesprungen werden. Die Prozeduren, die
+nach dem Inhalt des ersten Feldes suchen, arbeiten besonders
+schnell, da die entsprechenden Sätze über eine Hashmethode gefun­
+den werden.
+
+INT PROC satznr (EUDAT CONST)
+ Liefert aktuelle Satzposition.
+
+INT PROC saetze (EUDAT CONST)
+ Liefert Anzahl der Sätze.
+
+BOOL PROC dateiende (EUDAT CONST)
+ Liefert TRUE, wenn 'satznr' groesser als 'saetze' ist. Die letzte
+ erreichbare Satzposition liegt um eins hinter dem letzten Satz
+ (um auch am Ende anfügen zu können).
+
+PROC auf satz (EUDAT VAR, INT CONST satznr)
+ Positioniert auf den gewünschten Satz. Bei nicht existierenden
+ Sätzen wird auf den ersten bzw. hinter den letzten Satz ge­
+ sprungen.
+
+PROC weiter (EUDAT VAR)
+ Geht einen Satz weiter, jedoch nicht über das Dateiende hinaus.
+
+PROC zurueck (EUDAT VAR)
+ Geht einen Satz zurück, falls der erste Satz noch nicht erreicht
+ ist.
+
+PROC auf satz (EUDAT VAR, TEXT CONST muster)
+ Positioniert auf den ersten Satz, der als erstes Feld 'muster'
+ enthält, anderenfalls hinter den letzten Satz.
+
+PROC weiter (EUDAT VAR, TEXT CONST muster)
+ Geht weiter, bis das erste Feld 'muster' enthält, bzw. bis hinter
+ den letzten Satz.
+
+PROC zurueck (EUDAT VAR, TEXT CONST muster)
+ Geht zurück, bis das erste Feld 'muster' enthält, bzw. auf den
+ ersten Satz der EUDAS-Datei.
+
+
+6.4 Satzzugriffe
+
+Der aktuelle Satz ist ein SATZ-Objekt. Auf die Felder des aktuellen
+Satzes kann direkt zugegriffen werden.
+
+PROC feld lesen (EUDAT CONST, INT CONST feldnr,
+ TEXT VAR inhalt)
+ Wirkt wie 'feld lesen' auf den aktuellen Satz.
+
+PROC feld aendern (EUDAT VAR, INT CONST feldnr,
+ TEXT CONST inhalt)
+ Wirkt wie 'feld aendern' auf den aktuellen Satz.
+
+PROC feld bearbeiten (EUDAT CONST, INT CONST feldnr,
+ PROC (TEXT CONST, INT CONST, INT CONST) bearbeite)
+ Wirkt wie 'feld bearbeiten' auf den aktuellen Satz.
+
+Der aktuelle Satz kann auch als Ganzes bearbeitet werden.
+
+PROC satz lesen (EUDAT CONST, SATZ VAR satz)
+ Liefert den aktuellen Satz.
+
+PROC satz aendern (EUDAT VAR, SATZ CONST satz)
+ Ersetzt den aktuellen Satz durch 'satz'.
+
+PROC satz einfuegen (EUDAT VAR, SATZ CONST satz)
+ Fügt 'satz' vor dem aktuellen Satz ein.
+
+ FEHLER:
+
+ #on("i")#EUDAS-Datei voll#off("i")#
+ Eine EUDAS-Datei faßt mindestens 5000 Sätze.
+
+PROC satz loeschen (EUDAT VAR)
+ Löscht den aktuellen Satz.
+
+
+6.5 Sortieren und Reorganisieren
+
+Zum Sortieren können für die einzelnen Felder Typen angegeben
+werden, damit auch Zahlen und Daten richtig sortiert werden kön­
+nen. Außerdem kann die Feldreihenfolge angegeben werden, nach
+der sortiert werden soll.
+
+PROC feldinfo (EUDAT VAR, INT CONST feldnr, info)
+ Setzt den Feldtyp des Feldes 'feldnr'. Es bedeuten
+ -1 : normaler Text (Standard)
+ 0 : Text nach DIN. Ziffern und Sonderzeichen werden igno­
+ riert. Groß-und Kleinbuchstaben gelten gleich. Umlaute
+ werden beachtet.
+ 1 : Zahl (beim Vergleich werden alle Zeichen außer Zif­
+ fern ignoriert).
+ 2 : Datum. Es werden Daten der Form "tt.mm.jj" vergli­
+ chen.
+
+INT PROC feldinfo (EUDAT CONST, INT CONST feldnr)
+ Der Feldtyp des angegebenen Feldes wird geliefert. Zu Anfang
+ ist -1 voreingestellt.
+
+INT PROC unsortierte saetze (EUDAT CONST)
+ Liefert die Anzahl von Sätzen, die seit dem letzten Sortiervor­
+ gang geändert wurden. Bei einer neuen Datei, die noch nie
+ sortiert wurde, wird immer 0 geliefert.
+
+PROC dezimalkomma (TEXT CONST komma)
+ Stellt das Dezimalkomma ein, das beim Vergleich von Zahlen
+ gelten soll.
+
+ FEHLER:
+
+ #on("i")#Nicht erlaubtes Dezimalkomma#off("i")#
+ Nur Texte der Länge 1 sind zugelassen.
+
+TEXT PROC dezimalkomma
+ Liefert das eingestellte Dezimalkomma ("," ist voreingestellt).
+
+PROC sortiere (EUDAT VAR, TEXT CONST reihenfolge)
+ Sortiert die Datei in der von 'reihenfolge' angegebenen Reihen­
+ folge. Dabei enthält 'reihenfolge' an der Stelle 2*i+1 den Code
+ der Feldnummer, die als i-te in der Sortierung berücksichtigt
+ werden soll. Das Zeichen an der Stelle 2*i gibt an, ob das Feld
+ mit der davorstehenden Feldnummer aufsteigend ('+') oder
+ absteigend ('-') sortiert werden soll.
+
+PROC sortiere (EUDAT VAR)
+ Sortiert die Datei in der zuletzt eingestellten Reihenfolge.
+ Wurde noch keine Reihenfolge angegeben, wird die Datei in der
+ Feldreihenfolge sortiert.
+
+TEXT PROC sortierreihenfolge (EUDAT CONST)
+ Liefert die zuletzt eingestellte Reihenfolge. Wurde noch nicht
+ sortiert, so wird "" geliefert.
+
+Nach umfangreichen Änderungen an einer EUDAS-Datei ist eine
+Reorganisation sinnvoll, um "Textleichen" zu beseitigen.
+
+PROC reorganisiere (TEXT CONST dateiname)
+ Die EUDAS-Datei mit dem Namen 'dateiname' wird reorgani­
+ siert.
+
+
+6.6 EUDAS-Dateien als Assoziativspeicher
+
+In diesem Abschnitt soll ein Beispiel erläutert werden, in dem
+EUDAS-Dateien unabhängig von EUDAS für einen ganz anderen
+Zweck benutzt werden. Das folgende kurze Paket soll ein Abkür­
+zungsverzeichnis realisieren, das auf einer EUDAS-Datei basiert.
+
+
+ PACKET abkuerzungsverzeichnis
+ DEFINES
+ verzeichnis laden,
+ abkuerzung einfuegen,
+ abkuerzung aendern,
+ abkuerzung loeschen,
+ langform :
+
+ EUDAT VAR verz;
+ SATZ VAR satz;
+ TEXT VAR inhalt;
+
+ PROC verzeichnis laden (TEXT CONST dateiname) :
+
+ oeffne (verz, dateiname)
+
+ END PROC verzeichnis laden;
+
+ PROC abkuerzung einfuegen (TEXT CONST abk, lang) :
+
+ auf satz (verz, abk);
+ IF NOT dateiende (verz) THEN
+ errorstop ("Abkürzung existiert bereits")
+ ELSE
+ satz initialisieren (satz);
+ feld aendern (satz, 1, abk);
+ feld aendern (satz, 2, lang);
+ satz einfuegen (satz)
+ END IF
+
+ END PROC abkuerzung einfuegen;
+
+ PROC abkuerzung aendern (TEXT CONST abk, lang) :
+
+ auf satz (verz, abk);
+ IF dateiende (verz) THEN
+ errorstop ("Abkürzung existiert nicht")
+ ELSE
+ feld aendern (verz, 2, lang)
+ END IF
+
+ END PROC abkuerzung aendern;
+
+ PROC abkuerzung loeschen (TEXT CONST abk) :
+
+ auf satz (verz, abk);
+ IF NOT dateiende (verz) THEN
+ satz loeschen (verz)
+ END IF
+
+ END PROC abkuerzung loeschen;
+
+ TEXT PROC langform (TEXT CONST abk) :
+
+ auf satz (verz, abk);
+ IF dateiende (verz) THEN
+ inhalt := "";
+ errorstop ("Abkürzung nicht vorhanden")
+ ELSE
+ feld lesen (verz, 2, inhalt)
+ END IF;
+ inhalt
+
+ END PROC langform;
+
+ END PACKET abkuerzungsverzeichnis;
+
+
+Die Prozedur 'verzeichnis laden' koppelt die interne EUDAT-Vari­
+able 'verz' an eine benannte EUDAS-Datei, die eventuell vorher mit
+EUDAS erstellt wurde. In diesem Beispiel sind die Feldnamen egal;
+falls die übergebene EUDAS-Datei noch nicht existiert, wird sie mit
+0 Feldern eingerichtet, was aber nur für eine spätere Anzeige mit
+EUDAS störend wäre.
+ Grundlage für das Aufsuchen einer bestimmten Abkürzung bil­
+det immer die Prozedur 'auf satz', die nach dem Inhalt des ersten
+Feldes optimiert sucht. Falls die Abkürzung nicht gefunden wurde,
+wird auf das Dateiende positioniert, daher wird jeweils 'dateiende'
+abgefragt.
+ Beim Einfügen eines neuen Satzes muß eine komplette Satz­
+variable angegeben werden, die bereits mit den Inhalten gefüllt ist.
+Beim späteren Ändern kann jedoch direkt auf ein Feld zugegriffen
+werden, ohne die Satzvariable explizit rauszuholen.
+ Die Abfrage einer bestimmten Abkürzung bereitet dann keine
+Schwierigkeiten mehr.
+ Für die Verwendung von EUDAS-Dateien in diesem Beispiel
+spricht zum einen die einfache Programmierung, zum anderen aber
+auch die Möglichkeit, das erstellte Verzeichnis mit den Hilfsmitteln
+
diff --git a/doc/eudas/eudas.ref.7 b/doc/eudas/eudas.ref.7
new file mode 100644
index 0000000..31b3031
--- /dev/null
+++ b/doc/eudas/eudas.ref.7
@@ -0,0 +1,447 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (71)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+7 Verwaltung der offenen Dateien
+
+
+Die in diesem Kapitel beschriebene Schnittstelle verbindet mehrere
+EUDAS-Dateien zu einem großen Dateimodell. Diese virtuelle Datei
+dient als Grundlage für die meisten EUDAS-Funktionen. Zuerst muß
+eine Datei als Bestandteil der virtuellen Datei geöffnet werden, ehe
+sie bearbeitet werden kann. Es ist so bei den Funktionen keine
+Angabe mehr nötig, welche Datei gemeint ist.
+ Diese Schnittstelle ist in vielen Teilen für die interne
+EUDAS-Anwendung ausgelegt. Bei einigen Prozeduren werden aus
+Effizienzgründen keinerlei Überprüfungen auf illegale Aufrufe oder
+Parameter durchgeführt. Wollen Sie eine solche Prozedur dennoch
+verwenden, sollten Sie die Einhaltung der angegebenen Bedingungen
+sorgfältig überprüfen.
+
+
+7.1 Dateiverwaltung
+
+Mit 'oeffne' wird eine Datei zum Bearbeiten geöffnet. Mit 'kette' und
+'kopple' können weitere Dateien dazugekettet bzw. dazugekoppelt
+werden. Durch 'sichere' können veränderte Kopien zurückgeschrie­
+ben werden. Durch 'dateien loeschen' werden die internen Kopien
+gelöscht.
+ Mit 'anzahl dateien' kann die Anzahl der vorhandenen Dateien
+erfragt werden. 'anzahl koppeldateien' gibt Auskunft darüber, wie­
+viel Dateien davon gekoppelt sind. 'aendern erlaubt' gibt den Status
+wieder, der beim Öffnen der ersten Datei angegeben wurde. 'inhalt
+veraendert' gibt an, ob die angegebene Datei verändert wurde. Mit
+'eudas dateiname' können die Namen der geöffneten Dateien erfragt
+werden. Bei jedem 'oeffne' wird 'dateiversion' um 1 erhöht. Dies
+dient dazu, ein erfolgtes neues Öffnen von anderen Stellen aus zu
+entdecken.
+ Mit 'auf koppeldatei' kann die virtuelle Datei auf eine Koppel­
+datei umgeschaltet werden, so daß der Eindruck entsteht, nur diese
+Datei wäre geöffnet worden.
+
+PROC oeffne (TEXT CONST dateiname,
+ BOOL CONST aendern erlaubt)
+ Falls Ändern erlaubt sein soll, wird eine Kopie der angegebenen
+ Datei zur Bearbeitung für EUDAS angelegt. Vorher geöffnete
+ Dateien werden gelöscht. Die Änderungserlaubnis wird entspre­
+ chend gesetzt. Es wird die Satzposition der EUDAS-Datei ange­
+ nommen (Ausnahme: steht die EUDAS-Datei hinter dem letzten
+ Satz, wird auf Satz 1 positioniert). 'dateiversion' sowie 'anzahl
+ dateien' werden um 1 erhöht.
+
+ FEHLER:
+#f1#
+ #on("i")#Datei nicht gesichert#off("i")#
+ Eine vorher geöffnete Datei war verändert, aber nicht gesi­
+ chert.
+#f1#
+ #on("i")#Datei existiert nicht#off("i")#
+ Die angegebene Datei ist nicht vorhanden.
+#f1#
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Die angegebene Datei hat nicht den für EUDAS-Dateien festge­
+ legten Typ.
+
+PROC kopple (TEXT CONST dateiname)
+ Die angegebene Datei wird zu den bereits geöffneten Dateien
+ dazugekoppelt. Falls Ändern erlaubt ist, wird eine Kopie dieser
+ Datei verwendet. Dabei werden die ersten Felder der Datei, die
+ bereits in der Hauptdatei vorhanden sind, als Koppelfelder
+ festgelegt. Alle weiteren Felder werden zusätzlich zu den bis­
+ herigen angelegt. 'dateiversion', 'anzahl dateien' und 'anzahl 
+ koppeldateien' werden um 1 erhöht.
+
+ FEHLER:
+#f1#
+ #on("i")#keine Datei geoeffnet#off("i")#
+ Es muß vorher eine Datei geöffnet werden.
+#f1#
+ #on("i")#Zuviel Dateien geoeffnet#off("i")#
+ Die Anzahl der gleichzeitig geöffneten Dateien ist begrenzt.
+#f1#
+ #on("i")#Datei existiert nicht#off("i")#
+ Die angegebene Datei ist nicht vorhanden.
+#f1#
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Die angegebene Datei hat nicht den für EUDAS-Dateien festge­
+ legten Typ.
+#f1#
+ #on("i")#Zu viele Felder#off("i")#
+ Die Anzahl der Felder insgesamt ist begrenzt.
+#f1#
+ #on("i")#Zu viele Koppelfelder#off("i")#
+ Die Anzahl der Koppelfelder ist begrenzt.
+#f1#
+ #on("i")#keine Koppelfelder vorhanden#off("i")#
+ Das erste Feld der zu koppelnden Datei ist in der Hauptdatei
+ nicht vorhanden (unterschiedliche Feldnamen).
+
+PROC kette (TEXT CONST dateiname)
+ Die angegebene Datei wird an die Hauptdatei angekettet, d.h.
+ die Sätze der neuen Datei werden am bisherigen Dateiende
+ angefügt. Falls Ändern erlaubt ist, wird eine Kopie dieser Datei
+ verwendet. Die zu kettende Datei muß in der Feldstruktur nicht
+ mit der Hauptdatei übereinstimmen. Die aktuelle Satzposition
+ wird beibehalten. 'dateiversion' und 'anzahl dateien' werden um
+ 1 erhöht.
+
+ FEHLER:
+#f1#
+ #on("i")#keine Datei geoeffnet#off("i")#
+ Es muß vorher eine Datei geöffnet werden.
+#f1#
+ #on("i")#Zuviel Dateien geoeffnet#off("i")#
+ Die Anzahl der gleichzeitig geöffneten Dateien ist begrenzt.
+#f1#
+ #on("i")#Datei existiert nicht#off("i")#
+ Die angegebene Datei ist nicht vorhanden.
+#f1#
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Die angegebene Datei hat nicht den für EUDAS-Dateien festge­
+ legten Typ.
+
+PROC sichere (INT CONST dateinr, TEXT CONST dateiname)
+ Die geöffneten Dateien werden in der Reihenfolge ihres Öffnens
+ durchnumeriert (von 1 an). Die Arbeitskopie mit der angegebe­
+ nen Nummer wird unter dem angegebenen Namen gesichert, aber
+ selbst nicht verändert. Die vorher unter diesem Namen vorhan­
+ dene Datei wird gelöscht. War die zu sichernde Arbeitskopie
+ verändert worden, so wird sie anschließend als nicht verändert
+ angesehen.
+ Bedingungen:
+ 1 <= dateinr <= anzahl dateien
+
+PROC dateien loeschen (BOOL CONST auch geaenderte)
+ Es werden alle geöffneten Arbeitskopien gelöscht. EUDAS wird
+ wieder in den Anfangszustand versetzt. Wird 'auch geaenderte'
+ angegeben, wird bei geänderten, aber nicht gesicherten Dateien
+ die Fehlermeldung unterdrückt.
+
+ FEHLER:
+#f1#
+ #on("i")#Datei nicht gesichert#off("i")#
+ Eine vorher geöffnete Datei war verändert, aber nicht gesi­
+ chert.
+
+BOOL PROC auf koppeldatei
+ Liefert TRUE, wenn auf eine Koppeldatei umgeschaltet wurde.
+
+PROC auf koppeldatei (INT CONST nr)
+ Umschalten auf Koppeldatei 'nr'. Ist bereits umgeschaltet, wird
+ wieder zurückgeschaltet. In diesem Fall werden bei 'nr' = 1 die
+ Koppelfelder übernommen, anderenfalls nicht. Beim Umschalten
+ bleiben Satzposition, Markierungen und Suchmuster gespeichert.
+ In der Koppeldatei wird die beim letzten Umschalten eingestell­
+ te Position wieder eingenommen. 'dateiversion' wird um 1 er­
+ höht.
+
+INT PROC anzahl dateien
+ Gibt die Anzahl der insgesamt geöffneten Dateien an.
+
+INT PROC anzahl koppeldateien
+ Gibt die Anzahl der gekoppelten Dateien an.
+
+BOOL PROC aendern erlaubt
+ Reflektiert den Status, der bei 'oeffne' gesetzt wurde.
+
+BOOL PROC inhalt veraendert (INT CONST dateinr)
+ Gibt an, ob die geöffnete Datei mit der angegebenen Nummer
+ verändert wurde. Wird ggf. von 'sichere' zurückgesetzt.
+ Bedingung:
+ 1 <= dateinr <= anzahl dateien
+
+TEXT PROC eudas dateiname (INT CONST dateinr)
+ Liefert den Namen, unter dem die entsprechende Datei geöffnet
+ wurde.
+ Bedingung:
+ 1 <= dateinr <= anzahl dateien
+
+INT PROC dateiversion
+ Wird bei jedem 'oeffne', 'kette' und 'kopple' zyklisch erhöht.
+
+INT PROC folgedatei (INT CONST dateinr)
+ Eine geöffnete EUDAS-Datei wird in eine von zwei Listen auf­
+ genommen, die der geketteten Dateien und die der gekoppelten.
+ Diese Prozedur liefert jeweils die Nummer der nächsten Datei in
+ der Liste, am Ende aber 0. Die Liste der geketteten Dateien
+ beginnt immer mit 1, mit 'folgedatei (0)' erhält man die erste
+ gekoppelte Datei.
+ Bedingung:
+ 0 <= dateinr <= anzahl dateien
+
+
+7.2 Feldstruktur
+
+Die einzelnen Sätze der kombinierten EUDAS-Datei sind in Felder
+unterteilt. Diese setzen sich zusammen aus den Feldern der Haupt­
+datei und der einzelnen Koppeldateien, wobei die Koppelfelder je­
+weils nur einmal auftauchen.
+ 'anzahl felder' liefert die Anzahl der vorhanden Felder. Mit
+'feldnamen lesen' und 'feldnamen bearbeiten' können die Feldnamen
+abgefragt werden. 'feldnummer' liefert einen Index für einen vor­
+gegebenen Feldnamen, da die Felder immer über Nummern angespro­
+chen werden.
+ Die Prozeduren 'feld lesen' und 'feld bearbeiten' ermöglichen
+den Zugriff auf den Feldinhalt des aktuellen Satzes; durch 'feld
+aendern' kann dieser Inhalt abgeändert werden.
+
+INT PROC anzahl felder
+ Liefert die Anzahl der vorhanden Felder.
+
+PROC feldnamen lesen (INT CONST feldnr,
+ TEXT VAR feldname)
+ Liefert in 'feldname' den Namen des Feldes mit der Nummer
+ 'feldnr'.
+ Bedingung:
+ 1 <= feldnr <= anzahl felder
+
+PROC feldnamen bearbeiten (INT CONST feldnr,
+ PROC (TEXT CONST, INT CONST, INT CONST) bearbeite)
+ Die Prozedur 'bearbeite' wird aufgerufen. Als Parameter werden
+ ein Text und Anfangs- und Endposition des gewünschten Feld­
+ namens in diesem Text übergeben. Verhindert unnötiges Kopie­
+ ren des Feldnamens in eine TEXT-Variable. Der übergebene
+ Text darf nicht verändert werden!
+ Bedingung:
+ 1 <= feldnr <= anzahl felder
+
+INT PROC feldnummer (TEXT CONST feldname)
+ Liefert den index zu dem angegebenen Feldnamen. Falls ein
+ solcher Name nicht existiert, wird 0 geliefert.
+
+PROC feld lesen (INT CONST feldnr, TEXT VAR inhalt)
+ Liefert den Inhalt des angegebenen Feldes.
+ Bedingung:
+ 1 <= feldnr <= anzahl felder
+
+PROC feld bearbeiten (INT CONST feldnr,
+ PROC (TEXT CONST, INT CONST, INT CONST) bearbeite)
+ Die Prozedur 'bearbeite' wird aufgerufen. Der Feldinhalt des
+ angegebenen Feldes steht im übergebenen Text innerhalb der
+ Grenzen. Ist die Obergrenze kleiner als die Untergrenze, so ist
+ das Feld leer.
+ Bedingung:
+ 1 <= feldnr <= anzahl felder
+
+PROC feld aendern (INT CONST feldnr, TEXT CONST inhalt)
+ Ändert den Inhalt des angegebenen Feldes.
+ Bedingung:
+ NOT ende der datei
+ 1 <= feldnr <= anzahl felder
+
+INT PROC feldinfo (INT CONST feldnummer)
+ Liefert den Typ des angegebenen Feldes.
+ Bedingung:
+ 1 <= feldnummer <= anzahl felder
+
+PROC notizen lesen (INT CONST nr, TEXT VAR inhalt)
+ Liest die angegebenen Notizen ('nr' = 1,2,3) aus der ersten
+ Datei oder der umgeschalteten Koppeldatei.
+
+PROC notizen aendern (INT CONST nr, TEXT CONST inhalt)
+ Ändert die Notizen ('nr' = 1,2,3) der ersten Datei oder der um­
+ geschalteten Koppeldatei.
+
+
+7.3 Positionierung
+
+Das virtuelle Dateimodell von EUDAS verfügt ebenfalls über eine
+Satzposition, die verändert werden kann.
+ Durch 'satznummer' wird die aktuelle Satznummer geliefert,
+beim Koppeln kann über 'satzkombination' die Reihenfolge der Kop­
+pelkombinationen bestimmt werden. 'dateiende' zeigt an, ob die
+Satzposition hinter dem letzten Satz liegt. Mit 'weiter' und 'zurueck'
+erfolgt die eigentliche Positionierung. Hier kann außer der Positio­
+nierung um Einzelsätze auch die Positionierung auf den nächsten
+ausgewählten oder markierten Satz angefordert werden. Mit 'auf 
+satz' schließlich kann ein bestimmter Satz angesprungen werden.
+
+INT PROC satznummer
+ Liefert die Nummer des aktuellen Satzes. Die Sätze werden von
+ 1 an durchnumeriert, wobei über die geketteten Dateien wei­
+ tergezählt wird.
+ Bedingung:
+ anzahl dateien > 0
+
+INT PROC satzkombination
+ Liefert die laufende Nummer der Koppelkombination des aktuel­
+ len Satzes. Wird nur durch 'weiter' im Einzelsatzmodus erhöht.
+ Normalerweise 1.
+ Bedingung:
+ anzahl dateien > 0
+
+BOOL PROC dateiende
+ Gibt an, ob die Satzposition hinter dem letzten Satz liegt.
+
+PROC weiter (INT CONST modus)
+ Erhöht die aktuelle Satzposition. Für 'modus' gibt es 3 Möglich­
+ keiten:
+ 1: Falls eine weitere Satzkombination besteht, wird diese ein­
+ genommen, sonst zum nächsten Satz.
+ 2: Zum nächsten durch Suchbedingung ausgewählten Satz. Wird
+ optimiert.
+ 3: Zum nächsten markierten Satz. Wird optimiert.
+ Ist kein Satz mehr vorhanden, wird die Satzposition hinter dem
+ letzten Satz eingenommen.
+ Bedingung:
+ anzahl dateien > 0
+
+PROC zurueck (INT CONST modus)
+ Geht um einen Satz zurück. Die Modusangabe ist wie bei 'wei­
+ ter', jedoch wird im Modus 1 keine weitere Satzkombination
+ ausprobiert. Die Positionierung endet bei Satz 1.
+ Bedingung:
+ anzahl dateien > 0
+
+PROC auf satz (INT CONST satznr)
+ Geht auf den angegebenen Satz. Ist 'satznr' < 1, wird auf Satz 1
+ positioniert, ist der angegebene Satz nicht vorhanden, wird
+ hinter den letzten Satz positioniert. Es wird jeweils die erste
+ Satzkombination eingenommen.
+ Bedingung:
+ anzahl dateien > 0
+
+
+7.4 Änderungen
+
+Sätze des Dateimodells können eingefügt oder gelöscht werden.
+Durch das Einfügen entsteht ein leerer Satz vor dem aktuellen Satz;
+alle weiteren Sätze rücken eine Stelle weiter. Beim Löschen wird
+dieser Vorgang wieder rückgängig gemacht.
+ Durch 'satz einfuegen' wird ein Leersatz eingefügt; durch
+'satz loeschen' wird der aktuelle Satz gelöscht.
+ Sätze in gekoppelten Dateien werden grundsätzlich nicht ge­
+löscht; auch beim Einfügen entsteht nicht automatisch ein Leersatz
+in den gekoppelten Dateien. Änderungen in den Koppeldateien
+(durch 'feld aendern') werden gepuffert. Durch 'aenderungen ein­
+tragen' werden die Änderungen dann in die Koppeldateien eingetra­
+gen. Dabei kann auch ein neuer Satz in die Koppeldatei eingefügt
+werden. Bei Positionierungen wird diese Prozedur automatisch auf­
+gerufen.
+
+PROC satz einfuegen
+ Fügt vor dem aktuellen Satz einen Leersatz ein.
+ Bedingung:
+ anzahl dateien > 0
+
+PROC satz loeschen
+ Löscht den aktuellen Satz. Hat hinter dem letzten Satz keine
+ Wirkung.
+ Bedingung:
+ anzahl dateien > 0
+
+PROC aenderungen eintragen
+ Trägt die gepufferten Änderungen in die Koppeldateien ein.
+ Dabei können die folgenden Fälle auftreten:
+ 1. Der Satz in der Koppeldatei wird geändert.
+ Dies geschieht dann, wenn vorher ein passender Satz in der
+ Koppeldatei vorhanden war und die Koppelfelder nicht ver­
+ ändert wurden.
+ 2. In der Koppeldatei wird ein neuer Satz eingefügt.
+ Wenn die Koppelfelder und noch andere Felder einer Datei
+ geändert wurden, wird in dieser Datei ein neuer Satz einge­
+ fügt.
+ 3. Es wird neu gekoppelt.
+ Wurden nur die Koppelfelder einer Datei geändert, wird ein
+ neuer, zu diesen Feldern passender Satz gesucht. Nach
+ 'aenderungen eintragen' erscheinen unter den Feldern der
+ Datei die neuen Inhalte.
+
+
+7.5 Suchbedingungen
+
+Über 'suchbedingung' kann eine Suchbedingung eingetragen werden,
+die für jeden Satz geprüft werden soll. Mit 'satz ausgewaehlt' wird
+erfragt, ob der aktuelle Satz die Suchbedingung erfüllt. Die Such­
+bedingung kann mit 'suchbedingung loeschen' wieder ausgeschaltet
+werden.
+ Einzelne Sätze können auch markiert werden. Nach einem Öff­
+nen ist zunächst kein Satz markiert. Durch 'markierung  aendern'
+kann die Markierung eines Satzes geändert werden. 'satz markiert'
+fragt ab, ob der aktuelle Satz markiert ist. 'markierte saetze' liefert
+die Anzahl der markierten Sätze. Mit 'markierungen loeschen' wer­
+den alle Markierungen entfernt.
+
+PROC suchbedingung (INT CONST feldnr,
+ TEXT CONST bedingung)
+ Stellt für das angegebene Feld die im Text als Muster angege­
+ bene Suchbedingung ein. Weitere Aufrufe verknüpfen die Be­
+ dingungen mit UND (auch wenn das gleiche Feld erneut angege­
+ ben wird).
+ Bedingung:
+ anzahl dateien > 0
+ 1 <= feldnr <= anzahl felder
+
+ FEHLER:
+#f1#
+ #on("i")#Suchmuster zu umfangreich#off("i")#
+ Es wurden zu viele Vergleiche gefordert.
+
+BOOL PROC satz ausgewaehlt
+ Gibt an, ob die Suchbedingung auf den aktuellen Satz zutrifft.
+ Hinter dem letzten Satz wird immer FALSE geliefert.
+ Bedingung:
+ anzahl dateien > 0
+
+PROC suchbedingung lesen (INT CONST feldnr, TEXT VAR bedingung)
+ Liefert die zuletzt für das angegebene Feld eingestellte Bedin­
+ gung, falls die Suchbedingung nicht gelöscht und keine Datei
+ neu geöffnet wurde.
+ Bedingung:
+ 1 <= feldnr <= anzahl felder
+
+PROC suchbedingung loeschen
+ Löscht die eingestellte Suchbedingung wieder. Anschließend
+ sind alle Sätze ausgewählt.
+ Bedingung:
+ anzahl dateien > 0
+
+PROC markierung aendern
+ Ändert die Markierung des aktuellen Satzes ins Gegenteil.
+ Bedingung:
+ anzahl dateien > 0
+
+BOOL PROC satz markiert
+ Gibt an, ob der aktuelle Satz markiert ist.
+ Bedingung:
+ anzahl dateien > 0
+
+INT PROC markierte saetze
+ Gibt an, wieviel Sätze insgesamt markiert sind.
+ Bedingung:
+ anzahl dateien > 0
+
+PROC markierungen loeschen
+ Löscht alle Markierungen.
+ Bedingung:
+ anzahl dateien > 0
+
diff --git a/doc/eudas/eudas.ref.8 b/doc/eudas/eudas.ref.8
new file mode 100644
index 0000000..fc2b3bc
--- /dev/null
+++ b/doc/eudas/eudas.ref.8
@@ -0,0 +1,454 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (83)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+8 Funktionen zur Bearbeitung
+
+
+
+Die Verarbeitungsfunktionen arbeiten jeweils auf der aktuell geöff­
+neten Datei. Falls mindestens ein Satz markiert ist, werden nur
+markierte Sätze bearbeitet, anderenfalls die durch die Suchbedin­
+gung ausgewählten Sätze.
+
+
+8.1 Drucken
+
+Zum Drucken wird ein Druckmuster als Textdatei benötigt. Dessen
+Name muß beim Aufruf der Prozedur 'drucke' angegeben werden.
+Werden beim Übersetzen des Druckmusters Fehler entdeckt, so wird
+der Paralleleditor aufgerufen und kein Druckvorgang durchgeführt.
+ Normalerweise sendet der Druckgenerator die Ausgabe direkt
+zum Drucker. Alternativ kann die Ausgabe auch in eine Datei ge­
+schrieben werden. Dieses Verfahren kann mit 'direkt drucken' umge­
+stellt werden. Der Aufruf
+
+
+ direkt drucken (TRUE)
+
+
+sendet alle Dateien direkt zum Drucker, mit
+
+
+ direkt drucken (FALSE)
+
+
+wird die Ausgabe in Dateien abgelegt. Diese Dateien erhalten Namen
+der Form
+
+
+ "Druckmustername.a$n"
+
+
+wobei 'n' eine laufende Nummer zur Unterscheidung ist.
+ Soll die Druckausgabe in eine ganz bestimmte Datei geleitet
+werden, so kann vor dem Aufruf von 'drucke' die Prozedur 'druck­
+datei' aufgerufen werden, die als Parameter den Namen der Ausga­
+bedatei erhält. Existiert die Datei noch nicht, wird sie eingerichtet,
+ansonsten wird die Ausgabe am Ende angehängt.
+ Die Einstellung der Ausgabedatei gilt nur für einen Druckvor­
+gang und überschreibt für diesen Druckvorgang 'direkt drucken'.
+Beim nächsten Druckvorgang wird wieder die durch 'direkt drucken'
+festgelegte Einstellung verwendet.
+ Wenn beim Drucken ein großes Ausgabevolumen anfällt, kann es
+sinnvoll sein, die Ausgabe in mehrere kleine Dateien aufzuteilen.
+Dies gilt auch, wenn direkt gedruckt werden soll, da auch in diesem
+Fall eine Zwischendatei erzeugt werden muß. Die maximale Anzahl
+von Zeilen pro Datei wird durch 'max druckzeilen' angegeben.
+ Der dort angegeben Wert gilt nur ungefähr - ein Wechsel der
+Ausgabedatei findet dann statt, wenn die Ausgabedatei nach Bear­
+beitung eines Satzes die Maximalanzahl überschritten hat. In die
+neue Datei wird anschließend zuerst der Initialisierungsteil des
+Druckmusters kopiert, ehe mit der Ausgabe des nächsten Satzes
+fortgefahren wird.
+
+Die Prozeduren im einzelnen:
+
+
+PROC drucke (TEXT CONST druckmuster)
+
+ Die aktuell geöffnete Datei wird nach dem angegebenen Druck­
+ muster gedruckt.
+
+ FEHLER:
+#f1#
+ #on("i")#Datei "druckmuster" existiert nicht#off("i")#
+ Das angegebene Druckmuster ist nicht vorhanden.
+#f1#
+ #on("i")#keine Datei geoeffnet#off("i")#
+ Zum Drucken muß eine Datei geöffnet sein.
+#f1#
+ #on("i")#direkt Drucken nicht möglich#off("i")#
+ Es ist kein Druckprogramm installiert oder der Spooler läßt sich
+ mit 'print' nicht ansprechen. Der Druck wird abgebrochen, die
+ Ausgabedatei ist noch vorhanden.
+
+
+PROC direkt drucken (BOOL CONST ja)
+
+ Gibt an, ob die Druckausgaben direkt gedruckt oder in einer
+ Datei gesammelt werden sollen.
+
+
+PROC druckdatei (TEXT CONST ausgabedatei)
+
+ Leitet die Druckausgabe des nächsten Druckvorgangs in die
+ Datei 'ausgabedatei'. Die Einstellung von 'direkt drucken' wird
+ für diesen Druckvorgang überschrieben. Die Ausgabe wird am
+ Ende der Datei angehängt, falls nötig, wird die Ausgabedatei
+ vorher eingerichtet.
+
+
+PROC maxdruckzeilen (INT CONST zeilen)
+
+ Stellt die maximale Anzahl von Zeilen für die Ausgabedatei ein.
+ Beim Überschreiten dieses Wertes wird eine neue Datei ange­
+ fangen. Standardwert ist 4000.
+
+
+TEXT PROC lfd nr
+
+ Liefert während des Druckens die laufende Nummer des gerade
+ gedruckten Satzes als Text.
+
+
+BOOL PROC gruppenwechsel (INT CONST gruppennr)
+
+ Kann innerhalb eines Vor- oder Nachspanns beim Drucken ab­
+ gefragt werden, um festzustellen, ob die angegebene Gruppe
+ gewechselt und damit den Vor- bzw. Nachspann mitverursacht
+ hat (es können zu einem Zeitpunkt mehrere Gruppen wechseln).
+ Die Gruppennummer 0 gibt die Standardgruppe an, die nur vor
+ dem ersten und nach dem letzten Satz wechselt.
+
+
+8.2 Kopieren
+
+Zum selektiven Kopieren von EUDAS-Dateien wird ein Kopiermuster
+benötigt. Dieses gibt die Zuordnung zwischen Feldern der Ziel- und
+der Quelldatei an. Die Quelldatei ist immer die aktuell geöffnete
+Datei.
+ Die Kopierfunktion wird durch 'kopiere' aufgerufen. Parameter
+sind der Name der Zieldatei und das Kopiermuster als FILE. Alter­
+nativ kann statt des Kopiermusters eine Prozedur übergeben wer­
+den, die die Kopieranweisungen erhält.
+ Der eigentliche Kopiervorgang wird durch den Operator 'K'
+bewirkt. Dieser erhält den Zielfeldnamen und einen TEXT-Aus­
+druck als Parameter. Der Wert des TEXT-Ausdrucks wird in das
+jeweilige Feld der Zieldatei geschrieben.
+ Existiert die Zieldatei noch nicht, so wird sie mit den Feldern
+eingerichtet, die in den einzelnen 'K'-Ausdrücken angegeben sind
+und zwar in der angeführten Reihenfolge. Existiert die Zieldatei, so
+werden gegebenenfalls noch nicht vorhandene Felder am Ende ange­
+fügt.
+ Die Prozedur 'std kopiermuster' liefert zu einer gegebenen
+Zieldatei ein Standard-Muster, das als Auswahlgrundlage dienen
+kann. Existiert die Zieldatei nicht, werden alle Felder der Quell­
+datei 1 : 1 kopiert, anderenfalls wird zu jedem Feld der Zieldatei
+ein passendes Feld der Quelldatei gesucht - die Feldreihenfolge
+richtet sich in diesem Fall nach der Zieldatei.
+
+
+PROC kopiere (TEXT CONST dateiname,
+ FILE VAR kopiermuster)
+
+ Die aktuell geöffnete Datei wird nach den Angaben in 'kopier­
+ muster' in die Datei 'dateiname' kopiert. Das Kopiermuster wird
+ dem ELAN-Compiler übergeben. Tritt bei der Übersetzung ein
+ Fehler auf, wird der Paralleleditor aufgerufen.
+
+ FEHLER:
+#f1#
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Zieldatei existiert, ist aber keine EUDAS-Datei.
+#f1#
+ #on("i")#keine Datei geoeffnet#off("i")#
+ Es muß eine virtuelle Datei vorhanden sein.
+
+
+PROC kopiere (TEXT CONST dateiname, PROC kopierfunktion)
+
+ Wie oben, nur ist die Kopierfunktion gleich als Prozedur vor­
+ handen.
+
+ FEHLER:
+#f1#
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Zieldatei existiert, ist aber keine EUDAS-Datei.
+#f1#
+ #on("i")#keine Datei geoeffnet#off("i")#
+ Es muß eine virtuelle Datei vorhanden sein.
+
+
+OP K (TEXT CONST feldname, ausdruck)
+
+ Kopiert den Ausdruck in das Feld 'feldname' der Zieldatei.
+ Dieses Feld wird eingerichtet, falls es noch nicht existiert.
+ Dieser Operator ist nur während eines Kopiervorganges de­
+ finiert (also in einem Kopiermuster oder einer Kopierfunktion).
+ Er darf nicht in einer IF-Klausel stehen, sondern muß bei
+ jedem Satz mit gleichem Feldnamen an der gleichen Stelle auf­
+ gerufen werden.
+
+
+PROC std kopiermuster (TEXT CONST dateiname,
+ FILE VAR kopiermuster)
+
+ Liefert ein Standard-Kopiermuster, abhängig von der Zieldatei
+ 'dateiname'. Existiert diese nicht, wird die Quelldatei unverän­
+ dert kopiert, ansonsten richtet sich das Kopiermuster nach der
+ Zieldatei.
+
+
+8.3 Tragen
+
+Durch Tragen können Sätze komplett in eine Zieldatei transportiert
+werden. In der Quelldatei sind sie anschließend nicht mehr vorhan­
+den. Eine ganze Auswahl von Sätzen kann mit 'trage' transportiert
+werden. 'trage satz' transportiert nur den aktuellen Satz. Mit
+'hole satz' kann der letzte Satz der Zieldatei wieder zurückgeholt
+werden, so daß eine EUDAS-Datei auch als Zwischenspeicher für
+Einzelsätze verwendet werden kann.
+ Existiert die Zieldatei bereits, muß sie mindestens so viele
+Felder wie die Quelldatei besitzen, damit keine Informationen ver­
+lorengehen können. Die Feldnamen müssen nicht übereinstimmen.
+Existiert die Zieldatei noch nicht, wird sie mit den Feldern der
+Quelldatei eingerichtet.
+ Die Tragefunktion kann um eine gleichzeitige Prüfung erweitert
+werden. Dabei werden Bedingungen überprüft, die bei der Zieldatei
+gespeichert sind. Sätze, die diese Bedingungen verletzen, werden
+nicht getragen. Eine entsprechende Meldung wird in eine Protokoll­
+datei geschrieben, die als Parameter übergeben werden muß.
+ Die Prüfbedingungen stehen als ausführbares Programm in den
+Notizen der Zieldatei. Prüfbedingungen können mit mehreren Proze­
+duren formuliert werden. 'pruefe' nimmt eine beliebige Bedingung als
+Parameter und gibt bei Mißerfolg eine Meldung aus. 'wertemenge'
+prüft auf Übereinstimmung mit einem der angegebenen Werte. 'feld­
+maske' legt eine Maske für ein Feld fest, die auf den Inhalt zutref­
+fen muß.
+ Mit Hilfe der Prozedur 'eindeutige felder' können Satzduplikate
+erkannt werden. Auch diese werden nicht getragen.
+ Die bei den Prüfbedingungen angegebenen Feldnamen müssen in
+der Quelldatei vorhanden sein. Falls eine Prüfprozedur außerhalb
+von 'trage' aufgerufen wird, führt eine Verletzung der Prüfbedin­
+gung zu einem 'errorstop'.
+
+
+PROC trage (TEXT CONST dateiname,
+ FILE VAR protokoll, BOOL CONST test)
+
+ Alle ausgewählten Sätze werden in die Datei 'dateiname' getra­
+ gen. Diese wird gegebenenfalls eingerichtet. Falls 'test' ange­
+ geben ist, werden die in den Notizen der Zieldatei enthaltenen
+ Bedingungen geprüft. Nur in diesem Fall muß 'protokoll' initial­
+ isiert sein.
+
+ FEHLER:
+#f1#
+ #on("i")#kein Satz zum Tragen vorhanden#off("i")#
+ Die Quelldatei ist leer oder es ist keine Datei geöffnet.
+#f1#
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Zieldatei existiert, ist aber keine EUDAS-Datei.
+#f1#
+ #on("i")#Zieldatei hat falsche Felderzahl#off("i")#
+ Zu wenig Felder in der Zieldatei.
+
+
+PROC trage satz (TEXT CONST dateiname)
+
+ Der aktuelle Satz wird in die Datei 'dateiname' getragen.
+
+ FEHLER:
+#f1#
+ #on("i")#kein Satz zum Tragen vorhanden#off("i")#
+ Keine Datei geöffnet oder Datei ist am Ende.
+#f1#
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Zieldatei existiert, ist aber keine EUDAS-Datei.
+#f1#
+ #on("i")#Zieldatei hat falsche Felderzahl#off("i")#
+ Zu wenig Felder in der Zieldatei.
+
+
+PROC pruefe (TEXT CONST feldname, BOOL CONST bedingung)
+
+ Wenn die angegebene Bedingung FALSE liefert, wird eine Mel­
+ dung in die Protokolldatei geschrieben und der jeweilige Satz
+ nicht getragen.
+
+
+PROC wertemenge (TEXT CONST feldname. menge)
+
+ Es wird geprüft, ob das angegebene Feld in der Wertemenge
+ enthalten ist. Die einzelnen Werte in der Wertemenge werden
+ dabei durch Komma getrennt. Leerzeichen sind signifikant.
+
+
+PROC feldmaske (TEXT CONST feldname, maske)
+
+ Es wird geprüft, ob das angegebene Feld zu der Maske paßt. Die
+ Zeichen in der Maske haben dabei folgende Bedeutung:
+ '9' trifft auf jede Ziffer zu
+ 'X' trifft auf jedes Zeichen zu
+ 'A' trifft auf jeden Großbuchstaben zu (einschließlich
+ Umlaute)
+ 'a' trifft auf jeden Kleinbuchstaben zu (einschließlich
+ Umlaute und 'ß')
+ '*' trifft auf eine Folge beliebiger Zeichen zu (auch die
+ leere Folge). Eine sparsame Verwendung wird empfoh­
+ len, da die Bearbeitung sehr aufwendig ist.
+ Alle anderen Zeichen treffen nur auf ein gleiches Zeichen zu.
+
+
+PROC eindeutige felder (INT CONST anzahl)
+
+ Gibt an, die wieviel ersten Felder einen Satz eindeutig identifi­
+ zieren sollen. Ein Satz, der mit einem Satz der Datei in diesen
+ Feldern übereinstimmt, wird nicht getragen. Ohne diese Angabe
+ wird keine derartige Prüfung vorgenommen.
+
+
+PROC hole satz (TEXT CONST dateiname)
+
+ Holt den letzten Satz der angegebenen Datei und fügt ihn vor
+ dem aktuellen Satz ein.
+
+ FEHLER:
+#f1#
+ #on("i")#"dateiname" existiert nicht#off("i")#
+#f1#
+ #on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Zieldatei existiert, ist aber keine EUDAS-Datei.
+#f1#
+ #on("i")#Zieldatei hat falsche Felderzahl#off("i")#
+ Zu viele Felder in der angegebenen Datei.
+#f1#
+ #on("i")#Kein Satz zum Tragen vorhanden#off("i")#
+ Die angegebene Datei ist leer.
+#f1#
+ #on("i")#keine Datei geoeffnet#off("i")#
+ Es muß eine virtuelle Datei vorhanden sein.
+
+
+8.4 Verarbeitung
+
+Die ausgewählten Sätze der aktuellen Datei können nach einer
+Verarbeitungsvorschrift verändert oder geprüft werden. Dies ge­
+schieht durch die Prozedur 'verarbeite'. Als Parameter kann ent­
+weder ein Verarbeitungsmuster als FILE oder die Verarbeitungs­
+funktion direkt als Prozedur übergeben werden.
+ Die Vorschrift wird durch den Operator 'V' realisiert.
+
+
+PROC verarbeite (FILE VAR verarbeitungsmuster)
+
+ Die aktuelle Datei wird nach dem angegebenen Muster bearbei­
+ tet. Enthält die Vorschrift, die dem ELAN-Compiler übergeben
+ wird, einen Fehler, wird der Paralleleditor aufgerufen.
+
+ FEHLER:
+#f1#
+ #on("i")#keine Datei geoeffnet#off("i")#
+ Es muß eine virtuelle Datei vorhanden sein.
+
+
+PROC verarbeite (PROC verarbeitungsfunktion)
+
+ Wie oben, nur wird die Vorschrift direkt als Prozedur überge­
+ ben.
+
+ FEHLER:
+#f1#
+ #on("i")#keine Datei geoeffnet#off("i")#
+ Es muß eine virtuelle Datei vorhanden sein.
+
+
+OP V (TEXT CONST feldname, ausdruck)
+
+ Das angegebene Feld des aktuellen Satzes wird durch den Aus­
+ druck ersetzt.
+
+ FEHLER:
+#f1#
+ #on("i")#Das Feld "feldname" ist nicht definiert.#off("i")#
+ Das angegebene Feld ist nicht vorhanden.
+
+
+8.5 Funktionen in Ausdrücken
+
+Für Ausdrücke bei den in diesem Kapitel beschriebenen Prozeduren
+sind einfache Funktionen zur Abfrage von Feldinhalten vorhanden.
+Mit 'f' kann der Inhalt eines benannten Feldes erfragt werden, bei
+'wert' wird der Inhalt erst in eine REAL-Zahl umgewandelt, wobei
+nichtnumerische Zeichen ignoriert werden.
+ Die Prozedur 'textdarstellung' kann dazu verwendet werden,
+den Wert einer TEXT-Variablen als TEXT-Denoter in ELAN-Syntax
+darzustellen.
+ Die Prozedur 'zahltext' kann dazu verwendet werden, aus einer
+REAL-Zahl einen mit der richtigen Zahl von Nachkommastellen ver­
+sehenen, variabel langen Text zu machen.
+
+
+TEXT PROC f (TEXT CONST feldname)
+
+ Liefert den Inhalt des angegebenen Feldes.
+
+ FEHLER:
+#f1#
+ #on("i")#Das Feld "feldname" ist nicht definiert.#off("i")#
+
+
+REAL PROC wert (TEXT CONST feldname)
+
+ Liefert den Inhalt des angegebenen Feldes als REAL. Dabei
+ werden nichtnumerische Zeichen ignoriert, ausgenommen das
+ Minuszeichen und das eingestellte Dezimalkomma (s. 'dezimal­
+ komma'). Tritt kein numerisches Zeichen auf, wird der Wert 0.0
+ geliefert.
+
+ FEHLER:
+#f1#
+ #on("i")#Das Feld "feldname" ist nicht definiert.#off("i")#
+
+
+REAL PROC wert (TEXT CONST feldname, INT CONST kommastellen)
+
+ Wie 'wert' mit einem Parameter, nur daß das Ergebnis auf die
+ angegebene Anzahl von Nachkommastellen gerundet wird.
+
+ FEHLER:
+#f1#
+ #on("i")#Das Feld "feldname" ist nicht definiert.#off("i")#
+
+
+TEXT PROC textdarstellung (TEXT CONST anzeigetext)
+
+ Liefert 'anzeigetext' als TEXT-Denoter, also in Anführungs­
+ strichen. Anführungsstriche im Text werden dabei verdoppelt.
+ Steuerzeichen von 0 bis 31 werden in lesbare Form gebracht.
+
+
+TEXT PROC zahltext (REAL CONST wert, INT CONST kommastellen)
+
+ Liefert den Text des angegebenen Werts mit dem eingestellten
+ Dezimalkomma und mit der angegebenen Zahl von Nachkomma­
+ stellen. Sind die Kommastellen 0, wird auch das Komma unter­
+ drückt. Der Text erhält soviel Stellen, wie zur Darstellung
+ benötigt werden.
+
+
+TEXT PROC zahltext (TEXT CONST feldname,
+ INT CONST kommastellen)
+
+ Wirkt wie 'zahltext (wert (feldname), kommastellen)'.
+
diff --git a/doc/eudas/eudas.ref.9 b/doc/eudas/eudas.ref.9
new file mode 100644
index 0000000..dc2dd0d
--- /dev/null
+++ b/doc/eudas/eudas.ref.9
@@ -0,0 +1,194 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (93)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+9 Anzeige
+
+
+
+9.1 Fensterverwalter
+
+Funktionen, die einen Teil des Bildschirms in einem rechteckigen
+Fenster beschreiben, werden über den Fensterverwalter untereinan­
+der koordiniert. Jede Funktion fordert für ihren Fensterbereich eine
+Variable vom Typ FENSTER an. Vor jedem Bildschirmzugriff kann die
+Funktion erfahren, ob andere Programme den Bildschirm im Fenster­
+bereich überschrieben haben. Gleichzeitig meldet sie damit Verän­
+derungen an anderen Fenstern an, die sich mit dem eigenen über­
+schneiden.
+
+
+PROC fenster initialisieren (FENSTER VAR neu)
+
+ Jede Fenstervariable muß vor Benutzung initialisiert werden.
+
+
+PROC fenstergroesse setzen (FENSTER VAR fenster,
+ INT CONST x anf, y anf,
+ x laenge, y laenge)
+
+ Die Fenstergröße des Fensters wird gesetzt. 'x anf' und 'y anf'
+ werden von 1..n gezählt. Die Größe eines 24x80-Bildschirms
+ entspricht den Angaben (1, 1, 79, 24). Da das letzte Zeichen
+ einer Zeile wegen Rollgefahr nicht benutzt werden kann, werden
+ nur 79 Spalten angegeben.
+
+ FEHLER:
+
+ #on("i")#zu viele Fenster#off("i")#
+ Es sind nur 16 verschiedene Fenstergrößen möglich.
+
+
+PROC fenstergroesse (FENSTER CONST fenster,
+ INT VAR x anf, y anf,
+ x laenge, y laenge)
+
+ Meldet die eingestellte Größe des Fensters.
+
+
+PROC fensterzugriff (FENSTER CONST mein fenster,
+ BOOL VAR veraendert)
+
+ Ein Zugriff auf 'mein fenster' wird angemeldet. 'veraendert' gibt
+ an, ob das Fenster seit dem letzten Zugriff durch einen über­
+ schneidenden Zugriff verändert wurde. Beim ersten Zugriff ist
+ 'veraendert' immer TRUE.
+
+
+PROC fenster veraendert (FENSTER CONST fenster)
+
+ Falls ein Unterprogramm eine FENSTER-Variable des Hauptpro­
+ grammes benutzt, kennzeichnet das Unterprogramm das Fenster
+ mit dieser Prozedur als benutzt, damit das Hauptprogramm das
+ Bild neu ausgibt.
+
+
+PROC bildschirm neu
+
+ Gibt an, daß der Bildschirm von einer Funktion benutzt wurde,
+ die ihre Zugriffe nicht über den Fensterverwalter anmeldet.
+ Alle Fenster werden als verändert gekennzeichnet.
+
+
+9.2 Anzeigegrundfunktionen
+
+Sämtliche Anzeigefunktionen werden in einem Fenster abgewickelt,
+dessen Größe durch 'anzeigefenster' bestimmt wird.
+ Die Funktion 'bildausgeben' übernimmt die eigentliche Ausgabe.
+Dabei kann durch Parameter mitgeteilt werden, ob sich an der Datei
+außer der Markierung etwas geändert hat. Hat sich nichts geändert,
+wird zur Optimierung unter Umständen nur die Markierung neu
+ausgegeben. Das Bild wird jedoch auf jeden Fall ganz ausgegeben,
+wenn das Fenster von anderer Seite verändert wurde. Auch das
+Öffnen einer neuen Datei wird automatisch erkannt und richtig
+behandelt.
+ Welche Felder dargestellt werden sollen, kann durch 'feldaus­
+wahl' angegeben werden. Dabei ist für jeden Anzeigemodus eine
+eigene Feldauswahl möglich. Die Darstellung kann durch 'rollen' in
+vertikaler Richtung verschoben werden.
+ Mit 'uebersicht' kann die Übersicht ausgegeben werden. Ihre
+Größe wird durch 'uebersichtsfenster' angegeben.
+
+
+PROC anzeigefenster (INT CONST x anf, y anf,
+ x laenge, y laenge)
+
+ Das Anzeigefenster wird in der entsprechenden Größe reser­
+ viert.
+
+ FEHLER:
+
+ #on("i")#Anzeigefenster zu klein#off("i")#
+ Das Fenster ist zu schmal (< 40 Zeichen), um eine sinnvolle
+ Anzeige zuzulassen.
+
+
+PROC bild ausgeben (BOOL CONST datei veraendert)
+
+ Im Anzeigefenster wird das Bild je nach eingestelltem Modus
+ ausgegeben, wenn das Fenster verändert wurde oder 'satz ver­
+ aendert' TRUE ist. 'satz veraendert' muß immer dann angegeben
+ werden, wenn am Inhalt der virtuellen Datei etwas verändert
+ wurde.
+
+
+PROC feldauswahl (TEXT CONST feldcode)
+
+ Die im aktuellen Modus anzuzeigenden Felder und ihre Reihen­
+ folge werden ausgewählt. Dabei enthält 'feldcodes' an der i-ten
+ Stelle den Code der Feldnummer des Feldes, das an i-ter Posi­
+ tion erscheinen soll.
+
+
+PROC rollen (INT CONST anzahl)
+
+ Die Darstellung wird um die angegebene Anzahl von Zeilen
+ gerollt. Bei einer positiven Angabe wird zu höheren Feld- bzw.
+ Satznummern gerollt (Bild bewegt sich umgekehrt). Beim ersten
+ bzw. letzten Feld bzw. Satz hört das Rollen automatisch auf.
+
+
+PROC uebersichtsfenster (INT CONST x anf, y anf,
+ x laenge, y laenge)
+
+ Legt die Größe des Übersichtsfensters fest.
+
+
+PROC uebersicht (TEXT CONST feldauswahl)
+
+ Ruft eine Übersicht der aktuellen Datei auf, in der geblättert
+ und markiert werden kann. In 'feldauswahl' steht an der Stelle
+ i der Code der Feldnummer, die als i-tes in der Aufzählung
+ erscheinen soll.
+
+
+9.3 Editorfunktionen
+
+Es stehen drei Funktionen zur Verfügung, die den Editor im Anzei­
+gemodus benutzen. Sie dienen zum Einfügen und Ändern sowie zum
+Eingeben eines Suchmusters.
+ Der Editor wird durch ESC 'q' verlassen. Weitere ESC-Funk­
+tionen, die zum Verlassen führen sollen, können durch 'exit zeichen'
+angegegeben und nach Funktionsausführung mit 'exit durch' abge­
+fragt werden.
+
+
+PROC aendern (PROC hilfe)
+
+ Bietet den aktuellen Satz zum Ändern an. Steht die virtuelle
+ Datei am Ende, wird automatisch 'einfuegen' durchgeführt. Bei
+ ESC '?' wird 'hilfe' aufgerufen.
+
+
+PROC einfuegen (PROC hilfe)
+
+ Fügt vor dem aktuellen Satz einen Satz ein, dessen Inhalt im
+ Editor angegeben wird. Bei ESC '?' wird 'hilfe' aufgerufen.
+
+
+PROC suchen (PROC hilfe)
+
+ Im Editor wird eine neue Suchbedingung eingegeben. Bei ESC '?'
+ wird 'hilfe' aufgerufen.
+
+
+PROC exit durch (TEXT CONST zeichenkette)
+
+ Gibt die Zeichen an, die beim Drücken nach ESC zum Verlassen
+ des Editors führen sollen. Die eingegebenen Daten werden je­
+ doch vorher auf jeden Fall noch verarbeitet.
+
+
+TEXT PROC exit durch
+
+ Gibt an, durch welches Zeichen der Editor verlassen wurde.
+
diff --git a/doc/eudas/eudas.ref.fehler b/doc/eudas/eudas.ref.fehler
new file mode 100644
index 0000000..736d009
--- /dev/null
+++ b/doc/eudas/eudas.ref.fehler
@@ -0,0 +1,139 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (115)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+Fehlermeldungen
+
+
+
+In diesem Kapitel sind alle Fehlermeldungen aufgeführt, die von
+EUDAS erzeugt werden und zum Abbruch einer Funktion führen
+können.
+
+#on("i")#'n' ist keine Feldnummer#off("i")#
+ Es wurde eine Nummer als Feldnummer angegeben, die nicht er­
+ laubt ist.
+
+#on("i")#Datei ist keine EUDAS-Datei#off("i")#
+ Es wurde versucht, eine andere Datei als EUDAS-Datei zu bear­
+ beiten.
+
+#on("i")#inkonsistente EUDAS-Datei#off("i")#
+ Die interne Struktur der Datei ist zerstört. Kann durch Hardware­
+ probleme (Archiv-Lesefehler) oder EUDAS-interne Fehler ent­
+ standen sein.
+
+#on("i")#EUDAS-Datei voll#off("i")#
+ Eine EUDAS-Datei kann nur eine bestimmte Anzahl von Sätzen
+ aufnehmen (mindestens 5000).
+
+#on("i")#Nicht erlaubtes Dezimalkomma#off("i")#
+ Als Dezimalkomma kann nur ein einzelnes Zeichen angegeben
+ werden.
+
+#on("i")#Zuviel Dateien geoeffnet#off("i")#
+ Es können nicht mehr als 10 Dateien gleichzeitig geöffnet, geket­
+ tet und gekoppelt sein.
+
+#on("i")#Zu viele Felder#off("i")#
+ Alle geöffneten Dateien zusammen dürfen nicht mehr als 256
+ Felder der virtuellen Datei ergeben.
+
+#on("i")#Zu viele Koppelfelder#off("i")#
+ Es dürfen insgesamt nicht mehr als 32 Koppelfelder entstehen.
+
+#on("i")#keine Koppelfelder vorhanden#off("i")#
+ Eine Datei kann nicht gekoppelt werden, wenn Sie kein Koppelfeld
+ besitzt.
+
+#on("i")#keine Datei geoeffnet#off("i")#
+ Es kann nicht gekettet oder gekoppelt werden, wenn noch keine
+ Datei geöffnet wurde. Ebenfalls sind keine Verarbeitungsproze­
+ duren möglich.
+
+#on("i")#Nicht möglich, wenn auf Koppeldatei geschaltet#off("i")#
+ Wenn auf eine Koppeldatei umgeschaltet wurde, ist Öffnen, Ketten
+ und Koppeln nicht möglich.
+
+#on("i")#kein direkter Dateizugriff bei geketteten oder gekoppelten Dateien#off("i")#
+ Wenn Dateien gekettet oder gekoppelt sind, ist Sortieren und
+ Ändern der Feldstruktur nicht möglich.
+
+#on("i")#Datei nicht gesichert#off("i")#
+ Eine vorher geöffnete Datei ist verändert und nicht gesichert.
+
+#on("i")#Datei wird von anderer Task geändert#off("i")#
+ Das Öffnen der Datei zum Ändern ist im Moment nicht möglich, da
+ ein anderer Benutzer sie bereits ändert.
+
+#on("i")#Suchmuster zu umfangreich#off("i")#
+ Ein Suchmuster darf nicht mehr als 100 Vergleiche erfordern.
+
+#on("i")#direkt Drucken nicht moeglich#off("i")#
+ Entweder ist kein Druckprogramm installiert oder die Spooltask
+ reagiert nicht.
+
+#on("i")#Das Feld "Feldname" ist nicht definiert#off("i")#
+ Sie haben einen falschen Namen angegeben.
+
+#on("i")#Kein Satz zum Tragen vorhanden#off("i")#
+ Es wurde versucht, aus einer leeren Datei oder am Dateiende zu
+ tragen.
+
+#on("i")#Zieldatei hat falsche Felderzahl#off("i")#
+ Eine Zieldatei beim Tragen hat weniger Felder als die aktuelle
+ Datei. Daher würden beim Tragen Informationen verlorengehen.
+
+#on("i")#Zieldatei darf nicht geöffnet sein#off("i")#
+ Eine geöffnete Datei ist als Zieldatei nicht zulässig.
+
+#on("i")#Das Feld "Feldname" verletzt die Pruefbedingung#off("i")#
+ Eine Prüfprozedur wurde außerhalb des Tragens aufgerufen und
+ die Bedingung war nicht erfüllt.
+
+#on("i")#Das Feld "Feldname" ist nicht in der Wertemenge#off("i")#
+ Eine Prüfprozedur wurde außerhalb des Tragens aufgerufen und
+ die Bedingung war nicht erfüllt.
+
+#on("i")#Das Feld "Feldname" stimmt nicht mit der Maske ueberein#off("i")#
+ Eine Prüfprozedur wurde außerhalb des Tragens aufgerufen und
+ die Bedingung war nicht erfüllt.
+
+#on("i")#Zu viele Fenster#off("i")#
+ Es sind nicht mehr als 16 verschiedene Größen von Fenstern
+ möglich.
+
+#on("i")#Fenster zu klein#off("i")#
+ Ein Menü wurde in einem zu kleinen Fenster aufgerufen.
+
+#on("i")#Hilfe existiert nicht#off("i")#
+ Es wurde versucht, eine nicht vorhandene Hilfestellung aufzu­
+ rufen.
+
+#on("i")#Hilfe ist leer#off("i")#
+ Die angewählte Hilfestellung enthält keinen Text.
+
+#on("i")#Anzeigefenster zu klein#off("i")#
+ Das Anzeigefenster muß mindestens 40 Zeichen breit sein.
+
+#on("i")#Ungueltige Satznummer#off("i")#
+ Der angegebene Text stellt keine Satznummer dar.
+
+#on("i")#kein rekursiver Aufruf#off("i")#
+ Innerhalb von EUDAS darf 'eudas' nicht erneut aufgerufen wer­
+ den.
+
+#on("i")#Task existiert nicht#off("i")#
+ Es wurde versucht, eine nicht existente Task als Manager einzu­
+ stellen.
+
+
diff --git a/doc/eudas/eudas.ref.inhalt b/doc/eudas/eudas.ref.inhalt
new file mode 100644
index 0000000..ae997cb
--- /dev/null
+++ b/doc/eudas/eudas.ref.inhalt
@@ -0,0 +1,120 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (3)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+Inhalt
+
+
+
+ Vorwort . . . . . . . . . . . . . . . . . . . i
+ Inhalt . . . . . . . . . . . . . . . . . . . . iii
+
+
+I. Funktionen zum Nachschlagen
+
+#on("b")#1 Zustände und Bedienung#off("b")#
+#free (0.2)#
+1.1 Zustände . . . . . . . . . . . . . . . . . . . 3
+1.2 Menüs . . . . . . . . . . . . . . . . . . . . 8
+1.3 Auswahl . . . . . . . . . . . . . . . . . . . 8
+1.4 Hilfe und Dialog . . . . . . . . . . . . . . . 9
+1.5 Editor . . . . . . . . . . . . . . . . . . . . 9
+
+#on("b")#2 Zusammenstellung der Funktionen#off("b")#
+#free (0.2)#
+2.1 Menü 'Öffnen' . . . . . . . . . . . . . . . . 13
+2.2 Menü 'Einzelsatz' . . . . . . . . . . . . . . 17
+2.3 Menü 'Gesamtdatei' . . . . . . . . . . . . . . 21
+2.4 Menü 'Drucken' . . . . . . . . . . . . . . . . 23
+2.5 Menü 'Dateien' . . . . . . . . . . . . . . . . 25
+2.6 Menü 'Archiv' . . . . . . . . . . . . . . . . 27
+2.7 Kurzabfrage . . . . . . . . . . . . . . . . . 29
+
+#on("b")#3 Das virtuelle Dateimodell#off("b")#
+#free (0.2)#
+3.1 Dateistruktur . . . . . . . . . . . . . . . . 31
+3.2 Öffnen . . . . . . . . . . . . . . . . . . . . 32
+3.3 Koppeln . . . . . . . . . . . . . . . . . . . 33
+3.4 Änderungen . . . . . . . . . . . . . . . . . . 34
+3.5 Sichern . . . . . . . . . . . . . . . . . . . 36
+3.6 Umschalten auf Koppeldatei . . . . . . . . . . 36
+3.7 Mehrbenutzerbetrieb . . . . . . . . . . . . . 37
+
+#on("b")#4 Ansehen und Bearbeiten#off("b")#
+#free (0.2)#
+4.1 Anzeige . . . . . . . . . . . . . . . . . . . 39
+4.2 Satzauswahl . . . . . . . . . . . . . . . . . 42
+4.3 Sortieren und Reorganisieren . . . . . . . . . 44
+4.4 Bearbeiten . . . . . . . . . . . . . . . . . . 46
+
+#on("b")#5 Drucken und Druckmuster#off("b")#
+#free (0.2)#
+5.1 Druckmustersyntax . . . . . . . . . . . . . . 49
+5.2 Der Druckvorgang . . . . . . . . . . . . . . . 51
+5.3 Interpretation von Musterzeilen . . . . . . . 52
+5.4 Anschluß zum ELAN-Compiler . . . . . . . . . . 56
+5.5 Fehlermeldungen . . . . . . . . . . . . . . . 57
+
+
+II. EUDAS für Programmierer
+
+#on("b")#6 Struktur von EUDAS-Dateien#off("b")#
+#free (0.2)#
+6.1 Der Datentyp SATZ . . . . . . . . . . . . . . 61
+6.2 Der Datentyp EUDAT . . . . . . . . . . . . . . 63
+6.3 Satzposition . . . . . . . . . . . . . . . . . 64
+6.4 Satzzugriffe . . . . . . . . . . . . . . . . . 65
+6.5 Sortieren und Reorganisieren . . . . . . . . . 66
+6.6 EUDAS-Dateien als Assoziativspeicher . . . . . 68
+
+#on("b")#7 Verwaltung der offenen Dateien#off("b")#
+#free (0.2)#
+7.1 Dateiverwaltung . . . . . . . . . . . . . . . 71
+7.2 Feldstruktur . . . . . . . . . . . . . . . . . 75
+7.3 Positionierung . . . . . . . . . . . . . . . . 77
+7.4 Änderungen . . . . . . . . . . . . . . . . . . 78
+7.5 Suchbedingungen . . . . . . . . . . . . . . . 79
+
+#on("b")#8 Funktionen zur Bearbeitung#off("b")#
+#free (0.2)#
+8.1 Drucken . . . . . . . . . . . . . . . . . . . 83
+8.2 Kopieren . . . . . . . . . . . . . . . . . . . 85
+8.3 Tragen . . . . . . . . . . . . . . . . . . . . 87
+8.4 Verarbeitung . . . . . . . . . . . . . . . . . 89
+8.5 Funktionen in Ausdrücken . . . . . . . . . . . 90
+
+#on("b")#9 Anzeige#off("b")#
+#free (0.2)#
+9.1 Fensterverwalter . . . . . . . . . . . . . . . 93
+9.2 Anzeigegrundfunktionen . . . . . . . . . . . . 94
+9.3 Editorfunktionen . . . . . . . . . . . . . . . 95
+
+#on("b")#10 Programmierung der Menüs#off("b")#
+#free (0.2)#
+10.1 Menüformat . . . . . . . . . . . . . . . . . . 97
+10.2 Verwaltung der Menüs . . . . . . . . . . . . . 99
+10.3 Aufruf . . . . . . . . . . . . . . . . . . . . 101
+10.4 Dialog . . . . . . . . . . . . . . . . . . . . 103
+
+#on("b")#11 Programmierung von Anwendungen#off("b")#
+#free (0.2)#
+11.1 Musterprogramme . . . . . . . . . . . . . . . 105
+11.2 Dateianwendungen . . . . . . . . . . . . . . . 109
+11.3 Integrierte Anwendungen . . . . . . . . . . . 111
+
+
+III. Anhang
+
+ Fehlermeldungen . . . . . . . . . . . . . . . 115
+ Prozeduren mit Parametern . . . . . . . . . . 119
+ Register . . . . . . . . . . . . . . . . . . . 125
+
diff --git a/doc/eudas/eudas.ref.macros b/doc/eudas/eudas.ref.macros
new file mode 100644
index 0000000..1d24468
--- /dev/null
+++ b/doc/eudas/eudas.ref.macros
@@ -0,0 +1,73 @@
+#*format#
+#limit (13.5)##start (3.5,2.5)##pagelength (21.0)##block#
+#:firsthead (false)#
+#linefeed (1.07)#
+#*macro end#
+#*text#
+#type ("prop10")#
+#linefeed (1.07)#
+#*macro end#
+#*beispiel#
+#type ("12")#
+#linefeed (0.97)#
+#*macro end#
+#*bildschirm#
+#type ("15")#
+#linefeed(0.83)#
+#*macro end#
+#*proc#
+#type ("12")#
+#*macro end#
+#*endproc#
+#free (0.1)#
+#type ("prop10")#
+#linefeed (1.07)#
+#*macro end#
+#*abschnitt ($1,$2,$3)#
+#headodd#
+#on("b")#$1#right#$3 %#off("b")#
+#free (1.0)#
+#end#
+#on("b")##ib(9)#$1#ie(9,"   $3")# $2#off("b")#
+#*macro end#
+#*char($1)#
+$1
+#*macro end#
+#*kapitel ($1,$2,$3,$4)#
+#free (1.3)#
+#"nlq"#
+#type("roman.24")#
+#on("b")##center#$1#off("b")#
+#free (0.2)#
+#type ("roman.18")#
+#on("b")##center#$2 #off("b")#
+#on("b")##center# $3#off("b")#
+#on("b")##center#$4#off("b")#
+#type ("prop10")#
+#free (0.6)#
+#headeven#
+#on("b")#% $2 $3 $4#off("b")#
+#free (1.0)#
+#end#
+#headodd#
+#right##on("b")#%#off("b")#
+#free (1.0)#
+#end#
+#*macro end#
+#*f2#
+#free (0.2)#
+#*macro end#
+#*a ($1)#
+#on("b")#$1.#off("b")# 
+#*macro end#
+#*bsp ($1)#
+#type("12")#$1#type("prop")#
+#*macro end#
+#*f1#
+#free (0.1)#
+#*macro end#
+
+
+
+
+
diff --git a/doc/eudas/eudas.ref.proz b/doc/eudas/eudas.ref.proz
new file mode 100644
index 0000000..2007bc1
--- /dev/null
+++ b/doc/eudas/eudas.ref.proz
@@ -0,0 +1,205 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (119)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+Prozeduren mit Parametern
+
+
+
+
+:= (SATZ VAR, SATZ CONST) 6.1
+
+aendern (PROC hilfe) 9.3
+aendern erlaubt : BOOL 7.1
+aenderungen eintragen 7.4
+anzahl dateien : INT 7.1
+anzahl felder : INT 7.2
+anzahl koppeldateien : INT 7.1
+anzeigefenster (INT CONST x anf, y anf,
+ x laenge, y laenge) 9.2
+auf satz (EUDAT VAR, INT CONST satznr) 6.3
+auf satz (EUDAT VAR, TEXT CONST muster) 6.3
+auf satz (INT CONST satznr) 7.3
+ausfuehrtaste (TEXT CONST taste) 10.3
+auswahl anbieten (TEXT CONST name, FENSTER CONST f,
+ TEXT CONST hilfe,
+ PROC (TEXT VAR, INT CONST) inhalt) 10.3
+
+bild ausgeben (BOOL CONST datei veraendert) 9.2
+bildschirm neu 9.1
+
+dateiende (EUDAT CONST) : BOOL 6.3
+dateiende : BOOL 7.3
+dateien loeschen (BOOL CONST auch geaenderte) 7.1
+dateiversion : INT 7.1
+dezimalkomma (TEXT CONST komma) 6.5
+dezimalkomma : TEXT 6.5
+dialog 10.4
+dialogfenster (INT CONST x anf, y anf,
+ x laenge, y laenge) 10.4
+direkt drucken (BOOL CONST ja) 8.1
+druckdatei (TEXT CONST dateiname) 8.1
+drucke (TEXT CONST mustername) 8.1
+
+editget (TEXT CONST prompt, TEXT VAR eingabe,
+ TEXT CONST res, hilfe) 10.4
+eindeutige felder (INT CONST anzahl) 8.3
+einfuegen (PROC hilfe) 9.3
+eudas dateiname (INT CONST dateinr) : TEXT 7.1
+EUDAT 6.2
+exit durch (TEXT CONST exit zeichen) 9.3
+exit durch : TEXT 9.3
+
+f (TEXT CONST feldname) : TEXT 8.5
+fehler ausgeben 10.4
+feld aendern (SATZ VAR, INT CONST feldnr,
+ TEXT CONST inhalt) 6.1
+feld aendern (EUDAT VAR, INT CONST feldnr,
+ TEXT CONST inhalt) 6.4
+feld aendern (INT CONST feldnr, TEXT CONST inhalt) 7.2
+feldauswahl (TEXT CONST feldcodes) 9.2
+feld bearbeiten (SATZ CONST, INT CONST feldnr,
+ PROC (TEXT CONST, INT CONST, INT CONST) bearbeite) 6.1
+feld bearbeiten (EUDAT CONST, INT CONST feldnr,
+ PROC (TEXT CONST, INT CONST, INT CONST) bearbeite) 6.4
+feld bearbeiten (INT CONST feldnr,
+ PROC (TEXT CONST, INT CONST, INT CONST) bearbeite) 7.2
+felderzahl (SATZ CONST) : INT 6.1
+felderzahl (EUDAT CONST) : INT 6.2
+feldindex (SATZ CONST, TEXT CONST muster) : INT 6.1
+feldinfo (EUDAT VAR, INT CONST feldnr, info) 6.5
+feldinfo (EUDAT CONST, INT CONST feldnr) : INT 6.5
+feld lesen (SATZ CONST, INT CONST feldnr,
+ TEXT VAR inhalt) 6.1
+feld lesen (EUDAT CONST, INT CONST feldnr,
+ TEXT VAR inhalt) 6.4
+feld lesen (INT CONST feldnr, TEXT VAR inhalt) 7.2
+feldmaske (TEXT CONST feldname, maske) 8.3
+feldnamen aendern (EUDAT VAR, SATZ CONST namen) 6.2
+feldnamen bearbeiten (INT CONST feldnr,
+ PROC (TEXT CONST, INT CONST, INT CONST) bearbeite) 7.2
+feldnamen lesen (EUDAT CONST, SATZ VAR namen) 6.2
+feldnamen lesen (INT CONST feldnr, TEXT VAR name) 7.2
+feldnummer (TEXT CONST feldname) : INT 7.2
+FENSTER 9.1
+fenstergroesse (FENSTER CONST f,
+ INT VAR x anf, y anf,
+ x laenge, y laenge) 9.1
+fenstergroesse setzen (FENSTER VAR fenster,
+ INT CONST x anf, y anf,
+ x laenge, y laenge) 9.1
+fenster initialisieren (FENSTER VAR fenster) 9.1
+fenster veraendert (FENSTER CONST fenster) 9.1
+fensterzugriff (FENSTER CONST fenster,
+ BOOL VAR veraendert) 9.1
+
+global manager 10.2
+gruppenwechsel (INT CONST gruppennr) : BOOL 8.1
+
+hilfe anbieten (TEXT CONST name, FENSTER CONST f) 10.3
+hole satz (TEXT CONST dateiname) 8.3
+
+inhalt veraendert (INT CONST dateinr) : BOOL 7.1
+ja (TEXT CONST frage, hilfe) : BOOL 10.4
+
+K (TEXT CONST feldname, ausdruck) 8.2
+kette (TEXT CONST dateiname) 7.1
+kopiere (TEXT CONST dateiname, FILE VAR muster) 8.2
+kopiere (TEXT CONST dateiname, PROC kopierfunktion) 8.2
+kopple (TEXT CONST dateiname) 7.1
+
+lfd nr : TEXT 8.1
+
+markierte saetze : INT 7.5
+markierung aendern 7.5
+markierungen loeschen 7.5
+maxdruckzeilen (INT CONST anzahl zeilen) 8.1
+menue anbieten (ROW 6 TEXT CONST menuenamen,
+ FENSTER VAR f,
+ BOOL CONST esc erlaubt,
+ PROC (INT CONST, INT CONST) interpreter) 10.3
+menuedaten einlesen (TEXT CONST dateiname) 10.2
+menue loeschen (TEXT CONST name, INT CONST index) 10.2
+menue loeschen (BOOL CONST hilfen reduzieren) 10.2
+menue manager (DATASPACE VAR ds,
+ INT CONST order, phase,
+ TASK CONST order task) 10.2
+menuenamen (INT CONST index) : THESAURUS 10.2
+
+neuer dialog 10.4
+notizen aendern (EUDAT VAR, INT CONST notiz nr,
+ TEXT CONST notizen) 6.2
+notizen lesen (EUDAT CONST, INT CONST notiz nr,
+ TEXT VAR notizen) 6.2
+
+oeffne (EUDAT VAR, TEXT CONST dateiname) 6.2
+oeffne (TEXT CONST dateiname,
+ BOOL CONST aendern erlaubt) 7.1
+
+pruefe (TEXT CONST feldname, BOOL CONST bedingung) 8.3
+
+reorganisiere (TEXT CONST dateiname) 6.5
+rollen (INT CONST anzahl) 9.2
+
+saetze (EUDAT CONST) : INT 6.3
+SATZ 6.1
+satz aendern (EUDAT VAR, SATZ CONST neuer satz) 6.4
+satz ausgewaehlt : BOOL 7.5
+satz einfuegen (EUDAT VAR, SATZ CONST satz) 6.4
+satz einfuegen 7.4
+satz initialisieren (SATZ VAR satz) 6.1
+satzkombination : INT 7.3
+satz lesen (EUDAT CONST, SATZ VAR satz) 6.4
+satz loeschen (EUDAT VAR) 6.4
+satz loeschen 7.4
+satz markiert : BOOL 7.5
+satznr (EUDAT CONST) : INT 6.3
+satznummer : INT 7.3
+sichere (INT CONST dateinr, TEXT CONST dateiname) 7.1
+sortiere (EUDAT VAR, TEXT CONST reihenfolge) 6.5
+sortiere (EUDAT VAR) 6.5
+sortierreihenfolge (EUDAT CONST) : TEXT 6.5
+status anzeigen (TEXT CONST zeile) 10.3
+std kopiermuster (TEXT CONST dateiname, FILE VAR f) 8.2
+suchbedingung (INT CONST feldnr,
+ TEXT CONST bedingung) 7.5
+suchbedingung loeschen 7.5
+suchen (PROC hilfe) 9.3
+
+textdarstellung (TEXT CONST text) : TEXT 8.5
+trage (TEXT CONST dateiname, FILE VAR protokoll,
+ BOOL CONST test) 8.3
+trage satz (TEXT CONST dateiname) 8.3
+
+unsortierte saetze (EUDAT CONST) : INT 6.5
+
+V (TEXT CONST feldname, ausdruck) 8.4
+verarbeite (FILE VAR verarbeitungsmuster) 8.4
+verarbeite (PROC verarbeitungsfunktion) 8.4
+
+waehlbar (INT CONST menuenr, funktionsnr,
+ BOOL CONST moeglich) 10.3
+wahl (INT CONST stelle) : INT 10.3
+weiter (EUDAT VAR) 6.3
+weiter (EUDAT VAR, TEXT CONST muster) 6.3
+weiter (INT CONST modus) 7.3
+wert (TEXT CONST feldname) : REAL 8.5
+wert (TEXT CONST feldname, INT CONST kommastellen) : REAL 8.5
+wertemenge (TEXT CONST feldname, menge) 8.3
+
+zahltext (REAL CONST wert, INT CONST kommastellen) : TEXT 8.5
+zahltext (TEXT CONST feldname,
+ INT CONST kommastellen) : TEXT 8.5
+zurueck (EUDAT VAR) 6.3
+zurueck (EUDAT VAR, TEXT CONST muster) 6.3
+zurueck (INT CONST modus) 7.3
+
diff --git a/doc/eudas/eudas.ref.reg b/doc/eudas/eudas.ref.reg
new file mode 100644
index 0000000..a34307a
--- /dev/null
+++ b/doc/eudas/eudas.ref.reg
@@ -0,0 +1,436 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (125)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+Register
+
+
+
+#columns (2, 0.5)#
+#limit (6.5)#
+ABKUERZUNGEN-Anweisung 49
+Abkürzungsteil 49
+Abkürzungsverzeichnis 68
+Abkürzungszeile 50
+Abschlußzeile 39
+aendern 96
+Ändern 10, 19
+ -, nach Vorschrift 48
+aendern erlaubt 74
+Änderungen 34
+aenderungen eintragen 79
+Änderungsmuster 21
+Alternative 43
+Ankreuzen 8
+anzahl dateien 74
+anzahl felder 75
+anzahl koppeldateien 74
+Anzeige 39, 93
+anzeigefenster 95
+Arbeitskopie 13, 32
+ -, löschen 15, 36
+ -, sichern 15, 36
+Archivmanager 28
+ -, reservieren 29
+Archiv (Menü) 27
+Archivübersicht drucken 27
+Assoziativspeicher 68
+auf koppeldatei 74
+Aufräumen 26
+auf satz 65, 78
+Auf Satz Nr. 17
+Ausdrucken 24
+Ausführen 8
+ausfuehrtaste 8, 102
+AUSWAHL 97
+AUSWAHL: 4
+Auswahl 8
+ -, Format 98
+auswahl anbieten 103
+
+Bearbeiten 46
+BILD 97
+bild ausgeben 95
+bildschirm neu 94
+
+Datei, aufräumen 26
+ -, kopieren (logisch) 25
+ -, kopieren vom Archiv 27
+ -, löschen 25
+ -, löschen auf Archiv 28
+ -, Platzbedarf 26
+ -, reorganisieren 26
+ -, schreiben auf Archiv 27
+ -, umbenennen 25
+ -, virtuelle 32, 71
+Dateianwendungen 109
+Dateien Archiv, Übersicht 27
+dateiende 64, 78
+dateien loeschen 74
+Dateien (Menü) 25
+Dateien System, Übersicht 25
+Dateilimit 52
+Dateimanager 28
+Dateiname 40
+dateiversion 75
+DATUM 45
+Dezimalkomma 45
+dezimalkomma 67
+dialog 104
+Dialog 9, 103
+dialogfenster 104
+DIN 45
+direkt drucken 83f.
+Druckausgabe, Richtung 23
+druckdatei 85
+drucke 84
+Drucken 23, 49, 83
+ -, Archivübersicht 27
+Drucken (Menü) 23
+Druckmuster 23, 49, 83
+ -, Fehler 56
+Druckvorgang 51
+
+editget 104
+EDITIEREN: 6
+Editieren 23
+ -, Zeile 9
+Editor 9, 29
+eindeutige felder 47, 89
+einfuegen 96
+Einfügen 10, 19
+ -, Satz 36
+ -, Zeile 10
+EINGABE: 4
+Eingabe 9
+Einzelsatz (Menü) 17
+ELAN-Compiler 56
+ELAN-Kommandos 8
+ENDE 97
+Endekennzeichnung 40
+ESC '?' 6
+ESC '9' 4
+ESC '1' 4
+ESC '?' 4
+ESC '?' 3
+ESC 'D' 5
+ESC ESC 3
+ESC 'F' 5f.
+ESC 'g' 5
+ESC 'h' 4ff.
+ESC 'K' 36
+ESC OBEN 5
+ESC 'p' 5
+ESC 'q' 4, 6
+ESC RUBIN 5
+ESC RUBOUT 5
+ESC UNTEN 5
+ESC 'w' 4f.
+ESC 'z' 4f.
+eudas 29
+EUDAS: 3
+EUDAS-Datei, aufspalten 110
+ -, drucken 23, 49, 83
+ -, einrichten 13
+ -, ketten 14, 32
+ -, kopieren 21, 46, 85
+ -, koppeln 14, 32
+ -, nach Vorschrift ändern 48
+ -, öffnen 13, 32
+ -, reorganisieren 67
+ -, sortieren 22
+ -, Struktur 31, 61
+ -, tragen 46, 87
+ -, Übersicht 22
+ -, verändern 21
+eudas dateiname 75
+EUDAT 61, 63, 109
+EUMEL-Netz 28
+exit durch 96
+
+f 91
+FEHLER 5
+fehler ausgeben 104
+Feld 31
+FELD 98
+feld aendern 62, 65, 76
+Feldauswahl 20, 41, 95
+feld bearbeiten 62, 65, 76
+felderzahl 62, 63
+feldindex 62
+feldinfo 66, 77
+Feldinhalt 31, 39
+feld lesen 65, 76
+feldmaske 47, 89
+Feldmuster 53
+Feldname 31, 39
+ -, ändern 16
+ -, anfügen 16
+feldnamen aendern 63
+feldnamen bearbeiten 76
+feldnamen lesen 64, 76
+feldnummer 76
+Feldstruktur 15
+Feldtyp 31, 42
+Feldtypen 45, 66
+ -, ändern 16
+Feldvergleich 43
+Fenster 93
+fenstergroesse 94
+fenstergroesse setzen 93
+fenster initialisieren 93
+fenster veraendert 94
+fensterzugriff 94
+folgedatei 75
+Folgezeilen 41
+Formular 39
+FRAGE: 5
+Fragen 9
+Funktion, ausführen 8
+ -, gesperrte 8
+
+Gesamtdatei (Menü) 21
+Gib Kommando: 6
+global manager 36, 100
+Gruppe 51
+GRUPPE-Anweisung 49
+gruppenwechsel 51, 85
+
+Hauptdatei 32
+HILFE: 4
+HILFE 97, 99
+Hilfe 9
+ -, Format 98
+hilfe anbieten 103
+Holen 19
+hole satz 89
+HOP LINKS 4
+HOP 'o' 4
+HOP OBEN 3ff.
+HOP RECHTS 4
+HOP RETURN 4
+HOP RUBOUT 4
+HOP UNTEN 3ff.
+HOP 'x' 4
+
+inhalt veraendert 74
+Initialisieren 28
+Initialisierungsteil 49
+
+ja 104
+
+K 46, 86
+kette 73
+Ketten 14, 32
+Klassenwechsel 106
+Kombinationen 34
+Kommandos 8
+Kommandozeile 50
+kopiere 86
+Kopieren 21, 46, 85
+Kopieren (logisch) 25
+Kopieren vom Archiv 27
+Kopiermuster 21, 46
+KOPPEL 40
+Koppeldatei, umschalten auf 36
+Koppelfelder 33
+Koppeln 14, 32f.
+kopple 72
+Kurzabfrage 29
+
+LEER 3f.
+Leertaste 8
+lfd nr 85
+lineform 24
+LINKS 3f.
+Literaturangaben 108
+Löschen 25
+ -, Satz 36
+ -, Zeile 10
+Löschen auf Archiv 28
+
+Manager 13
+Manager (Mehrbenutzer) 16, 36
+markierte saetze 81
+Markierung 18, 40, 42
+markierung aendern 81
+Markierungen löschen 22
+markierungen loeschen 81
+maxdruckzeilen 85
+MEHR-Anweisung 50
+MENUE 97
+Menü 8
+ -, Aufruf 101
+ -, Verwaltung 99
+menue anbieten 101
+menuedaten einlesen 99
+Menüformat 97
+menue loeschen 100
+menue manager 100
+menuenamen 100
+Modi 55
+MODUS-Anweisung 50
+Musterprogramme 105
+Musterteil 50
+Musterzeichen 53
+Musterzeile 50
+ -, Interpretation 52
+
+Nachbearbeiten 24
+Nachspann 49
+NACHSPANN-Anweisung 49
+Namenskonflikte 33
+neuer dialog 104
+Normalmodus 55
+Notizen 15, 31, 64
+notizen aendern 64, 77
+notizen lesen 64, 77
+
+'o' 4
+OBEN 3f.
+ODER-Verknüpfung 43
+oeffne 63, 72
+Öffnen 32
+Öffnen (Menü) 13
+
+pageform 24
+Paralleleditor 56, 83
+Paßwort 29
+Platzbedarf 26
+Positionieren 17, 31, 64, 77
+Priorität 44
+Programmzeile 51
+Protokolldatei 47
+Prüfbedingungen 16, 31, 47, 64,
+ 87
+pruefe 47, 88
+Pufferplatz 54
+
+RECHTS 3f.
+Refinement 56
+reorganisiere 67
+Reorganisieren 26, 45, 67
+Reservieren 29
+RETURN 4
+Richtung Druckausgabe 23
+rollen 95
+Rollen 41
+RUBIN 4
+RUBOUT 4
+
+saetze 64
+SATZ 61
+Satz 31
+satz aendern 66
+satz ausgewaehlt 80
+Satzauswahl 42
+Satzeditor 9
+satz einfuegen 66, 79
+Satzformular 39
+satz initialisieren 62
+satzkombination 77
+satz lesen 66
+satz loeschen 66, 79
+satz markiert 81
+satznr 64
+satznummer 77
+Satznummer 39
+Satzposition 64
+Satzzeiger 31
+Satzzugriffe 65
+Schreiben auf Archiv 27
+SEITE 99
+sichere 73
+Sichern 15, 36
+sortiere 67
+Sortieren 22, 31, 44, 66
+Sortierreihenfolge 31, 44
+sortierreihenfolge 67
+Sortierzustand 45
+Spaltendruck 52
+Sperre 36
+Standard-Kopiermuster 21, 46
+status anzeigen 103
+Statuszeile 3
+std kopiermuster 87
+Suchbedingung 17, 39, 42
+ -, löschen 18
+ -, setzen 18
+suchbedingung 80
+suchbedingung lesen 80
+suchbedingung loeschen 80
+suchen 96
+Suchen, Optimierung 44
+Suchmuster 42
+ -, eingeben 10
+
+Tabellenmodus 55
+Tasten 3
+Tastenfunktionen 3
+TEXT 45
+textdarstellung 91
+Textdatei, ausdrucken 24
+ -, editieren 23
+ -, nachbearbeiten 24
+Textzeile 49f.
+trage 88
+Tragen 16, 19, 21, 46, 87
+trage satz 88
+
+uebersicht 95
+uebersichtsfenster 95
+Umbenennen 25
+Umbruch 40, 55
+Umschalten auf Koppeldatei 36
+UND-Verknüpfung 43
+unsortierte saetze 67
+UNTEN 3f.
+Überschrift 39
+Übersicht 22, 41
+Übersicht Dateien Archiv 27
+Übersicht Dateien System 25
+
+V 48, 90
+Verändern 21
+verarbeite 90
+Verarbeitung 89
+Verknüpfung von Bedingungen
+43
+virtuelle Datei 32, 71
+VORSPANN 98
+Vorspann 49
+VORSPANN-Anweisung 49
+
+waehlbar 102
+wahl 103
+Warten 6
+weiter 65, 78
+Weiter 17
+wert 91
+wertemenge 47, 88
+WIEDERHOLUNG-Anweisung 49
+Wiederholungsteil 49
+
+'x' 4
+
+ZAHL 45
+zahltext 91
+Zeichen, reservierte 44
+ZEIGEN: 6
+Zeilenende 54
+Zeilenwiederholung 55
+Zielarchiv 28
+Zurück 17
+zurueck 65, 78
+Zustand 3
+Zustandsübergänge 7
+
diff --git a/doc/eudas/eudas.ref.titel b/doc/eudas/eudas.ref.titel
new file mode 100644
index 0000000..223a839
--- /dev/null
+++ b/doc/eudas/eudas.ref.titel
@@ -0,0 +1,91 @@
+#limit (14.0)#
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#gs-MP BAP
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#free (6.0)#
+#on("b")#EUDAS#off("b")#
+#free (1.0)#
+#on("b")#Anwender-#off("b")#
+#on("b")#Datenverwaltungssystem#off("b")#
+#free (2.0)#
+#on ("b")#VERSION 4#off("b")#
+#free(1.0)#
+#on("u")#                                                    #off("u")#
+#free (0.5)#
+#on("b")#REFERENZHANDBUCH#off("b")#
+#block#
+#page#
+#free (9.5)#
+Hergestellt mit Hilfe der EUMEL-Textverarbeitung und des Pro­
+gramms FontMaster der Martin Schönbeck GmbH.
+#free (1.7)#
+Ausgabe September 1987
+
+Dieses Handbuch und das zugehörige Programm sind urheberrechtlich
+geschützt. Die dadurch begründeten Rechte, insbesondere der Ver­
+vielfältigung in irgendeiner Form, bleiben dem Autor vorbehalten.
+
+Es kann keine Garantie dafür übernommen werden, daß das Pro­
+gramm für eine bestimmte Anwendung geeignet ist. Die Verantwor­
+tung dafür liegt beim Kunden.
+
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrekt­
+heit und Vollständigkeit der Angaben wird aber keine Gewähr über­
+nommen. Das Handbuch kann jederzeit ohne Ankündigung geändert
+werden.
+
+(c) Copyright 1987 Thomas Berlage
+ Software-Systeme
+ Im alten Keller 3
+#free (0.1)#
+ D-5205 Sankt Augustin 1
+#page#
+#free (7.0)#
+#center##on("b")#I.#off("b")#
+#free (1.0)#
+#center##on("b")#FUNKTIONEN#off("b")#
+#center##on("b")#ZUM#off ("b")#
+#center##on("b")#NACHSCHLAGEN#off("b")#
+#page#
+#free (7.0)#
+#center##on("b")#II.#off("b")#
+#free (1.0)#
+#center##on("b")#EUDAS#off("b")#
+#center##on("b")#FÜR#off ("b")#
+#center##on("b")#PROGRAMMIERER#off("b")#
+#page#
+#free (7.0)#
+#center##on("b")#III.#off("b")#
+#free (1.0)#
+#center##on("b")#ANHANG#off("b")#
+
+
+
+
diff --git a/doc/eudas/eudas.ref.vorwort b/doc/eudas/eudas.ref.vorwort
new file mode 100644
index 0000000..f911be8
--- /dev/null
+++ b/doc/eudas/eudas.ref.vorwort
@@ -0,0 +1,81 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#EUDAS
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#center#1
+
+Vorwort
+
+
+
+Lieber EUDAS-Benutzer!
+
+Dies ist das zweite Handbuch, das Sie zu EUDAS bekommen. Wenn
+Sie sich mit EUDAS noch nicht auskennen, sollten Sie zunächst das
+#on("i")#Benutzerhandbuch#off("i")# zu Rate ziehen, ehe Sie in dieses Handbuch
+schauen.
+
+ Das #on("i")#Referenzhandbuch#off("i")# ist in zwei Teile geteilt. Im ersten Teil
+finden Sie eine Übersicht über alle EUDAS-Funktionen (im Kapitel
+2) sowie zusammengefaßte Informationen über die Bedienung (Kapi­
+tel 1) und die genaue Wirkung der einzelnen Funktionen (Kapitel 3
+bis 5). Dieser Teil soll Ihnen zum Nachschlagen dienen, wenn Sie
+eine bestimmte Information suchen.
+ Im zweiten Teil sind alle Informationen zusammengefaßt, die
+ein Programmierer zur Benutzung der EUDAS-Funktionen braucht. Es
+sei an dieser Stelle jedoch davon abgeraten, sofort eigene Program­
+me zu schreiben, da sich in vielen Fällen die gleiche Wirkung auch
+durch Programmierung innerhalb von EUDAS-Funktionen erreichen
+läßt (zum Beispiel in Druck- und Änderungsmustern).
+ Im Zweifelsfall orientieren Sie sich anhand von Kapitel 11, wie
+Sie Ihr Problem am besten lösen können.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/eudas/ref.abb.1-1 b/doc/eudas/ref.abb.1-1
new file mode 100644
index 0000000..d3b3217
--- /dev/null
+++ b/doc/eudas/ref.abb.1-1
@@ -0,0 +1,42 @@
+#limit (13.5)#
+#start (3.5, 5.0)#
+#lpos (0.5)##c pos (3.5)##c pos (4.7)##cpos (7.0)##c pos (10.5)#
+#table#
+      eudas   ESC q  
+
+    ESC ESC   ESC h
+#free (0.2)#
+GIB KDO:     EUDAS  
+#free (0.2)#
+    ESC h    
+    RET        LEER  'Buchst.'  
+
+        ESC q          
+
+        FEHLER
+
+
+  WARTEN      
+      n, j  
+        FRAGE
+
+      RET  
+        EINGABE
+#linefeed (0.5)#
+
+
+        ESC z          
+      ESC q  
+#linefeed (1.0)#
+        AUSWAHL
+
+      ESC q  
+        EDITIEREN
+
+      ESC q  
+        SATZEDITOR
+ESC ?   ESC q        
+      ESC q  
+HILFE       ZEIGEN
+
+
diff --git a/doc/eudas/register b/doc/eudas/register
new file mode 100644
index 0000000..9cca0fc
--- /dev/null
+++ b/doc/eudas/register
@@ -0,0 +1,490 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (181)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+Register
+
+
+
+#columns (2, 0.5)#
+#limit (6.5)#
+% 63, 69, 148
+%% 141
+& 63, 69, 103, 148
+<!> 57
+-- 103
+.. 102
+.a$ 65
+'+' 107
+'-' 107
+
+Abbruch 35
+Abkürzungen 133
+Abkürzungsteil 134, 140
+Absatzmarken 125, 129
+Abschlußzeile 45
+Abschneiden 71
+Abschnitt 67, 69, 134
+Alternative 99
+ -, globale 100
+ -, lokale 99
+AND 162
+Ändern 55
+Änderungen 83, 85, 90, 95
+ -, automatisch 121
+Änderungsmuster 121, 166
+Anführungsstrich 27, 34
+Ankreuzen 36, 40
+Anrede 138
+Anweisung 63
+ -, Textkosmetik 74
+Anzeige 44
+ -, rollen 97
+Arbeitsbereich 16
+Arbeitskopie 56, 84, 173
+ -, Beispiel 58
+ -, löschen 57
+Arbeitstask 16
+Archiv 32
+ -, anmelden 34
+ -diskette 36
+ -, lesen 34
+ -, löschen 176
+ -manager 175, 177
+ -menü 33, 174
+ -name 34, 36
+ -, schreiben 36
+ -übersicht 175
+Arithmetik 161
+Attribut 4, 29
+Aufräumen 173
+Ausdrucken 66
+Ausdrücke 116, 151
+ -, Zusammensetzung 152
+Ausgabedatei 66
+Ausgaberichtung 65
+Auswahlzustand 36, 40
+Automatische Änderungen 121
+
+Bedienungsregeln 39
+begin 16
+Benutzerhandbuch i
+Berechnungen 8
+Bewegen 45
+Bildschirmaufbau 45
+Bitte warten 34, 40
+blättern 46
+BOOL 154, 162
+
+Carriage Return 15
+CAT 167
+CONST 155
+CR 15
+Cursor 35, 46
+ -tasten 54
+
+date 137
+Datei 27
+ -arten 27
+ -, aufräumen 173
+ -auswahl 36
+ -größe, Begrenzung 124
+ -, kopieren 172
+ -limit 71
+ -, löschen 38, 172
+ -namen 172
+ -, Platzbedarf 173
+ -, reorganisieren 174
+ -sperre 95
+ -, umbenennen 172
+ -verwaltung 37
+ -, virtuelle 83
+Dateien, Archiv 174
+ - (Menü) 38, 171
+ -, System 171
+DATEIENDE 106
+Daten, ändern 55
+ -, anzeigen 44
+ -, sichern 33
+ -typen 152
+ -typen, umwandeln 154
+ -verwaltung 3
+Datum 44, 99, 133, 137
+DATUM 112
+DECR 167
+Denotation 154
+Dezimalkomma 111, 161
+Dezimalpunkt 148
+DIN 112
+Diskette 28, 32
+ -, formatieren 176
+ -, initialisieren 176
+Diskettenlaufwerk 175
+Doppeleinträge 121
+DOS 178
+Druckausgabe, Bearbeitung 125
+Drucken 7, 61
+ -, Ablauf 66
+ -, Aufruf 64, 66
+ - (Menü) 22, 65
+ -, Übersicht 175
+Druckersteuerungsanweisungen
+ 74, 124
+Druckmuster 13, 23, 61, 166
+ -, Fehler 134
+ -, Übersetzung 134, 142
+ -, Zeilenlänge 71
+Druckrichtung 123
+Druckverfahren 62
+
+Editieren 64
+Editor 34, 41, 52, 125
+eindeutige felder 121
+Einfügen 18, 52
+Eingabe, Daten 52
+ -, Suchmuster 46
+Eingabeüberprüfung 112
+Eingabezustand 35, 40
+Eingangsmenü 17
+Einzelsatz (Menü) 18, 44, 92, 97
+ELAN-Anweisungen 141
+ELAN-Ausdrücke 116, 151
+ELAN-Compiler 134
+ELIF 168
+ELSE 139
+ENDE 45
+Endesatz 45, 48, 53, 85
+ENTER 15
+ESC '1' 107
+ESC '?' 31, 39, 40
+ESC '9' 107
+ESC 'D' 99
+ESC ESC 41, 111
+ESC 'F' 67
+ESC 'g' 99
+ESC 'h' 35, 39, 40, 55, 107
+ESC 'K' 92
+ESC OBEN 97
+ESC 'p' 99
+ESC 'P' 118
+ESC 'q' 32ff.,40 , 47, 65, 107
+ESC RUBIN 54
+ESC RUBOUT 54
+ESC UNTEN 97
+ESC 'w' 32, 40, 53
+ESC 'z' 32, 36, 40, 95
+Etiketten 126
+eudas 30, 125
+EUDAS-Archivdiskette 11, 29
+EUDAS-Datei 27, 61, 171
+ -, drucken 61
+ -, einrichten 17, 51
+ -, Grenzen 29
+ -, kopieren 113
+ -, Mehrfachbenutzung 93
+ -, Struktur 28
+EUDAS, Aufruf 30
+ -, Installation 11
+ -, Start 15
+ -, Verlassen 24, 32
+EUMEL-Netz 175
+EUMEL-Textverarbeitung 5
+EUMEL-Zeichencode 110
+
+f 117, 134, 156
+FALSE 154
+Fehler, Druckmuster 66
+ -, quittieren 36
+ -zustand 35, 40
+Feld 29
+Feldauswahl 97, 106
+Felder, anfügen 111, 114
+Feldinhalt 29, 156, 160
+feldmaske 120
+Feldmuster 63, 69
+Feldmustertypen 71
+Feldnamen 29, 67
+ -, abfragen 67
+ -, Abgrenzung 72
+ -, ändern 112
+ -, eingeben 51
+ -, Länge 133
+Feldreihenfolge 113
+Feldstruktur 111
+Feldteil 45
+Feldtypen 110, 154
+ -, ändern 111
+Feldvergleich 103
+Formatieren 177
+Formbrief 74
+Formular 8, 44
+Fragezustand 38, 40
+Funktionen 152
+ -, ausführen 31, 46
+ -, auswählen 30
+ -, gesperrt 31
+Fußzeile 44
+
+Gib Kommando 41, 11
+global manager 93
+GRUPPE 145
+Gruppen 144
+ -definition 145
+ -, mehrere 145
+ -wechsel 145
+gruppenwechsel 145
+
+halt 39, 110
+Hardwarefehler 33
+Hauptdatei 87ff.
+Hilfe 31
+Hilfezustand 31, 40
+Hilfstexte 13, 31
+Hintergrunddiskette 12
+Hintergrundengpaß 124
+Holen 56
+HOP OBEN 40, 98, 106
+HOP RETURN 106
+HOP RUBIN 54
+HOP RUBOUT 54
+HOP UNTEN 40, 98, 106
+HOP 'x' 98
+
+IF 117
+IF-Abfragen 161, 168
+IF-Anweisungen 138
+INCR 167
+Init 176
+Initialisierungsteil 124, 143
+Installation 11
+int 140
+INT 153
+
+K 113
+Karteikarten 5
+KB 173
+Ketten 13, 83, 85, 95
+Kilobyte 173
+Klammern 163
+ -, spitze 72
+Kombination 89
+Kombinationsnummer 90
+Kopieren, logisch 172
+ -, EUDAS-Datei 112
+ - (vom Archiv) 34, 176
+Kopieranweisung 113
+Kopiermuster 113, 115, 166
+ -, Übersetzung 116
+KOPPEL 92
+Koppeldatei, Markierung 105
+ -, Position 93
+ -, umschalten 92
+Koppelfeld 86, 89
+ -, übernehmen 92
+Koppeln 13, 83, 85, 95
+ -, mehrere Dateien 87
+Koppelvorgang, Schema 87
+Korrekturversion 14
+
+Länge, feste 70, 137
+ -, variable 70
+Leerautomatik 73
+Leertaste 17, 31
+length 158
+lfd nr 137, 157
+limit 71, 125
+lineform 125, 129
+LINKS 31, 35
+linksbündig 71
+Linksschieben 128
+list (archive) 34
+Löschen 55
+ - (auf Archiv) 176
+ - (Datei) 172
+
+Manager 93, 95
+Managertask 175
+MARK 104
+Markieren 104
+ -, in Übersicht 107
+Markierung 104
+ -, löschen 105
+maxdruckzeilen 124
+MEHR 129
+Mehrfachbenutzung 93
+Menü 30
+Menüzustand 31, 40
+min 155
+Modi 128
+Multi-User 12
+Multi-User-System 16
+Musterbrief 139
+Musterteil 135
+Musterzeichen 70
+
+Nachbearbeitung 125
+Nachspann 68, 144
+NACHSPANN 68
+Negation 103
+Netz 175
+Numerieren 137
+
+'o' 40, 98
+OBEN 30, 106
+ODER 100
+Öffnen 17, 21, 43, 51, 57, 83, 95
+ - (Menü) 30
+Operatoren 152, 155
+ -, Priorität 163
+OR 163
+
+pageform 125
+Paralleleditor 67, 142
+Parameter 152
+Paßwort 94, 177
+Pfeiltasten 54
+Platzbedarf, Datei 173
+pos 159
+Position, feste 69
+ -, variable 69
+Positionierung 48
+Proportionalschrift 129
+Prüfbedingungen 118
+pruefe 120
+PUBLIC 13
+
+REAL 153
+real 155
+RECHTS 31, 55
+rechtsbündig 71, 137
+Referenzhandbuch i, 79
+Refinement 134, 140, 163
+Reorganisieren 174
+Reservieren 178
+RET 15
+RETURN 15
+Richtung, Druckausgabe 65, 123
+Rollen 97, 106
+RUBIN 35, 54
+RUBOUT 35, 54
+Runden 160
+
+Satz 29
+ -, anwählen 46
+ -editor 41, 47, 53, 92, 98
+ -, einfügen 52
+ -, holen 56
+ -, löschen 55
+ -, tragen 55
+Satz.Nr 46, 48
+Satznummer 45, 90
+Satzauswahl, kopieren 114
+Schreiben (auf Archiv) 36, 176
+Schreibmarke 35
+Schrifttypen 125
+Selektion 48
+Sichern 20, 56, 84, 95
+Single-User 12
+Single-User-System 16
+Sortieren 109
+ -, Optimierung 110
+ -, Zieldatei 115
+Sortierreihenfolge 109
+Spaltenbreite 126
+Spaltendruck 126
+Speicherplatz 14, 38, 176
+ -, Datei 173
+Sperren von Dateien 95
+Standard-Kopiermuster 115
+Stationsnummer 175
+Statistik 169
+Statuszeile 31, 39
+Stern 50, 101
+SUB 158, 163
+subtext 158
+SUCH 47
+Suchbedingung f. Drucken 67
+Suchbedingung, Kombination 49
+Suchbedingung löschen 48
+Suchbedingung setzen 46
+Suchen 21, 46
+ -, Optimierung 104
+Suchmuster 47, 99
+ -, Eingabe 47
+SV-Taste 16, 39
+System 32
+
+Tabellenmodus 128
+Tagesdatum 99
+Task, Manager 93
+Tasks 13
+Teildatei 114
+Teiltexte 158
+TEXT 112, 153
+text 140
+Textdatei 28, 61, 171
+ -, ändern 65
+ -, ansehen 65
+ -, ausdrucken 66
+ -, editieren 64
+Texte, verketten 156
+Text-Funktionen 156
+Textkonstanten 139
+Text, konstanter 117
+Text, Länge 158
+Textverarbeitung 3, 123
+THEN 139
+Tragen 55, 118
+TRUE 154
+
+Uhrzeit 133
+Umbruch 129
+Umlaute 143
+Umschalten auf Koppeldatei 92
+UND 100ff.
+UNTEN 30, 106
+Überschrift 45, 68
+Übersicht (Archiv) 34, 175
+ - (Dateien) 37, 171
+ - (Sätze) 105
+
+V 122
+VAR 165
+Variablen 165
+ -, Initialisierung 143, 167
+ -, Lebensdauer 166
+ -, Typ 165
+Verändern 121
+Vergleiche 102, 162
+virtuelle Datei 83
+Vorspann 68, 144
+VORSPANN 68
+
+Weiter 45, 48, 90
+wert 148, 160
+wertemenge 119
+WIEDERHOLUNG 63, 126
+
+'x' 36, 40
+
+ZAHL 110
+zahltext 148, 160
+Zeichen, reservierte 64, 69, 103
+Zeigen 40
+Zeile einfügen 54
+Zeilenfortsetzung 129
+Zeilenlänge 71
+Zielarchiv 175
+Zieldatei, Struktur 113
+Zurück 45, 48, 90
+Zustand 31, 40
+Zuweisung 166
+
+
diff --git a/doc/eudas/uedas.hdb.4 b/doc/eudas/uedas.hdb.4
new file mode 100644
index 0000000..ecbfd58
--- /dev/null
+++ b/doc/eudas/uedas.hdb.4
@@ -0,0 +1,686 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (27)#
+#headodd#
+#center#EUDAS#right#%
+
+#end#
+#headeven#
+%#center#EUDAS
+
+#end#
+#center#1
+
+4 Umgang mit Dateien und Menüs
+
+
+
+Zu Anfang dieses Teils sollen Sie zunächst die Terminologie von
+EUDAS kennenlernen. Das Karteikartenmodell des ersten Kapitels
+muß ja auf einem Rechner realisiert werden. Dazu müssen erst eini­
+ge Ausdrücke erklärt werden.
+
+
+4.1 EUDAS-Dateien
+
+Der wichtigste Ausdruck, der Ihnen noch sehr häufig begegnen wird,
+ist #on("i")#Datei#off("i")#. Eine Datei ist eine Sammlung von Informationen in einem
+Computer, die als ein Objekt transportiert und behandelt werden
+können. Dieser Name wurde analog zu "Kartei" gebildet, mit dem
+Unterschied, daß eine "Daten-Kartei" gemeint ist.
+ Jede Datei hat einen eigenen Namen, durch den sie identifiziert
+wird. Der Name ist oft in Anführungsstriche eingeschlossen - die
+Anführungsstriche gehören jedoch nicht zum Namen, sondern dienen
+nur zur Abgrenzung, welche Zeichen zum Namen gehören. Der Name
+ist also wie die Aufschrift auf einem Aktenordner. Wenn alle Ordner
+im Schrank stehen, können Sie anhand des Namens den richtigen
+Ordner finden, anderenfalls müßten Sie alle Ordner öffnen.
+
+#on("b")#Dateiarten#off("b")# Dateien werden nun für viele verschiedene Arten
+von
+Informationen benutzt. Sie können einerseits Texte enthalten oder
+auch Karteien, Grafiken, Formeln oder Zahlenkolonnen. Sie haben
+bereits im ersten Kapitel den Unterschied zwischen Datenverwaltung
+und Textverarbeitung kennengelernt. In diesem Zusammenhang sind
+die beiden ersten Verwendungsweisen wichtig.
+
+#limit (12.0)#
+ #on("i")#Textdateien#off("i")#
+ sind Dateien, die normale Texte enthalten, die mit
+ dem Editor verändert und einfach ausgedruckt
+ werden können. In ihnen werden also Informationen
+ gespeichert, wie die Textverarbeitung sie benötigt.
+
+ #on("i")#EUDAS-Dateien#off("i")#
+ sind dagegen Dateien, die Informationen in der
+ Form von Karteikarten enthalten. Sie haben also
+ die Struktur, wie sie von der Datenverwaltung be­
+ nötigt wird.
+#limit (13.5)#
+
+ Der Computer kann aber auch alle Arten von Dateien gleich­
+behandeln, und zwar dann, wenn der Inhalt der Dateien nicht be­
+trachtet werden muß.
+ Ein häufiger Fall ist zum Beispiel, wenn Dateien zur Sicherung
+auf eine Diskette geschrieben werden sollen. In diesem Fall genügt
+die Angabe des Namens; dem Rechner ist es egal, welchen Inhalt die
+Datei hat.
+ Anders ist es aber, wenn Sie den Inhalt betrachten wollen.
+Dazu brauchen Sie dann ein Programm, das die innere Struktur der
+Datei kennt. Textdateien können Sie zum Beispiel mit dem Editor
+ansehen. EUDAS-Dateien müssen Sie jedoch mit EUDAS ansehen, da
+der Editor die EUDAS-Struktur nicht kennt. Es ist in vielen Fällen
+sinnvoll, durch einen Zusatz im Dateinamen zu kennzeichnen, ob es
+sich um eine Textdatei oder eine EUDAS-Datei handelt.
+
+
+#free (3.7)#
+
+#center#Abb. 4-1 Struktur einer EUDAS-Datei
+
+
+#on("b")#Terminologie#off("b")# EUDAS verwendet bestimmte Ausdrücke, um die
+Strukturelemente einer EUDAS-Datei zu kennzeichnen. Die Struktur
+einer EUDAS-Datei ist schematisch in Abb. 4-1 dargestellt. Die
+Ausdrücke wurden nun nicht direkt aus dem Karteikartenmodell
+übernommen, da es auch noch andere Modelle gibt und keine fal­
+schen Assoziationen auftreten sollen.
+ EUDAS verwendet die Bezeichnung #on("i")#Satz#off("i")# für eine Karteikarte.
+Eine EUDAS-Datei besteht also aus einer Anzahl von gleichartigen
+Sätzen. Zur Veranschaulichung kann man sich diese nebeneinander­
+gelegt vorstellen.
+ Jeder Satz ist unterteilt in sogenannte #on("i")#Felder#off("i")#. Ein Feld ent­
+spricht einem Attribut bzw. einem Eintrag auf der Karteikarte. Ein
+Feld ist wiederum unterteilt in einen #on("i")#Feldnamen#off("i")# und einen #on("i")#Feldin­
+halt#off("i")#.
+ Der Feldname identifiziert ein bestimmtes Feld innerhalb eines
+Satzes. Die Feldnamen sind natürlich für alle Sätze gleich. Die
+Feldnamen einer EUDAS-Datei sind beliebig und können von Ihnen
+selbst festgelegt werden.
+ Der Feldinhalt enthält die eigentliche Information des entspre­
+chenden Attributs. Der Feldinhalt darf ebenfalls aus beliebig vielen
+Zeichen bestehen. Die Feldinhalte sind natürlich für jeden Satz
+verschieden und stellen die eigentliche gespeicherte Information
+dar.
+
+#on("b")#Grenzen#off("b")# Aus technischen Gründen gibt es natürlich auch
+einige
+Beschränkungen, die hier nicht verschwiegen werden sollen. Eine
+Datei kann maximal etwa 5000 Sätze enthalten, ein Satz darf aus
+maximal 255 Feldern bestehen. Insgesamt kann ein Satz etwa 32000
+Zeichen umfassen. Die einzelnen Sätze in der EUDAS-Datei werden
+durch ihre jeweilige Positionsnummer identifiziert, also quasi von 1
+bis 5000 durchnumeriert.
+
+
+4.2 EUDAS-Menüs
+
+In den folgenden Abschnitten sollen Sie lernen, wie die Bedienung
+von EUDAS funktioniert. Dazu sollen Sie eine EUDAS-Beispieldatei
+von der EUDAS-Diskette in Ihr System holen. Diese Datei brauchen
+Sie dann später, um die Funktionen von EUDAS zu kennenzulernen.
+ Die Beispieldatei hat den gleichen Inhalt wie die in Kapitel 3
+von Ihnen erstellte Datei. Falls Ihnen also die EUDAS-Archiv­
+diskette nicht zur Verfügung steht, können Sie in diesem Kapitel
+auch jede andere Archivdiskette verwenden.
+ Bitte beachten Sie im folgenden, daß Sie einfache Anführungs­
+striche nicht mit eingeben, doppelte Anführungsstriche aber wohl.
+
+#on("b")#EUDAS-Aufruf#off("b")# Zuerst müssen Sie EUDAS aufrufen. Dazu
+begeben
+Sie sich in die in Kapitel 3 eingerichtete Task ('continue ("arbeit")')
+und geben bei 'gib kommando:' das Kommando 'eudas':
+
+
+ gib kommando:
+ #on("i")#eudas#off("i")#<RET>
+
+
+Falls Ihr System über Menüs gesteuert wird, müssen Sie eine ent­
+sprechende Funktion wählen. Anschließend erscheint folgendes
+Menü:
+
+___________________________________________________________________________________________
+
+ EUDAS: Öffnen Einzelsatz Gesamtdatei Drucken Dateien Archiv
+ --------------:
+ EUDAS-Datei :
+ O Öffnen :
+ - Ketten :
+ - Koppeln :
+ --------------:
+ Arbeitskopie :
+ - Sichern :
+ --------------:
+ Aktuelle Datei:
+ - Notizen :
+ - Feldstrukt. :
+ - Prüfbeding. :
+ --------------:
+ Mehrbenutzer :
+ M Manager :
+ --------------:
+ :
+ :
+ :
+ :
+ :
+ Akt.Datei: Manager: Datum: 22.07.87
+___________________________________________________________________________________________
+
+
+#on("b")#Menüs#off("b")# Ein #on("i")#Menü#off("i")# ist eine Auswahl für einige verschiedene Funk­
+tionen. Die Funktionen sind jeweils benannt und werden durch einen
+davorstehenden Buchstaben oder ein Minuszeichen gekennzeichnet.
+Eine der Funktionen ist immer durch inverse Darstellung markiert.
+ Diese Markierung können Sie nun mit Hilfe der Pfeiltasten OBEN
+und UNTEN verschieben. Auf diese Weise können Sie sich die ge­
+wünschte Funktion auswählen. Die Funktionen werden jedoch durch
+das Markieren nicht ausgeführt. Sie können also beliebig mit den
+Pfeiltasten herumexperimentieren.
+ Ausgeführt wird die markierte Funktion, wenn Sie die Leertaste
+drücken. Sofort erscheint ein Stern vor dem Funktionsnamen, um
+anzuzeigen, daß die Ausführung beginnt. Probieren Sie dies jetzt
+nicht aus, dazu ist später Gelegenheit.
+ Funktionen mit einem Minuszeichen davor können Sie zwar
+anwählen (markieren), aber nicht ausführen. Solche Funktionen sind
+momentan gesperrt, weil ihre Ausführung keinen Sinn hat oder sogar
+Fehler erzeugen würde.
+ Mit den Pfeiltasten LINKS und RECHTS können Sie im Menüzu­
+stand weitere EUDAS-Menüs abrufen. Welche Menüs zur Verfügung
+stehen, zeigt Ihnen die oberste Bildschirmzeile. Das aktuelle Menü
+ist jeweils invers dargestellt.
+
+#on("b")#Hilfe#off("b")# Wenn Sie nun wissen möchten, welche Bedeutung die
+mar­
+kierte Funktion hat (die Funktionsbezeichnungen sind aus Platz­
+gründen sehr kurz gehalten), können Sie einen #on("i")#Hilfstext#off("i")# zu dieser
+Funktion abrufen. Dies erfolgt durch die Betätigung der Tasten ESC
+und '?' hintereinander. Diese doppelten Tastenkombinationen mit der
+ESC-Taste am Anfang werden Ihnen noch sehr häufig begegnen -
+denken Sie immer daran, die Tasten hintereinander und nicht
+gleichzeitig zu tippen. Der zeitliche Abstand zwischen den Tasten­
+drücken kann beliebig lang sein; hingegen sollten Sie eine Taste
+nicht zu lange drücken, da sonst eventuell eine automatische Wie­
+derholfunktion Ihrer Tastatur startet.
+ Probieren Sie nun die Tastenkombination ESC '?' aus. Als Reak­
+tion erscheint in der rechten Hälfte des Bildschirms ein Text. Dieser
+sollte Ihnen die gewünschten Informationen bieten.
+ Gleichzeitig hat sich aber auch die oberste Bildschirmzeile
+verändert. Sie zeigt jetzt folgendes Bild:
+
+___________________________________________________________________________________________
+
+ HILFE: Beenden: ESC q Seite weiter: ESC w Seite zurueck: ESC z
+___________________________________________________________________________________________
+
+
+#on("b")#Zustände#off("b")# Wenn Sie sich nicht im Menü befinden, fungiert
+die ober­
+ste Zeile als sogenannte #on("i")#Statuszeile#off("i")#. Diese Zeile zeigt immer an, in
+welchem #on("i")#Zustand#off("i")# das Programm sich befindet. Der Zustand des Pro­
+gramms hat nämlich Einfluß darauf, welche Tasten Sie drücken
+können und wie das Programm darauf reagiert. Die Statuszeile zeigt
+daher außer dem Zustand auch die wichtigsten Tastenfunktionen.
+ Sie kennen jetzt also schon zwei Zustände von EUDAS: den
+Menüzustand und den Hilfe-Zustand.
+
+#on("b")#Hilfe-Zustand#off("b")# Vom Menüzustand kommen Sie über die
+Tastenkom­
+bination ESC '?' in den Hilfe-Zustand. Im Hilfe-Zustand haben die
+Pfeiltasten OBEN und UNTEN keine Wirkung mehr (probieren Sie dies
+aus).
+ Ein Hilfstext besteht im allgemeinen aus mehreren Seiten. Die
+erste Seite enthält dabei die speziellen Informationen, danach
+folgen dann allgemeine Informationen. Mit den Tastenkombinationen
+ESC 'w' und ESC 'z' können Sie zwischen den Seiten umschalten
+(denken Sie daran, was oben über Tastenkombinationen gesagt
+wurde). Wenn Sie dies ausprobieren, werden Sie auf der zweiten
+Seite allgemeine Hinweise zur Menübedienung finden. Auf der letz­
+ten Seite wird ESC 'w' ignoriert, ebenso ESC 'z' auf der ersten Seite.
+ Mit der Tastenkombination ESC 'q' (quit) kehren Sie aus dem
+Hilfezustand in den vorherigen Zustand zurück. Diese Tastenkombi­
+nation löst allgemein in EUDAS die Rückkehr in den alten Zustand
+aus. Wenn Sie ESC 'q' getippt haben, erscheint die alte Menüzeile
+und Sie können wieder Funktionen auswählen.
+ Der Hilfszustand läßt sich von nahezu allen (noch zu bespre­
+chenden) Zuständen mit ESC '?' aufrufen. Es wird jeweils ein zum
+aktuellen Zustand passender Hilfstext ausgegeben.
+ Die möglichen Zustandsübergange sind nochmal in Abb. 4-2
+zusammengefaßt.
+
+
+#free (2.5)#
+
+#center#Abb. 4-2 Menü- und Hilfezustand
+
+
+#on("b")#EUDAS verlassen#off("b")# Im Menüzustand können Sie EUDAS jederzeit
+durch Tippen von ESC 'q' verlassen. Sie landen dann wieder bei 'gib
+kommando:'.
+
+
+4.3 Archivmenü
+
+#on("b")#System/Archiv#off("b")# An dieser Stelle müssen Sie sich die Begriffe #on("i")#Archiv#off("i")#
+und #on("i")#System#off("i")# klarmachen. Als Archiv bezeichnet man die Möglichkeit,
+bei Bedarf Disketten in Ihren Rechner einlegen können, um Dateien
+(und Programme) von anderen Rechnern zu übernehmen. Um diese
+Dateien bearbeiten zu können, müssen Sie sie in das System (Ihre
+Festplatte oder Hintergrunddiskette) kopieren.
+ Die wichtigste Aufgabe des Archivs ist es, Daten vor Beschädi­
+gung zu sichern. Durch Fehlbedienung oder Systemfehler kann es
+nämlich leicht geschehen, daß die Daten in Ihrem System verloren
+gehen oder zerstört werden. Wenn Sie die Daten jedoch auf einer
+Diskette gesichert und die Diskette sicher verwahrt haben, können
+Sie die Daten wiederherstellen.
+ Es ist sehr wichtig, daß Sie Ihre Dateien auf Archivdisketten
+sichern, denn ein einziger Hardwarefehler kann die Arbeit von
+Jahren vernichten (Sagen Sie nicht: "Mir passiert so etwas nicht" -
+bis jetzt hat es noch jeden erwischt).
+
+___________________________________________________________________________________________
+
+ EUDAS: Öffnen Einzelsatz Gesamtdatei Drucken Dateien Archiv
+ --------------:
+ Dateien Archiv:
+ U Übersicht :
+ D Üb. Drucken :
+ --------------:
+ Datei :
+ K Kopieren :
+ vom Archiv :
+ S Schreiben :
+ auf Archiv :
+ L Löschen :
+ auf Archiv :
+ --------------:
+ Archivdiskette:
+ I Init :
+ --------------:
+ Z Zielarchiv :
+ P Paßwort :
+ - Reservieren :
+ --------------:
+ :
+ :
+ Akt.Datei: Ziel: "ARCHIVE" Datum: 22.07.87
+___________________________________________________________________________________________
+
+
+#center#Abb. 4-3 Archivmenü
+
+
+#on("b")#Archivmenü#off("b")# Wenn Sie EUDAS aufrufen, befinden Sie sich
+immer im
+ersten Menü. Sie benötigen jedoch jetzt Funktionen aus dem sech­
+sten Menü 'Archiv'. Wählen Sie dieses Menü jetzt an. Es erscheint
+das in Abb. 4-3 dargestellte Bild. Die Funktionen in diesem Menü
+befassen sich mit beliebigen Dateien auf dem Archiv.
+ Für den Versuch legen Sie bitte die EUDAS-Archivdiskette ein.
+Dann wählen Sie die Funktion 'Übersicht' in dem Menü an, wenn sie
+nicht schon markiert ist. Sie können nun die ausgewählte Funktion
+durch Tippen der Leertaste ausführen.
+ In der obersten Zeile erscheint nun der Hinweis 'Bitte war­
+ten..'. Er zeigt an, daß nun eine Funktion ausgeführt wird, bei der
+Sie zunächst nichts tun können. Sie sollten in diesem Zustand keine
+Tasten drücken, denn EUDAS kann nicht darauf reagieren.
+
+#on("b")#Archivübersicht#off("b")# Nach einer mehr oder minder langen
+Aktivitäts­
+phase Ihres Diskettenlaufwerks erscheint dann die Archivübersicht.
+Das Erscheinungsbild mit dem markierten Editorbalken in der ober­
+sten Zeile kommt Ihnen vielleicht bekannt vor. Sie haben nämlich
+nichts anderes als das EUMEL-Kommando 'list (archive)' ausgeführt.
+Neu ist lediglich die Statuszeile:
+
+___________________________________________________________________________________________
+
+ ZEIGEN: Blättern: HOP OBEN, HOP UNTEN Beenden: ESC q Hilfe: ESC ?
+___________________________________________________________________________________________
+
+
+Wenn Sie sich die Übersicht angeschaut haben, verlassen Sie den
+Editor wieder mit ESC 'q'.
+ Beachten Sie, daß Sie unter EUDAS das Archiv nicht extra an­
+melden müssen; dies geschieht automatisch, wenn Sie eine Funktion
+aufrufen. Bei Leseoperationen müssen Sie nicht einmal den Archiv­
+namen wissen. Das Archiv wird automatisch wieder abgemeldet,
+wenn Sie das Archivmenü verlassen.
+
+#on("b")#Archiv lesen#off("b")# Unter den in der Übersicht aufgelisteten
+Dateien
+sollten Sie auch die Datei finden, die Sie brauchen. Sie heißt
+'Adressen'. An dieser Stelle ein kleiner Hinweis: An vielen Stellen
+werden Sie sehen, daß Dateinamen in Anführungsstriche einge­
+schlossen sind. Die Anführungsstriche gehören jedoch #on("i")#nicht#off("i")# zum
+Namen. Sie dienen nur zur Abgrenzung, da in Dateinamen beliebige
+Zeichen erlaubt sind. Wenn Sie aufgefordert werden, einen Datei­
+namen einzugeben, müssen Sie dies immer ohne Anführungsstriche
+tun.
+ Hoffentlich haben Sie in der ganzen Diskussion nicht das Ziel
+aus den Augen verloren: Sie sollten eine Datei ins System holen, um
+nachher mit ihr zu experimentieren. Zu diesem Zweck gibt es im
+Archivmenü die Funktion
+#free (0.2)#
+
+ K Kopieren
+ (vom Archiv)
+
+#free (0.2)#
+Wählen Sie diese Funktion jetzt mit den Pfeiltasten aus und drücken
+Sie zum Ausführen die Leertaste.
+
+#on("b")#Eingabezustand#off("b")# Nach kurzem 'Bitte warten..'-Zustand werden
+Sie
+im rechten Bildschirmteil nach dem Namen der Datei gefragt. Gleich­
+zeitig erscheint eine neue Statuszeile. Es ergibt sich folgendes Bild:
+
+___________________________________________________________________________________________
+
+ EINGABE: Bestätigen: RETURN Zeigen: ESC z Abbrechen: ESC h Hilfe: ESC ?
+ --------------:Dateiname:
+ Dateien Archiv:
+ U Übersicht :
+ D Üb. drucken :
+ --------------:
+ Datei :
+ * Kopieren :
+ vom Archiv :
+ ...
+
+___________________________________________________________________________________________
+
+
+Sie können in diesem Zustand den Namen der gewünschten Datei
+eingeben. Außer den in der Statuszeile genannten Funktionen kön­
+nen Sie die aus dem Editor bekannten Tasten benutzen, um den
+Text in der Zeile gegebenenfalls zu korrigieren (Pfeiltasten LINKS
+und RECHTS, RUBOUT, RUBIN). Die Schreibmarke (Cursor) zeigt Ihnen
+an, wo das nächste Zeichen plaziert wird.
+
+#on("b")#Abbruch#off("b")# Eine Tastenkombination verdient noch besondere
+Beach­
+tung: Mit ESC 'h' können Sie in vielen Situationen eine Funktion
+noch abbrechen - zum Beispiel wenn Sie irrtümlich die falsche
+Funktion gewählt haben.
+ Im Gegensatz zu ESC 'q' erfolgt hier die sofortige Rückkehr aus
+der Funktion ins Menü, möglichst ohne daß die Funktion Auswir­
+kungen hinterläßt. Bei einem Abbruch bleibt also in der Regel das
+System unverändert.
+
+#on("b")#Fehlerzustand#off("b")# Um auch die Fehlerbehandlung von EUDAS
+auszu­
+probieren, sollten Sie hier einen falschen Namen eingeben, zum
+Beispiel:
+#free (0.2)#
+
+ Dateiname: #on("i")#Adresen#off("i")#<RET>
+
+#free (0.2)#
+EUDAS sucht jetzt auf der Diskette nach einer Datei dieses Namens,
+findet sie aber nicht. Als Reaktion erscheint dann die Meldung:
+
+___________________________________________________________________________________________
+
+ !!! FEHLER !!! Quittieren: ESC q Hilfe zur Meldung: ESC ?
+ --------------:Dateiname: Adresen
+ Dateien Archiv:>>> "Adresen" gibt es nicht
+ U Übersicht :
+ D Üb. drucken :
+ --------------:
+ ...
+
+___________________________________________________________________________________________
+
+
+Im Normalfall sollten Sie die Fehlermeldung mit ESC 'q' quittieren,
+damit Sie den Befehl erneut versuchen können. Auch hier haben Sie
+die Möglichkeit, eine besondere Information zu dem Fehler abzurufen
+(es liegen jedoch nicht für alle möglichen Fehler spezielle Texte
+vor).
+ Nach dem Quittieren des Fehlers befinden Sie sich wieder im
+Menüzustand. Wiederholen Sie jetzt die Funktion, indem Sie die
+Leertaste tippen. Sie werden dann erneut nach dem Namen gefragt.
+
+#on("b")#Auswahlzustand#off("b")# Um endlich ans Ziel zu kommen, benutzen Sie
+diesmal eine sehr komfortable Abkürzung, die EUDAS Ihnen bietet.
+Durch Drücken von ESC 'z' können Sie sich nämlich alle möglichen
+Namen anzeigen lassen und den gewünschten einfach ankreuzen.
+ Anschließend sieht der Bildschirm wie in Abb. 4-4 aus. In die­
+sem Zustand können Sie mit den Pfeiltasten den Cursor zur ge­
+wünschten Datei bewegen und diese ankreuzen. Da Sie auch meh­
+rere Dateien in beliebiger Folge ankreuzen können, erscheint eine
+'1' vor der Datei zur Anzeige der Reihenfolge. Sie wollen aber nur
+diese eine Datei 'Adressen' holen und beenden die Auswahl daher
+mit ESC 'q'. Wenn alles glattgeht, wird jetzt die Datei vom Archiv
+ins System kopiert.
+
+#on("b")#Archiv schreiben#off("b")# Auf nahezu gleiche Weise können Sie mit
+der Funktion
+
+
+ S Schreiben
+ auf Archiv
+
+
+eine Datei wieder auf die Diskette schreiben. Als erstes müssen Sie
+dann den Namen der Archivdiskette eingeben, damit Sie nicht aus
+Versehen auf eine falsche Archivdiskette schreiben.
+ Auch hier können Sie die gewünschten Dateien ankreuzen (na­
+türlich bietet EUDAS dann die Dateien des Systems an). Sie brau­
+chen keine Angst zu haben, aus Versehen eine Datei mit gleichem
+Namen zu überschreiben - EUDAS fragt in solchen Fällen immer
+nochmal an.
+
+___________________________________________________________________________________________
+
+ AUSWAHL: Ankreuzen: 'x' Durchstreichen: 'o' Beenden: ESC q Hilfe: ESC ?
+ --------------:--------------------------------------------------------------
+ Dateien Archiv: Auswahl der Dateien auf dem Archiv.
+ U Übersicht : Gewuenschte Datei(en) bitte ankreuzen:
+ D Üb. Drucken :--------------------------------------------------------------
+ --------------: o "eudas.1"
+ Datei : o "eudas.2"
+ * Kopieren : o "eudas.3"
+ vom Archiv : o "eudas.4"
+ S Schreiben : o "eudas.init"
+ auf Archiv : o "eudas.generator"
+ L Löschen : o "Adressen"
+ auf Archiv :--------------------------------------------------------------
+ --------------:
+ Archivdiskette:
+ I Init :
+ --------------:
+ Z Zielarchiv :
+ P Paßwort :
+ - Reservieren :
+ --------------:
+ :
+ :
+ Akt.Datei: Ziel: "ARCHIVE" Datum: 22.07.87
+___________________________________________________________________________________________
+
+
+#center#Abb. 4-4 Dateiauswahl
+
+
+
+4.4 Dateiverwaltung
+
+So: nach dieser anstrengenden Arbeit sollen Sie sich überzeugen,
+daß die Datei 'Adressen' nun wirklich im System zur Verfügung
+steht. Dazu gehen Sie mit LINKS ein Menü zurück. Dieses Menü
+beschäftigt sich mit Dateien im System und ist in Abb. 4-5 gezeigt.
+ Auch hier finden Sie eine Funktion "Übersicht". Rufen Sie diese
+auf. Ganz analog zum Archiv erscheint eine Übersicht aller Dateien
+im Editor. Verlassen Sie die Übersicht wieder mit ESC 'q'.
+
+___________________________________________________________________________________________
+
+ EUDAS: Öffnen Einzelsatz Gesamtdatei Drucken Dateien Archiv
+ --------------:
+ Dateien System:
+ U Übersicht :
+ --------------:
+ Datei :
+ L Löschen :
+ N Umbenennen :
+ K Kopieren :
+ P Platzbedarf :
+ A Aufräumen :
+ --------------:
+ :
+ :
+ :
+ :
+ :
+ :
+ :
+ :
+ :
+ :
+ :
+ Akt.Datei: Task: "arbeit" Datum: 22.07.87
+___________________________________________________________________________________________
+
+
+#center#Abb. 4-5 Menü 'Dateien'
+
+
+#on("b")#Datei löschen#off("b")# Eine weitere Funktion aus diesem Menü werden
+Sie ebenfalls noch öfter brauchen, nämlich
+#free (0.2)#
+
+ L Löschen
+
+#free (0.2)#
+Mit dieser Funktion können Sie eine Datei wieder aus dem System
+entfernen - zum Beispiel wenn Sie sich die Adressen angesehen
+haben und danach den Speicherplatz nicht weiter verschwenden
+wollen. Als letztes Beispiel sollen Sie auch diese Funktion aufrufen
+(keine Angst, wir löschen die Datei nicht wirklich, es gibt vorher
+noch eine Notbremse).
+
+#on("b")#Fragezustand#off("b")# Als erstes werden Sie wieder nach dem
+Dateinamen
+gefragt (dies ist Ihnen schon bekannt). Hier haben Sie jetzt die
+Wahl, ob Sie den Namen eingeben oder mit ESC 'z' ankreuzen. Da das
+Löschen unwiederbringlich ist, werden Sie anschließend zur Sicher­
+heit gefragt, ob Sie die Datei wirklich löschen wollen:
+
+___________________________________________________________________________________________
+
+ FRAGE: Bejahen: j,J Verneinen: n,N Abbrechen: ESC h Hilfe: ESC ?
+ --------------:Dateiname: Adressen
+ Dateien System:"Adressen" im System loeschen (j/n) ?
+ U Übersicht :
+ --------------:
+ ...
+
+___________________________________________________________________________________________
+
+
+Diese Frage können Sie bejahen oder verneinen (oder die Funktion
+ohne Auswirkungen abbrechen). In diesem Fall sollten Sie die Frage
+verneinen - es sei denn, Ihnen hat das Spielen mit EUDAS so gut
+gefallen, daß Sie die ganze Prozedur wiederholen und die Datei
+nochmal vom Archiv holen wollen.
+
+
+4.5 Bedienungsregeln
+
+Mit dieser letzten Demonstration haben Sie jetzt schon fast alle
+Arten des Umgangs mit EUDAS kennengelernt. Sicher ist dies beim
+ersten Mal sehr verwirrend. Mit vier Regeln können Sie jedoch
+EUDAS immer bedienen:
+
+#limit (12.0)#
+ 1. Achten Sie darauf, welche möglichen Tastendrücke
+ in der Statuszeile stehen. Richten Sie sich danach!
+#free (0.2)#
+ 2. Sind Sie sich unsicher, rufen Sie Hilfsfunktion mit
+ ESC '?' auf. Damit erhalten Sie weitere Informatio­
+ nen.
+#free (0.2)#
+ 3. Funktioniert diese Tastenkombination nicht (geben
+ Sie dem Rechner eine kurze Zeit zum Reagieren),
+ versuchen Sie die Tastenkombinationen ESC 'h' (Ab­
+ bruch) oder ESC 'q' (Verlassen). Falls sich daraufhin
+ etwas verändert, fangen Sie wieder mit 1. an.
+#free (0.2)#
+ 4. Erfolgt darauf keine Reaktion, drücken Sie die SV-
+ Taste und versuchen Sie das Programm mit 'halt' zu
+ stoppen. Führt auch das nicht zum Erfolg, hat sich
+ Ihr Rechner "aufgehängt". Sie müssen den Rechner
+ dann neu starten. Wenn Sie keine Erfahrung mit
+ einer solchen Situation haben, wenden Sie sich an
+ Ihren Händler oder Systembetreuer.
+#limit (13.5)#
+
+Im Zusammenhang mit dem letzten Punkt sei nochmal auf die Wich­
+tigkeit einer regelmäßigen Datensicherung auf Archivdisketten
+hingewiesen. Im Normalfall sollten Sie aber mit den Punkten 1 bis 3
+zurechtkommen.
+
+#on("b")#Zustände#off("b")# Im letzten Abschnitt haben Sie eine ganze Reihe
+von
+Zuständen kennengelernt, die EUDAS einnehmen kann. In jedem
+Zustand haben Sie verschiedene Möglichkeiten zur Reaktion. Glück­
+licherweise erscheinen diese Möglichkeiten zum großen Teil in der
+Statuszeile.
+ Damit Sie die verwirrenden Erfahrungen des letzten Abschnitts
+etwas ordnen können, wollen wir an dieser Stelle die verschiedenen
+Zustände noch einmal zusammenfassen. Der Beschreibung vorange­
+stellt ist die jeweilige Kennzeichnung am Beginn der Statuszeile.
+
+EUDAS: #on("b")# Sie können mit ESC 'w' und ESC 'z' im Hilfstext blättern. Mit
+ ESC 'q' kommen Sie in den alten Zustand.
+
+AUSWAHL: Hier können Sie die gewünschten Namen mit 'x' ankreuzen
+ und mit 'o' wieder entfernen. Normales Beenden mit ESC 'q'.
+ Hilfestellung durch ESC '?'. Abbruch der gesamten Funktion mit
+ ESC 'h'.
+
+EINGABE: Hier können Sie eine einzelne Zeile eingeben oder ändern
+ (wie im Editor). Einfügen und Löschen mit RUBIN und RUBOUT.
+ Abbruch und Hilfestellung möglich.
+
+FRAGE: Beantworten Sie die gestellte Frage mit 'j' oder 'n'. Abbruch
+ (ESC 'h') und Hilfestellung (ESC '?') möglich.
+
+ZEIGEN: Mit HOP OBEN und HOP UNTEN können Sie in der Übersicht
+ blättern. Ende der Übersicht mit ESC 'q'. Hilfestellung möglich.
+
+!!! FEHLER !!! Quittieren Sie die Meldung mit ESC 'q'. Hilfestellung
+ möglich.
+
+Bitte warten.. In diesem Zustand keine Taste drücken, der Rechner
+ ist beschäftigt.
+
+Drei weitere Zustände, die Sie noch nicht kennengelernt haben, sind
+hier schon mal der Vollständigkeit halber aufgeführt:
+
+SATZ ÄNDERN:
+SATZ EINFÜGEN:
+SUCHMUSTER EINGEBEN: Satzeditor zum Eingeben von Feldinhalten.
+ Normales Verlassen mit ESC 'q'. Abbruch und Hilfestellung mög­
+ lich. Beschreibung s. 6.2.
+
+EDITIEREN: EUMEL-Editor mit Änderungsmöglichkeit für beliebige
+ Texte. Normales Verlassen mit ESC 'q'. Hilfestellung möglich.
+ Beschreibung der Möglichkeiten siehe EUMEL-Benutzerhand­
+ buch.
+
+Gib Kommando: Hier können Sie ein beliebiges ELAN-Kommando ein­
+ geben und mit RETURN bestätigen. Abbruch und Hilfestellung
+ möglich. Kann im Menü durch ESC ESC aufgerufen werden.
+
+Wie Sie sehen, werden auch hier wieder die gleichen Tastenkombi­
+nationen verwendet, die Sie schon kennen.
+ In dieser Übersicht sind jeweils nur die wichtigsten Tastenkom­
+binationen aufgeführt. Informieren Sie sich gegebenenfalls mit ESC
+'?'. Einige weitere Tastenfunktionen werden Sie im folgenden noch
+kennenlernen. Eine vollständige Übersicht finden Sie im Referenz­
+handbuch.
+
diff --git a/doc/graphic/Altes Handbuch - Teil 10 - Graphik b/doc/graphic/Altes Handbuch - Teil 10 - Graphik
new file mode 100644
index 0000000..36fa31e
--- /dev/null
+++ b/doc/graphic/Altes Handbuch - Teil 10 - Graphik
@@ -0,0 +1,831 @@
+#type ("trium10")##limit (13.5)#
+#block##start(2.5,2.5)##pagelength(21.0)##pagenr("%",418)##setcount(22)#
+#headeven#
+% EUMEL-Benutzerhandbuch
+
+
+
+#end#
+#headodd#
+ TEIL 10: Graphik %
+
+
+
+#end#
+#type("triumb14")#
+#ib(9)##center#TEIL 10: Graphik#ie(9)#
+#type("trium10")#
+#free(2.0)#
+#on("bold")##ib(9)##type("triumb14")#1. Übersicht#ie(9)#
+#type("trium10")#
+
+ #limit(12.0)##on("italics")#Dieser Teil des Benutzer-Handbuchs beschreibt die Graphik-
+ Möglichkeiten des EUMEL-Systems. Die Graphik-Pakete ge­
+ hören nicht zum EUMEL-Standard, sondern sind Anwender­
+ pakete, die im Quellcode ausgeliefert und von jeder Installation
+ in das System aufgenommen werden können. Unter Umständen
+ müssen Programme erstellt werden, die die Anpassungen für
+ spezielle graphische Geräte einer Installation vornehmen.
+#limit(13.5)##off("italics")#
+
+Das Graphik-System ermöglicht es, durch ELAN-Programme geräteunab­
+hängige Informationen für Zeichnungen ("#ib#Graphiken#ie#") zu erstellen. Die Graphik
+erzeugenden Programme brauchen dabei keine gerätespezifischen Größen sowie
+gerätespezifischen Unterprogramme zu enthalten. Sie befassen sich somit
+ausschließlich mit der Erzeugung der problemorientierten Information für die
+Konstruktion einer Zeichnung. Nach der geräteunabhängigen Erzeugung einer
+Graphik kann diese auf unterschiedlichen Geräten ausgegeben werden (z.B. erst
+auf einem Terminal zur Kontrolle und dann auf einem Plotter).
+
+Die EUMEL-Graphik umfaßt zwei- und dreidimensionale Graphik. Dabei
+entspricht die Y-Achse bei der zweidimensionalen Graphik der Z-Achse (Höhe)
+bei der dreidimensionalen Graphik. Im dreidimensionalen Fall sind perspektivi­
+sche, orthografische und schiefwinklige Projektionen mit beliebigen Betrach­
+tungswinkeln möglich.
+
+Bei der EUMEL-Graphik wird streng zwischen Erzeugung und Manipulation von
+Graphiken (Bildern) auf der einen und Darstellung der erzeugten Bilder auf der
+anderen Seite unterschieden. Für die Erzeugung und Manipulation der Graphi­
+ken existiert der Typ PICTURE, für die Darstellung der Bilder gibt es den Typ
+PICFILE. Dabei müssen Ausschnitt, Maßstab, Betrachtungswinkel und Pro­
+jektionsart erst bei der Darstellung festgelegt werden. Diese Konstruktion des
+Graphik-Systems hat folgende Vorteile:
+
+a) Programme, die Graphik-Informationen erzeugen, sind geräteunabhängig.
+ Das bedeutet, daß Programmierer sich ausschließlich mit einem logischen
+ Problem zu befassen brauchen und nicht mit gerätespezifischen Besonder­
+ heiten.
+
+b) Graphiken können auf mehreren unterschiedlich gearteten Geräten mehrmals
+ dargestellt werden, ohne daß das erzeugende Programm geändert oder neu
+ gestartet werden muß. Z.B. kann ein Programmierer eine Graphik erst auf
+ dem Terminal auf Richtigkeit und Größenverhältnisse überprüfen, bevor er die
+ Zeichnung auf einem Plotter zeichnen läßt.
+
+c) Graphiken können leicht geändert (z.B. vergrößert oder in eine Richtung
+ gestreckt) werden, ohne daß das erzeugende Programm erneut durchlaufen
+ werden muß. Zudem können Graphiken aneinander oder übereinander gelegt
+ werden.
+
+d) Graphiken mit unterschiedlichen Farben, Strichen usw. können leicht erzeugt
+ werden.
+
+e) Der Anschluß von neuen Graphik-Geräten durch Benutzer ist leicht möglich,
+ ohne daß die Graphik erzeugenden Programme modifiziert werden müssen.
+
+f) Plotter können wie Drucker an einen SPOOLER gehängt werden.
+
+g) Bilder können als PICFILEs gespeichert und versandt werden.
+#free(2.0)#
+#ib(9)##type("triumb14")#Erzeugung von Bildern#ie(9)#
+#type("trium10")#
+
+Bilder entstehen in Objekten vom Datentyp
+
+#type("modern12")#
+ PICTURE
+#type("trium10")#
+
+Diese müssen mit der Prozedur
+
+#type("modern12")#
+ nilpicture
+#type("trium10")#
+
+initialisiert werden. Sie enthalten dann ein leeres Bild, dessen Dimension noch
+nicht festgelegt ist. Die Dimension eines PICTUREs wird mit dem ersten
+Schreibzugriff ('move' oder 'draw') festgelegt. Ein PICTURE kann immer nur
+entweder zwei- oder dreidimensional sein. Außerdem kann einem PICTURE mit
+der Prozedur
+
+#type("modern12")#
+ pen
+#type("trium10")#
+
+genau ein virtueller Stift zugeordnet oder der aktuelle Stift erfragt werden.
+
+Die Erzeugung eines Bildes basiert auf dem Modell eines Plotters. Der (virtuelle)
+Zeichenstift kann mit
+
+#type("modern12")#
+ move
+#type("trium10")#
+
+ohne zu zeichnen an beliebige Stellen gefahren werden (reine Positionierung).
+Mit
+
+#type("modern12")#
+ draw
+#type("trium10")#
+
+wird der Stift veranlaßt, eine Linie von der aktuellen zur angegebenen Zielposi­
+tion zu zeichnen. 'move' löst also Bewegungen mit gehobenem, 'draw' solche mit
+gesenktem Stift aus. Um auch 'relatives' Zeichnen zu ermöglichen, existiert die
+Prozedur
+
+#type("modern12")#
+ where
+#type("trium10")#
+
+die die aktuelle Stiftposition liefert.
+#free(2.0)#
+#ib(9)##type("triumb14")#Manipulation von Bildern#ie(9)#
+#type("trium10")#
+
+Erstellte Bilder können als Ganzes manipuliert werden. Die Prozeduren
+
+#type("modern12")#
+ translate (* verschieben *)
+ stretch (* strecken bzw. stauchen *)
+ rotate (* drehen *)
+ reflect (* spiegeln *)
+#type("trium10")#
+
+verändern jeweils das ganze Bild. Es ist aber auch möglich, mehrere Bilder
+zusammenzufügen. Mit
+
+#type("modern12")#
+ CAT
+#type("trium10")#
+
+kann ein weiteres Bild angefügt werden. Dabei müssen allerdings beide
+PICTURE die gleiche Dimension haben. In solchen als ganzes manipulierten
+Bildern kann man ohne Einschränkung mit 'draw' und 'move' weiterzeichnen.
+#free(2.0)#
+#ib(9)##type("triumb14")#Darstellung#ie(9)#
+#type("trium10")#
+
+Für die Darstellung der erzeugten Bilder existiert der Typ
+
+#type("modern12")#
+ PICFILE
+#type("trium10")#
+
+Dieser besteht aus max. 128 PICTUREs, die mit den Prozeduren
+
+#type("modern12")#
+ put
+ get
+#type("trium10")#
+
+eingegeben bzw. ausgegeben werden können. PICFILE wird durch Datenräume
+realisiert, deshalb erfolgt die Assoziation an einen benannten Datenraum ähnlich
+wie beim FILE. Dafür wird die Prozedur
+
+#type("modern12")#
+ picture file
+#type("trium10")#
+
+verwandt. Ein neuer PICFILE enthält genau ein leeres PICTURE. Die Darstellung
+der PICFILEs auf Zeichengeräten erfolgt mit der Prozedur
+
+#type("modern12")#
+ plot
+#type("trium10")#
+
+Da die Graphiken aber in "Weltkoordinaten" erzeugt werden und die spätere
+Darstellung vollkommen unbeachtet bleibt, müssen gewisse Darstellungspara­
+meter für die Zeichnung gesetzt werden. Diese Parameter werden im PICFILE
+abgelegt und gelten jeweils für den gesamten PICFILE. Dadurch ist es möglich,
+einen PICFILE mit spezifizierter Darstellungsart über einen SPOOLER an einen
+Plotter zu senden oder die bei der letzten Betrachtung gewählte Darstellung mit
+in dem PICFILE gespeichert zu halten. Für die Darstellung können den virtuellen
+Stiften mit der Prozedur
+
+#type("modern12")#
+ select pen
+#type("trium10")#
+
+reale Stifte zugeordnet werden. Voreingestellt ist für alle virtuellen Stifte:
+Standardfarbe, Standardstärke, durchgängige Linie.
+
+Indem man einigen virtuellen Stiften den leeren Stift als realen Stift zuordnet,
+kann man einzelne PICTUREs ausblenden. Sowohl bei der Darstellung von
+zwei- als auch dreidimensionaler Graphik kann die gewählte Zeichenfläche auf
+dem Endgerät mit der Prozedur
+
+#type("modern12")#
+ viewport
+#type("trium10")#
+
+festgelegt werden. Voreingestellt ist das Quadrat mit der größtmöglichen Seiten­
+länge, d.h. der kürzeren Seite der hardwaremäßigen Zeichenfläche.
+#free(2.0)#
+#ib(9)##type("triumb14")#Darstellung zweidimensionaler Graphik#ie(9)#
+#type("trium10")#
+
+Bei der Darstellung zweidimensionaler Bilder muß der zu zeichnende Ausschnitt
+(das 'Fenster') angegeben werden. Mit der Prozedur
+
+#type("modern12")#
+ window
+#type("trium10")#
+
+wird durch Angabe der minimalen und maximalen X- bzw. Y-Koordinaten ein
+Fenster definiert. Da das so definierte Fenster auf die ganze (mit 'viewport'
+definierbare) Zeichenfläche abgebildet wird, ist der Abbildungsmaßstab durch das
+Zusammenspiel von 'viewport' und 'window' bestimmt. Da bei 'viewport' stan­
+dardmäßig das maximale Zeichenquadrat voreingestellt ist, wird in diesem Fall
+durch gleiche X- und Y-Fenstergröße eine winkeltreue Darstellung erreicht.
+#free(2.0)#
+#ib(9)##type("triumb14")#Darstellung dreidimensionaler Graphik#ie(9)#
+#type("trium10")#
+
+Im dreidimensionalen Fall wird das Fenster ebenfalls mit
+
+#type("modern12")#
+ window
+#type("trium10")#
+
+definiert, wobei dann allerdings auch der Bereich der dritten Dimension
+(Z-Koordinaten) zu berücksichtigen ist. Da die dreidimensionale Graphik auf
+eine zweidimensionale Fläche projiziert wird, können aber noch weitere Darstel­
+lungsparameter angegeben werden. Der Betrachtungswinkel wird mit Hilfe der
+Prozedur
+
+#type("modern12")#
+ view
+#type("trium10")#
+
+angegeben. Zur Spezifikation der gewünschten Projektionsart gibt es
+
+#type("modern12")#
+ orthographic (* orthographische Projektion *)
+ perspective (* perspektivische Projektion,
+ der Fluchtpunkt ist frei wählbar *)
+ oblique (* schiefwinklige Projektion *)
+#type("trium10")#
+#free(2.0)#
+#ib(9)##type("triumb14")#Beispiel (Sinuskurve)#ie(9)#
+#type("modern12")#
+
+ funktion zeichnen;
+ bild darstellen .
+
+funktion zeichen :
+ PICTURE VAR pic :: nilpicture;
+ REAL VAR x := -pi;
+ move (pic, x, sin (x));
+ REP x INCR 0.1;
+ draw (pic, x, sin (x))
+ UNTIL x >= pi PER .
+
+bild darstellen :
+ PICFILE VAR p :: picture file ("sinus");
+ window (p, -pi, pi, -1.0, 1.0);
+ put (p, pic);
+ plot (p) .
+#type("trium10")#
+#free(2.0)#
+#ib(9)##type("triumb14")#Beispiel (Würfel)#ie(9)#
+#type("modern12")#
+
+ wuerfel zeichen;
+ wuerfel darstellen.
+
+wuerfel zeichnen :
+ zeichne vorderseite;
+ zeichne rueckseite;
+ zeichne verbindungskanten.
+
+zeichne vorderseite :
+ PICTURE VAR vorderseite :: nilpicture;
+ move (vorderseite, 0.0, 0.0, 0.0);
+ draw (vorderseite, 1.0, 0.0, 0.0);
+ draw (vorderseite, 1.0, 0.0, 1.0);
+ draw (vorderseite, 0.0, 0.0, 1.0);
+ draw (vorderseite, 0.0, 0.0, 0.0).
+
+zeichne rueckseite :
+ PICTURE VAR rueckseite :: translate
+ (vorderseite, 0.0, 1.0, 0.0).
+
+zeichne verbindungskanten :
+ PICTURE VAR verbindungskanten :: nilpicture;
+ move (verbindungskanten, 0.0, 0.0, 0.0);
+ draw (verbindungskanten, 0.0, 1.0, 0.0);
+
+ move (verbindungskanten, 1.0, 0.0, 0.0);
+ draw (verbindungskanten, 1.0, 1.0, 0.0);
+
+ move (verbindungskanten, 1.0, 0.0, 1.0);
+ draw (verbindungskanten, 1.0, 1.0, 1.0);
+
+ move (verbindungskanten, 0.0, 0.0, 1.0);
+ draw (verbindungskanten, 0.0, 1.0, 1.0).
+
+wuerfel darstellen :
+ PICFILE VAR p := picture file ("wuerfel");
+ put (p, vorderseite);
+ put (p, rueckseite);
+ put (p, verbindungskanten);
+ window (p, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
+ view (p, 0.0, 40.0, 20.0);
+ orthographic (p);
+ plot (p).
+#type("trium10")#
+#free(2.0)#
+#ib(9)##type("triumb14")#Beschreibung der Graphik-Prozeduren#ie(9)#
+#type("trium10")#
+
+ #limit(12.0)##on("italics")#Zweidimensionale PICTUREs brauchen weniger Speicherplatz
+ als dreidimensionale. Daher werden in einigen Fehlermeldun­
+ gen unterschiedliche Größen angegeben.
+#limit(13.5)##off("italics")#
+
+:=
+ OP := (PICTURE VAR dest, PICTURE CONST source)
+ Zweck: Zuweisung
+
+ OP := (PICFILE VAR dest, DATASPACE CONST source)
+ Zweck: Assoziiert die PICFILE Variable 'dest' mit der DATASPACE CONST
+ 'source' und initialisiert die PICFILE Variable sofern nötig.
+ Fehlerfall:
+ * dataspace is no PICFILE
+ Der anzukoppelnde Datenraum hat einen falschen Typ.
+
+#ib#CAT#ie#
+ OP CAT (PICTURE VAR dest, PICTURE CONST source)
+ Zweck: Aneinanderfügen von zwei PICTURE's.
+ Fehlerfälle:
+ * OP CAT: left dimension <> right dimension
+ Es können nur PICTUREs mit gleicher Dimension angefügt werden.
+ * OP CAT: Picture overflow
+ Die beiden PICTURE überschreiten die maximale Größe eines
+ Pictures.
+
+#ib#act picture#ie#
+ PICTURE PROC act picture (PICFILE VAR p)
+ Zweck: Liefert das PICTURE des PICFILEs 'p', auf das mit 'backward' o.ä.
+ positioniert wurde.
+
+#ib#backward#ie#
+ PROC backward (PICFILE VAR p)
+ Zweck: Positioniert den PICFILE 'p' um ein PICTURE zurück.
+ Fehlerfall:
+ * backward at begin of file
+ Es wurde versucht vor den Anfang des PICFILEs zu positionieren.
+
+#ib#draw#ie#
+ PROC draw (PICTURE VAR pic, REAL CONST x, y)
+ Zweck: Die Prozedur zeichnet in dem (zweidimensionalen) Bild 'pic' eine
+ Linie von der aktuellen Position zur Position (x, y).
+ Fehlerfälle:
+ * picture overflow
+ Zu viele Befehle in einem PICTURE (z. Zeit max. 1927)
+ * picture is three dimensional
+ Ein PICTURE kann nur entweder zwei- oder dreidimensional sein.
+
+ PROC draw (PICTURE VAR pic, REAL CONST x, y, z)
+ Zweck: Die Prozedur zeichnet in dem (dreidimensionalen) Bild 'pic' eine
+ gerade Linie von der aktuellen Position zur Position (x, y, z).
+ Fehlerfälle:
+ * picture overflow
+ Zu viele Befehle in einem PICTURE (z. Zeit max. 1310)
+ * picture is only two dimensional
+ Ein PICTURE kann nur entweder zwei- oder dreidimensional sein.
+
+ PROC draw (PICTURE VAR pic, TEXT CONST text)
+ Zweck: Der angegebene Text wird in das Bild 'pic' eingetragen. Der Anfang
+ ist dabei die aktuelle Stiftposition. Diese wird nicht verändert.
+ Fehlerfall:
+ * picture overflow
+ Der Text paßt nicht mehr in das PICTURE.
+
+ PROC draw (PICTURE VAR pic, TEXT CONST text,
+ REAL CONST angle, height)
+ Zweck: Der angegebene Text wird unter dem Winkel 'angle' gegenüber der
+ Waagerechten und in der Größe 'height' in das PICTURE 'pic'
+ eingetragen. Der Anfang ist dabei die aktuelle Stiftposition. Diese
+ wird nicht verändert.
+ Fehlerfall:
+ * picture overflow
+ Der Text paßt nicht mehr in das PICTURE.
+
+ PROC draw (PICFILE VAR pic, REAL CONST x, y)
+ Zweck: Die Prozedur zeichnet in dem aktuellen (zweidimensionalen)
+ PICTURE des PICFILEs 'p' eine gerade Linie. Der (virtuelle) Stift wird
+ von der aktuellen Position zur Position (x, y) gefahren. Falls das
+ aktuelle PICTURE zu voll ist, wird automatisch auf das nächste
+ umgeschaltet.
+ Fehlerfälle:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128 PICTURE)
+ * picture is threedimensional
+ Das aktuelle PICTURE ist dreidimensional.
+
+ PROC draw (PICTFILE VAR pic, REAL CONST x, y, z)
+ Zweck: s. o.
+ Fehlerfälle:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128)
+ * picfile is only twodimensional
+ Das aktuelle PICTURE ist zweidimensional.
+
+ PROC draw (PICTFILE VAR pic, TEXT CONST text)
+ Zweck: Der angegebene Text wird in das aktuelle PICTURE des PICFILEs 'p'
+ eingetragen. Falls das aktuelle PICTURE zu voll ist, wird automatisch
+ auf das nächste umgeschaltet. Der Anfang ist dabei die aktuelle
+ Stiftposition. Diese wird nicht verändert.
+ Fehlerfall:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128)
+
+ PROC draw (PICFILE VAR pic, TEXT CONST text,
+ REAL CONST angle, height)
+ Zweck: Der angegebene Text wird unter dem Winkel 'angle' gegenüber der
+ Waagerechten und in der Größe 'height' in das aktuelle PICTURE
+ des PICFILES 'p' eingetragen. Falls das aktuelle PICTURE zu voll ist,
+ wird automatisch auf das nächste umgeschaltet. Der Anfang ist
+ dabei die aktuelle Stiftposition. Diese wird nicht verändert.
+ Fehlerfall:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128)
+
+#ib#eof#ie#
+ BOOL PROC eof (PICFILE CONST p)
+ Zweck: Liefert 'TRUE' wenn hinter das Ende des PICFILEs positioniert
+ wurde.
+
+#ib#extrema#ie#
+ PROC extrema (PICTURE CONST p,
+ REAL VAR x min, x max, y min, y max)
+ Zweck: Die Prozedur liefert die größten und kleinsten X- und Y-Koordi­
+ naten des PICTUREs 'p'. Diese werden in die Parameter 'x min', 'x
+ max', 'y min' und 'y max' eingetragen.
+
+ PROC extrema (PICTURE CONST p,
+ REAL VAR x min, x max, y min, y max, z min, z max)
+ Zweck: s.o.
+
+ PROC extrema (PICFILE VAR p, REAL VAR x min, x max, y min, y max)
+ Zweck: s.o.
+
+ PROC extrema (PICFILE VAR p,
+ REAL VAR x min, x max, y min, y max, z min, z max)
+ Zweck: s.o.
+
+#ib#forward#ie#
+ PROC forward (PICFILE VAR p)
+ Zweck: Positioniert den PICFILE um ein PICTURE weiter.
+ Fehlerfall:
+ * picfile overflow
+ Es sollte hinter das Ende des PICFILEs positioniert werden.
+
+#ib#get#ie#
+ PROC get (PICFILE VAR p, PICTURE VAR pic)
+ Zweck: Liest ein PICTURE aus einem PICFILE und positioniert auf das
+ Nächste.
+ Fehlerfall:
+ * input after end of picfile
+ Es sollte nach dem Ende des Picfiles gelesen werden.
+
+#ib#move#ie#
+ PROC move (PICTURE VAR pic, REAL CONST x, y)
+ Zweck: Der (virtuelle) Stift wird zur Position (x, y) gefahren.
+ Fehlerfälle:
+ * picture overflow
+ Zu viele Befehle in einem PICTURE (z. Zeit max. 1927 'moves')
+ * picture is three dimensional
+ Ein PICTURE kann nur entweder zwei- oder dreidimensional sein.
+
+ PROC move (PICTURE VAR pic, REAL CONST x, y, z)
+ Zweck: Der (virtuelle) Stift wird zur Position (x, y, z) gefahren.
+ Fehlerfälle:
+ * picture overflow
+ Zu viele Befehle in einem PICTURE (z. Zeit max. 1310)
+ * picture is only twodimensional
+ Ein PICTURE kann nur entweder zwei- oder dreidimensional sein.
+
+ PROC move (PICFILE VAR p, REAL CONST x, y)
+ Zweck: Der (virtuelle) Stift wird zur Position (x, y) gefahren. Falls das aktuelle
+ PICTURE des PICFILEs 'p' zu voll ist, wird automatisch auf das
+ nächste umgeschaltet.
+ Fehlerfall:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128 PICTUREs)
+
+ PROC move (PICFILE VAR p, REAL CONST x, y, z)
+ Zweck: Der (virtuelle) Stift wird zur Position (x, y, z) gefahren. Falls das
+ aktuelle PICTURE des PICFILEs 'p' zu voll ist, wird automatisch auf
+ das nächste umgeschaltet.
+ Fehlerfall:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128 PICTUREs)
+
+#ib#nilpicture#ie#
+ PICTURE PROC nilpicture
+ Zweck: Die Prozedure liefert ein leeres PICTURE zur Initialisierung.
+
+#ib#oblique#ie#
+ PROC oblique (PICFILE VAR p, REAL CONST a, b)
+ Zweck: Bei dem (dreidimensionalen!) Bild 'p' wird 'schiefwinklig' als
+ gewünschte Projektionsart eingestellt. Dabei ist (a, b) der Punkt in
+ der X-Y-Ebene, auf den der Einheitsvector in Z-Richtung
+ abgebildet werden soll.
+
+#ib#orthographic#ie#
+ PROC orthographic (PICFILE VAR p)
+ Zweck: Bei dem (dreidimensionalen!) Bild 'p' wird "orthografisch" als Pro­
+ jektionsart eingestellt. Bei der orthografischen Projektion wird ein
+ dreidimensionaler Körper mit parallelen Strahlen senkrecht auf die
+ Projektionsebene abgebildet.
+
+#ib#pen#ie#
+ INT PROC pen (PICTURE CONST pic)
+ Zweck: Liefert die Nummer des 'virtuellen Stifts'.
+
+ PICTURE PROC pen (PICTURE CONST pic, INT CONST pen)
+ Zweck: Liefert ein PICTURE mit dem Inhalt 'pic' und dem 'virtuellen Stift' mit
+ der Nummer 'pen'. Möglich sind die Nummern 1 - 16.
+ Fehlerfälle:
+ * PROC pen: pen [No] < 1
+ Der gewünschte Stift ist kleiner als 1.
+ * PROC pen: pen [No] > 16
+ Der gewünschte Stift ist größer als 16.
+
+#ib#perspective#ie#
+ PROC perspective (PICFILE VAR p, REAL CONST cx, cy, cz)
+ Zweck: Bei den dreidimensionalen PICTUREs des PICFILE's 'p' wird
+ "perspektivisch" als gewünschte Projektionsart eingestellt. Der Punkt
+ (cx, cy, cz) ist der Fluchtpunkt der Projektion, d.h. alle Parallelen zur
+ Blickrichtung schneiden sich in diesem Punkt.
+
+#ib#pic no#ie#
+ INT PROC pic no (PICFILE CONST p)
+ Zweck: Liefert die Nummer des aktuellen PICTUREs.
+
+#ib#picture file#ie#
+ DATASPACE PROC picture file (TEXT CONST name)
+ Zweck: Die Prozedur dient zur Assoziation eines benannten Datenraumes mit
+ einem PICFILE (s. Operator ':=').
+
+#ib#plot#ie#
+ PROC plot (TEXT CONST name)
+ Zweck: Der PICFILE mit dem Namen 'name' wird entspechend der angege­
+ benen Darstellungsart gezeichnet. Diese Parameter ('perspective',
+ 'orthographic', 'oblique', 'view', 'window' etc.) müssen vorher
+ eingestellt werden.
+ Fehlerfall:
+ * FILE does not exist
+ Es existiert kein PICFILE mit dem Namen 'name'
+
+ PROC plot (PICFILE VAR p)
+ Zweck: Der PICFILE 'p' wird entspechend der angegebenen Darstellungsart
+ gezeichnet. Diese Parameter müssen vorher eingestellt werden.
+
+ #on("bold")#Zweidimensional:
+#off("bold")#
+ obligat: 'window' (zweidimensional)
+ optional: 'view' (zweidimensional)
+ 'select pen'
+ 'viewport'
+
+ #on("bold")#Dreidimensional:
+#off("bold")#
+ obligat: 'window' (dreidimensional)
+ optional: 'view' (dreidimensional)
+ 'orthographic', 'perspective', 'oblique'
+ 'viewport'
+ 'select pen'
+
+#ib#put#ie#
+ PROC put (PICFILE VAR p, PICTURE CONST pic)
+ Zweck: Schreibt ein PICTURE in einen PICFILE und positioniert um eins
+ vor.
+ Fehlerfall:
+ * picfile overflow
+ Der PICFILE ist voll. (z. Z. max. 128 PICTURE)
+
+#ib#reset#ie#
+ PROC reset (PICFILE VAR p)
+ Zweck: Positioniert auf den Anfang eines Picfiles.
+
+#ib#rotate#ie#
+ PICTURE PROC rotate (PICTURE CONST pic, REAL CONST alpha)
+ Zweck: Das PICTURE 'pic' wird um den Punkt (0, 0) um den Winkel 'alpha'
+ (im Gradmaß) im mathematisch positiven Sinn gedreht.
+
+ PICTURE PROC rotate (PICTURE CONST pic,
+ REAL CONST alpha, beta, gamma)
+ Zweck: Das dreidimensionale PICTURE 'pic' wird um den Winkel 'alpha',
+ 'beta' oder 'gamma' im mathematisch positiven Sinn gedreht. Der
+ Winkel 'alpha' dreht um die X-Achse, der Winkel 'beta' um die
+ Y-Achse und 'gamma' um die Z-Achse. Es darf dabei nur jeweils
+ ein Winkel von 0.0 verschieden sein. Alle Winkel werden im
+ Gradmaß angegeben.
+
+#ib#select pen#ie#
+ PROC select pen (PICFILE VAR p,
+ INT CONST pen, colour, thickness, linetype)
+ Zweck: Für die Darstellung des Bildes 'p' soll dem "virtuellen Stift" 'pen' ein
+ realer Stift zugeordnet werden, der möglichst die Farbe 'colour' und
+ die Dicke 'thickness' hat und dabei Linien mit dem Typ 'line type'
+ zeichnet. Es wird die beste Annäherung für das Ausgabegerät für
+ diese Parameter genommen. Dabei gelten folgende Vereinbarun­
+ gen:
+
+ Farbe: negative Farben setzten den Hintergrund, positive Farben
+ zeichnen im Vordergrund.
+
+ 0 Löschstift (falls vorhanden)
+ 1 Standardfarbe des Endgeräts (schwarz oder weiß)
+ 2 rot
+ 3 blau
+ 4 grün
+ 5 schwarz
+ 6 weiß > 20 nicht normierte Sonderfarben
+
+ Dicke: 0
+ Standardstrichstärke des Endgerätes > 0
+ Strichstärke in 1/10 mm
+
+ Typ:
+ 0 keine sichtbare Linie
+ 1 durchgängige Linie
+ 2 gepunktete Linie
+ 3 kurz gestrichelte Linie
+ 4 lang gestrichelte Linie
+ 5 Strichpunktlinie
+
+ Die hier aufgeführten Möglichkeiten müssen nicht an allen grafischen
+ Endgeräten vorhanden sein. Der geräteabhängige Graphik-Treiber
+ wählt jeweils die für ihn bestmögliche Annäherung.
+
+ Fehlerfälle:
+ * pen < 1
+ * pen > 16
+
+#ib#size#ie#
+ INT PROC size (PICFILE CONST p)
+ Zweck: Liefert die aktuelle Größe eines PICFILEs in Bytes.
+
+#ib#stretch#ie#
+ PICTURE PROC stretch (PICTURE CONST pic, REAL CONST xc, yc)
+ Zweck: Das PICTURE 'pic' wird in X-Richtung um den Faktor 'xc', in
+ Y-Richtung um den Faktor 'yc' gestreckt (bzw. gestaucht). Dabei
+ bewirkt der Faktor
+ c > 1 eine Streckung
+ 0 < c < 1 eine Stauchung
+ c < 0 zusätzlich eine Achsenspiegelung
+
+ PICTURE PROC stretch (PICTURE CONST pic, REAL CONST xc, yc, zc)
+ Zweck: Das dreidimensionale PICTURE 'pic' wird entsprechend den
+ angegeben Faktoren 'xc', 'yc' und 'zc' gestreckt. Wirkung s.o.
+
+#ib#translate#ie#
+ PICTURE PROC translate (PICTURE CONST pic, REAL CONST dx, dy)
+ Zweck: Das PICTURE 'pic' wird um 'dx' und 'dy' verschoben.
+ Fehlerfall:
+ * picture is threedimensional
+ 'pic' ist dreidimensional.
+
+ PICTURE PROC translate (PICTURE CONST pic, REAL CONST dx, dy, dz)
+ Zweck: Das PICTURE 'pic' wird um 'dx', 'dy' und 'dz' verschoben.
+ Fehlerfall:
+ * picture is twodimensional
+ Das PICTURE 'pic' ist zweidimensional
+
+#ib#two dimensional#ie#
+ PROC two dimensional (PICFILE VAR p)
+ Zweck: Setzt als Projektionsart zweidimensional.
+
+#ib#view#ie#
+ PROC view (PICFILE VAR p, REAL CONST alpha, phi, theta)
+ Zweck: Dreidimensionale Bilder werden häufig nicht direkt von vorne
+ dargestellt, sondern für die Betrachtung gedreht. Mit der Prozedur
+ 'view' kann diese Betrachtungsrichtung durch die Polarwinkel 'phi'
+ und 'theta' angegeben werden. Mit dem Winkel 'alpha' kann dann
+ das Bild um den Mittelpunkt der Zeichenfläche gedreht werden.
+ Dadurch kann ein Bild auch auf einem Terminal hochkant gestellt
+ werden. Voreingestellt ist 'phi = 0, theta = 0 und alpha = 0', d.h.
+ direkt von oben.
+
+ Im Gegensatz zu 'rotate' hat 'view' keine Wirkung auf das eigentli­
+ che Bild (PICFILE), sondern nur auf die gewählte Darstellung. So
+ addieren sich zwar aufeinanderfolgende "Rotationen", 'view' aber
+ geht immer von der Nullstellung aus. Auch kann das Bild durch eine
+ "Rotation" ganz oder teilweise aus oder in das Darstellungsfenster
+ ('window') gedreht werden. Bei 'view' verändern sich die Koordina­
+ ten der Punkte nicht, d.h. das Fenster wird mitgedreht.
+
+#ib#viewport#ie#
+ PROC viewport (PICFILE VAR p,
+ REAL CONST hormin, hormax, vertmin, vertmax)
+ Zweck: Die Zeichenfläche auf dem Endgerät, auf dem das Bild dargestellt
+ werden soll, wird spezifiziert. Dabei wird sowohl die Größe als auch
+ die relative Lage der Zeichenfläche definiert. Der linke untere
+ Eckpunkt der physikalischen Zeichenfläche des Gerätes hat die
+ Koordinaten (0.0, 0.0). Die definierte Zeichenfläche erstreckt sich
+
+#type("modern12")#
+ 'hormin' - 'hormax' in der Horizontalen,
+ 'vertmin' - 'vertmax' in der Vertikalen.
+#type("trium10")#
+
+ So liegt der linke untere Eckpunkt dann bei (hormin, vertmin), der
+ rechte obere bei (hormax, vertmax).
+
+ Damit sowohl geräteunabhängige als auch maßstabsgerechte
+ Zeichnungen möglich sind, können die Koordinaten in zwei Arten
+ spezifiziert werden :
+
+ a) Gerätekoordinaten
+ Die Koordinaten können Werte von 0.0 bis 2.0 annehmen. Dabei
+ hat die kürzere Seite der physikalischen Zeichenfläche defini­
+ tionsgemäß die Länge 1.0.
+
+ b) absolute Koordinaten
+ Die Werte werden in cm angegeben. Für die Maximalwerte sind
+ nur Werte größer als 2.0 möglich.
+
+ Voreingestellt ist
+
+#type("modern12")#
+ viewport (0.0, 1.0, 0.0, 1.0),
+#type("trium10")#
+
+ d.h. das größtmöglichste Quadrat, beginnend in der linken unteren
+ Ecke der physikalischen Zeichenfläche. In vielen Fällen wird diese
+ Einstellung ausreichen, so daß der Anwender kein eigenes 'viewport'
+ definieren muß.
+
+ Der Abbildungsmaßstab wird durch das Zusammenspiel von 'view­
+ port' und 'window' festgelegt (siehe dort). Dabei ist insbesondere
+ darauf zu achten, daß winkeltreue Darstellungen nur bei gleichem
+ X- und Y-Maßstab möglich sind. Da man oft quadratische Fenster
+ ('window') verwendet, wurde als Standardfall auch ein quadratisches
+ 'viewport' gewählt.
+
+#ib#where#ie#
+ PROC where (PICTURE CONST pic, REAL VAR x, y)
+ Zweck: Die aktuelle Stiftposition wird in 'x' und 'y' eingetragen.
+ Fehlerfall:
+ * picture is threedimensional
+ Das PICTURE 'pic' ist dreidimensional
+
+ PROC where (PICTURE CONST pic, REAL VAR x, y, z)
+ Zweck: Die aktuelle Stiftposition wird in 'x', 'y' und 'z' eingetragen.
+ Fehlerfall:
+ * picture is twodimensional
+ Das PICTURE 'pic' ist zweidimensional
+
+#ib#window#ie#
+ PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max)
+ Zweck: Für die Darstellung eines zweidimensionalen Bildes wird das
+ darzustellende Fenster definiert. Alle Bildpunkte, deren X-Koordi­
+ naten im Intervall [x min, x max] und deren Y-Koordinaten im
+ Intervall [y min, y max] liegen, gehören zum definierten Fenster.
+ Vektoren, die über dieses Fenster hinausgehen, werden abge­
+ schnitten. Dieses Fenster wird auf die spezifizierte Zeichenfläche
+ abgebildet. (Das ist standardmäßig das größtmögliche Quadrat auf
+ dem ausgewählten Gerät).
+
+ Der Darstellungsmaßstab ergibt sich als
+
+#type("modern12")#
+ x max - x min
+ -----------------------------------------
+ horizontale Seitenlänge der Zeichenfläche
+
+ y max - y min
+ -----------------------------------------
+ vertikale Seitenlänge der Zeichenfläche
+#type("trium10")#
+
+ Für eine winkeltreue Darstellung müssen X- und Y-Maßstab
+ gleich sein! Einfach können winkeltreue Darstellung erreicht
+ werden, wenn das Fenster eine quadratische Form hat. Die
+ Zeichenfläche ('viewport') ist dementsprechend als Quadrat vorein­
+ gestellt.
+
+ PROC window (PICFILE VAR p,
+ REAL CONST x min, x max, y min, y max, z min, z max)
+ Zweck: Für die Darstellung eines dreidimensionalen Bildes wird das darzu­
+ stellende Fenster definiert. Alle Bildpunkte, deren X-Koordinaten im
+ Intervall [x min, x max] und deren Y-Koordinaten im Intervall [y min,
+ y max] und deren Z-Koordinaten im Intervall [z min, z max] liegen,
+ gehören zum definierten Fenster. Dieses dreidimensionale Fenster
+ (Quader) wird entsprechend der eingestellten Projektionsart (ortho­
+ grafisch, perspektivisch oder schiefwinklig) und den Betrachtungs­
+ winkeln (s. 'view') auf die spezifizierte Zeichenfläche abgebildet. (Das
+ ist standardmäßig das größtmögliche Quadrat auf dem ausgewählten
+ Gerät.) Linien, die außerhalb dieses Quadrates liegen, werden
+ abgeschnitten.
+
+ Anders als im zweidimensionalen Fall ist das Problem der Maßstäbe
+ nicht mehr nur durch das Zusammenspiel von 'window' und 'view­
+ port' zu beschreiben. Hier spielen auch Projektionsart und Dar­
+ stellungswinkel eine Rolle. Falls alle Darstellungswinkel den Wert 0.0
+ haben, gilt das für den zweidimensionalen Fall gesagte für die Ebene
+ (y = 0.0) entsprechend.
+
+#ib#write is possible#ie#
+ BOOL PROC write is possible (PICTURE CONST pic, INT CONST space)
+ Zweck: Liefert 'TRUE', falls 'space' Bytes Platz in 'pic' vorhanden ist.
+
+
+
+
+
+
diff --git a/doc/graphic/GRAPHIK.book b/doc/graphic/GRAPHIK.book
new file mode 100644
index 0000000..435d9e4
--- /dev/null
+++ b/doc/graphic/GRAPHIK.book
@@ -0,0 +1,897 @@
+#type ("times8")##limit (11.0)##start (2.2, 1.5)##pagelength (17.4)##block#
+
+#head#
+#type ("triumb14")#
+#center#EUMEL-Grafik-System
+
+#type ("times8")#
+#end#
+#type ("triumb14")# Teil 10: Graphik#type ("times8")#
+
+
+#type ("trium12")#
+#on("b")#1. Übersicht#off("b")#
+#type ("times8")#
+
+#limit (7.0)##type("times6")#
+ #on("i")#Dieser Teil des Benutzer-Handbuchs beschreibt die Graphik-
+ Fähigkeiten des EUMEL-Systems. Die Graphik-Pakete gehö­
+ ren nicht zum Eumel-Standard, sondern sind Anwenderpake­
+ te, die im Quellcode ausgeliefert und von jeder Installation in das
+ System aufgenommen werden können. #off("i")#
+#limit (11.0)#
+#foot#
+ Eventuell müssen Programme erstellt werden, die die Anpassungen für spezielle graphische Geräte einer Installation
+ vornehmen, soweit diese nicht von den EUMEL-Anbietern bezogen werden können.
+#end#
+
+#type("times8")#
+ Das #on("b")#Graphik-System#off("b")# ermöglicht es, durch ELAN-Programme geräteunabhängige Infor­
+ mationen für Zeichnungen (#on("i")#Graphiken#off("i")#) zu erstellen. Die Graphik erzeugenden Programme
+ brauchen dabei keine geräteabhängigen Größen oder Unterprogramme zu enthalten. Sie
+ befassen sich somit ausschließlich mit der Erzeugung der problemorientierten Information
+ für die Konstruktion einer Zeichnung. Nach der geräteunabhängigen Erzeugung einer
+ Graphik kann diese auf unterschiedlichen Geräten ausgegeben werden (z.B. erst auf einem
+ Terminal zur Kontrolle und dann auf einem Plotter).
+
+ Die EUMEL-Graphik umfaßt zwei- und dreidimensionale Graphik. Im dreidimensiona­
+ len Fall sind perspektivische, orthografische und schiefwinklige Projektionen mit beliebi­
+ gen Betrachtungswinkeln möglich.
+
+ Bei der EUMEL-Graphik wird streng zwischen Erzeugung und Manipulation von Gra­
+ phiken auf der einen und der Darstellung der erzeugten Bilder auf der anderen Seite
+ unterschieden. Für die Erzeugung und Manipulation der Graphiken wird von den Paketen
+ #on("i")#picture#off("i")# und #on("i")#picfile#off("i")# der Datentype #on("b")#PICTURE#off("b")# bzw. #on("b")#PICFILE#off("b")# zur Verfügung gestellt. Dabei
+ müssen Ausschnitt, Maßstab, Betrachtungswinkel und Projektionsart erst bei der Darstel­
+ lung festgelegt werden. Diese Konstruktion des Graphik-Systems hat folgende Vorteile:
+
+ a) Programme, die Graphik-Information erzeugen, sind geräteunabhängig. Das bedeu­
+ tet, das der Programmierer sich ausschließlich mit einem logischen Problem befassen
+ muß und nicht mit gerätespezifischen Besonderheiten.
+
+ b) Graphiken können auf mehreren unterschiedlich gearteten Geräten mehrmals darge­
+ stellt werden, ohne daß das erzeugende Programm geändert oder neu gestartet werden
+ muß. Z.B. kann ein Programmierer eine Graphik erst auf dem Terminal überprüfen,
+ bevor er die Graphik auf einem Plotter zeichnen läßt.
+
+ c) Graphiken können leicht geändert (z. B. vergrößert oder in eine Richtung gestreckt
+ o.ä.) werden, ohne daß sie erneut erzeugt werden müssen. Zudem können Graphiken
+ aneinander oder übereinander gelegt werden.
+
+ d) Graphiken mit unterschiedlichen Farben, Strichen usw. können leicht erzeugt werden.
+
+ e) Der Anschluß von neuen Graphik.Geräten durch Benutzer ist leicht möglich, ohe daß
+ die Graphik-Programme geändert werden müssen.
+
+ f) Plotter können wie Drucker an einen Spooler gehängt werden.
+
+ g) Bilder können als PICFILEs gespeichert und versandt werden.
+
+ h) Es können auch auf Systemen ohne graphische Ausgabegeräte Graphiken erzeugt
+ werden.
+
+ i) Es können mit einfachen Mitteln universelle Unterprogrammpakete erstellt werden,
+ um die Standardzeichnungen (Darstellen einer Funktion, Balken oder Liniendiagram­
+ me, Achsen etc.) zu erstellen.
+
+
+#type ("trium12")#
+#on("b")#2. Erzeugung von Bildern#off("b")#
+#type ("times8")#
+
+ Bilder entstehen in Objektion vom Datentyp #on("b")#PICTURE#off("b")#. Diese müssen mit der Prozedur
+ #on("i")#nilpicture#off("i")# initialisiert werden. Sie enthalten dann ein leeres Bild, dessen Dimension noch
+ nicht festgelegt ist. Die Dimension eines #on("i")#PICTURE#off("i")#s wird mit dem ersten Schreibzugriff
+ (#on("i")#move, draw#off("i")# o.ä.) festgelegt. Ein #on("i")#PICTURE#off("i")# kann immer nur entweder zwei- oder
+ dreidimensional sein.
+ Außerdem kann einem #on("i")#PICTURE#off("i")# mit der Prozedur #on("i")#pen#off("i")# genau ein virtueller Stift zugeord­
+ net oder der aktuelle Stift erfragt werden (Standardeinstellung: 1).
+
+ Für Erzeugung eines Bildes wird ein virtueller Zeichenstift benutzt, dem bei der Darstel­
+ lung jeweils genau ein realer Stift zugeordnet wird. Dieser Stift kann mit der Prozedur
+ #on("b")#move#off("b")# oder #on("b")#move r #off("b")#auf eine bestimmte Stelle positioniert werden ohne zu zeichnen. Mit
+ #on("b")#draw#off("b")# oder #on("b")#draw r#off("b")# wird eine Linie von der letzten Position zur angegebene Position
+ gezeichnet. Die aktuelle Stiftposition kann dabei mit #on("b")#where#off("b")# abgefragt werden.
+ Außerdem existiert noch die Prozedur #on("b")#draw#off("b")# die einen Text zur Beschriftung der Zeich­
+ nung darstellt, sowie #on("b")#bar#off("b")# zum Zeichnen eines Balkens für Balkendiagramme, #on("b")#circle#off("b")# zum
+ Zeichnen eines Kreisbogens für Kreisdiagramme und #on("b")#mark#off("b")# zum Markiern von Positionen.
+ Dabei wird die aktuelle Stiftposition aber nicht verändert.
+
+#type ("trium12")#
+#on("b")#3. Manipulation von PICTUREs#off("b")#
+#type ("times8")#
+
+ Erstellte PICTUREs können auch als Ganzes manipuliert werde. Dazu dienen die Prozedu­
+ ren #on("b")#translate, stretch#off("b")# und #on("b")#rotate#off("b")#. Es ist auch möglich mehrere PICTURE mit dem Opera­
+ tor #on("b")#CAT#off("b")# aneinanderzufügen, wenn beide PICTURE die gleiche Dimension haben. In
+ solcherart manipulierten Bildern kann ohne Einschränkung weitergezeichnet werden,
+ solange die maximale Größe nicht überschritten wird.
+
+#type ("trium12")#
+#on("b")#4. Darstellung und Speicherung #off("b")#
+#type ("times8")#
+
+ Für die Darstellung und Speicherung der erzeugten Bilder existiert der Typ #on("b")#PICFILE#off("b")#.
+ Dieser besteht aus eienm Datenraum mit max. 1024 PICTUREs, die mit den Prozeduren #on("b")#
+ delete picture, insert picture, read picture, write picture, get picture#off("b")# und #on("b")#put picture#off("b")# einge­
+ geben bzw. ausgegeben werden können.
+ Für die Positionierung innerhalb eines PICFILES stehen die Prozeduren #on("b")#to pic, up, down,
+ eof, picture no, pictures#off("b")# zur Verfügung.
+ Für die Assoziation mit einem benannten Datenraum existiert ähnlich wie beim Datentyp
+ FILE die Prozedur #on("b")#picture file#off("b")#; unbenannte Datenräume können mit dem Operator #on("b")#:=#off("b")#
+ assoziert werden.
+ Die Darstellung des PICFILES auf einem Zeichengerät erfolgt mit der Prozdur #on("b")#plot#off("b")#.
+ Da die Graphiken aber in #on("i")#Weltkoordinaten#off("i")# erzeugt werden und die spätere Darstellung
+ vollkommen unbeachtet bleibt, müssen gewisse Darstellungsparameter für die Zeichnung
+ gesetzt werden. Dies Parameter werden im PICFILE abgelegt und gelten jeweils für alle
+ darin enthaltenen PICTURE. Dadurch ist es möglich, einen PICFILE mit spezifierter
+ Darstellungsart über einen SPOOLER an einen Plotter zu senden oder die bei der letzten
+ Betrachtung gewählte Darstellung beizubehalten oder zu ändern.
+ Für die Darstellung können den virtuellen Stiften mit der Prozedur #on("b")#select pen#off("b")# reale Stifte
+ zugeordnet werden. Voreingestellt ist für alle virtuellen Stifte die Standardfarbe, Standard­
+ stärke und durchgängige Linie. Mit #on("b")#background#off("b")# kann eine bestimmte Hintergrundfarbe
+ gewählt werden.
+ Indem man einem PICTURE den Stift 0 zuordnet, kann man dieses auch Ausblenden
+ wenn es bei dieser Darstellung stört.
+ Die Größe der realen Zeichenfläche kann mit #on("b")#viewport#off("b")# eingestellt werden, wobei die
+ gesamte Zeichenfäche voreingestellt ist. Dadurch können auch mehrere PICFILE auf ein
+ Blatt oder einen Bildschirm gezeichnet werden, wenn man durch Angabe von #on("i")#background
+  (0)#off("i")# das Löschen der Zeichenfläche unterdrückt.
+
+
+#type ("trium12")#
+#on("b")#5. Darstellung zweidimensionaler Graphik#off("b")#
+#type ("times8")#
+
+ Bei der Darstellung zweidimensionaler Bilder muß der zu zeichnende Ausschnitt (das
+ #on("i")#Fenster#off("i")#) angegeben werden. Mit der Prozedur #on("b")#window#off("b")# wird durch Angabe der minimalen
+ und maximalen X- bzw. Y-Koordinaten ein Fenster definiert. Linien, die über dieses
+ Fenster hinausgehen, werden abgeschnitten. Dadurch kann man einen beliebigen Detailaus­
+ schnitt eines Bildes ausgeben, ohne das Bild neu generieren zu müssen.
+ Da das so definierte Fenster auf die mit #on("i")#viewport#off("i")# definierte Zeichenfläche abgebildet wird,
+ ist der Abbildungsmaßstab durch das Zusammenspiel von #on("i")#viewport#off("i")# und #on("i")#window#off("i")# bestimmt.
+ Wenn eine Winkeltreue Darstellung erreicht werdenn soll, muß das Verhältnis der durch
+ #on("i")#viewport#off("i")# eingestellten Breite und Höhe und das Verhältnis des durch #on("i")#window#off("i")# eingestellten
+ Ausschnitts gleich sein.
+
+#type ("trium12")#
+#on("b")#6. Darstellung dreidimensionaler Graphik#off("b")#
+#type ("times8")#
+
+ Bei dreidimensionalen Zeichnungen wird das Fenster ebenfalls mit #on("b")#window#off("b")# definiert,
+ wobei dann allerdings auch der Wertebereich der dritten Dimension (Z-Koordinaten) zu
+ berücksichtigen ist. Auch hierbei werden Linien, die über die spezifierte Darstellungs­
+ fläche hinausgehen abgeschnitten. Das Abschneiden erfolgt allerdings erst nach der Projek­
+ tion auf die Darstellungsfläche, so daß auch Vektoren zu sehen sind, die über das mit
+ #on("i")#window#off("i")# angegebene Quader hinausgehen, wenn ihre Projektion innerhalb der Zeichen­
+ fläche liegt.
+ Da die dreidimensionale Graphik auf eine zweidimensionale Fläche projeziert wird,
+ können aber noch weitere Darstellungsparameter angegeben werden. Der Betrachtungswin­
+ kel wird mit Hilfe der Prozedur #on("b")#view#off("b")# angegeben. Ebenfalls kann mit #on("b")#view#off("b")# der Winkel der
+ Y-Achse zur Horizontalen angegeben werden.
+ Zur Spezifikation der gewünschten Projektionsart existieren #on("b")#orthographic#off("b")# (orthographische
+ Projektion), #on("b")#perspective#off("b")# (perspektivische Projektion, der Fluchtpunkt ist frei wählbar) und
+ #on("b")#oblique#off("b")# (schiefwinklige Projektion).
+
+#page#
+#type ("trium12")#
+#on("b")#7. Beispiele#off("b")#
+#type ("times8")#
+
+ #on("u")#Sinuskurve#off("u")#
+
+#type("micro")#
+initialisiere picfile;
+zeichne überschrift;
+zeichne achsen;
+zeichne sinuskurve;
+wähle darstellung;
+plot (p) .
+
+initialisiere picfile:
+ PICFILE VAR p :: picture file ("SINUS") .
+
+zeichne überschrift:
+ PICTURE VAR überschrift :: nilpicture;
+ move (überschrift, -pi/2.0, 1.0);
+ draw (überschrift, "sinus (x) [-pi, +pi]", 0.0, 1.0, 0.6);
+ put picture (p, überschrift) .
+
+ zeichne achsen:
+ PICTURE VAR achsen :: nilpicture;
+ zeichne x achse;
+ zeichne y achse;
+ put picture (p, achsen) .
+
+ zeichne x achse:
+ move (achsen, -pi, 0.0);
+ draw (achsen, pi, 0.0) .
+
+ zeichne y achse:
+ move (achsen, 0.0, -1.0);
+ draw (achsen, 0.0, +1.0) .
+
+ zeichne sinuskurve:
+ PICTURE VAR sinus :: nilpicture;
+ REAL VAR x :: -pi;
+
+ move (sinus, x, sin (x));
+ REP x INCR 0.1;
+ draw (sinus, x, sin (x))
+ UNTIL x >= pi PER;
+
+ put picture (p, sinus) .
+
+ wähle darstellung:
+ window (p, -pi, pi, -1.0, 1.3);
+ viewport (p, 0.0, 0.0, 0.0, 0.0) .
+
+#page#
+#type ("times8")#
+ #on("u")#Achsenkreuz#off("u")#
+
+#type("micro")#
+initialisiere picfile;
+zeichne die x achse;
+zeichne die y achse;
+zeichne die z achse;
+stelle das achsenkreuz dar .
+
+initialisiere picfile:
+ PICFILE VAR p :: picture file ("KREUZ") .
+
+ zeichne die x achse:
+ PICTURE VAR x achse := nilpicture;
+ move (x achse, -1.0, 0.0, 0.0);
+ draw (x achse, "-X", 0.0, 0.0, 0.0);
+ draw (x achse, 1.0, 0.0, 0.0);
+ draw (x achse, "+X", 0.0, 0.0, 0.0);
+ put picture (p, x achse) .
+
+ zeichne die y achse:
+ PICTURE VAR y achse := nilpicture;
+ move (y achse, 0. 0, -1.0, 0.0);
+ draw (y achse, "-Y", 0.0, 0.0, 0.0);
+ draw (y achse, 0.0, 1.0, 0.0);
+ draw (y achse, "+Y", 0.0, 0.0, 0.0);
+ put picture (p, y achse) .
+
+ zeichne die z achse:
+ PICTURE VAR z achse := nilpicture;
+ move (z achse, 0. 0, 0.0, -1.0);
+ draw (z achse, "-Z", 0.0, 0.0, 0.0);
+ draw (z achse, 0.0, 0.0, 1.0);
+ draw (z achse, "+Z", 0.0, 0.0, 0.0);
+ put picture (p, z achse) .
+
+ stelle das achsenkreuz dar:
+ viewport (p, 0. 0, 1.0, 0.0, 1.0);
+ window (p, -1.1, 1.1, -1.1, 1.1);
+ oblique (p, 0.25, 0.15);
+ plot (p) .
+
+#foot#
+ #type("times6")#
+ Diese beiden Beispielprogramme befinden sich ebenfalls auf dem STD-Archive unter dem Namen #on("i")#Beispiel.Sinus#off("i")# und
+ #on("i")#Beispiel.Kreuz#off("i")#.
+#end#
+
+#page#
+#type ("triumb14")# Beschreibung der Graphik-Prozeduren
+#type ("times8")#
+
+
+#type ("trium12")#
+#on("b")#1. PICTURE-Prozeduren#off("b")#
+#type ("times8")#
+
+#limit (7.0)##type("times6")#
+ #on("i")#Zweidimensionale PICTURES brauchen weniger Speicherplatz
+ als dreidimensionale. Daher werden in einigen Fehlermeldungen
+ unterschiedliche Größen angegeben.
+
+#limit (11.0)##type("times8")#
+
+#type("times10")##on("b")#:=#off("b")##type("times8")#
+ OP := (PICTURE VAR l, PICTURE CONST r)
+ Zweck: Zuweisung
+
+#type("times10")##on("b")#CAT#off("b")##type("times8")#
+ OP CAT (PICTURE VAR l, PICTURE CONST r)
+ Zweck: Aneinanderfügen von zwei PICTURE.
+ Fehlerfälle:
+ * left dimension <> right dimension
+ Es können nur PICTURE mit gleicher Dimension angefügt werden.
+ * Picture overflow
+ Die beiden PICTURE überschreiten die maximale Größe eines PICTURE.
+
+#type("times10")##on("b")#nilpicture#off("b")##type("times8")#
+ PICTURE PROC nilpicture
+ Zweck: Die Prozedur liefert ein leeres PICTURE zur Initialisierung.
+
+ PICTURE PROC nilpicture (INT CONST pen)
+ Zweck: Die Prozedur liefert ein leeres PICTURE mit dem Stift #on("i")#pen#off("i")# zur Initialisierung.
+
+#type("times10")##on("b")#draw#off("b")##type("times8")#
+ PROC draw (PICTURE VAR p, TEXT CONST text, REAL CONST angle, height, ­
+ width)
+ Zweck: Der angegebene Text wird unter dem Winkel #on("i")#angle#off("i")# gegenüber der Waagerech­
+ ten mit der Zeichenhöhe #on("i")#hight#off("i")# und der Breite #on("i")#width#off("i")# gezeichnet. #on("i")#angle#off("i")# wird in
+ Winkelgrad angegeben. #on("i")#height#off("i")# und #on("i")#width#off("i")# werden in #on("i")#Prozenten#off("i")# der Breite bzw.
+ Höhe der Zeichenfläche angegeben, bei 0 wird
+ die Standardhöhe- und breite angenommen.
+ Der Anfang ist dabei die aktuelle Stiftposition, die nicht verändert wird. Es könne
+ auch die Steuerzeichen ""1"", ""2"", ""3"", ""10"", ""13"" benutzt werden,
+ wobei sie immer in der Richtung #on("i")#angle#off("i")# wirken.
+ Fehlerfälle:
+ * Picture overflow
+ Der Text paßt nicht mehr in das PICTURE.
+
+#type("times10")##on("b")#draw#off("b")##type("times8")#
+ PROC draw (PICTURE VAR p, REAL CONST x, y, z)
+ Zweck: Zeichnen einer Linie von der aktuellen Position zur Position (x, y, z).
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is two dimensional
+
+ PROC draw (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Zeichnen einer Linie von der aktuellen Position zur Position (x, y).
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+#type("times10")##on("b")#draw r#off("b")##type("times8")#
+ PROC draw r (PICTURE VAR p, REAL CONST x, y, z)
+ Zweck: Zeichnen einer Linie der Länge (x, y, z) relativ zur aktuellen Position.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is two dimensional
+
+ PROC draw r (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Zeichnen einer Linie der Länge (x, y) relativ zur aktuellen Position.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+#type("times10")##on("b")#move#off("b")##type("times8")#
+ PROC move (PICTURE VAR p, REAL CONST x, y, z)
+ Zweck: Die aktuelle Position wird auf (x, y, z) gesetzt.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is two dimensional
+
+ PROC move (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Die aktuelle Position wird auf (x, y) gesetzt.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+#type("times10")##on("b")#move r#off("b")##type("times8")#
+ PROC move r (PICTURE VAR p, REAL CONST x, y, z)
+ Zweck: Die aktuelle Position wird um (x, y, z) erhöht.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is two dimensional
+
+ PROC move r (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Die aktuelle Position wird um (x, y) erhöht.
+ Position.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+
+#type("times10")##on("b")#bar#off("b")##type("times8")#
+ PROC bar (PICTURE VAR p, REAL CONST width, hight, INT CONST pattern):
+ Zweck: Die Prozedur zeichnet an der aktuellen Position einen Balken mit dem Muster
+ #on("i")#pattern#off("i")#:
+ 0 = Leerer Balken
+ 1 = Gepunkteter Balken
+ 2 = Gefüllter Balken
+ 3 = Horizontale Linien
+ 4 = Vertikale Linien
+ 5 = Gekreuzte Linien
+ 6 = Diagonale Linien von Links nach Rechts
+ 7 = Diagonale Linien von Rechts nach Links
+ 8 = Gekreuzte diagonale Linien
+ > 8 = nicht normiertes Sondermuster
+ Die aktuelle Stiftposition wird dabei nicht verändert.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+ PROC bar (PICTURE VAR p, REAL CONST from, to, hight, INT CONST pattern):
+ Zweck: Die Prozedur zeichnet einen Balken von der Position #on("i")#from#off("i")# zur Position #on("i")#to#off("i")# und der
+ Höhe #on("i")#height#off("i")# mit dem Muster #on("i")#pattern#off("i")#.
+ s.o.
+
+#type("times10")##on("b")#circle#off("b")##type("times8")#
+ PROC circle (PICTURE VAR p, REAL CONST radius, from, to, INT CONST pattern)
+ Zweck: Die Prozedur zeichnet an der aktuellen Position ein Kreissegment vom Winkel
+ #on("i")#from#off("i")# bis #on("i")#to#off("i")# (im Gradmaß) mit dem Muster #on("i")#pattern#off("i")# (s.o.). Der #on("i")#radius#off("i")# wird in
+ Prozenten der Diagonalen der Zeichenfläche angegeben.
+ Die aktuelle Stiftposition wird dabei nicht verändert. Dieses Kreissegment ist in
+ jedem Fall 2-dimensional, so das es durch Drehungen nicht verändert wird.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+#type("times10")##on("b")#mark#off("b")##type("times8")#
+ PROC mark (PICTURE VAR p, REAL CONST size, INT CONST no)
+ Zweck: Es wird ein Marker mit der Größe #on("i")#size#off("i")# in Prozenten der Diagonalen der Zeichen­
+ fläche an der aktuellen Stiftposition ausgegeben, ohne diese zu verändern. Es
+ sollten dabei mindestens 10 verschiedene Marker gewählt werden können.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+
+#type("times10")##on("b")#dim#off("b")##type("times8")#
+ INT PROC dim (PICTURE CONST pic)
+ Zweck: Liefert die Dimension eines PICTURE.
+
+#type("times10")##on("b")#pen#off("b")##type("times8")#
+ INT PROC pen (PICTURE CONST p)
+ Zweck: Liefert den virtuellen Stift des PICTURE
+
+ PICTURE PROC pen (PICTURE CONST p, INT CONST pen)
+ Zweck: Setzen des (virtuellen) Stiftes eines PICTURE.
+ Bei #on("i")#pen#off("i")# = 0 wird das Picture nicht gezeichnet.
+ Fehlerfälle:
+ * pen out of range
+ Der gewünschte Stift ist kleiner als 0 oder größer als 16.
+
+#type("times10")##on("b")#extrema#off("b")##type("times8")#
+ PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y max)
+ Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICTURE.
+ Fehlerfälle:
+ * Picture is three dimensional
+
+ PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y max,  
+ z min, z max)
+ Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICTURE.
+ Fehlerfälle:
+ * Picture is two dimensional
+
+#type("times10")##on("b")#where#off("b")##type("times8")#
+ PROC where (PICTURE CONST p, REAL VAR x, y, z)
+ Zweck: Die Prozedur liefert die aktuelle Stiftposition.
+ Fehlerfälle:
+ * Picture is two dimensional
+
+ PROC where (PICTURE CONST p, REAL VAR x, y, z)
+ Zweck: Die Prozedur liefert die aktuelle Stiftposition. Fehlerfälle:
+ * Picture is three dimensional
+
+#type("times10")##on("b")#rotate#off("b")##type("times8")#
+ PROC rotate (PICTURE VAR p, REAL CONST angle)
+ Zweck: Das PICTURE wird um den Punkt (0, 0) um den Winkel #on("i")#angle#off("i")# (im Gradmaß) im
+ mathematisch positiven Sinn gedreht.
+
+ PROC rotate (PICTURE CONST p, REAL CONST phi, theta, lambda)
+ Zweck: Das PICTURE wird um den Winkel #on("i")#lambda#off("i")# um die Drehachse #on("i")#(phi, theta)#off("i")# ge­
+ dreht.
+
+#type("times10")##on("b")#stretch#off("b")##type("times8")#
+ PROC stretch (PICTURE VAR pic, REAL CONST sx, sy)
+ Zweck: Das PICTURE wird in X-Richtung um den Faktor #on("i")#sx#off("i")#, in Y-Richtung um den
+ Faktor #on("i")#sy#off("i")# gestreckt (bzw. gestaucht). Dabei bewirkt der Faktor
+ s > 1 eine Streckung
+ 0 < s < 1 eine Stauchung
+ s < 0 zusätzlich eine Achsenspiegelung.
+ Fehlerfälle:
+ * Picture is three dimensional
+
+ PROC stretch (PICTURE VAR p, REAL CONST sx, sy, sz)
+ Zweck: s. o.
+ Fehlerfälle:
+ * Picture is two dimensional
+
+#type("times10")##on("b")#translate#off("b")##type("times8")#
+ PROC translate (PICTURE VAR p, REAL CONST dx, dy)
+ Zweck: Das PICTURE wird um #on("i")#dx#off("i")# und #on("i")#dy#off("i")# verschoben. Fehlerfälle:
+ * Picture is three dimensional
+
+ PROC translate (PICTURE VAR p, REAL CONST dx, dy, dz)
+ Zweck: Das PICTURE wird um #on("i")#dx, dy#off("i")# und #on("i")#dz#off("i")# verschoben. Fehlerfälle:
+ * Picture is two dimensional
+
+
+#type ("trium12")#
+#on("b")#2. PICFILE-Prozeduren#off("b")#
+#type ("times8")#
+
+#type("times10")##on("b")#plot#off("b")##type("times8")#
+ PROC plot (TEXT CONST name)
+ Zweck: Der PICFILE mit dem Namen #on("i")#name#off("i")# wird entsprechend der angegebenen Dar­
+ stellungsart gezeichnet. Diese Parameter (#on("i")#perspective, orthographic, oblique, view,
+ window etc.#off("i")#) müssen vorher eingestellt werden.
+ Fehlerfälle:
+ * PICFILE does not exist
+ Es existiert kein PICFILE mit dem Namen #on("i")#name#off("i")#
+
+ PROC plot (PICFILE VAR p)
+ Zweck: Der PICFILE #on("i")#p#off("i")# wird entsprechend der angegebenen Darstellungsart gezeichnet.
+ Diese Parameter müssen vorher eingestellt werden:
+
+ #on("b")#zweidimensional:#off("b")#
+ obligat: #on("i")#window#off("i")# (zweidimensional)
+ optional: #on("i")#view#off("i")# (zweidimensional)
+ #on("i")#viewport#off("i")#
+ #on("i")#select pen#off("i")#
+
+ #on("b")#dreidimensional:#off("b")#
+ obligat: #on("i")#window#off("i")# (dreidimensional)
+ optional: #on("i")#view#off("i")# (dreidimensional)
+ #on("i")#orthographic | perspective | oblique#off("i")#
+ #on("i")#viewport#off("i")#
+ #on("i")#select pen#off("i")#
+
+
+#type("times10")##on("b")#select pen#off("b")##type("times8")#
+ PROC select pen (PICFILE VAR p, INT CONST pen, colour, thickness, line type)
+ Zweck: Für die Darstellung des Bildes #on("i")#p#off("i")# soll dem #on("i")#virtuellen#off("i")# Stift #on("i")#pen#off("i")# ein realer Stift
+ zugeordnet werden, der möglichst die Farbe #on("i")#colour#off("i")# und die Dicke #on("i")#thickness#off("i")# hat
+ und dabei Linien mit dem Typ #on("i")#line type#off("i")# zeichnet. Es wird die beste Annäherung
+ für das Ausgabegerät genommen.
+ Dabei gelten folgende Vereinbarungen:
+
+ #on("b")#Farbe:#off("b")# Negative Farben werden XOR gezeichnet (dunkel wird hell und hell wird
+ dunkel), Farbe 0 ist der Löschstift und positive Farben überschreiben
+ (ersetzen) den alten Punkt mit folgenden Werten:
+
+ 1 Standardfarbe des Endgerätes
+ 2 rot
+ 3 blau
+ 4 grün
+ 5 schwarz
+ 6 weiß
+ > 6 nicht normierte Sonderfarben
+
+
+ #on("b")#Dicke:#off("b")# 0 Standardstrichstärke des Endgerätes
+ > 0 Strichstärke in 1/10 mm.
+
+
+ #on("b")#Linientyp:#off("b")#
+ 0 keine sichtbare Linie
+ 1 durchgängige Linie
+ 2 gepunktete Linie
+ 3 kurz gestrichelte Linie
+ 4 lang gestrichelte Linie
+ 5 Strichpunktlinie
+ > 5 nicht normierte Linie
+
+
+ Die hier aufgeführten Möglichkeiten müssen nicht an allen graphischen Endge­
+ räten vorhanden sein. Der geräteabhängige Graphik-Treiber wählt jeweils die
+ bestmögliche Annäherung.
+
+ Fehlerfälle:
+ * pen out of range
+ #on("i")#pen#off("i")# muss im Bereich 1-16 sein.
+
+#type("times10")##on("b")#background#off("b")##type("times8")#
+ PROC background (PICFILE VAR p, INT CONST colour)
+ Zweck: Der Hintergrund wird auf die Farbe #on("i")#colour#off("i")# (s.o.) gesetzt wenn möglich.
+ Bei der Angabe #on("i")#background (p, 0)#off("i")# wird das Löschen des Bildschirms unterdrückt,
+ so daß das Zeichen mehrerer PICFILE auf einem Blatt möglich wird.
+
+ INT PROC background (PICFILE CONST p):
+ Zweck: Liefert die eingestellte Hintergrundfarbe.
+
+#type("times10")##on("b")#view#off("b")##type("times8")#
+ PROC view (PICFILE VAR p, REAL CONST alpha)
+ Zweck: Setzt den Winkel der Y-Achse zur Senkrechten auf #on("i")#alpha#off("i")# Grad, falls diese nicht
+ senkrecht auf der Betrachtungsebene steht.
+
+ PROC view (PICFILE VAR p, REAL CONST phi, theta)
+ Zweck: Dreidimensionale Bilder werden häufig nicht direkt von vorne dargestellt, son­
+ dern für die Betrachtung gedreht. Mit der Prozedur #on("i")#view#off("i")# kann die Betrachtungs­
+ richtung durch die Polarwinkel #on("i")#phi#off("i")# und #on("i")#theta#off("i")# (im Gradmass) angegeben werden.
+ Voreingestellt ist #on("i")#phi#off("i")# = 0 und #on("i")#theta#off("i")# = 0, d.h. senkrecht von oben (Die #on("i")#X-
+ Achse#off("i")# bildet die Horizontale und die #on("i")#Y-Achse#off("i")# bildet die Vertikale).
+ Im Gegensatz zu #on("i")#rotate#off("i")# hat #on("i")#view#off("i")# keine Wirkung auf das eigentliche Bild (die
+ PICTURE werden nicht verändert), sondern nur auf die gewählte Darstellung. So
+ addieren sich zwar aufeinanderfolgende #on("i")#Rotationen#off("i")#, #on("i")#view#off("i")# aber geht immer von der
+ Nullstellung aus. Auch kann das Bild durch eine #on("i")#Rotation#off("i")# ganz oder teilweise aus
+ oder in das Darstellungsfenster (#on("i")#window#off("i")# gedreht werden. Bei #on("i")#view#off("i")# verändern sich
+ die Koordinaten der Punkte nicht, d. h. das Fenster wird mitgedreht.
+
+ PROC view (PICFILE VAR p, REAL CONST x, y, z)
+ Zweck: Wie oben, nur werden die Winkel nicht in Polarkoordinaten angegeben, sondern
+ es wird die Blickrichtung als Vektor in Karthesischen Koordinaten angegeben.
+ (Der Betrachtungsvektor muß nicht normiert sein).
+
+#type("times10")##on("b")#viewport#off("b")##type("times8")#
+ PROC viewport (PICFILE VAR p, REAL CONST hormin, hormax, vertmin, vertmax)
+ Zweck: Die Zeichenfläche auf dem Endgerät, auf dem das Bild dargestellt werden soll,
+ wird spezifiziert. Dabei wird sowohl die Größe als auch die relative Lage der
+ Zeichenfläche definiert. Der linke untere Eckpunkt der physikalischen Zeichen­
+ fläche des Gerätes hat die Koordinaten (0, 0). Die definierte Zeichenfläche er­
+ streckt sich
+
+ #on("i")#hormin - hormax#off("i")# in der Horizontalen,
+ #on("i")#vertmin - vertmax#off("i")# in der Vertikalen.
+
+ So liegt der linke untere Eckpunkt dann bei (#on("i")#hormin, hormax#off("i")#), der rechte obere
+ Eckpunkt bei (#on("i")#hormax, vertmax#off("i")#).
+
+ Damit sowohl geräteunabhängige als auch maßstabgetreue Zeichnungen möglich
+ sind, können die Koordinaten in drei Arten spezifiziert werden:
+ a) #on("b")#Gerätekoordinaten#off("b")#
+ Die Koordinaten können Werte von 0.0 bis 2.0 annehmen. Dabei hat die
+ kürzere Seite der physikalischen Zeichenfläche definitionsgemäß die Länge
+ 1.0.
+ b) #on("b")#Absolute Koordinaten#off("b")#
+ Die Werte werden in #on("i")#cm#off("i")# angegeben. Dabei müssen die Maximalwerte aber
+ größer als 2.0 sein, da sonst Fall a) angenommen wird.
+ c) #on("b")#Maximale Zeichenfläche#off("b")# Bei der Angabe (0.0, 0.0, 0.0, 0.0) wird die maxi­
+ male physikalische Zeichenfläche eingestellt.
+
+ Voreingestellt ist
+ viewport (0.0, 0.0, 0.0, 0.0)
+ d.h. die größtmögliche physikalische Zeichenfläche, beginnend mit der linken
+ unteren Ecke.
+ Der Abbildungsmaßstab wird durch das Zusammenspiel von #on("i")#viewport#off("i")# und
+ #on("i")#window#off("i")# festgelegt (s. dort). Dabei ist insbesondere darauf zu achten, daß winkel­
+ treue Darstellung nur bei gleichen Verhältnissen von X-Bereich und Breite bzw.
+ von Y-Bereich und Höhe möglich ist.
+
+
+#type("times10")##on("b")#window#off("b")##type("times8")#
+ PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max)
+ Zweck: Für die Darstellung eines zweidimensionalen Bildes wird das darzustellende
+ Fenster definiert. Alle Bildpunkte, deren X-Koordinaten im Intervall [#on("i")#x min, x
+ max#off("i")#] und deren Y-Koordinaten im Bereich [#on("i")#y min, y max#off("i")#] liegen, gehören zum
+ definierten Fenster.Vektoren, die außerhalb dieses Fensters liegen, gehen über die
+ durch #on("i")#viewport#off("i")# Fläche hinaus und werden abgeschnitten.
+
+ Der Darstellungsmaßstab ergibt sich als
+
+ #ub#               x max - x min               #ue#
+ horizontale Seitenlänge der Zeichenfläche
+
+
+ #ub#               y max - y min               #ue#
+ vertikale Seitenlänge der Zeichenfläche
+
+ PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max,  
+ z min, z max)
+
+ Zweck: Für die darstellung eines dreidimensionalen Bildes wird das darzustellende Fenster
+ definiert. Alle Bildpunkte, deren X-Koordinaten im Intervall [#on("i")#x min, x max#off("i")#],
+ deren Y-Koordinaten im Bereich [#on("i")#y min, y max#off("i")#] und deren Z-Koordinaten im
+ Bereich [#on("i")#z min, z max#off("i")#] liegen, gehören zum definierten Fenster. Dieses dreidi­
+ mensionale Fenster (#on("i")#Quader#off("i")#) wird entsprechend der eingestellten Projektionsart
+ (orthographisch, perspektivisch oder schiefwinklig) und den Betrachtungswinkeln
+ (s. #on("i")#view#off("i")#) auf die spezifizierte Zeichenfläche abgebildet.
+ Anders als im zweidimensionalen Fall ist das Problem der Maßstaäbe nicht mehr
+ nur durch das Zusammenspiel von #on("i")#window#off("i")# und #on("i")#viewport#off("i")# zu beschreiben. Hier
+ spielen auch die Projektionsart und Darstellungswinkel herein.
+
+#type("times10")##on("b")#oblique#off("b")##type("times8")#
+ PROC oblique (PICFILE VAR p, REAL CONST a, b)
+ Zweck: Bei dem (dreidimensionalen) Bild #on("i")#p#off("i")# wird #on("u")#schiefwinklig#off("u")# als gewünschte Projek­
+ tionsart eingestellt. Dabei ist (#on("i")#a, b#off("i")#) der Punkt auf der X-Y-Ebene, auf den der
+ EinheitsVektor der Z-Richtung abgebildet werden soll.
+
+#type("times10")##on("b")#orthographic#off("b")##type("times8")#
+ PROC orthographic (PICFILE VAR p)
+ Zweck: Bei dem (dreidimensionalen) Bild #on("i")#p#off("i")# wird #on("u")#orthographisch#off("u")# als gewünschte Projek­
+ tionsart eingestellt. Bei der orthographischen Projektion wird ein dreidimensio­
+ naler Körper mit parallelen Strahlen senkrecht auf der Projektionsebene abge­
+ bildet.
+
+#type("times10")##on("b")#perpective#off("b")##type("times8")#
+ PROC perspective (PICFILE VAR p, REAL CONST cx, cy, cz)
+ Zweck: Bei dem (dreidimensionalen) Bild #on("i")#p#off("i")# wird #on("u")#perspektivisch#off("u")# als gewünschte Projek­
+ tionsart eingestellt. Der Punkt (#on("i")#cx, 1/cy, cz#off("i")#) ist der Fluchtpunkt der Projektion,
+ d. h. alle Parallen zur Z-Achse schneiden sich in diesem Punkt.
+
+#type("times10")##on("b")#extrema#off("b")##type("times8")#
+ PROC extrema (PICFILE VAR p, REAL VAR x min, x max, y min, y max)
+ Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICFILE.
+
+ PROC extrema (PICFILE VAR p, REAL VAR x min,x max,y min,y max,z min,z max)
+ Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICFILE.
+
+#type ("trium12")#
+#on("b")#3. Prozeduren zur Manipulation von PICFILE#off("b")#
+#type("times 8")#
+
+#type("times10")##on("b")#:=#off("b")##type("times8")#
+ OP := (PICFILE VAR l, PICFILE CONST r)
+ Zweck: Zuweisung des PIFILEs #on("i")#r#off("i")# an das PICFILE #on("i")#l#off("i")#
+
+ OP := (PICFILE VAR p, DATASPACE CONST d)
+ Zweck: Assoziert die PICFILE Variable #on("i")#p#off("i")# mit dem Datenraum #on("i")#d#off("i")# und initialisiert die
+ Variable, wenn nötig.
+ Fehlerfälle:
+ * dataspace is no PICFILE
+ Der anzukoppelnde Datenraum hat einen unzulässigen Typ
+
+#type("times10")##on("b")#picture file#off("b")##type("times8")#
+ DATASPACE PROC picture file (TEXT CONST name)
+ Zweck: Assoziaten eines benannten Datenraumes mit einem PICFILE (s.o.).
+
+#type("times10")##on("b")#to pic#off("b")##type("times8")#
+ PROC to pic (PICFILE VAR p, INT CONST pos)
+ Zweck: Positioniert auf das PICTURE Nummer #on("i")#pos#off("i")#.
+ Fehlerfälle:
+ * Position underflow
+ Es wurde eine Position kleiner Null angegeben.
+ * Position after eof
+ Es wurde versucht, hinter das Ende eines PICFILE zu positionieren. Die letzte
+ erlaubte Position ist #on("i")#pictures (p)+1#off("i")#.
+
+#type("times10")##on("b")#up#off("b")##type("times8")#
+ PROC up (PICFILE VAR p)
+ Zweck: Positioniert genau ein PICTURE zurück.
+ Fehlerfall:
+ * Position underflow
+ Es wurde versucht, vor das erste PICTURE zu positionieren
+
+ PROC up (PICFILE VAR p, INT CONST n)
+ Zweck: Positioniert genau #on("i")#n#off("i")# Picture zurück.
+ Fehlerfall:
+ * Position underflow
+ Es wurde versucht, vor das erste PICTURE zu positionieren
+
+#type("times10")##on("b")#down#off("b")##type("times8")#
+ PROC down (PICFILE VAR p)
+ Zweck: Positioniert genau ein PICTURE vorwärts.
+ Fehlerfall:
+ * Position after eof
+ Es wurde versucht, hinter das Ende eines PICFILE zu positionieren. Die letzte
+ erlaubte Position ist #on("i")#pictures (p)+1#off("i")#.
+
+ PROC down (PICFILE VAR p, INT CONST n)
+ Zweck: Positioniert genau #on("i")#n#off("i")# Picture vorwärts.
+ Fehlerfall:
+ * Position after eof
+ Es wurde versucht, hinter das Ende eines PICFILE zu positionieren Die letzte
+ erlaubte Position ist #on("i")#pictures (p)+1#off("i")#.
+
+#type("times10")##on("b")#delete picture#off("b")##type("times8")#
+ PROC delete picture (PICFILE VAR p)
+ Zweck: Löscht das aktuelle PICTURE
+
+#type("times10")##on("b")#insert picture#off("b")##type("times8")#
+ PROC insert picture (PICFILE VAR p)
+ Zweck: Fügt ein PICTURE #on("u")#vor#off("u")# der aktuellen Position ein.
+
+#type("times10")##on("b")#read picture#off("b")##type("times8")#
+ PROC read picture (PICFILE CONST p, PICTURE VAR pic)
+ Zweck: Liest das aktuelle PICTURE.
+
+#type("times10")##on("b")#write picture#off("b")##type("times8")#
+ PROC write picture (PICFILE VAR p, PICTURE CONST pic)
+ Zweck: Schreibt das PICTURE #on("i")#pic#off("i")# auf der aktuellen Position.
+
+#type("times10")##on("b")#put picture#off("b")##type("times8")#
+ PROC put picture (PICFILE VAR p, PICTURE CONST pic)
+ Zweck: Schreibt das PICTURE #on("i")#pic#off("i")# an die aktuelle Position und erhöht diese um 1.
+
+#type("times10")##on("b")#get picture#off("b")##type("times8")#
+ PROC get picture (PICFILE VAR p, PICTURE VAR pic)
+ Zweck: Liest das PICTURE #on("i")#pic#off("i")# an dir aktuellen Position und erhöht diese um 1.
+
+#type("times10")##on("b")#eof#off("b")##type("times8")#
+ BOOL PROC eof (PICFILE CONST p)
+ Zweck: Liefert genau dann #on("i")#TRUE#off("i")#, wenn das Ende eines PICFILE erreicht ist.
+
+#type("times10")##on("b")#picture no#off("b")##type("times8")#
+ INT PROC picture no (PICFILE CONST p)
+ Zweck: Liefert die Nummer des aktuellen PICTURE.
+
+#type("times10")##on("b")#pictures#off("b")##type("times8")#
+ INT PROC pictures (PICFILE CONST p)
+ Zweck: Liefert die Anzahl PICTURE eines PICFILE.
+
+
+#page#
+#type ("trium12")#
+#on("b")#4. Auslieferungsumfang#off("b")#
+#type ("times8")#
+
+ Die EUMEL-GRAPHIK wird auf einer Diskette mit folgendem Inhalt ausgeliefert.
+ Archive #on("i")#Graphik#off("i")#:
+
+ "gen Graphik"
+ "gen Plotter"
+ "GRAPHIK.book"
+ "GRAPHIK.Picfile"
+ "GRAPHIK.Transform"
+ "GRAPHIK.Plot"
+ "GRAPHIK.Plotter"
+ "GRAPHIK.Server"
+ "GRAPHIK.vektor plot"
+ "ZEICHENSATZ"
+ "PC.plot"
+ "HP7475.plot"
+ "Beispiel.Kreuz"
+ "Beispiel.Sinus"
+
+
+
+ #on("u")#Dateiinhalte#off("u")#
+
+ 1. "gen Graphik" Installationsprogramm für Terminals
+ 2. "gen Plotter" Installationsprogramm für Plotter
+ 3. "GRAPHIK.book" enthält diese Beschreibung.
+ 4. "GRAPHIK.Picfile" enthält die Pakete #on("i")#picture#off("i")# und #on("i")#picfile#off("i")#.
+ 5. "GRAPHIK.Transform" stellt das Paket #on("i")#transformation#off("i")# zur Verfügung, in dem
+ interne Prozeduren zur Projektion definiert werden.
+ 6. "GRAPHIK.Plot" definiert die Prozedur #on("i")#plot#off("i")# zur Darstellung eines
+ PICFILES auf dem Terminal
+ 7. "GRAPHIK.Plotter" definiert die Prozedur #on("i")#plotter#off("i")# zur Darstellung eines
+ PICFILES auf dem Plotter
+ 8. "GRAPHIK.Server" Server für einen Plotter-Spool
+ 9. "GRAPHIK.vektor plot" enthält Hilfsprogramme, die bei der Erstellung einer
+ eigenen Terminalanpassung benutzt werden können.
+ 10. "ZEICHENSATZ" enthält einen Zeichensatz für Terminals die im Graphik
+ Modus keinen Text ausgeben können.
+ 11. "PC.plot" Terminalanpassung für IBM-PC und ähnliche.
+ 12. "HP7475.plot" Terminalanpassung für HP7474-Plotter und Geräte mit
+ HP-GL.
+ 13. "Beispiel.Kreuz" Beispielprogramm
+ 14. "Beispiel.Sinus" Beispielprogramm
+
+#type ("trium12")#
+#on("b")#5. Installation#off("b")#
+#type ("times8")#
+
+
+ In der Datei #on("i")#gen Graphik#off("i")# ist ein Installationspragramm enthalten. Nach dem Starten des
+ Programms mit #on("i")#run ("gen Graphik")#off("i")# fragt es nach dem Dateinamen der Terminalanpas­
+ sung.
+ Steht keine Terminalanpassung für ein Endgerät zur Verfügung (und kann auch nicht
+ beschafft werden) so kann man durch Insertieren der Datei #on("i")#GRAPHIK.Picfile#off("i")# lediglich die
+ Leistungen der Pakete #on("i")#Picture#off("i")# und #on("i")#Picfile#off("i")# nutzen, ohne die erzeugten Graphiken darstellen
+ zu können.
+ Zur Benutzung eines #on("i")#Plotters#off("i")# über einen Spooler wird die Datei #on("i")#gen Plotter#off("i")# gestartet.
+
+
+ Beispiel:
+ 1. archive ("Graphik")
+ 2. fetch all (archive)
+ 3. release (archive)
+ 4. run ("gen Graphik")
+ <-- PC.Plot
+
+
+#type ("trium12")#
+#on("b")#6. Besonderheiten der PC.plot-Anpassung#off("b")#
+#type ("times8")#
+
+
+ Da der IBM-PC verschiedene Graphik- und Text-Modi kennt, wird durch das Pro­
+ gramm #on("i")#PC.plot#off("i")# die Prozedur #on("i")#graphik#off("i")# zusätzlich zur Verfügung gestellt. Sie erlaubt es den
+ PC in verschiedenen Graphik-Modi zu betreiben.
+
+ PROC graphik (INT CONST modus, pause)
+
+ Modus: 0 --- Keine Graphik (normaler Textmodus)
+ 1 --- hochauflösende Graphik, 50 Zeilen,
+ 640 * 400 Punkte, einfarbig
+ 2 --- hochauflösende Graphik, 25 Zeilen,
+ 640 * 400 Punkte, einfarbig
+ 3 --- mittlere Auflösung, 640 * 200 Punkte, 3 Farben
+ 4 --- IBM-PC Auflösung, 320 * 200 Punkte, 3 Farben.
+
+ Pause: Da der PC bei #on("i")#end plot#off("i")# wieder in den Normalmodus umschaltet und die Graphik
+ dann nicht mehr zu sehen ist, kann man eine #on("i")#pause#off("i")# angeben. Die hier eingestellte
+ Zeit ist aber nicht die Länge der Pause, sondern der Kehrwert der Blinkfrequenz
+ proportional.
+
+
diff --git a/doc/graphic/graphik beschreibung b/doc/graphic/graphik beschreibung
new file mode 100644
index 0000000..53ebe49
--- /dev/null
+++ b/doc/graphic/graphik beschreibung
@@ -0,0 +1,661 @@
+#type ("basker12")##limit (16.0)##block#
+
+#head#
+#type ("triumb18")#
+#center#EUMEL-Grafik-System
+#type ("basker12")#
+#end#
+ #on("italics")#gescheit, gescheiter,
+ gescheitert#off("italics")#
+
+#type ("basker14")#
+#on("bold")#Beschreibung der Graphik-Prozeduren#off("bold")#
+#type ("basker12")#
+
+ #on("italics")#Zweidimensionale PICTURE brauchen weniger Speicherplatz als dreidimen­
+ sionale. Daher werden in einigen Fehlermeldungen unterschiedliche Größen
+ angegeben.#off("italics")#
+
+#on("underline")#Picture-Prozeduren#off("underline")#
+PICTURE
+
+
+:=
+ OP := (PICTURE VAR l, PICTURE CONST r)
+ Zweck: Zuweisung
+
+CAT
+ OP CAT (PICTURE VAR l, PICTURE CONST r)
+ Zweck: Aneinanderfügen von zwei PICTURE.
+ Fehlerfälle:
+ * left dimension <> right dimension
+ Es können nur PICTURE mit gleicher Dimension angefügt werden.
+ * Picture overflow
+ Die beiden PICTURE überschreiten die maximale Größe eines
+ PICTURE.
+
+nilpicture
+ PICTURE PROC nilpicture
+ Zweck: Die Prozedur liefert ein leeres PICTURE zur Initialisierung.
+
+draw
+ PROC draw (PICTURE VAR p, TEXT CONST text)
+ Zweck: Der angegebene Text wird gezeichnet. Der Anfang ist dabei die aktuelle
+ Stiftposition, die nicht verändert wird.
+ Fehlerfälle:
+ * Picture overflow
+ Der Text paßt nicht mehr in das PICTURE.
+
+ PROC draw (PICTURE VAR p, TEXT CONST text, REAL CONST angle,
+ height, bright)
+ Zweck: Der angegebene Text wird unter dem Winkel #on("italics")#angle#off("italics")# gegenüber der
+ Waagerechten mit der Zeichenhöhe #on("italics")#hight#off("italics")# und der Breite #on("italics")#bright#off("italics")# gezeich­
+ net. Der Anfang ist dabei die aktuelle Stiftposition, die nicht verändert
+ wird.
+ Fehlerfälle:
+ * Picture overflow
+ Der Text paßt nicht mehr in das PICTURE.
+
+ PROC draw (PICTURE VAR p, REAL CONST x, y, z)
+ Zweck: Zeichnen einer Linie von der aktuellen Position zur Position (x, y, z).
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is two dimensional
+
+ PROC draw (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Zeichnen einer Linie von der aktuellen Position zur Position (x, y).
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+draw r PROC draw r (PICTURE VAR p, REAL CONST x, y, z)
+ Zweck: Zeichnen einer Linie der Länge (x, y, z) relativ zur aktuellen Position.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is two dimensional
+
+ PROC draw r (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Zeichnen einer Linie der Länge (x, y) relativ zur aktuellen Position.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+draw cm
+ PROC draw cm (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Zeichnen einer Linie von der aktuellen Position zur Position (x, y) cm.
+ Dabei werden die angegebenen Projektionsparameter nicht beachtet,
+ sondern die Angaben in #on("bold")#Zentimeter#off("bold")# berechnet.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+
+draw cm r
+ PROC draw cm r (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Zeichnen einer Linie der Länge (x, y) cm relativ zur aktuellen Position.
+ Dabei werden die angegebenen Projektionsparameter nicht beachtet,
+ sondern die Angaben in #on("bold")#Zentimeter#off("bold")# berechnet.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+
+move
+ PROC move (PICTURE VAR p, REAL CONST x, y, z)
+ Zweck: Die aktuelle Position wird auf (x, y, z) gesetzt.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is two dimensional
+
+ PROC move (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Die aktuelle Position wird auf (x, y) gesetzt.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+move r
+ PROC move r (PICTURE VAR p, REAL CONST x, y, z)
+ Zweck: Die aktuelle Position wird um (x, y, z) erhöht.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is two dimensional
+
+ PROC move r (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Die aktuelle Position wird um (x, y) erhöht.
+ Position.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+
+move cm
+ PROC move cm (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Die aktuelle Position wird auf (x, y) cm gesetzt. Dabei werden die an­
+ gegebenen Projektionsparameter nicht beachtet, sondern die Angaben in #on("bold")#
+ Zentimeter#off("bold")# berechnet.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+
+move cm r
+ PROC move cm r (PICTURE VAR p, REAL CONST x, y)
+ Zweck: Die aktuelle Position wird um (x, y) cm erhöht. Dabei werden die an­
+ gegebenen Projektionsparameter nicht beachtet, sondern die Angaben in #on("bold")#
+ Zentimeter#off("bold")# berechnet.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+
+bar
+ PROC bar (PICTURE VAR p, REAL CONST width, hight, INT CONST
+ pattern):
+ Zweck: Die Prozedur zeichnet an der aktuellen Position einen Balken mit dem
+ Muster #on("italics")#pattern#off("italics")#: 0 = Leerer Balken
+ 1 = Gepunkteter Balken
+ 2 = Gefüllter Balken
+ 3 = Horizontale Linien
+ 4 = Vertikale Linien
+ 5 = Gekreuzte Linien
+ 6 = Diagonale Linien von Links nach Rechts
+ 7 = Diagonale Linien von Rechts nach Links
+ 8 = Gekreuzte diagonale Linien.
+ Die aktuelle Stiftposition wird dabei nicht verändert.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+ * Unknown pattern
+ Das angegebene Muster liegt nicht im Bereich 0-8
+
+circle
+ PROC circle (PICTURE VAR p, REAL CONST from, to, INT CONST
+ pattern)
+ Zweck: Die Prozedur zeichnet an der aktuellen Position ein Kreissegment vom
+ Winkel #on("italics")#from#off("italics")# bis #on("italics")#to#off("italics")# (im Gradmaß) mit dem Muster #on("italics")#pattern#off("italics")# (s.o.). Die
+ aktuelle Stiftposition wird dabei nicht verändert.
+ Fehlerfälle:
+ * Picture overflow
+ Zu viele Befehle in einem PICTURE
+ * Picture is three dimensional
+ * Unknown pattern
+ Das angegebene Muster liegt nicht im Bereich 0-8
+
+dim
+ INT PROC dim (PICTURE CONST pic)
+ Zweck: Liefert die Dimension eines PICTURE.
+
+pen
+ INT PROC pen (PICTURE CONST p)
+ Zweck: Liefert den virtuellen Stift des PICTURE
+
+ PROC pen (PICTURE VAR p, INT CONST pen)
+ Zweck: Setzen des (virtuellen) Stiftes eines PICTURE. Bei pen=0 wird das
+ Picture nicht gezeichnet.
+ Fehlerfälle:
+ * pen out of range
+ Der gewünschte Stift ist kleiner als 0 oder größer als 16.
+
+extrema
+ PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y
+ max)
+ Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICTURE.
+ Fehlerfälle:
+ * Picture is three dimensional
+
+ PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y
+ max, z min, z max)
+ Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICTURE.
+ Fehlerfälle:
+ * Picture is two dimensional
+
+where
+ PROC where (PICTURE CONST p, REAL VAR x, y, z)
+ Zweck: Die Prozedur liefert die aktuelle Stiftposition (Angaben mit #on("italics")#cm#off("italics")# werden
+ dabei nicht berücksichtigt).
+ Fehlerfälle:
+ * Picture is two dimensional
+
+ PROC where (PICTURE CONST p, REAL VAR x, y, z)
+ Zweck: Die Prozedur liefert die aktuelle Stiftposition (Angaben mit #on("italics")#cm#off("italics")# werden
+ dabei nicht berücksichtigt).
+ Fehlerfälle:
+ * Picture is three dimensional
+
+rotate:
+ PROC rotate (PICTURE VAR p, REAL CONST angle)
+ Zweck: Das PICTURE wird um den Punkt (0, 0) um den Winkel #on("italics")#angle#off("italics")# (im
+ Gradmaß) im mathematisch positiven Sinn gedreht.
+ Dabei werden nur die Werte von #on("italics")#draw, draw r, move #off("italics")# und #on("italics")#move r#off("italics")#
+ verändert.
+
+ PROC rotate (PICTURE CONST p, REAL CONST phi, theta, lambda ) :
+ PICTURE 1-397
+ Zweck: Das PICTURE wird um den Winkel #on("italics")#lambda#off("italics")# um die Drehachse #on("italics")#(phi,
+ theta)#off("italics")# gedreht.
+ Dabei werden nur die Werte von #on("italics")#draw, draw r, move #off("italics")# und #on("italics")#move r#off("italics")#
+ verändert.
+
+stretch
+ PROC stretch (PICTURE VAR pic, REAL CONST sx, sy)
+ Zweck: Das PICTURE wird in X-Richtung um den Faktor #on("italics")#sx#off("italics")#, in Y-Rich­
+ tung um den Faktor #on("italics")#sy#off("italics")# gestreckt (bzw. gestaucht). Dabei bewirkt der
+ Faktor
+ s > 1 eine Streckung
+ 0 < s < 1 eine Stauchung
+ s < 0 zusätzlich eine Achsenspiegelung.
+ Dabei werden nur die Werte von #on("italics")#draw, draw r, move #off("italics")# und #on("italics")#move r#off("italics")#
+ verändert.
+ Fehlerfälle:
+ * Picture is three dimensional
+
+ PROC stretch (PICTURE VAR p, REAL CONST sx, sy, sz)
+ Zweck: s. o.
+ Fehlerfälle:
+ * Picture is two dimensional
+
+translate
+ PROC translate (PICTURE VAR p, REAL CONST dx, dy)
+ Zweck: Das PICTURE wird um #on("italics")#dx#off("italics")# und #on("italics")#dy#off("italics")# verschoben.
+ Dabei werden nur die Werte von #on("italics")#draw, draw r, move #off("italics")# und #on("italics")#move r#off("italics")#
+ verändert.
+ Fehlerfälle:
+ * Picture is three dimensional
+
+ PROC translate (PICTURE VAR p, REAL CONST dx, dy, dz)
+ Zweck: s. o.
+ Fehlerfälle:
+ * Picture is two dimensional
+
+plot PROC plot (PICTURE CONST p)
+ Zweck: Das Picfile wird gezeichnet.
+ Achtung: Es wird kein #on("italics")#begin plot#off("italics")# oder #on("italics")#end plot#off("italics")# durchgeführt. Es wird
+ auch kein Stift gsetzt und die Projektionsparameter bleiben
+ unverändert.
+
+
+#on("underline")#Graphische PICFILE-Prozeduren#off("underline")#
+plot
+ PROC plot (TEXT CONST name)
+ Zweck: Der PICFILE mit dem Namen #on("italics")#name#off("italics")# wird entsprechend der angegebenen
+ Darstellungsart gezeichnet. Diese Parameter (#on("italics")#perspective, orthographic,
+ oblique, view, window etc.#off("italics")#) müssen vorher eingestellt werden.
+ Fehlerfälle:
+ * PICFILE does not exist
+ Es existiert kein PICFILE mit dem Namen #on("italics")#name#off("underline")#
+
+ PROC plot (PICFILE VAR p)
+ Zweck: Der PICFILE #on("italics")#p#off("italics")# wird entsprechend der angegebenen Darstellungsart ge­
+ zeichnet. Diese Parameter müssen vorher eingestellt werden:
+
+ #on("bold")#zweidimensional:#off("bold")#
+ obligat: #on("italics")#window#off("italics")# (zweidimensional)
+ optional: #on("italics")#view#off("italics")# (zweidimensional)
+ #on("italics")#viewport#off("italics")#
+ #on("italics")#select pen#off("italics")#
+
+ #on("bold")#dreidimensional:#off("bold")#
+ obligat: #on("italics")#window#off("italics")# (dreidimensional)
+ optional: #on("italics")#view#off("italics")# (dreidimensional)
+ #on("italics")#orthographic | perspective | oblique#off("italics")#
+ #on("italics")#viewport#off("italics")#
+ #on("italics")#select pen#off("italics")#
+
+
+select pen
+ PROC select pen (PICFILE VAR p, INT CONST pen, colour, thickness, line
+ type,
+ BOOL VAR hidden lines) Zweck: Für die
+ Darstellung des Bildes #on("italics")#p#off("italics")# soll dem #on("italics")#virtuellen#off("italics")# Stift #on("italics")#pen#off("italics")# ein realer Stift
+ zugeordnet werden, der möglichst die Farbe #on("italics")#colour#off("italics")# und die Dicke #on("italics")#thick­
+ ness#off("italics")# hat und dabei Linien mit dem Typ #on("italics")#line type#off("italics")# zeichnet. Es wird die
+ beste Annäherung für das Ausgabegerät genommen.
+ Wenn #on("italics")#hidden lines#off("italics")# auf TRUE gesetzt wird, werden bei dreidimensionalen
+ Zeichnungen die verdeckten Linien mitgezeichnet, ansonsten werden sie
+ unterdrückt. Um sicherzustellen, das der Algorithmus auch funktioniert,
+ müssen die Linien allerdings von vorn nach hinten gezeichnet werden. Es
+ ist also nicht möglich, das Bild so zu drehen, das die hinteren Linien
+ zuerst gezeichnet werden.
+ Dabei gelten folgende Vereinbarungen:
+
+ #on("bold")#Farbe:#off("bold")# Negative Farben werden XOR gezeichnet (dunkel wird hell und
+ hell wird dunkel), Farbe 0 ist der Löschstift und positive Farben
+ überschreiben (ersetzen) den alten Punkt mit folgenden Werten:
+
+ 1 Standardfarbe des Endgerätes
+ 2 rot
+ 3 blau
+ 4 grün
+ 5 schwarz
+ 6 weiß
+ > 6 nicht normierte Sonderfarben
+
+
+ #on("bold")#Dicke:#off("bold")# 0 Standardstrichstärke des Endgerätes, ansonsten Strichstärke in
+ 1/10 mm.
+
+
+ #on("bold")#Linientyp:#off("bold")#
+ 0 keine sichtbare Linie
+ 1 durchgängige Linie
+ 2 gepunktete Linie
+ 3 kurz gestrichelte Linie
+ 4 lang gestrichelte Linie
+ 5 Strichpunktlinie
+ > 5 nicht normierte Linie
+
+ #on("bold")#Verdeckte Linien:#off("bold")#
+ TRUE Verdeckte Linien werden mitgezeichnet
+ FALSE Verdeckte Linien werden unterdrückt (nur bei drei­
+ dimensionalen PICTURE)
+
+ Die hier aufgeführten Möglichkeiten müssen nicht an allen graphischen
+ Endgeräten vorhanden sein. Der geräteabhängige Graphik-Treiber wählt
+ jeweils die bestmögliche Annäherung.
+
+ Fehlerfälle:
+ * pen out of range
+ #on("italics")#pen#off("italics")# muss im Bereich 1-16 sein.
+
+background
+ PROC background (PICFILE VAR p, INT CONST colour)
+ Zweck: Der Hintergrund wird auf die Farbe #on("italics")#colour#off("italics")# (s.o.) gesetzt wenn möglich.
+
+ INT PROC background (PICFILE CONST p):
+ Zweck: Liefert die eingestellte Hintergrundfarbe.
+
+view
+ PROC view (PICFILE VAR p, REAL CONST alpha)
+ Zweck: Setzt den Winkel der Y-Achse zur Senkrechten auf #on("italics")#alpha#off("italics")# Grad, falls
+ diese nicht senkrecht zur Betrachtungsebene steht.
+
+ PROC view (PICFILE VAR p, REAL CONST phi, theta)
+ Zweck: Dreidimensionale Bilder werden häufig nicht direkt von vorne dargestellt,
+ sondern für die Betrachtung gedreht. Mit der Prozedur #on("italics")#view#off("italics")# kann die
+ Betrachtungsrichtung durch die Polarwinkel #on("italics")#phi#off("italics")# und #on("italics")#theta#off("italics")# (im Gradmass)
+ angegeben werden. Voreingestellt ist #on("italics")#phi#off("italics")# = 0 und #on("italics")#theta#off("bold")# = 0, d.h. senk­
+ recht von oben.
+
+ Im Gegensatz zu #on("italics")#rotate#off("italics")# hat #on("italics")#view#off("italics")# keine Wirkung auf das eigentliche Bild
+ (PICFILE), sondern nur auf die gewählte Darstellung. So addieren sich
+ zwar aufeinanderfolgende #on("italics")#Rotationen#off("italics")#, #on("italics")#view#off("italics")# aber geht immer von der
+ Nullstellung aus. Auch kann das Bild durch eine #on("italics")#Rotation#off("italics")# ganz oder
+ teilweise aus oder in das Darstellungsfenster (#on("italics")#window#off("italics")# gedreht werden. Bei
+ #on("italics")#view#off("italics")# verändern sich die Koordinaten der Punkte nicht, d. h. das Fenster
+ wird mitgedreht.
+
+ PROC view (PICFILE VAR p, REAL CONST x, y, z)
+ Zweck: Wie oben, nur werden die Winkel nicht in Polarkoordinaten angegeben,
+ sondern es wird die Blickrichtung als Vektor in Karthesischen Koordina­
+ ten angegeben. (Die Länge darf ungleich 1 sein).
+
+viewport
+ PROC viewport (PICFILE VAR p, REAL CONST hormin, hormax, vertmin,
+ vertmax) : 1-709
+ Zweck: Die Zeichenfläche auf dem Endgerät, auf dem das Bild dargestellt werden
+ soll, wird spezifiziert. Dabei wird sowohl die Größe als auch die relative
+ Lage der Zeichenfläche definiert. Der linke untere Eckpunkt der physi­
+ kalischen Zeichenfläche des Gerätes hat die Koordinaten (0, 0). Die
+ definierte Zeichenfläche erstreckt sich
+
+ #on("italics")#hormin - hormax#off("italics")# in der Horizontalen,
+ #on("italics")#vertmin - vertmax#off("italics")# in der Vertikalen.
+
+ So liegt der linke untere Eckpunkt dann bei (#on("italics")#hormin, hormax#off("italics")#), der rechte
+ obere Eckpunkt bei (#on("italics")#hormax, vertmax#off("italics")#).
+
+ Damit sowohl geräteunabhängige als auch maßstabgetreue Zeichnungen
+ möglich sind, können die Koordinaten in zwei Arten spezifiziert werden:
+ a) #on("bold")#Gerätekoordinaten#off("bold")#
+ Die Koordinaten können Werte von 0.0 bis 2.0 annehmen. Dabei
+ hat die kürzere Seite der physikalischen Zeichenfläche definitionsge­
+ mäß die Länge 1.0.
+ b) #on("bold")#Absolute Koordinaten#off("bold")#
+ Die Werte werden in #on("italics")#cm#off("italics")# angegeben. Dabei müssen die Maximal­
+ werte aber größer als 2.0 sein, da sonst Fall a) angenommen wird.
+
+ Voreingestellt ist
+
+ viewport (0.0, 1.0, 0.0, 1.0)
+
+ d.h. das größtmögliche Quadrat, beginnend mit der linken unteren Ecke
+ der physikalischen Zeichenfläche. In vielen Fällen wird diese Einstellung
+ ausreichen, so daß der Anwender kein eigenes #on("italics")#viewport#off("italics")# definieren muss.
+
+ Der Abbildungsmaßstab wird durch das Zusammenspiel von #on("italics")#viewport#off("italics")# und
+ #on("italics")#window#off("italics")# festgelegt (s. dort). Dabei ist insbesondere darauf zu achten, daß
+ winkeltreue Darstellung nur bei gleichen X- und Y-Maßstab möglich
+ ist. Da man oft quadratische Fenster (#on("italics")#window#off("italics")#) verwendet, wurde als
+ Standardeinstellung auch ein quadratisches #on("italics")#viewport#off("italics")# gewählt.
+
+ Hinweis: Mit der Prozedur #on("italics")#check limit#off("italics")# aus dem PACKET #on("italics")#basis plot#off("italics")# kann die
+ Überprüfung der Grenzen des eingestellten #on("italics")#viewport#off("italics")#-Bereiches ein-
+ bzw. ausgeschaltet werden. Bei eingeschateter Überprüfung, werden
+ Linien, die den Bereich überschreiten, am Rand abgetrennt.
+
+
+window
+ PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max)
+ Zweck: Für die Darstellung eines zweidimensionalen Bildes wird das darzustel­
+ lende Fenster definiert. Alle Bildpunkte, deren X-Koordinaten im In-
+ tervall [#on("italics")#x min, x max#off("italics")#] und deren Y-Koordinaten im Bereich [#on("italics")#y min, y
+ max#off("italics")#] liegen, gehören zum definierten Fenster.Vektoren, die außerhalb
+ dieses Fensters liegen, gehen über die durch #on("italics")#viewport#off("italics")# Fläche hinaus
+ (s.dort).
+
+ Der Darstellungsmaßstab ergibt sich als
+
+ #ub#               x max - x min               #ue#
+ horizontale Seitenlänge der Zeichenfläche
+
+
+ #ub#               y max - y min               #ue#
+ vertikale Seitenlänge der Zeichenfläche
+
+ PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max,
+ z min, z max)
+
+ Zweck: Für die darstellung eines dreidimensionalen Bildes wird das darzustellende
+ Fenster definiert. Alle Bildpunkte, deren X-Koordinaten im Intervall [#on("italics")#x
+ min, x max#off("italics")#], deren Y-Koordinaten im Bereich [#on("italics")#y min, y max#off("italics")#] und
+ deren Z-Koordinaten im Bereich [#on("italics")#z min, z max#off("italics")#] liegen, gehören zum
+ definierten Fenster. Dieses dreidimensionale Fenster (#on("italics")#Quader#off("italics")#) wird ent­
+ sprechend der eingestellten Projektionsart (orthographisch, perspektivisch
+ oder schiefwinklig) und den Betrachtungswinkeln (s. #on("italics")#view#off("italics")#) auf die spezi­
+ fizierte Zeichenfläche abgebildet.
+ Anders als im zweidimensionalen Fall ist das Problem der Maßstaäbe
+ nicht mehr nur durch das Zusammenspiel von #on("italics")#window#off("italics")# und #on("italics")#viewport#off("italics")# zu
+ beschreiben. Hier spielen auch die Projektionsart und Darstellungswinkel
+ herein.
+
+oblique:
+ PROC oblique (PICFILE VAR p, REAL CONST a, b)
+ Zweck: Bei dem (dreidimensionalen) Bild #on("italics")#p#off("italics")# wir #on("underline")#schiefwinklig#off("underline")# als gewünschte
+ Projektionsart eingestellt. Dabei ist (#on("italics")#a, b#off("italics")#) der Punkt auf der X-Y-
+ Ebene, auf den der Einheitsvektor der Z-Richtung abgebildet werden
+ soll.
+
+orthographic
+ PROC orthographic (PICFILE VAR p)
+ Zweck: Bei dem (dreidimensionalen) Bild #on("italics")#p#off("italics")# wir #on("underline")#orthographisch#off("underline")# als gewünschte
+ Projektionsart eingestellt. Bei der orthographischen Projektion wird ein
+ dreidimensionaler Körper mit parallelen Strahlen senkrecht auf der Pro­
+ jektionsebene dabgebildet.
+
+perpective
+ PROC perspective (PICFILE VAR p, REAL CONST cx, cy, cz)
+ Zweck: Bei dem (dreidimensionalen) Bild #on("italics")#p#off("italics")# wir #on("underline")#perspectivisch#off("underline")# als gewünschte
+ Projektionsart eingestellt. Der Punkt (#on("italics")#cx, 1/cy, cz#off("underline")#) ist der Fluchtpunkt der
+ Projektion, d. h. alle Parallen zur Z-Achse schneiden sich in diesem
+ Punkt.
+
+extrema
+ PROC extrema (PICFILE VAR p, REAL VAR x min, x max, y min, y max)
+ Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICFILE.
+
+ PROC extrema (PICFILE VAR p, REAL VAR x min,x max,y min,y max,z
+ min,z max) : 1-651
+ Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICFILE.
+
+
+#on("underline")#Prozeduren zur Manipulation von PICFILE#off("underline")#
+:=
+ OP := (PICFILE VAR p, DATASPACE CONST d)
+ Zweck: Assoziert die PICFILE Variable #on("italics")#p#off("italics")# mit dem Datenraum #on("italics")#d#off("italics")# und initialisiert
+ die Variable, wenn nötig.
+ Fehlerfälle:
+ * dataspace is no PICFILE
+ Der anzukoppelnde Datenraum hat einen unzulässigen Typ
+
+picture file
+ DATASPACE PROC picture file (TEXT CONST name)
+ Zweck: Assoziaten eines benannten Datenraumes mit einem PICFILE (s.o.).
+
+put
+ PROC put (FILE VAR f, PICFILE VAR p)
+ Zweck: Schreibt den Inhalt eines PICFILE in ein FILE. Die Informationen
+ werden im internen Format abgelegt.
+
+get
+ PROC get (PICFILE VAR p, FILE VAR f)
+ Zweck: Liest den Inhalt eines PICFILE aus einem FILE. Die Informationen
+ müssen mit #on("italics")#put#off("italics")# geschrieben worden sein.
+ Fehlerfall:
+ * Picfile overflow
+ Es können nur maximal 1024 Picture (Sätze) in einem PICFILE abgelegt
+ werden.
+
+to first pic
+ PROC to first pic (PICFILE VAR p)
+ Zweck: Positioniert auf das erste PICTURE.
+
+to eof
+ PROC to last pic (PICFILE VAR p)
+ Zweck: Positioniert hinter das letzte PICTURE.
+
+to pic
+ PROC to pic (PICFILE VAR p, INT CONST pos)
+ Zweck: Positioniert auf das PICTURE Nummer #on("italics")#pos#off("italics")#.
+ Fehlerfälle:
+ * Position underflow
+ Es wurde eine Position kleiner Null angegeben. * Position after
+ eof Es wurde versucht, hinter das Ende eines PICFILE zu positionieren
+
+up
+ PROC up (PICFILE VAR p)
+ Zweck: Positioniert genau ein PICTURE zurück.
+ Fehlerfall:
+ * Position underflow
+ Es wurde versucht, vor das erste PICTURE zu positionieren
+
+ PROC up (PICFILE VAR p, INT CONST n)
+ Zweck: Positioniert genau #on("italics")#n#off("italics")# Picture zurück.
+ Fehlerfall:
+ * Position underflow
+ Es wurde versucht, vor das erste PICTURE zu positionieren
+
+down
+ PROC down (PICFILE VAR p)
+ Zweck: Positioniert genau ein PICTURE vorwärts.
+ Fehlerfall:
+ * Position after eof
+ Es wurde versucht, hinter das Ende eines PICFILE zu positionieren
+
+ PROC down (PICFILE VAR p, INT CONST n)
+ Zweck: Positioniert genau #on("italics")#n#off("italics")# Picture vorwärts.
+ Fehlerfall:
+ * Position after eof
+ Es wurde versucht, hinter das Ende eines PICFILE zu positionieren
+
+is first picture
+ BOOL PROC is first picture (PICFILE CONST p)
+ Zweck: Liefert genau dann #on("italics")#TRUE#off("italics")#, wenn das erste PICTURE erreicht ist.
+
+eof
+ BOOL PROC eof (PICFILE CONST p)
+ Zweck: Liefert genau dann #on("italics")#TRUE#off("italics")#, wenn das Ende eines PICFILE erreicht ist.
+
+picture no
+ INT PROC picture no (PICFILE CONST p)
+ Zweck: Liefert die Nummer des aktuellen PICTURE.
+
+pictures
+ INT PROC pictures (PICFILE CONST p)
+ Zweck: Liefert die Anzahl PICTURE eines PICFILE.
+
+delete picture
+ PROC delete picture (PICFILE VAR p)
+ Zweck: Löscht das aktuelle PICTURE
+
+insert picture
+ PROC insert picture (PICFILE VAR p)
+ Zweck: Fügt ein PICTURE #on("underline")#vor#off("underline")# der aktuellen Position ein.
+
+read picture
+ PROC read picture (PICFILE CONST p, PICTURE VAR pic)
+ Zweck: Liest das aktuelle PICTURE.
+
+write picture
+ PROC write picture (PICFILE VAR p, PICTURE CONST pic)
+ Zweck: Schreibt das PICTURE #on("italics")#pic#off("italics")# auf der aktuellen Position.
+
+put picture
+ PROC write picture (PICFILE VAR p, PICTURE CONST pic)
+ Zweck: Schreibt das PICTURE #on("italics")#pic#off("italics")# hinter das letzte PICTURE des PICFILE.
+ Die aktuelle Position wird nicht verändert.
+
+#page#
+ #on("italics")#Wo wir sind, da klappt nichts,
+ aber wir können nicht überall sein !#off("italics")#
+
+#type ("basker14")#
+#on("bold")#Kurzbeschreibung des Graphik-Editors#off("bold")#
+#type ("basker12")#
+
+In der Kommondozeile werden folgende Informationen angezeigt:
+
+#on("revers")#LEN nnnnn <...Name...> DIM n PEN nn Picture nnnn
+#off("revers")#
+
+
+Folgende Kommandos stehen zur Verfügung:
+
+ PICTURE PROC pic neu
+ PICFILE PROC picfile neu
+ PROC neu zeichnen
+
+ OP UP n (n PICTURE up)
+ OP DOWN n (n PICTURE down)
+ OP T n (to PICTURE n)
+
+ PROC oblique (REAL CONST a, b)
+ PROC orthographic
+ PROC perspective (REAL CONST cx, cy, cz)
+ PROC window (BOOL CONST dev)
+ PROC window (REAL CONST x min, x max, y min, y max)
+ PROC window (REAL CONST x min, x max, y min, y max, z min, z max)
+ PROC viewport (REAL CONST h min, h max, v min, v max)
+ PROC view (REAL CONST alpha)
+ PROC view (REAL CONST phi, theta)
+ PROC view (REAL CONST x, y, z)
+
+ PROC pen (INT CONST n)
+ PROC select pen (INT CONST pen, colour, thickness, line type, BOOL CONST
+ hidden)
+ PROC background (INT CONST colour)
+
+ PROC extrema pic
+ PROC extrema picfile
+ PROC selected pen
+
+ PROC rotate (REAL CONST angle)
+ PROC rotate (REAL CONST phi, theta, lambda )
+ PROC stretch (REAL CONST sx, sy)
+ PROC stretch (REAL CONST sx, sy, sz)
+ PROC translate (REAL CONST dx, dy)
+ PROC translate (REAL CONST dx, dy, dz)
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Inhaltsverzeichnis b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Inhaltsverzeichnis
new file mode 100644
index 0000000..5726636
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Inhaltsverzeichnis
@@ -0,0 +1,45 @@
+#limit (11.5)##pagelength (16.5)#
+#start (1.8,1.0)#
+Inhaltsverzeichnis
+
+
+
+1 Was kann gs-Herbert und Robbi 3
+
+2 Allgemeines zum Hamster-/Robotermodell 6
+2.1 Entstehung 6
+2.2 Kurzbeschreibung des Hamster-/Roboter-
+ Modells 7
+2.2.1 Befehle und Tests 7
+2.2.2 Landschafts-/Arbeitsfeldgestaltung 9
+2.3 Einsatzbereich 11
+2.4 Hinweise für den Einsatz in der Ausbildung 12
+2.5 Aufgabenmaterial 14
+2.6 Erfahrungen mit dem Hamster-/Roboter-Modell 14
+
+3 Installation von gs-Herbert und Robbi 17
+3.1 Voraussetzungen 17
+3.2 Lieferumfang 17
+3.3 Installation 18
+3.4 Direktstart des Medells 20
+
+4 Beschreibung der Menufunktionen 22
+4.1 Kurzhinweise zur Bedienung des Menus 23
+4.2 Menufunktionen zum Oberbegriff 'Info' 27
+4.3 Menufunktionen zum Oberbegriff 'Landschaft' 29
+ Menufunktionen zum Oberbegriff 'Arbeitsfeld' 29
+4.4 Menufunktionen zum Oberbegriff 'Programm' 35
+4.5 Menufunktionen zum Oberbegriff 'Lauf' 41
+4.6 Menufunktionen zum Oberbegriff 'Archiv' 46
+
+5 Detailbeschreibung der Basisbefehle 61
+
+6 Zusätzliche Kommandos 66
+
+
+
+
+
+
+
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 1 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 1
new file mode 100644
index 0000000..73c95f9
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 1
@@ -0,0 +1,93 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (3)#
+#headodd#
+#center#gs-Herbert und Robbi#right#%
+
+#end#
+#headeven#
+%#center#gs-Herbert und Robbi
+
+#end#
+#center#1
+
+#center#Was
+#center#kann
+#center#gs-Herbert und Robbi
+
+
+ Mit #on("b")#gs-Herbert und Robbi#off("b")# liegt das von Lothar Oppor
+entwickelte und von Wolfgang Weber weiterentwickelte
+Hamster-Modell nun eingebettet in die komfortable,
+menuorientierte Benutzerschnittstelle #on("b")#gs-DIALOG#off("b")# vor. Das
+Programm stellt eine wesentliche Erweiterung des 'alten'
+Hamster - Modells dar. Neben einer zweiten Modellvarian­
+te (Roboter) wurden eine Reihe nützlicher Funktionen in
+das Modell integriert. Sämtlich Funktionen werden über
+ein übersichtliches Menu angeboten, was gerade dem An­
+fänger die Arbeit mit dem Computer erleichtert.
+
+ #on("b")#gs-Herbert und Robbi#off("b")# kann zur Einführung in das al­
+gorithmische Problemlösen eingesetzt werden und soll
+dazu dienen, Programmierung #on("u")#einfach#off("u")# und #on("u")#spielerisch#off("u")# zu
+erlernen - ohne Ablenkung durch Betriebssystem oder gar
+Hardware-Eigenheiten.
+
+ Das Modell ist so einfach und überschaubar, daß ein
+Anfänger schon nach einer halben Stunde in der Lage ist,
+sich selbst kleine Aufgaben zu stellen und diese zu lösen.
+Die Modellumgebung ist so komfortabel, daß der Anfänger
+nach einer kurzen Einweisung selbständig mit dem Compu­
+termodell umgehen kann.
+
+- Durch die Menuführung sind nur noch wenige Be­
+ triebssystemkommandos zur Bedienung des Systems
+ notwendig.
+
+- Der Benutzer kann jederzeit Informationen anfordern
+ über:
+ - den zur Verfügung stehenden Befehlsumfang,
+ - die Möglichkeiten, den Lauf des Hamsters/Robo­
+ ters zu beeinflussen,
+ - die Möglichkeiten hinsichtlich der Landschafts­
+ gestaltung/Arbeitsfeldgestaltung
+ - die Bedienung des Menusystems
+ - die Wirkung der einzelnen Menufunktionen
+ - die Möglichkeiten/Bedienung des Editors
+
+- Neben der Steuerung des Hamsters/Roboters durch
+ Programme kann der Hamster/Roboter auch interaktiv
+ gesteuert werden; dabei wird ein Protokoll der ausge­
+ führten Aktionen in Form eines ablauffähigen ELAN-
+ Programms angelegt. Dieses Protokoll (Programm) kann
+ jederzeit eingesehen werden. Natürlich kann anschlie­
+ ßend der Hamster/Roboter die gleichen Aktionen, die
+ zuvor von Hand ausgeführt wurden, auch nach diesem
+ Programm ausführen.
+
+- Durch den (optional) erweiterbaren Befehlssatz kann
+ #on("b")#gs-Herbert und Robbi#off("b")# den Erfordernissen und der Lei­
+ stungsfähigkeit der Lernenden leicht angepaßt wer­
+ den.
+
+- Auch das Editieren und Drucken von Programmen sowie
+ Landschaften/Arbeitsfeldern erfolgt vom Menu aus.
+
+- Die Archivoperationen, die gerade Anfängern zunächst
+ große Probleme bereiten, können sämtlichst komforta­
+ bel vom Menu aus gehandhabt werden. Dabei werden
+ Anfragen an den Benutzer gestellt, die zumeist nur
+ mit 'ja' oder 'nein' zu beantworten sind; oder der Be­
+ nutzer hat in einer Auswahlliste die gewünschten Da­
+ teinamen anzukreuzen.
+
+- Die Archivoperationen stehen dem Benutzer auch unab­
+ hängig vom Hamster-/Robotermodell unter #on("b")#gs-DIALOG#off("b")#
+ zur Verfügung, so daß beim Verlassen der Modellum­
+ gebung "kein Bruch zu befürchten ist".
+
+- Die Fehlermeldungen sind detailliert und leicht ver­
+ ständlich, so daß auch Anfänger die Fehlerquelle(n)
+ zumeist ohne zusätzliche Hilfen lokalisieren und be­
+ seitigen können.
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 2 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 2
new file mode 100644
index 0000000..52526d6
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 2
@@ -0,0 +1,389 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (6)#
+#headodd#
+#center#gs-Herbert und Robbi#right#%
+
+#end#
+#headeven#
+%#center#gs-Herbert und Robbi
+
+#end#
+#center#2
+
+#center#Allgemeines
+#center#zum
+#center#Hamster-/Robotermodell
+
+
+2.1 Entstehung
+
+ Das Hamster - Modell wurde in der Gesellschaft für
+Mathematik und Datenverarbeitung (GMD), einer Großfor­
+schungseinrichtung des Bundes und des Landes Nord­
+rhein-Westfalen, von Lothar Oppor in Anlehnung an das
+Modell 'Karel the Robot' von Richard E. Pattis (Stanford
+University, USA) entwickelt und zunächst innerhalb der
+GMD und schon bald im Schulbereich eingesetzt.
+ Wolfgang Weber, Lehrer an der Gesamtschule Leopolds­
+höhe bei Bielefeld, entwickelte in Zusammenhang mit sei­
+ner Arbeit am Landesinstitut für Schule und Weiterbil­
+dung in Soest dieses Modell seit 1984 weiter. Sein Ziel war
+es, das Modell um solche Komponenten zu erweitern, daß es
+auch für Schüler der Sekundarstufe I im Anfangsunter­
+richt eingesetzt werden kann. Besondere Bedeutung kam
+dabei der Entwicklung einer komfortablen, einfach zu be­
+dienenden Benutzerschnittstelle zu, die es dem Anfänger
+ermöglicht, sich von Beginn an mit der eigentlichen Pro­
+blemstellung auseinanderzusetzen, ohne von Betriebssy­
+stem oder gar Hardware-Eigenheiten abgelenkt zu werden.
+ Mit dem vorliegenden Programm #on("b")#gs-Herbert und Robbi#off("b")#,
+das in die komfortable, menuorientierte Benutzer­
+schnittstelle #on("b")#gs-DIALOG#off("b")# eingebettet ist, dürfte diese Ar­
+beit vorerst zu einem Abschluß gebracht sein. Mit diesem
+Programm liegt nun eine Modellumgebung vor, die den
+gestellten Anforderungen gerecht wird.
+
+
+2.2 Kurzbeschreibung des Hamster-/Roboter-Modells
+
+ Das Hamster- und das Roboter - Modell sind analog
+aufgebaut und in Art und Umfang der Befehle identisch.
+Im ersten Modell kann 'Herbert der Hamster', im zweiten
+Modell 'Robbi der Roboter' auf dem Bildschirm durch vier
+sogenannte Basisbefehle gesteuert werden - 'Herbert' in
+einer 'Landschaft', 'Robbi' auf einem 'Arbeitsfeld' - beides
+Ebenen, die aus 23 x 40 Kacheln bestehen.
+ Auf dieser Ebene können sich noch Hindernisse und
+'Körner' (für Herbert) oder 'Werkstücke' (für Robbi) befin­
+den. Die Hindernisse stellen auf dem Bildschirm Barrieren
+dar, die umgangen werden müssen. Die Körner bzw. Werk­
+stücke können von Herbert in seinen 'Backentaschen' bzw.
+von Robbi in seinem 'Behälter' aufgenommen oder daraus
+(wieder) abgelegt werden.
+
+
+2.2.1 Befehle und Tests
+
+ Für die Steuerung von Herbert bzw.Robbi stehen vier
+Basisbefehle zur Verfügung (die in beiden Modellvarian­
+ten gleich sind):
+
+#on("u")#vor#off("u")#
+ Gehe eine Kachel (einen Schritt) in Laufrichtung vor.
+
+#on("u")#links um#off("u")#
+ Drehe Dich, wo Du stehst, um 90 Grad nach links.
+
+#on("u")#nimm#off("u")#
+ Nimm da, wo Du stehst, ein Korn/Werkstück auf.
+
+#on("u")#gib#off("u")#
+ Lege da, wo Du stehst, aus den Backentaschen/dem Be­
+ hälter ein Korn/Werkstück ab.
+
+ Da nur dort ein Korn/Werkstück aufgenommen werden
+kann, wo auch eines vorhanden ist oder nur vorgegangen
+werden kann, wenn die nächste Kachel noch zur Land­
+schaft/zum Arbeitsfeld gehört und nicht blockiert ist,
+sind die Befehle 'nimm', 'gib' und 'vor' nicht uneinge­
+schränkt ausführbar. Aus diesem Grunde sind noch die
+folgenden #on("u")#Basistests#off("u")# definiert:
+
+#on("u")#vorn frei#off("u")#
+ testet, ob die vor ihm liegende Kachel frei ist.
+
+#on("u")#korn da / werkstueck da#off("u")#
+ testet, ob auf der Kachel, auf der er steht, mindestens
+ ein Korn/Werkstück liegt.
+
+#on("u")#backen leer /behaelter leer#off("u")#
+ testet, ob kein Korn/Werkstück in den Backentaschen/im
+ Behälter ist.
+
+ Darüberhinaus können Sie bei der Installation des
+Systems noch festlegen, ob die folgenden #on("u")#Zusatztests#off("u")# zur
+Verfügung stehen sollen oder nicht:
+
+#on("u")#links frei#off("u")#
+ testet, ob die Kachel links neben ihm frei ist.
+
+#on("u")#rechts frei#off("u")#
+ testet, ob die Kachel rechts neben ihm frei ist.
+
+#on("u")#hinten frei#off("u")#
+ testet, ob die Kachel hinter ihm frei ist.
+
+#on("u")#korn vorn / werkstueck vorn#off("u")#
+ testet, ob auf der Kachel vor ihm mindestens ein Korn/
+ Werkstück liegt.
+
+#on("u")#korn links / werkstueck links#off("u")#
+ testet, ob auf der Kachel links neben ihm mindestens
+ ein Korn/ Werkstück liegt.
+
+#on("u")#korn rechts / werkstueck rechts#off("u")#
+ testet, ob auf der Kachel rechts neben ihm mindestens
+ ein Korn/Werkstück liegt
+
+#on("u")#korn hinten / werkstueck hinten#off("u")#
+ testet, ob auf der Kachel hinter ihm mindestens ein
+ Korn/Werkstück liegt.
+
+ Es gibt #on("u")#keinen#off("u")# Testbefehl, mit dem überprüft werden
+kann, ob der Rand der Ebene erreicht ist.
+
+
+2.2.2 Landschaftsgestaltung/Arbeitsfeldgestaltung
+
+ Der Benutzer kann selber Landschaften/Arbeitsfelder
+erstellen, auf denen Herbert bzw. Robbi bewegt werden
+kann. Es können aber auch fertige Ebenen verändert wer­
+den.
+ Eine Landschaft/ein Arbeitsfeld ist eine Ebene aus
+23 x 40 Kacheln. Eine Kachel kann auf dem Bildschirm so
+aussehen:
+
+ Leere Kachel : Blank und Punkt (" .")
+ Kornkachel : Blank und kleines o (" o")
+ Hindernis : zwei Nummernzeichen ("\#\#")
+
+ In dieser Landschaft steht auf einer der Kacheln Her­
+bert bzw. Robbi:
+
+ "A" mit Blickrichtung nach oben
+ ">" mit Blickrichtung nach rechts
+ "V" mit Blickrichtung nach unten
+ "<" mit Blickrichtung nach links
+
+
+#on("u")#Beispiel:#off("u")# Ausschnitt aus einer Landschaft:
+
+#on("b")#
+ . . . . . . . . . . . . . . . . . . . .
+ . . o o o o o o o o o o . . . . . . . .
+ . . o . . . . . . . . o . . . . . . . .
+ . . o . . . . . . . . o . . . . . . . .
+ . o o .\#\#\#\#\#\#\#\#\#\#\#\# . o . . . . . . . .
+ . o . .\#\# .V. . .\#\# . o o o o o o o . .
+ . o . .\#\# . o . .\#\# . . . . . . . o . .
+ . o o o o o o . .\#\# . . . o o o o o . .
+ . . . .\#\# . . . .\#\# . . . o . . . . . .
+ . . . .\#\# . . . .\#\# . . . o o o o . . .
+ . . . .\#\#\#\#\#\#\#\#\#\#\#\# . . . . . . o o . .
+ . . . . . . . . . . . . . . . . . . . .
+
+Während der Landschaftsgestaltung wirken folgende
+Tasten:
+
+<h> halt, beende die Landschafts-/Arbeitsfeld­
+ gestaltung
+<\#> setze ein Hindernis und gehe ein Feld
+ weiter
+<LEERTASTE> leere das Feld und gehe ein Feld weiter
+<g> lege hier ein Korn/Werkstück ab
+<n> nimm ein Korn/Werkstück auf (falls hier
+ welche liegen)
+<z> zeige, wie viele Körner/Werkstücke hier
+ liegen
+<k> ersetze diese Landschaft/diese Arbeitsfeld
+ durch die Kopie einer bereits vorhandenen
+ anderen Landschaft/eines bereits vorhan­
+ denen anderen Arbeitsfeldes
+
+- Durch Drücken der Fragezeichentaste (<?>) während der
+ Landschafts-/Arbeitsfeldgestaltung, können Sie sich
+ diese Hinweise auch auf dem Bildschirm einblenden
+ lassen.
+
+- Mit den Pfeiltasten kann Herbert/Robbi bewegt und
+ seine Richtung verändert werden.
+
+- Die Landschaftsgestaltung wird durch Tippen der
+ Taste <h> abgeschlossen. Die Position und die Blick­
+ richtung, die Herbert bzw. Robbi zu diesem Zeitpunkt
+ innehat, wird als Startposition vermerkt.
+
+- Auf dem Bildschirm wird dann noch die Zahl der Kör­
+ ner/Werkstücke erfragt, die Herbert bzw.Robbi zu Be­
+ ginn des Laufes in seinen Backentaschen/in seinem
+ Behälter haben soll. Hier muß eine Zahl zwischen 0 und
+ 32767 eingegeben werden.
+
+
+2.3 Einsatzbereich
+
+ Das Hamster-/Roboter-Modell soll dazu dienen, die
+Grundelemente des algorithmischen Problemlösens (Folge,
+Auswahl, Wiederholung etc.) #on("u")#einfach#off("u")# und #on("u")#spielerisch#off("u")# zu
+erlernen und sie in der Programmiersprache ELAN zu co­
+dieren. In der Bildschirmdarstellung erinnert das Ham­
+ster-/Roboter-Modell zunächst an ein einfaches Tele­
+spiel, eine Anwendung des Computers, die sicher bekannt
+ist. Darüberhinaus lassen sich leicht Bezüge zur Steue­
+rung von Industrierobotern herstellen.
+ Durch die komfortable Benutzerschnittstelle wird dem
+Anwender in der Anfangsphase eine Auseinandersetzung
+mit dem Betriebssystem "erspart". Die Arbeit mit dem Mo­
+dell setzt #on("u")#keine Vorerfahrungen und Kenntnisse#off("u")# voraus.
+Das Modell ist schon nach weniger als einer halben Stun­
+de für den Anfänger überschaubar. Er kann dann schon
+Aufgaben lösen, sich selbst Aufgaben stellen bzw. die
+gegebene Aufgabenstellung erweitern.
+ Das Modell zielt auf die Aktivierung des Lernenden
+und die Mitarbeit in allen Punkten: Aufgabenstellung,
+Lösungsgestaltung, Lösungstest und -verifizierung. Der
+Lernfortschritt kann in stärkerem Maße als im "herkömm­
+lichen Programmierunterricht" von den Lernenden selbst
+bestimmt werden. Der spielerische Anfang, die Veran­
+schaulichung der Programmausführung auf dem Bild­
+schirm, die Möglichkeit Fehler direkt und eigenständig
+zu erkennen, fördern die Motivation, die Kreativität und
+die Fehler- und Frustrationstoleranz.
+
+
+2.4 Hinweise für den Einsatz in der Ausbildung
+
+ Das Hamster-/Roboter-Modell ist angelegt für "Pro­
+grammieren" mit Bleistift und (kariertem) Papier. Für die
+Überlegungen, die anzustellen sind, ist der Computer
+selbst in der Anfangsphase #on("u")#nicht notwendig#off("u")#. Man kann
+Kachel-Landschaften / Kachel-Arbeitsfelder aufzeich­
+nen und vorgegebene oder sich selbst gestellte Aufgaben
+lösen. Die erstellten Programme werden ausgeführt, indem
+man z.B. eine kleine Büroklammer als Hamster/Roboter auf
+dem Papier oder der Folie dem Programm entsprechend ver­
+schiebt. Heftzwecken oder Pfennigstücke können als Kör­
+ner/ Werkstücke und Streichholzstücke als Hindernisse
+dienen.
+ #on("b")#gs-Herbert und Robbi#off("b")# verfügt auch über die Möglich­
+keit, den Hamster/Roboter interaktiv zu steuern. Auch
+hierüber ist ein Einstieg in den Umgang mit dem Modell
+möglich. Bei der interaktiven Steuerung kann der Ham­
+ster/Roboter von Hand durch Tastendruck auf dem Bild­
+schirm bewegt werden. Dabei können nur die vier Basisbe­
+fehle ('vor', 'links um', 'nimm' und 'gib') verwendet werden.
+Während der Steuerung von Hand wird ein "Protokoll" der
+ausgeführten Befehle angelegt - und zwar gleich in Form
+eines ablauffähigen ELAN-Programms. Dadurch hat der
+Benutzer einerseits die Möglichkeit, die Anweisungen, die
+durch Tastendruck gegeben wurden, zu kontrollieren,
+andererseits kann anschließend die Folge der eingegebe­
+nen Anweisungen auch als Programm vom Computer ausge­
+führt werden ('Teach in').
+
+ Nach diesem "ersten Kennenlernen des Modells" sollte
+man dann aber bei Problemstellungen, die ein systemati­
+sches Vorgehen erfordern, die Arbeit mit dem Computer
+unterbrechen und die Algorithmen jeweils auf dem Papier
+entwerfen. Auf die Ausführung der erstellten Anwei­
+sungsfolgen von Hand auf Papier/Folie sollte man #on("u")#auf
+keinen Fall gänzlich verzichten#off("u")# - auch, um den Lernen­
+den zu verdeutlichen, daß die Befehlsfolgen sowohl vom
+"Prozessor Mensch" als auch vom "Prozessor Computer"
+ausgeführt werden können; der Computer also nur ein
+Hilfswerkzeug ist.
+ Erst wenn das Bilden eigener benannter Anweisungen
+(Refinements/Prozeduren) den Lernenden hinreichend ver­
+traut ist, ist es sinnvoll, umfangreichere Problemstel­
+lungen anzugehen. Da dann auch die Programmausführung
+von Hand mühsam wird und ihren Reiz verliert, sollte man
+(wieder) zum Computermodell übergehen, um mit dessen Hil­
+fe die Programme auszuführen und zu überprüfen.
+ Nachdem die Lernenden die Basisbefehle sicher beherr­
+schen und eigene benannte Anweisungen unter Verwendung
+der Basisbefehle konstruieren können, können dann nach
+und nach die vorgegebenen Tests und damit auch die ande­
+ren Elemente der Algorithmenentwicklung (Auswahl, Wie­
+derholung etc.) in den Unterricht eingebracht werden.
+ Als notwendig hat es sich erwiesen, von Anfang an auf
+eine saubere Strukturierung und Modularisierung der
+Algorithmen zu achten. Gerade Lernende mit "Program­
+miererfahrung" neigen dazu, möglichst "kurze" Program­
+me schreiben zu wollen. Besonderen Wert sollten Sie auf
+eine treffende Namensgebung der einzelnen Module legen,
+selbst wenn die Lernenden das oft als "lästige Schreibar­
+beit" empfinden. Aufgaben können ein Einzel-, Partner-
+und Gruppenarbeit bearbeitet werden. Dabei hat sich die
+Arbeit in kleinen Gruppen als besonders effektiv erwie­
+sen. Die Lernenden sind untereinander zumeist sehr kri­
+tisch und fordern sich gegenseitig auf, "lesbare" Pro­
+gramme zu schreiben. Ein Austausch der Programme unter
+den Gruppen kann diesen Anspruch noch zusätzlich för­
+dern.
+
+
+2.5 Aufgabenmaterial
+
+ Zum Hamster-Roboter-Modell sind inzwischen eine Rei­
+he von Aufgaben / Aufgabensystemen enstanden. An dieser
+Stelle soll auf zwei Veröffentlichungen hingewiesen
+werden, in denen Sie solche Aufgaben / Aufgabensysteme
+finden können:
+
+Weber, Wolfgang et al., Das Hamster-/Roboter-Modell,
+ in: Landesinstitut für Schule und Weiterbildung
+ (Hrsg.), Materialien zur Lehrerfortbildung in
+ Nordrhein-Westfalen, Heft 1, Neue Technologien
+ - Informations- und Kommunikationstechnologi­
+ sche Inhalte im Wahlpflichtunterricht der Klas­
+ sen 9/10, Soest, 1986
+
+Ambros, Wolfgang, Der Hamster, Programmieren lernen in
+ einer Modellwelt, J.B. Metzlersche Verlagsbuch­
+ handlung, Stuttgart, 1987
+
+
+2.6 Erfahrungen mit dem Hamster-/Roboter-Modell
+
+ Seit 1982 wird das Hamster - Modell in der GMD zur
+Programmierausbildung eingesetzt. Die Ergebnisse sind
+hervorragend: Die Teilnehmer bewältigen in derselben
+Zeit erheblich mehr Inhalte als früher ohne Modell. Moti­
+vation, Selbständigkeit und Initiative prägen sich er­
+heblich früher und merklich stärker aus. Außerdem sind
+die am Modell erworbenen Kenntnisse tiefer und sicherer.
+ Seit 1983 wird das Hamster - Modell auch in mehreren
+Schulen mit sehr gutem Erfolg eingesetzt. Der Erfolg ist
+am größten im Blockunterricht (3 - 5 Tage z.B. in Projekt­
+wochen, Schullandheimaufenthalten etc.). Aber auch im
+stundenweisen Unterricht wird das Hamster-/Roboter-
+Modell mit gutem Erfolg eingesetzt.
+ Beide Zugänge, der Einstieg über das Arbeiten mit
+Bleistift und Papier und der Einstieg über die interakti­
+ve Steuerung des Hamsters/Roboters, haben sich als prak­
+tikabel erwiesen. Der Zugang über die interaktive Steue­
+rung bietet den Vorteil, die zumeist sehr hohe Motivation
+der Lernenden, "endlich mit dem Computer arbeiten zu
+können", auszunutzen. Sie lernen dabei das Computermo­
+dell auf einfache Weise kennen und haben einen ersten
+Umgang mit Bildschirm und Tastatur. Kleine, einfache
+Problemstellungen können von ihnen durch die interak­
+tive Steuerung schnell und sicher bearbeitet werden.
+"Nebenbei" lernen sie, neben der Wirkung der Basisbefeh­
+le, durch das mitgeführte Protokoll auch die Codierung
+in der Programmiersprache kennen. Allerdings verliert
+die interaktive Steuerung relativ schnell ihren Reiz,
+wenn die Lernenden erkennen, daß nur sehr einfache Pro­
+blemstellungen damit bearbeitet werden können. Dann
+sollte aber zur Arbeit mit Papier und Bleistift überge­
+gangen werden.
+ Die Entscheidung, ganz auf das Arbeiten mit Papier
+und Bleistift zu verzichten, hat sich als sehr nachteilig
+erwiesen. Die Lernenden "hacken" die Programme in die
+Maschine und handeln eher nach dem "Prinzip von Versuch
+und Irrtum" als nach sorgfältigen Überlegungen. Bei
+komplexeren Problemstellungen scheitern diese Teilneh­
+mer zumeist.
+ Erfahrungsgemäß nimmt nach einiger Zeit der Wunsch
+stark zu, eigene Ausgaben auf dem Bildschirm zu erzeugen
+und andere Problembereiche zu bearbeiten (zum "richtigen
+Programmieren" überzugehen). Sie sollten diesen Schritt
+dann auch nicht zu lange hinauszögern und das Modell
+auf keinen Fall überstrapazieren. Da das Modell selbst
+und auch der Umgang damit sehr einfach ist, besteht auch
+später die Möglichkeit, zum Modell zurückzukehren, um
+hieran weitere Elemente der Algorithmenentwicklung in
+einfacher und anschaulicher Form einzuführen.
+
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 3 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 3
new file mode 100644
index 0000000..c34b752
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 3
@@ -0,0 +1,199 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (17)#
+#headodd#
+#center#gs-Herbert und Robbi#right#%
+
+#end#
+#headeven#
+%#center#gs-Herbert und Robbi
+
+#end#
+#center#3
+
+#center#Installation
+#center#von
+#center#gs-Herbert und Robbi
+
+
+ Bevor Sie #on("b")#gs-Herbert und Robbi#off("b")# auf Ihrem Computer
+benutzen können, müssen Sie das Programm zunächst in­
+stallieren. Wenn #on("b")#gs-Herbert und Robbi#off("b")# auf Ihrem System
+schon zur Verfügung steht, können Sie dieses Kapitel
+ruhig überspringen.
+
+
+3.1 Voraussetzungen
+
+ Um #on("b")#gs-Herbert und Robbi#off("b")# auf Ihrem Computer betreiben
+zu können, muß das EUMEL-Betriebssystem installiert
+sein. #on("b")#gs-Herbert und Robbi#off("b")# setzt die Multi-User-Version
+voraus und ist lauffähig ab Version 1.7.5. #on("b")#gs-Herbert und
+Robbi#off("b")# setzt weiterhin voraus, daß auf Ihrem Computer
+bereits das Programm #on("b")#gs-DIALOG#off("b")# installiert ist.
+
+
+3.2 Lieferumfang
+
+ #on("b")#gs-Herbert und Robbi#off("b")# wird auf einer Diskette gelie­
+fert, die alle notwendigen Programme enthält (die Instal­
+lation von #on("b")#gs-DIALOG#off("b")# wird dabei vorausgesetzt!). Um den
+Inhalt der Diskette feststellen zu können, starten Sie
+Ihr System und bringen es dazu, daß 'gib kommando:' er­
+scheint. Dann legen Sie die Diskette ein und geben das
+Kommando:
+
+archive("gs-Herbert und Robbi");list(archive);
+release(archive) <RETURN>
+
+ Anschließend erscheint eine Übersicht der auf dem
+Archiv vorhandenen Programme. Folgende Programme soll­
+ten sich in der Übersicht befinden:
+
+ "gs-Herbert und Robbi 1"
+ "gs-Herbert und Robbi 2"
+ "gs-Herbert und Robbi 3"
+ "gs-MENUKARTE:Herbert und Robbi"
+ "gs-Herbert und Robbi/gen"
+
+ Eventuell können noch weitere Namen auf der Diskette
+vorhanden sein. Wenn Sie den Inhalt der Diskette kon­
+trolliert haben und diese Programme auf der Diskette
+vorhanden sind, können Sie #on("b")#gs-Herbert und Robbi#off("b")# instal­
+lieren.
+ Sollten Sie statt der Übersicht eine Fehlermeldung
+erhalten, überprüfen Sie bitte, ob die Diskette das rich­
+tige Format besitzt oder ob Ihr Diskettenlaufwerk Pro­
+bleme macht. Sollten dagegen Programme fehlen, so rekla­
+mieren Sie die Diskette.
+
+
+3.3 Installation
+
+ #on("b")#gs-Herbert und Robbi#off("b")# muß in einer Task installiert
+werden, in der bereits das Programm #on("b")#gs-DIALOG#off("b")# zur Ver­
+fügung steht. Alle Söhne und Enkel der neuen Task kön­
+nen anschließend das Hamster-/ Roboter-Modell aufrufen.
+Richten Sie also eine Task als Sohn der Task ein, in der
+auf Ihrem Computer bereits #on("b")#gs-DIALOG#off("b")# installiert ist. Wir
+nehmen hier an, daß #on("b")#gs-DIALOG#off("b")# in der Task 'MENU' instal­
+liert ist und die neue Task den Namen 'HAMSTER' erhalten
+soll. (Sie können für die Task auch einen beliebigen an­
+deren Namen wählen):
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+
+#off("b")#
+ --> gib supervisor kommando:
+#on("b")#
+ begin ("HAMSTER","MENU") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+
+ (Arbeiten mehrere Personen mit dem Computer, dann ist
+es sinnvoll, diese Task vor unbefugtem Zugriff durch ein
+Passwort zu schützen. Wie das gemacht wird, können Sie in
+Ihrem EUMEL-Benutzerhandbuch erfahren.)
+
+ Legen Sie dann die Archivdiskette ein, auf der sich
+#on("b")#gs-Herbert und Robbi#off("b")# befindet, und geben Sie das folgen­
+de Kommando:
+
+#on("b")#
+ archive("gs-Herbert und Robbi") <RETURN>
+
+ fetch("gs-Herbert und Robbi/gen",archive) <RETURN>
+
+ run <RETURN>
+#off("b")#
+
+ Sie haben damit das Generatorprogramm gestartet.
+Zunächst werden Sie gefragt, ob Sie den erweiterten Be­
+fehlssatz (mit Zusatztests) für den Hamster und Roboter
+zur Verfügung gestellt haben möchten. Beantworten Sie
+diese Frage je nach Wunsch mit 'ja' oder 'nein' durch Tip­
+pen der Taste <j> bzw. <n>.
+ Daraufhin wird die Installation automatisch durchge­
+führt. Lassen Sie während des gesamten Vorgangs die Ar­
+chivdiskette eingelegt. Die Generierung ist beendet, wenn
+der EUMEL-Eingangsbildschirm erscheint. Die Task, in der
+die Generierung stattfindet, wird automatisch zur Mana­
+gertask, das heißt, daß Söhne von ihr eingerichtet werden
+können.
+ Richten Sie sich gleich eine Sohntask (z.B mit dem Na­
+men 'hamster1') ein, dann können Sie das System sofort
+ausprobieren. Gehen Sie dazu folgendermaßen vor:
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+
+#off("b")#
+ --> gib supervisor kommando:
+#on("b")#
+ begin ("hamster1","HAMSTER") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+
+
+Mit dem Kommando
+
+#center##on("b")#hamster <RETURN> bzw. roboter <RETURN>#off("b")#
+
+rufen Sie nun das
+
+#center#Hamster-Modell bzw. Roboter-Modell
+
+auf.
+
+
+3.4 Direktstart des Modells
+ (Steht erst ab gs-DIALOG Version 1.1 zur Verfügung)
+
+ In Kapitel 3.3 haben wir Ihnen gezeigt, wie sie eine
+Sohntask einrichten und hier durch das Kommando 'ham­
+ster' bzw. 'roboter' das System aufrufen können. Wenn Sie
+immer nur mit einer Modellvariante arbeiten oder vor dem
+Benutzer die 'gib kommando:'-Ebene verbergen wollen,
+können Sie das System auch so einrichten, daß sich sofort
+nach Einrichten des Arbeitsbereichs das Menusystem mel­
+det. Für den Anfänger kann das die Arbeit durchaus er­
+leichtern.
+ Gehen Sie dazu in die Task, unterhalb der die Sohntasks
+eingerichtet werden sollen:
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+
+#off("b")#
+ --> gib supervisor kommando:
+#on("b")#
+ continue ("HAMSTER") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+#on("b")#
+ direktstart ("hamster", TRUE) <RETURN>
+#off("b")#
+
+ Durch das Kommando haben Sie festgelegt, daß sich
+alle Sohntasks direkt mit dem Hamstermenu melden. Möch­
+ten Sie lieber mit dem Roboter-Modell arbeiten, ist nur
+'hamster' durch 'roboter' zu ersetzen.
+ Durch den zweiten Parameter 'TRUE' legen Sie fest, daß
+in den Sohntasks nach Verlassen des Menus die jeweilige
+Task automatisch gelöscht wird. Statt 'TRUE' können Sie
+hier auch den Wert 'FALSE' eintragen. Dann wird nach Ver­
+lassen des Menus angefragt, ob die Task gelöscht werden
+soll. Wird die Frage bejaht, wird gelöscht - sonst wird die
+Task abgekoppelt (break) und kann durch 'continue' wieder
+angekoppelt werden.
+ Anmerkung: In der Task, in der Sie das Kommando
+'direktbefehl' gegeben haben, sollte nicht das Kommando
+'monitor' gegeben werden, da Sie durch dieses Kommando
+auch diese Task zu einer Task machen, die sich direkt mit
+dem Menu meldet und ggf. bei Verlassen des Menus automa­
+tisch gelöscht wird!
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 4 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 4
new file mode 100644
index 0000000..4f2d79a
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 4
@@ -0,0 +1,1312 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (22)#
+#headodd#
+#center#gs-Herbert und Robbi#right#%
+
+#end#
+#headeven#
+%#center#gs-Herbert und Robbi
+
+#end#
+#center#4
+
+#center#Beschreibung
+#center#der
+#center#Menufunktionen
+
+
+ Nach Aufruf meldet sich #on("b")#gs-Herbert und Robbi mit
+#on("u")#einem#off("u")# der folgenden Menus:
+
+
+#on("b")#
+HAMSTER: Info Landschaft Programm Lauf Archiv
++---------------------------+--------------------------------------------
+| l Landschaftsgestaltung |
+| b Befehlsvorrat |
+| s Steuerung des Laufs |
++---------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+-------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+#on("u")#oder#off("u")#
+
+#on("b")#
+ROBOTER: Info Arbeitsfeld Programm Lauf Archiv
++----------------------------+--------------------------------------------
+| a Arbeitsfeldgestaltung |
+| b Befehlsvorrat |
+| s Steuerung des Laufs |
++----------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+ Beide Varianten sind, wie schon gesagt, analog auf­
+gebaut. Aus diesem Grunde werden wir uns in den folgen­
+den Ausführungen auf die Beschreibung der Hamster -
+Variante beschränken.
+
+
+4.1 Kurzhinweise zur Bedienung des Menus
+
+ Die Bedienung des Menus ist sehr einfach. Eine aus­
+führliche Beschreibung dazu finden Sie in den Unterla­
+gen zum Programmsystem #on("b")#gs-DIALOG#off("b")#. An dieser Stelle sol­
+len nur die wesentlichen Bedienungsvorgänge beschrieben
+werden.
+
+- Mit der Tastenfolge <ESC><?> können Sie sich Informa­
+ tionen zur Bedienung des Menusystems in das Menu
+ einblenden lassen
+
+- Mit den Pfeiltasten <rechts> und <links> können Sie
+ zwischen den "Oberbegriffen" in der Kopfzeile wählen.
+ Der aktuelle Oberbegriff ist jeweils invers darge­
+ stellt. Das ausgeklappte 'Pull-Down-Menu' bezieht sich
+ auf diesen invers dargestellten Oberbegriff.
+
+- Mit den Pfeiltasten <hoch> und <runter> können Sie
+ zwischen den Menufunktionen wählen, die Ihnen im
+ aktuellen Pull-Down-Menu zur Auswahl angeboten
+ werden. Die aktuell angewählte Menufunktion wird
+ jeweils invers dargestellt. Die Trennlinien, die in
+ einigen Pull-Down-Menus sichtbar sind, dienen nur
+ der optischen Untergliederung; sie können nicht an­
+ gewählt werden und werden deshalb automatisch über­
+ sprungen. Die einzelnen Menupunkte sind "zyklisch
+ miteinander verknüpft", das heißt, man gelangt vom
+ untersten Menupunkt wieder zum obersten und umge­
+ kehrt. Menupunkte, vor denen ein Minuszeichen steht
+ ('-'), sind (zur Zeit) nicht aktivierbar; auch sie können
+ nicht angewählt werden und werden einfach über­
+ sprungen.
+
+- Durch Tippen der Fragezeichentaste (<?>) können Sie
+ sich jeweils zur aktuellen Menufunktion (invers im
+ Pull-Down-Menu) Informationen in das Menu einblen­
+ den lassen.
+
+- Um eine Menufunktion ausführen zu lassen, bewegen
+ Sie sich mit den Pfeiltasten auf die gewünschte Menu­
+ funktion im aktuellen Pull-Down-Menu und tippen
+ dann die <RETURN>-Taste. Steht vor dem gewünschten
+ Menupunkt ein einzelner Buchstabe oder eine Ziffer,
+ so kann durch Tippen der entsprechenden Taste diese
+ Menufunktion dadurch direkt aufgerufen werden. So­
+ bald eine Menufunktion aufgerufen worden ist, er­
+ scheint davor ein Stern ('*'). Daraus können Sie ent­
+ nehmen, daß das System bereits den Auftrag ausführt.
+
+- An verschiedenen Stellen werden Fragen an Sie ge­
+ richtet, die Sie mit 'ja' oder 'nein' beantworten müssen.
+ Tippen Sie dazu entsprechend der Entscheidung die
+ Taste <j> (für 'ja') bzw. <n> (für 'nein').
+
+- Werden Ihnen vom Menu aus Dateinamen zur Auswahl
+ angeboten, so können Sie den auf dem Bildschirm
+ sichtbaren Pfeil vor den gewünschten Namen positio­
+ nieren. Mit den Tasten <x> oder <RETURN> können Sie
+ den Namen ankreuzen. Ist die Auswahl mehrerer Datein­
+ amen möglich, so können Sie den Vorgang wiederholen.
+ Mit den Tasten <o> oder <RUBOUT> können Sie auch ein
+ Kreuz vor einem Namen wieder löschen. Daneben gibt es
+ noch einige Tastenfunktionen, die für die Bedienung
+ recht hilfreich sein können. Tippen Sie während der
+ Auswahl die Fragezeichentaste (<?>), so werden Ihnen
+ alle Bedienungsmöglichkeiten auf dem Bildschirm an­
+ gezeigt. Eine Auswahl, in der mehrere Dateien ange­
+ kreuzt werden dürfen, wird durch die Tastenfolge
+ <ESC><q> verlassen. Anschließend wird die eingestellte
+ Operation mit den angekreuzten Dateien ausgeführt.
+ Sind Sie versehentlich in eine solche Auswahl ge­
+ langt, so können Sie den Vorgang durch die Tasten­
+ kombination <ESC><h> abbrechen.
+
+- An einigen Stellen werden Sie aufgefordert, eine Ein­
+ gabe zu machen (z.B. einen Dateinamen einzugeben). Wird
+ Ihnen hier ein Vorschlag gemacht, den Sie akzeptieren,
+ so brauchen Sie zur Bestätigung nur die <RETURN>-
+ Taste zu tippen. Gefällt Ihnen der Vorschlag nicht
+ oder wird Ihnen kein Vorschlag gemacht, so machen Sie
+ bitte die gewünschte Eingabe. Zum Schreiben stehen
+ Ihnen alle aus dem Editor bekannten Funktionen zur
+ Verfügung. Mit der Taste <RUBOUT> können Sie Buch­
+ staben löschen, mit <RUBIN> einfügen. Die Eingabe wird
+ durch Tippen der <RETURN>-Taste abgeschlossen. Ist
+ der von Ihnen gewünschte Name schon in Ihrer Task
+ vorhanden und steht in der Fußzeile der Hinweis 'Zei­
+ gen: <ESC><z>', dann können Sie sich auch alle vorhan­
+ denen Namen zur Auswahl anbieten lassen und durch
+ Ankreuzen den beabsichtigten Namen auswählen.
+
+- Ihnen können auch mehrere Alternativen angeboten
+ werden, zwischen denen Sie wählen müssen. In der un­
+ tersten Zeile eines solchen Kastens, in denen Ihnen die
+ Alternativen auf dem Bildschirm eingeblendet werden,
+ sind die Möglichkeiten aufgeführt, die darüber be­
+ schrieben sind. Mit den Pfeiltasten können sie die
+ Markierung auf die gewünschte Alternative positio­
+ nieren und dann durch die <RETURN>-Taste zur Aus­
+ führung bringen. (Manchmal ist das auch durch Tippen
+ der den Alternativen vorangestellten Buchstaben oder
+ Ziffern möglich).
+
+- Durch die Tastenfolge <ESC><q> kann das Menu insge­
+ samt verlassen werden. Damit das nicht versehentlich
+ geschieht, wird jeweils die Frage gestellt, ob Sie das
+ Menu tatsächlich verlassen wollen. Diese Frage beant­
+ worten Sie bitte je nach Wunsch mit 'ja' oder 'nein'
+ durch Tippen der Tasten <j> bzw. <n>.
+
+#page#
+4.2 Menufunktionen zum Oberbegriff 'Info'
+
+ Das auf dem Bildschirm sichtbare Pull-Down-Menu ist
+oben abgebildet.
+
+#on("u")##on("b")#l Landschaftsgestaltung (a Arbeitsfeldgestaltung)#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich alle Tasten,
+ die bei der Landschafts-/Arbeitsfeldgestaltung
+ wirksam sind, anzeigen lassen.
+ In der Anzeige wird die jeweilige Tastenfunktion
+ erläutert. Während der Landschafts-/Arbeitsfeld­
+ gestaltung können Sie sich diese Informationen
+ durch Tippen der Fragezeichentaste (<?>) ebenfalls
+ einblenden lassen.
+
+#on("u")##on("b")#b Befehlsvorrat#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich die Befehle,
+ die Ihnen vom jeweiligen Modell zur Verfügung ge­
+ stellt werden, auf dem Bildschirm anzeigen lassen.
+ Anhand dieser Informationen können Sie auch
+ feststellen, ob in dem System, das Ihnen zur Verfü­
+ gung steht, der "eingeschränkte" oder "erweiterte"
+ Befehlssatz hinsichtlich der Tests realisiert ist.
+
+#on("u")##on("b")#s Steuerung des Laufs#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich die Möglich­
+ keiten anzeigen lassen, wie Sie auf einen Hamster-
+ /Roboterlauf durch Tastendruck Einfluß nehmen
+ können:
+
+ <ESC> : beende den Lauf (Programmabbruch
+ durch Tastendruck)
+ <?> : zeige diese Information (während des
+ Programmablaufs!)
+
+ 0 : Einzelschritt (dazu beliebige Taste
+ drücken)
+ 1 : geringste Geschwindigkeit
+ 9 : höchste Geschwindigkeit
+ 2 ... 8 : dazwischenliegende Geschwindigkeiten
+
+ <+> : laufe schneller
+ <-> : laufe langsamer
+
+ Zu Beginn eines Laufes ist die Geschwindigkeit '5'
+ eingestellt.
+#page#
+4.3 Menufunktionen zum Oberbegriff 'Landschaft'(Ar­
+ beitsfeld)
+
+#on("b")#
+HAMSTER: Info Landschaft Programm Lauf Archiv
+----------+--------------------+------------------------------------------
+ | n Neu erstellen |
+ | a Ansehen/Ändern |
+ | ---------------- |
+ | v Verzeichnis |
+ | ---------------- |
+ | l Löschen |
+ | d Drucken |
+ | ---------------- |
+ | k Kopieren |
+ | u Umbenennen |
+ +--------------------+
+
+
+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+#on("u")##on("b")#n Neu erstellen#off("b")##off("u")#
+ Mit dieser Funktion können Sie eine neue Land­
+ schaft/ein neues Arbeitsfeld unter einem neuen
+ Namen anlegen und gestalten.
+ Sie werden zunächst nach einem Namen für die
+ #on("u")#neue#off("u")# Landschaft/das #on("u")#neue#off("u")# Arbeitsfeld gefragt. Ge­
+ ben Sie einen beliebigen Namen (#on("u")#ohne Anführungs­
+ zeichen (!)#off("u")# und #on("u")#ohne das Präfix 'Flaeche:' (!)#off("u")#) ein und
+ schließen Sie die Eingabe durch <RETURN> ab. Dar­
+ aufhin wird Ihnen auf dem Bildschirm eine leere
+ Landschaft/ein leeres Arbeitsfeld angeboten.
+ Sollte schon eine Landschaft/ein Arbeitsfeld
+ mit diesem Namen in der Task vorhanden sein, so
+ werden Sie darauf aufmerksam gemacht. Sie können
+ sich während der Landschaftsgestaltung auch je­
+ derzeit eine Aufstellung der wirksamen Tasten mit
+ Beschreibung der Funktionen auf den Bildschirm
+ ausgeben lassen. Drücken Sie dazu die Fragezeichen­
+ taste (<?>).
+
+ Fehlerfälle:
+ - Eine Landschaft/ein Arbeitsfeld mit dem vorge­
+ schlagenen Namen existiert schon.
+
+#on("u")##on("b")#a Ansehen/Ändern#off("b")##off("u")#
+ Mit dieser Funktion können Sie schon in Ihrer
+ Task existierende Landschaften/Arbeitsfelder zur
+ Ansicht oder zur Überarbeitung anfordern.
+ Sie werden zunächst gefragt, ob Sie #on("u")#die zuletzt
+ bearbeitete Landschaft#off("u")#/#on("u")#das zuletzt bearbeitete Ar­
+ beitsfeld#off("u")# ansehen bzw. verändern möchten (sofern
+ Sie schon vorher mit dem Modell in der Task gear­
+ beitet haben).
+ Bejahen Sie diese Frage, dann wird Ihnen diese
+ Landschaft/dieses Arbeitsfeld zur Bearbeitung
+ angeboten. Verneinen Sie die Frage dagegen, so ge­
+ langen Sie in die 'Auswahl' (d.h es werden Ihnen alle
+ Landschaften/Arbeitsfelder in der Task zur Auswahl
+ angeboten). Nachdem Sie einen der Namen angekreuzt
+ haben, wird Ihnen die ausgewählte Landschaft/das
+ ausgewählte Arbeitsfeld zur Bearbeitung auf dem
+ Bildschirm angeboten. Ihnen stehen die Tastenfunk­
+ tionen wie bei der Neuerstellung zur Verfügung.
+
+ Fehlerfälle:
+ - In der Task existiert noch keine Landschaft/kein
+ Arbeitsfeld.
+
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich einen Über­
+ blick über die in Ihrer Task vorhandenen Land­
+ schaften/Arbeitsfelder verschaffen.
+ Nach Aufruf dieser Funktion wird eine Liste der
+ Landschaften/Arbeitsfelder auf dem Bildschirm
+ ausgegeben, die sich in Ihrer Task befinden. Da die
+ Liste selbst eine Datei ist, kann Sie mit der Tasten­
+ kombination <ESC><q> verlassen werden - hierauf
+ wird auch in der Kopfzeile der Datei hingewiesen.
+ Falls nicht alle Namen auf den Bildschirm passen,
+ können Sie das Fenster mit <HOP><runter> und
+ <HOP><hoch> verschieben.
+
+#on("u")##on("b")#l Löschen#off("b")##off("u")#
+ Mit dieser Funktion können Sie Landschaften/
+ Arbeitsfelder, die Sie nicht mehr benötigen, die
+ unnötig Platz belegen, löschen. Aber Vorsicht! Die
+ Landschaften/Arbeitsfelder verschwinden durch
+ diese Funktion unwiederbringlich!
+ Nach Aufruf dieser Funktion werden Ihnen alle
+ Landschaften/Arbeitsfelder, die sich in Ihrer Task
+ befinden, zur Auswahl angeboten. Hier können Sie
+ die gewünschten Namen ankreuzen. Die Auswahl wird
+ dann durch die Tastenfolge <ESC><q> verlassen.
+ Für jede einzelne Landschaft/jedes einzelne Ar­
+ beitsfeld wird noch einmal zur Sicherheit gefragt,
+ ob sie/es auch tatsächlich gelöscht werden soll. Zur
+ Bestätigung tippen Sie bitte die Taste <j> ('ja') - zur
+ Verhinderung <n> ('nein').
+
+ Fehlerfälle:
+ - In der Task exsitiert noch keine Landschaft/
+ kein Arbeitsfeld.
+
+#on("u")##on("b")#d Drucken#off("b")##off("u")#
+ Mit dieser Funktion können Sie Landschaften/
+ Arbeitsfelder über einen angeschlossenen Drucker
+ ausgeben lassen.
+ Nach Aufruf dieser Funktion werden Ihnen alle
+ Landschaften/Arbeitsfelder, die sich in Ihrer Task
+ befinden, zur Auswahl angeboten. Hier können Sie
+ die gewünschten Namen ankreuzen. Die Auswahl wird
+ dann durch die Tastenfolge <ESC><q> verlassen.
+ Die angekreuzten Landschaften/Arbeitsfelder
+ werden anschließend zum Drucker geschickt. Der
+ Vorgang wird auf dem Bildschirm protokolliert.
+
+ Fehlerfälle:
+ - In der Task existiert noch keine Landschaft/
+ kein Arbeitsfeld.
+ - Der Drucker ist nicht funktionsbereit.
+ - Der Drucker wird nicht über die Task 'PRINTER'
+ betrieben.
+ - Auf Ihrem System werden die Druckkosten abge­
+ rechnet. Sie müssen sich mit einer Codenummer
+ identifizieren.
+
+#on("u")##on("b")#k Kopieren#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich eine Kopie
+ einer/eines bereits in der Task vorhandenen Land­
+ schaft/Arbeitsfeldes anlegen. Das ist z.B. dann
+ sinnvoll, wenn Sie sich einen bestimmten 'Stand'
+ aufbewahren wollen oder wenn Sie eine Land­
+ schaft/ein Arbeitsfeld gestalten wollen, das einem
+ bereits vorhandenen ähnelt.
+ Nach Aufruf dieser Funktion werden Ihnen alle
+ Landschaften/Arbeitsfelder, die sich in Ihrer Task
+ befinden, zur Auswahl angeboten. Nach Ankreuzen
+ eines Namens wird die Auswahl automatisch verlas­
+ sen.
+ Anschließend wird der angekreuzte Name ange­
+ zeigt und der Name für die Kopie erfragt. Es muß ein
+ Name eingetragen werden, der in dieser Task noch
+ nicht für eine Landschaft/ein Arbeitsfeld verge­
+ ben wurde - ansonsten erfolgt ein Hinweis darauf
+ und es wird nicht kopiert!
+ Da man aber oft für die Kopie einen ähnlichen
+ Namen wie für das Original wählt, wird der 'alte'
+ Name vorgeschlagen. Aus genannten Gründen muß er
+ aber verändert werden. Sie können diesen Namen mit
+ den üblichen Editierfunktionen verändern oder mit
+ <HOP><RUBOUT> löschen und ganz neu eingeben. Sie
+ sparen aber eine Menge Tipparbeit, wenn Sie einen
+ langen Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Landschaft/ein Arbeitsfeld mit dem ge­
+ wünschten Namen existiert bereits in der Task.
+
+#on("u")##on("b")#u Umbenennen#off("b")##off("u")#
+ Mit dieser Funktion können Sie einer bereits
+ vorhandenen Landschaft/einem bereits vorhandenen
+ Arbeitsfeld einen neuen Namen geben.
+ Nach Aufruf dieser Funktion werden Ihnen alle
+ Landschaften/Arbeitsfelder, die sich in Ihrer Task
+ befinden, zur Auswahl angeboten. Nach Ankreuzen
+ eines Namens wird die Auswahl automatisch verlas­
+ sen.
+ Anschließend wird dieser Name angezeigt und der
+ zukünftige Name für die Landschaft/das Arbeitsfeld
+ erfragt. Es muß ein Name eingetragen werden, der in
+ dieser Task noch nicht für eine Landschaft/ein Ar­
+ beitsfeld vergeben wurde - ansonsten erfolgt ein
+ Hinweis darauf und die Landschaft/das Arbeitsfeld
+ wird nicht umbenannt!
+ Da man aber oft den 'neuen' Namen in Anlehnung
+ an den 'alten' Namen wählt, wird der 'alte' Name vor­
+ geschlagen. Aus genannten Gründen muß er aber
+ verändert werden. Sie können diesen Namen mit den
+ üblichen Editierfunktionen verändern oder mit
+ <HOP><RUBOUT> löschen und ganz neu eingeben. Sie
+ sparen aber eine Menge Tipparbeit, wenn Sie einen
+ langen Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Datei mit dem gewünschten Namen existiert
+ bereits in der Task.
+#page#
+4.4 Menufunktionen zum Oberbegriff 'Programm'
+
+#on("b")#
+HAMSTER: Info Landschaft Programm Lauf Archiv
+---------------------+--------------------+-------------------------------
+ | n Neu erstellen |
+ | a Ansehen/Ändern |
+ | ---------------- |
+ | v Verzeichnis |
+ | ---------------- |
+ | l Löschen |
+ | d Drucken |
+ | ---------------- |
+ | k Kopieren |
+ | u Umbenennen |
+ +--------------------+
+
+
+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+#on("u")##on("b")#n Neu erstellen#off("b")##off("u")#
+ Mit dieser Funktion können Sie eine neue Pro­
+ grammdatei anlegen und beschreiben.
+ Sie werden zunächst nach einem Namen für die
+ #on("u")#neue#off("u")# Programmdatei gefragt. Geben Sie einen belie­
+ bigen Namen (#on("u")#ohne Anführungszeichen (!)#off("u")#) ein und
+ schließen Sie die Eingabe durch <RETURN> ab. Dar­
+ aufhin wird Ihnen auf dem Bildschirm eine neue Da­
+ tei zum Beschreiben angeboten.
+ Sollte schon eine Programmdatei mit diesem Na­
+ men in der Task vorhanden sein, so werden Sie dar­
+ auf aufmerksam gemacht.
+ Sie können sich während des Schreibens die
+ wichtigsten Tastenfunktionen des Editers einblen­
+ den lassen. Tippen Sie dazu die Tastenfolge <ESC><?>.
+ Es erscheint dann das folgende Angebot aus dem Sie
+ auswählen können:
+
+ #on("b")#
+ +--------------------------------------------------+
+ | Der EUMEL - Editor |
+ | |
+ | b ... Beschreibung des Editors |
+ | w ... Wichtige Tasten |
+ | p ... Positionieren der Schreibmarke |
+ | k ... Korrigieren im Text (Einfügen/Löschen) |
+ | m ... Markierte Textpassagen bearbeiten |
+ | l ... Lernen im Editor |
+ | a ... Anweisungen im Editor (Kommandodialog) |
+ | |
+ | z ... Zurück in den Schreibmodus |
+ | |
+ | b w p k m l a z |
+ +--------------------------------------------------+
+#off("b")#
+
+ Fehlerfälle:
+ - Eine Datei mit dem vorgeschlagenen Namen exi­
+ stiert schon.
+
+#on("u")##on("b")#a Ansehen/Ändern#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich Dateien, die
+ schon in Ihrer Task existieren, ansehen oder auch
+ verändern.
+ Sie werden zunächst gefragt, ob Sie #on("u")#die zuletzt
+ bearbeitete Programmdatei#off("u")# ansehen bzw. verändern
+ möchten (sofern Sie schon vorher mit dem Modell in
+ der Task gearbeitet haben).
+ Bejahen Sie diese Frage, dann wird Ihnen diese
+ Programmdatei zur Bearbeitung angeboten. Vernei­
+ nen Sie die Frage dagegen, so gelangen Sie in die
+ 'Auswahl' (d.h es werden Ihnen alle Programmdateien
+ in der Task zur Auswahl angeboten). Nachdem Sie
+ einen der Namen angekreuzt haben, wird Ihnen die
+ ausgewählte Programmdatei zur Bearbeitung auf dem
+ Bildschirm angeboten.
+
+ Fehlerfälle:
+ - In der Task existiert noch keine Programmdatei.
+
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich einen Über­
+ blick über die in Ihrer Task vorhandenen Programm­
+ dateien verschaffen.
+ Nach Aufruf dieser Funktion wird eine Liste der
+ Programmdateien auf dem Bildschirm ausgegeben, die
+ sich in Ihrer Task befinden. Da die Liste selbst eine
+ Datei ist, kann Sie mit der Tastenkombination
+ <ESC><q> verlassen werden - hierauf wird auch in
+ der Kopfzeile der Datei hingewiesen. Falls nicht
+ alle Namen auf den Bildschirm passen, können Sie
+ das Fenster mit <HOP><runter> und <HOP><hoch> ver­
+ schieben.
+
+#on("u")##on("b")#l Löschen#off("b")##off("u")#
+ Mit dieser Funktion können Sie Programmdateien,
+ die Sie nicht mehr benötigen, die unnötig Platz be­
+ legen, löschen. Aber Vorsicht! Die Programmdateien
+ verschwinden durch diese Funktion unwieder­
+ bringlich!
+ Nach Aufruf dieser Funktion werden Ihnen alle
+ Programmdateien, die sich in Ihrer Task befinden,
+ zur Auswahl angeboten. Hier können Sie die ge­
+ wünschten Namen ankreuzen. Die Auswahl wird dann
+ durch die Tastenfolge <ESC><q> verlassen.
+ Für jede einzelne Programmdatei wird noch ein­
+ mal zur Sicherheit gefragt, ob sie auch tatsächlich
+ gelöscht werden soll. Zur Bestätigung tippen Sie
+ bitte die Taste <j> ('ja') - zur Verhinderung <n>
+ ('nein').
+
+ Fehlerfälle:
+ - In der Task exsitiert noch keine Programmdatei
+
+#on("u")##on("b")#d Drucken#off("b")##off("u")#
+ Mit dieser Funktion können Sie Programmdateien
+ über einen angeschlossenen Drucker ausgeben las­
+ sen.
+ Nach Aufruf dieser Funktion werden Ihnen alle
+ Programmdateien, die sich in Ihrer Task befinden,
+ zur Auswahl angeboten. Hier können Sie die ge­
+ wünschten Namen ankreuzen. Die Auswahl wird dann
+ durch die Tastenfolge <ESC><q> verlassen.
+ Die angekreuzten Programmdateien werden an­
+ schließend zum Drucker geschickt. Der Vorgang wird
+ auf dem Bildschirm protokolliert.
+
+ Fehlerfälle:
+ - In der Task existiert noch keine Programmdatei.
+ - Der Drucker ist nicht funktionsbereit.
+ - Der Drucker wird nicht über die Task 'PRINTER'
+ betrieben.
+ - Auf Ihrem System werden die Druckkosten abge­
+ rechnet. Sie müssen sich mit einer Codenummer
+ identifizieren.
+
+#on("u")##on("b")#k Kopieren#off("b")##off("u")#
+ Mit dieser Funktion können Sie sich eine Kopie
+ einer bereits in der Task vorhandenen Programmda­
+ tei anlegen. Das ist z.B. dann sinnvoll, wenn Sie sich
+ einen bestimmten 'Stand' aufbewahren wollen oder
+ wenn Sie ein Programm schreiben wollen, das einem
+ bereits vorhandenen ähnelt.
+ Nach Aufruf dieser Funktion werden Ihnen alle
+ Programmdateien, die sich in Ihrer Task befinden,
+ zur Auswahl angeboten. Nach Ankreuzen eines Na­
+ mens wird die Auswahl automatisch verlassen.
+ Anschließend wird der angekreuzte Name ange­
+ zeigt und der Name für die Kopie erfragt. Es muß ein
+ Name eingetragen werden, der in dieser Task noch
+ nicht für eine Programmdatei vergeben wurde; an­
+ sonsten erfolgt ein Hinweis darauf und es wird
+ nicht kopiert!
+ Da man aber oft für die Kopie einen ähnlichen
+ Namen wie für das Original wählt, wird der 'alte'
+ Name vorgeschlagen. Aus genannten Gründen muß er
+ aber verändert werden. Sie können diesen Namen mit
+ den üblichen Editierfunktionen verändern oder mit
+ <HOP><RUBOUT> löschen und ganz neu eingeben. Sie
+ sparen aber eine Menge Tipparbeit, wenn Sie einen
+ langen Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Programmdatei mit dem gewünschten Namen
+ existiert bereits in der Task.
+
+#on("u")##on("b")#u Umbenennen#off("b")##off("u")#
+ Mit dieser Funktion können Sie einer bereits
+ vorhandenen Programmdatei einen neuen Namen ge­
+ ben.
+ Nach Aufruf dieser Funktion werden Ihnen alle
+ Programmdateien, die sich in Ihrer Task befinden,
+ zur Auswahl angeboten. Nach Ankreuzen eines Na­
+ mens wird die Auswahl automatisch verlassen.
+ Anschließend wird dieser Name angezeigt und der
+ zukünftige Name für die Programmdatei erfragt. Es
+ muß ein Name eingetragen werden, der in dieser Task
+ noch nicht für eine Programmdatei vergeben wurde -
+ ansonsten erfolgt ein Hinweis darauf und die Pro­
+ grammdatei wird nicht umbenannt!
+ Da man aber oft den 'neuen' Namen in Anlehnung
+ an den 'alten' Namen wählt, wird der 'alte' Name vor­
+ geschlagen. Aus genannten Gründen muß er aber
+ verändert werden. Sie können diesen Namen mit den
+ üblichen Editierfunktionen verändern oder mit
+ <HOP><RUBOUT> löschen und ganz neu eingeben. Sie
+ sparen aber eine Menge Tipparbeit, wenn Sie einen
+ langen Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Programmdatei mit dem gewünschten Namen
+ existiert bereits in der Task.
+#page#
+4.5 Menufunktionen zum Oberbegriff 'Lauf'
+
+#on("b")#
+HAMSTER: Info Landschaft Programm Lauf Archiv
+---------------------------+------------------------+---------------------
+ | l Lauf nach Programm |
+ | h Handsteuerung |
+ +------------------------+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+#on("u")##on("b")#l Lauf nach Programm#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie den Ham­
+ ster/Roboter nach einem Programm in einer Land­
+ schaft/einem Arbeitsfeld laufen lassen. Sowohl das
+ Programm als auch die Landschaft/das Arbeitsfeld
+ müssen bereits existieren.
+ Sie werden zunächst gefragt, ob der Hamster/
+ Roboter #on("u")#das zuletzt bearbeitete Programm#off("u")# ausführen
+ soll. Bejahen Sie die Frage, so wird dieses Programm
+ ausgeführt; verneinen Sie die Frage dagegen, so
+ gelangen Sie in die 'Auswahl'. Nach Ankreuzen des
+ gewünschten Programmnamens wird das ausgewählte
+ Programm ausgeführt.
+ Nach der Abfrage bezüglich des Programmnamens
+ erfolgt dann eine weitere Abfrage nach dem Namen
+ der Landschaft/ des Arbeitsfeldes, in der/dem der
+ Hamster/Roboter nach dem zuvor ausgewählten Pro­
+ gramm laufen soll. Auch hier werden Sie zunächst
+ gefragt, ob Sie #on("u")#die zuletzt benutzte Landschaft/das
+ zuletzt benutzte Arbeitsfeld#off("u")# verwenden möchten.
+ Bejahen Sie die Frage, so wird das Programm in
+ dieser Landschaft/in diesem Arbeitsfeld ausge­
+ führt; verneinen Sie dagegen die Frage, so werden
+ Ihnen alle in der Task vorhandenen Landschaften/
+ Arbeitsfelder zur Auswahl angeboten. Durch An­
+ kreuzen eines Landschafts-/Arbeitsfeldnamens wird
+ die betreffende Landschaft/das betreffende Ar­
+ beitsfeld ausgewählt und das Programm in dieser
+ Landschaft/in diesem Arbeitsfeld ausgeführt.
+ Daneben haben Sie auch die Möglichkeit, im Pro­
+ gramm selbst als erste Anweisung den Befehl 'lands­
+ chaft ("Name");' oder 'arbeitsfeld ("Name");' anzuge­
+ ben. Für 'Name' muß dann natürlich der gewünschte
+ Landschafts-/Arbeitsfeldname eingetragen sein. Ist
+ eine solche Anweisung #on("u")#am Programmanfang#off("u")# vorhan­
+ den, so wird an Sie #on("u")#keine#off("u")# Abfrage bezüglich des
+ Landschafts-/Arbeitsfeldnamens gestellt; das Pro­
+ gramm wird in der #on("u")#angegebenen#off("u")# Landschaft/im #on("u")#ange­
+ gebenen#off("u")# Arbeitsfeld ausgeführt.
+ Sind im Programm noch Fehler enthalten, so wer­
+ den das Programm und die Fehlermeldungen gleich­
+ zeitig auf dem Bildschirm dargestellt (Paralleledi­
+ tor) und zur Korrektur angeboten. Für die Pro­
+ grammkorrektur stehen ebenfalls alle Editorfunk­
+ tionen zur Verfügung.
+ Während des Hamster-/Roboterlaufs können Sie
+ durch Tastendruck Einfluß nehmen (Geschwindigkeit
+ verändern, Programm abbrechen etc). Sehen Sie dazu
+ auch die Menufunktion 's Steuerung des Laufs' unter
+ dem Oberbegriff 'Info'. Standardmäßig beginnt ein
+ solcher Lauf immer mit einer mittleren Geschwin­
+ digkeit.
+ Ist der Hamster-/Roboterlauf ohne Fehler been­
+ det worden, werden Sie gefragt, ob Sie die Land­
+ schaft/das Arbeitsfeld in dem zuletzt angezeigten
+ Zustand aufbewahren wollen. Bejahen Sie diese Fra­
+ ge, so wird die Landschaft/das Arbeitsfeld in eine
+ Datei geschrieben. Die neue Landschaft/das neue
+ Arbeitsfeld erhält den Namen der alten Land­
+ schaft/des alten Arbeitsfeldes und das Zusatzkenn­
+ zeichen '.x'.
+ Sollte Ihnen beim Programmieren ein Fehler un­
+ terlaufen sein (z.B. eine Endlosschleife, so kann mit
+ der Taste <ESC> der Hamster-/Roboterlauf abgebro­
+ chen werden ("Notbremse").
+
+#on("u")##on("b")#h Handsteuerung#off("b")##off("u")#
+ Mit dieser Funktion können Sie den Hamster/
+ Roboter in einer/einem vorbereiteten Landschaft/
+ Arbeitsfeld durch Tasten steuern. Alle gültigen
+ Tastenbefehle werden in einem Protokoll festgehal­
+ ten. Da das entstehende Protokoll ein ELAN-
+ Programm ist, kann der Hamster/Roboter anschlie­
+ ßend die gleichen Aktionen anhand des Programms
+ wiederholt ausführen ('Teach In').
+ Sie werden zunächst gefragt, ob die Land­
+ schaft/das Arbeitsfeld, in dem der Hamster/Roboter
+ gesteuert werden soll, schon existiert. Beantworten
+ Sie die Frage mit 'nein', so werden Sie aufgefordert,
+ zunächst die Landschaft/das Arbeitsfeld zu gestal­
+ ten. Bejahen Sie die Frage, werden Ihnen alle in Ih­
+ rer Task vorhandenen Landschaften/Arbeitsfelder
+ zur Auswahl angeboten. Sie brauchen nur die ge­
+ wünschte Landschaft/das gewünschte Arbeitsfeld
+ anzukreuzen. Die/das angekreuzte Landschaft/Ar­
+ beitsfeld erscheint dann in folgender Darstellung
+ auf dem Bildschirm:
+
+#on("b")#
+#on("u")#Beispiel#off("u")#:
+
+ <v>or <l>inks um <n>imm <g>ib <p>rotokoll <e>nde
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . V . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . o\#\# o . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . .\#\# . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . o\#\# . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . .\#\# o . . . o . . . . . . . . . . . . . . .
+. . . . . . . . . . . . o\#\#\#\#\#\#\#\#\#\#\#\# o . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . o . o .\#\# . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . o\#\# . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . .\#\# . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . o\#\#o. . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+Gib Hamster-Befehl: letzter Befehl:
+
+#off("b")#
+ Durch Tastendruck können Sie nun den Hamster/
+ Roboter steuern (<v> - vor, <l> - links um, <n> -
+ nimm, <g> - gib). Sofern die Aktion ausführbar ist,
+ wird sie auf dem Bildschirm auch ausgeführt. Wird
+ dagegen eine Aktion verlangt, die nicht ausgeführt
+ werden kann (z.B. <v>, wenn der Hamster/Roboter
+ direkt vor einem Hindernis steht), so erscheint eine
+ entsprechende Fehlermeldung in der untersten Zeile
+ des Bildschirms. Nach einer kurzen Pause können
+ dann weitere Eingaben gemacht werden. Eine Fehlbe­
+ dienung führt also #on("u")#nicht#off("u")# zu einem Programmabbruch!
+ In der untersten Bildschirmzeile wird auch jeweils
+ der letzte Befehl zur Kontrolle angezeigt.
+ Alle korrekten Eingaben werden protokolliert.
+ Durch Drücken der Taste <p> (- protokoll) können Sie
+ sich jederzeit das während der Ausführung angeleg­
+ te Protokoll zeigen lassen. Es entsteht nämlich
+ automatisch im Hintergrund ein ablauffähiges
+ ELAN-Programm. Im Anschluß an eine solche Hand­
+ steuerung können Sie den Hamster/Roboter dann in
+ der gleichen Landschaft/im gleichen Arbeitsfeld
+ nach diesem Protokoll (Dateiname: PROTOKOLL) vom
+ Programm aus gesteuert laufen lassen.
+#page#
+4.6 Menufunktionen zum Oberbegriff 'Archiv'
+
+#on("b")#
+HAMSTER: Info Landschaft Programm Lauf Archiv
+---------------------------------+-------------------------+--------------
+ | r Reservieren |
+ | - Neue Diskette |
+ | --------------------- |
+ | - Schreiben |
+ | - Checken |
+ | - Kombination |
+ | - Holen/Lesen |
+ | - Löschen |
+ | --------------------- |
+ | - Verzeichnis |
+ | - Drucken |
+ | --------------------- |
+ | i Initialisieren |
+ | z Zieltask einstellen |
+ +---------------------+ +-------------------------+
+ | Dateiaustausch mit: |
+ | Archiv |
+ | Archivname: |
+ | --- |
+ +---------------------+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+ In diesem Kapitel werden alle die Menufunktionen be­
+schrieben, die Ihnen unter dem Oberbegriff 'Archiv' im
+Menu angeboten werden. Mit den Funktionen in diesem
+Menu können Sie aber nicht nur Dateien auf dem Archiv
+behandeln, sondern auch in anderen Tasks im Multi-
+User-System oder über das EUMEL-Netz sogar auf anderen
+Rechnern!
+ Wenn Sie dieses Pull-Down-Menu gerade aufgeschlagen
+haben, sind nicht alle Funktionen aktivierbar! Um weitere
+Funktionen zu aktivieren, muß erst einer der aktivierba­
+ren Menupunkte gewählt werden.
+ Bei der Archivbehandlung werden Ihnen jeweils alle in
+der Task vorhandenen Dateien zur Auswahl angeboten. Das
+System unterscheidet nicht von sich aus - wie unter den
+Oberbegriffen 'Landschaft'/'Arbeitsfeld' und 'Programm' -
+zwischen Landschaften/Arbeitsfeldern und Programmda­
+teien. In den hier gezeigten Listen können Sie aber Land­
+schaften/Arbeitsfelder daran erkennen, daß ihnen das
+Präfix 'Flaeche:' vorangestellt ist.
+
+#on("u")##on("b")#r Reservieren#off("b")##off("u")# (des Archivlaufwerks)
+ Im EUMEL-Multi-User-System haben normalerwei­
+ se mehrere Personen das Zugriffsrecht auf das Ar­
+ chivlaufwerk. Allerdings muß der Zugriff so gere­
+ gelt werden, daß sich die Beteiligten dabei nicht
+ gegenseitig "in die Quere kommen". Ein Zugriff auf
+ das Archivlaufwerk erfordert zunächst eine Anmel­
+ dung. Ist diese Anmeldung erfolgt, kann von den an­
+ deren Beteiligten so lange nicht mehr auf das Lauf­
+ werk zugegriffen werden - bis es wieder freigege­
+ ben worden ist.
+ Diese Anmeldung des Archivlaufwerkes erfolgt
+ über die Menufunktion 'r Reservieren'. Greift be­
+ reits eine andere Task auf das Laufwerk zu, so er­
+ halten Sie darüber einen Hinweis auf dem Bild­
+ schirm. Ansonsten wird an Sie die Frage gestellt, ob
+ die Diskette eingelegt und das Laufwerk geschlos­
+ sen ist.
+ Erst zu diesem Zeitpunkt ist sichergestellt, daß
+ Sie den alleinigen Zugriff auf das Laufwerk haben.
+ Deshalb sollten Sie, wenn Sie mit mehreren Personen
+ am Computer arbeiten, erst zum Zeitpunkt der Frage­
+ stellung die Diskette ins Laufwerk einlegen.
+ Nachdem Sie die Diskette eingelegt und die Frage
+ bejaht haben, ermittelt das System selbständig den
+ Namen der eingelegten Diskette, zeigt den Namen auf
+ dem Bildschirm (im kleinen Kasten links unten) an
+ und aktiviert die anderen Menupunkte des Pull-
+ Down-Menus.
+ Beim Verlassen des Pull-Down-Menus, wenn eine
+ andere Zieltask eingestellt wird oder wenn das Menu
+ gänzlich verlassen wird, wird die Reservierung au­
+ tomatisch aufgehoben!
+
+ Fehlerfälle:
+ - Das Laufwerk ist von einer anderen Task belegt.
+ - Die Diskette ist falsch eingelegt oder das Lauf­
+ werk ist nicht richtig geschlossen.
+ - Die Diskette ist nicht formatiert bzw. initiali­
+ siert.
+ - Die Diskette kann nicht gelesen werden (keine
+ EUMEL-Diskette, Diskette hat ein falsches For­
+ mat, Diskette ist verschmutzt...).
+
+#on("u")##on("b")#n Neue Diskette#off("b")##off("u")# (anmelden)
+ Der Dateiaustausch mit einer Diskette ist nur
+ dann möglich, wenn der im System eingestellte Dis­
+ kettenname (auf dem Bildschirm im kleinen Kasten
+ unten links sichtbar) mit dem tatsächlichen Namen
+ der Diskette übereinstimmt. Nach einem Disketten­
+ wechsel ist das aber in der Regel nicht mehr der
+ Fall. Greift man dann auf die neu eingelegte Dis­
+ kette zu, so erscheint die Fehlermeldung: 'Falscher
+ Archivname! Bitte neue Diskette anmelden!'.
+ Das Anmelden einer neuen Diskette - ohne einen
+ neuen Reserviervorgang - wird durch diese Menu­
+ funktion ermöglicht. Nach Aktivieren dieses Menu­
+ punktes wird der Name der eingelegten Diskette er­
+ mittelt, im System eingestellt und auf dem Bild­
+ schirm angezeigt.
+ Im Gegensatz zur Menufunktion 'r Reservieren'
+ greift das System ohne Anfrage an den Benutzer auf
+ das Archivlaufwerk zu (die Reservierung bleibt ja
+ bestehen). Ist das Archivlaufwerk reserviert, so ist
+ die Neuanmeldung einer Diskette über diese Menu­
+ funktion weniger zeitaufwendig.
+
+ Fehlerfälle:
+ - wie unter 'r Reservieren'.
+
+#on("u")##on("b")#s Schreiben#off("b")##off("u")# (Kopieren)
+ Alle Dateien der eigenen Task werden zur Aus­
+ wahl angeboten. Wenn Sie die Auswahl durch die
+ Tastenfolge <ESC><q> verlassen, überprüft das Sy­
+ stem zunächst, ob die Dateien in der eingestellten
+ Zieltask schon vorhanden sind. Ist das der Fall,
+ wird erfragt, ob die dort vorhandenen Dateien über­
+ schrieben, d.h. gelöscht werden dürfen (s.u.). An­
+ schließend werden alle angekreuzten Dateien in der
+ Reihenfolge, in der Sie sie angekreuzt haben, in die
+ eingestellte Zieltask kopiert. Der Vorgang wird auf
+ dem Bildschirm protokolliert. Die Originaldateien
+ in der eigenen Task bleiben dabei erhalten.
+ Wenn in der Zieltask schon eine Datei existiert,
+ die den gleichen Namen hat wie eine Datei, die Sie
+ dorthin kopieren möchten, so wird angefragt, ob die
+ vorher schon existierende Datei überschrieben (ge­
+ löscht!) werden soll. Bejahen Sie diese Frage, so wird
+ die bereits in der Zieltask existierende Datei (un­
+ wiederbringlich) gelöscht und die gewünschte Datei
+ dorthin transportiert. Ein Überschreiben aus Ver­
+ sehen ist nicht möglich, wenn Sie die an Sie gestell­
+ te Frage sorgfältig beantworten.
+ Verneinen Sie die Frage, so wird die Datei auch
+ nicht hinübertransportiert! Sie können die Datei
+ aber umbenennen (Menufunktion 'u Umbenennen' un­
+ ter den Oberbegriffen 'Landschaft'/Arbeitsfeld' bzw.
+ 'Programm') und anschließend mit anderem Namen
+ hinüberschreiben.
+ Beachten Sie, daß beim Überschreiben einer Datei
+ auf einer Archivdiskette der Speicherplatz der al­
+ ten (überschriebenen) Version im allgemeinen nicht
+ wiederverwendet werden kann. In einem solchen Fall
+ könnte die Diskette voll geschrieben werden, obwohl
+ eigentlich genügend Platz vorhanden wäre. Zur Op­
+ timierung wird deshalb zuerst überprüft, ob die
+ angekreuzten Dateien schon in der Zieltask vorhan­
+ den sind und löscht diese, wenn Sie Ihr Einver­
+ ständnis geben. Erst anschließend werden die Datei­
+ en insgesamt kopiert.
+ Normalerweise ist als Zieltask das Archivlauf­
+ werk der eigenen Station eingestellt. Mit der Menu­
+ funktion 'z Zieltask einstellen' kann diese Einstel­
+ lung aber verändert werden.
+
+ Fehlerfälle:
+ - Die Diskette ist falsch eingelegt oder beschä­
+ digt.
+ - Die Diskette kann nicht beschrieben werden
+ (Schreibfehler).
+ - Die Diskette ist voll.
+ - Sehen Sie auch unter 'r Reservieren'
+ 'z Zieltask einstellen'.
+
+#on("u")##on("b")#c Checken#off("b")##off("u")#
+ Diese Menufunktion kann nur ausgeführt werden,
+ wenn der Dateiaustausch mit einem Archiv(manager)
+ erfolgt - ansonsten ist diese Menufunktion auch
+ nicht aktivierbar. Die Menufunktion dient dazu, auf
+ Diskette geschriebene Dateien auf Lesefehler hin zu
+ prüfen. Es empfiehlt sich, diese Prüfroutine auf
+ neu auf die Diskette geschriebene Dateien anzuwen­
+ den. Sehen Sie dazu auch 'k Kombination'.
+ Alle Dateien der eingestellten Zieltask (Archiv)
+ werden zur Auswahl angeboten. Wenn Sie die Auswahl
+ durch die Tastenfolge <ESC><q> verlassen, werden
+ alle angekreuzten Dateien in der Reihenfolge, in
+ der Sie sie angekreuzt haben, "gecheckt", d.h. auf
+ Lesefehler hin überprüft. Der Vorgang wird auf dem
+ Bildschirm protokolliert.
+
+ Fehlerfälle:
+ - Lesefehler auf dem Archiv.
+ - Sehen Sie auch unter 'r Reservieren'.
+
+#on("u")##on("b")#k Kombination#off("b")##off("u")#
+ Diese Menufunktion ist eine Kombination aus den
+ beiden Menufunktionen 's Schreiben' und 'c Checken'
+ (Sehen Sie weitere Informationen auch dort!).
+ Alle Dateien der eigenen Task werden zur Aus­
+ wahl angeboten. Wenn Sie die Auswahl durch die Ta­
+ stenfolge <ESC><q> verlassen, werden alle ange­
+ kreuzten Dateien in der Reihenfolge, in der Sie sie
+ angekreuzt haben, in die eingestellte Zieltask ko­
+ piert (gegebenenfalls müssen bereits vorhandene
+ Dateien gleichen Namens in der Zieltask gelöscht
+ werden). Anschließend werden alle Dateien, die gera­
+ de geschrieben wurden, gecheckt, d.h. auf Lesefehler
+ hin untersucht. Beide Vorgänge werden auf dem
+ Bildschirm protokolliert.
+ Da die 'Check' - Operation nur bei Archivmana­
+ gern zulässig ist, ist diese Menufunktionen eben­
+ falls nur bei Archivmanagern aktivierbar. Zur Er­
+ läuterung sehen Sie bitte auch unter 'z Zieltask
+ einstellen'.
+
+#on("u")##on("b")#h Holen/Lesen#off("b")##off("u")#
+ Die Menufunktion dient dazu, Dateien, die bereits
+ auf einer Archivdiskette oder in einer anderen Task
+ existieren, in die eigene Task zu kopieren.
+ Alle Dateien der eingestellten Zieltask werden
+ zur Auswahl angeboten. Anschließend werden Kopien
+ der angekreuzten Dateien in der Reihenfolge des
+ Ankreuzens in die eigene Task geholt. Das Original
+ in der Zieltask bleibt dabei unverändert! Der Vor­
+ gang wird auf dem Bildschirm protokolliert.
+ Sind in der eigenen Task schon Dateien mit glei­
+ chem Namen vorhanden, so wird gefragt, ob die 'al­
+ ten' Dateien überschrieben (gelöscht) werden dürfen.
+ Nur wenn Sie zustimmen, werden die in Ihrer Task
+ existierenden Dateien (unwiederbringlich!) gelöscht
+ und Kopien der gleichnamigen Dateien aus der Ziel­
+ task angefertigt.
+ Stimmen Sie dem Löschvorgang nicht zu, dann
+ bleiben die bisherigen Dateien in Ihrer Task erhal­
+ ten - die Dateien aus der Zieltask werden dann aber
+ auch nicht in Ihre Task kopiert! Um dennoch die Ko­
+ pien zu erhalten, können Sie die namensgleichen
+ Dateien in Ihrer Task umbenennen und dann erst die
+ Dateien aus der anderen Task anfordern.
+ Normalerweise werden die Dateien vom Archiv der
+ eigenen Station geholt. Mit dem Menupunkt 'z Ziel­
+ task einstellen' kann diese Einstellung verändert
+ werden.
+
+ Fehlerfälle:
+ - Lesefehler auf dem Archiv.
+ - Sehen Sie auch unter 'r Reservieren'
+ 's Schreiben'
+ 'z Zieltask einstellen'.
+
+#on("u")##on("b")#l Löschen#off("b")##off("u")#
+ Die Menufunktion dient dazu, Dateien in der
+ Zieltask (unwiederbringlich!) zu löschen. Dazu wer­
+ den alle Dateien der eingestellten Zieltask zur Aus­
+ wahl angeboten. Anschließend werden die angekreuz­
+ ten Dateien in der Reihenfolge ihres Ankreuzens
+ gelöscht. Zur Sicherheit muß noch einmal für jede
+ einzelne Datei bestätigt werden, daß sie auch tat­
+ sächlich gelöscht werden soll.
+ Beachten Sie, daß beim Löschen einer Datei auf
+ einer Archivdiskette der Speicherplatz im allgemei­
+ nen nicht wieder verwendet werden kann. In einem
+ solchen Fall könnte die Diskette voll geschrieben
+ werden, obwohl eigentlich genügend Platz vorhan­
+ den wäre. Diese Probleme treten bei anderen Tasks,
+ die keine Archivmanager sind, nicht auf, da deren
+ Speicherplatz intelligenter verwaltet wird.
+ Normalerweise ist als Zieltask das Archiv der
+ eigenen Station eingestellt. Mit dem Menupunkt 'z
+ Zieltask einstellen' kann diese Einstellung verän­
+ dert werden.
+
+ Fehlerfälle:
+ - Sehen Sie auch unter 'r Reservieren'
+ 's Schreiben'
+ 'z Zieltask einstellen'.
+
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie sich einen
+ Überblick über die in der Zieltask (z.B. auf dem Ar­
+ chiv) vorhandenen Dateien verschaffen.
+ Nach Aufruf der Funktion wird eine Liste der
+ Dateien auf dem Bildschirm ausgegeben, die sich in
+ der Zieltask (z.B. auf dem Archiv) befinden. Ist die
+ Zieltask ein Archiv(manager), so wird auch ange­
+ zeigt, wieviel Platz auf der Diskette belegt ist. Da
+ die Liste selbst eine Datei ist, kann sie mit der Ta­
+ stenkombination <ESC><q> verlassen werden. Falls
+ nicht alle Dateinamen auf den Bildschirm passen,
+ können Sie das Fenster mit <HOP><hoch> und
+ <HOP><runter> verschieben.
+
+ Fehlerfälle:
+ - Sehen Sie unter 'z Zieltask einstellen'.
+
+#on("u")##on("b")#d Drucken#off("b")##off("u")#
+ Das Verzeichnis der Dateien in der Zieltask, das
+ man mit der Menufunktion 'v Verzeichnis' auf dem
+ Bildschirm angezeigt bekommt, kann mit dieser Me­
+ nufunktion ausgedruckt werden.
+ Zur Sicherheit wird angefragt, ob wirklich ein
+ solches Dateiverzeichnis der Zieltask gedruckt wer­
+ den soll. Bejaht man die Frage, so wird ein Dateiver­
+ zeichnis erstellt und zum Drucker geschickt.
+
+ Fehlerfälle:
+ - Der Drucker ist nicht funktionsbereit.
+ - Der Drucker wird nicht über die Task 'PRINTER'
+ betrieben.
+ - Auf Ihrem System werden die Druckkosten abge­
+ rechnet. Sie müssen sich mit einer Codenummer
+ identifizieren.
+
+#on("u")##on("b")#i Initialisieren#off("b")##off("u")#
+ Diese Menufunktion gestattet es, frische Disket­
+ ten zu formatieren, zu initialisieren bzw. be­
+ schriebene Disketten vollständig zu löschen und
+ ggf. dabei umzubenennen. Bei Aufruf dieser Menu­
+ funktion wird - sofern noch nicht geschehen - das
+ Archivlaufwerk automatisch reserviert.
+ Wenn Sie eine fabrikneue Diskette aus der Ver­
+ packung nehmen, müssen Sie diese zunächst #on("u")#forma­
+ tieren#off("u")#. Dabei wird die Diskette auf ein festgelegtes
+ physikalisches Format eingestellt. Ohne daß diese
+ Operation vorausgegangen ist, kann eine Diskette
+ weder beschrieben noch gelesen werden.
+ Prinzipiell braucht eine Diskette nur ein einzi­
+ ges Mal formatiert zu werden. Sie können Sie jedoch
+ jederzeit wieder formatieren - z.B. wenn Sie Disket­
+ ten haben, von denen Sie nicht genau wissen, für
+ welche Zwecke sie zuvor verwendet wurden.
+ Wenn Sie diese Menufunktion aktivieren, werden
+ Sie so zunächst gefragt, ob Sie die Diskette auch
+ formatieren wollen. Bejahen Sie die Frage, so werden
+ Ihnen mehrere Formate zur Auswahl angeboten:
+
+#on ("b")#
+ +------------------------------------+
+ | Formatieren einer Diskette |
+ | |
+ | Dies sind die möglichen Formate: |
+ | |
+ | 1 ..... 40 Spur - 360 KB |
+ | 2 ..... 80 Spur - 720 KB |
+ | 3 ..... 5 1/4" - 1,2 MB |
+ | 4 ..... 3 1/2" - 1,4 MB |
+ | s ..... Standard - Format |
+ | |
+ | 1 2 3 4 s |
+ +------------------------------------+
+#off("b")#
+
+ Erkundigen Sie sich bei Ihrem Händler, welches
+ Format Sie bei Ihrem Rechner und den von Ihnen
+ verwendeten Disketten einstellen müssen. Manche
+ Rechner unterstützen diese Operation innerhalb des
+ EUMEL-Systems auch gar nicht, das Formatieren muß
+ dann irgendwie anders außerhalb des EUMEL-Systems
+ geschehen.
+ Wenn Sie die Formatierung abgeschlossen oder
+ auch übersprungen haben, beginnt die eigentliche
+ Initialisierung der Diskette. Dabei wird als erstes
+ der Archivname auf die Diskette geschrieben. Alle
+ alten Daten, die sich ggf. auf der Diskette befinden,
+ werden bei diesem Vorgang unwiederbringlich (!)
+ gelöscht.
+ Zur Sicherheit überprüft das System in jedem
+ Falle, ob es sich um eine EUMEL - Diskette handelt,
+ und erfragt Ihr Einverständnis, ob die Diskette
+ wirklich initialisiert werden soll. Geben Sie hierzu
+ Ihr Einverständnis, dann wird noch der (neue) Ar­
+ chivname erfragt. Hatte die Diskette schon einen
+ Namen, dann wird dieser zum Überschreiben angebo­
+ ten. Wollen Sie den alten Archivnamen beibehalten,
+ so brauchen Sie nur die <RETURN>-Taste zu tippen,
+ ansonsten können Sie den Namen auch zuvor verän­
+ dern oder einen ganz neuen Namen hinschreiben.
+ Anhand des ausgegebenen Namens können Sie auch
+ überprüfen, ob Sie die richtige Diskette eingelegt
+ haben.
+ Das Initialisieren funktioniert natürlich nur,
+ wenn Sie als Zieltask einen Archivmanager einge­
+ stellt haben - ansonsten ist diese Menufunktion
+ gesperrt (nicht aktivierbar!).
+
+ Fehlerfälle:
+ - Formatieren ist nicht auf dem System möglich.
+ - Sehen Sie auch unter 'r Reservieren'
+ 'z Zieltask einstellen'.
+
+#on("u")##on("b")#z Zieltask einstellen#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie festlegen,
+ mit welcher Zieltask Sie kommunizieren, d.h. z.B. Da­
+ teien austauschen möchten. Normalerweise ist hier
+ das Archiv am eigenen Rechner eingestellt. Das wird
+ auch nach Aufklappen des Pull-Down-Menus im Ka­
+ sten links unten angezeigt.
+ Diese Menufunktion kann im Unterricht z.B. dazu
+ genutzt werden, um fertiggestellte Hausaufgaben in
+ eine bestimmte Task zu schicken (Vatertask) oder um
+ von dort z.B. vorgefertigte Landschaften oder/und
+ Programme abzuholen.
+ Sie können aber auch eine andere Task einstellen
+ (z.B. die Vatertask oder die Task 'PUBLIC'), um mit die­
+ sen Dateien auszutauschen oder um sich auch nur ei­
+ nen Überblick über die dort vorhandenen Dateien zu
+ verschaffen. Wenn Sie mit Ihrem Rechner in ein
+ EUMEL-Netz integriert sind, können Sie auch auf
+ Tasks anderer Rechner zugreifen oder auch Disketten
+ von Laufwerken anderer Rechner einlesen (z.B. wenn
+ Sie Disketten anderer Formate haben, die von Ihrem
+ Rechner nicht gelesen werden können).
+ Dabei werden zwei Anforderungen an die Zieltask
+ gestellt: Sie muß existieren und bereit für den Da­
+ teiaustausch sein, d.h es muß eine Managertask sein,
+ auf die Sie Zugriff haben. Versuchen Sie auf andere
+ Tasks zuzugreifen, so erhalten Sie entsprechende
+ (Fehler-)Meldungen.
+ Zu beachten ist noch, daß es im EUMEL-System ver­
+ schiedene Arten von Managertasks gibt - Archivma­
+ nager und normale Dateimanager. Der Unterschied
+ besteht darin, daß ein Archivmanager vom Benutzer
+ vor dem Zugriff reserviert werden muß - anschlie­
+ ßend hat nur dieser Benutzer (bis zur Aufgabe der
+ Reservierung) ein Zugriffsrecht auf den Manager.
+ Normale Dateimanager können dagegen von mehreren
+ Benutzern in beliebiger Reihenfolge angesprochen
+ werden.
+ Ein Archivmanager kann auch auf bestimmte Dis­
+ kettenformate spezialisert sein (z.B. auf das Lesen
+ von DOS-Disketten). Manche Rechner haben auch meh­
+ rere Archivmanager für verschiedene Laufwerke etc.
+ Durch Einstellen unterschiedlicher Archivmanager
+ können Sie dann auf verschiedenen Laufwerken ar­
+ chivieren.
+ Nach Aktivieren dieses Menupunktes werden Ihnen
+ die folgenden Alternativen angeboten:
+
+#on ("b")#
+ +-------------------------------------------+
+ | Dateiaustausch gewünscht mit: |
+ | |
+ | a ... Archiv (Eigene Station) |
+ | |
+ | v ... Vatertask |
+ | |
+ | p ... 'PUBLIC' (Eigene Station) |
+ | |
+ | s ... Sonstige Task |
+ | |
+ | |
+ | Archiv Vatertask PUBLIC Sonstige |
+ +-------------------------------------------+
+
+ Da der Dateiaustausch mit dem Standardarchiv
+ der eigenen Station (Task: 'ARCHIVE'), mit der Vater­
+ task und der Task 'PUBLIC' recht häufig in Anspruch
+ genommen wird, sind diese drei Optionen unter den
+ Alternativen direkt angegeben. Entscheiden Sie sich
+ für eine dieser drei Tasks, so nimmt das System alle
+ notwendigen Einstellungen vor. Möchten Sie dage­
+ gen in Kontakt mit einer anderen Task treten, so
+ wählen Sie die Alternative 's ... Sonstige Task'.
+ In diesem Falle haben Sie noch 3 Angaben zu machen:
+
+ - Zunächst werden Sie nach dem Namen der Zieltask
+ gefragt. Geben Sie den Namen der Zieltask - ohne
+ Anführungsstriche (!) - ein und schließen Sie die
+ Eingabe mit der <RETURN>-Taste ab. (Den ausge­
+ gebenen Namen der z.Z. eingestellten Task können
+ Sie dabei verändern bzw. überschreiben.)
+
+ - Dann wird die Nummer der Station im EUMEL-Netz
+ erfragt, auf der sich die Zieltask befindet. Die
+ Nummer Ihrer Station wird als Vorschlag ausge­
+ geben. Wollen Sie mit einer Task auf Ihrem Rech­
+ ner kommunizieren, so brauchen Sie diesen Vor­
+ schlag nur durch Drücken der <RETURN>-Taste
+ bestätigen - ansonsten tragen Sie zuvor die ent­
+ sprechende Stationsnummer ein. Ist Ihr Rechner
+ nicht in ein EUMEL-Netz integriert, so wird die
+ Stationsnummer 0 (Null) ausgegeben. Bitte bestä­
+ tigen Sie diese Stationsnummer durch Tippen der
+ <RETURN>-Taste.
+
+ - Zum Abschluß müssen Sie noch angeben, ob die
+ eingestellte Zieltask ein Archivmanager ist oder
+ nicht.
+
+ Das System versucht dann den Kontakt herzu­
+ stellen. Je nachdem, welche Einstellung Sie vorge­
+ nommen haben, sind bestimmte Funktionen innerhalb
+ des Menus nicht aktivierbar. Das System läßt nur
+ die Funktionen zu, die aufgrund Ihrer Einstellun­
+ gen zulässig sind.
+ Im Kasten links unten auf dem Bildschirm wird
+ jeweils angezeigt, welche Zieltask eingestellt ist.
+ Erscheint in diesem Kasten auch ein Hinweis auf den
+ Archivnamen, so haben Sie einen Archivmanager ein­
+ gestellt. Ist dagegen vor dem Namen der Zieltask
+ noch eine Zahl und ein Schrägstrich angegeben, so
+ haben Sie eine Zieltask auf einem anderen Rechner
+ eingestellt.
+ Bedenken Sie, daß Operationen mit Tasks auf an­
+ deren Stationen länger andauern können - werden
+ Sie nicht ungeduldig!
+ Sie können die Einstellung der Zieltask jeder­
+ zeit wieder verändern!
+
+ Fehlerfälle:
+ - Die eingestellte Zieltask existiert nicht.
+ - Die eingestellte Zieltask existiert zwar, ist aber
+ nicht empfangsbereit, d.h. ein Zugriff von Ihrer
+ Task aus ist nicht möglich!
+ - Das Netz ist nicht funktionsbereit (Collector-
+ Task fehlt).
+ - Die Kommunikation war nicht erfolgreich.
+ - Die gewünschte Operation kann mit der einge­
+ stellten Zieltask nicht ausgeführt werden (Ziel­
+ task ist z.B. gar kein Archivmanager - Sie aber
+ versuchen, das Laufwerk zu reservieren).
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 5 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 5
new file mode 100644
index 0000000..bb4a67b
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 5
@@ -0,0 +1,167 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (61)#
+#headodd#
+#center#gs-Herbert und Robbi#right#%
+
+#end#
+#headeven#
+%#center#gs-Herbert und Robbi
+
+#end#
+#center#5
+
+#center#Detailbeschreibung
+#center#der
+#center#Basisbefehle
+
+
+#on("u")#'vor' bewirkt:#off("u")#
+ - ein Eingabezeichen wird von der Tastatur gelesen
+ und ausgewertet.
+ - es wird je nach Verzögerungsfaktor (eine vorgege­
+ bene Wartezeit, die auch während des Programmlaufs
+ verändert werden kann) gewartet.
+ - falls die Kachel vor dem Hamster/Roboter noch frei
+ ist und zur Landschaft/zum Arbeitsfeld gehört,
+ geht der Hamster/ Roboter um eine Kachel in der
+ augenblicklichen Richtung vorwärts.
+ - falls vor dem Hamster/Roboter ein Hindernis liegt,
+ oder wenn er im Begriff ist, aus der Landschaft/aus
+ dem Arbeitsfeld herauszulaufen, wird das Programm
+ mit entsprechender Fehlermeldung abgebrochen.
+
+#on("u")#'links um' bewirkt:#off("u")#
+ - wie bei 'vor': Annahme eines Tastendruckes und
+ Warten.
+ - eine Drehung des Hamsters/Roboters um 90 Grad ge­
+ gen den Uhrzeigersinn.
+
+#on("u")#'nimm' bewirkt:#off("u")#
+ - wie bei 'vor': Annahme eines Tastendruckes und
+ Warten.
+ - falls auf der Kachel, auf der der Hamster/Roboter
+ steht, kein Korn/Werkstück liegt, wird das Programm
+ mit entsprechender Fehlermeldung abgebrochen.
+ - falls dort genau ein Korn/ein Werkstück liegt, wird
+ dieses auf dem Bildschirm entfernt. Es wird zu denen
+ in den Backentaschen/im Behälter addiert. Auf dem
+ Bildschirm erscheint an der Stelle (" .").
+ - falls mehrere Körner/Werkstücke dort liegen, wird
+ eines zu denen in den Backentaschen/im Behälter
+ addiert und von denen auf der Kachel subtrahiert.
+ Auf dem Bildschirm erscheint weiterhin an der Stel­
+ le (" o").
+
+#on("u")#'gib' bewirkt:#off("u")#
+ - wie bei 'vor': Annahme eines Tastendruckes und
+ Warten.
+ - falls die Backentaschen/der Behälter leer sind/ist,
+ wird das Programm mit entsprechender Fehlermel­
+ dung abgebrochen.
+ - falls auf der Kachel schon ein Korn/Werkstück oder
+ mehrere Körner/Werkstücke liegen, wird zu ihnen
+ eines addiert und von denen in den Backentaschen/
+ im Behälter subtrahiert. Der Bildschirm ändert sich
+ nicht.
+ - falls noch kein Korn/Werkstück auf dieser Kachel
+ liegt, wird auf dem Bildschirm ein (" o") ausgegeben
+ und von den Körnern/Werkstücken in den Backenta­
+ schen/im Behälter ein Korn/Werkstück subtrahiert.
+
+#on("u")#'vorn frei'#off("u")#
+ - liefert den Wahrheitswert TRUE, wenn vor dem Ham­
+ ster/ Roboter keine Hinderniskachel liegt, #on("u")#also
+ auch dann, wenn der Hamster/Roboter im Begriff ist,
+ über die Landschafts-/Arbeitsfeldgrenze (den
+ Bildschirmrand) hinauszulaufen!#off("u")# Wenn vor dem Ham­
+ ster/Roboter eine Hinderniskachel liegt, wird der
+ Wahrheitswert FALSE geliefert.
+
+#on("u")#'links frei'#off("u")#
+ - liefert den Wahrheitswert TRUE, wenn in Laufrich­
+ tung links vom Hamster/ Roboter keine Hindernis­
+ kachel liegt, #on("u")#also auch dann, wenn links vom Ham­
+ ster/Roboter die Landschafts-/Arbeitsfeldgrenze
+ (der Bildschirmrand) ist!#off("u")# Wenn links vom Hamster/
+ Roboter eine Hinderniskachel liegt, wird der Wahr­
+ heitswert FALSE geliefert.
+
+#on("u")#'rechts frei'#off("u")#
+ - liefert den Wahrheitswert TRUE, wenn in Laufrich­
+ tung rechts vom Hamster/Roboter keine Hindernis­
+ kachel liegt, #on("u")#also auch dann, wenn rechts vom Ham­
+ ster/Roboter die Landschafts-/Arbeitsfeldgrenze
+ (der Bildschirmrand) ist!#off("u")# Wenn rechts vom Hamster/
+ Roboter eine Hinderniskachel liegt, wird der Wahr­
+ heitswert FALSE geliefert.
+
+#on("u")#'hinten frei'#off("u")#
+ - liefert den Wahrheitswert TRUE, wenn in Laufrich­
+ tung hinter dem Hamster/Roboter keine Hindernis­
+ kachel liegt, #on("u")#also auch dann, wenn hinter dem Ham­
+ ster/Roboter die Landschafts-/Arbeitsfeldgrenze
+ (der Bildschirmrand) ist!#off("u")# Wenn hinter dem Hamster/
+ Roboter eine Hinderniskachel liegt, wird der Wahr­
+ heitswert FALSE geliefert.
+
+#on("u")#'korn da' und 'werkstueck da'#off("u")#
+ - liefern den Wahrheitswert TRUE, wenn auf der
+ Kachel, auf der der Hamster/Roboter steht, minde­
+ stens ein Korn/Werkstück liegt. Ansonsten wird der
+ Wahrheitswert FALSE geliefert.
+
+#on("u")#'korn vorn' und 'werkstueck vorn'#off("u")#
+ - liefern den Wahrheitswert TRUE, wenn auf der
+ Kachel, die in Laufrichtung vor dem Hamster/Robo­
+ ter liegt, mindestens ein Korn/Werkstück liegt. An­
+ sonsten wird der Wahrheitswert FALSE geliefert.
+ - Zur "Untersuchung" wird die vor ihm liegende
+ Kachel - sofern dort kein Hindernis ist - von ihm
+ betreten. Wenn er im Begriff ist, aus der Land­
+ schaft/dem Arbeitsfeld herauszulaufen, wird das
+ Programm mit entsprechender Fehlermeldung abge­
+ brochen.
+
+#on("u")#'korn links' und 'werkstueck links'#off("u")#
+ - liefern den Wahrheitswert TRUE, wenn auf der
+ Kachel, die in Laufrichtung links vom Hamster/
+ Roboter liegt, mindestens ein Korn/Werkstück liegt.
+ Ansonsten wird der Wahrheitswert FALSE geliefert.
+ - Zur "Untersuchung" wird die links neben ihm lie­
+ gende Kachel - sofern dort kein Hindernis ist - von
+ ihm betreten. Wenn er im Begriff ist, aus der Land­
+ schaft/dem Arbeitsfeld herauszulaufen, wird das
+ Programm mit entsprechender Fehlermeldung abge­
+ brochen.
+
+#on("u")#'korn rechts' und 'werkstueck rechts'#off("u")#
+ - liefern den Wahrheitswert TRUE, wenn auf der
+ Kachel, die in Laufrichtung rechts vom Hamster/
+ Roboter liegt, mindestens ein Korn/Werkstück liegt.
+ Ansonsten wird der Wahrheitswert FALSE geliefert.
+ - Zur "Untersuchung" wird die rechts neben ihm lie­
+ gende Kachel - sofern dort kein Hindernis ist - von
+ ihm betreten. Wenn er im Begriff ist, aus der Land­
+ schaft/dem Arbeitsfeld herauszulaufen, wird das
+ Programm mit entsprechender Fehlermeldung abge­
+ brochen.
+
+#on("u")#'korn hinten' und 'werkstueck hinten'#off("u")#
+ - liefern den Wahrheitswert TRUE, wenn auf der
+ Kachel, die in Laufrichtung hinter dem Hamster/
+ Roboter liegt, mindestens ein Korn/Werkstück liegt.
+ Ansonsten wird der Wahrheitswert FALSE geliefert.
+ - Zur "Untersuchung" wird die hinter ihm liegende
+ Kachel - sofern dort kein Hindernis ist - von ihm
+ betreten. Wenn er im Begriff ist, aus der Land­
+ schaft/dem Arbeitsfeld herauszulaufen, wird das
+ Programm mit entsprechender Fehlermeldung abge­
+ brochen.
+
+#on("u")#'backen leer' und 'behaelter leer'#off("u")#
+ - liefern den Wahrheitswert TRUE, wenn kein Korn/
+ kein Werkstück in den Backentaschen/im Behälter
+ notiert ist. Ansonsten wird der Wahrheitswert FALSE
+ geliefert.
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 6 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 6
new file mode 100644
index 0000000..0aeeff0
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 6
@@ -0,0 +1,73 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (66)#
+#headodd#
+#center#gs-Herbert und Robbi#right#%
+
+#end#
+#headeven#
+%#center#gs-Herbert und Robbi
+
+#end#
+#center#6
+
+#center#Zusätzliche Kommandos
+
+
+PROC landschaft (TEXT CONST landschaftsname)
+PROC arbeitsfeld (TEXT CONST arbeitsfeldname)
+ Steht einer dieser Prozeduraufrufe innerhalb eines
+ Hamster-/ Roboterprogramms vor dem ersten Befehl (am
+ Anfang der Datei), so wird die Anfrage nach einem Land­
+ schafts-/Arbeitsfeldnamen zu Beginn des Laufs über­
+ gangen. Außerdem ist es möglich, den Hamster/Roboter
+ in einem Programm durch meherere Landschaften/Ar­
+ beitsfelder laufen zu lassen. Beachten Sie bitte, daß
+ der Landschaftsname / Arbeitsfeldname hier in Anfüh­
+ rungszeichen, aber #on("u")#ohne#off("u")# das Präfix 'Flaeche:' angegeben
+ werden muß!
+
+PROC geschwindigkeit (INT CONST wert)
+ Möchte man von einem Programm aus eine bestimmte
+ Geschwindigkeit des Hamsters/Roboters bei der Pro­
+ grammausführung festlegen oder die Geschwindigkeit
+ vom Programm aus verändern, so kann man diese Proze­
+ dur verwenden. Zulässig sind für 'wert' nur Werte zwi­
+ schen 0 und 9. Dabei bedeuten:
+ 0: Einzelschrittmodus - Ausführung des nächsten
+ Schritts auf Tastendruck
+ 1: geringste Geschwindigkeit (Wartezeit : ca.
+ 50 Zehntelsekunden )
+ 9: höchste Geschwindigkeit (Wartezeit :
+ keine)
+ 2 - 8 sind dazwischenliegende Geschwindigkeiten
+
+TEXT PROC taste
+ Diese Prozedur liefert jeweils ein eingetipptes
+ Zeichen. Die Taste <ESC>, welche zum Programmabbruch
+ dient, wirkt sich schon aus, bevor hier ein Zeichen ge­
+ liefert werden könnte.
+
+PROC druckereinstellung fuer flaechenausdruck
+ Für den Landschafts-/Arbeitsfeldausdruck ist der
+ Standardschrifttyp des Druckers voreingestellt. Dabei
+ müssen 80 Druckpositionen in einer Zeile Platz haben.
+ Außerdem sind voreingestellt : \#limit (20.5)\#, \#on("b")\#
+ (Fettdruck) und \#start (0.0,0.0)\#. Zur Darstellung der
+ Hinderniskacheln wird das Zeichen '\#\#' (Code 222) ver­
+ wendet. Kann Ihr Drucker dieses Zeichen nicht darstel­
+ len (z.B. Typenraddrucker mit deutschem Zeichenzatz), so
+ können Sie hier ein #on("u")#anderes Zeichen#off("u")# auswählen. Weiter­
+ hin können Sie mit dieser Prozedur einen #on("u")#anderen
+ Schrifttyp#off("u")# und eine #on("u")#andere Startposition#off("u")# (linker obe­
+ rer Eckpunkt des Druckfeldes) einstellen. Nachdem Sie
+ das Kommando gegeben haben, wird zunächst der ge­
+ wünschte Schrifttyp erfragt. Geben Sie hier einen in
+ Ihrer Installation vorhandenen Schrifttyp an (nur den
+ Namen - ohne Anführungszeichen!). Anschließend werden
+ Sie nacheinander nach den beiden Startwerten (erst die
+ x-Richtung und dann die y-Richtung) gefragt. Geben
+ Sie hier jeweils einen Wert (als REAL) ein. Bedenken Sie
+ dabei, daß die 80 Druckpositionen nebeneinander Platz
+ haben müssen!
+
diff --git a/doc/hamster/gs-Herbert und Robbi handbuch.impressum b/doc/hamster/gs-Herbert und Robbi handbuch.impressum
new file mode 100644
index 0000000..4c8e79d
--- /dev/null
+++ b/doc/hamster/gs-Herbert und Robbi handbuch.impressum
@@ -0,0 +1,87 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#gs-Herbert und Robbi
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+
+#free (4.0)##on("b")#
+#center#gs-Herbert und Robbi
+
+
+#center#Benutzerhandbuch
+
+
+#center#Version 1.0
+
+
+#off("b")##center#copyright
+#center#Eva Latta-Weber
+#center#Software- und Hardware-Systeme, 1988
+#center#ERGOS GmbH, 1990
+#page#
+#block#
+#center#____________________________________________________________________________
+
+
+Copyright:  ERGOS GmbH   März 1990
+
+ Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+ maschinenlesbare Form sowie das Speichern in Informations­
+ systemen, auch auszugsweise, nur mit schriftlicher Einwilliging
+ Einwilligung der ERGOS GmbH gestattet.
+
+#center#____________________________________________________________________________
+
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender.
+
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden.
+
+Texterstellung :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+ erstellt und aufbereitet und auf einem Kyocera Laser­
+ drucker gedruckt.
+
+
+
+
+#center#___________________________________________________________________________
+
+
+
+Ergonomic Office Software GmbH
+
+Bergstr. 7 Telefon: (02241) 63075
+5200 Siegburg Teletex: 2627-2241413=ERGOS
+ Telefax: (02241) 63078
+
+
+#center#____________________________________________________________________________
+
diff --git a/doc/lisp/lisp handbuch b/doc/lisp/lisp handbuch
new file mode 100644
index 0000000..022c561
--- /dev/null
+++ b/doc/lisp/lisp handbuch
@@ -0,0 +1,2260 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#Lisp
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#free(7.0)#
+#center#LISP - Handbuch
+#free(2.0)#
+Stand: 08.08.86
+
+Installation von LISP
+
+begin ("LISP")
+reserve ("sprachen",archive)
+fetch all(archive)
+insert ("lisp.1")
+insert ("lisp.2")
+insert ("lisp.3")
+insert ("lisp.4")
+global manager
+begin ("lisp","LISP")
+fetch ("lisp.bootstrap")
+lisp
+#page#
+#start(2.5,1.5)#
+#block#
+#pageblock#
+#head#
+#center#LISP-Handbuch
+#center#%
+
+
+#end#
+
+
+#center#L I S P H a n d b u c h
+
+
+#center#Autor: John Mc.Carthy (M.I.T.1962)
+#center#übersetzt und angepaßt von J.Durchholz, P.Heyderhoff
+#center#Gesellschaft für Mathematik und Datenverarbeitung Sankt Augustin
+
+
+
+Inhaltsverzeichnis
+
+
+
+1. Die Sprache LISP #right##topage("p1")#
+
+1.1 Symbolische Ausdrücke #right##topage("p1.1")#
+1.2 Elementare Funktionen #right##topage("p1.2")#
+1.3 Listen Notation #right##topage("p1.3")#
+1.4 Syntax und Semantik der Sprache #right##topage("p1.4")#
+
+2. Das LISP-Interpreter-System #right##topage("p2")#
+
+2.1 Die universelle LISP-Funktion "evalquote" #right##topage("p2.1")#
+2.2 Anwendungsregeln und Beispiele #right##topage("p2.2")#
+2.3 Variablen #right##topage("p2.3")#
+2.4 Konstanten #right##topage("p2.4")#
+2.5 Funktionen #right##topage("p2.5")#
+
+3. Erweitertes LISP #right##topage("p3")#
+
+3.1 Gequotete Parameter #right##topage("p3.1")#
+3.2 Funktionen mit beliebig vielen Parametern #right##topage("p3.2")#
+3.3 Funktionale Parameter #right##topage("p3.3")#
+3.4 Prädikate und boolesche Konstanten #right##topage("p3.4")#
+3.5 Unbenannte Atome #right##topage("p3.5")#
+3.6 Aufruf von EUMEL aus #right##topage("p3.6")#
+
+4. Detailbeschreibungen #right##topage("p4")#
+
+4.1 Grundfunktionen #right##topage("p4.1")#
+4.2 Weitere Funktionen sowie Eingabe und Ausgabe #right##topage("p4.2")#
+4.3 Interpreter #right##topage("p4.3")#
+4.4 Kommandoprozeduren #right##topage("p4.4")#
+#page#
+
+1. Die Sprache LISP#goalpage("p1")#
+
+
+
+Die Sprache LISP ist primär für die Symbolmanipulation entworfen. Sie wurde für
+symbolische Berechnungen in verschiedenen Gebieten der künstlichen Intelligenz
+eingesetzt, u.a. für Differential- und Integralrechnung, Schaltkreistheorie, Mathemati­
+sche Logik, Spiele, etc..
+
+LISP ist eine formale mathematische Sprache. Daher ist es möglich, eine genaue und
+vollständige Beschreibung zu geben. Das ist der Sinn des ersten Abschnitts dieses
+Handbuchs. Andere Abschnitte werden Möglichkeiten zum vorteilhaften Einsatz von
+LISP und die Erweiterungen, die die Benutzung erleichtern, beschreiben.
+
+LISP unterscheidet sich von den meisten Programmiersprachen in drei Punkten.
+
+Der erste Punkt liegt in der Natur der Daten. In der Sprache LISP haben alle Daten
+die Form symbolischer Ausdrücke, die wir verkürzend LISP-Ausdrücke nennen wer­
+den. LISP-Ausdrücke haben keine Längenbegrenzung und eine verzweigte Baum­
+struktur, so daß Unterausdrücke leicht isoliert werden können. In LISP wird der meiste
+Speicherplatz für das Abspeichern der LISP-Ausdrücke in Form von Listenstruktu­
+ren gebraucht.
+
+Der zweite wichtige Teil der Sprache LISP ist die Quellsprache, die festlegt, wie die
+LISP-Ausdrücke verarbeitet werden sollen.
+
+Drittens kann LISP als LISP-Ausdrücke geschriebene Programme interpretieren und
+ausführen. Deshalb kann man die Sprache analog zu Assemblersprachen und im
+Gegensatz zu den meisten anderen höheren Programmiersprachen einsetzen, um
+Programme zu generieren, die gleich ausgeführt werden sollen.
+
+
+#page#
+
+1.1 Symbolische Ausdrücke #goalpage("p1.1")#
+
+
+
+Ein elementarer Ausdruck ist ein Atom.
+
+Definition: Ein Atom ist eine Zeichenkette bestehend aus Großbuchstaben und
+ Ziffern.
+
+
+Beispiele: A
+ APFEL
+ TEIL2
+ EXTRALANGEZEICHENKETTEAUSBUCHSTABEN
+ A4B66XYZ2
+
+
+Diese Symbole werden atomar genannt, weil sie als Ganzes aufgefaßt werden, das
+durch die LISP-Funktionen nicht weiter geteilt werden kann. A, B, und AB haben
+keinerlei Beziehung zueinander, außer der, daß sie alle verschiedene Atome sind.
+
+Alle LISP-Ausdrücke werden aus Atomen und den Satzzeichen "(", ")" und "."
+aufgebaut. Die grundlegende Operation zum Aufbau von LISP-Ausdrücken ist die,
+zwei LISP-Ausdrücke zusammenzufassen, um einen größeren herzustellen. Aus den
+zwei Atomen A und B kann man so den LISP-Ausdruck (A.B) bilden.
+
+Definition: Ein LISP-Ausdruck ist entweder ein Atom, oder aus folgenden Elemen­
+ ten in dieser Reihenfolge aufgebaut: Eine öffnende Klammer, ein
+ LISP-Ausdruck, ein Punkt, ein LISP-Ausdruck, eine schließende
+ Klammer. Zwischen den Bestandteilen eines nichtatomaren LISP-Aus­
+ druck können beliebig viele Leerzeichen eingestreut sein.
+
+Diese Definition ist rekursiv.
+
+
+Beispiele: ATOM
+ (A . B)
+ (A . (B . C))
+ ((A1 . A2) . B)
+ ((U . V) . (X . Y))
+ ((U . V) . (X . (Y . Z)))
+
+
+Um die Struktur solcher Ausdrücke zu verdeutlichen, wird in diesem Handbuch oft
+eine graphische Darstellung gewählt. In dieser Darstellung sind die Atome weiterhin
+Zeichenketten, statt der Paare steht jetzt aber ein Kasten
+
+
+ +-----+-----+
+ | o | o |
+ +-----+-----+
+
+
+von dem zwei Zeiger ausgehen, die auf die graphische Darstellung des ersten bzw.
+zweiten Elements des Paars zeigen.
+
+
+
+Beispiele: (A . B) +-----+-----+
+ | o | o |
+ +--+--+--+--+
+ | |
+ V V
+ A B
+
+ (A . (B . C)) +-----+-----+
+ | o | o |
+ +--+--+--+--+
+ | |
+ V V
+ A +-----+-----+
+ | o | o |
+ +--+--+--+--+
+ | |
+ V V
+ B C
+
+ ((U . V) . (X . (Y . Z))) +-----+-----+
+ | o | o |
+ +--+--+--+--+
+ | |
+ V V
+ +-----+-----+ +-----+-----+
+ | o | o | | o | o |
+ +--+--+--+--+ +--+--+--+--+
+ | | | |
+ V V V V
+ U V X +-----+-----+
+ | o | o |
+ +--+--+--+--+
+ | |
+ V V
+ Y Z
+
+
+
+
+
+
+#page#
+
+1.2 Elementare Funktionen #goalpage("p1.2")#
+
+
+Wir werden einige elementare Funktionen auf LISP-Ausdrücken einführen. Um die
+Funktionen von den LISP-Ausdrücken zu unterscheiden, werden wir Funktionsnamen
+mit Klein- statt Großbuchstaben schreiben. Außerdem steht der Funktionsname
+gefolgt von den Argumenten, auf die die Funktion angewendet werden soll, in Klam­
+mern eingeschlossen in einer Liste. Dabei sind die Argumente durch Blanks vonein­
+ander getrennt.
+
+Die erste Funktion, die wir einführen, heißt "cons". Sie hat zwei Argumente und wird
+dafür benutzt, LISP-Ausdrücke aus kleineren LISP-Ausdrücken aufzubauen.
+
+
+ Funktionsaufruf: Ergebnis:
+
+Beispiele: (cons A B) = (A . B)
+ (cons (A . B) C) = ((A . B) . C)
+ (cons (cons A B) C) = ((A . B) . C)
+
+
+Die Beispiele zeigen Funktionsaufrufe. Ein Funktionsaufruf ist eine Liste beginnend
+mit einem Funktionsnamen, gefolgt von Argumenten. Alle Funktionsaufrufe haben ein
+Ergebnis, das im Fall von LISP-Funktionen immer ein LISP-Ausdruck ist.
+
+In diesen Beispielen kommt nur die Funktion "cons" vor. Das letzte Beispiel ist ein
+Fall von Funktionsverkettung, das heißt, als Argument steht ein Funktionsaufruf. Um
+das Ergebnis eines Funktionsaufrufs zu berechnen, das Funktionsaufrufe als Argu­
+mente enthält, muß man statt dieser Argumente die Ergebnisse dieser Funktionsaufru­
+fe einsetzen, so daß man den äußeren Funktionsaufruf in einen Aufruf ohne Funk­
+tionsaufrufe als Argumente umwandelt.
+
+
+Beispiel: (cons (cons A B) C) = (cons (A . B) C) = ((A . B) . C)
+
+
+Es ist möglich, durch Verkettung der Funktion "cons" jeden LISP-Ausdruck aus
+seinen atomaren Komponenten aufzubauen.
+
+Die folgenden beiden Funktionen tun das genaue Gegenteil von "cons": sie liefern
+die Unterausdrücke eines gegebenen LISP-Ausdrucks.
+
+Die Funktion "head" hat ein Argument. Ihr Wert ist der erste Unterausdruck des
+zusammengesetzen Arguments. Der "head" eines Atoms ist nicht definiert.
+
+
+Beispiele: (head (A . B)) = A
+ (head (A . (B1 . B2))) = A
+ (head ((A1 . A2) . B)) = (A1 . A2)
+ (head A) ist nicht definiert
+
+
+Die Funktion "tail" hat ebenfalls ein Argument, und sie liefert das Argument bis auf
+dessen "head".
+
+
+Beispiele: (tail (A . B)) = B
+ (tail (A . (B1 . B2))) = (B1 . B2)
+ (tail ((A1 . A2) . B)) = B
+ (tail A) ist nicht definiert
+ (head (tail (A . (B1 . B2)))) = B1
+ (head (tail (A . B))) ist nicht definiert
+ (head (cons A B)) = A
+
+
+Es ist bei jedem LISP-Ausdruck möglich, durch eine geeignete Verkettung von
+"head" und "tail" zu jedem Atom im Ausdruck zu gelangen.
+
+Wenn "x" und "y" irgendwelche LISP-Ausdrücke repräsentieren, gelten die folgen­
+den Gleichungen immer:
+
+
+ (head (cons x y)) = x
+ (tail (cons x y)) = y
+
+
+Außerdem gilt die folgende Gleichung für jeden nichtatomaren LISP-Ausdruck "z":
+
+
+ (cons (head z) (tail z)) = z
+9
+
+Die Symbole "x", "y" und "z", die wir in diesen Gleichungen benutzt haben, nennt
+man Variablen. In LISP werden Variable benutzt, um LISP-Ausdrücke zu repräsentie­
+ren, und zwar repräsentiert eine Variable in einer Gleichung immer denselben
+LISP-Ausdruck. Variablennamen werden wie Funktionsnamen gebildet, d.h. sie
+können Kleinbuchstaben und Ziffern enthalten.
+
+Eine Funktion, deren Wert "wahr" oder "falsch" sein kann, wird Prädikat genannt. In
+LISP werden die Werte "wahr" und "falsch" durch die Atome "T" (true) und "F"
+(false) vertreten. Ein LISP-Prädikat ist also eine Funktion, deren Wert entweder "T"
+oder "F" ist.
+
+Das Prädikat "eq" ist ein Gleichheitstest für Atome. Es ist bei nicht atomaren Argu­
+menten nicht definiert.
+
+
+Beispiele: (eq A A) = T
+ (eq A B) = F
+ (eq A (A . B)) ist nicht definiert
+ (eq (A . B) B) ist nicht definiert
+ (eq (A . B) (A . B)) ist nicht definiert
+
+
+Das Prädikat "atom" hat das Ergebnis ("liefert") "T", wenn sein Argument atomar ist,
+und "F", wenn sein Argument zusammengesetzt ist.
+
+
+Beispiele: (atom EXTRALANGEZEICHENKETTE) = T
+ (atom (U . V)) = F
+ (atom (head (U . V))) = T
+
+#page#
+
+1.3 Listen-Notation #goalpage("p1.3")#
+
+
+
+Alle LISP-Ausdrücke, die wir bisher gesehen haben, waren in Punkt-Notation
+geschrieben. Normalerweise ist es allerdings einfacher, statt der vielen Punkte und
+Klammern Listen von LISP-Ausdrücken zu schreiben, etwa in der Art (A B C XYZ).
+
+LISP bietet eine solche Alternative zur Punkt-Notation an:
+
+Definition: Die Liste (a1 a2 ... an) ist äquivalent zum LISP-Ausdruck
+ (a1 . (a2 . (... . (an . NIL) ... ))).
+
+Graphisch ausgedrückt heißt das:
+
+
+ +-----+-----+
+ | o | o |
+ +--+--+--+--+
+ | |
+ V V
+ a1 +-----+-----+
+ | o | o |
+ +--+--+--+--+
+ | |
+ V V
+ a2
+ .
+ .
+ .
+
+ +-----+-----+
+ | o | o |
+ +--+--+--+--+
+ | |
+ V V
+ an NIL
+
+
+
+Oft werden wir für Listen auch die graphische Form
+
+
+ +-----+-----+ +-----+-----+ +-----+-----+
+ | o | o--+-->| o | o--+--> . . . | o | o--+--> NIL
+ +--+--+-----+ +--+--+-----+ +--+--+-----+
+ | | |
+ V V V
+ a1 a2 an
+
+
+benutzen.
+
+Aus der Graphik wird deutlich, daß NIL als eine Art Abschlußmarkierung für Listen
+dient.
+
+Eine leere Liste wird durch das Atom NIL dargestellt. Das Prädikat "null" liefert "T",
+wenn sein Argument eine leere Liste ist, sonst "F".
+
+
+Beispiele: (null NIL) = T
+ (null () ) = T
+ (null (A B)) = F
+
+
+Die Listenelemente können selbst wieder Listen oder Paare in Punkt-Notation sein,
+so daß Listen- und Punkt-Notation beliebig kombinierbar sind.
+
+
+ Beispiele: (A B C) = (A . (B . (C . NIL)))
+
+ +-----+-----+ +-----+-----+ +-----+-----+
+ | o | o--+-->| o | o--+-->| o | o--+--> NIL
+ +--+--+-----+ +--+--+-----+ +--+--+-----+
+ | | |
+ V V V
+ A B C
+
+ ((A . B) C) = ((A . B) . (C . NIL))
+
+ +-----+-----+ +-----+-----+
+ | o | o--+-->| o | o--+--> NIL
+ +--+--+-----+ +--+--+-----+
+ | |
+ V V
+ +-----+-----+ C
+ | o | o |
+ +--+--+--+--+
+ | |
+ V V
+ A B
+
+ ((A B) C) = ((A . (B . NIL)) . (C . NIL))
+
+ +-----+-----+ +-----+-----+
+ | o | o--+--------------->| o | o--+--> NIL
+ +--+--+-----+ +--+--+-----+
+ | |
+ | V
+ V C
+ +-----+-----+ +-----+-----+
+ | o | o--+-->| o | o--+--> NIL
+ +--+--+-----+ +--+--+-----+
+ | |
+ V V
+ A B
+
+ (A) = (A . NIL)
+
+ +-----+-----+
+ | o | o--+--> NIL
+ +--+--+-----+
+ |
+ V
+ A
+
+ ((A)) = ((A . NIL) . NIL)
+
+ +-----+-----+
+ | o | o--+--> NIL
+ +--+--+-----+
+ |
+ V
+ +-----+-----+
+ | o | o--+--> NIL
+ +--+--+-----+
+ |
+ V
+ A
+
+
+
+
+
+Es ist sehr hilfreich, mit den Ergebnissen der elementaren Funktionen vertraut zu
+sein, wenn diese Listen als Argumente erhalten. Zwar können die Ergebnisse notfalls
+immer durch Übersetzung in Punkt-Notation bestimmt werden, aber ein direktes
+Verständnis ist einfacher.
+
+
+Beispiele: (head (A B C)) = A
+ (tail (A B C)) = (B C)
+
+
+ (Daher auch die Namen "head" und "tail"! Frei übersetzt heißen die
+ beiden Funktionen "anfang" und "rest".)
+
+
+ (cons A (B C)) = (A B C)
+
+#page#
+
+1.4 Syntax und Semantik der Sprache #goalpage("p1.4")#
+
+
+
+Wir haben bisher einen Datentyp (LISP-Ausdrücke) und fünf elementare Funktionen
+eingeführt. Außerdem haben wir die folgenden Eigenschaften der Sprache beschrie­
+ben:
+
+1. Funktions- und Variablennamen werden wie die Namen von Atomen geschrie­
+ ben, außer, daß dafür Klein- statt Großbuchstaben verwendet werden.
+2. Die Argumente einer Funktion folgen dieser in der Liste. Eine solche Liste von
+ Funktion und folgenden Argumenten heißt Funktionsaufruf und hat einen LISP-
+ Ausdruck als Ergebnis.
+3. Funktionen können dadurch verkettet werden, daß ein Argument aus einem Funk­
+ tionsaufruf selbst wieder ein Funktionsaufruf ist, dessen Argumente selbst wieder
+ Funktionsaufrufe sein können, usw.
+
+Diese Regeln erlauben es, Funktionsdefinitionen wie
+
+
+ (third x) = (head (tail (tail x)))
+
+
+zu schreiben. "third" holt das dritte Element aus einer Liste.
+
+Die Klasse der Funktionen, die man auf diese Weise bilden kann, ist ziemlich be­
+schränkt und nicht sehr interessant. Eine viel größere Funktionenklasse kann man mit
+Hilfe des bedingten Ausdrucks schreiben; es handelt sich dabei um eine Möglichkeit,
+Verzweigungen in Funktionsdefinitionen einzubauen.
+
+Ein bedingter Ausdruck hat die Form
+
+
+ (cond (p1 a1) (p2 a2) ... (pn an) )
+
+
+Jedes pi ist ein Ausdruck, dessen Wert "T" oder "F" ist, also ein Prädikat. Die ai
+sind beliebige LISP-Ausdrücke.
+
+Die Bedeutung eines bedingten Ausdrucks ist folgende: Wenn p1 wahr ist, ist a1 der
+Wert des ganzen Ausdrucks. Wenn p1 falsch ist, wird getestet, ob p2 wahr ist; wenn
+das der Fall ist, ist a2 der Wert des Ausdrucks. Die pi werden also von links nach
+rechts durchgegangen, bis ein wahrer Ausdruck gefunden ist; das zugehörige ai ist
+dann der Wert des bedingten Ausdrucks. Wenn kein wahres pi gefunden ist, ist der
+bedingte Ausdruck nicht definiert.
+Jedes pi oder ai kann selbst wieder ein LISP-Ausdruck, ein Funktionsaufruf oder ein
+bedingter Ausdruck sein.
+
+
+Beispiel: (cond ((eq (head x) A) (cons B (tail x))) (T x) )
+
+
+Das Prädikat "T" ist immer wahr. Man liest es am besten als "SONST". Den Wert
+dieses Ausdruck erhält man, wenn man "head" von x durch B ersetzt, wenn der
+gerade gleich mit A ist, und sonst erhält man x.
+
+Der Hauptzweck von bedingten Ausdrücken ist die rekursive Definition von Funktio­
+nen.
+
+
+Beispiel: (firstatom x) = (cond ((atom x) x)
+ ( T (firstatom (head x)))
+ )
+
+
+Dies Beispiel definiert die Funktion "firstatom", die das erste Atom jedes LISP-Aus­
+drucks bestimmt. Diesen Ausdruck kann man so lesen: wenn "x" ein Atom ist, ist "x"
+selbst die Antwort; sonst muß "firstatom" auf "head" von "x" angewandt werden.
+
+Wenn also "x" ein Atom ist, wird der erste Zweig gewählt, der "x" liefert; sonst wird
+der zweite Zweig "firstatom (head x)" gewählt, weil "T" immer wahr ist.
+
+Die Definition von "firstatom" ist rekursiv, d.h. "firstatom" ist mit durch sich selbst
+definiert. Allerdings, wenn man immerzu den "head" von irgendeinem LISP-Aus­
+druck nimmt, errreicht man irgendwann ein Atom, so daß der Prozeß immer wohlde­
+finiert ist.
+
+Es gibt rekursive Funktionen, die nur für bestimmte Argumente wohldefiniert sind, für
+bestimmte andere dagegen unendlich rekursiv. Wenn das EUMEL-LISP-System
+einen Funktionsionsaufruf mit einer solchen Funktion und "kritischen" Argumenten
+interpretiert, gerät es in unendliche Rekursion, bis entweder der zur Verfügung ste­
+hende Platz im LISP-Heap ausgeschöpft ist (im Heap werden die LISP-Ausdrücke
+gespeichert) oder bis der Laufzeitstack überläuft (der Laufzeitstack ist ein normaler­
+weise unsichtbarer Bestandteil des ELAN-Systems).
+Wir werden jetzt die Berechnung von "(firstatom ((A . B) . C))" durchführen. Zunächst
+ersetzen wir die Variable x in der Funktionsdefinition durch ((A . B) . C) und erhalten
+
+
+ (firstatom ((A . B) . C)) =
+ (cond ( (atom ((A . B) . C)) ((A . B) . C) )
+ ( T (firstatom (head ((A . B) . C))) )
+ )
+
+((A . B) . C) ist kein Atom, deshalb wird daraus
+
+ = (cond ( T (firstatom (head ((A . B) . C)))) )
+ = (firstatom (head ((A . B) . C)) )
+ = (firstatom (A . B))
+
+
+
+An diesem Punkt müssen wir wieder die Definition von "firstatom" benutzen, diesmal
+aber für "x" überall "(A . B)" einsetzen.
+
+
+ (firstatom (A . B)) = (cond ( (atom (A . B)) (A . B) )
+ (T (firstatom (head (A . B))) )
+ )
+ = (cond (T (firstatom (head (A . B))) ) )
+ = (firstatom (head (A . B)) )
+ = (firstatom A)
+ = (cond ((atom A) A)
+ (T (firstatom (head A)) )
+ )
+ = A
+
+
+Wenn in den bedingten Ausdrücken statt der LISP-Ausdrücke arithmetische Aus­
+drücke verwendet würden, könnte man damit auch numerische Rechenvorschriften
+definieren, wie z.B. den Betrag einer Zahl durch
+
+
+ (abs x) = (cond ((x < 0) -x) (T x) )
+
+
+oder die Fakultät durch
+
+
+ (fak n) = (cond ((n = 0) 1)
+ (T (x * (fak (n - 1))))
+ )
+
+
+Die Fakultät terminiert bei negativen Argumenten nicht.
+
+Es ist bei den meisten Mathematikern (außer den Logikern) üblich, das Wort "Funk­
+tion" nicht präzise zu verwenden und auf Ausdrücke wie "2x+y" anzuwenden. Da wir
+Ausdrücke benutzen werden, die Funktionen repräsentieren, benötigen wir eine
+Notation, die Funktionen und Ausdrücke unterscheidet. Dafür ist die Lambda-Nota­
+tion von Alonzo Church geeignet.
+"f" soll ein Ausdruck sein, der für eine Funktion zweier ganzzahliger Variablen steht.
+
+Dann sollte es sinnvoll sein, den Funktionsaufruf
+
+
+ (f 3 4)
+
+
+zu schreiben, so daß man dadurch den Wert dieses Funktionsaufrufs berechnen kann;
+z.B. könnte "(summe 3 4) = 7" gelten.
+
+Wenn man "2x + y" als Funktion ansieht, kann man den Funktionsaufruf
+
+
+ ((2x + y) 3 4)
+
+
+schreiben. Der Wert dieses Ausdrucks ist aber nicht eindeutig bestimmt, denn es ist
+überhaupt nicht klar, ob nun "2*3+4" oder 2*4+3" gemeint ist. Eine Zeichenfolge
+wie "2x + y" werden wir deshalb Ausdruck und nicht Funktion nennen. Ein Ausdruck
+kann in eine Funktion umgewandelt werden, indem man die Zuordnung von Argumen­
+ten und Variablen festlegt. Bei "2x + y" könnte man beispielsweise festlegen, daß
+"x" immer das erste und "y" immer das zweite Argument sein soll.
+Wenn "a" ein Ausdruck in den Variablen x1, ... xn ist, dann ist
+
+
+ (lambda (x1 ... xn) a)
+
+
+eine Funktion mit n Argumenten. Den Wert der Funktionsaufrufe mit dieser Funktion
+(also der Ausdrücke der Form
+
+
+ ((lambda (x1 ... xn) a) (b1 ... bn))
+ erhält man, indem man die Variablen x1 ... xn durch die n Argumente des Aufrufs
+ersetzt. Beispielsweise ist
+
+
+ ((lambda (x y) (2*x + y)) (3 4)) = 2*3 + 4 = 10 ,
+
+
+während
+
+
+ ((lambda (y x) (2*x + y)) (3 4)) = 2*4 + 3 = 11
+
+
+ist.
+
+Die Variablen in einem Lambdaausdruck sind sogenannte Parameter (oder gebundene
+Variable). Interessant ist, daß eine Funktion sich nicht ändert, wenn man eine Variable
+systematisch durch eine andere Variable ersetzt, die nicht bereits im Lambdaausdruck
+vorkommt.
+
+
+ (lambda (x y) (2*y + x))
+
+
+ist also dasselbe wie
+
+
+ (lambda (u v) (2*v + u)) .
+
+
+Manchmal werden wir Ausdrücke benutzen, in denen eine Variable nicht durch das
+Lambda gebunden ist. Beispielsweise ist das n in
+
+
+ (lambda (x y) (x*n + y*n))
+
+
+nicht gebunden. Eine solche nicht gebundene Variable nennt man frei.
+Wenn für eine freie Variable vor der Benutzung kein Wert vereinbart wurde, ist der
+Wert des Funktionsaufrufs nicht definiert, falls der Wert der Variablen auf das Ergeb­
+nis einen Einfluß hat.
+
+Die Lambdanotation reicht allein für die Definition rekursiver Funktionen nicht aus.
+Neben den Variablen muß auch der Name der Funktion gebunden werden, weil er
+innerhalb der Funktion für eine Zeichenfolge steht.
+
+Wir hatten die Funktion "firstatom" durch die Gleichung
+
+
+ (firstatom x) = (cond ((atom x) x)
+ (T (firstatom (head x)))
+ )
+
+
+definiert. Mit der Lambda-Notation können wir schreiben:
+
+
+ firstatom = (lambda (x) (cond ((atom x) x)
+ (T (firstatom (head x)))
+ ) )
+
+
+
+Das Gleichheitszeichen ist in Wirklichkeit nicht Teil der LISP-Sprache, sondern eine
+Krücke, die wir nicht mehr brauchen, wenn wir die richtige Schreibweise eingeführt
+haben.
+
+Die rechte Seite der obigen Gleichung ist als Funktion nicht vollständig, da dort nichts
+darauf hinweist, daß das "firstatom" im einem bedingten Ausdruck für eben die rechte
+Seite steht. Deshalb ist die rechte Seite als Definition für die linke Seite ("firstatom")
+noch nicht geeignet.
+
+Damit wir Definitionen schreiben können, in denen der Name der gerade definierten
+Funktion auftaucht, führen wir die Label-Notation ein (engl. label = Marke, (Preis-)
+Schildchen). Wenn "a" eine Funktion ist, und "n" ihr Name, schreiben wir "(label n
+a)".
+
+Nun können wir die Funktion "firstatom" ohne Gleichheitszeichen schreiben:
+
+
+ (label firstatom (lambda (x) (cond ((atom x) x)
+ (T (firstatom (head x)))
+ ) ) )
+
+
+In dieser Definition ist "x" eine gebundene Variable und "firstatom" ein gebundener
+Funktionsname.
+#page#
+
+2. Das LISP-Interpreter-System#goalpage("p2")#
+
+
+
+2.1 Die universelle LISP-Funktion
+ "evalquote" #goalpage("p2.1")#
+
+
+
+Ein Interpreter oder eine allgemeine Funktion ist eine Funktion, die den Wert jedes
+gegebenen Ausdrucks berechnen kann, wenn der Ausdruck in einer geeigneten Form
+vorliegt. (Wenn der zu interpretierende Ausdruck einen Aufruf einer unendlich rekur­
+siven Funktion enthält, wird der Interpreter natürlich ebenfalls unendlich rekursiv.)
+Wir sind jetzt in der Lage, eine allgemeine LISP-Funktion
+
+
+ (evalquote function arguments)
+
+
+zu definieren. "evalquote" muß als erstes Argument ein LISP-Ausdruck übergeben
+werden. Dieser wird als Funktion aufgefasst und auf die folgenden Argumente ange­
+wendet.
+
+Im Folgenden sind einige nützliche Funktionen zur Manipulation von LISP-Aus­
+drücken angegeben. Einige von ihnen werden als Hilfsfunktionen für die Definition von
+"evalquote" gebraucht, die wir uns vorgenommen haben.
+
+
+ (equal x y)
+
+
+ist ein Prädikat, das wahr ist, wenn seine Argumente gleiche LISP-Ausdrücke sind.
+(Das elementare Prädikat "eq" ist ja nur für Atome definiert.)
+
+Die Definition von "equal" ist ein Beispiel für einen bedingten Ausdruck innerhalb
+eines bedingten Ausdrucks.
+
+
+(label equal
+ (lambda (x y)
+ (cond
+ ((atom x) (cond
+ ((atom y) (eq x y))
+ (T F)
+ )
+ )
+ ((equal (head x) (head y)) (equal (tail x) (tail y)))
+ (T F)
+ )
+ )
+)
+
+
+
+Folgende Funktion liefert einen LISP-Ausdruck, der gleich mit "destination" ist,
+außer daß darin überall statt "old" "new" steht.
+
+
+(changeall (destination old new))
+
+= (cond ((equal destination old) new)
+ ((atom destination) destination)
+ (T (cons (changeall (head destination) old new)
+ (changeall (tail destination) old new)
+ )
+ )
+ )
+
+
+Beispielsweise gilt
+
+
+(changeall ((A . B) . C) B (X . A)) = ((A . (X . A)) . C)
+
+
+Die folgenden Funktionen sind nützlich, wenn Listen verarbeitet werden sollen.
+
+1. (append x y)
+ hängt an die Liste "x" den LISP-Ausdruck "y".
+
+
+ (append x y) =
+ (cond ((null x) y)
+ (T (cons (head x) (append (tail x) y) ))
+ )
+
+
+2. (member list pattern)
+ Dies Prädikat testet, ob der LISP-Ausdruck "pattern" in der Liste "list" vor­
+ kommt.
+
+
+ (member list pattern) =
+ (cond ((null list) F)
+ ((equal (head list) pattern) T)
+ (T (member (tail list) pattern))
+ )
+
+
+3. (pairlist list1 list2 oldpairlist)
+ Diese Funktion liefert eine Liste von Paaren, die die sich entsprechenden Elemen­
+ te der Listen "list1" und "list2" enthalten, und an der noch die Liste "oldpairlist"
+ hängt.
+
+
+
+ (pairlist list1 list2 oldpairlist) =
+ (cond ((null list1) oldpairlist)
+ (T (cons (cons (head list1) (head list2))
+ (pairlist (tail list1) (tail list2) oldpairlist)
+ )
+ )
+ )
+
+
+Beispiel:
+ (pairlist (A B C) (U V W) ((D . X) (E . Y)) ) =
+ ((A . U) (B . V) (C . W) (D . X) (E . Y))
+
+
+Eine solche Liste von Paaren wird auch Assoziationsliste genannt, wenn das erste
+Element jedes Paars ein Atom ist, das über diese Liste mit dem zweiten Element
+assoziiert ist.
+
+5. (association pattern associationlist)
+ Wenn "association list" eine Assoziationsliste wie oben beschrieben ist, liefert
+ "association" das Paar der Liste, dessen erstes Element "pattern" ist. Es ist also
+ eine Funktion zum Durchsuchen von Tabellen.
+
+
+ (association pattern alist) =
+ (cond ((eq (head (head alist)) pattern) (head alist))
+ (T (association pattern (tail alist)))
+ )
+
+Beispiel:
+
+(association B ( (A . (M N))
+ (B . (HEAD X))
+ (C . (QUOTE M))
+ (B . (TAIL X))
+ ) ) = (B . (HEAD X))
+
+
+(replace expr alist)
+ "alist" muß eine Assoziationsliste sein. "replace" produziert einen Ausdruck, der
+ "expr" sehr ähnlich ist, nur sind alle Atome darin durch den LISP-Ausdruck
+ ersetzt, mit dem sie in "alist" assoziiert sind.
+
+
+ (replace expr alist) =
+ (cond ((atom expr) (association expr alist))
+ (T (cons (replace (head expr) alist)
+ (replace (tail expr) alist)
+ )
+ )
+ )
+
+Beispiel:
+
+ (replace (X SCHRIEB Y)
+ ((Y . (GOETZ VON BERLICHINGEN)) (X . GOETHE))
+ )
+
+ = (GOETHE SCHRIEB (GOETZ VON BERLICHINGEN))
+
+
+
+Die allgemeine Funktion "evalquote", die wir jetzt definieren wollen, gehorcht der
+folgendem Beispiel zugrundeliegenden Regel:
+
+
+Beispiel:
+ (evalquote
+Funktion: (LAMBDA (X Y) (CONS (HEAD X) Y) )
+Argumente: (A B) (C D)
+ )
+=
+ (apply
+Funktion: (LAMBDA (X Y) (CONS (HEAD X) Y))
+Argumentliste: ((QUOTE (A B)) (QUOTE (C D)))
+Bindung: NIL
+ )
+
+
+Die Argumente von "evalquote" werden also zu einer gequoteten Argumentliste von
+"apply". Die QUOTE-Funktion bewirkt, daß das Argument der QUOTE-Funktion
+wörtlich genommen, also nicht weiter evaluiert wird. Das dritte Argument von "apply",
+das NIL ist eine leere Bindeliste zur Bindung von Parametern und Argumenten im
+nächsten Schritt:
+
+
+=
+ (eval
+Argumente: (CONS (HEAD X) Y)
+Bindung: ((X.(A B)) (Y . (C D)))
+ )
+=
+ (cons (head (A B)) (C D))
+=
+ (A C D) = Ergebnis von "evalquote" .
+
+
+"evalquote" wird hauptsächlich durch die Hilfsfunktion "apply" definiert. "apply"
+berechnet Funktionsaufrufe, indem es die Argumente und die Parameter der Funktion
+bindet und den Funktionsrumpf berechnet. Die Bindungen werden in einer Assozia­
+tionsliste, der Bindeliste, gespeichert. Da bedingte Ausdrücke und Konstanten formal
+wie Funktionsaufrufe von Funktionen "cond" und "quote" aussehen, werden sie auch
+so behandelt.
+
+Wir definieren also:
+
+
+ (evalquote fkt expr) = (apply fkt (quote expr) NIL) .
+
+
+sowie :
+
+
+ (eval expr binding) =
+ (cond ((atom expr) (tail (association expr binding)))
+ (T (apply (head expr) (tail expr) binding))
+ )
+
+
+"eval" stellt also erst fest, ob es sich um ein Atom oder um einen Funktionsaufruf
+handelt. Da es nur diese beiden Möglichkeiten gibt, ist diese Einteilung vollständig.
+
+Atome sind immer Übersetzungen von Variablen, für die eine Bindung existieren muß,
+so daß ihr Wert aus der Bindeliste geholt wird.
+
+Funktionsaufrufe sind immer Listen; im zweiten Zweig werden die Funktion und die
+Parameterliste getrennt und an "apply" übergeben.
+
+Um sich die Aktionen in diesem zweiten Zweig von "eval" genauer vorstellen zu
+können, ist vielleicht die in Abschnitt 1.1 beschriebene graphische Darstellungsmetho­
+de hilfreich; beispielsweise würde sich ein Lambda-Ausdruck so ausnehmen:
+
+
+ +-----+-----+ +-----+-----+ +-----+-----+
+ | o | o--+-->| o | o--+-->| o | o--+-->NIL
+ +--+--+-----+ +--+--+-----+ +--+--+-----+
+ | | |
+ V V V
+ LAMBDA Parameterliste Ausdruck
+
+
+"apply" bekommt nun von "eval" eine Funktion und eine Parameterliste sowie die
+Bindeliste übergeben. Mit diesen beiden macht es folgendes:
+
+
+ (apply fn args binding) =
+(cond
+ ((atom fn)
+ (cond ((eq fn HEAD) (head (eval (head args) binding)))
+ ((eq fn TAIL) (tail (eval (head args) binding)))
+ ((eq fn CONS) (cons (eval (head args) binding)
+ (eval (head (tail args)) binding)
+ ) )
+ ((eq fn ATOM) (atom (eval (head args) binding)))
+ ((eq fn EQ) (eq (eval (head args) binding)
+ (eval (head (tail args)) binding)
+ ) )
+ ((eq fn QUOTE) (head args))
+ ((eq fn COND) (evalcond args binding))
+ (T (apply (tail (association fn binding)) args binding))
+ )
+ ((eq (head fn) LABEL)
+ (apply (head (tail (tail fn)))
+ args (cons (cons (head (tail fn))
+ (head (tail (tail fn)))
+ )
+ binding)
+ ) )
+ ((eq (head fn) LAMBDA) (eval (head (tail (tail fn)))
+ (pairlist (head (tail fn))
+ args binding)
+ ) )
+)
+
+
+
+
+
+
+Das erste Argument von "apply" ist eine Funktion (unter der Voraussetzung, daß
+"quote" und "cond" als Funktionen anerkannt werden).
+
+Wenn es eine der elementaren Funktionen "head", "tail", "cons", "atom" oder "eq"
+ist, wird die jweilige Funktion auf die Argumente angewandt, die vorher berechnet
+werden. Diese Berechnung erfolgt mit "eval", das ja für Variablen Werte aus der
+Bindeliste liefert und für Funktionsaufrufe das, was "apply" mit ihnen machen kann.
+
+Wenn es sich um "quote" handelt, wird das erste Argument unverändert geliefert
+"quote" heißt ja "dies ist eine Konstante, die so, wie sie da steht, übernommen wer­
+den soll".
+
+Wenn es sich um "cond" handelt, wird die Funktion "eval cond" aufgerufen, doch
+auch ihre Argumente werden nicht berechnet, außerdem gehört die Assoziationsliste
+zu den Argumenten:
+
+
+ eval (cond condlist, binding) =
+ (cond ((eval (head (head condlist)) binding)
+ (eval (head (tail (head condlist))) binding)
+ )
+ (T (cond (tail condlist) binding))
+ )
+
+
+
+Hier empfiehlt es sich, einen bedingten Ausdruck in graphischer Form hinzuschreiben
+und die Auswertung anhand der Zeichnung nachzuvollziehen.
+
+Wenn die Funktion nichts von alledem ist, wird in der Bindeliste nachgesehen, ob
+dies Atom nicht an eine Funktion gebunden ist; falls ja, wird eine Auswertung dieser
+Funktion mit den gleichen Argumenten versucht.
+
+Wenn das erste Argument von "apply" kein Atom ist, muß es ein LABEL- oder ein
+LAMBDA-Ausdruck sein.
+
+Ein LABEL-Ausdruck hat die Form
+
+
+ +-----+-----+ +-----+-----+ +-----+-----+
+ | o | o--+-->| o | o--+-->| o | o--+--> NIL
+ +--+--+-----+ +--+--+-----+ +--+--+-----+
+ | | |
+ V V V
+ LABEL Name Funktion
+
+
+Funktionsname und Definition werden in einem funktionalen Eintrag in die Bindeliste
+eingefügt, so daß der Name an die Funktion gebunden ist.
+
+Ein LAMBDA-Ausdruck hat die Form
+
+
+ +-----+-----+ +-----+-----+ +-----+-----+
+ | o | o--+-->| o | o--+-->| o | o--+--> NIL
+ +--+--+-----+ +--+--+-----+ +--+--+-----+
+ | | |
+ V V V
+ LAMBDA Parameterliste Ausdruck
+
+
+Dabei ist die Parameterliste eine Liste von Atomen, den Parametern. Die Auswertung
+läuft so ab, daß die Parameter durch "pairlist" an die Argumente gebunden werden
+und mit dieser neuen Bindeliste der Ausdruck berechnet wird.
+
+Das EUMEL-LISP bietet eine Reihe weiterer Möglichkeiten, die erst später beschrie­
+ben werden. Hier können wir allerdings schon die folgenden Punkte abhandeln:
+
+1. Jede LISP-Eingabe ist ein LISP-Ausdruck. Der "head" dieses Ausdrucks wird
+ als Funktion aufgefaßt und auf den gequoteten "tail" des Ausdrucks, nämlich die
+ nicht zu evaluierenden Argumente angewandt. Die Übersetzung von Kleinbuchsta­
+ ben in Großbuchstaben wird vom LISP-System übernommen.
+
+2. In der Theorie des reinen LISP müssen alle Funktionen außer den fünf Basisfunk­
+ tionen an allen Stellen wieder definiert werden, an denen sie aufgerufen werden.
+ Das ist eine für die Praxis äußerst unhandliche Regelung; das EUMEL-LISP-
+ System kennt weitere vordefinierte Funktionen und bietet die Möglichkeit, beliebig
+ viele weitere Standardfunktionen einzuführen, auch solche Funktionen, deren
+ Argumente nicht berechnet werden (wie "quote") oder solche, die beliebig viele
+ Argumente haben dürfen (wie "cond").
+
+3. Die Basisfunktion "eq" hat immer einen wohldefinierten Wert, dessen Bedeutung
+ im Fall, daß Nicht-Atome verglichen werden, im Kapitel über Listenstrukturen
+ erklärt wird.
+
+4. Außer in sehr seltenen Fällen schreibt man nicht (quote T), (quote F) oder (quote
+ NIL), sondern T, F und NIL.
+
+5. Es besteht die Möglichkeit, mit Ganzzahlen zu rechen, die als weiterer Typ von
+ Atomen gelten. Außerdem können TEXTe und Einzelzeichen (CHARACTERs)
+ gespeichert werden.
+
+6. Es besteht die Möglichkeit der Ein- und Ausgabe von LISP-Ausdrücken, Ganz­
+ zahlen, TEXTen und CHARACTERs.
+
+WARNUNG: Die oben angegebenen Definitionen von "eval" und "apply" dienen nur
+ pädagogischen Zwecken und sind nicht das, was wirklich im Interpreter
+ abläuft.
+ Um zu entscheiden, was wirklich vor sich geht, wenn der Interpreter
+ aufgerufen wird, sollte man sich an die ELAN-Quellprogramme halten.
+#page#
+
+2.2 Anwendungsregeln und Beispiele #goalpage("p2.2")#
+
+
+
+Die Funktionsweise des LISP-Interpreteres kann bequem unter Verwendung der
+Funktion "trace" verfolgt werden. Der Aufruf:
+
+
+ (trace)
+
+
+schaltet den Trace-Protokollmodus des Interpreters ein bzw. aus.
+
+Das folgende Beispiel ist ein LISP-Programm, das die drei Funktionen "union",
+"intersection" und "member" als Standardfunktionen einführt Die Funktionen lauten
+folgendermaßen:
+
+
+ (member pattern list) = (cond ((null list) F)
+ ((eq (head list) pattern) T)
+ (T (member pattern (tail list)))
+ )
+
+ (union x y) = (cond ((null x) y)
+ ((member (head x) y) (union (tail x) y))
+ (T (cons (head x) (union (tail x) y)))
+ )
+
+ (intersection x y) = (cond ((null x) NIL)
+ ((member (head x) y)
+ (cons (head x) (intersection
+ (tail x) y))
+ )
+ (T (intersection (tail x) y))
+ )
+
+
+Um die Funktionen als neue Standardfunktionen einzuführen, benutzen wir die Pseu­
+dofunktion "define":
+
+
+ (DEFINE
+ (MEMBER . (LAMBDA (PATTERN LIST)
+ (COND ((NULL LIST) F)
+ ((EQ (HEAD LIST) PATTERN) T)
+ (T (MEMBER PATTERN (TAIL LIST)))
+ ) ) )
+ (UNION . (LAMBDA (X Y)
+ (COND ((NULL X) Y)
+ ((MEMBER (HEAD X) Y) (UNION (TAIL X) Y))
+ (T (CONS (HEAD X) (UNION (TAIL X) Y)))
+ ) ) )
+ (INTERSECTION . (LAMBDA (X Y)
+ (COND ((NULL X) NIL)
+ ((MEMBER (HEAD X) Y)
+ (CONS (HEAD X) (INTERSECTION (TAIL
+ X) Y))
+ )
+ (T (INTERSECTION (TAIL X) Y))
+ ) ) )
+ )
+
+
+Die Funktion DEFINE, liefert als Pseudofunktion nicht nur einen LISP-Ausdruck als
+Ergebnis, sondern hat auch einen bleibenden Effekt, nämlich eine Veränderung im
+LISP-Heap.
+
+DEFINE hat beliebig viele Parameter der Form (Name . Funktion) und bewirkt, daß die
+Funktionen unter dem jeweiligen Namen im System verfügbar werden, also für die
+weitere Programmausführung definiert werden. Das Ergebnis von DEFINE ist eine
+Liste der neuen Funktionsnamen, also hier
+
+
+ (MEMBER UNION INTERSECTION)
+
+
+Der Wert den der LISP-Interpreter bei Eingabe von
+
+
+ (intersection (a1 a2 a3) (a1 a3 a5))
+
+
+liefert ist (A1 A3) ,
+
+
+Die Funktion
+
+
+ (union (x y z) (u v w x))
+
+
+liefert (Y Z U V W X) .
+
+
+
+Es folgen einige elementare Regeln für LISP-Programme:
+
+1. Ein LISP-Programm besteht aus einem Funktionsaufruf. Im Beispiel ist das die
+ Funktion DEFINE, die ihre Parameter (beliebig viele) berechnet und ausgibt. Die
+ Berechnung der Parameter erfolgt dabei in der Reihenfolge der Parameter (norma­
+ le LISP-Funktionen mit mehreren Parametern berechnen standardmäßig alle
+ Parameter, allerdings in irgendeiner Reihenfolge).
+
+2. LISP ist formatfrei, d.h. jedes Symbol kann in jeder Spalte stehen. Für die Bedeu­
+ tung des Programms ist nur die Reihenfolge der Symbole maßgeblich. Zeilen­
+ wechsel wird als Leerzeichen aufgefaßt.
+
+3. Atome müssen mit einem Buchstaben anfangen, damit sie nicht mit Zahlen ver­
+ wechselt werden.
+
+4. Ein LISP-Ausdruck der Form (A B C . D) ist eine Abkürzung für (A.(B.(C.D))).
+ Jede andere Plazierung des Punkts ist ein Fehler (falsch wäre z.B. (A . B C) ).
+
+5. Eine Anzahl von Basisfuntionen existiert von Anfang an, ohne daß sie durch
+ DEFINE eingeführt wurden. Der Programmierer kann weitere Funktionen bleibend
+ oder für die Dauer eines Programmlaufs einführen; dabei ist die Reihenfolge der
+ neuen Funktionen gleichgültig.
+#page#
+
+2.3 Variablen#goalpage("p2.3")#
+
+
+
+Eine Variable ist ein Symbol, das ein Argument einer Funktion repräsentiert. Man
+kann also schreiben: "a + b, wobei a = 3 und b = 4". In dieser Situation ist keine
+Verwechslung möglich, so daß klar ist, daß das Ergebnis 7 ist. Um zu diesem Ergeb­
+nis zu kommen, muß man die Zahlen anstelle der Variablen einsetzen und die Opera­
+tion ausführen, d.h. die Zahlen addieren.
+
+Ein Grund, weshalb das eindeutig ist, liegt darin, daß "a" und "b" nicht "direkt"
+addiert werden können, so daß etwa "ab" entsteht. In LISP kann die Situation viel
+komplizierter sein. Ein Atom kann eine Variable oder ein Atom sein.
+
+Sollte der zukünftige LISP-Benutzer an dieser Stelle entmutigt sein, sei ihm gesagt,
+daß hier nichts Neues eingeführt wird. Dieser Abschnitt ist nur eine Wiederholung der
+Überlegungen aus Abschnitt 1.4. Alles, was wir in diesem Abschnitt sagen, kann man
+aus den Regeln für LISP-Ausdrücke oder aus der allgemeinen Funktion "evalquote"
+ableiten.
+
+Der Formalismus, der in LISP die Variablen kennzeichnet, ist die Lambdanotation von
+Church. Der Teil des Interpreters, der die Variablen an Werte bindet, heißt "apply".
+Wenn "apply" auf eine Funktion stößt, die mit LAMBDA anfängt, wird die Variablenli­
+ste (Argumentliste) mit der Parameterliste gepaart und am Anfang der Bindeliste
+eingefügt.
+
+Während der Berechnung des Funktionsrumpfs müssen manchmal Variablen durch
+ihre Werte ersetzt werden. Das geschieht dadurch, daß ihr Wert in der Bindeliste
+nachgesehen wird. Wenn eine Variable mehrmals gebunden wurde, wird die zuletzt
+etablierte Bindung verwendet. Der Teil des Interpreters, der diese "Berechnungen"
+und die Berechnung von Funktionsaufrufen durchführt, heißt "eval".
+
+
+
+#page#
+
+2.4 Konstanten#goalpage("p2.4")#
+
+
+
+Manchmal heißt es, eine Konstante stehe für sich selbst, im Gegensatz zu einer
+Variablen, die für etwas anderes, nämlich ihren Wert, steht.
+Dies Konzept funktioniert in LISP nicht so ohne weiteres; es ist hier sinnvoller, zu
+sagen, eine Variable ist konstanter als die andere, wenn sie in einer höheren Ebene
+gebunden ist und ihren Wert seltener ändert.
+In LISP bleibt eine Variable im Bereich des LAMBDA konstant, von dem sie gebunden
+ist. Wenn eine Variable einen festen Wert hat, unabhängig davon, was in der Bindeli­
+ste steht, wird sie (echte) Konstante genannt. Dies wird mit Hilfe der Eigenschaftsliste
+(E-Liste) des Atoms erreicht.
+Jedes Atom hat eine E-Liste, in der Paare von Atomen und beliebigen Strukturen
+gespeichert sind. Ein Atom hat die Eigenschaft A, wenn in seiner E-Liste ein Paar
+mit dem Atom A enthält; die dazugehörige "beliebige Struktur" heißt Wert dieser
+Eigenschaft.
+Wenn ein Atom die Eigenschaft APVAL besitzt, ist es eine Konstante, deren Wert der
+Wert der Eigenschaft ist.
+Konstanten können durch die Pseudofunktion
+
+
+ (set atom wert)
+
+
+gesetzt werden; nach der Auswertung eines solchen Aufrufs hat das Atom "atom"
+immer den Wert "wert" - bis zum nächsten "set". Eine interessante Klasse von
+Konstanten sind solche Konstanten, die sich selbst als Wert haben. Ein Beispiel dafür
+ist NIL. Der Wert dieser Konstanten ist wieder NIL. Daher kann NIL nicht als Variable
+benutzt werden, da es ja eine Konstante ist. (T und F gehören ebenfalls zu dieser
+Klasse).
+
+#page#
+
+2.5 Funktionen#goalpage("p2.5")#
+
+
+
+Wenn ein LISP-Ausdruck für eine Funktion steht, ist die Situation ähnlich der, in der
+ein Atom für einen Wert steht. Wenn die Funktion rekursiv ist, muß sie einen Namen
+bekommen. Das geht mit einem LABEL-Ausdruck, der den Namen mit der Funk­
+tionsdefinition in der Bindeliste paart. Dadurch wird der Name an die Funktionsdefini­
+tion gebunden, so wie eine Variable an ihren Wert gebunden wird. In der Praxis setzt
+man LABEL selten ein. Normalerweise ist es einfacher, Name und Definition wie bei
+den Konstanten zu verknüpfen. Dies geschieht mit der Pseudofunktion DEFINE, die
+wir am Anfang des Kapitels benutzt haben.
+Diese Funktion kann beliebig viele Parameter der Form
+
+
+ (atom . funktion)
+
+
+haben, wobei "atom" der Name der zu definierenden Funktion "funktion" werden soll.
+Sie bewirkt, daß die Definition unter der Eigenschaft FUNCTION in der E-Liste des
+Atoms abgelegt wird.
+#page#
+
+3. Erweitertes LISP#goalpage("p3")#
+
+
+In diesem Kapitel werden wir einige Erweiterungen zum reinen LISP einführen. Zu
+diesen Erweiterungen gehören Möglichkeiten für Arithmetik, Zeichenkettenverarbei­
+tung, Funktionen, die spezielle Argumente erwarten, und Ein- und Ausgabe.
+
+In allen Fällen handelt es sich bei den Erweiterungen um zusätzliche Funktionen. So
+heißt das Kommando für die Ausgabe eines LISP-Ausdrucks PUT. Syntaktisch ist
+PUT nichts anderes als eine Funktion mit einem Argument. Sie kann mit anderen
+Funktionen verkettet werden, und diese Verkettung wird ganz auf die übliche Art
+behandelt, zuerst Berechnung der innern, dann der äußeren Funktionsaufrufe. Ein
+Ergebnis ist nur in dem trivialen Sinn vorhanden, daß PUT sein Argument wieder
+liefert, also die Identität ist.
+
+Funktionen, die eine Aktion wie Ein- oder Ausgabe bewirken, oder die Langzeitwir­
+kung (gesehen auf die Ausführungsdauer des Programms) haben, wie DEFINE und
+SET, heißen Pseudofunktionen. Es ist eine Besonderheit von LISP, daß alle Funktio­
+nen einschließlich den Pseudofunktionen ein Ergebnis haben müssen. In einigen
+Fällen ist das Ergebnis trivial und kann ignoriert werden.
+
+In diesem Kapitel beschreiben wir verschiedene Erweiterungen der Sprache LISP, die
+im System fest enthalten sind.
+
+
+#page#
+
+3.1 Gequotete Parameter #goalpage("p3.1")#
+
+
+
+Bevor ein Argument an eine Funktion übergeben wird, wird erst sein Wert in der
+Bindeliste nachgesehen, d.h. es wird nicht der Name der Variablen übergeben, son­
+dern ihr Wert. Wenn das Argument als Konstante behandelt werden soll, muß es
+ge"quotet" werden, d.h. statt "argument" steht (quote argument). Wenn ein Argument
+einer Funktion immer als Konstante behandelt werden soll, ist es bequemer, das
+Argument nicht jedesmal zu quoten. Das EUMEL-LISP-System erlaubt, in diesem
+Fall den formalen Parameter in der Funktionsdefinition bereits zu quoten.
+
+Dieser Mechanismus wurde auch benutzt, um QUOTE zu implementieren; die Funk­
+tion lautet
+
+
+ quote = (lambda ((QUOTE x)) x)
+
+
+
+
+#page#
+
+3.2 Funktionen mit beliebig vielen
+ Argumenten #goalpage("p3.2")#
+
+
+
+Ein Beispiel ist "list", das beliebig viele Argumente haben kann, die zu einer Liste
+zusammengefaßt werden. Da eine Funktion nur eine feste Anzahl von Parametern
+haben kann, eine Funktion mit beliebig vielen Argumenten aber gewiß keine feste
+Anzahl von Argumenten hat, werden die beliebig vielen Argumente zu einer Liste
+zusammengefaßt und ein einziger Parameter wird an diese Liste gebunden. Da "list"
+genau diese Liste liefern soll, wird diese Funktion ebenfalls zu einer "Identität":
+
+
+ list = (lambda ((INDEFINITE x)) x)
+
+
+Solche Parameter werden durch INDEFINITE gekennzeichnet. Sie können auch ge­
+quotet werden, indem man (INDEFINITE QUOTE parameter) schreibt; das wirkt so, als
+wären alle Argumente, die diesem Parameter zugeordnet werden, einzeln gequotet
+worden.
+
+
+ evalquote = (lambda (fkt (INDEFINITE QUOTE expr))
+ (apply fkt expr NIL) )
+
+
+
+#page#
+
+3.3 Funktionale Parameter #goalpage("p3.3")#
+
+
+
+In der Mathematik gibt es Funktionen, die andere Funktionen als Argument haben. In
+der Algebra könnte man die Funktion "(operation operator a b)" definieren, wobei
+"operator" ein funktionales Argument ist, das die Operation festlegt, die auf "a" und
+"b" ausgeführt werden soll. Beispielsweise gilt
+
+
+ operation (+ 3 4) = 7
+ operation (* 3 4) = 12
+
+
+In LISP sind funktionale Argumente sehr nützlich. Eine wichtige Funktion mit einem
+Argument ist MAPLIST. Ihre Definition ist
+
+
+ (LAMBDA (LIST (FUNCTION FN))
+ (COND ((NULL LIST) NIL)
+ (T (CONS (FN (HEAD LIST)) (MAPLIST (TAIL LIST) FN)))
+ ) )
+
+
+Diese Funktion nimmt eine Liste und eine Funktion als Argument und wendet die
+Funktion auf die Listenelemente an.
+
+
+#page#
+
+3.4 Prädikate und boolesche Konstanten #goalpage("p3.4")#
+
+
+
+Die booleschen Werte sind, wie in Kapitel 1 gesagt, T und F. Bei LISP-Ausdrücken
+müßte daraus (quote T) und (quote F) werden, aber da die APVALs dieser Atome
+wieder den Wert T und F haben, ist das quoten nicht nötig.
+
+Prädikate sind Funktionen, die T oder F als Ergebnis haben; es gibt also keine forma­
+len Unterschiede zwischen anderen Funktionen und Prädikaten.
+
+Daher ist es durchaus möglich, daß eine Funktion einen Wert liefert, der weder T
+noch F ist, daß aber durch einen bedingten Ausdruck an dieser Stelle ein boolescher
+Ausdruck verlangt wird. In diesem Fall ist die Wirkung des Ausdrucks nicht definiert.
+
+Das Prädikat EQ hat folgendes Verhalten:
+1. Wenn seine Argumente verschieden sind, ist das Ergebnis F.
+2. Wenn die Argumente dasselbe Atom sind, ist das Ergebnis T.
+3. Wenn die Argumente gleich, aber nicht atomar sind, ist das Ergebnis T oder F, je
+ nachdem, ob sie ein und dasselbe Objekt im Heap sind oder nicht.
+
+#page#
+
+3.5 Unbenannte Atome #goalpage("p3.5")#
+
+
+
+Die meisten Atome im EUMEL-LISP haben einen Namen, der sie bei Ein- und
+Ausgabeoperationen identifiziert.
+Es gibt aber auch Atome, die keinen Namen haben und stattdessen durch ihre Werte
+repräsentiert werden. Momentan sind das Ganzzahlen und Zeichenketten (TEXTe);
+auch die booleschen Werte kann man in einem weiteren Sinn dazurechnen.
+
+
+
+
+3.5.1 Ganzzahlen
+
+
+
+Im EUMEL-LISP gibt es Funktionen, die Basisoperationen und Tests durchführen.
+
+Ganzzahlen haben folgende Eigenschaften:
+
+1. Eine Ganzzahl besteht aus einem optionalen Vorzeichen und einer Folge von
+ Ziffern; zwischen Vorzeichen und Ziffern können Leerzeichen stehen.
+2. Der Wert einer Ganzzahl liegt zwischen -32768 und 32767 (minint und maxint).
+3. Eine Ganzzahl kann überall dort stehen, wo ein Atom stehen kann, außer als
+ Parameter.
+4. Ganzzahlen sind Konstanten; sie brauchen also nicht gequotet werden.
+#page#
+
+3.5.2 Arithmetische Funktionen und Prädikate
+
+
+
+Es folgt eine Liste aller arithmetischen Funktionen.
+Wenn ein Argument einer dieser Zahlen keine Ganzzahl ist, erfolgt eine Fehlermel­
+dung.
+
+ (sum x1 ... xn) liefert die Summe der xi; wenn keine Argumente gege­
+ ben werden, wird 0 geliefert.
+ (difference x y) liefert die Differenz von x und y.
+ (product x1 ... xn) liefert das Produkt seiner Argumente; wenn
+ keine Argumente gegeben werden, wird 1
+ geliefert.
+ (quotient x y) liefert den Quotienten von x und y, ohne den
+ Rest zu berücksichtigen.
+ (remainder x y) liefert den Rest der Division von x und y.
+ (getint) liest eine Zahl vom Bildschirm ein und
+ liefert sie.
+ (putint x) gibt x auf den Bildschirm aus. Identitäts funktion.
+
+
+
+
+
+3.5.3 Zeichenkettenverarbeitung
+
+
+
+Im Moment ist nur Zeichenketten-Ein- und Ausgabe implementiert.
+Die Ausgabe löst bei Argumenten, die keine Zeichenketten sind, eine Fehlermeldung
+aus.
+
+ (gettext) liest eine Zeichenkette ein und liefert sie.
+ (puttext x) gibt eine Zeichenkette aus.
+
+
+
+
+3.5.4 Test auf Gleichheit
+
+
+
+ (equal x y) testet, ob x und y vom gleichen Typ sind, und wenn ja, ob sie gleich
+ sind.
+#page#
+
+3.6 Aufruf von EUMEL aus #goalpage("p3.6")#
+
+
+Bevor man den LISP-Interpreter benutzen kann, muß er folgendermaßen implemen­
+tiert werden:
+
+archive ("lisp")
+fetch all (archive)
+release (archive)
+check off
+insert ("lisp.1")
+insert ("lisp.2")
+insert ("lisp.3")
+insert ("lisp.4")
+check on
+
+
+Das LISP-System verfügt über einen Heap, in dem alle LISP-Ausdrücke gespei­
+chert sind. Standardmäßig enthält der Heap eine Reihe von Funktionen, die nicht in
+den LISP-Programmen definiert werden müssen (Übersichten über die Standardfunk­
+tionen siehe Kapitel 3.5).
+
+Mit
+ lisp
+
+wird das LISP-System im EUMEL-Dialog gestartet. In einem Eingabefenster wird
+mit Hilfe des Paralleleditors eine LISP-EINGABE-Möglichkeit angeboten. Die Aus­
+gabe erfolgt in dem LISP-AUSGABE-Fenster.
+Das LISP-System kann folgendermaßen verlassen werden:
+<ESC> <ESC> break lisp <RETURN>.
+
+Statt dieser direkten Art der Benutzung der LISP-Maschine ist auch eine an ELAN
+angelehnte Art mit den Prozeduren "run lisp", insert lisp" usw. vorgesehen:
+
+Mit
+
+ run lisp (TEXT CONST dateiname)
+
+wird eine Kopie des Heaps angelegt, das Programm aus der Datei "dateiname" in die
+Kopie eingelesen und gestartet. Durch diesen Kopiermechanismus wird der Original­
+heap vor Zusammenbrüchen des LISP-Systems geschützt.
+
+ insert lisp (TEXT CONST dateiname)
+
+bewirkt dasselbe wie "run lisp"; allerdings wird jetzt direkt auf dem Originalheap
+gearbeitet. Dadurch sind alle Änderungen im Heap, die das Programm verursacht
+(meist Definition von Funktionen durch DEFINE) bleibend, aber auch ein Zusammen­
+bruch ist insoweit endgültig, als das LISP-System jetzt neu gestartet werden muß.
+Das geschieht mit
+
+ start lisp system (DATASPACE CONST dsname)
+
+"dsname" gibt dabei den Datenraum an, der die zum Hochfahren notwendigen Daten
+enthält. Solche Daten im richtigen Format enthält der Datenraum "lisp.bootstrap".
+Wenn der zuletzt benutzte Heap mit nicht mehr durch LISP-Programme erreich­
+bare Strukturen vollgestopft ist, schafft die Prozedur
+
+ collect lisp heap garbage
+
+Abhilfe; mit
+
+ lisp storage info
+
+kann man den Erfolg kontrollieren.
+#page#
+
+4. Detailbeschreibungen#goalpage("p4")#
+
+
+
+
+
+4.1 Grundfunktionen #goalpage("p4.1")#
+
+
+
+Die Datei "lisp.1" enthält ein Paket, das die Grundlage des LISP-Systems bildet. Es
+implementiert
+
+ - die primitiven LISP-Funktionen wie "cons", "null", etc.,
+ - die Verwaltung des Heaps, in dem die LISP-Strukturen und die Objektliste
+ (Oblist) gespeichert sind,
+ - einen Datentyp SYM, dessen Wertevorrat aus Zeigern auf die im Heap gespei­
+ cherten Strukturen besteht,
+ - Funktionen zur Konversion allgemeiner Daten in LISP-Strukturen (bisher reali­
+ siert: TEXT <--> SYM und INT <--> SYM).
+
+Durch die Implementation der Basisoperationen als exportierte und damit allgemein
+verfügbare ELAN-Prozeduren ist es möglich, LISP-Strukturen durch ELAN-Prog­
+ramme zu manipulieren; insbesonders können ELAN- und LISP-Programme über
+diese Strukturen miteinander kommunizieren.
+
+Anmerkung:
+Wenn Eigenschaften von "SYM"-Objekten beschrieben werden, sind immer die
+Eigenschaften der Strukturen gemeint, auf die die Objekte zeigen, wenn nichts ande­
+res angegeben wird.
+
+
+Es werden folgende Prozeduren exportiert:
+
+ PROC initialize lisp system (DATASPACE CONST new heap):
+ "new heap" ist der neue Datenraum, in dem der LISP-Heap ab sofort geführt
+ wird.
+ Vorsicht: Beim Wechsel zu einem neuen Datenraum sind die Werte der
+ SYM-Variablen, die auf Strukturen im alten Heap zeigen, natürlich wertlos!
+
+ PROC dump lisp heap (FILE VAR f):
+ In "f" wird ein Dump des Heaps erstellt. Dieser Dump ist nur mit Kenntnis des
+ Programmtextes aus "lisp 1" verständlich; er wird hier nicht beschrieben.
+
+ PROC lisp storage (INT VAR size, used):
+ Nach dem Aufruf gibt "size" die maximal verfügbare Anzahl von Knoten an,
+ während "used" die Anzahl der tatsächlich von LISP-Strukturen belegten
+ Knoten enthält. Zu diesen Strukturen können auch solche zählen, die nicht mehr
+ durch "head" oder "tail" etc. erreichbar sind.
+
+ PROC collect lisp heap garbage:
+ Löscht die im LISP-Heap nicht mehr durch "atom (TEXT CONST)", "proper­
+ ty", "head" und "tail" erreichbaren Strukturen. Es werden auch alle nur von
+ ELAN-Programmen aus über SYM-Variable erreichbare Strukturen gelöscht, so
+ daß die Werte dieser Variablen undefiniert werden.
+ Die Müllabfuhr wird von keiner Prozedur dieses Pakets aufgerufen, d.h. der
+ Benutzer, der ELAN-Programme einsetzt, braucht nicht alle Strukturen in den
+ Eigenschaftslisten von Atomen aufzubauen, um sie vor einer versehentlichen
+ Löschung durch die Müllabfuhr zu schützen, vorausgesetzt, er ruft sie nicht
+ selbst auf. Er muß allerdings darauf achten, daß im Heap noch genug Platz
+ bleibt.
+
+ OP := (SYM VAR left, SYM CONST right):
+ Nach der Zuweisung zeigt "left" auf die gleiche Struktur wie vorher "right".
+
+ SYM CONST nil, pname;
+ Zwei Konstanten, die dem LISP-System ständig zur Verfügung stehen müs­
+ sen. Ihre Drucknamen sind "NIL" bzw. "PNAME" (vgl. Schlußbemerkungen)
+
+ SYM PROC head (SYM CONST sym):
+ Entspricht der im Handbuch beschriebenen Funktion "head".
+
+ SYM PROC tail (SYM CONST sym):
+ Entspricht der im Handbuch beschriebenen Funktion "tail".
+
+ SYM PROC cons (SYM CONST head, tail):
+ Liefert einen SYM-Wert "zeiger" auf eine neue Struktur. Es gilt:
+ head ("zeiger") = "head" und tail ("zeiger") = "tail".
+
+ BOOL PROC eq (SYM CONST sym 1, sym 2):
+ Prüft, ob "sym 1" und "sym 2" auf dieselbe Struktur zeigen. Das ist genau dann
+ der Fall, wenn sie durch Zuweisung auseinander hervorgegangen sind oder wenn
+ sie auf das gleiche benannte Atom zeigen.
+
+ BOOL PROC equal (SYM CONST sym 1, sym 2):
+ Prüft, ob "sym 1" und "sym 2" dieselbe Struktur haben; "dieselbe Struktur"
+ braucht aber nicht "Identität" zu bedeuten, wie "eq" das verlangt.
+ Umgewandelte TEXTe und INTs werden richtig verglichen (siehe "sym (INT
+ CONST)" und "sym (TEXT CONST)").
+
+ BOOL PROC null (SYM CONST sym):
+ Prüft, ob "sym" gleich der Konstanten "NIL" ist (entspricht
+ eq ("sym", "NIL"), ist aber schneller).
+
+ BOOL PROC atom (SYM CONST sym):
+ Prüft, ob "sym" ein ( benanntes oder unbenanntes) Atom ist.
+
+ BOOL PROC is named atom (SYM CONST sym):
+ Prüft, ob "sym" ein benanntes Atom ist.
+
+ PROC begin oblist dump:
+ Vorbereitung für "next atom".
+
+ SYM PROC next atom:
+ Liefert das nächste Atom aus der Objektliste. In der Objektliste sind alle benann­
+ ten Atome, die der Heap enthält, aufgeführt (bis auf Ausnahmen; s."delete
+ atom"). "NIL" wird immer als letzte Atom geliefert.
+
+ SYM PROC atom (TEXT CONST name):
+ Liefert einen Zeiger auf das Atom mit dem Namen "name". Wenn kein solches
+ Atom in der Objektliste vorhanden ist, wird "NIL" geliefert.
+
+ SYM PROC new atom (TEXT CONST name):
+ Liefert einen Zeiger auf das Atom mit dem Namen "name". Wenn kein solches
+ Atom in der Objektliste vorhanden ist, wird ein neues mit diesem Namen in sie
+ eingefügt.
+
+ PROC create atom (TEXT CONST name):
+ Fügt ein Atom mit dem Namen "name" in die Objektliste ein. Wenn ein solches
+ Atom bereits existiert, wird stattdessen eine Fehlermeldung ausgegeben.
+
+ PROC delete atom (SYM CONST atom):
+ Streicht das Atom "atom" aus der Objektliste.
+
+ PROC begin property list dump (SYM CONST atom):
+ Vorbereitung für "next property".
+
+ PROC next property (SYM VAR property id, property):
+ Liefert die nächste Eigenschaft aus der Eigenschaftsliste des zuletzt durch
+ "begin property list dump" vorbereiteten Atoms. Wenn es sich bei der Eigen­
+ schaft um eine Flagge handelt, wird "property" auf "NIL" gesetzt; wenn es keine
+ nächste Eigenschaft mehr gibt, werden "property" und "property id" auf "NIL"
+ gesetzt.
+ Der Dump der Eigenschaftsliste beeinträchtigt die "Verwendbarkeit" des Atoms in
+ keiner Weise; es ist während des Dumps sogar möglich, Eigenschaften und
+ Flaggen zu lesen. Wenn während des Dumps Eigenschaften oder Flaggen geän­
+ dert oder geschrieben werden, ist mit fehlerhaften Dumpergebnissen zu rechnen.
+
+ PROC add property (SYM CONST atom, property id, property):
+ "property id" muß ein benanntes Atom sein. Führt eine neue Eigenschaft mit der
+ Bezeichnung "property id" und dem Wert "property" ein. Wenn bereits eine
+ Eigenschaft mit der gleichen Bezeichnung existiert, wird die alte Version über­
+ deckt, ist aber weiter vorhanden.
+
+ PROC alter property (SYM CONST atom, property id, property):
+ Bringt die Eigenschaft mit der Bezeichnung "property id" auf den neuen Wert
+ "property". Wenn eine Eigenschaft mit dieser Bezeichnung noch nicht existiert,
+ wird eine Fehlermeldung ausgegeben.
+
+ BOOL PROC property exists (SYM CONST atom, property id):
+ Prüft, ob das Atom eine Eigenschaft mit der Bezeichnung "property id" besitzt.
+
+ SYM PROC property (SYM CONST atom, property id):
+ Liefert den Wert der gerade sichtbaren Eigenschaft des Atoms, die die Bezeich­
+ nung "property id" hat. Falls die Eigenschaft nicht existiert, wird "NIL" geliefert.
+
+ PROC delete property (SYM CONST atom, property id):
+ Löscht den gerade sichtbaren Wert der Eigenschaft des Atoms, die die Bezeich­
+ nung "property id" hat. Wenn eine ältere Version dieser Eigenschaft durch "add
+ property" überdeckt wurde, wird diese jetzt wieder sichtbar. Jede Eigenschaft
+ bildet also für jedes Atom einen Stapel (Stack).
+
+ PROC add flag (SYM CONST atom, flag id):
+ Das Atom "atom" erhält die Flagge "flag id". Ein Atom kann dieselbe Flagge
+ durchaus mehrmals haben.
+
+ BOOL PROC flag (SYM CONST atom, flag id):
+ Prüft, ob "atom" mindestens eine Flagge "flag id" hat.
+
+ PROC delete flag (SYM CONST atom, flag id):
+ Löscht eine Flagge "flag id" von "atom". Wenn keine Flagge existiert, wird
+ nichts getan.
+
+ SYM PROC sym (TEXT CONST text):
+ Konvertiert "text" in ein unbenanntes Atom und liefert einen Zeiger auf dies
+ Atom.
+
+ TEXT PROC text (SYM CONST sym):
+ Konvertiert "sym" in einen TEXT zurück, wenn es sich um einen konvertierten
+ TEXT handelt; wenn nicht, wird eine Fehlermeldung ausgegeben.
+
+ BOOL PROC is text (SYM CONST sym):
+ Prüft, ob "sym" ein konvertierter TEXT ist.
+
+ SYM PROC sym character (TEXT CONST text):
+ "text" muß genau ein Zeichen enthalten. Das Zeichen wird in ein
+ CHARACTER-Objekt im Heap konvertiert und ein Zeiger auf dies Objekt gelie­
+ fert.
+
+ INT PROC character (SYM CONST sym):
+ "sym" muß auf ein CHARACTER-Objekt zeigen. Geliefert wird der Code des
+ dort gespeicherten Zeichens.
+
+ SYM PROC sym (INT CONST i 1, i 2):
+ Konvertiert "i 1" und "i 2" in ein unbenanntes Atom und liefert einen Zeiger
+ darauf.
+
+ INT PROC int 1 (SYM CONST sym):
+ INT PROC int 2 (SYM CONST sym):
+ Holt die Werte der ersten bzw. zweiten Ganzzahl aus "sym", wenn es sich um
+ ein konvertiertes INT-Paar handelt; wenn nicht, wird eine Fehlermeldung ausge­
+ geben.
+
+ BOOL PROC is int pair (SYM CONST sym):
+ Prüft, ob "sym" ein konvertiertes INT-Paar ist.
+
+
+Prozedurübergreifende Aussagen über das Paket "lisp.1":
+
+ - Es gibt benannte und unbenannte Atome.
+
+ - Die unbenannten Atome sind Konversionsprodukte.
+
+ - Vor dem ersten Aufruf von "delete atom" sind alle benannten Atome in der Ob­
+ jektliste enthalten; d.h. sie können alle durch "begin oblist dump" und wiederhol­
+ ten Aufruf von "next atom" erreicht werden.
+
+ - Jedes benannte Atom hat genau einen Namen, der immer gleich bleibt. Der
+ Name ist als Eigenschaft mit der Bezeichnung "pname" in der Eigenschaftsliste
+ gespeichert. "add property", "alter property" und "delete property" geben des­
+ halb eine Fehlermeldung aus, statt ihre normalen Aktionen durchzuführen, wenn
+ ihnen als Eigenschaftsbezeichnung "pname" übergeben wird.
+
+ - Es gibt keine zwei Atome, die denselben Namen haben; dadurch reduziert sich
+ die bei "eq" angegebene Fallunterscheidung auf einen Fall.
+
+ - Es kann durchaus zwei unbenannte Atome mit gleichen Werten geben, die von
+ "eq" nicht als gleich anerkannt werden, weil sie in verschiedenen Strukturen
+ gespeichert sind. "equal" achtet nicht auf die Position, sondern auf die Werte
+ der zu vergleichenden Strukturen.
+
+ - Mehrfache Zugriffe auf die gleiche Eigenschaft desselben Atoms werden so opti­
+ miert, daß die Eigenschaftsliste nur beim ersten Zugriff (meist durch "property
+ exists") durchsucht werden muß.
+
+
+
+#page#
+
+4.2 Weitere Funktionen sowie Eingabe und
+ Ausgabe #goalpage("p4.2")#
+
+
+
+Die Datei "lisp.2" enthält diverse Pakete, die die Verbindung vom LISP-System zur
+normalen EUMEL-Umgebung bilden. Momentan sind das Ein- und Ausgabe und
+(exemplarisch) die fünf Grundrechenarten für Ganzzahlen.
+
+Die Ein- und Ausgabe von LISP-Strukturen wird durch das Paket namens "lisp io"
+mit den folgenden Prozeduren ermöglicht:
+
+ PROC get (FILE VAR f, SYM VAR sym):
+ Nach dem Aufruf zeigt "sym" auf eine neue aus "f" eingelesene Struktur.
+ In der ersten und hinter der letzten Zeile des S-Ausdrucks dürfen keine weiteren
+ Daten stehen.
+
+ PROC get all (FILE VAR f, SYM VAR sym):
+ Wie "get (FILE V, SYM V)", nur daß die Datei nichts als den S-Ausdruck ent­
+ halten darf.
+
+ PROC get (SYM VAR sym):
+ Es wird mit "get all" ein S-Audruck von einer Scratch-Datei eingelesen, die
+ dem Benutzer vorher zum Editieren angeboten wird. Bei Einlesefehlern wird die
+ Datei zu Korrigieren angeboten, bis keine Fehler mehr auftreten.
+
+ PROC put (FILE VAR f, SYM CONST sym):
+ Wenn "sym" ein Ganzzahlpaar ist, wird die erste Zahl ausgegeben; wenn es ein
+ konvertierter TEXT ist, wird der ursprüngliche TEXT wieder ausgegeben; bei
+ einem benannten Atom oder einer allgemeinen LISP-Struktur wird ein S-Aus­
+ druck ausgegeben.
+
+ PROC put (SYM CONST sym):
+ Wie "put (FILE V, SYM CONST), außer daß die Augabe direkt auf den Bildschirm
+ erfolgt.
+
+
+Das Paket "lisp int" enthält die Prozeduren
+
+ SYM PROC sum (SYM CONST summandenliste);
+ Erwartet eine Liste von "int pair"-Summanden und liefert deren Summe.
+
+ SYM PROC difference (SYM CONST minuend, subtrahend):
+ Liefert die Differenz der Parameter.
+
+ SYM PROC product (SYM CONST faktorenliste):
+ Liefert das Produkt der Listenelemente.
+
+ SYM PROC quotient (SYM CONST dividend, divisor):
+ Liefert den Quotienten der Parameter.
+
+ SYM PROC remainder (SYM CONST dividend, divisor):
+ Liefert den Rest.
+
+#page#
+
+4.3 Interpreter #goalpage("p4.3")#
+
+
+Die Datei "lisp.3" enthält das Paket "lisp interpreter", das die Prozedur
+
+ SYM PROC evalquote (SYM CONST expression)
+
+exportiert. Es handelt sich dabei um den im EUMEL-LISP-Handbuch beschriebe­
+nen Interpreter.
+
+Wenn "expression" ein LISP-Ausdruck ist, liefert die Prozedur den Wert des Aus­
+drucks (vorausgesetzt, der LISP-Heap ist vorbereitet, siehe lisp.1).
+
+Wirkungsweise:
+"evalquote" ruft im Wesentlichen die Prozedur "eval" auf.
+"eval" erwartet als Argumente einen solchen LISP-Ausdruck wie "evalquote", benö­
+tigt aber zusätzlich eine sog. Bindeliste. In einer Bindeliste sind durch LAMBDA- und
+LABEL-Ausdrücke bereits gebundene Variable und ihre Werte gespeichert. Die
+Manipulation der Bindeliste ist durch eine Reihe von Refinements, die am Schluß des
+Pakets stehen, realisiert.
+
+Da bisher noch keine LAMBDA- oder LABEL-Ausdrücke verarbeitet wurden, über­
+gibt "evalquote" die leere Bindeliste.
+
+Wirkungsweise von
+
+ SYM PROC eval (SYM CONST expression, association list):
+
+"eval" kann als erstes Argument ein Atom oder eine zusammengesetzte Struktur
+erhalten.
+
+Atome werden als Variable aufgefaßt, deren Wert in der Bindeliste aufzusuchen ist.
+Vor der Konsultation der Bindeliste wird allerdings noch nach der Eigenschaft APVAL
+des Atoms gesehen; wenn sie vorhanden ist, handelt es sich um eine Konstante wie
+NIL, T oder F, die einen festen Wert hat, nämlich den Wert dieser Eigenschaft. Da
+diese Konstanten sich selbst als Wert haben, gilt "eval (NIL, Bindeliste) = NIL"
+(entsprechend für "T" und "F").
+
+Wenn das erste Arugment von "eval" zusammengesetzt ist, wird angenommen, daß
+es sich um einen Funktionsaufruf der Form
+
+
+ +-----+-----+
+ | o | o--+--> Argumentliste
+ +--+--+-----+
+ |
+ V
+ Funktion
+
+
+handelt. Die Bestandteile "Funktion" und "Argumentliste" werden mit der Bindeliste
+übergeben an:
+
+ SYM PROC apply (SYM CONST function, arguments, association list):
+
+"apply" hat die Aufgabe, die Argumente durch "eval" berechnen zu lassen (das
+unterbleibt allerdings unter bestimmten Umständen) und die Berechnungergebnisse an
+die Parameter der Funktion zu binden; zum Schluß muß der Wert des Funktions­
+rumpfs in Abhängigkeit von diesen neuen Bindungen als Ergebnis der gesamten
+Prozedur "apply" berechnet werden; diese Berechnung geschieht wieder durch
+"eval".
+
+Nur in einem LAMBDA-Ausdruck ist direkt bekannt, wo die Parameterliste steht.So­
+lange das nicht der Fall ist, muß entweder ein LABEL-Ausdruck oder ein Atom
+vorliegen.
+Ein LABEL-Ausdruck hat die Form
+
+
+ +-----+-----+ +-----+-----+ +-----+-----+
+ | o | o--+--->| o | o--+--->| o | NIL |
+ +--+--+-----+ +--+--+-----+ +--+--+-----+
+ | | |
+ V V V
+ LABEL Name Funktion
+
+
+Da der Name für die Dauer der Auswertung des Funktionsrumpfs an die Funktion
+gebunden sein muß, wird dis Paar als funktionaler Bindelisteneintrag gespeichert.
+Funktionale und nichtfunktionale Bindelisteneinträge sind eindeutig unterschieden.
+
+Nach dem Abspeichern wird wieder getestet, ob die Funktion diesmal ein
+LAMBDA-Ausdruck ist; wenn nicht, wird ein weiterer Schritt zum "Ablättern" von
+LABELs und Atomen versucht, usw.
+
+Wenn die Funktion ein Atom ist, werden analog zu den Vorgängen in "eval" erst die
+Eigenschaftsliste und dann die Bindeliste durchsucht.
+
+Ist die Eigenschaft FUNCTION in der Eigenschaftsliste vorhanden, ist der Wert der
+Eigenschaft die (evtl. weiter "abzublätternde") Funktion; ist die Eigenschaft nicht
+vorhanden, muß das Atom an eine Funktion gebunden sein, die dann aus der Binde­
+liste geholt werden kann.
+
+Da alle Funktionen (auch die Standardfunktionen) letztendlich als LAMBDA-Aus­
+drücke definiert sind, kommt "apply" auf diese Weise zuletzt zu einem LAMBDA-
+Ausdruck.
+
+Ein LAMBDA-Ausdruck hat die Form
+
+
+ +-----+-----+ +-----+-----+ +-----+-----+
+ | o | o--+--->| o | o--+--->| | |
+ +--+--+-----+ +--+--+-----+ +-----+-----+
+ | |
+ V V
+ LAMBDA Parameterliste
+
+
+Als nächster Schritt werden die Argumente für die zu berechnende Funktion an die
+Parameter der Parameterliste gebunden, d.h. es werden Parameter-Argument-Paare
+in die Bindeliste eingetragen.
+
+Die Methode des Eintrags ist je nach Art des Parameters unterschiedlich. Es gibt die
+folgenden Arten von Parametern:
+
+
+ 1. |
+ |
+ V
+ Name
+
+
+ "Name" ist hier - wie bei den restlichen Fällen - der Name des Parame­
+ ters. Diese Art von Parametern ist der Normalfall; die Argumente, die einem
+ solchen Parameter entsprechen, werden durch "eval" berechnet und zusammen
+ mit dem Parameter in einem Bindelisteneintrag gespeichert.
+
+
+ 2. |
+ |
+ V
+ +-----+-----+ +-----+-----+
+ | o | o--+--->| o | NIL +
+ +--+--+-----+ +--+--+-----+
+ | |
+ V V
+ QUOTE Name
+
+
+ In diesem Fall wird das Argument ohne weitere Verarbeitung in die Bindeliste
+ übernommen. Die Wirkung ist die gleiche, als wäre das Argument durch
+ "(QUOTE ... )" eingeschlossen.
+
+
+ 3. |
+ |
+ V
+ +-----+-----+ +-----+-----+
+ | o | o--+--->| o | NIL |
+ +--+--+-----+ +--+--+-----+
+ | |
+ V V
+ FUNCTION Name
+
+
+ Hier wird ein funktionaler Bindelisteneintrag erzeugt, so daß "Name" im Funk­
+ tionsrumpf als Name einer Funktion auftreten kann.
+
+
+ 4. |
+ |
+ V
+ +-----+-----+ +-----+-----+
+ | o | o--+--->| o | NIL |
+ +--+--+-----+ +--+--+-----+
+ | |
+ V V
+ INDEFINITE Name
+
+
+ Dies ist ein Parameter, der beliebig viele berechnete Argumente aufnehmen
+ kann. Der Einfachheit halber werden die Ergebnisse zu einer Liste zusammen­
+ gefaßt und mit "Name" in einen Bindelisteneintrag gesteckt.
+
+
+ 5. |
+ |
+ V
+ +-----+-----+ +-----+-----+ +-----+-----+
+ | o | o--+--->| o | o--+--->| o | NIL |
+ +--+--+-----+ +--+--+-----+ +--+--+-----+
+ | | |
+ V V V
+ INDEFINITE QUOTE Name
+
+
+ Dieser Parameter kann wie der in Fall 4. aufgeführte beliebig viele Argumente
+ aufnehmen, die zu einer Liste zusammengefaßt werden. Im Gegensatz zu 4.
+ wird aber wie bei 2. nichts durch "eval" berechnet, sondern die Argumente so
+ wie sie vorkommen übernommen.
+
+Auf einen Parameter der Form 4. oder 5. darf kein weiterer Parameter folgen, weil
+solch ein Parameter alle restlichen Argumente verbraucht. Solchen Parametern darf -
+als Ausnahme - auch kein Argument entsprechen; dann werden sie an die leere
+Liste (d.h. NIL) gebunden.
+
+Der letzte Kasten in der Beschreibung des LAMBDA-Ausdrucks ist mit Absicht leer
+geblieben; er kann eine der Formen
+
+
+ +-----+-----+ +----------+----------+
+ | o | NIL | oder | Ganzzahl | XXXXXXXX |
+ +--+--+-----+ +----------+----------+
+ |
+ V
+ Funktionsrumpf
+
+
+annehmen.
+
+Die erste Form heißt, daß die Funktion durch Berechnung des Funktionsrumpfs mittels
+"eval" berechnet werden soll; die zweite Form bewirkt den Aufruf einer der Standard­
+funktionen, je nachdem, welche Funktionsnummer bei "Ganzzahl" steht. In diesem
+zweiten Fall werden die Argumente aber nicht durch den Namen des Parameters
+identifiziert, sondern durch die Position des Eintrags in der Bindeliste. Dieser Pro­
+grammteil hängt also wesentlich von der Reihenfolge ab, in der die Bindelisteneinträ­
+ge, die bei der Parameter-Argument-Zuordnung entstehen, in die Bindeliste einge­
+fügt werden. Zur Zeit ist das die Umkehrung der Reihenfolge der Parameter.
+
+Die Namen der Refinements "arg 1", "arg 2", "arg 3" beziehen sich auch nicht auf
+die Position des Arguments in der Argumentsliste, sondern auf die Position des
+Eintrags in der Bindeliste.
+
+#page#
+
+4.4 Kommandoprozeduren #goalpage("p4.4")#
+
+
+
+Die Datei "lisp.4" enthält eine Reihe von Prozeduren, mit denen der LISP-Interpre­
+ter ähnlich wie der ELAN-Compiler aufgerufen werden kann.
+
+Die Prozedur
+
+ start lisp system
+
+ermöglicht das erneute Starten des LISP-Systems, oder wenn "übersetzte" Pro­
+gramme, die in einem Heap einer anderen Task liegen, in dieser Task verarbeitet
+werden sollen.
+
+Die Prozedur
+
+ lisp
+
+stellt die LISP-Maschine in einem Doppelfenster im Bildschirmdialog zur Verfügung.
+Bei der erstmaligen Benutzung muß die Datei "lisp.bootstrap" vorhanden sein.
+
+Die Prozedur
+
+ break lisp
+
+koppelt die LISP-Task vom Benutzer-Terminal ab und baut das Doppelfenster für
+den Bildschirmdialog neu auf.
+
+
+Die Prozedur
+
+ run lisp
+
+bewirkt, daß ein LISP-Programm eingelesen und ausgeführt wird; nach der Ausfüh­
+rung wird das Ergebnis der Berechnung ausgegeben. Diese Operationen werden auf
+einer Kopie des Heaps ausgeführt, so daß Änderungen keine Dauerwirkung haben.
+Mit
+
+ run lisp again
+
+wird das zuletzt eingelesene Programm noch einmal gestartet; da dafür die gleiche
+Kopie des Heaps wie bei "run" benutzt wird, kann das Ergebnis diesmal anders sein.
+
+ insert lisp
+
+wirkt wie "run lisp", außer daß diesmal alle Änderungen, die durch das Einlesen und
+Ausführen im Heap entstehen, dauerhaft sind.
+
+
+ PROC start lisp system (DATASPACE CONST heap):
+ Eine Kopie von "heap" wird der neue LISP-Heap. Wenn es sich um "nilspa­
+ ce" handelt, werden einige organisatorische Strukturen im Heap aufgebaut und
+ die Atome "NIL" und "PNAME" erzeugt.
+
+ PROC start lisp system (DATASPACE CONST heap, FILE VAR f):
+ Zunächst wird "start lisp system (heap)" gegeben.
+ Danach werden die Eigenschaftsbeschreibungen aus "f" in Strukturen im Heap
+ umgesetzt.
+
+ Jede Beschreibung in "f" muß mit dem Zeilenanfang beginnen und kann sich
+ über mehrere Zeilen erstrecken. Jede Beschreibung besteht aus den Elementen
+ <Atom> <Eigenschaft> <Wert>
+ wobei <Eigenschaft> der Name einer Eigenschaft (i.a. APVAL oder FUNCTION)
+ und <Wert> ein beliebiger S-Ausdruck sein müssen. Die drei Elemente müs­
+ sen jeweils durch mindestens ein Leerzeichen getrennt sein.
+
+ Wenn das Atom <Atom> nicht existiert, wird es erzeugt; danach wird <Wert>
+ unter <Eigenschaft> in der Eigenschaftsliste eingetragen.
+
+ Wenn <Eigenschaft> NIL ist, muß <Wert> wegfallen; dann wird nichts in die
+ Eigenschaftsliste eingetragen.
+
+ DATASPACE PROC lisp heap:
+ Liefert den LISP-Heap. Das ist manchmal für Sicherheitskopien etc. nützlich.
+ Die durch "run lisp" erzeugten Kopien sind nicht zugänglich.
+
+ PROC run lisp:
+ Ruft "run lisp (last param)" auf.
+
+ PROC run lisp (TEXT CONST file name):
+ Das in der Datei "file name" stehende LISP-Programm (d.h. der dort stehende
+ in einen S-Ausdruck übersetzte M-Ausdruck) wird in eine neue Kopie des
+ LISP-Heaps eingelesen und ausgeführt. Evtl. vorher durch "run lisp" erzeugte
+ Kopien des Heaps werden vorher gelöscht.
+
+ Wenn das Programm syntaktisch nicht korrekt ist, wird es im Paralleleditor zur
+ Korrektur angeboten.
+
+ PROC run lisp again:
+ Führt das zuletzt eingelesene Programm noch einmal im gleichen Heap aus.
+
+ PROC insert lisp:
+ Ruft "insert lisp (last param)" auf.
+
+ PROC insert lisp (TEXT CONST file name):
+ Wirkt wie "run lisp (file name)", nur daß alle Operationen auf dem Originalheap
+ ausgeführt werden. Auch "run lisp again" wirkt nun nicht mehr auf der Kopie.
+
diff --git a/doc/menugenerator/menu-generator handbuch.1 b/doc/menugenerator/menu-generator handbuch.1
new file mode 100644
index 0000000..c190c0a
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.1
@@ -0,0 +1,100 @@
+#type ("prop.lq")##limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (3)#
+#headodd#
+#center#ls-Menu-Generator#right#%
+
+#end#
+#headeven#
+%#center#ls-Menu-Generator
+
+#end#
+#type ("prop.breit.lq")#
+#center#1
+
+#center#Was
+#center#kann
+#center#ls-Menu-Generator
+#type ("prop.lq")#
+
+
+ In diesem Kapitel wollen wir Ihnen erläutern, was Sie
+mit #on("b")#ls-Menu-Generator#off("b")# anfangen können. Wir gehen davon
+aus, daß Ihnen die Benutzerschnittstelle #on("b")#ls-DIALOG#off("b")# be­
+kannt ist und daß Sie bereits mit einigen Anwendungen
+unter #on("b")#ls-DIALOG#off("b")# gearbeitet haben. Weiterhin setzen wir
+voraus, daß Sie Programmierkenntnisse (EUMEL/ELAN) be­
+sitzen.
+ Bisher war es Ihnen nur möglich, von uns fertigge­
+stellte Programme unter der komfortablen Benutzer­
+schnittstelle #on("b")#ls-DIALOG#off("b")# laufen zu lassen. Sie haben aber
+sicher erkannt, welche Vorteile es bietet, Programme un­
+ter einer einheitlichen Benutzeroberfläche zu realisie­
+ren:
+ Zunächst profitiert natürlich der Anwender von der
+einfachen und immer einheitlichen Bedienung solcher
+Programme. Der Aufwand, sich in neue Programmsysteme
+einzuarbeiten, wird erheblich reduziert. #on("b")#ls-DIALOG#off("b")# wurde
+ja auch speziell für den Unterricht konzipiert und ent­
+wickelt: Ziel war es, Computerlaien einen Zugang zum
+Computer zu verschaffen und den Umgang mit dem Compu­
+ter zu vereinfachen.
+
+ #on("b")#ls-Menu-Generator#off("b")#ist nun aber kein weiteres Anwen­
+dungsprogramm! #on("b")#ls-Menu-Generator#off("b")# ist stattdessen für
+den Programmierer gedacht, der selbst unter #on("b")#ls-DIALOG#off("b")#
+Anwendungssysteme entwickeln möchte. #on("u")#Wir erhoffen uns
+durch die Bereitstellung dieses Werkzeuges, daß sich auch
+andere engagierte Personen daran beteiligen, qualitativ
+hochwertige Software insbesondere für den Schulbereich
+unter #on("b")#ls-DIALOG#off("b")# zu entwickeln.#off("u")#
+
+ Mit #on("b")#ls-Menu-Generator#off("b")# haben Sie zwei Komponenten
+erworben: Das Generator-Programm zur Erzeugung von
+Menukarten und eine umfangreichen Dokumentation. Dabei
+enthält die Dokumentation nicht nur Informationen dar­
+über, wie Sie mit dem Generator-Programm arbeiten kön­
+nen - das natürlich auch. Darüberhinaus werden Ihnen
+alle Möglichkeiten, die #on("b")#ls-DIALOG#off("b")# zur Programmgestal­
+tung bietet, ausführlich erläutert - das macht den we­
+sentlichen Teil der Dokumentation aus!
+
+ #on("b")#ls-DIALOG#off("b")# ist eigentlich ein "Baukastensystem", auf
+das andere Programme zugreifen können. Sie wissen si­
+cherlich, wieviel Arbeit bei jedem Programm aufzuwen­
+den ist, um die Benutzerschnittstelle zu realisieren. Die
+Gestaltung und Pflege der Benutzerschnittstelle kann
+bis zu 50% der Gesamtarbeit an einem Programm ausmachen.
+#on("b")#ls-Menu-Generator#off("b")# soll Ihnen helfen, diese Arbeit zu
+verringern.
+
+ Alle Informationen, die ein Menu betreffen, sind in
+der sogenannten 'Menukarte' abgelegt. Wird nun ein Pro­
+gramm unter #on("b")#ls-DIALOG#off("b")# aufgerufen, so wird die entspre­
+chende Menukarte aus der "Menukarten - Sammeltask" ('ls-
+MENUKARTEN') geholt und an das System angekoppelt. An­
+schließend wird dem Anwender das Menu auf dem Bildschirm
+angeboten.
+ Das Erstellen solcher Menukarten ist mit dem Genera­
+torprogramm sehr einfach - es wird in Kapitel 4 beschrie­
+ben. Allerdings sollten Sie nicht die Arbeit unterschät­
+zen, die Sie für eine sorgfältig erstellte, mit allen In­
+formationtexten gefüllte Menukarte aufwenden müssen!
+
+ Bei den meisten Programmmen reicht aber ein einfaches
+Menu nicht aus. Bei vielen Verarbeitungsfunktionen ist
+es notwendig, mit dem Anwender einen Dialog zu führen:
+z.B. muß ein Dateiname erfragt, eine Information ausgege­
+ben und bestätigt, eine Auswahl oder eine Entscheidung
+getroffen werden. Alle Möglichkeiten, die #on("b")#ls-DIALOG#off("b")# dazu
+bereitstellt, sind in Kapitel 5 dokumentiert.
+
+ Einige Reihe von Verarbeitungsfunktionen treten in
+nahezu jeder Anwendung auf (Datei- und Archivhandling).
+Hier stellt #on("b")#ls-DIALOG#off("b")# schon vorgefertigte Module zur
+Verfügung. In Kapitel 6 zeigen wir Ihnen, wie Sie auf die­
+se Module zugreifen und sie in Ihr Programmsystem ein­
+binden können. In Kapitel 7 zeigen wir Ihnen außerdem,
+wie Sie eigene Fenster definieren können und welche Ope­
+rationen auf diesen Fenstern zur Verfügung stehen.
+
diff --git a/doc/menugenerator/menu-generator handbuch.2 b/doc/menugenerator/menu-generator handbuch.2
new file mode 100644
index 0000000..696ed28
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.2
@@ -0,0 +1,87 @@
+#type ("prop.lq")##limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (6)#
+#headodd#
+#center#ls-Menu-Generator#right#%
+
+#end#
+#headeven#
+%#center#ls-Menu-Generator
+
+#end#
+#type ("prop.breit.lq")#
+#center#2
+
+#center#Installation
+#center#von
+#center#ls-Menu-Generator
+#type ("prop.lq")#
+
+
+ Bevor Sie #on("b")#ls-Menu-Generator#off("b")# auf Ihrem System benut­
+zen können, müssen Sie das Programm zunächst installie­
+ren. Wenn #on("b")#ls-Menu-Generator#off("b")# auf Ihrem System schon zur
+Verfügung steht, können Sie dieses Kapitel ruhig über­
+springen.
+
+
+2.1 Voraussetzungen
+
+ Um #on("b")#ls-Menu-Generator#off("b")# auf Ihrem Computer betreiben
+zu können, muß das EUMEL-Betriebssystem (Multi-User-
+Version) installiert und das Programmpaket #on("b")#ls-DIALOG#off("b")#
+(Version 1.1) bereits insertiert sein.
+
+
+2.2 Lieferumfang
+
+ #on("b")#ls-Menu-Generator#off("b")# wird auf einer Diskette geliefert,
+die alle notwendigen Programme enthält. Folgende Dateien
+sollten sich auf der Diskette befinden:
+
+ "fonttab.ls-Menu-Generator"
+ "ls-MENUBASISTEXTE"
+ "Generatordatei: Archivmenu"
+ "ls-Menu-Generator 1"
+ "ls-Menu-Generator 2"
+ "ls-Menu-Generator/gen"
+
+ Eventuell können noch weitere Namen auf der Diskette
+vorhanden sein.
+
+
+2.3 Installation
+
+Die Installation erfolgt in #on("u")#zwei Schritten#off("u")#:
+
+ #on("u")#Zunächst#off("u")# muß die mitgelieferte Fonttabelle
+('fonttab.ls-Menu-Generator') in die Task 'configurator'
+geholt werden. Da Sie aus dem 'UR-Zweig' des EUMEL-
+Systems keinen schreibenden Zugriff auf die Task
+'configurator' haben, müssen Sie die Task 'configurator'
+an Ihr Terminal koppeln und die Datei 'fonttab.ls-Menu-
+Generator' von der Diskette in die Task kopieren.
+ #on("u")#Anschließend#off("u")# kann #on("b")#ls-Menu-Generator#off("b")# in einer Task
+installiert werden, in der bereits das Programm #on("b")#ls-DIALOG#off("b")#
+zur Verfügung steht. Richten Sie also eine Task als Sohn
+der Task ein, in der auf Ihrem Computer bereits #on("b")#ls-DIALOG#off("b")#
+installiert ist. Legen Sie dann die Archivdiskette ein,
+auf der sich #on("b")#ls-Menu-Generator#off("b")# befindet und geben Sie
+die folgenden Kommandos:
+
+ archive("ls-Menu-Generator") <RETURN>
+
+ fetch("ls-Menu-Generator/gen",archive) <RETURN>
+
+ run <RETURN>
+
+ Sie haben damit das Generatorprogramm gestartet; die
+Installation wird automatisch durchgeführt. Lassen Sie
+während des gesamten Vorgangs die Archivdiskette einge­
+legt. Die Generierung ist beendet, wenn der EUMEL-Ein­
+gangsbildschirm erscheint. Die Task, in der die Generie­
+rung stattfindet, wird automatisch zur Managertask, das
+heißt, daß Söhne von ihr eingerichtet werden können.
+
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.3 b/doc/menugenerator/menu-generator handbuch.3
new file mode 100644
index 0000000..e982988
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.3
@@ -0,0 +1,155 @@
+#block##pageblock#
+#pagenr("%",1)##setcount(1)##count per page#
+#headeven#
+gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#right#gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+3 - % #right#ERGOS
+#end#
+#bottomodd#
+#center#____________________________________________________________
+ERGOS #right# 3 - %
+#end#
+#ib#3 Die Arbeitsweise von gs-DIALOG#ie#
+
+
+In diesem Kapitel soll die grundsätzliche Arbeitsweise von gs-DIALOG erläutert
+werden. Sie erfahren, wie das Menusystem aufgebaut ist, wie man Menukarten an­
+koppelt und Menus zur Ausführung bringt. Ebenso wird erläutert, wie eine Menukarte
+aufgebaut ist.
+Wenn Sie die hier beschriebenen Vorgänge auf ihrem System nachvollziehen wollen,
+so muß in Ihrer Task das Programm 'gs-DIALOG' zur Verfügung stehen!
+
+
+#ib#3.1 Ankoppeln einer Menukarte - Ausführen eines Menus#ie#
+
+Vereinfacht gesagt ist eine Menukarte ein Datenraum, in dem alle Informationen, die
+zum Menu (zu den Menus) gehören, abgelegt sind. Der genaue Aufbau einer solchen
+Menukarte wird in Kapitel 3.2 beschrieben.
+Alle Menukarten, die auf einem System zur Verfügung stehen, werden in einer zentra­
+len Task ('gs-MENUKARTEN') bereitgehalten. Die Menukarten können von hier
+angefordert werden.
+Lassen Sie sich in Ihrem System eine Übersicht der vorhandenen Menukarten geben
+(list (/"gs-MENUKARTEN") <RETURN> ). Darauf wird Ihnen gegebenenfalls folgen­
+de Übersicht angeboten:
+
+ 01.09.87 "gs-MENUKARTE:Archiv"
+ 01.09.87 "gs-MENUKARTE:Herbert und Robbi"
+ 01.09.87 "gs-MENUKARTE:MP-BAP"
+ ...
+
+Zumindest die erste Menukarte müßte - sofern die gs-DIALOG-Basissoftware instal­
+liert ist - auf Ihrem System vorhanden sein. Die beiden anderen Menukarten sind
+natürlich nur dann vorhanden, wenn Sie die Programme 'gs-Herbert und Robbi'
+und 'gs-MP BAP' installiert haben.
+
+In einer weiteren Task (z.B. 'DIALOG') sind die Programme installiert, die es ermög­
+lichen, diese Menukarten zu handhaben. Alle Sohntasks dieser Task "erben" natür­
+lich diese Fähigkeiten. Von einer solchen Task aus kann nun eine Menukarte ange­
+fordert und ein darin enthaltenes Menu zur Ausführung gebracht werden. Das haben
+Sie sicher schon oft gemacht, z.B. wenn Sie den Befehl 'archiv' gegeben haben. Was
+hinter diesem Befehl steckt, sollen Sie sich jetzt klar machen:
+
+Wenn Sie den Befehl 'archiv' geben, wird zunächst die Menukarte
+'gs-MENUKARTE:Archiv' aus der Task 'gs-MENUKARTEN' angefordert und in Ihre
+Task kopiert. Davon merken Sie normalerweise nichts, denn nachdem die Ankopp­
+lung des Datenraumes (als unbenannter Datenraum) erfolgt ist, wird die Daten­
+raumkopie gelöscht; daher taucht der Name auch nie in Ihrer Dateiliste auf. Intern
+vermerkt das System, welche Menukarte aktuell angekoppelt ist. Soll wiederholt
+dieselbe Menukarte angekoppelt werden, so erübrigt sich das Kopieren aus der zen­
+tralen Bereitstellungstask.
+
+Nach dem Ankoppeln der Menukarte können Sie auf die in der Menukarte enthalte­
+nen Informationen zugreifen. Da in einer Menukarte mehrere Menus enthalten sein
+können, müssen Sie dem System noch mitteilen, welches Menu aktiviert werden soll.
+In der Menukarte 'gs-MENUKARTE:Archiv' ist nur ein Menu enthalten, das den
+Namen 'ARCHIV' hat (der Name des Menus erscheint übrigens bei der Präsentation
+immer oben links in der Kopfzeile).
+
+Sie sollen jetzt, ohne den Befehl 'archiv' zu verwenden, das Menu zur Ausführung
+bringen. Geben Sie dazu die folgenden Kommandos in der 'gib kommando:'- Ebene:
+
+ #ib#install menu#ie# ("gs-MENUKARTE:Archiv");
+ #ib#handle menu#ie# ("ARCHIV")
+
+Mit dem ersten Befehl koppeln Sie die genannte Menukarte an, mit dem zweiten
+Befehl bringen Sie das darin enthaltene Menu 'ARCHIV' zur Ausführung.
+Allerdings stellen Sie sicher auch einen Unterschied zur Ausführung des Befehls
+'archiv' fest, denn dort erscheint nicht erst unser "Software - Emblem" auf dem
+Bildschirm, sondern direkt das Menu.
+
+Wenn Ihnen eines der Programme 'gs-Herbert und Robbi' oder 'gs-MP BAP'
+bekannt ist, haben Sie unser Emblem aber sicher schon gesehen - wir verwenden es
+immer, um unsere Softwareprodukte kenntlich zu machen. Da man aber das Archiv­
+programm sehr häufig benötigt und es dann nur störend wirkt kann die Ausgabe
+unterdrückt werden. Daher gibt es den Befehl 'install menu' in zwei Versionen.
+Versuchen Sie es gleich einmal:
+
+ install menu ("gs-MENUKARTE:Archiv", FALSE);
+ handle menu ("ARCHIV")
+
+Die Präsentation des Menus erfolgt gleich aus zwei Gründen schneller als beim ersten
+Mal: einerseits wurde auf die Ausgabe unseres Software - Emblems verzichtet, ande­
+rerseits brauchte die Menukarte nicht erneut aus der Task 'gs-MENUKARTEN' kopiert
+zu werden, da sie ja schon angekoppelt war.
+Damit sind Sie nun in der Lage, Menukarten anzukoppeln und Menus zur Ausfüh­
+rung zu bringen.
+
+
+#ib#3.2 Aufbau/Inhalt einer Menukarte#ie#
+
+Eine Menukarte ist eine komplexe Datenstruktur, die bis zu 6 vollständige Menus
+aufnehmen kann. Weiterhin sind eine Reihe von Texten in jeder Menukarte abgelegt,
+auf die gs-DIALOG zurückgreift. Darüberhinaus kann der Anwendungsprogram­
+mierer bis zu 2000 Texte in die Menukarte auslagern, um so beim Insertieren seiner
+Programme den Umfang an Paketdaten geringer zu halten.
+Auf den ersten Blick scheint es wenig Sinn zu machen, mehrere Menus in einer
+Menukarte zu verwalten. Nehmen wir aber als Beispiel das Programmsystem
+gs-Herbert und Robbi. Hier ist ein Programm in zwei unterschiedlichen Ausprä­
+gungen zu behandeln. Sowohl das Hamster- als auch das Robotermenu befinden sich
+in einer Menukarte. Bei einem Wechsel zwischen den Modellen braucht also keine
+neue Menukarte angefordert, sondern nur ein neues Menu aus der aktuellen Menu­
+karte aktiviert zu werden.
+Zum anderen ist gs-DIALOG schon auf umfangreichere Programmsysteme vorberei­
+tet: Es ist nämlich möglich, von einem Menu aus ein weiteres Menu aus der aktuellen
+Menukarte zu aktivieren. Auf dem Bildschirm werden die beiden Menus dann ge­
+schachtelt (das zuletzt aktivierte vor dem aufrufenden Menu) angezeigt. Nach Verlas­
+sen der zweiten Menuebene gelangt der Benutzer automatisch in das Ausgangsmenu
+zurück.
+Zwar ist es nicht möglich, mehr als zwei Menus gleichzeitig zu aktivieren (geschach­
+telt auf dem Bildschirm darzustellen), doch können an verschiedenen Stellen des
+Ausgangsmenus ja unterschiedliche Menus aus der aktuellen Menukarte aktiviert
+werden.
+
+Jedes Menu in der Menukarte wird durch einen Namen gekennzeichnet. Dieser Name
+erscheint in der Kopfzeile oben links. Über diesen Namen kann das Menu aktiviert
+werden.
+Ein Menu besteht aus den sogenannten 'Oberbegriffen', die in der Kopfzeile angezeigt
+werden. In einer Kopfzeile können bis zu 10 Oberbegriffe verwaltet werden. Da zu
+jedem Oberbegriff bis zu 15 Verarbeitungsfunktionen (in den Pull-Down-Menus)
+verwaltet werden können, ist es möglich, in einem Menu bis zu 150 Verarbeitungs­
+funktionen abzulegen. Nutzt man alle 6 Menus einer Menukarte, so können maximal
+bis zu 900 Verarbeitungsfunktionen in einer Menukarte verwaltet werden.
+
+Eine Verarbeitungsfunktion besteht aus der/dem
+
+ - 'Ein-Zeichen-Kennung' - die angibt, durch welche Taste die Verarbei­
+ tungsfunktion ggf. aktiviert werden kann;
+ - 'Menupunktbezeichnung' - die im Pull-Down-Menu als Name für die
+ Verarbeitungsfunktion erscheint;
+ - 'Funktionsaufruf' - dem Namen der Prozedur, die bei der Aktivie­
+ rung des Menupunktes zur Ausführung ge­
+ bracht wird;
+ - 'Informationstext' - der zur aktuellen Verarbeitungsfunktion durch
+ Tippen der <?>-Taste abgerufen werden
+ kann.
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.4 b/doc/menugenerator/menu-generator handbuch.4
new file mode 100644
index 0000000..97e7491
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.4
@@ -0,0 +1,424 @@
+#block##pageblock#
+#pagenr("%",1)##setcount(1)##count per page#
+#headeven#
+gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#right#gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+4 - % #right#ERGOS
+#end#
+#bottomodd#
+#center#____________________________________________________________
+ERGOS #right# 4 - %
+#end#
+#ib#4 Erstellen einer neuen Menukarte#ie#
+
+
+Aus Kapitel 3 wissen Sie, wie man eine fertige Menukarte ankoppelt und wie man ein
+darin enthaltenes Menu zur Ausführung bringen kann. Außerdem wissen Sie bereits,
+welche Informationen in einer Menukarte untergebracht werden können. In diesem
+Kapitel nun wollen wir Ihnen zeigen, wie Sie eine eigene Menukarte entwickeln
+können.
+Damit Sie sich die Abläufe besser vorstellen können, werden wir die Vorgänge an
+einem Beispiel aufzeigen: Wir wollen eine 'kleine Textverarbeitung' schaffen, deren
+Verarbeitungsfunktionen über ein Menu angeboten werden.
+Es sei aber darauf hingewiesen, daß es nicht darum geht, eine voll funktionsfähige
+Textverarbeitung auszuarbeiten - vielmehr sollen die Erstellung der Menukarte und
+das Nutzen der durch gs-DIALOG bereitgestellten Werkzeuge exemplarisch auf
+gezeigt werden.
+
+
+#ib#4.1  Eintragen der Menupunkte#ie#
+
+Unsere Menukarte soll den Namen 'Kleine Textverarbeitung' erhalten, das darin
+enthaltene Menu den Namen 'SCRIPT'. Unter dem Oberbegriff 'Bearbeiten' sollen 5
+Verarbeitungsfunktionen angeboten werden. Insgesamt soll unser neues Menu fol
+genden Aufbau haben:
+
+SCRIPT: Bearbeiten
+
+ n Neu erstellen
+ a Ansehen/Ändern
+ ----------------
+ v Verzeichnis
+ ----------------
+ z Zeilenformtierung
+ s Seitenformatierung
+
+
+
+Zur Erzeugung der zugehörigen Menukarte schreiben Sie folgendes Pro­
+gramm in eine Datei:
+
+
+oeffne menukarte ("Kleine Textverarbeitung");
+oeffne menu ("SCRIPT");
+
+oberbegriff ("Bearbeiten");
+
+menufunktion ("n", "Neu erstellen", "neue datei editieren","");
+menufunktion ("a", "Ansehen/Ändern", "alte datei editieren","");
+trennlinie;
+menufunktion ("v", "Verzeichnis", "verzeichnis ausgeben","");
+trennlinie;
+menufunktion ("z", "Zeilenformatierung", "zeilen formatieren","");
+menufunktion ("s", "Seitenformatierung", "seiten formatieren","");
+
+schliesse menu;
+schliesse menukarte;
+
+
+Bevor wir Ihnen die Einzelheiten erklären, sollten Sie zuerst einmal Ihr neu erstelltes
+Menu ausprobieren. Verlassen Sie dazu die Datei und geben Sie das Kommando 'run'.
+Nachdem das von Ihnen geschriebene Programm übersetzt worden ist, meldet sich
+der Menu-Generator.
+Die an Sie gestellte Frage 'Sollen auch Anwendungs texte in die Menukarte aufge­
+nommen werden (j/n)?' beantworten Sie einfach mit n(ein). Auf dem Bildschirm
+wird angezeigt, wie die Menukarte erstellt wird. Auf das Ende der Menukartengenerie­
+rung wird hingewiesen. Wenn Sie sich jetzt die Dateiliste Ihrer Task anzeigen lassen,
+taucht dort eine Datei mit Namen 'gs-MENUKARTE:Kleine Textverarbeitung' auf - das
+ist die neue Menukarte.
+Sie möchten sicher gleich ausprobieren, ob das Menu Ihren Vorstellungen entspricht.
+Geben Sie dazu das Kommando 'testinstallation ("gs-MENUKARTE:Kleine Textver­
+arbeitung")'. Bitte geben Sie den Text genauso ein wie hier angegeben!
+Nach kurzer Zeit erscheint der Hinweis 'Installation abgeschlossen!'. Geben Sie nun
+den Befehl 'handle menu ("SCRIPT")'; hierdurch aktivieren Sie das von Ihnen neu
+erstellte Menu - es erscheint auf dem Bildschirm.
+
+Über den Befehl '#ib#testinstallation#ie#' haben Sie sich sicher gewundert. Ihnen ist ja
+schon der Befehl '#ib#install menu#ie#' bekannt. Dieser Befehl aber kann hier nicht ein­
+fach angewendet werden - er ist für den (späteren) "regulären Betrieb" vorgesehen.
+Bedenken Sie bitte zweierlei: Die Menukarte befindet sich nur in Ihrer Task, 'install
+menu' fordert die Menukarte aber aus der Task 'gs-MENU KARTEN' an. Ist eine
+Menukarte schon angekoppelt gewesen, so wird nicht erneut angekoppelt, sondern
+auf die angekoppelte Menukarte zurückgegriffen. Dies alles können wir bei der
+Menukartenerstellung nicht gebrauchen!
+Der Befehl 'testinstallation' sendet automatisch die Menukarte zur Task
+'gs-MENUKARTEN' und kennzeichnet Sie noch durch den eigenen Tasknamen (da
+durch können sich beim Multiuserbetrieb unterschiedliche Anwender mit gleichem
+Menukartennamen nicht gegenseitig stören). Die Menukarte wird anschließend in
+jedem Falle 'frisch' angekoppelt, so daß Sie nach dem Befehl immer die aktuelle
+Menukarte angekoppelt haben. Außerdem bleibt die Menukarte in Ihrer Task erhal­
+ten!
+
+Doch nun zur Erläuterung des oben notierten Programms:
+
+Ein Programm zur Erstellung einer Menukarte muß immer mit dem Befehl '#ib#oeffne
+menukarte#ie#' beginnen und mit dem Befehl '#ib#schliesse menukarte#ie#' abgeschlos­
+sen werden. Der Befehl 'oeffne menukarte' hat einen Parameter (TEXT CONST) -
+hierdurch wird festgelegt, welchen Namen die Menukarte haben soll. Durch das
+Kommando 'oeffne menu karte ("Menu 1")' entsteht also die Menukarte 'gs-MENU
+KARTE:Menu 1".
+In die Menukarte können jetzt bis zu 6 Menus eingetragen werden. Jeder Eintrag
+eines Menus beginnt mit dem Befehl '#ib#oeffne menu#ie#' und endet mit dem Befehl
+'#ib#schliesse menu#ie#'. Der Befehl 'oeffne menu' hat hier einen Parameter (TEXT
+CONST) - hierdurch wird festgelegt, welchen Namen das Menu erhalten soll. Unter
+diesem Namen kann später das Menu angesprochen werden (z.B. 'handle menu
+("SCRIPT")'.
+
+Den Befehl 'oeffne menu' gibt es noch in zwei weiteren Ausführungen:
+Mit drei Textparametern - neben dem Namen des Menus können hier noch zwei
+Prozedurnamen angegeben werden. Diese Prozeduren werden beim Einstieg in das
+Menu bzw. beim Verlassen des Menus aufgerufen. Hiervon wird z.B. Gebrauch ge­
+macht, wenn das Archiv-Menu in eine Menukarte integriert ist: Wenn das Menu
+verlassen wird, soll sichergestellt sein, daß das Archiv automatisch freigege ben wird.
+Mehr hierüber erfahren Sie im Kapitel 6.1, in dem aufgezeigt wird, wie das Archiv-
+Menu in andere Menus eingebunden wird.
+Mit sechs Textparametern - neben den eben genannten drei Parametern können noch
+drei Texte übergeben werden. Diese Texte werden beim Aufruf des Menus unten
+rechts auf dem Bildschirm ausgegeben. Bei unseren Software-Produkten (z.B.
+'gs-Herbert und Robbi') machen wir davon Gebrauch, um Hinweise auf das
+Produkt, die Versionsnummer etc. zu geben. Die Hinweise bleiben nur kurz auf dem
+Bildschirm und verschwinden nach kurzer Zeit automatisch, oder wenn Sie irgen
+deine Taste tippen. Bei der Notation der Texte müssen Sie sich allerdings an einige
+Regeln halten (sehen Sie dazu Kapitel 5.12).
+
+Zwischen den Befehlen 'oeffne menu' und 'schliesse menu' werden nun die Oberbe­
+griffe (Kopfzeile) und die zugehörigen Verarbeitungsfunktionen eingetragen. Dabei
+müssen Sie sich genau an folgende Abfolge halten:
+Zuerst wird jeweils der Oberbegriff genannt, der in der Kopfzeile auftauchen soll.
+Direkt unter dem jeweiligen Oberbegriff werden die Menufunktionen eingetragen, die
+im zugehörigen 'Pull-Down-Menu' als Verarbeitungsfunktionen angeboten werden
+sollen. Die einzelnen Oberbegriffe mit Ihren zugehörigen Verarbeitungsfunktionen
+werden blockweise hintereinander notiert. Dadurch ergibt sich die folgende Struktur:
+
+
+oeffne menu ("Menuname");
+
+oberbegriff ("Oberbegriff 1");
+
+menufunktion ("1", "Verarbeitungsfunktion 1", "", "");
+menufunktion ("2", "Verarbeitungsfunktion 2", "", "");
+...
+
+oberbegriff ("Oberbegriff 2");
+
+menufunktion ("1", "Verarbeitungsfunktion 1", "", "");
+menufunktion ("2", "Verarbeitungsfunktion 2", "", "");
+...
+
+oberbegriff ("Oberbegriff 3");
+
+menufunktion ("1", "Verarbeitungsfunktion 1", "", "");
+menufunktion ("2", "Verarbeitungsfunktion 2", "", "");
+...
+
+... schliesse menu;
+
+
+Die Oberbegriffe werden in die Kopfzeile von links nach rechts eingetragen. Maximal
+können 10 Oberbegriffe eingetragen werden. Wählen Sie die Bezeichnungen nicht zu
+lang, denn sie müssen alle neben dem Namen des Menus in der Kopfzeile Platz
+finden (Ansonsten erhalten Sie hierauf bei der Menukartengenerierung einen Hin­
+weis, die Generierung wird abgebrochen!)!
+
+Den Befehl '#ib#oberbegriff#ie#' gibt es in zwei Versionen:
+In der hier aufgezeigten Version mit einem (TEXT-) Parameter: Hierdurch wird der
+Oberbegriff in der Kopfzeile festgelegt. In der zweiten Version hat der Befehl drei
+(TEXT-)Parameter: Durch den ersten wird - wie eben - die Kopfzeilenbezeichnung
+festgelegt. Daneben können noch zwei Prozedurnamen angegeben werden. Die
+Prozedur mit dem erstgenannten Namen wird beim Einstieg (vor dem "Ausklappen"
+des Pull-Down-Menus) ausgeführt, die Prozedur mit dem zweitgenannten Namen vor
+dem Ausstieg ("Einklappen"). Beim 'Archiv-Pull-Down-Menu' machen wir hiervon
+Gebrauch. Beim Einstieg wird dafür gesorgt, daß nur bestimmte Verarbeitungsfunk­
+tionen aktivierbar sind; beim Ausstieg wird sichergestellt, daß das Archivlaufwerk
+automatisch freigegeben wird.
+
+Unter einem Oberbegriff können Sie bis zu 15 Verarbeitungsfunktionen in ein Pull-
+Down-Menu eintragen. Die Verarbeitungsfunktionen können Sie optisch vonein ander
+trennen. Dafür steht der Befehl '#ib#trennlinie#ie#' zur Verfügung. Aber beachten Sie, er
+belegt den gleichen Platz wie eine Verarbeitungsfunktion.
+
+Zum Eintragen einer Verarbeitungsfunktion steht der Befehl '#ib#menufunktion#ie#' zur
+Verfügung. Der Befehl besitzt vier (TEXT-)Parameter. Die ersten beiden Parameter
+werden auch auf dem Bildschirm ausgegeben.
+Der erste Parameter legt fest, über welche Taste diese Verarbeitungsfunktion direkt
+zur Ausführung gebracht werden kann. Wenn eine Eintragung erfolgt, muß diese aus
+genau einem Zeichen bestehen. Innerhalb eines Pull-Down-Menus muß dieses
+Zeichen eindeutig sein, d.h. es darf nur einmal verwendet werden. Ansonsten er­
+scheint bei der Menugenerierung eine Fehlermeldung.
+Der zweite Parameter ist die Bezeichnung der Verarbeitungsfunktion, die dem Be­
+nutzer im Pull-Down-Menu angeboten wird. Wählen Sie die Bezeichnung bitte immer
+prägnant und möglichst mit dem Buchstaben beginnend, den Sie auch als ersten
+Parameter angegeben haben! Der Länge dieser Bezeichnung ist nur durch die Bild­
+schirmbreite (nicht mehr als 60 Zeichen) begrenzt, allerdings wählt gs-DIALOG die
+Breite des Pull-Down-Menus nach der längsten Bezeichnung, die im jeweiligen Pull-
+Down-Menu auftritt. Wenn die Bezeichnungen ganz unterschiedlich lang sind, sieht
+das nicht sonderlich gut aus, aber probieren Sie es ruhig einmal aus und entscheiden
+Sie selbst.
+
+Der dritte Parameter ist der Name der Prozedur, die bei der Aktivierung der Verarbei­
+tungsfunktion ausgewählt werden soll. Zum Zeitpunkt der Erstellung und des Testens
+des Menusystems braucht diese Prozedur noch nicht zu existieren. Damit ist es
+möglich, die Menuentwicklung völlig unabhängig von der Entwicklung der Verarbei­
+tungsfunktionen zu betreiben; Sie brauchen nur die späteren Namen der aufzurufen­
+den Prozeduren festzulegen! Aktivieren Sie eine solche Verarbeitungsfunktion im
+Pull-Down-Menu, die noch nicht fertiggestellt ist, so erscheint der Hinweis 'unbe­
+kanntes Kommando' - das kann aber auch geschehen, wenn die Verarbeitungsfunk­
+tion schon existiert, Sie aber bei der Eintragung einen (Schreib-)Fehler gemacht
+haben!
+
+Der vierte Parameter ist der Text, der als sogenannter Infotext ausgegeben wird wenn
+Sie auf die entsprechende Verarbeitungsfunktion positioniert haben und hier die
+<?>-Taste tippen. In unserem Beispiel haben wir keinen Infotext eingetragen.
+Versuchen Sie im Menu jetzt die <?>-Taste zu tippen, so erscheint der Hinweis
+'Leider ist zu diesem Menupunkt kein Info-Text eingetragen!'. Für die Handhabung
+des Menus sind diese Informationstexte nicht wichtig, sie dienen ausschließlich der
+Information des Benutzers.
+Die Arbeit zur Formulierung/Abfassung dieser Texte sollten Sie nicht unterschätzen.
+Sie sollten sich bei einer ernsthaften Anwendung aber diese Arbeit machen. Gerade
+der Anfänger, der mit Ihrem Menusystem arbeitet, wird Ihnen diese Arbeit danken.
+Wie Sie diese Texte komfortabel erstellen und in die Menutafel einbinden können,
+erklären wir Ihnen im nächsten Kapitel.
+
+
+#ib#4.2 Erstellung und Einbinden von Informationstexten#ie#
+
+Bisher haben wir noch keine Informationstexte zu den Menupunkten in die Menu­
+karte eingetragen. Diese Eintragung erfolgt über den vierten Parameter des Befehls
+'menufunktion'. Möchten Sie dort nur einige wenige Worte eintragen, so kann das
+direkt geschehen. Meist aber sind die Informationen zu einem Menupunkt doch
+länger, sie erstrecken sich über mehrere Zeilen.
+Zur Übergabe des Informationstextes steht aber nur ein Textparameter zur Verfügung.
+Würde man längere Texte direkt eintragen, wäre das bei der Menukartenerstellung
+sicher sehr unübersichtlich. Zum anderen benötigt gs-DIALOG den Text schon in
+aufbereiteter Form, d.h. es müssen z.B. Zeilenenden etc. kenntlich gemacht wer den.
+Damit Sie sich nun nicht alle Regeln der Texterstellung für gs-DIALOG merken
+müssen, bietet Ihnen gs-Menu-Generator eine komfortable Möglichkeit, diese
+Informationstexte zu entwickeln. Wir wollen das an einem Beispiel verdeutlichen:
+
+Erzeugen Sie sich eine Datei mit dem Namen 'Textprobe' und schreiben Sie z.B.
+folgenden Text, der ein Informationstext zum Menupunkt 'Neu erstellen' sein könnte,
+hinein:
+
+Text neu erstellen
+
+Das System erfragt zunächst den Namen für die Datei, in die
+der neue Text geschrieben werden soll. Anschließend wird eine
+leere Datei mit dem gewünschten Namen zum Beschreiben
+angeboten.
+Das Schreiben in eine solche Datei wird durch viele Hilfen
+erleichtert. Deshalb ist es ratsam, sich nach und nach mit
+den Möglichkeiten, die der Editor bietet, vertraut zu machen.
+Die Möglichkeiten sind im EUMEL-Benutzerhandbuch ausführlich
+beschrieben.
+
+Verlassen Sie nun die Datei und geben Sie in der 'gib kommando:'-Ebene folgendes
+Kommando:
+
+ #ib#textprozedur#ie# ("Textprobe", "mein erster infotext")
+
+Auf dem Bildschirm erscheint zunächst der Hinweis 'Bitte warten ...', anschließend
+werden Sie - wie aus der Textverarbeitung (lineform) bekannt - aufgefordert, entspre­
+chende Trennungen vorzunehmen.
+Das eben eingegebene Kommando bewirkt nämlich, daß der in der Datei 'Textprobe'
+enthaltene Text für gs-DIALOG so aufbereitet wird, daß er in einer Box innerhalb des
+Menus eingeblendet werden kann. Die Zeilen werden auf die entsprechende Länge
+zugeschnitten und der Text in den Zeilen wird geblockt, soweit Sie keine Absatzmarke
+(<RETURN>) gesetzt haben.
+Der so den Regeln von gs-DIALOG entsprechend aufbereitete Text wird automatisch
+in eine Textprozedur "verpackt", die den von Ihnen als zweiten Parameter übergebe­
+nen Namen erhält. Beachten Sie deshalb bei der Festlegung des Namens, daß er mit
+einem Kleinbuchstaben beginnt und weiterhin nur Kleinbuchstaben, Ziffern und
+Leerzeichen enthält!
+Diese Textprozedur finden Sie anschließend in der Datei 'Textprobe.a'. An der En­
+dung '.a' können Sie erkennen, daß in dieser Datei ein "aufbereiteter" Text enthalten
+ist.
+Wenn Sie sich, nachdem auf dem Bildschirm der Hinweis 'Textprozedur ist erstellt!'
+erschienen ist, die Datei 'Textprobe.a' ansehen, so hat diese folgenden Inhalt:
+
+
+TEXT PROC mein erster infotext:
+" Text neu erstellen "13"" +
+" "13"" +
+" Das System erfragt zunächst den Namen für die Datei, in die der "13""+
+" neue Text geschrieben werden soll. Anschließend wird eine leere "13""+
+" Datei mit dem gewünschten Namen zum Beschreiben angeboten. "13""+
+" Das Schreiben in eine solche Datei wird durch viele Hilfen er-"13""+
+" leichtert. Deshalb ist es ratsam, sich nach und nach mit den Mög-"13""+
+" lichkeiten, die der Editor bietet, vertraut zu machen. "13"" +
+" Die Möglichkeiten sind im EUMEL-Benutzerhandbuch ausführlich be-"13""+
+" schrieben. "
+END PROC mein erster infotext;
+
+
+Kopieren Sie nun den Inhalt der Datei 'Textprobe.a' in die Datei, in die Sie das Pro­
+gramm zur Generierung Ihrer Menukarte geschrieben haben und ergänzen Sie die
+Ein tragung beim ersten Menupunkt in folgender Weise:
+
+
+TEXT PROC mein erster infotext:
+" Text neu erstellen "13"" +
+" "13"" +
+" Das System erfragt zunächst den Namen für die Datei, in die der"13""+
+" neue Text geschrieben werden soll. Anschließend wird eine leere"13""+
+" Datei mit dem gewünschten Namen zum Beschreiben angeboten. "13""+
+" Das Schreiben in eine solche Datei wird durch viele Hilfen er-"13""+
+" leichtert. Deshalb ist es ratsam, sich nach und nach mit den Mög-"13""+
+" lichkeiten, die der Editor bietet, vertraut zu machen. "13""+
+" Die Möglichkeiten sind im EUMEL-Benutzerhandbuch ausführlich be-"13""+
+" schrieben. "
+END PROC mein erster infotext;
+
+oeffne menukarte ("Kleine Textverarbeitung");
+oeffne menu ("SCRIPT");
+
+oberbegriff ("Bearbeiten");
+
+menufunktion ("n", "Neu erstellen", "neue datei editieren",
+ mein erster infotext);
+menufunktion ("a", "Ansehen/Ändern","alte datei editieren", "");
+trennlinie;
+menufunktion ("v", "Verzeichnis", "verzeichnis ausgeben", "");
+trennlinie;
+menufunktion ("z", "Zeilenformatierung", "zeilen formatieren", "");
+menufunktion ("s", "Seitenformatierung", "seiten formatieren", "");
+
+schliesse menu;
+schliesse menukarte;
+
+
+Starten Sie erneut das Programm mit 'run' und erstellen Sie dadurch eine neue
+Menukarte. Installieren Sie anschließend die neue Menukarte mit dem Kommando
+'test installation ("gs-MENUKARTE:Kleine Textverarbeitung")' und bringen Sie das
+Menu mit dem Kommando 'handle menu ("SCRIPT")' zur Ausführung. Wenn Sie jetzt
+auf dem Menu punkt 'n Neu erstellen' die <?>-Taste tippen, erscheint der von
+Ihnen eingegebene Infotext in einer Box innerhalb des Menus. Die Größe der Box
+wird automatisch durch den Text bestimmt. Die Box ist maximal 65 Zeichen breit
+und 14 Zeilen hoch.
+
+Nachdem Sie nun in der Lage sind, solche Informationstexte zu erstellen und sie in
+die Menukarte einzubinden, möchten wir Ihnen noch einige Möglichkeiten der
+"Kosmetik solcher Informationstexte" aufzeigen.
+Häufig möchte man die Überschrift eines solchen Informationstextes zentriert über
+dem Text dargestellt haben. Das läßt sich auch hier einfach bewerkstelligen: Schrei­
+ben Sie dazu als erstes Zeichen der Zeile, die zentriert werden soll, das Zeichen '%'
+und schließen Sie die Zeile mit einer Absatzmarke (<RETURN>) ab.
+Möchten Sie innerhalb des Textes eine Textpassage invers dargestellt haben, so kenn­
+zeichnen Sie den Anfang der Inversdarstellung durch das Zeichen '$' und das Ende
+der Inversdarstellung durch das Zeichen '&'. Der Text wird anschließend entspre­
+chend aufbereitet. Allerdings sollte die Textpassage nicht über Zeilengrenzen hinaus­
+gehen!
+Möchten Sie in unserem Beispiel die Überschrift zentriert und invers dargestellt
+haben, so ersetzen Sie die erste Zeile der Datei 'Textprobe' durch die Zeile: %$Text
+neu erstellen&. Wenn Sie anschließend den gesamten oben beschriebenen Vorgang
+wiederholen, erscheint die Überschift zentriert und invers dargestellt innerhalb der
+Box im Menu.
+
+
+#ib#4.3 Auslagerung von anwendungsbezogenen Texten in die
+Menukarte#ie#
+
+Wie schon in Kapitel 3.2 erwähnt, kann der Anwendungsprogrammierer bis zu 2000
+Texte aus seinen Programmen in die Menukarte auslagern, um so den Umfang an
+Paketdaten geringer zu halten, allerdings darf die Gesamtkapazität einer Menukarte
+(eines Datenraumes) dabei nicht überschritten werden.
+
+Die Texte müssen in einer Datei zeilenweise notiert sein. Sie müssen (wie TEXT-Deno­
+ter) in Anführungsstriche eingefaßt sein, allerdings dürfen die Texte länger als
+(normale) TEXT-Denoter (255 Zeichen) sein. Innerhalb der Textzeile dürfen auch die
+Ausgabecodes "4", "5", "7", "10", "13", "14", und "15" verwendet werden. Innerhalb
+der Textzeile darzustellende Anführungszeichen unterliegen den gleichen Besonder­
+heiten wie sonst auch bei TEXT-Denotern.
+Machen wir ein Beispiel! Schreiben Sie in eine Datei mit Namen 'Neue Texte' die
+folgenden Zeilen:
+
+"Dieses ist der erste eingetragene Text!"
+"Hier ist eine "15"Markierung"14" im Text!"
+"Dieses ist die letzte Zeile!"
+
+Um diese Texte in die Menukarte einzubinden, starten Sie jetzt noch einmal Ihr
+Generierungprogramm für die Menukarte. Auf die Frage 'Sollen auch Anwendungstex­
+te in die Menukarte aufgenommen werden (j/n) ?' antworten Sie jetzt allerdings mit
+j(a). Daraufhin werden Ihnen die in Ihrer Task vorhandenen Dateien zur Auswahl
+angeboten. Kreuzen Sie die Datei 'Neue Texte' an, in der ja die eben genannten Texte
+eingetragen sind.
+Bei der Menukartengenerierung werden die Texte aus der Datei in die Menukarte
+eingebunden. Sollten Sie bei Notierung der Texte in der Datei formale Fehler gemacht
+haben, so werden Sie darauf hingewiesen.
+Um nun auf die eingelagerten Texte zurückgreifen zu können, muß erst einmal die
+neue Menukarte angekoppelt werden. Wie das geht, wissen Sie ja schon ('testin stalla­
+tion').
+Mit dem Befehl '#ib#anwendungstext#ie# (INT CONST zeilennummer)' (1 <= zeilen­
+nummer <= 2000) wird Ihnen nun der Text, der in der angegebenen Zeile steht,
+geliefert. Probieren Sie es doch gleich an Ihrer Menukarte aus: 'put (anwendungs­
+text (1))', 'put (anwendungstext (2))' usw.. Die eingelagerten Texte müßten jetzt auf
+dem Bildschirm erscheinen. Geben Sie eine Zeilennummer an, die nicht belegt ist, so
+wird der Text 'Kein Text vorhanden!' geliefert.
+
+Es können natürlich auch Texte abgelegt werden, die von gs-DIALOG aus aufgegrif­
+fen werden. Zur Konvertierung von Informationstexten steht die Prozedur '#ib#text zeile#ie#
+(TEXT CONST dateiname)' zur Verfügung. Diese Prozedur arbeitet genauso wie die
+Prozedur 'textprozedur', nur wird in der Ausgabedatei ('dateiname.a') der formatierte
+Text nicht als Textprozedur, sondern als einzeiliger Text geliefert. Sie können aber
+auch für gs-DIALOG Texte "von Hand" gestalten. Dazu müssen Sie sich an die
+Regeln für die Texte für gs-DIALOG halten, die in Kapitel 5.12 erläutert sind.
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.5 b/doc/menugenerator/menu-generator handbuch.5
new file mode 100644
index 0000000..c002f1a
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.5
@@ -0,0 +1,975 @@
+#block##pageblock#
+#pagenr("%",1)##setcount(1)##count per page#
+#headeven#
+gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#right#gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+5 - % #right#ERGOS
+#end#
+#bottomodd#
+#center#____________________________________________________________
+ERGOS #right# 5 - %
+#end#
+#ib#5  Dialoge innerhalb des Menus#ie#
+
+
+In Kapitel 4 haben Sie erfahren, wie Sie eine eigene Menukarte entwickeln können;
+sicher haben Sie das schon ausprobiert und sich Ihr selbstgestaltetes Menu auf dem
+Bildschirm angesehen. Bislang erscheint aber noch der Hinweis 'unbekanntes Kom­
+mando', wenn Sie eine Menufunktion aktivieren - denn die Prozeduren, die Sie bei
+der Aktivierung der Menufunktion aufrufen, sind ja noch nicht fertiggestellt!
+Bei vielen Menufunktionen ist es notwendig, mit dem Benutzer noch einen Dialog zu
+führen: z.B. muß ein Dateiname erfragt, eine Information ausgegeben und bestätigt,
+eine Auswahl oder eine Entscheidung getroffen werden. In diesem Kapitel sollen
+Ihnen nun die Möglichkeiten vorgestellt werden, die Ihnen zur Verfügung stehen, um
+einen solchen Dialog mit dem Benutzer zu führen. Dieser Dialog wird innerhalb des
+Menus geführt. Alle Prozeduren, die sich auf diesen Menu-Dialog beziehen, enthalten
+deshalb den Wortbestandteil 'menu'.
+
+Hier noch einige Tips! Damit Sie Ihre Menu-Dialoge testen können, empfiehlt
+sich folgendes Vorgehen: Sie erstellen zuerst Ihre Menukarte und tragen schon die
+Namen für die jeweils aufzurufenden Prozeduren ein - wie wir es in Kapitel 4 ge­
+macht haben. Mit 'testinstallation' installieren Sie dann in Ihrer Task die neue Menu­
+karte.
+Nun schreiben Sie Ihre Prozeduren, die Sie unter das Menu legen wollen. Ist eine
+Prozedur "testreif", so müssen Sie sie zunächst insertieren, denn das Menusystem gs-
+DIALOG kann nur auf insertierte Prozeduren zugreifen. Anschließend rufen Sie das
+Menu (z.B. 'SCRIPT') aus der Menukarte mit dem Befehl 'handle menu ("SCRIPT")'
+(Hier ist der jeweilige Menuname einzusetzen!) auf. Wenn Sie den entsprechenden
+Menupunkt aktivieren, müßte Ihr Programm ablaufen.
+Es ist günstig, eine eigene Task zum Testen der Prozeduren anzulegen, damit diese
+hin und wieder gelöscht werden kann.
+
+
+#ib#5.1 Eingabe eines Textes/Namens#ie# ('#ib#menuanswer#ie#')
+
+Wenn der Benutzer in unserem Beispiel die Menufunktion 'Neu erstellen' aktiviert
+hat, muß der Name der Datei erfragt werden, die neu erstellt werden soll. Dafür steht
+die Prozedur 'menuanswer' zur Verfügung. Die in die Menukarte eingetragene Proze­
+dur 'neue datei editieren' (Siehe Kapitel 4.1) könnte dann folgendermaßen aussehen:
+
+
+PROC neue datei editieren:
+ TEXT VAR dateiname := menuanswer ("Bitte den gewünschten Dateinamen:",
+ "", 5);
+ IF dateiname <> "" AND NOT exists (dateiname)
+ THEN command dialogue (FALSE); #ib#cursor on#ie#;
+ edit (dateiname);
+ #ib#cursor off#ie#; command dialogue (TRUE);
+ regenerate menuscreen (* sehen Sie dazu Kapitel 5.10 *)
+ FI
+END PROC neue datei editieren;
+
+
+Schauen wir uns zuerst die Prozedur 'menuanswer' an. Die Prozedur hat drei Para­
+meter. Mit dem ersten Parameter legen Sie den Text fest, der innerhalb der Box
+ausgegeben wird, die auf dem Bildschirm erscheint. Der Text dient ausschließlich der
+Information des Anwenders.
+Mit dem zweiten Parameter können Sie dem Benutzer einen Vorschlag für die Einga­
+be machen, der zum Editieren ausgegeben wird. Da eine solche Vorgabe aber in die­
+ser Situation sinnlos wäre, verzichten wir darauf ("").
+
+Die auf dem Bildschirm erscheinende Box hat folgendes Aussehen:
+
+ +-------------------------------------+
+ I Bitte den gewünschten Dateinamen: I
+ I I
+ I I
+ I Eingabe: I
+ +-------------------------------------+
+
+
+Die Boxbreite und -höhe wird vom System automatisch anhand des von Ihnen als
+ersten Parameter übergebenen Textes festgelegt. Sie haben noch verschiedene Mög­
+lichkeiten, diesen Text zu gestalten (mehrere Zeilen, Inversdarstellung etc.) - auf
+diese Möglichkeiten gehen wir in Kapitel 5.13 detailliert ein.
+In unserem Beispiel erscheint die Box in der Mitte des Menubildschirms. Diese
+Festlegung treffen wir durch die Angabe der Position '5' als dritten Parameter. Sie
+können hier zwischen 5 verschiedenen Positionen wählen: 1 - oben links, 2 - oben
+rechts, 3 - unten links, 4 - unten rechts, 5 - zentral im Menubildschirm - mehr dazu
+in Kapitel 5.12.
+
+Mit dem Erscheinen der obigen Box auf dem Bildschirm ändert sich automatisch
+auch die Fußzeile im Menu, über die der Benutzer Informationen zur Bedienung
+erhält. Hier erscheint der Hinweis: 'Fertig: <RETURN>  Abbruch: <ESC><h>'.
+Um diese Hinweise brauchen Sie sich aber nicht zu kümmern , da sie alle automa­
+tisch gesetzt werden.
+Die Prozedur 'menuanswer' hat noch folgende Besonderheit: Es ist nicht möglich,
+den Namen 'break' einzugeben! Diese Eingabe wird automatisch abgefangen. Es hat
+sich gezeigt, daß Anwender manchmal versuchen, über <ESC><q> die Eingabe
+zu verlassen. In diesem Falle entstünde hier eine Datei mit Namen 'break' - was aber
+nicht sinnvoll wäre.
+Nach der Eingabe liefert die Prozedur 'menuanswer' als Wert den vom Benutzer
+eingegebenen Text - dabei sind führende und folgende Leerzeichen schon abgeschnit­
+ten ('compress'). Wurde die Prozedur mit <ESC><h> verlassen, so wird niltext
+geliefert.
+
+Wird in obiger Prozedur die Eingabe mit <ESC><h> abgebrochen oder existiert
+bereits eine Datei mit dem eingegebenen Namen, so verschwindet die Box, und der
+Menubildschirm wird automatisch in den alten Zustand gebracht.
+Wenn schon eine Datei mit dem Namen existiert, dann wäre es sinnvoll, den Benutzer
+darauf aufmerksam zu machen. Wie ein solcher Hinweis in das Menu eingeblendet
+werden kann, erklären wir im Kapitel 5.2.
+
+gs-DIALOG ist so geschrieben, daß der Cursor möglichst wenig störend wirkt. Aus
+diesem Grunde wird der Cursor immer an einer Stelle "geparkt". Sofern Ihr System es
+zuläßt und eine entsprechende Anpassung vorliegt, wird der Cursor ganz ausgeschal­
+tet. Denken Sie bitte daran, auch wenn er auf Ihrem Bildschirm ständig sichtbar ist!
+Wenn also jetzt eine Eingabe erfolgen soll, ist es notwendig, den Cursor anzuschalten.
+Wenn Sie wieder in das Menu zurückkehren, sollte der Cursor wieder ausgeschal­
+tet werden, damit er dort nicht stört.
+Wenn Sie die Prozedur 'edit' mit einem neuen Namen als Parameter aufrufen, erfragt
+das System, ob die Datei neu eingerichtet werden soll. Diese Anfrage muß hier unter­
+drückt werden, damit nicht irgendwelche Texte in den Menubildschirm geschrieben
+werden. Das Unterdrücken der Abfrage erreichen Sie durch Ausschalten des Kom­
+mandodialoges. Nach Einrichten der Datei muß der Kommandodialog aber wieder
+eingeschaltet werden, da gs-DIALOG das Eingeschaltetsein für eine fehlerfreie Funk­
+tion voraussetzt!
+
+Mit dem Befehl '#ib#regenerate menuscreen#ie#' (sehen Sie dazu auch Kapitel 5.10) wird der
+aktuelle Menubildschirm erneut vollständig auf den Bildschirm geschrieben (repro­
+duziert). Das ist notwendig, weil die Prozedur 'edit' den Bildschirm benutzt hat.
+Durch diesen Befehl wird der Menubildschirm exakt in der Form hergestellt, wie er
+zuletzt ausgesehen hat. Auch wenn Sie geschachtelte Menubildschirme haben, wer­
+den diese durch den einen Befehl reproduziert. So können Sie in Ihren Verarbei­
+tungsfunktionen mit dem Bildschirm "machen was Sie wollen" - Sie kehren mit dem
+letztgenannten Befehl immer wieder so in das Menu zurück, wie Sie es verlassen
+haben.
+
+
+#ib#5.2 Ausgabe einer Information#ie# ('#ib#menuinfo#ie#')
+
+In der Prozedur 'neue datei editieren' (Kapitel 5.1) wäre es sinnvoll, den Benutzer zu
+informieren, wenn bereits eine Datei mit dem eingegebenen Namen existiert. Hierfür
+steht die Prozedur 'menuinfo' zur Verfügung.
+
+Beispiel:
+
+menuinfo (" Eine Datei mit dem Namen "13" existiert schon!");
+
+Dadurch wird folgende Box ins Menu geschrieben:
+
+ +----------------------------+
+ I I
+ I Eine Datei mit dem Namen I
+ I existiert schon I
+ I I
+ +----------------------------+
+
+Die Box erscheint in der Mitte des Menus (Position 5); in der Fußzeile wird der Hin­
+weis ausgegeben 'Zum Weitermachen bitte irgendeine Taste tippen!'. Dann wartet das
+System so lange, bis eine Taste gedrückt wird. Anschließend wird der aktuelle Menu­
+schirm wiederhergestellt.
+Die Prozedur 'menuinfo' gibt es noch in zwei weiteren Versionen, nämlich mit zwei
+bzw. drei Parametern. Im ersten Fall kann über den zweiten Parameter noch die
+Position (1, 2, 3, 4, 5) innerhalb des Menubildschirmes festgelegt werden (sehen Sie
+dazu Kapitel 5.12). Mit dem dritten Parameter kann ggf. noch die Wartezeit festgelegt
+werden, die das System maximal verstreichen läßt, bevor es von sich aus das Pro­
+gramm fortsetzt.
+
+'menuinfo (" Eine Datei mit dem Namen "13" existiert schon!", 3, 40)'
+
+gibt die oben gezeigte Box aus, aber links unten in der Ecke des Menubildschirms
+(Position 3). Das System wartet (maximal) 4 Sekunden (40 Zehntel) und setzt dann -
+auch ohne Tastendruck - das Programm fort. Diese Prozedur mit gesondert angege­
+bener Wartezeit verwendet man dann, wenn man nicht unbedingt die Kenntnisnahme
+der Information durch den Benutzer bestätigt haben möchte.
+
+
+#ib#5.3 Auswahl eines Namen durch Ankreuzen#ie# ('#ib#menuone#ie#')
+
+Während bei der Neuerstellung einer Datei ein Name neu erfragt werden muß, kann
+man beim Menupunkt 'Ansehen/Ändern' auf schon vorhandene Dateien zugreifen.
+Sie können dem Benutzer z.B. alle Dateien in der Task zur Auswahl anbieten. Sobald
+der Benutzer einen Namen angekreuzt hat, soll die entsprechende Datei geöffnet wer­
+den. Dafür steht der Befehl 'menuone' zur Verfügung:
+
+
+PROC alte datei editieren:
+ TEXT CONST kopf :: "Textdatei ansehen/ändern",
+ hinweis :: "Bitte gewünschte Datei ankreuzen";
+ TEXT VAR dateiname := menuone (ALL myself, kopf, hinweis, FALSE);
+ IF dateiname <> ""
+ THEN #ib#cursor on#ie#;
+ edit (dateiname);
+ #ib#cursor off#ie#;
+ FI;
+ regenerate menuscreen
+END PROC alte datei editieren;
+
+
+Die Prozedur 'menuone' hat 4 Parameter: Als erster Parameter ist ein Thesaurus zu
+übergeben, in dem die zur Auswahl stehenden Namen enthalten sind. Zum Thesau­
+rushandling werden noch einige zusätzliche Funktionen zur Verfügung gestellt (z.B.
+daß nur Dateien eines bestimmten Typs zur Auswahl angeboten werden können) -
+diese Funktionen werden in Kapitel 5.14 erläutert. In unserem Beispiel werden alle
+Dateien zur Auswahl angeboten, die in der Task zur Verfügung stehen.
+Die beiden Texte, die als 2. und 3. Parameter übergeben werden, erscheinen zur
+Kennzeichnung im Kopf der Auswahlliste. Der als zweiter Parameter übergebene Text
+erscheint zentriert und invers dargestellt auf dem Bildschirm, der als dritter Parame­
+ter übergebene Text nur zentriert. Es ist sinnvoll, mit dem ersten Text (2.Parame­
+ter) die zur Zeit aktivierte Menufunktion anzuzeigen, denn der Menubildschirm wird
+ja durch die Auswahlliste überschrieben. So kann sich der Benutzer besser im Menu­
+system orientieren.
+Mit dem 4. Parameter wird festgelegt, ob der Bildschirm nach der Auswahl "ge­
+reinigt", d.h. der alte Menubildschirm wiederhergestellt werden soll. Da in unserem
+Falle normalerweise im Anschluß an die Auswahl eine Datei auf dem Bildschirm
+editiert wird, verzichten wir auf die "automatische Regenerierung" des Menubild­
+schirms. Dieses besorgen wir nach dem Editieren durch das Kommando 'regenerate
+menuscreen' "von Hand".
+Auf das Fenster, das für die Auswahl auf dem Bildschirm angezeigt wird, können Sie
+keinen Einfluß nehmen - es wird vom System selbständig festgelegt. Dadurch können
+Sie die Auswahl, wie auch die anderen Dialogkomponenten ebenso in geschachteleten
+Menus aufrufen, ohne daß es zu Problemen kommt.
+
+
+#ib#5.4 Auswahl mehrerer Namen durch Ankreuzen#ie# ('#ib#menusome#ie#')
+
+Es ist nicht immer sinnvoll, daß der Benutzer nur einen Namen auswählen, d.h.
+ankreuzen kann. Bei der Zeilenformatierung könnte man z.B. zulassen, daß gleich
+mehrere Dateinamen angekreuzt werden können. Im Anschluß an die Auswahl sollen
+dann alle angekreuzten Dateien mit 'lineform' bearbeitet werden. Für diesen Zweck
+steht die Prozedur 'menusome' zur Verfügung. Sie hat die gleichen Parameter wie die
+in 5.3 erläuterte Prozedur 'menuone' - nur daß hier die Auswahl mehrerer Namen
+möglich ist. Verläßt der Benutzer die Auswahl durch <ESC><q>, so wird ein
+Thesaurus mit allen angekreuzten Namen geliefert; bei Verlassen mit <ESC><h>
+ein leerer Thesaurus. Beispiel:
+
+
+PROC zeilen formatieren:
+ TEXT CONST kopf :: "Textdateien zeilenweise formatieren",
+ hinweis :: "Bitte gewünschte Dateien ankreuzen";
+ THESAURUS VAR dateinamen := menusome (ALL myself, kopf, hinweis,
+ FALSE);
+ cursor on;
+ formatiere dateien;
+ cursor off;
+ regenerate menuscreen.
+
+ formatiere dateien:
+ INT VAR zaehler;
+ FOR zaehler FROM 1 UPTO highest entry (dateinamen) REP
+ IF name (dateinamen, zaehler) <> ""
+ THEN lineform (name (dateinamen, zaehler))
+ FI
+ PER
+END PROC zeilen formatieren;
+
+
+
+#ib#5.5 Eingabe eines Textes/Namens - alternativ: Auswahl
+ durch Ankreuzen#ie# ('#ib#menuanswerone#ie#','#ib#menuanswersome#ie#')
+
+Sehr häufig kommt es vor, daß der Benutzer auf die zuletzt bearbeitete Datei zurück­
+greifen will. In Kapitel 5.3 haben wir dem Benutzer bei der Menufunktion 'Anse­
+hen/Ändern' gleich alle Dateien zur Auswahl angeboten. Hier wäre es vielleicht gün­
+stiger gewesen, ihm die zuletzt bearbeitete Datei anzubieten und erst auf Wunsch die
+Liste aller Dateien zum Ankreuzen. Das läßt sich auf verschiedene Weise realisieren -
+wir werden Ihnen in diesem und in den folgenden Kapiteln verschiedene Möglich­
+keiten aufzeigen:
+
+Sie können z.B. mit der Prozedur 'menuanswerone' arbeiten. Wie Sie schon aus dem
+Namen entnehmen können, handelt es sich dabei um eine Prozedur, die eigentlich
+aus zwei Prozeduren, nämlich 'menuanswer' und 'menuone' zusammengesetzt ist.
+Stellen Sie sich vor, sie führen den Namen der zuletzt bearbeiteten Datei in Ihrem
+Programm unter der Variablen 'letzte datei'. Dann könnte die Prozedur 'alte datei
+editieren' aus Kapitel 5.3 auch folgendermaßen geschrieben werden:
+
+
+TEXT VAR letzte datei;
+...
+
+
+PROC alte datei editieren:
+ TEXT CONST hinweis letzte :: "Zuletzt bearbeitete Datei:",
+ kopf :: "Textdatei ansehen/ändern",
+ hinweis :: "Bitte gewünschte Datei ankreuzen";
+ TEXT VAR dateiname := menuanswerone (hinweis letzte,
+ letzte datei,
+ ALL myself, kopf,
+ hinweis, FALSE);
+ IF dateiname <> ""
+ THEN cursor on;
+ edit (dateiname);
+ letzte datei := dateiname;
+ cursor off;
+ FI;
+ regenerate menuscreen
+END PROC alte datei editieren;
+
+
+Insgesamt hat die Prozedur 6 Parameter: Die ersten beiden Parameter beziehen sich
+auf die Eingabe ('menuanswer'). Wie dort kann auch hier der Text festgelegt werden,
+der in der Box auf dem Bildschirm erscheint.
+Der zweite Parameter ist der Text, der dem Benutzer zum Editieren angeboten wird -
+hier der zuletzt benutzte Dateiname. Möchte der Benutzer auf die Datei mit dem an­
+gebotenen Namen zugreifen, braucht er nur mit <RETURN> zu bestätigen.
+Möchte er die Auswahl zum Ankreuzen angeboten bekommen, so braucht er nur die
+Tastenfolge <ESC><z> (für 'Zeigen') zu tippen. Auf diese Auswahl beziehen sich
+die letzten 4 Parameter, die die gleiche Bedeutung haben wie bei der Prozedur
+'menuone'. Auf die Möglichkeit, durch <ESC><z> eine Auswahl angeboten zu
+bekommen, wird in der Fußzeile des Menus hingewiesen.
+
+Aber Achtung! Sie sollten sich einer "Gefahr" bei diesem Vorgehen bewußt sein. Der
+Benutzer hat natürlich so die Möglichkeit, auch einen anderen Namen als den vorge­
+schlagenen anzugeben - einen Namen, der noch nicht in der Dateiliste enthalten ist.
+In einem solchen Falle würde Ihnen bei obiger Prozedur der Menubildschirm "ka­
+puttgeschrieben", denn das System fragt (bei eingeschaltetem Kommandodialog) an,
+ob eine Datei mit dem Namen eingerichtet werden soll. Für diesen Fall sollten Sie also
+unbedingt eine Vorsorge treffen (z.B. indem Sie den Benutzer darauf hinweisen, daß
+der eingegebene Name nicht akzeptiert wird)!
+
+Sie vermuten sicher schon ganz richtig, daß es entsprechend auch die Prozedur
+'menuanswersome' gibt, die zunächst einen Dateinamen erfragt und auf Wunsch
+eine Auswahl anbietet, in der mehrere Dateinamen angekreuzt werden können. Die
+Prozedur hat ebenfalls 6 Parameter, die identisch zur Prozedur 'menuanswerone'
+sind. Allerdings liefert die Prozedur 'menuanswersome' in jedem Fall einen Thesau­
+rus; wurde die Auswahl mit <ESC><h> abgebrochen, so liefert sie einen leeren
+Thesaurus.
+
+
+#ib# 5.6 Die Ja/Nein - Entscheidung#ie# ('#ib#menuyes#ie#','#ib#menuno#ie#')
+
+In Kapitel 5.5 trat das Problem auf, daß der Benutzer einen "unzulässigen" Namen
+eingeben konnte. Dieses Problem können wir umgehen: Wir fragen den Benutzer ein­
+fach, ob er mit der zuletzt bearbeiteten Datei arbeiten will und lassen Ihm nur die
+Chance, mit 'Ja' oder 'Nein' zu antworten. Im ersten Fall bieten wir ihm eben diese
+Datei an - ansonsten die Auswahl zum Ankreuzen.
+
+Hierfür stehen die Prozeduren 'menuyes' und 'menuno' zur Verfügung, die von Ihrer
+Funktion her den Ihnen bekannten Prozeduren 'yes' und 'no' gleichen. Die beiden
+Menu-Prozeduren haben jeweils zwei Parameter:
+
+
+TEXT VAR letzte datei;
+...
+
+PROC alte datei editieren:
+ TEXT CONST kopf :: "Textdatei ansehen/ändern",
+ hinweis :: "Bitte gewünschte Datei ankreuzen";
+ TEXT VAR dateiname;
+ IF menuyes (" Wollen Sie mit der Datei "13"" +
+ " '" +letzte datei+ "'"13" arbeiten", 5)
+ THEN editiere letzte datei
+ ELSE dateiname := menuone (ALL myself, kopf, hinweis, FALSE);
+ editiere ausgewaehlte datei
+ FI;
+ regenerate menuscreen.
+
+ editiere letzte datei:
+ cursor on; edit (letzte datei); cursor off.
+
+ editiere ausgewaehlte datei:
+ IF dateiname <> ""
+ THEN cursor on; edit (dateiname); cursor off;
+ letzte datei := dateiname
+ FI
+END PROC alte datei editieren;
+
+
+Über den zweiten Parameter legen Sie die Position auf dem Bildschirm innerhalb des
+Menus fest (1, 2, 3, 4, 5; sehen Sie auch Kapitel 5.12). Der erste Parameter ist ein
+Text, welcher der gs-DIALOG-Syntax gehorchen muß (die Codes "13" bewirken
+einen Zeilenvorschub; sehen Sie auch Kapitel 5.13). Er wird in einer Box auf den
+Bildschirm geschrieben und durch 'Ja  Nein' ergänzt:
+
+
+ +-----------------------------+
+ I I
+ I Wollen Sie mit der Datei I
+ I 'Dateiname' I
+ I arbeiten? I
+ I I
+ I Ja    Nein I
+ I I
+ +-----------------------------+
+
+Für 'Dateiname' ist auf Ihrem Bildschirm dann natürlich der aktuelle Inhalt von
+'letzte datei' eingetragen.
+Die Prozedur 'menuyes' liefert TRUE, wenn mit 'Ja' geantwortet wurde und FALSE,
+wenn mit 'Nein' geantwortet wurde. Die Prozedur 'menuno' wirkt wie 'NOT menuyes'.
+Nach Eingabe von 'Ja', 'Nein' (durch Tippen der Anfangsbuchstaben oder Positionie­
+rung auf die Antwort und anschließendem <RETURN>) wird der Menubildschirm
+automatisch regeneriert. Auch die entsprechenden Hinweise in der Fußzeile werden
+natürlich automatisch gesetzt.
+
+
+#ib#5.7 Die Alternativentscheidung#ie# ('#ib#menualternative#ie#')
+
+Im letzten Kapitel haben wir Ihnen die Prozeduren 'menuyes' und 'menuno' in Ihrer
+Wirkungsweise erläutert. Eigentlich sind die beiden Prozeduren nur ein (häufig
+benötigter) Spezialfall der Prozedur 'menualternative'. Die Funktionsweise der Proze­
+dur 'menualternative' dürfte Ihnen schon aus dem 'Archivmenu' bekannt sein: Wenn
+Sie eine neue Zieltask einstellen, werden Ihnen nämlich vier Alternativen zur Auswahl
+angeboten (Archiv, Vatertask, PUBLIC, Sonstige Task).
+Auf unsere Textverarbeitung bezogen könnten wir z.B. vor der Zeilenformatierung
+(lineform) über die Alternativentscheidung den gewünschten Schrifttyp abfragen. Wir
+wollen dem Benutzer in diesem Beispiel fünf Schrifttypen (schmal, elite, pica, letter,
+groß) zur Auswahl anbieten:
+
+
+
+TEXT VAR schrifttyp;
+...
+
+PROC schrifttyp waehlen:
+ TEXT CONST info :: " Auswahl der Schrifttypen: "13""13""
+ + " s ... schmal (17 Zeichen pro Zoll) "13""
+ + " e ... elite (12 Zeichen pro Zoll) "13""
+ + " p ... pica (10 Zeichen pro Zoll) "13""
+ + " l ... letter (Proportionalschrift) "13""
+ + " g ... groß ( 5 Zeichen pro Zoll) ",
+
+ liste :: "schmal"13"elite"13"pica"13"letter"13"groß",
+ tasten :: "seplgSEPLG";
+
+ INT VAR auswahl := menualternative (info, liste, tasten, 5, TRUE);
+ SELECT auswahl OF
+ CASE 1, 101, 106: schrifttyp := "17"
+ CASE 2, 102, 107: schrifttyp := "12"
+ CASE 3, 103, 108: schrifttyp := "10"
+ CASE 4, 104, 109: schrifttyp := "prop"
+ CASE 5, 105, 110: schrifttyp := "5"
+ OTHERWISE (* behalte alten Schrifttyp bei *)
+ END SELECT
+END PROC schrifttyp waehlen;
+
+
+Hätten wir diese Prozedur in unsere Prozedur 'zeilen formatieren' eingebunden, so
+zeigte sich bei Aktivierung folgende Einblendung in den Menubildschirm:
+
+
+
+ +---------------------------------------+
+ I I
+ I Auswahl der Schrifttypen: I
+ I I
+ I s ... schmal (17 Zeichen pro Zoll) I
+ I e ... elite (12 Zeichen pro Zoll) I
+ I p ... pica (10 Zeichen pro Zoll) I
+ I l ... letter (Proportionalschrift) I
+ I g ... groß ( 5 Zeichen pro Zoll) I
+ I I
+ I schmal elite pica letter groß I
+ I I
+ +---------------------------------------+
+
+Die Prozedur 'menualternative' besitzt insgesamt 5 Parameter. Wie Ihnen schon von
+von anderen Prozeduren bekannt ist, wird mit dem vorletzten (4.) Parameter die
+Position innerhalb des Menubildschirms bestimmt - hier also die Plazierung in die
+Mitte des Menubildschirms.
+Mit dem 5. Parameter können Sie noch festlegen, ob der Benutzer die Möglichkeit
+haben soll, die Alternativauswahl mit <ESC><h> abzubrechen (bei TRUE, wie im
+Beispiel) oder eben nicht.
+
+Mit dem 1. Parameter wird der Informationstext festgelegt, der auf dem Bildschirm
+innerhalb der Box erscheinen soll. Für die Funktion der Alternativauswahl ist die­
+ser Inhalt völlig belanglos - er dient ausschließlich der Information des Benutzers.
+Der Text kann - wie hier - z.B. durch eine Einteilung in Zeilen gestaltet werden
+(durch den Code "13").
+Der Text in den Zeilen sollte nicht zu breit sein, da er noch in eine Box innerhalb des
+Menubildschirms hineinpassen muß! Damit es auch bei geschachtelten Menus zu
+keinen Problemen kommt, sollte eine Zeile nicht breiter als 64 Zeichen sein. Aber
+keine Angst: Sie können gs-DIALOG durch zu lange Texte nicht durcheinanderbrin­
+gen - wenn Ihr Text zu breit ist, wird er rigoros abgeschnitten und einfach nicht
+angezeigt.
+
+Mit dem 2. Parameter übergeben Sie die Auswahlliste, die in der letzten Zeile der Box
+dargestellt wird. Hier dürfen insgesamt bis zu 10 Alternativen angegeben werden -
+bedenken Sie dabei aber unbedingt, daß diese Liste ebenfalls nicht zu lang werden
+darf (ebenfalls höchstens 64 Zeichen).
+Zwischen jeder von Ihnen notierten Alternative muß zur Kennung der Code "13"
+eingetragen werden - wie oben im Beispiel gezeigt. Da nachher in der Box zwischen
+den einzelnen Alternativen je drei Leerzeichen eingefügt werden, können Sie sich
+immer an der von Ihnen übergebenen Zeichenkette orientieren. Hat Ihre Auswahlliste
+nicht mehr als 64 Zeichen, dann ist sie in jedem Falle auf dem Bildschirm darstell­
+bar.
+Über diese Auswahlliste erfolgt normalerweise die Auswahl. Mit den Cursortasten links
+und rechts kann der Benutzer auf die gewünschte Alternative positionieren (auf dem
+Bildschirm invers dargestellt) und dann die <RETURN>-Taste tippen.
+Die Prozedur 'menualternative liefert dann einen Zahlenwert, nämlich die Position
+der gewählten Alternative in der als 2. Parameter übergebenen Liste (wird in unse­
+rem Beispiel die Alternative 'letter' gewählt, so liefert die Prozedur den Wert 4).
+Haben Sie den Abbruch durch <ESC><h> zugelassen (5. Parameter), so wird im
+Falle eines solchen Abbruchs der Wert '0' geliefert.
+
+Mit dem 3. Parameter können Sie noch festlegen, über welche Tasten eine Auswahl
+erfolgen soll. Wenn Sie hier niltext ("") angeben, ist eine Auswahl über die Tasten
+nicht möglich. Im Beispiel haben wir hier die Anfangsbuchstaben der im Text ge­
+nannten Schrifttypen gewählt und als Eingabe sowohl Klein- als auch Großbuchsta­
+ben gestattet. Erfolgt nun die Auswahl über das Tippen einer zugelassenen Taste,
+dann wird Ihre Position in der im 3. Parameter übergebenen Zeichenkette ermittelt
+und der Wert '100' dazuaddiert. Tippt in unserem Falle der Benutzer die Taste
+<L>, wird der Wert '109' geliefert.
+
+Es erfolgt übrigens kein Hinweis in der Fußzeile, ob eine Auswahl über das Tippen
+einer Taste möglich ist! Wenn Sie von der Möglichkeit Gebrauch machen, sollten Sie
+dieses durch die Gestaltung Ihres Informationstextes andeuten - wie wir es im Bei­
+spiel auch getan haben.
+
+
+#ib#5.8 Die Menunotiz#ie# ('#ib#write menunotice#ie#', '#ib#erasemenunotice#ie#')
+
+Innerhalb des Menus können Sie für den Benutzer auch eine Notiz ablegen. Wir
+machen z.B. bei der Archivverwaltung Gebrauch davon. Dort wird nämlich ständig
+angezeigt, mit welcher Task kommuniziert wird und - sofern es sich um einen Ar­
+chivmanager handelt - wie die (angemeldete) Diskette heißt. Wenn Sie z.B. dem
+Benutzer das aktuelle Datum im Menu anzeigen wollen, insertieren Sie die folgende
+Prozedur:
+
+
+PROC datum anzeigen:
+ write menunotice ("Datum: " + date, 4)
+END PROC datum anzeigen;
+
+
+Die Prozedur 'write menunotice' besitzt zwei Parameter. Mit dem ersten Parameter
+wird der Text übergeben, der in der Box ausgegeben werden soll. Er unterliegt eben­
+falls der gs-DIALOG-Syntax für Texte. Durch den zweiten Parameter wird wieder die
+Position innerhalb des Menus festgelegt (hier rechts unten: Position 4).
+
+Wenn Sie jetzt in Ihrer Menukarte die Prozedur 'oberbegriff  ("Bearbeiten")' in fol­
+gender Weise abändern:
+
+
+ oberbegriff ("Bearbeiten", "datum anzeigen", "erase menunotice")
+
+
+dann wird jedesmal, wenn das Pull-Down-Menu unter dem Oberbegriff 'Bearbeiten'
+aufgefaltet wird, unten rechts (Position 4) das aktuelle Datum in einer Box ange­
+zeigt. Diese Notiz verschwindet, wenn in ein anderes Pull-Down-Menu gewechselt
+wird.
+
+Auf den ersten Eindruck scheinen die Prozeduren 'write menunotice' und 'menuinfo'
+gleich zu sein - das ist aber nicht der Fall: Bei 'menuinfo' wird der Text in einer Box
+ausgegeben und so lange gewartet, bis der Benutzer eine Taste getippt hat (oder die
+angegebene Zeit verstrichen ist). Bei 'write menunotice' wird ebenfalls ein Text in
+einer Box auf den Menubildschirm geschrieben. Diese Box bleibt aber über längere
+Zeit bestehen (auf Erscheinen und Verschwinden kann der Benutzer selbst keinen
+Einfluß nehmen!) - und zwar solange, bis die Notiz gelöscht wird (mit 'erase menu­
+notice'; in unserem Beispiel, wenn das Pull-Down-Menu gewechselt wird) oder durch
+ein neues 'write menunotice' überschrieben wird. In einem Menu kann nämlich zu
+einem Zeitpunkt nur eine Menunotiz abgelegt werden.
+Wenn der Bildschirm durch gs-DIALOG-Prozeduren überschrieben wird, wird die
+Menunotiz ebenfalls ständig mitaufgefrischt, und auch, wenn Sie den Befehl 'regene­
+rate menuscreen' oder 'refresh submenu' geben.
+
+
+#ib#5.9 Fußzeilen im Menu#ie# ('#ib#menufootnote#ie#', '#ib#oldmenufootnote#ie#')
+
+In den Fußzeilen innerhalb des Menus werden dem Benutzer Bedienhinweise ange­
+zeigt. Die Fußzeile wird aber auch dazu benutzt, den Benutzer über Prozesse zu
+informieren, die im Hintergrund ablaufen - erst recht dann, wenn Sie einige Zeit in
+Anspruch nehmen. Sie zeigen dem Benutzer an, daß er nicht "unruhig" zu werden
+braucht, sondern das System "mit sich" beschäftigt ist.
+Im allgemeinen braucht sich der Programmierer um diese Fußnoten nicht zu küm­
+mern, denn sie werden von den einzelnen Komponenten des Systems automatisch
+gesetzt. Wir können aber z.B. dem Benutzer einen Hinweis geben, wenn unter dem
+Menupunkt 'Verzeichnis' eine Liste erstellt wird. Die Prozedur könnte dann folgen­
+dermaßen notiert werden:
+
+
+PROC verzeichnis ausgeben:
+ menufootnote ("Bitte warten... Ich erstelle eine Dateiliste");
+ FILE VAR f :: sequential file (output, "Dateiliste");
+ list (f); modify (f);
+ old menufootnote;
+ entferne eigenen namen;
+ zeige liste an;
+ forget ("Dateiliste", quiet).
+
+ entferne eigenen namen:
+ TEXT VAR zeile :: ""; INT VAR i;
+ FOR i FROM lines (f) DOWNTO 1 REP
+ to line (f, i);
+ read record (f, zeile);
+ UNTIL pos (zeile, "Dateiliste") > 0 PER;
+ delete record (f).
+
+ zeige liste an:
+ to line (f, 1);
+ menuwindowshow (f) (* Sehen Sie Kapitel 5.11.1*)
+END PROC verzeichnis ausgeben;
+
+
+Beachten Sie, daß der Text nicht länger als 64 Zeichen ist, damit er auch bei ge­
+schachtelten Menus vollständig ausgegeben werden kann. Sollte der Text dennoch zu
+lang sein, wird er vom System auf die entsprechende Länge gestutzt.
+Haben Sie mit 'menufootnote' eine eigene Fußzeile gesetzt, so können Sie die da­
+durch gelöschte Zeile durch den Befehl 'old menufootnote' wieder hinschreiben.
+Ansonsten wird Ihre Fußzeile von der nächsten automatisch (d.h. vom System) ge­
+setzten Fußnote überschrieben. In dem obigen Beispiel hätten Sie also gut auf den
+Befehl 'old menufootnote' verzichten können.
+
+Durch 'old menufootnote' wird die letzte Fußnote, die automatisch vom System ge­
+setzt wurde, reproduziert. Der in der obigen Prozedur verwendete Befehl 'menuwin­
+dowshow' ist bisher noch nicht erläutert. Sehen Sie dazu bitte das Kapitel 5.11.1.
+
+
+#ib#5.10 Wiederherstellung des Menubildschirms#ie# ('#ib#regenerate
+ menuscreen#ie#','#ib#refresh submenu#ie#')
+
+Der Befehl 'regenerate menuscreen' ist Ihnen schon aus diversen Beispielprogram­
+men dieses Handbuches bekannt. Ist der Menubildschirm "kaputtgeschrieben" oder
+der Bildschirm für andere Zwecke benutzt worden, so läßt sich durch diesen Befehl
+der Menubildschirm in seinem letzten Zustand reproduzieren (auch bei geschachtel­
+ten Menus!). Durch den Befehl wird der Bildschirm gelöscht und komplett neu
+aufgebaut.
+
+Ein vollständiger Bildschirmaufbau ist aber gar nicht immer nötig. Wenn Sie sicher
+sind, daß durch Ihre Operationen nur der Bereich zwischen den beiden durchgezo­
+genen Linien, die die Kopf- und Fußzeile abtrennen, betroffen ist, brauchen Sie nur
+den Befehl 'refresh submenu' zu geben. Hierdurch wird das aktuelle Pull-Down-
+Menu neu aufgebaut und - sofern gesetzt - die Menunotiz. Wenn möglich, ist er dem
+Befehl 'regenerate menuscreen vorzuziehen, da hierfür weniger Zeit benötigt wird
+und weniger "Unruhe" auf dem Bildschirm entsteht.
+Sorgen Sie aber unbedingt dafür, daß der von Ihnen benutzte Bildschirmbereich
+zuvor "gereinigt" wird, denn das besorgt 'refresh subnmenu' nicht!
+
+
+#ib#5.11 Arbeiten im Menufenster#ie#
+
+Neben den vorab aufgezeigten Möglichkeiten können Sie innerhalb des Menus auch
+noch ein Fenster öffnen. Innerhalb dieses Fensters stehen Ihnen alle Möglichkei­
+ten zur Verfügung, die Sie auch sonst zum Beschreiben des gesamten Bildschirms
+haben - und noch einiges mehr.
+Wir machen z.B. intensiv beim Archivhandling Gebrauch davon. So werden Ihnen
+Verzeichnisse angezeigt, Sie können verfolgen, wie die einzelnen Dateien vom Archiv
+geholt werden oder dorthin geschrieben werden und einiges mehr. In diesem Kapitel
+wollen wir Ihnen die Möglichkeiten aufzeigen, die Sie innerhalb des Menufensters
+haben.
+
+Auf die Größe des Menufensters haben Sie keinen Einfluß, sie wird vom System ge­
+setzt ("normales" Menu: 77 Zeichen breit und 20 Zeichen hoch; geschachteltes
+Menu: 71 Zeichen breit und 16 Zeichen hoch). Hierdurch ist sichergestellt, daß alle
+Operationen auch in geschachtelten Menus ohne Probleme ausführbar sind. Alle
+Prozeduren, die sich auf Aktionen im Menufenster beziehen, enthalten die Silbe
+'menuwindow'.
+Sie können mit den hier beschriebenen Prozeduren ähnlich arbeiten, wie mit den
+entsprechenden Prozeduren ohne den Wortbestandteil 'menuwindow' auf dem
+ganzen Bildschirm. Allerdings gibt es einige Unterschiede, auf die Sie achten sollten!
+
+
+5.11.1 Datei anzeigen/editieren
+ ('#ib#menuwindowshow#ie#', '#ib#menuwindowedit#ie#')
+
+Von der Prozedur 'menuwindowshow (FILE VAR f)' haben wir im letzten Kapitel
+schon Gebrauch gemacht, um das Verzeichnis der Dateien in der Task innerhalb des
+Menus anzuzeigen. Die Prozedur gibt es in zwei Versionen mit je einem Parameter.
+Einmal kann, wie im vorigen Kapitel, ein FILE angegeben werden, andererseits kann
+auch der Name der anzuzeigenden Datei als Text übergeben werden ('menuwindow­
+show (TEXT CONST dateiliste)'). Durch den Befehl wird innerhalb des Menus ein
+umrandetes Fenster geöffnet, in der das angegebene File/die Datei angezeigt wird. Bei
+'menuwindowshow' kann die Datei nur eingesehen, nicht aber schreibend verändert
+werden.
+Die Prozedur 'menuwindowedit' gibt es ebenfalls in den zwei Ausprägungen. Sie
+verhält sich zur vorgenannten identisch - nur kann hier auch die Datei schreibend
+verändert werden.
+
+
+5.11.2 Menufenster öffnen/anzeigen ('#ib#show menuwindow#ie#')
+
+Wenn Sie eigene Operationen in einem Fenster im Menu ausführen lassen wollen,
+muß dieses Fenster zunächst auf dem Bildschirm angezeigt werden. Durch den
+Befehl 'show menuwindow' wird ein entsprechender Rahmen innerhalb des Menus
+ausgegeben und der Bereich innerhalb dieses Rahmens (das Fenster) gelöscht.
+Auf die Größe des Fensters innerhalb des aktuellen Menus können Sie - wie bereits
+eingangs gesagt - keinen Einfluß nehmen.
+Zu einem Zeitpunkt kann immer nur ein Menufenster geöffnet sein, da das Fenster
+schon den größtmöglichen sinnvollen Bereich des aktuellen Menus belegt. Ein er­
+neutes 'show menuwindow' hätte die gleiche Wirkung wie das nachfolgend beschrie­
+bene 'menuwindowpage' - nur wird hier zusätzlich noch der Rahmen des Fensters
+mitausgegeben.
+
+
+5.11.3 Menufenster löschen (putzen) ('#ib#menuwindowpage#ie#')
+
+Durch den Befehl 'menuwindowpage' wird das Fenster innerhalb des aktuellen
+Menus gelöscht; der Rahmen des Fensters bleibt bestehen, da er nicht mit zum ei­
+gentlichen Fenster gehört. Durch den Befehl wird der Menubildschirm nicht(!)
+rekonstruiert!
+
+
+5.11.4 Positionierungen im Menufenster
+ ('#ib#menuwindowline#ie#', '#ib#menuwindowcursor#ie#')
+
+Mit 'menuwindowline' wird, wie auch sonst auf dem Bildschirm, an den Anfang der
+nächsten Zeile positioniert. Diesen Befehl gibt es, ebenso wie den Befehl 'line' (der
+auf dem Gesamtbildschirm operiert) ohne und mit einem Parameter. Durch 'menu­
+windowline (3)' wird an den Anfang der "drittnächsten" Zeile innerhalb des Menu­
+fensters positioniert.
+
+Aber Achtung! Der Befehl 'menuwindowline' weist einen deutlichen Unterschied zum
+Ihnen bekannten Befehl 'line' auf. Wird nämlich die untere Fenstergrenze überschrit­
+ten, so rollt (scrollt) der Bildschirm nicht um die entsprechenden Zeilen nach oben,
+wie Sie es von 'line' gewohnt sind - statt dessen wird der Fensterinhalt gelöscht und
+wieder oben im Fenster zu schreiben begonnen. Es erscheint, als ob auf ein neues
+Fenster positioniert würde.
+Innerhalb des Fensters können Sie auch den Cursor positionieren, wie Sie es vom
+Bildschirm gewohnt sind - allerdings nur innerhalb der aktuell gültigen Grenzen. In
+einem Menu ist das Fenster 77 Zeichen breit und 20 Zeichen hoch; in einem ge­
+schachtelten Menu 71 Zeichen breit und 16 Zeichen hoch.
+Wird außerhalb des aktuellen Menufensters positioniert, wird das Fenster gelöscht
+und die Fensterposition (1, 1) angenommen.
+
+
+5.11.5 Informationen über die aktuelle Menu-Fenster position ('#ib#get
+menuwindowcursor#ie#', '#ib#remaining menuwindowlines#ie#')
+
+Mit der Prozedur 'get menuwindowcursor (INT VAR spalte, zeile)' kann die aktuelle
+Position des Cursors innerhalb des Menufensters erfragt werden. Die Prozedur hat
+zwei Parameter, die als 'INT VAR' deklariert sein müssen. Der erste Parameter enthält
+anschließend die aktuelle Spalte, der zweite die aktuelle Zeile.
+
+Mit der werteliefernden Prozedur 'remaining menuwindowlines' kann die Anzahl der
+noch verbleibenden Zeilen innerhalb des aktuellen Menufensters erfragt werden. Die
+Prozedur wurde deshalb zur Verfügung gestellt, weil der Fensterinhalt - im Gegensatz
+zum normalen Bildschirm - nicht gescrollt werden kann. So können Sie sich vorab
+informieren, ob der Text, der von Ihnen ausgegeben werden soll, noch Platz findet, so
+daß während der Ausgabe nicht plötzlich der Fensterinhalt gelöscht wird.
+
+
+5.11.6 Ausgabe/Eingabe innerhalb des Menufensters
+ ('#ib#menuwindowout#ie#', '#ib#menuwindowget#ie#',
+ '#ib#menuwindoweditget#ie#', '#ib#menuwindowyes#ie#',
+ '#ib#menuwindowno#ie#')
+
+Innerhalb des Menufensters können mit der Prozedur 'menuwindowout' Texte ausge­
+geben werden - die Prozedur hat einen TEXT-Parameter. Sollen INTEGER- oder REAL-
+Werte ausgegeben werden, so müssen diese Werte zuerst in Texte konvertiert werden.
+Bitte beachten Sie unbedingt, daß innerhalb des Fensters nicht gescrollt wird und
+auch kein Zeilenumbruch stattfindet! Ist ein Text länger als die verbleibende Restzei­
+le, so wird der Text bis zum Fensterende ausgegeben und die Ausgabe am Anfang der
+nächsten Zeile fortgesetzt. So ist sichergestellt, daß in keinem Falle die Fenstergren­
+zen überschritten werden.
+Sobald die letzte Position des aktuellen Menufensters beschrieben ist (unten rechts in
+der Fensterecke), wird der Fensterinhalt komplett gelöscht und die Ausgabe in der
+ersten Zeile des "neuen" Fensters fortgesetzt. Auf Zeilenumbruch und Scrolling wurde
+verzichtet, da der Realisierungsaufwand dafür zu hoch gewesen wäre.
+
+Mit der Prozedur 'menuwindowget (TEXT VAR text)' können Sie auch Texte innerhalb
+des Menufensters einlesen - INTEGER-/ REAL-Werte müssen ggf. von Hand konvertiert
+werde. Die Eingabe wird durch <RETURN> abgeschlossen. Es muß mindestens ein
+Zeichen (ungleich Leerzeichen) eingegeben werden. Von der Eingabe werden die
+führenden Leerzeichen abgeschnitten.
+Ist der einzugebende Text länger als die noch verbleibende Restzeile, so wird der Text
+in der Restzeile gescrollt. Sind in der aktuellen Zeile weniger als 7 Zeichen für die
+Eingabe vorhanden, so wird automatisch für die Eingabe an den Anfang der nächsten
+Zeile positioniert.
+
+Ab gs-DIALOG-Version 1.1 steht auch die Prozedur 'menuwindoweditget (TEXT VAR
+text)' zur Verfügung, durch die ein Text zum Editieren vorgegeben werden kann. Es
+ist allerdings darauf zu achten, daß der Text in jedem Falle initialisiert wird!
+
+Die beiden Prozeduren 'menuwindowyes' und 'menuwindowno' ähneln den Ihnen
+bekannten Prozeduren 'yes' und 'no'. Sie operieren nur auf dem Menufenster. Be­
+denken Sie aber bitte, daß, wenn bei der Ausgabe des Textes die Fenstergrenze über­
+schritten wird, der Resttext in der nächsten Zeile ausgegeben wird. Wird dabei sogar
+die untere Fenstergrenze überschritten, so wird der komplette Fensterinhalt gelöscht
+und die Ausgabe in der linken oberen Ecke des "neuen Fensters" fortgesetzt!
+
+
+5.11.7 Weiter Prozeduren ('#ib#menuwindowcenter#ie#',
+ '#ib#menuwindowstop#ie#')
+
+Es werden noch zwei weitere Prozeduren für das Menufenster zur Verfügung gestellt,
+die bei der Programmentwicklung ganz nützlich sein können.
+Mit 'menuwindowcenter (TEXT CONST text)' werden vor und hinter dem übergebe­
+nen Text so viele Leerzeichen angefügt, daß der Text zentriert in der Menufenster-Zei­
+le ausgegeben wird. Bevor Sie den Text mit 'menuwindowout' ausgeben, müssen Sie
+an den Anfang einer Zeile positionieren, denn die Anzahl der vorangestellten Blanks
+wird unter Annahme dieser Zeilenposition ermittelt! Innerhalb der Zeile werden ggf.
+vorhandene Texte überschrieben.
+
+Durch die Prozedur 'menuwindowstop' wird an den Anfang der übernächsten Zeile
+positionert und der Text 'Zum Weitermachen bitte irgendeine Taste tippen!' ausgege­
+ben. Danach wird so lange gewartet, bis eine Taste getippt wird. Mit 'menuwindow­
+stop (INT CONST zeilenzahl) kann auch noch die Anzahl der Zeilen bestimmt wer­
+den, die vorwärtspositioniert werden soll (Standard: 2 Zeilen).
+
+
+#ib#5.12 Festlegung der Boxpositionen innerhalb des Menus#ie#
+
+In vielen Fällen kann der Programmierer noch entscheiden, an welcher Position
+innerhalb des Menus die Box erscheinen soll (z. B. bei 'menuanswer', 'menuinfo',
+'menuyes', 'menuno', 'menunotice' etc.). Die Positionen sind von 1 bis 5 durchnu­
+meriert und haben folgende Bedeutung:
+
++----------------------------------------+
+I I
++----------------------------------------+
+I I
+I +-----+ +-----+ I
+I I 1 I I 2 I I
+I +-----+ +-----+ I
+I I
+I +-----+ I
+I I 5 I I
+I +-----+ I
+I I
+I +-----+ +-----+ I
+I I 3 I I 4 I I
+I +-----+ +-----+ I
+I I
++----------------------------------------+
+I I
++----------------------------------------+
+#page#
+#ib#5.13 gs-DIALOG-Syntax (Regeln zur Erstellung von Texten)#ie#
+
+Werden Texte als Parameter übergeben, die in einer Box ausgegeben werden sollen,
+so kann dieser Text durch Einfügen von Steuerzeichen noch gestaltet werden, z.B.
+kann der Programmierer so den Zeilenaufbau bestimmen.
+Das System analysiert den eingegebenen Text. Jedesmal, wenn innerhalb des Textes
+der Code "13" erscheint, wird innerhalb der Box auf den nächsten Zeilenanfang
+positioniert. So ist eine Einteilung eines Textes in Zeilen leicht möglich. Soll eine
+Leerzeile eingefügt werden, so geben Sie einfach zweimal den Code "13" ("13""13").
+Bei der Textanalyse wird die jeweilige Zeilenlänge vermerkt. Die Box wird vom System
+gerade so breit gewählt, daß die längste vorkommende "Zeile" im Text gerade noch in
+die Box paßt.
+Aber Vorsicht! Die jeweilige Box kann innerhalb des Menus nur eine Maximalgröße
+annehmen (64 Zeichen breit und 14 Zeilen hoch). Wird von einer "Zeile" diese
+Maximalgröße überschritten, so wird die Zeile abgeschnitten und nur bis zur Maxi­
+malbreite der Box ausgegeben.
+
+Ein Text für eine solche Box könnte z.B. so aussehen:
+
+
+menuinfo (" Informationstexte "13" sind meist"13" zu
+lang!")
+
+
+das ergibt folgende Ausgabe in der Box:
+
+
+ +-----------------------+
+ I I
+ I Informationstexte I
+ I sind meist I
+ I zu lang I
+ I I
+ +-----------------------+
+
+Es ist auch möglich, in solchen Texten Textpassagen invers darzustellen. Dazu wer­
+den in den Text die Codes zum Ein- ("15") und Ausschalten ("14") der Markierung
+eingefügt. Solche markierten Textpassagen dürfen aber nicht über interne Zeilen­
+grenzen (Code "13") hinausgehen. Sie müßten dann am Zeilenende aus- und am
+nächsten Zeilenanfang wiedereingeschaltet werden.
+Soll in der obigen Box das Wort 'Informationstexte' invers dargestellt werden, so wäre
+z.B. folgendes Kommando zu geben:
+
+
+menuinfo (" "15"Informationstexte"14" "13"" +
+ " sind meist"13" zu lang!")
+
+
+#ib#5.14 Thesaurushandling#ie#
+
+Neben den allgemein zur Verfügung gestellten Thesaurusoperationen stellt
+gs-DIALOG einige weitere bereit. Mit der Prozedur 'THESAURUS PROC #ib#infix namen#ie#
+(THESAURUS CONST thes, TEXT CONST infix)' werden aus allen Dateinamen des
+angegebenen Thesaurus die herausgefiltert, die den Wortbestandteil 'infix' enthalten -
+und zwar gleichgültig, an welcher Position! Die herausgefilterten Dateinamen werden
+in einem Thesaurus geliefert. Im Programmsystem 'gs-Herbert und Robbi' mach­
+en wir z.B. Gebrauch davon, wenn wir nur die Landschaften der eigenen Task zur
+Auswahl anbieten wollen:
+
+
+THESAURUS VAR thes :: infix namen (ALL myself, "Flaeche:")
+
+
+Daneben gibt es eine ähnliche Prozedur, mit der man die Dateien eines bestimmten
+Dateityps herausfiltern kann. Mit
+
+
+THESAURUS VAR thes :: infix namen (ALL myself, 1003)
+
+
+werden alle Dateien mit dem Typ '1003' (normale Textfiles) herausgefiltert. Neben
+den beiden gibt es auch noch eine Prozedur, die beide Fälle miteinander koppelt:
+
+
+THESAURUS VAR thes :: infix namen (ALL myself, "gs-MENUKARTE:", 1954)
+
+
+Mit der folgenden Prozedur:
+
+
+THESAURUS VAR thes :: #ib#ohne praefix#ie# (ALL myself, "Flaeche:")
+
+
+wird aus den Dateinamen im angegebenen Thesaurus jeweils der führende Wortbe­
+standteil entfernt. Wir machen z.B. in gs-Herbert und Robbi davon Gebrauch, um
+die Landschaften/Arbeitsfelder anbieten zu können, ohne jeweils den Wortbestandteil
+'Flaeche:' miterscheinen zu lassen.
+
+Ganz nützlich ist auch noch die folgende Informationsprozedur '#ib#not empty#ie#
+(THESAURUS CONST thes)', mit der man z.B. feststellen kann, ob eine Auswahl ohne
+Ankreuzen oder mit <ESC><h> abgebrochen wurde:
+
+
+
+PROC zeilen formatieren:
+ TEXT CONST kopf :: "Textdateien zeilenweise formatieren",
+ hinweis :: "Bitte gewünschte Dateien ankreuzen";
+ THESAURUS VAR dateinamen := menusome (ALL myself, kopf, hinweis,
+ FALSE);
+
+ IF not empty (dateinamen)
+ THEN cursor on;
+ formatiere dateien;
+ cursor off;
+ FI;
+ regenerate menuscreen.
+
+ formatiere dateien:
+ INT VAR zaehler;
+ FOR zaehler FROM 1 UPTO highest entry (dateinamen) REP
+ IF name (dateinamen, zaehler) <> ""
+ THEN lineform (name (dateinamen, zaehler))
+ FI
+ PER
+END PROC zeilen formatieren;
+
+
+
+#ib#5.15 Aktivieren und Deaktivieren von Menupunkten#ie#
+
+Daß Verarbeitungsfunktionen aktiviert und deaktiviert werden können, haben Sie
+schon in unserem Archiv-Pull-Down-Menu gesehen. Deaktivierte Menupunkte sind
+durch ein vorgestelltes '-'-Zeichen gekennzeichnet; diese Menufunktionen werden
+übersprungen, wenn Sie versuchen, darauf zu positionieren.
+
+Zur Aktivierung und Deaktivierung von Menupunkten stehen die Prozeduren '#ib#activate#ie#
+(TEXT CONST menupunktname)' und '#ib#deactivate#ie# (TEXT CONST menupunktname)'
+zur Verfügung. Zu beachten ist, daß diese Prozeduren nicht ständig aufrufbar sind -
+der jeweils angegebene 'menupunktname' muß sich nämlich auf das aktuelle Pull-
+Down-Menu beziehen! Als Menupunktname muß jeweils der Name angegeben wer­
+den, der bei der entsprechenden Menufunktion als 2. Parameter übergeben wurde.
+Ist der angegebene 'menupunktname' im aktuellen Pull-Down-Menu nicht enthalten,
+so wird die Anweisung ignoriert!
+
+Auch bei den Prozeduren' activate (INT CONST punktnummer)' und 'deactivate (INT
+CONST punktnummer)' gilt diese Einschränkung. Die beiden Prozeduren arbeiten
+schneller als die eben aufgezeigten, denn es muß im aktuellen Pull-Down-menu
+nicht mehr nach der jeweiligen Position gesucht werden. Die Positionen werden von
+oben nach unten durchgezählt. Beachten Sie aber unbedingt, daß die Trennlinien
+mitgezählt werden müssen!
+Die Prozeduren "zeigen nur dann Wirkung", wenn sie von einer Verarbeitungsfunk­
+tion des aktuell entfalteten Pull-Down-Menus aus aufgerufen werden (das geschieht
+im Archivmenu z.B. aus den beiden Menufunktionen 'Reservieren' und 'Initialisieren'
+heraus) oder wenn Sie beim Einstieg in ein Pull-Down-Menu bzw. beim Ausstieg
+daraus aufgerufen werden; d.h. aus einer Prozedur heraus, die bei 'oberbegriff' als
+2./3. Parameter in das Menukarten-Generierungsprogramm eingetragen ist. Beim
+Archiv-Pull-Down-Menu besorgt das die Prozedur 'menu archiv grundeinstellung'
+(sehen Sie dazu auch Kapitel 6.1).
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.6 b/doc/menugenerator/menu-generator handbuch.6
new file mode 100644
index 0000000..a0dd3b5
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.6
@@ -0,0 +1,235 @@
+#block##pageblock#
+#pagenr("%",1)##setcount(1)##count per page#
+#headeven#
+gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#right#gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+6 - % #right#ERGOS
+#end#
+#bottomodd#
+#center#____________________________________________________________
+ERGOS #right# 6 - %
+#end#
+#ib#6  Einbinden der Datei- und Archivoperationen#ie#
+
+
+Sie haben bereits erfahren, wie Sie eine Menukarte generieren und ankoppeln kön­
+nen. Im letzten Kapitel haben wir Ihnen die Möglichkeiten aufgezeigt, innerhalb des
+Menus einen Dialog mit dem Benutzer zu führen. Sie sind somit in der Lage, Ihre
+eigenen Anwendungen unter der Benutzeroberfläche gs-DIALOG zu erstellen.
+Wie sich gezeigt hat, treten eine Reihe von Verarbeitungsfunktionen in nahezu jeder
+Anwendung auf. Im EUMEL-System benötigt man bei fast allen Anwendungspro­
+grammen auch die Möglichkeiten, Dateien auf dem Archiv zu sichern oder von dort
+zu holen; auch Umbenennen, Kopieren, Drucken, Reorganisieren ... von Dateien
+zählen sicher zu den häufig benötigten Verarbeitungsfunktionen. Wünschenswert ist
+es natürlich, daß in allen Programmen unter einer Benutzeroberfläche die "Stan­
+dard-Verarbeitungsfunktionen" in immer gleicher Weise zur Verfügung stehen!
+
+Dieser Vorteil liegt sogar nicht nur auf der Seite des Anwenders - auch der Anwen­
+dungsprogrammierer profitiert davon: Dann nämlich, wenn er diese Standard-Verar­
+beitungsfunktionen nicht immer neu schreiben muß, sondern auf vorgefertigte
+Prozeduren und natürlich auch auf die zugehörigen Informationstexte zurückgreift.
+
+Wir haben uns deshalb entschlossen, diese Standard-Verarbeitungsfunktionen zum
+Datei- und Archivhandling bereits in das Basissystem gs-DIALOG zu integrieren und
+Ihnen mit gs-Menu-Generator Dateien zur Verfügung zu stellen, in denen die
+Programme zur Einbindung dieser Prozeduren in Ihre eigenen Programmsysteme
+ebenso enthalten sind wie alle dazugehörigen Informationstexte.
+In diesem Kapitel soll nun beschrieben werden, wie Sie diese vorgefertigten Module in
+Ihre Menukarten/Programme einbinden können und was Sie dabei beachten müs­
+sen.
+
+
+#ib#6.1 Einbinden der Archivoperationen#ie#
+
+Auf der von uns gelieferten Diskette 'gs-Menu-Generator', befindet sich auch die
+Datei 'Generatordatei: Archivmenu'. Darin ist das vollständige Menukarten-Generie­
+rungs-Programm zur Generierung der Menukarte 'gs-MENUKARTE: Archiv' inclusive
+aller Informationstexte enthalten. U.a. befindet sich darin eben das folgende Pro­
+gramm:
+
+
+oeffne menukarte ("Archiv");
+oeffne menu ("ARCHIV", "", "menu archiv reservierung aufgeben");
+
+
+oberbegriff ("Dateien");
+
+menufunktion ("v", "Verzeichnis", "menu dateien verzeichnis",
+ dateiverzeichnistext);
+trennlinie;
+menufunktion ("l", "Löschen", "menu dateien loeschen",
+ dateiloeschentext);
+menufunktion ("d", "Drucken", "menu dateien drucken",
+ dateidruckentext);
+trennlinie;
+menufunktion ("k", "Kopieren", "menu dateien kopieren",
+ dateikopierentext);
+menufunktion ("u", "Umbenennen", "menu dateien umbenen­
+ nen",
+ dateiumbenennentext);
+trennlinie;
+menufunktion ("s", "Speicherplatz", "menu dateien speicherplatz",
+ dateispeicherplatztext);
+menufunktion ("a", "Aufräumen", "menu dateien aufraeumen",
+ dateiaufraeumtext);
+
+
+oberbegriff ("Archiv", "menu archiv grundeinstellung (4)",
+ "menu archiv reservierung aufgeben");
+
+menufunktion ("r", "Reservieren", "menu archiv reservieren",
+ archivreserviertext);
+menufunktion ("n", "Neue Diskette", "menu archiv neue diskette",
+ neuediskettetext);
+trennlinie;
+menufunktion ("s", "Schreiben", "menu archiv schreiben",
+ archivschreibtext);
+menufunktion ("c", "Checken", "menu archiv checken",
+ archivchecktext);
+menufunktion ("k", "Kombination", "menu archiv schreibcheck",
+ archivkombinationstext);
+menufunktion ("h", "Holen/Lesen", "menu archiv holen",
+ archivholtext);
+menufunktion ("l", "Löschen", "menu archiv loeschen",
+ archivloeschtext);
+trennlinie;
+menufunktion ("v", "Verzeichnis", "menu archiv verzeichnis",
+ archivverzeichnistext);
+menufunktion ("d", "Drucken", "menu archiv verzeichnis
+ drucken",
+ archivdruckentext);
+trennlinie;
+menufunktion ("i", "Initialisieren", "menu archivinitialisieren",
+ archivinitialisiertext);
+menufunktion ("z", "Zieltask einstellen", "menu archiv zieltask
+ einstellen",
+ archivzieltasktext);
+schliesse menu;
+schliesse menukarte;
+
+
+Wie schon oben erwähnt, sind auch alle Informationstexte in der Datei enthalten, die
+jeweils über den 4. Parameter der Prozeduren 'menufunktion' in die Menukarte
+eingebunden werden. Wir haben Sie hier nicht extra abgedruckt; Sie können ja die
+entsprechende Datei auf der Diskette einsehen!
+
+Zu dem Programm möchten wir jedoch noch einige wichtige Anmerkungen machen,
+damit Sie die entsprechenden Verarbeitungsfunktionen in Ihre Menukarte einbinden
+können.
+
+Wenden wir uns zunächst den Archivoperationen zu. gs-DIALOG stellt die folgenden
+Verarbeitungsfunktionen bereit:
+
+
+ PROC #ib#menu archiv reservieren#ie#,
+ PROC #ib#menu archiv neue diskette#ie#,
+ PROC #ib#menu archiv schreiben#ie#,
+ PROC #ib#menu archiv checken#ie#,
+ PROC #ib#menu archiv schreibcheck#ie#,
+ PROC #ib#menu archiv holen#ie#,
+ PROC #ib#menu archiv loeschen#ie#,
+ PROC #ib#menu archiv verzeichnis#ie#,
+ PROC #ib#menu archiv verzeichnis drucken#ie#,
+ PROC #ib#menu archiv initialisieren#ie#,
+ PROC #ib#menu archiv zieltask einstellen#ie#,
+
+
+Durch diese elf Prozeduren werden die entsprechenden Menufunktionen ausgeführt.
+
+Außerdem werden noch folgende Prozeduren bereitgestellt:
+
+
+ PROC #ib#menu archiv grundeinstellung#ie# (INT CONST ort)
+ PROC #ib#menu archiv reservierung aufgeben#ie#
+
+
+Diesen beiden Prozeduren sollten Sie bei der Einbindung der Archivfunktionen in
+Ihre Menukarten besondere Beachtung schenken. Wie Sie im Programm auf der Seite
+zuvor sehen, taucht die Prozedur 'menu archiv reservierung aufgeben' gleich zweimal
+auf: einmal als 3.Parameter der Prozedur 'oberbegriff' und einmal als 3.Parameter
+der Prozedur 'oeffne menu' - und das aus folgendem Grund:
+
+Wenn der Benutzer die Archivoperationen verläßt, dann sollte automatisch das Archiv
+freigegeben werden, um so - auch bei Multi-User-Betrieb - ein einwandfreies Archiv­
+handling zu gewährleisten. Nun kann der Benutzer das Pull-Down-Menu 'Archiv' aber
+eben auf zweierlei Weise verlassen: Einmal durch den Wechsel in ein anderes Pull-
+Down-Menu der gleichen Menukarte - oder aber er verläßt insgesamt das Menu. Im
+ersten Falle wird das Archiv abgemeldet, weil ja die als 3.Parameter bei 'oberbegriff'
+eingetragene Prozedur ausgeführt wird - im zweiten Falle, weil die als 3.Parameter
+bei 'oeffne menu' eingetragene Prozedur ausgeführt wird. Diese Eintragungen sollten
+Sie auf keinen Fall bei der Einbindung der Archivoperationen vergessen.
+
+Die Prozedur 'menu archiv grundeinstellung (INT CONST ort)' sollte bei den Archiv­
+operationen immer als 2. Parameter in der Prozedur 'oberbegriff' übergeben wer­
+den. Nur wenn diese Prozedur beim Entfallten des Archiv-Pull-Down-Menus ausge­
+führt wird, ist die einwandfreie Funktion des Archivsystems sichergestellt. Dadurch
+geschieht nämlich folgendes:
+
+ 1) Als Zieltask wird das Archiv der eigenen Station eingestellt - unabhängig
+ davon, mit welcher Einstellung das Menu zuvor verlassen wurde.
+
+ 2) Es wird die Zieltask auf dem Bildschirm angezeigt.
+
+ 3) Die entsprechenden Menupunkte werden aktiviert bzw. deaktiviert.
+
+ 4) Es wird festgelegt, an welcher Stelle innerhalb des Menus die Menunotiz zur
+ Anzeige der Zieltask (und ggf. des Archivnamens) ausgegeben wird.
+
+Im Programm oben ist hierfür die Position 4 (rechts unten in der Ecke) gewählt. Wir
+haben diese Festlegung deswegen so getroffen, weil das Archiv-Pull-Down-Menu
+ziemlich weit links auf dem Bildschirm erscheint (es sind nur zwei Oberbegriffe
+eingetragen!). So stören sich Archiv-Pull-Down-Menu und die Menunotiz nicht gegen­
+seitig. In unseren Anwendungssystemen 'gs-Herbert und Robbi' und
+'gs-MP-BAP' haben wir dagegen die Position '3' eingetragen, damit die Menunotiz
+unten links in der Ecke erscheint, weil das Archiv-Pull-Down-Menu ganz rechts auf
+dem Bildschirm entfaltet wird.
+
+Achtung! Uns ist es sehr, sehr wichtig, daß zumindest die Archivfunktionen in allen
+Anwendungen unter gs-DIALOG in gleicher Weise zur Verfügung gestellt werden. Um
+das sicherzustellen, sind die Funktionen so in gs-DIALOG integriert, daß das System
+nur dann reibungslos funktioniert, wenn Sie sich an die eben aufgezeigten Regeln für
+die Einbindung in Ihr Anwendungssystem halten! Für die korrekte Funktionsweise
+muß im Archiv-Pull-Down-Menu auch immer exakt die Reihenfolge (der Aufbau) der
+Verarbeitungsfunktionen eingehalten werden. Auch die Namen sollten immer gleich
+gewählt werden!
+
+Wir hoffen, daß Sie als Programmierer für diese doch etwas rigorose Maßnahme
+Verständnis haben - dafür versichern wir Ihnen, daß wir sehr viel Gedanken und
+Arbeit in die Konstruktion des Archivsystems investiert haben!
+
+Auf eine Einschränkung muß allerdings noch hingewiesen werden:Das Archiv-
+Pull-Down-Menu kann aus technischen Gründen nicht das erste, ganz links in einem
+Menu stehende sein; es kann frühestens unter dem zweiten Oberbegriff in das Menu
+aufgenommen werden! Es ist z.Z. nicht möglich, im ganz links stehenden Pull-
+Down-Menu deaktivierte Menupunkte zu behandeln.
+
+
+#ib#6.2 Einbinden der Dateiopertionen#ie#
+
+gs-DIALOG stellt neben den Archivoperationen standardmäßig auch einige Dateiope­
+rationen bereit. Folgende Prozeduren stehen zur Verfügung:
+
+
+ PROC #ib#menu dateien verzeichnis#ie#,
+ PROC #ib#menu dateien loeschen#ie#,
+ PROC #ib#menu dateien drucken#ie#,
+ PROC #ib#menu dateien kopieren#ie#,
+ PROC #ib#menu dateien umbenennen#ie#,
+ PROC #ib#menu dateien speicherplatz#ie#,
+ PROC #ib#menu dateien aufraeumen#ie#.
+
+
+Die Prozeduren bedürfen in Ihrer Wirkung sicher kaum einer Erklärung. Die Wir­
+kungsweise können Sie einfach ausprobieren, indem Sie die entsprechenden Ver­
+arbeitungsfunktionen im Archiv-Menu einfach einmal aktivieren.
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.7 b/doc/menugenerator/menu-generator handbuch.7
new file mode 100644
index 0000000..2e6f0ba
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.7
@@ -0,0 +1,367 @@
+#block##pageblock#
+#pagenr("%",1)##setcount(1)##count per page#
+#headeven#
+gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#right#gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+7 - % #right#ERGOS
+#end#
+#bottomodd#
+#center#____________________________________________________________
+ERGOS #right# 7 - %
+#end#
+#ib#7  Eigene Fenster und Fensteroperationen #ie#
+
+
+In Kapitel 5.11 haben wir Ihnen gezeigt, wie Sie innerhalb des Menus ein Fenster
+(das Menufenster) öffnen können. Innerhalb dieses Bereichs stehen Ihnen die
+wesentlichen Ein- und Ausgabeoperationen zur Verfügung, die Sie auch sonst vom
+Bildschirm her kennen. Auf die Größe des Menufensters können Sie allerdings keinen
+Einfluß nehmen, da die Fenstergröße automatisch vom System (gs-DIALOG) festge­
+legt wird - je nachdem, ob Sie mit einem Menu oder mit geschachtelten Menus
+arbeiten.
+Auf die Einschränkungen bzw. Abweichungen gegenüber den Möglichkeiten, die Sie
+bei Benutzung des ganzen Bildschirms haben, haben wir Sie ausdrücklich hingewie­
+sen: So ist es nicht möglich, den Text innerhalb eines Fensters zu rollen (scrolling);
+statt dessen wird bei Überschreiten der unteren Fenstergrenze der Fensterinhalt
+gelöscht und die Ausgabe oben im "neuen" Fenster fortgesetzt.
+Als wir gs-DIALOG konzipierten und die ersten Anwendungen unter dieser Benutzer­
+schnittstelle entwarfen, fiel uns auf, daß es sehr günstig für die Strukturierung des
+Bildschirms innerhalb der Anwendungsprogramme ist, wenn man den Bildschirm in
+Bereiche (Fenster) einteilen und den Fenstern entsprechende Funktionen zuweisen
+kann (z.B. Eingabe-, Informations-, Kontroll-Fenster etc.). Sinnvoll ist es dann, auch
+die entsprechenden Ein-/Ausgaberoutinen zur Verfügung zu haben, die sich auf die
+einzelnen Fenster beziehen.
+
+In diesem Kapitel werden wir Ihnen zeigen, wie Sie eigene Fenster definieren und
+darin Ein- und Ausgaben realisieren können. Für die Fenster gelten die gleichen
+Einschränkungen wie für das Menufenster - d.h. ein Rollen des Textes (scrolling) ist
+nicht möglich. Die Fensterposition und -größe innerhalb des Bildschirms können Sie
+aber festlegen.
+
+
+#ib#7.1 Definition von Fenstern ('window')#ie#
+
+Das Fensterkonzept in gs-DIALOG ist sehr einfach gehalten: Durch die Definition
+des Fenters werden nur Bereiche auf dem Bildschirm festgelegt, auf die sich
+bestimmte Ein-/Ausgabeprozeduren beziehen.
+
+Wir wollen Ihnen die Verwendung von Fenstern wieder an einem kleinen Beispiel
+verdeutlichen - bleiben wir dazu bei unserer Textverarbeitung: Für die Seitenforma­
+tierung müßte der Benutzer den oberen und linken Rand, die Schreibfeldbreite und
+die Schreibfeldlänge festlegen. Dazu wollen wir dem Benutzer die aktuellen Werte
+anzeigen und ggf. eine Neueinstellung vornehmen lassen. Ein Programm dazu könnte
+so aussehen:
+
+
+WINDOW VAR info :: window ( 2, 2, 32, 9),
+ frage :: window (36, 2, 40, 3),
+ daten :: window (36, 7, 40, 4);
+
+TEXT VAR oberer rand :: " 2.54",
+ linker rand :: " 2.54",
+ feldbreite :: "16.00",
+ feldlaenge :: "24.50";
+
+
+zeige aktuelle werte an;
+frage nach neueinstellung.
+
+zeige aktuelle werte an:
+ page; show (info);
+ out (info, center (info, invers ("Aktuell eingestellte Werte:")));
+ cursor (info, 2, 4);
+ out (info, "Oberer Rand : " + oberer rand + " cm");
+ cursor (info, 2, 5);
+ out (info, "Linker Rand : " + linker rand + " cm");
+ cursor (info, 2, 7);
+ out (info, "Schreibfeldbreite : " + feldbreite + " cm");
+ cursor (info, 2, 8);
+ out (info, "Schreibfeldlänge : " + feldlaenge + " cm").
+
+frage nach neueinstellung:
+ show (frage);
+ cursor (frage, 1, 1);
+ out (frage, center (frage, invers ("Papierformat einstellen:")));
+ cursor (frage, 2, 3);
+ IF yes ("Neueinstellung vornehmen")
+ THEN neue werte erfragen
+ FI.
+
+neue werte erfragen:
+ show (daten);
+ erfrage oberen rand;
+ erfrage linken rand;
+ erfrage feldbreite;
+ erfrage feldlaenge.
+
+erfrage oberen rand:
+ REAL VAR neuer oberer rand;
+ cursor (daten, 1, 1);
+ out (daten, center (daten, invers ("Oberen Rand einstellen:")));
+ cursor (daten, 2, 3);
+ out (daten, "Bitte den neuen Wert: ");
+ get (daten, neuer oberer rand);
+ oberer rand := text (neuer oberer rand, 5, 2);
+ cursor (info, 23, 4);
+ out (info, oberer rand).
+
+erfrage linken rand:
+ (* analog zu 'erfrage oberen rand *).
+
+erfrage feldbreite:
+ (* analog zu 'erfrage oberen rand *).
+
+erfrage feldlaenge:
+ (* analog zu 'erfrage oberen rand *).
+
+
+
+Am Anfang des Programms werden drei Fenster definiert. Das "Infofenster" erscheint
+links oben auf dem Bildschirm, in ihm werden die aktuell eingestellten Werte ange­
+zeigt. Das "Fragefenster" erscheint neben dem ersten Fenster oben rechts auf dem
+Bildschirm.
+Beantwortet der Benutzer die dort ausgegebene Frage 'Neueinstellung vornehmen
+(j/n)?' mit 'ja', dann erscheint unter dem zweiten Fenster ein drittes
+("Datenfenster"). Innerhalb dieses Fensters können nacheinander die neuen Werte
+eingelesen werden (nicht alle Prozeduren sind hier ausgeführt!).
+
+Die Definition eines Fensters erfolgt in folgender Weise:
+
+ #ib#WINDOW#ie# VAR fenstername :: #ib#window#ie# ( x, y, xsize, ysize);
+
+Der Fenstervariablen wird durch 'window' eine Größe zugeordnet. Mit den ersten
+beiden Werten legen Sie die linke obere Ecke des Fensters ('x' bezeichnet die Spalten,
+'y' die Zeilen) auf dem Gesamtbildschirm fest. Mit 'xsize' bestimmen Sie die Fenster­
+breite (Spaltenzahl), mit 'ysize' die Höhe des Fensters (Zeilenzahl). Der Fenster­
+cursor hat die Position (1,1).
+Die linke obere Ecke des ersten Fensters im Programm hat also die Position ( 2, 2).
+Das Fenster ist 32 Spalten breit und 9 Zeilen hoch; es kann unter dem Namen 'info'
+angesprochen werden.
+Bei der Festlegung der Fenstermaße ist der Rahmen des Fensters nicht berücksich­
+tigt - er gehört nicht zum Fenster dazu! Haben Sie die Absicht, das Fenster mit
+Rahmen auszugeben, dann sollten Sie das bei der Fensterdefinition berücksichtigen.
+Wir haben es im Beispielprogramm auch gemacht: Die linke obere Ecke hat gerade
+die Position (2,2) erhalten, damit noch der Rahmen Platz hat. Mit Rahmen ist unser
+Fenster also 34 Spalten breit und 11 Zeilen hoch. Die linke obere Ecke des zweiten
+Fensters ('frage') legen wir deshalb in die 36. Spalte und 2. Zeile, damit auch hier
+Platz für den Rahmen bleibt.
+Eine wichtige Einschränkung sollten Sie unbedingt berücksichtigen: Da manche
+Terminals mit Beschreiben der Position (80,24) automatisch den Bildschirm
+löschen, haben wir die maximale Ausdehnung eines umrandeten Fensters auf (2, 2,
+77, 22) festgelegt. Überschreiten Sie irgendwo diese Grenzen, dann wird kein Rah­
+men mehr erzeugt. Der Rahmen wird auch dann nicht erzeugt, wenn er in der 0.
+Zeile, 0.Spalte, 25 Zeile oder 80 Spalte zu liegen käme - erst recht natürlich nicht,
+wenn diese Werte noch unter- bzw. überschritten werden.
+
+
+#ib#7.2 Anzeigen/Löschen von Fenstern#ie#
+ ('#ib#show#ie#', '#ib#page#ie#', '#ib#erase#ie#', '#ib#out frame#ie#')
+
+Mit dem Befehl 'show (WINDOW VAR w)' wird das Fenster 'w' angezeigt. Der Fenster­
+variablen müssen natürlich zuvor die Maße des Fensters zugewiesen sein. Durch den
+Befehl wird um den angegebenen Fensterbereich ein Rahmen gezogen und der
+"Innenbereich" des Fensters gelöscht. Möchten Sie das Fenster ohne Rahmen ange­
+zeigt haben, so verwenden Sie nur den Befehl 'page (WINDOW VAR w)'. Durch die­
+sen Befehl wird nur der "Innenbereich" des Fensters gelöscht.
+Haben Sie das Fenster einmal mit 'show' ausgegeben und wollen den Fensterinhalt
+löschen, so verwenden Sie auch hier den Befehl 'page (WINDOW VAR w)', denn der
+Rahmen braucht ja nicht erneut ausgegeben zu werden.
+Möchten Sie ein Fenster und den zugehörigen Rahmen löschen, dann steht Ihnen der
+Befehl 'erase (WINDOW VAR w) zur Verfügung: Durch den Befehl wird sowohl der
+"Innenbereich" des Fensters als auch der Rahmen gelöscht.
+Sie können natürlich auch selbst einen Rahmen um ein Fenster setzen. Dafür steht
+der Befehl 'out frame (WINDOW VAR w)' zur Verfügung. Der Rahmen wird ebenfalls
+um den durch 'w' bestimmten Fensterbereich gezogen - der "Innenbereich" bleibt
+unberührt!
+
+Sollten Sie ein Fenster mit dem Befehl 'show' ausgeben (oder mit 'out frame' einen
+Rahmen erzeugen) wollen, aber kein Rahmen auf dem Bildschirm erscheint, so
+haben Sie die zulässigen Fenstergrenzen überschritten. Sehen Sie dazu auch Kapitel
+7.1.
+
+
+#ib#7.3 Operationen innerhalb des Fensters#ie#
+
+Innerhalb des selbstdefinierten Fensters stehen Ihnen die gleichen Operationen zur
+Verfügung wie innerhalb des Menufensters. Bezieht sich eine Operation auf ein
+Fenster, so wird der interne Fensterbezeichner als erster Parameter übergeben.
+
+
+#ib#7.3.1 Datei anzeigen/editieren #ie#('#ib#edit#ie#', '#ib#show#ie#')
+
+Zum Anzeigen einer Datei steht die Prozedur 'show' zur Verfügung. Dabei kann
+einmal ein FILE angegeben werden ('show (WINDOW VAR w, FILE VAR f)') oder aber
+der Name der anzuzeigenden Datei ('show (WINDOW VAR w, TEXT VAR dateiname)').
+Die Datei kann nur eingesehen, nicht aber schreibend verändert werden.
+Die Prozedur 'edit' gibt es ebenfalls in den zwei Ausprägungen. Hier kann die Datei
+im Gegensatz zu 'show' auch schreibend verändert werden.
+Durch diesen Befehl wird jeweils innerhalb des angegebenen Fensters die Datei
+ausgegeben. Sofern die Lage des Fensters es zuläßt, wird automatisch ein Rahmen
+um das Dateifenster gezogen.
+
+
+#ib#7.3.2 Positionierungen im Fenster#ie#
+ ('#ib#cursor#ie#', '#ib#get cursor#ie#', '#ib#line#ie#', '#ib#remaining lines#ie#')
+
+Mit 'cursor (WINDOW VAR w, INT CONST spalte, zeile)' können Sie den Cursor inner­
+halb des angegebenen Fensters positionieren. Werden dabei die Fenstergrenzen über-
+oder unterschritten, so wird der Fensterinhalt gelöscht und auf die Position (1, 1)
+innerhalb des Fensters positioniert.
+Mit der Prozedur 'get cursor (WINDOW VAR w, INT VAR spalte, zeile)' können Sie die
+aktuelle Cursorposition innerhalb des angegebenen Fensters erfragen.
+Wollen Sie an den Anfang der nächsten Zeile positionieren, dann verwenden Sie den
+Befehl 'line (WINDOW VAR w)' - wollen Sie gleich mehrere Zeilen vorwärtspositionie­
+ren, dann benutzen Sie den Befehl 'line (WINDOW VAR w, INT VAR anzahl zeilen)'.
+Wird allerdings bei einem der beiden letzten Befehle die untere Fenstergrenze über­
+schritten, so wird der Fensterinhalt gelöscht und die Operation in der ersten Zeile des
+neuen Fensters fortgesetzt.
+Die Informations-Prozedur 'remaining lines (WINDOW VAR w)' liefert Ihnen die
+Anzahl der unterhalb der aktuellen Zeile noch im Fenster vorhanden Zeilen.
+
+
+#ib#7.3.3 Ein- und Ausgaben innerhalb des Fensters#ie#
+ ('#ib#out#ie#', '#ib#put#ie#', '#ib#putline#ie#', '#ib#get#ie#', '#ib#getline#ie#', '#ib#yes#ie#', '#ib#no#ie#')
+
+Mit der Prozedur 'out (WINDOW VAR w, TEXT CONST text)' können Sie einen Text
+innerhalb des angegebenen Fensters ausgeben. Paßt der Text nicht mehr in die
+aktuelle Zeile, so wird er in der nächsten Zeile fortgesetzt.
+Bedenken Sie, daß innerhalb der Fenster kein Wortumbruch realisiert ist. Ebenso­
+wenig ist das Rollen (scrolling) des Fensterinhalts möglich: Erfolgt die Ausgabe eines
+Textes über die untere Fenstergrenze hinaus, so wird der Fensterinhalt gelöscht und
+die Ausgabe an der Position (1, 1) des Fensters fortgesetzt.
+Zur Ausgabe von Texten stehen noch die beiden Prozeduren 'put (WINDOW VAR w,
+TEXT CONST text)' und 'putline (WINDOW VAR w, TEXT CONST text)' zur Verfügung.
+Bei erstgenannter Prozedur wird gegenüber 'out' an die Ausgabe noch ein Leerzei­
+chen angehängt, bei der zweiten wird zusätzlich an den Anfang der nächsten Zeile
+positioniert.
+Zahlenwerte können mit den Prozeduren 'put (WINDOW VAR w, INT CONST intwert)'
+und 'put (WINDOW VAR w, REAL CONST realwert)' ausgegeben werden. An die
+Zahlenwerte wird jeweils ein Leerzeichen angehängt.
+
+Für das Einlesen von Werten steht die Prozedur 'get' in mehreren Varianten zur
+Verfügung. Mit 'get (WINDOW VAR w, TEXT VAR text)' kann ein Text an der aktuellen
+Position des Fensters eingelesen werden. Stehen in der aktuellen Zeile des Fensters
+weniger als 5 Zeichenpositionen für die Eingabe zur Verfügung, so wird automatisch
+auf den Anfang der nächsten Zeile innerhalb des Fensters positioniert.
+Über einen dritten Parameter können noch zusätzliche Festlegungen getroffen wer­
+den: Soll die Eingabe noch durch weitere Zeichen (außer Positionierungszeichen)
+abgeschlossen werden können, so werden die Zeichen als TEXT übergeben( 'get
+(WINDOW VAR w, TEXT VAR text, TEXT CONST separator)'), soll die Maximallänge des
+einzugebenden Textes festgelegt sein, so wird diese als INT übergeben ('get (WINDOW
+VAR w, TEXT VAR text, INT CONST laenge)').
+
+Mit den Prozeduren 'get (WINDOW VAR w, INT VAR intwert)' und 'get (WINDOW VAR
+w, INT VAR realwert)' können auch Zahlenwerte innerhalb des Fensters eingelesen
+werden.
+
+Damit dem Anwender auch Vorschläge für der Eingabe gemacht werden können,
+steht die Prozedur 'editget' in zwei Variationen zur Verfügung. Bei 'editget' (WINDOW
+VAR w, TEXT VAR ausgabe) wird 'ausgabe zum Editieren ausgegeben. Daneben
+existiert noch ein 'editget' mit 7 Parametern, der detailliert bei der Zusammenstel­
+lung der Befehle erläutert ist.
+
+Ebenso wie auf dem Gesamtbildschirm und innerhalb des Menufensters stehen auch
+hier die beiden Prozeduren 'yes (WINDOW VAR w, TEXT CONST frage)' und 'no
+(WINDOW VAR w, TEXT CONST frage)' zur Verfügung.
+
+
+#ib#7.3.4 Weitere Prozeduren #ie#('#ib#center#ie#', '#ib#stop#ie#')
+
+Mit 'center (WINDOW VAR w, TEXT CONST text)' werden vor dem angegebenen Text
+so viele Leerzeichen angehängt, daß der Text zentriert in der aktuellen Fensterzeile
+ausgegeben wird - wenn der Cursur bei der Ausgabe auf der ersten Position der Zeile
+steht. Dabei werden aber bereits vorhandene Zeileninhalte überschrieben.
+
+Durch die Prozedur 'stop (WINDOW VAR w)' wird innerhalb des angegebenen Fen­
+sters an den Anfang der übernächsten Zeile positioniert und der Text " Zum Weiter­
+machen bitte irgendeine Taste tippen!" ausgegeben. Möchten Sie nicht an den Anfang
+der übernächsten Zeile positionieren, so können Sie die Anzahl der Zeilen auch
+explizit festlegen durch 'stop (WINDOW VAR w, INT CONST zeilenzahl).
+
+
+#ib#7.4 Boxoperationen#ie#
+
+Innerhalb des Menufensters (sehen Sie Kapitel 5) stehen Ihnen die Prozeduren
+'menuanswer', 'menuinfo', 'menuone', 'menusome', 'menuanswerone',
+'menuanswersome', 'menuyes', 'menuno', 'menualternative', 'write menunotice' und
+'menufootnote' zur Verfügung. Alle diese Prozeduren bezogen sich auf das von
+gs-DIALOG automatisch gesetzte Menufenster.
+Auch innerhalb der von Ihnen selbst definierten Fenster können Sie auf ähnliche
+Prozeduren zurückgreifen. Da wir die eben genannten Prozeduren in Kapitel 5 sehr
+detailliert beschrieben haben, werden wir hier nur auf die entsprechenden
+Beschreibungen verweisen und ggf. die Besonderheiten/Abweichnungen erwähnen.
+Zu beachten ist, daß innerhalb des Fensters weder die oberen noch die unteren zwei
+Zeilen von der "Box" beschrieben werden. Die oberen bleiben ständig frei - die unter­
+en werden zur Ausgabe der zugehörigen Benutzerinformation (Fußnote) benutzt -
+das sollten Sie bei der Festlegung der Fenstergröße bzw. bei der Länge der zu über­
+gebenden Texte berücksichtigen. Bei der Übergabe der Texte müssen Sie sich an die
+gs-DIALOG Syntax-Regeln halten, die in Kapitel 5.12 beschrieben sind.
+
+Die Prozedur '#ib#boxanswer#ie# (WINDOW VAR w, TEXT CONST ausgabetext, antwortvorgabe,
+INT CONST position)' arbeitet wie die Prozedur 'menuanswer (TEXT CONST ausgabe­
+text, antwortvorgabe, INT CONST position)' nur innerhalb des Fensters 'w' (sehen Sie
+auch Kapitel 5.1).
+
+Die Prozedur '#ib#boxinfo#ie#' gibt es in zwei Ausführungen: 'boxinfo (WINDOW VAR w, TEXT
+CONST text)' arbeitet wie 'menuinfo (TEXT CONST text)', allerdings auf dem angege­
+benen Fenster. Bei 'boxinfo (WINDOW VAR w, TEXT CONST text, INT CONST position,
+timelimit)' kann über den dritten Parameter noch die relative Position im angegebe­
+nen Fenster (sehen Sie dazu Kapitel 5.12) und über den vierten Parameter die Zeit­
+spanne festgelegt werden, für die die Information erscheint (sehen Sie auch Kap.
+5.2).
+
+Die Prozedur '#ib#boxone#ie# (WINDOW VAR w, THESAURUS CONST thesaurus, TEXT CONST
+text1, text2, BOOL CONST mit reinigung)' arbeitet wie die Prozedur 'menuone
+(THESAURUS CONST thesaurus, TEXT CONST text1, text2, BOOL CONST mit reini­
+gung)'. Zu bedenken ist hier, daß die Auswahl innerhalb des Fensters Platz finden
+muß. Der Aufruf dieser Prozedur ist daher nur möglich, wenn das angegebene Fen­
+ster mindestens 60 Spalten breit und 17 Zeilen hoch ist. Ansonsten kommt es zu
+einer Fehlermeldung (sehen Sie auch Kap. 5.3).
+
+Die Prozedur '#ib#boxsome#ie# (WINDOW VAR w, THESAURUS CONST thesaurus, TEXT
+CONST text1, text2, BOOL CONST mit reinigung)' arbeitet wie die Prozedur
+'menusome (THESAURUS CONST thesaurus, TEXT CONST text1, text2, BOOL CONST
+mit reinigung)'. Hinsichtlich der Fenstergröße gelten die gleichen Einschränkungen
+wie bei 'boxone' (sehen Sie auch Kap. 5.4).
+
+Die Prozeduren '#ib#boxanswerone#ie#' und '#ib#boxanswersome#ie#' entsprechen den Prozeduren
+'menuanswerone' und 'menuanswersome'; es wird nur zusätzlich jeweils als erster
+Parameter das aktuelle Fenster übergeben. Hinsichtlich der Fenstergröße gelten die
+gleichen Einschränkungen wie bei 'boxone' (sehen Sie auch Kap. 5.5).
+
+Die Prozeduren '#ib#boxyes#ie#', '#ib#boxno#ie#' und '#ib#boxalternative#ie#' entsprechen den Prozeduren
+'menuyes', 'menuno' und 'menualternative'; es wird nur zusätzlich jeweils als erster
+Parameter das aktuelle Fenster übergeben (sehen Sie auch Kap. 5.6 und 5.7).
+
+Die Prozedur '#ib#boxnotice#ie#' unterscheidet sich von der Prozedur 'write menunotice'
+erheblich: Letztgenannte Prozedur hat zwei Parameter. Durch den ersten wird der
+Ausgabetext übergeben, mit dem zweiten wird die relative Position innerhalb des
+Menubildschirms festgelegt. Sowohl Text als auch Position werden vom System ge­
+speichert. Bei jedem Neuaufbau eines Pull-Down-Menus oder des Menubildschirms
+wird die Notiz neu mitaufgebaut.
+Die Prozedur 'boxnotice (WINDOW VAR w, TEXT CONST text, INT CONST position, INT
+VAR x, y, xsize, ysize) dagegen hat sieben Parameter. Über den ersten wird das aktuel­
+le Fenster festgelegt. Die beiden nächsten Parameter entsprechen den beiden Para­
+metern von 'write menunotice'. Über die letzten vier Parameter werden die Posi­
+tion/Maße der Box geliefert, die ja erst durch das Aussehen der übergebenen Texte
+festgelegt werden. Weder Text noch Position der Boxnotiz werden vermerkt. Wollen Sie
+die Notiz löschen, so verwenden Sie eine der Prozeduren '#ib#page#ie# (INT CONST x, y, xsize,
+ysize)' oder '#ib#page up#ie# (INT CONST x, y, xsize, ysize)'. Im ersten Falle erscheint es dem
+Betrachter, als ob die Box von oben nach unten "aufgerollt" würde, im zweiten Falle
+von unten nach oben.
+
+Mit den Prozeduren '#ib#out footnote#ie# (WINDOW VAR w, TEXT CONST text)' wird in der
+untersten Zeile des Fensters 'w' der angegebene Text ausgegeben. In der vorletzten
+Zeile des Fensters wird eine Trennlinie ausgegeben. Die Fußnote incl. der Trennline
+kann durch den Befehl '#ib#erase footnote#ie#' gelöscht werden.
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.8 b/doc/menugenerator/menu-generator handbuch.8
new file mode 100644
index 0000000..66eb6cf
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.8
@@ -0,0 +1,1676 @@
+#block##pageblock#
+#pagenr("%",1)##setcount(1)##count per page#
+#headeven#
+gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#right#gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+8 - % #right#ERGOS
+#end#
+#bottomodd#
+#center#____________________________________________________________
+ERGOS #right# 8 - %
+#end#
+#ib#8  Kurzbeschreibung der Befehle #ie#
+
+
+Durch #u#(*)#e# gekennzeichnete Prozeduren stehen (zumindest in der hier dokumentier­
+ten Form) erst ab gs-DIALOG Version 1.1 zur Verfügung!
+
+
+#ib#activate#ie#
+PROC activate (TEXT CONST punktname):
+
+Zweck: Mit der Prozedur kann ein (deaktivierter) Menupunkt im aktuellen
+ Pull-Down-Menu aktiviert, d.h. zur Ausführung freigegeben werden. Das
+ '-'-Zeichen vor der Punktbezeichnung verschwindet auf dem Bildschirm,
+ statt dessen erscheint das Zeichen, über den die Menufunktion direkt
+ aktivierbar ist. 'punktname' muß eine Punktbezeichnung sein, die genau
+ in der angegebenen Schreibweise im aktuellen Pull-Down-Menu vorhan­
+ den ist (über den 2. Parameter der Prozedur 'menufunktion' in die
+ Menukarte eingetragen wurde) - ansonsten wird diese Anweisung igno­
+ riert. Die Prozedur "zeigt nur dann Wirkung", wenn sie aus einer Verar­
+ beitungsfunktion des aktuell entfalteten Pull-Down-Menus heraus oder
+ durch die "Startprozedur"/"Leaveprozedur" des aktuellen Pull-Down-
+ Menus (sehen Sie auch 'oberbegriff') aufgerufen wird.
+ Die Veränderung wird nicht sofort auf dem Bildschirm angezeigt, sondern
+ erst, wenn das Pull-Down-Menu das nächste Mal vom System regeneriert
+ wird; ansonsten muß das Kommando 'refresh submenu' gegeben werden.
+
+
+PROC activate (INT CONST punktposition):#u#(*)#e#
+Zweck: arbeitet wie obiges 'activate', allerdings werden die Menupunkte nicht
+ über ihre Bezeichnung, sondern über ihre Position im (aktuellen) Pull-
+ Down-Menu identifiziert. Die Positionen sind von oben nach unten durch­
+ numeriert. Beachten Sie, daß Trennlinien eine Position belegen und
+ mitgezählt werden. Die Prozedur arbeitet schneller als obige!
+
+
+#ib#anwendungstext#ie#
+TEXT PROC anwendungstext (INT CONST zeilennummer):
+
+Zweck: Mit diesem Befehl können Texte angesprochen (geholt) werden, die in die
+ Menukarte ausgelagert wurden. Es wird der Text aus der angekoppelten
+ Menukarte geliefert, der bei der "Einlagerung" in der Zeile 'zeilen­
+ nummer' stand.
+Fehler: Kein Text vorhanden! (In der angekoppelten Menukarte ist unter der
+ 'zeilennummer' kein Anwendungstext eingetragen.)
+ Bitte achten Sie auf folgendes: Wenn Sie eine neue Menukarte generiert
+ haben, muß diese erst an die aktuelle Task gekoppelt werden, bevor Sie
+ auf die dort eingetragenen (Anwendungs-)Texte zugreifen können (z.B.
+ mit 'testinstallation').
+
+
+#ib#areax#ie#
+INT PROC areax (WINDOW VAR w)
+Zweck: Liefert den Wert 'x' des Fensters w.
+
+
+#ib#areaxsize#ie#
+INT PROC areaxsize (WINDOW VAR w)
+Zweck: Liefert den den Wert 'xsize' des Fensters w.
+
+
+#ib#areay#ie#
+INT PROC areay (WINDOW VAR w)
+Zweck: Liefert den den Wert 'y' des Fensters w.
+
+
+#ib#areaysize#ie#
+INT PROC areaysize (WINDOW VAR w)
+Zweck: Liefert den den Wert 'ysize' des Fensters w.
+
+
+#ib#balken links#ie#
+TEXT PROC balken links:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" als "linker
+ Balken" (̄) ausgegeben wird.
+
+
+PROC balken links (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" als "linker Balken" ausgegeben werden soll.
+
+
+#ib#balken oben#ie#
+TEXT PROC balken oben:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" als "oberer
+ Balken" (�) ausgegeben wird.
+
+
+PROC balken oben (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" als "oberer Balken" ausgegeben werden soll.
+
+
+#ib#balken rechts#ie#
+TEXT PROC balken rechts:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" als "rechter
+ Balken" (̃) ausgegeben wird.
+
+
+PROC balken rechts (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" als "rechter Balken" ausgegeben werden soll.
+
+
+#ib#balken unten#ie#
+TEXT PROC balken unten:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" als "unterer
+ Balken" (̂) ausgegeben wird.
+
+
+PROC balken unten (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" als "unterer Balken" ausgegeben werden soll.
+
+
+#ib#boxalternative#ie#
+INT PROC boxalternative (WINDOW VAR w,
+ TEXT CONST infotext,
+ auswahlliste,
+ zusatztasten,
+ INT CONST position,
+ BOOL CONST mit abbruch):
+
+Zweck: Vergl. 'menualternative'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menualternative' automatisch gesetzt wird. Der 'infotext' muß
+ den gs-DIALOG-Syntax-Regel gehorchen! Die 'auswahlliste' muß nach
+ festen Regeln erstellt werden (sehen Sie Kap. 5.7)
+
+
+#ib#boxanswer#ie#
+TEXT PROC boxanswer (WINDOW VAR w,
+ TEXT CONST infotext,
+ vorgabe,
+ INT CONST  position):
+
+Zweck: Vergl. 'menuanswer'. Hier wird nur zusätzlich das Fenster festgelegt, das
+ bei 'menuanswer' automatisch gesetzt wird. Der 'infotext' muß den
+ gs-DIALOG-Syntax-Regel gehorchen!
+
+
+#ib#boxanswerone#ie#
+TEXT PROC boxanswerone (WINDOW VAR w,
+ TEXT CONST infotext,
+ vorgabe,
+ THESAURUS CONST thes,
+ TEXT CONST ueberschrift,
+ hinweis,
+ BOOL CONST mit reinigung):
+
+Zweck: Vergl. 'menuanswerone'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuanswerone' automatisch gesetzt wird.
+Fehler: Fenster für Auswahl zu klein (x < 56, y < 15)
+
+
+#ib#boxanswersome#ie#
+THESAURUS PROC boxanswersome (WINDOW VAR w,
+ TEXT CONST infotext,
+ vorgabe,
+ THESAURUS CONST thes,
+ TEXT CONST ueberschrift,
+ hinweis,
+ BOOL CONST mit reinigung):
+
+Zweck: Vergl. 'menuanswersome'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuanswersome' automatisch gesetzt wird.
+Fehler: Fenster für Auswahl zu klein (x < 56, y < 15)
+
+
+#ib#boxinfo#ie#
+PROC boxinfo (WINDOW VAR w, TEXT CONST infotext,
+ INT CONST position, timelimit):
+
+Zweck: Vergl. 'menuinfo'. Hier wird nur zusätzlich das Fenster festgelegt, das bei
+ 'menuinfo' automatisch gesetzt wird. Der 'infotext' muß den gs-DIALOG-
+ Syntax-Regel gehorchen!
+
+
+PROC boxinfo (WINDOW VAR w, TEXT CONST infotext):
+
+ wirkt wie: boxinfo (w, infotext, 5, maxint)
+
+
+#ib#boxno#ie#
+BOOL PROC boxno (WINDOW VAR w,
+ TEXT CONST frage,
+ INT CONST  position):
+
+ wirkt wie: NOT boxyes (w, frage, position)
+
+
+#ib#boxnotice#ie#
+PROC boxnotice (WINDOW VAR w,
+ TEXT CONST infotext,
+ INT CONST  position
+ INT VAR x, y, xsize, ysize):
+
+Zweck: Mit 'w' wird das aktuelle Fenster festgelegt. In 'infotext' wird der Text
+ übergeben, der als Notiz ausgegeben werden soll, der Text muß den
+ gs-DIALOG-Syntax-Regeln entsprechen. Mit 'position' wird die relative
+ Lage innerhalb des Fensters 'w' bestimmt. Über die letzten vier Parameter
+ werden die Position/Maße der Box geliefert. Weder Text noch Position
+ werden vermerkt.
+
+
+#ib#boxone#ie#
+TEXT PROC boxone (WINDOW VAR w,
+ THESAURUS CONST thes,
+ TEXT CONST ueberschrift,
+ hinweis,
+ BOOL CONST mit reinigung):
+
+Zweck: Vergl. 'menuone'. Hier wird nur zusätzlich das Fenster festgelegt, das bei
+ 'menuone' automatisch gesetzt wird.
+Fehler: Fenster für Auswahl zu klein (x < 56, y < 15)
+
+
+#ib#boxsome#ie#
+THESAURUS PROC boxsome (WINDOW VAR w,
+ THESAURUS CONST thes,
+ TEXT CONST ueberschrift,
+ hinweis,
+ BOOL CONST mit reinigung):
+
+Zweck: Vergl. 'menusome'. Hier wird nur zusätzlich das Fenster festgelegt, das
+ bei 'menusome' automatisch gesetzt wird.
+Fehler: Fenster für Auswahl zu klein (x < 56, y < 15)
+
+
+#ib#boxyes#ie#
+BOOL PROC boxyes (WINDOW VAR w,
+ TEXT CONST frage,
+ INT CONST  position):
+
+Zweck: Vergl. 'menuyes'. Hier wird nur zusätzlich das Fenster festgelegt, das bei
+ 'menuyes' automatisch gesetzt wird. Die 'frage' muß den gs-DIALOG-
+ Syntax-Regel gehorchen!
+
+
+#ib#center#ie#
+TEXT PROC center (WINDOW VAR w, TEXT CONST text):
+
+Zweck: Vergl. 'menuwindowcenter'. Hier wird nur zusätzlich das Fenster festge­
+ legt, das bei 'menuwindowcenter' automatisch gesetzt wird.
+
+
+TEXT PROC center (INT CONST laenge,
+ TEXT CONST text):
+
+Zweck: "Ummantelt" 'text' mit Leerzeichen, so daß 'text' etwa in der Mitte zu
+ stehen kommt. Der gelieferte Text hat die Länge 'laenge'.
+
+
+TEXT PROC center (TEXT CONST text):
+
+ wirkt wie: center (79, text)
+
+
+#ib#clear buffer#ie#
+PROC clear buffer
+
+Zweck: Leert den Zeichenpuffer
+
+
+#ib#clear buffer and count#ie#
+INT PROC clear buffer and count (TEXT CONST
+ zeichen):
+
+Zweck: Leert den Zeichenpuffer und liefert die Häufigkeit des Vorkommens von
+ 'zeichen' im Zeichenpuffer.
+
+
+#ib#current menuwindow#ie#
+WINDOW PROC current menuwindow:
+
+Zweck: liefert das aktuelle Menufenster (die Einzelwerte können dann mit
+ 'areax', 'areay', 'areaxsize' und 'areaysize' erfragt werden).
+
+
+#ib#cursor#ie#
+PROC cursor (WINDOW VAR w, INT CONST spalte,
+ zeile):
+
+Zweck: Vergl. 'menuwindowcursor'. Hier wird nur zusätzlich das Fenster festge­
+ legt, das bei 'menuwindowcursor' automatisch gesetzt wird.
+
+
+#ib#cursor off#ie#
+PROC cursor off:
+
+Zweck: Sofern die EUMEL-Installation die Möglichkeit bietet, wird der Cursor aus
+ dem Bildschirm ausgeblendet.
+ Wenn neue Verarbeitungsfunktionen entwickelt werden, sollte zu Beginn
+ der Cursor eingeschaltet und nach Abschluß der Cursor wieder ausge­
+ schaltet werden (sehen Sie auch Kap. 5.1).
+
+
+PROC cursor off (TEXT CONST zeichenkette):
+
+Zweck: Neufestlegung der 'zeichenkette', die ausgegeben werden soll, um bei der
+ aktuellen EUMEL-Installation den Cursor auf den Befehl 'cursor off' hin
+ auszuschalten.
+
+
+#ib#cursor on#ie#
+PROC cursor on:
+
+Zweck: Sofern die EUMEL-Installation die Möglichkeit bietet, wird der Cursor auf
+ dem Bildschirm angezeigt. Wenn neue Verarbeitungsfunktionen entwik­
+ kelt werden, sollte zu Beginn der Cursor eingeschaltet und nach Abschluß
+ der Cursor wieder ausgeschaltet werden (sehen Sie auch Kap. 5.1).
+
+
+PROC cursor on (TEXT CONST zeichenkette):
+
+Zweck: Neufestlegung der 'zeichenkette', die ausgegeben werden soll, um bei der
+ aktuellen EUMEL-Installation den Cursor auf den Befehl 'cursor on' hin
+ anzuschalten.
+
+
+#ib#deactivate#ie#
+PROC deactivate (TEXT CONST punktname):
+
+Zweck: Vergl. 'activate (TEXT CONST punktname)'.
+ Im Gegensatz zu der Prozedur wird hier 'punktname' deaktiviert und
+ beim (nächsten) Erscheinen der Menupunktbezeichnung ein '-'Zeichen
+ vorangestellt. Es gelten die gleichen Einschränkungen wie bei 'activate'!
+
+
+PROC deactivate (INT CONST punktposition):#u#(*)#e#
+Zweck: arbeitet wie obiges 'deactivate', allerdings werden die Menupunkte nicht
+ über ihre Bezeichnung, sondern über ihre Position im (aktuellen) Pull-
+ Down-Menu identifiziert. Die Positionen sind von oben nach unten durch­
+ numeriert. Beachten Sie, daß Trennlinien eine Position belegen und
+ mitgezählt werden. Die Prozedur arbeitet schneller als obige!
+
+
+#ib#direktstart#ie#
+PROC direktstart (TEXT CONST prozedurname,
+ BOOL CONST mit loeschen):#u#(*)#e#
+Zweck: Macht aus der aktuellen Task eine Manager-Task ('global manager').
+ Werden neue Sohntasks eingerichtet, so melden sich diese nicht - wie
+ gewohnt - mit der 'gib kommando:'-Ebene. Statt dessen wird die Prozedur
+ 'prozedurname' ausgeführt. Das Kommando ist dann sinnvoll, wenn sich
+ die Sohntask gleich mit einem Menu melden soll. In der Prozedur
+ 'prozedurname' muß dann die entsprechende Menukarte angekoppelt
+ und das gewünschte Menu zur Ausführung gebracht werden. Hat 'mit
+ loeschen den Wert 'TRUE', so wird nach Verlassen der Menuebene die
+ Task automatisch gelöscht; bei 'FALSE' wird noch angefragt, ob die Task
+ gelöscht werden soll. Wird die Frage bejaht, wird gelöscht; sonst wird die
+ Task abgekoppelt (break) und kann durch 'continue' wieder angekoppelt
+ werden.
+ In der Task, in der das Kommando 'direktbefehl' gegeben wurde, sollte
+ nicht das Kommando 'monitor' gegeben werden, da dadurch auch die­
+ se Task zu einer Task gemacht würde, die sich direkt mit dem Menu
+ meldet und ggf. bei Verlassen des Menus automatisch gelöscht wird! Die
+ 'gib kommando:'-Ebene ist dadurch unzugänglich!
+
+
+#ib#ecke oben links#ie#
+TEXT PROC ecke oben links:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" links oben in der
+ Ecke (ω) ausgegeben wird.
+
+
+PROC ecke oben links (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" links oben in der Ecke ausgegeben werden soll.
+
+
+#ib#ecke oben rechts#ie#
+TEXT PROC ecke oben rechts:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" rechts oben in
+ der Ecke (�) ausgegeben wird.
+
+
+PROC ecke oben rechts (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" rechts oben in der Ecke ausgegeben werden soll.
+
+
+#ib#ecke unten links#ie#
+TEXT PROC ecke unten links:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" links unten in
+ der Ecke (�) ausgegeben wird.
+
+
+PROC ecke unten links (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" links unten in der Ecke ausgegeben werden soll.
+
+
+#ib#ecke unten rechts#ie#
+TEXT PROC ecke unten rechts:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" rechts unten in
+ der Ecke (�) ausgegeben wird.
+
+
+PROC ecke unten rechts (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" rechts unten in der Ecke ausgegeben werden soll.
+
+
+#ib#edit#ie#
+PROC edit (WINDOW VAR w, TEXT CONST dateiname):
+
+Zweck: Vergl. 'menuwindowedit'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuwindowedit' automatisch gesetzt wird.
+
+
+PROC edit (WINDOW VAR w, FILE VAR f):
+
+Zweck: Vergl. 'menuwindowedit'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuwindowedit' automatisch gesetzt wird.
+
+
+#ib#editget#ie#
+PROC editget (WINDOW VAR w, TEXT VAR text):#u#(*)#e#
+Zweck: Eingabe mit Editiermöglichkeit von 'text'. 'text' wird ausgegeben. Die
+ Eingabe wird mit RETURN beendet. 'text' darf höchstens 79 Zeichen
+ lang sein! Fehler: Text nicht initialisiert.
+
+
+PROC editget (WINDOW VAR w, TEXT VAR text,
+ INT CONST max laenge, scroll,
+ TEXT CONST sep, res,
+ TEXT VAR exit char):#u#(*)#e#
+Zweck: Wie oben. Über 'max laenge' kann festgelegt werden , wie lang der einzu­
+ gebende Text ('text') maximal sein darf. Über 'scroll' wird die Breite des
+ Zeilenfensters festgelegt, bevor gerollt wird (jedoch nicht über die rech­
+ te Fenstergrenze hinaus). Über 'sep' können Zeichen bestimmt werden,
+ bei denen die Eingabe (zusätzlich zu RETURN) beendet werden soll. Über
+ 'res' können reservierte Tasten angegeben werden. Wird eine dieser
+ Tasten mit ESC betätigt, wird die Eingabe beendet. In 'exit char' steht
+ dann ESC und das Zeichen, mit dem der Editor verlassen wurde.
+Fehler: Text nicht initialisiert.
+
+
+#ib#erase#ie#
+PROC erase (WINDOW VAR fenster):
+
+Zweck: Der durch 'fenster' beschrieben Bildschirmbereich wird gelöscht - ein­
+ schließlich des Rahmens, der den Fensterbereich umgibt (vergl. Sie auch
+ 'page')!
+
+
+#ib#erase footnote#ie#
+PROC erase footnote (WINDOW VAR fenster):
+
+Zweck: Die letzten beiden Zeilen in 'fenster' (in der die Fußnote nebst Trennlinie
+ eingetragen sind) werden gelöscht (vergl. Sie auch 'out footnote')!
+
+
+#ib#erase menunotice#ie#
+PROC erase menunotice:
+
+Zweck: Sofern zuvor mit 'write menunotice' (sehen Sie auch dort) eine Menunotiz
+ gesetzt wurde, wird diese gelöscht, ansonsten hat die Prozedur keine
+ Wirkung.
+
+
+#ib#get#ie#
+PROC get (WINDOW VAR w, TEXT CONST eingabe):
+
+Zweck: Vergl. 'menuwindowget'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuwindowget' automatisch gesetzt wird.
+
+
+PROC get (WINDOW VAR w, INT CONST wert):
+
+Zweck: Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe)'. Der eingelesene Wert
+ wird anschließend entsprechend konvertiert.
+
+
+
+PROC get (WINDOW VAR w, REAL CONST wert):
+
+Zweck: Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe)'. Der eingelesene Wert
+ wird anschließend entsprechend konvertiert.
+
+
+PROC get (WINDOW VAR w, TEXT CONST eingabe,
+ INT CONST laenge):
+
+Zweck: Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe)'. Zusätzlich wird die
+ Eingabe beendet, wenn der eingegebene Text die Länge 'laenge' erreicht
+ hat.
+
+
+PROC get (WINDOW VAR w, TEXT CONST eingabe,
+ TEXT CONST separator):
+
+Zweck: Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe)'. Zusätzlich werden
+ über 'separtor' die Zeichen festgelegt, die zusätzlich zu den Positionie­
+ rungszeichen die Eingabe beenden.
+
+
+#ib#get cursor#ie#
+PROC get cursor (WINDOW VAR w, INT VAR spalte,
+ zeile):
+
+Zweck: Vergl. 'get menuwindowcursor'. Hier wird nur zusätzlich das Fenster
+ festgelegt, das bei 'get menuwindowcursor' automatisch gesetzt wird.
+
+
+#ib#getline#ie#
+PROC getline (WINDOW VAR w, TEXT CONST eingabe):
+
+Zweck: Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe). Nur wird hier die
+ Eingabe ausschließlich über die Positionierungstasten - nicht aber über
+ das Leerzeichen beendet.
+
+
+#ib#get menuwindowcursor#ie#
+PROC get menuwindowcursor (INT VAR spalte, zeile):
+
+Zweck: Mit der Prozedur wird die aktuelle Cursorposition innerhalb des Menu­
+ fensters erfragt.
+
+
+#ib#handle menu#ie#
+PROC handle menu (TEXT CONST menuname):
+
+Zweck: Bringt das in der angekoppelten Menukarte enthaltene Menu mit dem
+ Namen 'menuname' zur Ausführung, d.h. das entsprechende Menu wird
+ auf dem Bildschirm präsentiert und kann mit den üblichen Tastenfunk­
+ tionen gehandhabt werden.
+ (Anmerkung: Die Menufunktionen können natürlich nur dann ausge­
+ führt werden, wenn die zugehörigen Programme in der aktuellen Task
+ zuvor insertiert wurden - ansonsten erscheint auf dem Bildschirm jeweils
+ der Hinweis 'unbekanntes Kommando'!)
+Fehler: Das Menu 'menuname' ist nicht in der angekoppelten Menukarte!
+
+
+#ib#infix namen#ie#
+THESAURUS PROC infix namen (THESAURUS CONST thes,
+ TEXT CONST infix):
+
+Zweck: Die Prozedur liefert einen Thesaurus, in dem alle Namen enthalten sind,
+ die in 'thes' übergeben wurden und die den Wortbestandteil 'infix' enthal­
+ ten (gleichgültig an welcher Position).
+
+
+THESAURUS PROC infix namen (THESAURUS CONST thes,
+ INT CONST dateityp):
+
+Zweck: Die Prozedur liefert einen Thesaurus, in dem alle Dateinamen enthalten
+ sind, die in 'thes' übergeben wurden und die den Dateityp 'dateityp'
+ haben.
+
+
+THESAURUS PROC infix namen (THESAURUS CONST thes,
+ TEXT CONST infix,
+ INT CONST dateityp):
+
+ wirkt wie: infix namen (infix namen (thes, infix), dateityp)
+
+
+#ib#install menu#ie#
+PROC install menu (TEXT CONST menukartenname,
+ BOOL CONST mit emblem):
+
+Zweck: Mit diesem Befehl wird die Menukarte mit dem Namen 'menukarten­
+ name' aus der Task 'gs-MENUKARTEN' in die aktuelle Task kopiert. Die
+ Menukarte wird als unbenannter Datenraum an die Task gekoppelt. Der
+ benannte Datenraum wird gelöscht. Der Name der angekoppelten Menu­
+ karte wird vermerkt.
+ Stimmt der Name der angekoppelten Menukarte mit dem Namen der
+ angeforderten Menukarte überein, dann wird nicht erneut eine Kopie
+ angefordert, sondern auf der bereits angekoppelten Menukarte gearbeitet.
+ Hat 'mit emblem' den Wert 'TRUE', dann wird unser 'Software-Emblem'
+ während des Ankoppelvorgangs auf dem Bildschirm ausgegeben, bei
+ 'FALSE' nicht.
+Fehler: Die Menukarte 'menukartenname' existiert nicht in der Task
+ 'gs-MENUKARTEN'.
+
+
+PROC install menu (TEXT CONST menukartenname):
+
+ wirkt wie: install menu (TEXT CONST menukartenname, TRUE)
+
+
+#ib#invers#ie#
+TEXT PROC invers (TEXT CONST text):
+
+Zweck: Liefert den Text 'text' invers dargestellt. An den Text wird zuvor ein Leer­
+ zeichen angehängt.
+
+
+#ib#kreuz#ie#
+TEXT PROC kreuz:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" als "Kreuz" (̗)
+ ausgegeben wird.
+
+
+PROC kreuz (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" als "Kreuz" ausgegeben werden soll.
+
+
+#ib#line#ie#
+PROC line (WINDOW VAR w, INT CONST anzahl):
+
+Zweck: Vergl. 'menuwindowline'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuwindowline' automatisch gesetzt wird.
+
+
+PROC line (WINDOW VAR w):
+
+ wirkt wie: line (w, 1)
+
+
+#ib#menualternative#ie#
+INT PROC menualternative (TEXT CONST infotext,
+ auswahlliste,
+ zusatztasten,
+ INT CONST position,
+ BOOL CONST mit abbruch):
+
+Zweck: Mit der Prozedur können dem Benutzer innerhalb des Menubildschirms
+ mehrere Alternativen zur Entscheidung angeboten werden, von denen er
+ sich für eine entscheiden kann.
+ Auf dem Bildschirm wird innerhalb des Menus eine Box ausgegeben.
+ Boxbreite und -höhe werden vom System automatisch anhand des über­
+ gebenen 'infotext'es (bzw. der 'auswahlliste') festgelegt. Der in 'infotext'
+ übergebene Text wird innerhalb der Box angezeigt. Der Text muß den
+ gs-DIALOG-Syntax-Regeln (sehen Sie Kap. 5.13) entsprechen - er dient
+ ausschließlich der Information des Benutzers.
+ In der letzten Zeile der Box wird die 'auswahlliste' angeboten. Zwischen
+ jeder notierten Alternative muß in 'auswahlliste' der code "13" eingetra­
+ gen sein. In der Box werden zwischen den Alternativen je drei Leerzei­
+ chen eingefügt. Es können maximal 10 Alternativen angegeben werden,
+ die aber incl. der eingefügten Leerzeichen eine Gesamtbreite von 64
+ Zeichen nicht überschreiten dürfen. Über diese Liste erfolgt durch Posi­
+ tionierung und anschließendem <RETURN> die Entscheidung für eine
+ Alternative. Die Prozedur liefert dann als Zahlenwert die Position der
+ gewählten Alternative in der übergebenen Auswahlliste.
+ Über 'mit abbruch' wird festgelegt, ob die Alternativentscheidung durch
+ die Tastenfolge <ESC><h> abgebrochen werden kann oder nicht. Ist
+ das zulässig und geschehen, dann wird der Wert 0 geliefert.
+ Über 'zusatztasten' kann noch festgelegt werden, ob die Entscheidung
+ auch durch Tippen bestimmter Tasten angegeben werden kann. Sind hier
+ Zeichen angegeben und erfolgt die Entscheidung über das Tippen einer
+ zugelassenen Taste, dann wird die Position der getippten Taste in der
+ unter 'zusatztasten' übergebenen Zeichenkette ermittelt und der Wert 100
+ hinzuaddiert (sehen Sie dazu auch Kap. 5.7).
+ Nach der Entscheidung wird der Menubildschirm automatisch in den
+ Ausgangszustand versetzt.
+
+
+#ib#menuanswer#ie#
+TEXT PROC menuanswer (TEXT CONST infotext,
+ vorgabe,
+ INT CONST position):
+
+Zweck: Die Prozedur ermöglicht den Dialog mit dem Benutzer innerhalb des
+ Menus. Sie liefert einen vom Benutzer eingegebenen (bzw. modifizierten)
+ Text/Namen.
+ Auf dem Bildschirm wird innerhalb des Menus eine Box ausgegeben.
+ Boxbreite und -höhe werden vom System automatisch anhand des über­
+ gebenen 'infotext'es festgelegt. Der in 'infotext' übergebene Text wird
+ innerhalb der Box angezeigt. Der Text muß den gs-DIALOG-Syntax-Regeln
+ (sehen Sie Kap. 5.13) entsprechen.
+ In der letzten Zeile der ausgegebenen Box erscheint der Text "Eingabe:".
+ Über 'vorgabe' kann dem Benutzer ein Text zum Editieren angeboten
+ werden. Mit 'position' wird die relative Lage der Box innerhalb des Menu­
+ bildschirms festgelegt (1, 2, 3, 4, 5: sehen Sie dazu Kap. 5.12).
+ Die Eingabe kann durch <RETURN> abgeschlossen oder durch
+ <ESC><h> abgebrochen werden, in letzterem Falle wird niltext ("")
+ geliefert.
+ Der gelieferte Wert ist von führenden und folgenden Leerzeichen befreit
+ (compress). Es ist nicht möglich, den Namen 'break' einzugeben (sehen
+ Sie dazu Kap.5.1).
+
+
+#ib#menuanswerone#ie#
+TEXT PROC menuanswerone (TEXT CONST infotext,
+ vorgabe, THESAURUS CONST thesaurus,
+ TEXT CONST ueberschrift, hinweis,
+ BOOL CONST mit reinigung):
+
+Zweck: Die Prozedur ist aus den zwei Prozeduren 'menuanswer' und 'menuone'
+ zusammengesetzt (sehen Sie auch dort). In einer Box innerhalb des
+ Menus wird der 'infotext' ausgegeben und eine Eingabe erwartet; ggf.
+ kann ein Text in 'vorgabe' zum Editieren ausgegeben werden. Wird die
+ Eingabe mit <RETURN> abgeschlossen, wird der eingegebene Text
+ geliefert. Statt der Eingabe kann der Benutzer sich durch die Tastenfolge
+ <ESC><z> auch die in 'thesaurus' übergebenen Namen zur Auswahl
+ anbieten lassen. Wird ein Name angekreuzt, wird dieser geliefert; wird die
+ Auswahl durch <ESC><h> abgebrochen, wird niltext ("") geliefert.
+Fehler: Fenster für Auswahl zu klein (x < 56, y < 15)
+
+
+#ib#menuanswersome#ie#
+THESAURUS PROC menuanswersome (TEXT CONST
+ infotext, vorgabe,
+ THESAURUS CONST thesaurus,
+ TEXT CONST ueberschrift, hinweis,
+ BOOL CONST mit reinigung):
+
+Zweck: Die Prozedur ist aus den zwei Prozeduren 'menuanswer' und 'menusome'
+ zusammengesetzt (sehen Sie auch dort). In einer Box innerhalb des
+ Menus wird der 'infotext' ausgegeben und eine Eingabe erwartet; ggf.
+ kann ein Text in 'vorgabe' zum Editieren ausgegeben werden. Wird die
+ Eingabe mit <RETURN> abgeschlossen, wird der eingegebene Text in
+ einem Thesaurus geliefert. Statt der Eingabe kann der Benutzer sich
+ durch die Tastenfolge <ESC><z> auch die in 'thesaurus' übergebenen
+ Namen zur Auswahl anbieten lassen. Werden Namen angekreuzt, werden
+ diese in einem Thesaurus geliefert; wird die Auswahl durch
+ <ESC><h> abgebrochen, wird ein leerer Thesaurus geliefert.
+Fehler: Fenster für Auswahl zu klein (x < 56, y < 15)
+
+
+#ib#menu archiv checken#ie#
+PROC menu archiv checken:
+
+Zweck: Über diese Prozedur kann das "Checken" von Dateien auf dem Archiv in
+ das Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbe­
+ dingt Kap. 6.1!
+
+
+#ib#menu archiv grundeinstellung#ie#
+PROC menu archiv grundeinstellung (INT CONST ort):
+
+Zweck: Hierüber wird die Grundeinstellung des Archivpakets vorgenommen: Dazu
+ wird als Zieltask das Archiv der eigenen Station eingestellt. Dieses wird
+ auch über eine Menunotiz im Menu angezeigt. Die entsprechenden Menu­
+ punkte werden aktiviert bzw. deaktiviert. Sehen Sie dazu unbedingt Kap.
+ 6.1!
+ Über 'ort' wird festgelegt, an welcher Stelle innerhalb des Menus die
+ Menunotiz zur Anzeige der Zieltask (und ggf. des Archivnamens) ausge­
+ geben wird (sehen Sie dazu Kap. 5.12).
+
+
+#ib#menu archiv holen#ie#
+PROC menu archiv holen:
+
+Zweck: Über diese Prozedur kann das Holen von Dateien vom Archiv in das
+ Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbedingt
+ Kap. 6.1!
+
+
+#ib#menu archiv initialisieren#ie#
+PROC menu archiv initialisieren:
+
+Zweck: Über diese Prozedur kann das Formatieren/ Initialisieren eines Archivs in
+ das Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbe­
+ dingt Kap. 6.1!
+
+
+#ib#menu archiv loeschen#ie#
+PROC menu archiv loeschen:
+
+Zweck: Über diese Prozedur kann das Löschen von Dateien auf dem Archiv in das
+ Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbedingt
+ Kap. 6.1!
+
+
+#ib#menu archiv neue diskette#ie#
+PROC menu archiv neue diskette:
+
+Zweck: Über diese Prozedur kann das Anmelden einer neuen Diskette bei schon
+ reserviertem Archiv in das Archiv-Pull-Down-Menu eingebunden werden.
+ Sehen Sie dazu unbedingt Kap. 6.1!
+
+
+#ib#menu archiv reservieren#ie#
+PROC menu archiv reservieren:
+
+Zweck: Über diese Prozedur kann die Archivreservierung in das Archiv-Pull-
+ Down-Menu eingebunden werden. Sehen Sie dazu unbedingt Kap. 6.1!
+
+
+#ib#menu archiv reservierung aufgeben#ie#
+PROC menu archiv reservierung aufgeben:
+
+Zweck: Über diese Prozedur kann eine bestehende Archivreservierung aus dem
+ Menu heraus aufgegeben werden. Sehen Sie dazu unbedingt Kap. 6.1!
+
+
+#ib#menu archiv schreibcheck#ie#
+PROC menu archiv schreibcheck:
+
+Zweck: Über diese Prozedur kann das Schreiben von Dateien auf das Archiv und
+ das sich automatisch daran anschließende "Checken" der zuvor geschrie­
+ benen Dateien in das Archiv-Pull-Down-Menu eingebunden werden.
+ Sehen Sie dazu unbedingt Kap. 6.1!
+
+
+#ib#menu archiv schreiben#ie#
+PROC menu archiv schreiben:
+
+Zweck: Über diese Prozedur kann das Schreiben von Dateien auf das Archiv in
+ das Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbe­
+ dingt Kap. 6.1!
+
+
+#ib#menu archiv verzeichnis#ie#
+PROC menu archiv verzeichnis:
+
+Zweck: Über diese Prozedur kann die Ausgabe eines Inhaltsverzeichnisses des
+ Archivs auf dem Bildschirm in das Archiv-Pull-Down-Menu eingebunden
+ werden. Sehen Sie dazu unbedingt Kap. 6.1!
+
+
+#ib#menu archiv verzeichnis drucken#ie#
+PROC menu archiv verzeichnis drucken:
+
+Zweck: Über diese Prozedur kann die Ausgabe eines Inhaltsverzeichnisses des
+ Archivs über den Drucker in das Archiv-Pull-Down-Menu eingebunden
+ werden. Sehen Sie dazu unbedingt Kap. 6.1!
+
+
+#ib#menu archiv zieltask einstellen#ie#
+PROC menu archiv zieltask einstellen:
+
+Zweck: Über diese Prozedur kann die Festlegung der Zieltask, mit der die Inter­
+ taskkommunikation abgewickelt werden soll, in das Archiv-Pull-Down-
+ Menu eingebunden werden. Sehen Sie dazu unbedingt Kap. 6.1!
+
+
+#ib#menu dateien aufraeumen#ie#
+PROC menu dateien aufraeumen:
+
+Zweck: Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+ Datei erfragt, die aufgeräumt, d.h. reorganisiert werden soll. Existiert
+ keine Datei mit dem angegebenen Namen, so erfolgt ein Hinweis darauf.
+ Statt der Eingabe des Dateinamens kann auch die Tastenfolge
+ <ESC><z> getippt werden. Daraufhin werden alle Dateinamen der
+ Task zur Auswahl angeboten. Hier können die gewünschten Dateinamen
+ angekreuzt werden. Anschließend werden die angekreuzten Dateien
+ reorganisiert. Der Vorgang wird auf dem Bildschirm protokolliert. Am
+ Ende des Vorgangs wird der Menubildschirm automatisch regeneriert. Es
+ können natürlich nur Dateien des Typs 1003 (Textfiles) reorganisiert
+ werden; sofern andere Dateien ausgewählt werden, erfolgt ein Hinweis
+ darauf.
+
+
+#ib#menu dateien drucken#ie#
+PROC menu dateien drucken:
+
+Zweck: Durch diese Prozedur wird innerhalb des aktuellen Menus (auch bei
+ geschachtelten(!)) der Name der Datei erfragt, die gedruckt werden soll.
+ Anschließend wird die Datei mit dem angegebenen Namen gedruckt.
+ Existiert keine Datei mit dem angegebenen Namen, so erfolgt ein Hinweis
+ darauf.
+ Statt der Eingabe des Dateinamens kann auch die Tastenfolge
+ <ESC><z> getippt werden. Daraufhin werden alle Dateinamen der
+ Task zur Auswahl angeboten. Alle angekreuzten Dateien werden an­
+ schließend gedruckt. Der Vorgang wird auf dem Bildschirm protokolliert.
+ Am Ende wird der Menubildschirm automatisch regeneriert.
+
+
+#ib#menu dateien kopieren#ie#
+PROC menu dateien kopieren:
+
+Zweck: Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+ Datei erfragt, die kopiert werden soll. Existiert keine Datei mit dem
+ angegebenen Namen, so erfolgt ein Hinweis darauf. Statt der Eingabe des
+ Dateinamens kann auch die Tastenfolge <ESC><z> getippt werden.
+ Daraufhin werden alle Dateinamen der Task zur Auswahl angeboten. Hier
+ kann ein Dateiname angekreuzt werden. Nun wird der Name erfragt, den
+ die Kopie erhalten soll. Existiert der Name bereits, erfolgt ein Hinweis
+ darauf, sonst wird die Datei kopiert. Der Menubildschirm wird automa­
+ tisch regeneriert.
+
+
+#ib#menu dateien loeschen#ie#
+PROC menu dateien loeschen:
+
+Zweck: Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+ Datei erfragt, die gelöscht werden soll. Anschließend wird die Datei mit
+ dem angegebenen Namen gelöscht, sofern die Sicherheitsabfrage zum
+ Löschen mit 'Ja' beantwortet wurde. Existiert keine Datei mit dem ange­
+ gebenen Namen, so erfolgt ein Hinweis darauf. Statt der Eingabe des
+ Dateinamens kann auch die Tastenfolge <ESC><z> getippt werden.
+ Daraufhin werden alle Dateinamen der Task zur Auswahl angeboten. Alle
+ angekreuzten Dateien werden anschließend (nach jeweiliger Sicherheits­
+ anfrage) gelöscht. Der Vorgang wird auf dem Bildschirm protokolliert. Am
+ Ende wird der Menubildschirm automatisch regeneriert.
+
+
+#ib#menu dateien speicherplatz#ie#
+PROC menu dateien speicherplatz:
+
+Zweck: Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+ Datei erfragt, deren Speicherplatz ermittelt werden soll. Existiert keine
+ Datei mit dem angegebenen Namen, so erfolgt ein Hinweis darauf. Statt
+ der Eingabe des Dateinamens kann auch die Tastenfolge <ESC><z>
+ getippt werden. Daraufhin werden alle Dateinamen der Task zur Aus­
+ wahl angeboten. Hier können die gewünschten Dateinamen angekreuzt
+ werden. Anschließend wird der Speicherplatz der angekreuzten Datei(en)
+ ermittelt und im Menufenster ausgegeben. Im Anschluß an die Anzeige
+ wird der Menubildschirm automatisch regeneriert.
+
+
+#ib#menu dateien umbenennen#ie#
+PROC menu dateien umbenennen:
+
+Zweck: Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+ Datei erfragt, die umbenannt werden soll. Existiert keine Datei mit dem
+ angegebenen Namen, so erfolgt ein Hinweis darauf. Statt der Eingabe des
+ Dateinamens kann auch die Tastenfolge <ESC><z> getippt werden.
+ Daraufhin werden alle Dateinamen der Task zur Auswahl angeboten. Hier
+ kann ein Dateiname angekreuzt werden. Nun wird der Name erfragt, den
+ die Datei anschließend erhalten soll. Existiert der Name bereits, erfolgt ein
+ Hinweis darauf, sonst wird die Datei umbenannt. Der Menubildschirm
+ wird automatisch regeneriert.
+
+
+#ib#menu dateien verzeichnis#ie#
+PROC menu dateien verzeichnis
+
+Zweck: Mit der Prozedur kann innerhalb des aktuellen Menus ein Verzeichnis der
+ Dateien der eigenen Task ausgegeben werden. Nach Verlassen des Ver­
+ zeichnisses durch <ESC><q> wird der Menubildschirm automatisch
+ regeneriert.
+
+
+#ib#menufootnote#ie#
+PROC menufootnote (TEXT CONST fussnotentext):
+
+Zweck: Mit der Prozedur kann der Text in der "Fußzeile" des aktuellen Menubild­
+ schirms (zumeist Hinweise an den Benutzer) ersetzt werden. Der vorhan­
+ dene Text wird gelöscht und stattdessen 'fussnotentext' notiert. Der Text
+ bleibt so lange erhalten, bis er durch eine andere selbstgesetzte Fußnote
+ ('menufootnote') oder durch die alte vom System gesetzte Fußnote ('old
+ menufootnote'; sehen Sie auch dort) überschrieben wird. Sofern
+ gs-DIALOG-Prozeduren aufgerufen werden, die selbst Ausgaben in der
+ Fußzeile machen, wird die durch 'menufootnote' gesetzte Fußnote eben­
+ falls überschrieben. Wenn der Text länger als die aktuelle Menubild­
+ schirmbreite ist,wird der Text abgeschnitten. Damit der Text auch in
+ geschachtelten Menus vollständig ausgegeben werden kann, sollte er nicht
+ länger als 69 Zeichen sein.
+
+
+#ib#menufunktion#ie#
+PROC menufunktion (TEXT CONST kuerzel,
+ punktbezeichnung,
+ prozedurname,
+ infotext):
+
+Zweck: Der Befehl wird für die Generierung von Menukarten benötigt. Mit diesem
+ Befehl wird in das aktuell geöffnete Menu unter dem aktuellen Oberbe­
+ griff eine Verarbeitungsfunktion eingetragen. Mit 'kuerzel' wird die Taste
+ bestimmt, über die die Verarbeitungsfunktion direkt aktiviert werden
+ kann. 'kuerzel' muß innerhalb eines Pull-Down-Menus eindeutig gewählt
+ sein! Unter 'punktbezeichnung' wird der Text eingetragen, der im Pull-
+ Down-Menu ausgegeben werden soll. In 'prozedurname' steht der Name
+ der Prozedur (als Text(!)), die bei Aktivierung des Menupunktes ausge­
+ führt werden soll. In 'infotext' steht der Text, der als Information zu
+ diesem Menupunkt bei Tippen der <?>-Taste angezeigt werden soll.
+Fehler: Menupunkt-Kürzel ist länger als ein Zeichen.
+ Menupunktkürzel kommt mehrfach vor.
+ Menupunktbezeichnung ist zu lang (> 60 Zeichen).
+ Zu viele Menupunkte in einem Pull-Down-Menu (> 15).
+
+
+#ib#menuinfo#ie#
+PROC menuinfo (TEXT CONST infotext, INT CONST
+ position, timelimit):
+
+Zweck: Die Prozedur ermöglicht es, innerhalb des Menus einen Hinweis (Infor­
+ mationstext) auszugeben. Im Menubildschirm erscheint der 'infotext' in
+ einer Box. Boxbreite und -höhe werden vom System automatisch anhand
+ des übergebenen 'infotext'es festgelegt. 'infotext' muß den gs-DIALOG-
+ Syntax-Regeln (sehen Sie Kap. 5.13) entsprechen. Mit 'position' wird die
+ relative Lage der Box innerhalb des Menubildschirms festgelegt (1, 2, 3,
+ 4, 5: sehen Sie dazu Kap. 5.12). Mit 'timelimit' kann die Zeitdauer (in
+ Zehntelsekunden) festgelegt werden, für die der Hinweis höchstens er­
+ scheint. Die Anzeige kann vom Benutzer durch Tippen einer beliebigen
+ Taste abgebrochen werden.
+
+
+PROC menuinfo (TEXT CONST infotext,
+ INT CONST position):
+
+ wirkt wie: menuinfo (infotext, position, maxint)
+
+
+PROC menuinfo (TEXT CONST infotext):
+
+ wirkt wie: menuinfo (infotext, 5)
+
+
+#ib#menukartenname#ie#
+TEXT PROC menukartenname:#u#(*)#e#
+Zweck: Liefert den Namen der zur zeit angekoppelten Menukarte. Ist keine
+ Menukarte angekoppelt, wird niltext ("") geliefert.
+
+
+#ib#menuno#ie#
+BOOL PROC menuno (TEXT CONST frage,
+ INT CONST position):
+
+ wirkt wie: NOT menuyes (frage, position)
+
+
+#ib#menuone#ie#
+TEXT PROC menuone (THESAURUS CONST thesaurus,
+ TEXT CONST ueberschrift,
+ hinweis,
+ BOOL CONST mit reinigung):
+
+Zweck: Durch die Prozedur werden dem Benutzer innerhalb des Menubild­
+ schirms Namen zur Auswahl angeboten. Nach Ankreuzen eines Namens
+ wird die Auswahl automatisch verlassen. Der angekreuzte Name wird
+ geliefert. Wird die Auswahl durch <ESC><h> abgebrochen, so wird
+ niltext ("") geliefert. In 'thesaurus' wird ein THESAURUS mit den Namen
+ übergeben, die zur Auswahl angeboten werden sollen (sehen Sie dazu
+ auch Kap. 5.14). Die beiden Texte 'ueberschrift' und 'hinweis' erscheinen
+ zur Kennzeichnung im Kopf der Auswahlliste: 'ueberschrift' zentriert und
+ invers dargestellt, 'hinweis' nur zentriert. Hat 'mit reinigung' den Wert
+ TRUE, so wird nach der Auswahl der Menubildschirm automatisch wie­
+ deraufgebaut, bei FALSE wird darauf verzichtet.
+Fehler: Fenster für Auswahl zu klein (x < 56, y < 15)
+
+
+#ib#menusome#ie#
+THESAURUS PROC menusome (THESAURUS CONST
+ thesaurus,
+ TEXT CONST ueberschrift,
+ hinweis,
+ BOOL CONST mit reinigung):
+
+Zweck: Durch die Prozedur werden dem Benutzer innerhalb des Menubild­
+ schirms Namen zur Auswahl angeboten. Die Auswahl kann durch die
+ Tastenfolge <ESC><q> verlassen werden. Der/ die angekreuzte(n)
+ Name(n) wird/werden in einem Thesaurus geliefert. Wird die Auswahl
+ durch die Tastenfolge <ESC><h> abgebrochen oder wurde kein Name
+ angekreuzt, dann wird ein leerer Thesaurus geliefert. In 'thesaurus' wird
+ ein Thesaurus mit den Namen übergeben, die zur Auswahl angeboten
+ werden sollen (sehen Sie dazu auch Kap. 5.14). Die beiden Texte
+ 'ueberschrift' und 'hinweis' erscheinen zur Kennzeichnung im Kopf der
+ Auswahlliste: 'ueberschrift' zentriert und invers dargestellt, 'hinweis' nur
+ zentriert. Hat 'mit reinigung' den Wert TRUE, so wird nach der Auswahl
+ der Menubildschirm automatisch wiederaufgebaut, bei FALSE wird darauf
+ verzichtet.
+Fehler: Fenster für Auswahl zu klein (x < 56, y < 15)
+
+
+#ib#menuwindowcenter#ie#
+TEXT PROC menuwindowcenter (TEXT CONST text):
+
+Zweck: Die Prozedur liefert einen Text, der so lang ist, wie das aktuelle Menufen­
+ ster breit ist. Dazu wird 'text' so mit Leerzeichen "ummantelt" daß 'text'
+ etwa in der Mitte zu stehen kommt. Steht der Cursor bei Ausgabe dieses
+ Textes am Anfang der Zeile, erscheint der Text zentriert in der Zeile
+ (vorhandene Zeileninhalte werden dadurch überschrieben (der Cursor
+ steht dann auf dem rechten Fensterrand!).
+
+
+#ib#menuwindowcursor#ie#
+PROC menuwindowcursor (INT CONST spalte, zeile):
+
+Zweck: Mit diesem Befehl kann der Cursor innerhalb des aktuellen Menufensters
+ positioniert werden. Ein "normales" Menufenster ist 77 Zeichen breit und
+ 20 Zeichen hoch; ein Menufenster in einem geschachtelten Menu ist 71
+ Zeichen breit und 16 Zeichen hoch). (Sehen Sie auch die Informations­
+ prozeduren 'get menuwindowcursor' und 'remaining menuwindowlines').
+Fehler: Wird außerhalb des aktuellen Menufensters positioniert, wird der Fenster­
+ inhalt gelöscht und die Fensterposition (1,1) angenommen.
+
+
+#ib#menuwindowedit#ie#
+PROC menuwindowedit (TEXT CONST dateiname):
+
+Zweck: Durch den Befehl wird innerhalb des Menus ein umrandetes Fenster
+ geöffnet und die Datei mit dem Namen 'dateiname' zum Editieren ausge­
+ geben. Auf die Größe des Menufensters kann kein Einfluß genommen
+ werden - sie wird selbständig vom System gesetzt ("normales" Menu: 77
+ Zeichen breit und 20 Zeichen hoch; geschachteltes Menu 71 Zeichen
+ breit und 16 Zeichen hoch).
+Fehler: Die Datei mit dem Namen 'dateiname' existiert nicht.
+
+
+PROC menuwindowedit (FILE VAR f):
+
+Zweck: Vergl. obige 'menuwindowedit'-Prozedur. Die Datei 'f' muß mit der Verar­
+ beitungsart 'modify' assoziiert worden sein.
+
+
+#ib#menuwindoweditget#ie#
+PROC menuwindoweditget (TEXT VAR text):#u#(*)#e#
+Zweck: Vergl. 'menuwindowget (TEXT VAR text)' Zusätzlich kann hier in 'text' ein
+ Text zum Editieren vorgegeben werden.
+Fehler: Text nicht initialisiert.
+
+
+#ib#menuwindowget#ie#
+PROC menuwindowget (TEXT VAR text):
+
+Zweck: Mit der Prozedur können Texte innerhalb des Menufensters eingelesen
+ werden (INTEGER- und REAL-Werte müssen ggf. "von Hand" konvertiert
+ werden). Die Eingabe wird durch <RETURN> abgeschlossen. Es muß
+ mindestens ein Zeichen (ungleich Leerzeichen) eingegeben werden. Von
+ der Eingabe werden die führenden Leerzeichen abgeschnitten. Ist der
+ einzugebende Text länger als die noch verbleibende Restzeile, so wird der
+ Text in der Restzeile gescrollt. Sind in der aktuellen Zeile weniger als 7
+ Zeichenpositionen für die Eingabe vorhanden, so wird automatisch für die
+ Eingabe an den Anfang der nächsten Zeile positioniert.
+
+
+#ib#menuwindowline#ie#
+PROC menuwindowline (INT CONST anzahl):
+
+Zweck: Die Prozedur 'menuwindowline' hat innerhalb des Menubildschirms eine
+ ähnliche Wirkung wie die Prozedur 'line' auf dem Gesamtbildschirm. Es
+ werden 'anzahl' Zeilenwechsel vorgenommen. Wird allerdings die untere
+ Grenze des Menubildschirms überschritten, dann rollt (scrollt) der Bild­
+ schirm nicht die entsprechende Anzahl Zeilen nach oben, statt dessen
+ wird der Fensterinhalt gelöscht und die Operation oben im Fenster fort­
+ gesetzt.
+
+
+PROC menuwindowline:
+
+ wirkt wie: menuwindowline (1)
+
+
+#ib#menuwindowout#ie#
+PROC menuwindowout (TEXT CONST text):
+
+Zweck: Mit der Prozedur können innerhalb des aktuellen Menufensters Texte
+ ausgegeben werden. Sollen INTEGER- oder REAL-Werte ausgegeben wer­
+ den, müssen diese zunächst in Texte konvertiert werden. Ist der Text
+ länger als die verbleibende Restzeile innerhalb des aktuellen Menufen­
+ sters, so wird der Text bis zum Fensterende (rechts) ausgegeben und die
+ Ausgabe am Anfang der nächsten Zeile fortgesetzt. Sobald die letzte Posi­
+ tion des aktuellen Menufensters (unten rechts in der Fensterecke) be­
+ schrieben wurde, wird der Fensterinhalt gelöscht und die Ausgabe an der
+ Position (1,1) des Fensters fortgesetzt.
+
+
+#ib#menuwindowpage#ie#
+PROC menuwindowpage:
+
+Zweck: Durch den Befehl 'menuwindowpage' wird der Inhalt des Fensters inner­
+ halb des aktuellen Menus gelöscht (das "Menufenster") (vergleichen Sie
+ auch 'show menuwindow'). Der Rahmen des Fensters (der bei 'show
+ menuwindow' ausgegeben wurde), bleibt bestehen, da er nicht mit zum
+ eigentlichen Fenster gehört. Durch den Befehl wird der Menubildschirm
+ nicht rekonstruiert! Soll das Fenster geschlossen werden, ist der Befehl
+ 'regenerate menuscreen' zu geben.
+
+
+#ib#menuwindowshow#ie#
+PROC menuwindowshow (TEXT CONST dateiname):
+
+Zweck: Vergl. 'menuwindowedit'-Prozedur. Die Datei 'dateiname' kann nicht
+ schreibend verändert werden.
+
+
+PROC menuwindowshow (FILE VAR f):
+
+Zweck: Vergl. obige 'menuwindowshow'-Prozedur. Die Datei 'f' muß mit der
+ Verarbeitungsart 'modify' assoziiert worden sein.
+
+
+#ib#menuwindowstop#ie#
+PROC menuwindowstop (INT CONST zeilenzahl):
+
+Zweck: Innerhalb des Menufensters werden 'zeilenzahl' Zeilenwechsel vorge­
+ nommen und der Text " Zum Weitermachen bitte irgendeine Taste tip­
+ pen!" ausgegeben. Danach wird so lange gewartet, bis eine Taste getippt
+ wird.
+
+
+PROC menuwindowstop:
+
+ wirkt wie: menuwindowstop (2)
+
+
+#ib#menuyes#ie#
+BOOL PROC menuyes (TEXT CONST frage,
+ INT CONST position):
+
+Zweck: Die Prozedur dient dazu, innerhalb des Menus eine Ja/Nein-Entscheidung
+ des Benutzers einzuholen. Im Gegensatz zur Standardprozedur 'yes'
+ arbeitet diese Prozedur unabhängig davon, ob der Kommandodialog ein-
+ oder ausgeschaltet ist. Auf dem Bildschirm wird innerhalb des Menus eine
+ Box ausgegeben. Boxbreite und -höhe werden vom System automatisch
+ anhand der übergebenen 'frage' festgelegt. Der in 'frage' übergebene Text
+ wird um ein Fragezeichen (?) ergänzt und innerhalb der Box angezeigt.
+ Der Text muß den gs-DIALOG-Syntax-Regeln (sehen Sie Kap. 5.13)
+ entsprechen. In der letzten Zeile der ausgegebenen Box erscheint der Text
+ "Ja    Nein". Die Prozedur 'menuyes' liefert TRUE, wenn mit 'Ja' geantwor­
+ tet wurde und FALSE, wenn mit 'Nein' geantwortet wurde (durch Tippen
+ der Anfangsbuchstaben oder Positionierung auf die Antwort und ab­
+ schließendes <RETURN>). Der Menubildschirm wird automatisch
+ regeneriert. Mit 'position' wird die relative Lage der Box innerhalb des
+ Menubildschirms festgelegt (1, 2, 3, 4, 5: sehen Sie dazu Kap. 5.12).
+
+
+#ib#no#ie#
+BOOL PROC no (WINDOW VAR w, TEXT CONST frage):
+
+ wirkt wie: NOT yes (w, frage).
+
+
+#ib#not empty#ie#
+BOOL PROC not empty (THESAURUS CONST thes):
+
+Zweck: Dient der Prüfung, ob ein Thesaurus Namen enthält oder nicht. Die
+ Prozedur liefert TRUE, wenn Namen in 'thes' enthalten sind, sonst FALSE.
+
+
+#ib#oberbegriff#ie#
+PROC oberbegriff (TEXT CONST punktname,
+ startprocname,
+ leaveprocname):
+
+Zweck: Der Befehl wird bei der Generierung von Menukarten benötigt. Mit diesem
+ Befehl wird die Bezeichnung 'punktname' in die Kopfzeile des aktuell
+ geöffneten Menus eingetragen. Die in 'startprocname' übergebene Proze­
+ dur wird ausgeführt, bevor das zugehörige Pull-Down-Menu auf dem
+ Bildschirm "ausgeklappt" wird; die in 'leaveprocname' übergebene Pro­
+ zedur, wenn in ein anderes Pull-Down-Menu gewechselt wird (beachten
+ Sie, daß die Prozedurnamen als Texte(!) übergeben werden).
+Fehler: Menukarte noch nicht geöffnet ('oeffne menukarte' fehlt).
+ Menu noch nicht geöffnet ('oeffne menu' fehlt).
+ Zu viele Oberbegriffe im Menu (> 10).
+ Die Kopfzeile ist zu lang (> 70 Zeichen).
+
+
+PROC oberbegriff (TEXT CONST punktname):
+
+ wirkt wie: oberbegriff (punktname, "", "")
+
+
+#ib#oeffne menu#ie#
+PROC oeffne menu (TEXT CONST menuname,
+ einstiegsproc,
+ ausstiegsproc, infotext1,
+ infotext2, infotext3):
+
+Zweck: Der Befehl wird für die Generierung von Menukarten benötigt. Durch den
+ Befehl wird innerhalb der Menukarte ein Menu mit dem Namen
+ 'menuname' angelegt. Über diesen Namen kann das Menu auch später
+ angesprochen werden (mit 'handle menu'). Die unter 'einstiegsproc'
+ übergebene Prozedur wird bei der Aktivierung des Menus ausgeführt, die
+ unter 'ausstiegsproc' übergebene Prozedur, wenn das Menu (mit
+ <ESC><q>) verlassen wird (beachten Sie, daß die Prozedurnamen als
+ Texte(!) übergeben werden!). In 'infotext1', 'infotext2' und 'infotext3'
+ können Hinweise eingetragen werden, die bei Erscheinen des Menus auf
+ dem Bildschirm für kurze Zeit in einer Box rechts unten angezeigt wer­
+ den. Die Erstellung der Boxtexte ist an genaue Regeln gebunden (sehen
+ Sie dazu Kap. 5.13). Sehen Sie auch bei 'schliesse menu'.
+
+
+PROC oeffne menu (TEXT CONST menuname,
+ einstiegsproc,
+ ausstiegsproc):
+
+ wirkt wie: oeffne menu (menuname, einstiegsproc,
+ ausstiegsproc, "", "", "")
+
+
+PROC oeffne menu (TEXT CONST menuname):
+
+ wirkt wie: oeffne menu (menuname, "", "")
+
+
+#ib#oeffne menukarte#ie#
+PROC oeffne menukarte (TEXT CONST menukartenname):
+
+Zweck: Der Befehl wird bei der Generierung von Menukarten benötigt. Ein Pro­
+ gramm zur Erstellung einer Menukarte muß immer mit diesem Befehl
+ beginnen. Durch den Befehl wird ein Datenraum mit dem Namen
+ 'gs-MENUKARTE:menukartenname' eingerichtet; der Wortbestandteil
+ 'gs-MENUKARTE:' wird dabei automatisch vor den angegebenen Namen
+ gesetzt (sehen Sie auch 'schliesse menukarte').
+Fehler: Eine Menukarte mit dem angegebenen Namen existiert bereits in der
+ Task. Bei der Generierung wird dann angefragt, ob die alte Menukarte
+ gelöscht werden darf.
+
+
+#ib#ohne praefix#ie#
+THESAURUS PROC ohne praefix (THESAURUS CONST thes,
+ TEXT CONST praefix):
+
+Zweck: Liefert in einem Thesaurus alle Namen aus dem übergebenen Thesaurus
+ 'thes', die mit dem Wortbestandteil 'praefix' beginnen. Bei den gelie­
+ ferten Namen ist dieser führende Wortbestandteil entfernt.
+
+
+#ib#old menufootnote#ie#
+PROC old menufootnote:
+
+Zweck: Der aktuelle Text in der Fußzeile des aktuellen Menubildschirms wird
+ durch den hier zuletzt vom System gesetzten Text überschrieben. Die
+ Prozedur wird benutzt, um eine selbstgesetzte Fußnote (sehen Sie auch
+ 'write menunotice') zu löschen.
+
+
+#ib#out#ie#
+PROC out (WINDOW VAR w, TEXT CONST text):
+
+Zweck: Vergl. 'menuwindowout'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuwindowout' automatisch gesetzt wird.
+
+
+#ib#out frame#ie#
+PROC out frame (WINDOW VAR fenster):
+
+Zweck: Um den durch 'fenster' angegebenen Bildschirmbereich wird ein Rahmen
+ gezogen.
+
+
+#ib#out footnote#ie#
+PROC out footnote (WINDOW VAR fenster,
+ TEXT CONST textzeile):
+
+Zweck: In der untersten Zeile des Fensters 'fenster' wird 'textzeile' ausgegeben, in
+ der vorletzten Zeile eine Trennzeile. Sehen Sie auch 'erase footnote'.
+
+
+#ib#page#ie#
+PROC page (WINDOW VAR fenster,
+ BOOL CONST mit rahmen):
+
+Zweck: Der durch 'fenster' beschriebene Fensterbereich wird gelöscht. Hat 'mit
+ rahmen' den Wert TRUE, wird der Rahmenbereich ebenfalls gelöscht.
+
+
+PROC page (WINDOW VAR fenster):
+
+ wirkt wie: page (fenster, FALSE).
+
+
+#ib#put#ie#
+PROC put (WINDOW VAR w, TEXT CONST text):
+
+ wirkt wie: out (w, text + " ")
+
+
+PROC put (WINDOW VAR w, INT CONST zahl):
+
+ wirkt wie: put (w, text (zahl))
+
+
+PROC put (WINDOW VAR w, REAL CONST zahl):
+
+ wirkt wie: put (w, text (zahl))
+
+
+#ib#putline#ie#
+PROC putline (WINDOW VAR w, TEXT CONST text):
+
+ wirkt wie: put (w, text); line (w)
+
+
+#ib#regenerate menuscreen#ie#
+PROC regenerate menuscreen:
+
+Zweck: Der Befehl wird verwendet, um den Menubildschirm (z.B. nach der
+ Nutzung für anwendungsbezogene Ausgaben) in seinem letzten Zustand
+ zu reproduzieren. Der Bildschirm wird gelöscht. Anschließend wird der
+ aktuelle Menubildschirm vollständig neu aufgebaut - auch bei geschach­
+ telten Menus. (sehen Sie auch 'refresh submenu')
+
+
+#ib#refresh submenu#ie#
+PROC refresh submenu:
+
+Zweck: Der Befehl dient dazu, das aktuelle Pull-Down-Menu (z.B. nach Über­
+ schreiben) und ggf. eine gesetzte Menunotiz erneut auf den Bildschirm zu
+ schreiben. Betroffen ist nur der Bereich zwischen den Trennlinien der
+ Kopf- und Fußzeile. Für das vorausgehende Löschen verwendeter Bild­
+ schirmbereich ist der Programmierer verantwortlich. Im Gegensatz zu
+ 'regenerate menuscreen' findet hier kein kompletter Bildschirmaufbau
+ statt. Wenn möglich, dann ist dieser Befehl dem Befehl 'regenerate
+ menuscreen' wegen des geringeren Zeitaufwandes vorzuziehen.
+
+
+#ib#remaining lines#ie#
+INT PROC remaining lines (WINDOW VAR w):
+
+Zweck: Die Prozedur liefert die Anzahl der Zeilen im Fenster 'w', die noch
+ zwischen Cursor und unterer Fenstergrenze vorhanden sind.
+
+
+#ib#remaining menuwindowlines#ie#
+INT PROC remaining menuwindowlines
+
+Zweck: Die Prozedur liefert die Anzahl der Zeilen im aktuellen Menufenster, die
+ noch zwischen Cursor und unterer Fenstergrenze vorhanden sind.
+
+
+#ib#reset dialog#ie#
+PROC reset dialog:
+
+Zweck: Das Menusystem wird in den Anfangszustand versetzt. (Keine Menukarte
+ angekoppelt; Anzahl der geöffneten Menus: 0)
+
+
+#ib#schliesse menu#ie#
+PROC schliesse menu:
+
+Zweck: Der Befehl wird bei der Generierung von Menukarten benötigt. Durch den
+ Befehl wird ein Menu in einer Menukarte abgeschlossen (sehen Sie auch
+ 'oeffne menu')
+
+
+#ib#schliesse menukarte#ie#
+PROC schliesse menukarte
+
+Zweck: Der Befehl wird bei der Generierung von Menukarten benötigt. Durch den
+ Befehl wird eine Menukarte abgeschlossen (sehen Sie auch 'oeffne
+ menukarte')
+
+
+#ib#senkrecht#ie#
+TEXT PROC senkrecht:
+
+ Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" als senkrechter
+ Strich (�) ausgegeben wird.
+
+
+PROC senkrecht (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" als senkrechter Strich ausgegeben werden soll.
+
+
+#ib#show#ie#
+PROC show (WINDOW VAR fenster):
+
+Zweck: Das Fenster 'fenster' wird auf dem Bildschirm angezeigt (das Fenster
+ muß zuvor durch 'window' initialisiert worden sein). Um den angegebe­
+ nen Fensterbereich wird automatisch ein Rahmen gezogen. Der Rahmen
+ gehört nicht zum Fenster dazu! (Soll das Fenster ohne Rahmen ausgege­
+ ben werden, dann muß der Befehl 'page' verwendet werden.) Der Bereich
+ innerhalb des Rahmens (Fensterbereich) wird gelöscht.
+
+
+#ib#show#ie#
+PROC show (WINDOW VAR w, TEXT CONST dateiname):
+
+Zweck: Vergl. 'menuwindowshow'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuwindowshow' automatisch gesetzt wird.
+
+
+PROC show (WINDOW VAR w, FILE VAR f):
+
+Zweck: Vergl. 'menuwindowshow'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuwindowshow' automatisch gesetzt wird.
+
+
+#ib#show menuwindow#ie#
+PROC show menuwindow:
+
+Zweck: Durch den Befehl 'show menuwindow' wird ein entsprechender Rahmen
+ innerhalb des Menubildschirms ausgegeben und der Bereich innerhalb
+ dieses Rahmens (das Fenster) gelöscht (sehen Sie auch 'menuwindow­
+ page'). Innerhalb des Fensters können anschließend verschiedene Opera­
+ tionen ausgeführt werden. Auf die Größe des Menufensters kann kein
+ Einfluß genommen werden - sie wird selbständig vom System gesetzt
+ ("normales" Menu: 77 Zeichen breit und 20 Zeichen hoch; geschachteltes
+ Menu 71 Zeichen breit und 16 Zeichen hoch).
+
+
+#ib#stdinfoedit#ie#
+PROC stdinfoedit (TEXT CONST dateiname):#u#(*)#e#
+Zweck: Löscht den Bildschirm und bietet die Datei 'dateiname' in einem festge­
+ legten zum Editieren an. In der Fußzeile wird die Information "Info:
+ <ESC><?>  Verlassen: <ESC><q>" angezeigt. Nach Tippen von
+ <ESC><?> werden Editorinformationen in den Bildschirm einge­
+ blendet.
+
+
+PROC stdinfoedit (FILE VAR f):#u#(*)#e#
+Zweck: Wie obige 'stdinfoedit'-Prozedur'. Die Datei 'f' muß mit der Verarbei­
+ tungsart 'modify' assoziiert worden sein.
+
+
+PROC stdinfoedit (TEXT CONST dateiname,
+ INT CONST oberste zeile):#u#(*)#e#
+Zweck: Wie obige Prozedur (die wie 'stdwinfoedit (w, 1)' wirkt). Allerdings kön­
+ nen bis zu zwei Zeilen oben auf dem Bildschirm unbenutzt bleiben (z.B.
+ um die Kopfzeile des Menus weiterhin anzuzeigen). 'oberste zeile' gibt an,
+ welche Bildschirmzeile die erste von dieser Prozedur benutzte ist
+ (1<= oberste zeile<=3).
+
+
+PROC stdinfoedit (FILE VAR f,
+ INT CONST oberste zeile):#u#(*)#e#
+Zweck: Wie obige 'stdinfoedit'-Prozedur'. Die Datei 'f' muß mit der Verarbei­
+ tungsart 'modify' assoziiert worden sein.
+
+
+#ib#stop#ie#
+PROC stop (WINDOW VAR w, INT CONST zeilenzahl):
+
+Zweck: Vergl. 'menuwindowstop'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuwindowstop' automatisch gesetzt wird.
+
+
+PROC stop (WINDOW VAR w):
+
+ wirkt wie: stop (w, 1).
+
+
+#ib#testinstallation#ie#
+PROC testinstallation (TEXT CONST menutafelname):
+
+Zweck: Die Menutafel mit dem Namen 'menutafelname' (muß mit dem
+ 'gs-MENUKARTE:' beginnen!) wird als aktuelle Menutafel an gs-DIALOG
+ gekoppelt. Durch den Befehl wird die angegebene Menutafel zur Task
+ 'gs-MENUAKRTEN' geschickt. Dem Namen wird zur Kennzeichnung noch
+ der Taskname der Sendertask angehängt (dadurch können sich bei
+ Multi-User-Betrieb verschiedene Anwender mit gleichen Menukarten­
+ namen nicht stören). Die Menukarte wird anschließend in jedem Fall
+ "frisch" angekoppelt. Außerdem bleibt die Menukarte (als benannter
+ Datenraum) in der Task erhalten!
+ (Mit dem Befehl 'handle menu' kann nun ein Menu aus der Menukarte
+ zur Ausführung gebracht werden oder mit 'anwendungstext' auf in die
+ Menukarte ausgelagerte Texte zugegriffen werden.)
+ Hinweis: Von Zeit zu Zeit muß der Systembetreuer die überflüssigen
+ Menukarten aus der Task 'gs-MENUKARTEN' entfernen, da die Anwender
+ aus Ihrer Task die Karten nicht löschen können!
+Fehler: 'menutafelname' gibt es nicht!
+ 'menutafelname' hat falsche(n) Typ/Bezeichnung (keine
+ gs-MENUKARTE)!
+
+
+#ib#trennlinie#ie#
+PROC trennlinie:
+
+Zweck: Der Befehl wird bei der Generierung von Menukarten benötigt. Durch den
+ Befehl wird unter dem aktuellen Oberbegriff eine Trennlinie zur opti­
+ schen Trennung einzelner Menupunkte eingetragen. Die Trennlinie belegt
+ den gleichen Platz wie eine Verarbeitungsfunktion.
+Fehler: Zu viele Menupunkte in einem Pull-Down-Menu (maximal 15 incl. der
+ Trennlinien!).
+
+
+#ib#textprozedur#ie#
+PROC textprozedur (TEXT CONST dateiname,
+ prozedurname):
+
+Zweck: Der Befehl wird benötigt, um Texte entsprechend der gs-DIALOG-Syntax
+ aufzuarbeiten. Der in die Datei 'dateiname' geschrieben Text wird bear­
+ beitet. Die Prozedur eignet sich insbesondere dafür, Informationstexte
+ aufzuarbeiten, die zu den einzelnen Menufunktionen ausgegeben werden,
+ wenn der Benutzer die Tastenfolge <ESC><?> tippt (sehen Sie auch
+ 'textzeile'). Der aufbereitete Text steht anschließend in der Datei 'datei­
+ name.a'. Der Text ist in eine Textprozedur "verpackt", die den Namen hat,
+ der als zweiter Parameter übergeben wird.
+ Die Zeilen werden dabei so zugeschnitten, daß Sie in einer Box in das
+ aktuelle Menu eingeblendet werden können. Boxbreite und -höhe werden
+ automatisch gesetzt (max. 65 Zeichen breit und 14 Zeichen hoch)); die
+ Zeilen werden geblockt, sofern in der Datei keine Absatzmarkierung
+ (<RETURN>) am Ende der Zeile vorhanden ist. Soll eine Zeile zentriert
+ werden, so muß als erstes Zeichen der Zeile das Zeichen '%' notiert sein -
+ die Zeile muß durch eine Absatzmarke abgeschlossen sein. Textpassagen,
+ die invers (markiert) dargestellt werden sollen, müssen duch das Zeichen
+ '$' eingeleitet und durch das Zeichen '&' abgeschlossen werden. Markier­
+ te Textpassagen dürfen (nach dem Zuschnitt!) nicht über Zeilengrenzen
+ hinausgehen!
+Fehler: Datei 'dateiname' existiert nicht!
+ Fonttabelle 'fonttab.gs-Menu-Generator' existiert nicht! (Fonttabelle von
+ gs-Menu-Generator-Diskette in die Task 'configurator' laden!)
+ Text ist zu lang - bitte kürzen! (Text darf in aufbereiteter Form maximal
+ 14 Zeilen umfassen!)
+ Zeilenformatierung mit <ESC> abgebrochen!
+
+
+
+#ib#textzeile#ie#
+PROC textzeile (TEXT CONST dateiname):
+
+Zweck: Der Befehl wird benötigt, um Texte entsprechend der gs-DIALOG-Syntax
+ aufzuarbeiten. Der in die Datei 'dateiname' geschrieben Text wird bear­
+ beitet. Die Prozedur eignet sich insbesondere dafür, anwendungsbezogene
+ Texte aufzuarbeiten, die in die Menukarte ausgelagert werden sollen
+ (sehen Sie auch 'textprozedur'). Der aufbereitete Text steht anschließend
+ in der Datei 'dateiname.a' in einer Zeile notiert.
+
+
+#ib#waagerecht#ie#
+TEXT PROC waagerecht:
+
+Zweck: Liefert das Zeichen, das bei der Darstellung der "Kästen" als waagerechter
+ Strich (̇) ausgegeben wird.
+
+
+PROC waagerecht (TEXT CONST zeichen):
+
+Zweck: Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+ stellung der "Kästen" als waagerechter Strich ausgegeben werden soll.
+
+
+#ib#window#ie#
+WINDOW PROC window (INT CONST x, y, xsize, ysize):
+
+Zweck: Einer Fenstervariablen (WINDOW VAR name) wird die Lage und Größe
+ zugeordnet (über den Zuweisungsoperator ':='). Gleichzeitig wird das
+ Fenster initialisiert.
+ Mit den ersten beiden Parametern wird die Lage der linken oberen Ecke
+ des Fensters bestimmt (x: Spalte; y: Zeile). Mit 'xsize' wird die Fenster­
+ breite, mit 'ysize' die Fensterhöhe festgelegt.
+ Das Fenster wird noch nicht(!) angezeigt (sehen Sie dazu 'show' und
+ 'page'). Ein Rahmen wird nicht zum Fenster gezählt; er kann aber mit
+ der Prozedur 'show' ausgegeben werden. Ein Fenster darf nicht breiter als
+ 80 und höher als 24 Zeichen sein. Umrahmte Fenster unterliegen weite­
+ ren Einschränkungen (sehen Sie auch 'show'). Ein Fenster muß min­
+ destens 6 Zeichen breit und 3 Zeichen hoch sein.
+Fehler: 'Window' ungültig
+
+
+#ib#write menunotice#ie#
+PROC write menunotice (TEXT CONST notiztext,
+ INT CONST position):
+
+Zweck: Die Prozedur dient dazu, innerhalb des Menus in einer Box einen "dauer­
+ haften Informationstext" auszugeben. Die Box bleibt nämlich so lange
+ bestehen, bis sie explizit gelöscht (sehen Sie auch 'erase menunotice')
+ oder durch einen neuen Notiztext überschrieben wird. Wenn der Bild­
+ schirm durch gs-DIALOG-Prozeduren überschrieben wird, wird die
+ Menunotiz ebenfalls ständig mitaufgefrischt und auch, wenn der Befehl
+ 'regenerate menuscreen' oder 'refresh submenu' gegeben wird (Sehen Sie
+ im Gegensatz dazu auch 'menuinfo' ("kurzzeitiger Informationstext").
+ Im Menubildschirm erscheint der 'infotext' in einer Box. Boxbreite und
+ -höhe werden vom System automatisch anhand des übergebenen 'notiz­
+ text'es festgelegt. 'notiztext' muß den gs-DIALOG-Syntax-Regeln (sehen Sie
+ Kap. 5.13) entsprechen. Mit 'position' wird die relative Lage der Box
+ innerhalb des Menubildschirms festgelegt (1, 2, 3, 4, 5: sehen Sie dazu
+ Kap. 5.12). In einem Menu kann zu einem Zeitpunkt nur eine Menunotiz
+ abgelegt werden. Durch ein erneutes 'write menunotice' wir eine beste­
+ hende Menunotiz überschrieben.
+
+
+#ib#yes#ie#
+BOOL PROC yes (WINDOW VAR w, TEXT CONST frage):
+
+Zweck: Vergl. 'menuwindowyes'. Hier wird nur zusätzlich das Fenster festgelegt,
+ das bei 'menuwindowyes' automatisch gesetzt wird.
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.impressum b/doc/menugenerator/menu-generator handbuch.impressum
new file mode 100644
index 0000000..404826d
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.impressum
@@ -0,0 +1,88 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#ls Menü-Generator
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+
+#free (4.0)##on("b")#
+#center#gs-Menu-Generator
+
+
+#center#Benutzerhandbuch
+
+
+#center#Version 1.0
+
+
+#off("b")##center#copyright
+#center#Eva Latta-Weber
+#center#Software- und Hardware-Systeme, 1988
+#center#ERGOS GmbH, 1990
+#page#
+#block#
+#center#____________________________________________________________________________
+
+
+Copyright:  ERGOS GmbH   März 1990
+
+ Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+ maschinenlesbare Form sowie das Speichern in Informations­
+ systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+ der ERGOS GmbH gestattet.
+
+
+#center#____________________________________________________________________________
+
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender.
+
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden.
+
+Texterstellung :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+ erstellt und aufbereitet und auf einem Kyocera Laser­
+ drucker gedruckt.
+
+
+
+
+#center#___________________________________________________________________________
+
+
+
+Ergonomic Office Software GmbH
+
+Bergstr. 7 Telefon: (02241) 63075
+5200 Siegburg Teletex: 2627-2241413=ERGOS
+ Telefax: (02241) 63078
+
+
+#center#____________________________________________________________________________
+
diff --git a/doc/menugenerator/menu-generator handbuch.index b/doc/menugenerator/menu-generator handbuch.index
new file mode 100644
index 0000000..0aacd97
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.index
@@ -0,0 +1,258 @@
+#block##pageblock#
+#pagenr("%",1)##setcount(1)##count per page#
+#headeven#
+gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#right#gs-Menu-Generator
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+I - % #right#ERGOS
+#end#
+#bottomodd#
+#center#____________________________________________________________
+ERGOS #right# I - %
+#end#
+Index
+
+
+activate 5 - 28
+activate 8 - 1
+anwendungstext 4 - 13
+anwendungstext 8 - 2
+areax 8 - 2
+areaxsize 8 - 2
+areay 8 - 2
+areaysize 8 - 2
+balken links 8 - 2
+balken oben 8 - 3
+balken rechts 8 - 3
+balken unten 8 - 3
+boxalternative 8 - 4
+boxalternative 7 - 10
+boxanswer 8 - 4
+boxanswer 7 - 9
+boxanswerone 8 - 4
+boxanswerone 7 - 10
+boxanswersome 8 - 5
+boxanswersome 7 - 10
+boxinfo 8 - 5
+boxinfo 7 - 9
+boxno 8 - 5
+boxno 7 - 10
+boxnotice 8 - 6
+boxnotice 7 - 10
+boxone 8 - 6
+boxone 7 - 10
+boxsome 8 - 6
+boxsome 7 - 10
+boxyes 8 - 7
+boxyes 7 - 10
+center 8 - 7
+center 7 - 8
+clear buffer 8 - 7
+clear buffer and count 8 - 7
+current menuwindow 8 - 8
+cursor 8 - 8
+cursor 7 - 6
+cursor off 8 - 8
+cursor off 5 - 6
+cursor off 5 - 2
+cursor on 8 - 8
+cursor on 5 - 6
+cursor on 5 - 2
+deactivate 8 - 9
+deactivate 5 - 28
+direktstart 8 - 9
+ecke oben links 8 - 10
+ecke oben rechts 8 - 10
+ecke unten links 8 - 10
+ecke unten rechts 8 - 10
+edit 8 - 11
+edit 7 - 6
+editget 8 - 11
+erase 7 - 5
+erase 8 - 11
+erase footnote 8 - 12
+erase footnote 7 - 11
+erase menunotice 8 - 12
+erasemenunotice 5 - 15
+get 8 - 12
+get 7 - 7
+get cursor 8 - 13
+get cursor 7 - 6
+getline 7 - 7
+getline 8 - 13
+get menuwindowcursor 5 - 21
+get menuwindowcursor 8 - 13
+handle menu 3 - 2
+handle menu 8 - 13
+infix namen 8 - 14
+infix namen 5 - 26
+install menu 3 - 2
+install menu 4 - 3
+install menu 8 - 14
+invers 8 - 15
+kreuz 8 - 15
+line 8 - 15
+line 7 - 6
+menualternative 8 - 15
+menualternative 5 - 12
+menuanswer 8 - 17
+menuanswer 5 - 2
+menuanswerone 8 - 17
+menuanswerone 5 - 8
+menuanswersome 5 - 8
+menuanswersome 8 - 18
+menu archiv checken 8 - 18
+menu archiv checken 6 - 4
+menu archiv grundeinstellung 6 - 4
+menu archiv grundeinstellung 8 - 18
+menu archiv holen 8 - 19
+menu archiv holen 6 - 4
+menu archiv initialisieren 8 - 19
+menu archiv initialisieren 6 - 4
+menu archiv loeschen 8 - 19
+menu archiv loeschen 6 - 4
+menu archiv neue diskette 8 - 19
+menu archiv neue diskette 6 - 4
+menu archiv reservieren 6 - 4
+menu archiv reservieren 8 - 19
+menu archiv reservierung aufgeben 6 - 4
+menu archiv reservierung aufgeben 8 - 19
+menu archiv schreibcheck 8 - 20
+menu archiv schreibcheck 6 - 4
+menu archiv schreiben 6 - 4
+menu archiv schreiben 8 - 20
+menu archiv verzeichnis 8 - 20
+menu archiv verzeichnis 6 - 4
+menu archiv verzeichnis drucken 6 - 4
+menu archiv verzeichnis drucken 8 - 20
+menu archiv zieltask einstellen 6 - 4
+menu archiv zieltask einstellen 8 - 20
+menu dateien aufraeumen 8 - 21
+menu dateien aufraeumen 6 - 6
+menu dateien drucken 6 - 6
+menu dateien drucken 8 - 21
+menu dateien kopieren 6 - 6
+menu dateien kopieren 8 - 22
+menu dateien loeschen 8 - 22
+menu dateien loeschen 6 - 6
+menu dateien speicherplatz 6 - 6
+menu dateien speicherplatz 8 - 22
+menu dateien umbenennen 8 - 23
+menu dateien umbenennen 6 - 6
+menu dateien verzeichnis 6 - 6
+menu dateien verzeichnis 8 - 23
+menufootnote 5 - 17
+menufootnote 8 - 23
+menufunktion 4 - 6
+menufunktion 8 - 24
+menuinfo 5 - 4
+menuinfo 8 - 24
+menukartenname 8 - 25
+menuno 8 - 25
+menuno 5 - 10
+menuone 5 - 6
+menuone 8 - 25
+menusome 5 - 7
+menusome 8 - 26
+menuwindowcenter 8 - 26
+menuwindowcenter 5 - 23
+menuwindowcursor 5 - 21
+menuwindowcursor 8 - 27
+menuwindowedit 8 - 27
+menuwindowedit 5 - 19
+menuwindoweditget 8 - 27
+menuwindoweditget 5 - 22
+menuwindowget 8 - 28
+menuwindowget 5 - 22
+menuwindowline 8 - 28
+menuwindowline 5 - 21
+menuwindowno 5 - 22
+menuwindowout 5 - 22
+menuwindowout 8 - 28
+menuwindowpage 8 - 29
+menuwindowpage 5 - 20
+menuwindowshow 5 - 19
+menuwindowshow 8 - 29
+menuwindowstop 5 - 23
+menuwindowstop 8 - 29
+menuwindowyes 5 - 22
+menuyes 5 - 10
+menuyes 8 - 30
+no 8 - 30
+no 7 - 7
+not empty 5 - 27
+not empty 8 - 30
+oberbegriff 8 - 31
+oberbegriff 4 - 5
+oeffne menu 8 - 31
+oeffne menu 4 - 3
+oeffne menukarte 8 - 32
+oeffne menukarte 4 - 3
+ohne praefix 5 - 26
+ohne praefix 8 - 32
+oldmenufootnote 5 - 17
+old menufootnote 8 - 32
+out 7 - 7
+out 8 - 33
+out footnote 7 - 11
+out footnote 8 - 33
+out frame 8 - 33
+out frame 7 - 5
+page 8 - 33
+page 7 - 11
+page 7 - 5
+page up 7 - 11
+put 8 - 33
+put 7 - 7
+putline 8 - 34
+putline 7 - 7
+refresh submenu 5 - 18
+refresh submenu 8 - 34
+regenerate menuscreen 8 - 34
+regenerate menuscreen 5 - 18
+regenerate menuscreen 5 - 4
+remaining lines 8 - 34
+remaining lines 7 - 6
+remaining menuwindowlines 5 - 21
+remaining menuwindowlines 8 - 34
+reset dialog 8 - 35
+schliesse menu 4 - 3
+schliesse menu 8 - 35
+schliesse menukarte 8 - 35
+schliesse menukarte 4 - 3
+senkrecht 8 - 35
+show 8 - 35
+show 7 - 5
+show 8 - 36
+show 7 - 6
+show menuwindow 8 - 36
+show menuwindow 5 - 20
+stdinfoedit 8 - 36
+stop 7 - 8
+stop 8 - 37
+testinstallation 8 - 37
+testinstallation 4 - 3
+textprozedur 4 - 8
+textprozedur 8 - 38
+text zeile 4 - 13
+textzeile 8 - 39
+trennlinie 4 - 6
+trennlinie 8 - 38
+waagerecht 8 - 39
+WINDOW 7 - 2
+window 7 - 4
+window 8 - 40
+write menunotice 8 - 40
+write menunotice 5 - 15
+yes 7 - 7
+yes 8 - 41
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.inhalt b/doc/menugenerator/menu-generator handbuch.inhalt
new file mode 100644
index 0000000..8b1aef4
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.inhalt
@@ -0,0 +1,72 @@
+#type ("elite.lq")##limit (11.5)##pagelength (16.5)##pageblock#
+#start (1.8,0.0)#
+#type ("prop.breit.lq")#
+Inhaltsverzeichnis
+#type ("elite.lq")#
+
+
+1 Was kann ls-Menu-Generator 3
+
+2 Installation von ls-Menu-Generator 6
+2. 1 Voraussetzungen 6
+2. 2 Lieferumfang 6
+2. 3 Installation 7
+
+3 Die Arbeitsweise von ls-DIALOG 8
+3. 1 Ankoppeln einer Menukarte/ 8
+ Ausführen eines Menus
+3. 2 Aufbau/Inhalt einer Menukarte 11
+
+4. Erstellen einer neuen Menukarte 13
+4. 1 Eintragen der Menupunkte 13
+4. 2 Erstellung und Einbinden von 20
+ Informationstexten
+4. 3 Auslagerung von anwendungsbezogenen 24
+ Texten in die Menukarte
+
+5. Dialoge innerhalb des Menus 27
+5. 1 Eingabe eines Textes/Namens 28
+5. 2 Ausgabe einer Information 31
+5. 3 Auswahl eines Namen durch Ankreuzen 32
+5. 4 Auswahl mehrerer Namen durch Ankreuzen 34
+5. 5 Eingabe eines Textes/Namens - alternativ: 35
+ Auswahl durch Ankreuzen
+5. 6 Die Ja/Nein - Entscheidung 37
+5. 7 Die Alternativentscheidung 39
+5. 8 Die Menunotiz 43
+5. 9 Fußzeilen im Menu 44
+5.10 Wiederherstellung des Menubildschirms 46
+5.11 Arbeiten im Menufenster 47
+5.11.1 Datei anzeigen/editieren 48
+5.11.2 Menufenster öffnen/anzeigen 48
+5.11.3 Menufenster löschen(putzen) 49
+5.11.4 Positionierungen im Menufenster 49
+5.11.5 Informationen über die aktuelle 50
+ Menu-Fensterposition
+5.11.6 Aus-/Eingabe innerhalb des Menufensters 51
+5.11.7 Weitere Prozeduren 52
+5.12 Festlegung der Boxpositionen innerhalb 53
+ des Menus
+5.13 ls-DIALOG-Syntax 54
+ (Regeln zur Erstellung von Texten)
+5.14 Thesaurushandling 55
+5.15 Aktivieren/Deaktivieren von Menupunkten 57
+
+6. Einbinden der Datei- und Archivoperationen 59
+6. 1 Einbinden der Archivoperationen 60
+6. 2 Einbinden der Dateioperationen 65
+
+7. Eigene Fenster und Fensteroperationen 66
+7. 1 Definition von Fenstern 67
+7. 2 Anzeigen/Löschen von Fenstern 70
+7. 3 Operationen innerhalb des Fensters 71
+7. 3.1 Datei anzeigen/editieren 71
+7. 3.2 Positionierungen im Fenster 72
+7. 3.3 Ein- und Ausgaben innerhalb des Fensters 73
+7. 3.4 Weitere Prozeduren 74
+7. 4 Boxoperationen 75
+
+8. Kurzbeschreibung der Befehle 78
+
+9. Register 125
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Inhaltsverzeichnis b/doc/mp-bap/A5 - Doku: gs-MP BAP - Inhaltsverzeichnis
new file mode 100644
index 0000000..9507802
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Inhaltsverzeichnis
@@ -0,0 +1,50 @@
+#limit (11.5)##pagelength (16.5)##pageblock#
+#start (1.8,0.0)#
+Inhaltsverzeichnis
+
+
+1 Was kann gs-MP BAP 3
+
+2 Allgemeines zum Simulationsprogramm 6
+2.1 Entstehung 6
+2.2 Beschreibung des Programmkerns 7
+ - ein Simulationslauf
+2.3 Das Teilprogramm 'Materialprüfung' 9
+2.4 Das Teilprogramm 'Bildschirmarbeitsplatz' 10
+2.5 Hinweise zum Einsatz des Programmsystems 12
+2.6 Erfahrungen mit dem Programmsystem 13
+2.7 Hinweise auf Arbeitsmaterial 14
+
+3 Installation von gs-MP BAP 16
+3.1 Voraussetzungen 16
+3.2 Lieferumfang 16
+3.3 Installation 17
+3.4 Organisation des Task - Systems 19
+3.5 Direktstart des Systems 20
+
+4 Eine kleine Beispielsitzung 22
+4.1 Aufruf von 'Bildschirmarbeitsplatz' (BAP) 22
+4.2 Einstellung von Simulationsparametern 23
+4.3 Ein Simulationslauf 26
+4.4 Die Simulationsauswertung/das Protokoll 28
+4.5 Hinweise zur Protokollauswertung 36
+4.5.1 Der Bewertungsfaktor 36
+4.5 2 Fehlerzeichenhäufigkeit in den Werkstücken 38
+4.5 3 Fehlerhafte Auswertungen 38
+
+5 Beschreibung der Menufunktionen 40
+5.1 Kurzhinweise zur Bedienung der Menus 40
+5.2 Menufunktionen z. Oberbegriff 'Simulation' 44
+5.3 Menufunktionen z. Oberbegriff 'Parameter' 48
+5.4 Menufunktionen z. Oberbegriff 'Konfiguration' 56
+5.5 Menufunktionen z. Oberbegriff 'Dateien' 58
+5.6 Menufunktionen z. Oberbegriff 'Archiv' 60
+
+6 Hinweise für den Systembetreuer 61
+
+
+
+
+
+
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1
new file mode 100644
index 0000000..e418764
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1
@@ -0,0 +1,119 @@
+#type ("12.lq")##limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (3)#
+#headodd#
+#center#gs-MP BAP#right#%
+
+#end#
+#headeven#
+%#center#gs-MP BAP
+
+#end#
+#center#1
+
+#center#Was
+#center#kann
+#center#gs-MP BAP
+
+
+ #on("b")#gs-MP BAP#off("b")# ist ein Programm, mit dem die Arbeit
+an einem Bildschirmarbeitsplatz unter ganz unter­
+schiedlichen Aspekten simuliert werden kann. Vom
+Benutzer wird dabei verlangt, eine Art "Kontrolltä­
+tigkeit am Bildschirm" auszuüben. Während dieser
+Arbeit werden Daten über den Arbeitsverlauf erfaßt,
+die (später) ausgewertet werden können.
+ #on("b")#gs-MP BAP#off("b")# ist so gestaltet, daß es für ganz un­
+terschiedliche Zwecke eingesetzt werden kann. Es
+ist möglich, sämtliche Simulationsparameter den
+eigenen Wünschen und der jeweiligen Situation an­
+zupassen. Daneben besteht die Möglichkeit, die Si­
+mulationsprotokolle offensichtlich oder "heimlich"
+zu erfassen.
+ #on("b")#gs-MP BAP#off("b")# kann dazu benutzt werden, um Anwendern
+lediglich die Belastungen eines Bildschirmarbeits­
+platzes an einem Beispiel darzulegen; es ist aber
+genauso möglich, ihm eindrucksvoll aufzuzeigen, wie
+eine Kontrolle am Bildschirmarbeitsplatz - ohne
+sein Wissen - erfolgen kann. Auf der Basis dieser
+Erfahrungen lassen sich dann ganz neue Fragestel­
+lungen thematisieren (Möglichkeiten/Befugnis der/
+zur Kontrolle am (Bildschirm-) Arbeitsplatz; Daten­
+schutz; Betriebsvereinbarungen zu Computerarbeits­
+plätzen und vieles mehr).
+ Durch die Möglichkeit, die Simulationsparameter
+vielfältig zu variieren, können verschiedenste Un­
+tersuchungen mit dem Programm durchgeführt werden:
+Angefangen von Untersuchungen zur Konzentrations­
+fähigkeit bei unterschiedlichen Umgebungsbedingun­
+gen (z.B. Lichtverhältnisse, Musik am Arbeitsplatz,
+etc.), über Untersuchungen zum optimalen Arbeits­
+phasen - Pausen - Rhythmus (z.B. zur Fragestellung,
+ob lange Arbeitsphasen mit langen Pausen günstiger
+sind als kurze Arbeitsphasen mit immer wieder ein­
+gestreuten kleineren Pausen oder umgekehrt - wenn
+die Gesamtzeit konstant ist), bis hin zu Untersu­
+chungen zur Ergonomie von Computerarbeitsplätzen
+(z.B. hinsichtlich der Tastaturbelegung, Nützlich­
+keit eines eigenen Cursorblockes, etc.).
+ Anhand der aufgezeigten Möglichkeiten wird
+sicher deutlich, daß der Einsatz des Programms
+nicht auf den Informatikunterricht beschränkt ist.
+Ebensogut ist, bei entsprechender Fragestellung,
+ein Einsatz im gesellschafts- / sozialwissenschaft­
+lichen Unterricht, im Biologieunterricht, in den
+kaufmännischen Lernbereichen oder im Technikunter­
+richt denkbar. Das Programm ist auch für die Aufar­
+beitung verschiedener Fragestellungen bei der Vor-
+und Nachbereitung von Betriebspraktika geeignet.
+ Um all diese Möglichkeiten auch den Ausbildern
+offenzuhalten, die keinerlei Vorerfahrungen mit
+Computern haben, aber dieses Programm einsetzen
+möchten, ist die Simulationsumgebung so komforta­
+bel, daß jeder Benutzer innerhalb weniger Minuten
+das gesamte Programmsystem überblicken und bedienen
+kann.
+
+- Durch die Einbettung in die komfortable Benut­
+ zerschnittstelle #on("b")#gs-DIALOG#off("b")#, sind nur noch wenige
+ Betriebssystemkommandos zur Bedienung des Sy­
+ stems notwendig.
+
+- Der Benutzer kann jederzeit Informationen über
+ die Bedienung des Menusystems und die Wirkung
+ der einzelnen Menufunktionen anfordern, die ihm
+ daraufhin in den aktuellen Bildschirm eingeblen­
+ det werden.
+
+- Dem Benutzer wird ständig angezeigt, welche Mög­
+ lichkeiten der Bedienung bestehen, welche Tasten
+ wirksam sind und welche Wirkung deren Betätigung
+ hat. Menufunktionen, deren Wirkungen zu bestimm­
+ ten Zeitpunkten sinnlos oder fehlerhaft wären,
+ werden "inaktiviert", d.h. sind dem Benutzer gar
+ nicht erst zugänglich.
+
+- Die Auswertung der Simulationsprotokolle erfolgt
+ vom Menu aus durch einfaches Ankreuzen der ge­
+ wünschten Protokolldateien. Es besteht sowohl
+ die Möglichkeit, die Auswertungen auf dem Bild­
+ schirm anzeigen als auch über den Drucker ausge­
+ ben zu lassen.
+
+- Die Festlegung der Simulationsparameter ist kin­
+ derleicht. Die aktuell eingestellten Werte kön­
+ nen jederzeit eingesehen werden. Zur Einstellung
+ werden umfangreiche Informationen und Hilfen
+ ausgegeben. Eine Fehlbedienung ist ausgeschlos­
+ sen.
+
+- In das System ist eine komfortable Archivbehand­
+ lung integriert, so daß auch für den Computer­
+ laien die Konservierung der Simulationsergebnis­
+ se auf einfachste Weise möglich ist.
+
+- Bei auftretenden Fehlern erhält der Benutzer
+ konkrete, verständliche Fehlermeldungen, die
+ zumeist mit einem Zusatz versehen sind, wie die
+ "Situation bereinigt werden kann".
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2
new file mode 100644
index 0000000..b063ea3
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2
@@ -0,0 +1,302 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (6)#
+#headodd#
+#center#gs-MP BAP#right#%
+
+#end#
+#headeven#
+%#center#gs-MP BAP
+
+#end#
+#center#2
+
+#center#Allgemeines
+#center#zum
+#center#Simulationsprogramm
+
+
+2.1 Entstehung
+
+ Das Simulationsprogramm #on("b")#gs-MP BAP#off("b")# basiert auf
+einer Idee von Hartmut Spenn und Mene Wolf, die
+eine Unterrichtsreihe mit dem Titel "Der gläserne
+Arbeiter" im Rahmen der Materialien zur Lehrerfort­
+bildung in Nordrhein Westfalen (Neue Technologien,
+informations- und kommunikationstechnologische In­
+halte im Wahlpflichtunterricht der Klassen 9/10)
+beschrieben und dazu ein Grundprogramm für den C64
+in COMAL geschrieben haben.
+ Dieses Grundprogramm diente einmal als Ausgangs­
+punkt für #on("b")#gs-MP BAP#off("b")#. Allerdings wuchsen die An­
+sprüche an das System immer mehr, so daß eine Reihe
+weiterer Funktionen hinzugefügt wurden. Ein wesent­
+liches Ziel war es, ein Simulationsprogramm zur
+Verfügung zu stellen, daß umfangreiche Variations­
+möglichkeiten - ohne jegliche Programmierkenntnisse
+- bietet; ein Programm, das selbst von einem völli­
+gen Computerlaien innerhalb weniger Minuten über­
+blickt und sicher bedient werden kann.
+
+ Erst als die komfortable Benutzerschnittstelle
+#on("b")#gs-DIALOG#off("b")# zur Verfügung stand, konnte dieses Ziel
+erreicht werden. Heute präsentiert sich Ihnen ein
+Programmsystem, in dem Sie jede Programmfunktion
+von einem Menu aus wählen können. Durch Informa­
+tionstexte, die Sie jederzeit abrufen können, und
+durch die Bedienungshinweise werden Sie sicher
+durch das Programmsystem geführt. Sie haben komfor­
+table Möglichkeiten, die Simulationsparameter zu
+variieren. Das Programmsystem ist gegen Fehlbedie­
+nungen mehrfach abgesichert.
+
+
+2.2 Beschreibung des Programmkerns
+ - ein Simulationslauf
+
+ Mit #on("b")#gs-MP BAP#off("b")# kann die Arbeit an einem Bild­
+schirmarbeitsplatz simuliert werden. Der Benutzer
+übt am Bildschirm eine Art "Kontrolltätigkeit" aus.
+Die Interpretation dieser Tätigkeit ist offen: So
+kann man sich vorstellen, daß "Werkstücke" auf dem
+Bildschirm angezeigt werden, die auf Fehler hin
+untersucht werden sollen; dabei muß jeder gefundene
+Fehler markiert werden. Der Benutzer kann sich auch
+vorstellen, er sei bei einer Tageszeitung beschäf­
+tigt und habe die aus der Redaktion eingehenden
+Artikel auf Tippfehler hin zu untersuchen - natür­
+lich müssen die Tippfehler "verbessert" werden.
+Andere Interpretationen sind denkbar.
+ Das Grundprinzip des Simulationslaufes ist recht
+einfach - ein typischer Bildschirm könnte so ausse­
+hen:
+#free (9.5)#
+ Im oberen Bereich des Bildschirms werden alle
+Daten angezeigt, die der Benutzer während des Simu­
+lationslaufes benötigt. Links oben sind alle Tasten
+angegeben, die für die Handhabung des Programms
+notwendig sind. Rechts oben wird der Benutzer über
+die Simulationszeiten und das festgelegte 'Fehler­
+zeichen' informiert.
+ Im unteren Bereich des Bildschirms wird ein
+rechteckiger Block ausgegeben, der sich aus ver­
+schiedenen Zeichen (z.B. Buchstaben, Ziffern, Son­
+derzeichen) zusammensetzt. Der Benutzer hat jetzt
+die Aufgabe, die Blöcke daraufhin zu untersuchen,
+ob in ihnen das angegebene Fehlerzeichen auftaucht.
+ Entdeckt er solche Zeichen im Block auf dem
+Bildschirm, so ist es seine Aufgabe, den Cursor
+(Lichtfleck) auf dem Bildschirm mit Hilfe festge­
+legter Tasten an die entsprechende Position zu
+steuern und eine 'Ausbesserung' (Kennzeichnung/
+Korrektur) vorzunehmen. Ist der Benutzer der Mei­
+nung, alle Fehlerzeichen bearbeitet zu haben, so
+kann er den nächsten Block (das nächste Werkstück/
+den nächsten Artikel) durch Tippen einer festgeleg­
+ten Taste anfordern.
+ Die Arbeit ist dabei streng in 'Arbeitsphasen'
+und 'Pausen' eingeteilt - der Rhythmus wird aber
+vom Programm und nicht vom Benutzer bestimmt. Wäh­
+rend des Simulationslaufes werden alle wesentlichen
+Kenndaten protokolliert. Diese können später ausge­
+wertet werden.
+ In unserem konkreten Beispiel hat der Benutzer
+nach dem Fehlerzeichen 'F' zu suchen. Er hat insge­
+samt 34 Minuten zu arbeiten; dabei ist seine Ar­
+beitszeit eingeteilt in 3 Arbeitsphasen zu je 10
+Minuten mit zwei dazwischenliegenden Pausen von je
+2 Minuten.
+ Zur Bedienung des Systems kann er die (Cursor-)
+Pfeiltasten <rechts>, <links>, <hoch> und <runter>
+benutzen; damit kann er den Lichtfleck innerhalb
+des Zeichen-Blocks bewegen. Zur Ausbesserung dient
+die <HOP>-Taste. Mit der <ESC>-Taste kann er je­
+weils die neuen Werkstücke (Artikel) zur Bearbei­
+tung anfordern.
+
+
+2.3 Das Teilprogramm 'Materialprüfung' (MP)
+
+ Gemeinsamer Bestandteil beider Programmteile ist
+der sogenannte "Simulationslauf" - ein eben ge­
+schilderter Arbeitsprozeß am Bildschirm. Diesem
+Simulationslauf gehen im Teilprogramm 'Materialprü­
+fung' (MP) jedoch noch umfangreiche Informationen
+voraus, die dem Benutzer die anschließend zu ver­
+richtende Tätigkeit detailliert erläutern. Gleich
+nach Aufruf des Programmteils wird der Benutzer
+noch nach einer "Identifikation" gefragt und aufge­
+fordert, z.B. den Vor- und Nachnamen einzugeben.
+Die hier eingegebene Kennung ist auch Bestandteil
+des Namens des Protokolls, das über den dann fol­
+genden Simulationslauf angelegt wird.
+ Am Ende des Simulationslaufes wird dem Benutzer,
+sofern das System entsprechend konfiguriert ist,
+eine 'Kurzauswertung' seiner Arbeit auf dem Bild­
+schirm präsentiert. Zusätzlich wird - ohne daß der
+Benutzer es merkt - das angelegte Protokoll in die
+Vatertask geschickt und in der eigenen Task ge­
+löscht.
+
+
+2.4 Das Teilprogramm 'Bildschirmarbeitsplatz'
+ (BAP)
+
+ Nach Aufruf des Teilprogramms erscheint auf dem
+Bildschirm ein Menu, von dem aus eine Vielzahl von
+Funktionen gewählt werden kann. Natürlich ist es
+auch von hier aus möglich, einen oben beschriebenen
+Simulationslauf zu starten. Im Gegensatz zum Pro­
+grammteil 'Materialprüfung' wird hier aber auf die
+umfangreichen Informationen zur Handhabung des
+Systems verzichtet und zum Abschluß auch keine Pro­
+tokolldatei zur Vatertask geschickt - die Proto­
+kolldatei verbleibt in der eigenen Task.
+ Daneben können vom Menu aus auch Protokolldatei­
+en ausgewertet werden. Sie können dabei noch ent­
+scheiden, ob Sie die Auswertungen auf dem Bild­
+schirm angezeigt oder aber auf dem angeschlossenen
+Drucker ausgegeben haben möchten.
+ Weiterhin können Sie sämtliche Simulationspara­
+meter vom Menu aus Ihren Wünschen gemäß einstellen.
+So ist es möglich, die Breite und Höhe des Werk­
+stücks zu variieren und zu entscheiden, ob die
+Werkstücke "normal" oder "invers" dargestellt wer­
+den sollen. Sie können das 'Fehlerzeichen' festle­
+gen und überhaupt die Zeichen bestimmen, aus denen
+die Werkstücke aufgebaut werden. Daneben haben Sie
+noch die Möglichkeit, zu bestimmen, welche Tasten
+auf der Tastatur welche Funktion beim Simulations­
+lauf haben sollen.
+ Sie legen von hier aus auch fest, in wie viele
+Arbeitsphasen die Arbeitszeit unterteilt wird und
+wie lange eine einzelne Arbeitsphase und die zwi­
+schen den Arbeitsphasen liegende Pause dauern sol­
+len. Auch hinsichtlich der Bewertung können Sie
+Festlegungen treffen - nach dem von Ihnen hier ein­
+gestellten Wertungsschlüssel werden nämlich die
+Protokolldateien ausgewertet.
+ Ihnen obliegt es auch, zu bestimmen, ob mit je­
+der Protokollauswertung die umfangreichen Erläute­
+rungen ausgegeben werden sollen und ob der Benutzer
+am Ende eines Simulationslaufes eine 'Kurzauswer­
+tung' über seine Arbeit auf dem Bildschirm erhalten
+soll oder nicht.
+ Zusätzlich werden Ihnen noch eine Reihe von Mög­
+lichkeiten zur Datei- und Archivbehandlung angebo­
+ten. So können Sie komfortabel Dateien löschen,
+kopieren, umbenennen, etc., Dateien auf Diskette
+konservieren oder gespeicherte Dateien von dort
+holen und vieles mehr.
+
+
+2.5 Hinweise zum Einsatz des Programmsystems
+
+ Aus den Beschreibungen in 2.3 und 2.4 ist Ihnen
+sicher schon die unterschiedliche Absicht, die hin­
+ter den beiden Programmteilen steckt, klar gewor­
+den. Die beiden Programmteile richten sich nämlich
+auch an ganz unterschiedliche Nutzergruppen.
+ Das Teilprogramm 'Materialprüfung' (MP) ist vor­
+nehmlich für den 'unerfahrenen'/'unbefangenen' Be­
+nutzer gedacht. Ihm werden nämlich umfangreiche
+Informationen ausgegeben. Mit diesem Programmteil
+ist eben auch die "heimliche" Erfassung der Simula­
+tionsdaten möglich. Dieser Teil des Programms wird
+sicherlich dann Anwendung finden, wenn die Fragen
+um die Möglichkeiten und Gefahren der Kontrolle am
+(Bildschirm-) Arbeitsplatz im Vordergrund der Be­
+trachtungen stehen.
+ Das Teilprogramm 'Bildschirmarbeitsplatz' (BAP)
+hat zumindest zwei ganz unterschiedliche Einsatz­
+aspekte:
+
+ Einerseits dient es dem Lehrer/Ausbilder dazu,
+die gewünschten Simulationsparameter für das Teil­
+programm 'Materialprüfung' einzustellen. Die aktu­
+elle Einstellung, die mit dem Teilprogramm 'Bild­
+schirmarbeitsplatz' getroffen wurde, ist in der
+jeweilgen Task gültig, in der die Einstellung vor­
+genommen wurde. Die Einstellung wird aber auch von
+allen Sohntasks übernommen, die sich nach der je­
+weiligen Einstellung neu anmelden. Darüber hinaus
+dient dieses Teilprogramm dem Lehrer/Ausbilder
+dazu, die (ihm zugestellten) Simulationsprotokolle
+auszuwerten.
+ Andererseits hat das Teilprogramm 'Bildschirm­
+arbeitsplatz' auch einen "eigenen Charakter":
+Gerade bei den schon oben angesprochenen Untersu­
+chungen (zur Konzentrationsfähigkeit in Abhängikeit
+von verschiedenen Faktoren, zur Bedeutung der Ar­
+beitsphasen-Pausen-Rhythmen, zur 'Ergonomie am Ar­
+beitsplatz', etc.) bietet sich hier ein schneller,
+komfortabler Wechsel zwischen Parametereinstellung
+und Simulationsläufen - ohne unnötigen Zeitverlust;
+erst recht, wenn mehrere Simulationsläufe aufeinan­
+der folgen.
+
+
+2.6 Erfahrungen mit dem Programmsystem
+
+ Das Programmsystem wurde bereits in verschiede­
+nen Klassen/ Kursen ab der Jahrgangsstufe 8 einge­
+setzt, und zwar in verschiedenen Fachbereichen und
+Schulformen. Die Akzeptanz ist sehr hoch; die Hand­
+habung des Programmsystems bereitete selbst Kolle­
+gen, die noch nie zuvor an einem Computer gesessen
+hatten, keinerlei Schwierigkeiten. Von der Hand­
+habung des Programms her ist deshalb sicher auch
+keine Alteruntergrenze hinsichtlich der "Eignung"
+anzugeben.
+ Jedoch scheint eine Bearbeitung mit den oben
+angegebenen Zielsetzungen erst auf dem Erfahrungs­
+horizont der Jahrgangsstufe 8 sinnvoll zu sein.
+Eine Bearbeitung der Fragestellungen in der von
+Hartmut Spenn und Mene Wolf (siehe Kapitel 2.7)
+vorgeschlagenen Tiefe scheint allerdings erst am
+Ende der Jahrgangsstufe 9 bzw. in der Jahrgangsstu­
+fe 10 erreichbar.
+ Besonders interessant scheint der Einsatz bei
+der Vor- bzw. Nachbereitung von Betriebspraktika zu
+sein. Durch die unmittelbare Berührung mit den
+"neuen Technologien am Arbeitsplatz" ist das Inter­
+esse an der Bearbeitung entsprechender Fragestel­
+lungen sehr hoch und eine Sensibilisierung für die
+angesprochenen Problematiken zu erreichen.
+ Die angegebenen Fragestellungen im Zusammenhang
+mit diesem Programmsystem können auch Thema einer
+Projektwoche/von Projekttagen sein. Besonders be­
+währt hat sich hier die Zusammenarbeit mit Kollegen
+aus dem gesellschafts-/sozialwissenschaftlichen
+Bereich. Ein Unterrichtsgang, z.B. in einen Super­
+markt mit modernen Scannerkassen, bei einer Tages­
+zeitung (Kleinanzeigenaufnahme am Freitag-Vormit­
+tag) o.ä., bei dem die "im Hintergrund (möglicher­
+weise) ablaufenden Prozesse" bewußt gemacht werden,
+kann das Vorhaben noch abrunden.
+ Zum Einsatz in der Sekundarstufe II liegen erst
+wenige Erfahrungen vor. Mit Sicherheit bietet das
+Programm einen "anderen", interessanten Einstieg in
+den Informatikunterricht der Jahrgangsstufe 11 und
+kann auch bei der Aufarbeitung entsprechender Fra­
+gestellungen zu späteren Zeitpunkten herangezogen
+werden. Erfahrungen aus anderen Fachbereichen lie­
+gen (noch) nicht vor.
+
+
+2.7 Hinweise auf Arbeitsmaterial
+
+ Ausdrücklich sei an dieser Stelle auf die Ausar­
+beitung von Hartmut Spenn und Mene Wolf hingewie­
+sen:
+
+Spenn, Hartmut; Wolf, Mene; Der gläserne Arbeiter,
+ Elektronische Leistungs- und Verhaltenskon­
+ trolle am Arbeitsplatz
+ in: Landesinstitut für Schule und Weiterbildung
+ (Hrsg.), Materialien zur Lehrerfortbildung
+ in Nordrhein-Westfalen, Heft 4, Neue Tech­
+ nologien - Informations- und Kommunuika­
+ tionstechnologische Inhalte im Wahlpflicht­
+ unterricht der Klassen 9/10, Soest, 1986.
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3
new file mode 100644
index 0000000..f589a93
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3
@@ -0,0 +1,237 @@
+#limit (11.0)##pagelength (16.5)##block##pageblock#
+#start (2.0,0.0)#
+#page (16)#
+#headodd#
+#center#gs-MP BAP#right#%
+
+#end#
+#headeven#
+%#center#gs-MP BAP
+
+#end#
+#center#3
+
+#center#Installation
+#center#von
+#center#gs-MP BAP
+
+
+ Bevor Sie #on("b")#gs-MP BAP#off("b")# auf Ihrem Computer benutzen
+können, müssen Sie das Programm zunächst installie­
+ren. Wenn #on("b")#gs-MP BAP#off("b")# auf Ihrem System schon zur Ver­
+fügung steht, können Sie dieses Kapitel ruhig über­
+springen.
+
+
+3.1 Voraussetzungen
+
+ Um #on("b")#gs-MP BAP#off("b")# auf Ihrem Computer betreiben zu
+können, muß das EUMEL-Betriebssystem installiert
+sein. #on("b")#gs-MP BAP#off("b")# setzt die Multi-User-Version voraus
+und ist lauffähig ab Version 1.7.5. #on("b")#gs-MP BAP#off("b")# setzt
+weiterhin voraus, daß auf Ihrem Computer bereits
+das Programm #on("b")#gs-DIALOG#off("b")# installiert ist.
+
+
+3.2 Lieferumfang
+
+ #on("b")#gs-MP BAP#off("b")# wird auf einer Diskette geliefert, die
+alle notwendigen Programme enthält (die Installa­
+tion von #on("b")#gs-DIALOG#off("b")# wird dabei vorausgesetzt!). Um
+den Inhalt der Diskette feststellen zu können,
+starten Sie Ihr System und bringen es dazu, daß
+'gib kommando:' erscheint. Dann legen Sie die Dis­
+kette ein und geben das Kommando:
+
+ archive("gs-MP BAP");list(archive);
+ release(archive) <RETURN>
+
+ Anschließend erscheint eine Übersicht der auf
+dem Archiv vorhandenen Programme. Folgende Program­
+me sollten sich in der Übersicht befinden:
+
+ "gs-MP BAP 1"
+ "gs-MP BAP 2"
+ "gs-MENUKARTE:MP-BAP"
+ "gs-MP BAP/gen"
+
+ Eventuell können noch weitere Namen auf der Dis­
+kette vorhanden sein. Wenn Sie den Inhalt der Dis­
+kette kontrolliert haben und diese Programme auf
+der Diskette vorhanden sind, können Sie #on("b")#gs-MP BAP#off("b")#
+installieren.
+ Sollten Sie statt der Übersicht eine Fehlermel­
+dung erhalten, überprüfen Sie bitte, ob die Disket­
+te das richtige Format besitzt oder ob Ihr Disket­
+tenlaufwerk Probleme macht. Sollten dagegen Pro­
+gramme fehlen, so reklamieren Sie die Diskette.
+
+
+3.3 Installation
+
+ #on("b")#gs-MP BAP#off("b")# muß in einer Task installiert werden,
+in der bereits das Programm #on("b")#gs-DIALOG#off("b")# zur Verfügung
+steht. Alle Söhne und Enkel der neuen Task können
+anschließend auf die Programme (Materialprüfung /
+Bildschirmarbeitsplatz) zugreifen. Richten Sie also
+eine Task als Sohn der Task ein, in der auf Ihrem
+Computer bereits #on("b")#gs-DIALOG#off("b")# installiert ist. Wir
+nehmen hier an, daß #on("b")#gs-DIALOG#off("b")# in der Task 'MENU'
+installiert ist und die neue Task den Namen 'MP
+BAP' erhalten soll. (Sie können für die Task auch
+einen beliebigen anderen Namen wählen):
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+#off("b")#
+
+ --> gib supervisor kommando:
+#on("b")#
+ begin ("MP BAP","MENU") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+
+ (Arbeiten mehrere Personen mit dem Computer,
+dann ist es sinnvoll, diese Task vor unbefugtem
+Zugriff durch ein Passwort zu schützen. Wie das
+gemacht wird, können Sie in Ihrem EUMEL-Benutzer­
+handbuch erfahren.)
+
+ Legen Sie dann die Archivdiskette ein, auf der
+sich #on("b")#gs-MP BAP#off("b")# befindet, und geben Sie das folgende
+Kommando:
+
+#on("b")#
+ archive("gs-MP BAP") <RETURN>
+
+ fetch("gs-MP BAP/gen",archive) <RETURN>
+
+ run <RETURN>
+#off("b")#
+
+ Sie haben damit das Generatorprogramm gestartet.
+Beantworten Sie die Frage, ob Sie das Archiv ange­
+meldet und die Diskette eingelegt haben, mit 'ja'
+durch Tippen der Taste <j>.
+ Daraufhin wird die Installation automatisch
+durchgeführt. Lassen Sie während des gesamten Vor­
+gangs die Archivdiskette eingelegt. Sie erhalten
+einen Hinweis, wenn die Diskette entnommen werden
+kann! Die Generierung ist beendet, wenn der EUMEL-
+Eingangsbildschirm erscheint. Die Task, in der die
+Generierung stattfindet, wird automatisch zur Mana­
+gertask, das heißt, daß Söhne von ihr eingerichtet
+werden können.
+ Richten Sie sich gleich eine Sohntask (z.B mit
+dem Namen 'mp bap') ein, dann können Sie das System
+sofort ausprobieren. Gehen Sie dazu folgendermaßen
+vor:
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+#off("b")#
+
+ --> gib supervisor kommando:
+#on("b")#
+ begin ("mp bap","MP BAP") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+
+Mit dem Kommando
+
+#center##on("b")#mp <RETURN> bzw. bap <RETURN>#off("b")#
+
+können Sie nun das Programm
+
+#center#'Materialprüfung' bzw. 'Bildschirmarbeitsplatz'
+
+aufrufen.
+
+
+3.4 Organisation des Task - Systems
+
+ Wollen Sie unter anderem das Teilprogramm 'Ma­
+terialprüfung' (MP) nutzen, so sollten Sie beden­
+ken, daß die dabei entstehenden Simulationsproto­
+kolle in die Vatertask geschickt werden. Die Vater­
+task sollte sich daher ständig im Wartezustand be­
+finden, um die Protokolle auch aufnehmen zu können.
+So kann es sinnvoll sein, eine 'Zwischentask' ein­
+zurichten, damit auch andere ungestört mit dem Si­
+mulationsprogramm arbeiten können. Gehen Sie dazu
+etwa folgendermaßen vor:
+ In der Task 'mp bap', in der Sie bisher gearbei­
+tet haben, geben Sie bei 'gib kommando:' den Be­
+fehl:
+
+ #on("b")#global manager <RETURN>#off("b")#
+
+ Sie gestatten dadurch, daß Söhne dieser Task
+eingerichtet werden können. Auf dem Bildschirm er­
+scheint der EUMEL-Eingangsbildschirm.
+ Alle Anwender (Schüler) melden sich dann als
+Sohn der Task 'mp bap' an:
+
+ #on("b")#begin ("Anwender1", "mp bap") <RETURN>#off("b")#
+ #on("b")#begin ("Anwender2", "mp bap") <RETURN>#off("b")#
+ #on("b")#begin ("Anwender3", "mp bap") <RETURN>#off("b")#
+ ...
+
+ Die Simulationsprotokolle finden Sie dann an­
+schließend in der Task 'mp bap'.
+
+
+3.5 Direktstart des Systems
+ (Steht erst ab gs-DIALOG Version 1.1 zur Ver­
+ fügung)
+
+ In den Kapitel 3.3/3.4 haben wir Ihnen gezeigt,
+wie sie Sohntasks einrichten und hier durch das
+Kommando 'mp' bzw. 'bap' das System aufrufen kön­
+nen. Wenn Sie immer nur mit einer Modellvariante
+arbeiten oder vor dem Benutzer die 'gib komman­
+do:'-Ebene verbergen wollen, können Sie das System
+auch so einrichten, daß sich sofort nach Einrichten
+des Arbeitsbereichs das Menusystem meldet. Für den
+Anfänger kann das die Arbeit durchaus erleichtern.
+ Gehen Sie dazu in die Task, unterhalb der die
+Sohntasks eingerichtet werden sollen:
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+
+#off("b")#
+ --> gib supervisor kommando:
+#on("b")#
+ continue ("mp bap") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+#on("b")#
+ direktstart ("mp", TRUE) <RETURN>
+#off("b")#
+
+ Durch das Kommando haben Sie festgelegt, daß
+sich alle Sohntasks direkt mit dem Programm 'Mate­
+rialprüfung' melden. Möchten Sie lieber mit 'Bild­
+schirmarbeitsplatz' arbeiten, ist nur 'mp' durch
+'bap' zu ersetzen. In diesem Falle meldet sich das
+System gleich mit dem BAP-Menu.
+ Durch den zweiten Parameter 'TRUE' legen Sie
+fest, daß in den Sohntasks nach Verlassen des Menus
+die jeweilige Task automatisch gelöscht wird. Statt
+'TRUE' können Sie hier auch den Wert 'FALSE' ein­
+tragen. Dann wird nach Verlassen des Menus ange­
+fragt, ob die Task gelöscht werden soll. Wird die
+Frage bejaht, wird gelöscht - sonst wird die Task
+abgekoppelt (break) und kann durch 'continue' wie­
+der angekoppelt werden.
+ Anmerkung: In der Task, in der Sie das Kommando
+'direktbefehl' gegeben haben, sollte nicht das Kom­
+mando 'monitor' gegeben werden, da Sie durch dieses
+Kommando auch diese Task zu einer Task machen, die
+sich direkt mit dem Menu meldet und ggf. bei Ver­
+lassen des Menus automatisch gelöscht wird!
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4
new file mode 100644
index 0000000..6236d91
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4
@@ -0,0 +1,638 @@
+#limit (11.0)##pagelength (16.5)##block##pageblock#
+#start (2.0,0.0)#
+#page (22)#
+#headodd#
+#center#gs-MP BAP#right#%
+
+#end#
+#headeven#
+%#center#gs-MP BAP
+
+#end#
+#center#4
+
+#center#Eine
+#center#kleine
+#center#Beispielsitzung
+
+
+4.1 Aufruf von 'Bildschirmarbeitsplatz' (BAP)
+
+ Wenn Sie, wie in Kapitel 3 beschrieben, eine
+Sohntask der Task eingerichtet haben, in der #on("b")#gs-MP
+BAP#off("b")# installiert ist, und dort bei 'gib kommando:'
+den Befehl:
+
+ #on("b")#bap <RETURN>#off("b")#
+
+geben, erscheint - nach dem #on("b")#gs-DIALOG#off("b")#-Eingangsbild­
+schirm - das folgende Menu:
+
+#on("b")#
+BAP: Simulation Parameter Konfiguration Dateien Archiv
++-------------------------------+-----------------------------------------
+| s Simulation ausführen |
+| --------------------------- |
+| a Auswertung auf Bildschirm |
+| d Drucken von Auswertungen |
++-------------------------------+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+4.2 Einstellung von Simulationsparametern
+
+ Bevor Sie eine Neueinstellung von Simulations­
+parametern vornehmen, sollten Sie sich einen Über­
+blick über die zur Zeit eingestellten Werte ver­
+schaffen. Zwar wäre es möglich, gleich einen Simu­
+lationslauf zu starten, doch müßten Sie dann gleich
+34 Minuten arbeiten - denn standardmäßig ist das
+Simulationssystem auf 3 Arbeitsphasen von je 10
+Minuten Dauer und zwei dazwischenliegende Pausen
+von je 2 Minuten eingestellt.
+ Wenn Sie sich die Einstellung anzeigen lassen
+wollen, müssen Sie das Pull-Down-Menu wechseln.
+Gehen Sie als durch Tippen der Pfeiltaste <rechts>
+zum Oberbegriff 'Parameter'. Dadurch wird das fol­
+gende Pull-Down-Menu aufgeschlagen:
+
+#on("b")#
+BAP: Simulation Parameter Konfiguration Dateien Archiv
+-------+---------------------------+--------------------------------------
+ | e Einstellung anzeigen |
+ | s Standardwerte |
+ | ----------------------- |
+ | b Breite des Werkstücks |
+ | h Höhe des Werkstücks |
+ | i Invers-/Normal |
+ | z Zeichensatz |
+ | f Fehlerzeichen |
+ | t Tastenbelegung |
+ | ----------------------- |
+ | a Anzahl Arbeitsphasen |
+ | d Dauer Arbeitsphase |
+ | p Pausendauer |
+ | ----------------------- |
+ | w Wertungsschlüssel |
+ +---------------------------+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+Nach Tippen der Taste <e> (für 'Einstellung anzei­
+gen') erscheint der folgende Bildschirm:
+
+#on("b")#
++-----------------------------------++-----------------------------------+
+| || Wertungsschlüssel |
+| Breite : 15 Zeichen || Bewertungs- |
+| Höhe : 12 Zeichen || faktor |
+| Darstellung : normal || |
+| Zeichensatz : A...Z (26 Zeichen)||1.0| + |
+| Fehlerzeichen: F || | + |
+| || | + |
+| Nach rechts : <rechts> || | + |
+| Nach links : <links> || | + |
+| Nach oben : <hoch> ||0.5| + |
+| Nach unten : <runter> || | + |
+| Ausbesserung : <HOP> || | + |
+| Nächstes : <ESC> || | + |
+| || | + |
+| Anzahl der Arbeitsphasen: 3 ||0.0+--|--|--|--|--|--|--|--|--|--| |
+| Dauer einer Arbeitsphase: 10 min || 0.0 0.5 1.0|
+| Dauer einer Pause : 2 min || |
+| || Ausbesserungsrate|
+| Simulationsgesamtdauer : 34 min || |
++-----------------------------------++-----------------------------------+
+--------------------------------------------------------------------------
+Zum Weitermachen irgendeine Taste tippen!
+#off("b")#
+
+ Oben links wird das "Aussehen" der Werkstücke
+auf dem Bildschirm beschrieben. Nach diesen Angaben
+sind die Werkstücke 15 Zeichen breit und 12 Zeichen
+hoch. Sie werden auf dem Bildschirm normal (nicht
+invers) dargestellt. Die Werkstücke werden aus den
+Großbuchstaben 'A ... Z' zusammengesetzt, wobei 'F'
+das Fehlerzeichen ist, nach dem gesucht werden
+soll.
+ Der Cursor kann mit den Pfeiltasten (<rechts>,
+<links>, <hoch> und <runter>) innerhalb des Werk­
+stücks bewegt werden. Steht der Cursor auf einem
+Fehlerzeichen, so verschwindet es, wenn die <HOP>-
+Taste getippt wird. Nach Tippen der <ESC>-Taste
+erscheint das nächste Werkstück auf dem Bildschirm.
+ Darunter sind die Informationen angegeben, die
+uns eigentlich interessieren: Die Anzahl/Zeiten für
+Arbeitsphasen und Pausen. Sie sollen die Simula­
+tionszeiten jetzt so verändern, daß die Gesamtsimu­
+lationszeit 3 Minuten beträgt. Wählen Sie dazu zu­
+erst die Menufunktion 'Anzahl Arbeitsphasen' durch
+Tippen der Taste <a>. Dann erscheint auf dem Bild­
+schirm folgendes Bild:
+
+#on("b")#
++-------------------------++-------------------------------------------+
+| Informationen || Anzahl Arbeitsphasen festlegen: |
+| || |
+| Kleinster Wert: 2 || Anzahl Arbeitsphasen neu festlegen (j/n)? |
+| Größter Wert: 20 || |
+| || |
+| Eingestellter Wert: 3 || |
++-------------------------++-------------------------------------------+
+
+
+
+ +-------------------------------------+
+ | Simulationszeiten: |
+ | |
+ | Anzahl der Arbeitsphasen: 3 |
+ | Dauer einer Arbeitsphase: 10 min |
+ | Dauer einer Pause : 2 min |
+ | |
+ | Simulationsgesamtdauer : 34 min |
+ +-------------------------------------+
+
+
+ Wenn Sie die im Fenster oben rechts gestellte
+Frage bejahen (Taste <j> tippen), ändert sich der
+Fensterinhalt:
+
+#on("b")#
++-------------------------++---------------------------------------------+
+| Informationen || Anzahl Arbeitsphasen festlegen: |
+| || |
+| Kleinster Wert: 2 ||Mit den Pfeilen <hoch> und <runter> den Wert|
+| Größter Wert: 20 ||einstellen. Eingabe mit <RETURN> abschließen.|
+| || |
+| Eingestellter Wert: 3 ||Bitte die Anzahl der Arbeitsphasen: 3 |
++-------------------------++---------------------------------------------+
+
+ Bestimmt ist Ihnen schon klar, was zu tun ist:
+Mit der Pfeiltaste <runter> stellen Sie den
+kleinstmöglichen Wert (2) ein - anschließend tippen
+Sie die <RETURN>-Taste. Schauen Sie auf das Fenster
+ganz unten - jetzt hätten Sie nur noch 24 Minuten
+zu arbeiten. Bevor Sie die anderen Parameter ein­
+stellen, bestätigen Sie bitte, daß Sie mit der An­
+zahl der Arbeitsphasen einverstanden sind.
+ Gehen Sie jetzt ebenso vor, um die 'Dauer (ei­
+ner) Arbeitsphase' und die 'Pausendauer' einzustel­
+len - eine Beschreibung dazu ist sicher überflüs­
+sig.
+ Rechts im Fenster ist noch der 'Wertungsschlüs­
+sel' angegeben - seine Bedeutung erläutern wir aber
+erst in Zusammenhang mit der Auswertung der Simula­
+tionsprotokolle.
+
+
+4.3 Ein Simulationslauf
+
+ So, jetzt können Sie zum Ausprobieren einen kur­
+zen Simulationslauf starten. Gehen Sie dazu zurück
+zum Pull-Down-Menu ganz links und wählen Sie hier
+die Menufunktion 'Simulation ausführen'. Zunächst
+werden Sie nach einer "Identifikation" gefragt.
+Geben Sie z.B. Ihren Namen ein und tippen Sie an­
+schließend die <RETURN>-Taste. Auf dem Bildschirm
+erscheinen oben alle Informationen, die Sie während
+der Simulation benötigen; darunter erscheint der
+Hinweis, daß mit dem nächsten Tastendruck die erste
+Arbeitsphase beginnt. Wenn das erste Werkstück auf
+dem Bildschirm erscheint, sieht das z.B. so aus:
+
+#on("b")#
++-------------------------------+ +-------------------------------------+
+| Nach rechts : <rechts> | | Anzahl der Arbeitsphasen: 3 |
+| Nach links : <links> | | Dauer einer Arbeitsphase: 10 min |
+| Nach oben : <hoch> | | Dauer einer Pause : 2 min |
+| Nach unten : <runter> | | Simulationsgesamtdauer : 34 min |
+| Ausbesserung : <HOP> | | |
+| Nächstes : <ESC> | | Fehlerzeichen : F |
++-------------------------------+ +-------------------------------------+
+
+ GFMKLPDRFGTZQAL
+ RTWOJLMNVWQHTRS
+ PZBFVDDSWWAFGBD
+ EWWQAKGHHJINMPA
+ WSSDEKLJNHHGTFD
+ GGTEWLVCXFFRPTR
+ TREKGLMNTREFGTW
+ TRWFGLMBVCCDSAQ
+ HGFRWZTCXYAASWW
+ MNNBHGTREWQKJLO
+ CCXSDRFGHKLPOZR
+ RWPPKHJUUZTFDSE
+
+
+ Nun dürfen Sie einmal zeigen, was Sie können.
+Bitte achten Sie darauf, daß Sie in jeder Arbeits­
+phase mindestens ein Werkstück bearbeiten - sonst
+könnte es später zu Fehlern bei der Auswertung kom­
+men. Sie sollen sich ja auch nicht ausruhen, son­
+dern arbeiten!
+ Pausen werden Ihnen auf dem Bildschirm ange­
+zeigt. Auch wenn Sie weiterarbeiten wollen - um die
+Pausen kommen Sie nicht herum! Am Ende einer Pause
+wird ein Hinweis auf das Pausenende ausgegeben.
+ Nach der letzten Arbeitsphase erhalten Sie eine
+Kurzauswertung des aktuellen Simualtionslaufes auf
+den Bildschirm (wenn Ihnen das nicht gefällt, kön­
+nen Sie das später auch abschalten). Zur Erläute­
+rung der angegebenen Daten in der 'Kurzauswertung'
+sehen Sie bitte das folgende Kapitel.
+
+
+4.4 Die Simulationsauswertung/das Simulations­
+ protokoll
+
+ Wenn Sie wollen, können Sie das Protokoll, das
+über Ihre Arbeit angefertigt wurde, gleich auswer­
+ten lassen. Wählen Sie dazu die Menufunktion 'Aus­
+wertung auf Bildschirm' (im gleichen Pull-Down-
+Menu). Ihnen werden jetzt alle Protokolle, die sich
+in Ihrer Task befinden, zur Auswahl angeboten.
+Wahrscheinlich ist es zur Zeit nur eine Protokoll­
+datei.
+ Jetzt sehen Sie auch, warum von Ihnen vor Simu­
+lationsbeginn eine "Identifikation" erbeten wurde.
+Sie ist Bestandteil des Protokollnamens - danach
+können Sie nämlich die Protokolle zuordnen. Verwen­
+den Sie mehrfach die gleiche Identifikation, so
+werden die Protokolle in der Reihenfolge ihrer An­
+lage durchnumeriert.
+ Wenn Sie den/die Dateinamen angekreuzt haben
+(z.B. mit <RETURN>) und die Auswahl durch <ESC><q>
+verlassen, werden die angekreuzten Protokolldateien
+ausgewertet und anschließend auf dem Bildschirm
+angezeigt.
+ Das Protokoll ist jeweils nach folgendem Schema
+aufgebaut: Zunächst werden Datum und Uhrzeit des
+Simulationslaufs ausgegeben; anschließend alle
+Kenndaten der Simulation, so daß daraus die gesamte
+Konfiguration des Simulationssystems rekonstruier­
+bar ist. Es folgt die "Gesamtauswertung" des Simu­
+lationslaufes, die identisch ist mit der auf dem
+Bildschirm angezeigten 'Kurzauswertung'. Die Ge­
+samtauswertung erfolgt nach den gleichen Grundsät­
+zen wie die sich anschließenden Auswertungen der
+einzelnen Werkstücke (es werden hier nur die ggf.
+angefallenen Pausenüberschreitung(en) mit in die
+Beurteilung einbezogen).
+ Das Protokoll ist durch die angehängten Bemer­
+kungen nahezu selbsterklärend. Damit Sie sich einen
+Eindruck verschaffen können, haben wir auf den
+nächsten Seiten ein ausgewertetes Protokoll abge­
+druckt. Bitte studieren Sie es eingehend - insbe­
+sondere die Anmerkungen am Ende des Protokolls:
+
+
+
+
+
+
+#on("b")#
+ gs-Protokoll: TEST - Auswertung
+ ===============================
+Datum : 03.09.87 Uhrzeit (zu Beginn): 10:21
+
+ Kenndaten der Werkstückbearbeitung:
+ ===================================
+Nach rechts : <rechts> Anzahl der Arbeitsphasen: 3
+Nach links : <links> Dauer einer Arbeitsphase: 10 min
+Nach oben : <hoch> Dauer einer Pause : 2 min
+Nach unten : <runter> Simulationsgesamtdauer : 34 min
+Ausbesserung : <HOP>
+Nächstes : <ESC> Fehlerzeichen : F
+
+Werkstückbreite : 15 Zeichen
+Werkstückhöhe : 12 Zeichen
+Anzahl Zeichen pro Werkstück : 180 Zeichen
+Umfang des Zeichensatzes : A ... Z ( 26 Zeichen)
+
+ Beispielwerkstück:
+ ------------------
+ QQSEUZSTABQBZWI
+ UKZVNYPHCPLQMGH
+ NDJZPCMOOPQQICL
+ ARELRDKUOOZWOIE
+ NASIPRLRQUKJHGN
+ YJJVKIGWCJOLRTL
+ FXSZBOBIBKQPYXN
+ JJFKFMEVALZNDPU
+ VTWWIHKWRMPMHZP
+ CSSFZBOSACLARKQ
+ WAAIMHJELLFKIWA
+ XLNHUCZRVXOXHRL
+
+
+
+ G e s a m t a u s w e r t u n g:
+ ================================
+Anzahl der vollständig bearbeiteten Werkstücke : 51
+Anzahl der Zeichen pro Werkstück : 180
+Anzahl der insgesamt untersuchten Zeichen : 9180
+
+Anzahl der Bedienfehler : 3
+
+Anzahl der vorgegebenen Fehler : 363
+Anzahl der Fehlerkorrekturen : 304
+Arbeitszeit (incl. Pausenüberschreitungen) : 1792.5 sec
+Anzahl bearbeiteter Zeichen pro Sekunde : 5.1
+
+Ausbesserungsrate : 0.8
+Bewertungsfaktor : 0.8
+
+Gesamtbewertung (incl. Pausenüberschreitungen) : 4.3
+================================================ ========
+Arbeitszeit (ohne Pausenüberschreitungen) : 1788.5 sec
+Anzahl bearbeiteter Zeichen pro Sekunde : 5.1
+Gesamtbewertung (ohne Pausenüberschreitungen) : 4.3
+================================================ ========
+
+
+ Einzelauswertung der Werkstücke:
+ ================================
+
+Werk- | Anzahl | Vorge- | Anzahl | Benö- | Zei- | Aus- |Bewer- | Bewer-
+stück- | Be- | gebene | Kor- | tigte | chen | bes- |tungs- | tungs-
+nummer | dien- | Feh- | rek- | Zeit | pro | se- |faktor | zahl
+ | feh- | ler- | turen | [sec] | Se- | rungs-| |
+ | ler | zahl | | | kunde | rate | |
+--------------------------------------------------------------------------
+ | | | | | | | |
+ 1 | 0 | 5 | 3 | 45.6 | 3.9 | 0.6 | 0.6 | 2.4
+ 2 | 0 | 10 | 6 | 33.5 | 5.4 | 0.6 | 0.6 | 3.2
+ 3 | 0 | 5 | 4 | 35.7 | 5.0 | 0.8 | 0.8 | 4.0
+ 4 | 0 | 3 | 3 | 33.9 | 5.3 | 1.0 | 1.0 | 5.3
+ 5 | 0 | 10 | 7 | 38.0 | 4.7 | 0.7 | 0.7 | 3.3
+ 6 | 0 | 5 | 4 | 37.2 | 4.8 | 0.8 | 0.8 | 3.9
+ 7 | 0 | 9 | 8 | 36.9 | 4.9 | 0.9 | 0.9 | 4.3
+ 8 | 0 | 5 | 4 | 31.7 | 5.7 | 0.8 | 0.8 | 4.5
+ 9 | 0 | 4 | 3 | 27.3 | 6.6 | 0.8 | 0.8 | 4.9
+ 10 | 0 | 6 | 6 | 33.3 | 5.4 | 1.0 | 1.0 | 5.4
+ 11 | 0 | 3 | 3 | 25.0 | 7.2 | 1.0 | 1.0 | 7.2
+ 12 | 0 | 6 | 3 | 28.6 | 6.3 | 0.5 | 0.5 | 3.1
+ 13 | 0 | 11 | 10 | 37.9 | 4.7 | 0.9 | 0.9 | 4.3
+ 14 | 0 | 4 | 4 | 38.3 | 4.7 | 1.0 | 1.0 | 4.7
+ 15 | 0 | 11 | 8 | 39.3 | 4.6 | 0.7 | 0.7 | 3.3
+ 16 | 0 | 5 | 4 | 28.4 | 6.3 | 0.8 | 0.8 | 5.1
+ 17 | 0 | 4 | 4 | 36.4 | 4.9 | 1.0 | 1.0 | 4.9
+ 18 | 0 | 15 | 14 | 44.9 | 4.0 | 0.9 | 0.9 | 3.7
+
+ PAUSE ---> Überzogen um 2.2 sec
+
+ 19 | 0 | 3 | 3 | 38.9 | 4.6 | 1.0 | 1.0 | 4.6
+ 20 | 0 | 11 | 10 | 40.2 | 4.5 | 0.9 | 0.9 | 4.1
+ 21 | 0 | 8 | 7 | 34.7 | 5.2 | 0.9 | 0.9 | 4.5
+ 22 | 0 | 7 | 5 | 30.3 | 5.9 | 0.7 | 0.7 | 4.2
+ 23 | 0 | 4 | 4 | 33.9 | 5.3 | 1.0 | 1.0 | 5.3
+ 24 | 0 | 7 | 7 | 39.5 | 4.6 | 1.0 | 1.0 | 4.6
+ 25 | 0 | 6 | 4 | 28.1 | 6.4 | 0.7 | 0.7 | 4.3
+ 26 | 0 | 11 | 10 | 34.8 | 5.2 | 0.9 | 0.9 | 4.7
+ 27 | 0 | 11 | 9 | 34.2 | 5.3 | 0.8 | 0.8 | 4.3
+ 28 | 0 | 10 | 8 | 35.0 | 5.1 | 0.8 | 0.8 | 4.1
+ 29 | 0 | 9 | 8 | 36.4 | 4.9 | 0.9 | 0.9 | 4.4
+ 30 | 0 | 8 | 7 | 34.8 | 5.2 | 0.9 | 0.9 | 4.5
+ 31 | 0 | 10 | 8 | 36.2 | 5.0 | 0.8 | 0.8 | 4.0
+ 32 | 0 | 10 | 10 | 44.0 | 4.1 | 1.0 | 1.0 | 4.1
+ 33 | 0 | 8 | 8 | 44.4 | 4.1 | 1.0 | 1.0 | 4.1
+ 34 | 0 | 4 | 3 | 35.6 | 5.1 | 0.8 | 0.8 | 3.8
+
+ PAUSE ---> Überzogen um 1.8 sec
+
+ 35 | 0 | 8 | 8 | 42.7 | 4.2 | 1.0 | 1.0 | 4.2
+ 36 | 1 | 8 | 8 | 45.3 | 4.0 | 1.0 | 1.0 | 4.0
+ 37 | 0 | 5 | 5 | 34.3 | 5.2 | 1.0 | 1.0 | 5.2
+ 38 | 0 | 5 | 4 | 27.9 | 6.5 | 0.8 | 0.8 | 5.2
+ 39 | 0 | 10 | 8 | 39.5 | 4.6 | 0.8 | 0.8 | 3.6
+ 40 | 1 | 7 | 6 | 35.5 | 5.1 | 0.9 | 0.9 | 4.3
+ 41 | 0 | 3 | 3 | 29.5 | 6.1 | 1.0 | 1.0 | 6.1
+ 42 | 0 | 5 | 5 | 30.2 | 6.0 | 1.0 | 1.0 | 6.0
+ 43 | 0 | 6 | 3 | 28.0 | 6.4 | 0.5 | 0.5 | 3.2
+ 44 | 0 | 5 | 4 | 30.2 | 6.0 | 0.8 | 0.8 | 4.8
+ 45 | 0 | 5 | 4 | 33.1 | 5.4 | 0.8 | 0.8 | 4.4
+ 46 | 0 | 8 | 7 | 33.7 | 5.3 | 0.9 | 0.9 | 4.7
+ 47 | 0 | 9 | 7 | 32.2 | 5.6 | 0.8 | 0.8 | 4.3
+ 48 | 0 | 9 | 8 | 37.5 | 4.8 | 0.9 | 0.9 | 4.3
+ 49 | 0 | 4 | 4 | 32.0 | 5.6 | 1.0 | 1.0 | 5.6
+ 50 | 0 | 9 | 7 | 34.8 | 5.2 | 0.8 | 0.8 | 4.0
+ 51 | 1 | 9 | 4 | 29.2 | 6.2 | 0.4 | 0.4 | 2.7
+ | | | | | | | |
+==========================================================================
+
+( 52 | 0 | 7 | 7 | 35.9 | 5.0 | 1.0 | 1.0 | 5.0)
+
+ Anmerkungen:
+ =============
+
+ - Das zuletzt bearbeitete Werkstück (in der obigen Tabelle unterhalb
+ der letzten Trennlinie in Klammern angegeben) wurde nicht vollstän-
+ dig innerhalb der zur Verfügung stehenden Zeit bearbeitet.
+ Aus diesem Grunde wird es bei der Auswertung (Gesamtwertung) nicht
+ berücksichtigt!
+
+ - Bei der Auflistung der Daten der einzelnen Werkstücke sind auch die
+ Pausen eingetragen, so daß sich die einzelnen Arbeitsphasen erken-
+ nen und miteinander vergleichen lassen. Die dabei notierten Zeiten
+ geben die Pausenüberschreitungen an. Diese Zeiten bleiben bei der
+ Betrachtung der einzelnen Werkstücke unberücksichtigt, fließen aber
+ in die Gesamtauswertung ein!
+
+ - Die Anzahl der Bedienfehler ist ein Maß für die Sicherheit im Um-
+ gang mit dem System. Bei den weiteren Auswertungen bleibt die Be-
+ dienfehlerzahl allerdings unberücksichtigt!
+
+ - Die 'Vorgegebene Fehlerzahl', die 'Anzahl Korrekturen' und die 'Be-
+ nötigte Zeit [sec]' wurden bei der Bearbeitung des Werkstücks er-
+ faßt. Auf diesen Daten beruhen die folgenden Auswertungen!
+
+ - Da die Werkstücke ganz unterschiedliche Größen haben können, eignet
+ sich die 'Benötigte Zeit [sec]', die für die Bearbeitung eines je-
+ den Werkstücks ermittelt wird, als Maß für die "Arbeitsgeschwindig-
+ keit" nicht! Stattdessen wird ermittelt, wie viele Zeichen pro Se-
+ kunde "bearbeitet" wurden:
+
+ Anzahl Zeichen pro Werkstück
+ Zeichen pro Sekunde = ----------------------------
+ Benötigte Zeit [sec]
+
+ Die 'Anzahl Zeichen pro Werkstück' kann aus der Werkstückbreite und
+ Werkstückhöhe ermittelt werden:
+
+ Anzahl Zeichen pro Werkstück = Werkstückbreite * Werkstückhöhe
+
+ - Aus der (zufällig) 'Vorgegebenen Fehlerzahl' und der 'Anzahl Kor-
+ rekturen' wird die 'Ausbesserungsrate' ermittelt:
+
+ Anzahl Korrekturen
+ Ausbesserungsrate = ----------------------
+ Vorgegebene Fehlerzahl
+
+ Die Ausbesserungsrate gibt an, welcher Anteil der vorhandenen Feh-
+ ler ausgebessert wurde. Sie ist ein Maß für die Güte der verrichte-
+ ten Arbeit.
+
+ - Der 'Bewertungsfaktor' ist abhängig von der 'Ausbesserungsrate'. Er
+ läßt sich aus dem folgenden Diagramm entnehmen:
+
+ Bewertungs-
+ faktor
+
+ 1.0| +
+ | +
+ | +
+ | +
+ | +
+ 0.5| +
+ | +
+ | +
+ | +
+ | +
+ 0.0+--|--|--|--|--|--|--|--|--|--|
+ 0.0 0.5 1.0
+ Ausbesserungsrate
+
+
+ In diesem Diagramm ist festgelegt, wie die einzelnen 'Ausbesse-
+ rungsraten' bewertet werden.
+
+ - Am Ende wird die 'Bewertungszahl' folgendermaßen ermittelt:
+
+ Bewertungszahl = Zeichen pro Sekunde * Bewertungsfaktor
+
+ Da der 'Bewertungsfaktor' nur Werte zwischen 0 und 1 annehmen kann,
+ ist die 'Bewertungszahl' ein Wert zwischen 0 und der 'Zeichen pro
+ Sekunde'. Die "Arbeitsleistung" war um so größer, je höher die 'Be-
+ wertungszahl ist.
+
+Eine weitere Kommentierung des Protokolls dürfte
+sich wohl erübrigen, wenn Sie die Anmerkungen in­
+tensiv studiert haben.
+
+
+4.5 Hinweise zur Protokollauswertung
+
+4.5.1 Der Bewertungsfaktor
+
+ Sie haben sich sicher über den sogenannten 'Be­
+wertungsfaktor' gewundert, der an verschiedenen
+Stellen genannt wird - aber bisher unberücksichtigt
+blieb. In den bisher aufgezeigten Situationen war
+der Bewertungsfaktor identisch mit der 'Ausbesse­
+rungsrate'. Warum dieser Faktor gesondert einge­
+führt wurde, möchten wir an einem kleinen Beispiel
+erläutern:
+ Wenn Ihnen der Auswertalgorithmus vor dem Simu­
+lationslauf bekannt gewesen wäre und Sie die Ab­
+sicht gehabt hätten, eine möglichst hohe Bewer­
+tungszahl zu erzielen, wäre folgende "Arbeitsstra­
+tegie" erfolgversprechend gewesen:
+ Sobald ein Werkstück auf dem Bildschirm er­
+scheint, bewegen Sie den Cursor schnellstens zum
+ersten Fehlerzeichen, das Sie entdecken können und
+löschen es mit der Ausbesserungstaste. Sollten zu­
+fällig noch weiterer Fehlerzeichen in unmittelbarer
+Nähe zu sehen sein, so können Sie sie ja auch "aus­
+merzen" - aber dann schnell das nächste Werkstück
+anfordern usw.
+ Machen wir uns klar, was das bedeutet: Da sie
+das Werkstück in sehr kurzer Zeit bearbeitet haben,
+wird der eigentlich entscheidende Faktor hinsicht­
+lich der Auswertung "enorm in die Höhe getrieben"
+(die Anzahl der Zeichen pro Sekunde). Da Sie bei
+dieser Strategie zumeist nur 2 - 4 Sekunden zur
+Bearbeitung eines Werkstücks brauchen, erhalten Sie
+- auf das obige Beispielprotokoll bezogen - Werte
+zwischen 90.0 und 45.0 (bearbeitete Zeichen pro
+Sekunde).
+ Im Schnitt treten pro Werkstück etwa 7 Fehler­
+zeichen auf (sehen Sie dazu auch unter 'Aufbau der
+Werkstücke'), von denen Sie dann eines korrigiert
+haben. Sie kommen also auf eine durchschnittliche
+Ausbesserungsrate von 0.14. Wäre - wie im obigen
+Beispielprotokoll - der Bewertungsfaktor mit der
+Ausbesserungsrate identisch, so erhielten Sie Be­
+wertungszahlen zwischen 12.9 und 6.4. Ein deut­
+licher Unterschied zur "Leistung" die im Protokoll
+dokumentiert ist - oder?
+ Das aber ist nicht Sinn der dem Benutzer ge­
+stellten Aufgabe! Es würde auch nicht einer sinn­
+vollen 'Kontrolltätigkeit' entsprechen, wenn derart
+viele Fehler unentdeckt blieben. Um hier "regulie­
+rend" einschreiten zu können, ist der 'Bewertungs­
+faktor' eingeführt worden. So können Sie festlegen,
+daß Werkstücke, in denen weniger als 80% der Fehler
+entdeckt wurden, bei der Auswertung unberücksich­
+tigt bleiben. Sie brauchen dazu nur den Bewertungs­
+schlüssel entsprechend einzustellen. ("Ziehen Sie
+dazu bei der Einstellung des Bewertungsschlüssels
+die ersten 8 Kreuzchen auf die Grundlinie").
+ Anders ausgedrückt: Durch die Manipulation des
+Bewertungsschlüssels können Sie die Anforderungen,
+die an die Werkstückbearbeitung gestellt werden,
+festlegen. Hierdurch entscheiden Sie über die Wer­
+tigkeit von Schnelligkeit und Genauigkeit.
+ Übrigens wird der zur Simulationszeit einge­
+stellte Wertungsschlüssel mit im Protokoll notiert.
+Eine Auswertung des Protokolls mit verschiedenen
+Wertungsschlüsseln ist so nicht möglich - und auch
+nicht sinnvoll. Denn sonst könnte es ja vorkommen,
+daß der Anwender ein ganz anderes Ergebnis in der
+Kurzauswertung auf dem Bildschirm gezeigt bekommt
+als er nachher im Protokoll nachlesen kann. Wenn
+Sie also mit einem veränderten Wertungsschlüssel
+arbeiten wollen, müssen Sie ihn #on("u")#vor dem Simula­
+tionslauf#off("u")# eingestellt haben!
+
+
+4.5.2 Fehlerzeichenhäufigkeit in den Werkstücken
+
+ Die Häufigkeit des Auftretens der Fehlerzeichen
+in den einzelnen Werkstücken kann deutlich schwan­
+ken. Die Werkstücke werden nämlich mit Hilfe des
+Zufallszahlengenerators aufgebaut. Je nach Anzahl
+der verschiedenen Zeichen, die in einem Werkstück
+auftreten können, ändert sich auch der Anteil der
+auftretenden Fehlerzeichen.
+ In unserem bisher betrachteten Beispiel können
+26 verschiedene Buchstaben im Werkstück auftreten.
+Ein Werkstück besteht aus 180 Zeichen. In 1/26 al­
+ler Fälle müßte also das Fehlerzeichen auftreten,
+d.h. also etwa 7 Fehlerzeichen pro Werkstück - al­
+lerdings auf eine große Anzahl von produzierten
+Werkstücken bezogen. Da die Werkstücke zufällig
+zusammengesetzt werden, gilt dieser Wert natürlich
+nicht für das einzelne Werkstück!
+
+
+4.5.3 Fehlerhafte Auswertungen
+
+ In zwei Situationen kann es zu Fehlern bei der
+Auswertung von Protokollen kommen:
+
+ Wurde der Simulationslauf mit der <SV>-Taste
+rigoros abgebrochen, so ist ggf. eine sinnvolle
+Auswertung des Protokolls nicht möglich, da nur
+unvollständige Daten vorhanden sind.
+
+ In der letzten Arbeitsphase eines Simulations­
+laufes muß zumindest ein Werkstück angefordert wor­
+den sein. Dehnt ein Anwender die letzte Pause so
+lange aus, daß das Pausenende über das Ende der
+letzten Arbeitsphase hinausreicht, so erscheinen im
+Protokoll keine Werte für die einzelnen Werkstücke
+- in der Gesamtauswertung sind (fast) alle Werte
+auf '0' gesetzt.
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5
new file mode 100644
index 0000000..d08e4a7
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5
@@ -0,0 +1,699 @@
+#limit (11.0)##pagelength (16.5)##block##pageblock#
+#start (2.0,0.0)#
+#page (40)#
+#headodd#
+#center#gs-MP BAP#right#%
+
+#end#
+#headeven#
+%#center#gs-MP BAP
+
+#end#
+#center#5
+
+#center#Beschreibung
+#center#der
+#center#Menufunktionen
+
+#center#(Programmteil 'Bildschirmarbeitsplatz' (BAP))
+
+
+5.1 Kurzhinweise zur Bedienung des Menus
+
+ Die Bedienung des Menus ist sehr einfach. Eine
+ausführliche Beschreibung dazu finden Sie in den
+Unterlagen zum Programmsystem #on("b")#gs-DIALOG#off("b")#. An dieser
+Stelle sollen nur die wesentlichen Bedienungsvor­
+gänge beschrieben werden.
+
+- Mit der Tastenfolge <ESC><?> können Sie sich
+ Informationen zur Bedienung des Menusystems in
+ das Menu einblenden lassen.
+
+- Mit den Pfeiltasten <rechts> und <links> können
+ Sie zwischen den "Oberbegriffen" in der Kopfzei­
+ le wählen. Der aktuelle Oberbegriff ist jeweils
+ invers dargestellt. Das ausgeklappte 'Pull-
+ Down-Menu' bezieht sich auf diesen invers darge­
+ stellten Oberbegriff.
+
+- Mit den Pfeiltasten <hoch> und <runter> können
+ Sie zwischen den Menufunktionen wählen, die
+ Ihnen im aktuellen Pull-Down-Menu zur Auswahl
+ angeboten werden. Die aktuell angewählte Menu­
+ funktion wird jeweils invers dargestellt. Die
+ Trennlinien, die in einigen Pull-Down-Menus
+ sichtbar sind, dienen nur der optischen Unter­
+ gliederung; sie können nicht angewählt werden
+ und werden deshalb automatisch übersprungen. Die
+ einzelnen Menupunkte sind "zyklisch miteinander
+ verknüpft", das heißt, man gelangt vom untersten
+ Menupunkt wieder zum obersten und umgekehrt.
+ Menupunkte, vor denen ein Minuszeichen steht
+ ('-'), sind (zur Zeit) nicht aktivierbar; auch
+ sie können nicht angewählt werden und werden
+ einfach übersprungen.
+
+- Durch Tippen der Fragezeichentaste (<?>) können
+ Sie sich jeweils zur aktuellen Menufunktion (in­
+ vers im Pull-Down-Menu) Informationen in das
+ Menu einblenden lassen.
+
+- Um eine Menufunktion ausführen zu lassen, bewe­
+ gen Sie sich mit den Pfeiltasten auf die ge­
+ wünschte Menufunktion im aktuellen Pull-Down-
+ Menu und tippen dann die <RETURN>-Taste. Steht
+ vor dem gewünschten Menupunkt ein einzelner
+ Buchstabe oder eine Ziffer, so kann durch Tippen
+ der entsprechenden Taste diese Menufunktion da­
+ durch direkt aufgerufen werden. Sobald eine Me­
+ nufunktion aufgerufen worden ist, erscheint da­
+ vor ein Stern ('*'). Daraus können Sie entneh­
+ men, daß das System bereits den Auftrag aus­
+ führt.
+
+- An verschiedenen Stellen werden Fragen an Sie
+ gerichtet, die Sie mit 'ja' oder 'nein' beant­
+ worten müssen. Tippen Sie dazu entsprechend der
+ Entscheidung die Taste <j> (für 'ja') bzw. <n>
+ (für 'nein').
+
+- Werden Ihnen vom Menu aus Dateinamen zur Auswahl
+ angeboten, so können Sie den auf dem Bildschirm
+ sichtbaren Pfeil vor den gewünschten Namen posi­
+ tionieren. Mit den Tasten <x> oder <RETURN> kön­
+ nen Sie den Namen ankreuzen. Ist die Auswahl
+ mehrerer Dateinamen möglich, so können Sie den
+ Vorgang wiederholen. Mit den Tasten <o> oder
+ <RUBOUT> können Sie auch ein Kreuz vor einem
+ Namen wieder löschen. Daneben gibt es noch eini­
+ ge Tastenfunktionen, die für die Bedienung recht
+ hilfreich sein können. Tippen Sie während der
+ Auswahl die Fragezeichentaste (<?>), so werden
+ Ihnen alle Bedienungsmöglichkeiten auf dem Bild­
+ schirm angezeigt. Eine Auswahl, in der mehrere
+ Dateien angekreuzt werden dürfen, wird durch die
+ Tastenfolge <ESC><q> verlassen. Anschließend
+ wird die eingestellte Operation mit den ange­
+ kreuzten Dateien ausgeführt. Sind Sie versehent­
+ lich in eine solche Auswahl gelangt, so können
+ Sie den Vorgang durch die Tastenkombination
+ <ESC><h> abbrechen.
+
+- An einigen Stellen werden Sie aufgefordert, eine
+ Eingabe zu machen (z.B. einen Dateinamen einzu­
+ geben). Wird Ihnen hier ein Vorschlag gemacht,
+ den Sie akzeptieren, so brauchen Sie zur Bestä­
+ tigung nur die <RETURN>-Taste zu tippen. Ge­
+ fällt Ihnen der Vorschlag nicht oder wird Ihnen
+ kein Vorschlag gemacht, so machen Sie bitte die
+ gewünschte Eingabe. Zum Schreiben stehen Ihnen
+ alle aus dem Editor bekannten Funktionen zur
+ Verfügung. Mit der Taste <RUBOUT> können Sie
+ Buchstaben löschen, mit <RUBIN> einfügen. Die
+ Eingabe wird durch Tippen der <RETURN>-Taste
+ abgeschlossen. Ist der von Ihnen gewünschte Name
+ schon in Ihrer Task vorhanden und steht in der
+ Fußzeile der Hinweis 'Zeigen: <ESC><z>', dann
+ können Sie sich auch alle vorhandenen Namen zur
+ Auswahl anbieten lassen und durch Ankreuzen den
+ beabsichtigten Namen auswählen.
+
+- Ihnen können auch mehrere Alternativen angeboten
+ werden, zwischen denen Sie wählen müssen. In der
+ untersten Zeile eines solchen Kastens, in denen
+ Ihnen die Alternativen auf dem Bildschirm einge­
+ blendet werden, sind die Möglichkeiten aufge­
+ führt, die darüber beschrieben sind. Mit den
+ Pfeiltasten können sie die Markierung auf die
+ gewünschte Alternative positionieren und dann
+ durch die <RETURN>-Taste zur Ausführung bringen.
+ (Manchmal ist das auch durch Tippen der den Al­
+ ternativen vorangestellten Buchstaben oder Zif­
+ fern möglich).
+
+- Durch die Tastenfolge <ESC><q> kann das Menu
+ insgesamt verlassen werden. Damit das nicht ver­
+ sehentlich geschieht, wird jeweils die Frage
+ gestellt, ob Sie das Menu tatsächlich verlassen
+ wollen. Diese Frage beantworten Sie bitte je
+ nach Wunsch mit 'ja' oder 'nein' durch Tippen
+ der Tasten <j> bzw. <n>.
+
+#page#
+5.2 Menufunktionen zum Oberbegriff 'Simulation'
+
+#on("b")#
+BAP: Simulation Parameter Konfiguration Dateien Archiv
++-------------------------------+-----------------------------------------
+| s Simulation ausführen |
+| --------------------------- |
+| a Auswertung auf Bildschirm |
+| d Drucken von Auswertungen |
++-------------------------------+
+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+#on("u")##on("b")#s Simulation ausführen#off("b")##off("u")#
+ Mit dieser Menufunktion starten Sie einen
+ Simulationslauf. Bevor Sie aber mit der Arbeit
+ am Bildschirmarbeitsplatz beginnen können,
+ wird eine "Identifikation" (Vor- und Nachname)
+ von Ihnen verlangt. Das Protokoll, das bei der
+ Simulation entsteht, erhält dann die hier ein­
+ gegebene Kennung. Geben Sie für mehrere Proto­
+ kolle den gleichen Namen an, so werden die
+ Protokolle in der Reihenfolge ihrer Anlage
+ durchnumeriert.
+ Nach Eingabe der Kennung werden oben auf
+ dem Bildschirm die zur Zeit eingestellten Si­
+ mulationsdaten angezeigt - alle Daten, die Sie
+ zur Bedienung während der Simulation benöti­
+ gen. Die eigentliche Simulation beginnt erst
+ mit dem nächsten Tastendruck; dazu erfolgt ein
+ Hinweis auf dem Bildschirm.
+ Nach Abschluß der Simulation wird Ihnen
+ gegebenenfalls (sehen Sie dazu auch die Menu­
+ funktion 'k Kurzauswertung' unter dem Oberbe­
+ griff 'Konfiguration') eine Kurzauswertung auf
+ dem Bildschirm ausgegeben. Anschließend gelan­
+ gen Sie zurück in das Menu.
+ Diese Menufunktion hat eine ähnliche Wir­
+ kung wie der Aufruf des Programms 'Material­
+ prüfung' (MP). Im Gegensatz zum Aufruf des
+ Programms 'Materialprüfung' (MP - mit dem Be­
+ fehl: mp <RETURN>) werden hier allerdings kei­
+ ne ausführlichen Informationen vor dem eigent­
+ lichen Simulationslauf ausgegeben, sondern es
+ wird nur nach einer Identifikation (Vorname
+ und Nachname) gefragt. Nach Abschluß der Si­
+ mulation verbleibt das Protokoll in der Task -
+ es wird nicht, wie im Programmteil 'Material­
+ prüfung', in die Vatertask geschickt.
+
+#on("u")##on("b")#a Auswertung auf Bildschirm#off("b")##off("u")#
+ Alle Simulationsprotokolle, die sich in
+ Ihrer Task befinden, werden Ihnen zur Auswahl
+ angeboten. Wenn Sie den/die gewünschten Proto­
+ kollnamen angekreuzt und die Auswahl mit der
+ Tastenfolge <ESC><q> verlassen haben, werden
+ die Protokolle nacheinander in der Ankreuzrei­
+ henfolge ausgewertet und die Auswertungen auf
+ dem Bildschirm angezeigt.
+ Die gesamte Auswertung kann zwar nicht auf
+ einmal auf dem Bildschirm angezeigt werden -
+ Sie können aber das Fenster mit <HOP><hoch>
+ und <HOP><runter> rollen und so in die gesamte
+ Datei Einsicht nehmen. Gegebenenfalls (sehen
+ Sie dazu auch die Menufunktion 'u Umfang der
+ Auswertung' unter dem Oberbegriff 'Konfigura­
+ tion') werden an das Ende der eigentlichen
+ Ergebnisse noch Erläuterungen zum Protokoll
+ ausgegeben. (Zur Protokollauswertung selbst
+ sehen Sie bitte Kapitel 4.4). Da die Auswer­
+ tung jeweils in eine Datei geschrieben wird,
+ können Sie sie mit der Tastenkombination
+ <ESC><q> verlassen.
+
+ Fehlerfälle: - Sehen Sie dazu bitte Kapitel
+ 4.5.3
+
+#on("u")##on("b")#d Drucken von Auswertungen#off("b")##off("u")#
+ Alle Simulationsprotokolle, die sich in
+ Ihrer Task befinden, werden Ihnen zur Auswahl
+ angeboten. Wenn Sie den/die gewünschten Proto­
+ kollnamen angekreuzt und die Auswahl mit der
+ Tastenfolge <ESC><q> verlassen haben, werden
+ die Protokolle nacheinander in der Ankreuzrei­
+ henfolge ausgewertet und die Auswertdateien
+ zum Drucker geschickt.
+ #on("b")#ACHTUNG!#off("b")# Zum Ausdruck von Simulationsproto­
+ kollen muß unbedingt diese Menufunktion ge­
+ wählt werden! Zwar können normale Textdateien
+ auch mit dem Menupunkt 'Drucken' unter dem
+ Oberbegriff 'Dateien' ausgedruckt werden - das
+ gilt aber nicht für die bei den Simulationen
+ erzeugten Protokolldateien, die Sie am Präfix
+ 'gs-Protokoll:' erkennen können.
+ Der Ausdruck der Protokollauswertungen er­
+ folgt normalerweise im Standardschrifttyp Ih­
+ res Druckers. Es besteht allerdings die Mög­
+ lichkeit, einen anderen Schrifttyp für den
+ Ausdruck der Protokolldateien einzustellen.
+ Sehen Sie dazu bitte im Kapitel 6 'Hinweise
+ für den Systembetreuer'.
+
+#page#
+5.3 Menufunktionen zum Oberbegriff 'Parameter'
+
+#on("b")#
+BAP: Simulation Parameter Konfiguration Dateien Archiv
+-------+---------------------------+--------------------------------------
+ | e Einstellung anzeigen |
+ | s Standardwerte |
+ | ----------------------- |
+ | b Breite des Werkstücks |
+ | h Höhe des Werkstücks |
+ | i Invers-/Normal |
+ | z Zeichensatz |
+ | f Fehlerzeichen |
+ | t Tastenbelegung |
+ | ----------------------- |
+ | a Anzahl Arbeitsphasen |
+ | d Dauer Arbeitsphase |
+ | p Pausendauer |
+ | ----------------------- |
+ | w Wertungsschlüssel |
+ +---------------------------+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+#on("u")##on("b")#e Einstellung anzeigen#off("b")##off("u")#
+ Auf dem Bildschirm erscheinen zwei Fenster.
+ Im Fenster links werden alle Werte angezeigt,
+ die die Parameter zur Zeit annehmen. Oben kön­
+ nen Sie ablesen, welches Aussehen ein Werk­
+ stück nach der augenblicklichen Einstellung
+ auf dem Bildschirm hätte. Darunter ist angege­
+ ben, welche Tasten bei der Bearbeitung der
+ Werkstücke während des Simulationslauf benutzt
+ werden können. Unten ist noch aufgeführt, wie
+ viele Arbeitsphasen vorgesehen sind und wie
+ lange die Arbeitsphasen, Pausen und die Ge­
+ samtsimulation dauern.
+ Im Fenster rechts wird ein Diagramm ausge­
+ geben. Hier ist der Bewertungsfaktors in Ab­
+ hängigkeit von der Ausbesserungsrate darge­
+ stellt. Hinsichtlich der Bedeutung des Bewer­
+ tungsfaktors sehen Sie bitte in Kapitel 4.5.1.
+ Die Anzeige kann durch Tippen einer belie­
+ bigen Taste verlassen werden.
+
+#on("u")##on("b")#s Standardwerte#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie mit ei­
+ nem Tastendruck die sogenannten "Standardwer­
+ te" einstellen - die Werte, die die Parameter
+ haben, wenn das System "frisch installiert"
+ ist.
+ Zur Sicherheit zeigt das System die aktuel­
+ len Werte an und erfragt, ob Sie die Standard­
+ werte tatsächlich einstellen wollen. Bejahen
+ Sie diese Frage, so werden alle aktuellen Wer­
+ te durch die Standardwerte überschrieben und
+ auf dem Bildschirm angezeigt. Von dieser Ein­
+ stellung ist auch der Wertungsschlüssel be­
+ troffen - der aber nicht angezeigt wird. Die
+ Einstellung wird derart vorgenommen, daß Be­
+ wertungsfaktor und Ausbesserungsrate identisch
+ sind.
+
+#on("u")##on("b")#b Breite des Werkstücks#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie die An­
+ zahl der Zeichen je Werkstückzeile festlegen.
+ Im Fenster links oben werden der kleinstmög­
+ liche Wert (1), der größtmögliche Wert (70)
+ und der aktuell eingestellte Wert angezeigt.
+ Unten erscheint zur Kontrolle ein Werkstück,
+ das den aktuellen Parameterwerten entspricht.
+ Im Fenster rechts oben wird an Sie die Fra­
+ ge gerichtet, ob Sie tatsächlich eine Verände­
+ rung vornehmen möchten. Haben Sie versehent­
+ lich diesen Menupunkt gewählt, verneinen Sie
+ einfach diese Frage (Taste <n>) und gelangen
+ so - unter Beibehaltung des z.Z. eingestellten
+ Wertes - zurück in das Menu.
+ Bejahen Sie die Frage, so erhalten Sie die
+ Möglichkeit, den bisher eingestellten Wert mit
+ der Pfeiltaste <hoch> zu erhöhen, mit der
+ Pfeiltaste <runter> zu erniedrigen - aller­
+ dings nur innerhalb der angezeigten Grenzen.
+ Wenn Sie die gewünschte Einstellung vorgenom­
+ men und die Eingabe durch <RETURN> abgeschlos­
+ sen haben, erscheint ein Werkstück in der neu
+ eingestellten Breite unten auf dem Bildschirm.
+ Bejahen Sie die Frage, ob Sie mit der Werk­
+ stückbreite einverstanden sind, dann gelangen
+ Sie ins Menu zurück; ansonsten können Sie die
+ Werkstückbreite nach gleichem Verfahren erneut
+ einstellen.
+
+#on("u")##on("b")#h Höhe des Werkstücks#off("b")##off("u")#
+ Die Einstellung der Werkstückhöhe (Anzahl
+ Zeichen pro Werkstückspalte) erfolgt analog
+ zur Einstellung der Werkstückbreite - sehen
+ Sie bitte dort.
+
+#on("u")##on("b")#i Invers-/Normal#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie festle­
+ gen, ob das zu bearbeitende Werkstück 'normal'
+ oder 'invers' dargestellt wird. Diese Darstel­
+ lung ist aber immer in Abhängigkeit von der
+ Grundeinstellung Ihres Bildschirms zu sehen.
+ Wenn Ihr Bildschirm normalerweise helle Zei­
+ chen auf dunklem Grund darstellt, so bedeutet
+ 'normal' eben diese Einstellung; 'invers' be­
+ deutet dann, daß die Zeichen des Werkstücks
+ dunkel auf hellem Grund dargestellt werden -
+ bei anderer Bildschirmgrundeinstellung eben
+ umgekehrt.
+ Unten auf dem Bildschirm wird Ihnen zur
+ Kontrolle ein Werkstück in aktueller Darstel­
+ lung gezeigt. Im Fenster oben rechts erscheint
+ die Frage, ob Sie eine Veränderung der augen­
+ blicklichen Einstellung wünschen. Je nachdem,
+ ob Sie die Frage bejahen oder verneinen, wird
+ eine Veränderung vorgenommen oder nicht.
+
+#on("u")##on("b")#z Zeichensatz#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie das Feh­
+ lerzeichen festlegen und bestimmen, aus wel­
+ chen Zeichen die Werkstücke zusammengesetzt
+ werden sollen. Bejahen Sie die Frage nach der
+ Neufestlegung des Zeichensatzes, so werden
+ Ihnen im Fenster links alle möglichen Zeichen
+ angezeigt. Die Zeichen werden hier in der Rei­
+ henfolge ihres internen Codes ausgegeben. Sie
+ können nun - indem Sie einfach die entspre­
+ chende Taste tippen - eines der angegebenen
+ Zeichen als 'Fehlerzeichen' bestimmen. Es wird
+ daraufhin invers dargestellt.
+ Anschließend können Sie die Zeichen bestim­
+ men, die sonst noch im Werkstück vorkommen
+ sollen. Allerdings sind Sie bei dieser Wahl
+ nicht so frei wie bei der Wahl des Fehlerzei­
+ chens. Es muß sich um einen zusammenhängenden
+ Bereich von Zeichen handeln, die um das Feh­
+ lerzeichen gruppiert sind - 'zusammenhängend'
+ bezieht sich dabei auf die Reihenfolge der
+ Zeichen im Fenster links.
+ Die Festlegung selbst erfolgt in zwei Etap­
+ pen. Zuerst können Sie den Bereich der Zeichen
+ bestimmen, die in der Reihenfolge vor dem Feh­
+ lerzeichen stehen. Mit der Pfeiltaste <hoch>
+ markieren Sie den Bereich, der vor dem Fehler­
+ zeichen liegt; mit der Pfeiltaste <runter>
+ können Sie ggf. die Markierung wieder rückgän­
+ gig machen. Wenn Sie so den gewünschten Be­
+ reich markiert haben, tippen Sie die
+ <RETURN>-Taste.
+ Anschließend bestimmen Sie den Bereich hin­
+ ter dem Fehlerzeichen auf vergleichbare Weise
+ und schließen auch hier die Einstellung mit
+ der <RETURN>-Taste ab. Daraufhin wird Ihnen
+ der eingestellte Zeichensatz mit markiertem
+ Fehlerzeichen noch einmal zur Kontrolle im
+ Fenster links ausgegeben. Sind Sie mit der
+ Einstellung einverstanden, so bejahen Sie die
+ an Sie gerichtete Frage und gelangen ins Menu
+ zurück; ansonsten können Sie nach gleichem
+ Verfahren die Einstellung korrigieren.
+
+#on("u")##on("b")#f Fehlerzeichen#off("b")##off("u")#
+ Diese Menufunktion ist dann sinnvoll zu
+ wählen, wenn Sie den eingestellten Zeichensatz
+ beibehalten und nur das Fehlerzeichen verän­
+ dern wollen. Wenn Sie die Frage bejaht haben,
+ eine Veränderung vornehmen zu wollen, haben
+ Sie die Möglichkeit, durch Verschiebung der
+ Markierung im Fenster links (durch die Tasten
+ <hoch> und <runter>) das neue Fehlerzeichen
+ einzustellen. Die Einstellung wird durch
+ <RETURN> abgeschlossen. Sind Sie mit dem ein­
+ gestellten Fehlerzeichen einverstanden, gelan­
+ gen Sie zurück ins Menu; ansonsten können Sie
+ Ihre Einstellung korrigieren.
+
+#on("u")##on("b")#t Tastenbelegung#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie die Ta­
+ sten bestimmen, die bei einem Simulationslauf
+ zur Bedienung des Systems benutzt werden kön­
+ nen. Ihnen wird im Fenster links oben die ak­
+ tuelle Einstellung angezeigt. Haben Sie sich
+ entschlossen, eine Neueinstellung vorzunehmen,
+ werden nacheinander die entsprechenden Tasten
+ erfragt. Sie brauchen dabei jeweils nur die
+ Taste zu tippen, die Sie für die entsprechende
+ Funktion vorgesehen haben.
+ Sie können die Tasten nahezu frei wählen.
+ Es ist allerdings nicht erlaubt, die <SV>-
+ Taste zu wählen. Ebensowenig wird die Einstel­
+ lung akzeptiert, wenn Sie Mehrfachbelegungen
+ vornehmen, d.h, eine Taste für mehrere Funk­
+ tionen vorschlagen. Achten Sie deshalb immer
+ auf den Kommentar zur Einstellung im Fenster
+ unten links. Ist die Neueinstellung fehler­
+ haft, so erfolgt ein Hinweis darauf - in einem
+ solchen Falle bleibt die alte Tastenbelegung
+ erhalten.
+
+#on("u")##on("b")#a Anzahl Arbeitsphasen#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie festle­
+ gen, in wie viele Arbeitsphasen ein Simula­
+ tionslauf jeweils eingeteilt werden soll. Im
+ Fenster links oben werden der kleinstmögliche
+ Wert (2), der größtmögliche Wert (20) und der
+ aktuell eingestellte Wert angezeigt. Im Fen­
+ ster unten wird die aktuelle Simulationsdauer
+ angezeigt.
+ Im Fenster rechts oben wird an Sie die Fra­
+ ge gerichtet, ob Sie tatsächlich eine Verände­
+ rung vornehmen möchten. Bejahen Sie die Frage,
+ so erhalten Sie die Möglichkeit, den bisher
+ eingestellten Wert mit der Pfeiltaste <hoch>
+ zu erhöhen, mit der Pfeiltaste <runter> zu
+ erniedrigen - allerdings nur innerhalb der
+ angezeigten Grenzen.
+ Wenn Sie die gewünschte Einstellung vorge­
+ nommen und die Eingabe durch <RETURN> abge­
+ schlossen haben, erscheinen die neuen Simula­
+ tionszeiten im Fenster unten. Bejahen Sie die
+ Frage, ob Sie mit der Arbeitsphasenanzahl ein­
+ verstanden sind, dann gelangen Sie ins Menu
+ zurück; ansonsten können Sie nach gleichem
+ Verfahren die getroffene Einstellung korrigie­
+ ren.
+
+#on("u")##on("b")#d Dauer Arbeitsphase#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie festle­
+ gen, wie lange eine Arbeitsphase dauern soll.
+ Es kann ein Wert zwischen 1 min und 60 min
+ eingestellt werden. Das Einstellverfahren ver­
+ läuft analog zur Festlegung der Anzahl der
+ Arbeitsphasen - sehen Sie bitte dort.
+
+#on("u")##on("b")#p Pausendauer#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie festle­
+ gen, wie lange die Pause zwischen je zwei Ar­
+ beitsphasen dauern soll. Es kann ein Wert zwi­
+ schen 1 min und 30 min eingestellt werden. Das
+ Einstellverfahren verläuft analog zur Festle­
+ gung der Anzahl der Arbeitsphasen - sehen Sie
+ bitte dort.
+
+#on("u")##on("b")#w Wertungsschlüssel#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie den Wer­
+ tungsschlüssel festlegen. Zur genauen Erläu­
+ terung der Bedeutung des Bewertungsfaktors
+ sehen Sie bitte Kapitel 4.5.1.
+ Im Fenster links wird der aktuell einge­
+ stellte Wertungsschlüssel angezeigt. Stellen
+ Sie sich die ins Koordinatensystem eingetrage­
+ nen Kreuzchen durch einen Streckenzug verbun­
+ den vor. Entscheiden Sie sich für eine Neu­
+ festlegung, dann können Sie mit den Pfeil­
+ tasten <hoch> und <runter> nacheinander die
+ einzelnen Kreuzchen im Koordinatensystem nach
+ oben bzw. nach unten verschieben.
+ Haben Sie ein Kreuzchen an die gewünschte
+ Stelle positioniert, so tippen Sie als Kenn­
+ zeichen dafür die <RETURN>-Taste. So gelangen
+ Sie zum nächsten Kreuzchen bzw. nach dem letz­
+ ten Kreuzchen zurück in das Fenster oben
+ rechts. Wenn Sie mit dem eingestellten Wer­
+ tungsschlüssel einverstanden sind, gelangen
+ Sie zurück ins Menu; ansonsten können Sie die
+ vorgenommene Einstellung korrigieren.
+
+#page#
+5.4 Menufunktionen zum Oberbegriff 'Konfigu­
+ ration'
+
+#on("b")#
+BAP: Simulation Parameter Konfiguration Dateien Archiv
+--------------------+---------------------------+-------------------------
+ | u Umfang der Auswertung |
+ | k Kurzauswertung |
+ +---------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+#on("u")##on("b")#u Umfang der Auswertung#off("b")##off("u")#
+ Mit dieser Menufunktion können Sie festle­
+ gen, ob am Ende einer Protokollauswertung die
+ sogenannten 'Anmerkungen', die die Zusammen­
+ hänge im Protokoll erläutern, jeweils mit aus­
+ gegeben werden sollen oder nicht. Die hier
+ getroffene Festlegung gilt sowohl für die Aus­
+ wertung auf dem Bildschirm als auch für den
+ Ausdruck über einen angeschlossenen Drucker.
+ Zum Verständnis der Auswertungen sind die
+ Anmerkungen sehr hilfreich. Hat man aber meh­
+ rere Simulationsläufe absolviert, bei denen
+ der Wertungsschlüssel identisch ist, so wäre
+ es überflüssig, jeweils die Anmerkungen mit
+ ausgeben zu lassen.
+ Die aktuelle Einstellung (mit/ohne Anmer­
+ kungen) wird im Fenster links oben angezeigt.
+ Im Fenster rechts oben wird die Frage ge­
+ stellt, ob Sie eine Veränderung der Einstel­
+ lung wünschen. Nur wenn Sie diese Frage beja­
+ hen, wird die Einstellung verändert; ansonsten
+ gelangen Sie unter Beibehaltung der alten Ein­
+ stellung ins Menu zurück.
+
+#on("u")##on("b")#k Kurzsauswertung#off("b")##off("u")#
+ Standardmäßig wird am Ende eines Simula­
+ tionslaufes eine Kurzauswertung auf dem Bild­
+ schirm ausgegeben. Wenn Sie diese überflüssig
+ finden oder wenn Sie es aus didaktischen Grün­
+ den vorziehen, auf eine solche Kurzauswertung
+ zu verzichten, können Sie diese Kurzauswertung
+ durch diese Menufunktion ab- bzw. wieder ein­
+ schalten.
+ Die hier getroffene Einstellung ist auch
+ gültig für anschließend eingerichtete Sohn­
+ tasks - und zwar sowohl für das Teilprogramm
+ 'Bildschirmarbeitsplatz' als auch für das
+ Teilprogramm 'Materialprüfung'.
+ Die aktuelle Einstellung (mit/ohne Kurzaus­
+ wertung) wird im Fenster links oben angezeigt.
+ Im Fenster rechts oben wird die Frage ge­
+ stellt, ob Sie eine Veränderung der Einstel­
+ lung wünschen. Nur wenn Sie diese Frage beja­
+ hen, wird die Einstellung verändert; ansonsten
+ gelangen Sie unter Beibehaltung der alten Ein­
+ stellung ins Menu zurück
+
+#page#
+5.5 Menufunktionen zum Oberbegriff 'Dateien'
+
+#on("b")#
+BAP: Simulation Parameter Konfiguration Dateien Archiv
+------------------------------------+-------------------+-----------------
+ | v Verzeichnis |
+ | --------------- |
+ | l Löschen |
+ | d Drucken |
+ | --------------- |
+ | k Kopieren |
+ | u Umbenennen |
+ | --------------- |
+ | s Speicherplatz |
+ | a Aufräumen |
+ +-------------------+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+ Die einzelnen Menufunktionen zu diesem Oberbe­
+griff sind detailliert im Handbuch zum Programm
+#on("b")#gs-DIALOG#off("b")# beschrieben und können dort nachgeschla­
+gen werden. An dieser Stelle seien nur einige Be­
+sonderheiten genannt, die hinsichtlich des Pro­
+grammsystems #on("b")#gs-MP BAP#off("b")# zutreffen:
+ Protokolldateien, die während eines Simulations­
+laufs angelegt werden, können Sie am Präfix 'gs-
+Protokoll:' erkennen. Diese Protokolldateien können
+#on("u")#nicht#off("u")# mit der in diesem Pull-Down-Menu angegebenen
+Menufunktion 'd Drucken' über den Drucker ausge­
+druckt werden. Die Simulationsdaten sind in den
+Protokolldateien nämlich in einem gesonderten For­
+mat aufgezeichnet, das vom Drucker nicht ausgewer­
+tet werden kann.
+ Für die Auswertung und den anschließenden Aus­
+druck dieser Protokolldateien ist die Menufunktion
+'d Drucken von Auswertungen' unter dem Oberbegriff
+'Simulation' bereitgestellt!
+ Sie können den Protokolldateien mit der Menu­
+funktion 'u Umbenennen' einen neuen Namen geben.
+Achten Sie aber #on("u")#unbedingt(!)#off("u")# darauf, daß das Präfix
+'gs-Protokoll:' bei der Umbenennung erhalten bleibt
+- sonst wird die Datei nicht mehr als Protokollda­
+tei vom Auswertsystem erkannt!
+ Die eben angesprochenen Protokolldateien können
+auch nicht mit der Menufunktion 'a Aufräumen' bear­
+beitet werden, da hier nur "normale" Textdateien
+akzeptiert werden - im übrigen sind die Protokoll­
+dateien immer optimal organisiert.
+
+#page#
+5.6 Menufunktionen zum Oberbegriff 'Archiv'
+
+#on("b")#
+BAP: Simulation Parameter Konfiguration Dateien Archiv
+------------------------------------------+-------------------------+-----
+ | r Reservieren |
+ | n Neue Diskette |
+ | --------------------- |
+ | s Schreiben |
+ | c Checken |
+ | k Kombination |
+ | h Holen/Lesen |
+ | l Löschen |
+ | --------------------- |
+ | v Verzeichnis |
+ | d Drucken |
+ | --------------------- |
+ | i Initialisieren |
+ | z Zieltask einstellen |
+ +---------------------+ +-------------------------+
+ | Dateiaustausch mit: |
+ | Archiv |
+ | Archivname: |
+ | gs-MP BAP |
+ +---------------------+
+--------------------------------------------------------------------------
+Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>
+#off("b")#
+
+ Die einzelnen Menufunktionen zu diesem Oberbe­
+griff sind detailliert im Handbuch zum Programm
+#on("b")#gs-DIALOG#off("b")# beschrieben und können dort nachgeschla­
+gen werden.
+
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6
new file mode 100644
index 0000000..7d485d7
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6
@@ -0,0 +1,53 @@
+#limit (11.0)##pagelength (16.5)##block##pageblock#
+#start (2.0,0.0)#
+#page (61)#
+#headodd#
+#center#gs-MP BAP#right#%
+
+#end#
+#headeven#
+%#center#gs-MP BAP
+
+#end#
+#center#6
+
+#center#Hinweise
+#center#für den
+#center#Systembetreuer
+
+
+ Für den Ausdruck von Protokollauswertungen ist
+der Standardschrifttyp des Druckers voreingestellt.
+Sie haben aber die Möglichkeit, einen anderen
+Schrifttyp für den Protokollausdruck einzustellen.
+Dafür sind die beiden folgenden Prozeduren vorbe­
+reitet:
+
+PROC druckereinstellung fuer protokolldatei
+ (TEXT CONST schrifttyp, REAL CONST linker
+ rand, oberer rand, schreibfeldbreite,
+ schreibfeldlaenge)
+
+ Geben Sie einen in Ihrer Installation vorhan­
+ denen Schrifttyp an. Beachten Sie bei der
+ Festlegung der anderen Maße (wie gewohnt in
+ cm), daß auf dem Schreibfeld 80 Druckpositio­
+ nen nebeneinander Platz haben müssen!
+
+
+PROC std druckereinstellung fuer protokolldatei
+
+ Sie können mit diesem Befehl wieder die Ein­
+ stellung vornehmen, die sonst standardmäßig
+ von #on("b")#gs-MP BAP#off("b")# vorgegeben wird:
+
+ schrifttyp : "" (Standard-
+ schrifttyp)
+ linker rand : 0.0 (cm)
+ oberer rand : 0.0 (cm)
+ schreibfeldbreite : 21.0 (cm)
+ schreibfeldlaenge : 29.5 (cm)
+
+
+
+
diff --git a/doc/mp-bap/gs-MP BAP handbuch.impressum b/doc/mp-bap/gs-MP BAP handbuch.impressum
new file mode 100644
index 0000000..91c6ce0
--- /dev/null
+++ b/doc/mp-bap/gs-MP BAP handbuch.impressum
@@ -0,0 +1,104 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#gs-MP BAP
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+
+#free (4.0)##on("b")#
+#center#gs-MP BAP
+
+
+#center#Benutzerhandbuch
+
+
+#center#Version 1.0
+
+
+#off("b")##center#copyright
+#center#Eva Latta-Weber
+#center#Software- und Hardware-Systeme, 1988
+#center#ERGOS GmbH, 1990
+#page#
+#block#
+#center#____________________________________________________________________________
+
+
+Copyright:  ERGOS GmbH   März 1990
+
+ Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+ maschinenlesbare Form sowie das Speichern in Informations­
+ systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+ der ERGOS GmbH gestattet.
+
+
+#center#____________________________________________________________________________
+
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender.
+
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden.
+
+Texterstellung :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+ erstellt und aufbereitet und auf einem Kyocera Laser­
+ drucker gedruckt.
+
+
+
+
+#center#___________________________________________________________________________
+
+
+
+Ergonomic Office Software GmbH
+
+Bergstr. 7 Telefon: (02241) 63075
+5200 Siegburg Teletex: 2627-2241413=ERGOS
+ Telefax: (02241) 63078
+
+
+#center#____________________________________________________________________________
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/programming/programmierhandbuch.1 b/doc/programming/programmierhandbuch.1
new file mode 100644
index 0000000..24f2b03
--- /dev/null
+++ b/doc/programming/programmierhandbuch.1
@@ -0,0 +1,650 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 1 : Einleitung","1")#
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 1 : Einleitung
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+1 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #rigth#1 - %
+#end#
+
+TEIL 1 : Einleitung
+
+
+1.1 Allgemeines über EUMEL
+
+Dieses Buch bietet eine Übersicht über die Standardprozeduren des Betriebssystem
+EUMEL. Es bietet damit sowohl Hilfestellung für die Benutzung der standardmäßig
+vorhandenen Kommandos als auch für die Programmierung, also die Erweiterung
+dieses Kommandovorrats. Es ist jedoch kein Lehrbuch der Programmierung!
+
+In den ersten drei Kapiteln dieses Programmierhandbuches werden einige Grund­
+begriffe des Systems, die grundlegende Programmiersprache (ELAN) und der
+EUMEL-Editor erläutert.
+
+Das vierte Kapitel bietet eine Übersicht über diejenigen Prozeduren und Operatoren,
+die eher der 'Job-Control-Language' zugerechnet werden können, also häufig im
+Kommandodialog benutzt werden.
+
+Im fünften Teil sind diejenigen Operationen beschrieben, die meistenteils für die
+Programmierung benutzt werden. (Compiler, Operationen auf den elementaren Daten­
+typen, Dateien, Ein- und Ausgabe usw.).
+
+Diese Trennung ist jedoch recht willkürlich, es ist ja gerade eine der wichtigen Eigen­
+schaften dieses Betriebssystems, daß es keine Trennung zwischen der Kommando­
+sprache des Betriebssystems und Programmmiersprache für das System gibt. Jedes
+Systemkommando ist Aufruf einer ELAN Prozedur, jede neue Prozedur stellt eine
+Erweiterung des Kommandovorrats des Systems dar.
+
+Aus Gründen der Übersichtlichkeit der Zusammenstellung ist dieses Buch nicht frei
+von Vorwärtsverweisen!
+
+#page#
+
+1.2 Struktur des Betriebssystems EUMEL
+
+Grundlegend für das Verständnis des Betriebssystems EUMEL ist der Begriff der
+#on("b")#Task#off("b")#. Eine Task kann als theoretisch unendliche Wiederholung eines Systempro­
+gramms der Form:
+
+ 'nimm Kommando entgegen'
+ 'verarbeite Kommando'
+
+aufgefaßt werden. Einige Tasks existieren bereits als Grundstock des Systems,
+weitere werden von Benutzern des Systems erschaffen und dienen als persönliche
+Arbeitsumgebung für den 'Eigentümer'. Eine Task kann als benutzereigener, unab­
+hängiger Computer im Computer betrachtet werden, denn sie kann Kommandos
+entgegennehmen und ausführen und Daten verwalten und aufbewahren.
+
+Eine Task kann neu erzeugt werden, an einen Bildschirm gekoppelt werden und
+beendet werden.
+
+Das Tasksystem ist in einer baumartigen Struktur angeordnet. Außer der Wurzel 'UR'
+hat jede Task einen Vorgänger ('Vater-Task') und möglicherweise Nachfolger
+('Sohn-Tasks').
+
+#on("u")##ib#Task-Organisation#ie##off("u")#
+
+
+ SUPERVISOR
+ -
+ SYSUR
+ ARCHIVE
+ configurator
+ OPERATOR
+ shutup
+
+ UR
+ PUBLIC
+ Benutzertask1
+ Benutzertask2
+ Benutzertask3
+ .....
+
+
+
+Jeder Benutzer arbeitet innerhalb eines EUMEL-Systems, indem er eine Task an
+sein Terminal koppelt und dort Programme aufruft.
+
+Dateien sind grundsätzlich Eigentum einer Task. Es ist grundlegend für das Verständ­
+nis des Betriebssystems EUMEL, die Beziehung zwischen Tasks und Dateien zu
+erkennen.
+
+Eine Task ist ein Prozeß, der gegebenenfalls Dateien besitzt. Dateien können nur in
+einer Task existieren. Um eine Datei einer anderen Task zur Verfügung zu stellen,
+wird eine Kopie der Datei an die andere Task geschickt, die sendende Task ist da­
+nach Eigentümer des 'Originals', die empfangende Task Eigentümer der 'Kopie'.
+
+Soll eine Hierarchie von Dateien aufgebaut werden, so ist sie über eine Hierarchie
+von Tasks zu realisieren, da in einer Task alle Dateien gleichberechtigt sind.
+
+Bis zu dieser Stelle war stets von Dateien die Rede. Dateien sind jedoch ein Spezial­
+fall der grundlegenderen Struktur des Datenraumes.
+
+Ein #ib#Datenraum#ie# ist ein allgemeiner Datenbehälter. Ein Datenraum kann beliebige
+Daten aufnehmen und erlaubt direkten Zugriff auf diese Daten. Die Struktur der Daten
+im Datenraum unterscheidet sich nicht von der Struktur der Programmdaten. Der
+'innere Datentyp' eines Datenraums wird vom Programmierer festgelegt.
+
+Vorgeprägt vom System gibt es Textdateien, jeder andere Datentyp muß vom Pro­
+grammierer geprägt werden, um so Dateien erzeugen zu können, die Objekte eben
+dieses neuen Typs enthalten.
+#page#
+
+
+1.3 Eigenschaften des Betriebssystems
+
+Der erste Entwurf des Mikroprozessor-Betriebssystems EUMEL (#on("b")#E#off("b")#xtendable multi
+#on("b")#U#off("b")#ser #on("b")#M#off("b")#icroprozessor #on("b")#EL#off("b")#AN system) entstand 1979 mit dem Anspruch, auf Mikrocom­
+putern den Anwendern Hilfsmittel und Unterstützungen zu bieten, wie sie sonst nur
+auf Großrechnern zur Verfügung gestellt werden.
+
+Aspekte, die EUMEL von anderen Betriebssystemen für Mikrocomputer unterscheiden,
+sind:
+
+- Hardwareunabhängigkeit
+- Multitaskingkonzept
+- Multiuserbetrieb
+- Erweiterbarkeit
+- virtuelle Speicherverwaltung
+- Datensicherheit
+
+
+
+#on("u")##on("b")#Das EUMEL-Schichtenmodell#off("b")##off("u")#
+
+Die Hardwareunabhängigkeit des Betriebssystems EUMEL begründet sich in seinem
+Aufbau aus Schichten (sogenannten virtuellen Maschinen), die einen klar definierten
+Leistungsumfang haben.
+
+#center#beliebige Anwendungen
+#center#Textverarbeitung, Datenbanken etc.
+
+#center#Systemdienste: Monitor, Dateiverwaltung, Editor
+#center#Task-System
+#center#Standardpakete (BOOL, INT, REAL, TEXT)
+#center#ELAN-Compiler
+
+#center#EUMEL0
+#center#(virtueller Prozessor mit eigenem Befehlssatz)
+
+#center#SHard (Gerätetreiber)
+
+#center#Hardware
+
+
+Jede Schicht erwartet und erhält von ihren Nachbarn wohldefinierte Eingaben und gibt
+wohldefinierte Ausgaben weiter. Änderungen in einer Schicht müssen also in den
+angrenzenden Schichten beachtet werden, aber nicht in allen Teilen des Systems.
+
+Um EUMEL auf Rechner mit einem neuen Prozessortyp zu portieren, wird zunächst
+eine auf die Eigenheiten des Prozessors abgestimmte EUMEL0-Maschine entworfen
+und eine Hardwareanpassung (#ib#SHard#ie# : Software/Hardware-Interface) für einen
+Rechner mit diesem Prozessor hergestellt. Alle höheren Schichten des Systems
+bleiben unberührt. Weitere mit diesem Prozessortyp ausgestattete Rechner können mit
+EUMEL betrieben werden, indem ein SHard für dieses Rechnermodell geschrieben
+wird.
+
+Aus Benutzersicht ist wichtig, daß dadurch jegliche Software, die auf irgendeinem
+Rechner unter EUMEL verfügbar ist, auf jedem anderen Rechner, für den eine
+EUMEL Portierung existiert, lauffähig ist und gleiches Verhalten zeigt. Eine Vernet­
+zung beliebiger Rechner, auf die EUMEL portiert ist, ist problemlos möglich.
+
+Desweiteren ist für den Benutzer des Systems von Bedeutung, daß er von der hard­
+warenahen Schicht entfernt ist. Weder die Programmiersprache noch irgendwelche
+speziellen Systemfunktionen gewähren direkten Zugriff auf den Speicher oder Regi­
+sterinhalte. Diese Tatsache hat weitreichende Folgen in Hinsicht auf Datenschutz und
+Systemsicherheit.
+
+
+
+
+Multi-Tasking-/Multi-User-Betrieb
+Wie einleitend dargestellt, besteht ein EUMEL-System aus diversen Tasks. Durch
+eine Aufteilung der Prozessorzeit in Zeitscheiben ist eine (quasi) parallele Bedienung
+mehrerer Tasks möglich.
+
+Die multi-user-Fähigkeit des Betriebssystems wird durch den Anschluß mehrerer
+Bildschirmarbeitsplätze (Terminals) an V.24 Schnittstellen des Rechners erreicht.
+Dabei wird jeder Schnittstelle eine sogenannte Kanalnummer zugeordnet. Jeder
+Benutzer kann seine Task dann an einen Kanal (=Terminal) koppeln und an diesem
+Terminal gleichzeitig mit anderen Benutzern arbeiten.
+
+
+
+
+Prozeßkommunikation und Netzwerkfähigkeit
+Grundlage der Kommunikation ist die 'Manager-Eigenschaft' von Tasks. Eine Task
+ist 'Manager', wenn sie Aufträge anderer Tasks annehmen und ausführen kann.
+Insbesondere kann ein Manager veranlaßt werden, eine an ihn geschickte Datei anzu­
+nehmen, bzw. eine ihm gehörende Datei an die fordernde Task zu schicken.
+
+Derartige Kommunikationslinien verlaufen normalerweise in der Baumstruktur des
+Systems: z.B. ist die Task 'PUBLIC' (vergl. Seite 2) grundsätzlich Manager-Task.
+Eine unterhalb von PUBLIC liegende Task kann eine Datei an PUBLIC senden, bzw.
+von PUBLIC holen.
+
+Es ist auch möglich, eine Task für den Zugriff beliebiger anderer Tasks zu öffnen und
+somit beliebige Kommunikationspfade aufzubauen. Prinzipiell ist damit auch schon der
+Aufbau eines Netzwerkes beschrieben, denn sendende und empfangende Tasks
+können sich auf verschiedenen Rechnern befinden.
+
+Durch selbst erstellte Programme kann der Eigentümer einer 'Manager-Task' die
+Reaktion dieser Task auf einen Auftrag von außen bestimmen. Beispielsweise kann
+ein Manager derart programmiert werden, daß er nur Dateien empfängt und ausdruckt,
+aber niemals Dateien verschickt (Spool-Task).
+
+
+
+Erweiterbarkeit
+Die Programmiersprache ELAN ist im EUMEL-System gleichzeitig Programmier-
+und System-Kommandosprache (JCL), denn jedes Kommando ist Aufruf einer
+ELAN-Prozedur und jede vom Benutzer geschriebene ELAN-Prozedur erweitert
+den Kommandovorrat des Systems.
+
+Da alle EUMEL-Werkzeuge (einschließlich Editor) selbst ELAN-Programme sind,
+kann das System vom Benutzer selbst durch Hinzufügen eigener ELAN-Programme
+oder Programmpakete beliebig erweitert werden. Dabei können die bereits implemen­
+tierten Systemteile (z.B. die Fenstertechnik des Editors) genutzt werden.
+
+Ein Benutzer muß, um alle Möglichkeiten vom EUMEL zu nutzen, nur eine Sprache
+lernen und nicht - wie bei anderen Betriebssystemen - zwei unterschiedliche, eine
+Kommando- und eine Programmiersprache.
+
+ELAN selbst ist eine PASCAL-ähnliche Programmiersprache, die mit Hilfe der
+schrittweisen Verfeinerung (Refinement-Konzept) die Top-Down-Programmierung
+unterstützt. Das Paketkonzept, das der Modularisierung dient, und die freie Wahl von
+Bezeichnernamen sind Voraussetzung für übersichtliche und effiziente Programmie­
+rung.
+
+
+
+
+Virtuelle Speicherverwaltung
+Im EUMEL-System wird der Hauptspeicherplatz nach dem #on("b")#Demand-Paging-Prinzip#off("b")#
+verwaltet. Daten und Programme werden dazu in Seiten von 512 Byte aufgeteilt. Nur
+diejenigen Seiten, die wirklich benötigt werden, werden vom Hintergrundspeicher
+(Platte) in den Hauptspeicher geholt. Damit ist für den Benutzer bezüglich seiner
+Programm- bzw. Dateigrößen nicht mehr der Hauptspeicher, sondern die Hinter­
+grundkapazität von Bedeutung. Die Durchsatzgeschwindigkeit (Performance) ist
+abhängig von der Größe des RAM-Speichers und der Zugriffsgeschwindigkeit des
+Hintergrundmediums. Das Demand-Paging-Verfahren ist Grundlage für den
+Multi-User-Betrieb, wobei der Hauptspeicherplatz möglichst effizient zu nutzen und
+kein Benutzer zu benachteiligen ist.
+
+Beim Duplizieren eines Datenraumes wird im EUMEL-System lediglich eine logische,
+keine physische Kopie erzeugt. Zwei Seiten (zweier Datenräume) heißen dann gekop­
+pelt (geshared), wenn beide Seiten physisch demselben Block zugeordnet sind. Erst
+bei einem Schreibzugriff werden die Seiten entkoppelt (entshared) und tatsächlich
+physisch kopiert. Daher der Name "#on("b")#copy-on-write#off("b")#".
+
+Dieses Prinzip wird natürlich auch systemintern angewandt. Beispielsweise erbt eine
+Sohn-Task den Kommandovorrat der Vater-Task, indem der Standard-Datenraum,
+der die vorübersetzten ELAN-Prozeduren enthält, in der beschriebenen Weise kopiert
+wird. Prozeduren, die später hinzugefügt werden, werden natürlich nicht vererbt, da
+die Standard-Datenräume dann entkoppelt werden.
+
+
+
+
+Datensicherheit
+Störungen (inklusive Stromausfall) werden systemseitig durch eine automatische
+#on("b")#Fixpoint-Rerun-Logik#off("b")# aufgefangen, indem zum Zeitpunkt eines Fixpunkts der Inhalt
+des RAM Speichers, der seit dem letzten #ib#Fixpunkt#ie# verändert wurde auf den
+permanenten Speicher (Festplatte) geschrieben wird. Somit kann nach einer Störung
+immer auf den Systemzustand des letzten Fixpunktes aufgesetzt werden und die
+Datenverluste halten sich in erträglichen Grenzen.
+
+Der Zeitraum zwischen zwei Fixpunkten beträgt standardmäßig 15 Minuten, kann aber
+vom Benutzer anders eingestellt werden.
+
+Auch bei dieser Sicherung wird das Copy-on-write-Prinzip angewendet, so daß
+Platz- und Zeitaufwand gering sind und den normalen Ablauf nicht stören.
+
+#page#
+
+1.4 Wichtige Begriffe
+
+- #on("b")##ib#archive#ie##off("b")#. Spezielle Task zur Verwaltung des Diskettenlaufwerks. Da für die
+ längerfristige Datenhaltung und zur zusätzlichen Datensicherung Dateien auf
+ Disketten geschrieben werden, besitzt das EUMEL-System für diese Aufgabe
+ eine besondere Task, die die Bedienung vereinfacht und exklusiven Zugriff auf das
+ Laufwerk garantiert.
+
+- #on("b")##ib#configurator#ie##off("b")#. Besondere Task im Systemzweig des EUMEL-Systems. In
+ dieser Task ist die #ib#Konfiguration#ie# von Kanälen möglich, d.h. Kanal und
+ angeschlossenenes Gerät werden aufeinander abgestimmt.
+
+- #on("b")##ib#editor#ie##off("b")#. Programm zur Dateibearbeitung am Bildschirm. Das Programm wird
+ durch das ( Monitor- ) Kommando 'edit' und die Eingabe des Namens der ge­
+ wünschten Datei als Parameter gestartet.
+
+ Da ein Bildschirm normalerweise auf 80 Zeichen Zeilenbreite und 24 Zeilen be­
+ schränkt ist, kann der Editor als Fenster betrachtet werden, das über die mögli­
+ cherweise weitaus größere Datei bewegt wird und durch das der betrachtete Aus­
+ schnitt der Datei bearbeitet werden kann.
+
+- #on("b")##ib#manager task#ie##off("b")#. Task, die Aufträge von anderen Tasks entgegennehmen und
+ ausführen #on("u")#kann#off("u")#. Beispielsweise ist die Verwaltung von Dateien, die mehreren
+ Benutzern (= anderen Tasks) zugänglich sein sollen, eine typische Aufgabe für
+ einen Manager.
+
+- #on("b")##ib#Monitor#ie##off("b")#. Der Empfänger von Kommandos innerhalb einer Task ist der Monitor. Der
+ Monitor ist sichtbar durch eine Zeile, in der 'gib kommando' steht. In diese Zeile
+ werden #ib#Kommando#ie#s und erforderliche Parameter eingegeben.
+
+- #on("b")##ib#Supervisor#ie##off("b")#. Spezielle Task zur Überwachung eines EUMEL-Systems. Ein
+ Benutzer kann durch die Supervisor-Kommandos Leistungen von dieser Task
+ fordern: neue Task einrichten, Task wiederaufnehmen und diverse Informationen.
+
+- #on("b")##ib#Task#ie##off("b")#. Beliebig langlebiger Prozeß im EUMEL-System, der die Arbeits­
+ umgebung für Benutzer bildet. Jede Task besitzt einen #ib#Standard-Datenraum#ie#, der
+ Code und Compilertabellen der Task enthält und kann weitere Datenräume
+ (Dateien) besitzen.
+
+#page#
+
+1.5 Die Notation in diesem Buch
+
+Beachten Sie bitte folgende Regeln der Aufschreibung:
+
+- Funktionstasten werden ebenso wie besondere Tastenkombinationen explizit als
+ Tasten dargestellt:
+
+ <SV> <ESC> <e>
+
+
+- Alles, was Sie am Bildschirm Ihres Rechners schreiben oder lesen sollen, ist in
+ Textbereiche, die einen Bildschirm darstellen, eingefaßt.
+
+ Beispiel:
+
+____________________________________________________________________________
+ gib kommando:
+ edit ("mein programm")
+
+____________________________________________________________________________
+
+
+- Innerhalb des Handbuchs sind in der Aufschreibung die Konventionen der Pro­
+ grammiersprache ELAN berücksichtigt. Dabei sind folgende Besonderheiten zu
+ beachten:
+
+ 1) Kommandos werden grundsätzlich klein geschrieben.
+
+ 2) Dateinamen u.ä. sind Textdenoter und werden somit in Klammern und Anfüh­
+ rungsstriche gesetzt. In diesem Buch steht an den Stellen, wo ein Dateiname
+ auftaucht #on("i")# 'dateiname' #off("i")#; den Namen, den Sie tatsächlich verwenden, können
+ Sie frei wählen.
+
+ 3) Falls besondere Begriffe oder Beispiele innerhalb eines normalen Textes
+ auftreten, werden sie in einfache Anführungsstriche gesetzt.
+
+
+#page#
+
+1.6 Die Funktionstasten des EUMEL-Systems
+
+Die Lage der EUMEL-Funktionstasten entnehmen Sie bitte der speziellen Installa­
+tionsanleitung zu dem von Ihnen benutzten Gerät. #l pos (0.0)##l pos(4.0)#
+
+
+<v> <^> <>> <<> Positionierungstasten
+#table#
+
+<SHIFT> Umschalttaste
+
+<CR> Eingabe-/ Absatztaste
+
+<ESC> Kommandotaste
+
+<SV> Supervisortaste
+
+<HOP> Verstärkertaste
+
+<RUBOUT> Löschtaste
+
+<RUBIN> Einfügetaste
+
+<TAB> Tabulatortaste
+
+<MARK> Markiertaste
+
+<STOP> Stoptaste
+
+<WEITER> Weitertaste
+#tableend##clear pos#
+
+Weitere Informationen hierzu finden Sie in der Installationsanleitung zu dem von Ihnen
+benutzten Rechner oder Terminal.
+#page#
+
+1.7 Eine Beispielsitzung
+
+Im Folgenden wird eine Beispielsitzung skizziert, in der ein ELAN-Programm erstellt
+und getestet wird.
+
+ <SV> SUPERVISOR aufrufen
+
+
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8/M
+
+
+ gib supervisor kommando:
+ begin("meine erste Task")
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+____________________________________________________________________________
+
+
+
+
+Durch das Kommando 'begin ("meine erste Task")', welches durch <CR> abgeschlos­
+sen werden muß, wird eine Task mit dem Namen 'meine erste Task' im Benutzer­
+zweig, also unterhalb von 'PUBLIC' angelegt. Würde diese Task bereits existieren, so
+könnten Sie sie mit 'continue ("meine erste Task")' an das Terminal holen.
+
+____________________________________________________________________________
+
+ gib kommando :
+ edit ("mein erstes Programm")
+
+____________________________________________________________________________
+
+
+In der Task eröffnen Sie eine Datei mit dem Kommando 'edit ("dateiname")'.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ edit ("mein erstes Programm")
+ "mein erstes Programm" neu einrichten (j/n) ? j
+
+____________________________________________________________________________
+
+
+Falls diese Datei neu ist, erfolgt eine Kontrollfrage (zur Kontrolle der gewünschten
+Schreibweise des Dateinamens), die Sie durch <j> bejahen.
+
+
+____________________________________________________________________________
+ ............ mein erstes Programm ............... Zeile 1 #markon#
+_
+____________________________________________________________________________
+
+
+
+
+
+
+In die noch leere Datei tippen Sie nun den Programmtext ein.
+
+
+____________________________________________________________________________
+ ............ mein erstes Programm ............... Zeile 1
+ _INT PROC ggt (INT CONST a, b):
+ INT VAR b kopie :: abs (b), a kopie :: abs (a);
+ WHILE b kopie <> 0 REPEAT
+ INT VAR rest := a kopie MOD b kopie;
+ a kopie := b kopie;
+ b kopie := rest
+ END REPEAT;
+ a kopie
+ END PROC gt;
+
+ REP
+ lies 2 zahlen ein;
+ gib groessten gemeinsamen teiler aus
+ UNTIL no ("weitertesten") PER.
+
+ lies 2 zahlen ein:
+ line; put ("2 Zahlen eingeben:");
+ INT VAR a, b;
+ get (a); get (b).
+
+ gib groessten gemeinsamen teiler aus:
+ put ("der größte gemeinsame Teiler von");
+ put (a); put ("und"); put (b); put ("ist"); put (ggt (a,b));
+ line.
+
+____________________________________________________________________________
+
+
+In dem Programmbeispiel wird ein Prozedur 'ggt' definiert, die den größten gemein­
+samen Teiler zweier Zahlen bestimmt. Die Prozedur soll für verschiedene Beispiele
+getestet werden; dies geschieht in dem Hauptprogramm, das solange Zahlen einliest
+und den größten gemeinsamen Teiler ausgibt, bis der Benutzer auf die Frage 'weiter­
+testen (j/n) ?' mit <n> antwortet.
+
+Haben Sie das Programm eingegeben, so können Sie die Bearbeitung dieser Pro­
+grammdatei durch Drücken der Tasten <ESC> <q> (nacheinander!) beenden.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ run ("mein erstes Programm")
+
+____________________________________________________________________________
+
+
+Um Ihr Programm zu übersetzen und auszuführen, geben Sie das Kommando
+'run ("dateiname")'.
+
+Der Verlauf der Übersetzung, die zwei Läufe über das Programm erfordert, ist am
+Zähler, der an der linken Seite des Bildschirms ausgegeben wird, zu erkennen.
+
+Werden beim Übersetzen des Programms Fehler entdeckt, so werden diese im 'note­
+book' parallel zur Programmdatei gezeigt. In dem Beispielprogramm wurde ein
+Schreibfehler in Zeile 9 gemacht.
+
+
+____________________________________________________________________________
+ ............ mein erstes Programm ............... Zeile 1
+ _INT PROC ggt (INT CONST a, b):
+ INT VAR b kopie :: abs (b), a kopie :: abs (a);
+ WHILE b kopie <> 0 REPEAT
+ INT VAR rest := a kopie MOD b kopie;
+ a kopie := b kopie;
+ b kopie := rest
+ END REPEAT;
+ a kopie
+ END PROC gt;
+
+ REP
+ .................. notebook ..................... Zeile 1 #markon#
+ Zeile 9 FEHLER bei >> gt <<
+ ist nicht der PROC Name
+
+
+____________________________________________________________________________
+
+
+
+Diesen Fehler müssen Sie nun verbessern.
+
+____________________________________________________________________________
+ ............ mein erstes Programm ............... Zeile 9
+ INT PROC ggt (INT CONST a, b):
+ INT VAR b kopie :: abs (b), a kopie :: abs (a);
+ WHILE b kopie <> 0 REPEAT
+ INT VAR rest := a kopie MOD b kopie;
+ a kopie := b kopie;
+ b kopie := rest
+ END REPEAT;
+ a kopie
+ END PROC ggt;_
+
+ REP
+ .................. notebook ..................... Zeile 1
+ Zeile 9 FEHLER bei >> gt <<
+ ist nicht der PROC Name
+
+____________________________________________________________________________
+
+
+
+
+Haben Sie das Programm korrigiert, so können Sie die Datei durch Drücken der
+Tasten <ESC> <q> (nacheinander!) wieder verlassen.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ run ("mein erstes Programm")
+
+____________________________________________________________________________
+
+
+Nach Eingabe von <R> wird das Programm erneut übersetzt.
+
+
+____________________________________________________________________________
+
+ Keine Fehler gefunden, 136 B Code, 82 B Paketdaten generiert
+
+
+ ******* ENDE DER UEBERSETZUNG *******
+
+
+ 2 Zahlen eingeben: _
+
+____________________________________________________________________________
+
+
+Das Programm war jetzt fehlerfrei. Nach der Übersetzung wurde die Ausführung
+gestartet. Nun können Beispiele getestet werden.
+
+____________________________________________________________________________
+
+ 2 Zahlen eingeben: 125 250
+ der größte gemeinsame Teiler von 125 und 225 ist 25
+ weitertesten (j/n) ?
+
+____________________________________________________________________________
+
+
+Beantwortet man die Frage mit <n>, so wird die Ausführung des Programms beendet.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+
+____________________________________________________________________________
+
+
+Um die Arbeit in der Task zu beenden, geben Sie auch an dieser Stelle <ESC> <q>
+(nacheinander!) ein.
+
+Nach Verlassen der Task ist wiederum die EUMEL-Tapete auf dem Bildschirm. Jede
+weitere Aktion wird wiederum von hier aus durch <SV> begonnen. Insbesondere vor
+dem #ib#Ausschalten des Geräts#ie# muß nach <SV> eine Task des priviliegierten System­
+zweigs (oft: '#ib#shutup#ie#') mit <ESC> <c> an das Terminal gekoppelt werden, in der das
+Kommando 'shutup' gegeben wird.
+
diff --git a/doc/programming/programmierhandbuch.2a b/doc/programming/programmierhandbuch.2a
new file mode 100644
index 0000000..a204091
--- /dev/null
+++ b/doc/programming/programmierhandbuch.2a
@@ -0,0 +1,1845 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 2 : ELAN","2")#
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 2 : ELAN
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+2 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right# 2 - %
+#end#
+
+TEIL 2: ELAN
+
+2.1 Besondere Eigenschaften von ELAN
+
+Kerneigenschaften von ELAN sind das #ib#Paketkonzept#ie# und die Methode des
+#ib#Refinements#ie#.
+
+#on("b")#Paketkonzept:#off("b")#
+ELAN bietet die Möglichkeit, neue Datentypen sowie Prozeduren und Operatoren auf
+diesen Datentypen zu definieren. Eine solche Definition von Algorithmen und Daten­
+typen kann zu einer logischen Einheit, einem Paket, zusammengefaßt werden. Pakete
+können in einer Task vorübersetzt werden und erweitern damit automatisch den
+Sprachumfang.
+
+#on("b")#Methode des Refinements:#off("b")#
+Die Methode des Refinements erlaubt das schrittweise Herleiten von Problemlösungen
+von der jeweils geeigneten Terminologie herunter zu den von ELAN standardmäßig
+angebotenen Sprachelementen. Durch diese Vorgehensweise wird in äußerst starkem
+Maße ein strukturierter Programmentwurf gemäß dem Top-Down-Prinzip gefördert.
+
+Die Programmiersprache ELAN wird im EUMEL-System zu folgenden Zwecken
+eingesetzt:
+
+- Systemimplementationssprache
+- Kommandosprache
+- Anwenderprogrammiersprache
+#page#
+
+2.2 Lexikalische Elemente
+
+Unter lexikalischen Elementen einer Programmiersprache versteht man die Elemente,
+in denen ein Programm notiert wird.
+
+In ELAN sind dies:
+
+- Schlüsselwörter
+- Bezeichner
+- Sonderzeichen
+- Kommentare
+
+
+
+
+2.2.1 Schlüsselwörter
+
+Einige Wörter haben in ELAN eine feste Bedeutung und können somit nicht frei
+gewählt werden. Solche Wörter werden im EUMEL-System in Großbuchstaben
+geschrieben, Leerzeichen dürfen nicht enthalten sein.
+
+Beispiele:
+
+
+VAR
+INT
+WHILE
+
+
+Wie später beschrieben wird, gibt es in ELAN auch die Möglichkeit, neue Schlüssel­
+wörter einzuführen.
+
+
+#page#
+
+2.2.2 Bezeichner
+
+Bezeichner oder Namen werden benutzt, um Objekte in einem Programmtext zu
+benennen und zu identifizieren (z.B: Variablennamen, Prozedurnamen).
+
+Namen werden in ELAN folgendermaßen formuliert:
+
+Das erste Zeichen eines Namens muß immer ein Kleinbuchstabe sein. Danach dürfen
+bis zu 254 Kleinbuchstaben, aber auch Ziffern folgen. Zur besseren Lesbarkeit können
+Leerzeichen in einem Namen erscheinen, die aber nicht zum Namen zählen. Sonder­
+zeichen sind in Namen nicht erlaubt.
+
+Beispiele für #on("b")#korrekte#off("b")# Bezeichner:
+
+
+das ist ein langer name
+x koordinate
+nr 1
+
+
+
+Beispiele für #on("b")#falsche#off("b")# Bezeichner:
+
+
+x*1
+1 exemplar
+Nr 1
+#page#
+
+2.2.3 Sonderzeichen
+
+Sonderzeichen sind Zeichen, die weder Klein- oder Großbuchstaben, noch Ziffern
+sind. Sie werden in ELAN als Trennzeichen oder als Operatoren benutzt.
+
+In ELAN gibt es folgende Trennungszeichen:
+
+- das Semikolon (';') trennt Anweisungen
+- der Doppelpunkt (':') trennt Definiertes und Definition
+- der Punkt ('.') wird als Endezeichen für bestimmte Programmabschnitte, als Dezi­
+ malpunkt und als Selektor-Zeichen für Datenstrukturen benutzt
+- das Komma (',') trennt Parameter
+- Klammernpaare ('(', ')') werden zum Einklammern von Parameterlisten oder Teil­
+ ausdrücken benutzt
+- mit Anführungszeichen ('"') werden Text-Denoter umrahmt
+- eckige Klammernpaare ('[', ']') werden zur Subskription benutzt.
+
+
+Als Operatornamen sind folgende Sonderzeichen erlaubt:
+
+- ein Sonderzeichen, sofern es nicht als Trennzeichen benutzt wird:
+ ! $ % & ' * + - / < = > ? § ^ ' ~
+- eine Kombination von zwei Sonderzeichen. Diese Kombination muß jedoch bereits
+ in ELAN existieren:
+ := <= >= <> **
+
+#page#
+
+2.2.4 Kommentare
+
+Kommentare dienen ausschließlich der Dokumentation eines Programms. Sie werden
+vom Compiler überlesen und haben somit keinen Einfluß auf die Ausführung eines
+Programms. Sie dürfen an beliebigen Stellen eines Programmtextes geschrieben
+werden, jedoch nicht innerhalb von Schlüsselwörtern und Namen. Ein Kommentar darf
+über mehrere Zeilen gehen. In ELAN sind Kommentare nur in wenigen Fällen notwen­
+dig, da Programme durch andere Mittel gut lesbar geschrieben werden können.
+
+Ein Kommentar in ELAN wird durch Kommentarklammern eingeschlossen. Es gibt
+folgende Formen von Kommentarklammern:
+
+(* Kommentar *)
+{ Kommentar }
+\#( Kommentar )#
+
+Die letzte Version '\#( Kommentar )\#' wird im EUMEL-System nicht
+unterstützt; statt dessen gibt es noch folgende Möglichkeit:
+
+\# Kommentar \#
+
+Da bei der Kommentarkennzeichnung mit \# für Kommentaranfang und -ende das
+gleiche Zeichen benutzt wird, ist eine Schachtelung hier nicht möglich.
+#page#
+
+2.3 Datenobjekte
+
+Eine Klasse von Objekten mit gleichen Eigenschaften wird in Programmiersprachen
+Datentyp genannt. Dabei hat ein Datentyp immer einen Namen, der die Klasse von
+Objekten sinnvoll kennzeichnet. Als ein Datenobjekt wird ein Exemplar eines Daten­
+typs (also ein spezielles Objekt einer Klasse) bezeichnet.
+
+Datentypen sind in ELAN ein zentrales Konzept. Jedes der in einem ELAN-
+Programm verwandten Datenobjekte hat einen Datentyp; somit kann man Datentypen
+auch als Eigenschaften von Datenobjekten ansehen. Für jeden Datentyp sind nur
+spezielle Operationen sinnvoll. Man kann nun Compilern die Aufgabe überlassen zu
+überprüfen, ob stets die richtige Operation auf einen Datentyp angewandt wird.
+
+
+
+2.3.1 Elementare Datentypen
+
+Einige Datentypen spielen bei der Programmierung eine besondere Rolle, weil sie
+häufig benötigt werden.
+
+In ELAN sind das die Datentypen für
+
+- ganze Zahlen (INT)
+- reelle Zahlen (REAL)
+- Zeichen und Zeichenfolgen (TEXT)
+- Wahrheitswerte (BOOL).
+
+Diese Datentypen sind von der Sprache ELAN vorgegeben und werden elementare
+Datentypen genannt. Für effiziente Rechnungen mit elementaren Datentypen gibt es
+in den meisten Rechnern spezielle Schaltungen, so daß die Hervorhebung und be­
+sondere Rolle, die sie in Programmiersprachen spielen, gerechtfertigt ist. Zudem hat
+man Werte-Darstellungen (Denoter) innerhalb von Programmen für die elementaren
+Datentypen vorgesehen.
+
+
+
+2.3.1.1 Denoter für elementare Datentypen
+
+Die Darstellung eines Werts in einem Rechner zur Laufzeit eines Programms wird
+Repräsentation genannt. Wenn es eindeutig ist, daß es sich nur um die Repräsenta­
+tion im Rechner handelt, spricht man kurz von Werten. Um mit Objekten elementarer
+Datentypen arbeiten zu können, muß es in einem Programm die Möglichkeit geben,
+Werte eines Datentyps zu bezeichnen (denotieren). Die Werte-Darstellungen, die in
+ELAN Denoter genannt werden, sind für jeden Datentyp unterschiedlich. Wie bereits
+erwähnt, haben alle Datenobjekte in ELAN (also auch Denoter) nur einen - vom
+Compiler feststellbaren - Datentyp. Aus der Form eines Denoters ist also der Daten­
+typ erkennbar:
+
+
+
+INT-Denoter:
+Sie bestehen aus einer Aneinanderreihung von Ziffern.
+
+Beispiele:
+
+
+17
+007
+32767
+0
+
+
+Führende Nullen spielen bei der Bildung des Wertes keine Rolle (sie werden vom
+ELAN-Compiler überlesen). Negative INT-Denoter gibt es nicht. Negative Werte
+werden durch eine Aufeinanderfolge des monadischen Operators '-' (siehe 2.4.1.1)
+und eines INT- Denoters realisiert.
+
+
+REAL-Denoter:
+Hier gibt es zwei Formen:
+Die erste besteht aus zwei INT-Denotern, die durch einen Dezimalpunkt getrennt
+werden.
+
+Beispiele:
+
+
+0.314159
+17.28
+
+
+Der Dezimalpunkt wird wie ein Komma in der deutschen Schreibweise benutzt. Nega­
+tive REAL-Denoter gibt es wiederum nicht.
+
+Die zweite Form wird als "wissenschaftliche Notation" bezeichnet. Sie findet dann
+Verwendung, wenn sehr große Zahlen oder Zahlen, die nahe bei Null liegen, darge­
+stellt werden müssen.
+
+Beispiele:
+
+
+3.0 e5
+3.0e-5
+
+
+Der INT-Denoter hinter dem Buchstaben #on("b")#e#off("b")# gibt an, wie viele Stellen der Dezimal­
+punkt nach rechts (positive Werte) bzw. nach links (negative Werte) zu verschieben
+ist. Dieser Wert wird Exponent und der Teil vor dem Buchstaben #on("b")#e#off("b")# Mantisse genannt.
+
+
+TEXT-Denoter:
+Sie werden in Anführungszeichen eingeschlossen.
+
+Beispiele:
+
+
+"Das ist ein TEXT-Denoter"
+"Jetzt ein TEXT-Denoter ohne ein Zeichen: ein leerer Text"
+""
+
+
+Zu beachten ist, daß das Leerzeichen ebenfalls ein Zeichen ist. Soll ein Anführungs­
+zeichen in einem TEXT erscheinen (also gerade das Zeichen, welches einen Denoter
+beendet), so muß es doppelt geschrieben werden.
+
+Beispiele:
+
+
+"Ein TEXT mit dem ""-Zeichen"
+"Ein TEXT-Denoter nur mit dem ""-Zeichen:"
+""""
+
+
+Manchmal sollen Zeichen in einem TEXT-Denoter enthalten sein, die auf dem
+Eingabegerät nicht zur Verfügung stehen. In diesem Fall kann der Code-Wert des
+Zeichens angegeben werden.
+
+Beispiel:
+
+
+"da"251""
+
+
+ist gleichbedeutend mit "daß". Der Code-Wert eines Zeichens ergibt sich aus der
+EUMEL-Code-Tabelle (siehe 5.2.4.1), in der jedem Zeichen eine ganze Zahl zuge­
+ordnet ist.
+
+
+BOOL-Denoter:
+Es gibt nur zwei BOOL-Denoter:
+TRUE für "wahr" und FALSE für "falsch".
+
+
+
+2.3.1.2 LET-Konstrukt für Denoter
+
+Neben der Funktion der Abkürzung von Datentypen (siehe 2.6.3) kann das LET-
+Konstrukt auch für die Namensgebung für Denoter verwandt werden.
+
+Die LET-Vereinbarung sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#LET#off("i")##off("b")# Name #on("i")##on("b")#=#off("i")##off("b")# Denoter
+
+
+Mehrere Namensgebungen können durch Komma getrennt werden.
+
+
+____________________________________________________________________________
+ .......................... Beispiele: .........................
+ LET anzahl = 27;
+ LET pi = 3.14159,
+ blank = " ";
+____________________________________________________________________________
+
+
+Der Einsatz von LET-Namen für Denoter hat zwei Vorteile:
+
+- feste Werte im Programm sind leicht zu ändern, da nur an einer Stelle des Pro­
+ gramms der Denoter geändert werden muß
+ (z.B.: In Vereinbarungen von Reihungen (siehe 2.6.1) können LET-Denoter, im
+ Gegensatz zu Konstanten, als Obergrenze angegeben werden. Dieser
+ Wert kann dann auch an anderen Stellen des Programms, z.B. in Schlei­
+ fen (siehe 2.4.2.5), benutzt werden. Bei Änderung der Reihungsgröße
+ braucht dann nur an einer Stelle des Programms der Wert geändert zu
+ werden.)
+- der Name gibt zusätzliche Information über die Bedeutung des Denoters.
+
+
+
+2.3.2 Zugriffsrecht
+
+Von manchen Datenobjekten weiß man, daß sie nur einmal einen Wert erhalten
+sollen. Sie sollen also nicht verändert werden. Oder man weiß, daß in einem Pro­
+grammbereich ein Datenobjekt nicht verändert werden soll. Um ein unbeabsichtigtes
+Verändern zu verhindern, wird in ELAN dem Datenobjekt ein zusätzlicher Schutz
+mitgegeben: das Zugriffsrecht oder Accessrecht.
+
+In der Deklaration eines Datenobjekts können folgende Accessattribute angegeben
+werden:
+
+- #on("i")##on("b")#VAR #off("i")##off("b")# für lesenden und schreibenden (verändernden) Zugriff
+
+- #on("i")##on("b")#CONST#off("i")##off("b")# für nur lesenden Zugriff.
+
+
+
+2.3.3 Deklaration
+
+Damit man Datenobjekte in einem Programm ansprechen kann, gibt man einem
+Datenobjekt einen Namen (wie z.B. einen Personennamen, unter der sich eine wirk­
+liche Person "verbirgt"). Will man ein Datenobjekt in einem Programm verwenden, so
+muß man dem Compiler mitteilen, welchen Datentyp und welches Accessrecht das
+Objekt haben soll. Das dient u.a. dazu, nicht vereinbarte Namen (z.B. verschriebene)
+vom Compiler entdecken zu lassen. Weiterhin ist aus dem bei der Deklaration ange­
+gebenen Datentyp zu entnehmen, wieviel Speicherplatz für das Objekt zur Laufzeit zu
+reservieren ist.
+
+Eine Deklaration oder Vereinbarung besteht aus der Angabe von
+
+- Datentyp
+- Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")#)
+- Name des Datenobjekts.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR mein datenobjekt;
+
+____________________________________________________________________________
+
+
+Verschiedene Datenobjekte mit gleichem Datentyp und Accessrecht dürfen in einer
+Deklaration angegeben werden; sie werden durch Kommata getrennt. Mehrere Dekla­
+rationen werden - genauso wie Anweisungen - durch das Trennzeichen Semikolon
+voneinander getrennt.
+
+____________________________________________________________________________
+ .......................... Beispiele: .........................
+ INT VAR mein wert, dein wert, unser wert;
+ BOOL VAR listen ende;
+ TEXT VAR zeile, wort;
+
+____________________________________________________________________________
+
+
+2.3.4 Initialisierung
+
+Um mit den vereinbarten Datenobjekten arbeiten zu können, muß man ihnen einen
+Wert geben. Hat ein Datenobjekt noch keinen Wert erhalten, so sagt man, sein Wert
+sei undefiniert. Das versehentliche Arbeiten mit undefinierten Werten ist eine beliebte
+Fehlerquelle. Deshalb wird von Programmierern streng darauf geachtet, diese Fehler­
+kuelle zu vermeiden. Eine Wertgebung an ein Datenobjekt kann (muß aber nicht)
+bereits bei der Deklaration erfolgen. In ELAN wird dies Initialisierung genannt. Für mit
+CONST vereinbarte Datenobjekte ist die Initialisierung die einzige Möglichkeit, ihnen
+einen Wert zu geben. Die Initialisierung von Konstanten ist zwingend vorgeschrieben
+und wird vom Compiler überprüft.
+
+Die Initialisierung besteht aus der Angabe von
+
+- Datentyp
+- Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")#)
+- Name des Datenobjekts
+- Operator #on("i")##on("b")#::#off("i")##off("b")# oder #on("i")##on("b")#:=#off("i")##off("b")#
+- Wert, den das Datenobjekt erhalten soll (Denoter, Ausdruck).
+
+____________________________________________________________________________
+ .......................... Beispiele: .........................
+ INT CONST gewuenschtes gehalt :: 12 000;
+ TEXT VAR zeile :: "";
+ REAL CONST pi :: 3.14159, zwei pi := 2.0 * pi;
+ BOOL VAR bereits sortiert :: TRUE;
+____________________________________________________________________________
+#page#
+
+2.4 Programmeinheiten
+
+Neben Deklarationen (Vereinbarungen) sind Programmeinheiten die Grundbestandteile
+von ELAN.
+
+
+Programmeinheiten können sein:
+
+#on("b")#- elementare Programmeinheiten #off("b")#
+ - Ausdruck
+ - Zuweisung
+ - Refinementanwendung
+ - Prozeduraufruf
+
+#on("b")#- zusammengesetzte Programmeinheiten #off("b")#
+ - Folge
+ - Abfrage
+ - Auswahl
+ - Wiederholung
+
+#on("b")#- abstrahierende Programmeinheiten #off("b")#
+ - Refinementbvereinbarung
+ - Prozedurvereinbarung
+ - Operatorvereinbarung
+ - Paketvereinbarung.
+#page#
+
+2.4.1 Elementare Programmeinheiten
+
+
+2.4.1.1 Ausdruck
+
+Ausdrücke sind eine Zusammenstellung von Datenobjekten (Denoter, VAR- oder
+CONST-Objekte) und Operatoren. Jeder korrekte Ausdruck liefert einen Wert. Der
+Typ des Ausdrucks wird bestimmt durch den Typ des Wertes, den der Ausdruck
+liefert.
+
+
+Operatoren
+
+Operatoren werden in ELAN durch ein oder zwei Sonderzeichen oder durch Groß­
+buchstaben als Schlüsselwort dargestellt (siehe 2.4.3.3).
+
+Als Operanden (also die Datenobjekte, auf die ein Operator "wirken" soll) dürfen
+VAR- und CONST-Datenobjekte, Denoter oder Ausdrücke verwendet werden. Typ
+der Operanden und des Resultats eines Operators werden in der Operatorvereinba­
+rung festgelegt (siehe 2.4.3.3).
+
+Man unterscheidet zwei Arten von Operatoren:
+
+#on("b")#- monadische Operatoren #off("b")#
+ Monadischen Operatoren haben nur einen Operanden, der rechts vom Operator­
+ zeichen geschrieben werden muß.
+
+ Beispiel:
+
+
+ - a
+ NOT x
+
+
+ Der '-' - Operator liefert den Wert von a mit umgekehrten Vorzeichen. a muß
+ dabei vom Datentyp INT oder REAL sein.
+ Der Operator 'NOT' realisiert die logische Negation. y muß vom Datentyp BOOL
+ sein.
+
+
+#on("b")#- dyadische Operatoren #off("b")#
+ Dyadische Operatoren haben zwei Operanden. Das Operatorzeichen steht zwi­
+ schen den beiden Operanden.
+
+ Beispiele:
+
+
+ a + b
+ a - b
+ a * b
+ a DIV b
+ a ** b
+ x < y
+ x <> y
+ x AND y
+ x OR y
+
+
+ In den ersten fünf Beispielen werden jeweils die Werte von zwei INT-Objekten a
+ und b addiert (Operatorzeichen: '+'), subtrahiert ('-'), multipliziert ('*'), dividiert
+ (ganzzahlige Division ohne Rest: 'DIV') und potenziert ('**').
+ Im sechsten und siebten Beispiel werden zwei BOOL-Werte x und y verglichen
+ und im achten und neunten Beispiel die logische Operation 'und' (Operator 'AND')
+ bzw. 'oder' (Operator 'OR') durchgeführt.
+
+
+Priorität von Operatoren
+
+Es ist erlaubt, einen Ausdruck wiederum als Operanden zu verwenden. Praktisch
+bedeutet dies, daß mehrere Operatoren und Datenobjekte zusammen in einem Aus­
+druck geschrieben werden dürfen.
+
+Beispiele:
+
+
+a + 3 - b * c
+- a * b
+
+
+Die Reihenfolge der Auswertung kann man durch Angabe von Klammern steuern.
+
+Beispiel:
+
+
+(a + b) * (a + b)
+
+
+Es wird jeweils erst 'a + b' ausgewertet und dann erst die Multiplikation durchge­
+führt. In ELAN ist es erlaubt, beliebig viel Klammernpaare zu verwenden (Regel: die
+innerste Klammer wird zuerst ausgeführt). Es ist sogar zulässig, Klammern zu ver­
+wenden, wo keine notwendig sind, denn überflüssige Klammernpaare werden überle­
+sen. Man muß jedoch beachten, daß Ausdrücke, und damit auch z.B. #on("b")#(a)#off("b")#, immer
+Accessrecht CONST haben.
+
+Beispiel:
+
+
+((a - b)) * 3 * ((c + d) * (c - d))
+
+
+Somit können beliebig komplizierte Ausdrücke formuliert werden.
+
+Um solche Ausdrücke einfacher zu behandeln und sie so ähnlich schreiben zu kön­
+nen, wie man es in der Mathematik gewohnt ist, wird in Programmiersprachen die
+Reihenfolge der Auswertung von Operatoren festgelegt. In ELAN wurden neun Ebe­
+nen, Prioritäten genannt, festgelegt:
+
+
+#on("bold")#Priorität Operatoren
+#off("bold")#
+
+ 9 alle monadischen Operatoren
+ 8 **
+ 7 *, /, DIV, MOD
+ 6 +, -
+ 5 =, <>, <, <=, >, >=
+ 4 AND
+ 3 OR
+ 2 alle übrigen, nicht in dieser Tabelle aufgeführten
+ dyadischen Operatoren
+ 1 :=
+
+(Die erwähnten Operatoren in der Tabelle werden in der Beschreibung der Standard­
+prozeduren und -Operatoren besprochen).
+
+Operatoren mit der höchsten Priorität werden zuerst ausgeführt, dann die mit der
+nächst niedrigeren Priorität usw.. Operatoren mit gleicher Priorität werden von links
+nach rechts ausgeführt. Dadurch ergibt sich die gewohnte Abarbeitungsfolge wie beim
+Rechnen.
+
+Beispiel:
+
+
+-2 + 3 * 2 ** 3
+
+a) -2
+b) 2 ** 3
+c) 3 * (2 ** 3)
+d) ((-2)) + (3 * (2 ** 3))
+
+
+Wie bereits erwähnt, ist es immer erlaubt, Klammern zu setzen. Ist man sich also
+über die genaue Abarbeitungsfolge nicht im Klaren, so kann man Klammern verwen­
+den.
+
+
+
+2.4.1.2 Zuweisung
+
+Ein spezieller Operator ist die Zuweisung.
+
+Form:
+
+
+Variable #on("i")##on("b")#:=#off("i")##off("b")# Wert
+
+
+Dieser Operator hat immer die geringste Priorität, wird also immer als letzter einer
+Anweisung ausgeführt. Die Zuweisung wird verwendet, um einer Variablen einen
+neuen Wert zu geben. Der Operator ':=' liefert kein Resultat (man sagt auch, er
+liefert keinen Wert) und verlangt als linken Operanden ein VAR-Datenobjekt, an den
+der Wert des rechten Operanden zugewiesen werden soll). Der Wert des linken Oper­
+anden wird also verändert. Der rechte Operand wird nur gelesen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ a := b;
+
+____________________________________________________________________________
+
+
+Hier wird der Wert von 'b' der Variablen 'a' zugewiesen. Der vorher vorhandene Wert
+von 'a' geht dabei verloren. Man sagt auch, der Wert wird überschrieben.
+
+Als rechter Operand des ':='-Operators darf auch ein Ausdruck stehen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ a := b + c;
+
+____________________________________________________________________________
+
+
+Hier wird das Resultat von 'b + c' an die Variable 'a' zugewiesen. Man beachte
+dabei die Prioritäten der Operatoren '+' (Priorität 6) und ':=' (Priorität 1): die Addition
+wird vor der Zuweisung ausgeführt. Die Auswertung von Zuweisungen mit Ausdrücken
+muß immer so verlaufen, da die Zuweisung stets die niedrigste Priorität aller Operato­
+ren hat.
+
+Oft kommt es vor, daß ein Objekt auf der linken und rechten Seite des Zuweisungs­
+operators erscheint, z.B. wenn ein Wert erhöht werden soll.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ a := a + 1;
+
+____________________________________________________________________________
+
+
+Hier wird der "alte", aktuelle Wert von 'a' genommen, um '1' erhöht und dem Objekt
+'a' zugewiesen. Man beachte, daß hier in einer Anweisung ein Datenobjekt unter­
+schiedliche Werte zu unterschiedlichen Zeitpunkten haben kann.
+
+
+
+2.4.1.3 Refinementanwendung
+
+In ELAN ist es möglich, Namen für Ausdrücke oder eine bzw. mehrere Anweisungen
+zu vergeben. Das Sprachelement, das diese Namensgebung ermöglicht, heißt Refi­
+nement. Die Ausführung eines solchen Namens heißt Refinementanwendung, die
+Namensgebung heißt Refinementvereinbarung (siehe 2.4.3.1). Die Ausdrücke oder
+Anweisungen bilden den Refinementrumpf. Ein Refinement kann man in einem Pro­
+gramm unter dem Refinementnamen ansprechen. Man kann sich die Ausführung so
+vorstellen, als würden der Refinementrumpf immer dort eingesetzt, wo der Name des
+Refinements als Operation benutzt wird.
+
+
+
+2.4.1.4 Prozeduraufruf
+
+Eine Prozedur ist eine Sammlung von Anweisungen und Daten, die zur Lösung einer
+bestimmten Aufgabe benötigt werden. Eine Prozedur wird in einer Prozedurvereinba­
+rung definiert (siehe 2.4.3.2). Eine solche Prozedur kann man in einem Programm
+unter einem Namen (eventuell unter Angabe von Parametern) ansprechen. Man
+spricht dann vom Aufruf einer Prozedur oder einer Prozeduranweisung.
+
+Formen des Prozeduraufrufs:
+
+- #on("b")#Prozeduren ohne Parameter#off("b")# werden durch den Prozedurnamen angesprochen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ pause;
+
+____________________________________________________________________________
+
+
+ (Die Prozedur 'pause' wartet bis ein Zeichen eingegeben wird)
+
+
+- #on("b")#Prozeduren mit Parameter#off("b")# werden durch
+
+
+ Prozedurnamen #on("i")##on("b")#(#off("i")##off("b")# aktuelle Parameterliste #on("i")##on("b")#)#off("i")##off("b")#
+
+
+ aufgerufen. Eine Parameterliste ist entweder ein Datenobjekt oder mehrere durch
+ Kommata getrennte Datenobjekte.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ pause (10);
+
+____________________________________________________________________________
+
+
+ (Mit der Prozedur 'pause (INT CONST zeitgrenze)' kann für eine Zeitdauer von
+ 'zeitgrenze' in Zehntel-Sekunden gewartet werden. Die Wartezeit wird durch
+ Erreichen der Zeitgrenze oder durch Eingabe eines Zeichens abgebrochen)
+
+
+ Bei den aktuellen Parametern ist folgendes zu beachten:
+
+ a) Wird ein VAR-Parameter in der Definition der Prozedur vorgeschrieben, darf
+ kein Ausdruck als aktueller Parameter "übergeben" werden, weil an einen
+ Ausdruck nichts zugewiesen werden kann. Ausdrücke haben - wie bereits
+ erwähnt - das Accessrecht CONST.
+
+____________________________________________________________________________
+ ........................ Gegenbeispiel: .......................
+ TEXT VAR text1, text2;
+ text1 := "Dieses Beispiel ";
+ text2 := "Fehlermeldung";
+ insert char (text1 + text2, "liefert eine", 17);
+
+____________________________________________________________________________
+
+
+ (Die Prozedur 'insert char (TEXT VAR string, TEXT CONST char, INT CONST
+ pos)' fügt das Zeichen 'char' in den Text 'string' an der Position 'pos' ein)
+
+ b) Wird ein CONST-Parameter verlangt, dann darf in diesem Fall ein Ausdruck
+ als aktueller Parameter geschrieben werden. Aber auch ein VAR-Datenobjekt
+ darf angegeben werden. In diesem Fall wird eine Wandlung des Accessrechts
+ (CONSTing) vorgenommen: der aktuelle Parameter erhält sozusagen für die
+ Zeit der Abarbeitung der Prozedur das Accessrecht CONST.
+
+
+ In ELAN sind auch Prozeduren als Parameter erlaubt. Die Prozedur als aktueller
+ Parameter wird in der Parameterliste folgendermaßen angegeben:
+
+
+ Resultattyp #on("i")##on("b")#PROC#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# virtuelle Parameterliste #on("i")##on("b")#)#off("i")##off("b")# Procname
+
+
+ Die Angabe des Resultattyps entfällt, wenn es sich nicht um eine wertliefernde
+ Prozedur handelt. Die virtuelle Parameterliste inklusive der Klammern entfällt, falls
+ die Prozedur keine Parameter hat. Die virtuelle Parameterliste beschreibt die
+ Parameter der Parameterprozedur. Es werden Datentyp und Zugriffsrecht eines
+ jeden Parameters angegeben, jedoch ohne Namen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ wertetabelle (REAL PROC (REAL CONST) sin,
+ untergrenze, obergrenze, schrittweite);
+
+
+ (Die Prozedur 'sin' wird an die Prozedur 'wertetabelle' übergeben)
+
+____________________________________________________________________________
+
+
+2.4.2 Zusammengesetzte Programmeinheiten
+
+
+2.4.2.1 Folge
+
+Mehrere in einer bestimmten Reihenfolge auszuführende Anweisungen werden als
+Folge bezeichnet. In ELAN kann man eine oder mehrere Anweisungen in eine Pro­
+grammzeile schreiben oder eine Anweisung über mehrere Zeilen. Das setzt jedoch
+voraus, daß die Anweisungen voneinander getrennt werden. Die Trennung von Anwei­
+sungen erfolgt in ELAN durch das Trennsymbol Semikolon. Es bedeutet soviel wie:
+"führe die nächste Anweisung aus".
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ put ("mein");
+ put (1);
+ put (". Programm")
+
+____________________________________________________________________________
+
+
+(Die Prozedur 'put' gibt den als Parameter angegebenen Wert auf dem Ausgabegerät
+aus)
+
+
+
+2.4.2.2 Abfrage
+
+Mit Abfragen steuert man die bedingte Ausführung von Anweisungen. Abhängig von
+einer Bedingung wird in zwei verschiedene Programmabschnitte verzweigt.
+
+Der formale Aufbau einer Abfrage sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#IF#off("i")##off("b")# Bedingung
+ #on("i")##on("b")#THEN#off("i")##off("b")# Abschnitt
+ #on("i")##on("b")#ELSE#off("i")##off("b")# Abschnitt
+#on("i")##on("b")#END IF#off("i")##off("b")#
+
+
+Der ELSE-Teil darf dabei auch fehlen. Anstelle von #on("i")##on("b")#END IF#off("i")##off("b")# darf auch die Abkürzung #on("i")##on("b")#FI#off("i")##off("b")# (IF von hinten gelesen) benutzt werden.
+
+In folgenden Beispielen wird der Absolutbetrag von 'a' ausgegeben:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR a;
+ get (a);
+ IF a < 0
+ THEN a := -a
+ END IF;
+ put (a)
+
+____________________________________________________________________________
+
+
+Die Umkehrung des Vorzeichens von a im THEN-Teil wird nur durchgeführt, wenn
+der BOOLesche Ausdruck ('a < 0') den Wert TRUE liefert. Liefert er den Wert
+FALSE, wird die Anweisung, die der bedingten Anweisung folgt (nach END IF), ausge­
+führt. Das obige Programm kann auch anders geschrieben werden:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR a;
+ get (a);
+ IF a < 0
+ THEN put (-a)
+ ELSE put (a)
+ END IF
+
+____________________________________________________________________________
+
+
+Der THEN-Teil wird wiederum ausgeführt, wenn die BOOLesche Bedingung erfüllt
+ist. Liefert sie dagegen FALSE, wird der ELSE-Teil ausgeführt.
+
+Die bedingte Anweisung ermöglicht es, abhängig von einer Bedingung eine oder
+mehrere Anweisungen ausführen zu lassen. Dabei können im THEN- bzw. ELSE-
+Teil wiederum bedingte Anweisungen enthalten sein.
+
+
+Abfragekette
+Bei Abfrageketten kann das ELIF-Konstrukt eingesetzt werden. (ELIF ist eine Zu­
+sammenziehung der Worte ELSE und IF).
+
+Anstatt
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ IF bedingung1
+ THEN aktion1
+ ELSE IF bedingung2
+ THEN aktion2
+ ELSE aktion3
+ END IF
+ END IF;
+
+____________________________________________________________________________
+
+
+kann man besser
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ IF bedingung1
+ THEN aktion1
+ ELIF bedingung2
+ THEN aktion2
+ ELSE aktion3
+ END IF;
+
+____________________________________________________________________________
+
+
+schreiben.
+
+
+
+2.4.2.3 Auswahl
+
+Die Auswahl wird benutzt, wenn alternative Anwendungen in Abhängikeit von Werten
+eines Datenobjekts ausgeführt werden sollen.
+
+Der formale Aufbau der Auswahl sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#SELECT#off("i")##off("b")# INT-Ausdruck #on("i")##on("b")#OF#off("i")##off("b")#
+ #on("i")##on("b")#CASE#off("i")##off("b")# 1. Liste von INT-Denotern #on("i")##on("b")#:#off("i")##off("b")# Abschnitt
+ #on("i")##on("b")#CASE#off("i")##off("b")# 2. Liste von INT-Denotern #on("i")##on("b")#:#off("i")##off("b")# Abschnitt
+ .
+ .
+ .
+ #on("i")##on("b")#CASE#off("i")##off("b")# n. Liste von INT-Denotern #on("i")##on("b")#:#off("i")##off("b")# Abschnitt
+ #on("i")##on("b")#OTHERWISE#off("i")##off("b")# Abschnitt
+#on("i")##on("b")#END SELECT#off("i")##off("b")#
+
+
+Eine Liste von INT-Denotern besteht aus einem oder mehreren durch Kommata ge­
+trennten INT-Denotern. Der OTHERWISE-Teil darf auch fehlen. Man sollte ihn
+jedoch verwenden, um Fehlerfälle abzufangen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ SELECT monat OF
+ CASE 2: IF schaltjahr
+ THEN tage := 29
+ ELSE tage := 28
+ END IF
+ CASE 4, 6, 9, 11: tage := 30
+ CASE 1, 3, 5, 7, 8, 10 ,12: tage := 31
+ OTHERWISE kein monat
+ END SELECT;
+
+____________________________________________________________________________
+
+
+(In diesem Programmausschnitt werden die Tage eines Monats bestimmt)
+
+
+
+2.4.2.4 Wertliefernde Abfrage und
+ wertliefernde Auswahl
+
+
+Soll eine Abfrage oder eine Auswahl einen Wert liefern, dann darf der ELSE- bzw.
+der OTHERWISE-Teil nicht fehlen und alle Zweige müssen einen Wert liefern.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ SELECT monat OF
+ CASE 2: IF schaltjahr
+ THEN 29
+ ELSE 28
+ END IF
+ CASE 4, 6, 9, 11: 30
+ CASE 1, 3, 5, 7, 8, 10 ,12: 31
+ OTHERWISE kein monat; 0
+ END SELECT;
+
+____________________________________________________________________________
+
+
+2.4.2.5 Wiederholung
+
+Die Wiederholung dient zur mehrfachen Ausführung von Anweisungen, meist in Ab­
+hängigkeit von einer Bedingung. Darum wird die Wiederholungsanweisung oft auch
+Schleife genannt und die in ihr enthaltenen Anweisungen Schleifenrumpf.
+
+Es gibt verschiedene Schleifentypen:
+
+- Endlosschleife
+- abweisende Schleife
+- nicht abweisende Schleife
+- Zählschleife.
+
+
+Endlosschleife
+Bei der Endlosschleife wird nicht spezifiziert, wann die Schleife beendet werden soll.
+
+Form:
+
+
+#on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Anstelle von #on("i")##on("b")#REPEAT#off("i")##off("b")# darf die Abkürzung #on("i")##on("b")#REP#off("i")##off("b")# und anstelle von #on("i")##on("b")#END REPEAT#off("i")##off("b")#
+das Schlüsselwort #on("i")##on("b")#PER#off("i")##off("b")# (REP von hinten gelesen)
+benutzt werden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ break;
+ REPEAT
+ fixpoint;
+ pause (18000)
+ END REPEAT
+
+____________________________________________________________________________
+
+
+Wird dieses Programm in einer Task im SYSUR-Zweig ausgeführt, so führt diese
+Task Fixpunkte im Abstand von 30 Minuten durch.
+
+
+
+Abweisende Schleife
+Bei der abweisenden Schleife wird die Abbruchbedingung an den Anfang der Schleife
+geschrieben.
+
+Form:
+
+
+#on("i")##on("b")#WHILE#off("i")##off("b")# Bedingung #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Bei jedem erneuten Durchlauf der Schleife wird überprüft, ob der BOOLesche Aus­
+druck den Wert TRUE liefert. Ist das nicht der Fall, wird die Bearbeitung mit der
+Anweisung fortgesetzt, die auf das Schleifenende folgt. Die Schleife wird abweisende
+Schleife genannt, weil der Schleifenrumpf nicht ausgeführt wird, wenn die Bedingung
+vor Eintritt in die Schleife bereits FALSE liefert.
+
+
+Nicht abweisende Schleife
+Anders verhält es sich bei der nicht abweisenden Schleife. Bei der nicht abweisenden
+Schleife wird die Abbruchbedingung an das Ende der Schleife geschrieben.
+
+Form:
+
+
+#on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#UNTIL#off("i")##off("b")# Bedingung #on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Hier wird der Schleifenrumpf auf jeden Fall einmal bearbeitet. Am Ende des Rumpfes
+wird die BOOLesche Bedingung abgefragt. Liefert sie den Wert FALSE, wird die
+Schleife erneut abgearbeitet. Liefert die Bedingung den Wert TRUE, wird die Schleife
+abgebrochen und mit der ersten Anweisung hinter der Schleife in der Bearbeitung
+fortgefahren.
+
+Bei den beiden letztgenannten Arten der Wiederholungsanweisung ist es wichtig, daß
+Elemente der BOOLeschen Bedingung in der Schleife verändert werden, damit das
+Programm terminieren kann, d.h. die Schleife abgebrochen wird.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TEXT VAR wort, satz :: "";
+ REPEAT
+ get (wort);
+ satz CAT wort;
+ satz CAT " "
+ UNTIL wort = "." PER;
+
+____________________________________________________________________________
+
+
+Dises Programm liest solange Wörter ein und verbindet diese zu einem Satz, bis ein
+Punkt eingegeben wurde.
+
+
+
+Zählschleife
+Zählschleifen werden eingesetzt, wenn die genaue Anzahl der Schleifendurchläufe
+bekannt ist.
+
+Form:
+
+
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Anfangswert #on("i")##on("b")#UPTO#off("i")##off("b")# Endwert #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Bei Zählschleifen wird eine Laufvariable verwendet, die die INT-Werte von 'Anfangs­
+wert' bis 'Endwert' in Schritten von 1 durchläuft. 'Anfangswert' und 'Endwert' können
+beliebige INT-Ausdrücke sein. Diese Schleife zählt "aufwärts". Wird anstatt #on("i")##on("b")#UPTO#off("i")##off("b")#
+das Schlüsselwort #on("i")##on("b")#DOWNTO#off("i")##off("b")# verwendet, wird mit Schritten von 1 "abwärts" gezählt.
+
+Form:
+
+
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Endwert #on("i")##on("b")#DOWNTO#off("i")##off("b")# Anfangswert #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Die Laufvariable darf in der Schleife nicht verändert werden. Nach dem normalen
+Schleifenende ist der Wert der Laufvariablen nicht definiert.
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR summe :: 0, i;
+ FOR i FROM 1 UPTO 100 REPEAT
+ summe INCR i
+ END REPEAT
+
+____________________________________________________________________________
+
+
+Dieses Programm berechnet die Summe der natürlichen Zahlen von 1 bis 100.
+
+
+Die verschiedenen Schleifenarten können kombiniert werden:
+
+
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Anfangswert #on("i")##on("b")#UPTO#off("i")##off("b")# Endwert
+#on("i")##on("b")#WHILE#off("i")##off("b")# Bedingung #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Anfangswert #on("i")##on("b")#UPTO#off("i")##off("b")# Endwert #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#UNTIL#off("i")##off("b")# Bedingung #on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+
+
+
+#on("i")##on("b")#WHILE#off("i")##off("b")# Bedingung #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#UNTIL#off("i")##off("b")# Bedingung #on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+#page#
+
+2.4.3 Abstrahierende Programmeinheiten
+
+
+2.4.3.1 Refinementvereinbarung
+
+In ELAN ist es möglich, Namen für Ausdrücke oder eine bzw. mehrere Anweisungen
+zu vergeben. Das Sprachelement, das diese Namensgebung ermöglicht, heißt Refi­
+nement. Die Ausführung eines solchen Namens heißt Refinementanwendung (siehe
+2.4.1.3), die Namensgebung heißt Refinementvereinbarung. Die Ausdrücke oder
+Anweisungen bilden den Refinementrumpf.
+
+Werden in einem Programm Refinements benutzt, dann wird der Programmteil bis
+zum ersten Refinement durch einen Punkt abgeschlossen. Die Refinementvereinba­
+rung sieht folgendermaßen aus:
+
+
+Name #on("i")##on("b")#:#off("i")##off("b")#
+ Abschnitt #on("i")##on("b")#.#off("i")##off("b")#
+
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR a, b, x;
+ einlesen von a und b;
+ vertauschen von a und b;
+ vertauschte werte ausgeben.
+
+ einlesen von a und b:
+ get (a);
+ get (b).
+
+ vertauschen von a und b:
+ x := a;
+ a := b;
+ b := x.
+
+ vertauschte werte ausgeben:
+ put (a);
+ put (b).
+
+____________________________________________________________________________
+
+
+Für den Namen 'einlesen von a und b' werden die Anweisungen 'get (a); get (b)' vom
+ELAN-Compiler eingesetzt. Man kann also die ersten vier Zeilen des Programms als
+eigentliches Programm ansehen, wobei die Namen durch die betreffenden Anwei­
+sungen ersetzt werden. Ein Refinement hat also keinen eigenen Datenbereich, d.h.
+Vereinbarungen, die in Refinements gemacht werden, gelten auch außerhalb des
+Refinements.
+
+
+
+Vorteile der Refinementanwendung
+Durch die sinnvolle Verwendung von Refinements wird ein Programm im Programm
+und nicht in einer separaten Beschreibung dokumentiert. Weiterhin kann ein Pro­
+gramm "von oben nach unten" ("top down") entwickelt werden: Das obige - zuge­
+geben einfache - Beispielprogramm wurde in drei Teile zerlegt und diese durch
+Namen beschrieben. Bei der Beschreibung von Aktionen durch Namen wird gesagt
+was gemacht werden soll. Es wird noch nicht beschrieben wie, denn auf dieser Stufe
+der Programmentwicklung braucht man sich um die Realisierung der Refinements
+(noch) keine Sorgen zu machen. Das erfolgt erst, wenn das Refinement programmiert
+werden muß. Dabei können wiederum Refinements verwendet werden usw., bis man
+auf eine Ebene "heruntergestiegen" ist, bei der eine (jetzt: Teil-) Problemlösung sehr
+einfach ist und man sie direkt hinschreiben kann. Man beschäftigt sich also an jedem
+Punkt der Problemlösung nur mit einem Teilaspekt des gesamten Problems. Zudem
+sieht man - wenn die Refinements einigermaßen vernünftig verwendet werden -
+dem Programm an, wie die Problemlösung entstanden ist.
+
+Die Verwendung von Refinements hat also eine Anzahl von Vorteilen.
+Refinements ermöglichen:
+
+- "top down" - Programmierung
+- Strukturierung von Programmen und damit effiziente Fehlersuche und gute Wart­
+ barkeit
+- Dokumentation im Programmtext.
+
+
+Wertliefernde Refinements
+Refinements können auch dort verwendet werden, wo ein Wert erwartet wird, z.B. in
+einem Ausdruck oder einer 'put'-Anweisung. In diesem Fall muß die letzte Anwei­
+sung des Refinements einen Wert liefert.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR a :: 1, b :: 2, c :: 3;
+ put (resultat).
+
+ resultat:
+ (a * b + c) ** 3.
+
+____________________________________________________________________________
+
+
+Man kann auch ein wertlieferndes Refinement mit mehreren Anweisungen schrei­
+ben.
+
+Allgemeine Regel:
+Die letzte Anweisung eines Refinements bestimmt, ob es einen Wert liefert - und
+wenn ja, von welchen Datentyp.
+
+
+
+2.4.3.2 Prozedurvereinbarung
+
+Eine Prozedur ist eine Sammlung von Anweisungen und Daten, die zur Lösung einer
+bestimmten Aufgabe benötigt werden.
+
+Der formale Aufbau einer Prozedur sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#PROC#off("i")##off("b")# Prozedurname #on("i")##on("b")#:#off("i")##off("b")#
+ Prozedurrumpf
+#on("i")##on("b")#END PROC#off("i")##off("b")# Prozedurname
+
+
+Der Prozedurrumpf kann Deklarationen, Anweisungen und Refinements enthalten.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC loesche bildschirm ab aktueller cursorposition:
+ out (""4"")
+ END PROC loesche bildschirm ab aktueller cursorposition
+
+____________________________________________________________________________
+
+
+Verwendung von Prozeduren
+Prozeduren werden verwendet, wenn
+
+- Anweisungen und Datenobjekte unter einem Namen zusammengefaßt werden
+ sollen ("Abstraktion")
+- gleiche Anweisungen von mehreren Stellen eines Programms verwandt werden
+ sollen (Codereduktion), u.U. mit verschieden Datenobjekten (Parameter)
+- Datenobjekte nur innerhalb eines Programmteils benötigt werden und diese nicht
+ von dem gesamten Programm angesprochen werden sollen.
+
+In den folgenden Programmfragmenten werden zwei Werte vertauscht. In der ersten
+Lösung wird ein Refinement, in der zweiten eine Prozedur verwandt.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ IF a > b
+ THEN vertausche a und b
+ END IF;
+ put (a);
+ put (b);
+ vertausche a und b.
+
+ vertausche a und b:
+ INT CONST x :: a;
+ a := b;
+ b := x.
+
+____________________________________________________________________________
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC vertausche a und b:
+ INT CONST x :: a;
+ a := b;
+ b := x
+ END PROC vertausche a und b;
+
+ IF a > b
+ THEN vertausche a und b
+ END IF;
+ put (a);
+ put (b);
+ vertausche a und b;
+
+____________________________________________________________________________
+
+
+Beim ersten Hinsehen leisten beide Programme das Gleiche. Es gibt jedoch drei
+wichtige Unterschiede:
+
+1) Das Refinement 'vertausche a und b' wird zweimal (vom ELAN-Compiler) ein­
+ gesetzt, d.h. der Code ist zweimal vorhanden. Die Prozedur dagegen ist vom Code
+ nur einmal vorhanden, wird aber zweimal - durch das Aufführen des Prozedur­
+ namens - aufgerufen.
+
+2) Die Variable 'x' ist in der ersten Programmversion während des gesamten Ablauf
+ des Programms vorhanden, d.h. ihr Speicherplatz ist während dieser Zeit belegt.
+ Solche Datenobjekte nennt man statische Datenobjekte oder auch (aus Gründen,
+ die erst etwas später offensichtlich werden) Paket-Objekte. Das Datenobjekt 'x'
+ der rechten Version dagegen ist nur während der Bearbeitung der Prozedur vor­
+ handen, sein Speicherplatz wird danach freigegeben. Solche Datenobjekte, die nur
+ kurzfristig Speicher belegen, werden dynamische Datenobjekte genannt.
+
+ Prozeduren sind also ein Mittel, um die Speicherbelegung zu beeinflussen.
+
+3) Da Refinements keinen eigenen Datenbereich haben, kann die Variable 'x' in der
+ ersten Programmversion - obwohl sie in einem Refinement deklariert wurde -
+ von jeder Stelle des Programms angesprochen werden. Solche Datenobjekte
+ werden globale Datenobjekte genannt. Das Datenobjekt 'x' der Prozedur dagegen
+ kann nur innerhalb der Prozedur angesprochen werden, es ist also ein lokales
+ Datenobjekt der Prozedur. Innerhalb der Prozedur dürfen globale Datenobjekte
+ (also Objekte, die außerhalb von Prozeduren deklariert wurden) auch angespro­
+ chen werden.
+
+ Eine Prozedur in ELAN bildet im Gegensatz zu Refinements einen eigenen Gültig­
+ keitsbereich hinsichtlich Datenobjekten und Refinements, die innerhalb der Pro­
+ zedur deklariert werden. Prozeduren sind somit ein Mittel, um die in ihr dekla­
+ rierten Datenobjekte hinsichtlich der Ansprechbarkeit nach Außen "abzuschotten".
+
+
+
+Prozeduren mit Parametern
+Prozeduren mit Parametern erlauben es, gleiche Anweisungen mit unterschiedlichen
+Datenobjekten auszuführen.
+
+Form:
+
+
+#on("i")##on("b")#PROC#off("i")##off("b")# Prozedurname #on("i")##on("b")#(#off("i")##off("b")# formale Parameterliste #on("i")##on("b")#)#off("i")##off("b")# #on("i")##on("b")#:#off("i")##off("b")#
+ Prozedurrumpf
+#on("i")##on("b")#END PROC#off("i")##off("b")# Prozedurnamen
+
+
+Die Parameterliste besteht aus einem oder mehreren durch Kommata getrennten Para­
+metern. Ein Parameter wird mit Datentyp, Accessrecht und Namen angegeben.
+Ähnlich wie bei der Datendeklaration braucht man für aufeinanderfolgende Parameter
+mit gleichem Datentyp und gleichem Accessrecht die Attribute nur einmal anzugeben.
+Parameter mit Accessrecht #on("i")##on("b")#CONST#off("i")##off("b")# sind Eingabeparameter, Parameter mit Access­
+recht #on("i")##on("b")#VAR#off("i")##off("b")# realisieren Ein-/Ausgabeparameter.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC vertausche (INT VAR a, b):
+ INT VAR x :: a;
+ a := b;
+ b := x
+ END PROC vertausche;
+
+ INT VAR eins :: 1,
+ zwei :: 2,
+ drei :: 3;
+ vertausche (eins, zwei);
+ vertausche (zwei, drei);
+ vertausche (eins, zwei);
+ put (eins); put (zwei); put (drei)
+
+____________________________________________________________________________
+
+
+Die Datenobjekte 'a' und 'b' der Prozedur 'vertausche' werden formale Parameter
+genannt. Sie stehen als Platzhalter für die bei einem Prozeduraufruf einzusetzenden
+aktuellen Parameter (in obigen Beispiel die Datenobjekte 'eins', 'zwei' und 'drei').
+
+
+
+Prozeduren als Parameter
+Es ist auch möglich, Prozeduren als Parameter zu definieren.
+
+Eine Prozedur als Parameter wird folgendermaßen in der Parameterliste spezifiziert:
+
+Resultattyp #on("i")##on("b")#PROC#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# virtuelle Parameterliste #on("i")##on("b")#)#off("i")##off("b")# Prozedurname
+
+
+Die Angabe des Resultattyps entfällt, wenn es sich nicht um eine wertliefernde Proze­
+dur handelt. Die virtuelle Parameterliste inklusive der Klammern entfällt, falls die
+Prozedur keine Parameter hat. Die virtuelle Parameterliste beschreibt die Parame­
+ter der Parameterprozedur. Es werden Datentyp und Zugriffsrecht eines jeden Para­
+meters angegeben, jedoch ohne Namen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC wertetabelle (REAL PROC (REAL CONST) funktion,
+ REAL CONST untergrenze, obergrenze,
+ schrittweite):
+
+ REAL VAR wert;
+ putline ("W E R T E T A B E L L E");
+ putline ("-----------------------");
+ wert := untergrenze;
+ REPEAT
+ put (text (wert, 10, 5));
+ put (text (funktion (wert), 10, 5));
+ line;
+ wert INCR schrittweite
+ UNTIL wert > obergrenze PER
+
+ END PROC wertetabelle;
+
+ (* Prozeduraufruf: *)
+ wertetabelle (REAL PROC (REAL CONST) sin, 0.0, pi, 0.2)
+
+____________________________________________________________________________
+
+
+Wertliefernde Prozeduren
+Eine wertliefernde Prozedur sieht folgendermaßen aus:
+
+
+Resultattyp #on("i")##on("b")#PROC#off("i")##off("b")# Prozedurname #on("i")##on("b")#(#off("i")##off("b")# formale Parameterliste #on("i")##on("b")#)#off("i")##off("b")# #on("i")##on("b")#:#off("i")##off("b")#
+ wertliefernder Prozedurrumpf
+#on("i")##on("b")#END PROC#off("i")##off("b")# Prozedurnamen
+
+
+
+Die Parameterliste inklusive Klammerung kann fehlen. Der Prozedurrumpf muß einen
+Wert mit dem in Resultattyp angegeben Datentyp liefern.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT PROC max (INT CONST a, b):
+ IF a > b
+ THEN a
+ ELSE b
+ END IF
+ END PROC max;
+
+ put (max (3, 4))
+
+____________________________________________________________________________
+
+
+(In diesem Beispiel wird das Maximum von 'a' und 'b' ermittelt und ausgegeben)
+
+#page#
+
+2.4.3.3 Operatorvereinbarung
+
+Operatoren können in ELAN ähnlich wie Prozeduren definiert werden. Operatoren
+müssen einen und können maximal zwei Operatoren besitzen (monadische und dyadi­
+sche Operatoren).
+
+Form:
+
+
+Resultattyp #on("i")##on("b")#OP#off("i")##off("b")# Opname #on("i")##on("b")#(#off("i")##off("b")# ein oder zwei Parameter #on("i")##on("b")#)#off("i")##off("b")# #on("i")##on("b")#:#off("i")##off("b")#
+ Operatorrumpf
+#on("i")##on("b")#END OP#off("i")##off("b")# Opname
+
+
+Der Resultattyp wird nur bei wertliefernden Operatoren angegeben.
+
+Als Operatornamen sind erlaubt:
+
+- ein Sonderzeichen, sofern es nicht als Trennzeichen benutzt wird:
+ ! $ % & ' * + - / < = > ? § ^ ' ~
+- eine Kombination von zwei Sonderzeichen. Diese Kombination muß jedoch bereits
+ in ELAN existieren:
+ := <= >= <> **
+- ein Schlüsselwort (siehe 2.2.1).
+
+
+
+Vereinbarung eines monadischen Operators
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT OP SIGN (REAL CONST argument):
+ IF argument < 0.0 THEN -1
+ ELIF argument = 0.0 THEN 0
+ ELSE 1
+ FI
+ END OP SIGN
+
+____________________________________________________________________________
+
+
+(Der Operator 'SIGN' liefert abhängig vom Vorzeichen des übergebenen Wertes den
+INT-Wert -1, 0 oder 1)
+
+
+
+Vereinbarung eines dyadischen Operators
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TEXT OP * (INT CONST anzahl, TEXT CONST t):
+ INT VAR zaehler :: anzahl;
+ TEXT VAR ergebnis :: "";
+ WHILE zaehler > 0 REP
+ ergebnis := ergebnis + t;
+ zaehler := zaehler - 1
+ END REP;
+ ergebnis
+ END OP *;
+
+____________________________________________________________________________
+
+
+(Der Operator '*' verkettet 'anzahl'- mal den Text 't')
+
+
+
+2.4.3.4 Paketvereinbarung
+
+Pakete sind in ELAN eine Zusammenfassung von Datenobjekten, Prozeduren, Opera­
+toren und Datentypen. Diese bilden den Paketrumpf. Elemente eines Pakets (Prozedu­
+ren, Operatoren, Datentypen) können außerhalb des Pakets nur angesprochen werden,
+wenn sie in der Schnittstelle des Pakets, die auch "interface" genannt wird, aufge­
+führt werden. Mit anderen Worten: es können alle Elemente eines Pakets von außen
+nicht angesprochen werden, sofern sie nicht über die Schnittstelle "nach außen ge­
+reicht" werden. Pakete können separat übersetzt werden, so daß der "Zusammen­
+bau" eines umfangreichen Programms aus mehreren Paketen möglich ist.
+
+Der formale Aufbau eines Pakets sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#PACKET#off("i")##off("b")# Paketname #on("i")##on("b")#DEFINES#off("i")##off("b")# Schnittstelle #on("i")##on("b")#:#off("i")##off("b")#
+ Paketrumpf
+#on("i")##on("b")#END PACKET#off("i")##off("b")# Paketname
+
+
+In der Schnittstelle werden Prozeduren und Operatoren nur mit ihrem Namen, durch
+Kommata getrennt, angegeben. Weiterhin können Datentypen und mit CONST verein­
+barte Datenobjekte in der Schnittstelle aufgeführt werden, aber keine VAR-Datenob­
+jekte, weil diese sonst über Paket-Grenzen hinweg verändert werden könnten.
+
+Im Gegensatz zu einer Prozedur kann ein PACKET nicht aufgerufen werden (nur die
+Elemente der Schnittstelle können benutzt werden).
+
+Pakete werden zu folgenden Zwecken eingesetzt:
+
+- Spracherweiterung
+- Schutz vor fehlerhaftem Zugriff auf Datenobjekte
+- Realisierung von abstrakten Datentypen.
+
+
+
+Spracherweiterung
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PACKET fuer eine prozedur DEFINES swap:
+
+ PROC swap (INT VAR a, b):
+ INT CONST x :: a;
+ b := a;
+ a := x
+ END PROC swap
+
+ END PACKET fuer eine prozedur
+
+____________________________________________________________________________
+
+
+Dies ist ein Paket, das eine Tausch-Prozedur für INT-Datenobjekte bereitstellt. Das
+PACKET kann übersetzt und dem ELAN-Compiler bekannt gemacht werden
+(EUMEL: "insertieren"). Ist das geschehen, kann man 'swap' wie alle anderen Proze­
+duren (z.B. 'put', 'get') in einem Programm verwenden. Tatsächlich werden die mei­
+sten Prozeduren und Operatoren (aber auch einige Datentypen), die in ELAN zur
+Verfügung stehen, nicht durch den ELAN-Compiler realisiert, sondern durch solche
+PACKETs. Um solche Objekte einigermaßen zu standardisieren, wurde in der
+ELAN-Sprachbeschreibung festgelegt, welche Datentypen, Prozeduren und Operato­
+ren in jedem ELAN-System vorhanden sein müssen. Solche Pakete werden Stan­
+dard-Pakete genannt. Jeder Installation - aber auch jedem Benutzer - steht es
+jedoch frei, zu den Standard-Paketen zusätzliche Pakete dem Compiler bekannzu­
+geben, und damit den ELAN-Sprachumfang zu erweitern.
+
+
+
+Schutz vor fehlerhaftem Zugriff auf Datenobjekte
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PACKET stack handling DEFINES push, pop, init stack:
+
+ LET max = 1000;
+ ROW max INT VAR stack; (* siehe Kapitel Reihung, 2.6.1. *)
+ INT VAR stack pointer;
+
+ PROC init stack:
+ stack pointer := 0
+ END PROC init stack;
+
+ PROC push (INT CONST dazu wert):
+ stack pointer INCR 1;
+ IF stack pointer > max
+ THEN errorstop ("stack overflow")
+ ELSE stack [stack pointer] := dazu wert
+ END IF
+ END PROC push;
+
+ PROC pop (INT VAR von wert):
+ IF stack pointer = 0
+ THEN errorstop ("stack empty")
+ ELSE von wert := stack [stack pointer];
+ stack pointer DECR 1
+ END IF
+ END PROC pop
+
+ END PACKET stack handling;
+
+____________________________________________________________________________
+
+
+Dieses Packet realisiert einen Stack. Den Stack kann man über die Prozeduren 'init
+stack', 'push' und 'pop' benutzen.
+#page#
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ init stack;
+ werte einlesen und pushen;
+ werte poppen und ausgeben.
+
+ werte einlesen und pushen:
+ INT VAR anzahl :: 0, wert;
+ REP
+ get (wert);
+ push (wert);
+ anzahl INCR 1
+ UNTIL ende kriterium END REP.
+
+ werte poppen und ausgeben:
+ INT VAR i;
+ FOR i FROM 1 UPTO anzahl REP
+ pop (wert);
+ put (wert)
+ END REP.
+
+____________________________________________________________________________
+
+
+Die Datenobjekte 'stack' und 'stack pointer' haben nur Gültigkeit innerhalb des
+PACKETs 'stack handling'.
+
+Anweisungen wie z.B.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ put (stack [3]);
+ stack [27] := 5
+
+____________________________________________________________________________
+
+
+
+außerhalb des PACKETs 'stack handling' sind also verboten und werden vom
+ELAN-Compiler entdeckt.
+
+Ein PACKET bietet also auch einen gewissen Schutz vor fehlerhafter Verwendung von
+Programmen und Datenobjekten. Wichtig ist weiterhin, daß die Realisierung des
+Stacks ohne weiteres geändert werden kann, ohne daß Benutzerprogramme im 'main
+packet' geändert werden müssen, sofern die Schnittstelle nicht verändert wird. Bei­
+spielsweise kann man sich entschließen, den Stack nicht durch eine Reihung, son­
+dern durch eine Struktur zu realisieren. Davon bleibt ein Benutzerprogramm unbe­
+rührt.
+
+
+
+Realisierung von abstrakten Datentypen
+Der Vollständigkeit halber wird folgendes Beispiel hier gezeigt. Wie neue Datentypen
+definiert werden, wird in Kapitel 2.7.1. erklärt.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PACKET widerstaende DEFINES WIDERSTAND, REIHE, PARALLEL,
+ :=, get, put:
+
+ TYPE WIDERSTAND = INT;
+
+ OP := (WIDERSTAND VAR l, WIDERSTAND CONST r):
+ CONCR (l) := CONCR (r)
+ END OP :=;
+
+ PROC get (WIDERSTAND VAR w):
+ INT VAR i;
+ get (i);
+ w := WIDERSTAND : (i)
+ END PROC get;
+
+ PROC put (WIDERSTAND CONST w):
+ put (CONCR (w))
+ END PROC put;
+
+ WIDERSTAND OP REIHE (WIDERSTAND CONST l, r):
+ WIDERSTAND : ( CONCR (l) + CONCR (r))
+ END OP REIHE;
+
+ WIDERSTAND OP PARALLEL (WIDERSTAND CONST l, r):
+ WIDERSTAND :
+ ((CONCR (l) * CONCR (r)) DIV (CONCR (l) + CONCR (r)))
+ END OP PARALLEL
+
+ END PACKET widerstaende
+
+____________________________________________________________________________
+
+
+Dieses Programm realisiert den Datentyp WIDERSTAND und mit den Operationen
+eine Fachsprache.
+
+
+
+2.4.4 Terminatoren für Refinements,
+ Prozeduren und Operatoren
+
+
+Das LEAVE-Konstrukt wird verwendet, um eine benannte Anweisung (Refinement,
+Prozedur oder Operator) vorzeitig zu verlassen. Es ist auch möglich, geschachtelte
+Refinements zu verlassen.
+
+Form:
+
+#on("i")##on("b")#LEAVE#off("i")##off("b")# Name
+
+
+Durch eine (optionale) WITH-Angabe kann auch eine wertliefernde benannte Anwei­
+sung verlassen werden.
+
+Form:
+
+#on("i")##on("b")#LEAVE#off("i")##off("b")# Name #on("i")##on("b")#WITH#off("i")##off("b")# Ausdruck
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT OP ** (INT CONST basis, exp):
+ IF exp = 0
+ THEN LEAVE ** WITH 1
+ ELIF exp < 0
+ THEN LEAVE ** WITH 0
+ FI;
+
+ INT VAR zaehler, ergebnis;
+ ergebnis := basis;
+ FOR zaehler FROM 2 UPTO exp REP
+ ergebnis := ergebnis * basis
+ PER;
+ ergebnis
+ END OP **
+
+____________________________________________________________________________
+
+
+(Diese Operation realisiert die Exponentiation für INT-Werte)
+
+
+
+2.4.5 Generizität von Prozeduren
+ und Operatoren
+
+
+In ELAN ist es möglich, unterschiedlichen Prozeduren bzw. Operatoren gleiche
+Namen zu geben. Solche Prozeduren (Operatoren) werden generische Prozeduren
+(Operatoren) genannt. Die Identifizierung erfolgt durch Anzahl, Reihenfolge und Daten­
+typ der Parameter (Operanden).
+
+Deshalb werden Prozeduren und Operatoren unter Angabe des Prozedur- bzw. des
+Operatorkopfes dokumentiert.
+
+Beispiele:
+
+
+INT OP MOD (INT CONST l, r)
+REAL OP MOD (REAL CONST l, r)
+
+
+Der MOD-Operator liefert den Rest einer Division. Er ist sowohl für INT- wie auch
+für REAL-Datenobjekte definiert.
+
+
+
+PROC put (INT CONST wert)
+PROC put (REAL CONST wert)
+PROC put (TEXT CONST wert)
+
+
+Die put-Prozedur ist für INT-, REAL- und TEXT-Datenobjekte definiert.
+
+
+
+Priorität von generischen Operatoren
+Bei der Neudefinition von Operatoren kann man bereits benutzte Sonderzeichen oder
+Schlüsselwörter benutzen. In diesem Fall bekommt der neudefinierte Operator die
+gleiche Priorität wie der bereits vorhandene Operator.
+
+
+
+2.4.6 Rekursive Prozeduren
+ und Operatoren
+
+
+Alle Prozeduren und Operatoren dürfen in ELAN rekursiv sein.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT PROC fakultaet (INT CONST n):
+ IF n > 0
+ THEN fakultaet (n-1) * n
+ ELSE 1
+ END IF
+ END PROC fakultaet
+
+____________________________________________________________________________
+
+
+Die Fakultätsfunktion ist kein gutes Beispiel für eine Rekursion, denn das Programm
+kann leicht in eine iterative Version umgewandelt werden:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT PROC fakultaet (INT CONST n):
+ INT VAR prod :: 1, i;
+ FOR i FROM 2 UPTO n REP
+ prod := prod * i
+ END REP;
+ prod
+ END PROC fakultaet
+
+____________________________________________________________________________
+
+
+Die Umwandlung von einem rekursiven Programm in ein iteratives ist übrigens immer
+möglich, jedoch oft nicht so einfach, wie in dem Beispiel der Ackermann-Funktion:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT PROC acker (INT CONST m, n):
+ IF m = 0
+ THEN n + 1
+ ELIF n = 0
+ THEN acker (m-1, 0)
+ ELSE acker (m - 1, acker (m, n - 1))
+ ENDIF
+ END PROC acker
+
+____________________________________________________________________________
+
+
+Das eigentliche Einsatzgebiet von rekursiven Algorithmen liegt aber bei den 'back­
+track'-Verfahren. Diese werden eingesetzt, wenn eine exakte algorithmische Lösung
+nicht bekannt ist oder nicht gefunden werden kann und man verschiedene Versuche
+machen muß, um zu einem Ziel (oder Lösung) zu gelangen.
+
diff --git a/doc/programming/programmierhandbuch.2b b/doc/programming/programmierhandbuch.2b
new file mode 100644
index 0000000..c2103ba
--- /dev/null
+++ b/doc/programming/programmierhandbuch.2b
@@ -0,0 +1,1395 @@
+#headandbottom("52","EUMEL-Benutzerhandbuch","TEIL 2 : ELAN","2")#
+#pagenr ("%", 52)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 2 : ELAN
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+2 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#2 - %
+#end#
+
+
+2.5 Programmstruktur
+
+Ein ELAN-Programm kann aus mehreren Moduln (Bausteinen) aufgebaut sein, die in
+ELAN PACKETs genannt werden. Das letzte PACKET wird "main packet" genannt,
+weil in diesem das eigentliche Benutzerprogramm (Hauptprogramm) enthalten ist.
+Dies soll eine Empfehlung sein, in welcher Reihenfolge die Elemente eines PACKETs
+geschrieben werden sollen:
+
+Ein "main packet" kann aus folgenden Elementen bestehen:
+
+a) Deklarationen und Anweisungen. Diese müssen nicht in einer bestimmten Reihen­
+ folge im Programm erscheinen, sondern es ist möglich, erst in dem Augenblick zu
+ deklarieren, wenn z.B. eine neue Variable benötigt wird. Es ist jedoch gute Pro­
+ grammierpraxis, die meisten Deklarationen an den Anfang eines Programms oder
+ Programmteils (Refinement, Prozedur) zu plazieren.
+
+ <Deklarationen> ;
+ <Anweisungen>
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR erste zahl, zweite zahl;
+
+ page;
+ put ("erste Zahl = "); get (erste zahl);
+ put ("zweite Zahl ="); get (zweite zahl)
+
+____________________________________________________________________________
+
+
+b) Deklarationen, Refinements und Anweisungen. In diesem Fall ist es notwendig, die
+ Refinements hintereinander zu plazieren. Refinement-Aufrufe und/oder
+ Anweisungen sollten textuell vorher erscheinen.
+
+ <Deklarationen> ;
+ <Refinement-Aufrufe und/oder Anweisungen> .
+ <Refinements>
+
+ Innerhalb der Refinements sind Anweisungen und/oder Deklarationen möglich.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR erste zahl, zweite zahl;
+
+ loesche bildschirm;
+ lies zwei zahlen ein.
+
+ loesche bildschirm:
+ page.
+
+ lies zwei zahlen ein:
+ put ("erste Zahl = "); get (erste zahl);
+ put ("zweite Zahl ="); get (zweite zahl).
+
+____________________________________________________________________________
+
+
+c) Deklarationen, Prozeduren und Anweisungen. Werden Prozeduren vereinbart,
+ sollte man sie nach den Deklarationen plazieren. Danach sollten die Anweisungen
+ folgen:
+
+ <Deklarationen> ;
+ <Prozeduren> ;
+ <Anweisungen>
+
+ Mehrere Prozeduren werden durch ";" voneinander getrennt. In diesem Fall sind
+ die Datenobjekte aus den Deklarationen außerhalb von Prozeduren statisch, d.h.
+ während der gesamten Laufzeit des Programm vorhanden. Solche Datenobjekte
+ werden auch PACKET-Daten genannt. Im Gegensatz dazu sind die Datenobjekte
+ aus Deklarationen in Prozeduren dynamische Datenobjekte, die nur während der
+ Bearbeitungszeit der Prozedur existieren. Innerhalb einer Prozedur dürfen wieder­
+ um Refinements verwendet werden. Ein Prozedur-Rumpf hat also den formalen
+ Aufbau wie unter a) oder b) geschildert.
+
+ Die Refinements und Datenobjekte, die innerhalb einer Prozedur deklariert wurden,
+ sind lokal zu dieser Prozedur, d.h. können von außerhalb nicht angesprochen
+ werden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR erste zahl, zweite zahl;
+
+ PROC vertausche (INT VAR a, b):
+ INT VAR x;
+
+ x := a;
+ a := b;
+ b := x
+ END PROC vertausche;
+
+ put ("erste Zahl = "); get (erste zahl);
+ put ("zweite Zahl ="); get (zweite zahl);
+ IF erste zahl > zweite zahl
+ THEN vertausche (erste zahl, zweite zahl)
+ FI
+
+____________________________________________________________________________
+
+
+d) Deklarationen, Prozeduren, Anweisungen und PACKET-Refinements. Zusätzlich
+ zu der Möglichkeit c) ist es erlaubt, neben den Anweisungen außerhalb einer
+ Prozedur auch Refinements zu verwenden:
+
+ <Deklarationen> ;
+ <Prozeduren> ;
+ <Anweisungen> .
+ <Refinements>
+
+ Diese Refinements können nun in Anweisungen außerhalb der Prozeduren benutzt
+ werden oder auch durch die Prozeduren (im letzteren Fall spricht man analog zu
+ globalen PACKET-Daten auch von PACKET-Refinements oder globalen Refine­
+ ments). In PACKET-Refinements dürfen natürlich keine Datenobjekte verwandt
+ werden, die lokal zu einer Prozedur sind.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR erste zahl, zweite zahl;
+
+ PROC vertausche (INT VAR a, b):
+ INT VAR x;
+
+ x := a;
+ a := b;
+ b := x
+ END PROC vertausche;
+
+ loesche bildschirm;
+ lies zwei zahlen ein;
+ ordne die zahlen.
+
+ loesche bildschirm:
+ page.
+
+ lies zwei zahlen ein:
+ put ("erste Zahl = "); get (erste zahl);
+ put ("zweite Zahl ="); get (zweite zahl).
+
+ ordne die zahlen:
+ IF erste zahl > zweite zahl
+ THEN vertausche (erste zahl, zweite zahl)
+ FI
+
+____________________________________________________________________________
+#page#
+
+2.6 Zusammengesetzte Datentypen
+
+In ELAN gibt es die Möglichkeit, gleichartige oder ungleichartige Datenobjekte zu
+einem Objekt zusammenzufassen.
+
+
+2.6.1 Reihung
+
+Die Zusammenfassung gleichartiger Datenobjekte, wird in ELAN eine Reihung (ROW)
+genannt. Die einzelnen Objekte einer Reihung werden Elemente genannt.
+
+Eine Reihung wird folgendermaßen deklariert:
+
+- Schlüsselwort #on("i")##on("b")#ROW#off("i")##off("b")#
+- Anzahl der zusammengefaßten Elemente
+ (INT-Denoter oder durch LET definierter Name)
+- Datentyp der Elemente
+- Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")# )
+- Name der Reihung.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ ROW 10 INT VAR feld
+
+____________________________________________________________________________
+
+
+Im obigen Beispiel wird eine Reihung von 10 INT-Elementen deklariert. ROW 10 INT
+ist ein (neuer, von den elementaren unterschiedlicher) Datentyp, für den keine Opera­
+tionen definiert sind, außer der Zuweisung. Das Accessrecht (VAR im obigen Bei­
+spiel) und der Name ('feld') gilt - wie bei den elementaren Datentypen - für diesen
+neuen Datentyp, also für alle 10 Elemente.
+
+Warum gibt es keine Operationen außer der Zuweisung? Das wird sehr schnell
+einsichtig, wenn man bedenkt, daß es ja sehr viele Datentypen (zusätzlich zu den
+elementaren) gibt, weil Reihungen von jedem Datentyp gebildet werden können:
+
+
+ROW 1 INT ROW 1 REAL
+ROW 2 INT ROW 2 REAL
+ : :
+ROW maxint INT ROW maxint REAL
+
+ROW 1 TEXT ROW 1 BOOL
+ROW 2 TEXT ROW 2 BOOL
+ : :
+ROW maxint TEXT ROW maxint BOOL
+
+
+Für die elementaren INT-, REAL-, BOOL- und TEXT-Datentypen sind unter­
+schiedliche Operationen definiert. Man müßte nun für jeden dieser zusammengesetz­
+ten Datentypen z.B. auch 'get'- und 'put'-Prozeduren schreiben, was allein vom
+Schreibaufwand sehr aufwendig wäre. Das ist der Grund dafür, daß es keine vorgege­
+bene Operationen auf zusammengesetzte Datentypen gibt.
+
+Zugegebenermaßen könnte man mit solchen Datentypen, die nur über eine Operation
+verfügen (Zuweisung), nicht sehr viel anfangen, wenn es nicht eine weitere vorgege­
+bene Operation gäbe, die Subskription. Sie erlaubt es, auf die Elemente einer Reih­
+ung zuzugreifen und den Datentyp der Elemente "aufzudecken".
+
+Form:
+
+Rowname #on("i")##on("b")#[#off("i")##off("b")# Indexwert #on("i")##on("b")#]#off("i")##off("b")#
+
+Beispiel:
+
+
+feld [3]
+
+
+bezieht sich auf das dritte Element der Reihung 'feld' und hat den Datentyp INT. Für
+INT-Objekte haben wir aber einige Operationen, mit denen wir arbeiten können.
+
+____________________________________________________________________________
+ ........................... Beispiele: ........................
+ feld [3] := 7;
+ feld [4] := feld [3] + 4;
+
+____________________________________________________________________________
+
+
+Eine Subskription "schält" also vom Datentyp ein ROW ab und liefert ein Element der
+Reihung. Die Angabe der Nummer des Elements in der Reihung nennt man Subskript
+oder Index (in obigem Beispiel '3'). Der Subskript wird in ELAN in eckigen Klammern
+angegeben, um eine bessere Unterscheidung zu den runden Klammern in Ausdrücken
+zu erreichen. Ein subskribiertes ROW-Datenobjekt kann also überall da verwendet
+werden, wo ein entsprechender Datentyp benötigt wird (Ausnahme: nicht als Schlei­
+fenvariable).
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC get (ROW 10 INT VAR feld):
+ INT VAR i;
+ FOR i FROM 1 UPTO 10 REP
+ put (i); put ("tes Element bitte:");
+ get (feld [i]);
+ line
+ END REP
+ END PROC get;
+
+ PROC put (ROW 10 INT CONST feld):
+ INT VAR i;
+ FOR i FROM 1 UPTO 10 REP
+ put (i); put ("tes Element ist:");
+ put (feld [i]);
+ line
+ END REP
+ END PROC put
+
+____________________________________________________________________________
+
+
+In diesen Beispielen werden Reihungen als Parameter benutzt.
+
+Diese beiden Prozeduren werden im folgenden Beispiel benutzt um 10 Werte einzu­
+lesen und die Summe zu berechnen:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ ROW 10 INT VAR werte;
+ lies werte ein;
+ summiere sie;
+ drucke die summe und einzelwerte.
+
+ lies werte ein:
+ get (werte).
+
+ summiere sie:
+ INT VAR summe :: 0, i;
+ FOR i FROM 1 UPTO 10 REP
+ summe INCR werte [i]
+ END REP.
+
+ drucke die summe und einzelwerte:
+ put (werte);
+ line;
+ put ("Summe:"); put (summe).
+
+____________________________________________________________________________
+
+
+Da es möglich ist, von jedem Datentyp eine Reihung zu bilden, kann man natürlich
+auch von einer Reihung eine Reihung bilden:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ ROW 5 ROW 10 INT VAR matrix
+
+____________________________________________________________________________
+
+
+Für eine "doppelte" Reihung gilt das für "einfache" Reihungen gesagte. Wiederum
+existieren keine Operationen für dieses Datenobjekt (außer der Zuweisung), jedoch ist
+es durch Subskription möglich, auf die Elemente zuzugreifen:
+
+
+matrix [3]
+
+
+liefert ein Datenobjekt mit dem Datentyp ROW 10 INT.
+
+Subskribiert man jedoch 'matrix' nochmals, so erhält man ein INT:
+
+
+matrix [2] [8]
+
+
+(jede Subskription "schält" von Außen ein ROW vom Datentyp ab).
+#page#
+
+2.6.2 Struktur
+
+Strukturen sind Datenverbunde wie Reihungen, aber die Komponenten können unglei­
+chartige Datentypen haben. Die Komponenten von Strukturen heißen Felder (Reihun­
+gen: Elemente) und der Zugriff auf ein Feld Selektion (Reihungen: Subskription). Eine
+Struktur ist - genauso wie bei Reihungen - ein eigener Datentyp, der in einer
+Deklaration angegeben werden muß.
+
+Die Deklaration einer Struktur sieht folgendermaßen aus:
+
+- Schlüsselwort #schl ("STRUCT#off("i")##off("b")#
+- unterschiedliche Datenobjekte in Klammern. Die Datenobjekte werden mit Datentyp und Namen angegeben
+- Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")# )
+- Name der Struktur.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ STRUCT (TEXT name, INT alter) VAR ich
+
+____________________________________________________________________________
+
+
+Wiederum existieren keine Operationen auf Strukturen außer der Zuweisung und der
+Selektion, die es erlaubt, Komponenten aus einer Struktur herauszulösen.
+
+Die Selektion hat folgende Form:
+
+Objektname #on("i")##on("b")#.#off("i")##off("b")# Feldname
+
+Beispiele:
+
+
+ich . name
+ich . alter
+
+
+Die erste Selektion liefert einen TEXT-, die zweite ein INT-Datenobjekt. Mit diesen
+(selektierten) Datenobjekten kann - wie gewohnt - gearbeitet werden (Ausnahme:
+nicht als Schleifenvariable).
+
+Zum Datentyp einer Struktur gehören auch die Feldnamen:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ STRUCT (TEXT produkt name, INT artikel nr) VAR erzeugnis
+
+____________________________________________________________________________
+
+
+Die obige Struktur ist ein anderer Datentyp als im ersten Beispiel dieses Abschnitts,
+da die Namen der Felder zur Unterscheidung hinzugezogen werden. Für Strukturen -
+genauso wie bei Reihungen - kann man sich neue Operationen definieren.
+
+Im folgenden Programm werden eine Struktur, die Personen beschreibt, die Prozedu­
+ren 'put', 'get' und der dyadische Operator HEIRATET definiert. Anschließend werden
+drei Paare verHEIRATET.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC get (STRUCT (TEXT name, vorname, INT alter) VAR p):
+ put ("bitte Nachname:"); get ( p.name);
+ put ("bitte Vorname:"); get ( p.vorname);
+ put ("bitte Alter:"); get ( p.alter);
+ line
+ END PROC get;
+
+ PROC put (STRUCT (TEXT name, vorname, INT alter) CONST p):
+ put (p.vorname); put (p.name);
+ put ("ist");
+ put (p.alter);
+ put ("Jahre alt");
+ line
+ END PROC put;
+
+ OP HEIRATET
+ (STRUCT (TEXT name, vorname, INT alter) VAR w,
+ STRUCT (TEXT name, vorname, INT alter) CONST m):
+ w.name := m.name
+ END OP HEIRATET;
+
+____________________________________________________________________________
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ ROW 3 STRUCT (TEXT name, vorname, INT alter) VAR frau,
+ mann;
+
+ personendaten einlesen;
+ heiraten lassen;
+ paardaten ausgeben.
+
+ personendaten einlesen:
+ INT VAR i;
+ FOR i FROM 1 UPTO 3 REP
+ get (frau [i]);
+ get (mann [i])
+ END REP.
+
+ heiraten lassen:
+ FOR i FROM 1 UPTO 3 REP
+ frau [i] HEIRATET mann [i]
+ END REP.
+
+ paardaten ausgeben:
+ FOR i FROM 1 UPTO 3 REP
+ put (frau [i]);
+ put ("hat geheiratet:"); line;
+ put (mann [i]); line
+ END REP.
+
+____________________________________________________________________________
+
+
+Reihungen und Strukturen dürfen miteinander kombiniert werden, d.h. es darf eine
+Reihung in einer Struktur erscheinen oder es darf eine Reihung von einer Struktur
+vorgenommen werden. Selektion und Subskription sind in diesen Fällen in der Reihen­
+folge vorzunehmen, wie die Datentypen aufgebaut wurden (von außen nach innen).
+#page#
+
+2.6.3 LET-Konstrukt für zusammengesetzte Datentypen
+
+
+Die Verwendung von Strukturen oder auch Reihungen kann manchmal schreibauf­
+wendig sein. Mit dem LET-Konstrukt darf man Datentypen einen Namen geben.
+Dieser Name steht als Abkürzung und verringert so die Schreibarbeit. Zusätzlich wird
+durch die Namensgebung die Lesbarkeit des Programms erhöht.
+
+Form:
+
+#on("i")##on("b")#LET#off("i")##off("b")# Name #on("i")##on("b")#=#off("i")##off("b")# Datentyp
+
+Der Name darf nur aus Großbuchstaben (ohne Blanks) bestehen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ LET PERSON = STRUCT (TEXT name, vorname, INT alter);
+
+ PROC get (PERSON VAR p):
+ put ("bitte Nachname:"); get ( p.name);
+ put ("bitte Vorname:"); get ( p.vorname);
+ put ("bitte Alter:"); get ( p.alter);
+ line
+ END PROC get;
+
+ PROC put (PERSON CONST p):
+ put (p.vorname); put (p.name); put ("ist");
+ put (p.alter); put ("Jahre alt"); line
+ END PROC put;
+
+ OP HEIRATET (PERSON VAR f, PERSON CONST m):
+ f.name := m.name
+ END OP HEIRATET;
+
+ ROW 3 PERSON VAR mann, frau;
+
+____________________________________________________________________________
+
+
+Überall, wo der abzukürzende Datentyp verwandt wird, kann stattdessen der Name
+PERSON benutzt werden. Wohlgemerkt: PERSON ist kein neuer Datentyp, sondern
+nur ein Name, der für STRUCT (....) steht. Der Zugriff auf die Komponenten des
+abgekürzten Datentyps bleibt erhalten (was bei abstrakten Datentypen, die später
+erklärt werden, nicht mehr der Fall ist).
+
+Neben der Funktion der Abkürzung von Datentypen kann das LET-Konstrukt auch
+zur Namensgebung für Denoter verwandt werden (siehe 2.3.1.2).
+
+
+
+2.6.4 Denoter für zusammengesetzte
+ Datentypen (Konstruktor)
+
+
+Oft ist es notwendig, Datenverbunden Werte zuzuweisen (z.B.: bei der Initialisierung).
+Dies kann durch normale Zuweisungen erfolgen:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ LET PERSON = STRUCT (TEXT name, vorname, INT alter);
+
+ PERSON VAR mann;
+
+ mann.name := "meier";
+ mann.vorname := "egon";
+ mann.alter := 27
+
+____________________________________________________________________________
+
+
+Eine andere Möglichkeit für die Wertbesetzung von Datenverbunden ist der Konstruk­
+tor:
+
+Form:
+
+Datentyp #on("i")##on("b")#:#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Wertliste #on("i")##on("b")#)#off("i")##off("b")#
+
+In der Wertliste wird für jede Komponente des Datentyps, durch Kommata getrennt,
+ein Wert aufgeführt. Besteht eine der Komponenten wiederum aus einem Datenver­
+bund, muß innerhalb des Konstruktors wiederum ein Konstruktor eingesetzt werden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ LET PERSON = STRUCT (TEXT name, vorname, INT alter);
+
+ PERSON VAR mann, frau;
+
+ frau := PERSON : ( "niemeyer", "einfalt", 65);
+ frau HEIRATET PERSON : ( "meier", "egon", 27)
+
+____________________________________________________________________________
+
+
+Ein Konstruktor ist also ein Mechanismus, um ein Datenobjekt eines Datenverbundes
+in einem Programm zu notieren.
+
+Konstruktoren sind natürlich für Reihungen auch möglich:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ ROW 7 INT VAR feld;
+ feld := ROW 7 INT : ( 1, 2, 3, 4, 5, 6, 7);
+____________________________________________________________________________
+#page#
+
+2.7 Abstrakte Datentypen
+
+
+2.7.1 Definition neuer Datentypen
+
+Im Gegensatz zur LET-Vereinbarung für Datentypen, bei der lediglich ein neuer
+Name für einen bereits vorhandenen Datentyp eingeführt wird und bei der somit auch
+keine neuen Operationen definiert werden müssen (weil die Operationen für den
+abzukürzenden Datentyp verwandt werden können), wird durch eine TYPE-Verein­
+barung ein gänzlich neuer Datentyp eingeführt.
+
+Form:
+
+#on("i")##on("b")#TYPE#off("i")##off("b")# Name #on("i")##on("b")#=#off("i")##off("b")# Feinstruktur
+
+Der Name darf nur aus Großbuchstaben (ohne Blanks) bestehen. Die Feinstruktur
+(konkreter Typ, Realisierung des Datentyps) kann jeder bereits definierte Datentyp
+sein.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TYPE PERSON = STRUCT (TEXT name, vorname, INT alter)
+
+____________________________________________________________________________
+
+
+Der neudefinierte Datentyp wird abstrakter Datentyp genannt. Im Gegensatz zu
+Strukturen und Reihungen stehen für solche Datentypen noch nicht einmal die Zuwei­
+sung zur Verfügung. Ein solcher Datentyp kann genau wie alle anderen Datentypen
+verwendet werden (Deklarationen, Parameter, wertliefernde Prozeduren, als Kompo­
+nenten in Reihungen und Strukturen usw.).
+
+Wird der Datentyp über die Schnittstelle des PACKETs anderen Programmteilen zur
+Verfügung gestellt, so müssen Operatoren und/oder Prozeduren für den Datentyp
+ebenfalls "herausgereicht" werden. Da dann der neudefinierte Datentyp genauso wie
+alle anderen Datentypen verwandt werden kann, aber die Komponenten (Feinstruktur)
+nicht zugänglich sind, spricht man von abstrakten Datentypen.
+
+Welche Operationen sollten für einen abstrakten Datentyp zur Verfügung stehen?
+Obwohl das vom Einzelfall abhängt, werden meistens folgende Operationen und
+Prozeduren definiert:
+
+- 'get'- und 'put'-Prozeduren.
+- Zuweisung (auch für die Initialisierung notwendig).
+- Denotierungs-Prozedur (weil kein Konstruktor für den abstrakten Datentyp außer­
+ halb des definierenden PACKETs zur Verfügung steht)
+
+
+
+2.7.2 Konkretisierung
+
+Um neue Operatoren und/oder Prozeduren für einen abstrakten Datentyp zu schrei­
+ben, ist es möglich, auf die Komponenten des Datentyps (also auf die Feinstruktur)
+mit Hilfe des Konkretisierers zuzugreifen. Der Konkretisierer arbeitet ähnlich wie die
+Subskription oder Selektion: er ermöglicht eine typmäßige Umbetrachtung vom ab­
+strakten Typ zum Datentyp der Feinstruktur.
+
+Form:
+
+#on("i")##on("b")#CONCR#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Ausdruck #on("i")##on("b")#)#off("i")##off("b")#
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TYPE MONAT = INT;
+
+ PROC put (MONAT CONST m):
+ put ( CONCR (m))
+ END PROC put;
+
+____________________________________________________________________________
+
+
+Der Konkretisierer ist bei Feinstrukturen notwendig, die von elementarem Datentyp
+sind. Besteht dagegen die Feinstruktur aus Reihungen oder Strukturen, dann wird
+durch eine Selektion oder Subskription eine implizite Konkretisierung vorgenommen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TYPE LISTE = ROW 100 INT;
+
+ LISTE VAR personal nummer;
+ ...
+ personal nummer [3] := ...
+ (* das gleiche wie *)
+ CONCR (personal nummer) [3] := ...
+
+____________________________________________________________________________
+
+
+2.7.3 Denoter für abstrakte
+ Datentypen (Konstruktor)
+
+
+Denoter für neudefinierte Datentypen werden mit Hilfe des Konstruktors gebildet:
+
+Form:
+
+Datentyp #on("i")##on("b")#:#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Wertliste #on("i")##on("b")#)#off("i")##off("b")#
+
+In der Wertliste wird für jede Komponente des Datentyps, durch Kommata getrennt,
+ein Wert aufgeführt. Besteht eine der Komponenten wiederum aus einem Datenver­
+bund, muß innerhalb des Konstruktors wiederum ein Konstruktor eingesetzt werden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TYPE GEHALT = INT;
+
+ GEHALT VAR meins :: GEHALT : (10000);
+
+____________________________________________________________________________
+
+
+Besteht die Feinstruktur aus einem Datenverbund, muß der Konstruktor u.U. mehrfach
+geschachtelt angewandt werden:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TYPE KOMPLEX = ROW 2 REAL;
+
+ KOMPLEX CONST x :: KOMPLEX : ( ROW 2 REAL : ( 1.0, 2.0));
+
+____________________________________________________________________________
+
+
+Auf die Feinstruktur über den Konkretisierer eines neudefinierten Datentyps darf nur in
+dem PACKET zugegriffen werden, in dem der Datentyp definiert wurde. Der Konstruk­
+tor kann ebenfalls nur in dem typdefinierenden PACKET verwandt werden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PACKET widerstaende DEFINES WIDERSTAND, REIHE, PARALLEL,
+ :=, get, put:
+
+ TYPE WIDERSTAND = INT;
+
+ OP := (WIDERSTAND VAR l, WIDERSTAND CONST r):
+ CONCR (l) := CONCR (r)
+ END OP :=;
+
+ PROC get (WIDERSTAND VAR w):
+ INT VAR i;
+ get (i);
+ w := WIDERSTAND : (i)
+ END PROC get;
+
+ PROC put (WIDERSTAND CONST w):
+ put (CONCR (w))
+ END PROC put;
+
+ WIDERSTAND OP REIHE (WIDERSTAND CONST l, r):
+ WIDERSTAND : ( CONCR (l) + CONCR (r))
+ END OP REIHE;
+
+ WIDERSTAND OP PARALLEL (WIDERSTAND CONST l, r):
+ WIDERSTAND :
+ ((CONCR (l) * CONCR (r)) DIV (CONCR (l) + CONCR (r)))
+ END OP PARALLEL
+
+ END PACKET widerstaende
+
+____________________________________________________________________________
+
+
+Dieses Programm realisiert den Datentyp WIDERSTAND und mit den Operationen
+eine Fachsprache, mit dem man nun leicht WIDERSTANDs-Netzwerke berechnen
+kann, wie z.B. folgendes:
+
+
+
+ +---R4---+
+ | |
+ +---R1---+ +---R5---+
+ | | | |
+ ---+ +---R3---+ +---
+ | | | |
+ +---R2---+ +---R6---+
+ | |
+ +---R7---+
+
+
+Zur Berechnung des Gesamtwiderstandes kann nun folgendes Programm geschrieben
+werden:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ ROW 7 WIDERSTAND VAR r;
+ widerstaende einlesen;
+ gesamtwiderstand berechnen;
+ ergebnis ausgeben.
+
+ widerstaende einlesen:
+ INT VAR i;
+ FOR i FROM 1 UPTO 7 REP
+ put ("bitte widerstand R"); put (i); put (":");
+ get (r [i]);
+ END REP.
+
+ gesamtwiderstand berechnen:
+ WIDERSTAND CONST rgesamt :: (r [1] PARALLEL r [2]) REIHE
+ r [3] REIHE (r [4] PARALLEL r [5] PARALLEL r [6]
+ PARALLEL r [7]).
+
+ ergebnis ausgeben:
+ line;
+ put (rgesamt).
+____________________________________________________________________________
+#page#
+
+2.8 Dateien
+
+Dateien werden benötigt, wenn
+
+- Daten über die Abarbeitungszeit eines Programms aufbewahrt werden sollen;
+- der Zeitpunkt oder Ort der Datenerfassung nicht mit dem Zeitpunkt oder Ort der
+ Datenverarbeitung übereinstimmt;
+- die gesamte Datenmenge nicht auf einmal in den Zentralspeicher eines Rechners
+ paßt;
+- die Anzahl und/oder Art der Daten nicht von vornherein bekannt sind.
+
+Eine Datei ("file") ist eine Zusammenfassung von Daten, die auf Massenspeichern
+aufbewahrt wird. Dateien sind in bestimmten Informationsmengen, den Sätzen ("re­
+cords") organisiert.
+
+
+
+2.8.1 Datentypen FILE und DIRFILE
+
+In ELAN gibt es zwei Arten von Dateien. Sie werden durch die Datentypen FILE
+und DIRFILE realisiert:
+
+
+
+FILE:
+sequentielle Dateien. Die Sätze können nur sequentiell gelesen bzw. geschrieben
+werden. Eine Positionierung ist nur zum nächsten Satz möglich.
+
+
+DIRFILE:
+indexsequentielle Dateien. Die Positionierung erfolgt direkt mit Hilfe eines Schlüssels
+("key") oder Index, kann aber auch sequentiell vorgenommen werden.
+
+#on("b")#Wichtig: #off("b")#
+DIRFILEs sind auf dem EUMEL-System standardmäßig nicht implementiert! Deswe­
+gen wird auf diesen Dateityp hier nicht weiter eingegangen.
+#page#
+
+2.8.2 Deklaration und Assoziierung
+
+Dateien müssen in einem ELAN-Programm - wie alle anderen Objekte auch -
+deklariert werden.
+
+Form:
+
+#on("i")##on("b")#FILE#off("i")##off("b")# #on("i")##on("b")#VAR#off("i")##off("b")# interner Dateibezeichner
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ FILE VAR f
+
+____________________________________________________________________________
+
+
+Dabei ist zu beachten, daß im EUMEL-System alle FILEs als VAR deklariert werden
+müssen, denn jede Lese/Schreib-Operation verändert einen FILE.
+
+Dateien werden normalerweise vom Betriebsystem eines Rechners aufbewahrt und
+verwaltet. Somit ist eine Verbindung von einem ELAN-Programm, in dem eine Datei
+unter einem Namen - wie jedes andere Datenobjekt auch - angesprochen werden
+soll, und dem Betriebssystem notwendig. Dies erfolgt durch die sogenannte Assozi­
+ierungsprozedur. Die Assoziierungsprozedur 'sequential file' hat die Aufgabe, eine in
+einem Programm deklarierte FILE VAR mit einer bereits vorhandenen oder noch
+einzurichtenden Datei des EUMEL-Systems zu koppeln.
+
+Form:
+
+#on("i")##on("b")#sequential file#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Betriebsrichtung, Dateiname #on("i")##on("b")#)#off("i")##off("b")#
+
+Es gibt folgende Betriebsrichtungen (TRANSPUTDIRECTIONs):
+
+
+input:
+Die Datei kann vom Programm nur gelesen werden. Durch 'input' wird bei der Asso­
+ziierung automatisch auf den ersten Satz der Datei positioniert. Ist die zu lesende
+Datei nicht vorhanden, wird ein Fehler gemeldet.
+
+
+output:
+Die Datei kann vom Programm nur beschrieben werden. Durch 'output' wird bei der
+Assoziierung automatisch hinter den letzten Satz der Datei positioniert (bei einer
+leeren Datei also auf den ersten Satz). Ist die Datei vor der Assoziierung nicht vor­
+handen, wird sie automatisch eingerichtet.
+
+
+modify:
+Im EUMEL-System gibt es noch die Betriebsrichtung 'modify'.
+Die Datei kann vom Programm in beliebiger Weise gelesen und beschrieben werden.
+Im Gegensatz zu den Betriebsrichtungen 'input' und 'output', bei denen ausschließlich
+ein rein sequentielles Lesen oder Schreiben erlaubt ist, kann bei 'modify' beliebig
+positioniert, gelöscht, eingefügt und neu geschrieben werden.
+
+Nach erfolgter Assoziiierung ist auf den zuletzt bearbeiteten Satz positioniert. Die
+Datei wird automatisch eingerichtet, wenn sie vor der Assoziierung nicht vorhanden
+war.
+
+Der zweite Parameter der Assoziierungsprozedur gibt an, unter welchem Namen die
+Datei in der Task existiert oder eingerichtet werden soll.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ FILE VAR meine datei :: sequential file (output, "xyz");
+
+____________________________________________________________________________
+
+
+Folgendes Beispiel zeigt ein Programm, welches eine Datei liest und auf dem Ausga­
+bemedium ausgibt:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ FILE VAR f :: sequential file (input, "datei1");
+ TEXT VAR satz;
+ WHILE NOT eof (f) REP
+ getline (f, satz);
+ putline (satz);
+ END REP.
+
+____________________________________________________________________________
+
+
+Eine genau Übersicht der für Dateien existierende Operatoren und Prozeduren finden
+Sie im Teil 5.3.
+#page#
+
+2.9 Abstrakte Datentypen
+ im EUMEL-System
+
+
+
+2.9.1 Datentyp TASK
+
+Tasks müssen im Rechnersystem eindeutig identifiziert werden; sogar im EUMEL-
+Rechner-Netz sind Tasks eindeutig identifizierbar. Dazu wird der spezielle Datentyp
+'TASK' benutzt, denn die Identifizierung einer Task über den Namen ist nicht eindeu­
+tig. Der Benutzer kann ja einen Tasknamen ändern, eine Task löschen und eine
+neue Task mit gleichem Namen einrichten, die jedoch nicht gleich reagiert. Somit
+werden Tasks eindeutig über Variablen vom Datentyp TASK identifiziert.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TASK VAR plotter := task ("PLOTTER 1")
+
+____________________________________________________________________________
+
+
+Die Taskvariable 'plotter' bezeichnet jetzt die Task im System, die augenblicklich den
+Namen "PLOTTER 1" hat. Die Prozedur 'task' liefert den systeminternen Taskbe­
+zeichner.
+
+Nun sind Taskvariablen auch unter Berücksichtigung der Zeit und nicht nur im aktuel­
+len Systemzustand eindeutig. Der Programmierer braucht sich also keine Sorgen
+darüber zu machen, daß seine Taskvariable irgendwann einmal eine "falsche" Task
+(nach Löschen von "PLOTTER 1" neu eingerichtete gleichen oder anderen Namens)
+identifiziert. Wenn die Task "PLOTTER 1" gelöscht worden ist, bezeichnet 'plotter'
+keine gültige Task mehr.
+
+Unbenannte Tasks haben alle den Pseudonamen "-". Sie können nur über Taskvari­
+ablen angesprochen werden.
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC generate shutup manager:
+ TASK VAR son;
+ begin ("shutup", PROC shutup manager, son)
+ END PROC generate shutup manager;
+
+ PROC shutup manager:
+ disable stop;
+ command dialogue (TRUE);
+ REP
+ break;
+ line;
+ IF yes ("shutup")
+ THEN clear error;
+ shutup
+ FI
+ PER
+ END PROC shutup manager
+
+____________________________________________________________________________
+
+
+Ein Taskvariable wird zum Beispiel als Parameter für die Prozedur 'begin' benötigt.
+
+begin
+ #on("b")#PROC begin (TEXT CONST son name, PROC start,
+ TASK VAR new task)#off("b")#
+ Die Prozedur richtet eine Sohntask mit Namen 'son name' (im Beispiel: shutup)
+ ein, die mit der Prozedur 'start' (im Beispiel: shutup manager) gestartet wird. 'new
+ task' (im Beispiel: son) identifiziert den Sohn, falls die Sohntask korrekt eingerich­
+ tet wurde.
+#page#
+
+2.9.2 Datentyp THESAURUS
+
+Ein Thesaurus ist ein Namensverzeichnis, das bis zu 200 Namen beinhalten kann.
+Dabei muß jeder Name mindestens ein Zeichen und höchstens 100 Zeichen lang sein.
+Steuerzeichen (code < 32) werden im Namen folgendermaßen umgesetzt:
+
+#on("i")##on("b")#steuerzeichen#off("b")##off("i")# wird umgesetzt in #on("i")##on("b")#"""" + code(steuerzeichen) + """"#off("b")##off("i")#
+
+Ein Thesaurus ordnet jedem eingetragenen Namen einen Index zwischen 1 und 200
+(einschließlich) zu. Diese Indizes bieten dem Anwender die Möglichkeit, Thesauri zur
+Verwaltung benannter Objekte zu verwenden. (Der Zugriff erfolgt dann über den Index
+eines Namens in einem Thesaurus). So werden Thesauri u.a. von der Dateiverwaltung
+benutzt. Sie bilden die Grundlage der ALL- und SOME-Operatoren.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ initialisiere;
+ arbeite thesaurus ab.
+
+ initialisiere:
+ THESAURUS VAR eine auswahl :: SOME (myself);
+ TEXT VAR thesaurus element;
+ INT VAR index :: 0.
+
+ arbeite thesaurus ab:
+ REPEAT
+ get (eine auswahl, thesaurus element, index);
+ IF thesaurus element = ""
+ THEN LEAVE arbeite thesaurus ab
+ FI;
+ fuehre aktionen durch
+ PER.
+
+ fuehre aktionen durch:
+ edit (thesaurus element);
+ lineform (thesaurus element);
+ pageform (thesaurus element);
+ print (thesaurus element).
+
+____________________________________________________________________________
+
+
+Dieses Beispiel führt für eine Auswahl der in der Task befindlichen Dateien nachein­
+ander die Kommandos 'edit', 'lineform', 'pageform' und 'print' aus.
+
+Die benutzten Operatoren und Prozeduren leisten folgendes:
+
+#ix("SOME")#
+ #on("b")#THESAURUS OP SOME (TASK CONST task) #off("b")#
+ Der Operator bietet das Verzeichnis der in der angegeben Task befindlichen
+ Dateien zum Editieren an. Namen, die nicht gewünscht sind, müssen aus dem
+ Verzeichnis gelöscht werden.
+
+
+#ix("get")#
+ #on("b")#PROC get (THESAURUS CONST t, TEXT VAR name, INT VAR index)
+ #off("b")# Die Prozedur liefert den nächsten Eintrag aus dem angegebenen Thesaurus 't'.
+ 'Nächster' heißt hier, der kleinste vorhandene mit einem Index größer als 'index'.
+ Dabei wird in 'name'der Name und in 'index'der Index des Eintrags geliefert.
+#page#
+
+2.9.3 Datenräume
+
+Datenräume sind die Grundlage von Dateien im EUMEL-System. Einen Datenraum
+kann man sich als eine Sammlung von Daten vorstellen (u.U. leer). Man kann einem
+Datenraum durch ein Programm einen Datentyp "aufprägen". Nach einem solchen
+"Aufpräge"-Vorgang kann der Datenraum wie ein "normaler" Datentyp behandelt
+werden.
+
+Standarddateien (FILEs) sind eine besondere Form von Datenräumen. Sie können nur
+Texte aufnehmen, da sie ja hauptsächlich für die Kommunikation mit dem Menschen
+(vorwiegend mit Hilfe des Editors bzw. Ein-/ Ausgabe) gedacht sind. Will man Zahlen
+in einen FILE ausgeben, so müssen diese zuvor in Texte umgewandelt werden. Hier­
+für stehen Standardprozeduren zur Verfügung (z.B. 'put (f, 17)').
+
+Will man aber Dateien zur Kommunikation zwischen Programmen verwenden, die
+große Zahlenmengen austauschen, verursachen die Umwandlungen von Zahlen in
+TEXTe und umgekehrt unnötigen Rechenaufwand. Zu diesem Zweck werden im
+EUMEL-System Datenräume eingesetzt, die es gestatten, beliebige Strukturen
+(Typen) in Dateien zu speichern. Solche Datenräume kann man weder mit dem Editor
+noch mit dem Standarddruckprogramm (print) bearbeiten, da diese ja den Typ des in
+dem Datenraum gespeicherten Objektes nicht kennen.
+
+
+
+2.9.3.1 Datentyp DATASPACE
+
+Datenräume können als eigener Datentyp (DATASPACE) in einem Programm behan­
+delt werden. Somit können Datenräume (als Ganzes) ohne Kenntnis eines eventuell
+(vorher oder später) aufgeprägten Typs benutzt werden.
+
+Als Operationen auf DATASPACE-Objekte sind nur Transporte, Löschen und Zuwei­
+sung zugelassen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ DATASPACE VAR ds
+
+____________________________________________________________________________
+
+
+Für Datenräume ist die Zuweisung definiert. Der Zuweisungsoperator (':=') bewirkt
+eine Kopie des Datenraums vom rechten auf den linken Operanden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ DATASPACE VAR datenraum :: nilspace;
+
+____________________________________________________________________________
+
+
+Die Prozedur 'nilspace' liefert einen leeren Datenraum. Der Datenraum 'datenraum' ist
+also eine Kopie des leeren Datenraums.
+
+Die Prozeduren und Operatoren für Datenräume werden im Teil 5.4.7 beschrieben.
+#page#
+
+2.9.3.2 BOUND-Objekte
+
+Wie bereits erwähnt, kann man einem Datenraum einen Datentyp aufprägen. Dazu
+werden #ib#BOUND#ie#-Objekte benutzt. Mit dem Schlüsselwort #on("i")##on("b")#BOUND#off("i")##off("b")#, welches in der
+Deklaration vor den Datentyp gestellt wird, teilt man dem ELAN-Compiler mit, daß
+die Werte eines Datentyps in einem Datenraum gespeichert sind bzw. gespeichert
+werden sollen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ BOUND ROW 1000 REAL VAR liste
+
+____________________________________________________________________________
+
+
+Die Ankopplung des BOUND-Objekts an eine Datei erfolgt mit dem Operator #on("i")##on("b")#:=#off("i")##off("b")#.
+
+Form:
+
+BOUND-Objekt #on("i")##on("b")#:=#off("i")##off("b")# Datenraum
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ BOUND ROW 1000 REAL VAR gehaltsliste := new ("Gehälter")
+
+____________________________________________________________________________
+
+
+Die Prozedur 'new' kreiert dabei einen leeren Datenraum (hier mit dem Namen 'Ge­
+hälter'), der mit Hilfe der Zuweisung (hier: Initialisierung) an die Variable 'gehaltsliste'
+gekoppelt wird.
+
+Nun kann man mit der 'gehaltsliste' arbeiten wie mit allen anderen Feldern auch. Die
+Daten, die in 'gehaltsliste' gespeichert, werden eigentlich im Datenraum 'Gehälter'
+abgelegt.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ gehaltsliste [5] := 10 000.0; (* Traumgehalt *)
+ gehaltsliste [index] INCR 200.0; (* usw. *)
+
+____________________________________________________________________________
+
+
+Man kann auch Prozeduren schreiben, die auf der Gehaltsliste arbeiten.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC sort (ROW 1000 REAL VAR liste):
+ ...
+ END PROC sort;
+ ...
+ sort (CONCR (gehaltsliste));
+ ...
+
+____________________________________________________________________________
+
+
+Man beachte, daß der formale Parameter der Prozedur 'sort' nicht mit BOUND spezi­
+fiziert werden darf (BOUND wird nur bei der Deklaration des Objekts angegeben). Das
+ist übrigens ein weiterer wichtiger Vorteil von BOUND-Objekten: man kann alle
+Prozeduren des EUMEL-Systems auch für BOUND-Objekte verwenden, nur die
+Datentypen müssen natürlich übereinstimmen.
+
+
+Häufige Fehler bei der Benutzung von Datenräumen
+
+- Wenn man an ein DATASPACE-Objekt zuweist (z.B.: DATASPACE VAR ds :=
+ new ("mein datenraum")), so erhält man, wie bereits erwähnt, eine Kopie des
+ Datenraums in 'ds'. Koppelt man jetzt 'ds' an ein BOUND-Objekt an und führt
+ Änderungen durch, so wirken diese nur auf die Kopie und nicht auf die Quelle.
+ Für Änderungen in der Quelle, also in der vom Datei-Manager verwalteten Datei,
+ ist stets direkt anzukoppeln.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ BOUND ROW 10 INT VAR reihe;
+ INT VAR i;
+
+ PROC zeige dsinhalt (TEXT CONST datenraum):
+ BOUND ROW 10 INT VAR inhalt := old (datenraum);
+ INT VAR j;
+ line;
+ putline ("Inhalt:" + datenraum);
+ FOR j FROM 1 UPTO 10 REP
+ put (inhalt (j))
+ PER
+ END PROC zeige dsinhalt;
+
+ (* falsch: es wird auf der Kopie gearbeitet: *)
+ DATASPACE VAR ds := new ("Gegenbeispiel: Zahlen 1 bis 10");
+ reihe := ds;
+ besetze reihe;
+ zeige dsinhalt ("Gegenbeispiel: Zahlen 1 bis 10");
+
+ (* richtig: es wird auf dem Datenraum gearbeitet: *)
+ reihe := new ("Beispiel: Zahlen 1 bis 10");
+ besetze reihe;
+ zeige dsinhalt ("Beispiel: Zahlen 1 bis 10").
+
+ besetze reihe:
+ FOR i FROM 1 UPTO 10 REP
+ reihe (i) := i
+ PER.
+
+____________________________________________________________________________
+
+
+ Der Datenraum 'Gegenbeispiel: Zahlen 1 bis 10' wird nicht mit Werten besetzt,
+ sondern die Kopie dieses Datenraums, der unbenannte Datenraum 'ds'. Auf dem
+ direkt angekoppelten Datenraum 'Beispiel: Zahlen 1 bis 10' werden die Werte
+ gespeichert.
+
+
+- Wenn man ein DATASPACE-Objekt benutzt, ohne den Datei-Manager zu
+ verwenden, so muß man selbst dafür sorgen, daß dieses Objekt nach seiner
+ Benutzung wieder gelöscht wird. Das Löschen geschieht durch die Prozedur
+ 'forget'. Ein automatisches Löschen von DATASPACE-Objekten erfolgt nicht bei
+ Programmende (sonst könnten sie ihre Funktion als Datei nicht erfüllen). Nur
+ durch 'forget' oder beim Löschen einer Task werden alle ihr gehörenden
+ DATASPACE-Objekte gelöscht und der belegte Speicherplatz freigegeben.
+
+
+- Ferner ist zu beachten, daß vor der Ankopplung an ein BOUND-Objekt das
+ DATASPACE-Objekt initialisiert wird (im Normalfall mit 'nilspace').
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ DATASPACE VAR ds := nilspace;
+ BOUND ROW 1000 REAL VAR real feld := ds;
+ ....
+ real feld [index] := wert;
+ ....
+ forget (ds) (* Datenraum löschen,
+ damit der Platz wieder verwendet wird *)
+
+____________________________________________________________________________
+
+
+- Will man auf die Feinstruktur eines BOUND-Objekts zugreifen, so muß man
+ strenggenommen den Konkretisierer benutzen:
+
+ Form:
+
+ #on("i")##on("b")#CONCR#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Ausdruck #on("i")##on("b")#)#off("i")##off("b")#
+
+ Der Konkretisierer ermöglicht eine typmäßige Umbetrachtung vom BOUND-Objekt
+ zum Datentyp der Feinstruktur. Ist der Zugriff jedoch eindeutig, so wird 'CONCR'
+ automatisch vom Compiler ergänzt.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ BOUND INT VAR i := old ("i-Wert");
+ INT VAR x;
+ x := wert.
+
+ wert:
+ IF x < 0
+ THEN 0
+ ELSE CONCR (i)
+ FI.
+
+____________________________________________________________________________
+
+
+In diesem Beispiel muß der Konkretisierer benutzt werden, da sonst der Resultattyp
+des Refinements nicht eindeutig ist (BOUND oder INT?).
+
+
+
+2.9.3.3 Definition neuer Dateitypen
+
+Durch die Datenräume und die Datentyp-Definition von ELAN ist es für Programmie­
+rer relativ einfach, neue Datei-Datentypen zu definieren. In der Regel reicht der
+Datentyp FILE für "normale" Anwendungen aus, jedoch kann es manchmal sinnvoll
+und notwendig sein, neue Datei-Typen für spezielle Aufgaben zu definieren.
+
+In diesem Abschnitt soll an dem Beispiel DIRFILE (welcher zwar im ELAN-Standard
+definiert, aber nicht im EUMEL-System realisiert ist) gezeigt werden, wie ein neuer
+Datei-Datentyp definiert wird:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PACKET dirfiles DEFINES DIRFILE, :=, dirfile, getline, ...:
+
+ LET maxsize = 1000;
+
+ TYPE DIRFILE = BOUND ROW maxsize TEXT;
+ (* DIRFILE besteht aus TEXTen; Zugriff erfolgt ueber einen
+ Schluessel, der den Index auf die Reihung darstellt *)
+
+ OP := (DIRFILE VAR dest, DATASPACE CONST space):
+ CONCR (dest) := space
+ END OP :=;
+
+ DATASPACE PROC dirfile (TEXT CONST name):
+ IF exists (name)
+ THEN old (name)
+ ELSE new (name)
+ FI
+ END PROC dirfile;
+
+ PROC getline (DIRFILE CONST df, INT CONST index,
+ TEXT VAR record):
+ IF index <= 0
+ THEN errorstop ("access before first record")
+ ELIF index > maxsize
+ THEN errorstop ("access after last record")
+ ELSE record := df [index]
+ FI
+ END PROC getline;
+
+ PROC putline (DIRFILE CONST df, INT CONST index,
+ TEXT VAR record):
+ ...
+ END PROC putline;
+
+ ...
+ END PACKET dirfiles;
+
+____________________________________________________________________________
+
+
+Die Prozedur 'dirfile' ist die Assoziierungsprozedur für DIRFILEs (analog 'sequential
+file' bei FILEs). 'dirfile' liefert entweder einen bereits vorhandenen Datenraum oder
+richtet einen neuen ein. Um eine Initialisierung mit der 'dirfile'-Prozedur vorneh­
+men zu können, braucht man auch einen Zuweisungsoperator, der den Datenraum an
+den DIRFILE-Datentyp koppelt.
+
+Zugriffe auf einen DIRFILE sind nun relativ einfach zu schreiben. Im obigen Beispiel
+wird nur die Prozedur 'getline' gezeigt.
+
+Nun ist es möglich, Programme zu schreiben, die den DIRFILE-Datentyp benut­
+zen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ DIRFILE VAR laeufer :: dirfile ("Nacht von Borgholzhausen");
+ INT VAR nummer;
+ TEXT VAR name;
+
+ REP
+ put ("Startnummer bitte:");
+ get (nummer);
+ line;
+ put ("Name des Laeufers:");
+ get (name);
+ putline (laeufer, nummer, name);
+ line
+ UNTIL no ("weiter") END REP;
+ ...
+
+____________________________________________________________________________
+#page#
+
+2.9.4 Datentyp INITFLAG
+
+Im Multi-User-System ist es oft notwendig, Pakete beim Einrichten einer neuen
+Task in dieser neu zu initialisieren. Das muß z.B. bei der Dateiverwaltung gemacht
+werden, da die neue Task ja nicht die Dateien des Vaters erbt. Mit Hilfe von
+INITFLAG-Objekten kann man zu diesem Zweck feststellen, ob ein Paket in dieser
+Task schon initialisiert wurde.
+
+
+INITFLAG
+ #on("b")#TYPE INITFLAG #off("b")#
+ Erlaubt die Deklaration entsprechender Flaggen.
+
+:=
+ #on("b")#OP := (INITFLAG VAR flag, BOOL CONST flagtrue) #off("b")#
+ Erlaubt die Initialisierung von INITFLAGs
+
+initialized
+ #on("b")#BOOL PROC initialized (INITFLAG VAR flag) #off("b")#
+ Wenn die Flagge in der Task A auf TRUE oder FALSE gesetzt wurde, dann liefert
+ sie beim ersten Aufruf den entsprechenden Wert, danach immer TRUE (in der
+ Task A!).
+
+ Beim Einrichten von Söhnen wird die Flagge in den Sohntasks automatisch auf
+ FALSE gesetzt. So wird erreicht, daß diese Prozedur in den neu eingerichteten
+ Söhnen und Enkeltasks genau beim ersten Aufruf FALSE liefert.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PACKET stack DEFINES push, pop:
+
+ INITFLAG VAR in this task := FALSE ;
+ INT VAR stack pointer ;
+ ROW 1000 INT VAR stack ;
+
+ PROC push (INT CONST value) :
+
+ initialize stack if necessary ;
+ ....
+
+ END PROC push ;
+
+ PROC pop (INT VAR value) :
+
+ initialize stack if necessary ;
+ ....
+
+ END PROC pop ;.
+
+ initialize stack if necessary :
+ IF NOT initialized (in this task)
+ THEN stack pointer := 0
+
+ FI .
+
+ END PACKET stack
+____________________________________________________________________________
+
diff --git a/doc/programming/programmierhandbuch.3 b/doc/programming/programmierhandbuch.3
new file mode 100644
index 0000000..eade335
--- /dev/null
+++ b/doc/programming/programmierhandbuch.3
@@ -0,0 +1,728 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 3 : Editor","3")#
+#pagenr("%",1)##setcount##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 3 : Editor
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+3 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#3 - %
+#end#
+
+TEIL 3: Der Editor
+
+Mit dem #ib#EUMEL-Editor#ie# steht für den Teil der Programmierung, der aus der Eingabe
+von Programmtext besteht, dasselbe komfortable Werkzeug zur Verfügung, wie für die
+Textverarbeitung. Merkmale des EUMEL-Editors sind die einfache Fenstertechnik
+und die übersichtliche Bedienung durch wenige Funktionstasten.
+
+Eine mit dem Editor erzeugte Textdatei ist maximal 4075 Zeilen lang, die maximale
+Breite einer Zeile beträgt 16000 Zeichen.
+
+
+
+3.1 Ein- und Ausschalten des Editors
+
+Der Editor wird eingeschaltet durch Eingabe von:
+
+____________________________________________________________________________
+ gib kommando :
+ #ib#edit#ie# ("dateiname")
+
+____________________________________________________________________________
+
+
+Falls eine Datei unter dem eingegebenen Namen existiert, wird ein Fenster auf dieser
+Datei an der Stelle geöffnet, an der zuletzt ein Zugriff auf diese Datei stattfand.
+
+Existiert noch keine Datei unter dem angegebenen Namen in der Task, folgt eine
+Anfrage, ob eine Datei unter dem eingegebenen Namen neu eingerichtet werden soll:
+
+____________________________________________________________________________
+ gib kommando :
+ edit("dateiname")
+ "dateiname" neu einrichten (j/n) ?
+
+____________________________________________________________________________
+
+
+Die Abfrage dient der Kontrolle der Schreibweise. Man kann ggf. das Einrichten der
+Datei ablehnen, den Dateinamen verbessern und das Kommando erneut geben.
+
+Bei korrekter Schreibweise bejahen Sie die Kontrollfrage#u# 1)#e#mit
+
+#center#<j> <J> <y> oder <Y>
+
+
+Es erscheint ein leerer Editorbildschirm. Die oberste Zeile des Bildschirms ist die
+#ib#Titelzeile#ie#. In ihr kann nicht geschrieben werden. Sie zeigt jedoch verschiedene nütz­
+liche Dinge an: den Namen der Datei, die Nummer der aktuellen Zeile, in der gerade
+geschrieben wird, Tabulatormarken, Einfügemodus, Lernmodus usw.
+
+____________________________________________________________________________
+ #mark on# ............... dateiname ....................#mark off# Zeile 1 #mark on# #mark off#
+ _
+
+____________________________________________________________________________
+
+
+
+Wollen Sie die #ib#Schreibarbeit beenden#ie# und den #ib#Editor ausschalten#ie#, so drücken Sie die
+beiden Tasten
+
+<ESC> <q>
+
+nacheinander. Sie haben damit den #ib#Editor verlassen#ie# und befinden sich wieder auf
+Monitor-Ebene.
+#page#
+
+3.2 Die Funktionstasten
+
+Die Funktionstasten realisieren diejenigen Fähigkeiten des Editor, die über die reine
+Zeicheneingabe hinausgehen. Wo die Tasten auf Ihrem Gerät liegen, hängt von dem
+jeweiligen Gerätetyp ab. Die Wirkung der Tasten ist im Weiteren erläutert.
+
+#l pos (0.0)##l pos(4.0)#
+#table#
+#free(0.5)#
+#taste1(" SHIFT ")# Umschalttaste
+#tableend#
+#free(0.5)#
+<v> <^> <>> <<> Positionierungstasten
+#table#
+#free(0.5)#
+<CR> Eingabe-/ Absatztaste
+#free(0.5)#
+<ESC> Kommandotaste
+#free(0.5)#
+<HOP> Verstärkertaste
+#free(0.5)#
+<TAB> Tabulatortaste
+#free(0.5)#
+<MARK> Markiertaste
+#free(0.5)#
+<RUBOUT> Löschtaste
+#free(0.5)#
+<RUBIN> Einfügetaste
+#free(0.5)#
+<SV> Supervisortaste
+#free(0.5)#
+<STOP> Stoptaste
+#free(0.5)#
+<WEITER> Weitertaste
+#tableend##clear pos#
+#free(0.5)#
+Es kann sein, daß Tasten nicht richtig beschriftet sind. Die Installations-anleitung
+muß dann die Entsprechungen beschreiben. Natürlich können sich weitere Funktions­
+tasten außer den im folgenden beschriebenen auf Ihrer Tastatur befinden. Diese
+haben standardmäßig jedoch keine besondere Bedeutung für den Editor.
+
+#page#
+
+3.3 Die Wirkung der Funktionstasten
+
+<SHIFT>
+
+#ib#Umschalttaste#ie#
+
+Wird diese Taste gleichzeitig mit einer anderen betätigt, so wird ein Buchstabe in
+Großschreibung, bei den übrigen Tasten das obere Zeichen, ausgegeben. So wird z.B.
+anstelle der "9" das Zeichen ")" ausgegeben.
+#free(0.5)#
+<>> <<>
+
+<v> <^>
+
+Positionierungstasten
+
+#ib#Positionierung des Cursors#ie# um eine Spalten-/Zeilenposition in die jeweilige Richtung.
+#free(0.5)#
+<CR>
+
+#ib#Eingabetaste / Absatztaste#ie#, Carriage Return, kurz: 'CR'
+
+Diese Taste schließt die aktuelle Zeile explizit ab und es wird an den Beginn der
+nächsten Zeile positioniert. Einrückungen werden beibehalten.
+
+Der EUMEL-Editor ist auf automatischen Wortumbruch voreingestellt, d.h. ein Wort,
+das über das 77. Zeichen der aktuellen Zeile herausreichen würde, wird automatisch
+in die nächste Zeile gerückt (siehe 'word wrap' 4.2.5). Die Absatztaste wird also
+benötigt, um explizite Zeilenwechsel und Einrückungen bei der Textformatierung zu
+erhalten. Eine Absatzmarke wird durch ein 'blank' hinter dem letzten Zeichen der
+Zeile erzeugt und ist im Editor an der Inversmarkierung am rechten Bildschirmrand zu
+erkennen.
+
+Im EUMEL-System werden Kommandos auf einer Kommandozeile, auf der alle
+Editorfunktionen zur Verfügung stehen, eingegeben. Auf dieser Ebene beendet die
+Taste also ausdrücklich die Kommandoeingabe, das gegebene Kommando wird an­
+schließend analysiert und ausgeführt.
+
+<HOP>
+
+"#ib#Verstärkertaste#ie#"; wird als Vorschalttaste bedient.
+
+In Kombination mit anderen Funktionstasten wird deren Wirkung verstärkt.
+
+
+<HOP> <v>
+
+Steht der Cursor nicht am unteren Bildrand, so wird er dorthin positioniert. Steht er
+am unteren Bildrand, so wird um einen Bildschirminhalt "weitergeblättert".
+
+Entsprechend werden auch die Tasten : <^> <>> <<> mit der HOP-Taste verstärkt.
+
+#page#
+<HOP> <RUBIN>
+
+#ib#Einfügen von Textpassagen#ie#. Die HOP-Taste in Verbindung mit RUBIN und RUBOUT
+wird zum 'verstärkten' Löschen und Einfügen verwendet.
+
+Ab der aktuellen Position des Cursors 'verschwindet' der restliche Text. Es kann wie
+bei der anfänglichen Texteingabe fortgefahren werden. Die Anzeige '#ib#REST#ie#' in der
+Titelzeile erinnert daran, daß noch ein Resttext existiert. Dieser erscheint nach einem
+neuerlichen Betätigen der beiden Tasten HOP RUBIN wieder auf dem Bildschirm (die
+Anzeige 'REST' verschwindet dann wieder).
+
+____________________________________________________________________________
+ ................ dateiname ..................... Zeile 4
+ In diesem Text soll vor dem zweiten Satz 
+ etwas eingefügt werden. Hierzu wird der
+ Cursor an die Position geführt, an der 
+ ein beliebiger Text eingefügt werden soll.#absatz#
+
+____________________________________________________________________________
+
+
+Nach Betätigen der Taste #on("i")##on("b")#HOP#off("i")##off("b")# und #on("i")##on("b")#RUBIN#off("i")##off("b")#sieht der Bildschirm wie folgt aus:
+
+____________________________________________________________________________
+ .............. dateiname ........REST.......... Zeile 4
+ In diesem Text soll vor dem zweiten Satz 
+ etwas eingefügt werden.
+
+
+____________________________________________________________________________
+
+
+
+Nun kann beliebig viel Text eingefügt werden. Nochmaliges Betätigen von HOP und
+RUBIN führt den Text-Rest wieder bündig heran.
+
+#page#
+<HOP> <RUBOUT>
+
+Löscht die Zeile ab Cursor-Position bis Zeilenende.
+
+____________________________________________________________________________
+ ................ dateiname ..................... Zeile 4
+ Soll eine ganze Zeile oder ein Textrest 
+ gelöscht werden, so positioniert man an die 
+ Stelle, ab der gelöscht werden soll. Rest löschen....
+ Nach HOP RUBOUT ist der Zeilenrest gelöscht.#absatz#
+
+____________________________________________________________________________
+
+
+
+Nach Betätigen der Tasten #on("i")##on("b")#HOP#off("i")##off("b")# und #on("i")##on("b")#RUBOUT#off("i")##off("b")# sieht der Bildschirm wie folgt aus.
+
+____________________________________________________________________________
+ ............... dateiname .................... Zeile 4
+ Soll eine ganze Zeile oder ein Textrest 
+ gelöscht werden, so positioniert man an die 
+ Stelle, ab der gelöscht werden soll.
+ Nach HOP RUBOUT ist der Zeilenrest gelöscht.#absatz#
+
+____________________________________________________________________________
+
+
+
+Steht der Cursor am Zeilenanfang, wird nach HOP RUBOUT dementsprechend die
+ganze Zeile gelöscht und die Lücke durch Nachrücken der Folgezeilen geschlossen
+(HOP RUBOUT betätigen).
+#page#
+<TAB>
+
+#ib#Tabulatortaste#ie#
+
+Mit der Tabulatortaste werden die eingestellten Tabulatorpositionen angesprungen.
+Jeder Tastendruck läßt den Cursor auf die nächste eingestellte Tabulatorposition
+springen.
+
+#on("i")#Voreingestellte#off("i")# Tabulatorpositionen sind die beiden Schreibgrenzen, Textanfang in der
+Zeile und Ende der Zeile.
+
+Weitere Tabulatorpositionen können durch Positionierung auf die gewünschte Spalte
+und #on("i")##on("b")#HOP#off("i")##off("b")# #on("i")##on("b")#TAB#off("i")##off("b")# gesetzt werden. Sie können gelöscht werden, indem sie mit #on("i")##on("b")#TAB#off("i")##off("b")#
+angesprungen und mit #on("i")##on("b")#HOP#off("i")##off("b")# #on("i")##on("b")#TAB#off("i")##off("b")#
+ausgeschaltet werden.
+
+Die gesamte eingestellte Tabulalation kann durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#TAB#off("i")##off("b")# ein-/ und ausge­
+schaltet werden.
+
+Die eingestellten Tabulatorpositionen erkennen Sie an den Tabulatorzeichen (Dachzei­
+chen) in der obersten Bildschirmzeile.
+#page#
+<MARK>
+
+#ib#Ein- bzw. Ausschalten der Markierung#ie#.
+
+Bei Betätigung dieser Taste wird in einen speziellen #ib#Markierzustand#ie# geschaltet. Alles,
+was Sie jetzt schreiben bzw. durch Bewegen des Cursors in Richtung Dateiende
+kennzeichnen, steht als #on("i")#markierter#off("i")# Bereich für die Bearbeitung zur Verfügung. Zur
+besseren Sichtbarkeit wird der markierte Bereich invers zum übrigen Text dargestellt.
+
+Wird der Cursor in eine Richtung bewegt, wird das gesamte Textstück zwischen
+Einschaltpunkt der Markierung und aktueller Cursorposition markiert. Rückwärtsbewe­
+gungen des Cursors verkürzen den markierten Bereich wieder.
+
+Durch erneutes Betätigen der MARK-Taste schalten Sie den Markier-Zustand
+wieder aus.
+
+Mit weiteren Kommandos kann der Bereich nun bearbeitet werden:
+
+<ESC> <d> Markierten Abschnitt in 'Scratch'-Datei kopieren.
+
+<ESC> <p> Markierten Abschnitt herauskopieren.
+
+<ESC> <RUBOUT> Markierten Abschnitt löschen.
+
+
+Der mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#p#off("i")##off("b")# oder#on("i")##on("b")#d#off("i")##off("b")# kopierte Bereich kann beliebig oft in derselben oder einer
+anderen Datei ein/angefügt werden.
+
+Der mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#RUBOUT#off("i")##off("b")# gelöschte Abschnitt kann genau einmal durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#RUBOUT#off("i")##off("b")#
+an anderer Stelle derselben Datei eingefügt werden.
+
+(vgl. ESC-Taste, Operationen auf Markierungen, 3-#topage("ESC")#)
+#page#
+<RUBIN>
+
+#ib#Ein- bzw. Ausschalten des Einfügemodus.#ie#
+
+Das Betätigen der Taste schaltet in den Einfügemodus. Der Zustand wird durch das
+Wort "RUBIN" im linken Drittel der Titelzeile der Datei angezeigt. Vor dem Zeichen,
+auf dem der Cursor steht, wird eingefügt. Nochmaliges Betätigen der Taste schaltet
+den Einfügemodus aus.
+#free(1.0)#
+<RUBOUT>
+
+#ib#Löschtaste#ie#
+
+Das Zeichen, auf dem der Cursor steht, wird gelöscht. Wenn der Cursor, wie bei
+fortlaufender Eingabe üblich, hinter dem letzten Zeichen einer Zeile steht, wird das
+letzte Zeichen gelöscht.
+
+#page#
+
+3.4 ESC Kommandos
+
+<ESC>
+
+#ib#Kommandotaste#ie#
+
+Mit der ESC-Taste in Kombination mit einer Folgetaste werden vordefinierte Aktionen
+ausgelöst. Es gibt Aktionen, die vorprogrammiert zur Verfügung stehen, und Sie selbst
+können weitere hinzufügen.
+
+Der Kommandodialog wird eingeschaltet durch:
+
+<ESC> <ESC>
+
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando:                                             
+
+____________________________________________________________________________
+
+
+Der Kommandodialog ermöglicht die Eingabe von beliebigen Kommandos ohne den
+Editor verlassen zu müssen. Insbesondere Such- und Kopieroperationen stellen auch
+für den Programmierer nützliches Werkzeug dar (siehe 3.5).
+
+Auf der Kommandozeile kann jedes Kommando gegeben werden. Die Kommandozeile
+kann wie eine normale Textzeile editiert werden. Nach #on("i")##on("b")#CR#off("i")##off("b")# verschwindet die Kom­
+mandozeile und das Kommando wird ausgeführt.
+
+Falls ein Fehler auftritt erfolgt eine entsprechende Fehlermeldung in der Kopfzeile und
+die Kommandozeile erscheint erneut.
+
+Um ein weiteres Editor-Fenster zu 'öffnen', betätigt man im Editor
+
+<ESC>  <e>
+
+Betätigt man ESC e ungefähr in der Mitte des Bildschirms, hat man das Fenster auf
+die neue Datei in der unteren Hälfte des Bildschirms und die 'alte' Datei in der
+oberen Bildschirmhälfte. Zunächst wird der Dateiname erfragt. Nach dessen Eingabe
+und #on("i")##on("b")#CR#off("i")##off("b")# wird ein Fenster auf eröffnet. Die obere linke Ecke des Fensters befindet
+sich an der aktuellen Cursor-Position. Dabei darf sich der Cursor nicht zu sehr am
+rechten oder unteren Rand befinden, weil das Fenster sonst zu klein würde. In diesem
+'Fenster' kann man dann genauso arbeiten wie im 'normalen' Editor.
+
+Mit der Tastenfolge
+
+<ESC>  <w>
+
+wechselt man von einem Fenster (zyklisch) in das benachbarte. Es gibt eine Hier­
+archie zwischen den Fenstern in der Reihenfolge, in der eines im anderen einge­
+richtet worden ist. Gibt man
+
+<ESC>  <q>
+
+in einem Fenster, so verschwindet dieses und alle darin eingeschachtelten Fenster,
+und man befindet sich im übergeordneten Fenster.
+
+Durch
+
+<ESC>  <p> oder <ESC>  <d>
+
+schreibt man einen markierten Teil in eine 'Scratch'-Datei (nicht editierbarer
+Zwischenspeicher); durch ESC p wird ein markierter Text aus der Ursprungsdatei
+entfernt und in die 'Scratch'-Datei geschrieben. Im Gegensatz dazu wird er durch
+ESC d kopiert. Durch
+
+<ESC>  <g>
+
+fügt man ihn in eine andere (oder dieselbe) Datei ein. Im Unterschied zu ESC RUBIN
+wird die temporäre Datei dadurch nicht entleert.
+
+Die für ESC p, bzw. ESC d benutzte #ib#'Scratch'-Datei#ie#, die nicht editierbar ist, ist nicht
+mit dem sogenannten Notizbuch zu verwechseln. Das Notizbuch ist eine Datei, in der
+alle Editorfunktionen benutzt werden können, auf die jedoch ohne Angabe eines
+Dateinamens durch
+
+<ESC> <n>
+
+ab der aktuellen Cursorposition ein Fenster eröffnet wird. Das Notizbuch nimmt
+insbesondere Fehlermeldungen und Meldungen bei der Übersetzung von Programmen
+auf.
+
+<ESC> <v>
+
+erlaubt vom äußeren Fenster aus alle eingeschachtelten Fenster zu verlassen.
+#page#
+
+Vorbelegte Tasten
+
+#ib#ESC q#ie# Verlassen des Editors bzw. der eingeschachtelten Fenster.
+
+#ib#ESC e#ie# Weiteres Editorfenster einschalten.
+
+#ib#ESC n#ie# Notizbuch 'anzeigen'.
+
+#ib#ESC v#ie# Dateifenster auf ganzen Bildschirm vergrößern
+ bzw. Bildschirm rekonstruieren (eingeschachteltes Fenster verlas­
+ sen).
+
+#ib#ESC w#ie# Dateiwechsel beim Fenstereditor.
+
+#ib#ESC f#ie# Nochmalige Ausführung des letzten Kommandos.
+
+#ib#ESC b#ie# Das Fenster wird auf den linken Rand der aktuellen (ggf. verscho­
+ benen) Zeile gesetzt.
+
+ESC > Zum nächsten Wortanfang.
+
+ESC < Zum vorherigen Wortanfang.
+
+#ib#ESC 1#ie# Zum Anfang der Datei.
+
+#ib#ESC 9#ie# Zum Ende der Datei.
+#page#
+
+Operationen auf Markierungen
+
+
+#goalpage("ESC")#
+#ib#ESC RUBOUT#ie# Markiertes "vorsichtig" löschen.
+
+#ib#ESC RUBIN#ie# Mit ESC RUBOUT vorsichtig Gelöschtes einfügen.
+
+#ib#ESC p#ie# Markiertes löschen und in die Notiz-Datei schreiben. Kann mit ESC
+ g an anderer Stelle reproduziert werden.
+
+#ib#ESC d#ie# Duplizieren:
+ Markiertes in die Notiz-Datei kopieren, anschließend die
+ Markierung abschalten. Kann mit ESC g beliebig oft reproduziert
+ werden.
+
+#ib#ESC g#ie# Mit ESC p gelöschten oder mit ESC d duplizierten Text an aktuelle
+ Cursor-Stelle schreiben, d.h. Notiz-Datei an aktueller Stelle einfü­
+ gen.
+#page#
+
+Zeichen schreiben
+Diese Tasten sind standardmäßig so vorbelegt wie hier aufgeführt, sie können aber
+von Benutzern und in Anwenderprogrammen geändert werden.
+
+#ib#ESC a#ie# Schreibt ein ä.
+#ib#ESC A#ie# Schreibt ein Ä.
+#ib#ESC o#ie# Schreibt ein ö.
+#ib#ESC O#ie# Schreibt ein Ö.
+#ib#ESC u#ie# Schreibt ein ü.
+#ib#ESC U#ie# Schreibt ein Ü.
+#ib#ESC s#ie# Schreibt ein ß.
+#ib#ESC (#ie# Schreibt eine [.
+#ib#ESC )#ie# Schreibt eine ].
+#ib#ESC <#ie# Schreibt eine {.
+#ib#ESC >#ie# Schreibt eine }.
+#ib#ESC \##ie# Schreibt ein \#, das auch gedruckt werden kann.
+#ib#ESC ­#ie# Schreibt einen (geschützten) Trennstrich, siehe Textverarbeitung.
+#ib#ESC k#ie# Schreibt ein (geschütztes) "k", siehe Textverarbeitung.
+#ib#ESC blank#ie# Schreibt ein (geschütztes) Leerzeichen, siehe Textverarbeitung.
+#free(0.7)#
+
+Kommando auf Taste legen
+
+#ib#ESC ESC#ie# Kommandodialog einschalten
+
+#ib#ESC ! taste#ie# Im Kommandodialog:
+ Geschriebenes Kommando auf Taste legen.
+
+#ib#ESC ? taste#ie# Im Kommandodialog:
+ Auf 'taste' gelegtes Kommando zum Editieren anzeigen.
+
+#ib#ESC k#ie# Im Kommandodialog:
+ Das zuletzt editierte Kommando (einzeilige ELAN-Programm)
+ anzeigen.
+
+
+Der Lernmodus
+Der Lernmodus ermöglicht beliebige Tastensequenzen zu speichern und auf eine
+Taste 't' zu legen. Durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#t#off("i")##off("b")# wird die gesamte Sequenz ausgeführt.
+
+Nicht belegt werden können die vom System vorbelegten Tasten (3-14).
+
+Beispielsweise könnte es für einen Programmierer sinnvoll sein die Tastenfolge
+'THEN' 'CR' '>' '>' '>' '>' auf die Taste #on("i")##on("b")#T#off("i")##off("b")# zu legen. Durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#T#off("i")##off("b")# wird 'THEN' in
+die aktuelle Zeile geschrieben und der Cursor mit passender Einrückung in die
+Einrückung in die Folgezeile gesetzt.
+
+
+#ib#ESC HOP#ie# #ib#Lernen einschalten#ie#.
+
+#ib#ESC HOP taste#ie# #ib#Lernen ausschalten#ie# und Lernsequenz auf 'taste'legen.
+
+#ib#ESC HOP HOP#ie# #ib#Gelerntes vergessen#ie#. Bedingung ist, daß man die Lernsequenz in
+ der Task löscht, in der man sie hat lernen lassen.
+
+
+#on("b")#
+#center#A C H T U N G :
+Der Lernmodus bleibt eingeschaltet, auch wenn der Editor beendet wird. Dann werden
+die folgenden Monitor-Kommandos usw. usf. 'gelernt'. Durch unsinniges 'Lernen'
+lassen sich schlimmstenfalls beliebige Verwüstungen anrichten.
+
+Der Lernmodus wird in der Editor-Kopfzeile angezeigt. Falls der Editor beendet wird,
+ohne den Lernmodus auszuschalten, erfolgt eine Warnung auf Monitor-Ebene.
+
+Um den Lernmodus zu beenden drücken Sie:
+
+<ESC> <HOP> <HOP>
+
+Dadurch wird der Lernmodus ausgeschaltet und nichts gelernt, die Gefahr ist gebannt.#off("b")#
+
+#page#
+<SV>
+
+#ib#SUPERVISOR-Taste#ie#
+
+Betätigen Sie diese Taste im Editor, dann unterbrechen Sie Ihre Editierarbeit und
+erhalten die Meldung
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8/M
+
+
+ gib supervisor kommando:
+
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+____________________________________________________________________________
+
+
+
+Wollen Sie nun im Editor fortfahren bzw. haben Sie irrtümlich die SV-Taste betätigt,
+dann geben Sie das Kommando
+
+____________________________________________________________________________
+
+ gib supervisor kommmando :
+ continue ("meine task")
+
+____________________________________________________________________________
+
+
+
+(falls Ihre Task, in der Sie arbeiteten, wirklich "meine task" hieß!)
+
+Um Ihren in Bearbeitung befindlichen Text wieder vollständig auf dem Bildschirm zu
+sehen, betätigen die die Tasten
+
+<ESC> <b>
+
+Sie sind wieder an der Stelle, an der Sie den Text mit der SV-Taste verlassen ha­
+ben, und können normal weiterarbeiten.
+
+#on("u")#Achtung:#off("u")# Die SV-Taste kann, je nach Terminal, durch das Betätigen von zwei
+Tasten gleichzeitig realisiert sein (oft 'CTRL b'). Beachten Sie die Beschreibung Ihrer
+Tastatur!
+
+
+
+#on("b")#
+Für die Programmierung ist die Tastenfolge <SV> <ESC> <h> von Bedeutung, da hier­
+durch der Fehler 'halt vom Terminal' erzeugt wird. Dadurch können unerwünscht
+laufende Programme abgebrochen werden.
+#off("b")#
+#page#
+<STOP>
+
+#ib#Unterbrechen einer Ausgabe#ie# (oft auch als CTRL a realisiert).
+
+Haben Sie diese Taste aus Versehen betätigt, erkennen Sie dies daran, daß der
+Editor nicht "reagiert". Betätigen Sie die WEITER-Taste (oft auch CTRL c).
+#free(1.0)#
+<WEITER>
+
+Unterbrochene Ausgabe fortsetzen.
+
+Ein mit der STOP-Taste angehaltene Ausgabe können Sie durch Betätigen der
+#ib#WEITER-Taste#ie# fortsetzen.
+
+
+#on("u")#VORSICHT:#off("u")# Die STOP-Taste unterbricht nur die Ausgabe auf den Bildschirm. Zei­
+ chen, die während des STOP eingegeben werden, werden gespeichert
+ und nach 'WEITER' ausgegeben!
+
+
+#page#
+
+3.5 Positionieren, Suchen, Ersetzen
+ im Kommandodialog
+
+
+Um das Editorfenster auf eine bestimmte Zeile zu positionieren wird einfach diese
+Zeilennummer angegeben.
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando: 123                                          
+
+____________________________________________________________________________
+
+
+
+Falls die Zeilenzahl der Datei geringer als die angegebene Zeilennummer ist, wird auf
+die letzte Zeile positioniert.
+
+
+Um das Editorfenster auf ein bestimmtes Textstück zu positionieren, wird der gesuch­
+te Text, ggf. mit Suchrichtung angegeben.
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando: "END PROC"                                  
+
+____________________________________________________________________________
+
+
+Die Suchrichtung kann durch 'D' (down) oder 'U' (up) zusätzlich spezifiziert werden.
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando: U "INT VAR schleifenzaehler"                 
+
+____________________________________________________________________________
+
+
+
+Um beliebige Texte durch andere zu ersetzen, dienen die Operatoren 'C' (change)
+bzw. 'CA' (change all).
+
+Bei Ausführung dieses Kommandos wird zunächst nach #on("u")#unten#off("u")# in der editierten Datei
+nach dem zu ersetzenden Text gesucht. Wenn der Text gefunden wird, wird er durch
+den hinter dem Operator stehenden Text ersetzt.
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando: "lb" C "lange bezeichnung"                   
+
+____________________________________________________________________________
+
+
+
+Bei Anwendung von 'CA' wird jedes Auftreten des gesuchten Textes ab der
+Cursorposition durch den Ersatztext ersetzt, bis das Dateiende errreicht ist.
+
+Weitere Erklärungen zum Suchen und Ersetzen in 5.5.
+#page#
+
+Weitere Hilfen
+
+
+Textabschnitt an anderer Stelle der Datei einsetzen:
+
+- Abschnitt markieren und mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#d#off("i")##off("b")# zwischenspeichern.
+
+- Zweites Editorfenster auf die Datei mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#e#off("i")##off("b")# öffnen.
+
+- Nach #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# Zeilennummer oder Suchbegriff angeben und mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#g#off("i")##off("b")# Abschnitt an der gewünschte Stelle einsetzen.
+
+
+
+Textabschnitt schnell herauskopieren und sichern:
+
+- Gewünschten Abschnitt markieren
+
+- #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# PUT("dateiname") #on("i")##on("b")#CR#off("i")##off("b")#
+ Der Abschnitt wird in die Datei 'dateiname' geschrieben. Falls die Frage 'dateina­
+ me' löschen (j/n) verneint wird, wird der Abschnitt, an das Ende der Datei angefügt.
+ Dadurch können Textabschnitte schnell gesammelt werden.
+
+
+Komplette Datei in die editierte Datei einfügen:
+
+- #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# GET("dateiname") #on("i")##on("b")#CR#off("i")##off("b")#
+ Der komplette Inhalt von 'dateiname' wird an die aktuelle Position geschrieben.
+
+
+Breitere Zeile erzeugen:
+
+- #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# limit(123) #on("i")##on("b")#CR#off("i")##off("b")#
+ Die Zeilenbreite wird auf 123 Zeichen geändert. Der maximal zulässige Wert ist
+ 16000. Dieser Wert bezieht sich auf den Zeilenumbruch. Bei Zeilenbreite > 77 wird
+ nur die aktuelle Zeile verschoben. Um für den ganzen Bildschirm die rechte Seite
+ der Datei zu sehen, kann die linken Spalte des Bildschirmfenster neu gesetzt wer­
+ den:
+
+ #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# margin(60) #on("i")##on("b")#CR#off("i")##off("b")#
+
+ Die Normaleinstellung wird durch 'limit(77)' und 'margin(1)' wiederhergestellt.
+
diff --git a/doc/programming/programmierhandbuch.4 b/doc/programming/programmierhandbuch.4
new file mode 100644
index 0000000..650d945
--- /dev/null
+++ b/doc/programming/programmierhandbuch.4
@@ -0,0 +1,1692 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 4 : Kommandosprache","4")#
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 4 : Kommandosprache
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+4 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#4 - %
+#end#
+TEIL 4: Kommandosprache
+
+In Teil 4 sind diejenigen Kommandos beschrieben, die erfahrungsgemäß eher der
+Handhabung der Arbeitsumgebung zuzurechnen sind. Es ist den Verfassern bewußt,
+daß Auswahl und Zusammenstellung recht willkürlich sind, weil eine klare Abgrenzung
+zum Teil 5, welcher die Kommandos, die dem Thema: 'Programmierung' zugeordnet
+werden, nicht möglich ist.
+
+Der Teil 4 ist in die Themen:
+
+- 4.1. Supervisor-Kommandos
+
+- 4.2.1 Hilfs- und Informationsprozeduren
+
+- 4.2.2 Thesaurus
+
+- 4.2.3 Tasks
+
+- 4.2.4 Handhabung von Dateien
+
+- 4.2.5 Editor
+
+- 4.2.6 Dateitransfer
+
+- 4.2.7 Passwortschutz
+
+- 4.2.8 Archiv
+
+gegliedert. Insbesondere zu 4.2.4 ist anzumerken, daß nur Kommandos, die ganze
+Dateien betreffen hier erläutert sind. Kommandos, die Dateiinhalte betreffen (Suchen,
+Ersetzen etc.) sind in 3.5, bzw. 5.3 beschrieben.
+#page#
+
+4.1 Supervisor
+
+Es gibt genau sieben vom Supervisor akzeptierte Kommandos. Diese Kommandos
+können gegeben werden wenn nach dem Einschalten des Geräts oder dem Abkoppeln
+einer Task die SV-Taste gedrückt wurde und die sogenannte EUMEL-Tapete
+erscheint.
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8.1/M
+
+
+ gib supervisor kommando:
+
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+____________________________________________________________________________
+
+
+
+
+Desweiteren kann <SV> in einer Task gedrückt werden, um durch <ESC> <h> einen
+Programmabbruch einzuleiten.
+
+Im Gegensatz zu den im weiteren beschriebenen, durch ELAN Prozeduren realisierten
+Kommandos, sind diese Supervisor-Kommandos nicht als Prozeduren im System und
+mithin nicht durch 'help (...)' anzeigbar.
+#page#
+'begin'
+ #on("b")#PROC begin (TEXT CONST taskname) #off("b")#
+ Richtet eine neue Task als Sohn von PUBLIC ein.
+
+
+ #on("b")#PROC begin (TEXT CONST taskname, vatertask) #off("b")#
+ Richtet eine neue Task als Sohn der Task 'vatertask' ein, falls die Vater-Task
+ eine Manager-Task ist. Falls diese Task keinen Managerstatus besitzt, passiert
+ nichts! In diesem Falle muß das Kommando durch <SV> abgebrochen werden.
+
+
+ FEHLER : "taskname" existiert bereits
+ "vatertask" gibt es nicht
+
+
+
+
+'continue'
+ #on("b")#PROC continue (TEXT CONST taskname) #off("b")#
+ Eine existierende Task wird an das Terminal des Benutzers angekoppelt.
+
+ FEHLER : "taskname" gibt es nicht
+
+
+ Falls 'begin' oder 'continue' trotz korrekter Voraussetzungen kein Resultat zeigen,
+ 'hängt' die betroffene Task. Beim 'begin' Kommando kann das der Fall sein, falls
+ die Vater-Task nicht durch 'break' abgekoppelt wurde, sondern mit < SV > verlas­
+ sen wurde. In diesem Fall muß das Kommando durch <SV> abgebrochen werden,
+ die Vater-Task angekoppelt und mit <ESC> <q> korrekt abgekoppelt werden.
+#page#
+'break'
+ #on("b")#PROC break #off("b")#
+ Das Terminal wird vom Rechner abgekoppelt.
+
+
+
+'halt'
+ #on("b")#PROC halt #off("b")#
+ Das laufende Programm der dem Terminal aktuell zugeordneten Task wird abge­
+ brochen.
+
+ Falls in der an das Terminal gekoppelten Task ein laufendes Programm abgebro­
+ chen werden soll, muß zunächst durch <SV> der Supervisor aufgerufen werden.
+ Durch das Supervisor-Kommando 'halt' wird der Fehler 'halt from terminal'
+ induziert. Das Programm wird wie durch jeden anderen Fehler abgebrochen, falls
+ nicht 'disable stop' gesetzt wurde!
+
+
+
+#page#
+'storage info'
+ #on("b")#PROC storage info #off("b")#
+ Informationsprozedur über den belegten und den verfügbaren Hintergrund-Spei­
+ cher des gesamten Systems in KByte#u#1)#e#.
+
+#foot#
+
+ 1) Bei der derzeit aktuellen '+' Version EUMEL 1.8.1/M+ sind die beiden Anga­
+ ben mit 4 zu multiplizieren !
+#end#
+ Das Terminal wird unmittelbar abgekoppelt!
+
+
+
+'task info'
+ #on("b")#PROC task info #off("b")#
+ Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der Vater/
+ Sohn-Beziehungen durch Einrückungen.
+
+
+
+
+'help'
+ #on("b")#PROC help #off("b")#
+ Kurzbeschreibung der SV-Kommandos.
+#page#
+
+4.2 Monitor
+
+Unter dem Stichwort Monitor-Kommandos sind an dieser Stelle Kommandos be­
+schrieben, die ständig zur Handhabung der Arbeitsumgebung benutzt werden.
+Gleichwohl sei sofort darauf hingewiesen, daß jedes ELAN Programm dem Monitor zur
+Ausführung übergeben werden kann. Es gibt also keine speziellen Monitor-
+Kommandos, sondern nur eine Reihe von Prozeduren (=Kommandos), die in dieser
+Umgebung erfahrungsgemäß besonders häufig benutzt werden.
+
+
+#on("u")#4.2.1 Hilfs- und Informationsprozeduren#off("u")#
+
+- Pakete, Prozeduren : packets, bulletin , help
+ Parameter
+
+- Tasksystem zeigen : task info , task status
+
+- Speicherplatz zeigen : storage , storage info
+
+
+#on("u")#4.2.2 Thesaurus #off("u")#
+
+- besondere Thesauri : ALL , all , SOME , remainder
+
+- Verknüpfung : + , - , /
+
+
+#on("u")#4.2.3 Taskoperationen#off("u")#
+
+- besondere Tasknamen : archive , brother , father , myself
+ printer , public , son , supervisor
+- Terminal abkoppeln : break
+- Task löschen : end
+- Manager-Task : global manager , free global manager
+- Umbenennen der Task : rename myself
+
+#page#
+#on("u")#4.2.4 Handhabung von Dateien #off("u")#
+
+ : copy , edit , forget , list , rename , show
+
+
+#on("u")#4.2.5 Editor #off("u")#
+
+- Editieren : edit , editget , show
+- Tastenbelegung : kommando auf taste (legen) ,
+ lernsequenz auf taste (legen) ,
+ std tastenbelegung ,
+ taste enthält kommando ,
+ word wrap
+
+
+#on("u")#4.2.6 Transfer #off("u")#
+
+- Datei holen : fetch , fetchall
+- Datei senden : save , saveall
+- Drucken : print
+- Datei löschen : erase
+
+
+#on("u")#4.2.7 Passwortschutz #off("u")#
+
+- 'begin' absichern : begin password
+- 'continue' absichern : task password
+- Dateien absichern : enter password
+- Systemzweig sichern : family password
+
+
+#on("u")#4.2.8 Das Archiv #off("u")#
+
+- Reservieren/freigeben : archive , release
+- Formatieren : format
+- Löschen : clear
+- Kontrollesen : check
+
+
+#page#
+
+4.2.1 Hilfsprozeduren
+
+Die drei Prozeduren listen ihre Ausgabe jeweils in eine temporäre Datei, die mit
+'show' (s. 4.2.5) gezeigt wird.
+
+
+'packets'
+ #on("b")#PROC packets #off("b")#
+ Auflisten der Namen aller insertierten Pakete in der Task.
+
+
+
+
+
+
+'bulletin'
+ #on("b")#PROC bulletin (TEXT CONST paket name) #off("b")#
+ Listen aller in der DEFINES-Liste des Pakets mit dem Namen "paket name"
+ enthaltenen Prozeduren.
+
+ FEHLER : ... ist kein Paketname
+
+
+ #on("b")#PROC bulletin #off("b")#
+ Es wird eine Liste aller bisher insertierten Objekte erstellt. Diese Liste ist paket­
+ weise sortiert. 'bulletin' zeigt also eine Liste #on("u")#aller#off("u")# Prozeduren an, die in der Task
+ benutzt werden können.
+#page#
+'help'
+ #on("b")#PROC help (TEXT CONST name) #off("b")#
+ Listen aller Prozeduren / Operatoren mit dem Namen "name". Der Name des
+ Packets in dessen Schnittstelle die Prozedur steht wird mit ausgegeben.
+
+ Falls es kein Objekt des erfragten Namens gibt, erfolgt die Ausgabe:
+
+ unbekannt "name".
+
+ Beispiel:
+____________________________________________________________________________
+
+ gib kommando :
+ help("save")
+
+____________________________________________________________________________
+
+
+ liefert:
+
+____________________________________________________________________________
+
+PACKET nameset:
+
+ save........... (THESAURUS CONST, TASK CONST)
+ save........... (THESAURUS CONST)
+
+PACKET globalmanager:
+
+ save........... (DATASPACE CONST, TEXT CONST, TASK CONST)
+ save........... (TEXT CONST, TASK CONST)
+ save........... (TEXT CONST)
+ save...........
+
+____________________________________________________________________________
+
+
+
+ Desweiteren kann auch nach Prozedurnamen gesucht werden, die nur annähernd
+ bekannt sind, indem ein Suchmuster spezifiziert wird. Das Suchmuster besteht aus
+ dem bekannten Teil des Namens und dem Operator '*', der vor und/oder nach
+ dem Suchbegriff gesetzt werden kann. '*' bezeichnet eine beliebige (auch leere)
+ Zeichenkette.
+
+ Beispiel: Gesucht werden die verschiedenen 'info' Prozeduren:
+
+____________________________________________________________________________
+ gib kommando :
+ help("*info*")
+
+____________________________________________________________________________
+
+
+
+____________________________________________________________________________
+
+ taskinfo....... (INT CONST, INT CONST)
+ taskinfo....... (INT CONST, FILE VAR)
+ taskinfo....... (INT CONST)
+ taskinfo.......
+ editinfo....... (FILE VAR, INT CONST)
+ editinfo....... (FILE CONST) --> INT
+ storageinfo....
+
+____________________________________________________________________________
+
+
+
+ Dieser Stern darf nicht mit dem 'joker' des 'Pattern Matching' verwechselt werden.
+ In der 'help' Prozedur darf '*' #on("u")#nicht#off("u")# in den Suchbegriff eingesetzt werden, sondern
+ nur an Wortanfang und -Ende gesetzt werden.
+
+
+#page#
+
+Informationsprozeduren
+
+'storage'
+ #on("b")#INT PROC storage (TASK CONST task) #off("b")#
+ Informationsprozedur über den logisch belegten Hintergrund-Speicher der Task.
+ (Angabe in KByte, bzw. 4KB Einheiten bei der '+'-Version)
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ put(storage(myself))
+ 1234
+
+ gib kommando :
+
+____________________________________________________________________________
+
+
+'storage info'
+ #on("b")#PROC storage info #off("b")#
+ Informationsprozedur über den belegten und den verfügbaren Hintergrund-Spei­
+ cher des gesamten Systems. Die Ausgabe erfolgt in KByte, bei der aktuellen
+ '+'-Version in 4 KByte Einheiten.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ storage info
+ 1234K von 12000K
+
+ gib kommando :
+____________________________________________________________________________
+#page#
+
+'task info'
+ #on("b")#PROC task info #off("b")#
+ Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der Vater/
+ Sohn-Beziehungen (Angabe durch Einrückungen).
+
+
+ #on("b")#PROC task info (INT CONST art) #off("b")#
+ Informiert über alle Tasks im System. Mit 'art' kann man die Art der Zusatz-
+ Information auswählen.
+
+ art=1: entspricht 'task info' ohne Parameter, d.h. es gibt nur die Tasknamen
+ unter Angabe der Vater/Sohn-Beziehungen aus.
+
+ art=2: gibt die Tasknamen aus. Zusätzlich erhalten Sie Informationen über die
+ verbrauchte CPU-Zeit der Task, die Priorität, den Kanal, an dem die
+ Task angekoppelt ist, und den eigentlichen Taskstatus. Hierbei bedeuten:
+
+ 0 -busy- Task ist aktiv.
+ 1 i/o Task wartet auf Beendigung des Outputs oder auf
+ Eingabe.
+ 2 wait Task wartet auf Sendung von einer anderen Task.
+ 4 busy-blocked Task ist rechenwillig, aber blockiert#u#1)#e#.
+ 5 i/o -blocked Task wartet auf I/O, ist aber blockiert.
+ 6 wait-blocked Task wartet auf Sendung, ist aber blockiert. Ach­
+ tung: Die Task wird beim Eintreffen einer Sendung
+ automatisch entblockiert.
+ > 6 dead
+
+ art=3: wie 2, aber zusätzlich wird der belegte Speicher angezeigt. (Achtung:
+ Prozedur ist zeitaufwendig!).
+
+#foot#
+
+1) Eine Blockierung kann von 'Scheduler' veranlaßt werden
+ (siehe Systemhandbuch)
+#end#
+
+#page#
+____________________________________________________________________________
+
+ gib kommando :
+ task info(2)
+
+____________________________________________________________________________
+
+
+
+ liefert:
+
+____________________________________________________________________________
+
+ ............................ ...............................
+ 15.05.87 10:39 CPU PRIO CHAN STATUS
+ SUPERVISOR.......................... 0000:19:47 0 - wait
+ -................................ 0000:07:54 0 - wait
+ SYSUR............................ 0000:34:02 0 - wait
+ shutup dialog................ 0000:05:26 0 - i/o
+ configurator................. 0000:04:17 0 - wait
+ OPERATOR..................... 0000:00:14 0 - i/o
+ ARCHIVE...................... 0000:10:33 0 31 wait
+ net.......................... 0006:41:56 0 - wait
+ net timer................ 0000:02:48 2 - i/o
+ net port................. 0000:40:23 0 7 wait
+ PRINTER...................... 0000:05:59 0 - wait
+ -........................ 0000:00:11 0 - wait
+ UR.................................. 0000:02:11 0 - wait
+ PUBLIC........................... 0002:02:03 0 - wait
+ task1........................ 0000:41:50 0 - -busy-
+ task2........................ 0000:03:10 0 - i/o
+ task3........................ 0000:57:28 0 1 -busy-
+
+____________________________________________________________________________
+
+
+#page#
+
+
+ #on("b")#PROC task info (INT CONST art, FILE VAR infodatei) #off("b")#
+ Wie oben, die Ausgabe wird jedoch in die Datei 'infodatei' geschrieben.
+
+____________________________________________________________________________
+
+ FILE VAR info := sequential file(output,"infodatei") ;
+ taskinfo(3, info);
+
+____________________________________________________________________________
+
+
+ #on("b")#PROC task info ( INT CONST art, stationsnr) #off("b")#
+ Ermöglicht im Netzbetrieb 'task info' über die Station mit der Nummer 'stationsnr'.
+
+____________________________________________________________________________
+
+ gib kommando :
+ taskinfo(1,12) ;
+
+____________________________________________________________________________
+#page#
+'task status'
+
+ #on("b")#PROC task status #off("b")#
+ Informationsprozedur über den Zustand der eigenen Task. Informiert über
+ - Name der Task, Datum und Uhrzeit;
+ - verbrauchte CPU-Zeit;
+ - belegten Speicherplatz;
+ - Kanal, an den die Task angekoppelt ist;
+ - Zustand der Task (rechnend u.a.m.);
+ - Priorität.
+
+ #on("b")#PROC task status (TASK CONST t) #off("b")#
+ Wie obige Prozedur, aber über die Task mit dem internen Tasknamen 't'.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ task status (public)
+
+ 15.05.87 10:30 TASK: PUBLIC
+
+ Speicher: 1234K
+ CPU Zeit: 0011.12:23
+ Zustand : wait, (Prio 0), Kanal -
+
+____________________________________________________________________________
+#page#
+
+4.2.2 Thesaurus
+
+Ein #ib#Thesaurus#ie# ist ein #ib#Namensverzeichnis#ie#, das bis zu 200 Namen beinhalten kann.
+Dabei muß jeder Namen mindestens ein Zeichen und darf höchstens 100 Zeichen
+lang sein. Steuerzeichen (code < 32) in Namen werden umgesetzt (siehe 2.9.2).
+
+Thesauri werden unter anderem von der Dateiverwaltung benutzt, um das Dateiver­
+zeichnis einer Task zu führen.
+
+Man kann einen Thesaurus selbst erstellen, indem eine Datei z.B. mit Namen von
+Dateien gefüllt wird. Diese Datei kann dann als Thesaurus für weitere Aktionen die­
+nen.
+
+
+
+- Thesaurus liefern : ALL , all , SOME , remainder
+- Auswählen : LIKE
+- Verknüpfen : + , - , /
+
+
+
+#on("b")#ACHTUNG#off("b")# : Bei der Verwendung von Thesaurus Operationen in Verbindung mit
+'fetch', 'save' etc. ist zu beachten, daß mit 'SOME', 'ALL' und 'all' zunächst nur eine
+Auswahl aus einer Liste getroffen wird. Zusätzlich muß das Ziel oder die Quelle des
+Dateitransfers vereinbart werden.
+
+Ein beliebter Fehler ist z.B.: 'fetch (ALL archive)'.
+
+Hier ist nicht weiter spezifiziert, von wo Dateien geholt werden sollen - also werden
+sie von 'father' geholt! (s. 4.2.5)
+
+Falls die Dateien vom Archiv geholt werden sollen, ist das Archiv als Quelle zu be­
+nennen:
+
+Also : 'fetch (ALL archive, archive)' = Hole alle Dateien, die in dem Thesaurus von
+ 'archive' sind von der Task 'archive'.
+#page#
+'ALL'
+ THESAURUS OP ALL (TASK CONST task)
+ Liefert einen Thesaurus, der alle Dateinamen der angegebenen Task enthält.
+
+
+
+ #on("b")#THESAURUS OP ALL (TEXT CONST dateiname) #off("b")#
+ Liefert einen Thesaurus, der die in der angegebenen Datei vorhandenen Namen
+ (jede Zeile ein Name) enthält.
+
+
+
+
+'all'
+ #on("b")#THESAURUS PROC all #off("b")#
+ Liefert einen Thesaurus, der alle Dateinamen der eigenen Task enthält. Entspricht
+ 'ALL myself'.
+
+
+
+
+'SOME'
+ #on("b")#THESAURUS OP SOME (THESAURUS CONST thesaurus) #off("b")#
+ Bietet den angegebenen Thesaurus zum editieren an. Dort können nicht erwünsch­
+ te Namen gestrichen werden.
+
+
+
+ #on("b")#THESAURUS OP SOME (TASK CONST task) #off("b")#
+ Aufruf von: SOME ALL task.
+
+
+ #on("b")#THESAURUS OP SOME (TEXT CONST dateiname) #off("b")#
+ Aufruf von: SOME ALL dateiname.
+
+#page#
+'remainder'
+ #on("b")#PROC remainder #off("b")#
+ Liefert nach einem 'errorstop' die noch nicht bearbeiteten Dateien.
+
+____________________________________________________________________________
+
+ gib kommando :
+ save all (archive)
+
+ '"....." kann nicht geschrieben werden (Archiv voll)'
+
+____________________________________________________________________________
+
+
+
+ Nachdem man eine neue Floppy ins Archivlaufwerk gelegt hat, kann man mit
+
+
+____________________________________________________________________________
+ gib kommando :
+ save (remainder, archive)
+
+____________________________________________________________________________
+
+ den Rest der Dateien auf die nächste Floppy sichern.
+#page#
+'LIKE'
+ #on("b")#THESAURUS OP LIKE (THESAURUS CONST thesaurus, TEXT CONST muster) #off("b")#
+ Alle im Thesaurus enthaltenen Dateien, die dem 'muster' entsprechen sind im
+ Ergebnisthesaurus enthalten.
+
+ (Die Syntax von 'muster' ist bei der Beschreibung des Pattern-Matching (5.4)
+ beschrieben)
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ print (all LIKE "*.p")
+
+____________________________________________________________________________
+
+
+ Alle Dateien, deren Name mit '.p' endet, werden gedruckt.
+
+#page#
+'+'
+ #on("b")#THESAURUS OP + (THESAURUS CONST links, rechts) #off("b")#
+ Liefert die Vereinigungsmenge von 'links' und 'rechts'.
+ Achtung: Die Vereinigungsmenge enthält keine Namen mehrfach.
+
+ #on("b")#THESAURUS OP + (THESAURUS CONST links, TEXT CONST rechts)#off("b")#
+ Fügt dem Thesaurus 'rechts' zu, wenn 'rechts' noch nicht im Thesaurus enthal­
+ ten ist.
+
+
+
+
+'-'
+ #on("b")#THESAURUS OP - (THESAURUS CONST links, rechts) #off("b")#
+ Liefert die Differenzmenge. Achtung: Die Differenzmenge enthält keine Namen
+ mehrfach.
+
+ #on("b")#THESAURUS OP - (THESAURUS CONST links, TEXT CONST rechts)#off("b")#
+ Nimmt den Namen 'rechts' aus dem Thesaurus.
+
+____________________________________________________________________________
+
+ gib kommando :
+ fetch(ALL father - ALL myself)
+
+____________________________________________________________________________
+
+
+'/'
+ #on("b")#THESAURUS OP / (THESAURUS CONST links, rechts) #off("b")#
+ Liefert die Schnittmenge
+ Achtung: Die Schnittmenge enthält keine Namen mehrfach.
+
+
+#page#
+
+4.2.3 Tasks
+
+Zur Identifizierung von Tasks dienen sogenannte 'interne Taskbezeichner'. Ein solcher
+Taskbezeichner wird beim Einrichten einer neuen Task vergeben. Interne Taskbe­
+zeichner sind auch unter Berücksichtigung der Zeit eindeutig.
+
+Der Zugriff auf interne Taskbezeichner erfolgt über Prozeduren und Operatoren, die
+auf Objekte des Datentyps TASK (siehe 2.9.1) angewandt werden.
+
+Zusätzlich zum internen Tasknamen, der nicht auszugeben ist, haben Tasks meistens
+einen Namen#u#1) #e#.
+#foot#
+
+1) Unbenannte Tasks haben den Pseudonamen "-".
+#end#
+
+Aus Benutzersicht können benannte Tasks innerhalb eines Rechners vollständig und
+eindeutig über ihren Namen identifiziert werden.
+
+
+- Task liefern : / , task , niltask
+
+- Verwandtschaften : brother , father , myself , son
+
+- Ausgezeichnete Tasks : archive , printer , public , supervisor
+
+- Namen liefern : name
+
+- Tasknamen ändern : rename myself
+
+- Reservieren bes. Tasks : reserve
+
+#page#
+'/'
+ #on("b")#TASK OP / (TEXT CONST taskname) #off("b")#
+ Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene Katal­
+ og wird automatisch aktualisiert
+
+ (identisch mit der PROC task (TEXT CONST taskname).
+
+ FEHLER : "taskname" gibt es nicht
+
+
+ #on("b")#TASK OP / (INT CONST station number, TEXT CONST name) #off("b")#
+ Liefert im Netzbetrieb die Task des angegebenen Namen von der Station mit der
+ angegebenen Nummer.
+
+
+
+'niltask'
+ #on("b")#TASK CONST niltask #off("b")#
+ Bezeichner für "keine Task". So liefern die Prozeduren 'son', 'brother' und 'father'
+ als Resultat 'niltask', wenn keine Sohn-, Bruder- oder Vatertask existiert.
+
+
+
+'task'
+ #on("b")#TASK PROC task (TEXT CONST taskname) #off("b")#
+ Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene Katal­
+ og wird automatisch aktualisiert.
+
+ FEHLER : "taskname" gibt es nicht
+
+
+ #on("b")#TASK PROC task (INT CONST channel number) #off("b")#
+ Liefert den Namen der Task, die an dem angegebenen Kanal hängt.
+#page#
+'brother'
+ #on("b")#TASK PROC brother (TASK CONST task) #off("b")#
+ Liefert den nächsten Bruder von 'task'. Falls kein Bruder existiert, wird 'niltask'
+ geliefert. Aktualisiert den eigenen Katalog nicht automatisch!
+
+
+
+'father'
+ #on("b")#TASK PROC father #off("b")#
+ Liefert die eigene Vatertask.
+
+
+ #on("b")#TASK PROC father (TASK CONST task) #off("b")#
+ Liefert den Vater von 'task'. Existiert kein Vater (z.B. bei UR), wird niltask gelie­
+ fert. Aktualisiert den eigenen Katalog nicht automatisch!
+
+
+
+'myself'
+ #on("b")#TASK PROC myself #off("b")#
+ Liefert eigenen Task-Bezeichner.
+
+
+
+'son'
+ #on("b")#TASK PROC son (TASK CONST task) #off("b")#
+ Liefert den ersten Sohn von 'task'. Falls keiner im Katalog vermerkt ist, wird
+ 'niltask' geliefert. Aktualisiert den eigenen Katalog nicht automatisch!
+
+
+#page#
+'archive'
+ #on("b")#TASK PROC archive #off("b")#
+ Liefert den internen Taskbezeichner der aktuellen Task mit Namen ARCHIVE.
+ Diese Prozedur dient zum schnellen und bequemen Ansprechen der Archivtask.
+
+
+
+'printer'
+ #on("b")#TASK PROC printer #off("b")#
+ Liefert den internen Taskbezeichner der aktuellen Task mit Namen #ib#PRINTER#ie#.
+ Diese Prozedur dient zum schnellen und bequemen Ansprechen des Druckspoo­
+ lers.
+
+
+'public'
+ #on("b")#TASK PROC public #off("b")#
+ Liefert den internen Taskbezeichner der Task #ib#PUBLIC#ie#.
+
+
+
+
+'supervisor'
+ #on("b")#TASK PROC supervisor #off("b")#
+ Liefert den internen Taskbezeichner des Supervisors.
+
+
+#page#
+'name'
+ #on("b")#TEXT PROC name (TASK CONST task) #off("b")#
+ Liefert den Namen von 'task'. Die Task muß noch im System existieren, sonst ist
+ der Name nicht mehr bekannt. Falls die 'task' noch nicht im eigenen Katalog
+ enthalten ist, wird er aktualisiert.
+
+
+
+'rename myself'
+ #on("b")#PROC rename myself (TEXT CONST neuer name) #off("b")#
+ Name der eigenen Task wird in 'neuer name' geändert. Wirkt wie Löschung und
+ Wiedereinrichten der Task in Bezug auf alle TASK VAR's die sich auf diese Task
+ beziehen.
+
+ FEHLER : Task existiert bereits
+ Name unzulässig
+ => anderen Namen wählen
+
+
+
+'reserve'
+ #on("b")#PROC reserve (TASK CONST task) #off("b")#
+ Reservieren einer Task für den ausschließlichen Dialog mit der Task, in der das
+ Kommando gegeben wurde.
+
+ #on("b")#PROC reserve (TEXT CONST message, TASK CONST task) #off("b")#
+ Wie 'reserve (TASK CONST task)' mit Übergabe einer 'message'.
+
+
+ Die reservierte Task muß ein spezieller Manager, (z.B. /"DOS" aus dem Werkzeug
+ MS-DOS-DAT) sein !
+#page#
+
+4.2.4 Handhabung von Dateien
+
+'copy'
+ #on("b")#PROC copy (TEXT CONST quelle, ziel) #off("b")#
+ Kopiert die Datei 'quelle' in eine neue Datei mit dem Namen 'ziel' in der Benut­
+ zer-Task.
+
+ FEHLER : "ziel" existiert bereits
+ "quelle" gibt es nicht
+ zu viele Dateien
+
+
+
+'forget'
+ #on("b")#PROC forget (TEXT CONST dateiname) #off("b")#
+ Löschen einer Datei mit dem Namen 'dateiname' in der Benutzer-Task.
+
+ FEHLER : "datei" gibt es nicht
+
+
+ #on("b")#PROC forget (THESAURUS CONST thesaurus) #off("b")#
+ Löscht die im 'thesaurus' enthaltenen Dateien in der Benutzer-Task.
+
+ Im Dialog erfolgt vor dem Löschen einer Datei standardmäßig die Abfrage:
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ forget("einedatei")
+ "einedatei" löschen(j/n) ?
+
+____________________________________________________________________________
+
+#page#
+'list'
+ #on("b")#PROC list #off("b")#
+ Listet alle Dateien der Benutzer-Task mit Namen und Datum des letzten Zugriffs
+ auf dem Terminal auf.
+
+
+ #on("b")#PROC list (TASK CONST task) #off("b")#
+ Listet alle Dateien der angegebenen 'task' mit Namen und Datum der letzten
+ Änderung auf dem Terminal auf. Die Task muß Manager sein.
+
+
+ #on("b")#PROC list (FILE VAR liste) #off("b")#
+ Listet alle Dateinamen in die Datei 'liste', die mit 'output'(s. 5.3.5) assoziiert sein
+ muß.
+
+
+ #on("b")#PROC list (FILE VAR liste, TASK CONST manager) #off("b")#
+ Listet alle Dateien der Task 'manager' mit Namen und Datum der letzten Ände­
+ rung in die Datei 'liste'.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ FILE VAR f:= sequential file (output,"list");list(f,archive)
+
+____________________________________________________________________________
+
+#page#
+'rename'
+ #on("b")#PROC rename (TEXT CONST altername, neuername) #off("b")#
+ Umbenennen einer Datei von 'altername' in 'neuername'.
+
+
+
+ FEHLER : "neuername" gibt es bereits
+ "altername" gibt es nicht
+#page#
+
+4.2.5 Editor-Prozeduren
+
+'edit'
+ #on("b")#PROC edit (TEXT CONST dateiname) #off("b")#
+ Ruft den Editor mit 'dateiname' auf.
+
+
+ #on("b")#PROC edit #off("b")#
+ a) Im Monitor:
+ Ruft den Editor mit den zuletzt verwandten Dateinamen auf.
+
+ b) Im Editor:
+ Der Dateiname wird erfragt.
+
+ Für jedes 'edit' gilt:
+ Wurde 'edit' zum ersten Mal aufgerufen, nimmt das Fenster den gesamten Bild­
+ schirm ein. Bei erneutem 'edit'-Aufruf wird ein Fenster nach rechts unten ab der
+ aktuellen Cursor-Position eröffnet.
+
+
+ #on("b")#PROC edit (THESAURUS CONST t) #off("b")#
+ Editieren aller in dem Thesaurus 't' enthaltenen Dateien nacheinander.
+
+
+ Weitere 'edit-Prozeduren', die z.B. Variation der Fenstergröße etc. zulassen, sind
+ in 5.4.6 beschrieben.
+
+#page#
+'editget'
+ #on("b")#PROC editget (TEXT VAR editsatz) #off("b")#
+ Ausgabe einer (Kommando)zeile, in der Editorfunktionen zur Verfügung
+ stehen siehe Teil 5.5.1.4.
+
+
+
+'show'
+ #on("b")#PROC show (TEXT CONST dateiname) #off("b")#
+ Die Datei wird am Bildschirm gezeigt. Positionierung und Suchen funktionieren wie
+ in 'edit', Aktionen die Änderungen in der Datei bewirken würden, werden nicht
+ angenommen.
+
+
+
+ #on("b")#PROC show #off("b")#
+ 'show' auf der zuletzt bearbeiteten Datei.
+
+#page#
+'kommando auf taste legen'
+ #on("b")#PROC kommando auf taste legen (TEXT CONST taste, elan programm)#off("b")#
+ Die Taste 'taste' wird mit dem angegebenen ELAN-Programm belegt. Durch <ESC>
+ <taste> wird das Programm direkt ausgeführt.
+
+____________________________________________________________________________
+
+ gib kommando :
+ kommando auf taste legen ("a","fetch (SOME archive,archive)")
+
+____________________________________________________________________________
+
+
+
+'kommando auf taste'
+ #on("b")#TEXT PROC kommando auf taste (TEXT CONST taste)#off("b")#
+ Falls 'taste' mit einem ELAN-Programm belegt ist, liefert die Prozedur den
+ Programmtext, andernfalls den leeren Text niltext.
+
+____________________________________________________________________________
+
+ gib kommando :
+ put (kommando auf taste("f"))
+
+____________________________________________________________________________
+
+
+
+'taste enthaelt kommando'
+ #on("b")#BOOL PROC taste enthaelt kommando (TEXT CONST taste)#off("b")#
+ Liefert TRUE falls 'taste' mit einem ELAN-Programm belegt ist.
+
+
+'lernsequenz auf taste legen'
+ #on("b")#PROC lernsequenz auf taste legen (TEXT CONST taste, sequenz)#off("b")#
+ 'taste' wird mit der Zeichenfolge 'sequenz' belegt. Durch <ESC> <taste> wird die
+ Zeichenfolge an der aktuellen Position ausgegeben.
+
+ Als Zeichenfolge sind natürlich auch einzelne Zeichen und EUMEL-Codes zuläs­
+ sig.
+
+ Die vom System vorbelegten Tasten sind in 3.4 'Zeichen schreiben' aufgelistet.
+
+____________________________________________________________________________
+
+ gib kommando :
+ lernsequenz auf taste legen ("x","gib kommando :"13""2""2"")
+
+____________________________________________________________________________
+
+
+
+'lernsequenz auf taste'
+ #on("b")#TEXT PROC lernsequenz auf taste (TEXT CONST taste) #off("b")#
+ Liefert die auf 'taste' gelegte Zeichenfolge.
+
+
+'std tastenbelegung'
+ #on("b")#PROC std tastenbelegung #off("b")#
+ Die Standard-Tastenbelegung (s.3.4) wird (wieder) hergestellt.
+
+
+'word wrap'
+ #on("b")#PROC word wrap (BOOL CONST b) #off("b")#
+ Der automatische Zeilenumbruch wird durch 'word wrap (FALSE)' aus- und durch
+ 'word wrap (TRUE)' eingeschaltet. Wird diese Prozedur während des Editierens
+ aufgerufen, gilt die Einstellung für die aktuelle Textdatei. Wird die Prozedur als
+ Monitor-Kommando gegeben, so gilt die Eingabe als Voreinstellung für neue
+ Dateien.
+#page#
+
+4.2.6 Dateitransfer
+
+Unter diesem Abschnitt sind diejenigen Prozeduren beschrieben, die der simplen
+Kommunikation mit Manager-Tasks dienen: Holen oder Senden einer Dateikopie,
+Löschen in der Manager-Task.
+
+#on("b")#ACHTUNG : Für alle Prozeduren gilt: falls die Manager-Task nicht existiert, wird eine
+Fehlermeldung erzeugt, existiert eine Task des angegebenen Namens, die aber nicht
+Managertask ist, so terminieren die Prozeduren nicht!
+#off("b")#
+
+
+'fetch'
+ #on("b")#PROC fetch (TEXT CONST dateiname, TASK CONST manager) #off("b")#
+ Kopiert die Datei 'dateiname' aus der Task 'manager'
+
+
+ #on("b")#PROC fetch (THESAURUS CONST th, TASK CONST manager) #off("b")#
+ Kopiert alle Dateien, deren Namen im Thesaurus th enthalten sind, aus der Task
+ 'manager'.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ fetch(ALL(12/"PUBLIC"), 12/"PUBLIC")
+
+____________________________________________________________________________
+
+
+
+ Mit diesem Kommando werden (in einem EUMEL Netz) alle Dateien der Task
+ 'PUBLIC' des Rechners mit der Stationsnummer 12 in diesem Netz kopiert.
+
+#page#
+____________________________________________________________________________
+
+ gib kommando :
+ fetch(SOME archive , archive)
+
+____________________________________________________________________________
+
+
+
+ Bietet den Thesaurus von 'ARCHIVE' an, nach Auswahl werden alle Dateien deren
+ Namen nicht gelöscht wurden, von der Diskette kopiert.
+
+
+ #on("b")#PROC fetch (TEXT CONST dateiname) #off("b")#
+ Kopiert die Datei 'dateiname' aus der Task 'father'
+
+
+ #on("b")#PROC fetch (THESAURUS CONST th) #off("b")#
+ Kopiert alle Dateien, deren Namen in 'th' sind aus der Task 'father'.
+
+
+
+'fetchall'
+
+ #on("b")#PROC fetchall #off("b")#
+ entspricht: fetch (ALL father, father)
+
+
+ #on("b")#PROC fetchall (TASK CONST manager)#off("b")#
+ entspricht: fetch(ALL manager, manager)
+
+#page#
+'save'
+ #on("b")#PROC save (TEXT CONST dateiname, TASK CONST manager) #off("b")#
+ Kopiert die Datei 'dateiname' in die Task 'manager'
+
+
+ #on("b")#PROC save (THESAURUS CONST th, TASK CONST manager) #off("b")#
+ Kopiert alle Dateien, deren Namen im Thesaurus th enthalten sind, in die Task
+ 'manager'.
+
+____________________________________________________________________________
+
+ gib kommando :
+ save(all, (12/"PUBLIC"))
+
+____________________________________________________________________________
+
+
+ Mit diesem Kommando werden (in einem EUMEL Netz) alle Dateien der eigenen
+ Task in die Task 'PUBLIC' des Rechners mit der Stationsnummer 12 in diesem
+ Netz kopiert.
+
+____________________________________________________________________________
+
+ gib kommando :
+ save(SOME myself, manager)
+
+____________________________________________________________________________
+
+
+ Bietet den eigenen Thesaurus an, nach Auswahl werden alle Dateien deren
+ Namen nicht gelöscht wurden, zur Task 'manager' kopiert.
+
+
+ #on("b")#PROC save (TEXT CONST dateiname) #off("b")#
+ Kopiert die Datei 'dateiname' in die Task 'father'
+
+
+ #on("b")#PROC save (THESAURUS CONST th) #off("b")#
+ Kopiert alle Dateien, deren Namen in 'th' enthalten sind, in die Task 'father'.
+
+
+ #on("b")#PROC save #off("b")#
+ Kopiert die zuletzt bearbeitete Datei in die Task 'father'
+
+
+
+
+'saveall'
+ #on("b")#PROC saveall #off("b")#
+ entspricht: save (all, father)
+
+
+ #on("b")#PROC saveall (TASK CONST manager) #off("b")#
+ entspricht: save (ALL myself, manager)
+
+#page#
+'erase'
+ #on("b")#PROC erase (TEXT CONST dateiname, TASK CONST manager) #off("b")#
+ Löscht die Datei 'dateiname' aus der Task 'manager'
+
+
+ #on("b")#PROC erase (THESAURUS CONST th, TASK CONST manager) #off("b")#
+ Löscht alle Dateien, deren Namen im Thesaurus th enthalten sind, aus der Task
+ 'manager'.
+
+
+ #on("b")#PROC erase (TEXT CONST dateiname) #off("b")#
+ Löscht die Datei 'dateiname' aus der Task 'father'
+
+
+ #on("b")#PROC erase (THESAURUS CONST th) #off("b")#
+ Löscht alle Dateien, deren Namen in 'th' sind, aus der Task 'father'
+
+
+ #on("b")#PROC erase #off("b")#
+ Löscht die zuletzt bearbeitete Datei aus der Task 'father'
+
+
+#page#
+'print'
+ Das Kommando 'print' beinhaltet den Auftrag an die Task 'PRINTER' die enthal­
+ tene(n) Datei(en) auszudrucken.
+
+ Voraussetzung ist natürlich, daß die Druckersoftware ordnungsgemäß benutzt
+ wurde, um 'PRINTER' einzurichten. Siehe dazu Systemhandbuch Teil 6.
+
+
+ #on("b")#PROC print (TEXT CONST dateiname) #off("b")#
+ Kopiert die Datei 'dateiname' in die Task 'PRINTER'.
+
+
+ #on("b")#PROC print (THESAURUS CONST th) #off("b")#
+ Kopiert alle Dateien, deren Namen im Thesaurus 'th' enthalten sind, in die Task
+ 'PRINTER'.
+
+
+ #on("b")#PROC print #off("b")#
+ Kopiert die zuletzt bearbeitete Datei in die Task 'PRINTER'.
+
+
+#page#
+
+4.2.7 Passwortschutz
+
+Der Passwortschutz im EUMEL-System ist in verschiedener Ausprägung möglich.
+Einfachste Möglichkeit ist der Schutz einer Task durch ein Passwort. Falls diese Task
+nicht Manager ist, können alle Daten und Programme, die nur in dieser Task zur
+Verfügung stehen, auch nur vom Besitzer der Task benutzt werden.
+
+Ähnlich kann auch von einer Manager-Task aus der gesamte Zweig unterhalb dieser
+Task mit einem Passwort geschützt werden: beispielsweise kann es empfehlenswert
+sein, den Systemzweig komplett zu schützen, indem in SYSUR ein entsprechendes
+Passwort vereinbart wird.
+
+Ein Umgehen des Passwortschutzes bei Manager-Tasks (durch Einrichten einer
+Sohn-Task und 'fetchall') wird durch ein 'begin password' verhindert.
+
+Auch einzelne Dateien lassen sich schützen, indem Lese/Schreibpasswörter für den
+Dateitransfer vereinbart werden.
+
+Generell gilt für die Verwendung von Passworten:
+
+- Passworte, die zu naheliegend gewählt sind (Vorname des Lebenspartners o.ä.)
+ sind meistens sinnlos, falls wirklich Datenschutz bezweckt ist.
+
+- Passworte, die so raffiniert sind, daß sogar ihr Schöpfer sie vergißt, führen zu
+ 100%igem Datenverlust, da die betroffene Task oder Datei nur noch gelöscht
+ werden kann.
+
+- Die Vereinbarung von "-" als Passwort bewirkt, daß die entsprechende Aktion
+ nicht mehr durchgeführt werden kann. Wird z.B. '-' als 'task password'
+ eingegeben, so kann die Task nie wieder an ein Terminal gekoppelt werden.
+
+- Passwörter können geändert werden, indem das entsprechende Kommando noch
+ einmal mit dem neuen Passwort gegeben wird.
+
+#page#
+'begin password'
+
+ #on("b")#PROC begin password (TEXT CONST passwort) #off("b")#
+
+ Auf Supervisor-Ebene wird vor Einrichten einer neuen Task als Sohn der Task in
+ der das 'begin password' gegeben wurde, dieses erfragt.
+
+ Das Password vererbt sich auf die hinzukommenden Sohn-Tasks.
+
+____________________________________________________________________________
+
+ #on("b")#SYSUR#off("b")#
+ maintenance :
+ begin password ("alles dicht")
+
+____________________________________________________________________________
+
+
+bewirkt:
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8.1/M
+
+
+ gib supervisor kommando:
+ begin ("sabotage","SYSUR")
+ Passwort:
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+
+____________________________________________________________________________
+
+
+#page#
+'enter password'
+ #on("b")#PROC enter password (TEXT CONST datei, schreibpass, lesepass)
+ #off("b")#
+ Hiermit können ausgewählte Dateien einer Manager-Task geschützt werden. Die
+ angegebene Datei wird mit Schreib- und Lesepassword versehen. Die Pass­
+ wörter werden in der eigenen Task nicht berücksichtigt.
+
+ Bei einem lesenden Zugriff (fetch) von irgendeiner Task aus auf die entsprechende
+ Datei in der Manager-Task muß das Lesepasswort, bei schreibendem Zugriff
+ (save/erase) das Schreibpasswort vereinbart sein.
+
+
+____________________________________________________________________________
+
+ maintenance :
+ enter password ("wichtige datei","sicher","heit")
+
+____________________________________________________________________________
+
+
+
+
+ #on("b")#PROC enter password (TEXT CONST password) #off("b")#
+ Passwort für den Dateitransfer einstellen. Falls zwei verschiedene Passwörter für
+ Lesen und Schreiben vereinbart werden sollen, so sind sie als ein Text durch "/"
+ getrennt einzugeben.
+
+____________________________________________________________________________
+
+ gib kommando :
+ enter password ("sicher/heit")
+
+ gib kommando :
+ save(SOME all)
+
+____________________________________________________________________________
+#page#
+'family password'
+ #on("b")#PROC family password (TEXT CONST geheim) #off("b")#
+ Einstellen eines Passworts für den Zweig des Systems , der unterhalb der (Mana­
+ ger) Task liegt, in der das 'family password' eingegeben wurde. Dabei erhalten
+ alle Tasks, die kein Password oder dasselbe wie diese Manager-Task haben, das
+ 'family password'. Tasks in dem Zweig, die ein eigenes anderes besitzen, behal­
+ ten dieses.
+
+____________________________________________________________________________
+
+ PUBLIC
+
+ Task1 ""
+
+ Task2 family password("fingerweg")
+ Task21 geheim
+ Task22 ""
+
+ Task3 ""
+ Task31 ""
+
+____________________________________________________________________________
+
+
+
+
+bewirkt:
+
+____________________________________________________________________________
+ PUBLIC
+
+ Task1 ""
+
+ Task2 fingerweg
+ Task21 geheim
+ Task22 fingerweg
+
+ Task3 ""
+ Task31 ""
+
+____________________________________________________________________________
+
+
+#page#
+
+'task password'
+
+ #on("b")#PROC task password (TEXT CONST geheim) #off("b")#
+ Einstellen eines Passworts für die Task in der es gegeben wird. Ist eine Task mit
+ einem Passwort geschützt, so wird durch den Supervisor nach dem 'continue'-
+ Kommando das Passwort angefragt (Entsprechend dem 'begin password'). Nur
+ nach Eingabe des richtigen Passworts gelangt man in die gewünschte Task. Das
+ Passwort kann durch nochmaligen Aufruf von 'task password' geändert werden,
+ z.B. wenn es in regelmäßigen Abständen geändert werden muß, um personenbe­
+ zogene Daten zu schützen.
+
+#page#
+
+4.2.8 Das Archiv
+
+Mit dem Terminus 'Archiv' wird beim EUMEL-System ein Diskettenlaufwerk bezeich­
+net, das nur Datensicherungsaufgaben dient. Falls ein Rechner eins von zwei vorhan­
+denen Diskettenlaufwerk als Arbeitsspeicher benutzt, so wird dieses als Hintergrund
+bezeichnet. Falls Sie einen derartigen Rechner benutzen, können Sie der Installa­
+tionsanleitung entnehmen, welches Laufwerk welcher Aufgabe zugeordnet ist.
+
+Das #ib#Archiv#ie# übernimmt im EUMEL-System die Verwaltung der langfristigen Daten­
+haltung. Das Archiv sollen Sie benutzen, um:
+
+- Sicherungskopien wichtiger Dateien außerhalb des Rechners zu besitzen;
+
+- nicht benötigte Dateien außerhalb einer Task zu halten (Speicherplatzersparnis!);
+
+- Dateien auf andere Rechner zu übertragen.
+
+Das Archiv wird im EUMEL-System durch die Task 'ARCHIVE', die das Disketten­
+laufwerk des Rechners verwaltet, realisiert.
+
+- reservieren : archive
+
+- freigeben : release
+
+- löschen : clear , format
+
+- prüfen : check
+
+#page#
+'archive'
+ #on("b")#PROC archive (TEXT CONST archivname) #off("b")#
+ Reservierung der Task ARCHIVE für den exklusiven Dialog mit der aufrufenden
+ Task. 'archivname' wird bei allen folgenden Archivoperationen mit dem der Disket­
+ te zugewiesenen (und hoffentlich auf dem Aufkleber vermerkten) Namen abgegli­
+ chen.
+
+
+
+'release'
+ #on("b")#PROC release (TASK CONST archive) #off("b")#
+ Nach diesem Kommando kann die Task 'ARCHIVE' mit ihren Leistungen von einer
+ anderen Task in Anspruch genommen werden. Falls dieses Kommando nicht
+ gegeben wird, aber seit 5 Minuten kein Dialog mit 'archive' stattfand, kann eine
+ andere Task durch die Anforderung 'archive("diskettenname")' das Archiv reser­
+ vieren. Durch diese Maßnahme wird verhindert, daß ein vergeßlicher Benutzer bei
+ einem System mit mehreren Benutzern das Archiv blockiert.
+
+#page#
+
+'clear'
+ #on("b")#PROC clear (TASK CONST archive) #off("b")#
+ Löschen des Disketten-Inhaltsverzeichnisses und Zuweisung des in der Reservie­
+ rung eingegebenen Namens.
+
+____________________________________________________________________________
+
+ gib kommando :
+ archive("name"); #ib#clear#ie# (archive)
+
+____________________________________________________________________________
+
+
+ Durch die Ausführung des Kommandos erhält die eingelegte Diskette den in der
+ Reservierung angegebenen Namen. #on("b")#Das Inhaltsverzeichnis, das sich auf der
+ Diskette befindet, wird gelöscht. Damit sind die Daten, die sich eventuell auf
+ dieser Diskette befanden, nicht mehr auffindbar#off("b")#. Die Diskette entspricht einer neu
+ formatierten Diskette#u#1)#e#.
+
+ Man kann also eine beschriebene Diskette nicht umbenennen, ohne die darauf
+ befindlichen Daten zu löschen.
+
+ #foot#
+
+ #u#1)#e# Das Kommando 'format' enthält implizit 'clear'.
+#end#
+
+ Eine Neuformatierung ist demnach bei Wiederverwendung der Diskette nicht
+ notwendig.
+
+#page#
+'format'
+ #on("b")#PROC format (TASK CONST archive) #off("b")#
+ Formatieren einer Diskette. Vor der erstmaligen Benutzung einer Archivdiskette
+ muß diese formatiert, d.h. in Spuren und Sektoren für die Positionierung des
+ Schreib-/Lesekopfes des Diskettenlaufwerks eingeteilt werden, um überhaupt ein
+ Beschreiben der Diskette zu ermöglichen. Die Einteilung ist geräteabhängig, häufi­
+ ge Formate sind:
+
+ 40 Spuren zu je 9 Sektoren (360 K)
+ 80 Spuren zu je 9 Sektoren (720 K).
+
+ Die #on("b")#Erst#off("b")#benutzung einer #ib#Archivdiskette#ie# erfordert nach der Reservierung des Ar­
+ chivs das Kommando:
+
+____________________________________________________________________________
+
+ gib kommando :
+ archive("diskname");
+
+ gib kommando :
+ format (archive);
+
+____________________________________________________________________________
+
+
+Erst nach einer Kontrollabfrage:
+
+____________________________________________________________________________
+
+ gib kommando:
+ format (archive)
+
+ Archiv "diskname" formatieren ? (j/n)
+
+____________________________________________________________________________
+
+
+
+ wird tatsächlich formatiert und die Diskette steht mit dem Namen "diskname" für
+ Archivoperationen zur Verfügung.
+
+#page#
+
+ #on("b")#PROC format (INT CONST code, TASK CONST archive) #off("b")#
+ Bei einigen Rechnern ist es möglich, die Formatierung zu variieren. Falls beim
+ Formatieren auf einem solchen Rechner ein anderes als das Standardformat
+ erzeugt werden soll, so ist die Codierung des gewünschten Formats mitanzuge­
+ ben.
+
+
+ Beispiel: Für ein Gerät mit 5,25 Zoll Disketten wäre z.B. einstellbar:
+ code 0 : Standardformat
+ code 1 : 2D , 40 Spuren , 9 Sektoren
+ code 2 : 2D , 80 Spuren , 9 Sektoren
+ code 3 : HD , 80 Spuren ,15 Sektoren
+
+ 'format (archive)' erzeugt ebenso wie 'format (0,archive)' eine
+ standardformatierte Diskette, 'format (3,archive)' erzeugt eine High
+ Density Formatierung (HD Floppy benutzen!).
+
+#on("b")#
+ ACHTUNG: Wird eine bereits beschriebene Diskette noch einmal formatiert, so
+ sind alle Daten, die auf der Diskette waren, verloren.
+
+ Die Umformatierung einer Diskette (z.B. von 720K auf 360K) auf
+ unterschiedlichen Laufwerken kann zu Problemen führen.
+#off("b")#
+#page#
+'check'
+ #on("b")#PROC check (TEXT CONST dateiname, TASK CONST task) #off("b")#
+ Überprüft, ob die Datei 'dateiname' auf dem Archiv lesbar ist.
+
+
+ #on("b")#PROC check (THESAURUS CONST t, TASK CONST task) #off("b")#
+ Überprüft, ob die in dem Thesaurus 't' enthaltenen Dateien auf dem Archiv lesbar
+ sind.
+
+
+ Mit diesem Kommando kann nach dem Beschreiben einer Diskette überprüft wer­
+ den, ob die Datei(en) lesbar sind. Hierdurch können also verschmutzte oder
+ beschädigte Disketten erkannt werden.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ save (all , archive)
+
+ gib kommando :
+ check (ALL archive, archive)
+
+____________________________________________________________________________
+
+#page#
+
+Beispiel:
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ archive ("neu")
+
+ gib kommando :
+ format (archive)
+
+____________________________________________________________________________
+
+
+liefert zunächst die Kontollfrage:
+
+____________________________________________________________________________
+
+ gib kommando :
+ format (archive)
+
+ Archiv "neu" formatieren ? (j/n)
+
+____________________________________________________________________________
+
+
+Nach Eingabe 'j'
+
+____________________________________________________________________________
+
+ gib kommando :
+ saveall (archive)
+
+ gib kommando :
+ archive("alt") (* nächste Diskette *)
+
+ gib kommando :
+ fetch(SOME archive ,archive)
+
+____________________________________________________________________________
+
+
+Der Thesaurus des Archivs wird angezeigt:
+#page#
+____________________________________________________________________________
+
+ .................alt (100 K belegt von 720 K)...............
+
+ 01.02.87 25 K "handbuch teil 1"
+ 01.03.87 23 K "handbuch teil 2"
+ 01.04.87 20 K "handbuch teil 3"
+ 01.05.87 32 K "handbuch teil 4"
+
+____________________________________________________________________________
+
+
+
+
+
+Zum Abschluß Archiv freigeben!
+____________________________________________________________________________
+
+ gib kommando :
+ release(archive)
+
+____________________________________________________________________________
+#page#
+
+Fehlermeldungen des Archivs
+Versucht man, eine Datei vom Archiv zu holen, kann es vorkommen, daß das Ar­
+chiv-System
+
+____________________________________________________________________________
+
+ gib kommando :
+ fetch ("datei", archive)
+ #ib#Lese-Fehler (Archiv)#ie#
+
+____________________________________________________________________________
+
+
+
+meldet und den Lese-Vorgang abbricht. Dies kann auftreten, wenn die Floppy
+beschädigt oder aus anderen Gründen nicht lesbar ist (z.B. nicht justierte Disket­
+ten-Geräte). In einem solchen Fall vermerkt das Archiv-System intern, daß die Datei
+nicht korrekt gelesen werden kann. Das sieht man z.B. bei 'list (archive)'. Dort ist der
+betreffende Datei-Name mit dem Zusatz 'mit Lese-Fehler' gekennzeichnet. Um
+diese Datei trotzdem zu lesen, muß man sie unter ihrem Dateinamen mit dem Zusatz
+'mit Lese-Fehler' lesen.
+
+____________________________________________________________________________
+
+ gib kommando:
+ fetch ("datei mit Lese-Fehler", archive)
+
+____________________________________________________________________________
+
+
+
+Die Datei wird in diesem Fall trotz Lese-Fehler (Informationsverlust!) vom Archiv
+gelesen.
+#page#
+
+Weitere Fehlermeldungen des Archivs:
+
+
+FEHLER : Lesen unmöglich (Archiv)
+ Die Archiv-Diskette ist nicht eingelegt oder die Tür des Laufwerks ist nicht
+ geschlossen.
+ => Diskette einlegen bzw. Tür schließen.
+
+FEHLER : Schreiben unmöglich (Archiv)
+ Die Diskette ist schreibgeschützt.
+ => falls wirklich gewünscht, Schreibschutz entfernen.
+
+FEHLER : Archiv nicht angemeldet
+ Das Archiv wurde nicht angemeldet
+ => 'archive ("name")' geben.
+
+FEHLER : Lese-Fehler (Archiv)
+ Siehe Lesen unmöglich
+
+FEHLER : Schreibfehler (Archiv)
+ Die Diskette kann nicht (mehr) beschrieben werden.
+ => Andere Diskette verwenden.
+
+FEHLER : Speicherengpass
+ Im System ist nicht mehr genügend Platz, um eine Datei vom Archiv zu
+ laden.
+ => ggf. Dateien löschen.
+
+FEHLER : RERUN bei Archiv-Zugriff Das System wurde bei einer Archiv-Operation
+ durch Ausschalten bzw. Reset unterbrochen.
+
+FEHLER : "dateiname" gibt es nicht
+ Die Datei "dateiname" gibt es nicht auf dem Archiv.
+ => mit 'list(archive)' Archiv prüfen.
+
+FEHLER : Archiv heißt ...
+ Die eingelegte Diskette hat einen anderen als den eingegebenen Archivna­
+ men.
+ => Kommando 'archive' mit korrektem Namen geben.
+
+FEHLER : Archiv wird von Task ... benutzt
+ Das Archiv wurde von einem anderen Benutzer reserviert.
+ => Abwarten.
+
+FEHLER : "dateiname" kann nicht geschrieben werden (Archiv voll)
+ Die Datei ist zu groß für die eingelegte Diskette.
+ => Andere Diskette für diese Datei nehmen.
+
+FEHLER : Archiv inkonsistent
+ Die eingelegte Diskette hat nicht die Struktur einer Archiv-Diskette.
+ => 'format (archive)' vergessen.
+
+FEHLER : save/erase wegen Lese-Fehler verboten
+ Bei Archiven mit Lese-Fehler sind Schreiboperationen verboten, weil ein
+ Erfolg nicht garantiert werden kann.
+
diff --git a/doc/programming/programmierhandbuch.5 b/doc/programming/programmierhandbuch.5
new file mode 100644
index 0000000..a921572
--- /dev/null
+++ b/doc/programming/programmierhandbuch.5
@@ -0,0 +1,1329 @@
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 5 : Programmierung
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+5 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#5 - %
+#end#
+
+TEIL 5: Programmierung
+
+
+5.1 Der ELAN-Compiler
+
+Der ELAN-Compiler des EUMEL-Systems dient zweierlei Aufgaben: zum einen der
+Übersetzung von ELAN-Programmen, zum anderen der Verwaltung der taskeigenen
+Modulbibliothek.
+
+Diese Moduln, in ELAN Pakete (siehe 2.4.3.4ff.) genannt, stellen als vorübersetzte,
+und damit abrufbereite#u#1)#e# Prozeduren den Kommandovorrat einer Task dar.
+
+Der Codebereich einer Task liegt in ihrem Standarddatenraum (ds4). Die Größe dieses
+Codebereiches beträgt 256K. Der Inhalt besteht zunächst aus den von der Vatertask
+ererbten (durch Kopie des ds4 dieser Task) Moduln, im weiteren allen in dieser Task
+neu hinzu insertierten Packeten.
+#on("b")#
+
+
+ACHTUNG: Durch ständiges Neuinsertieren eines Packets kann der
+ Codebereich der betroffenen Task zum Überlaufen
+ gebracht werden!
+
+
+#foot#
+
+1) Die von anderen Systemen her gewohnten Phasen 'Binden' und 'Laden' sind
+ durch das EUMEL-ELAN-Compiler-Konzept unnötig.
+#end#
+Jedes Kommando im EUMEL-System ist der Aufruf einer, in der Schnittstelle eines
+bereits insertierten Packetes stehenden, Prozedur.
+
+Kommandos für den ELAN-Compiler:
+
+- Übersetzen : do , insert , run , runagain
+
+- Protokollieren : check , checkon/off ,
+ prot , protoff , warnings on/off
+
+
+#page#
+'do'
+ #on("b")#PROC do (TEXT CONST program)#off("b")#
+ Übersetzen und Ausführen von 'program' von einem Programm aus. 'program'
+ muß ein ausführbares ELAN Programm sein.
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ PACKET reo DEFINES reorganize all:
+
+ PROC reorganize all(THESAURUS CONST thes):
+ do (PROC (TEXT CONST) reorganize ,thes)
+ (* Die Prozedur 'reorganize' (siehe 5-52), die einen*)
+ (* Dateinamen als Parameter verlangt, wird auf alle *)
+ (* Dateien des Thesaurus 'thes' angewandt. *)
+ END PROC reorganize all;
+ END PACKET reo;
+
+____________________________________________________________________________
+
+
+'insert'
+ #on("b")#PROC insert (TEXT CONST dateiname) #off("b")#
+ Insertieren eines oder mehrerer PACKETs aus der Datei 'dateiname'. Der Pro­
+ grammtext muß sich in #on("u")#einer#off("u")# Datei befinden.
+
+
+ #on("b")#PROC insert #off("b")#
+ Insertieren eines oder mehrerer PACKETs. Der Dateiname ist der zuletzt benutzte
+ Dateiname.
+
+
+ #on("b")#PROC insert (THESAURUS CONST t) #off("b")#
+ Insertieren aller PACKETs, die in den Dateien des Thesaurus 't' enthalten sind.
+
+
+#page#
+'run'
+ #on("b")#PROC run #off("b")#
+ Übersetzen und Ausführen eines ELAN-Programms. Der Programmtext muß sich
+ in einer Datei befinden. Der Dateiname ist der zuletzt benutzte Dateiname.
+
+
+ #on("b")#PROC run (TEXT CONST dateiname) #off("b")#
+ Wie oben. Der Programmtext wird aus der Datei mit dem Namen 'dateiname'
+ geholt.
+
+
+
+'runagain'
+ #on("b")#PROC runagain #off("b")#
+ Nochmaliges Ausführen des zuletzt mit 'run' übersetzten ELAN-Programms.
+ Wurde in der letzten Übersetzung ein Fehler gefunden, erfolgt die Meldung:
+
+ FEHLER : "run again nicht möglich"
+
+#page#
+'check'
+ #on("b")#BOOL PROC check #off("b")#
+ Informationsprozedur, die TRUE liefert, wenn 'check' eingeschaltet ist.
+
+ #on("b")#PROC check on #off("b")#
+ Einschalten der Generierung von Zeilennummern durch den ELAN-Compiler. Der
+ bei der Übersetzung erzeugte Code wird ca. 25% umfangreicher!
+ Voreinstellung im 'PUBLIC'- Zweig: 'check on'.
+
+ #on("b")#PROC check off #off("b")#
+ Ausschalten der Generierung von Zeilennummern durch den ELAN-Compiler.
+ Voreinstellung im 'SYSUR' - Zweig: 'check off.
+
+
+'prot'
+ #on("b")#BOOL PROC prot #off("b")#
+ Informationsprozedur, die TRUE liefert, gdw. 'prot' eingeschaltet ist.
+
+ #on("b")#PROC prot (TEXT CONST dateiname) #off("b")#
+ Einschalten des Compilerlistings auf dem Bildschirm. Das Listing wird gleichzeitig
+ in die Datei 'dateiname' geschrieben.
+
+ #on("b")#PROC prot off #off("b")#
+ Ausschalten des Listings.
+
+
+'warnings'
+ #on("b")#BOOL PROC warnings #off("b")#
+ Informationsprozedur, die TRUE liefert gdw. 'warnings' eingeschaltet ist.
+
+ #on("b")#PROC warnings on #off("b")#
+ Warnungen werden wie Fehlermeldungen ins Notizbuch ausgegeben.
+
+ #on("b")#PROC warnings off#off("b")#
+ Warnungen werden nicht mit in das Notizbuch ausgegeben.
+#page#
+
+5.1.1 Fehlermeldungen des ELAN-Compilers
+erfolgen stets in der Form:
+
+#ib#COMPILER ERROR#ie#: <zahl>
+
+wobei <zahl> folgende Werte annehmen kann:
+
+#on("bold")#<zahl> Bedeutung und eventuelle Abhilfe#off ("bold")#:
+
+ 101 Überlauf der Namenstabelle
+ Die Anzahl der Namen aller sichtbaren Pakete ist zu groß oder es wurden
+ die Anführungstriche eines TEXT-Denoters vergessen.
+ => Keine Abhilfe.
+
+ 102 Überlauf der Symboltabelle
+ Die Anzahl der deklarierten Objekte ist zu groß.
+ => Programm in Pakete unterteilen.
+
+ 103 Überlauf des Zwischencodebereiches
+ => Programm in Pakete unterteilen.
+
+ 104 Überlauf der Permanenttabelle
+ Zu viele Pakete insertiert.
+ => Keine (neue Task beginnen).
+
+ 106 Paketdatenadresse zu groß
+ Im Paket wird zuviel Platz ( > 64K ) von globalen Datenobjekten und
+ Denotern eingenommen.
+ => Keine Abhilfe.
+
+ 107 Lokale Datenadresse zu groß
+ Im Paket wird zuviel Platz ( > 32K ) von lokalen Datenobjekten belegt.
+ => Keine Abhilfe.
+ #page#
+ 204 Überlauf des Compilerstack
+ => Keine Abhilfe.
+
+ 301 Modulnummern-Überlauf
+ Zu viele sichtbare Pakete, Prozeduren und Operatoren ( > 2048 ).
+ => Keine Abhilfe.
+
+ 303
+ siehe 304
+
+ 304 Zu viele Ansprungadressen
+ In dem gerade übersetzten Modul (Prozedur, Operator oder Paketrumpf)
+ werden vom Compiler zu viele Marken benötigt (mehr als 2000). Marken
+ werden z.B. für die Codegenerierung von Auswahl (IF ...) und Wieder­
+ holung (REP ...) gebraucht. Insbesondere bei SELECT-Anweisungen
+ werden 'casemax - casemin + 2' Marken benötigt, wobei 'casemax' der
+ INT-Wert des maximalen, 'casemin' der des minimalen CASE-Wertes
+ ist. Dieser Fehler ist somit fast immer auf zu viele und/oder zu weit ge­
+ spannte SELECT-Anweisungen zurückzuführen.
+ => SELECT-Anweisungen über mehrere Prozeduren verteilen oder
+ Spannweiten verringern.
+
+ 305 Codeüberlauf
+ Der insgesamt erzeugte sichtbare Code ist zu umfangreich ( > 256K ).
+ => Keine Abhilfe.
+
+ 306 Paketdatenadresse zu groß
+ Insgesamt zu viele Datenobjekte in den Paketen ( > 128K ).
+ => Keine Abhilfe.
+
+ 307 Temporäre Datenadresse zu groß
+ Zu viele (lokale) Datenobjekte in einer Prozedur ( > 32K ).
+ => Prozedur in mehrere unterteilen, so daß die Datenobjekte sich über
+ mehrere Prozeduren verteilen.
+
+ 308 Modulcode-Überlauf
+ Ein Modul (Prozedur, Operator oder Paket-Initialisierungsteil) ist zu groß
+ ( > 7.5 KB Code).
+ => In mehrere Prozeduren oder Pakete zerlegen.
+
+ 309 Zuviele Paketdaten
+ (Insgesamt mehr als 128K Paketdaten)
+ => Keine Abhilfe
+
+
+#page#
+
+5.2 Standardtypen
+
+
+5.2.1 Bool
+
+Der Wertebereich für Datenobjekte vom Typ BOOL besteht aus den Werten TRUE
+und FALSE.
+
+'AND'
+ #on("b")#BOOL OP AND (BOOL CONST a, b) #off("b")#
+ Logisches UND, liefert TRUE gdw. a und b TRUE sind.
+
+
+'CAND'
+ #on("b")#BOOL OP CAND #off("b")#
+ Bedingtes logisches UND, entspricht: 'IF a THEN b ELSE false FI'. Der zweite
+ Operand wird nicht ausgewertet, falls er für das Ergebnis nicht relevant ist.
+
+
+'COR'
+ #on("b")#BOOL OP COR #off("b")#
+ Bedingtes logisches ODER, entspricht: 'IF a THEN true ELSE b FI'. Der zweite
+ Operand wird nicht ausgewertet, falls er für das Ergebnis nicht relevant ist.
+
+
+'false'
+ #on("b")#BOOL CONST false #off("b")#
+
+
+'NOT'
+ #on("b")#BOOL OP NOT (BOOL CONST a) #off("b")#
+ Logische Negation.
+
+
+'OR'
+ #on("b")#BOOL OP OR (BOOL CONST a, b) #off("b")#
+ Logisches ODER, liefert TRUE gdw. a und/oder b TRUE ist.
+
+
+'true'
+ #on("b")#BOOL CONST true #off("b")#
+
+
+'XOR'
+ #on("b")#BOOL OP XOR (BOOL CONST a, b) #off("b")#
+ Exklusives ODER, liefert TRUE gdw. entweder a oder b TRUE ist.
+
+#page#
+
+5.2.2 Integer-Arithmetik
+
+Ein Datenobjekt vom Typ INT belegt im Speicher 2 Bytes. Zulässige INT - Werte
+sind die ganzen Zahlen von -32768 bis +32767 einschließlich.
+
+Falls größere ganze Zahlen benötigt werden, muß das Packet 'LONGINT', welches
+sich auf dem Archive 'std.zusatz' befindet, nachinsertiert werden (siehe 6.1.2).
+
+Operationen für Integers:
+
+- Vergleich : = , <> , < , <= , > , >=
+
+- Verknüpfung : + , - , * , ** , DECR , DIV , INCR
+
+- Sonstiges : abs , ABS , initialize random , max , maxint , min ,
+ minint , MOD , random , sign , SIGN , text
+#page#
+':='
+ #on("b")#INT OP := (INT VAR a, INT CONST b) #off("b")#
+ Zuweisung.
+
+
+'='
+ #on("b")#BOOL OP = (INT CONST a, b) #off("b")#
+ Vergleich.
+
+
+'<>'
+ #on("b")#BOOL OP <> (INT CONST a, b) #off("b")#
+ Vergleich auf Ungleichheit.
+
+
+'<'
+ #on("b")#BOOL OP < (INT CONST a, b) #off("b")#
+ Vergleich auf kleiner.
+
+
+'<='
+ #on("b")#BOOL OP <= (INT CONST a, b) #off("b")#
+ Vergleich auf kleiner gleich.
+
+
+'>'
+ #on("b")#BOOL OP > (INT CONST a, b) #off("b")#
+ Vergleich auf größer.
+
+
+'>='
+ #on("b")#BOOL OP >= (INT CONST a, b) #off("b")#
+ Vergleich auf größer gleich.
+
+#page#
+'+'
+ #on("b")#INT OP + (INT CONST a) #off("b")#
+ Monadischer Operator (Vorzeichen, ohne Wirkung).
+
+ #on("b")#INT OP + (INT CONST a, b) #off("b")#
+ Addition.
+
+
+'-'
+ #on("b")#INT OP - (INT CONST a) #off("b")#
+ Vorzeichen-Umkehrung.
+
+
+ #on("b")#INT OP - (INT CONST a, b) #off("b")#
+ Subtraktion.
+
+
+'*'
+ #on("b")#INT OP * (INT CONST a, b) #off("b")#
+ Multiplikation.
+
+
+'**'
+ #on("b")#INT OP ** (INT CONST arg, exp) #off("b")#
+ Exponentiation mit 'exp' >= 0
+
+
+'DECR'
+ #on("b")#OP DECR (INT VAR links, INT CONST rechts) #off("b")#
+ Wirkt wie links := links - rechts
+
+
+'DIV'
+ #on("b")#INT OP DIV (INT CONST a, b) #off("b")#
+ INT-Division.
+
+ FEHLER :
+ - DIV durch 0
+
+
+'INCR'
+ #on("b")#OP INCR (INT VAR links, INT CONST rechts) #off("b")#
+ Wirkt wie links := links + rechts
+
+#page#
+'abs'
+ #on("b")#INT PROC abs (INT CONST argument) #off("b")#
+ Absolutbetrag eines INT-Wertes.
+
+
+ #on("b")#INT OP ABS (INT CONST argument) #off("b")#
+ Absolutbetrag eines INT-Wertes.
+
+
+'initialize random'
+ #on("b")#PROC initialize random (INT CONST wert) #off("b")#
+ Initialisieren der 'random'-Prozedur, um nicht reproduzierbare Zufallszahlen zu
+ bekommen. Diese 'initialize random'-Prozedur gilt für den "INT-Random Gene­
+ rator".
+
+
+'max'
+ #on("b")#INT PROC max (INT CONST links, rechts) #off("b")#
+ Liefert den Größten der beiden INT-Werte.
+
+
+'maxint'
+ #on("b")#INT CONST maxint #off("b")#
+ Größter INT-Wert im EUMEL-System (32 767).
+
+
+'min'
+ #on("b")#INT PROC min (INT CONST links, rechts) #off("b")#
+ Liefert den Kleinsten der beiden INT-Werte.
+
+
+ min ( 3.0, 2.0) ==> 2.0
+ min (-2.0, 3.0) ==> -2.0
+
+
+
+'minint'
+ #on("b")#INT CONST minint #off("b")#
+ Kleinster INT-Wert im EUMEL-System (-32768).
+
+
+'MOD'
+ #on("b")#INT OP MOD (INT CONST links, rechts) #off("b")#
+ Liefert den Rest einer INT-Division.
+
+
+ 3 MOD 2 ==> 1
+ -3 MOD 2 ==> 1
+
+
+ FEHLER :
+ - DIV durch 0
+
+
+'random'
+ #on("b")#INT PROC random (INT CONST lower bound, upper bound) #off("b")#
+ Pseudo-Zufallszahlen-Generator im Intervall 'upper bound' und 'lower bound'
+ einschließlich. Es handelt sich hier um den "INT Random Generator".
+
+
+'real'
+ #on("b")#REAL PROC real (INT CONST a) #off("b")#
+ Konvertierungsprozedur.
+
+#page#
+'sign'
+ #on("b")#INT PROC sign (INT CONST argument) #off("b")#
+ Feststellen des Vorzeichens eines INT-Wertes. Folgende Werte werden geliefert:
+
+
+ argument > 0 ==> 1
+ argument = 0 ==> 0
+ argument < 0 ==> -1
+
+
+
+ #on("b")#INT OP SIGN (INT CONST argument) #off("b")#
+ Feststellen des Vorzeichens eines INT-Wertes.
+
+
+'text'
+ #on("b")#TEXT PROC text (INT CONST zahl) #off("b")#
+ Konvertierung des INT Wertes 'zahl' in den kürzest möglichen Text. Das Vorzei­
+ chen bleibt erhalten.
+
+ #on("b")#TEXT PROC text (INT CONST zahl, länge) #off("b")#
+ Konvertierung des INT Wertes 'zahl' in einen Text der Länge 'länge'. Das
+ Vorzeichen bleibt erhalten. Falls der Text kürzer als 'länge' ist, wird er links
+ (vorne) mit Leerzeichen aufgefüllt, falls er länder ist wird 'länge' mal "*"
+ ausgegeben.
+
+____________________________________________________________________________
+
+ out ("X:"); out(text(12345,7)) ; line;
+ out ("Y:"); out(text(12345,3)) ;
+ (* ergibt *)
+ X: 12345
+ Y:***
+
+____________________________________________________________________________
+#page#
+
+5.2.3 Real-Arithmetik
+
+Für den Datentyp REAL gibt es außer den üblichen Verknüpfungs- und Vergleichs­
+operationen noch eine Anzahl mathematischer Prozeduren und Operationen. Teilweise
+stehen diese in mehr als einer Version zur Verfügung.
+
+Jedes Datenobjekt vom Typ REAL belegt im Speicher 8 Byte.
+
+REALs haben eine 13-stellige #ib#Mantisse#ie#, die im Rechner dezimal geführt wird. (Das
+heißt, bei Konversionen zwischen interner und TEXT-Darstellung treten keine Run­
+dungsfehler auf.) Der Wertebereich wird durch folgende Eckwerte abgegrenzt:
+#dpos(0.5,".")##lpos(4.5)#
+
+#table#
+ 9.999999999999e+126 größter REAL-Wert
+ 0.000000000001 kleinster positiver REAL-Wert mit x + 1.0 > 1.0
+ 9.999999999999e-126 kleinster positiver REAL-Wert > 0.0
+ -9.999999999999e-126 größter negativer REAL-Wert
+ -9.999999999999e+126 kleinster REAL-Wert
+
+#clearpos#
+#tableend#
+
+- Vergleiche : = , <> , < , <= , > , >=
+
+- Verknüpfungen : + , - , * , / , ** , DECR , INCR
+
+- Diverse : abs , arctan , arctand , cos , cosd , decimal
+ exponent , e , exp , floor , frac , initialize
+ random , int , ln , log2 , log10 , max ,
+ maxreal , min , MOD , pi , random , round ,
+ sign , SIGN , sin , sind , smallreal , sqrt ,
+ tan , tand , text
+
+#page#
+':='
+ #on("b")#REAL OP := (REAL VAR a, REAL CONST b) #off("b")#
+ Zuweisung.
+
+
+'='
+ #on("b")#BOOL OP = (REAL CONST a, b) #off("b")#
+ Vergleich.
+
+
+'<>'
+ #on("b")#BOOL OP <> (REAL CONST a, b) #off("b")#
+ Vergleich auf Ungleichheit.
+
+
+'<'
+ #on("b")#BOOL OP < (REAL CONST a, b) #off("b")#
+ Vergleich auf kleiner.
+
+
+'<='
+ #on("b")#BOOL OP <= (REAL CONST a, b) #off("b")#
+ Vergleich auf kleiner gleich.
+
+
+'>'
+ #on("b")#BOOL OP > (REAL CONST a, b) #off("b")#
+ Vergleich auf größer.
+
+
+'>='
+ #on("b")#BOOL OP >= (REAL CONST a, b) #off("b")#
+ Vergleich auf größer gleich.
+
+#page#
+'+'
+ #on("b")#REAL OP + (REAL CONST a) #off("b")#
+ Monadischer Operator (Vorzeichen, ohne Wirkung).
+
+
+ #on("b")#REAL OP + (REAL CONST a, b) #off("b")#
+ Addition.
+
+
+'-'
+ #on("b")#REAL OP - (REAL CONST a) #off("b")#
+ Vorzeichen-Umkehrung.
+
+
+ #on("b")#REAL OP - (REAL CONST a, b) #off("b")#
+ Subtraktion.
+
+
+'*'
+ #on("b")#REAL OP * (REAL CONST a, b) #off("b")#
+ Multiplikation.
+
+
+'/'
+ #on("b")#REAL OP / (REAL CONST a, b) #off("b")#
+ Division.
+
+ FEHLER :
+ - Division durch 0
+
+
+'**'
+ #on("b")#REAL OP ** (REAL CONST arg, exp) #off("b")#
+ Exponentiation.
+
+ #on("b")#REAL OP ** (REAL CONST arg, INT CONST exp) #off("b")#
+ Exponentiation.
+
+
+'DECR'
+ #on("b")#OP DECR (REAL VAR links, REAL CONST rechts) #off("b")#
+ Wirkt wie links := links - rechts
+
+
+'INCR'
+ #on("b")#OP INCR (REAL VAR links, REAL CONST rechts) #off("b")#
+ Wirkt wie links := links + rechts
+
+#page#
+'abs'
+ #on("b")#REAL PROC abs (REAL CONST wert) #off("b")#
+ Absolutbetrag eines REAL-Wertes.
+
+ #on("b")#REAL OP ABS (REAL CONST wert) #off("b")#
+ Absolutbetrag eines REAL-Wertes.
+
+
+'arctan'
+ #on("b")#REAL PROC arctan (REAL CONST x) #off("b")#
+ Arcus Tangens-Funktion. Liefert einen Wert in Radiant.
+
+
+'arctand'
+ #on("b")#REAL PROC arctand (REAL CONST x) #off("b")#
+ Arcus Tangens-Funktion. Liefert einen Wert in Grad.
+
+
+'cos'
+ #on("b")#REAL PROC cos (REAL CONST x) #off("b")#
+ Cosinus-Funktion. 'x' muß in Radiant angegeben werden.
+
+
+'cosd'
+ #on("b")#REAL PROC cosd (REAL CONST x) #off("b")#
+ Cosinus-Funktion. 'x' muß in Winkelgrad angegeben werden.
+
+
+'decimal exponent'
+ #on("b")#INT PROC decimal exponent (REAL CONST mantisse) #off("b")#
+ Liefert aus einem REAL-Wert den dezimalen Exponenten als INT-Wert.
+
+
+'e'
+ #on("b")#REAL PROC e #off("b")#
+ Eulersche Zahl (2.718282).
+
+
+'exp'
+ #on("b")#REAL PROC exp (REAL CONST z) #off("b")#
+ Exponentialfunktion.
+
+
+'floor'
+ #on("b")#REAL PROC floor (REAL CONST real) #off("b")#
+ Schneidet die Nachkommastellen des REAL-Wertes 'real' ab.
+
+
+'frac'
+ #on("b")#REAL PROC frac (REAL CONST z) #off("b")#
+ Liefert die Stellen eines REAL-Wertes hinter dem Dezimalpunkt.
+
+
+'initialize random'
+ #on("b")#PROC initialize random (REAL CONST z) #off("b")#
+ Initialisieren der 'random'-Prozedur mit verschiedenen Werten für 'z', um nicht
+ reproduzierbare Zufallszahlen zu bekommen. Diese Prozedur gilt für den
+ 'REAL-Random Generator'.
+
+
+'int'
+ #on("b")#INT PROC int (REAL CONST a) #off("b")#
+ Konvertierungsprozedur. Die Nachkommastellen werden abgeschnitten.
+ Bsp: int (3.9) => 3
+
+
+'ln'
+ #on("b")#REAL PROC ln (REAL CONST x) #off("b")#
+ Natürlicher Logarithmus.
+
+ FEHLER :
+ - ln mit negativer Zahl
+ Nur echt positive Argumente sind zulässig.
+
+
+'log2'
+ #on("b")#REAL PROC log2 (REAL CONST z) #off("b")#
+ Logarithmus zur Basis 2.
+
+ FEHLER :
+ - log2 mit negativer zahl
+ Nur echt positive Argumente sind zulässig.
+
+
+'log10'
+ #on("b")#REAL PROC log10 (REAL CONST x) #off("b")#
+ Logarithmus zur Basis 10.
+
+ FEHLER :
+ - log10 mit negativer zahl
+ Nur echt positive Argumente sind zulässig.
+
+
+'max'
+ #on("b")#REAL PROC max (REAL CONST links, rechts) #off("b")#
+ Liefert den Größten der beiden REAL-Werte.
+
+
+'maxreal'
+ #on("b")#REAL CONST maxreal #off("b")#
+ Größter REAL-Wert im EUMEL-System (9.999999999999e126).
+
+
+'min'
+ #on("b")#REAL PROC min (REAL CONST links, rechts) #off("b")#
+ Liefert den Kleinsten der beiden REAL-Werte.
+
+
+'MOD'
+ #on("b")#REAL OP MOD (REAL CONST links, rechts) #off("b")#
+ Modulo-Funktion für REALs (liefert den Rest). Beispiele:
+
+
+ 5.0 MOD 2.0 ==> 1.0
+ 4.5 MOD 4.0 ==> 0.5
+
+
+
+'pi'
+ #on("b")#REAL CONST pi #off("b")#
+ Die Zahl pi (3.141593).
+
+
+'random'
+ #on("b")#REAL PROC random #off("b")#
+ Pseudo-Zufallszahlen-Generator im Intervall 0 und 1. Es handelt sich hier um
+ den "REAL Random Generator".
+
+
+'round'
+ #on("b")#REAL PROC round (REAL CONST real, INT CONST digits) #off("b")#
+ Runden eines REAL-Wertes auf 'digits' Stellen. Für positive Werte wird auf
+ Nachkommastellen gerundet. Beispiel:
+
+
+ round (3.14159, 3)
+
+
+ liefert '3.142'. Für negative 'digits'-Werte wird auf Vorkommastellen gerundet.
+
+
+ round (123.456, -2)
+
+
+ liefert '100.0'. Abweichung vom Standard: Es wird mit 'digits'-Ziffern gerundet.
+
+
+'sign'
+ #on("b")#INT PROC sign (REAL CONST argument) #off("b")#
+ Feststellen des Vorzeichens eines REAL-Wertes.
+
+ #on("b")#INT OP SIGN (REAL CONST argument) #off("b")#
+ Feststellen des Vorzeichens eines REAL-Wertes.
+
+
+'sin'
+ #on("b")#REAL PROC sin (REAL CONST x) #off("b")#
+ Sinus-Funktion. 'x' muß in Radiant (Bogenmaß) angegeben werden.
+
+
+'sind'
+ #on("b")#REAL PROC sind (REAL CONST x) #off("b")#
+ Sinus-Funktion. 'x' muß im Winkelgrad angegeben werden.
+
+
+'smallreal'
+ #on("b")#REAL PROC smallreal #off("b")#
+ Kleinster darstellbarer REAL-Wert im EUMEL-System für den
+
+
+ 1.0 - smallreal <> 1.0
+ 1.0 + smallreal <> 1.0
+
+
+ gilt (1.0E-12).
+
+
+'sqrt'
+ #on("b")#REAL PROC sqrt (REAL CONST z) #off("b")#
+ Wurzel-Funktion.
+
+ FEHLER :
+ - sqrt von negativer Zahl
+ Das Argument muß größer gleich 0.0 sein.
+
+
+'tan'
+ #on("b")#REAL PROC tan (REAL CONST x) #off("b")#
+ Tangens-Funktion. 'x' muß in Radiant angegeben werden.
+
+
+'tand'
+ #on("b")#REAL PROC tand (REAL CONST x) #off("b")#
+ Tangens-Funktion. 'x' muß in Winkelgrad angegeben werden.
+
+
+'text'
+ #on("b")#TEXT PROC text (REAL CONST real) #off("b")#
+ Konvertierung eines REAL-Wertes in einen TEXT. Ggf. wird der TEXT in Expo­
+ nenten-Darstellung geliefert.
+
+ #on("b")#TEXT PROC text (REAL CONST real, laenge) #off("b")#
+ Konvertierung eines REAL-Wertes in einen TEXT. Der TEXT wird in Exponen­
+ ten-Darstellung geliefert. Um diese Darstellung zu ermöglichen ist der Wert
+ 'laenge' größer oder gleich 8 anzugeben.
+
+ #on("b")#TEXT PROC text (REAL CONST real, INT CONST laenge, fracs)#off("b")#
+ Konvertierung eines REAL-Wertes in einen TEXT. Dabei gibt 'laenge' die Länge
+ des Resultats einschließlich des Dezimalpunktes und 'fracs' die Anzahl der Dezi­
+ malstellen an. Kann der REAL-Wert nicht wie gewünscht dargestellt werden, wird
+
+
+ laenge * "*"
+
+
+ geliefert.
+
+#page#
+
+5.2.4 Text
+
+Jedes Datenobjekt vom Typ TEXT besteht aus einem festen Teil von 16 Bytes und
+möglicherweise aus einem flexiblen Teil auf dem #on("i")##on("b")#Heap#off("i")##off("b")#. Im festen Teil werden Texte
+bis zur Länge von 13 Zeichen untergebracht. Wenn eine TEXT-Variable einen Wert
+mit mehr als 13 Zeichen Länge annimmt, werden alle Zeichen auf dem Heap unterge­
+bracht. Genauer ergibt sich folgendes Bild:
+
+ kurzer Text (Länge <= 13):
+
+ Heap-Link 2 Bytes
+ Textlänge 1 Byte
+ Text 13 Bytes
+
+ langer Text (Länge > 13):
+
+ Heap-Link 2 Bytes
+ 255 1 Byte
+ Länge 2 Bytes
+ ungenutzt 11 Bytes
+
+Wenn eine Variable einmal Platz auf dem Heap bekommen hat, behält sie diesen
+vorbeugend auch dann, wenn sie wieder einen kurzen Text als Wert erhält. So muß
+wahrscheinlich kein neuer Platz auf dem Heap zugewiesen werden, wenn sie wieder
+länger wird. Das gilt allerdings nur bis zur nächsten #ib#Garbage Collection#ie# auf den
+TEXT-Heap, denn dabei werden alle Heap-Container minimal gemacht bzw. ge­
+löscht, wenn sie nicht mehr benötigt werden. Der Platz auf dem Heap wird in Vielfa­
+chen von 16 Bytes vergeben. In Fremddatenräumen wird in jedem #ib#Container#ie# neben
+dem eigentlichen Text auch die Containerlänge untergebracht.
+#page#
+Beispiele: TEXT-Länge Speicherbedarf (Byte)
+
+ 0 16
+ 13 16
+ 14 32
+ 15 48
+ 30 48
+ 31 64
+ 46 64
+ 47 80
+ 62 80
+
+
+Die Heapgröße eines Fremddatenraums berechnet sich als:
+
+ 1024 * 1024 = 1048056 - stat Bytes
+
+'stat' ist dabei die statische Größe der Datenstruktur, die dem Datenraum aufgeprägt
+wurde. Bei einem BOUND ROW 1000 TEXT ergibt sich also eine Heapgröße von
+
+ 1048056 - (1000 * 16) = 1032056 Bytes.
+
+
+
+'heap size'
+ #on("b")#INT PROC heap size #off("b")#
+ Informationsprozedur für die Größe (in KB) des TEXT-Heaps.
+
+#page#
+
+TEXT- Operationen:
+
+- Vergleich : = , <> , < , <= , > , >=
+ LEXEQUAL , LEXGREATER ,
+ LEXGREATEREQUAL
+
+- Verkettung : + , * , CAT
+
+- Veränderung : change , change all , code , compress , delete
+ char , insert char , length , LENGTH , max
+ text length , pos , real , replace , SUB ,
+ subtext , text
+#page#
+
+Der EUMEL-Zeichensatz
+#goalpage("codetab")#
+Das EUMEL System definiert einen Zeichensatz, der gewährleistet, daß gleiche Text­
+zeichen auf allen Maschinen gleich codiert werden.
+ Die interne Darstellung wird durch die folgende EUMEL-Codetabelle
+beschrieben. Der Zeichensatz beruht auf dem ASCII-Zeichensatz mit Erweiterungen.
+Der in der Tabelle freie Bereich (z.B code(127) bis code(213)) ist nicht einheitlich
+verfügbar und wird deshalb nicht beschrieben. Die Codierung bildet mithin auch
+Grundlage für Vergleiche und Sortierungen.
+
+Die Korrekte Darstellung dieser Zeichen auf Bildschirm, Drucker etc. setzt natürlich
+eine korrekte Konfiguration der Geräte voraus. Die Anpassung eines Geräts an diesen
+Zeichensatz ist im EUMEL-Systemhandbuch in Teil 2 beschrieben.
+
+
+ I 0 1 2 3 4 5 6 7 8 9
+---+--------------------------------------
+3 I SP ! " \# $ % & '
+ I
+4 I ( ) * + , - . / 0 1
+ I
+5 I 2 3 4 5 6 7 8 9 : ;
+ I
+6 I < = > ? § A B C D E
+ I
+7 I F G H I J K L M N O
+ I
+8 I P Q R S T U V W X Y
+ I
+9 I Z [ \ ] ^ _ ` a b c
+ I
+10 I d e f g h i j k l m
+ I
+11 I n o p q r s t u v w
+ I
+12 I x y z { | } ~
+ I
+13 I
+. I
+. I
+. I
+20 I
+ I
+21 I Ä Ö Ü ä ö ü
+ I
+22 I k ­ \# SP
+ I
+23 I
+ I
+24 I
+ I
+25 I ß
+#page#
+':='
+ #on("b")#TEXT OP := (TEXT VAR a, TEXT CONST b) #off("b")#
+ Zuweisung.
+
+
+'='
+ #on("b")#BOOL OP = (TEXT CONST links, rechts) #off("b")#
+ Vergleich von zwei Texten auf Gleichheit (Texte mit ungleichen Längen sind
+ immer ungleich).
+
+
+'<>'
+ #on("b")#BOOL OP <> (TEXT CONST links, rechts) #off("b")#
+ Vergleich von zwei Texten auf Ungleichheit (Texte mit ungleichen Längen sind
+ stets ungleich).
+
+
+'<'
+ #on("b")#BOOL OP < (TEXT CONST links, rechts) #off("b")#
+ Vergleich zweier Texte auf kleiner ('links' kommt lexikographisch vor 'rechts').
+
+
+'<='
+ #on("b")#BOOL OP <= (TEXT CONST links, rechts) #off("b")#
+ Vergleich von zwei Texten auf kleiner gleich ('links' kommt lexikographisch vor
+ oder ist gleich 'rechts').
+
+
+'>'
+ #on("b")#BOOL OP > (TEXT CONST links, rechts) #off("b")#
+ Vergleich zweier Texte auf größer ('links' kommt lexikographisch nach 'rechts').
+
+
+'>='
+ #on("b")#BOOL OP >= (TEXT CONST links, rechts) #off("b")#
+ Vergleich zweier Texte auf größer gleich ('links' kommt lexikographisch nach oder
+ ist gleich 'rechts').
+
+#page#
+'LEXEQUAL'
+ #on("b")#BOOL OP LEXEQUAL (TEXT CONST links, rechts) #off("b")#
+ Prüfung auf lexikalische Gleichheit.
+
+
+'LEXGREATER'
+ #on("b")#BOOL OP LEXGREATER (TEXT CONST links, rechts) #off("b")#
+ Prüfung ob der Text 'links' lexikalisch größer als 'rechts' ist.
+
+
+'LEXGREATEREQUAL'
+ #on("b")#BOOL OP LEXGREATEREQUAL (TEXT CONST links, rechts) #off("b")#
+ Prüfung ob der Text 'links' lexikalisch größer oder gleich dem Text 'rechts' ist.
+
+
+
+ Die drei Operatoren prüfen nach folgenden Regeln:
+
+ - Buchstaben haben die aufsteigende Reihenfolge 'A' bis 'Z'. Dabei werden kleine
+ und große Buchstaben gleich behandelt.
+
+ - Umlaute werden wie üblich ausgeschrieben. (Ä = Ae usw.)
+ (ß = ss)
+
+ - Alle Sonderzeichen (auch Ziffern) außer ' '(Leerzeichen) und '-' werden igno­
+ riert, diese beiden Zeichen werden gleich behandelt.
+
+#page#
+'+'
+ #on("b")#TEXT OP + (TEXT CONST links, rechts) #off("b")#
+ Verkettung der Texte 'links' und 'rechts' in dieser Reihenfolge. Die Länge des
+ Resultats ergibt sich aus der Addition der Längen der Operanden.
+
+
+'*'
+ #on("b")#TEXT OP * (INT CONST faktor, TEXT CONST quelle) #off("b")#
+ 'faktor' fache Erstellung von 'quelle' und Verkettung. Dabei muß
+
+
+ times >= 0
+
+
+ sein, sonst wird 'niltext' geliefert.
+
+
+'CAT'
+ #on("b")#OP CAT (TEXT VAR links, TEXT CONST rechts) #off("b")#
+ hat die gleiche Wirkung wie
+
+
+ links := links + rechts
+
+
+ Hinweis: Der Operator 'CAT' hat eine geringere Heap-Belastung als die Opera­
+ tion mit expliziter Zuweisung.
+
+#page#
+'change'
+ #on("b")#PROC change (TEXT VAR senke, TEXT CONST alt, neu) #off("b")#
+ Ersetzung des (Teil-) TEXTes 'alt' in 'senke' durch 'neu' bei dem erstmaligen
+ Auftreten. Ist 'alt' nicht in 'senke' vorhanden, so wird keine Meldung abgesetzt
+ (Abweichung vom Standard). Die Länge von 'senke' kann sich dabei verändern.
+ Beispiel:
+
+
+ TEXT VAR mein text :: "EUMEL-Benutzerhandbuch";
+ change (mein text, "Ben", "N");
+ (* EUMEL-Nutzerhandbuch *)
+
+
+ #on("b")#PROC change (TEXT VAR senke, INT CONST von, bis, TEXT CONST neu) #off("b")#
+ Der TEXT 'neu' wird in den TEXT 'senke' anstatt des TEXTes, der zwischen 'von'
+ und 'bis' steht, eingesetzt. Die Länge von 'senke' kann sich dabei verändern.
+ Beispiel:
+
+
+ TEXT VAR mein text :: "EUMEL-Benutzerhandbuch";
+ change (mein text, 7, 9, "N"); (* wie oben *)
+
+
+
+'change all'
+ #on("b")#PROC change all (TEXT VAR senke, TEXT CONST alt, neu) #off("b")#
+ Der Teiltext 'alt' wird durch 'neu' in 'senke' ersetzt. Im Unterschied zur 'chan­
+ ge'-Prozedur findet die Ersetzung nicht nur bei dem erstmaligen Auftreten von
+ 'alt' statt, sondern so oft, wie 'alt' in 'senke' vorhanden ist. Beispiel:
+
+
+ TEXT VAR x :: "Das ist ein Satz";
+ change all (x, " ", ""); (* DasisteinSatz *)
+
+#page#
+'code'
+ #on("b")#TEXT PROC code (INT CONST code) #off("b")#
+ Wandelt einen INT-Wert 'code' in ein Zeichen um. 'code' muß
+
+
+ 0 <= code <= 255
+
+
+ sein.
+
+ #on("b")#INT PROC code (TEXT CONST text) #off("b")#
+ Wandelt ein Zeichen 'text' in einen INT-Wert um. Ist
+
+
+ LENGTH text <> 1
+
+
+ dann wird der Wert -1 geliefert (also bei mehr als ein Zeichen oder niltext).
+ (Codetabelle auf Seite 5- #topage("codetab")#)
+
+
+'compress'
+ #on("b")#TEXT PROC compress (TEXT CONST text) #off("b")#
+ Liefert den TEXT 'text' ohne führende und nachfolgende Leerzeichen.
+
+
+'delete char'
+ #on("b")#PROC delete char (TEXT VAR string, INT CONST delete pos)#off("b")#
+ Löscht ein Zeichen aus dem Text 'string' an der Position 'delete pos'. Für
+
+
+ delete pos <= 0
+
+
+ oder
+
+
+ delete pos > LENGTH string
+
+
+ wird keine Aktion vorgenommen.
+
+#page#
+'insert char'
+ #on("b")#PROC insert char (TEXT VAR string, TEXT CONST char,INT CONST insert pos)#off("b")#
+ Fügt ein Zeichen 'char' in den Text 'string' an der Position 'insert pos' ein. Für
+
+
+ insert pos > LENGTH string + 1
+
+
+ wird keine Aktion vorgenommen. Daher ist es möglich, mit dieser Prozedur auch
+ am Ende eines Textes (Position: LENGTH string + 1) ein Zeichen anzufügen.
+
+
+'length'
+ #on("b")#INT PROC length (TEXT CONST text) #off("b")#
+ Anzahl von Zeichen ("Länge") von 'text' einschließlich Leerzeichen.
+
+
+'LENGTH'
+ #on("b")#INT OP LENGTH (TEXT CONST text) #off("b")#
+ Anzahl von Zeichen ("Länge") von 'text' einschließlich Leerzeichen.
+
+
+'max text length'
+ #on("b")#INT CONST max text length #off("b")#
+ Maximale Anzahl von Zeichen in einem TEXT (32 000).
+
+#page#
+'pos'
+ #on("b")#INT PROC pos (TEXT CONST quelle, pattern) #off("b")#
+ Liefert die erste Position des ersten Zeichens von 'pattern' in 'quelle', falls 'pat­
+ tern' gefunden wird. Wird 'pattern' nicht gefunden oder ist 'pattern' niltext, so wird
+ der Wert '0' geliefert. Beispiel:
+
+
+ TEXT VAR t1 :: "abcdefghijk...xyz",
+ t2 :: "cd";
+ ... pos (t1, t2) ... (* liefert 3 *)
+ ... pos (t2, t1) ... (* liefert 0 *)
+
+
+
+ #on("b")#INT PROC pos (TEXT CONST quelle, pattern, INT CONST von)#off("b")#
+ Wie obige Prozedur, jedoch wird erst ab der Position 'von' ab gesucht. Dabei gilt
+ folgende Einschränkung:
+
+
+ length (pattern) < 255
+
+
+
+ #on("b")#INT PROC pos (TEXT CONST quelle, low char, high char, INT CONST von#off("b")#
+ Liefert die Position des ersten Zeichens 'x' in 'quelle' ab der Position 'von', so daß
+
+
+ low char <= x <= high char
+
+
+ 'low char' und 'high char' müssen TEXTe der Länge 1 sein. Wird kein Zeichen in
+ 'quelle' in dem Bereich zwischen 'low char' und 'high char' gefunden, wird der
+ Wert '0' geliefert. Beispiel:
+
+____________________________________________________________________________
+
+ (*Suche nach dem ersten Zeichen <> blank nach einer Leerspalte*)
+ TEXT VAR zeile :: "BlaBla Hier gehts weiter";
+ INT VAR pos erstes blank :: pos (zeile, " "),
+ ende leerspalte ::
+ pos (zeile, ""33"",""254"", pos erstes blank);
+
+____________________________________________________________________________
+
+#page#
+'real'
+ #on("b")#REAL PROC real (TEXT CONST text) #off("b")#
+ Konvertierung eines TEXTes 'text' in einen REAL-Wert. Achtung: Zur Zeit werden
+ keine Überprüfungen vorgenommen, d.h. in dem TEXT muß ein REAL-Wert
+ stehen.
+
+
+'replace'
+ #on("b")#PROC replace (TEXT VAR senke, INT CONST position, TEXT CONST quelle)#off("b")#
+ Ersetzung eines Teiltextes in 'senke' durch 'quelle' an der Position 'position' in
+ 'senke'. Es muß gelten
+
+
+ 1 <= position <= LENGTH senke
+
+
+ d.h. 'position' muß innerhalb von 'senke' liegen und 'quelle' muß von der Posi­
+ tion 'position' ab in 'senke' einsetzbar sein. Dabei bleibt die Länge von 'senke'
+ unverändert.
+
+
+'SUB'
+ #on("b")#TEXT OP SUB (TEXT CONST text, INT CONST pos) #off("b")#
+ Liefert ein Zeichen aus 'text' an der Position 'pos'. Entspricht
+
+
+ subtext (text, pos, pos)
+
+
+ Anmerkung: Effizienter als obiger Prozedur-Aufruf. Für
+
+
+ pos <= 0
+ pos > LENGTH text
+
+
+ wird niltext geliefert.
+
+#page#
+'subtext'
+ #on("b")#TEXT PROC subtext (TEXT CONST quelle, INT CONST von) #off("b")#
+ Teiltext von 'quelle', der bei der Position 'von' anfängt. Die Länge des Resultats
+ ergibt sich also zu
+
+
+ LENGTH quelle - von + 1
+
+
+ d.h. von der Position 'von' bis zum Ende von 'quelle'. 'von' muß innerhalb von
+ 'quelle' liegen. Ist von < 1, dann wird 'quelle' geliefert. Falls von > LENGTH
+ quelle ist, wird niltext geliefert.
+
+
+ #on("b")#TEXT PROC subtext (TEXT CONST quelle, INT CONST von, bis)#off("b")#
+ Teiltext von 'quelle' von der Position 'von' bis einschließlich der Position 'bis'. Die
+ Länge des Resultats ist also
+
+
+ bis - von + 1
+
+
+ Dabei muß gelten
+
+
+ 1 <= von <= bis <= LENGTH quelle
+
+
+ d.h. die Positionen 'von' und 'bis' müssen in dieser Reihenfolge innerhalb von
+ 'quelle' liegen. Ist
+
+
+ bis >= LENGTH quelle
+
+
+ wird 'subtext (quelle, von)' ausgeführt. Für die Bedingungen für 'von' siehe vor­
+ stehende Beschreibung von 'subtext'.
+
+
+'text'
+ #on("b")#TEXT PROC text (TEXT CONST quelle, INT CONST laenge) #off("b")#
+ Teiltext aus 'quelle' mit der Länge 'laenge', beginnend bei der Position 1 von
+ 'quelle'. Es muß gelten
+
+
+ 1 <= laenge <= LENGTH quelle
+
+
+ d.h. der gewünschte Teiltext muß aus 'quelle' ausblendbar sein.
+ Wenn gilt:
+
+ laenge > LENGTH quelle
+
+
+ wird der zu liefernde TEXT mit der an 'laenge' fehlenden Zeichen mit Leerzeichen
+ aufgefüllt.
+
+ #on("b")#TEXT PROC text (TEXT CONST quelle, INT CONST laenge, von)#off("b")#
+ Teiltext aus 'quelle' mit der Länge 'laenge', beginnend an der Position 'von' in
+ dem TEXT 'quelle'. Entspricht
+
+
+ text (subtext (quelle, von, LENGTH quelle),laenge)
+
+
+ Es muß
+
+
+ laenge >= 0
+ 1 <= von <= LENGTH quelle
+
+
+ gelten, d.h. 'von' muß eine Position angeben, die innerhalb von 'quelle' liegt. Für
+
+
+ laenge > LENGTH quelle - von + 1
+
+
+ also wenn die angegebene Länge 'laenge' größer ist als der auszublendende Text,
+ wird das Resultat rechts mit Leerzeichen aufgefüllt. Wenn
+
+
+ laenge < LENGTH quelle - von + 1
+
+
+ d.h. wenn die angegebene Länge kleiner ist als der Teiltext von 'von' bis zum
+ letzten Zeichen von 'quelle', wird das Resultat mit der Länge
+
+
+ LENGTH quelle - von + 1
+
+
+ geliefert.
+
diff --git a/doc/programming/programmierhandbuch.5b b/doc/programming/programmierhandbuch.5b
new file mode 100644
index 0000000..d91bcc9
--- /dev/null
+++ b/doc/programming/programmierhandbuch.5b
@@ -0,0 +1,1481 @@
+#pagenr("%",40)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 5 : Programmierung
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+5 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#5 - %
+#end#
+
+5.3 Der Datentyp FILE (Textdateien)
+
+Der Datentyp FILE definiert Dateien von sequentieller Struktur, die Texte enthalten.
+Ein Objekt vom Datentyp FILE ist charakterisiert durch:
+
+1) seine Betriebsrichtung : input = nur lesender Zugriff
+ (TRANSPUTDIRECTION) output= nur schreibender Zugriff
+ modify= lesender und schreibender Zugriff.
+2) seinen Namen.
+
+Betriebsrichtung und Name werden in der Assoziierungsprozedur 'sequential file'
+(siehe Kap 2.8.2) festgelegt.
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ TEXT VAR name := ausgabe ;
+
+ FILE VAR f := sequential file(output,name) ;
+
+
+____________________________________________________________________________
+
+
+
+Das Festlegen einer Betriebsrichtung impliziert eine Kontrolle der Benutzung der
+betreffenden Datei, hilft somit Programmierfehler zu vermeiden.
+
+ACHTUNG : #on("b")##on("u")#Alle#off("b")##off("u")# Prozeduren, die auf FILEs zugreifen, verlangen Objekte vom Typ
+ FILE VAR, da die Lese/Schreiboperationen als ändernd betrachtet wer­
+ den (müssen).
+
+#page#
+
+5.3.1 Assoziierung
+
+'sequential file'
+ #on("b")#FILE PROC sequential file (TRANSPUTDIRECTION CONST mode, DATASPACE VAR ds) #off("b")#
+ Assoziierung einer sequentiellen Datei mit dem Dataspace 'ds' und der Betriebs­
+ richtung 'mode' (vergl. 'modify', 'input' bzw. 'output'). Diese Prozedur dient zur
+ Assoziierung eines temporären Datenraums in der Benutzer-Task, der nach der
+ Beendigung des Programmlaufs nicht mehr zugriffsfähig ist (weil der Name des
+ Datenraums nicht mehr ansprechbar ist). Somit muß der Datenraum explizit vom
+ Programm gelöscht werden.
+
+
+ #on("b")#FILE PROC sequential file (TRANSPUTDIRECTION CONST mode,TEXT CONST name)#off("b")#
+ Assoziierung einer sequentiellen Datei mit dem Namen 'name' und der Betriebs­
+ richtung 'mode' (vergl. 'input' bzw. 'output'). Existiert der FILE bereits, dann wird
+ mit 'input' auf den Anfang des FILEs, bei 'output' hinter den letzten Satz der datei
+ positioniert. Existiert dagagen der FILE noch nicht und ist die
+ TRANSPUTDIRECTION 'output' oder 'modify', wird ein neuer FILE eingerich­
+ tet.
+
+ FEHLER : "name" gibt es nicht"
+ Es wurde versucht, einen nicht vorhandenen FILE mit 'input' zu asso­
+ ziieren.
+
+#page#
+
+'input'
+ #on("b")#PROC input (FILE VAR f) #off("b")#
+ Ändern der Verarbeitungsart von 'modify' oder 'output' in 'input'. Dabei wird auf
+ den ersten Satz der Datei positioniert.
+
+ #on("b")#TRANSPUTDIRECTION CONST input #off("b")#
+ Assoziierung in Zusammenhang mit der Prozedur 'sequential file' einer sequentiel­
+ len Datei mit der 'TRANSPUTDIRECTION' 'input' (nur lesen).
+
+
+'output'
+ #on("b")#PROC output (FILE VAR file) #off("b")#
+ Ändern der Verarbeitungsart von 'input' oder 'modify' in 'output'. Dabei wird hinter
+ den letzten Satz der Datei positioniert.
+
+ #on("b")#TRANSPUTDIRECTION CONST output #off("b")#
+ In Verbindung mit der Prozedur 'sequential file' kann eine Datei assoziiert werden
+ mit der Betriebsrichtung 'output' (nur schreiben).
+
+
+'modify'
+ #on("b")#PROC modify (FILE VAR f) #off("b")#
+ Ändern der Betriebsrichtung von 'input' oder 'output' in die Betriebsrichtung 'mo­
+ dify'.
+
+ #on("b")#TRANSPUTDIRECTION CONST modify #off("b")#
+ Diese Betriebsrichtung erlaubt das Vorwärts- und Rückwärts-Positionieren und
+ das beliebige Einfügen und Löschen von Sätzen. 'modify' wird für die Assoziie­
+ rungsprozedur 'sequential file' benötigt.
+
+
+
+#page#
+
+5.3.2 Informationsprozeduren
+
+'eof'
+ #on("b")#BOOL PROC eof (FILE CONST file) #off("b")#
+ Informationsprozedur auf das Ende eines FILEs. Liefert den Wert TRUE, sofern
+ hinter den letzten Satz eines FILEs positioniert wurde.
+
+
+'line no'
+ #on("b")#INT PROC line no (FILE CONST file) #off("b")#
+ Liefert die aktuelle Zeilennummer.
+
+
+'lines'
+ #on("b")#PROC lines (FILE VAR f) #off("b")#
+ Liefert die Anzahl der Zeilen der Datei 'f'.
+
+
+'headline'
+ #on("b")#TEXT PROC headline (FILE CONST f) #off("b")#
+ Liefert den Inhalt der Kopfzeile der Datei 'f'.
+
+ #on("b")#PROC headline (FILE VAR f, TEXT CONST ueberschrift) #off("b")#
+ Setzt #ib#'ueberschrift' in die Kopfzeile#ie# der Datei 'f'.
+#page#
+
+5.3.3 Betriebsrichtung INPUT
+
+In der Betriebsrichtung 'input' sind nur Leseoperationen auf der Datei zugelassen. Die
+Assoziierungsprozedur 'sequential file' bewirkt:
+
+1) Falls die Eingabedatei noch nicht existiert, wird eine Fehlermeldung ausgegeben.
+
+2) Falls es eine Datei des Namens gibt, wird auf das erste Zeichen des ersten
+ Satzes positioniert.
+
+
+
+'get'
+ #on("b")#PROC get (FILE VAR f, INT VAR number) #off("b")#
+ Lesen des nächsten Wortes aus der Datei 'f' und Konvertierung des Wortes zu
+ einem Integer-Objekt.
+
+ #on("b")#PROC get (FILE VAR f, REAL VAR number) #off("b")#
+ Lesen des nächsten Wortes aus der Datei 'f' und Konvertierung des Wortes zu
+ einem Real-Objekt.
+
+
+ #on("b")#PROC get (FILE VAR f, TEXT VAR text) #off("b")#
+ Lesen des nächsten Wortes aus der Datei 'f'.
+
+ #on("b")#PROC get (FILE VAR f, TEXT VAR text, TEXT CONST delimiter)#off("b")#
+ Lesen eines TEXT-Wertes 'text' von der Datei 'f', bis das Zeichen 'delimiter'
+ angetroffen wird. Ein eventueller Zeilenwechsel in der Datei wird dabei übergan­
+ gen.
+
+ #on("b")#PROC get (FILE VAR f, TEXT VAR text, INT CONST maxlength)#off("b")#
+ Lesen eines TEXT-Wertes 'text' von der Datei 'f' mit 'maxlength' Zeichen. Ein
+ eventueller Zeilenwechsel in der Datei wird dabei nicht übergangen.
+
+
+
+'getline'
+ #on("b")#PROC get line (FILE VAR file, TEXT VAR record) #off("b")#
+ Lesen der nächsten Zeile aus der sequentiellen Datei 'file'.
+ Mögliche Fehler bei Betriebsrichtung 'input':
+
+ "Datei zu"
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+
+ "Leseversuch nach Dateiende"
+ Es wurde versucht, über die letzte Zeile einer Datei zu lesen.
+
+ "Leseversuch auf output file"
+ Es wurde versucht, von einem mit 'output' assoziierten FILE zu lesen.
+
+ "Unzulässiger Zugriff auf modify-FILE"
+
+#page#
+
+5.3.4 Betriebsrichtung OUTPUT
+
+In der Betriebsrichtung 'output' sind nur Schreiboperationen auf der Datei zugelassen.
+Die Assoziierungsprozedur 'sequential file' bewirkt:
+
+1) Falls die Ausgabedatei noch nicht existiert, wird sie angelegt und auf den ersten
+ Satz positioniert.
+
+2) Falls es bereits eine Datei des Namens gibt, wird hinter den letzten Satz positio­
+ niert, die Datei wird also fortgeschrieben.
+
+
+'put'
+ #on("b")#PROC put (FILE VAR f, INT CONST number) #off("b")#
+ Ausgabe eines INT-Wertes 'number' in die Datei 'f'. Dabei wird ein Leerzeichen
+ an die Ausgabe angefügt.
+
+ #on("b")#PROC put (FILE VAR f, REAL CONST number) #off("b")#
+ Ausgabe eines REAL-Wertes 'number' in die Datei 'f'. Dabei wird ein Leerzei­
+ chen an die Ausgabe angefügt.
+
+ #on("b")#PROC put (FILE VAR f, TEXT CONST text) #off("b")#
+ Ausgabe eines TEXT-Wertes 'text' in die Datei 'f'. Dabei wird ein Leerzeichen an
+ die Ausgabe angefügt.
+
+
+
+'putline'
+ #on("b")#PROC putline (FILE VAR file, TEXT CONST record) #off("b")#
+ Ausgabe eines TEXTes 'record' in die Datei 'file'. Danach wird auf die nächste
+ Zeile positioniert. 'file' muß mit 'output' assoziiert sein.
+
+
+'write'
+ #on("b")#PROC write (FILE VAR f, TEXT CONST text) #off("b")#
+ Schreibt 'text' in die Datei 'f' (analog 'put (f, text)'), aber ohne Trennblank.
+
+
+'line'
+ #on("b")#PROC line (FILE VAR file) #off("b")#
+ Positionierung auf die nächste Zeile der Datei 'file'. Wird versucht, über das Ende
+ eines mit 'input' assoziierten FILEs zu positionieren, wird keine Aktion vorgenom­
+ men.
+
+ #on("b")#PROC line (FILE VAR file, INT CONST lines) #off("b")#
+ Positionierung mit 'lines' Zeilen Vorschub in der Datei 'file'.
+
+
+ FEHLER: "Datei zu!"
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+
+ "Schreibversuch auf input-File"
+ Es wurde versucht, auf einen mit 'input' assoziierten FILE zu
+ schreiben.
+
+
+ Bei Textdateien, die mit dem Editor weiterbearbeitet werden sollen, ist also zu
+ beachten: ine Ausgabe mit 'put' setzt ein 'blank' hinter die Ausgabe. Falls dieses
+ Leerzeichen das letzte Zeichen in der Zeile ist, wird eine Absatzmarke in der Zeile
+ gesetzt. Wird mit 'write' oder 'putline' ausgegeben, steht kein Leerzeichen und
+ somit keine Absatzmarke am Zeilenende.
+#page#
+
+5.3.5 Betriebsrichtung MODIFY
+
+In der Betriebsrichtung 'modify' sind Lese- und Schreiboperationen auf der Datei
+zugelassen. Desweiteren ist beliebiges Positionieren in der Datei erlaubt. Neue Sätze
+können an beliebiger Stelle in die Datei eingefügt werden, die sequentielle Struktur
+der Datei bleibt erhalten. Die Assoziierungsprozedur 'sequential file' bewirkt:
+
+1) Falls die Ausgabedatei noch nicht existiert, wird sie angelegt.
+
+2) Falls es bereits eine Datei des Namens gibt, ist undefiniert wo positioniert ist. Die
+ erste Positionierung muß explizit vorgenommen werden!
+
+
+
+'col'
+ #on("b")#PROC col (FILE VAR f, INT CONST position) #off("b")#
+ Positionierung auf die Spalte 'position' innerhalb der aktuellen Zeile.
+
+ #on("b")#INT PROC col (FILE CONST f) #off("b")#
+ Liefert die aktuelle Position innerhalb der aktuellen Zeile.
+
+
+'down'
+ #on("b")#PROC down (FILE VAR f) #off("b")#
+ Positionieren um eine Zeile vorwärts.
+
+ #on("b")#PROC down (FILE VAR f, INT CONST number) #off("b")#
+ Positionieren um 'number' Zeilen vorwärts.
+
+
+'to line'
+ #on("b")#PROC to line (FILE VAR f, INT CONST number) #off("b")#
+ Positionierung auf die Zeile 'number'.
+
+
+'up'
+ #on("b")#PROC up (FILE VAR f) #off("b")#
+ Positionieren um eine Zeile rückwärts.
+
+ #on("b")#PROC up (FILE VAR f, INT CONST number) #off("b")#
+ Positionieren um 'number' Zeilen rückwärts.
+
+#page#
+'delete record'
+ #on("b")#PROC delete record (FILE VAR file) #off("b")#
+ Der aktuelle Satz der Datei 'file' wird gelöscht. Der folgende Satz wird der aktuelle
+ Satz.
+
+
+'insert record'
+ #on("b'PROC insert record (FILE VAR file) #off("b")#
+ Es wird ein leerer Satz in die Datei 'file' vor die aktuelle Position eingefügt. Dieser
+ Satz kann anschließend mit 'write record' beschrieben werden (d.h. der neue Satz
+ ist jetzt der aktuelle Satz).
+
+
+
+'read record'
+ #on("b")#PROC read record (FILE CONST file, TEXT VAR record) #off("b")#
+ Liest den aktuellen Satz der Datei 'file' in den TEXT 'record'. Die Position wird
+ dabei nicht verändert.
+
+
+
+'write record'
+ #on("b")#PROC write record (FILE VAR file, TEXT CONST record) #off("b")#
+ Schreibt einen Satz in die Datei 'file' an die aktuelle Position. Dieser Satz muß
+ bereits vorhanden sein, d.h. mit 'write record' kann keine leere Datei beschrieben
+ werden, sondern es wird der Satz an der aktuellen Position überschrieben. Die
+ Position in der Datei wird nicht verändert.
+
+
+#page#
+
+5.3.6 FILE -Ausschnitte
+
+Ähnlich den Editorfunktionen 'ESC RUBOUT' und 'ESC RUBIN', die erlauben ganze
+Abschnitte einer Datei zu löschen und das Gelöschte an anderer Stelle wiedereinzu­
+fügen, gibt es die Möglichkeit per Programm solche Segmente
+eines 'modify-FILEs' zu verschieben.
+
+
+'clear removed'
+ #on("b")#PROC clear removed (FILE VAR f) #off("b")#
+ Das mit 'remove' entfernte Segment wird gelöscht und nicht an anderer Stelle
+ eingefügt.
+
+
+'reinsert'
+ #on("b")#PROC reinsert (FILE VAR f) #off("b")#
+ Das mit 'remove' entfernte Segment wird vor die aktuelle Zeile wiedereingefügt.
+
+
+'remove'
+ #on("b")#PROC remove (FILE VAR f, INT CONST size) #off("b")#
+ Löscht 'size' Zeilen vor der aktuellen Position aus 'f'. Das Segment wird in einen
+ internen Puffer geschrieben.
+
+
+'reorganize'
+ #on("b")#PROC reorganize (TEXT CONST datei)#off("b")#
+ Reorganisation von 'datei'. Die durch Löschen und Einfügen aus vielen
+ Segmenten bestehende Datei wird zu einem Segment zusammengefügt, die
+ aktuelle Position ist danach das erste Zeichen der ersten Zeile.
+
+ Durch diese Prozedur kann ggf. Speicherplatz gespart werden.
+
+ #on("b")#PROC reorganize#off("b")#
+ Reorganisation der zuletzt bearbeiteten Datei.
+
+
+'segments'
+ #on("b")#PROC segments (FILE VAR f) #off("b")#
+ Liefert die Anzahl der Segmente von 'f'. Eine große Anzahl von Segmenten kann
+ langsamere Zugriffe zur Folge haben.
+
+#page#
+
+5.4 Suchen und Ersetzen in Textdateien
+
+Such- und Ersetzungsprozeduren können sowohl interaktiv beim Editieren (siehe
+dazu 3.3), als auch in Prozeduren, die auf FILEs (siehe 5.3) arbeiten, angewandt
+werden.
+
+Die dazu dienenden Prozeduren sind im Paket 'pattern match' enthalten. Mit 'Pattern
+Matching' (Muster treffen) wird ein Verfahren bezeichnet Gleichheit von Objekten
+anhand von Regeln, denen diese Objekte genügen, zu überprüfen.
+
+Da oft nach Texten gesucht werden muß, deren genaue Ausprägung nicht bekannt ist,
+oder deren Auftreten nur in einem bestimmten Zusammenhang interessiert, gibt es die
+Möglichkeit feststehende Textelemente mit Elementen ungewisser Ausprägung zu
+kombinieren, also Textmuster zu erzeugen.
+
+Um einen Text zu suchen, muß die Suchrichtung und der gesuchte Text oder ein
+Muster, welches diesen Text beschreibt, angegeben werden.
+
+- Aufbauen von Textmustern : + , - , OR , any , bound , notion
+
+- Suchen nach Textmustern : down , downety , up , uppety
+
+- Treffer registrieren : LIKE , UNLIKE , at , pattern found
+
+- Treffer herausnehmen : ** , match , matchend , matchpos ,
+ somefix , word
+
+- Ändern in Dateien : change
+
+
+Nach einem erfolgreichen Suchvorgang ist stets auf das erste Zeichen der zu such­
+enden Zeichenkette positioniert.
+
+
+Eine besondere Funktion kommt dem 'joker' zu: Dieses Symbol (Defaultwert: '*') steht
+für eine beliebige Zeichenkette beliebiger Länge. Insbesondere bei Ersetzungsaktionen
+in denen dieses Zeichen zur Musterbeschreibung verwendet wird, ist daher Vorsicht
+geboten und sorgfältig zu testen.
+
+#page#
+
+5.4.1 Aufbau von Textmustern
+
+'+'
+ #on("b")#TEXT OP + (TEXT CONST links, rechts) #off("b")#
+ Verkettung der Texte 'links' und 'rechts' zu 'linksrechts'. Falls das Ergebnis länger
+ als die maximal zulässige Textlänge ist, ist es undefiniert.
+
+ Wenn 'muster1' einen beliebigen Text finden sollte, ( Siehe: PROC any) wird das
+ Ende des von 'muster1' erkannten Textes durch den Anfang des von 'muster2'
+ erkannten Textes im Nachhinein definiert.
+
+
+
+'-'
+ #on("b")#TEXT OP - (TEXT CONST alphabet) #off("b")#
+ Der Operator liefert das zu 'alphabet' komplementäre Alphabet, also alle Zeichen
+ gemäß der EUMEL Codetabelle (5.2.4), die nicht in 'alphabet' enthalten sind.
+ Sinnvoll im Zusammenhang mit der Textprozedur 'any'.
+
+
+'OR'
+ #on("b")#TEXT OP OR (TEXT CONST links, rechts) #off("b")#
+ Liefert die Alternative von 'links' und 'rechts'. Die Reihenfolge spielt beim Suchen
+ keine Rolle.
+
+
+
+'any'
+ Die Textprozedur 'any' liefert einen unbekannten Text unbestimmter Länge.
+ Dieser Text sollte entweder durch festen Text sinnvoll eingegrenzt werden, oder
+ direkt eingeschränkt werden.
+
+
+ #on("b")#TEXT PROC any #off("b")#
+ Beschreibt einen beliebigen Text.
+
+ #on("b")#TEXT PROC any (INT CONST laenge) #off("b")#
+ Beschreibt einen beliebigen Text der angebenen Länge.
+
+
+ #on("b")#TEXT PROC any (TEXT CONST alphabet) #off("b")#
+ Beschreibt einen beliebigen Text, der nur aus Zeichen besteht, die in 'alphabet'
+ enthalten sind.
+
+
+ #on("b")#TEXT PROC any (INT CONST laenge, TEXT CONST alphabet) #off("b")#
+ Beschreibt einen Text der vorgegebenen Länge, der nur aus den in 'alphabet'
+ vorgegebenen Zeichen besteht.
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ Die Textprozedur 'any' liefert einen unbekannten Text unbe­
+ stimmter Länge. Dieser Text sollte entweder durch festen Text
+ sinnvoll eingegrenzt werden, oder direkt eingeschränkt werden.
+gib kommando: D("D" OR "d" + any (2,"aeirs")
+ Sucht nach bestimmten Artikeln: 'der', 'die', 'das' etc.
+
+____________________________________________________________________________
+
+
+
+'bound'
+ #on("b")#TEXT PROC bound #off("b")#
+ Bezeichnet ein Muster der Länge null, das nur am Zeilenanfang oder am Zeilenen­
+ de gefunden wird. Ein Präfix 'bound' fordert, daß das gesuchte Muster in der
+ ersten Spalte beginnen muß, ein Postfix 'bound' fordert, daß das Muster mit dem
+ Zeilenende abschließt.
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ Die Textprozedur 'any' liefert einen unbekannten Text unbe­
+ stimmter Länge. Dieser Text sollte entweder durch festen
+ Textsinnvoll eingegrenzt werden, oder direkt eingeschränkt
+ werden.
+gib kommando: U(bound + any (" "))
+
+____________________________________________________________________________
+
+
+
+ liefert Treffer bei eingerückten Zeilen.
+
+
+
+'notion'
+ #on("b")#PROC notion (TEXT CONST suchwort) #off("b")#
+ Mit dieser Prozedur kann ein #on("u")#Wort#off("u")# spezifiziert werden, nach dem gesucht werden
+ soll. Bei der Suche nach 'suchwort' wird nur dann ein Treffer geliefert, wenn
+ 'suchwort' als Wort, also begrenzt von ' ' (blank), '.' , ',' oder anderen Sonderzei­
+ chen ist.
+
+ #on("b")#PROC notion (TEXT CONST suchwort, INT CONST reg) #off("b")#
+ Wie oben, der Treffer wird im Register 'reg' gespeichert.
+
+#page#
+
+5.4.2 Suche nach Textmustern
+
+'down'
+ #on("b")#PROC down (FILE VAR f, TEXT CONST muster) #off("b")#
+ Suche nach 'muster' in der Datei 'f' in Richtung Dateiende. Wird 'muster' gefun­
+ den, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man hinter
+ dem letzten Zeichen der Datei.
+
+ Achtung: 'down' sucht vom nächsten Zeichen rechts ab, so daß wiederholtes
+ Suchen keine Endlosschleife ergibt.
+
+
+ #on("b")#PROC down (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")#
+ Wie obiges 'down', es wird aber maximal nur 'number'-Zeilen weit nach 'muster'
+ gesucht.
+
+
+
+'downety'
+ #on("b")#PROC downety (FILE VAR f, TEXT CONST muster) #off("b")#
+ Suche nach 'muster' in der Datei 'f' in Richtung Dateiende. Wird 'muster' gefun­
+ den, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man auf
+ dem letzten Zeichen der Datei.
+
+ Achtung: 'downety' sucht (im Gegensatz zu 'down') vom aktuellen Zeichen an.
+ Daher muß explizit vorwärts positioniert werden.
+
+
+ #on("b")#PROC downety (FILE VAR f, TEXT CONST muster, INT CONST number) #off("b")#
+ Wie obiges 'downety', aber maximal nur 'number'-Zeilen weit.
+#page#
+'up'
+ #on("b")#PROC up (FILE VAR f, TEXT CONST muster) #off("b")#
+ Suche nach 'muster' in der Datei 'f' in Richtung Dateianfang. Wird 'muster'
+ gefunden, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man
+ auf dem ersten Zeichen der Datei.
+
+ Achtung: 'up' sucht vom nächsten Zeichen links ab, so daß wiederholtes Suchen
+ keine Endlosschleife ergibt.
+
+
+ #on("b")#PROC up (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")#
+ Wie obiges 'up', aber maximal nur 'number'-Zeilen weit.
+
+
+
+'uppety'
+ #on("b")#PROC uppety (FILE VAR f, TEXT CONST muster) #off("b")#
+ Suche nach 'muster' in der Datei 'f' in Richtung Dateianfang. Wird 'muster'
+ gefunden, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man
+ auf dem ersten Zeichen der Datei.
+
+ Achtung: 'uppety' sucht (im Gegensatz zu 'up') vom aktuellen Zeichen.
+
+
+ #on("b")#PROC uppety (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")#
+ Wie obiges 'uppety', aber maximal nur 'number'-Zeilen weit.
+
+#page#
+
+5.4.3 Treffer registrieren
+
+'LIKE'
+ #on("b")#BOOL OP LIKE (TEXT CONST text , muster) #off("b")#
+ Liefert TRUE, falls der Text 'text' 'muster' entspricht. In 'muster' kann das
+ Spezialzeichen '*' verwandt werden, das abkürzend für die Konkatenation mit
+ 'any' steht.
+
+ Daraus folgt, daß das Suchen oder Ersetzen des Zeichens '*' nur durch
+ any (1,"*") zu bewerkstelligen ist.
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ \#Druckdateien aus Thesaurus löschen\#
+ gib kommando:"*.p" C ""
+ 16.04.87 "Handbuch teil1"
+ 04.05.87 "Handbuch teil1.p"
+ 16.04.87 "Handbuch teil2"
+ 06.05.87 "Handbuch teil2.p"
+
+____________________________________________________________________________
+
+
+
+ aber:
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ \#Vordere Kommentarklammern löschen \#
+ gib kommando:"(" + any(1,"*") C ""
+ lernsequenz auf taste legen("a" , "archive") ;
+ (* lernsequenz auf taste legen("(" , ""91"") ; *)
+ (* lernsequenz auf taste legen(")" , ""93"") ; *)
+ kommando auf taste legen("P" , "print("""")"8""8""11"") .
+
+____________________________________________________________________________
+
+
+
+'UNLIKE'
+ #on("b")#BOOL OP UNLIKE (TEXT CONST text , muster) #off("b")#
+ Wirkt wie: '(NOT text LIKE muster)'
+#page#
+
+5.4.4 Treffer herausnehmen
+
+Mit Hilfe der 'Register' ist es möglich identifizierte Texte zwischenzuspeichern und in
+weiteren Aktionen weiterzuverwenden.
+
+
+'**'
+ #on("b")#TEXT OP ** (TEXT CONST muster, INT CONST register)#off("b")#
+ Der als 'muster' erkannte Text wird einem 'Register' mit der Nummer 'register'
+ zugeordnet. Es können 256 Register (1 bis 256) benutzt werden.
+
+
+'match'
+ #on("b")#TEXT PROC match (INT CONST nr) #off("b")#
+ Liefert den Text der dem Register 'nr' zuletzt zugeordnet wurde.
+
+
+'matchpos'
+ #on("b")#INT PROC matchpos (INT CONST nummer) #off("b")#
+ Liefert die Spaltennummer, auf der das dem Register 'nummer' zugeordnete Mu­
+ ster in der Zeile beginnt.
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+
+ gib kommando:D("file"+any+"("+(any ** (1)...
+
+____________________________________________________________________________
+#page#
+
+5.4.5 Ändern in Dateien
+
+'change'
+ #on("b")#PROC change (FILE VAR datei, INT CONST von, bis , TEXT CONST neuertext)#off("b")#
+ In der Datei wird in der aktuellen Zeile in den Ausschnitt zwischen 'von' und 'bis'
+ der Text 'neuertext' eingesetzt.
+
+ entspricht:
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ FILE VAR file := sequential file (modify, name)
+ TEXT VAR zeile;
+ .
+ .
+ read record (file ,zeile);
+ change (zeile, von, bis ,"neuertext");
+ write record (file, zeile);
+ .
+
+____________________________________________________________________________
+
+#page#
+
+5.4.6 Editor-Prozeduren
+
+'edit'
+ #on("b")#edit (TEXT CONST datei)#off("b")#
+ Editieren der Datei 'datei'. Das Editorfenster ist maximal groß (von 1,1 bis
+ max,max). Der Standard-Kommandointerpreter ist gültig, so daß Eingaben, die
+ mit #schl("ESC")# beginnen, interpretiert werden, wie in 3.4 'Vorbelegte Tasten' beschrie­
+ ben.
+
+ #on("b")#edit#off("b")#
+ Wie oben, editiert wird die Datei mit dem zuletzt benutzten Namen.
+
+ #on("b")#edit (THESAURUS CONST thes)#off("b")#
+ Wie oben, editiert werden alle Dateien, deren Namen im Thesaurus 'thes' enthal­
+ ten sind.
+
+ #on("b")#edit (TEXT CONST datei, INT CONST von x, von y, bis x, bis y)#off("b")#
+ Editieren der Datei 'datei'. Das Editorfenster hat die linke obere Ecke bei 'von x,
+ von y' und die rechte untere Ecke bei 'bis x, bis y'.
+
+ #on("b")#edit (FILE VAR f)#off("b")#
+ Editieren der als 'sequential file' assoziierten Textdatei 'f'.
+
+ #on("b")#edit (FILE VAR, INT CONST von x, von y, bis x, bis y)#off("b")#
+ Editieren der als 'sequential file' assoziierten Textdatei in einem Fenster mit der
+ linken, oberen Ecke 'von x, von y' und der rechten, unteren Ecke 'bis x, bis y'.
+
+ #on("b")#edit (FILE VAR f, TEXT CONST res,
+ PROC (TEXT CONST) kdo interpreter)#off("b")#
+ Editieren der als 'sequential file' assoziierten Textdatei 'f'. In 'res' werden reser­
+ vierte Zeichen übergeben, die von der Prozedur 'kdo interpreter' als Kommandos
+ interpretiert werden, wenn sie als ESC-Sequenz eingegeben werden.
+ Beispiel : #schl("ESC ")# #schl("e")#
+
+#page#
+'editget'
+ #on("b")#editget (TEXT VAR ausgabe) #off("b")#
+ Aufruf des Zeileneditor. An der aktuellen Cursorposition wird eine Zeile ausgegeben in
+ der 'ausgabe' steht. Für diese Zeile stehen alle Editiermöglichkeiten zur
+ Verfügung, 'ausgabe' kann also beliebig überschrieben, ergänzt etc. werden. Die
+ Eingabe wird durch #schl("CR")# abgeschlossen. Im Gegensatz zur Prozedur 'get' ist auch
+ eine leere Eingabe möglich.
+
+ #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, INT CONST scroll,
+ TEXT CONST sep, TEXT CONST res, TEXT VAR exit) #off("b")#
+ Wie oben, die Zeilenlänge ist jedoch auf 'zeile' Zeichen begrenzt. Die Eingabe
+ wird durch #schl("CR")# oder durch eine Cursorbewegung über die Position 'zeile' hinaus
+ abgeschlossen.
+
+ Die Angabe 'scroll' setzt die Breite des Zeilenfensters fest, wird diese Breite
+ überschritten, so wird 'ausgabe' gerollt.
+
+ In 'sep' (Separator) können Zeichen festgesetzt werden, mit denen die Eingabe
+ beendet wird (zusätzlich zu CR !).
+
+ In 'res' (reservierte Tasten) können Tasten festgelegt werden, die in Verbindung
+ mit <ESC> die Eingabe beenden.
+
+ Wurde der Zeileneditor durch einen Separator verlassen, so steht in 'exit' dieses
+ Zeichen. Falls der Zeileneditor durch eine reservierte Taste verlassen, so enthält
+ 'exit' 'ESC' und die Taste.
+
+ #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, INT CONST scroll)#off("b")#
+ Bedeutung der Parameter siehe oben.
+
+ #on("b")#editget (TEXT VAR ausgabe, TEXT CONST sep, TEXT CONST res,
+ TEXT VAR exit) #off("b")#
+ Bedeutung der Parameter siehe oben.
+
+ #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, TEXT VAR exit) #off("b")#
+ Bedeutung der Parameter siehe oben.
+#page#
+
+5.4.7 Sortierung von Textdateien
+
+Für die Sortierung von Textdateien gibt es zwei Sortierprogramme:
+
+- Sortierung nach ASCII : sort
+
+- Sortierung nach
+ deutschem Alphabet : lexsort
+
+
+'sort'
+ #on("b")#PROC sort (TEXT CONST datei) #off("b")#
+ Diese Prozedur sortiert die Datei 'datei' zeilenweise gemäß der von der EUMEL
+ Codetabelle (siehe 5.2.4) vorgegebenen Reihenfolge. Zur Sortierung werden die
+ Zeilen vom ersten Zeichen der Zeile beginnend, zeichenweise verglichen und
+ dementsprechend sortiert.
+
+ #on("b")#PROC sort (TEXT CONST datei, INT CONST position) #off("b")#
+ Sortierkriterien wie oben, jedoch wird bei Vergleich und Sortierung der Satz erst
+ ab der Position 'position' beachtet. Sortiert wird der ganze Satz!
+
+
+'lex sort'
+ #on("b")#PROC lex sort (TEXT CONST datei) #off("b")#
+ Zeilenweise Sortierung nach lexikographischer Reihenfolge gemäß DIN 5007. Zu
+ den Vergleichen werden die Operatoren LEXEQUAL, LEXGRATER,
+ LEXGRATEREQUAL benutzt (siehe 5.2.4).
+
+ #on("b")#PROC lex sort (TEXT CONST datei, INT CONST position) #off("b")#
+ Lexikalische Sortierung durch Vergleich ab Position 'position'.
+
+#page#
+
+5.4.8 Prozeduren auf Datenräumen
+
+Neben den Textdateien gibt es im EUMEL-System den Typ Datenraum, der Objekte
+jeglichen Typs aufnehmen kann und direkten Zugriff auf die Objekte gewährt (siehe
+2.9.2).
+
+Für Objekte von Type Datenraum (nicht für die in Datenräumen enthaltenen Objekte!)
+existieren folgende Standardprozeduren:
+
+
+':='
+ #on("b")#OP := ( DATASPACE VAR ds1, DATASPACE CONST ds2)#off("b")#
+ Der Datenraum 'ds1' wird als Kopie von 'ds2' angelegt. Es handelt sich zunächst
+ um eine logische Kopie, eine physische Kopie wird erst nach einem Schreibzugriff
+ auf 'ds1' oder 'ds2' nötig.
+
+
+'new'
+ #on("b")#DATASPACE PROC new (TEXT CONST dsname) #off("b")#
+ Liefert einen neuen Datenraum namens 'dsname'.
+
+____________________________________________________________________________
+
+ DATASPACE VAR ds := new ("datenraum")
+ (* ergibt zwei Datenräume 'ds' und 'datenraum'! *)
+
+____________________________________________________________________________
+
+
+
+'nilspace'
+ #on("b")#DATASPACE PROC nilspace#off("b")#
+ Der 'nilspace' ist ein leerer Datenraum, der ausschließlich als Quelle zum Kopie­
+ ren bei der Initialisierung Verwendung finden darf.
+
+
+'old'
+ #on("b")#DATASPACE PROC old (TEXT CONST dsname) #off("b")#
+ Liefert einen bereits existierenden Datenraum (oder auch eine Datei) mit dem
+ Namen 'dsname'.
+
+ FEHLER : "dsname" gibt es nicht
+
+
+'type'
+ #on("b")#PROC type (DATASPACE CONST ds, INT CONST typ)#off("b")#
+ Der Datenraum 'ds' erhält den frei wählbaren Schlüssel 'typ'. Es muß eine positive
+ Zahl gewählt werden. Der Datenraum muß zum Zeitpunkt der Typzuweisung an
+ ein BOUND Objekt gekoppelt (gewesen) sein.
+
+ #on("b")#INT PROC type (DATASPACE CONST ds)#off("b")#
+ Liefert den Schlüssel des Datenraums 'ds'. Falls 'ds' nie an ein BOUND Objekt
+ gekoppelt war, liefert die Prozedur einen Wert < 0, sonst 0 (keine Zuweisung
+ erfolgt) oder die zugewiesene Typnummer.
+
+
+'dataspaces'
+ #on("b")#INT PROC dataspaces (TASK CONST task) #off("b")#
+ Liefert die Anzahl der Datenräume der Task 'task'.
+
+ #on("b")#INT PROC dataspaces #off("b")#
+ Anzahl der Datenräume von 'myself'.
+
+
+'ds pages'
+ #on("b")#INT PROC ds pages (DATASPACE CONST ds)#off("b")#
+ Liefert die Anzahl der durch 'ds' belegten Seiten (je 512 Byte).
+
+
+'storage'
+ #on("b")#INT PROC storage (DATASPACE CONST ds)#off("b")#
+ Liefert den von 'ds' belegten Speicherplatz in KB.
+
+#page#
+'copy'
+ #on("b")#PROC copy (DATASPACE CONST ds, TEXT CONST datei) #off("b")#
+ Eine neue Datei mit dem Namen 'datei' wird angelegt. Der Inhalt der Datei ist eine
+ Kopie des Inhalts des Datenraumes 'ds'.
+
+
+'forget'
+ #on("b")#PROC forget (DATASPACE CONST ds)#off("b")#
+ Der Datenraum 'ds' wird gelöscht#u#1)#e#.
+
+#foot#
+
+ 1) Durch diese Prozedur steht nicht unmittelbar mehr freier Speicherplatz zur
+ Verfügung. Die physische Räumung von Speicherplatz erfolgt durch die
+ 'Müllabfuhr' bei einem Fixpunkt.
+#end#
+
+'fetch'
+ #on("b")#PROC fetch (DATASPACE CONST ziel, TEXT CONST datei,
+ TASK CONST manager) #off("b")#
+ Aus der Task 'manager' wird der Datenraum der Datei 'datei' in den eigenen
+ Datenraum 'ziel' kopiert.
+
+
+'save'
+ #on("b")#PROC save (DATASPACE CONST quelle, TEXT CONST datei,
+ TASK CONST manager) #off("b")#
+ Der eigene Datenraum 'quelle' wird in die Datei 'datei' in der Task 'manager'
+ kopiert.
+#page#
+
+5.5 Eingabe/Ausgabe
+
+- Eingabesteuerzeichen : HOP , � � � � , TAB , RUBIN , RUBOUT
+ CR , MARK , ESC
+
+- Ausgabesteuerzeichen : HOME , � � � � , CL EOP , CL EOL
+ CPOS , BELL , CR , ENDMARK , BEGINMARK
+
+- Positionierung : cursor , get cursor , line , page
+
+- Eingabe : get , getline , inchar , incharety
+
+- Ausgabe : cout , out , out subtext , put , putline ,
+ TIMESOUT , write
+
+- Kontrolle : online , pause , sysin , sysout
+
+- Zeitmessung : clock , date , day , hour , pause , time
+ time of day
+
+#page#
+
+5.5.1 E/A auf Bildschirm
+
+Steuerzeichen und Standardprozeduren zur Ein- Ausgabe am Bildschirm werden
+zur Steuerung des Dialogverhaltens von Prozeduren benutzt.
+
+
+5.5.1.1 Eingabesteuerzeichen
+Eingabesteuerzeichen werden durch die Funktionstasten (s. 3.2) erzeugt. Die Wirkung
+der Tasten ist ebenfalls an dieser Stelle beschrieben.
+
+Durch die Tasten werden folgende Codes an Programme gegeben:
+
+Codierung I Bezeichnung
+-----------+--------------
+HOP I 1
+RECHTS I 2
+OBEN I 3
+LINKS I 8
+TAB I 9
+UNTEN I 10
+RUBIN I 11
+RUBOUT I 12
+CR I 13
+MARK I 16
+ESC I 27
+
+
+#page#
+
+5.5.1.2 Ausgabesteuerzeichen
+
+Die Ausgabe dieser Zeichen bewirkt folgendes Verhalten der Bildschirmausgabe.
+
+Code I Name I Wirkung
+-----+-------------+-------------------------------------------------------
+ 0 I NUL I keine Wirkung
+ 1 I HOME I Cursor in die linke obere Ecke setzen (Position 0,0!)
+ 2 I RECHTS I Cursor eine Stelle nach rechts setzen
+ 3 I OBEN I Cursor eine Zeile höher setzen
+ 4 I CL EOP I Rest der Seite löschen
+ 5 I CL EOL I Rest der Zeile löschen
+ 6 I CPOS I Cursor setzen, nächstes Ausgabezeichen bestimmt die
+ I I y-Position, das darauf folgende die x-Position.
+ 7 I BELL I akustisches Signal
+ 8 I LINKS I Cursor eine Stelle nach links setzen
+10 I UNTEN I Cursor eine Stelle nach unten setzen
+13 I CR I Cursor an den Anfang der nächsten Zeile setzen
+14 I ENDMARK I Ende des markierten Bereichs
+15 I BEGINMARK I Anfang des markierten Bereichs
+
+
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ TEXT VAR ausgabe := (""7""15"V O R S I C H T"14"7"");
+ out(ausgabe);
+
+____________________________________________________________________________
+
+#page#
+
+5.5.1.3 Positionierung
+
+'cursor'
+ #on("b")#PROC cursor (INT CONST column, row) #off("b")#
+ Positioniert den Cursor auf dem Bildschirm, wobei 'column' die Spalte und 'row'
+ die Zeile angibt. Die zulässigen Bereiche von 'column' und 'row' sind geräteab­
+ hängig.
+
+
+
+'get cursor'
+ #on("b")#PROC get cursor (INT VAR x, y) #off("b")#
+ Erfragung der aktuellen Cursor-Position. Die Koordinaten des Cursors werden in
+ 'x' und 'y' geliefert. Die aktuelle Cursor-Position ist nach Ausgabe von 'HOME'
+ (Code = 1) oder einer Positionierung des Cursors mit der Prozedur 'cursor' stets
+ definiert. Die Prozedur 'get cursor' liefert jedoch undefinierte Werte, wenn über
+ den rechten Rand einer Zeile hinausgeschrieben wurde (die Wirkung einer solchen
+ Operation hängt von der Hardware eines Terminals ab).
+
+
+'line'
+ #on("b")#PROC line #off("b")#
+ Es wird zum Anfang einer neuen Zeile positioniert.
+
+ #on("b")#PROC line (INT CONST number) #off("b")#
+ Es werden 'number' Zeilenwechsel vorgenommen.
+
+
+'page'
+ #on("b")#PROC page #off("b")#
+ Es wird zum Anfang einer neuen Seite positioniert (hier: linke obere Ecke (Position
+ 1,1 !) des Bildschirms, wobei der Bildschirm gelöscht wird).
+
+#page#
+
+5.5.1.4 Eingabe
+
+
+Grundlegende Prozeduren
+Die folgenden Prozeduren dienen ausschließlich der Eingabe vom Terminal.
+
+'editget'
+ Siehe 5.4.6
+
+
+'getchar'
+ #on("b")#PROC getchar (TEXT VAR zeichen)#off("b")#
+ Liest genau ein Zeichen von der Tastatur und schreibt es in die Variable 'zeichen'.
+
+
+'inchar'
+ #on("b")#PROC inchar (TEXT VAR character) #off("b")#
+ Wartet solange, bis ein Zeichen von der Tastatur eingegeben wird, und schreibt
+ dieses Zeichen in die Variable 'character'.
+
+
+'incharety'
+ #on("b")#TEXT PROC incharety #off("b")#
+ Versucht, ein Zeichen von der Tastatur zu lesen. Wurde kein Zeichen eingegeben,
+ wird niltext geliefert.
+
+ #on("b")#TEXT PROC incharety (INT CONST time limit) #off("b")#
+ Versucht, ein Zeichen vom Bildschirm zu lesen. Dabei wird maximal eine 'time
+ limit' lange Zeit auf das Zeichen gewartet (gemessen in Zehntel-Sekunden).
+
+#page#
+
+Umleitbare Eingabeprozeduren
+Die folgenden Eingabeprozeduren lesen ebenfalls vom Terminal, die Eingabequelle
+kann jedoch durch die Prozedur 'sysin' umgestellt werden. Falls in 'sysin' eine Datei
+angegeben wird wird die Eingabe statt vom Terminal aus dieser Datei gelesen.
+
+
+'sysin'
+ #on("b")#PROC sysin (TEXT CONST file name) #off("b")#
+ Eingabe-Routinen lesen nicht mehr vom Benutzer-Terminal, sondern aus der
+ Datei 'file name'.
+
+ #on("b")#TEXT PROC sysin #off("b")#
+ Liefert den Namen der eingestellten 'sysin'-Datei. "" bezeichnet das Benutzer-
+ Terminal.
+
+
+'get'
+ #on("b")#PROC get (INT VAR number) #off("b")#
+ Einlesen eines INT-Wertes vom Bildschirm. Der einzulesende INT-Wert kann
+ bei der Eingabe vom Terminal editiert werden.
+
+ #on("b")#PROC get (REAL VAR value) #off("b")#
+ Einlesen eines REAL-Wertes vom Bildschirm. Der einzulesende REAL-Wert
+ kann bei der Eingabe vom Terminal editiert werden.
+
+ #on("b")#PROC get (TEXT VAR word) #off("b")#
+ Liest einen Text in die Variable 'word' mit maximal 255 Zeichen. Es werden
+ solange Zeichen vom Terminal gelesen, bis ein Leerzeichen oder #schl("CR")# eingegeben
+ wird. Dabei werden führende Leerzeichen übergeben. Der einzulesende Text
+ kann bei der Eingabe editiert werden. Eine leere Eingabe ist nicht erlaubt.
+
+ #on("b")#PROC get (TEXT VAR word, INT CONST laenge) #off("b")#
+ Liest einen Text vom Bildschirm mit der Länge 'laenge' oder bis #schl("CR")# eingegeben
+ wird. Der einzulesende Wert kann bei der Eingabe editiert werden.
+
+ #on("b")#PROC get (TEXT VAR word, TEXT CONST separator) #off("b")#
+ Liest einen Text vom Bildschirm, bis ein Zeichen 'separator' angetroffen oder #schl("CR")#
+ eingegeben wird. Der einzulesende Text kann bei der Eingabe editiert werden.
+
+
+'getline'
+ #on("b")#PROC get line (TEXT VAR line) #off("b")#
+ Das System wartet auf eine Zeile vom Bildschirm (max. 255 Zeichen). #schl("CR")# been­
+ det die Eingabe.
+
+#page#
+
+5.5.1.5 Ausgabe
+
+
+Grundlegende Prozeduren
+Die folgenden Prozeduren dienen ausschließlich der Ausgabe auf das Terminal.
+
+
+'cout'
+ #on("b")#PROC cout (INT CONST number) #off("b")#
+ Schreibt 'number' an die aktuelle Cursor-Position auf den Bildschirm. Anschlie­
+ ßend wird an diese Position wieder zurück positioniert. 'number' muß > 0 sein.
+ Paßt 'number' nicht mehr auf die Zeile, so ist die Wirkung von 'cout' nicht de­
+ finiert. 'cout' gibt den Wert von 'number' nur aus, wenn genügend freie Kanal-
+ Kapazität für diese Ausgabe vorhanden ist. Das hat zur Folge, daß Programme
+ nicht auf die Beendigung einer Ausgabe von 'number' warten müssen und ggf.
+ Ausgaben überschlagen werden.
+
+
+'out'
+ #on("b")#PROC out (TEXT CONST text) #off("b")#
+ Ausgabe eines Textes auf dem Bildschirm. Im Unterschied zu 'put' wird kein
+ Blank an den ausgegebenen Text angefügt.
+
+
+
+'out subtext'
+ #on("b")#PROC out subtext (TEXT CONST source, INT CONST from) #off("b")#
+ Ausgabe eines Teiltextes von 'source' von der Position 'from' bis Textende. Es
+ wird keine Aktion vorgenommen für
+
+
+ from > LENGTH source
+
+
+ #on("b")#PROC out subtext (TEXT CONST source, INT CONST from, to)#off("b")#
+ Ausgabe eines Teiltextes von 'source' von der Position 'from' bis zur Position 'to'.
+ Für
+
+
+ to > LENGTH source
+
+
+ wird out subtext (source, from) ausgeführt.
+
+ #on("b")#PROC out text (TEXT CONST source, INT CONST from, to) #off("b")#
+ Ausgabe eines Teiltextes von 'source' von der Position 'from' bis zur Position 'to'.
+ Für
+
+
+ to > LENGTH source
+
+
+ wird für die fehlenden Zeichen Blanks ausgegeben.
+
+
+
+'TIMESOUT'
+ #on("b")#OP TIMESOUT (INT CONST times, TEXT CONST text) #off("b")#
+ Ausgabe eines TEXTes 'text' 'times'mal. An die Ausgabe wird im Gegensatz zu
+ 'put' kein Leerzeichen angefügt. Es wird kein Text ausgegeben für
+
+
+ times < 1
+
+
+#page#
+
+Umleitbare Ausgabeprozeduren
+Die folgenden Ausgabeprozeduren schreiben ebenfalls auf das Terminal, die Ausgabe
+kann jedoch durch die Prozedur 'sysout' umgeleitet werden. Falls in 'sysout' eine
+Datei angegeben wird wird die Ausgabe statt zum
+Terminal in die angegebene Datei geleitet.
+
+
+'sysout'
+ #on("b")#PROC sysout (TEXT CONST file name) #off("b")#
+ Ausgabe-Routinen gehen nicht mehr zum Benutzer-Terminal, sondern in die
+ Datei 'file name'.
+
+ #on("b")#TEXT PROC sysout #off("b")#
+ Liefert den Namen der eingestellten 'sysout'-Datei. "" bezeichnet das Benut­
+ zer-Terminal.
+
+
+'line'
+ #on("b")#line#off("b")#
+ Positionierung auf den Anfang einer neuen Ausgabezeile.
+
+ #on("b")#line (INT CONST faktor)#off("b")#
+ Nächste Ausgabezeile um 'faktor' Zeilen weiter positionieren.
+
+
+'put'
+ #on("b")#PROC put (INT CONST number) #off("b")#
+ Ausgabe eines INT-Wertes auf dem Bildschirm. Anschließend wird ein Leer­
+ zeichen ausgegeben.
+
+ #on("b")#PROC put (REAL CONST real) #off("b")#
+ Ausgabe eines REAL-Wertes auf dem Bildschirm. Anschließend wird ein Leer­
+ zeichen ausgegeben.
+
+ #on("b")#PROC put (TEXT CONST text) #off("b")#
+ Ausgabe eines Textes auf dem Bildschirm. Nach der Ausgabe von 'text' wird ein
+ Blank ausgegeben, um nachfolgenden Ausgaben auf der gleichen Zeile voneinan­
+ der zu trennen. Hardwareabhängig sind die Aktionen, wenn eine Ausgabe über
+ eine Zeilengrenze (hier: Bildschirmzeile) vorgenommen wird. Meist wird die Ausga­
+ be auf der nächsten Zeile fortgesetzt.
+
+
+'putline'
+ #on("b")#PROC putline (TEXT CONST text) #off("b")#
+ Ausgabe von 'text' auf dem Bildschirm. Nach der Ausgabe wird auf den Anfang
+ der nächsten Zeile positioniert. Gibt man TEXTe nur mit 'putline' aus, so ist
+ gesichert, daß jede Ausgabe auf einer neuen Zeile beginnt. Hardwareabhängig
+ sind die Aktionen, wenn eine Ausgabe über eine Zeilengrenze (hier: Bildschirm­
+ zeile) vorgenommen wird. Meist wird die Ausgabe auf der nächsten Zeile fort­
+ gesetzt.
+
+
+'write'
+ #on("b")#PROC write (TEXT CONST text) #off("b")#
+ Gibt 'text' ohne Trennblank aus ('put' mit Trennblank).
+
+#page#
+
+5.5.1.6 Kontrolle
+
+'online'
+ #on("b")#BOOL PROC online #off("b")#
+ Liefert TRUE, wenn die Task mit einem Terminal gekoppelt ist.
+
+
+'pause'
+ #on("b")#PROC pause (INT CONST time limit) #off("b")#
+ Wartet 'time limit' in Zehntel-Sekunden. Bei negativen Werten ist die Wirkung
+ nicht definiert. Die Wartezeit wird nicht nur durch das Erreichen der Grenze ab­
+ gebrochen, sondern auch durch die Eingabe eines beliebigen Zeichens.
+
+ #on("b")#PROC pause#off("b")#
+ Wartet bis zur Eingabe eines beliebigen Zeichens.
+
+
+#page#
+
+5.5.2 Zeitmessung
+
+'clock'
+ #on("b")#REAL PROC clock (INT CONST index) #off("b")#
+ Datum und Uhrzeit werden vom EUMEL-System für alle Tasks geführt. Neben
+ einer Uhr ('Realzeituhr'), die das Datum und die aktuelle Uhrzeit enthält, wird eine
+ Uhr für die von der Task verbrauchte CPU-Zeit geführt ('CPU-Zeituhr'). Beide
+ Zeiten werden vom System als REALs realisiert. Die Prozedur 'clock' liefert die
+ aktuellen Werte dieser Uhren. Bei 'index = 0' wird die akkumulierte CPU-Zeit
+ der Task, bei 'index = 1' der Wert der Realzeituhr geliefert.
+
+ Mit den REAL-Werten der Uhren kann ohne weiteres gerechnet werden, jedoch
+ sind nur Werte > 0 definiert. Die REAL-Werte der Realzeituhr beginnen beim
+ 1.1.1900 um 0 Uhr. Es sind nur Werte für dieses Jahrhundert zugelassen. Werte
+ der Realzeituhr in lesbarer Form kann man durch die Konvertierungsprozeduren
+ 'date' (vergl. 5- #topage("date")# ) (für den aktuellen Tag) und 'time of day' (Uhrzeit, vergl.
+ 5-#topage("time")#) erhalten.
+
+ Um die benötigte CPU-Zeit eines Programms zu berechnen, muß man die
+ CPU-Zeituhr zweimal abfragen. Um solche Zeiten in lesbarer Form zu erhalten,
+ kann man die Konvertierungsprozedur 'time' (vergl. 5- #topage("time")#) verwenden. Beispiel:
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ REAL CONST anfang :: clock (0);
+ berechnungen;
+ REAL CONST ende :: clock (0);
+ put ("benoetigte CPU-Zeit in Sek:");
+ put (time (ende - anfang))
+
+____________________________________________________________________________
+#page#
+'date'
+#goalpage("date")#
+ #on("b")#TEXT PROC date (REAL CONST time) #off("b")#
+ Konvertierungsprozedur für das Datum, welches sich aus dem Aufruf der Prozedur
+ 'clock (1)' ergibt. Das Datum wird in der Form 'tt.mm.jj' geliefert. Beispiel:
+
+____________________________________________________________________________
+
+ put (date (clock (1))) (* z.B.: 24.12.87 *)
+
+____________________________________________________________________________
+
+
+ #on("b")#REAL PROC date (TEXT CONST datum) #off("b")#
+ Konvertierungsprozedur für ein Datum in der Form 'tt.mm.jj'. Liefert einen
+ REAL-Wert, wie ihn die Prozedur 'clock (1)' liefern würde. Beispiel:
+
+____________________________________________________________________________
+
+ put (date ("24.12.87")) (* 6.273539e10 *)
+
+____________________________________________________________________________
+
+
+ #on("b")#TEXT PROC date#off("b")#
+ Liefert das Tagesdatum. Wirkt wie 'date (clock (1))', ist jedoch erheblich schneller.
+
+
+
+'day'
+ #on("b")#REAL CONST day #off("b")#
+ Liefert die Anzahl der Sekunden eines Tages (86 400.0).
+
+
+
+'hour'
+ #on("b")#REAL CONST hour #off("b")#
+ Liefert die Anzahl der Sekunden einer Stunde (3600.0).
+
+
+
+'pause'
+ #on("b")#PROC pause (INT CONST time limit) #off("b")#
+ Wartet 'time limit' in Zehntel-Sekunden. Bei negativen Werten ist die Wirkung
+ nicht definiert. Die Wartezeit wird nicht nur durch das Erreichen der Grenze ab­
+ gebrochen, sondern auch durch die Eingabe eines beliebigen Zeichens.
+
+
+
+'time'
+#goalpage("time")#
+ #on("b")#TEXT PROC time (REAL CONST time) #off("b")#
+ Konvertierungsprozedur für die Zeiten der CPU-Zeituhr. Liefert die Zeiten in der
+ Form 'hh:mm:ss.s'. Vergl. dazu 'clock'.
+
+ #on("b")#TEXT PROC time (REAL CONST value, INT CONST laenge) #off("b")#
+ Konvertiert die Zeit in externe Darstellung. Für die 'laenge'-Werte ergibt sich:
+
+
+ laenge = 10 (* hh:mm:ss.s *)
+ laenge = 12 (* hhhh:mm:ss.s *)
+
+
+
+ #on("b")#REAL PROC time (TEXT CONST time) #off("b")#
+ Konvertierungsprozedur für Texte der CPU-Zeituhr in REAL-Werte.
+
+
+
+'time of day'
+ #on("b")#TEXT PROC time of day (REAL CONST time) #off("b")#
+ Konvertierungsprozedur für REALs, wie sie die Realzeituhr
+ liefert. Es wird die Tageszeit in der Form 'hh:mm' geliefert. Beispiel:
+
+____________________________________________________________________________
+
+ put (time of day (clock (1))) (* z.B.: 17:25 *)
+
+____________________________________________________________________________
+
+
+ #on("b")#TEXT PROC time of day #off("b")#
+ Liefert die aktuelle Tageszeit. Entspricht
+
+____________________________________________________________________________
+
+ time of day (clock (1))
+
+____________________________________________________________________________
+#page#
+
+5.6 Scanner
+
+Der Scanner kann benutzt werden, um festzustellen, welche Art von Symbolen in
+einem TEXT enthalten sind. Die Repräsentation der Symbole müssen dabei der
+ELAN-Syntax entsprechen. Folgende #ib#Symbole#ie# kann der Scanner erkennen:
+
+ - "tags", d.h. Namen,
+ - "bolds", d.h. Schlüsselworte,
+ - "number", d.h. INT oder REAL Zahlen,
+ - Operatoren,
+ - "delimiter", d.h. Begrenzer wie z.B. ";",
+ - und das Ende des Scan-Textes.
+
+
+Der Scanner überliest Kommentare und Leerzeichen zwischen den Symbolen. Der
+(erste) zu verarbeitende Text muß mit der Prozedur
+
+
+ #ib#scan#ie#
+
+
+in den Scanner "hineingesteckt" werden. Mit der Prozedur
+
+
+ #ib#next symbol#ie#
+
+
+wird das jeweils nächste Symbol des TEXTes geholt. Am Ende wird "end of scan"
+und als Symbol 'niltext' geliefert. Falls innerhalb eines TEXT-Denoters oder eines
+Kommentars "end of scan" auftritt, wird "within text" bzw. "within comment" gemel­
+det. Der Scan-Prozeß kann dann mit dem nächsten zu scannenden TEXT (der
+nächsten Zeile) fortgesetzt werden. Dafür wird nicht die Prozedur 'scan', sondern
+
+
+ #ib#continue scan#ie#
+
+
+verwandt. Sie setzt im letzten Scan-Zustand (z.B. Kommentar oder TEXT-Deno­
+ter) wieder auf, so daß auch Folgen von TEXTen (Zeilen) wie z.B. Dateien leicht
+gescannt werden können.
+
+Mit den Prozeduren
+
+
+ scan (* meldet eine Datei zum scannen an *)
+ next symbol (* holt die Symbole *)
+
+
+kann man auch eine Datei nach ELAN-Symbolen untersuchen.
+
+____________________________________________________________________________
+
+ FILE VAR f :: ...
+ ...
+ scan (f); (* beginnt das Scanning in
+ der nächsten Zeile *)
+ TEXT VAR symbol;
+ INT VAR type;
+ REP
+ next symbol (f, symbol, type);
+ verarbeite symbol
+ UNTIL type >= 7 END REP.
+
+____________________________________________________________________________
+
+#page#
+
+Scanner-Kommandos
+
+
+'continue scan'
+ #on("b")#PROC continue scan (TEXT CONST scan text) #off("b")#
+ Das Scanning soll mit 'scan text' fortgesetzt werden. Falls der Scan-Vorgang
+ beim vorigen 'scan text' innerhalb eines TEXT-Denoters oder eines Kommentars
+ abgebrochen wurde, wird er jetzt entsprechend mit dem nächsten 'next symbol'
+ fortgesetzt. Der erste Teil-Scan einer Folge muß aber stets mit 'scan' eingeleitet
+ werden!
+
+'next symbol'
+ #on("b")#PROC next symbol (TEXT VAR symbol, INT VAR type) #off("b")#
+ Holt das nächste Symbol. In "symbol" steht der TEXT des Symbols, so z.B. die
+ Ziffern eines INT-Denoters. Bei TEXT-Denotern werden die führenden und
+ abschließenden Anführungsstriche abgeschnitten. Leerzeichen oder Kommentare
+ spielen in "tags" oder "numbers" keine Rolle. Zwischen Symbolen spielen Leer­
+ zeichen oder Kommentare keine Rolle. In "type" steht eine Kennzeichung für den
+ Typ des Symbols:
+
+ tag = 1 ,
+ bold = 2 ,
+ number = 3 ,
+ text = 4 ,
+ operator = 5 ,
+ delimiter = 6 ,
+ end of file = 7 ,
+ within comment = 8 ,
+ within text = 9 .
+
+ Wird Scan-Ende innerhalb eines Kommentars gefunden, so wird 'niltext' und
+ 'within comment' geliefert. Wird Scan-Ende innerhalb eines TEXT-Denoters
+ gefunden, so wird der schon analysierte Teil des Denoters und 'within text' gelie­
+ fert.
+
+ #on("b")#PROC next symbol (TEXT VAR symbol) #off("b")#
+ s.o. Es wird aber nur der Text des Symbols (ohne Typ) geliefert.
+
+ #on("b")#PROC next symbol (FILE VAR f, TEXT CONST symbol) #off("b")#
+ Arbeitet wie obige Prozeduren, jedoch auf einen FILE.
+
+ #on("b")#PROC next symbol (FILE VAR f, TEXT CONST symbol, INT VAR type)#off("b")#
+ Arbeitet wie obige Prozeduren, jedoch auf einen FILE.
+
+
+'scan'
+ #on("b")#PROC scan (TEXT CONST scan text) #off("b")#
+ Meldet einen 'scan text' für den Scanner zur Verarbeitung an. Die Prozedur 'scan'
+ muß vor dem ersten Aufruf von 'next symbol' gegeben werden. Im Gegensatz zu
+ 'continue scan' normiert 'scan' den inneren Zustand des Scanners, d.h. vorherige
+ Scan-Vorgänge haben keinen Einfluß mehr auf das Scanning.
+
+ #on("b")#PROC scan (FILE VAR f) #off("b")#
+ Wie obige Prozedur, jedoch auf einen FILE. Die zu scannende Zeile ist die näch­
+ ste Zeile im FILE 'f' ('scan' macht zuerst ein 'getline').
+
diff --git a/doc/programming/programmierhandbuch.6 b/doc/programming/programmierhandbuch.6
new file mode 100644
index 0000000..ce11f6f
--- /dev/null
+++ b/doc/programming/programmierhandbuch.6
@@ -0,0 +1,1441 @@
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 6 : Das Archiv 'std.zusatz'
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+6 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#6 - %
+#end#
+
+TEIL 6: Das Archiv 'std.zusatz'
+
+Das Archiv 'std.zusatz' enthält Pakete, die nur bei Bedarf insertiert werden sollen.
+Eine Einbindung in das EUMEL Grundsystem würde dieses ungebührlich unfangreich
+machen.
+
+Das Archiv enthält zusätzliche Software für:
+
+- mathematische Operationen : complex , longint , vector , matrix
+
+- Analyse : reporter , referencer
+
+- Taschenrechnerfunktion
+ zur Editor-Erweiterung : TeCal , TeCal Auskunft
+
+
+#page#
+
+6.1. Erweiterungen um
+ Mathematische Operationen
+
+
+6.1.1 COMPLEX
+
+Das Packet COMPLEX erweitert das System um den Datentyp COMPLEX (komplexe
+Zahlen) und Operationen auf komplexen Zahlen. Folgende Operationen stehen für
+COMPLEX zur Verfügung:
+
+- Einfache Operatoren : := , = , <> , + ,- , *
+
+- Eingabe/Ausgabe : get , put
+
+- Denotierungsprozedur : complex , complex i , complex one , com­
+ plex zero
+
+- Komponenten : real part , imag part
+
+- bes. Funktionen : ABS , CONJ , phi , dphi , sqrt
+
+#page#
+
+COMPLEX Operationen
+
+
+'TYPE COMPLEX'
+ Komplexe Zahl, bestehend aud Realteil 're' und Imaginärteil 'im'.
+
+
+':='
+ #on("b")#OP := (COMPLEX VAR a, COMPLEX CONST b) #off("b")#
+ Zuweisung.
+
+
+'='
+ #on("b")#BOOL OP = (COMPLEX CONST a, b) #off("b")#
+ Vergleich von 'a' und 'b' auf Gleichheit.
+
+
+'<>'
+ #on("b")#BOOL OP <> (COMPLEX CONST a, b) #off("b")#
+ Vergleich von 'a' und 'b' auf Ungleichheit.
+
+
+'+'
+ #on("b")#COMPLEX OP + (COMPLEX CONST a, b) #off("b")#
+ Summe von 'a' und 'b'.
+
+
+'-'
+ #on("b")#COMPLEX OP - (COMPLEX CONST a, b) #off("b")#
+ Differenz von 'a' und 'b'.
+
+
+'*'
+ #on("b")#COMPLEX OP * (COMPLEX CONST a, b) #off("b")#
+ Multiplikation von 'a' mit 'b'.
+
+
+'/'
+ #on("b")#COMPLEX OP / (COMPLEX CONST a, b) #off("b")#
+ Division von 'a' mit 'b'.
+
+#page#
+'get'
+ #on("b")#PROC get (COMPLEX VAR a) #off("b")#
+ Einlesen eines komplexen Wertes vom Bildschirm in der Form zweier REAL-De­
+ noter. Die Eingabe kann editiert werden.
+
+
+'put'
+ #on("b")#PROC put (COMPLEX CONST a) #off("b")#
+ Ausgabe eines komplexen Wertes auf dem Bildschirm in Form zweier REAL-
+ Werte. Hinter jedem REAL-Wert wird ein Leerzeichen angefügt.
+
+
+'complex'
+ #on("b")#COMPLEX PROC complex (REAL CONST re, im) #off("b")#
+ Denotierungsprozedur. Angabe in kartesischen Koordinaten.
+
+
+'complex i'
+ #on("b")#COMPLEX PROC complex i #off("b")#
+ Denotierungsprozedur für den komplexen Wert '0.0 + i 1.0'.
+
+
+'complex one'
+ #on("b")#COMPLEX PROC complex one #off("b")#
+ Denotierungsprozedur für den komplexen Wert '1.0 + i 0.0'.
+
+
+'complex zero'
+ #on("b")#COMPLEX PROC complex zero #off("b")#
+ Denotierungsprozedur für den komplexen Wert '0.0 + i 0.0'.
+
+
+'imag part'
+ #on("b")#REAL PROC imag part (COMPLEX CONST number) #off("b")#
+ Liefert den Imaginärteil des komplexen Wertes 'number'.
+
+
+'real part'
+ #on("b")#REAL PROC real part (COMPLEX CONST number) #off("b")#
+ Liefert den Real-Teil des komplexen Wertes 'number'.
+
+
+'ABS'
+ #on("b")#REAL OP ABS (COMPLEX CONST x) #off("b")#
+ REAL-Betrag von 'x'.
+
+
+'CONJ'
+ #on("b")#COMPLEX OP CONJ (COMPLEX CONST number) #off("b")#
+ Liefert den konjugiert komplexen Wert von 'number'.
+
+
+'dphi'
+ #on("b")#REAL PROC dphi (COMPLEX CONST x) #off("b")#
+ Winkel von 'x' (Polardarstellung).
+
+
+'phi'
+ #on("b")#REAL PROC phi (COMPLEX CONST x) #off("b")#
+ Winkel von 'x' (Polardarstellung) in Radiant.
+
+
+'sqrt'
+ #on("b")#COMPLEX PROC sqrt (COMPLEX CONST x) #off("b")#
+ Wurzelfunktion für komplexe Werte.
+
+#page#
+
+6.1.2 LONGINT
+
+LONGINT ist ein Datentyp, für den (fast) alle Prozeduren und Operatoren des Daten­
+typs INT implementiert wurden. LONGINT unterscheidet sich von INT dadurch, daß
+erheblich größere Werte darstellbar sind.
+
+Für den Datentyp LONGINT stehen folgende Operationen zur Verfügung:
+
+- Operatoren : := , = , <> , < , <= ,> , >= , + , - , * ,
+ ** ,
+ ABS , DECR , DIV , INCR , MOD , SIGN
+
+- Eingabe/Ausgabe : get , put
+
+
+- Math. Prozeduren : abs , int , longint , max , max logint , min ,
+ random , sign , text , zero
+
+
+
+LONGINT-Operationen
+
+
+'TYPE LONGINT'
+ Datentyp
+
+
+':='
+ #on("b")#OP := (LONGINT VAR links, LONGINT CONST rechts) : #off("b")#
+ Zuweisungsoperator
+
+
+'= '
+ #on("b")#BOOL OP = (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf Gleichheit.
+
+
+'<>'
+ #on("b")#BOOL OP <> (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf Ungleichheit.
+
+
+'< '
+ #on("b")#BOOL OP < (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf kleiner.
+
+
+'<='
+ #on("b")#BOOL OP <= (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf kleiner gleich.
+
+
+'> '
+ #on("b")#BOOL OP > (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf größer.
+
+
+'>='
+ #on("b")#BOOL OP >= (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf größer gleich.
+
+
+'+ '
+ #on("b")#LONGINT OP + (LONGINT CONST argument) #off("b")#
+ Monadischer Operator. Ohne Wirkung.
+
+ #on("b")#LONGINT OP + (LONGINT CONST links, rechts) #off("b")#
+ Addition zweier LONGINTs.
+
+
+'- '
+ #on("b")#LONGINT OP - (LONGINT CONST argument) #off("b")#
+ Vorzeichenumkehrung.
+
+ #on("b")#LONGINT OP - (LONGINT CONST links, rechts) #off("b")#
+ Subtraktion zweier LONGINTs.
+
+
+'* '
+ #on("b")#LONGINT OP * (LONGINT CONST links, rechts) #off("b")#
+ Multiplikation von zwei LONGINTs.
+
+
+'**'
+ #on("b")#LONGINT OP ** (LONGINT CONST argument, exponent) #off("b")#
+ Exponentiation zweier LONGINTs mit positivem Exponenten.
+
+ FEHLER :
+ LONGINT OP ** : negative exponent
+ Der 'exponent' muß >= 0 sein.
+ 0 ** 0 is not defined
+ 'argument' und 'exponent' dürfen nicht gleich 0 sein.
+
+
+ #on("b")#LONGINT OP ** (LONGINT CONST argument, INT CONST exponent)#off("b")#
+ Exponentiation eines LONGINT mit positiven INT Exponenten.
+
+ FEHLER :
+ LONGINT OP ** : negative exponent
+ Der 'exponent' muß >= 0 sein.
+ 0 ** 0 is not defined
+ 'argument' und 'exponent' dürfen nicht gleich 0 sein.
+
+'ABS'
+ #on("b")#LONGINT OP ABS (LONGINT CONST argument) #off("b")#
+ Absolutbetrag eines LONGINT.
+
+
+'DECR'
+ #on("b")#OP DECR (LONGINT VAR resultat, LONGINT CONST ab) #off("b")#
+ resultat := resultat - ab
+
+
+'DIV'
+ #on("b")#LONGINT OP DIV (LONGINT CONST links, rechts) #off("b")#
+ Division zweier LONGINTs.
+
+ FEHLER :
+ Division durch 0
+ 'rechts' muß <> 0 sein.
+
+
+'INCR'
+ #on("b")#LONGINT OP INCR (LONGINT VAR resultat, LONGINT CONST dazu)#off("b")#
+ resultat := resultat + dazu
+
+
+
+'MOD'
+ #on("b")#LONGINT OP MOD (LONGINT CONST links, rechts) #off("b")#
+ Modulo-Funktion für LONGINTs. Der Rest einer LONGINT-Division wird ermit­
+ telt.
+
+ FEHLER :
+ text (links) + 'MOD 0'
+ 'rechts' muß ungleich null sein.
+
+
+'SIGN'
+ #on("b")#INT OP SIGN (LONGINT CONST longint) #off("b")#
+ Feststellen des Vorzeichens von 'longint'. Liefert:
+
+
+ 0 wenn 'longint' = 0,
+ 1 wenn 'longint' > 0,
+ -1 wenn 'longint' < 0.
+
+
+#page#
+'get'
+ #on("b")#PROC get (LONGINT VAR zahl) #off("b")#
+ Eingabe eines LONGINTs vom Terminal.
+
+ #on("b")#PROC get (FILE VAR file, LONGINT VAR zahl) #off("b")#
+ Einlesen von 'zahl' aus der sequentiellen Datei 'file'. Die Datei muß mit 'input'
+ assoziiert sein (vergl. 'sequential file').
+
+ FEHLER :
+ Datei zu
+ Leseversuch nach Daateiende
+ Leseversuch auf output-FILE
+
+
+'put'
+ #on("b")#PROC put (LONGINT CONST longint) #off("b")#
+ Ausgabe eines LONGINTs auf dem Bildschirm. Anschließend wird ein Leerzeichen
+ ausgegeben. Hardwareabhängig sind die Aktionen, wenn eine Ausgabe über die
+ Bildschirmzeilengrenze vorgenommen wird. Meist wird jedoch die Ausgabe auf der
+ nächsten Zeile fortgesetzt.
+
+ #on("b")#PROC put (FILE VAR file, LONGINT CONST zahl) #off("b")#
+ Ausgabe von 'zahl' in die sequentielle Datei 'file'. 'file' muß mit 'output' assoziiert
+ sein.
+
+ FEHLER :
+ Datei zu
+ Schreibversuch auf input-FILE
+#page#
+'abs'
+ #on("b")#LONGINT PROC abs (LONGINT CONST argument) #off("b")#
+ Absolutbetrag eines LONGINT.
+
+
+'int'
+ #on("b")#INT PROC int (LONGINT CONST longint) #off("b")#
+ Konvertierung von LONGINT nach INT.
+
+ FEHLER :
+ integer overflow
+ 'longint' ist größer als 'maxint'.
+
+
+'longint'
+ #on("b")#LONGINT PROC longint (INT CONST int) #off("b")#
+ Konvertierung von 'int' nach LONGINT.
+
+ #on("b")#LONGINT PROC longint (TEXT CONST text) #off("b")#
+ Konvertierung von 'text' nach LONGINT.
+
+
+'max'
+ #on("b")#LONGINT PROC max (LONGINT CONST links, rechts) #off("b")#
+ Liefert das Maximum zweier LONGINTs.
+
+
+'maxlongint'
+ #on("b")#LONGINT PROC max longint #off("b")#
+ Liefert größten LONGINT Wert.
+
+
+'min'
+ #on("b")#LONGINT PROC min (LONGINT CONST links, rechts) #off("b")#
+ Liefert das Minimum zweier LONGINTs.
+
+
+'random'
+ #on("b")#LONGINT PROC random (LONGINT CONST lower bound, upper bound)#off("b")#
+ Pseudo-Zufallszahlen-Generator im Intervall 'lower bound' und 'upper bound'
+ einschließlich. Es handelt sich hier um den 'LONGINT Random Generator'.
+
+
+'sign'
+ #on("b")#INT PROC sign (LONGINT CONST longint) #off("b")#
+ Feststellen des Vorzeichens von 'longint'. Liefert:
+
+
+ 0 wenn 'longint' = 0,
+ 1 wenn 'longint' > 0,
+ -1 wenn 'longint' < 0.
+
+
+
+'text'
+ #on("b")#TEXT PROC text (LONGINT CONST longint) #off("b")#
+ Konvertierung von 'longint' nach TEXT.
+
+ #on("b")#TEXT PROC text (LONGINT CONST longint, INT CONST laenge) #off("b")#
+ Konvertierung von 'longint' nach TEXT. Die Anzahl der Zeichen soll 'laenge'
+ betragen. Für
+
+
+ LENGTH (text (longint)) < laenge
+
+
+ werden die Zeichen rechtsbündig in einen Text mit der Länge 'laenge' eingetra­
+ gen. Ist der daraus entstehende TEXT kleiner als 'laenge', werden die an 'laenge'
+ fehlenden Zeichen im TEXT mit Leerzeichen aufgefüllt. Für
+
+
+ LENGTH (text (longint)) > laenge
+
+
+ wird ein Text mit der Länge 'laenge' geliefert, der mit '*'-Zeichen gefüllt ist.
+
+
+'zero'
+ #on("b")#LONGINT PROC zero #off("b")#
+ Liefert LONGINT Wert Null.
+
+
+#page#
+
+6.1.3 VECTOR
+
+Der Datentyp VECTOR erlaubt Operationen auf Vektoren aus Elementen vom Typ
+REAL. Im Gegensatz zur Struktur 'ROW m REAL' muß die Anzahl der Elemente nicht
+zur Übersetzungszeit deklariert werden, sondern kann zur Laufzeit festgelegt werden.
+Somit kann eine zur Übersetzungszeit unbekannte Anzahl von REALs bearbeitet
+werden, wobei nur soviel Speicherplatz wie nötig verwendet wird. Die maximale Größe
+eines VECTOR beträgt 4000 Elemente.
+
+Der in den Operationen ':=', 'idn' und 'vector' benutzte Datentyp INITVECTOR wird
+nur intern gehalten. Er dient der Speicherplatzersparnis bei der Initialisierung.
+
+
+- Operatoren : := , = , <> , + , - , * , /
+ LENGTH , SUB
+
+- Eingabe/Ausgabe : get , put
+
+- Besondere Vector- : length , nilvector , norm , vector , replace
+ Operationen
+
+#page#
+':='
+ #on("b")#OP := (VECTOR VAR ziel, VECTOR CONST quelle) #off("b")#
+ Zuweisung. Nach der Zuweisung gilt auch
+
+
+ length (quelle) = length (ziel)
+
+
+ d.h. der linke Operand besitzt nach der Zuweisung genauso viele Elemente wie
+ 'quelle', unabhängig davon, ob 'ziel' vor der Zuweisung mehr oder weniger Ele­
+ mente als 'quelle' besaß. Beispiel:
+
+
+ VECTOR VAR y :: vector (10, 1.0),
+ z :: vector (15, 2.0);
+ ...
+ y := z; (* length (y) liefert nun 15 ! *)
+
+
+ #on("b")#OP := (VECTOR VAR ziel, INITVECTOR CONST quelle) #off("b")#
+ Dient zur Initialisierung eines VECTORs. Beispiel:
+
+
+ VECTOR VAR x :: vector (17);
+
+
+ 'vector' erzeugt ein Objekt vom Datentyp INITVECTOR. Dieses Objekt braucht
+ nicht soviel Speicherplatz wie ein VECTOR-Objekt. Dadurch wird vermieden, daß
+ nach erfolgter Zuweisung nicht ein durch 'vector' erzeugtes Objekt auf dem Heap
+ unnötig Speicherplatz verbraucht.
+
+
+'='
+ #on("b")#BOOL OP = (VECTOR CONST a, b) #off("b")#
+ Vergleich zweier Vektoren. Der Operator liefert FALSE, wenn die Anzahl der
+ Elemente von 'a' und 'b' ungleich ist oder wenn zwei Elemente mit gleichem
+ Index ungleich sind. Beispiel:
+
+
+ VECTOR VAR x :: vector (10, 1.0),
+ y :: vector (15, 2.0),
+ z :: vector (10, 1.0);
+ ... x = y ... (* FALSE *)
+ ... x = z ... (* TRUE *)
+
+
+'<>'
+ #on("b")#BOOL OP <> (VECTOR CONST a, b) #off("b")#
+ Vergleich zweier Vektoren auf Ungleichheit (NOT (a = b)).
+
+
+'+'
+ #on("b")#VECTOR OP + (VECTOR CONST a) #off("b")#
+ Monadisches '+' für VECTOR. Keine Auswirkung.
+
+ #on("b")#VECTOR OP + (VECTOR CONST a, b) #off("b")#
+ Elementweise Addition der Vektoren 'a' und 'b'. Beispiel:
+
+
+ VECTOR VAR x, (* 'x' hat undefinierte Länge *)
+ a :: vector (10, 1.0),
+ b :: vector (10, 2.0);
+ ...
+ x := a + b; (* 'x' hat nun 10 Elemente mit Werten'3.0'
+ *)
+
+ FEHLER :
+ VECTOR OP + : LENGTH a <> LENGTH b
+ 'a' und 'b' haben nicht die gleiche Anzahl von Elementen.
+
+
+'-'
+ #on("b")#VECTOR OP - (VECTOR CONST a) #off("b")#
+ Monadisches '-'.
+
+ #on("b")#VECTOR OP - (VECTOR CONST a, b) #off("b")#
+ Elementweise Subtraktion der Vektoren 'a' und 'b'.
+
+ FEHLER :
+ VECTOR OP - : LENGTH a <> LENGTH b
+ 'a' und 'b' haben nicht die gleiche Anzahl von Elementen.
+
+'*'
+ #on("b")#REAL OP * (VECTOR CONST a, b) #off("b")#
+ Skalarprodukt zweier Vektoren. Liefert die Summe der elementweisen Multiplika­
+ tion der Vektoren 'a' und 'b'. Beachte eventuelle Rundungsfehler! Beispiel:
+
+
+ REAL VAR a;
+ VECTOR VAR b :: vector (10, 2.0),
+ c :: vector (10, 2.0);
+ ...
+ a := b * c; (* 40.0 *)
+
+ FEHLER :
+ REAL OP * : LENGTH a <> LENGTH b
+ 'a' und 'b' haben nicht die gleiche Anzahl von Elementen.
+
+ #on("b")#VECTOR OP * (VECTOR CONST a, REAL CONST s) #off("b")#
+ Multiplikation des Vektors 'a' mit dem Skalar 's'.
+
+ #on("b")#VECTOR OP * (REAL CONST s, VECTOR CONST a) #off("b")#
+ Multiplikation des Skalars 's' mit dem Vektor 'a'.
+
+
+'/'
+ #on("b")#VECTOR OP / (VECTOR CONST a, REAL CONST s) #off("b")#
+ Division des Vektors 'a' durch den Skalar 's'. Beispiel:
+
+
+ VECTOR VAR a, (* 'a' hat undefinierte Laenge *)
+ b :: vector (10, 4.0);
+ ...
+ a := b / 2.0;
+ (* 'a' hat nun 10 Elemente mit Werten '2.0' *)
+
+
+
+'LENGTH'
+ #on("b")#INT OP LENGTH (VECTOR CONST a) #off("b")#
+ Liefert die Anzahl der Elemente von 'a'.
+
+
+'SUB'
+ #on("b")#REAL OP SUB (VECTOR CONST v, INT CONST i) #off("b")#
+ Liefert das 'i'-te Element von 'v'.
+
+ FEHLER :
+ OP SUB : subscript overflow
+ Der Index 'i' liegt außerhalb des Vektors (i > LENGTH v).
+ OP SUB : subscript underflow
+ Der Index 'i' liegt außerhalb des Vektors (i < 1).
+
+#page#
+'get'
+ #on("b")#PROC get (VECTOR VAR a, INT CONST l) #off("b")#
+ Einlesen der Elemente von 'a' vom Terminal, wobei 'l' die Anzahl der Elemente
+ angibt.
+
+ FEHLER :
+ PROC get : size <= 0
+ Die angeforderte Elementanzahl 'l' muß > 0 sein.
+
+
+'put'
+ #on("b")#PROC put (VECTOR CONST v) #off("b")#
+ Ausgabe der Werte der Elemente von 'v' auf dem Terminal.
+
+
+#page#
+'length'
+ #on("b")#INT PROC length (VECTOR CONST a) #off("b")#
+ Liefert die Anzahl der Elemente von 'a'. Beispiel:
+
+
+ VECTOR VAR a :: vector (10, 1.0),
+ b :: vector (15, 2.0);
+ ...
+ ... length (a) ... (* 10 *)
+ ... length (b) ... (* 15 *)
+
+
+
+'nilvector'
+ #on("b")#INITVECTOR PROC nilvector #off("b")#
+ Erzeugen eines Vektors mit einem Element mit dem Wert '0.0'.
+
+
+'norm'
+ #on("b")#REAL PROC norm (VECTOR CONST v) #off("b")#
+ Euklidische Norm (Wurzel aus der Summe der Quadrate der Elemente).
+
+
+
+'replace'
+ #on("b")#PROC replace (VECTOR VAR v, INT CONST i, REAL CONST r)#off("b")#
+ Zuweisung des i-ten Elementes von 'v' mit dem Wert von 'r'. Beispiel:
+
+
+ VECTOR VAR v :: ...;
+ ...
+ replace (v, 13, 3.14);
+ (* Das 13. Element von 'v' bekommt den Wert '3.14' *)
+
+ FEHLER :
+ PROC replace : subscript overflow
+ Der Index 'i' liegt außerhalb des Vektors (i > LENGTH v).
+ PROC replace : subscript underflow
+ Der Index 'i' liegt außerhalb des Vektors (i < 1).
+
+
+'vector'
+ #on("b")#INITVECTOR PROC vector (INT CONST l) #off("b")#
+ Erzeugen eines Vektors mit 'l' Elementen. Ein INITVECTOR-Objekt benötigt nicht
+ soviel Speicherplatz wie ein VECTOR-Objekt. Die Elemente werden mit dem
+ Wert '0.0' initialisiert.
+
+ FEHLER :
+ PROC vector : size <= 0
+ Die angeforderte Elementanzahl 'l' muß > 0 sein.
+
+ #on("b")#INITVECTOR PROC vector (INT CONST l, REAL CONST value)#off("b")#
+ Erzeugen eines Vektors mit 'l' Elementen. Ein INITVECTOR-Objekt benötigt nicht
+ soviel Speicherplatz wie ein VECTOR-Objekt. Die Elemente werden mit dem
+ Wert 'value' initialisiert. Beispiel:
+
+
+ VECTOR VAR v := vector (17, 3.14159);
+ (* 'v' hat 17 Elemente mit den Wert '3.14159' *)
+
+ FEHLER :
+ PROC vector : size <= 0
+ Die angeforderte Elementanzahl 'l' muß > 0 sein.
+
+#page#
+
+6.1.4 MATRIX
+
+Der Datentyp MATRIX erlaubt Operationen auf m x n Matrizen. Im Gegensatz zur
+Struktur 'ROW m ROW n REAL' muß die Anzahl der Elemente nicht zur Überset­
+zungszeit deklariert werden, sondern kann zur Laufzeit festgelegt werden. Somit kann
+eine zur Übersetzungszeit unbekannte Anzahl von REALs bearbeitet werden, wobei
+nur soviel Speicherplatz wie nötig verwendet wird. Die maximale Größe einer MATRIX
+beträgt 4000 Elemente.
+
+Der in den Operationen ':=', 'idn' und 'matrix' benutzte Datentyp INITMATRIX wird
+nur intern gehalten. Er dient der Speicherplatzersparnis bei der Initialisierung.
+
+
+- Operatoren : := , = , <> , + , - , *
+ COLUMNS , DET , INV , ROWS , TRANSP ,
+
+- Eingabe/Ausgabe : get , put
+
+- Besondere Matrix- : column , idn , matrix , row , sub
+ Operationen transp ,
+ replace column , replace element ,
+ replace row
+
+
+
+#page#
+':='
+ #on("b")#OP := (MATRIX VAR l, MATRIX CONST r) #off("b")#
+ Zuweisung von 'r' auf 'l'. Die MATRIX 'l' bekommt u.U. eine neue Anzahl von
+ Elementen. Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 4, 0.0),
+ b :: matrix (5, 5, 3.0);
+ ...
+ a := b; (* 'a' hat jetzt 5 x 5 Elemente *)
+
+
+ #on("b")#OP := (MATRIX VAR l, INITMATRIX CONST r) #off("b")#
+ Dient zur Initialisierung einer Matrix. Beispiel:
+
+
+ MATRIX VAR x :: matrix (17, 4);
+
+
+ 'matrix' erzeugt ein Objekt vom Datentyp INITMATRIX. Dieses Objekt braucht
+ nicht soviel Speicherplatz wie ein MATRIX-Objekt. Dadurch wird vermieden, daß
+ nach erfolgter Zuweisung nicht ein durch 'matrix' erzeugtes Objekt auf dem Heap
+ unnötig Speicherplatz verbraucht.
+
+'='
+ #on("b")#BOOL OP = (MATRIX CONST l, r) #off("b")#
+ Vergleich zweier Matrizen. Der Operator '=' liefert FALSE, wenn die Anzahl
+ Spalten oder Reihen der Matrizen 'l' und 'r' ungleich ist und wenn mindestens ein
+ Element mit gleichen Indizes der zwei Matrizen ungleiche Werte haben. Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 3),
+ b :: matrix (3, 3, 1.0),
+ c :: matrix (4, 4);
+ ... a = b ...
+ (* FALSE wegen ungleicher Werte *)
+ ... a = c ...
+ (* FALSE wegen ungleicher Groesse *)
+ ... b = c ...
+ (* FALSE wegen ungleicher Groesse *)
+
+
+
+'<>'
+ #on("b")#BOOL OP <> (MATRIX CONST l, r) #off("b")#
+ Vergleich der Matrizen 'l' und 'r' auf Ungleichheit.
+
+
+'+'
+ #on("b")#MATRIX OP + (MATRIX CONST m) #off("b")#
+ Monadisches '+'. Keine Auswirkungen.
+
+ #on("b")#MATRIX OP + (MATRIX CONST l, r) #off("b")#
+ Addition zweier Matrizen. Die Anzahl der Reihen und der Spalten muß gleich sein.
+ Beispiel:
+
+ MATRIX VAR a :: matrix (3, 43, 1.0),
+ b :: matrix (3, 43, 2.0),
+ summe;
+ summe := a + b;
+ (* Alle Elemente haben den Wert '3.0' *)
+
+
+ FEHLER:
+ MATRIX OP + : COLUMNS l <> COLUMNS r
+ Die Anzahl der Spalten von 'l' und 'r' sind nicht gleich.
+ MATRIX OP + : ROWS l <> ROWS r
+ Die Anzahl der Zeilen von 'l' und 'r' sind nicht gleich.
+
+
+'-'
+ #on("b")#MATRIX OP - (MATRIX CONST m) #off("b")#
+ Monadisches Minus. Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 4, 10.0)
+ a := - a; (* Alle Elemente haben den Wert '- 10.0' *)
+
+
+ #on("b")#MATRIX OP - (MATRIX CONST l, r) #off("b")#
+ Subtraktion zweier Matrizen. Die Anzahl der Reihen und Spalten muß gleich sein.
+
+ FEHLER:
+ MATRIX OP - : COLUMNS l <> COLUMNS r
+ Die Anzahl der Spalten von 'l' und 'r' sind nicht gleich.
+ MATRIX OP - : ROWS l <> ROWS r
+ Die Anzahl der Zeilen von 'l' und 'r' sind nicht gleich.
+
+'*'
+ #on("b")#MATRIX OP * (REAL CONST r, MATRIX CONST m) #off("b")#
+ Multiplikation einer Matrix 'm' mit einem Skalar 'r'. Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 4, 2.0);
+ ...
+ a := 3 * a; (* Alle Elemente haben den Wert '6.0' *)
+
+
+ #on("b")#MATRIX OP * (MATRIX CONST m, REAL CONST r) #off("b")#
+ Multiplikation einer Matrix 'm' mit einem Skalar 'r'.
+
+ #on("b")#MATRIX OP * (MATRIX CONST l, r) #off("b")#
+ Multiplikation zweier Matrizen. Die Anzahl der Spalten von 'l' und die Anzahl der
+ Zeilen von 'r' müssen gleich sein. Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 4, 2.0),
+ b :: matrix (4, 2, 3.0),
+ produkt;
+ produkt := a * b;
+ (* Alle Elemente haben den Wert '24.0' *)
+
+
+ FEHLER :
+ MATRIX OP * : COLUMNS l <> ROWS r
+ Die Anzahl der Spalten von 'l' muß mit der Anzahl der Zeilen von 'r'
+ übereinstimmen.
+
+ #on("b")#VECTOR OP * (VECTOR CONST v, MATRIX CONST m) #off("b")#
+ Multiplikation des Vektors 'v' mit der Matrix 'm'.
+
+ FEHLER :
+ VECTOR OP * : LENGTH v <> ROWS m
+ Die Anzahl der Elemente von 'v' stimmt nicht mit den Anzahl der Zeilen
+ von 'm' überein.
+
+ #on("b")#VECTOR OP * (MATRIX CONST m, VECTOR CONST v) #off("b")#
+ Multiplikation der Matrix 'm' mit dem Vektor 'v'.
+
+ FEHLER :
+ VECTOR OP * : COLUMNS m <> LENGTH v
+ Die Anzahl der Spalten von 'm' stimmt nicht mit der Anzahl der Ele­
+ menten von 'v' überein.
+
+
+'COLUMNS'
+ #on("b")#INT OP COLUMNS (MATRIX CONST m) #off("b")#
+ Liefert die Anzahl der Spalten von 'm'. Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 4),
+ b :: matrix (7, 10);
+ put (COLUMNS a); (* 4 *)
+ put (COLUMNS b); (* 10 *)
+
+
+
+'DET'
+ #on("b")#REAL OP DET (MATRIX CONST m) #off("b")#
+ Es wird der Wert der Determinanten von 'm' geliefert.
+
+ FEHLER :
+ OP DET : no square matrix
+ Die Matrix ist nicht quadratisch, d.h. ROWS m <> COLUMNS m
+
+
+'INV'
+ #on("b")#MATRIX OP INV (MATRIX CONST m) #off("b")#
+ Liefert als Ergebnis die Inverse von 'm' (Achtung: starke Rundungsfehler möglich).
+
+ FEHLER:
+ OP INV : no square matrix
+ Die Matrix 'm' ist nicht quadratisch,
+ d.h. ROWS m <> COLUMNS m
+ OP INV : singular matrix
+ Die Matrix ist singulär.
+
+
+'ROWS'
+ #on("b")#INT OP ROWS (MATRIX CONST m) #off("b")#
+ Liefert die Anzahl der Zeilen von 'm'. Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 4),
+ b :: matrix (7, 10);
+ ...
+ put (ROWS a); (* 3 *)
+ put (ROWS b); (* 7 *)
+
+
+
+'TRANSP'
+ #on("b")#MATRIX OP TRANSP (MATRIX CONST m) #off("b")#
+ Liefert als Ergebnis die transponierte Matrix 'm'.
+
+#page#
+'get'
+ #on("b")#PROC get (MATRIX VAR m, INT CONST rows, columns) #off("b")#
+ Einlesen von Werten für die Matrix 'm' vom Terminal mit 'rows'-Zeilen und
+ 'columns'-Spalten.
+
+
+'put'
+ #on("b")#PROC put (MATRIX CONST m) #off("b")#
+ Ausgabe der Werte einer Matrix auf dem Terminal.
+#page#
+'column'
+ #on("b")#VECTOR PROC column (MATRIX CONST m, INT CONST i) #off("b")#
+ Die 'i'-te Spalte von 'm' wird als VECTOR mit 'ROWS m' Elementen geliefert.
+ Beispiel:
+
+
+ MATRIX CONST a :: matrix (3, 4);
+ VECTOR VAR b :: column (a, 1);
+ (* 'b' hat drei Elemente mit den Werten '0.0' *)
+
+ FEHLER:
+ PROC column : subscript overflow
+ Der Index 'i' liegt außerhalb der Matrix 'm' (i > COLUMNS m).
+ PROC column : subscript underflow
+ Der Index 'i' liegt außerhalb der Matrix 'm' (i < 1).
+
+'idn'
+ #on("b")#INITMATRIX PROC idn (INT CONST size) #off("b")#
+ Erzeugen einer Einheitsmatrix vom Datentyp INITMATRIX. Beispiel:
+
+
+ MATRIX VAR a :: idn (10);
+ (* Erzeugt eine Matrix mit 10 x 10 Elementen, deren
+ Werte '0.0' sind, mit der Ausnahme der Diagonalele­
+ mente, die den Wert '1.0' haben.*)
+
+ FEHLER :
+ PROC idn : size <= 0
+ Die angeforderte 'size' Anzahl Spalten oder Zeilen muß > 0 sein.
+
+
+'matrix'
+ #on("b")#INITMATRIX PROC matrix (INT CONST rows, columns) #off("b")#
+ Erzeugen eines Datenobjekts vom Datentyp INITMATRIX mit 'rows' Zeilen und
+ 'columns' Spalten. Alle Elemente werden mit dem Wert '0.0' initialisiert. Beispiel:
+
+
+ MATRIX CONST :: matrix (3, 3);
+
+ FEHLER:
+ PROC matrix : rows <= 0
+ Die angeforderte Zeilenanzahl 'rows' muß > 0 sein.
+ PROC matrix : columns <= 0
+ Die angeforderte Spaltenanzahl 'columns' muß > 0 sein.
+
+ #on("b")#INITMATRIX PROC matrix (INT CONST rows, columns, REAL CONST value)#off("b")#
+ Erzeugen eines Datenobjekts vom Datentyp MATRIX mit 'rows' Zeilen und 'co­
+ lumns' Spalten. Alle Elemente der erzeugten MATRIX werden mit dem Wert
+ 'value' initialisiert. Beispiel:
+
+
+ MATRIX CONST :: matrix (3, 3, 3.14);
+
+ FEHLER:
+ PROC matrix : rows <= 0
+ Die angeforderte Zeilenanzahl 'rows' muß > 0 sein.
+ PROC matrix : columns <= 0
+ Die angeforderte Spaltenanzahl 'columns' muß > 0 sein.
+
+
+'row'
+ #on("b")#VECTOR PROC row (MATRIX CONST m, INT CONST i) #off("b")#
+ Die 'i'-te Reihe von 'm' wird als VECTOR mit 'COLUMNS m' Elementen gelie­
+ fert. Beispiel:
+
+
+ MATRIX CONST a :: matrix (3, 4);
+ VECTOR VAR b :: row (a, 1);
+ (* 'b' hat vier Elemente mit den Werten '0.0'*)
+
+ FEHLER:
+ PROC row : subscript overflow
+ Der Index 'i' liegt außerhalb der Matrix 'm' (i > ROWS m).
+ PROC row : subscript underflow
+ Der Index 'i' liegt außerhalb der Matrix 'm' (i < 1).
+
+
+'sub'
+ #on("b")#REAL PROC sub (MATRIX CONST m, INT CONST row, column) #off("b")#
+ Liefert den Wert eines Elementes von 'm', welches durch die Indizes 'row' und
+ 'column' bestimmt wird. Beispiel:
+
+
+ MATRIX VAR m :: matrix (5, 10, 1.0);
+ put (sub (m, 3, 7));
+
+ FEHLER:
+ PROC sub : row subscript overflow
+ Der Index 'row' liegt außerhalb von 'm' (row > ROWS m).
+ PROC sub : row subscript underflow
+ Der Index 'row' liegt außerhalb von 'm' (row < 1).
+ PROC sub : column subscript overflow
+ Der Index 'column' liegt außerhalb von 'm' (column > ROWS m).
+ PROC sub : row subscript underflow
+ Der Index 'column' liegt außerhalb von 'm' (column < 1).
+
+
+'transp'
+ #on("b")#PROC transp (MATRIX VAR m) #off("b")#
+ Transponieren der Matrix 'm', wobei kaum zusätzlicher Speicherplatz benötigt
+ wird.
+
+#page#
+'replace column'
+ #on("b")#PROC replace column (MATRIX VAR m, INT CONST column index, VECTOR
+ CONST column value) #off("b")#
+ Ersetzung der durch 'column index' definierten Spalte in der MATRIX 'm' durch
+ den VECTOR 'column value'. Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 5, 1.0);
+ VECTOR VAR b :: vector (3, 2.0);
+ ...
+ replace column (a, 2, b);
+ (* Die zweite Spalte von 'a' wird durch die Werte von
+ 'b' ersetzt *)
+
+ FEHLER:
+ PROC replace column : LENGTH columnvalue <> ROWS m
+ Die Anzahl der Zeilen der MATRIX 'm' stimmt nicht mit der Anzahl der
+ Elemente von 'columnvalue' überein.
+ PROC replace column : column subscript overflow
+ Der Index 'columnindex' liegt außerhalb von 'm'
+ (columnindex > COLUMNS m).
+ PROC sub : column subscript underflow
+ Der Index 'columnindex' liegt außerhalb von 'm' (columnindex < 1).
+
+
+'replace element'
+ #on("b")#PROC replace element (MATRIX VAR m , INT CONST row, column,
+ REAL CONST value) #off("b")#
+ Ersetzung eines Elementes von 'm' in der 'row'-ten Zeile und 'column'-ten
+ Spalte durch den Wert 'value'. Beispiel:
+
+
+ MATRIX VAR a :: matrix (5, 5);
+ ...
+ replace element (1, 1, 3.14159);
+
+ FEHLER:
+ PROC replace element : row subscript overflow
+ Der Index 'row' liegt außerhalb von 'm' (row > ROWS m).
+ PROC replace element : row subscript underflow
+ Der Index 'row' liegt außerhalb von 'm' (row < 1).
+ PROC replace element : column subscript overflow
+ Der Index 'column' liegt außerhalb von 'm' (column > COLUMNS m).
+ PROC replace element : row subscript underflow
+ Der Index 'column' liegt außerhalb von 'm' (column < 1).
+
+
+'replace row'
+ #on("b")#PROC replace row (MATRIX VAR m, INT CONST rowindex,
+ VECTOR CONST rowvalue) #off("b")#
+ Ersetzung der Reihe 'rowindex' in der MATRIX 'm' durch den VECTOR 'rowvalue'.
+ Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 5, 1.0);
+ VECTOR VAR b :: vector (5, 2.0);
+ ...
+ replace row (a, 2, b);
+ (* Die 2. Reihe von 'a' wird durch Werte von 'b'ersetzt *)
+
+ FEHLER:
+ PROC replace row : LENGTH rowvalue <> COLUMNS m
+ Die Anzahl der Spalten der MATRIX 'm' stimmt nicht mit der Anzahl der
+ Elemente von 'rowvalue' überein.
+ PROC replace row : row subscript overflow
+ Der Index 'rowindex' liegt außerhalb von 'm'
+ (rowindex > ROWS m).
+ PROC sub : row subscript underflow
+ Der Index 'rowindex' liegt außerhalb von 'm' (rowindex < 1).
+
+6.2 Programmanalyse
+
+Das Packet 'reporter' ermöglicht:
+
+a) Ablaufinformationen ("trace");
+b) #ib#Häufigkeitszählung#ie# ("frequency count");
+c) Programmunterbrechung bei Nichterfüllung einer Bedingung ("#ib#assertion#ie#").
+
+
+'Installation'
+Das Programm befindet sich in der Datei 'reporter' und kann wie üblich insertiert
+werden. Jedoch muß es mit 'check off' übersetzt werden, damit keine Zeilennummern
+für 'reporter' generiert werden. Dies ist notwendig, damit die Zeilennummern des zu
+testenden Programms nicht mit den Zeilennummern des Programms 'reporter' ver­
+wechselt werden können. Beispiel:
+
+
+ check off; insert ("reporter"); check on
+
+
+Mit dem Kommando
+
+
+ #ib#generate reports#ie# ("testdatei")
+
+
+werden die oben erwähnten Prozeduraufrufe ('#ib#report#ie#') in das zu testende Programm,
+welches in der Datei 'testdatei' steht, geschrieben. Die Prozeduraufrufe werden nach
+jedem Prozedur-, Operator- oder Refinement-Kopf eingefügt und erhalten den
+entsprechenden Namen als Parameter. Diese Prozeduraufrufe werden gekennzeichnet,
+damit sie von der Prozedur
+
+
+ eliminate reports ("testdatei")
+
+
+automatisch wieder entfernt werden können. Beispiel (für die eingefügten Prozedurauf­
+rufe):
+
+
+ ...
+ PROC beispiel (INT CONST mist):
+ \#\#report ("PROC beispiel");\#\#
+ ...
+
+
+
+'Automatische Ablaufinformation'
+Ist ein Programm mit 'generate reports' mit 'report'-Aufrufen versehen worden, kann
+es wie gewohnt übersetzt werden. Wird das Programm vom ELAN-Compiler kor­
+rekt übersetzt und dann gestartet, wird bei jedem Antreffen eines 'report'-Aufrufs der
+Parameter (Name der Prozedur, Operator oder Refinement) in eine Datei, die
+TRACE-Datei geschrieben. Die TRACE-Datei wird beim Programmlauf automatisch
+von 'reporter' unter dem Namen 'TRACE' eingerichtet.
+
+Mit Hilfe dieser Datei kann der Programmablauf verfolgt werden. Es ist damit auch
+möglich festzustellen, wo eine "Endlos-Rekursion" auftritt. Die Ablaufinformationen
+bestehen nur aus den Namen der angetroffenen Prozeduren und Refinements. Trotz­
+dem können die Anzahl der Informationen sehr umfangreich werden. Deshalb gibt es
+die Möglichkeit, die Erzeugung der Ablaufinformationen ab- bzw. wieder anzuschal­
+ten. Dazu gibt es die Möglichkeit, in das zu testende Programm die Prozeduren
+
+
+ #ib#report on#ie#
+ #ib#report off#ie#
+
+
+einzufügen und das zu testende Programm mit diesen Prozeduraufrufen (erneut) zu
+übersetzen.
+
+
+'Benutzereigene Ablaufinformation'
+Zusätzlich zu den von 'generate reports' eingefügten 'report'-Aufrufen kann ein
+Benutzer eigene Aufrufe an geeigneten Stellen in ein Programm schreiben. Dafür
+werden weitere 'report'-Prozeduren zur Verfügung gestellt, die als ersten Parameter
+ein TEXT-Objekt (meist Name des Objekts oder der Ausdruck selbst) und als zwei­
+ten ein INT/REAL/TEXT/ BOOL-Objekt (der zu überprüfende Wert oder Ausdruck)
+enthalten. Beispiel:
+
+
+ ...
+ PROC beispiel (INT CONST mist):
+ \#\#report ("beispiel");\#\# (* automatisch eingefuegte *)
+ INT VAR mist :: ...; ...
+ \#\#report ("mist:", mist);\#\# (* vom Benutzer per Hand einge­
+ fuegt *)
+ ...
+
+
+Folgende 'report'-Routinen stehen zur Verfügung, damit man sie "von Hand" in ein
+zu testendes Programm einfügen kann:
+
+
+ PROC report on
+ PROC report off
+ PROC report (TEXT CONST message)
+ PROC report (TEXT CONST message, INT CONST value)
+ PROC report (TEXT CONST message, REAL CONST value)
+ PROC report (TEXT CONST message, TEXT CONST value)
+ PROC report (TEXT CONST message, BOOL CONST value)
+
+
+Wichtig: Hier - wie bei allen anderen "von Hand eingefügten" Aufrufen - sollte
+ein Nutzer sich an die Konvention halten, diese in "\#\#" einzuklammern. Mit 'eliminate
+reports' werden diese Einfügungen automatisch entfernt. Sollen diese Aufrufe aber
+immer im Programm erhalten bleiben (jedoch nicht wirksam sein), sollten sie
+
+a) vor 'generate reports'-Aufruf mit jeweils '\#\#\#' eingefaßt werden. Beispiel:
+ \#\#\# report ("...") \#\#\#
+ So steht das 'report'-Statement in einem Kommentar. 'generate reports' wandelt
+ '\#\#\#' --> '\#\#\#\#' um, so daß ein solches Statement wirksam wird. 'eliminate
+ reports' wandelt ein '\#\#\#\#' --> '\#\#\#' zurück.
+
+b) nach 'generate reports' in '\#\#\#\#' eingefaßt werden.
+
+
+'Häufigkeitszählung'
+Eine Häufigkeitszählung erhält man, in dem man in das zu testende Programm die
+Aufrufe
+
+
+ count on
+ count off
+
+
+einfügt. Ist die Häufigkeitszählung eingeschaltet, merkt sich 'reporter' die Anzahl der
+Durchläufe für jede Prozedur bzw. Refinement. Mit der Prozedur
+
+
+ #ib#generate counts#ie# ("zu testende datei")
+
+
+werden die vermerkten Häufigkeiten in das zu testende Programm direkt eingefügt.
+Die Häufigkeiten werden wie oben beschrieben gekennzeichnet, so daß sie mit 'elimi­
+nate reports' entfernt werden können.
+
+
+'Assertions'
+Zusätzlich zu den oben erwähnten Möglichkeiten bietet 'reporter' noch die Prozedur
+
+
+ #ib#assert#ie#
+
+
+an. Diese Prozedur kann von einem Programmierer an einer Stelle in das zu testende
+Programm eingefügt werden, an der bestimmte Bedingungen erfüllt sein müssen. Die
+Prozedur 'assert' steht in zwei Formen zur Verfügung:
+
+
+ PROC #ib#assert#ie# (BOOL CONST zusicherung)
+ PROC assert (TEXT CONST message, BOOL CONST zusicherung)
+
+
+Ist der Wert von 'zusicherung' nicht TRUE, wird der Programmlauf abgebrochen.
+
+
+
+reporter - Kommandos
+
+
+'count on'
+ #on("b")#PROC count on #off("b")#
+ Schaltet die Häufigkeitszählung ein.
+
+'count off'
+ #on("b")#PROC count off #off("b")#
+ Schaltet die Häufigkeitszählung aus.
+
+'eliminate reports'
+ #on("b")#PROC eliminate reports (TEXT CONST datei) #off("b")#
+ Entfernt gekennzeichnete 'report'-Aufrufe aus der Datei 'datei'.
+
+'generate reports'
+ #on("b")#PROC generate reports (TEXT CONST datei) #off("b")#
+ Fügt 'report'-Aufrufe in die Datei 'datei' ein und kennzeichnet diese mit '\#\#'.
+
+'report on'
+ #on("b")#PROC report on #off("b")#
+ Schaltet die Ablaufinformationen in die Datei 'TRACE' ein.
+
+'report off'
+ #on("b")#PROC report off #off("b")#
+ Schaltet die Ablaufinformationen wieder aus.
+
+'generate counts'
+ #on("b")#PROC generate counts (TEXT CONST datei) #off("b")#
+ Bringt die Häufigkeitszählung (wie oft eine Prozedur oder Refinement durchlaufen
+ wurde) in die Programmdatei 'datei'. Mit 'eliminate reports' werden diese wieder
+ automatisch entfernt.
+
+'assert'
+ #on("b")#PROC assert (TEXT CONST message, BOOL CONST value) #off("b")#
+ Schreibt 'message' und den Wert von 'value' in die TRACE-Datei. Ist 'value'
+ FALSE, wird angefragt, ob das Programm fortgesetzt werden soll.
+#page#
+
+Referencer
+
+
+'referencer' wird durch
+
+
+ referencer ("ref datei", "referenz liste")
+
+
+aufgerufen, wobei die Datei 'referenz liste' nicht existieren darf. 'referenz liste' enthält
+nach Ablauf des Programms die gewünschte Liste, die sogenannte #ib# Referenzliste#ie#.
+
+#ub#Achtung#ue#: 'referencer' arbeitet ausschließlich mit Namen und verarbeitet nur wenige
+syntaktische Konstrukte. Darum ist es nur erlaubt, ein PACKET auf einmal von 'refe­
+rencer' verarbeiten zu lassen. Verarbeitet man mehrere PACKETs auf einmal, kann es
+geschehen, daß gleichnamige Objekte in unterschiedlichen Paketen zu Warnungen
+(vergl. die unten beschriebenen Überprüfungen) führen.
+
+In der Referenzliste sind
+
+- alle Objekte mit ihrem Namen (in der Reihenfolge ihres Auftretens im Programm)
+
+- alle Zeilennummern, in der das Objekt angesprochen wird
+
+- die Zeilennummern, in der das Objekt deklariert wurde ('L' für ein lokales und 'G'
+ für ein globales Objekt, 'R' für ein Refinement)
+
+verzeichnet.
+
+Die Referenzliste kann u.a. dazu dienen, zu kontrollieren, ob und wie (bzw. wo) ein
+Objekt angesprochen wird. Dies lohnt sich selbstverständlich nur bei etwas umfan­
+greicheren Programmen (bei "Mini"-Programmen kann man dies sofort sehen).
+
+Bei der Erstellung der Referenzliste nimmt das Programm 'referencer' gleichzeitig
+einige Überprüfungen vor, die helfen können, ein Programm zu verbessern:
+
+1. Warnung bei mehrzeiligen Kommentaren.
+
+2. Überdeckungsfehler. Wird ein Objekt global (auf PACKET-Ebene) und nochmals
+ lokal in einer Prozedur deklariert, ist das globale Objekt nicht mehr ansprechbar.
+ Überdeckungen sind nach der gültigen Sprachdefinition z.Zt. noch erlaubt, werden
+ aber bei einer Revision des Sprachstandards verboten sein.
+
+3. Mehrmaliges Einsetzen von Refinements. Wird ein Refinement mehrmals einge­
+ setzt (das ist völlig legal), sollte man überlegen, ob sich dieses Refinement nicht
+ zu einer Prozedur umgestalten läßt.
+
+4. Nicht angewandte Refinements. Wird ein Refinement zwar deklariert, aber nicht
+ "aufgerufen", erfolgt eine Warnung.
+
+5. Nicht angesprochene Daten-Objekte. Werden Daten-Objekte zwar deklariert,
+ aber im folgenden nicht angesprochen, wird eine Warnung ausgegeben. Hinweis:
+ Alle Objekte, die nur wenig angesprochen werden, also nur wenige Zeilennum­
+ mern in der Referenzliste besitzen, sind verdächtig (Ausnahmen: importierte
+ Prozeduren, LET-Objekte u.a.m.).
+
+
+
+referencer - Kommandos
+
+
+'referencer'
+ #on("b")#PROC referencer (TEXT CONST check file, dump file) #off("b")#
+ Überprüft 'check file'. In 'dump file' steht nach Abschluß die Referenzliste.
+
+#page#
+
+6.3 Rechnen im Editor
+
+Das Programm TeCal ermöglicht einfache Rechnungen (ähnlich wie mit einem Ta­
+schenrechner) unter der Benutzung des Editors. Gleichzeitig stehen dem Benutzer
+aber alle Fähigkeiten des Editors zur Verfügung. TeCal ermöglicht Rechnungen auf
+einfache Weise zu erstellen oder Tabellenspalten zu berechnen. Zur Benutzung
+müssen 'TeCal' und 'TeCal Auskunft' insertiert werden.
+
+TeCal wird aus dem Editor heraus durch 'ESC t' oder durch das Editor-Kommando
+
+
+ tecal
+
+
+aktiviert. Dadurch wird in der untersten Zeile des Bildschirms eine Informationszeile
+aufgebaut, in der die (Zwischen-) Ergebnisse einer Rechnung zur Kontrolle fest­
+gehalten werden.
+
+
+
+Arbeitsweise
+
+
+Wenn TeCal insertiert ist, kann die Taschenrechnerfunktion jederzeit durch <ESC> <t>
+aufgerufen werden. Aus der editierten Datei werden Werte mit <ESC> <L> gelesen,
+durch <ESC> <+> (bzw. -,*,/) verknüpft und mit <ESC> <S> an die aktuelle Cursor­
+position geschrieben werden.
+
+Der von TeCal errechnete Wert wird durch <ESC> <S> derart ausgegeben, daß an der
+Stelle an der der Cursor steht die letzte Stelle vor dem Dezimalpunkt geschrieben
+wird.
+
+Die Eingabe von Klammern geschieht durch <ESC> <(> <ESC> <)>.
+
+Durch die Hilfsfunktion <ESC> <?> lassen sich die TeCal Funktionen auflisten.
+
+Der Prozentoperator <ESC> <%> erlaubt einfache Rechnungen der Form: 'zahl' <ESC> <+>
+<ESC> <%> <ESC> <=> .
+
+Derartige Folgen können natürlich mit der bekannten Editor-Lernfunktion auch ge­
+lernt werden, so daß sich z.B. die Mehrwertsteuerberechnung auf wenige Tasten
+reduziert.
+
+Spalten können summiert werden, indem auf der #on("u")#untersten#off("u")# Zahl einer Spalte <ESC> <V>
+eingegeben wird. Daraufhin werden alle darüberliegende Zahlen addiert, bis ein
+Zeichen auftritt, das nicht in einer Zahl auftritt (Leerzeichen stören nicht!).
+
+____________________________________________________________________________
+ ............
+ 55.00
+ 66.99
+ 123.45
+
+ 99.99
+
+ 9876.54
+ ...........
+
+ Anzeige: 0.00 14.00% Memory: 0.00
+
+____________________________________________________________________________
+
+
+TeCal Prozeduren
+
+
+'evaluate'
+ #on("b")#evaluate (TEXT CONST zeile, INT CONST von) #off("b")#
+ Ausdruck 'zeile' ab der Stelle 'von' berechnen.
+
+ #on("b")#evaluate (TEXT CONST zeile) #off("b")#
+ Ausdruck 'zeile' ab Stelle 1 berechnen.
+
+
+'kommastellen'
+ #on("b")#kommastellen (INT CONST stellen) #off("b")#
+ Berechnungen auf 'stellen' Zahlen hinter dem Komma einstellen.
+
+
+'merke'
+ #on("b")#PROC merke (INT CONST zahl)#off("b")#
+ Integer 'zahl' im Merkregister abspeichern.
+
+ #on("b")#PROC merke (REAL CONST zahl)#off("b")#
+ Real 'zahl' im Merkregister abspeichern.
+
+'prozentsatz'
+ #on("b")#PROC prozentsatz (INT CONST zahl) #off("b")#
+ Prozentsatz von 'zahl' Prozent einstellen. Der Wert wird automatisch konvertiert.
+
+ #on("b")#PROC prozentsatz (REAL CONST zahl) #off("b")#
+ Prozentsatz von 'zahl' Prozent einstellen.
+
+
+'tecal'
+ #on("b")#PROC tecal (FILE VAR f) #off("b")#
+ Datei 'f', die mit 'sequential file' assoziiert ist, mit TeCal editieren.
+
+ #on("b")#PROC tecal (TEXT VAR datei) #off("b")#
+ 'datei' mit TeCal editieren.
+
+ #on("b")#PROC tecal #off("b")#
+ Zuletzt editierte Datei mit TeCal editieren.
+
+
+'tecalauskunft'
+ #on("b")#PROC tecalauskunft #off("b")#
+ Auskunft zeigen.
+
+ #on("b")#PROC tecalauskunft (TEXT CONST zeichen) #off("b")#
+ Auskunft zu 'zeichen' zeigen.
+
diff --git a/doc/programming/programmierhandbuch.index b/doc/programming/programmierhandbuch.index
new file mode 100644
index 0000000..f3f4ede
--- /dev/null
+++ b/doc/programming/programmierhandbuch.index
@@ -0,0 +1,449 @@
+#pagenr("%",1)##block##pageblock#
+#headandbottom("1","EUMEL-Benutzerhandbuch","INDEX","Index")#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#INDEX
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Index - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Index - %
+#end#
+#lpos(0.2)##lpos(6.2)#
+
+INDEX
+
+#table#
+* 5-11, 5-18, 5-32, 6-19, 6-27, 6-4, 6-9
+** 5-11, 5-19, 5-60, 6-10
++ 4-20, 5-11, 5-18, 5-32, 5-54, 6-18, 6-26, 6-3, 6-9
+- 4-20, 5-11, 5-18, 5-54, 6-18, 6-26, 6-3, 6-9
+/ 4-20, 4-22, 5-18, 6-19, 6-4
+:= 2-91, 5-10, 5-17, 5-30, 5-65, 6-17, 6-25, 6-3, 6-8
+< 5-10, 5-17, 5-30, 6-8
+<= 5-10, 5-17, 5-30, 6-8
+<> 5-10, 5-17, 5-30, 6-18, 6-26, 6-3, 6-8
+= 5-10, 5-17, 5-30, 6-17, 6-25, 6-3, 6-8
+> 5-10, 5-17, 5-30, 6-9
+>= 5-10, 5-17, 5-30, 6-9
+
+Abfragekette 2-25
+ABS 6-10, 6-6
+abs 5-13, 5-20, 6-13
+Abweisende Schleife 2-29
+ALL 4-17
+all 4-17
+AND 5-7
+any 5-54
+Archiv 4-44
+Archivdiskette 4-47
+archive 1-9, 4-24, 4-45
+arctan 5-20
+arctand 5-20
+assert 6-39
+assertion 6-36
+Assertions 6-39
+Ausgabesteuerzeichen 5-70
+Ausschalten des Geräts 1-17
+Automatische Ablaufinformation 6-37
+
+begin 2-78, 4-3
+begin password 4-40
+Benutzereigene Ablaufinformation 6-37
+BOOL-Denoter: 2-9
+BOUND 2-83
+bound 5-56
+break 4-4
+brother 4-23
+bulletin 4-8
+
+CAND 5-7
+CAT 5-32
+change 5-33
+change 5-61
+change all 5-33
+check 4-49, 5-4
+clear 4-46
+clear removed 5-51
+clock 5-80
+code 5-34
+col 5-48
+column 6-31
+COLUMNS 6-28
+COMPILER ERROR 5-5
+complex 6-5
+complex i 6-5
+complex one 6-5
+complex zero 6-5
+compress 5-34
+configurator 1-9
+CONJ 6-6
+Container 5-26
+continue 4-3
+continue scan 5-83
+copy 4-26, 5-67
+COR 5-7
+cos 5-20
+cosd 5-20
+count off 6-39
+count on 6-39
+cout 5-75
+cursor 5-71
+
+dataspaces 5-66
+date 5-81
+Datenraum 1-3
+Datensicherheit 1-8
+day 5-81
+decimal exponent 5-20
+DECR 5-12, 5-19, 6-10
+delete char 5-34
+delete record 5-50
+Der EUMEL-Zeichensatz 5-29
+Der Lernmodus 3-17
+DET 6-28
+DIRFILE 2-73
+DIV 5-12, 6-11
+do 5-2
+down 5-48, 5-57
+downety 5-57
+dphi 6-6
+ds pages 5-66
+
+e 5-21
+edit 3-1, 4-29, 5-62
+editget 4-30, 5-63, 5-72
+editor 1-9
+Editor verlassen 3-2
+Ein- bzw. Ausschalten der Markierung 3-9
+Ein- bzw. Ausschalten des Einfügemodus 3-10
+Einfügen von Textpassagen 3-6
+Eingabesteuerzeichen 5-69
+Eingabetaste / Absatztaste 3-4
+eliminate reports 6-39
+Endlosschleife 2-28
+enter password 4-41
+eof 5-43
+erase 4-37
+Erweiterbarkeit 1-6
+
+ESC ) 3-16
+ESC ( 3-16
+ESC > 3-16
+ESC < 3-16
+ESC 9 3-14
+ESC 1 3-14
+ESC a 3-16
+ESC A 3-16
+ESC b 3-14
+ESC blank 3-16
+ESC d 3-15
+ESC e 3-14
+ESC ESC 3-16
+ESC f 3-14
+ESC g 3-15
+ESC HOP 3-17
+ESC HOP HOP 3-17
+ESC HOP taste 3-17
+ESC k 3-16
+ESC n 3-14
+ESC O 3-16
+ESC o 3-16
+ESC p 3-15
+ESC q 3-14
+ESC RUBIN 3-15
+ESC RUBOUT 3-15
+ESC s 3-16
+ESC ? taste 3-16
+ESC ! taste 3-16
+ESC U 3-16
+ESC u 3-16
+ESC v 3-14
+ESC w 3-14
+ESC k 3-16
+ESC ­ 3-16
+
+EUMEL-Editor 3-1
+evaluate 6-44
+exp 5-21
+
+false 5-7
+family password 4-42
+father 4-23
+Fehlermeldungen des Archivs 4-52
+fetch 4-33, 5-67
+fetchall 4-34
+FILE 2-73
+Fixpunkt 1-8
+floor 5-21
+forget 4-26, 4-47, 5-67
+frac 5-21
+
+Garbage Collection 5-26
+Gelerntes vergessen 3-17
+generate counts 6-40
+generate reports 6-40
+get 2-80, 5-44, 5-73, 6-5, 6-12, 6-21, 6-30
+getchar 5-72
+get cursor 5-71
+getline 5-45, 5-74
+
+Häufige Fehler bei der Benutzung von Datenräumen 2-85
+Häufigkeitszählung 6-36
+halt 4-4
+headline 5-43
+heap size 5-27
+help 4-5, 4-9
+hour 5-81
+
+idn 6-31
+imag part 6-6
+inchar 5-72
+incharety 5-72
+INCR 5-12, 5-19, 6-11
+INITFLAG 2-91
+initialized 2-91
+initialize random 5-13, 5-21
+input 2-75, 5-42
+insert 5-2
+insert char 5-35
+insert record 5-50
+Installation 6-36
+int 5-21
+int 6-13
+INT-Denoter: 2-7
+INV 6-28
+
+Kommando 1-9
+kommando auf taste 4-31
+kommando auf taste legen 4-31
+Kommando auf Taste legen 3-16
+Kommandotaste 3-11
+kommastellen 6-44
+Konfiguration 1-9
+
+length 5-35, 6-22
+LENGTH 5-35, 6-19
+Lernen ausschalten 3-17
+Lernen einschalten 3-17
+lernsequenz auf taste 4-32
+lernsequenz auf taste legen 4-32
+Lese-Fehler (Archiv) 4-52
+LEXEQUAL 5-31
+LEXGREATER 5-31
+LEXGREATEREQUAL 5-31
+lex sort 5-64
+LIKE 4-19, 5-59
+line 5-47, 5-71, 5-77
+line no 5-43
+lines 5-43
+list 4-27
+ln 5-22
+Löschtaste 3-10
+log10 5-22
+log2 5-22
+longint 6-13
+
+manager task 1-9
+Mantisse 5-16
+Markierzustand 3-9
+match 5-60
+matchpos 5-60
+matrix 6-32
+max 5-13, 5-22, 6-13
+maxint 5-13
+maxlongint 6-13
+maxreal 5-22
+max text length 5-35
+merke 6-45
+min 5-13, 5-23, 6-14
+minint 5-14
+MOD 5-14, 5-23, 6-11
+modify 2-75, 5-42
+Monitor 1-9
+Multi-Tasking-/Multi-User-Betrieb 1-5
+myself 4-23
+
+name 4-25
+Namensverzeichnis 4-16
+Netzwerkfähigkeit 1-6
+new 5-65
+next symbol 5-83
+next symbol 5-85
+Nicht abweisende Schleife 2-29
+nilspace 5-65
+niltask 4-22
+nilvector 6-22
+norm 6-22
+NOT 5-8
+notion 5-56
+
+old 5-66
+online 5-79
+Operationen auf Markierungen 3-15
+Operatoren 2-14
+OR 5-8
+OR 5-54
+out 5-75
+output 2-75, 5-42
+out subtext 5-76
+
+packets 4-8
+page 5-71
+Paketkonzept 2-1
+pause 5-79, 5-82
+phi 6-6
+pi 5-23
+pos 5-36
+Positionierung 5-71
+Positionierung des Cursors 3-4
+print 4-38
+PRINTER 4-24
+printer 4-24
+Priorität von generischen Operatoren 2-49
+Priorität von Operatoren 2-16
+prot 5-4
+Prozeduren als Parameter 2-39
+Prozeduren mit Parametern 2-38
+prozentsatz 6-45
+Prozeßkommunikation 1-6
+PUBLIC 4-24
+public 4-24
+put 5-46, 5-78, 6-12, 6-21, 6-30, 6-5
+putline 5-46, 5-78
+
+random 5-14, 5-23, 6-14
+read record 5-50
+real 5-14, 5-37
+REAL-Denoter: 2-8
+Realisierung von abstrakten Datentypen 2-47
+real part 6-6
+referencer 6-42
+Referenzliste 6-41
+Refinements 2-1
+reinsert 5-51
+release 4-45
+remainder 4-18
+remove 5-51
+rename 4-28
+rename myself 4-25
+reorganize 5-52
+replace 5-37, 6-22
+replace column 6-34
+replace element 6-34
+replace row 6-35
+report 6-36
+report off 6-40
+report on 6-40
+reserve 4-25
+REST 3-6
+round 5-23
+row 6-32
+ROWS 6-29
+run 5-3
+runagain 5-3
+
+save 4-35, 5-67
+saveall 4-36
+scan 5-86
+Schreibarbeit beenden 3-2
+Schutz vor fehlerhaftem Zugriff auf Datenobjekte 2-45
+Scratch-Datei 3-13
+segments 5-52
+sequential file 5-41
+SHard 1-5
+show 4-30
+shutup 1-17
+sign 5-15, 5-24, 6-14
+SIGN 6-11
+sin 5-24
+sind 5-24
+smallreal 5-24
+SOME 2-80, 4-17
+son 4-23
+sort 5-64
+Spracherweiterung 2-44
+sqrt 5-24, 6-6
+Standard-Datenraum 1-9
+std tastenbelegung 4-32
+STOP-Taste 3-20
+storage 4-11, 5-66
+storage info 4-5, 4-11
+sub 6-33
+SUB 5-37, 6-20
+subtext 5-38
+supervisor 4-24
+Supervisor 1-9
+SUPERVISOR-Taste 3-18
+Symbole 5-83
+sysin 5-73
+sysout 5-77
+
+Tabulatortaste 3-8
+tan 5-25
+tand 5-25
+task 4-22
+Task 1-9
+task info 4-5, 4-12
+Task-Organisation 1-2
+task password 4-43
+task status 4-15
+taste enthaelt kommando 4-31
+tecal 6-45
+tecalauskunft 6-45
+text 5-15, 5-25, 5-39, 6-15
+TEXT-Denoter: 2-9
+Thesaurus 4-16
+time 5-82
+time of day 5-82
+TIMESOUT 5-76
+Titelzeile 3-2
+to line 5-48
+transp 6-33
+TRANSP 6-29
+true 5-8
+type 5-66
+TYPE COMPLEX 6-3
+TYPE LONGINT 6-8
+
+Überschrift in die Kopfzeile 5-43
+Umschalttaste 3-4
+UNLIKE 5-59
+Unterbrechen einer Ausgabe 3-20
+up 5-49
+up 5-58
+uppety 5-58
+
+vector 6-23
+Vereinbarung eines dyadischen Operators 2-42
+Vereinbarung eines monadischen Operators 2-42
+Verstärkertaste 3-5
+Verwendung von Prozeduren 2-35
+Virtuelle Speicherverwaltung 1-7
+Vorbelegte Tasten 3-17
+
+warnings 5-4
+WEITER-Taste 3-20
+Wertliefernde Prozeduren 2-40
+Wertliefernde Refinements 2-34
+word wrap 4-32
+write 5-78
+write 5-47
+write record 5-50
+
+XOR 5-8
+
+Zählschleife 2-30
+Zeichen schreiben 3-16
+zero 6-15
+#tableend#
+
diff --git a/doc/programming/programmierhandbuch.inhalt b/doc/programming/programmierhandbuch.inhalt
new file mode 100644
index 0000000..45b3f1f
--- /dev/null
+++ b/doc/programming/programmierhandbuch.inhalt
@@ -0,0 +1,249 @@
+#setcount (1)#
+#block##pageblock#
+#pagenr ("%", 1)#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Inhalt
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+
+#center#____________________________________________________________
+I - % #right#GMD
+#end#
+#bottomodd#
+
+#center#____________________________________________________________
+GMD #right# I - %
+#end#
+
+#lpos(0.2)##lpos(1.8)##lpos(9.0)#
+
+TEIL 1 : Einleitung
+#table#
+1.1 Allgemeines über EUMEL 1
+1.2 Struktur des Betriebssystems EUMEL 2
+1.3 Eigenschaften des Betriebssystems 4
+ Multi-Tasking-/Multi-User-Betrieb 5
+ Prozeßkommunikation und Netzwerkfähigkeit 6
+ Erweiterbarkeit 6
+ Virtuelle Speicherverwaltung 7
+ Datensicherheit 8
+1.4 Wichtige Begriffe 9
+1.5 Die Notation in diesem Buch 10
+1.6 Die Funktionstasten des EUMEL-Systems 11
+1.7 Eine Beispielsitzung 12
+#tableend#
+
+
+
+
+TEIL 2 : ELAN
+#table#
+2.1 Besondere Eigenschaften von ELAN 1
+2.2 Lexikalische Elemente 2
+2.2.1 Schlüsselwörter 2
+2.2.2 Bezeichner 3
+2.2.3 Sonderzeichen 4
+2.2.4 Kommentare 5
+2.3 Datenobjekte 6
+2.3.1 Elementare Datentypen 6
+2.3.1.1 Denoter für elementare Datentypen 7
+ INT-Denoter: 7
+ REAL-Denoter: 8
+ TEXT-Denoter: 9
+ BOOL-Denoter: 9
+2.3.1.2 LET-Konstrukt für Denoter 10
+2.3.2 Zugriffsrecht 11
+2.3.3 Deklaration 11
+2.3.4 Initialisierung 12
+2.4 Programmeinheiten 13
+2.4.1 Elementare Programmeinheiten 14
+2.4.1.1 Ausdruck 14
+ Operatoren 14
+ Priorität von Operatoren 16
+2.4.1.2 Zuweisung 18
+2.4.1.3 Refinementanwendung 19
+2.4.1.4 Prozeduraufruf 20
+2.4.2 Zusammengesetzte Programmeinheiten 22
+2.4.2.1 Folge 22
+2.4.2.2 Abfrage 23
+2.4.2.3 Auswahl 26
+2.4.2.4 Wertliefernde Abfrage
+ und wertliefernde Auswahl 27
+2.4.2.5 Wiederholung 27
+ Abfragekette 25
+ Endlosschleife 28
+ Abweisende Schleife 29
+ Nicht abweisende Schleife 29
+ Zählschleife 30
+2.4.3 Abstrahierende Programmeinheiten 32
+2.4.3.1 Refinementvereinbarung 32
+ Vorteile der Refinementanwendung 33
+ Wertliefernde Refinements 34
+2.4.3.2 Prozedurvereinbarung 35
+2.4.3.3 Operatorvereinbarung 41
+ Verwendung von Prozeduren 35
+ Prozeduren mit Parametern 38
+ Prozeduren als Parameter 39
+ Wertliefernde Prozeduren 40
+ Vereinbarung eines monadischen Operators 42
+ Vereinbarung eines dyadischen Operators 42
+2.4.3.4 Paketvereinbarung 43
+ Spracherweiterung 44
+ Schutz vor fehlerhaftem Zugriff
+ auf Datenobjekte 45
+ Realisierung von abstrakten Datentypen 47
+2.4.4 Terminatoren für Refinements,
+ Prozeduren und Operatoren 48
+2.4.5 Generizität von Prozeduren und Operatoren 49
+ Priorität von generischen Operatoren 49
+2.4.6 Rekursive Prozeduren und Operatoren 50
+2.5 Programmstruktur 52
+2.6 Zusammengesetzte Datentypen 56
+2.6.1 Reihung 56
+2.6.2 Struktur 61
+2.6.3 LET-Konstrukt für
+ zusammengesetzte Datentypen 64
+2.6.4 Denoter für zusammengesetzte
+ Datentypen (Konstruktor) 65
+2.7 Abstrakte Datentypen 67
+2.7.1 Definition neuer Datentypen 67
+2.7.2 Konkretisierung 69
+2.7.3 Denoter für abstrakte Datentypen (Konstruktor) 70
+2.8 Dateien 73
+2.8.1 Datentypen FILE und DIRFILE 73
+ FILE: 73
+ DIRFILE: 73
+2.8.2 Deklaration und Assoziierung 74
+ input: 75
+ output: 75
+ modify: 75
+2.9 Abstrakte Datentypen im EUMEL-System 77
+2.9.1 Datentyp TASK 77
+2.9.2 Datentyp THESAURUS 79
+2.9.3 Datenräume 81
+2.9.3.1 Datentyp DATASPACE 82
+2.9.3.2 BOUND-Objekte 83
+ Häufige Fehler bei der Benutzung von Datenräume 85
+2.9.3.3 Definition neuer Dateitypen 88
+2.9.4 Datentyp INITFLAG 91
+#tableend#
+
+
+
+
+TEIL 3 : Der Editor
+#table#
+3.1 Ein- und Ausschalten des Editors 1
+3.2 Die Funktionstasten 3
+3.3 Die Wirkung der Funktionstasten 4
+3.4 ESC Kommandos 11
+ Operationen auf Markierungen 15
+ Zeichen schreiben 16
+ Kommando auf Taste legen 16
+ Vorbelegte Tasten 17
+ Der Lernmodus 17
+3.5 Positionieren, Suchen, Ersetzen
+ im Kommandodialog 21
+ Weitere Hilfen 23
+#tableend#
+
+
+
+
+TEIL 4 : Kommandosprache
+#table#
+4.1 Supervisor 2
+4.2 Monitor 6
+4.2.1 Hilfsprozeduren 8
+ Informationsprozeduren 11
+4.2.2 Thesaurus 16
+4.2.3 Tasks 21
+4.2.4 Handhabung von Dateien 26
+4.2.5 Editor-Prozeduren 29
+4.2.6 Dateitransfer 33
+4.2.7 Passwortschutz 39
+4.2.8 Das Archiv 44
+ Fehlermeldungen des Archivs 52
+#tableend#
+
+
+
+
+TEIL 5 : Programmierung
+#table#
+5.1 Der ELAN-Compiler 1
+5.1.1 Fehlermeldungen des ELAN-Compilers 5
+5.2 Standardtypen 7
+5.2.1 Bool 7
+5.2.2 Integer-Arithmetik 9
+5.2.3 Real-Arithmetik 16
+5.2.4 Text 26
+ Der EUMEL-Zeichensatz 29
+5.3.1 Assoziierung 41
+5.3.2 Informationsprozeduren 43
+5.3.3 Betriebsrichtung INPUT 44
+5.3.4 Betriebsrichtung OUTPUT 46
+5.3.5 Betriebsrichtung MODIFY 48
+5.3.6 FILE -Ausschnitte 51
+5.4 Suchen und Ersetzen in Textdateien 53
+5.4.1 Aufbau von Textmustern 54
+5.4.2 Suche nach Textmustern 57
+5.4.3 Treffer registrieren 59
+5.4.4 Treffer herausnehmen 60
+5.4.5 Ändern in Dateien 61
+5.4.6 Editor-Prozeduren 62
+5.4.7 Sortierung von Textdateien 64
+5.4.8 Prozeduren auf Datenräumen 65
+5.5 Eingabe/Ausgabe 68
+5.5.1 E/A auf Bildschirm 69
+5.5.1.1 Eingabesteuerzeichen 69
+5.5.1.2 Ausgabesteuerzeichen 70
+5.5.1.3 Positionierung 71
+ Grundlegende Prozeduren 72
+ Umleitbare Eingabeprozeduren 73
+ Grundlegende Prozeduren 75
+ Umleitbare Ausgabeprozeduren 77
+5.5.1.4 Eingabe 72
+5.5.1.5 Ausgabe 75
+5.5.1.6 Kontrolle 79
+5.5.2 Zeitmessung 80
+5.6 Scanner 83
+ Scanner-Kommandos 85
+#tableend#
+
+
+
+
+TEIL 6 : Das Archiv 'std zusatz'
+#table#
+6.1 Erweiterungen um Mathematische Operationen 2
+6.1.1 COMPLEX 2
+6.1.2 LONGINT 7
+6.1.3 VECTOR 16
+6.1.4 MATRIX 24
+6.2 Programmanalyse 36
+ reporter - Kommandos 39
+ Referencer 41
+ referencer - Kommandos 42
+6.3 Rechnen im Editor 43
+ Arbeitsweise 43
+ TeCal Prozeduren 44
+#tableend#
+
+
+
+
+Anhang : ELAN-Syntaxdiagramme
+
+
+
+
+INDEX
+
diff --git a/doc/programming/programmierhandbuch.titel b/doc/programming/programmierhandbuch.titel
new file mode 100644
index 0000000..79b09b0
--- /dev/null
+++ b/doc/programming/programmierhandbuch.titel
@@ -0,0 +1,52 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#Programmierhandbuch
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#block##pageblock#
+#start(5.0,1.5)#
+
+#lpos(3.0)#
+#table#
+
+
+
+
+
+
+Benutzerhandbuch
+
+Programmierung
+
+
+
+Stand: 1.7.87
+
+#tableend##page#
+
+
diff --git a/doc/prolog/prolog handbuch b/doc/prolog/prolog handbuch
new file mode 100644
index 0000000..ea7c6a5
--- /dev/null
+++ b/doc/prolog/prolog handbuch
@@ -0,0 +1,581 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#Prolog
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+
+Dr.P.Heyderhoff 12.03.1987
+GMD.F2.G2
+
+
+
+
+
+
+ E L A N - P R O L O G
+ _____________________
+
+ (Die Fachsprache der künstlichen Intelligenz)
+
+#on("u")#Benutzungsanleitung und technische Beschreibung#off("u")#
+
+
+Elan-Prolog ist eine Computersprache der fünften Generation, die für
+die Praxis der Programmierung und die Lehre in Informatik eine neue
+Dimension erschließt. Für den professionellen Programmierer eröffnet sie
+neue Möglichkeiten, mächtige Anwendungen, wie Expertensysteme und andere
+neuartige Systeme der Wissensverarbeitung zu entwickeln.
+
+Elan-Prolog unterscheidet sich grundsätzlich von üblichen konventionellen
+Programmiersprachen. In Sprachen wie Elan und Pascal muß der Programmierer
+genau angeben, wie ein gewünschtes Ergebnis errechnet werden soll. Um was es
+sich dabei handelt, steht bestenfalls dann in der Dokumentation. Ganz anders
+ist es in Prolog. PROLOG steht für PROgrammieren in LOgik und basiert auf
+dem Prädikaten-Kalkül, der bekanntesten Form der formalen Logik. Also in
+Prolog schreibt der Programmierer hin, worin das Problem besteht. Er bedient
+sich dabei dieser formalen Logik. Prolog versucht dann eine Lösung zu
+finden. Der Lösungsweg ist dabei im Programm nicht vorgeschrieben. Das
+entlastet den Programmierer, und er kann seine ganze Kraft auf die logische
+Beschreibung des Problems konzentrieren.
+
+Elan-Prolog ist ein interpretatives System, das voll kompatibel ist mit dem
+Edinburgh Standard Prolog und in in komfortabler Weise in das Betriebssystem
+Eumel eingebettet ist.
+
+Eigenschaftes von Elan-Prolog:
+
+- Syntax gemäß dem Edinburgh Standard Prolog nach Clocksin-Mellish
+
+- Interpretierendes System mit inkrementellem Einpass-Compiler
+
+- Interaktiver Mehrfenster-Texteditor des Eumelsystems
+
+- Zugriff auf Elan-Prozeduren als Prolog-Regeln
+
+- Geschwindigkeit ca. 100 LIPS auf IBM/PC-XT
+
+- optionale dynamische Ablaufverfolgung
+
+- Erklärungskomponente
+
+- Eingabe und Ausgabe von Prolog-Ausdrücken und Klartext
+
+- Programmiert und dokumentiert in ELAN (über 2000 Zeilen)
+
+- daher besonders für den Informatik-Unterricht geeignet
+#page#
+#on("u")#Beschränkungen des Elan-Prolog:#off("u")#
+
+Folgende Beschränkungen gelten für die Implementierung von Elan-Prolog im
+Eumel-Systems:
+
+- Maximal 16000 Fakten und Regeln
+
+- Maximal 16000 Terme zur Konstruktion von Ausdrücken, Listen und Regeln
+
+- Maximal 800 Variablenbindungen
+
+- Maximal 800 Einträge im Beweisbaum
+
+- Maximal 4000 Bezeichner für Atome und Variablen
+
+- Maximal 16000 Buchstaben für alle Bezeichner zusammen
+
+
+Wie sieht ein Prolog-Programm aus?
+
+Ein Prolog-Programm besteht aus
+
+ - Fakten über Objekte und ihre Beziehungen
+
+ - Regeln über Objekte und ihre Beziehungen
+
+und besonders wichtig:
+
+ - Der Benutzer kann Prolog über die Fakten und Regeln ausfragen.
+
+Fakten aus einer Wissensbasis, nämlich dem Prolog-Programm, sind z.B.:
+
+ enthaelt (wisky, aethanol).
+
+Das wird gelesen als: "Wisky enthält Aethanol.". Grundzüge der sehr
+einfachen Syntax lassen sich hieran erklären. Ein Faktum wird geschrieben
+wie in diesem Beispiel:
+
+ - Erst kommt der Name der Relation, geschrieben wie ein Elan-Name in
+ kleinen Buchstaben.
+
+ - Dann folgt in runden Klammern und durch Kommata getrennt eine Liste
+ von Objektnamen.
+
+ - Zum Schluß steht ein Punkt.
+
+Regeln sind Problembeschreibungen in der Form von logischen Ausdrücken der
+symbolischen Logik, wie z.B. die folgende Regel:
+
+ bewirkt (A, B, kopfschmerz) :- enthaelt (A, aethanol),
+ enthaelt (B, aspirin ).
+
+Das wird gelesen als: "Wenn man eine Droge A, die Aethanol enthält,
+und eine Droge B, die Aspirin enthält gleichzeitig einnimmt, dann bewirkt
+das Kopfschmerzen." Wie man sieht werden logische Variablen mit großen
+Buchstaben (wie Elan-Operatoren) geschrieben. Das Zeichen ":-" steht für das
+logische Wenn, und das Komma(",") für die logische Konjunktion. Die logische
+Disjunktion wird durch Semikolon(";") ausgedrückt.
+#page#
+Neben der hiermit vorgestellten Prefix-Schreibweise für Relationen gibt es in
+ELAN-Prolog auch noch eine Infix-Schreibweise für zweistellige Relationen.
+Hierbei werden die Relationen als Infix-Operatoren in großen
+Buchstaben geschrieben (wie in ELAN) und zwischen die beiden Operanden
+gesetzt. Als Operatoren sind auch die in Elan üblichen Operatoren
+
+ ( +, -, *, /, MOD, =, <, >, <=, >=, <> )
+zulässig.
+
+In Infixausdrücken (wie z.B. 2+3*4) gelten die bekannten Vorrangregeln. Auch
+Klammern sind zulässig. Selbstdefinierte Operatoren haben niedrigste
+Priorität.
+
+Obiges Beispiel in Infix-Schreibweise:
+
+ wisky ENTHAELT aethanol.
+
+ bewirkt (A, B, kopfschmerz) :- A ENTHAELT aethanol,
+ B ENTHAELT aspirin.
+
+
+Objekte in Prolog können Atome oder Listen sein. Für Atome gibt es zwei
+Schreibweisen:
+
+ - genau so wie Elan-Bezeichner, also bestehend aus kleinen Buchstaben
+ und Blanks. Dabei werden die Blanks eliminiert.
+
+ - genauso wie Elan-Texte, nämlich in Gänsefüßchen eingeschlossen.
+
+Für Listen von Objekten gibt es wiederrum zwei Schreibweisen, wie folgende
+zwei unterschiedlichen Notationen des gleichen Beispiels zeigen:
+
+ - [ das, ist, [ zum, beispiel ], eine, liste ]
+
+ - [ das, ist, [ zum | [ beispiel | [] ] ], eine, liste ]
+
+Im zweiten Fall ist die als drittes Element in der Gesamtlisten enthaltene
+Teilliste mit dem Konstruktor "|" und der leeren Liste "[]" zusammengesetzt.
+Die Grundoperationen, die aus der Programmiersprache LISP bekannt sind,
+können als Prolog-Fakten unmittelbar wie folgt definiert werden:
+
+ eq (X, X).
+ head ([X|Y], X).
+ tail ([X|Y], Y).
+ cons (X, Y, [X|Y]).
+#page#
+#on("u")#Standard - Operatoren von Elan-Prolog:#off("u")#
+
+Im System sind nur ganz wenige Standardoperatoren eingebaut. Es sind die
+folgenden Fakten:
+
+ - ! . der CUT-Operator schaltet des Backtracking ab.
+
+ - bye. beendet die prolog Anwendung.
+
+ - listing. zeigt alle insertierten Regeln.
+
+ - listing (X). zeigt alle insertierten Regeln über X.
+
+ - call (X). X wird ausgeführt.
+
+ - write (X). das an X gebundenen Prolog-Objekts wird ausgegeben,
+ writeq (X). und wenn nicht eindeutig, gequotet,
+ put (X). das Zeichen, dessen ASCII-Code X ist wird ausgegeben,
+ name (X,[Y]). unifiziert das Atom X mit der Liste seiner Buchstaben.
+
+ - read (X). ein Objekt wird gelesen und an die Variable gebunden.
+ get0 (X). das nächste Zeichen wird gelesen,
+ get (X). das nächste druckbare Zeichen wird gelesen,
+
+ - X = Y . Die an X und Y gebundenen Objekte sind gleich,
+ X <> Y . sie sind ungleich,
+ X <= Y . sie sind kleiner oder gleich,
+ X == Y . sie sind wörtlich gleich,
+ X =.. [F|A] . X ist der Term mit Funktor F und Argumentliste A.
+
+ - X + Y . sie sollen addiert,
+ X - Y . subtrahiert,
+ X * Y . multipliziert,
+ X / Y . dividiert,
+ X MOD Y . der Divisionsrest soll ermittelt werden,
+ die Auswertung geschieht durch den 'is'-Operators.
+
+ - X IS EXPR . Das Ergebnis des arithmetischen Ausdrucks EXPR wird
+ gebildet und mit X unifiziert.
+
+ - incr (X). der arithmetische Wert von X wird um eins erhöht.
+
+ - assertz ([X]). insertiert die Regel X am Ende einfügend.
+ asserta ([Χ]). insertiert die Regel X am Anfang einfügend.
+ retract ([X]). entfernt die Regel X wieder.
+ clause (X,[Y]). holt die Regel Y mit dem Kopf X aus der Knowledgebase.
+
+ - functor (X,Y,Z) Y ist der Funktor von X und Z ist seine Arität.
+ arg (X,Y,Z). Z ist das x-te Argument der Funktion Y.
+
+ - elan (X). Ausführung der insertierten ELAN-Prozedur X
+ elan (X,Y). Ausführung von X mit dem TEXT-CONST-Parameter Y
+
+ - elan(trace,on). schaltet den dynamischen Ablaufverfolger ein und
+ elan(trace,off) schaltet ihn wieder ab.
+
+ - elan(consult,X) lädt das Prologprogramm aus der Datei namens X hinzu.
+ elan(reconsult,X) ersetzt das Prologprogramm aus der Datei X.
+ elan(abolish,X) entfernt alle Regeln mit dem Namen X.
+#page#
+#on("u")#Das Dialogverhalten von Elan-Prolog:#off("u")#
+
+Elan-Prolog wird, sobald es in das Eumel-System insertiert ist, als Prozedur
+mit dem Namen "prolog" und einem optionalen TEXT-Parameter aufgerufen. Der
+Textparameter enthält den Namen einer Datei, die ein Prolog-Programm enthält,
+das geladen werden soll. Fehlt der Parameter, wird, wie üblich, die zuletzt
+bearbeitete Datei genommen. Im Prolog-Dialog können später weitere
+Prolog-Programme mit der Prozedur namens "consult" hinzugeladen werden.
+
+Also
+einfachster Aufruf: prolog ("")
+
+Antwort: ?-
+Beispiel-Eingabe: 3 = 3
+Antwort: yes
+ ?-
+Eingabe: 4 = -5
+Antwort: no
+ ?-
+
+Besondere Dialogkommandos:
+
+ ?-
+Eingabe: ?
+Antwort z.B.: 13.5 SEC
+ ?-
+Eingabe: listing
+Antwort: { zeigt alle aktuell verfügbaren Regeln }
+ ?-
+Eingabe: {ESCAPE} q
+Ausgabe: gib kommando:
+
+Eingabe: prolog again
+Ausgabe: ?-
+Eingabe: [sum, permute] {in eckigen Klammern!}
+ { konsultiert diese beiden Dateien }
+Antwort z.B.: 25 rules inserted.
+ ?-
+Eingabe: [-sum, -permute]
+ { löscht und rekonsultiert aus diesen Dateien }
+Antwort z.B.: 25 rules inserted.
+
+Eingabe: {ESCAPE} {ESCAPE}
+Antwort: gib kommado:
+Elan-Eingabe z.B.: show ("standard")
+ { zeigt die Datei dieses Namens }
+ ?-
+
+Auf diese Weise können bequem Eumel-Kommandos gegeben werden. Die
+Umschaltung vom Prolog- zum Eumelmonitor-Betrieb erfolgt durch die Tasten
+{ESCAPE},{ESCAPE} und {RETURN}. Wie üblich ist das zuletzt verwendete
+Kommando auch im Prolog-Dialog mit dem Escapekommando "{ESCAPE} k"
+wiederzubekommen. Das Kommando "{ESCAPE} q" beendet den Dialog.
+#page#
+#on("u")#Ausprobieren der Prolog-Programmbeispiele:#off("u")#
+
+Zum Ausprobieren sind die Prologbeispiele "eq", "permute" und "mann"
+beigefügt.
+
+Beispiel: ?-
+Eingabe: [permute] {in eckigen Klammern!}
+Antwort: 5 rules inserted.
+ ?-
+Eingabe: marquise(X)
+Antwort: beautiful marquise your beautiful eyes make me die of love
+Eingabe: {Semicolon}
+Antwort: your beautiful eyes beautiful marquise make me die of love
+ { usw }
+Eingabe: {Return}
+Antwort: ?-
+
+Jede #on("u")#Eingabe von Semicolon#off("u")# liefert als Antwort die nächste Permutation. Wenn
+eine andere Taste gedrückt wird, bricht die Ausgabe weiterer Ergebnisse ab.
+
+#on("u")#Eingabe von Fragezeichen#off("u")# liefert neben der Angabe der benötigten
+Rechenzeit eine Erklärung der letzten Antwort durch Ausgabe aller zu dieser
+Antwort führenden Schlußfolgerungen. Dabei wird der Beweisbaum in Form einer
+Einrückstruktur dargestellt. Die Einrückung stellt die Erklärungstiefe dar.
+
+
+#on("u")#Benutzung von Prolog von Elan-Programmen aus#off("u")#
+
+Wenn man Prolog als Unterprogramm von Elan aus aufrufen will, geht man
+folgendermaßen vor:
+
+1. Laden einer Wissensbasis,
+ die in einer Datei namens <knowledgebase> z.B."permute" bereitsteht:
+
+ push ("bye"13"");
+ prolog ("permute");
+
+
+2. Abfragen an diese Wissensbasis:
+
+ TEXT VAR query, answer;
+ query:= "marquise (X)";
+ IF prolog ( query, answer)
+ THEN put (answer)
+ ELSE put ("NO")
+ FI;
+
+In diesem Anwendungsbeispiel liefert die Ausgabeanweisung 'put (answer)':
+
+ beautiful marquise your beatiful eyes make me die of love
+
+#page#
+#on("u")#Literatur:#off("u")#
+
+
+1.) W.F.Clocksin, C.S.Mellish:
+ Programming in Prolog
+ Springer 1984
+
+2.) M.H.van Emden:
+ An interpreting algorithm for prolog programs
+ in Implementations of Prolog, Ellis Herwood Ltd, 1984
+
+3.) Alain Colmerauer:
+ Prolog in 10 Figures
+ Communications of the ACM December 1985
+
+4.) J. Cohen:
+ Describing Prolog by its Interpretation and Compilation
+ Communications of the ACM December 1985
+
+5.) Alain Colmerauer:
+ Les system q ou un formalisme pour alalyser et synthetiser des phrases
+ sur ordinateur.
+ Intern.Rep. 43, Departement d'informatique. Universite de Montreal
+ Sept. 1970
+#page#
+(*************************************************************************)
+(* *)
+(* Elan-Prolog *)
+(* *)
+(* Programm-Beispiele: *)
+(* *)
+(****************** standard (nach Clocksin-Mellish) ********************)
+
+abolish (X) :- elan (abolish, X).
+append ([], X, X) :- !.
+append ([X|Y], Z, [X|W]) :- append (Y, Z, W).
+atom (X) :- functor (X, Y, 0).
+atomic (X) :- atom (X); integer (X).
+consult (X) :- elan (consult, X).
+end :- bye.
+fail :- [].
+findall (X, Y, Z) :- tell ("$$"), write ("("), findall (X,Y);
+ write (")"), told, see ("$$"), read (Z),
+ seen, elan (forget, "$$").
+findall (X, Y) :- call (Y), writeq (X), write (","), [].
+integer (X) :- functor (X, Y, -1).
+listing (X).
+member (X, [X|Z]).
+member (X, [Y|Z]) :- member (X, Z).
+nl :- elan (line).
+non var (X) :- var (X), !, []; .
+not (X) :- call (X), !, []; .
+notrace :- elan (trace, off).
+reconsult (X) :- elan (reconsult, X).
+repeat.
+repeat :- repeat.
+see (X) :- elan (sysin, X).
+seen :- elan (sysin, "").
+tab (X) :- tab(X,1).
+tab (X,Y) :- Y<=X, !, put (32), incr(Y), tab(X,Y);.
+tell (X) :- elan (sysout, X).
+told :- elan (sysout, "").
+trace :- elan (trace, on).
+true.
+< (X, Y) :- <= (X, Y), <> (X, Y).
+> (X, Y) :- <= (Y, X).
+>= (X, Y) :- < (Y, X).
+#page#
+(**************************** sum ***********************************)
+
+suc (0, 1). suc (1, 2). suc (2, 3). suc (3, 4). suc (4, 5).
+suc (5, 6). suc (6, 7). suc (7, 8). suc (8, 9).
+sum (0, X, X).
+sum (X, Y, Z):- suc (V, X), sum (V, Y, W), suc (W, Z).
+plus (X, [0,0], X):- !.
+plus (X, Y, Z):- plus one (V, Y), plus (X, V, W), !, plus one (W, Z).
+plus one ([X, Y], [V, W]):- suc (Y, W), X = V, !;
+ Y = 9, suc (X, V), W = 0.
+treereverse (X,Y):- rev (X,Y), !; rev (Y,X), !.
+rev ([], []).
+rev ([X|Y], Z):- X <> [H|T], rev (Y, W), !, append (W, [X], Z);
+ rev (X, V), rev (Y, W), !, append (W, [V], Z).
+
+(**************************** permute ************************************)
+
+permute ([], []).
+permute ([E|X], Z):-
+ permute (X, Y), insert (E, Y, Z).
+insert (E, X, [E|X]).
+insert (E, [F|X], [F|Y]):-
+ insert (E, X, Y).
+marquise(RESULT):-
+ permute (["beautiful marquise",
+ "your beautiful eyes",
+ "make me",
+ "die",
+ "of love"
+ ],
+ RESULT).
+
+(**************************** puzzle ************************************)
+
+ {Solution: 9,5,6,7,0,8,2}
+puzzle:- repeat, permute ((9,8,7,6,5,2,0), SENDMORY),
+ write (SENDMORY),
+ puzzle (SENDMORY, SEND, MORE, MONEY),
+ elan (line),
+ write (SEND), write (+),
+ write (MORE), write (=),
+ write (MONEY).
+
+puzzle([S,E,N,D,O,R,Y], SEND, MORE, MONEY):-
+ SEND IS ((S * 10 + E) * 10 + N) * 10 + D,
+ MORE IS ((10 + O) * 10 + R) * 10 + E,
+ MONEY IS (((10 + O) * 10 + N) * 10 + E) * 10 + Y,
+ MONEY IS SEND + MORE.
+
+permute ([], []).
+permute ([E|X], Z):- permute (X, Y), insert (E, Y, Z).
+
+insert (E, X, [E|X]).
+insert (E, [F|X], [F|Y]):- insert (E, X, Y).
+
+repeat.
+repeat:- repeat.
+#page#
+(**************************** prieks ***********************************)
+
+ist priek (bo priek).
+ist priek (ki priek).
+ist priek (bla priek).
+
+WER GNASELT WEN :- population (B),
+ member ([WEN, WER, _], B),
+ bedingungen (B).
+
+WER KNAUDERT WEN:- population (B),
+ member ([WER, _, WEN], B),
+ bedingungen (B).
+
+population (B):- sind prieks (U, V, W),
+ sind knauderarten (R, S, T),
+ B = [ [drausla puemfe, U, R],
+ [glessla puemfe, V, S],
+ [hapla puemfe, W, T] ].
+
+sind prieks (X,Y,Z):- ist priek (G),
+ ist priek (H), H<>G,
+ ist priek (I), I<>G, I<>H, !,
+ permute ([G,H,I], [X,Y,Z]).
+
+sind knauderarten (X,Y,Z):- ist knauderart (G),
+ ist knauderart (H), H<>G,
+ ist knauderart (I), I<>G, I<>H, !,
+ permute ([G,H,I],[X,Y,Z]).
+
+ist knauderart (an).
+ist knauderart (ab).
+ist knauderart (ueber).
+
+bedingungen (B):- not member ([hapla puemfe,ki priek,_],B) ,
+ not member ([hapla puemfe,_,ueber],B) ,
+ not member ([drausla puemfe,bo priek,_],B) ,
+ not member ([_,bo priek,ab],B) ,
+ noch ne bedingung (B) ,
+ weitere bedingungen (B) , !.
+
+weitere bedingungen (B):- not member([_,ki priek,ueber],B),
+ not member([_,bo priek,ueber],B)
+ ;
+ member([drausla puemfe,_,an],B).
+
+noch ne bedingung (B):- not member ([drausla puemfe,ki priek,_],B)
+ ;
+ not member ([glessla puemfe,_,ueber],B).
+
+permute ([], []).
+permute (X, [Y|Z]):- delete (Y ,X, E), permute (E, Z).
+delete (X, [X|Z], Z).
+delete (X, [Y|Z], [Y|E]):- delete (X, Z, E).
+member (X, [X|Z]).
+member (X, [Y|Z]):- member (X, Z).
+not member (X, []).
+not member (X, [Y|Z]):- X <> Y, not member (X,Z).
+#page#
+(**************************** calc ************************************)
+
+{ CALC evaluates arithmetic expressions with store }
+
+calc:- eval ([], RS), write (result store), write (RS), nl.
+
+eval (SI, SO):-
+ read (CALC), nonvar (CALC), eval member (CALC, SI, SO).
+
+eval member (CALC, SI, SO):-
+ member (CALC, [stop,end,bye,eof]), SO=SI;
+ eval (CALC,I,SI,ST), write (I), eval (ST,SO);
+ write (error in), write (CALC), nl, eval (SI, SO).
+
+eval (I, I, S, S):- integer (I).
+eval (N, I, S, S):- atom (N), eval atom (N, I, S).
+
+eval atom (N, I, S):-
+ member (N=I, S);
+ write ("error: Cell"), write (N),
+ write("not found in store. 0 substituted."), nl, I=0.
+
+eval ( L+R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J+K.
+eval ( L-R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J-K.
+eval ( L*R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J*K.
+eval ( L/R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J/K.
+
+eval (N=O, I, SI, SO):-
+ atom (N), eval (O,I,SI,ST), eval repl (N,I,ST,SO).
+
+eval repl (N, I, [], [=(N,I)]).
+eval repl (N, I, [=(N,_)|S], [=(N,I)|S]).
+eval repl (N, I, [=(M,J)|SI], [=(M,J)|SO]):- eval repl (N, I, SI, SO).
+
diff --git a/doc/prozess/Anhang Prozess b/doc/prozess/Anhang Prozess
new file mode 100644
index 0000000..8415268
--- /dev/null
+++ b/doc/prozess/Anhang Prozess
@@ -0,0 +1,92 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#center##on("b")#Anhang#off("b")#
+
+#center##on("b")#Bezugsquellenverzeichnis#off("b")#
+
+
+ - AKTRONIK
+ Elektronik-Großhandel
+ A. Kaup
+ Teichstraße 9
+ 4401 Saerbeck
+ Tel.: 02574/8008 - 8009
+
+
+
+ - BICOS Computer GmbH
+ Werkering 6
+ Postfach 1229
+ 4800 Bielefeld 1
+ Tel.: 0521/34011
+
+
+
+ - lattasoft
+ Eva Latta-Weber
+ Software-  und
+ Hardware-Systeme
+ Brehmstraße 7
+ 4800 Bielefeld 1
+ Tel.: 0521/38919
+
+
+
+ - Landesinstitut für Schule
+ und Weiterbildung
+ Paradieser Weg 64
+ 4770 Soest
+ Tel.: 02921/683-1
+
+#page#
+#on("b")#Anhang#off("b")#
+
+#on("b")#Verzeichnis der Abbildungen#off("b")#
+
+Abb. 1: MUFI geöffnet
+Abb. 2: Mögliche DIP-Schalter-Stellung beim MUFI
+Abb. 3: Einbau des MUFIs in den Terminalkanal
+Abb. 4: RS232-Adapter geöffnet
+Abb. 5: Mögliche Jumperposition beim RS232-Adapter
+Abb. 6: Auswahl der Interface-Anpassung
+Abb. 7: Anschluß Leuchtdiodenanzeige -Kombikarte
+Abb. 8: Pinbelegung auf der E/A-Karte
+Abb. 9: Eingangsbildschirm ls-Prozess
+Abb.10: Menubildschirm zum Oberbegriff 'Interface'
+Abb.11: Information bei unkonfiguriertem System
+Abb.12: Auswahl der Steckplatzart
+Abb.13: Compact-Box: Belegung der Kanäle
+Abb.14: Auswahl einer Interfacekarte
+Abb.15: Kanalbelegung D/A-Karte (Einzelsteckplatz)
+Abb.16: A/D-Karte: Angabe der Schalterstellung
+Abb.17: A/D-Karte: Kanalbel./Spannungsber.(Bspl.)
+Abb.18: Ausgabetest - Einblendung
+Abb.19: Eingabetest - Einblendung
+Abb.20: Beispiellochkarte
+Abb.21: Aufbau eines Drehpotentiometers
+Abb.22: Eingangsbildschirm ls-Prozess
+Abb.23: Befehlsübersicht
+Abb.24: Auswahl Ausgabebefehle
+Abb.25: Auswahl Eingabebefehle
+Abb.26: Auswahl Testbefehle
+Abb.27: Auswahl 'Weitere Befehle'
+Abb.28: Menubildschirm zum Oberbegriff 'Interface'
+Abb.29: Menubildschirm zum Oberbegriff 'Programm'
+Abb.30: Informationsauswahl zum EUMEL-Editor
+Abb.31: Menubildschirm zum Oberbegriff 'Archiv'
+Abb.32: Auswahl der Archiv-Formate
+Abb.33: Auswahl der Zieltask
+
+
+
diff --git a/doc/prozess/Inhalt Prozess b/doc/prozess/Inhalt Prozess
new file mode 100644
index 0000000..ab9616a
--- /dev/null
+++ b/doc/prozess/Inhalt Prozess
@@ -0,0 +1,84 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#center##on("b")#Inhaltsverzeichnis#off("b")#
+
+1 Was kann gs-Prozess
+
+2 Allgemeines zur Prozeßdatenverarbeitung
+2.1 Welche Hardware-Lösungen gibt es zur Zeit ?
+2.2 Die besonderen Probleme unter EUMEL
+2.3 Die Wahl des Interface-Systems
+
+3 Installation des Interface-Systems
+3.1 Das MUFI der Firma BICOS als Adapter
+3.1.1 Einstellung der DIP-Schalter am MUFI
+3.1.2 Einbau des MUFIs in den Terminalkanal
+3.1.3 Das MUFI an separater serieller Schnittstelle
+3.2 Der RS232-Adapter der Firma AKTRONIK
+3.3 Verbindung Adapter - Interface-System
+3.4 Bereitstellung des Interface-Systems
+
+4 Installation von gs-Prozess
+4.1 Voraussetzungen
+4.2 Lieferumfang
+4.3 Installation
+4.4 Anmerkungen zur Erstinstallation
+
+5 Konfiguration von gs-Prozess
+5.1 Kontrolle der Konfigurationen/Anschlüsse
+5.2 Vorbereitungen für den Ein-/Ausgabetest
+5.2.1 Anschluß einer Leuchtdiodenanzeige an die Kombikarte
+5.2.2 Anschluß des Codekartenlesers (Drahtstück)
+5.3 Konfiguration von gs-Prozess
+5.3.1 Auswahl der Steckplatzart/Interfacekarte
+5.3.2 Bedeutung der Kanalnummern
+5.4 Aus- und Eingabetest
+5.5 Mögliche Fehlerfälle
+
+6 Arbeiten mit gs-Prozess
+6.1 Kleine Beispiele zur digitalen Ausgabe
+6.1.1 Möglichkeit eines Programmabbruchs
+6.1.2 Die "sonstigen" Befehle
+6.1.3 Schreibweise für Bitmuster/Bitsymbole
+6.1.4 Befehle für die digitale Ausgabe
+6.1.5 Befehle für die analoge Ausgabe
+6.2 Kleine Beispiele zur digitalen Eingabe
+6.2.1 Befehle für die digitale Eingabe
+6.2.2 Eingabetests
+6.2.3 Befehle für die analoge Eingabe
+6.3 Hinweise auf Aufgabenmaterial
+
+7 Beschreibung der Menufunktionen
+7.1 Kurzhinweise zur Bedienung der Menus
+7.2 Menufunktionen zum Oberbegriff 'Info'
+7.3 Menufunktionen zum Oberbegriff 'Interface'
+7.4 Menufunktionen zum Oberbegriff 'Programm'
+7.5 Menufunktionen zum Oberbegriff 'Archiv'
+
+8 Detailbeschreibung der Basisbefehle und Tests
+
+9 Hinweise für den Systembetreuer/    Programmierer
+9.1 Vergabe der Kanäle/Organisation des Tasksystems
+9.2 Informationsprozeduren
+9.3 Neufestlegung des Interfacekanals
+9.4 Fixieren der Konfiguration
+9.5 Mögliche Fehlerfälle
+9.6 Weitere Möglichkeiten
+
+Anhang: Bezugsquellenverzeichnis
+ Verzeichnis der Abbildungen
+
+
+
+
diff --git a/doc/prozess/gs-Prozess handbuch.impressum b/doc/prozess/gs-Prozess handbuch.impressum
new file mode 100644
index 0000000..ca22b10
--- /dev/null
+++ b/doc/prozess/gs-Prozess handbuch.impressum
@@ -0,0 +1,104 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#gs-Prozess
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+
+#free (4.0)##on("b")#
+#center#gs-Prozess
+
+
+#center#Benutzerhandbuch
+
+
+#center#Version 1.0
+
+
+#off("b")##center#copyright
+#center#Eva Latta-Weber
+#center#Software- und Hardware-Systeme, 1988
+#center#ERGOS GmbH, 1990
+#page#
+#block#
+#center#____________________________________________________________________________
+
+
+Copyright:  ERGOS GmbH   März 1990
+
+ Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+ maschinenlesbare Form sowie das Speichern in Informations­
+ systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+ der ERGOS GmbH gestattet.
+
+
+#center#____________________________________________________________________________
+
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender.
+
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden.
+
+Texterstellung :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+ erstellt und aufbereitet und auf einem Kyocera Laser­
+ drucker gedruckt.
+
+
+
+
+#center#___________________________________________________________________________
+
+
+
+Ergonomic Office Software GmbH
+
+Bergstr. 7 Telefon: (02241) 63075
+5200 Siegburg Teletex: 2627-2241413=ERGOS
+ Telefax: (02241) 63078
+
+
+#center#____________________________________________________________________________
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/prozess/gs-Prozess-2 b/doc/prozess/gs-Prozess-2
new file mode 100644
index 0000000..376143e
--- /dev/null
+++ b/doc/prozess/gs-Prozess-2
@@ -0,0 +1,255 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#on("b")#2  Allgemeines zur Prozeßdatenverarbeitung#off("b")#
+
+In diesem Kapitel erfahren Sie, warum unter EUMEL/ELAN die Prozeßdatenver­
+arbeitung bisher kaum Berücksichtigung gefunden hat und welche Probleme zu
+überwinden waren. Es wird aufgezeigt, warum unter EUMEL/ELAN nicht jedes Inter­
+facesystem verwendet werden kann; außerdem werden die Gründe für die Wahl eines
+bestimmten Interfacesystems genannt.
+
+
+#on("b")#2.1  Welche Hardware-Lösungen gibt es zur Zeit ?#off("b")#
+
+Wie schon in Kapitel 1 erwähnt, ist zum Messen, Steuern und Regeln mit dem
+Computer ein Hardware-Interface notwendig, über das der "Kontakt zur Außenwelt"
+hergestellt wird.
+
+
+#on("b")#
+ Computer <--------> Interface <--------> Modell
+#off("b")#
+
+
+Interfaces (zu deutsch etwas mißverständlich: Schnittstellen) verbinden innerhalb
+eines Systems Teilsysteme und einzelne Funktionseinheiten miteinander. Dabei
+werden z.B. #on("b")#Hardware-Schnittstellen#off("b")# (Um diese geht es vornehmlich in diesem
+Kapitel), #on("b")#Hardware-Software-Schnittstellen#off("b")# (Nach Festlegung, welche Funktionen
+eines Rechnersystems von der Hardware und welche von der Software übernommen
+werden, erfolgt hierüber die Verknüpfung der beiden Komponenten), #on("b")#Software-
+Schnittstellen#off("b")# (zwischen Programmoduln), #on("b")#Mensch-Maschine-Schnittstellen#off("b")#
+(Benutzerschnittstellen - wie z.B. #on("b")#gs-DIALOG#off("b")#) unterschieden.
+
+Wenn wir im folgenden von 'Interface' reden, ist damit immer eine 'Hardware-
+Schnittstelle' gemeint.
+
+Über ein solches Interface (eine Hardware-Schnittstelle) können an den Computer
+externe Geräte/Modelle angeschlossen werden, die vom Computer aus gesteuert
+werden. Dabei setzt das Interface die vergleichsweise schwachen Signale des
+Computers in Ströme und Spannungen um, mit denen z.B. eine Lampe oder ein
+Motor betrieben werden kann. Umgekehrt senden externe Geräte/Modelle über das
+Interface Signale an den Computer, die von ihm ausgewertet werden. So müssen z.B.
+Widerstandsveränderungen eines Temperaturfühlers oder die Stellung eines Schalters
+in eine vom Computer erfaßbare Form umgewandelt werden.
+
+Inzwischen bieten verschiedene Hersteller (FISCHER, LEGO, AKTRONIK, PHYWE,
+etc.) und Lehrmittelverlage (METZLER, CVK, etc.) eine Reihe von Lösungen an.
+Leider sind die meisten Lösungen auf ganz spezielle Computertypen zugeschnitten
+und somit nicht an anderen Computertypen verwendbar - außerdem unterscheiden
+sich die verschiedenen Lösungen z.T. ganz erheblich im Leistungsumfang.
+
+Einzellösungen, insbesondere an den gängigen Homecomputern, gibt es schon seit
+langem. Voraussetzung ist zumeist, daß der Computer über einen speziellen
+Anschluß ('Userport' oder 'Joystick-Eingang') verfügt. Oder es werden Platinen
+geliefert, die in spezielle Steckplätze (Slots) einzustecken sind, wo sie vom Computer
+aus angesprochen werden können.
+
+Bei all diesen Lösungen konnten wir 'EUMELaner' nur neidvoll zuschauen. Der
+Vorteil, den wir sonst so zu schätzen wissen, ein einheitliches Betriebssystem auf ganz
+unterschiedlicher Hardware zur Verfügung zu haben, wird hier zum Nachteil. Eine
+einheitliche Lösung schien zu Anfang völlig aussichtslos zu sein.
+
+
+#on("b")#2.2  Die besonderen Probleme unter EUMEL#off("b")#
+
+Das Betriebssystem EUMEL gestattet es nicht, beliebig auf Hardwarekomponenten des
+Rechners zuzugreifen - und das aus gutem Grund, denn sonst wäre ein reibungsloser
+Multi-User-Betrieb nicht gewährleistet. Man kann aber den Zugriff auf neue Hard­
+warekomponenten im EUMEL-System etablieren. Allerdings ist das etwas aufwendiger
+als in anderen Systemen, denn das sogenannte 'Shard', die 'Software-Hardware-
+Schnittstelle', muß angepaßt werden.
+
+Unsere ersten "Gehversuche" mit der Prozeßdatenverarbeitung unter EUMEL haben
+so angefangen. Es ist aber leicht einzusehen, daß dieser Weg nicht sinnvoll ist. Denn
+dann müßten alle EUMEL-Shards (es gibt ja für jeden Rechnertyp mindestens eines)
+entsprechend geändert werden, ggf. müßten für verschiedene Lösungen verschiedene
+Versionen entwickelt werden - eine Aufgabe, die niemand bereit wäre zu überneh­
+men.
+
+
+#on("b")#2.3  Die Wahl des Interface-Systems#off("b")#
+
+Unser Ziel war klar: Wir wollten ein gängiges, käuflich zu erwerbendes Hardware-
+Interface möglichst universell an Computern verschiedener Hersteller unter dem
+Betriebssystem EUMEL ansprechen können.
+
+Nach Sichtung der angebotenen Systeme kamen nur drei in die engere Wahl: das
+LEGO-Interface, das FISCHER-Technik-Interface und das AKTRONIK-Interface (Soft­
+ware-kompatibel dazu ist das PHYWE-Interface).
+
+Bei der Auswahl hielten wir es für sinnvoll, die Empfehlung des Landesinstituts für
+Schule und Weiterbildung in Soest zu berücksichtigen, in der folgende Anforderungen
+an Interfaces formuliert sind:
+
+ - 8 digitale Eingänge
+ - 8 digitale Ausgänge
+ - optional: analoge Ein- und Ausgabe.
+
+Allen gestellten Anforderungen wird nur das AKTRONIK-Interface gerecht. Das System
+ist modular aufgebaut, je nach Anforderungen kann mit verschiedenen Steckkarten
+gearbeitet werden. Es gibt eine "Kompaktlösung", bei der die wichtigsten Funktionen
+bereitgestellt werden (8 digitale Eingänge, 8 digitale Ausgänge, 2 analoge Eingänge).
+Darüber hinaus kann auch noch mit dem sog. 'Modul-Bus' gearbeitet werden, bei
+dem gleichzeitig mehrere Steckkarten angesprochen werden können. Mit ent­
+sprechender Steckkarte ist auch die analoge Ausgabe möglich.
+
+Die beiden anderen Interfaces erfüllen die oben genannten Anforderungen nicht: Das
+LEGO-Interface verfügt über nur 6 digitale Ausgänge und 2 digitale Eingänge; analoge
+Ein- und Ausgabe ist gar nicht möglich.
+
+Das FISCHER-Technik-Inteface verfügt über 8 digitale Ausgänge und 8 digitale Ein­
+gänge. Das Interface verfügt auch über einen analogen Eingang - allerdings nicht
+über einen Analog-Digital-Wandler-Baustein! Das bedeutet, daß der angeschlossene
+Rechner die Auswertung der eingehenden Daten übernehmen muß - ein zeit­
+kritischer Prozeß, der in einem Multi-User-System nicht garantiert werden kann. Die
+analoge Ausgabe ist grundsätzlich nicht möglich, das System ist in sich abgeschlossen
+und kann sich ändernden Anforderungen ebensowenig angepaßt werden wie das
+LEGO-Interface.
+
+
+Wir entschieden uns also dafür, die weitere Entwicklung auf der Basis des
+AKTRONIK-Interfaces zu betreiben. Es galt jedoch noch, dieses Interface mit dem
+Computer zu verbinden - und das möglichst universell: möglichst unabhängig von der
+verwendeten Computerhardware.
+
+Dieses Ziel ist nur dann zu erreichen, wenn man die 'Standardschittstellen' des
+Computers berücksichtigt, die unter EUMEL problemlos ansprechbar sind: die
+parallelen (Centronics) und seriellen (V24) Schnittstellen. Diese 'Standardschnitt­
+stellen' sind zwar nicht für den direkten Anschluß der Modelle/Interfaces geeignet,
+über einen "Adapter" aber ist ein Anschluß möglich.
+
+Die Entscheidung fiel schnell gegen eine Verwendung der parallelen (Centronics)
+Schnittstelle. Die meisten Computer verfügen nur über eine dieser Schnittstellen, die
+zumeist auch schon durch den Drucker belegt ist. Außerdem handelt es sich dabei in
+der Regel um eine unidirektionale Schnittstelle - d.h. die Daten können vom
+Computer zum Endgerät (z.B. Drucker) gelangen, nicht aber vom Endgerät zum
+Computer. Somit wären zwar Steuerungsvorgänge, nicht aber Meß- und Regelungs­
+vorgänge über die Schnittstelle möglich.
+
+Einige Hersteller nutzen die Datenleitungen, über die z.B. der Drucker dem Rechner
+mitteilt, daß der interne Speicher voll bzw. das Papier zuende ist. Über diese Leitung
+werden Daten seriell übertragen und vom Rechner ausgewertet. Unter EUMEL
+scheidet diese Lösung aber aus, denn um hier eine sichere Auswertung zu gewähr­
+leisten, müßten Maschinenspracheprogramme eingebunden werden; das ist aber
+unter EUMEL nicht möglich.
+
+Damit war festgelegt, daß die weitere Entwicklung auf der Basis des AKTRONIK-Inter­
+faces über die serielle Schnittstelle erfolgen sollte. Wie schon erwähnt, ist das Inter­
+face auf keinen Fall direkt an die serielle Schnittstelle anschließbar. Wie der Name
+schon sagt, werden die Daten bei einer seriellen Schnittstelle seriell übertragen - um
+Prozeßdatenverarbeitung zu betreiben, müssen die Daten aber parallel vorliegen.
+
+Notwendig ist also ein "Adapter", der einen Seriell-Parallel-/Parallel-Seriell-Wandler
+beinhaltet, so daß die Verbindung zwischen Computer und Interface hergestellt
+werden kann.
+
+Inzwischen sind uns hier zwei (käuflich zu erwerbende) Lösungen bekannt - der
+"RS232-Adapter" der Firma AKTRONIK und das "MUFI" (Multifunktionales Interface)
+der Firma BICOS:
+
+Das MUFI ist sicherlich der universeller verwendbare "Adapter" (leider aber auch die
+kostspieligere Lösung). Einerseits kann es ebenso wie der "RS232-Adapter" an eine
+separate serielle Schnittstelle angeschlossen werden, andererseits verfügt es über
+einen zweiten - den eigentlich interessanten Betriebsmodus: Es kann nämlich auch
+in den Terminalkanal eingebaut werden.
+
+Die Idee, die dahintersteckt, ist folgende: Das MUFI verfügt (neben der eigentlich
+wichtigen bidirektionalen parallelen Schnittstelle) über einen (seriellen) Eingang und
+einen (seriellen) Ausgang. So kann das MUFI einfach in eine Leitung zwischen
+Computer und Terminal eingebaut werden. In ausgeschaltetem Zustand hat es
+keinen Einfluß auf den Datenaustausch zwischen Rechner und Terminal - als ob es
+gar nicht vorhanden wäre. In eingeschaltetem Zustand dagegen "horcht es den
+Datenfluß zwischen Rechner und Terminal ab". Auf eine vereinbarte Parole
+(Zeichenkombination) hin, "weiß es", daß die folgenden Daten nicht für das
+Terminal, sondern eben für sich bestimmt sind. Diese, und nur diese Daten werden
+aus dem Datenstrom vom MUFI "herausgefischt" und intern sachgerecht weiterver­
+arbeitet. Alle anderen Daten werden unbeeinflußt an das Terminal weitergeleitet,
+damit ja nicht der reibungslose Betrieb gestört wird. Natürlich ist das MUFI ebenso in
+der Lage, die gerade extern anliegenden Daten zu ermitteln und in den Datenstrom
+zum Computer "einzuschleusen".
+
+Um diese Aufgaben bewältigen zu können, wurde das MUFI mit einem eigenen,
+schnellen Mikroprozessor ausgestattet, der in der Lage ist, den Datenfluß zu
+bewältigen. Zudem wurde versucht, das MUFI mit soviel Intelligenz (Firmware)
+auszustatten, daß alle zeitkritischen Prozesse bei der Ansteuerung des Interface-
+Systems vom MUFI selbst erledigt und die Daten vom MUFI so aufbereitet werden,
+daß sie möglichst einfach weitergegeben und verarbeitet werden können.
+
+Durch die Beschränkung der Baud-Rate auf maximal 19200 ist die Verarbeitungs­
+geschwindigkeit allerdings auch beschränkt. Die rechnerisch maximale Ausgabetakt­
+rate von 320 Hz bei 19200 Baud und 160 Hz bei 9600 Baud wird von #on("b")#gs-Prozess#off("b")# auf
+einem 80386-Rechner im Alleinbetrieb tatsächlich erreicht. Natürlich bedeuten
+mehrere gleichzeitig betriebene MUFIs an einem Rechner Geschwindigkeitseinbußen.
+Ebenso sinkt die Ausgabetaktrate bei Prozessoren mit geringerem Durchsatz (8088:
+maximal 120 Hz). Für die Anwendungen in der Schule sind diese Geschwindigkeiten
+aber hinreichend.
+
+Die Vorteile des MUFI für diejenigen, die EUMEL im Multi-User-Betrieb nutzen, liegen
+dennoch klar auf der Hand:
+
+ - Es werden keine weiteren seriellen Schnittstellen benötigt. (Die vorhandenen
+ sind sowieso schon weitgehend belegt. Gegebenenfalls würden zusätzliche
+ Kosten verursacht.)
+
+ - Es sind keine weiteren Kabelverlegungen zwischen Rechner und Arbeitsplatz
+ notwendig, trotzdem befindet sich das MUFI direkt am Bildschirmarbeits­
+ platz.
+
+ - Das beim Anschluß an eine separate Schnittstelle notwendige, zeitauf­
+ wendige Ansteuern des Interface-Kanals entfällt.
+
+
+Arbeiten Sie an einem Einzelplatz-System (z.B. IBM-kompatibler Rechner nur mit
+Monitor) so ist ein Betrieb des MUFIs im Terminal-Kanal nicht möglich. Hier bleibt
+nur der Betrieb des Interface-Systems an einer separaten seriellen Schnittstelle.
+Sinnvoll ist aber auch ein solcher Betrieb, wenn (zunächst) nur die Hardware für
+einen Arbeitsplatz zur Verfügung steht. Das Interface kann dann nämlich von meh­
+reren Tasks abwechselnd angesprochen werden.
+
+Beim Anschluß an eine separate serielle Schnittstelle sind die Leistungen des MUFIs
+und des RS232-Adapters gleichwertig. Da das abwechselnde Ansprechen einer
+seriellen Schnittstelle und der Tastatur/des Monitors unter EUMEL relativ zeitauf­
+wendig ist, sind hier keine hohe Ausgabegeschwindigkeiten zu erwarten: bei einem
+8088-Rechner ca. 40 Hz, bei Prozessoren mit höherem Durchsatz eben entsprechend
+mehr. Dennoch ist das für die meisten Anwendungen in der Schule schnell genug.
+
+Für Spezialanwendungen ist auch die direkte Ansprache der Schnittstelle möglich.
+Hierbei sind Ausgabetaktraten von 960 Hz bei 19200 Baud bzw. 480 Hz bei 9600
+Baud möglich. Für die schulische Praxis (in der Sekundarstufe I) ist diese "direkte
+Ansprache" aber ungeeignet, da weitergehende Programmierkenntnisse erforderlich
+sind. Zudem kann bei Programmierfehlern "die Task am Kanal hängenbleiben".
+Genaueres dazu sehen Sie bitte im Kapitel 'Hinweise für den Systembetreuer/
+Programmierer'.
+
+Die Hardware-Konstellation stellt sich im Überblick also folgendermaßen dar:
+#on("b")#
+
+ Computer <---> Adapter <---> Interface <---> Modell
+
+ (mit se- ('MUFI' (AKTRONIK)
+ rieller oder
+ Schnitt- 'RS232-
+ stelle) Adapter')
+#off("b")#
+
diff --git a/doc/prozess/gs-Prozess-3 b/doc/prozess/gs-Prozess-3
new file mode 100644
index 0000000..3fae1bd
--- /dev/null
+++ b/doc/prozess/gs-Prozess-3
@@ -0,0 +1,346 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#on("b")#3  Installation des Interface-Systems#off("b")#
+
+In diesem Kapitel erfahren Sie, wie Sie Ihr Interface-System an den Rechner an­
+schließen und welche Einstellungen noch vorzunehmen sind. Für Details und weiter­
+gehende Informationen sehen Sie bitte in den Handbüchern / Begleitmaterialien der
+Firmen BICOS bzw. AKTRONIK nach.
+
+Am Ende des Kapitels 2 haben wir festgestellt, daß das Interface-System über einen
+Adapter mit dem Computer verbunden werden muß. An das Interface-System lassen
+sich dann entsprechende Modelle anschließen:
+
+#on("b")# Computer <----> Adapter <----> Interface <----> Modell
+
+ (mit se- ('MUFI' (AKTRONIK)
+ rieller oder
+ Schnitt- 'RS232-
+ stelle) Adapter') #off("b")#
+
+Wir möchten Ihnen zuerst erklären, wie Sie den jeweiligen Adapter mit dem
+Computer verbinden und welche Einstellungen am Adapter vorzunehmen sind. An­
+schließend beschreiben wir, wie Sie das Interface-System an den Adapter anschlie­
+ßen.
+
+Wie schon in Kapitel 2 erwähnt, können Sie zwischen zwei Adaptern wählen - dem
+MUFI der Firma BICOS und dem RS232-Adapter der Firma AKTRONIK. Letztge­
+nannter kann nur an einer separaten seriellen Schnittstelle betrieben werden,
+während das MUFI zusätzlich auch in den Terminalkanal eingebaut werden kann.
+
+
+#on("b")#3.1  Das MUFI der Firma BICOS als Adapter#off("b")#
+
+Für den Betrieb in einem Terminalkanal sollte das MUFI über eine sog. "Schnitt­
+stellen-Automatik" verfügen, die verhindert, daß das MUFI in ausgeschaltetem
+Zustand oder mit abgezogenem Netzstecker den Datenfluß zwischen Rechner und
+Terminal unterbricht. Diese sehr sinnvolle Automatik wird von BICOS #on("b")#nicht
+standardmäßig#off("b")# eingebaut. Sie sollten bei eventuellen Bestellungen darauf achten.
+Bevor Sie das MUFI in den Terminalkanal einbauen oder an eine separate serielle
+Schnittstelle anschließen, ist noch die Einstellung der DIP-Schalter zu kontrollieren
+bzw. eine Neueinstellung vorzunehmen.
+
+
+#on("b")#3.1.1  Einstellung der DIP-Schalter am MUFI#off("b")#
+
+Versichern Sie sich, daß das MUFI noch nicht an das Netz angeschlossen ist. Öffnen
+Sie dann das Gehäuse, indem Sie die vier Schrauben an der Unterseite des MUFIs
+(direkt neben den Füßen) lösen. Heben Sie nun #on("b")##on("b")#vorsichtig#off("b")##off("b")# den hellen Deckel des
+Gehäuses ab. Aber Achtung! Der Deckel bleibt über Kabel mit dem Fußteil ver­
+bunden! Legen Sie vorsichtig den Deckel neben das MUFI, so daß die Kabelver­
+bindungen nicht belastet werden.
+
+ +---------------------------------------------------+
+ | +-------+ +------------+ |
+ | | | | | +---------+ |
+ | +-------+ | | | DIP- | |
+ | +-------+ | | | Schalter| |
+Rück- | | | | | +---------+ | Vorder-
+seite | +-------+ | | +--------------+ | seite
+ | +-------+ | SCN68000 | | | |
+ | | | | | +--------------+ |
+ | +-------+ | | |
+ | +-------+ | | |
+ | | | | | |
+ | +-------+ +------------+ |
+ +---------------------------------------------------+
+
+
+
+#center#Abb.1: MUFI geöffnet
+
+
+Im Inneren des Fußteiles fällt Ihnen sofort der größte CHIP auf, der u.a. die
+Bezeichnung 'SCN68000' trägt. Drehen Sie das MUFI so vor sich, daß an der linken
+Seite dieses Chips die vier gleichen, mittelgroßen Chips zu liegen kommen. Dann
+sehen Sie rechts vom großen Chip, ganz hinten im Gehäuse eine kleine Plastikbox
+mit DIP-Schaltern, die die folgende Aufschrift trägt:
+
+#on("b")#
+ O N
+ 1 2 3 4
+#off("b")#
+
+Den durchsichtigen Deckel dieser kleinen Plastikbox müssen Sie nun öffnen, um die
+Stellung der DIP-Schalter einsehen zu können. Dazu verwenden Sie am besten einen
+Kugelschreiber oder einen kleinen Schraubendreher. Heben Sie damit den Deckel an
+der rechten Seite leicht an, dann läßt sich der Deckel nach links herüberlegen. Weist
+ein Schalter nach hinten (in dieser Lage des MUFIs von Ihrem Körper weg), so hat er
+die Stellung 'ON', weist er nach vorn (zu Ihrem Körper hin), so hat er die Stellung
+'OFF'.
+
+
+Beispiel:
+
+ +---------------------------------------+
+ | +-----+ +-----+ +-----+ +-----+ |
+ | |+++++| | | | | | | |
+ | |+++++| | | | | | | | ON
+ | |+++++| | | | | | | |
+ | |+++++| | | | | | | |
+ | | | | | | | | | |
+ | | | | | | | | | |
+ | | | | | | | | | |
+ | | | |+++++| |+++++| |+++++| |
+ | | | |+++++| |+++++| |+++++| |
+ | | | |+++++| |+++++| |+++++| | OFF
+ | | | |+++++| |+++++| |+++++| |
+ | +-----+ +-----+ +-----+ +-----+ |
+ +---------------------------------------+
+
+ 1 2 3 4
+
+#center#Abb.2:  Mögliche DIP-Schalter-Stellung beim MUFI
+
+
+Dabei haben die DIP-Schalter folgende Bedeutung:
+
+#on("b")#
+ 1 ON : Modulbusbetrieb
+ OFF : Parallelportbetrieb
+
+ 2 ON : RTS/CTS Hardware Handshake
+ OFF : XON-/XOFF-Protokoll
+
+ 3 ON : 9600 Baud
+ OFF : 19200 Baud
+
+ 4 ON : Even Parity
+ OFF : No Parity
+
+#off("b")#
+Wenn Sie das MUFI im Terminalkanal betreiben wollen, müssen Sie je nachdem, wie
+Sie Ihr Terminal konfiguriert haben, die entsprechende Einstellung vornehmen.
+
+Betreiben Sie das Terminal mit einer Übertragungsrate von 19200 Baud, so sollten
+Sie unbedingt mit XON/XOFF-Protokoll arbeiten - es sei denn, das Terminal unter­
+stützt RTS/CTS! In jedem Falle muß der DIP-Schalter 1 in die Stellung ON gebracht
+werden (der Betrieb des Interface-Systems der Firma AKTRONIK wird hier "Modul­
+busbetrieb" genannt).
+
+Wenn Sie das MUFI an einer separaten seriellen Schnittstelle betreiben wollen, #on("b")#muß#off("b")#
+der Datenaustausch mit dem RTS/CTS-Protokoll abgewickelt werden. Versichern Sie
+sich, daß Ihr Kabel darauf ausgelegt ist!
+
+Nach dieser Einstellung der DIP-Schalter ist das MUFI betriebsbereit. Schrauben Sie
+bitte den Gehäusedeckel mit den vier Schrauben wieder fest.
+
+
+#on("b")#3.1.2  Einbau des MUFIs in den Terminalkanal#off("b")#
+
+Um das MUFI in den Terminalkanal einbauen zu können, müssen Sie zunächst die
+Zuleitung vom Rechner zum Terminal am Terminal lösen. Auf der Rückseite des
+MUFIs befinden sich zwei Stecker, die mit V24/1 und V24/2 bezeichnet sind. Ver­
+inden Sie nun das Kabel, was ursprünglich vom Computer zum Terminal führte, mit
+dem MUFI, indem Sie es an den mit V24/2 gekennzeichneten Stecker anstecken. Sie
+benötigen jetzt noch ein weiteres (kurzes) V24-Kabel, um das MUFI mit dem
+Terminal zu verbinden. Es wird einerseits auf den mit V24/1 gekennzeichneten
+Stecker am MUFI aufgesteckt; das andere Ende wird mit dem Terminal in gleicher
+Weise verbunden, wie das ursprüngliche Kabel zwischen Rechner und Terminal.
+
+
+ +--------------------------+
+ | +----------------------+ |
+ | | V24/1 V24/2 | |
+ | | | | | |
+ | +----|-----------|-----+ |
+ +------|-----------|-------+
+ | |
+ | |
+ ZUM <-----+ +-----> ZUM
+ TERMINAL COMPUTER
+
+
+#center#Abb.3: Einbau des MUFIs in den Terminalkanal
+
+
+Beachten Sie bitte, daß die V24-Schnittstellen des MUFIs auf 8 Datenbits und 1 Stop­
+bit fest eingestellt sind - ggf. müssen Sie Ihre Terminalkonfiguration hieran anpassen.
+Kontrollieren Sie aber in jedem Falle, ob die Konfiguration mit diesen Daten überein­
+stimmt!
+
+Koppeln Sie dazu die Task 'configurator' an Ihr Terminal (mit 'continue
+("configurator") <RETURN>') und geben Sie dann das Kommando 'configurate
+<RETURN>'. Für alle vorhandenen Kanäle werden Sie nun nacheinander gefragt,
+ob Sie eine Konfiguration vornehmen wollen. Bei den "interessanten Kanälen" ant­
+worten Sie mit 'ja' (<j>).
+
+Wollen Sie sich nur die aktuelle Konfiguration ansehen, so beantworten Sie alle dann
+gestellten Fragen zum Kanal mit 'ja' (<j>), dann bleibt die aktuelle Einstellung
+erhalten. Der Konfigurationsdialog ist im EUMEL-Systemhandbuch auf den Seiten 6 -
+8 detailliert beschrieben.
+
+Die Verschaltung der V24-Kabel ist in der Bedienungsanweisung zum MUFI erläutert,
+ggf. können Sie entsprechende Kabel von der Firma BICOS beziehen.
+
+Wenn alle Kabelverbindungen gesteckt sind, sollten Sie auf alle Fälle erst einmal #on("b")#bei
+ausgeschaltetem MUFI#off("b")# prüfen, ob das Terminal sich noch bedienen läßt. Wenn das
+Terminal keine Reaktion mehr zeigt, obwohl es vorher (ohne MUFI) reibungslos
+funktioniert hat, dann haben Sie entweder ein MUFI ohne "Schnittstellen-Automatik"
+vor sich (vergl. Sie dazu Kap. 3.1), oder an den Kabelverbindungen stimmt irgend­
+etwas nicht. In diesem Falle sollten Sie noch einmal alle Anschlüsse und eventuell
+auch die interne Verschaltung der Kabel überprüfen.
+
+
+#on("b")#3.1.3  Das MUFI an separater serieller Schnittstelle#off("b")#
+
+Wenn Sie das MUFI als Endgerät an einer separaten seriellen Schnittstelle betreiben,
+dann stecken Sie das vom Computer kommende Kabel auf den mit V24/2
+bezeichneten Stecker an der Rückseite des MUFIs. Damit ein einwandfreier Betrieb
+gewährleistet ist, sollten Sie einen sog. "Kurzschlußstecker" auf die dann freie
+25polige D-Subminiatur-Buchse (V24/1) am MUFI aufstecken. Haben Sie eine solche
+nicht zur Hand, können Sie zwei kleine Brücken einsetzen: Nehmen Sie dazu zwei
+kleine Drahtstücke und verbinden Sie einmal Pin (Öffnung) 2 mit Pin 3 und außer­
+dem Pin 4 mit Pin 5.
+
+In der Task 'configurator' muß der Kanal, an dem das MUFI angeschlossen ist, auf
+'transparent, 8 Bit, 1 Stopbit, RTS/CTS-Protokoll' eingestellt werden, weiterhin je nach
+MUFI-DIP-Schalter-Stellung auf '9600' bzw. '19200 Baud' und 'no parity' bzw. 'even
+parity'.
+
+
+#on("b")#3.2  Der RS232-Adapter der Firma AKTRONIK#off("b")#
+
+Bevor Sie den Adapter an die serielle Schnittstelle anschließen, ist noch die einge­
+stellte Baudrate zu überprüfen bzw. eine Neueinstellung vorzunehmen.
+
+Öffnen Sie das Gehäuse des Adapters, indem Sie die vier Schrauben an der Unterseite
+lösen. Drehen Sie den Adapter so vor sich, daß die 25polige D-Subminiatur-Buchse
+von Ihrem Körper wegzeigt. Vorn rechts sind dann zwei parallele 8polige Pfosten­
+steckerleisten sichtbar.
+
+#center#25-pol. D-Subminiatur-Stecker
+
+ +---------------+
+ | |
+ +---+ +---+
+ | +------+ |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | +------+ |
+ | +------+ |
+ | | | +-------+ |
+ | +------+ | | |
+ | +------+ +-------+ |
+ | | | +-------+ |
+ | +------+ | <-|---------Jumper-Leiste
+ | +-------+ |
+ +---+ +---+
+ | Baudrate |
+ +---------------+
+
+
+#center#Abb.4:  RS232-Adapter geöffnet
+
+
+Auf einem Paar steckt ein 'Jumper', mit dem die Baudrate eingestellt wird.
+Gegebenenfalls ist dieser Jumper umzustecken. Anschließend schrauben Sie das
+Gehäuse mit den vier entfernten Schrauben wieder zu.
+
+ +---------+
+ | o o | 300
+ | o o | 600
+ | o o | 1200
+ | o o | 2400
+ | o o | 4800
+ | o o | 9600
+ Jumper ---> | o o | 19200
+ | o o | 38400
+ +---------+
+ Baudrate
+
+
+#center#Abb.5:  Mögliche Jumperposition beim RS232-Adapter
+
+
+Nun muß noch in der Task 'configurator' der entsprechende Kanal konfiguriert
+werden. Koppeln Sie dazu die Task 'configurator' an Ihr Terminal (mit 'continue
+("configurator") <RETURN>') und geben Sie dann das Kommando 'configurate
+<RETURN>'. Für alle vorhandenen Kanäle werden Sie nun nacheinander gefragt,
+ob Sie eine Konfiguration vornehmen wollen. Beim vorgesehenen Kanal antworten Sie
+mit 'ja' (<j>).
+
+Wollen Sie sich nur die aktuelle Konfiguration ansehen, so beantworten Sie alle dann
+gestellten Fragen zum Kanal mit 'ja' (<j>), dann bleibt die aktuelle Einstellung
+erhalten. Der Konfigurationsdialog ist im EUMEL-Systemhandbuch auf den Seiten 6 -
+8 detailliert beschrieben.
+
+Folgende Konfigurationsmerkmale müssen eingestellt werden:
+
+ transparent, 8 Bit, 2 Stopbit, no Parity, #on("b")#kein#off("b")# Protokoll
+
+Die Baudrate ist entsprechend der Jumper-Stellung einzustellen.
+
+Am Adapter ist ein Kabel mit 25poligem D-Subminiatur-Stecker bereits fest montiert.
+Sollte der Stecker nicht an Ihren Rechner passen, so müßten Sie ein entsprechendes
+Adapterkabel basteln oder kaufen.
+
+
+
+#on("b")#3.3  Verbindung Adapter - Interface-System#off("b")#
+
+Nachdem Sie nun den Adapter (MUFI oder RS232-Adapter) an den Rechner ange­
+schlossen haben, müssen Sie noch die Verbindung zum Interface-System herstellen.
+Dabei ist es gleichgültig, ob Sie eine Compact-Box, einen Einzelsteckplatz oder einen
+Mehrfachsteckplatz benutzen, denn alle diese Geräte verfügen über den gleichen
+Anschlußstecker. Den RS232-Adapter können Sie direkt an das Interface-System
+anschließen, denn er verfügt bereits über einen entsprechenden Stecker.
+
+Für das MUFI benötigen Sie ein Anschlußkabel, das auf der einen Seite einen
+36poligen Centronics-Stecker und auf der anderen Seite einen 25poligen D-Sub­
+miniatur-Stecker besitzt (von der Firma BICOS zu beziehen).
+
+
+#on("b")#3.4  Bereitstellung des Interface-Systems#off("b")#
+
+Sofern Sie eine Compact-Box angeschlossen haben, brauchen Sie nur noch das mitge­
+lieferte Netzteil mit der Compact-Box und dem Netz zu verbinden und die ent­
+sprechende Spannung laut beiliegender Bedienungsanweisung der Fa. AKTRONIK
+einzustellen.
+
+Wenn Sie mit einem Einzelsteckplatz oder einem Mehrfachsteckplatz arbeiten,
+müssen Sie zunächst noch eine Interface-Karte einstecken. Für einen anschließenden
+Test des Systems (sehen Sie dazu Kapitel 5) empfiehlt es sich, eine Kombikarte oder
+eine E/A-Karte zu verwenden. Nach dem Einstecken der Interface-Karte ist der Steck­
+platz noch mit dem Netzstecker an das Stromnetz anzuschließen, um eine
+Spannungsversorgung zu gewährleisten.
+
+
+
+
+
+
+
diff --git a/doc/prozess/gs-Prozess-4 b/doc/prozess/gs-Prozess-4
new file mode 100644
index 0000000..e106df1
--- /dev/null
+++ b/doc/prozess/gs-Prozess-4
@@ -0,0 +1,173 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#on("b")#4  Installation von gs-Prozess#off("b")#
+
+
+Bevor Sie #on("b")#gs-Prozess#off("b")# auf Ihrem Computer benutzen können, müssen Sie das
+Programm zunächst installieren. Wenn #on("b")#gs-Prozess#off("b")# auf Ihrem System schon zur
+Verfügung steht, können Sie dieses Kapitel ruhig überspringen.
+
+
+
+#on("b")#4.1  Voraussetzungen#off("b")#
+
+
+Um #on("b")#gs-Prozess#off("b")# auf Ihrem Computer betreiben zu können, muß das EUMEL-
+Betriebssystem installiert sein. #on("b")#gs-Prozess#off("b")# setzt die Multi-User-Version voraus und ist
+lauffähig ab Version 1.8.x. #on("b")#gs-Prozess#off("b")# setzt weiterhin voraus, daß auf Ihrem
+Computer bereits das Programm #on("b")#gs-DIALOG#off("b")# (Version 1.1) installiert ist.
+
+
+
+#on("b")#4.2  Lieferumfang#off("b")#
+
+
+#on("b")#gs-Prozess#off("b")# wird auf einer Diskette geliefert, die alle notwendigen Programme ent­
+hält (die Installation von #on("b")#gs-DIALOG#off("b")# wird dabei vorausgesetzt!). Um den Inhalt der
+Diskette feststellen zu können, starten Sie Ihr System und bringen es dazu, daß 'gib
+kommando:' erscheint. Dann legen Sie die Diskette ein und geben das Kommando:
+
+
+#on("b")##center#archive("gs-Prozess");list(archive);release(archive) <RETURN>#off("b")#
+#page#
+Anschließend erscheint eine Übersicht der auf dem Archiv vorhandenen Programme.
+Folgende Programme sollten sich in der Übersicht befinden:
+
+
+ "gs-Prozess 1 für MUFI im Terminalkanal"
+ "gs-Prozess 1 für MUFI als Endgerät"
+ "gs-Prozess 1 für AKTRONIK Adapter"
+ "gs-Prozess 2"
+ "gs-Prozess 3"
+ "gs-Prozess 4"
+ "gs-Prozess 5"
+ "gs-MENUKARTE:Prozess"
+ "gs-Prozess/gen"
+
+
+Eventuell können noch weitere Namen auf der Diskette vorhanden sein. Wenn Sie den
+Inhalt der Diskette kontrolliert haben und diese Programme auf der Diskette vor­
+handen sind, können Sie #on("b")#gs-Prozess#off("b")# installieren.
+
+Sollten Sie statt der Übersicht eine Fehlermeldung erhalten, überprüfen Sie bitte, ob
+die Diskette das richtige Format besitzt oder ob Ihr Diskettenlaufwerk Probleme
+macht. Sollten dagegen Programme fehlen, so reklamieren Sie die Diskette.
+
+
+#on("b")#4.3  Installation#off("b")#
+
+#on("b")#gs-Prozess#off("b")# muß in einer Task installiert werden, in der bereits das Programm
+#on("b")#gs-DIALOG#off("b")# zur Verfügung steht. Alle Söhne und Enkel der neuen Task können
+anschließend mit #on("b")#gs-Prozess#off("b")# arbeiten. Richten Sie also eine Task als Sohn der Task
+ein, in der auf Ihrem Computer bereits #on("b")#gs-DIALOG#off("b")# installiert ist. Wir nehmen hier
+an, daß #on("b")#gs-DIALOG#off("b")# in der Task 'MENU' installiert ist und die neue Task den Namen
+'PDV' erhalten soll. (Sie können für die Task auch einen beliebigen anderen Namen
+wählen):
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+
+ --> gib supervisor kommando:
+
+ begin ("PDV","MENU") <RETURN>
+
+ --> gib kommando:
+
+
+#off("b")#
+(Arbeiten mehrere Personen mit dem Computer, dann ist es sinnvoll, diese Task vor
+unbefugtem Zugriff durch ein Passwort zu schützen. Wie das gemacht wird, können
+Sie in Ihrem EUMEL-Benutzerhandbuch erfahren.)
+
+
+Legen Sie dann die Archivdiskette ein, auf der sich #on("b")#gs-Prozess#off("b")# befindet, und geben
+Sie das folgende Kommando:
+
+
+#on("b")#
+ archive("gs-Prozess") <RETURN>
+
+ fetch("gs-Prozess/gen",archive) <RETURN>
+
+ run <RETURN>
+
+#off("b")#
+
+Sie haben damit das Generatorprogramm gestartet. Bevor die Generierung allerdings
+ausgeführt werden kann, müssen Sie dem System noch Angaben über den ver­
+wendeten Adapter machen. Die zur Verfügung stehenden Anpassungen werden Ihnen
+zur Auswahl angeboten:
+ +--------------------------------------------------------+
+ | Auswahl der Interface-Anpassung |
+ | Bitte gewünschte Anpassung ankreuzen! |
+ |--------------------------------------------------------|
+ | Auswahl  e i n e r  Datei durch Ankreuzen |
+ |--------------------------------------------------------|
+ |==> > gs-Prozess 1 für MUFI im Terminalkanal |
+ | > gs-Prozess 1 für MUFI als Endgerät |
+ | > gs-Prozess 1 für AKTRONIC-Adapter |
+ | |
+ +--------------------------------------------------------|
+ | Info: <?> Fertig: <ESC><q> Abbrechen: <ESC><h> |
+ +--------------------------------------------------------+
+#center#Abb.6:  Auswahl der Interface-Anpassung
+
+
+Bringen Sie den Pfeil mit den Pfeiltasten vor die gewünschte Anpassung und drücken
+Sie die <RETURN>-Taste.
+
+Haben Sie als Anpassung "gs-Prozess für AKTRONIK Adapter" oder "gs-Prozess für
+MUFI als Endgerät" gewählt, so erscheint als nächstes die Aufforderung:
+
+#center##on("b")#'Gib Interface-Kanal:'#off("b")#
+
+Geben Sie hier die Kanalnummer der seriellen Schnittstelle ein, an der der Adapter
+betrieben werden soll.
+
+Die Installation wird automatisch durchgeführt. Lassen Sie während des gesamten
+Vorgangs die Archivdiskette eingelegt. Die Generierung ist beendet, wenn der
+EUMEL-Eingangsbildschirm erscheint. Die Task, in der die Generierung stattfin­
+det, wird automatisch zur Managertask, das heißt, daß Söhne von ihr eingerichtet
+werden können.
+
+
+#on("b")#4.4  Anmerkungen zur Erstinstallation#off("b")#
+
+Mit der Installation der Software ist das Gesamtsystem allerdings noch nicht betriebs­
+bereit. Dazu fehlen #on("b")#gs-Prozess#off("b")# noch einige Informationen. Bisher ist #on("b")#gs-Prozess#off("b")#
+nämlich nur bekannt, welchen Adapter Sie verwenden und ob Sie ihn im Terminal­
+kanal oder an einer separaten Schnittstelle betreiben wollen.
+
+Um das angeschlossene Interface-System sachgerecht ansteuern zu können, benötigt
+#on("b")#gs-Prozess#off("b")# aber noch Informationen über die Hardware-Konstellation. Diese Mit­
+teilungen, die noch gemacht werden müssen, nennen wir "Konfiguration von
+#on("b")#gs-Prozess#off("b")#". Wie diese Konfiguration vorgenommen wird und wie Sie anschließend
+Ihr Interface-System testen, ist im Kapitel 5 detailliert beschrieben.
+
+#on("b")#gs-Prozess#off("b")# bietet Ihnen eine Reihe von Möglichkeiten, die vorhandene Hardware
+möglichst effektiv zu nutzen. So ist es möglich, wenn Sie Ihre(n) Adapter an
+separater/separaten Schnittstelle(n) betreiben, von verschiedenen Tasks aus auf
+einen Adapter zuzugreifen. Gerade in der Anschaffungsphase, wenn noch nicht
+genügend Hardware zur Verfügung steht, ist das eine sinnvolle/preiswerte Möglich­
+keit, von verschiedenen Arbeitsplätzen aus Prozeßdatenverarbeitung zu betreiben.
+
+Zu diesem Zeitpunkt würde es aber zu weit führen, hierzu Details zu erläutern.
+Beschreibungen dieser Möglichkeiten finden Sie im Kapitel "Hinweise für den
+Systembetreuer/ Programmierer".
+
+#on("b")#
+Sie sollten sich zunächst darauf beschränken, ein Interface-System "zum
+Laufen zu bringen". Verfahren Sie dazu bitte genau, wie im Kapitel 5
+beschrieben.#off("b")#
+
diff --git a/doc/prozess/gs-prozess-1 b/doc/prozess/gs-prozess-1
new file mode 100644
index 0000000..f6a3696
--- /dev/null
+++ b/doc/prozess/gs-prozess-1
@@ -0,0 +1,99 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#on("b")#1  Was kann gs-Prozess#off("b")#
+
+#on("b")#gs-Prozess#off("b")# ist ein Programmsystem unter dem Betriebssystem EUMEL, mit dem ein
+Anwendungsbereich erschlossen werden kann, der bisher in der Schule zumeist sehr
+stiefmütterlich behandelt wurde: die Prozeßdatenverarbeitung - das Messen, Steuern
+und Regeln mit dem Computer.
+
+Es wird dadurch möglich, externe Modelle/Geräte (z.B. eine Ampelanlage) zu steuern
+oder von externen Meßfühlern (z.B. einem Temperaturfühler) oder Eingabeeinheiten
+(z.B. einem Lochkartenleser) Daten aufzunehmen. Durch die Kombination der
+beiden Vorgänge können sogar komplexe geregelte Systeme in Modellen nachgebildet
+werden.
+
+Eigentlich ist eine solch stiefmütterliche Behandlung dieses Anwendungsbereiches
+von Computern in der Schule gar nicht einzusehen, denn in der Forschung, im
+Dienstleistungsbereich, im privaten Bereich und vor allem in der Produktion gibt es
+eine Vielzahl von Anwendungen, z.B.:
+
+ Meßdatenerfassung und -auswertung bei Experimenten, Wetterbeobachtung,
+ seismologische Untersuchungen, ..., Ampelsteuerungen, Verkehrsleitsysteme, ...,
+ Scannerkassen, Scheckkartenleser, Geldautomaten, ..., Waschmaschinen,
+ Heizungsanlagen, Modelleisenbahnen, ..., CNC-Maschinen, Universalhand­
+ habungsautomaten (Roboter),...
+
+In den meisten Fällen werden Computer eingesetzt, die speziell für diesen
+Anwendungsbereich entwickelt wurden. Insbesondere an die Verarbeitungsge­
+schwindigkeit solcher Systeme werden sehr hohe Anforderungen gestellt. Solche
+Systeme sind für die schulische Verwendung viel zu teuer. Zumeist sind auch die in
+der Realität ablaufenden Vorgänge so komplex, daß sie als Ganzes gar nicht im
+Unterricht nachgebildet werden können.
+
+Das aber kann auch nicht Ziel einer Auseinandersetzung mit diesem Anwendungs­
+bereich in der Schule sein. Hier gilt es, unter didaktisch-methodischen Gesichts­
+punkten, Grundprinzipen der Prozeßdatenverarbeitung zu vermitteln und beispiel­
+hafte Anwendungen an Modellen zu erarbeiten und zu erproben. In einem zeitge­
+mäßen Informatikunterricht darf dieser wichtige Anwendungsbereich von Computern
+nicht ausgespart bleiben.
+
+Bisher scheiterte das Messen, Steuern und Regeln mit dem Computer in der Schule
+meistens daran, daß es keine standardisierten Software- und Hardware-Systeme und
+auch keine geeigneten Modelle gab. Das aber hat sich inzwischen geändert.
+Verschiedene Hersteller bieten Interface-Systeme und Modelle an, die gut verwendet
+werden können.
+
+Auch #on("b")#gs-Prozess#off("b")# greift auf ein solches Interface-System zu, das aus mehreren
+Einzelkomponenten besteht (mehr dazu in den folgenden Kapiteln). Das sind Geräte,
+über die der Computer "Kontakt" mit den 'Endgeräten' (z.B. Modellen) aufnimmt:
+Hier werden Ausgaben des Computers in "elektrische Impulse" umgesetzt, mit denen
+Modelle angesprochen werden können (z.B. Lämpchen ein- und ausgeschaltet,
+Motoren zu Drehungen nach links oder rechts veranlaßt werden können). Ein­
+gehende "Impulse" werden in "computerangemessene Form" umgewandelt und an
+den Computer weitergegeben.
+
+Der Aufwand, der betrieben werden muß, um ein Interfacesystem sachgerecht anzu­
+steuern, ist erheblich. Es kostet einige Mühe und vor allem viel Zeit, um alle Details
+des Interfacesystems und seiner Programmierung kennenzulernen, und es gehört
+eine gehörige Portion Erfahrung und vor allem viel Geduld dazu, um Fehlfunktionen
+zu analysieren und letztlich zu beheben. Das alles ist einem Anwender, dem es z.B.
+darum geht, ein bestimmtes Modell anzusteuern, nicht zumutbar.
+
+Hier schafft nun #on("b")#gs-Prozess#off("b")# Abhilfe! #on("b")#gs-Prozess#off("b")# ist eingebettet in die komfortable
+Benutzerschnittstelle #on("b")#gs-DIALOG#off("b")#, so daß der Einarbeitungsaufwand in das
+Programmsystem gering und eine einfache Bedienung des Systems gewährleistet ist.
+
+Ähnlich wie bei #on("b")#gs-Herbert und Robbi#off("b")# wird eine komplette Programmier­
+umgebung zur Verfügung gestellt, die alle Funtionen enthält (Informationen,
+Konfiguration des Systems, Erstellung und Ausführung von Programmen, Archiv­
+handling), die bei der Arbeit von Bedeutung sein können - natürlich jetzt auf das
+Messen, Steuern und Regeln bezogen. Durch diese Programmierumgebung wird
+selbst dem Computerneuling ermöglicht, einen einfachen, eingängigen Zugang zu
+diesem Anwendungsbereich zu finden.
+
+#on("b")#gs-Prozess#off("b")# stellt einen Basisbefehlssatz (Eingabe-, Ausgabebefehle und Tests) zur
+Verfügung, mit dessen Hilfe Lösungsalgorithmen aus diesem Anwendungsbereich
+angemessen formuliert werden können. Dabei kann sich der Anwender ganz auf sein
+Problem konzentrieren, da er sich um die spezifische Ansteuerung des Interfaces
+nicht zu kümmern braucht - das erledigt #on("b")#gs-Prozess#off("b")#.
+
+Der Basisbefehlssatz besteht aus nur wenigen Befehlen, um das Erlernen und den
+Umgang damit möglichst einfach zu gestalten. Andererseits ist der Befehlssatz so
+umfangreich und universell, daß alle schulisch relevanten Problemstellungen aus
+diesem Anwendungsbereich angemessen bearbeitet werden können.
+
+
+
+
diff --git a/doc/prozess/gs-prozess-5 b/doc/prozess/gs-prozess-5
new file mode 100644
index 0000000..5c44f29
--- /dev/null
+++ b/doc/prozess/gs-prozess-5
@@ -0,0 +1,819 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#on("b")#5  Konfiguration von gs-Prozess#off("b")#
+#on("b")#    Test des Interface-Systems#off("b")#
+
+In diesem Kapitel erfahren Sie, wie Sie #on("b")#gs-Prozess#off("b")# entsprechend der angeschlossenen
+Hardware konfigurieren müssen. Anschließend zeigen wir Ihnen, wie Sie Ihr Inter­
+face-System testen können.
+
+Wir gehen hier davon aus, daß die Hardware-Voraussetzungen erfüllt, das Interface-
+System über einen Adapter (MUFI / RS232-Adapter) angeschlossen und #on("b")#gs-Prozess#off("b")#
+auf dem Rechner installiert sind.
+
+
+#on("b")#5.1  Kontrolle der Konfigurationen/Anschlüsse#off("b")#
+
+Bevor Sie mit der Arbeit beginnen, überzeugen Sie sich unbedingt (noch einmal)
+davon, daß die Konfigurationen und die Steckverbindungen den Vorgaben ent­
+sprechen:
+
+- #on("b")#MUFI im Terminalkanal:#off("b")#
+
+ Sind die beiden Kabel zum Rechner und zum Terminal an der Rückseite des
+ MUFIs korrekt aufgesteckt (sehen Sie Abb.3)? Haben Sie die notwendigen
+ Konfigurationen vorgenommen (Task 'configurator', MUFI-DIP-Schalter, Ter­
+ minal)? Ist das Netzkabel des MUFIs mit dem Stromnetz verbunden? Ist das
+ Verbindungskabel zwischen MUFI und Interface-System an der Vorderseite des
+ MUFIs und am Interface-System (Compact-Box, Einzel- oder Mehrfachsteck­
+ platz) aufgesteckt?
+#page#
+- #on("b")#MUFI als Endgerät:#off("b")#
+
+ Ist das vom Computer kommende Kabel auf den mit V24/2 gekennzeichneten
+ Stecker aufgesteckt? Haben Sie auf den freien Stecker (V24/1) einen "Kurz­
+ schlußstecker" aufgesteckt? Haben Sie ein Kabel verwendet, über welches das
+ RTS/CTS-Protokoll abgewickelt werden kann? Haben Sie den Kanal, an dem das
+ MUFI betrieben wird, den Anweisungen in Kapitel 3.1.3 entsprechend kon­
+ figuriert? Sind die DIP-Schalter im MUFI entsprechend eingestellt? Ist das
+ Netzkabel des MUFIs mit dem Stromnetz verbunden? Ist das Verbindungskabel
+ zwischen MUFI und Interface-System an der Vorderseite des MUFIs und am
+ Interface-System (Compact-Box, Einzel- oder Mehrfachsteckplatz) aufgesteckt?
+
+
+- #on("b")#RS232-Adapter:#off("b")#
+
+ Ist das Schnittstellen-Kabel korrekt am Computer angeschlossen? Haben Sie den
+ Kanal, an dem der RS232-Adapter betrieben wird, den Anweisungen in Kapitel
+ 3.2 entsprechend konfiguriert? Ist der Jumper im RS232-Adapter korrekt aufge­
+ steckt? Ist der RS232-Adapter an das Interface-System (Compact-Box, Einzel-
+ oder Mehrfachsteckplatz) angesteckt? Ist der 3polige Platinenstecker des
+ Adapters in die 12V-Spannungsversorgungs-Buchse des Interface-Systems
+ eingesteckt?
+
+
+- #on("b")#Compact-Box#off("b")#
+
+ Ist die Compact-Box an das zugehörige Netzgerät angeschlossen? Ist der Stecker
+ wirklich richtig herum eingesteckt? Ist das Netzteil mit dem Stromnetz ver­
+ bunden?
+
+- #on("b")#Einzelsteckplatz#off("b")#
+
+ Ist eine Kombi-Karte oder eine E/A-Karte eingesteckt? Ist das Netzkabel des
+ Steckplatz-Netzgerätes mit dem Stromnetz verbunden?
+#page#
+- #on("b")#Mehrfachsteckplatz#off("b")#
+
+ Ist ein passendes Netzteil an den Mehrfachsteckplatz angeschlossen? Ist das
+ zugehörige Netzkabel mit dem Stromnetz verbunden? Ist eine Kombi- oder
+ E/A-Karte in einen Steckplatz eingesteckt?
+
+
+#on("b")#5.2  Vorbereitungen für den Ein-/Ausgabetest#off("b")#
+
+Für den Ausgabetest sollte eine 8elementige Leuchtdiodenanzeige zur Verfügung
+stehen, um am Interface-System die Ausgaben kontrollieren zu können. Sofern Sie
+mit der Compact-Box arbeiten oder eine E/A-Karte verwenden, brauchen Sie sich
+darum nicht weiter zu kümmern, denn in diese Systeme ist eine Leuchtdioden­
+anzeige integriert. Wenn Sie dagegen mit einer Kombikarte arbeiten, muß eine
+gesonderte Anzeige (kann leicht selbst gebaut werden oder ist fertig zu kaufen bei der
+Fa. AKTRONIK) angeschlossen werden.
+
+Für den Eingabetest reicht ein kleines Drahtstück, an dem zwei kleine Lötschuhe
+angelötet sind - schön wäre es, wenn ein Codekarten-Leser zur Verfügung stünde.
+
+
+#on("b")#5.2.1  Anschluß einer Leuchtdiodenanzeige an die Kombikarte#off("b")#
+
+Stecken Sie den 8poligen Platinenstecker, der an der Leuchtdiodenanzeige befestigt
+ist, auf die mit "AUSG." gekennzeichnte Buchse der Kombikarte. Den Lötschuh des
+einzelnen Drahtes an der Leuchtdiodenanzeige stecken Sie auf den Masse-Lötstift
+direkt neben der "Ausgangs-Buchse" der Kombikarte (sehen Sie Abb. 7). Da die
+Leuchtdiodenanzeige mit Spannung versorgt werden muß, müssen jetzt noch zwei
+Kabel - wie in der Abb. 7 dargestellt (Kabel 1 und Kabel 2) - aufgesteckt werden.
+#page#
+
+
+
+ +---------------------------------------------------------------+
+ | 4-7 o----------+ |
+ | +-+-----------+-+ | |
+ | | | O | | GMD o | |
+ | | | | | | Kabel 1 |
+ | | | | | | |
+ | v | | O | | | |
+ | | | | | | |
+ | E| | | | | |
+ | | | O | | | |
+ | +-+-------------+ ___________| |
+ | o -----------| |
+ | Ausg. | |
+ | +---------------+ O 0 | |
+ | | +-----------+ | 1 O | |
+ ---+---|-|---| | | O 2 | |
+ ---+---|-|---| | | 3 O | |
+ ---+---|-|---| | | O 4 | |
+ ---|---|-|---| | | 5 O | |
+ ---|---|-|---| | | O 6 | |
+ ---|---|-|---| | | 7 O | |
+ | | +-----------+ | | |
+ | +---------------+ | |
+<-----------------o | Kabel 2 |
+ Zur Leuchtdiodenanzeige | |
+ | +---------------+ | |
+ | | O | O 0 | |
+ | | O | 1 O | |
+ | | O | O 2 | |
+ | | O | 3 O | |
+ | | O | O 4 | |
+ | | O | 5 O | |
+ | | O | O 6 | |
+ | | O | 7 O | |
+ | +---------------+ | |
+ | GMD o o +5V | |
+ | | | |
+ | +----------------------------+ |
+ | |
+ | +---------------+ |
+ | | O | + O |
+ | | O | O E2 |
+ | | O | GMD O |
+ | +---------------+ |
+ | |
+ | +---------------+ |
+ | | O | + O |
+ | | O | O E2 |
+ | | O | GMD O |
+ | +---------------+ |
+ | o o o o o o o o o o |
+ | | | | | | | | | | | |
+ | +-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+ |
+ | | | |
+ +----------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+----------+
+ | | | | | | | | | | | | | | | | | | | | |
+ | | | | | | | | | | | | | | | | | | | | |
+
+#center#Abb.7:  Anschluß Leuchtdiodenanzeige - Kombikarte
+
+#on("b")#ACHTUNG!#off("b")# Bei dieser Spannungversorgung auf der Kombikarte (+5V) darf #on("b")#auf
+keinen Fall#off("b")# eine größere Last (z.B. Motor oder auch nur eine Glühbirne) ange­
+schlossen werden, da dadurch die Interfacekarte bzw. das Netzteil im Einzelsteck­
+platz beschädigt werden könnte.
+#page#
+Möchten Sie eine größere Last anschließen, so benötigen Sie ein stabilisiertes Netzteil
+mit "ordentlich geglättetem" Gleichstrom. Die Masse (Minuspol) des Netztteils be­
+festigen Sie an dem Lötschuh (oder der davorliegenden Klemme), der zwischen den
+beiden Lötstiften liegt, an denen in der Abb.7 das Kabel 1 befestigt ist. Den Pluspol
+des Netzteiles verbinden Sie mit mit einem der Lötstifte (bzw. an der davorliegenden
+Klemme), auf dem jetzt das Kabel 1 befestigt ist. Damit alle 8 Ausgänge mit Span­
+nung versorgt werden, müssen Sie auch hier ebenfalls eine Brücke zum zweiten
+Lötschuh (oder der Klemme davor), an dem in der Zeichnung Kabel 1 befestigt ist,
+anbringen.
+
+Da die Compact-Box ohnehin durch das Netzteil versorgt wird, kann es hier nicht zu
+Komplikationen kommen. Wollen Sie eine größere Last an die E/A-Karte anschließen,
+so benötigen Sie z.B. eine Relais-Box.
+
+
+
+#on("b")#5.2.2  Anschluß des Codekartenlesers (Drahtstück)#off("b")#
+
+Stecken Sie den 8poligen Platinenstecker, der am Codekartenleser befestigt ist, auf
+die Eingangsbuchse an Ihrem Interface-System. Dann muß noch der 3polige
+Platinenstecker, der ebenfalls am Codekartenleser befestigt ist, an die 12V-Span­
+nungsversorgungs-Buchse an Ihrem Interface-System aufgesteckt werden.
+
+haben Sie keinen Codekartenleser zur Hand, so reicht für den Eingabetest auch ein
+kleines Kabelstück aus, an dessen Enden jeweils ein Lötschuh angelötet sein sollte.
+Stecken Sie den einen Lötschuh auf einen +5V-Lötstift Ihres Interface-Systems. Das
+andere Ende des Kabels wird zunächst noch nicht befestigt.
+
+Auf der Kombikarte sind die +5V-Lötstifte beschriftet und damit leicht zu finden. Wo
+Sie einen +5V-Lötstift auf der E/A-Karte finden, können Sie der folgenden Abbildung
+entnehmen:
+#page#
+ Leuchtdiodenanzeige
+ |
+ +---------------------------------------+------------+
+ | +---------------+ | |
+ | | O | O 0 V |
+Digital- | | O | 1 O o o o o o o o o |
+Ausgang | | O | O 2 |
+ | | O | 3 O |
+ | | O | O 4 |
+ | | O | 5 O |
+ | | O | O 6 |
+ | | O | 7 O |
+ | +---------------+ |
+ | +---------------+ |
+ | | O | O 0 |
+Digital- | | O | 1 O |
+Eingang | | O | O 2 |
+ | | O | 3 O |
+ | | O | O 4 |
+ | | O | 5 O |
+ | | O | O 6 |
+ | | O | 7 O |
+ | +---------------+ |
+ | +---------------+ |
+ | | O | O 0 |
+Versorgungs- | | O | 1 O |
+und | | O | O 2 |
+Steuer- | | O | 3 O |
+leitung | | O | O 4 |
+ | | O | 5 O |
+ | | O---5V------O 6 |
+ | | O | 7 O |
+ | +-------|-------+ | |
+ | | | |
+ | +---------------+ |
+ | | |
+ | GMD |
+ | |
+ | o o o o o o o o o o |
+ | | | | | | | | | | | |
+ | +-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+ |
+ | | | |
+ +----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---+
+ | | | | | | | | | | | | | | | | | | | | |
+ | | | | | | | | | | | | | | | | | | | | |
+
+
+#center#Abb.8:  Pinbelegung auf der E/A-Karte
+
+
+#on("b")#5.3  Konfiguration von gs-Prozess#off("b")#
+
+Normalerweise kann in jeder Task, in der #on("b")#gs-Prozess#off("b")# zur Verfügung steht, die
+Konfiguration vorgenommen werden (beachten Sie aber bitte die Bemerkungen im
+Kapitel "Hinweise für den Systembetreuer/Programmierer").
+
+Richten Sie eine Sohntask der Task ein, in der #on("b")#gs-Prozess#off("b")# installiert ist - in unserem
+Fall soll das die Task 'PDV' sein. Die Sohntask soll den Namen 'pdvtest' erhalten:
+#page#
+#on("b")#
+ <SV> (Supervisor - Taste)
+#off("b")#
+ --> gib supervisor kommando:
+#on("b")#
+ begin ("pdvtest","PDV") <RETURN>
+#off("b")#
+ --> gib kommando:
+#on("b")#
+ pdv <RETURN>
+#off("b")#
+
+Daraufhin erscheint der in Abb.9 dargestellte Menubildschirm. Über die Menupunkte
+im dann sichtbaren Pull-Down-Menu können Sie diverse Informationen zu
+#on("b")#gs-Prozess#off("b")# abrufen, auf die wir hier allerdings nicht weiter eingehen wollen. Statt­
+dessen drücken Sie bitte die 'Pfeiltaste rechts'. Sie gelangen so zum Menu unter dem
+Oberbegriff "Interface" (Abb. 10).
+
+
++---------------------------------------------------------------------+
+| PDV:  Info Interface Programm Archiv |
+|-------+------------------------+------------------------------------+
+| | u  Übersicht Befehle | |
+| | --------------------- | |
+| | a  Ausgabebefehle | |
+| | e  Eingabebefehle | |
+| | t  Testbefehle | |
+| | w  Weitere Befehle | |
+| | --------------------- | |
+| | b  Bitmuster | |
+| | s  Symbole/Zeichen | |
+| | d  Digital-/Analogwerte| |
+| +------------------------+ |
+| |
+| +----------------------------------------+ |
+| | gs-Prozess | |
+| | Version 1.0 | |
+| | | |
+| | Copyright Ρ 1988 bei Eva Latta-Weber, | |
+| | Bielefeld | |
+| +----------------------------------------+ |
++---------------------------------------------------------------------+
+|Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>|
++---------------------------------------------------------------------+
+
+
+ Abb.9:  Eingangsbildschirm #on("b")#gs-Prozess#off("b")#
+#page#
+
++-----------------------------------------------------------------------+
+| PDV:  Info Interface Programm Archiv |
++-------+-------------------+-------------------------------------------+
+| | i  Informationen | |
+| | ---------------- | |
+| | k  Konfigurieren | |
+| | ---------------- | |
+| | a  Ausgabetest | |
+| | e  Eingabetest | |
+| +-------------------+ |
+| |
+| |
+| |
++---------------------------------------------------------------------- +
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++-----------------------------------------------------------------------+
+
+ #center#Abb.10:  Menubildschirm zum Oberbegriff 'Interface'
+
+
+Über den ersten Menupunkt ("Informationen") kann die aktuelle Konfiguration des
+Interfaces erfragt werden. Wenn Sie diesen Menupunkt aktivieren und es ist weder in
+dieser Task noch in einer übergeordneten Task eine Konfiguration vorgenommen
+worden, erhalten Sie die folgende Warnung:
+
+ +----------------------------------------+
+ | Interface ist noch nicht konfiguriert! |
+ +----------------------------------------+
+#center#Abb.11:  Information bei unkonfiguriertem System
+
+
+Ist schon eine Konfiguration, z.B. in der Vatertask vorgenommen worden, so wird
+Ihnen die aktuellen Einstellung angezeigt (s.u.).
+#page#
+#on("b")#5.3.1  Auswahl der Steckplatzart/Interfacekarte#off("b")#
+
+Da Sie in jedem Falle eine Konfiguration von #on("b")#gs-Prozess#off("b")# vornehmen sollen,
+aktivieren Sie jetzt bitte den Menupunkt "Konfigurieren". Daraufhin erscheint die
+folgende Auswahl:
+ +-----------------------------+
+ | Auswahl der Steckplatzart |
+ | |
+ | c Compactbox |
+ | e Einzelsteckplatz |
+ | m Mehrfachsteckplatz |
+ | |
+ | Compact   Einzel   Mehrfach |
+ +-----------------------------+
+
+#center#Abb.12:  Auswahl der Steckplatzart
+
+
+Haben Sie eine Compact-Box angeschlossen, so ist die Konfiguration schnell erledigt:
+Sie tippen die Taste <c>. Daraufhin wird die komplette Konfiguration ausgeführt
+und die Einstellung eingeblendet.
+ +------------------------------------+
+ | Eingestellt: Compactbox |
+ | |
+ | Belegung der Kanäle: |
+ | |
+ | Kanal 1:   Analogeingang 1 (E1) |
+ | |
+ | Kanal 2:   Analogeingang 2 (E2) |
+ | |
+ | Kanal 3:   Digitaleingang |
+ | |
+ | Kanal 4:   Digitalausgang |
+ +------------------------------------+
+
+#center#Abb.13:  Compact-Box: Belegung der Kanäle
+#page#
+Die Anzeige verschwindet, wenn Sie eine beliebige Taste tippen.
+
+Anders dagegen, wenn Sie zuvor dem System mitgeteilt haben, daß ein Einzelsteck­
+platz bzw. ein Mehrfachsteckplatz angeschlossen ist. In diesem Fall müssen Sie
+#on("b")#gs-Prozess#off("b")# noch mitteilen, welche Steckkarten Sie verwenden. Dazu wird Ihnen die
+folgende Auswahl angeboten:
+
+ +----------------------------------+
+ | Angabe der Interfacekarte: |
+ | |
+ | k  Kombikarte |
+ | e  E/A - Karte |
+ | d  D/A - Wandler - Karte |
+ | a  A/D - Wandler - Karte |
+ | 0  Keine Steckkarte |
+ | |
+ | Kombi  E/A  D/A  A/D  Keine |
+ +----------------------------------+
+
+
+#center#Abb.14:  Auswahl einer Interfacekarte
+
+
+Wenn Sie eine Kombikarte, eine E/A-Karte oder eine D/A-Wandler-Karte verwenden,
+ist durch die jeweilige Angabe der Einstellvorgang abgeschlossen. #on("b")#gs-Prozess#off("b")# teilt
+Ihnen daraufhin - ähnlich wie bei der Compact-Box - jeweils die Belegung der Kanäle
+mit. Bei Nutzung der D/A-Wandler-Karte wird zusätzlich der gültige Spannungs­
+bereich angezeigt.
+#page#
+
+ +------------------------------------------------------+
+ | Einzelsteckplatz mit D/A - Karte: |
+ | |
+ | Belegung der Kanäle: |
+ | |
+ | Die Karte stellt einen Analogausgang zur Verfügung, |
+ | der auf zwei Arten angesprochen werden kann:        |
+ | |
+ | Kanal 1:    Spannungsbereich  -5 V  -  +5 V |
+ | |
+ | Kanal 2:    Spannungsbereich   0 V  -  +5 V |
+ | |
+ +------------------------------------------------------+
+
+#center#Abb.15:  Kanalbelegung D/A-Karte (Einzelsteckplatz)
+
+
+Haben Sie dagegen eine A/D-Wandler-Karte angegeben, so erfragt #on("b")#gs-Prozess#off("b")# noch
+die Schalterstellung der DIP-Schalter auf der A/D-Wandler-Karte. Über diese Schalter­
+stellung kann der Spannungsbereich der Analogeingänge festgelegt werden. Das
+erfolgt nach folgendem Prinzip:
+
+Das Spannungsintervall wird jeweils über 3 Schalter festgelegt. Für den Eingang 1
+stehen die Schalter 1, 2 und 3 zur Verfügung, für denn Eingang 2 die Schalter 4, 5
+und 6. Im folgenden werden wir die Einstellung für den Eingang 1 aufzeigen - für den
+Eingang 2 ist mit den drei genannten Schaltern synonym zu verfahren.
+
+Steht Schalter 1 in der Position 'ON', so ist ein Spannungsintervall von 0V - 25V einge­
+stellt (Fall 1) - unabhängig von der Stellung der anderen beiden Schalter. Innerhalb
+eines Schaltertripletts "dominiert" nämlich ein Schalter mit kleinerer Nummer über
+den/die mit größerer Nummer. Ist Schalter 1 in Stellung 'OFF' und Schalter 2 in
+Stellung 'ON', so ist ein Spannungsbereich von 0V - 2,5V eingestellt (Fall 2). Sind die
+beiden ersten Schalter in der Position 'OFF' und nur der Schalter 3 in der Position
+'ON', so ist ein Spannungsintervall von 0V - 0,25V eingestellt (Fall 3).
+#page#
+Eine besondere Bedeutung kommt noch den Schaltern 7 und 8 zu, denn sie beein­
+flussen noch die eben genannten Intervalle. Dabei ist überraschenderweise der
+Schalter 7 für den Eingang 2 und der Schalter 8 für den Eingang 1 zuständig. Die drei
+oben genannten Fälle gelten nämlich nur, wenn Schalter 8 in der Position 'OFF' steht.
+In der Position 'ON' werden die durch das Schaltertriplett eingestellten Spannungs­
+intervalle dagegen symmmetrisch um 0V angelegt: im Fall 1 also der Bereich von
+-12,5V - +12,5V, im Fall 2 von -1,25V - +1,25V und im Fall 3 von -0,125V -
++0,125V.
+ +----------------------------------------------------+
+ | Angabe der Schalterstellungen auf der A/D - Karte: |
+ | |
+ | Bitte die aktuelle Schalterstellung eintragen: |
+ | |
+ | Es bedeutet: 1 - Schalterstellung "on" |
+ | 0 - Schalterstellung "off" |
+ | |
+ | Nummer: 12345678 |
+ | |
+ | Eingabe: 10010010 |
+ +----------------------------------------------------+
+#center#Abb.16:  A/D-Karte: Angabe der Schalterstellung
+
+
+Der Spannungsbereich wird von #on("b")#gs-Prozess#off("b")# aus der Schalterstellung automatisch
+ermittelt und neben den festgelegten Kanalnummer angezeigt. Die obige Schalter­
+stellung führt somit zu folgender Meldung:
+
+ +----------------------------------------------------------------+
+ | Einzelsteckplatz mit A/D - Karte: |
+ | |
+ | Zwei analoge Einträge stehen zur Vefügung: |
+ | |
+ | Kanal 1: (E1) Spannungsbereich 0.000 V  -  +25.000 V |
+ | |
+ | Kanal 2: (E2) Spannungsbereich -12.500 V  -  +12.500 V |
+ | |
+ +----------------------------------------------------------------+
+#center#Abb.17:  A/D-Karte: Kanalbel./Spannungsber.(Bspl.)
+#page#
+Während Sie bei Verwendung eines Einzelsteckplatzes nur einmal nach all diesen
+Angaben gefragt werden, erfolgt die Abfrage bei einem Mehrfachsteckplatz viermal
+hintereinander. Haben Sie einen Steckplatz nicht belegt, so tippen Sie bei der Angabe
+der Interfacekarte die Taste <0> (keine Steckkarte).
+
+
+#on("b")#5.3.2  Bedeutung der Kanalnummern#off("b")#
+
+Nachdem Sie #on("b")#gs-Prozess#off("b")# die Angaben zur Konfiguration (Steckplatzart/Interface­
+kartenart) mitgeteilt haben, teilt Ihnen das System jeweils die Kanalnummern mit.
+Diese Nummern sollten Sie sich merken, denn wenn Sie mit dem von #on("b")#gs-Prozess#off("b")# zur
+Verfügung gestellten Befehlen programmieren wollen, müssen Sie jeweils diese
+Kanalnummern angeben. Fordern Sie von einem Kanal eine Aktion, die nicht ausge­
+führt werden kann/nicht sinnvoll ist, so kann Ihnen dadurch eine Fehlermeldung
+zugestellt werden.
+
+Auf der Compact-Box bzw. der Kombikarte an einem Einzelsteckplatz ist die
+Numerierung identisch: die beiden Analogeingänge haben die Kanalnummern 1 und
+2, der Digitaleingang hat die Nummer 3 und der Digitalausgang die Nummer 4.
+
+Die E/A-Karte verfügt nur über je einen digitalen Eingang und digitalen Ausgang, die
+über die Kanäle 1 und 2 angesprochen werden können. Damit nun aber auch
+Programme, die für die Compact-Box bzw. eine Kombikarte geschrieben sind, auch
+auf der E/A-Karte laufen, können diese beiden Kanäle auch unter der Kanalnummer
+3 (Eingang) bzw. 4 (Ausgang) angesprochen werden. Natürlich ist ein solches
+Programm nur dann auf der E/A-Karte lauffähig, wenn keine Analogeingänge ange­
+sprochen werden, denn die sind ja auf der E/A-Karte gar nicht vorhanden!
+
+Die Kanalnummern auf einem Mehrfachsteckplatz werden nach folgendem System
+vergeben: Die Kanalnummern sind immer zweistellig. Über die erste Ziffer wird der
+Steckplatz (1 - 4) identifiziert, über die zweite Ziffer der eigentliche Kanal auf der
+Steckkarte. Steckt also z.B. in Steckplatz 3 eine Kombikarte (4 mögliche Kanäle) und
+möchten Sie hier den Digitalausgang (Kanal 4) ansprechen, so muß als Kanal die
+Nummer 34 angegeben werden.
+#page#
+Aber auch hier gibt es eine zusätzliche Vereinbarung: Der erste Steckplatz eines
+Mehrfachsteckplatzes kann (zusätzlich) wie ein Einzelsteckplatz angesprochen
+werden. Bei Belegung des ersten Steckplatzes mit einer Kombikarte, können Sie die
+Karte also über die Kanalnummern 11, 12, 13 und 14 ansprechen und zusätzlich
+über die Nummern 1, 2, 3 und 4. Der Sinn der dahintersteckt ist Ihnen sicher sofort
+klar geworden: Dadurch kann ein Programm, das z.B. für die Compact-Box ge­
+schrieben wurde, ohne Änderung übernommen werden, wenn eine Kombikarte auf
+Steckplatz 1 des Mehrfachsteckplatzes steckt etc..
+
+
+#on("b")#5.4  Aus- und Eingabetest#off("b")#
+
+Nun wird es spannend, denn Sie sollen jetzt testen, ob Sie mit Ihrem Interface-System
+arbeiten können. Sofern Sie mit dem MUFI als Adapter arbeiten, schalten Sie das
+MUFI mit dem Schalter an der Vorderseite ein.
+
+Wenn Sie das MUFI im Terminalkanal betreiben, kann das Einschalten dazu führen,
+daß eine unsinnige Zeichenkette auf dem Bildschirm erscheint. Diese Zeichen
+werden durch den "Einschaltknack" verursacht und haben eigentlich nichts zu
+bedeuten. Allerdings läßt sich die Ausgabe auch nicht verhindern. Die Zeichen ver­
+schwinden bei der nächsten Menubedienung.
+
+Wenn Sie alle Hinweise in Kapitel 5.1 beachtet haben, müßte spätestens jetzt das
+Interface-System betriebsbereit sein - gleichgültig, welchen Adapter und welche
+Interface-Komponenten Sie verwenden.
+
+Aktivieren Sie nun den Menupunkt 'Ausgabetest', indem Sie z.B. die Taste <a>
+tippen. Wenn Sie eine Compact-Box angeschlossen haben, müßte die folgende Ein­
+blendung in Ihrem Menubildschirm erscheinen:
+#page#
+ +-------------------------------------------------------------+
+ | Ausgabetest |
+ | |
+ | Ausgabe an Kanal 4 (= Digitalausgang der Compact-Box) |
+ |-------------------------------------------------------------|
+ | |
+ | |
+ | |
+ | Ausgabewert: 129 |
+ | |
+ |-------------------------------------------------------------|
+ | Bitte einen Wert zwischen 0 und 255 eingeben! |
+ | |
+ +-------------------------------------------------------------+
+#center#Abb.18:  Ausgabetest - Einblendung
+
+
+Eine nahezu identische Einblendung erhalten Sie, wenn Sie einen Einzelsteckplatz
+mit Kombi- oder E/A-Karte angeschlossen haben.
+
+Da beim Ausgabetest nur die Ausgänge einer Karte angesprochen werden, ist ein
+Ausgabetest an einer A/D-Wandler-Karte nicht möglich! An einer D/A-Wandler-Karte
+kann zwar prinzipiell ein Ausgabetest erfolgen - ist aber nicht sinnvoll, da die zur
+Kontrolle notwendige Leuchtdiodenanzeige hier nicht angeschlossen werden kann.
+
+Wenn Sie einen Mehrfachsteckplatz angeschlossen haben, werden Sie zuvor noch
+gefragt, welchen Steckplatz Sie testen wollen. Bitte beachten Sie hier das im vorigen
+Abschnitt Gesagte. Ansonsten ist auch hier die anschließende Einblendung nahezu
+identisch.
+
+Zum Testen geben Sie jetzt einige Werte zwischen 0 und 255 ein. Nach jeder Eingabe
+tippen Sie bitte die <RETURN>-Taste. Bei Eingabe der '0' müßten alle Leucht­
+dioden dunkel sein. Bei '1' dürfte nur die letzte Leuchtdiode (rechts) aufleuchten,
+bei 128 nur die erste (links); bei 255 müßten alle 8 Leuchtdioden der Anzeige auf­
+leuchten.
+#page#
+Sollten wider Erwarten Fehler aufgetreten sein, lesen Sie bitte im Kapitel 5.5 nach.
+Wenn alles wie beschrieben funktioniert hat, gehen Sie gleich zum Eingabetest über.
+Verlassen Sie dazu den Ausgabetest durch die Tastenfolge <ESC><q> und
+aktivieren Sie anschließend den Menupunkt 'Eingabetest' indem Sie z.B. die Taste
+<e> tippen.
+
+Außer bei der E/A-Karte im Einzelsteckplatz werden Sie hier zusätzlich nach der
+Nummer des Kanals gefragt, über den der Einlesetest erfolgen soll. Das liegt daran,
+daß sich auf den meisten Interfacesystemen mehrere Eingänge befinden. Beim
+Einzelsteckplatz werden die Auswahlmöglichkeiten vorgegeben; beim Mehrfachsteck­
+platz erfolgt eine freie Eingabe der Kanalnummern.
+
+Wenn Sie eine Compact-Box angeschlossen haben, müßte die folgende Einblendung
+in Ihrem Menubildschirm erscheinen:
+
+ +-------------------------------------------------------------+
+ | Eingabetest |
+ | |
+ | Eingabe von Kanal 3 (= Digitaleingang der Compact-Box) |
+ | |
+ |-------------------------------------------------------------|
+ | |
+ | |
+ | Eingelesener Wert: 129 |
+ |-------------------------------------------------------------|
+ | |
+ +-------------------------------------------------------------+
+
+#center#Abb.19:  Eingabetest - Einblendung
+
+
+Wenn Sie den Codekartenleser am Digitaleingang angeschlossen haben und alles
+korrekt funktioniert, müßte als eingelesener Wert die Zahl 255 erscheinen. Legen Sie
+eine Lochkarte ein oder legen Sie einen Finger zwischen Beleuchtung und Licht­
+sensoren. Daraufhin müßte sich die Anzeige auf dem Bildschirm ändern. Nun
+können Sie versuchen, durch Abdecken der Sensoren die bei der Ausgabe schon
+angesprochenen Testwerte zu erhalten.
+#page#
+Wenn Sie über keinen Codekartenleser verfügen, so benutzen Sie jetzt bitte das kleine
+Kabelstück, das Sie auf den +5V-Lötschuh aufgesteckt haben und dessen anderes
+Ende bisher noch nirgendwo aufgesteckt ist. Berühren Sie nun mit diesem freien
+Ende die Stifte, die im 8poligen Eingangs-Platinenstecker sichbar sind. Wird kein Pin
+berührt, müßte auf dem Bildschirm der Wert '0' erscheinen. Berühren Sie einen der
+Pins an der Seite, müßte der Wert '1', berühren Sie den an der anderen Seite, müßte
+der Wert '128' erscheinen. Wenn Sie also nacheinander die Pins berühren, müßten
+die Zahlenwerte 1, 2, 4, 8, 16, 32, 64, 128 erscheinen.
+
+Wenn sowohl Ausgabe- als auch Eingabetest korrekt abgewickelt werden konnten,
+brauchen Sie das Kapitel 5.5 nicht zu lesen, denn das beschäftigt sich nur mit
+Fehlern, die bisher aufgetreten sein könnten. Den Eingabetest verlassen Sie bitte
+durch die Tastenfolge <ESC><q>.
+
+
+#on("b")#5.5  Mögliche Fehlerfälle#off("b")#
+
+#on("b")#
+- Das MUFI wurde in den Terminalkanal eingebaut. Selbst beim vom Netz
+ getrennten MUFI ist kein Terminalbetrieb möglich:
+#off("b")#
+
+ --> Das neu eingefügte Kabel ist unzureichend oder falsch verdrahtet. Bitte
+ Hinweise im MUFI-Handbuch lesen bzw. Informationen von BICOS ein­
+ holen.
+
+
+#on("b")#
+- Das MUFI wurde in den Terminalkanal eingebaut. Beim Einschalten des
+ MUFIs erscheinen unsinnige Zeichenketten auf dem Bildschirm bzw. das
+ Einschalten hat noch schwerwiegendere Folgen: #off("b")#
+
+ --> Der "Einschaltknack" des MUFI "schlägt auf andere Systemkomponenten
+ durch". Sofern nur Zeichen auf dem Bildscchirm erscheinen, ist das weit­
+ gehend unproblematisch - kann auch nicht beseitigt werden. Ansonsten
+ erst das MUFI, dann das Terminal bzw. den Rechner einschalten. Ggf.
+ Rücksprache mit BICOS.
+#page#
+#on("b")#
+- Das MUFI wurde in den Terminalkanal eingebaut. Bei ausgeschaltetem
+ MUFI ist ein einwandfreier Terminalbetrieb möglich, bei einge­
+ schaltetem MUFI reagiert das Terminal nicht mehr:
+#off("b")#
+
+ --> MUFI- und Terminalkonfiguration passen nicht zueinander (Baudrate,
+ Protokoll, Anzahl der Stopbits). Einstellungen am Terminal, in der Task
+ 'configurator' und die DIP-Schalter-Stellung im MUFI kontrollieren; ggf.
+ Neueinstellung.
+
+ --> MUFI defekt - Rücksprache mit BICOS.
+
+
+#on("b")#
+- Beim Austest erscheint die Einblendung "Interface ist noch nicht
+ konfiguriert!":
+#off("b")#
+
+ --> #on("b")#gs-Prozess#off("b")# wurde noch nicht konfiguriert. Unter dem Oberbegriff 'Inter­
+ face' den Menupunkt 'Konfigurieren' aktivieren und den Ausführungen in
+ Kapitel 5.3 folgend die Konfiguration vornehmen.
+
+ --> Bei Betrieb des Interface Systems an separater serieller Schnittstelle werden
+ unbenannte Sohntasks eingerichtet (unter der eigenen Task bzw. unter
+ einer "zentralen Abwicklungstask"). Diese unbenannte Sohntask wurde
+ irrtümlich gelöscht. Abhilfe: Neukonfiguration vornehmen. #on("b")#*)#off("b")#
+
+ --> Bei Betrieb des Interface-Systems an separater serieller Schnittstelle und
+ "zentraler Abwicklungstask" wurde in der "zentralen Abwicklungs-Task"
+ eine Neukonfiguration von #on("b")#gs-Prozess#off("b")# vorgenommen. Die dabei ent­
+ standene unbenannte Sohntask wird von den "alten" Sohntasks nicht mehr
+ erkannt. Abhilfe: Alle Sohntasks, die auf die "zentrale Abwicklungstask"
+ zugreifen, löschen und neu einrichten. #on("b")#*)#off("b")#
+#page#
+#on("b")#
+- Es erscheint die Fehlermeldung "Interface meldet sich nicht!":
+#off("b")#
+
+ --> Der angeschlossene Adapter ist ohne Spannungsversorgung. Netzstecker
+ des Adapters überprüfen. Beim MUFI den Schalter an der Vorderseite in
+ Stellung 'Ein' bringen. Beim RS232-Adapter den 3poligen Platinenstecker
+ in die 12V-Spannungsversorgungsbuchse am Interface-System einstecken.
+
+ --> Es wurde bei der Installation von #on("b")#gs-Prozess#off("b")# eine falsche Interface-
+ Kanal-Nummer angegeben. Die Kanalnummer kann mit 'put(interface­
+ kanal) <RETURN>' erfragt werden. Kanalnummer überprüfen. Ggf. neue
+ Kanalnummer angeben. Dafür steht die Prozedur 'PROC interfacekanal
+ (INT CONST nummer)' zur Verfügung.
+
+ --> Speziell beim MUFI: Das MUFI wurde zwischenzeitlich (versehentlich)
+ ausgeschaltet oder es kam zu einem "ungeregeltem Bedienungsabbruch"
+ z.B. durch Drücken der SV-Taste im laufenden Betrieb. Die interne Ein­
+ stellung des MUFIs ist verändert. Abhilfe: Menupunkt verlassen, MUFI
+ ausschalten, einige Sekunden warten, MUFI anschalten, Menupunkt neu
+ anwählen.
+
+
+#on("b")#
+- Es erscheint die Fehlermeldung "Interface-Kanal ist belegt!:
+#off("b")#
+
+ --> Das Interface-System ist an einer separaten seriellen Schnittstelle ange­
+ schlossen. Am Kanal wurden schon andere Geräte betrieben, die nicht
+ ordentlich abgemeldet wurden. Mit 'taskinfo (2) <RETURN>' kann die
+ Belegung der Kanäle eingesehen werden. Ggf. erst ein Terminal an den
+ Kanal anschließen (Kanal umkonfigurieren!) und dort 'break
+ <RETURN>' geben. Oder von einer privilegierten Task aus die ange­
+ koppelte Task "abschießen".
+
+ --> Das Interface-System ist an einer separaten seriellen Schnittstelle ange­
+ schlossen. Eine andere Task greift bereits auf das Interface-System am
+ eingestellten Kanal zu. Benutzer bitten, den Kanal freizugeben. #on("b")#*)#off("b")#
+#page#
+#on("b")#
+- Es erscheint die Fehlermeldung "Interface-Task ist besetzt!":
+#off("b")#
+
+ --> Das Interface-System ist an einer separaten seriellen Schnittstelle ange­
+ schlossen. Die Kommunikation erfolgt über eine "zentrale Abwicklungs­
+ task". Auf diese Task greift zur Zeit ein anderer Benutzer zu. Mit dem
+ anderen Benutzer verständigen und warten, bis die Task freigegeben wird.
+ #on("b")#*)#off("b")#
+
+
+#on("b")#
+- Es erschient die Fehlermeldung "An Kanal ... ist keine Digitaleingabe
+ (Digiatalausgabe, Analogeingabe, Analogausgabe) möglich!":
+#off("b")#
+
+ --> Laut Konfiguration ist die gewünschte Leistung am angegebenen Kanal auf
+ der angeschlossenen Interfacekarte nicht möglich. Kanal neu konfigurieren
+ oder anderen Kanal ansprechen bzw. Interface-Karte wechseln und neu
+ konfigurieren.
+
+
+#on("b")#
+- Es erschient die Fehlermeldung "Kanalnummer ... ist unzulässig!":
+#off("b")#
+
+ --> Es wurde eine - bezogen auf das angeschlossene Interface-System - un­
+ sinnige Kanalnummer angegeben. Diese Fehlermeldung erscheint in jedem
+ Falle, wenn die Kanalnummer kleiner als 1 oder größer als 49 ist! Abhilfe:
+ korrekte Kanalnummer angeben.
+
+
+#on("b")#
+- Es erschient die Fehlermeldung "Interface kann nicht geöffnet werden!":
+#off("b")#
+
+ --> Interessanter Fehler! Bitte alle Details der Fehlersituation notieren und an
+ ERGOS einsenden!
+#page#
+#on("b")#
+- Beim Austest erscheint zwar keine Fehlermeldung, aber die Leucht­
+ diodenanzeige zeigt auf verschiedene Ausgabewerte keine Reaktion
+ (bleibt dunkel oder unsinnige fixe Anzeige):
+#off("b")#
+
+ --> Die angeschlossene Leuchtdiodenanzeige ist nicht korrekt angeschlossen.
+ Platinenstecker (Digitalausgang) überprüfen; Massekabel überprüfen; die
+ beiden Überbrückungskabel (Abb.7) überprüfen.
+
+ --> Steckplatz/Compact-Box wird nicht mit Spannung versorgt. Netzkabel/An­
+ schluß zum Netzteil überprüfen.
+
+ --> Verbindungskabel Adapter - Interface-System nicht richtig aufgesteckt oder
+ intern falsch verdrahtet.
+
+
+#on("b")#
+- Beim Austest erscheinen verschiedene Ausgabemuster an den Leucht­
+ dioden, die Muster sind aber nicht korrekt:
+#off("b")#
+
+ --> Kabel vom Adapter zum Interface ist falsch verdrahtet.
+
+ --> Kabel in der Leuchtdiodenanzeige (Selbstbau ?) sind falsch verdrahtet.
+
+
+#on("b")#*)#off("b")# Die hier genannten Fehlermeldungen sind bei der oben beschriebenen Erst­
+ installation (noch) nicht möglich. Sie können erst auftreten, wenn weiter­
+ gehende Installationen erfolgt sind (z.B. Installation einer "zentralen Abwick­
+ lungs-Task" etc.). Zum Verständnis lesen Sie bitte das Kapitel "Hinweise für den
+ Systembetreuer/Programmierer".
+
+
+
+
+
+
+
+
diff --git a/doc/prozess/gs-prozess-6 b/doc/prozess/gs-prozess-6
new file mode 100644
index 0000000..a3835cd
--- /dev/null
+++ b/doc/prozess/gs-prozess-6
@@ -0,0 +1,641 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#on("b")#6  Arbeiten mit gs-Prozess#off("b")#
+
+In diesem Kapitel werden wir Ihnen die Basisbefehle von #on("b")#gs-Prozess#off("b")# vorstellen und
+erläutern, was die einzelnen Befehle bewirken. Dabei werden wir an einfachen
+Beispielen aufzeigen, wie Sie mit #on("b")#gs-Prozess#off("b")# arbeiten können.
+
+Wir gehen hier davon aus, daß die Hardware-Voraussetzungen erfüllt, das Interface-
+System angeschlossen und die Software (#on("b")#gs-Prozess#off("b")#) auf dem Rechner installiert
+sind. Sie sollten #on("b")#gs-Prozess#off("b")# bereits konfiguriert und einen Ein- und Ausgabetest
+durchgeführt haben.
+
+In unserer Beschreibung gehen wir weiterhin davon aus, daß als Interface-System
+eine Compact-Box verwendet wird. Alle hier beschriebenen Beispiele gelten ganz
+genauso für einen Einzelsteckplatz mit Kombikarte (hier müssen Sie nur zusätzlich
+eine Leuchtdiodenanzeige anschließen - aber Sie wissen ja schon, wie das gemacht
+wird.) Bei anderen Hardware-Konfigurationen ist darauf zu achten, daß ggf. andere
+Kanalnummern anzugeben sind.
+
+Die Compact-Box verfügt - genau wie die Kombikarte - über zwei analoge Eingänge
+(Kanal 1 und Kanal 2), über einen digitalen Eingang (Kanal 3) sowie über einen
+digitalen Ausgang (Kanal 4). Wie Sie schon bei der Konfiguration von #on("b")#gs-Prozess#off("b")#
+gesehen haben, haben Sie keinen Einfluß auf die Numerierung der Kanäle - die wird
+vom #on("b")#gs-Prozess#off("b")# vorgegeben. Diese Kanalnummer müssen Sie kennen, wenn Sie das
+System ansprechen (programmieren) wollen (ggf. können Sie die Kanalnummern
+durch Aktivieren des Menupunktes 'Information' unter dem Oberbegriff 'Interface'
+erfragen).
+
+
+#on("b")#6.1  Kleine Beispiele zur digitalen Ausgabe#off("b")#
+
+Bei diesem Einführungsbeispiel wollen wir uns zunächst ausschließlich auf die
+digitale Ausgabe beschränken. Wenn Sie die Compact-Box (oder eine E/A-Karte)
+angeschlossen haben, benötigen Sie hierzu keine zusätzliche Hardware, ansonsten
+schließen Sie bitte an Ihren digitalen Ausgang eine 8-elementige Leuchtdiodenanzeige
+an.
+#page#
+Sie haben sicher schon an einer Autobahnbaustelle ein sogenanntes "Lauflicht"
+gesehen. Es erscheint, als ob ein Licht über die aufgestellten Barken hinwegläuft.
+Dadurch soll auf die Baustellenein- bzw. -ausfahrt hingewiesen werden. Dieser Effekt
+wird dadurch erreicht, daß die Lampen, die an den Barken angebracht sind, nach­
+einander ein- und auch wieder ausgeschaltet werden.
+
+Wir wollen jetzt auf unserer 8-elementigen Leuchtdiodenanzeige ein solches Lauflicht
+nachbilden. Dabei soll das "Licht von rechts nach links über die Anzeige wandern".
+
+Um das Programm zu schreiben, aktivieren Sie im #on("b")#gs-Prozess#off("b")#-Menu unter dem
+Oberbegriff "Programm" den Menupunkt "Neu erstellen". Sie werden dann nach
+einem Namen gefragt, den Sie der Programmdatei geben wollen. Tragen Sie hier
+einen beliebigen Namen ein, und tippen Sie anschließend die <RETURN>-Taste.
+Notieren Sie dann das folgende ELAN-Programm:
+
+#on("b")#
+ initialisiere interface;
+ REP
+ lauflichtdurchgang;
+ warte (2.0)
+ UNTIL abbruch gewuenscht PER.
+
+ lauflichtdurchgang:
+ bitmuster ausgeben (4, "OOOOOOOI");
+ bitmuster ausgeben (4, "OOOOOOIO");
+ bitmuster ausgeben (4, "OOOOOIOO");
+ bitmuster ausgeben (4, "OOOOIOOO");
+ bitmuster ausgeben (4, "OOOIOOOO");
+ bitmuster ausgeben (4, "OOIOOOOO");
+ bitmuster ausgeben (4, "OIOOOOOO");
+ bitmuster ausgeben (4, "IOOOOOOO")
+#off("b")#
+
+
+Wenn Sie das Programm fertiggeschrieben haben, verlassen Sie die Datei durch die
+Tastenfolge <ESC><q>. Sie gelangen wieder zum Menu und aktivieren jetzt den
+Menupunkt "Starten". Daraufhin wird das Programm übersetzt und ausgeführt.
+#page#
+#on("b")#6.1.1  Möglichkeit eines Programmabbruchs#off("b")#
+
+Wir hoffen natürlich, daß das Programm genau die Ausgabe an der Leuchtdioden­
+anzeige erzeugt, die Sie erwartet haben.
+
+Als Ausgangsbedingung der Schleife haben wir den Testbefehl 'abbruch gewuenscht'
+verwendet. Dieser Befehl wird von #on("b")#gs-Prozess#off("b")# zur Verfügung gestellt. Durch den
+Testbefehl wird überprüft, ab zwischenzeitlich die Tastenkombination <ESC><q>
+eingegeben wurde. Ist das bei unserem Programm der Fall, so wird die Schleife
+('regulär') beendet.
+
+Aber bitte etwas Geduld: Das Programm wird nicht sofort nach Eingabe der Tasten­
+folge "abgebrochen". Hat nämlich gerade ein neuer 'lauflichtdurchgang' begonnen,
+so wird das Refinement natürlich erst vollständig abgearbeitet. Erst dann wird
+geprüft, ob die Tastenfolge zwischenzeitlich eingegeben wurde.
+
+Sollten Sie einmal in einer Situation sein, in der Sie ein Programm tatsächlich
+abbrechen müssen, so ist das (in den meisten Fällen) über die Tastenfolge
+<ESC><h> möglich. Diese Tastenkombination sollten Sie sich für "Notfälle"
+merken. Vielleicht probieren Sie sie gleich an unserem Beispiel aus.
+
+
+#on("b")#6.1.2  Die "sonstigen" Befehle#off("b")#
+
+Gehen wir zunächst auf die beiden Befehle 'initialisiere interface' und 'warte' sowie
+auf den Testbefehl 'abbruch gewuenscht ein:
+
+#on("b")#
+PROC initialisiere interface
+#off("b")#
+
+ Jedes Programm zur Prozeßdatenverarbeitung, das auf das Interface-System
+ zugreift, sollte mit diesem Befehl beginnen. Durch diesen Befehl wird das System
+ in einen definierten Anfangszustand versetzt; systeminterne Variablen werden
+ initialisiert, so daß vom Programm aus darauf zugegriffen werden kann.
+#page#
+#on("b")#
+PROC warte (REAL CONST wert)
+PROC warte (INT CONST wert)
+#off("b")#
+
+ Der Befehl 'warte' ähnelt dem Ihnen sicher bekannten Befehl 'pause'. Allerdings
+ wird hier als Parameter (INT oder REAL) die Wartezeit in Sekunden angegeben -
+ bei 'pause' dagegen die Anzahl der Zehntelsekunden. Der eigentliche Unterschied
+ besteht aber darin, daß 'warte' im Gegensatz zu 'pause' ein "Nothalt" - d.h. die
+ Tastenkombination <ESC><h>, die wir im vorigen Kapitel beschrieben haben
+ - registriert. Aus diesem Grunde sollte in Prozeßdatenverarbeitungsprogrammen
+ mit 'warte' statt mit 'pause' gearbeitet werden.
+
+
+#on("b")#
+BOOL PROC abbruch gewuenscht
+#off("b")#
+
+ Die Prozedur liefert den Wert 'TRUE', wenn zwischenzeitlich die Tasten­
+ kombination <ESC><q> eingegeben wurde, sonst den Wert 'FALSE'.
+
+
+#on("b")#6.1.3  Schreibweise für Bitmuster/Bitsymbole#off("b")#
+
+Beim Befehl 'bitmuster ausgeben', wird eine Zeichenkette, die aus 8 Zeichen besteht,
+übergeben - das sog. Bitmsuster. In unserem Falle kommen hier nur die Zeichen 'I'
+und 'O' vor. Ihnen ist sicher die Bedeutung sofort klar gewesen:
+
+ 'I' bedeutet, daß an der entsprechenden Position ein High-Pegel (5V) angelegt
+ werden soll; 'O' bedeutet, daß an der entsprechenden Position ein Low-
+ Pegel (0V) angelegt werden soll.
+
+So werden über den ersten Befehl im Refinement 'lauflichtdurchgang' alle Leucht­
+dioden ausgeschaltet, nur die Leuchtdiode ganz rechts wird angeschaltet. Über den
+zweiten Befehl wird diese wieder ausgeschaltet und dafür aber die zweite von rechts
+eingeschaltet usw.
+#page#
+Neben den Zeichen 'I' und 'O' dürfen auch die Zeichen 'X' und 'T' in der über­
+gebenen Zeichenkette auftauchen. Um die Bedeutung zu verstehen, muß man
+wissen, daß #on("b")#gs-Prozess#off("b")# den jeweils letzten Zustand des digitalen Ausgangs speichert
+(durch 'initialisiere interface' werden alle Ausgänge auf 'O' gesetzt).
+
+ 'X' bedeutet, daß an der entsprechenden Position der zuletzt dagewesene
+ Zustand erhalten bleibt, d.h. durch diese Ausgabe nicht beeinflußt wird.
+
+ 'T' bedeutet, daß an der entsprechenden Position der zuletzt dagewesene
+ Zustand "umgekehrt" wird. Lag zuletzt ein Low-Pegel (O) an, so wird
+ daraus ein High-Pegel (I) und umgekehrt.
+
+Sie können sich nun sicher sofort erklären, was das folgende Programm bewirkt:
+
+
+#on("b")#
+ initialisiere interface;
+ bitmuster ausgeben (4, "OIOIOIOI");
+ REP
+ bitmuster ausgeben (4, "TTTTTTTT");
+ warte (1)
+ UNTIL abbruch gewuenscht PER
+#off("b")#
+
+
+Durch den ersten Befehl 'bitmuster ausgeben' wird jede zweite Leuchtdiode ange­
+schaltet, die anderen werden ausgeschaltet. Durch den zweiten Befehl in der Schleife
+wird nun jeweils jeder Zustand in "das Gegenteil umgekehrt", so daß ein Blinklicht
+entsteht, bei dem abwechselnd einmal die einen vier, dann die anderen vier Leucht­
+dioden aufleuchten - und das jeweils für eine Sekunde.
+
+
+#on("b")#6.1.4  Befehle für die digitale Ausgabe#off("b")#
+
+Einen Befehl, mit dem der digitale Ausgang des Interfaces angesprochen werden
+kann, haben Sie schon in Kapitel 6.1 kennengelernt:
+#page#
+#on("b")#
+PROC bitmuster ausgeben (INT CONST kanal,
+ TEXT CONST zeichenkette)
+#off("b")#
+
+Über den ersten Parameter wird der Kanal angegeben, über den der digitale Ausgang
+angesprochen werden kann; bei uns ist das der Kanal 4 auf der Compact-Box. Über
+den zweiten Parameter wird das sogenannte Bitmuster übergeben; ein Text, der aus
+genau 8 Zeichen besteht. Dabei dürfen die Zeichen "I, O, X und T verwendet werden
+(sehen Sie dazu auch Kapitel 6.1.3).
+
+#on("b")#gs-Prozess#off("b")# stellt noch zwei weitere Befehle für die digitale Ausgabe zur Verfügung.
+Um die Wirkungsweise der Befehle zu verdeutlichen, hier das erste Beispiel (das
+Lauflicht) in einer zweiten Version:
+
+#on("b")#
+ initialisiere interface;
+ REP
+ lauflichtdurchgang;
+ warte (2.0)
+ UNTIL abbruch gewuenscht PER.
+
+ lauflichtdurchgang:
+ INT VAR zeiger;
+ FOR zeiger FROM 0 UPTO 7 REP
+ schalte aktuelle leichtdiode an;
+ schalte vorgaenger aus
+ PER.
+
+ schalte aktuelle leuchtdiode an:
+ bitsymbol ausgeben (4, zeiger, "I").
+
+ schalte vorgaenger aus:
+ IF zeiger = 0
+ THEN bitsymbol ausgeben (4, 7, "O")
+ ELSE bitsymbol ausgeben (4, zeiger - 1, "O")
+ FI.
+#off("b")#
+
+#on("b")#
+PROC bitsymbol ausgeben (INT CONST kanal, bitnummer,
+ TEXT CONST zeichen)
+#off("b")#
+#page#
+Während durch den Befehl 'bitmuster ausgeben' auf alle 8 Ausgänge gleichzeitig
+Einfluß genommen werden kann, wird mit dem Befehl 'bitsymbol ausgeben' gezielt
+nur genau einer der 8 Ausgänge, d.h. eines der 8 Bits manipuliert. Welcher Ausgang /
+welches Bit manipuliert werden soll, wird über den zweiten Parameter festgelegt: hier
+kann einer der Werte 0...7 angegeben werden (Beachten Sie die Numerierung der
+Ausgänge (!)).
+
+Als dritter Parameter wird ein Text übergeben, der aus genau einem Zeichen
+bestehen muß. Ebenso wie beim Befehl 'bitmuster ausgeben' sind hier die Zeichen I,
+O, X und T zulässig. Sie haben hier auch die gleiche Bedeutung.
+
+Mit dem dritten Ausgabebefehl für den digitalen Ausgang können wir das Beispiel
+noch in einer dritten Version notieren:
+
+#on("b")#
+ initialisiere interface;
+ REP
+ lauflichtdurchgang;
+ warte (2.0)
+ UNTIL abbruch gewuenscht PER.
+
+ lauflichtdurchgang:
+ INT VAR wert :: 1;
+ REP
+ dezimalwert ausgeben (4, wert);
+ wert := 2 * wert
+ UNTIL wert > 128 PER.
+#off("b")#
+
+#on("b")#
+PROC dezimalwert ausgeben (INT CONST kanal, wert)
+#off("b")#
+
+'wert' kann Werte zwischen 0 und 255 annehmen. Das zugehörige Bitmuster wird
+dann am angegebenen Kanal ausgegeben. Anhand dieses Befehls wird Ihnen sicher
+auch klar, warum gerade die oben beschriebene Numerierung der Bits gewählt
+wurde.
+#page#
+#on("b")#6.1.5  Befehle für die analoge Ausgabe#off("b")#
+
+Neben der 'digitalen' Ausgabe ist auch eine 'analoge' Ausgabe möglich. Allerdings
+wollen wir die Beschreibung der Befehle an dieser Stelle sehr kurz halten, denn eine
+"analoge" Ausgabe ist nur möglich, wenn Sie eine D/A-Karte besitzen.
+
+Auf der D/A-Karte steht nur ein physikalischer Ausgabekanal zur Verfügung, der von
+#on("b")#gs-Prozess#off("b")# jedoch über zwei Kanalnummern angesprochen werden kann.
+
+Über den Ausgabekanal 1 können Spannungswerte zwischen -5V und +5V aus­
+gegeben werden, über den Ausgabekanal 2 Spannungswerte zwischen 0V und +5V.
+
+Dafür stellt #on("b")#gs-Prozess#off("b")# zwei Befehle bereit:
+
+#on("b")#
+PROC spannungswert ausgeben (INT CONST kanal,
+ REAL CONST wert)
+#off("b")#
+
+'wert' kann, in Abhängigkeit vom angegebenen Kanal, Werte zwischen -5.0 und +5.0
+(bei Kanal 1) bzw. 0.0 und +5.0 (bei Kanal 2) annehmen. Bei dem Versuch, Werte
+außerhalb dieser Grenzen anzugeben, erhalten Sie die Fehlermeldung "Der
+Spannungswert ... ist nicht zulässig!".
+
+
+#on("b")#
+PROC wert an analogausgang ausgeben (INT CONST kanal, wert)
+#off("b")#
+
+Für 'wert' kann eine Zahl zwischen 0 und 255 angegeben werden. Dabei wird 0 auf
+den kleinstmöglichen Spannungswert am jeweilgen Kanal (bei Kanal 1 also auf -5V,
+bei Kanal 2 auf 0V) und 255 auf den größtmöglichen Spannungswert am jeweilgen
+Kanal (bei beiden Kanälen auf +5V) abgebildet. Das Intervall zwischen kleinst- und
+größtmöglichem Spannungswert wird in 255 gleichgroße Teilintervalle eingeteilt. Es
+wird nun die Spannung ausgegeben, die der Intervallnummer entspricht.
+Anmerkung: Dieser Befehl hat nur einen "geringen praktischen Nutzwert"; er dient
+ vornehmlich dazu, den Wandlungsprozeß zu verdeutlichen.
+#page#
+#on("b")#6.2  Kleine Beispiele zur digitalen Eingabe#off("b")#
+
+Für die im folgenden beschriebenen kleinen Beispiele benötigen Sie einen Code­
+kartenleser und einige Codekarten (können auch von der Fa. AKTRONIK bezogen
+werden). Der Anschluß des Codekartenlesers an Ihr Interface-System ist denkbar
+einfach. Stecken Sie den 8poligen Platinenstecker des Codekartenlesers in die Buchse
+des Digitaleinganges der Steckkarte bzw. der Compact-Box und den 3poligen
+Platinenstecker in die passende Spannungsversorgungsbuchse (12V) am Steckplatz
+bzw. auf der Compact-Box - fertig! Bei eingeschalteter Betriebsspannung müßte nun
+der Codekartenleser beleuchtet sein.
+
+Auf den Lochkarten sind bis zu 8 Löcher eingestanzt. Dabei können bestimmte
+Löcher (Bits) für die Erfassung definierter Merkmale verwendet werden. Dazu kann
+eine Karte in bestimmte Bereiche aufgeteilt werden.
+
+In unserem kleinen Beispiel stellen wir uns vor, daß eine (Modell-)Sparkasse zwei
+Filialen hat. Sie hat an Ihre "Kunden" Codekarten verteilt. Die Filialen sind durch
+Farben gekennzeichnet. Die oberen (höchstwertigen) zwei Bits der Karte sollen diese
+Farbe kodiert enthalten, damit auch der "Sparkassen-Computer" die Farbe schnell
+ermitteln kann. Die Karte soll folgenden Aufbau haben:
+
+ +---------------------------------+
+ | O o o O o o O |
+ | | |
+ | Farbbits| Kundennummer |
+ | | |
+ | | |
+ | | |
+ | |
+ +---------------------------------+
+
+
+#center#Abb.20 Beispiellochkarte
+#page#
+Bit 7 sei für rote, Bit 6 für grüne Farbe gesetzt, d.h. gelocht. Wie wollen jetzt ein
+Programm erstellen, das auf Eingabe einer Karte deren Farbe und den durch die
+ersten 6 Bits bestimmten Wert (Kundennummer) ausgibt:
+
+#on("b")#
+ initialisiere interface;
+ REP
+ erfasse lochkarte
+ UNTIL abbruch gewuenscht PER.
+
+ erfasse lochkarte:
+ warte bis karte im leser;
+ gib farbe aus;
+ gib kundennummer aus;
+ warte bis keine karte im leser.
+
+ warte bis karte im leser:
+ put ("Bitte eine Codekarte einlegen!"); line;
+ WHILE NOT alles abgedunkelt REP
+ tue nichts
+ END REP;
+ WHILE alles abgedunkelt REP
+ tue nichts
+ END REP;
+ warte (1).
+
+ warte bis keine karte im leser:
+ put ("Bitte die Karte entnehmen!");
+ REP
+ tue nichts
+ UNTIL alles beleuchtet PER.
+
+ alles abgedunkelt:
+ bitmuster (3) = "OOOOOOOO".
+
+ alles beleuchtet:
+ bitmuster (3) = "IIIIIIII".
+
+ gib farbe aus:
+ IF bitsymbol (3, 7) = "I"
+ THEN put ("rote Karte"); line
+ ELSE put ("grüne Karte");line
+ FI;
+#page#
+ gib kundennummer aus:
+ INT VAR kundennummer :: 0, bitnummer;
+ FOR bitnummer FROM 0 UPTO 5 REP
+ registriere gesetztes bit
+ PER;
+ put ("Kundennummer:"); put (kundennummer): line.
+
+ registriere gesetztes bit:
+ IF bit ist gesetzt (3, bitnummer)
+ THEN kundennummer INCR (2 ** bitnummer)
+ FI.
+
+
+#off("b")#
+ (Hinweis: Es handelt sich hier um ein Beispielprogramm, an dem diverse
+ Befehle erläutert werden sollen - die Programmierung ist nicht
+ optimal! Im Refinement 'warte bis karte im leser' ist es z.B.
+ günstiger, solange einzulesen, bis der eingelesene Wert "stabil" ist.
+ Auch das Refinement 'registriere gesetztes bit' würde man so nicht
+ programmieren, sondern nach einem Einlesevorgang (Bitmuster)
+ über Textoperationen aus dem Bitmuster die 'kundennummer'
+ ermitteln...).
+
+Bevor wir Ihnen die Funktionsweise der von #on("b")#gs-Prozess#off("b")# bereitgestellten Prozeduren
+im Detail erläutern, möchten wir Ihnen noch ein paar kurze Erläuterungen zum
+obigen Programm geben.
+
+Besondere Aufmerksamkeit sollten Sie den Refinements 'warte bis karte im leser' und
+'warte bis keine karte im leser' schenken. Im erstgenannten Refinement ist sicherzu­
+stellen, daß das Einschieben der Karte (erst muß alles abgedunkelt werden - dann
+müssen einige Positionen beleuchtet sein) registriert wird. Um Fehlauswertungen der
+Karte zu vermeiden (z.B. beim Verkanten einer Karte) wird zur Sicherheit vor der
+Auswertung eine Sekunde gewartet. Am Ende des Lesevorgangs soll sichergestellt
+werden, daß die Karte auch entnommen worden ist (alle Positionen wieder beleuchtet
+sind).
+#page#
+Wir prüfen im Refinement 'gib farbe aus' nur das 7. Bit (sehen Sie die Erklärung zu
+'bitsymbol'). Ist das Bit gesetzt (die Karte hier gelocht), so identifizieren wir die Farbe
+Rot, sonst Grün. Natürlich ist es möglich, mit 2 "Farbbits" vier Farben zu ver­
+schlüsseln: z.B. Rot, wenn nur Bit 7 gesetzt ist; Grün, wenn nur Bit 6 gesetzt ist; Blau,
+wenn Bit 7 und Bit 6 gesetzt sind; Gelb, wenn weder Bit 7 noch Bit 6 gesetzt sind.
+Dadurch wird der Auswertalgorithmus aber etwas aufwendiger. Vielleicht probieren
+Sie es nacher einmal.
+
+Die Prozedur 'tue nichts' wird schon von #on("b")#gs-Prozess#off("b")# bereitgestellt. Es wird keine
+Aktion ausgeführt - jedoch überprüft, ob zwischenzeitlich die Tastenfolge
+<ESC><h> ("Notbremse") eingegeben wurde. Es empfiehlt sich, diese Prozedur
+gerade in Schleifenrümpfen einzusetzten, damit die Möglichkeit besteht, bei einer
+"Endlosschleife" einen Abbruch herbeizuführen (sonst "hängt" die Task ggf. am
+Interfacekanal)!
+
+
+#on("b")#6.2.1  Befehle für die digitale Eingabe#off("b")#
+
+In Kapitel 6.1.4 haben Sie die Befehle für die digitale Ausgabe kennengelernt, die
+Ihnen #on("b")#gs-Prozess#off("b")# zur Verfügung stellt. Zu jedem dieser drei Befehle gibt es das
+"Gegenstück" auch als Eingabebefehl. Alle Eingabebefehle sind als werteliefernde
+Prozeduren (Funktionen) ausgelegt.
+
+In den Refinements 'alles abgedunkelt' und 'alles beleuchtet' benutzen wir den
+Befehl:
+
+#on("b")#
+TEXT PROC bitmuster (INT CONST kanal)
+#off("b")#
+
+Über den Parameter wird der Kanal angegeben, über den der digitale Eingang ange­
+sprochen werden kann; bei uns ist das der Kanal 3 auf der Compact-Box. Die
+Prozedur liefert einen Text, der aus acht Zeichen besteht. Dabei können nur die
+Zeichen "I und "O" auftreten (sehen Sie dazu auch Kapitel 6.1.3).
+#page#
+Die beiden gerade genannten Refinements hätten aber auch so notiert werden
+können:
+
+#on("b")#
+ alles abgedunkelt:
+ dezimalwert (3) = 0.
+
+ alles beleuchtet:
+ dezimalwert (3) = 255.
+#off("b")#
+
+#on("b")#
+INT PROC dezimalwert (INT CONST kanal)
+#off("b")#
+
+Über den Parameter wird der Kanal angegeben, über den der digitale Eingang ange­
+sprochen werden kann; bei uns ist das wieder der Kanal 3 auf der Compact-Box. Die
+Prozedur liefert einen Integer-Wert zwischen 0 und 255 (sehen Sie dazu auch unter
+'dezimalwert ausgeben' im Kapitel 6.1.4).
+
+Den dritten Eingabebefehl für den Digitaleingang, den #on("b")#gs-Prozess#off("b")# bereitstellt, finden
+Sie im Refinement 'gib farbe aus':
+
+#on("b")#
+TEXT PROC bitsymbol (INT CONST kanal, bitnummer)
+#off("b")#
+
+Wie schon bei den anderen beiden Eingabebefehlen wird hier über den ersten
+Parameter der Eingabekanal festgelegt; bei uns auf der Compact-Box ist das wieder
+der Kanal 3. Über den zweiten Parameter wird die Nummer des Bits angegeben,
+dessen Wert ermittelt werden soll. Ist das betreffende Bit gesetzt, so liefert die
+Prozedur das Zeichen "I", sonst das Zeichen "O" (sehen Sie dazu auch das Kapitel
+6.1.3 'Schreibweise für Bitmuster/Bitsymbole').
+
+
+#on("b")#6.2.2  Eingabetests#off("b")#
+
+Neben diesen drei Eingabebefehlen stellt #on("b")#gs-Prozess#off("b")# noch zwei Testbefehle zur
+Verfügung, die man häufig gut verwenden kann. Auf einen greifen wir schon im
+Refinement 'registriere gesetztes bit' zurück:
+#page#
+#on("b")#
+BOOL PROC bit ist gesetzt (INT CONST kanal, bitnummer)
+#off("b")#
+
+Die Parameter sind die gleichen wie beim Befehl 'bitsymbol'. Zunächst liest die
+Prozedur die aktuelle Einstellung am angegebenen Digitaleingang ('kanal') ein und
+untersucht dann das Bit mit der angegebenen Bitnummer (0, ..., 7). Die Prozedur
+liefert den Wert 'TRUE', wenn das Bit mit der entsprechenden Bitnummer gesetzt ist
+(die Prozedur bitsymbol' mit gleichen Parametern also den Wert "I" liefern würde),
+sonst 'FALSE' (die Prozedur bitsymbol' mit gleichen Parametern also den Wert "O"
+liefern würde).
+
+Den zweiten Testbefehl haben wir im obigen Programm noch nicht verwendet. Wir
+könnten damit aber auch die Refinements 'alles abgedunkelt' und 'alles beleuchtet'
+folgendermaßen notieren:
+
+#on("b")#
+ alles abgedunkelt:
+ bitmuster gleich (3, "OOOOOOOO").
+
+ alles beleuchtet:
+ bitmuster gleich (3, "IIIIIIII").
+#off("b")#
+
+
+#on("b")#
+BOOL PROC bitmuster gleich (INT CONST kanal,
+ TEXT CONST vorgabe)
+#off("b")#
+
+Wie bereits zuvor wird über den ersten Parameter der Kanal angegeben, über den der
+Digitaleingang angesprochen werden kann. Zunächst liest die Prozedur am ange­
+gebenen Kanal die aktuelle Einstellung ein und vergleicht es mit der 'vorgabe'. Der
+eigentliche Vorteil der Prozedur liegt darin, daß bei der Beschreibung der 'vorgabe'
+neben den Zeichen "I" und "O" auch das Zeichen "X" verwendet werden darf. z.B.
+"IOXXXXX". Entspricht das eingelesene Bitmuster der 'vorgabe', so liefert die Prozedur
+den Wert 'TRUE', sonst den Wert 'FALSE'. In gerade genannten Beispiel liefert die
+Prozedur also immer dann 'TRUE', wenn eine Karte mit der Markierung für Rot
+eingeschoben wurde - gleichgültig, welche Kundennummer eingestanzt ist.
+#page#
+#on("b")#6.2.3  Befehle für die analoge Eingabe#off("b")#
+
+Die analoge Eingabe möchten wir Ihnen an einem ganz einfachen Beispiel vor Augen
+führen. Sie brauchen dazu nur ein ganz normales Drehpotentiometer (ca. 5kOhm),
+das Sie in jedem Elektronik-Fachgeschäft für wenig Geld erhalten können. Ein
+solches Drehpotentiometer verfügt über drei Anschlüsse. Wenn man sich den inneren
+Aufbau vor Augen führt, ist die Belegung der drei Anschlüsse auch recht einsichtig.
+
+
+ siehe Physikbuch!!
+
+
+
+#on("b")##center#Abb.21 Aufbau eines Drehpotentiometers#off("b")#
+
+Löten Sie ggf. auf die drei Anschlüsse je einen Lötschuh, um eine einfache Steckver­
+bindung zur Kombikarte/Compact-Box herstellen zu können. Wichtig ist vor allem,
+daß der mittlere Anschluß am Drehpotentiometer auf den mittleren Stecksockel am
+Analogeingang auf der Kombikarte/Compact-Box aufgesteckt wird. Die beiden
+anderen Anschlüsse können können Sie beliebig auf die beiden dann noch freien
+Lötstifte (+ und �) des gleichen Analogeingangs aufstecken.
+
+Starten Sie dann das folgende Programm:
+
+#on("b")#
+ initialisiere interface;
+ page;
+ REP
+ notiere potentiometerwert
+ UNTIL abbruch gewuenscht PER.
+
+ notiere potentiometerwert:
+ put (wert von analogeingang (1));
+ line.
+#off("b")#
+#page#
+Nach dem Start des Programms müßten auf dem Bildschirm untereinander immer
+wieder die gleiche Zahl (ein Wert zwischen 0 und 255) auftauchen. Wenn Sie dann
+am Potentiometer drehen, müßten sich auch die Werte auf dem Bildschirm ändern.
+
+Sie hätten das Refinement 'notiere potentiometerwert' auch folgendermaßen notieren
+können:
+
+#on("b")#
+ notiere potentiometerwert:
+ put (spannungswert (1));
+ line.
+#off("b")#
+
+Statt Wert zwischen 0 und 255 zu erhalten, müßten Sie jetzt Werte zwischen 0.0 und
+5.0 erhalten.
+
+
+#on("b")#
+REAL PROC spannungswert (INT CONST kanal)
+#off("b")#
+
+Über den Parameter wird der Kanal angegeben, über den der analoge Eingang ange­
+sprochen werden kann; bei uns ist das der Kanal 1 (oder 2) auf der Kombikarte/
+Compact-Box. Auf der Kombikarte/Compact-Box können nur Spannungswerte
+zwischen 0.0V und 5.0V eingelesen werden. Auf der A/D-Karte kann der Bereich für
+die einzulesenden Sapnnungwerte durch die Schalterstellung auf der Karte eingestellt
+werden (Sehen Sie dazu auch Kapitel 5.3.1).
+
+
+#on("b")#
+REAL PROC wert von analogeingang (INT CONST kanal)
+#off("b")#
+
+Über den Parameter wird der Kanal angegeben, über den der analoge Eingang ange­
+sprochen werden kann; bei uns ist das der Kanal 1 (oder 2) auf der Kombikarte/
+Compact-Box. Geliefert werden Werte zwischen 0 und 255.
+
+Tatsächlich wird aber ein Spannungswert vom Analogeingang eingelesen. Dieser
+Spannungswert wird vom Analog-Digital-Wandler auf der Karte nach folgendem
+Verfahren gewandelt:
+#page#
+Dem größtmöglichen Spannungswert an diesem Eingang wird der Wert 255, dem
+kleinstmöglichen der Wert 0 zugeordnet. Das Intervall zwischen dem kleinst- und
+größtmöglichen Spannungswert wird in 255 gleichgroße Teilintervalle eingeteilt. Es
+wird nun die Nummer des Intervalls geliefert, in das die eingelesene Spannung fällt.
+Kleinst- und größtmögliche Spannungswerte sind abhängig von der aktuellen Steck­
+karte, Interface-Konfiguration).
+
+
+#on("b")#6.3  Hinweise auf Aufgabenmaterial#off("b")#
+
+Eine Fülle von Beispielanwendungen sind beschrieben in:
+
+ Landesinstitut für Schule und Weiterbildung (Hrsg.), Materialien zur Lehrerfort­
+ bildung in Nordrhein-Westfalen, Heft 2, Neue Technologien - Informations­
+ technologische Inhalte im Wahlpflichtunterricht der Klassen 9/10, 2. über­
+ arbeitete Auflage 1987
+
diff --git a/doc/prozess/gs-prozess-7 b/doc/prozess/gs-prozess-7
new file mode 100644
index 0000000..db3b9d1
--- /dev/null
+++ b/doc/prozess/gs-prozess-7
@@ -0,0 +1,1121 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#on("b")#7  Beschreibung der Menufunktionen#off("b")#
+
+Nach Aufruf meldet sich #on("b")#gs-Prozess#off("b")# zunächst mit dem #on("b")#gs-DIALOG#off("b")#-Emblem. Kurze
+Zeit später erscheint das folgende Menu auf dem Bildschirm:
+
++---------------------------------------------------------------------+
+| PDV:  Info Interface Programm Archiv |
+|-------+------------------------+------------------------------------+
+| | u  Übersicht Befehle | |
+| | --------------------- | |
+| | a  Ausgabebefehle | |
+| | e  Eingabebefehle | |
+| | t  Testbefehle | |
+| | w  Weitere Befehle | |
+| | --------------------- | |
+| | b  Bitmuster | |
+| | s  Symbole/Zeichen | |
+| | d  Digital-/Analogwerte| |
+| +------------------------+ |
+| |
+| +----------------------------------------+ |
+| | gs-Prozess | |
+| | Version 1.0 | |
+| | | |
+| | Copyright Ρ 1988 bei Eva Latta-Weber, | |
+| | Bielefeld | |
+| +----------------------------------------+ |
++---------------------------------------------------------------------+
+|Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>|
++---------------------------------------------------------------------+
+
+#center#Abb.22:  Eingangsbildschirm #on("b")#gs-Prozess#off("b")#
+
+
+Bevor wir Ihnen die Bedeutung der einzelnen Menupunkte erklären, geben wir erst
+noch einige grundsätzliche Hinweise zur Bedienung des Menusystems für diejenigen
+Leser, die im Umgang mit Menus unter #on("b")#gs-DIALOG#off("b")# nicht geübt sind.
+#page#
+#on("b")#7.1  Kurzhinweise zur Bedienung der Menus#off("b")#
+
+Die Bedienung des Menus ist sehr einfach. Eine ausführliche Beschreibung dazu
+finden Sie in den Unterlagen zum Programmsystem #on("b")#gs-DIALOG#off("b")#. An dieser Stelle
+sollen nur die wesentlichen Bedienungsvorgänge beschrieben werden.
+
+- Mit der Tastenfolge <ESC><?> können Sie sich Informationen zur Bedienung
+ des Menusystems in das Menu einblenden lassen.
+
+- Mit den Pfeiltasten <rechts> und <links> können Sie zwischen den "Ober­
+ begriffen" in der Kopfzeile wählen. Der aktuelle Oberbegriff ist jeweils invers
+ dargestellt. Das ausgeklappte 'Pull-Down-Menu' bezieht sich auf diesen invers
+ dargestellten Oberbegriff.
+
+- Mit den Pfeiltasten <hoch> und <runter> können Sie zwischen den Menu­
+ funktionen wählen, die Ihnen im aktuellen Pull-Down-Menu zur Auswahl ange­
+ boten werden. Die aktuell angewählte Menufunktion wird jeweils invers darge­
+ stellt. Die Trennlinien, die in einigen Pull-Down-Menus sichtbar sind, dienen nur
+ der optischen Untergliederung; sie können nicht angewählt werden und werden
+ deshalb automatisch übersprungen. Die einzelnen Menupunkte sind "zyklisch
+ miteinander verknüpft", das heißt, man gelangt vom untersten Menupunkt
+ wieder zum obersten und umgekehrt. Menupunkte, vor denen ein Minuszeichen
+ steht ('-'), sind (zur Zeit) nicht aktivierbar; auch sie können nicht angewählt
+ werden und werden einfach übersprungen.
+
+- Durch Tippen der Fragezeichentaste (<?>) können Sie sich jeweils zur
+ aktuellen Menufunktion (invers im Pull-Down-Menu) Informationen in das
+ Menu einblenden lassen.
+
+- Um eine Menufunktion ausführen zu lassen, bewegen Sie sich mit den Pfeiltasten
+ auf die gewünschte Menufunktion im aktuellen Pull-Down-Menu und tippen
+ dann die <RETURN>-Taste. Steht vor dem gewünschten Menupunkt ein
+#page#
+ einzelner Buchstabe oder eine Ziffer, so kann durch Tippen der entsprechenden
+ Taste diese Menufunktion dadurch direkt aufgerufen werden. Sobald eine Menu­
+ funktion aufgerufen worden ist, erscheint davor ein Stern ('*'). Daraus können
+ Sie entnehmen, daß das System bereits den Auftrag ausführt.
+
+- An verschiedenen Stellen werden Fragen an Sie gerichtet, die Sie mit 'ja' oder
+ 'nein' beantworten müssen. Tippen Sie dazu entsprechend der Entscheidung die
+ Taste <j> (für 'ja') bzw. <n> (für 'nein').
+
+- Werden Ihnen vom Menu aus Dateinamen zur Auswahl angeboten, so können Sie
+ den auf dem Bildschirm sichtbaren Pfeil vor den gewünschten Namen
+ positionieren. Mit den Tasten <x> oder <RETURN> können Sie den Namen
+ ankreuzen. Ist die Auswahl mehrerer Dateinamen möglich, so können Sie den
+ Vorgang wiederholen. Mit den Tasten <o> oder <RUBOUT> können Sie auch
+ ein Kreuz vor einem Namen wieder löschen. Daneben gibt es noch einige Ta­
+ stenfunktionen, die für die Bedienung recht hilfreich sein können. Tippen Sie
+ während der Auswahl die Fragezeichentaste (<?>), so werden Ihnen alle
+ Bedienungsmöglichkeiten auf dem Bildschirm angezeigt. Eine Auswahl, in der
+ mehrere Dateien angekreuzt werden dürfen, wird durch die Tastenfolge
+ <ESC><q> verlassen. Anschließend wird die eingestellte Operation mit den
+ angekreuzten Dateien ausgeführt. Sind Sie versehentlich in eine solche Auswahl
+ gelangt, so können Sie den Vorgang durch die Tastenkombination <ESC><h>
+ abbrechen.
+
+- An einigen Stellen werden Sie aufgefordert, eine Eingabe zu machen (z.B. einen
+ Dateinamen einzugeben). Wird Ihnen hier ein Vorschlag gemacht, den Sie
+ akzeptieren, so brauchen Sie zur Bestätigung nur die <RETURN>-Taste zu
+ tippen. Gefällt Ihnen der Vorschlag nicht oder wird Ihnen kein Vorschlag ge­
+ macht, so machen Sie bitte die gewünschte Eingabe. Zum Schreiben stehen
+ Ihnen alle aus dem Editor bekannten Funktionen zur Verfügung. Mit der Taste
+ <RUBOUT> können Sie Buchstaben löschen, mit <RUBIN> einfügen. Die
+#page#
+ Eingabe wird durch Tippen der <RETURN>-Taste abgeschlossen. Ist der von
+ Ihnen gewünschte Name schon in Ihrer Task vorhanden und steht in der Fußzeile
+ der Hinweis 'Zeigen: <ESC><z>', dann können Sie sich auch alle vor­
+ handenen Namen zur Auswahl anbieten lassen und durch Ankreuzen den beab­
+ sichtigten Namen auswählen.
+
+- Ihnen können auch mehrere Alternativen angeboten werden, zwischen denen Sie
+ wählen müssen. In der untersten Zeile eines solchen Kastens, in denen Ihnen die
+ Alternativen auf dem Bildschirm eingeblendet werden, sind die Möglichkeiten
+ aufgeführt, die darüber beschrieben sind. Mit den Pfeiltasten können sie die
+ Markierung auf die gewünschte Alternative positionieren und dann durch die
+ <RETURN>-Taste zur Ausführung bringen. (Manchmal ist das auch durch
+ Tippen der den Alternativen vorangestellten Buchstaben oder Ziffern möglich).
+
+- Durch die Tastenfolge <ESC><q> kann das Menu insgesamt verlassen
+ werden. Damit das nicht versehentlich geschieht, wird jeweils die Frage gestellt,
+ ob Sie das Menu tatsächlich verlassen wollen. Diese Frage beantworten Sie bitte je
+ nach Wunsch mit 'ja' oder 'nein' durch Tippen der Tasten <j> bzw. <n>.
+
+
+#on("b")#7.2  Menufunktionen zum Oberbegriff 'Info'#off("b")#
+
+Das auf dem Bildschirm sichtbare Pull-Down-Menu ist oben abgebildet.
+
+#on("b")#u   Übersicht Befehle#off("b")#
+
+Mit dieser Funktion können Sie sich eine Übersicht der Befehle, die Ihnen
+#on("b")#gs-Prozess#off("b")# zur Verfügung stellt, in den aktuellen Bildschirm einblenden lassen:
+#page#
+#free(2.0)#
+ +------------------------------------------------------------+
+ | Ausgabebefehle: Eingabebefehle: |
+ | |
+ | dezimalwert ausgeben dezimalwert |
+ | bitmuster ausgeben bitmuster |
+ | bitsymbol ausgeben bitsymbol |
+ | spannungswert ausgeben spannungswert |
+ | wert an analogausgang ausgeben wert von analogeingang |
+ | |
+ | |
+ | Testbefehle: Weitere Befehle: |
+ | |
+ | bitmuster gleich initialisiere interface |
+ | bit ist gesetzt warte |
+ | |
+ +------------------------------------------------------------+
+#center#Abb.23:  Befehlsübersicht
+
+ Es werden 'Eingabebefehle', 'Ausgabebefehle' und 'Testbefehle' unterschieden.
+ Darüberhinaus werden 'Weitere Befehle' angegeben. Eine ausführliche
+ Beschreibung der einzelnen Befehle ist unter den gleichnamigen Menupunkten
+ abrufbar.
+
+
+#on("b")#a   Ausgabebefehle#off("b")#
+
+ Mit dieser Funktion können Sie sich die zur Verfügung stehenden Ausgabe­
+ befehle detailliert erläutern lassen. Zuerst gelangen Sie in eine Auswahl, von
+ der aus zu jedem einzelnen Ausgabebefehl eine Informationstafel abgerufen
+ werden kann:
+#page#
+#free(2.0)#
+ +-------------------------------------+
+ | Ausgabebefehle: |
+ | |
+ | 1  dezimalwert ausgeben |
+ | |
+ | 2  bitmuster ausgeben |
+ | 3  bitsymbol ausgeben |
+ | |
+ | 4  spannungswert ausgeben |
+ | 5  wert an analogausgang ausgeben |
+ | |
+ | z  Zurück in das Menu |
+ | |
+ | 1   2   3   4   5   z |
+ +-------------------------------------+
+
+#center#Abb.24:  Auswahl Ausgabebefehle
+
+ Auf jeder Informationstafel ist ein kleines Beispiel zur Verwendung des Befehls
+ angegeben, das auch erläutert wird. Anschließend wird ausführlich auf die
+ Parameter der Befehle eingegangen (Datentyp, Wertebereich, etc.). Aus den
+ einzelnen Informationstafeln gelangen Sie immer wieder zur Auswahl zurück.
+ Wird die Auswahl selbst verlassen, gelangen Sie zurück ins Ausgangsmenu.
+
+
+#on("b")#e   Eingabebefehle#off("b")#
+
+ Mit dieser Funktion können Sie sich die zur Verfügung stehenden Eingabe­
+ befehle detailliert erläutern lassen. Zuerst gelangen Sie in eine Auswahl, von
+ der aus zu jedem einzelnen Eingabebefehl eine Informationstafel abgerufen
+ werden kann:
+#page#
+#free(1.0)#
+ +------------------------------+
+ | Eingabebefehle: |
+ | |
+ | 1  dezimalwert |
+ | |
+ | 2  bitmuster |
+ | 3  bitsymbol |
+ | |
+ | 4  spannungswert |
+ | 5  wert von analogeingang |
+ | |
+ | z  Zurück in das Menu |
+ | |
+ | 1   2   3   4   5   z |
+ +------------------------------+
+
+
+#center#Abb.25:  Auswahl Eingabebefehle
+
+ Auf jeder Informationstafel ist ein kleines Beispiel zur Verwendung des Befehls
+ angegeben, das auch erläutert wird. Anschließend wird ausführlich auf die
+ Parameter der Befehle (Datentyp, Wertebereich, etc.) und die Werte, die
+ geliefert werden, eingegangen.
+
+ Aus den einzelnen Informationstafeln gelangen Sie immer wieder zur Auswahl
+ zurück. Wird die Auswahl selbst verlassen, gelangen Sie zurück ins Ausgangs­
+ menu.
+
+
+#on("b")#t   Testbefehle#off("b")#
+
+ Mit dieser Funktion können Sie sich die zur Verfügung stehenden Testbefehle
+ detailliert erläutern lassen. Zuerst gelangen Sie in eine Auswahl, von der aus zu
+ jedem einzelnen Testbefehl eine Informationstafel abgerufen werden kann:
+#page#
+ +------------------------+
+ | Testbefehle: |
+ | |
+ | 1  bitmuster gleich |
+ | 2  bit ist gesetzt |
+ | |
+ | z  Zurück in das Menu |
+ | |
+ | 1   2   z |
+ +------------------------+
+
+#center#Abb.26:  Auswahl Testbefehle
+
+ Auf jeder Informationstafel ist ein kleines Beispiel zur Verwendung des Befehls
+ angegeben, das auch erläutert wird. Anschließend wird ausführlich auf die
+ Parameter der Befehle (Datentyp, Wertebereich, etc.) und die Werte, die ge­
+ liefert werden, eingegangen.
+ Aus den einzelnen Informationstafeln gelangen Sie immer wieder zur Auswahl
+ zurück. Wird die Auswahl selbst verlassen, gelangen Sie zurück ins Ausgangs­
+ menu.
+
+
+#on("b")#w   Weitere Befehle#off("b")#
+
+ Hier werden noch weitere zur Verfügung stehende Befehle erläutert, die für die
+ Programmierung ganz hilfreich sind. Zuerst gelangen Sie in eine Auswahl, von
+ der aus zu jedem Befehl eine Informationstafel abgerufen werden kann:
+
+
+ +----------------------------+
+ | Weitere Befehle: |
+ | |
+ | 1  initialisiere interface |
+ | 2  warte |
+ | |
+ | z  Zurück in das Menu |
+ | |
+ | 1   2   z |
+ +----------------------------+
+
+#center#Abb.27:  Auswahl 'Weitere Befehle'
+#page#
+ Aus den einzelnen Informationstafeln gelangen Sie immer wieder zur Auswahl
+ zurück. Wird die Auswahl selbst verlassen, gelangen Sie zurück ins Ausgangs­
+ menu.
+
+
+#on("b")#b   Bitmuster#off("b")#
+
+ Nach Aufruf dieser Funktion wird der Aufbau der Bitmuster erläutert, die als
+ Parameter übergeben oder auch von Prozeduren geliefert werden.
+
+ Insbesondere wird auf die Numerierung der einzelnen Bits eingegangen.
+
+
+#on("b")#s   Symbole/Zeichen#off("b")#
+
+ Nach Aufruf der Funktion werden die Zeichen erläutert, die bei der Be­
+ schreibung von Bitmustern und Bitsymbolen Verwendung finden.
+
+
+#on("b")#d   Digital-/Analogwerte#off("b")#
+
+ Bei den beiden Befehlen 'wert an analogausgang ausgeben' und 'wert von
+ analogeingang', wird ein Wert zwischen 0 und 255 als Parameter übergeben
+ bzw. von der Prozedur geliefert. Am Analogausgang wird aber eine Spannung
+ ausgegeben bzw. eingelesen. Hier wird erläutert, wie die Spannungswerte
+ innerhalb der Prozeduren gewandelt werden.
+
+
+#on("b")#7.3  Menufunktionen zum Oberbegriff 'Interface'#off("b")#
+
+Über die Menufunktionen unter diesem Oberbegriff nehmen Sie die Konfiguration
+von #on("b")#gs-Prozess#off("b")# vor. Ebenso ist von hier aus ein Test des Interface-Systems möglich.
+#page#
+
++-----------------------------------------------------------------------+
+| PDV:  Info Interface Programm Archiv |
++-------+-------------------+-------------------------------------------+
+| | i  Informationen | |
+| | ---------------- | |
+| | k  Konfigurieren | |
+| | ---------------- | |
+| | a  Ausgabetest | |
+| | e  Eingabetest | |
+| +-------------------+ |
+| |
+| |
+| |
++---------------------------------------------------------------------- +
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++-----------------------------------------------------------------------+
+
+#center#Abb.28:  Menubildschirm zum Oberbegriff 'Interface'
+
+
+#on("b")#i   Informationen#off("b")#
+
+ Mit dieser Menufunktion können Sie sich zu jedem Zeitpunkt die aktuell
+ eingestellte Konfiguration von #on("b")#gs-Prozess#off("b")# anzeigen lassen. Sie können er­
+ sehen, welches Interface-System eingestellt ist, wie die Kanäle belegt und
+ numeriert sind (sehen Sie das Beispiel in Abb.13).
+
+ Ist eine Compact-Box oder ein Einzelsteckplatz eingestellt, erhalten Sie die
+ Informationen direkt eingeblendet. Ist dagegen ein Mehrfachsteckplatz einge­
+ stellt, gelangen Sie in eine Auswahl. Von hier aus können Sie Informationen zu
+ jedem einzelnen Steckplatz getrennt abrufen.
+
+ Fehlerfälle:
+ - Wurde #on("b")#gs-Prozess#off("b")# bisher noch nicht konfiguriert, so erhalten Sie eine
+ Warnung (sehen Sie Abb.11). In diesem Falle ist zunächst eine Konfigura­
+ tion von #on("b")#gs-Prozess#off("b")# vorzunehmen (sehen Sie die Beschreibung zur
+ nächsten Menufunktion).
+#page#
+#on("b")#k   Konfigurieren#off("b")#
+
+ Mit dieser Menufunktion können Sie #on("b")#gs-Prozess#off("b")# auf das aktuell angeschlos­
+ sene Interface-System einstellen. Dazu haben Sie verschiedene Angaben zu
+ machen.
+
+ Zunächst wird Ihnen eine Auswahl der Steckplatzart angeboten (sehen Sie
+ dazu Abb.12). Hier können Sie zur Zeit zwischen Compact-Box, Einzelsteck­
+ platz und Mehrfachsteckplatz wählen.
+
+ Ist eine Compact-Box angeschlossen, ist mit der hier gemachten Angabe die
+ Konfiguration abgeschlossen; die aktuelle Kanalbelegung wird Ihnen dann nur
+ noch zur Information eingeblendet.
+
+ Bei Einzel- und Mehrfachsteckplatz haben Sie noch anzugeben, welche Inter­
+ facekarte eingesteckt ist. Beim Einzelsteckplatz ist diese Angabe nur einmal zu
+ machen, beim Mehrfachsteckplatz halt mehrfach. Hierzu wird Ihnen aber
+ ebenfalls eine Auswahl angeboten (sehen Sie Abb.14). Nach jeder vorge­
+ nommenen Einstellung wird Ihnen zur Information die Kanalbelegung mitge­
+ teilt. Sofern Sie eine A/D-Karte verwenden, wird noch die Schalterstellung auf
+ der Karte erfragt, denn daraus kann #on("b")#gs-Prozess#off("b")# die eingestellte Eingangsem­
+ pfindlichkeit ermitteln.
+
+
+#on("b")#a   Ausgabetest#off("b")#
+
+ Mit dieser Menufunktion können Sie auf einfache Weise testen, ob Ihr Inter­
+ face-System korrekte Ausgaben erzeugt. Nach Aktivieren der Menufunktion
+ erhalten Sie die Möglichkeit, Ausgabewerte einzutragen (sehen Sie Abb.18).
+ Jede Eintragung ist durch <RETURN> abzuschließen.
+
+ Für den Ausgabetest sollte eine Leuchtdiodenanzeige zur Verfügung stehen, um
+ die Ausgaben am Interface kontrollieren zu können. Für detailliertere Informa­
+ tionen lesen Sie bitte unbedingt Kapitel 5.
+#page#
+ Fehlerfälle:
+ - Interface meldet sich nicht!
+ Abhilfe: Überprüfen, ob der Adapter ordnungsgemäß angeschlossen
+ und eingeschlatet ist (sehen Sie Kapitel 5). Wenn ein MUFI
+ verwendet wird, MUFI aus- und nach kurzer Pause wieder
+ einschalten. Noch einmal den Ausgabetest versuchen.
+ - Interface-Kanal belegt!
+ (Kann nur beim Betrieb von MUFI als Endgerät oder bei RS232-Adapter
+ auftreten!)
+ Abhilfe: Feststellen, welche Task an den Interface-Kanal gekoppelt ist
+ ('taskinfo (2) <RETURN>') und diese dann abmelden
+ ('break' oder 'end'). Die Nummer des Interfacekanals kann
+ mit dem Kommando 'put (interfacekanal) <RETURN>'
+ erfragt werden.
+ - Sehen Sie bitte die detaillierte Fehlerliste in Kapitel 5.5.
+
+
+#on("b")#e   Eingabetest#off("b")#
+
+ Mit dieser Menufunktion können Sie auf einfache Weise testen, ob über Ihr
+ Interface-System korrekte Eingaben möglich sind. Nach Aktivieren der Menu­
+ funktion erhalten Sie die Möglichkeit, am Interface angelegte Eingabewerte
+ abzulesen (sehen Sie Abb.19).
+
+ Für den Eingabetest sollte ein Codekartenleser oder zumindest ein kurzer
+ Draht zur Verfügung stehen. Für detailliertere Informationen lesen Sie bitte
+ unbedingt Kapitel 5.
+
+ Fehlerfälle:
+ - Interface meldet sich nicht!
+ Abhilfe: Überprüfen, ob der Adapter ordnungsgemäß angeschlossen
+ und eingeschlatet ist (sehen Sie Kapitel 5). Wenn ein MUFI
+ verwendet wird, MUFI aus- und nach kurzer Pause wieder
+ einschalten. Noch einmal den Ausgabetest versuchen.
+#page#
+ - Interface-Kanal belegt!
+ (Kann nur beim Betrieb von MUFI als Endgerät oder bei RS232-Adapter
+ auftreten!)
+ Abhilfe: Feststellen, welche Task an den Interface-Kanal gekoppelt ist
+ ('taskinfo (2) <RETURN>') und diese dann abmelden
+ ('break' oder 'end'). Die Nummer des Interfacekanals kann
+ mit dem Kommando 'put (interfacekanal) <RETURN>'
+ erfragt werden.
+ - Sehen Sie bitte die detaillierte Fehlerliste in Kapitel 5.5.
+
+
+#on("b")#7.4  Menufunktionen zum Oberbegriff 'Programm'#off("b")#
+
+
++-------------------------------------------------------------------------+
+| PDV:  Info Interface Programm Archiv |
+|---------------------+---------------------+-----------------------------|
+| | n  Neu erstellen | |
+| | a  Ansehen/Ändern | |
+| | | |
+| | s  Starten | |
+| | w  Wiederholen | |
+| | | |
+| | v  Verzeichnis | |
+| | | |
+| | l  Löschen | |
+| | d  Drucken | |
+| | | |
+| | k  Kopieren | |
+| | u  Umbenennen | |
+| +---------------------+ |
+|-------------------------------------------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++-------------------------------------------------------------------------+
+
+#center#Abb.29:  Menubildschirm zum Oberbegriff 'Programm'
+#page#
+#on("b")#n   Neu erstellen#off("b")#
+
+ Mit dieser Funktion können Sie eine neue Programmdatei anlegen und be­
+ schreiben.
+
+ Sie werden zunächst nach einem Namen für die #on("b")#neue#off("b")# Programmdatei gefragt.
+ Geben Sie einen beliebigen Namen (#on("b")#ohne Anführungszeichen (!)#off("b")#) ein und
+ schließen Sie die Eingabe durch <RETURN> ab. Daraufhin wird Ihnen auf
+ dem Bildschirm eine neue Datei zum beschreiben angeboten.
+
+ Sollte schon eine Programmdatei mit diesem Namen in der Task vorhanden
+ sein, so werden Sie darauf aufmerksam gemacht.
+
+ Sie können sich während des Schreibens die wichtigsten Tastenfunktionen des
+ Editors einblenden lassen. Tippen Sie dazu die Tastenfolge <ESC><?>. Es
+ erscheint dann das folgende Angebot aus dem Sie auswählen können:
+
+
+ +------------------------------------------------+
+ | Der EUMEL - Editor |
+ | |
+ | b ... Beschreibung desEditors |
+ | w ... Wichtige Tasten |
+ | p ... Positionieren der Schreibmarke |
+ | k ... Korrigieren im Text (Einfügen/Löschen) |
+ | m ... Markierte Textpassagen bearbeiten |
+ | l ... Lernen im Editor |
+ | a ... Anweisungen im Editor (Kommandodialog) |
+ | |
+ | z ... Zurück in den Schreibmodus |
+ | |
+ | b   w   p   k   m   l   a   z |
+ | |
+ +------------------------------------------------+
+
+#center#Abb.30:  Informationsauswahl zum EUMEL-Editor
+#page#
+ Fehlerfälle:
+ - Eine Datei mit dem vorgeschlagenen Namen existiert schon.
+
+
+#on("b")#a   Ansehen/Ändern#off("b")#
+
+ Mit dieser Funktion können Sie sich Dateien, die schon in Ihrer Task
+ existieren, ansehen oder auch verändern.
+
+ Sie werden zunächst gefragt, ob Sie #on("b")#die zuletzt bearbeitete Programmdatei#off("b")#
+ ansehen bzw. verändern möchten (sofern Sie schon vorher mit #on("b")#gs-Prozess#off("b")# in
+ der Task gearbeitet haben).
+
+ Bejahen Sie diese Frage, dann wird Ihnen diese Programmdatei zur Be­
+ arbeitung angeboten. Verneinen Sie die Frage dagegen, so gelangen Sie in die
+ 'Auswahl' (d.h es werden Ihnen alle Programmdateien in der Task zur Auswahl
+ angeboten). Nachdem Sie einen der Namen angekreuzt haben, wird Ihnen die
+ ausgewählte Programmdatei zur Bearbeitung auf dem Bildschirm angebo­
+ ten.
+
+ Fehlerfälle:
+ - In der Task existiert noch keine Programmdatei.
+
+
+#on("b")#s   Starten#off("b")#
+
+ Mit dieser Menufunktion können Sie eine Programmdatei übersetzen und
+ ausführen lassen.
+
+ Sie werden zunächst gefragt, ob #on("b")#das zuletzt bearbeitete Programm#off("b")# ausgeführt
+ werden soll. Bejahen Sie die Frage, so wird dieses Programm gestartet; ver­
+ neinen Sie die Frage dagegen, so gelangen Sie in die 'Auswahl'. Nach An­
+ kreuzen des gewünschten Programmnamens wird das ausgewählte Programm
+ ausgeführt.
+#page#
+ Sind im Programm noch Fehler enthalten, so werden das Programm und die
+ Fehlermeldungen gleichzeitig auf dem Bildschirm dargestellt (Paralleleditor)
+ und zur Korrektur angeboten. Für die Programmkorrektur stehen ebenfalls alle
+ Editorfunktionen zur Verfügung.
+
+ Sollte Ihnen beim Programmieren ein Fehler unterlaufen sein (z.B. eine
+ Endlosschleife), so kann mit der Tastenfolge <ESC><h> der Programmlauf
+ abgebrochen werden ("Notbremse").
+
+
+#on("b")##on("b")#w   Wiederholen#off("b")#
+
+ Mit dieser Funktion können Sie den Ablauf des zuletzt ausgeführten
+ Programms wiederholen, ohne daß das Programm neu übersetzt wird.
+
+ Beachten Sie aber bitte, daß Veränderungen am Programmtext, die seit dem
+ letzten Prtogrammlauf vorgenommen wurden, #on("b")#nicht#off("b")# berücksichtigt werden;
+ dazu muß das Programm erneut mit der Menufunktion 's Starten' übersetzt
+ werden.
+
+ Ist die Wiederholung eines Programmlaufs nicht möglich, so erfolgt ein Hin­
+ weis darauf.
+
+
+#on("b")#v   Verzeichnis#off("b")#
+
+ Mit dieser Funktion können Sie sich einen Überblick über die in Ihrer Task
+ vorhandenen Programmdateien verschaffen.
+
+ Nach Aufruf dieser Funktion wird eine Liste der Programmdateien auf dem
+ Bildschirm ausgegeben, die sich in Ihrer Task befinden. Da die Liste selbst
+ eine Datei ist, kann Sie mit der Tastenkombination <ESC><q> verlassen
+ werden - hierauf wird auch in der Kopfzeile der Datei hingewiesen. Falls nicht
+ alle Namen auf den Bildschirm passen, können Sie das Fenster mit
+ <HOP><runter> und <HOP><hoch> verschieben.
+#page#
+#on("b")#l   Löschen#off("b")#
+
+ Mit dieser Funktion können Sie Programmdateien, die Sie nicht mehr
+ benötigen, die unnötig Platz belegen, löschen. Aber Vorsicht! Die Programm­
+ dateien verschwinden durch diese Funktion unwiederbringlich!
+
+ Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+ Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+ <ESC><q> verlassen.
+
+ Für jede einzelne Programmdatei wird noch einmal zur Sicherheit gefragt, ob
+ sie auch tatsächlich gelöscht werden soll. Zur Bestätigung tippen Sie bitte die
+ Taste <j> ('ja') - zur Verhinderung <n> ('nein').
+
+ Fehlerfälle:
+ - In der Task exsitiert noch keine Programmdatei.
+
+
+#on("b")#d   Drucken#off("b")#
+
+ Mit dieser Funktion können Sie Programmdateien über einen angeschlossenen
+ Drucker ausgeben lassen.
+
+ Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+ Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+ <ESC><q> verlassen.
+
+ Die angekreuzten Programmdateien werden anschließend zum Drucker ge­
+ schickt. Der Vorgang wird auf dem Bildschirm protokolliert.
+#page#
+ Fehlerfälle:
+ - In der Task existiert noch keine Programmdatei.
+ - Der Drucker ist nicht funktionsbereit.
+ - Der Drucker wird nicht über die Task 'PRINTER' betrieben.
+ - Auf Ihrem System werden die Druckkosten abgerechnet. Sie müssen sich
+ mit einer Codenummer identifizieren.
+
+
+#on("b")#k   Kopieren#off("b")#
+
+ Mit dieser Funktion können Sie sich eine Kopie einer bereits in der Task
+ vorhandenen Programmdatei anlegen. Das ist z.B. dann sinnvoll, wenn Sie sich
+ einen bestimmten 'Stand' aufbewahren wollen oder wenn Sie ein Programm
+ schreiben wollen, das einem bereits vorhandenen ähnelt.
+
+ Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+ wird die Auswahl automatisch verlassen.
+
+ Anschließend wird der angekreuzte Name angezeigt und der Name für die
+ Kopie erfragt. Es muß ein Name eingetragen werden, der in dieser Task noch
+ nicht für eine Programmdatei vergeben wurde; ansonsten erfolgt ein Hinweis
+ darauf und es wird nicht kopiert!
+
+ Da man aber oft für die Kopie einen ähnlichen Namen wie für das Original
+ wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+ aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+ funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+ eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+ Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Programmdatei mit dem gewünschten Namen existiert bereits in der
+ Task.
+#page#
+#on("b")#u   Umbenennen#off("b")#
+
+ Mit dieser Funktion können Sie einer bereits vorhandenen Programmdatei
+ einen neuen Namen geben.
+
+ Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+ wird die Auswahl automatisch verlassen.
+
+ Anschließend wird dieser Name angezeigt und der zukünftige Name für die
+ Programmdatei erfragt. Es muß ein Name eingetragen werden, der in dieser
+ Task noch nicht für eine Programmdatei vergeben wurde - ansonsten erfolgt
+ ein Hinweis darauf und die Programmdatei wird nicht umbenannt!
+
+ Da man aber oft den 'neuen' Namen in Anlehnung an den 'alten' Namen
+ wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+ aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+ funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+ eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+ Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Programmdatei mit dem gewünschten Namen existiert bereits in der
+ Task.
+#page#
+#on("b")#7.5  Menufunktionen zum Oberbegriff 'Archiv'#off("b")#
+
+
++-----------------------------------------------------------------------+
+| PDV:  Info Interface Programm Archiv |
+|------------------+------------------------+---------------------------|
+| | r  Reservieren | |
+| | -  Neue Diskette | |
+| | | |
+| | -  Schreiben | |
+| | -  Checken | |
+| | -  Kombination | |
+| | -  Holen/Lesen | |
+| | -  Löschen | |
+| | | |
+| | -  Verzeichnis | |
+| | -  Drucken | |
+| | | +---------------------+ |
+| | i  Initialisieren | | Dateiaustausch mit:| |
+| | z  Zieltask einstellen | | Archiv | |
+| +------------------------+ | Archivname: | |
+| | __________ | |
+| +---------------------+ |
+|-----------------------------------------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++-----------------------------------------------------------------------+
+
+#center#Abb.31:  Menubildschirm zum Oberbegriff 'Archiv'
+
+
+In diesem Kapitel werden alle die Menufunktionen beschrieben, die Ihnen unter dem
+Oberbegriff 'Archiv' im Menu angeboten werden. Mit den Funktionen in diesem Menu
+können Sie aber nicht nur Dateien auf dem Archiv behandeln, sondern auch in
+anderen Tasks im Multi-User-System oder über das EUMEL-Netz sogar auf anderen
+Rechnern!
+
+Wenn Sie dieses Pull-Down-Menu gerade aufgeschlagen haben, sind nicht alle Funk­
+tionen aktivierbar! Um weitere Funktionen zu aktivieren, muß erst einer der aktivier­
+baren Menupunkte gewählt werden.
+#page#
+#on("b")#r   Reservieren#off("b")# (des Archivlaufwerks)
+
+ Im EUMEL-Multi-User-System haben normalerweise mehrere Personen das
+ Zugriffsrecht auf das Archivlaufwerk. Allerdings muß der Zugriff so geregelt
+ werden, daß sich die Beteiligten dabei nicht gegenseitig "in die Quere
+ kommen". Ein Zugriff auf das Archivlaufwerk erfordert zunächst eine An­
+ meldung. Ist diese Anmeldung erfolgt, kann von den anderen Beteiligten so
+ lange nicht mehr auf das Laufwerk zugegriffen werden, bis es wieder freige­
+ geben worden ist.
+
+ Diese Anmeldung des Archivlaufwerkes erfolgt über die Menufunktion 'r Reser­
+ vieren'. Greift bereits eine andere Task auf das Laufwerk zu, so erhalten Sie
+ darüber einen Hinweis auf dem Bildschirm. Ansonsten wird an Sie die Frage
+ gestellt, ob die Diskette eingelegt und das Laufwerk geschlossen ist.
+
+ Erst zu diesem Zeitpunkt ist sichergestellt, daß Sie den alleinigen Zugriff auf
+ das Laufwerk haben. Deshalb sollten Sie, wenn Sie mit mehreren Personen am
+ Computer arbeiten, erst zum Zeitpunkt der Fragestellung die Diskette ins
+ Laufwerk einlegen.
+
+ Nachdem Sie die Diskette eingelegt und die Frage bejaht haben, ermittelt das
+ System selbständig den Namen der eingelegten Diskette, zeigt den Namen auf
+ dem Bildschirm (im kleinen Kasten unten) an und aktiviert die anderen
+ Menupunkte des Pull-Down-Menus.
+
+ Beim Verlassen des Pull-Down-Menus, wenn eine andere Zieltask eingestellt
+ wird oder wenn das Menu gänzlich verlassen wird, wird die Reservierung
+ automatisch aufgehoben!
+#page#
+ Fehlerfälle:
+ - Das Laufwerk ist von einer anderen Task belegt.
+ - Die Diskette ist falsch eingelegt oder das Laufwerk ist nicht richtig ge­
+ schlossen.
+ - Die Diskette ist nicht formatiert bzw. initialisiert.
+ - Die Diskette kann nicht gelesen werden (keine EUMEL-Diskette, Diskette
+ hat ein falsches Format, Diskette ist verschmutzt...).
+
+
+#on("b")#n   Neue Diskette#off("b")# (anmelden)
+
+ Der Dateiaustausch mit einer Diskette ist nur dann möglich, wenn der im
+ System eingestellte Diskettenname (auf dem Bildschirm im kleinen Kasten
+ unten sichtbar) mit dem tatsächlichen Namen der Diskette übereinstimmt.
+ Nach einem Diskettenwechsel ist das aber in der Regel nicht mehr der Fall.
+ Greift man dann auf die neu eingelegte Diskette zu, so erscheint die Fehlermel­
+ dung: 'Falscher Archivname! Bitte neue Diskette anmelden!'.
+
+ Das Anmelden einer neuen Diskette - ohne einen neuen Reservierungsvorgang
+ - wird durch diese Menufunktion ermöglicht. Nach Aktivieren dieses Menu­
+ punktes wird der Name der eingelegten Diskette ermittelt, im System eingestellt
+ und auf dem Bildschirm angezeigt.
+
+ Im Gegensatz zur Menufunktion 'r Reservieren' greift das System ohne Anfrage
+ an den Benutzer auf das Archivlaufwerk zu (die Reservierung bleibt ja
+ bestehen). Ist das Archivlaufwerk reserviert, so ist die Neuanmeldung einer
+ Diskette über diese Menufunktion weniger zeitaufwendig.
+
+ Fehlerfälle:
+ - wie unter 'r Reservieren'.
+#page#
+#on("b")#s   Schreiben#off("b")# (Kopieren)
+
+ Alle Dateien der eigenen Task werden zur Auswahl angeboten. Wenn Sie die
+ Auswahl durch die Tastenfolge <ESC><q> verlassen, überprüft das System
+ zunächst, ob die Dateien in der eingestellten Zieltask schon vorhanden sind. Ist
+ das der Fall, wird erfragt, ob die dort vorhandenen Dateien überschrieben, d.h.
+ gelöscht werden dürfen (s.u.). Anschließend werden alle angekreuzten Dateien
+ in der Reihenfolge, in der Sie sie angekreuzt haben, in die eingestellte Zieltask
+ kopiert. Der Vorgang wird auf dem Bildschirm protokolliert. Die Original­
+ dateien in der eigenen Task bleiben dabei erhalten.
+
+ Wenn in der Zieltask schon eine Datei existiert, die den gleichen Namen hat
+ wie eine Datei, die Sie dorthin kopieren möchten, so wird angefragt, ob die
+ vorher schon existierende Datei überschrieben (gelöscht!) werden soll. Bejahen
+ Sie diese Frage, so wird die bereits in der Zieltask existierende Datei (un­
+ wiederbringlich) gelöscht und die gewünschte Datei dorthin transportiert. Ein
+ Überschreiben aus Versehen ist nicht möglich, wenn Sie die an Sie gestellte
+ Frage sorgfältig beantworten.
+
+ Verneinen Sie die Frage, so wird die Datei auch nicht hinübertransportiert! Sie
+ können die Datei aber umbenennen (Menufunktion 'u Umbenennen' unter
+ den Oberbegriffen 'Landschaft'/Arbeitsfeld' bzw. 'Programm') und an­
+ schließend mit anderem Namen hinüberschreiben.
+
+ Beachten Sie, daß beim Überschreiben einer Datei auf einer Archivdiskette der
+ Speicherplatz der alten (überschriebenen) Version im allgemeinen nicht
+ wiederverwendet werden kann. In einem solchen Fall könnte die Diskette voll
+ geschrieben werden, obwohl eigentlich genügend Platz vorhanden wäre. Zur
+ Optimierung wird deshalb zuerst überprüft, ob die angekreuzten Dateien
+ schon in der Zieltask vorhanden sind und löscht diese, wenn Sie Ihr Einver­
+ ständnis geben. Erst anschließend werden die Dateien insgesamt kopiert.
+#page#
+ Normalerweise ist als Zieltask das Archivlaufwerk der eigenen Station einge­
+ stellt. Mit der Menufunktion 'z Zieltask einstellen' kann diese Einstellung aber
+ verändert werden.
+
+ Fehlerfälle:
+ - Die Diskette ist falsch eingelegt oder beschädigt.
+ - Die Diskette kann nicht beschrieben werden (Schreibfehler).
+ - Die Diskette ist voll.
+ - Sehen Sie auch unter 'r Reservieren'
+ 'z Zieltask einstellen'.
+
+
+#on("b")#c   Checken#off("b")#
+
+ Diese Menufunktion kann nur ausgeführt werden, wenn der Dateiaustausch
+ mit einem Archiv(manager) erfolgt - ansonsten ist diese Menufunktion auch
+ nicht aktivierbar. Die Menufunktion dient dazu, auf Diskette geschriebene
+ Dateien auf Lesefehler hin zu prüfen. Es empfiehlt sich, diese Prüfroutine auf
+ neu auf die Diskette geschriebene Dateien anzuwenden. Sehen Sie dazu auch
+ 'k Kombination'.
+
+ Alle Dateien der eingestellten Zieltask (Archiv) werden zur Auswahl angeboten.
+ Wenn Sie die Auswahl durch die Tastenfolge <ESC><q> verlassen, werden
+ alle angekreuzten Dateien in der Reihenfolge, in der Sie sie angekreuzt haben,
+ "gecheckt", d.h. auf Lesefehler hin überprüft. Der Vorgang wird auf dem Bild­
+ schirm protokolliert.
+
+ Fehlerfälle:
+ - Lesefehler auf dem Archiv.
+ - Sehen Sie auch unter 'r Reservieren'.
+
+#page#
+#on("b")#k   Kombination#off("b")#
+
+ Diese Menufunktion ist eine Kombination aus den beiden Menufunktionen 's
+ Schreiben' und 'c Checken' (Sehen Sie weitere Informationen auch dort!).
+
+ Alle Dateien der eigenen Task werden zur Auswahl angeboten. Wenn Sie die
+ Auswahl durch die Tastenfolge <ESC><q> verlassen, werden alle ange­
+ kreuzten Dateien in der Reihenfolge, in der Sie sie angekreuzt haben, in die
+ eingestellte Zieltask kopiert (gegebenenfalls müssen bereits vorhandene
+ Dateien gleichen Namens in der Zieltask gelöscht werden). Anschließend
+ werden alle Dateien, die gerade geschrieben wurden, gecheckt, d.h. auf Lese­
+ fehler hin untersucht. Beide Vorgänge werden auf dem Bildschirm
+ protokolliert.
+
+ Da die 'Check' - Operation nur bei Archivmanagern zulässig ist, ist diese Menu­
+ funktionen ebenfalls nur bei Archivmanagern aktivierbar. Zur Erläuterung
+ sehen Sie bitte auch unter 'z Zieltask einstellen'.
+
+
+#on("b")#h   Holen/Lesen#off("b")#
+
+ Die Menufunktion dient dazu, Dateien, die bereits auf einer Archivdiskette oder
+ in einer anderen Task existieren, in die eigene Task zu kopieren.
+
+ Alle Dateien der eingestellten Zieltask werden zur Auswahl angeboten. An­
+ schließend werden Kopien der angekreuzten Dateien in der Reihenfolge des
+ Ankreuzens in die eigene Task geholt. Das Original in der Zieltask bleibt dabei
+ unverändert! Der Vorgang wird auf dem Bildschirm protokolliert.
+
+ Sind in der eigenen Task schon Dateien mit gleichem Namen vorhanden, so
+ wird gefragt, ob die 'alten' Dateien überschrieben (gelöscht) werden dürfen.
+ Nur wenn Sie zustimmen, werden die in Ihrer Task existierenden Dateien
+ (unwiederbringlich!) gelöscht und Kopien der gleichnamigen Dateien aus der
+ Zieltask angefertigt.
+#page#
+ Stimmen Sie dem Löschvorgang nicht zu, dann bleiben die bisherigen Dateien
+ in Ihrer Task erhalten - die Dateien aus der Zieltask werden dann aber auch
+ nicht in Ihre Task kopiert! Um dennoch die Kopien zu erhalten, können Sie die
+ namensgleichen Dateien in Ihrer Task umbenennen und dann erst die Dateien
+ aus der anderen Task anfordern.
+
+ Normalerweise werden die Dateien vom Archiv der eigenen Station geholt. Mit
+ dem Menupunkt 'z Zieltask einstellen' kann diese Einstellung verändert
+ werden.
+
+ Fehlerfälle:
+ - Lesefehler auf dem Archiv.
+ - Sehen Sie auch unter 'r Reservieren'
+ 's Schreiben'
+ 'z Zieltask einstellen'.
+
+
+#on("b")#l   Löschen#off("b")#
+
+ Die Menufunktion dient dazu, Dateien in der Zieltask (unwiederbringlich!) zu
+ löschen. Dazu werden alle Dateien der eingestellten Zieltask zur Auswahl ange­
+ boten. Anschließend werden die angekreuzten Dateien in der Reihenfolge ihres
+ Ankreuzens gelöscht. Zur Sicherheit muß noch einmal für jede einzelne Datei
+ bestätigt werden, daß sie auch tatsächlich gelöscht werden soll.
+
+ Beachten Sie, daß beim Löschen einer Datei auf einer Archivdiskette der
+ Speicherplatz im allgemeinen nicht wieder verwendet werden kann. In einem
+ solchen Fall könnte die Diskette voll geschrieben werden, obwohl eigentlich
+ genügend Platz vorhanden wäre. Diese Probleme treten bei anderen Tasks, die
+ keine Archivmanager sind, nicht auf, da deren Speicherplatz intelligenter
+ verwaltet wird.
+#page#
+ Normalerweise ist als Zieltask das Archiv der eigenen Station eingestellt. Mit
+ dem Menupunkt 'z Zieltask einstellen' kann diese Einstellung verändert
+ werden.
+
+ Fehlerfälle:
+ - Sehen Sie auch unter 'r Reservieren'
+ 's Schreiben'
+ 'z Zieltask einstellen'.
+
+
+#on("b")#v   Verzeichnis#off("b")#
+
+ Mit dieser Menufunktion können Sie sich einen Überblick über die in der
+ Zieltask (z.B. auf dem Archiv) vorhandenen Dateien verschaffen.
+
+ Nach Aufruf der Funktion wird eine Liste der Dateien auf dem Bildschirm
+ ausgegeben, die sich in der Zieltask (z.B. auf dem Archiv) befinden. Ist die
+ Zieltask ein Archiv(manager), so wird auch angezeigt, wieviel Platz auf der
+ Diskette belegt ist. Da die Liste selbst eine Datei ist, kann sie mit der Tasten­
+ kombination <ESC><q> verlassen werden. Falls nicht alle Dateinamen auf
+ den Bildschirm passen, können Sie das Fenster mit <HOP><hoch> und
+ <HOP><runter> verschieben.
+
+ Fehlerfälle:
+ - Sehen Sie unter 'z Zieltask einstellen'.
+
+
+#on("b")#d   Drucken#off("b")#
+
+ Das Verzeichnis der Dateien in der Zieltask, das man mit der Menufunktion 'v
+ Verzeichnis' auf dem Bildschirm angezeigt bekommt, kann mit dieser Menu­
+ funktion ausgedruckt werden.
+#page#
+ Zur Sicherheit wird angefragt, ob wirklich ein solches Dateiverzeichnis der
+ Zieltask gedruckt werden soll. Bejaht man die Frage, so wird ein Dateiver­
+ zeichnis erstellt und zum Drucker geschickt.
+
+ Fehlerfälle:
+ - Der Drucker ist nicht funktionsbereit.
+ - Der Drucker wird nicht über die Task 'PRINTER' betrieben.
+ - Auf Ihrem System werden die Druckkosten abgerechnet. Sie müssen sich
+ mit einer Codenummer identifizieren.
+
+
+#on("b")#i  Initialisieren#off("b")#
+
+ Diese Menufunktion gestattet es, frische Disketten zu formatieren, zu
+ initialisieren bzw. beschriebene Disketten vollständig zu löschen und ggf. dabei
+ umzubenennen. Bei Aufruf dieser Menufunktion wird - sofern noch nicht
+ geschehen - das Archivlaufwerk automatisch reserviert.
+
+ Wenn Sie eine fabrikneue Diskette aus der Verpackung nehmen, müssen Sie
+ diese zunächst #on("b")#formatieren#off("b")#. Dabei wird die Diskette auf ein festgelegtes
+ physikalisches Format eingestellt. Ohne daß diese Operation vorausgegangen
+ ist, kann eine Diskette weder beschrieben noch gelesen werden.
+
+ Prinzipiell braucht eine Diskette nur ein einziges Mal formatiert zu werden. Sie
+ können Sie jedoch jederzeit wieder formatieren - z.B. wenn Sie Disketten ha­
+ ben, von denen Sie nicht genau wissen, für welche Zwecke sie zuvor verwendet
+ wurden.
+
+ Wenn Sie diese Menufunktion aktivieren, werden Sie so zunächst gefragt, ob Sie
+ die Diskette auch formatieren wollen. Bejahen Sie die Frage, so werden Ihnen
+ mehrere Formate zur Auswahl angeboten:
+#page#
+ +----------------------------------+
+ | Formatieren einer Diskette |
+ | |
+ | Dies sind die möglichen Formate: |
+ | |
+ | 1 .... 40 Spur - 360 KB |
+ | 2 .... 80 Spur - 720 KB |
+ | 3 .... 5 1/4" - 1,2 MB |
+ | 4 .... 3 1/2" - 1,4 MB |
+ | s .... Standard - Format |
+ | |
+ | |
+ | 1   2   3   4   s |
+ +----------------------------------+
+
+#center#Abb.32:  Auswahl der Archiv-Formate
+
+ Erkundigen Sie sich bei Ihrem Händler, welches Format Sie bei Ihrem Rechner
+ und den von Ihnen verwendeten Disketten einstellen müssen. Manche Rechner
+ unterstützen diese Operation innerhalb des EUMEL-Systems auch gar nicht,
+ das Formatieren muß dann irgendwie anders außerhalb des EUMEL-Systems
+ geschehen.
+
+ Wenn Sie die Formatierung abgeschlossen oder auch übersprungen haben,
+ beginnt die eigentliche Initialisierung der Diskette. Dabei wird als erstes der
+ Archivname auf die Diskette geschrieben. Alle alten Daten, die sich ggf. auf der
+ Diskette befinden, werden bei diesem Vorgang unwiederbringlich (!) gelöscht.
+
+ Zur Sicherheit überprüft das System in jedem Falle, ob es sich um eine EUMEL
+ - Diskette handelt, und erfragt Ihr Einverständnis, ob die Diskette wirklich
+ initialisiert werden soll. Geben Sie hierzu Ihr Einverständnis, dann wird noch
+ der (neue) Archivname erfragt. Hatte die Diskette schon einen Namen, dann
+ wird dieser zum Überschreiben angeboten. Wollen Sie den alten Archivnamen
+ beibehalten, so brauchen Sie nur die <RETURN>-Taste zu tippen, ansonsten
+ können Sie den Namen auch zuvor verändern oder einen ganz neuen Namen
+ hinschreiben. Anhand des ausgegebenen Namens können Sie auch über­
+ prüfen, ob Sie die richtige Diskette eingelegt haben.
+#page#
+ Das Initialisieren funktioniert natürlich nur, wenn Sie als Zieltask einen
+ Archivmanager eingestellt haben - ansonsten ist diese Menufunktion gesperrt
+ (nicht aktivierbar!).
+
+ Fehlerfälle:
+ - Formatieren ist nicht auf dem System möglich.
+ - Sehen Sie auch unter 'r Reservieren'
+ 'z Zieltask einstellen'.
+
+
+#on("b")#z   Zieltask einstellen#off("b")#
+
+ Mit dieser Menufunktion können Sie festlegen, mit welcher Zieltask Sie
+ kommunizieren, d.h. z.B. Dateien austauschen möchten. Normalerweise ist hier
+ das Archiv am eigenen Rechner eingestellt. Das wird auch nach Aufklappen des
+ Pull-Down-Menus im Kasten unten angezeigt.
+
+ Diese Menufunktion kann im Unterricht z.B. dazu genutzt werden, um fertig­
+ gestellte Hausaufgaben in eine bestimmte Task zu schicken (Vatertask) oder um
+ von dort z.B. vorgefertigte Landschaften oder/und Programme abzuholen.
+
+ Sie können aber auch eine andere Task einstellen (z.B. die Vatertask oder die
+ Task 'PUBLIC'), um mit diesen Dateien auszutauschen oder um sich auch nur
+ einen Überblick über die dort vorhandenen Dateien zu verschaffen. Wenn Sie
+ mit Ihrem Rechner in ein EUMEL-Netz integriert sind, können Sie auch auf
+ Tasks anderer Rechner zugreifen oder auch Disketten von Laufwerken anderer
+ Rechner einlesen (z.B. wenn Sie Disketten anderer Formate haben, die von
+ Ihrem Rechner nicht gelesen werden können).
+
+ Dabei werden zwei Anforderungen an die Zieltask gestellt: Sie muß existieren
+ und bereit für den Dateiaustausch sein, d.h es muß eine Managertask sein, auf
+ die Sie Zugriff haben. Versuchen Sie auf andere Tasks zuzugreifen, so erhalten
+ Sie entsprechende (Fehler-)Meldungen.
+#page#
+ Zu beachten ist noch, daß es im EUMEL-System verschiedene Arten von
+ Managertasks gibt - Archivmanager und normale Dateimanager. Der Unter­
+ schied besteht darin, daß ein Archivmanager vom Benutzer vor dem Zugriff
+ reserviert werden muß - anschließend hat nur dieser Benutzer (bis zur Aufgabe
+ der Reservierung) ein Zugriffsrecht auf den Manager. Normale Dateimanager
+ können dagegen von mehreren Benutzern in beliebiger Reihenfolge ange­
+ sprochen werden.
+
+ Ein Archivmanager kann auch auf bestimmte Diskettenformate spezialisert sein
+ (z.B. auf das Lesen von DOS-Disketten). Manche Rechner haben auch mehrere
+ Archivmanager für verschiedene Laufwerke etc. Durch Einstellen unterschied­
+ licher Archivmanager können Sie dann auf verschiedenen Laufwerken
+ archivieren.
+
+ Nach Aktivieren dieses Menupunktes werden Ihnen die folgenden Alternativen
+ angeboten:
+
+
+ +-----------------------------------------+
+ | Dateiaustausch gewünscht mit: |
+ | |
+ | a ...   Archiv (Eigene Station) |
+ | |
+ | v ...   Vatertask |
+ | |
+ | p ...   'PUBLIC' (Eigene Station) |
+ | |
+ | s ...   Sonstige Task |
+ | |
+ | Archiv   Vatertask   PUBLIC   Sonstige |
+ +-----------------------------------------+
+
+#center#Abb.33:  Auswahl der Zieltask
+
+ Da der Dateiaustausch mit dem Standardarchiv der eigenen Station (Task:
+ 'ARCHIVE'), mit der Vatertask und der Task 'PUBLIC' recht häufig in Anspruch
+ genommen wird, sind diese drei Optionen unter den Alternativen direkt ange­
+#page#
+ geben. Entscheiden Sie sich für eine dieser drei Tasks, so nimmt das System
+ alle notwendigen Einstellungen vor. Möchten Sie dagegen in Kontakt mit einer
+ anderen Task treten, so wählen Sie die Alternative 's ... Sonstige Task'. In
+ diesem Falle haben Sie noch 3 Angaben zu machen:
+
+ - Zunächst werden Sie nach dem Namen der Zieltask gefragt. Geben Sie den
+ Namen der Zieltask - ohne Anführungsstriche (!) - ein und schließen Sie
+ die Eingabe mit der <RETURN>-Taste ab. (Den ausgegebenen Namen der
+ z.Z. eingestellten Task können Sie dabei verändern bzw. überschreiben.)
+
+ - Dann wird die Nummer der Station im EUMEL-Netz erfragt, auf der sich
+ die Zieltask befindet. Die Nummer Ihrer Station wird als Vorschlag ausge­
+ geben. Wollen Sie mit einer Task auf Ihrem Rechner kommunizieren, so
+ brauchen Sie diesen Vorschlag nur durch Drücken der <RETURN>-Taste
+ bestätigen - ansonsten tragen Sie zuvor die entsprechende Stationsnummer
+ ein. Ist Ihr Rechner nicht in ein EUMEL-Netz integriert, so wird die
+ Stationsnummer 0 (Null) ausgegeben. Bitte bestätigen Sie diese Stations­
+ nummer durch Tippen der <RETURN>-Taste.
+
+ - Zum Abschluß müssen Sie noch angeben, ob die eingestellte Zieltask ein
+ Archivmanager ist oder nicht.
+
+ Das System versucht dann den Kontakt herzustellen. Je nachdem, welche
+ Einstellung Sie vorgenommen haben, sind bestimmte Funktionen innerhalb
+ des Menus nicht aktivierbar. Das System läßt nur die Funktionen zu, die
+ aufgrund Ihrer Einstellungen zulässig sind.
+
+ Im Kasten unten auf dem Bildschirm wird jeweils angezeigt, welche Zieltask
+ eingestellt ist. Erscheint in diesem Kasten auch ein Hinweis auf den Archiv­
+ namen, so haben Sie einen Archivmanager eingestellt. Ist dagegen vor dem
+ Namen der Zieltask noch eine Zahl und ein Schrägstrich angegeben, so haben
+ Sie eine Zieltask auf einem anderen Rechner eingestellt.
+#page#
+ Bedenken Sie, daß Operationen mit Tasks auf anderen Stationen länger an­
+ dauern können - werden Sie nicht ungeduldig!
+
+ Sie können die Einstellung der Zieltask jederzeit wieder verändern!
+
+ Fehlerfälle:
+ - Die eingestellte Zieltask existiert nicht.
+ - Die eingestellte Zieltask existiert zwar, ist aber nicht empfangsbereit, d.h.
+ ein Zugriff von Ihrer Task aus ist nicht möglich!
+ - Das Netz ist nicht funktionsbereit (Collector-Task fehlt).
+ - Die Kommunikation war nicht erfolgreich.
+ - Die gewünschte Operation kann mit der eingestellten Zieltask nicht ausge­
+ führt werden (Zieltask ist z.B. gar kein Archivmanager - Sie aber ver­
+ suchen, das Laufwerk zu reservieren).
+
diff --git a/doc/prozess/gs-prozess-8 b/doc/prozess/gs-prozess-8
new file mode 100644
index 0000000..c36ccc9
--- /dev/null
+++ b/doc/prozess/gs-prozess-8
@@ -0,0 +1,377 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#on("b")#8  Detailbeschreibung der Basisbefehle und Tests#off("b")#
+
+
+#on("b")#
+BOOL PROC abbruch gewuenscht
+#off("b")#
+
+ - erfragt, ob inzwischen durch einen Basisbefehl die Tastenfolge <ESC><q>
+ im Eingabestrom registriert worden ist. Ist das der Fall, liefert die Prozedur
+ den Wert 'TRUE', sonst 'FALSE'.
+
+
+#on("b")#
+BOOL PROC bit ist gesetzt (INT CONST kanal, bitnummer)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Digital-Eingabe möglich!".
+ - untersucht, ob die angegebene Bitnummer zulässig ist (0 #on("b")#<#off("b")# 'bitnummer' #on("b")#<#off("b")#
+ 7). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung "Bit­
+ nummer ... ist nicht zulässig!".
+ - liest den aktuell anliegenden Wert am angegebenen Kanal.
+ - liefert den Wert 'TRUE', wenn in der binären Darstellung das Bit mit der
+ angegebenen Bitnummer gesetzt ist ("I"), sonst den Wert 'FALSE'.
+
+#on("b")#
+TEXT PROC bitmuster (INT CONST kanal)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+#page#
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Digital-Eingabe möglich!".
+ - liest den aktuell anliegenden Wert am angegebenen Kanal ein und wandelt
+ ihn in die binäre Darstellung.
+ - liefert einen Text der Länge 8, bestehend aus den Zeichen "I" und/oder "O".
+
+
+#on("b")#
+PROC bitmuster ausgeben (INT CONST kanal,
+ TEXT CONST bitmuster)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Aus­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Digital-Ausgabe möglich!".
+ - untersucht die übergebene Zeichenkette (bitmuster) auf korrekte Länge (8
+ Zeichen). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung
+ "Das Bitmuster ... hat eine unzulässige Länge!".
+ - überprüft die in der übergebenen Zeichenkette (bitmuster) vorkommenden
+ Symbole auf ihre Zulässigkeit ("I", "O", "X", "T"). Taucht ein unzulässiges
+ Symbol auf, erfolgt ein Abbruch mit der Fehlermeldung "... ist ein unzu­
+ lässiges Bitsymbol in ...!".
+#page#
+ - aus dem am angegebenen Kanal zuletzt ausgegeben Wert und der über­
+ gebenen Zeichenkette (bitmuster) wird der auszugebende Dezimalwert er­
+ mittelt. Dieser Dezimalwert wird am angegebenen Kanal ausgegeben. Dabei
+ bedeuten "I", daß das betreffende Bit gesetzt wird,  "O", daß das betreffende
+ Bit nicht gesetzt wird,  "X", daß das betreffende Bit gegenüber der zuvor
+ erfolgten Ausgabe am gleichen Kanal nicht verändert wird und   "T", daß das
+ betreffende Bit gegenüber der zuvor erfolgten Ausgabe am gleichen Kanal
+ invertiert wird.
+
+
+#on("b")#
+BOOL PROC bitmuster gleich (INT CONST kanal,
+ TEXT CONST vergleichsmuster)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Digital-Eingabe möglich!".
+ - untersucht die übergebene Zeichenkette (bitmuster) auf korrekte Länge (8
+ Zeichen). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung
+ "Das Bitmuster ... hat eine unzulässige Länge!".
+ - überprüft die im 'vergleichsmuster' vorkommenden Symbole auf ihre Zu­
+ lässigkeit ("I", "O", "X"). Taucht ein unzulässiges Symbol auf, erfolgt ein
+ Abbruch mit der Fehlermeldung "... ist ein unzulässiges Bitsymbol in ...!".
+ - liest den aktuell anliegenden Wert am angegebenen Kanal ein und wandelt
+ ihn in die binäre Darstellung.
+ - überprüft, ob das eingelesene Bitmuster zum 'vergleichsmuster' "paßt". Ist
+ das der Fall, wird der Wert 'TRUE' geliefert, sonst der Wert 'FALSE'.
+#page#
+#on("b")#
+TEXT PROC bitsymbol (INT CONST kanal, bitnummer)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Digital-Eingabe möglich!".
+ - untersucht, ob die angegebene Bitnummer zulässig ist (0 #on("b")#<#off("b")# 'bitnummer' #on("b")#<#off("b")#
+ 7). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung "Bit­
+ nummer ... ist nicht zulässig!".
+ - liest den aktuell anliegenden Wert am angegebenen Kanal ein und wandelt
+ ihn in die binäre Darstellung.
+ - liefert einen Text der Länge 1, nämlich "I" oder "O".
+
+
+#on("b")#
+PROC bitsymbol ausgeben (INT CONST kanalnummer, bitnummer,
+ TEXT CONST bitsymbol)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Aus­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Digital-Ausgabe möglich!".
+#page#
+ - untersucht, ob die angegebene Bitnummer zulässig ist (0 #on("b")#<#off("b")# 'bitnummer' #on("b")#<#off("b")#
+ 7). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung "Bit­
+ nummer ... ist nicht zulässig!".
+ - überprüft das übergebene Bitsymbol auf Zulässigkeit ("I", "O", "X", "T").
+ Taucht ein unzulässiges Symbol auf oder besteht das Bitsymbol aus mehr als
+ einem Zeichen, erfolgt ein Abbruch mit der Fehlermeldung "... ist ein unzu­
+ lässiges Bitsymbol!".
+ - ermittelt aus dem am angegebenen Kanal zuletzt ausgegeben Wert und der
+ übergebenen Bitnummer/dem übergebenen Bitsymbol den auszugebende
+ Dezimalwert. Dieser Dezimalwert wird am angegebenen Kanal ausgegeben.
+ Dabei bedeuten "I", daß das betreffende Bit gesetzt wird,  "O", daß das be­
+ treffende Bit nicht gesetzt wird,  "X", daß das betreffende Bit gegenüber der
+ zuvor erfolgten Ausgabe am gleichen Kanal nicht verändert wird und  "T", daß
+ das betreffende Bit gegenüber der zuvor erfolgten Ausgabe am gleichen Kanal
+ invertiert wird.
+
+
+#on("b")#
+INT PROC dezimalwert (INT CONST kanal)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Digital-Eingabe möglich!".
+ - liest den aktuell anliegenden Wert am angegebenen Kanal ein.
+ - liefert einen INT-Wert mit  0 #on("b")#<#off("b")# 'wert' #on("b")#<#off("b")# 255.
+#page#
+#on("b")#
+PROC dezimalwert ausgeben (INT CONST kanal, wert)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Aus­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Digital-Ausgabe möglich!".
+ - ermittelt den auszugebenden Wert durch die Rechnung
+#on("b")#
+#center#ausgabe = wert MOD 256,
+#off("b")#
+ und gibt diesen am angegebenen Kanal aus.
+
+
+#on("b")#
+PROC initialisiere interface
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob das Programm korrekt (mit 'run pdv') gestartet wurde. Ist das
+ nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung "PDV-Programme
+ müssen mit 'run pdv' gestartet werden!". Dieser Fehler kann nicht auftreten,
+ wenn die Programme vom #on("b")#gs-Prozess#off("b")#-Menu gestartet werden!
+ - An jeden Digitalausgang des angeschlossenen Interface-Systems wird der Wert
+ '0', an jeden Analogausgang eine "Nullspannung" angelegt (d.h. alles wird
+ "ausgeschaltet"). Die internen Variablen werden dabei initialisiert.
+#page#
+#on("b")#
+PROC spannungswert (INT CONST kanal)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine analoge Ein­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Analog-Eingabe möglich!".
+ - ermittelt die laut Konfiguration aktuelle Obergrenze (u max) und Untergrenze
+ (u min) des Spannungsbereiches am angegebenen Analogeingang.
+ - liest den aktuell anliegenden Wert (0 #on("b")#<#off("b")# 'wert' #on("b")#<#off("b")# 255) am angegebenen
+ Kanal ein und wandelt ihn nach folgender Rechnung:
+
+#on("b")#
+ real(wert) * (u max - u min)
+ lieferwert = ---------------------------- + u min
+ 255.0
+
+#off("b")#
+ - liefert einen REAL-Wert mit  u min #on("b")#<#off("b")# 'lieferwert' #on("b")#<#off("b")# u max, gerundet auf drei
+ Nachkommastellen.
+
+
+#on("b")#
+PROC spannungswert ausgeben (INT CONST kanal,
+ REAL CONST spannung)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+#page#
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine analoge Aus­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Analog-Ausgabe möglich!".
+ - ermittelt die laut Konfiguration aktuelle Obergrenze (u max) und Untergrenze
+ (u min) des Spannungsbereiches am angegebenen Analogausgang und prüft,
+ ob  u min #on("b")#<#off("b")# 'spannung' #on("b")#<#off("b")# u max. Ist das nicht der Fall, erfolgt ein Abbruch
+ mit der Fehlermeldung 'Der Spannungswert ... ist nicht zulässig!".
+ - wandelt die angegebene 'spannung' nach der Rechnung:
+
+#on("b")#
+ (wert - u min) * 255.0
+ ausgabewert = int ( ---------------------- + 0.5 )
+ u max - u min
+
+#off("b")#
+ - gibt den ermittelten 'ausgabewert' am angegebenen Kanal aus.
+
+
+#on("b")#
+REAL PROC temperatur (REAL CONST spannungswert)
+#off("b")#
+
+ - errechnet aus dem Spannungswert, der vom Temperaturfühler eingelesen
+ wurde, der Thermometerkonstanten und der Minimaltemperatur die
+ Temperatur in �C.
+ - liefert einen REAL-Wert (die Temperatur in �C).
+ So nur anwendbar auf den Temperaturfühler der Fa. AKTRONIK!
+
+
+#on("b")#
+PROC tue nichts
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+#page#
+#on("b")#
+PROC warte (INT CONST sekunden)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - wirkt sonst wie 'pause (sekunden * 10)'.
+
+
+#on("b")#
+PROC warte (REAL CONST sekunden)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - wirkt sonst wie 'pause (int (sekunden * 10.0 + 0.5))'.
+
+
+#on("b")#
+PROC wert an analogausgang ausgeben (INT CONST kanal, wert)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine analoge Aus­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Analog-Ausgabe möglich!".
+ - ermittelt den auszugebenden Wert durch die Rechnung
+
+#on("b")#
+#center#ausgabe = wert MOD 256,
+
+#off("b")#
+ und gibt diesen Wert am angegebenen Kanal aus. Die am Analogausgang
+ auszugebende Spannung wird vom D/A-Wandler des Interface-Systems er­
+ mittelt.
+#page#
+#on("b")#
+INT PROC wert von analogeingang (INT CONST kanal)
+#off("b")#
+
+ - untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+ Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+ "Programm-Abbruch durch <ESC><h>!".
+ - registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde.
+ - untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+ 'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "Kanalnummer ... ist unzulässig!".
+ - untersucht, ob am angegebenen Kanal laut Konfiguration eine analoge Ein­
+ gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+ meldung "An Kanal ... ist keine Analog-Eingabe möglich!".
+ - liefert den vom A/D-Wandler des Interface-Systems gelieferten Wert mit 0 #on("b")#<#off("b")#
+ 'lieferwert' #on("b")#<#off("b")# 255.
+
diff --git a/doc/prozess/gs-prozess-9 b/doc/prozess/gs-prozess-9
new file mode 100644
index 0000000..6551b01
--- /dev/null
+++ b/doc/prozess/gs-prozess-9
@@ -0,0 +1,477 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (1)#
+#headodd#
+#center#gs-Prozess#right#%
+
+#end#
+#headeven#
+%#center#gs-Prozess
+
+#end#
+#center#1
+
+#on("b")#9  Hinweise für den Systembetreuer/   Programmierer#off("b")#
+
+Sie haben wahrscheinlich bisher - ausschließlich zu Testzwecken - mit nur einem
+Interface-System gearbeitet. In diesem Kapitel möchten wir Ihnen Vorschläge
+machen, wie Sie Ihr Tasksystem organisieren können, um möglichst effektiv und
+störungsfrei mit der vorhandenen Hardware zu arbeiten.
+
+Neben den Möglichkeiten der Organisation des Systems werden wir Ihnen zeigen, wie
+Sie eine einmal vorgenommene Konfiguration/Organisation "fixieren", d.h. schützen
+können.
+
+Im letzten Teil dieses Kapitels werden wir für den #on("b")#routinierten(!) Programmierer#off("b")#,
+Möglichkeiten aufzeigen, wie man, unter weitgehender Umgehung von #on("b")#gs-Prozess#off("b")#,
+Programme für spezielle Anwendungen entwickeln kann. Schon an dieser Stelle sei
+ausdrücklich gesagt, daß dabei alle "Sicherheiten", die #on("b")#gs-Prozess#off("b")# normalerweise
+bietet, nicht (mehr) vorhanden sind.
+
+
+#on("b")#9.1  Vergabe der Kanäle/Organisation des Tasksystems#off("b")#
+
+Zur optimalen Organisation Ihres Systems sollten Sie wissen, in welcher Task die
+Konfiguration sinnvollerweise vorzunehmen ist. Da die Aspekte sehr vielfältig sind,
+werden wir verschiedene Situationen beschreiben. Lesen Sie die Ausführungen zu der
+Situation, die der Ihren am ehesten entspricht.
+
+
+#on("b")#
+1) Es stehen mehrere MUFIs als Adapter zur Verfügung. Alle MUFIs sollen
+ im Terminalkanal betrieben werden. Die Arbeitsplätze sind alle mit
+ dem gleichen Interfacesystem ausgestattet.
+#off("b")#
+#page#
+ Sie sind hervorragend ausgestattet. Die Organisation und Konfiguration des
+ Systems ist sehr einfach:
+
+ Es ist sinnvoll, die Konfiguration von #on("b")#gs-Prozess#off("b")# in der Task vorzunehmen, in
+ der Sie #on("b")#gs-Prozess#off("b")# installiert haben. Das hat den Vorteil, daß alle Sohntasks,
+ die sich anschließend anmelden, diese Konfiguration "erben".
+
+ Bei dieser Ausstattung ist es sinnvoll die Konfiguration zu "fixieren", um irrtüm­
+ lichen oder "böswilligen" Umkonfigurationen vorzubeugen. Sehen Sie dazu
+ Kapitel 9.4.
+
+
+#on("b")#
+2) Es stehen mehrere MUFIs als Adapter zur Verfügung. Alle MUFIs sollen
+ im Terminalkanal betrieben werden. Die Arbeitsplätze sind aber mit
+ verschiedenen Interface-Systemen ausgestattet.
+#off("b")#
+
+ Wenn die Bestückung der einzelnen Arbeitsplätze ständig wechselt, ist es nicht
+ sinnvoll, eine generelle Konfiguration vorzugeben. Teilen Sie jedem Anwender
+ mit, daß er selbst für die Konfiguration seines Systems zuständig ist. Er sollte bei
+ jedem Neuankoppeln seiner Task zumindest die Konfiguration überprüfen und
+ ggf. den Vorgaben entsprechend eine Anpassung vornehmen. Es ist nicht sinn­
+ voll, die jeweilige Konfiguration zu fixieren.
+
+ Wenn Sie zwar unterschiedliche Interface-Systeme verwenden, aber die Inter­
+ face-Systeme einzelnen MUFIs eindeutig zuordnen können, lohnt es sich schon,
+ eine Konfiguration des Systems vorzugeben.
+
+ Richten Sie zu diesem Zwecke so viele Tasks ein, wie Sie unterschiedliche
+ Interface-Systeme zur Verfügung haben, und ordnen Sie jedem Interface-System
+ eindeutig je eine Task zu. Die Namen der Tasks sollten Sie so wählen, daß sofort
+ ersichtlich ist, welchem Interface-System sie zugeordnet ist.
+
+ Nehmen Sie in jeder Task eine Konfiguration von #on("b")#gs-Prozess#off("b")# entsprechend
+ dem zugeordneten Interface-System vor.
+#page#
+ Auch hier ist es sinnvoll, die vorgenommenen Konfigurationen zu "fixieren", um
+ irrtümlichen oder "böswilligen" Umkonfigurationen vorzubeugen. Sehen Sie
+ dazu Kapitel 9.4.
+
+ Die Anwender sollten sich später jeweils als Sohntask der Task anmelden, die
+ sich dem an ihrem Arbeitsplatz vorhandenen Interface-System eindeutig zu­
+ ordnen läßt.
+
+
+#on("b")#
+3) Es steht nur ein MUFI als Adapter zur Verfügung. Das MUFI soll im
+ Terminalkanal betrieben werden.
+#off("b")#
+
+ Je nachdem, ob Sie eine feste Hardware am MUFI betreiben oder nicht, sollten
+ Sie sich an den beiden zuvor beschriebenen Fällen orientieren.
+
+
+#on("b")#
+4) Es steht nur ein RS232-Adapter oder ein MUFI, das als Endgerät an
+ einer separaten Schnittstelle betrieben werden soll, zur Verfügung. Es
+ soll nur von einem Arbeitsplatz/einer Task aus mit dem angeschlos­
+ senen Interface-System gearbeitet werden.
+#off("b")#
+
+ Nehmen Sie die Installation/Konfiguration wie unter 5) beschrieben vor.
+ Arbeiten Sie nur in der Task, in der Sie die Konfiguration vorgenommen haben.
+
+
+#on("b")#
+5) Es steht nur ein Adapter zur Verfügung. Sie wollen aber die Möglichkeit
+ schaffen, daß von verschiedenen Tasks abwechselnd darauf zugegriffen
+ werden kann.
+#off("b")#
+
+ Es ist gleichgültig, ob Sie ein MUFI oder einen RS232-Adapter verwenden - sie
+ sollten den Adapter an einer separaten seriellen Schnittstelle betreiben.
+#page#
+ Auch wenn Sie ein MUFI besitzen, kann es vorteilhaft sein, das MUFI nicht im
+ Terminalkanal, sondern an einer separaten Schnittstelle zu betreiben:
+
+ Beim Betrieb im Terminalkanal kann nämlich nur die Task mit dem MUFI
+ kommunizieren, die an das Terminal gekoppelt ist, in dessen Zuleitung das
+ MUFI eingebaut ist. Das wird hier zum Nachteil, denn wenn eine andere Task
+ auf das Interface-System zugreifen möchte, muß erst die alte Task abgekoppelt
+ und die neue an das Terminal mit dem MUFI angekoppelt werden.
+
+ Der Betrieb an einer separaten Schnittstelle bietet hier wahrscheinlich viel­
+ fältigere Möglichkeiten, wenngleich Sie dadurch auch Geschwindigkeitsein­
+ bußen hinnehmen müssen.
+
+ #on("b")#gs-Prozess#off("b")# bietet Ihnen bei Betrieb eines Adapters an einer separaten seriellen
+ Schnittstelle nämlich die Möglichkeit, abwechselnd von verschiedenen Tasks auf
+ den Adapter und das angeschlossene Interface-System zugreifen zu können.
+
+ Teilen Sie bei der Installation (automatischen Generierung) von #on("b")#gs-Prozess#off("b")#
+ dem System gleich mit, daß Sie Ihren Adapter (ob nun MUFI oder
+ RS232-Adapter) an einer separaten seriellen Schnittstelle betreiben wollen.
+ Schon bei dieser Installation werden Sie nach der Kanalnummer gefragt.
+
+ Wir gehen hier davon aus, daß Sie immer mit dem gleichen Interface-System an
+ diesem Adapter arbeiten werden. In diesem Falle empfiehlt es sich, gleich in der
+ Task, in der Sie die Installation vorgenommen haben, auch die Konfiguration
+ von #on("b")#gs-Prozess#off("b")# vorzunehmen und die Konfiguration zu "fixieren". Durch die
+ Konfiguration in dieser Task, "erben" alle Sohntasks, die anschließend ange­
+ meldet werden, diese Konfiguration.
+
+ Wenn Sie sich mit 'taskinfo <RETURN>' einen Katalog ausgeben lassen,
+ werden Sie feststellen, daß eine weitere Task als unbenannter Sohn ("-") Ihrer
+ Task eingerichtet worden ist. Sie haben nämlich Ihre Task zu einer "zentralen
+ Abwicklungstask" gemacht - genauer gesagt die unbenannte Sohntask.
+#page#
+ Wenn Sie aus Ihrer Task, in der Sie die Konfiguration vorgenommen haben, mit
+ dem Interface-System kommunizieren, erfolgt der Zugriff über diese unbe­
+ nannte Sohntask!
+
+ Sie schaffen dadurch aber zusätzlich die Möglichkeit, daß mehrere Sohntasks -
+ natürlich abwechselnd - über diese "zentrale Abwicklungstask" mit dem Inter­
+ face-System kommunizieren. Selbstverständlich setzt der Zugriff auf das Inter­
+ face-System eine Absprache zwischen den Beteiligten voraus!
+
+
+ Gerade in der Aufbauphase, wenn erst wenige Geräte zur Verfügung stehen, ist
+ das eine Möglichkeit, von verschiedenen Arbeitsplätzen aus mit nur einem Adap­
+ ter/Interface-System Prozeßdatenverarbeitung zu betreiben.
+
+
+#on("b")#
+6) Sie wollen mehrere Adapter an separaten seriellen Schnittstellen
+ betreiben.
+#off("b")#
+
+ In diesem Falle ist es sinnvoll - bevor Sie eine Konfiguration vornehmen - gleich
+ nach der Installation von #on("b")#gs-Prozess#off("b")# für jeden einzelnen Adapter eine Sohntask
+ unter der Task einzurichten, in der #on("b")#gs-Prozess#off("b")# installiert ist. Jede dieser Sohn­
+ tasks koppeln Sie mit einem festen Kanal, an dem ein Adapter/Interface-System
+ angeschlossen ist.
+
+ Sie brauchen dazu #on("b")#gs-Prozess#off("b")# nicht mehrfach zu installieren; wir haben für
+ diesen Fall vorgesorgt. Für die Kopplung der Tasks an die einzelnen Kanäle steht
+ die Prozedur 'PROC interfacekanal (INT CONST kanalnummer)' zur Verfügung.
+ Geben Sie also in einer Task z.B. das Kommando 'interfacekanal (5)
+ <RETURN>', so wird von dieser Task aus das Interface-System am Kanal 5
+ angesprochen.
+
+ Über die Prozedur 'INT PROC interfacekanal' können Sie sich in jeder Task
+ informieren, über welchen Kanal die Kommunikation mit dem Interface-System
+ abgewickelt wird: z.B. mit 'put (interfacekanal) <RETURN>'.
+#page#
+ Ihnen ist sicher klar, daß es auch hier sinnvoll ist, den Namen der jeweiligen
+ Task so zu wählen, daß daraus sofort der betreffende Interfacekanal ablesbar
+ ist.
+
+ In jeder so an einen Kanal gekoppelten Task sollten Sie die Konfiguration von
+ #on("b")#gs-Prozess#off("b")# vornehmen und ggf. "fixieren". Jede solche Task richtet auto­
+ matisch eine unbenannte Sohntask ("-") ein, die sich wie eine "zentrale Ab­
+ wicklungstask" verhält. Wenn Sie also aus Ihrer Task oder aus neu einge­
+ richteten Sohntasks mit dem Interface-System kommunizieren, so erfolgt das
+ über die "zentrale Abwicklungstask".
+
+
+#on("b")#9.2  Informationsprozeduren#off("b")#
+
+Zur Information stehen dem Systembetreuer drei wichtige Prozeduren zur Verfügung:
+
+#on("b")#
+TEXT PROC adapterart
+#off("b")#
+
+Hiermit können Sie in Erfahrung bringen, welche Interfaceanpassung z.Z. in der
+aktuellen Task insertiert ist: MUFI im Terminalkanal, MUFI als Endgerät oder
+AKTRONIK-Adapter (RS232-Adapter).
+
+
+#on("b")#
+INT PROC interfacekanal
+#off("b")#
+
+Hiermit können Sie in Erfahrung bringen, über welchen Kanal z.Z. mit dem Inter­
+face-System aus der Task kommuniziert wird. Die Prozedur steht allerdings nur dann
+zur Verfügung, wenn das Interface-System an einer separaten Schnittstelle betrieben
+wird - sonst erscheint der Hinweis 'FEHLER: unbekanntes Kommando'.
+
+Es gibt noch einen Befehl, mit dem Sie sich über den Zustand des Interface-Systems
+informieren können:
+#page#
+#on("b")#
+PROC oeffne interface (INT VAR testwert)
+#off("b")#
+
+Die Prozedur versucht, die aktuelle Betriebsart einzustellen. Anschließend erhalten
+Sie eine 'Erfolgsauskunft'. Dabei bedeuten:
+
+ 0 - alles okay
+ -1 - Interface ist noch nicht konfiguriert
+ -2 - Interface-Task ist besetzt
+ -3 - Interfacekanal ist belegt
+ -4 - Interface meldet sich nicht
+ -5 - Interface kann nicht geöffnet werden
+
+Ist der Adapter an einer separaten Schnittstelle angeschlossen, so arbeitet der Befehl
+über die "zentrale Abwicklungstask". Als Antwort können alle genannten Codes auftre­
+ten; beim MUFI im Terminalkanal allerdings nur die Codes 0, -1 und -4. Die oben
+genannten Fehlermeldungen sind detailliert in Kapitel 5.5 erläutert.
+
+Sie sollten anschließend #on("b")#unbedingt#off("b")# das Kommando 'schliesse interface' geben: Eine
+eventuell durch 'oeffne interface' vollzogene Betriebsartumstellung wird dadurch
+rückgängig gemacht.
+
+
+
+#on("b")#9.3  Neufestlegung des Interfacekanals#off("b")#
+
+Wenn Sie mit MUFI(s) im Terminalkanal arbeiten, spielen Kanalnummern für das
+Ansprechen des/der MUFIs keine Rolle. Das jeweilige MUFI kann in diesem Falle
+nämlich immer nur von der Task aus angesprochen werden, die an das Terminal
+gekoppelt ist, in dessen Zuleitung das MUFI eingebaut wurde.
+
+Wenn Sie Adapter (MUFI oder RS232-Adapter) an separaten seriellen Schnittstellen
+betreiben, so legen Sie schon bei der Installation von #on("b")#gs-Prozess#off("b")# den Kanal fest,
+über den die Task mit dem Interface-System kommuniziert. Wie wir schon oben be­
+schrieben haben, können Sie den Interface-Kanal mit der Prozedur 'PROC interface­
+kanal (INT CONST kanalnummer)' neu festlegen. Beachten Sie dabei aber bitte
+folgendes:
+#page#
+Wenn Sie in einer Task #on("b")#gs-Prozess#off("b")# konfigurieren und zuvor entschieden haben, daß
+der Adapter an einer separaten Schnittstelle betrieben wird, so wird automatisch eine
+unbenannte Sohntask ("-") eingerichtet. Diese Sohntask wird zur "zentralen Abwick­
+lungstask". Wenn Sie nun aus der Task, in der Sie die Konfiguration vorgenommen
+haben, oder aus einer Sohntask dieser Task, die anschließend eingerichtet wird, mit
+dem Interface-System kommunizieren, so erfolgt diese Kommunikation über diese
+unbenannte Sohntask. Daher wählten wir die Bezeichnung "zentrale Abwicklungs­
+task".
+
+Da die "zentrale Abwicklungstask" den "Zustand der Vatertask" in dem Augenblick
+erbt, in dem Sie eingerichtet wird, würde eine später erfolgende Neufestlegung des
+Interfacekanals nicht von Ihr registriert und damit auch nicht wirksam.
+
+#on("b")#Es ist unbedingt notwendig#off("b")#, in der Task, in der Sie eine Neufestlegung des Interface-
+Kanals vornehmen, #on("b")#gs-Prozess#off("b")# auch neu zu konfigurieren! Bei der Neukonfiguration
+wird nämlich die unbenannte Sohntask gelöscht und neu eingerichtet.
+
+(Das hier beschriebene Phänomen ist Ihnen wahrscheinlich schon aus der
+PRINTER-Task bekannt).
+
+Hinsichtlich der Sicherheit des Systems hat dieses Vorgehen aber einen Vorteil: wenn
+in den "zugänglichen Sohntask", die über eine "zentrale Abwicklungstask" mit dem
+Interface-System kommunizieren eine Neueinstellung des Interface-Kanals vorge­
+nommen wird, so bleibt diese unwirksam (solange in der Sohntask nicht umkonfigu­
+riert wird - was sich aber verhindern läßt! Sehen Sie dazu das folgende Kapitel!).
+
+
+#on("b")#9.4  Fixieren der Konfiguration#off("b")#
+
+Prinzipiell kann in jeder Task, in der #on("b")#gs-Prozess#off("b")# zur Verfügung steht, die Konfigura­
+tion (von #on("b")#gs-Prozess#off("b")#) vorgenommen werden. Gerade von unerfahrenen Anwendern
+könnte aber irrtümlich eine Umkonfiguration vorgenommen werden. Aber nicht nur
+das: auch erfahrene Anwender könnten "böswillig" die Konfiguration verändern. Aus
+diesem Grunde ist es ggf. sinnvoll, eine vorgenommene Konfiguration zu fixieren
+(schützen).
+#page#
+Dazu steht die Prozedur 'PROC pdv konfiguration zugelassen (BOOL CONST ent­
+scheidung)' zur Verfügung. Mit dem Kommando 'pdv konfiguration zugelassen
+(FALSE) <RETURN>' sperren Sie in der aktuellen Task und in allen Sohntasks, die
+sich #on("b")#anschließend#off("b")# unter dieser Task anmelden, den Menupunkt 'k Konfigurieren'
+unter dem Oberbegriff 'Interface'.
+
+Sofern nötig, können Sie diese Sperre mit dem Kommando 'pdv konfiguration zuge­
+lassen (TRUE) <RETURN>' wieder aufheben, #on("b")#allerdings nur in der Task, in der Sie
+auch die Sperre gesetzt haben#off("b")#, denn #on("b")#gs-Prozess#off("b")# merkt sich diesen Tasknamen!
+Wenn Sie also ein Password auf diese Task legen, und damit anderen den Zugang
+verwehren, kann auch eine "böswilligie Umkonfiguration" verhindert werden.
+
+
+#on("b")#9.5  Mögliche Fehlerfälle#off("b")#
+
+Wenn Fehlermeldungen auftreten, so finden Sie Fehlerbeschreibungen und Möglich­
+keiten zur Abhilfe im Kapitel 5.5 beschrieben. Auf einen Fehlerzustand möchten wir
+Sie hier noch besonders hinweisen:
+
+#on("b")#Interfacekanal ist belegt!#off("b")#
+
+ Über den angegebenen Kanal greift schon eine andere Task auf das angeschlos­
+ sene Interface-System zu. Vielleicht wurde der betreffende Kanal auch zuvor für
+ andere Zwecke verwendet - anschließend hat der Benutzer den Kanal nicht
+ ordentlich freigegeben. Geben Sie in der 'gib kommmando'-Ebene den Befehl
+ 'taskinfo (2) <RETURN>'. In der Spalte mit der Überschrift 'CHAN' müßte jetzt
+ irgendwo die Kanalnummer auftauchen. Steht die Kanalnummer bei einem Sohn
+ der Task 'SUPERVISOR', so liegt der letztgenannte Fall vor, sonst der erstge­
+ nannte.
+
+ Abhilfe: Schließen Sie Ihr Interface-System an einen anderen Kanal an oder
+ bitten Sie den betreffenden Anwender, den Kanal freizugeben.
+ Ist das nicht möglich, so kann aus einer Systemtask das Kommando
+ 'end (canal (kanalnummer))' <RETURN>' gegeben werden. Statt
+ 'kanalnummer' ist natürlich die tatsächliche Nummer (z.B. '4')
+ anzugeben.
+#page#
+#on("b")#9.6  Weitere Möglichkeiten#off("b")#
+
+Ihnen ist sicher aufgefallen, daß wir uns bemüht haben, einen sinnvollen Kompro­
+miß zwischen Sicherheit in der Handhabung und Geschwindigkeit des Systems zu
+finden. In Zweifelsfällen haben wir uns eher zugunsten der Sicherheit entschieden.
+
+Sicher werden Sie inzwischen bemerkt haben, daß die Kommunikation mit einem
+Adapter (MUFI oder RS232-Adapter) an einer separaten seriellen Schnittstelle recht
+zeitaufwendig ist.
+
+Prinzipiell standen uns bei der Konzeption zwei Möglichkeiten zur Verfügung: Ent­
+weder wir gestalten jeden Basisbefehl so, daß wir uns zu Beginn der Ausführung
+jeweils direkt an den betreffenden Kanal ankoppeln und am Ende der Ausführung
+des Befehls wieder abkoppeln - oder wir richten eine "zentrale Abwicklungstask" ein
+und nutzen die Intertaskkommunikation des EUMELs. Wir haben uns nach diversen
+Tests für die zweite Variante entschieden: Einmal zeigte sich, daß dieses Verfahren
+weit weniger zeitaufwendig ist als das ständige An- und Abkoppeln an den Interface-
+Kanal. Zum anderen konnten wir so die Möglichkeit schaffen, über diese "zentrale
+Abwicklungstask" den abwechselnden, koordinierten Zugriff mehrerer Tasks auf ein
+Interface-System zu realiseren.
+
+Wenn Sie nun aber spezielle Anwendungen schreiben wollen, für die die Geschwin­
+digkeit beim Ansprechen des Interface-Systems an einer separaten Schnittstelle nicht
+ausreicht, so möchten wir Ihnen hier noch eine Möglichkeit aufzeigen, dieses
+Problem zu bewältigen.
+
+Auch an dieser Stelle sei noch einmal ausdrücklich darauf hingewiesen, daß Sie bei
+dieser Programmiermöglichkeit auf alle Sicherheiten, die Ihnen #on("b")#gs-Prozess#off("b")# bietet,
+verzichten müssen. Deshalb sollten Sie diesen Weg nur beschreiten, wenn Sie ein
+hinlängliches Maß an Programmierroutine besitzen! Die zur Verfügung stehenden
+Befehle und die Besonderheiten möchten wir Ihnen an einem kleinen Beispiel­
+programm aufzeigen:
+#page#
+#on("b")#
+ LET ausgabekanal = 4,
+ eingabekanal = 3;
+
+ INT VAR test, eingabewert;
+ INT VAR terminalkanal :: channel (myself);
+ schliesse interface;
+ continue (interfacekanal);
+ oeffne interface direkt (test);
+ IF test < 0
+ THEN continue (terminalkanal);
+ errorstop ("Funktionsfehler Interface-System")
+ FI;
+ initialisiere interface direkt;
+ eigentliches programm;
+ schliesse interface direkt;
+ continue (terminalkanal).
+
+ eigentliches programm:
+ direkt ausgeben (ausgabekanal, 3);
+ eingabewert := direkteingabe (eingabekanal).
+#off("b")#
+
+Wenn Sie ein solches Programm geschrieben haben, starten Sie es bitte mit dem
+Befehl 'run pdv' oder aus dem Menusystem heraus mit der Menufunktion 's Starten'.
+(Bei 'run' kann der Befehl 'schliesse interface' gestrichen werden!).
+
+Für die eigentliche Programmierung des Interface-Systems stehen Ihnen nur zwei
+Befehle zur Verfügung:
+
+#on("b")#
+PROC direkt ausgeben (INT CONST kanal, wert)
+#off("b")#
+
+ - ermittelt den auszugebenden Wert durch die Rechnung
+
+#on("b")##center#ausgabe = wert MOD 256#off("b")#
+
+ und gibt diesen am Ausgabekanal aus.
+
+ Der Befehl ähnelt dem Befehl 'dezimalwert ausgeben' - hat aber im Gegensatz
+ dazu keinerlei "Fehlerfänger": so werden Sie z.B. nicht darauf aufmerksam
+ gemacht, wenn der angegebene Kanal gar kein Ausgang ist, etc.)
+#page#
+#on("b")#
+INT PROC direkteingabe (INT CONST kanal)
+#off("b")#
+
+ - liest den aktuell anliegenden Wert am angegebenen Kanal ein.
+ - liefert einen INT-Wert mit 0 � 'wert' � 255.
+
+ Der Befehl ähnelt dem Befehl 'dezimalwert' - hat aber im Gegensatz dazu
+ ebenfalls keinerlei "Fehlerfänger"!
+
+
+Das obige Programm beginnt mit dem Befehl 'schliesse interface'. Sicher kommt es
+Ihnen sonderbar vor, daß zu Beginn des Programms das Interface geschlossen wird,
+wo wir es doch eigentlich "öffnen" müßten. Ihnen wird die Funktion aber sofort klar,
+wenn Sie sich die Situation vor Augen führen:
+
+Als Sie #on("b")#gs-Prozess#off("b")# in Ihrer Task konfiguriert haben, und festlegten, daß der Adapter
+an einer separaten Schnittstelle "hängt", richtete #on("b")#gs-Prozess#off("b")# automatisch eine
+unbenannte Sohntask ("-") als "zentrale Abwicklungstask" ein, die durch das
+Kommando 'run pdv' bzw. durch die Menufunktion 's Starten' an den Interfacekanal
+gekoppelt wird. Der Befehl 'schliesse interface' koppelt die Task "-" wieder vom Inter­
+face-Kanal ab, so daß Sie direkt darauf zugreifen können. Außerdem werden die
+internen Einstellungen im Adapter wieder in Ausgangsstellung gebracht.
+
+Mit der Prozedur 'PROC oeffne interface direkt (INT VAR testwert)' sprechen Sie das
+Interface neu an. Dabei wird ein angeschlossener Adapter automatisch auf Betriebs­
+bereitschaft getestet und dann auf den Betrieb an einer separaten seriellen Schnitt­
+stelle umgestellt (nur beim MUFI).
+
+Über 'testwert' erhalten Sie eine Rückmeldung. Dabei haben die gelieferten 'test­
+werte' folgende Bedeutung:
+
+ 0 - Interface betriebsbereit
+ -4 - Interface #on("b")#nicht#off("b")# betriebsbereit
+ (Interface meldet sich nicht)
+#page#
+Der Befehl 'initialisiere interface direkt' wirkt ähnlich wie der schon oben be­
+schriebene Befehl 'initialisiere interface', jedoch #on("b")#nicht#off("b")# über den "Umweg zentrale
+Abwicklungstask" - sondern halt 'direkt' am Interface-Kanal. Einzige Aufgabe hier:
+Alle Ausgabe-Kanäle auf Wert '0' bzw. Nullspannung setzen.
+
+Durch das abschließende 'schliesse interface direkt' bringen Sie ein angeschlossenes
+MUFI wieder in die "Ausgangsstellung".
+
+Beachten Sie bei der Programmierung bitte unbedingt, daß Sie ständig zwischen dem
+Kanal, an dem Sie arbeiten (Terminal) und dem Interfacekanal hin- und herschalten
+(müssen), wenn Ein- oder Ausgaben auf dem Terminal erfolgen sollen. Die direkte
+Programmierung lohnt sich demnach nur, wenn aufeinanderfolgende Aktionen am
+Interfacekanal durchgeführt werden (z.B. Schrittmotorsteuerungen etc.).
+
+Treten Programmfehler auf, während Sie an den Interfacekanal gekoppelt sind,
+haben Sie keine Chance, von Ihrem Terminalkanal aus auf das Interface zuzugreifen
+- denn das "hängt am Interfacekanal" (z.B. bei "Programmabsturz" oder Endlos­
+schleife).
+
+Bei Ihrer Programmierung sollten Sie diesem Fall vorbeugen (disable stop - enable
+stop). Ansonsten müßten Sie aus einer Systemtask den Kanal "abschießen". Geben
+Sie dazu in einer Systemtask z.B. das Kommando 'end (canal (5)) <RETURN>',
+wenn das Interface-System über den Kanal 5 angesprochen wird.
+
diff --git a/doc/system/systemhandbuch.1 b/doc/system/systemhandbuch.1
new file mode 100644
index 0000000..a8f53bb
--- /dev/null
+++ b/doc/system/systemhandbuch.1
@@ -0,0 +1,1685 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#Systemhandbuch
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#start(5.1,1.5)#
+#free(4.0)#
+#center#EUMEL
+
+
+#center#Systemhandbuch
+
+
+
+
+
+
+
+
+
+#center#copyright ERGOS GmbH, 1990
+
+
+#page#
+#block#
+
+Copyright: ERGOS GmbH April 1990
+
+ Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+ maschinenlesbare Form sowie das Speichern in Informations­
+ systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+ der ERGOS GmbH gestattet.
+
+
+ +-----------------------------------------------------+
+
+
+
+
+
+
+
+Autoren : Jochen Liedtke
+ Dietmar Heinrichs
+ Rainer Hahn
+ Christian Szymanski
+ Thomas Müller
+
+Texterstellung : Dieser Text wurde mit der ERGOS-EUMEL Textverarbeitung erstellt
+ und aufbereitet und auf einem Kyocera Laserdrucker ge­
+ druckt.
+#page#
+
+
+
+
+
+
+
+ +----------------------------------------------+
+
+
+
+
+#page#
+
+#start(2.5,1.5)#
+#pageblock#
+#block#
+#headeven#
+
+%#center#EUMEL-Systemhandbuch
+
+
+#end#
+#headodd#
+
+#center#Einführung#right#%
+
+
+#end#
+
+#ib(9)#Einführung#ie(9)#
+
+Der größte Teil dieses Systemhandbuchs ist für Anwender geschrieben, die tiefer in
+das EUMEL-System einsteigen und evtl. Systemergänzungen oder Systemänderun­
+gen programmieren wollen. Der erste Teil ist allerdings für alle interessant, die ein
+EUMEL-System verwenden, selbst für Anfänger, die ihr System zum ersten Mal in
+Betrieb nehmen wollen. Entsprechend der verschiedenen Adressatenkreise unter­
+scheiden sich die einzelnen Kapitel stark in der Beschreibungsart. Deshalb:
+
+#on("b")##on("i")#Sind Sie EUMEL-Neuling?#off("b")##off("i")#
+
+ Dann sollten Sie #on("b")##on("i")#vor#off("b")##off("i")# dem Einschalten Ihres Systems die Einführung des Kapi­
+ tels "System einrichten" lesen. Dort werden keine weiteren Kenntnisse voraus­
+ gesetzt. Danach sollten Sie erst einmal durch praktisches Arbeiten mit Hilfe des
+ Benutzerhandbuchs etwas mit dem System vertraut werden.
+
+
+#on("b")##on("i")#Haben Sie schon einige Zeit mit dem EUMEL gearbeitet?#off("b")##off("i")#
+#on("b")##on("i")#Sind Sie mit dem System einigermaßen vertraut?#off("b")##off("i")#
+
+ Dann lesen Sie den kompletten Teil 1 ("System einrichten") dieses Systemhand­
+ buchs.
+ Das Lesen der folgenden Kapitel ist für den einfachen Betrieb des EUMEL-
+ Systems nicht erforderlich. Sie setzen auch intime Kenntnis des Systems auf
+ dem Niveau des Benutzerhandbuchs voraus und würden Anfänger leicht verwir­
+ ren.
+
+
+#on("b")##on("i")#Haben Sie Probleme mit Ihrer Hardware?#off("b")##off("i")#
+
+ #on("i")#Wenn Sie nichts von Hardware verstehen, wenden Sie sich an einen Fachmann!#off("i")#
+
+ Wenn Sie ein gewisses Grundwissen über Hardware haben, dann lesen Sie Teil 2
+ ("Hardware und ihre Steuerung"). In diesem Kapitel sollten Sie "3. Kanä­
+ le und Konfigurierung" erst einmal auslassen.
+
+
+#on("b")##on("i")#Wollen Sie tiefer in das Betriebssystem einsteigen?#off("b")##off("i")#
+#on("b")##on("i")#Haben Sie EUMEL-Erfahrung?#off("b")##off("i")#
+#on("b")##on("i")#Haben Sie Programmiererfahrung?#off("b")##off("i")#
+
+ Dann lesen Sie im Systemhandbuch alles, was Ihnen interessant erscheint.
+#page#
+#headeven#
+
+%#center#EUMEL-Systemhandbuch
+
+
+#end#
+#headodd#
+
+#center#1. System einrichten#right#%
+
+
+#end#
+
+#ib(9)#1. #ib#System einrichten#ie##ie(9)#
+
+#ib(9)#1.1. Einführung#ie(9)#
+
+#ib(9)#Wie Ihr System aufgebaut ist#ie(9)#
+
+Der kleinstmögliche EUMEL-Rechner besteht aus einem #ib#Rechnerkern#ie# und einem Ter­
+minal:
+
+
+ Rechnerkern Terminal 1
+
+
+ #on("i")#Anmerkung: In manchen Fällen ist das Terminal hardwaremäßig in den Rechner
+ integriert. Trotzdem fassen wir diese physische Einheit dann als
+ zwei logisch getrennte Komponenten auf, nämlich Rechnerkern
+ und Terminal!#off("i")#
+
+Wie man sieht, hat das #ib#Terminal#ie# die Nummer 1. Das bedeutet, daß es über Kanal 1 mit
+dem Rechnerkern verbunden ist. Das EUMEL-System kennt 16 solche #ib#Kanäle#ie#, wobei es
+von der konkreten Hardware abhängt, welche Kanäle wirklich vorhanden sind und
+welche Geräte man daran anschließen kann. (Allerdings ist der Kanal 1 als Verbindung
+zum Terminal 1 immer vorhanden.)
+
+In den meisten Fällen wird auch ein #ib#Drucker#ie# angeschlossen sein. Die genaue An­
+schlußart ist wieder von der konkret verwendeten Hardware abhängig. Nehmen wir an,
+er sei an Kanal 4 angeschlossen:
+
+
+
+ Rechnerkern Terminal 1
+
+ Drucker (Kanal 4)
+
+
+
+Man sieht also, daß Lücken bei der Verwendung der Kanäle auftreten dürfen. Bei
+Multi-User-Systemen können, sofern die entsprechenden Schnittstellen vorhanden
+sind, weitere Terminals und andere Geräte (z.B. #ib#Plotter#ie#) angeschlossen werden:
+
+
+
+ Rechnerkern Terminal 1
+
+ Terminal 2
+
+ Plotter (Kanal 3)
+
+ Drucker (Kanal 4)
+
+ Terminal 5
+
+ Terminal 6
+
+
+
+
+
+#ib(9)#1.2. Wie Sie die EUMEL-Software erhalten und
+ installieren#ie(9)#
+
+
+
+Betriebssystem : EUMEL (Version 1.8)
+Hardware : IBM-PC/AT, IBM-PC/XT und Kompatible
+SHard-Version : 4.9 und 5.0
+
+Erforderliche Disketten
+
+ - EUMEL-Generierungsdiskette : "SETUP-EUMEL AT" (bzw. "SETUP-
+ EUMEL XT")
+ - EUMEL-Systemdisketten : "HG0" und "HG1" (EUMEL0-Maschine
+ und Hintergrund) evtl. auch nur eine 1,2
+ MB Hintergrunddiskette
+
+Die Diskette "SETUP-EUMEL" ist ein kleines EUMEL-System zur Installation des Be­
+triebssystems EUMEL auf einem AT/XT kompatiblen Rechner. Auf diesem System
+laufen Programme ab, die im Dialog mit dem Benutzer das Einrichten einer oder
+mehrerer EUMEL-Partitionen ermöglichen.
+#on("b")#Diese Diskette darf nicht schreibgeschützt sein!#off("b")#
+
+Beim Einrichten einer EUMEL-Partition wird nach Prüfung der Festplatte durch
+"SETUP-EUMEL" der hardwarenahe Teil des EUMEL-Systems, 'SHard' (Software/
+Hardware-Interface), auf die Festplatte geschrieben.
+
+Die Hintergrunddisketten beinhalten das eigentliche Betriebssystem EUMEL (den
+Systemkern (EUMEL-0-Maschine)) und die darauf aufbauenden Systemteile (Hinter­
+grund)).
+
+
+Leistungen des SETUP EUMEL
+
+Wenn Sie bereits ein Betriebssystem auf Ihrer Festplatte installiert haben, müssen Sie
+darauf achten, daß noch ausreichend Platz für ein EUMEL-System übrig ist. Die Min­
+destgröße einer Partition für ein EUMEL-System beträgt ca. 1MB, die maximale Größe
+ist vom benutzten Systemkern abhängig: der in der Version 1.8.6 M+ verwendete
+Systemkern u186+ \#1523 erlaubt eine maximale Größe von 128 MB. Andere, ältere
+EUMEL Versionen erlauben nur eine Partitionsgröße von 16 MB. Aus Kompatibilitäts­
+gründen stellt das Installationsprogramm eine Kontrollfrage bei Überschreiten der 16
+MB Grenze.
+
+Soll neben EUMEL auch eine MS-DOS Partition auf der Festplatte sein, muß, da
+MS-DOS standardmäßig die gesamte Festplatte belegt, dieses System gesichert, mit
+dem MS-DOS-Kommando 'fdisk' (o.ä.) die Partition gelöscht und entsprechend kleiner
+neu eingerichtet werden. Sie können auch bei der EUMEL-Installation alle bereits
+bestehenden Systeme löschen; dazu bietet Ihnen der SETUP-EUMEL die Option
+'Löschen der gesamten Partitionstabelle' an. Dabei gehen jedoch alle Daten auf der
+Festplatte verloren. Achten Sie also darauf, daß sie alle Daten vorher gesichert haben!
+
+Um nun die Partitionierung für Ihr EUMEL-System vorzunehmen, legen Sie die Diskette
+"SETUP-EUMEL" ohne Schreibschutzmarke in das Start-Laufwerk. Sollten Sie ein Gerät
+mit zwei Laufwerken besitzen, dann ist es das Laufwerk A:. (Bei Unklarheiten im Benut­
+zerhandbuch des Herstellers nachsehen.)
+
+Schalten Sie nun den Rechner ein bzw. betätigen Sie den Tastatur-RESET, wenn Ihr
+Gerät bereits eingeschaltet ist (meistens mit dem gleichzeitigen Druck der Tasten
+CTRL, ALT und DEL).
+
+Der SETUP-EUMEL gibt zunächst folgende SHard-Meldung aus:
+
++--------------------------------------------+
+i i
+i Setup-SHard für EUMEL auf IBM PC/AT, V 4.8 i
+i Copyright (C) 1989 ERGOS GmbH, Siegburg i
+i i
++--------------------------------------------+
+
+Warten Sie beim Hochfahren des SETUP-EUMELs, bis Ihnen nach einem Zwischen­
+bildschirm ("SETUP-EUMEL für Modul-SHard") eine Partitionstabelle angezeigt wird.
+Dieser können Sie entnehmen, ob bereits Partitionen auf der Festplatte eingerichtet
+und wie diese spezifiziert sind.
+
+Angezeigt werden neben Größe, Start- und Endspur der einzelnen Partitionen auch
+eine Typ-Nummer. Für EUMEL-Partitionen werden in aufsteigender Reihenfolge die
+Typ-Nummern 69 bis 72, für MS-DOS je nach Größe der eingerichteten Partition die
+Nummern 1 oder 4 vergeben. Außerdem wird die gerade aktive Partition durch einen
+entsprechenden Eintrag in der Tabelle kenntlich gemacht. "Aktiv" ist die Partition, die
+nach dem nächsten Einschalten des Rechners bzw. nach dem nächsten Tastatur-
+RESET gestartet würde.
+
+
+Sie sehen zusätzlich ein Menü mit folgenden zur Auswahl stehenden Funktionen:
+
++------------------------------------------------------------+
+i i
+i - EUMEL-Partition einrichten 1 i
+i - erneuern (Neuer SHard) 2 i
+i - aktivieren 3 i
+i - löschen 4 i
+i - Partitionstabelle löschen 5 i
+i - SHard-Konfiguration anzeigen 6 i
+i - SHard konfigurieren 7 i
+i - SHardmodule laden oder löschen 8 i
+i - SETUP-EUMEL beenden 0 i
+i i
++------------------------------------------------------------+
+
+#on("i")##on("u")#EUMEL - Partition einrichten #off("u")##off("i")#
+
+Eine neue EUMEL-Partition wird gemäß den im weiteren erfragten Angaben eingerich­
+tet. In die Partition wird ein SHard geschrieben, dessen Konfiguration die gelieferte
+Grundkonfiguration oder die von Ihnen eingestellte ist (s. Partitionieren der Festplatte,
+Seite 3).
+
+
+#on("i")##on("u")#EUMEL - Partition erneuern (Neuer SHARD)#off("u")##off("i")#
+
+In eine bereits vorhandene Partition wird ein SHard in der eingestellten Konfiguration
+geschrieben. Der bis dahin vorhandene SHard wird überschrieben. Die Möglichkeit
+besteht jedoch nur, wenn die Partition mit einem SETUP-EUMEL eingerichtet worden
+ist.
+
+Erneuern bedeutet, nur den SHard #on("u")#auszutauschen#off("u")# auf einer Partition, die schon einen
+fertigen EUMEL enthält, ohne daß man dabei den EUMEL löscht. Das ist dann sinnvoll,
+wenn man eine neue Version des SHard benutzen möchte oder den SHard aus ir­
+gendwelchen Gründen (z.B. Streamer gekauft) um einen oder mehrere Module erwei­
+tern will.
+
+Diese Aktion kann nur durchgeführt werden, wenn bereits ein SHard mit der Versions­
+nummer 4.x in dieser Partion vorhanden ist. Ältere (Version 2.7, 2.8 etc.) können #on("u")#nicht#off("u")#
+ersetzt werden.
+
+
+#on("i")##on("u")#EUMEL - Partition aktivieren#off("u")##off("i")#
+
+Eine Partition wird ausgewählt und aktiv gesetzt, d.h. beim nächsten Start des Re­
+chners wird das System, das auf dieser Partition steht, hochgefahren.
+
+
+#on("i")##on("u")#EUMEL - Partition löschen #off("u")##off("i")#
+
+Hierbei wird ein Eintrag aus der Partitionstabelle entfernt. Die EUMEL-Partition wird
+nicht wirklich gelöscht, d.h. wenn man nach dem Löschen den Plattenbereich noch
+nicht anderweitig verwendet hat, kann das EUMEL-System auf dieser Partition durch
+ein "EUMEL-Partition einrichten" auf genau demselben Plattenbereich (Start-/Endzy­
+linder) wieder hergestellt werden.
+
+
+#on("i")##on("u")#Partitionstabelle löschen#off("u")##off("i")#
+
+Dies ist eine sehr gefährliche Option !
+Es werden hiermit #on("u")##on("b")#alle#off("b")##off("u")# Partitionen auf der Platte gelöscht (nicht nur die von EUMEL).
+Auch hier gilt zwar, daß die Partitionen selbst an sich unangetastet bleiben und wie­
+derhergestellt werden könnten, aber dies ist bei anderen Betriebssystemen oft nicht
+möglich. Also #on("u")#VORSICHT#off("u")#.
+
+
+#on("i")##on("u")#SHard-Konfiguration anzeigen #off("u")##off("i")#
+
+Die Module des SHard, der bereitgestellt ist, um auf die Platte geschrieben zu werden,
+werden angezeigt. Es werden alle definierten Kanäle angezeigt und zu jeder Kanal­
+nummer der assoziierte Modulname. Aufgelistet ist die zuletzt mit dem SETUP-EUMEL
+zusammengestellte Konfiguration.
+
+
+#on("i")##on("u")#SHard konfigurieren #off("i")##off("u")#
+
+Zusammenstellen von einer SHardbasis und SHardmodulen zu einem neuen SHard,
+um eine neue Partition einzurichten oder den SHard einer bestehenden Partition zu
+ersetzen.
+ACHTUNG: Bitte diesen Menuepunkt nicht experimentell benutzen! Eine Anleitung
+ zum Thema Module etc. wird separat erscheinen.
+#page#
+#on("i")##on("u")#SHardmodule laden oder löschen #off("u")##off("i")#
+
+Hiermit können neue Module oder neue Versionen von Modulen in den SETUP-EUMEL
+geladen werden oder nicht mehr benötigte Module gelöscht werden. Die neuen Modu­
+le werden von einer EUMEL-Archivdiskette gelesen, deren Name zuvor eingegeben
+werden muß.
+ACHTUNG: Bitte diesen Menüpunkt nicht experimentell benutzen! Eine Anleitung
+ zum Thema Module etc. wird separat erscheinen.
+
+
+#on("i")##on("u")#SETUP-EUMEL beenden #off("u")##off("i")#
+
+SETUP-Programm ordnungsgemäß beenden.
+ENDE-Meldung abwarten!
+
+
+
+
+Die eigentliche Partitionierung beginnt nun, indem Sie Menü-Punkt 1 "EUMEL-Partition
+einrichten" anwählen. (Punkt 1 wird Ihnen nur dann #on("b")#nicht#off("b")# angeboten, wenn die Fest­
+platte bereits vollständig belegt ist. Sichern Sie dann das alte System und löschen eine
+oder alle Partitionen.) Die Kontrollabfrage "Neue EUMEL-Partition einrichten? (j/n)"
+beantworten Sie entsprechend mit "j".
+
+Beim Generieren einer EUMEL-Partition werden Angaben zu Größe und Startzylinder
+abgefragt. Dafür werden Vorgaben gemacht, die Sie bestätigen, indem Sie die
+<RETURN>-Taste betätigen, oder die Sie überschreiben können. Die abschließende
+Abfrage "Sind die Partitionsangaben korrekt?" fordert Sie zur Überprüfung Ihrer Einga­
+ben auf.
+
+Nach der Eingabe und der Überprüfung der Sektoren erscheint eine Meldung wie z.B.:
+
++--------------------------------------------------+
+i i
+i Ich habe keine schlechten Sektoren gefunden i
+i SHard wird auf die Partition geschrieben i
+i Bitte betätigen Sie eine Taste! i
+i i
++--------------------------------------------------+
+
+oder
+
++--------------------------------------------------+
+i i
+i Ich habe 2 schlechte Sektoren gefunden i
+i SHard wird auf die Partition geschrieben i
+i Bitte betätigen Sie eine Taste! i
+i i
++--------------------------------------------------+
+
+Danach gelangen Sie wieder in das Generierungsmenü. Wählen Sie "0" für "SETUP-
+EUMEL beenden". Über eine Sicherheitsfrage verlassen Sie nun den ersten Teil der
+Installation. Warten Sie #on("b")#unbedingt#off("b")#, bis auf dem Bildschirm die Meldung "ENDE" er­
+scheint, bevor Sie die Diskette "SETUP EUMEL" aus dem Laufwerk nehmen.
+
+
+
+Installieren eines EUMEL-Hintergrundes
+
+Im nächsten Schritt wird auf ihrer Festplatte das vollständige EUMEL-System instal­
+liert.
+
+Bitte betätigen Sie den Tastatur-Reset an Ihrem Rechner (oder die Tasten CTRL, ALT
+und DEL oder den AUS-/EIN-Schalter).
+
+Auf dem Bildschirm erscheint die folgende Meldung:
+
++--------------------------------------------------------------------------+
+i i
+i SHard für EUMEL auf IBM PC,AT,XT, V 4.7 i
+i Copyright (c) 1985, 86, 87, 88, 89 Martin Schönbeck Beratungen GmbH, i
+i Spenge i
+i Ladevorgang kann durch Tastendruck unterbrochen werden i
+i Habe leider keine EUMEL-0-Maschine gefunden i
+i Ladevorgang unterbrochen, drücken Sie eine Taste um fortzufahren. i
+i i
++--------------------------------------------------------------------------+
+
+Legen Sie nun die erste Hintergrunddiskette (HG0) in das Laufwerk ein und betätigen
+Sie eine Taste. Der Systemkern wird geladen und es erscheinen Angaben zu HG-,
+RAM-, und Pufferkapazität sowie zu den angeschlossenen Kanälen, diesmal jedoch
+bezogen auf die Festplatten-Partition. Warten Sie nun, bis die Meldung "HG ungültig"
+kommt. Drücken Sie anschließend eine beliebige Taste.
+Falls Sie in ein bereits bestehendes EUMEL-System einen neuen Urlader einspielen
+wollen, lesen Sie bitte den Abschnitt "Installation eines neuen Urladers".
+
+#page#
+#free(1.0)#
+Ein Menü bietet Ihnen dann folgende Auswahl:
+
++-----------------------------------------+
+i i
+i (1) Systemstart i
+i (2) Hintergrund vom Archiv laden i
+i (3) Hardwaretest i
+i (4) neuen Urlader vom Archiv laden i
+i i
++-----------------------------------------+
+
+Wählen Sie Menü-Punkt (2) "Hintergrund vom Archiv laden" und bestätigen Sie die
+Abfrage "Alten HG überschreiben?" mit "j".
+
+Das Laden des Hintergrundes kann einige Minuten in Anspruch nehmen. Sie werden
+mit der Meldung "Nächstes HG-Archiv eingelegt? (j/n)" zum Einlegen der Folgedisket­
+te(n) aufgefordert, was Sie anschließend mit der Eingabe von "j" quittieren.
+
+Es können bei beschädigten Disketten Lesefehler auftreten; dann gibt das System eine
+der Meldungen 'Harter Lesefehler' bzw. 'Softerror' aus. Bei letzterem könnte der ent­
+sprechende Sektor nach mehrmaligem Versuch noch gelesen werden. Bei einem
+harten Lesefehler können Sie die Diskette nicht verwenden. Bitte benachrichtigen Sie
+die Firma, von der Sie die Disketten erhalten haben.
+
+Wenn der Hintergrund eingelesen ist, erscheint die Aufforderung 'fertig, bitte RESET'.
+#on("b")#Vergessen Sie nicht#off("b")#, vor der Betätigung des Tastatur-RESET die Hintergrunddiskette
+aus dem Diskettenlaufwerk zu entfernen.
+
+Wenn Sie während des Hochfahrens keine Taste drücken, dann startet der Lader durch
+und das EUMEL-System meldet sich mit einer Tabelle von Geräteanpassungen:
+
++--------------------------------------------------------------------------+
+i i
+i psi transparent pc.1.25 pc.2.25 i
+i pc.3.25 pc.1.24 pc.2.24 pc.3.24 i
+i psi25 tandberg.2244s DEC.VT100.ascii DEC.VT100 i
+i DEC.VT220.ascii DEC.VT220.german FT10/20.german FT10/20.ascii i
+i ampex210.ascii ampex210.german ampex220.german ampex232 i
+i Wyse.WY50.ascii Wyse.WY50.german Wyse.WY60.german i
+i Wyse.WY120.german i
+i i
+i Kanal 1 (j/n) i
+i i
++--------------------------------------------------------------------------+
+
+Da unterschiedliche Tastaturen auch unterschiedliche Tastenbelegungen haben, ist es
+notwendig, mit Hilfe der Konfigurationstabelle Ihre Tastatur und Ihren Bildschirm an
+das EUMEL-System anzupassen. Dafür bietet Ihnen das System "Kanäle" an. #on("u")#Kanal 1#off("u")#
+entspricht dem Haupt-Terminal des Rechners, #on("u")#muß also auf jeden Fall konfiguriert
+werden#off("u")#. Beantworten Sie also die Frage "Kanal 1 (j/n)" mit "j".
+Das EUMEL-System funktioniert auch, wenn Sie zunächst nur Kanal 1 mit der Anpas­
+sung konfigurieren, die Ihrem Gerätetyp entspricht. Wenn Ihr Rechner eine AT-Tastatur
+hat, ist die korrekte Konfiguration "pc.1"; die Konfigurationen "pc.2" und "pc.3" decken
+die meisten der Rechner ab, deren Tastenbelegung von der Standard-AT Tastatur
+geringfügig abweicht. Die Erweiterung ".24" bzw. ".25" gibt die Anzahl der Bildschirm­
+zeilen wieder. Standardmäßig sind im SHard 24 Zeilen eingestellt.
+
+Weitere Kanäle zum Anschluß von Druckern oder weiteren Terminals können jederzeit
+bei Bedarf vorgenommen werden (EUMEL Systemhandbuch Teil 1).
+Die Anfrage nach der Konfiguration weiterer Kanäle kann deshalb verneint werden. Die
+Abfrage 'koennen unbenutzte Geraetetypen geloescht werden (j/n)' beantworten Sie
+einstweilen mit 'n'. Anschließend werden noch Datum und Uhrzeit abgefragt. Damit ist
+das Erstinstallationsprogramm abgeschlossen und es erscheint die Meldung 'mainten­
+ance :'. Geben Sie an dieser Stelle <ESC> <q> (nacheinander) ein. Sie haben damit
+die Task 'configurator' ordnungsgemäß verlassen. Erst damit ist sichergestellt, daß die
+eingestellte Konfiguration wirksam wird.
+
+
+Installation eines neuen Urladers
+
+Wenn Sie den alten Urlader mit einem neuen (z.B. protected mode) überschreiben
+wollen, starten Sie das EUMEL-System zunächst neu. Sobald die Meldung
+
+ #on("b")#Ladevorgang kann durch Tastendruck unterbrochen werden#off("b")#
+
+erscheint, drücken Sie eine beliebige Taste (z.B. ENTER). Auf dem Bildschirm er­
+scheint nun zusätzlich die Meldung
+
+ #on("b")#Ladevorgang unterbrochen, drücken Sie eine Taste um fortzufahren#off("b")#
+#page#
+Legen Sie nun die Diskette mit dem neuen Urlader in das Bootlaufwerk und drücken
+Sie wieder eine beliebige Taste. Danach werden folgende Meldungen auf dem Bild­
+schirm ausgegeben:
+
++-----------------------------------------------------+
+i i
+i EUMEL wird von Diskette geladen i
+i i
+i i
+i E U M E L - Vortest i
+i i
+i Terminals: 1 .... i
+i RAM-Groesse (gesamt): .... kB i
+i Pufferbereich: .... kB i
+i Hintergrund-Speicher .... kB i
+i i
+i Speichertest: ********** i
+i i
++-----------------------------------------------------+
+
+In der Zeit, in der die Sternchen des Speichertests erscheinen, drücken Sie bitte wieder
+die ENTER-Taste. Nach dem Speichertest erscheint dann folgendes Menü:
+
++-----------------------------------------------------+
+i i
+i (1) Systemstart i
+i (2) neuen Hintergrund vom Archiv laden i
+i (3) Hardwaretest i
+i (4) neuen Urlader vom Archiv laden i
+i i
++-----------------------------------------------------+
+
+Wählen Sie Menüpunkt 4 und auf dem Bildschirm erscheinen die folgenden Zeilen:
+
+#box("-0.1","0.0","8.0","1.0")#
+ \# xxx
+ fertig, bitte RESET
+
+wobei hinter dem \#-Zeichen die übertragenen Blöcke des neuen Urladers gezählt
+werden.
+
+Anschließend entfernen Sie bitte die Urladerdiskette aus dem Laufwerk und drücken
+den RESET-Schalter Ihres Rechners. Das EUMEL-Betriebssystem wird nun mit dem
+neuen Urlader gestartet.
+
+
+Tastenbelegung:
+
+EUMEL-Zeichen: Taste auf dem IBM-PC/AT
+
+ MARK : +--------+
+ i bild i (oder Pfeil nach oben)
+ +--------+
+
+ RUBIN : +--------+
+ i Einfüg i
+ +--------+
+
+ RUBOUT : +--------+
+ i Lösch i
+ +--------+
+
+ TAB : +--------+
+ i <= => i
+ +--------+
+
+ HOP : +--------+
+ i Pos 1 i
+ +--------+
+
+ ESC : +------------+
+ i Eing Lösch i
+ +------------+
+
+ SV : +------------+ +-------+
+ i CTRL g i oder i F1 i
+ +------------+ +-------+
+
+Bemerkung: Die CTRL-Taste kann auch mit STRG bezeichnet sein.
+
+Sollte die Tastaturbelegung noch nicht die EUMEL-spezifischen Tasten (HOP, MARK,
+SV, RUBIN, RUBOUT) an den entsprechenden Orten anbieten, können Sie durch
+Ankoppeln der Task "configurator" und Absetzen des Befehls "configurate" die Tastatu­
+ren (auch für zusätzlich angeschlossene Terminals) kanalweise umkonfigurieren. Nähe­
+res entnehmen Sie bitte dem Systemhandbuch, S.6ff.
+
+
+Zusatzprogramme
+
+Nachdem das System vollständig installiert ist, kann noch typspezifische Software
+eingespielt werden. Diese befindet sich auf der Diskette 'EUMEL-Archiv "AT" (bzw.
+"XT")'. Der folgende Ablauf skizziert schon das Prinzip jeder Arbeit in einem EUMEL-
+System: Task ankoppeln mit 'continue("taskname")' bzw. 'begin("taskname")', Eingabe
+von Kommandos wie 'edit', 'run' oder 'generate shutup dialog manager', abschließend
+Task abkoppeln durch <ESC> <q>. Eine ausführliche Beschreibung finden Sie in
+den EUMEL-Handbüchern.
+#page#
+Wenn Sie nach Einstellen des Kanals 1 die Task 'configurator' verlassen haben, befin­
+den Sie Sich auf Supervisor-Ebene. Um die auf der Diskette befindlichen Programme
+an der richtigen Stelle zu übersetzen, sind folgende Schritte notwendig:
+
+Drücken Sie die <SV>-Taste (F1). Damit landen Sie im Supervisor-Menü, dem
+Systemverteiler. Mit <ESC> <c> und Eingabe des Tasknamens 'SYSUR' (auf Groß­
+schreibung achten!) holen Sie die Task 'SYSUR' an das Terminal. Diese Task meldet
+sich mit 'maintenance:'. Da Sie mit einem Mehrbenutzersystem arbeiten, müssen Sie
+das Diskettenlaufwerk zunächst für sich reservieren: 'archive("AT")'. Erst dann können
+Sie Dateien von der Diskette holen: 'fetch("AT install",archive)' und das Installations­
+programm ausführen: 'run'. Der weitere Ablauf erfordert keine Eingriffe.
+
+Nach Ablauf der Programme sollten Sie schließlich eine besondere Task zum Abschal­
+ten einrichten. Dazu müssen Sie nocheinmal die Task 'SYSUR' an den Bildschirm
+holen und dort das durch die Zusatzsoftware (u.a.) neu hinzugewonnene Kommando
+'generate shutup dialog manager' geben. Nach Absetzen des Kommandos können Sie
+'SYSUR' durch <ESC> <q> wieder verlassen.
+
+Um menügesteuert das Betriebssystem abzuschalten oder einen Partitionswechsel
+vorzunehmen, steht Ihnen die Task 'shutup dialog' zur Verfügung. Bei Ausführung des
+Supervisor-Kommandos 'continue("shutup dialog")' wird Ihnen die aktuelle Partitions­
+tabelle angezeigt, so wie Sie diese bereits bei der Generierung kennengelernt haben,
+d.h. mit Angabe von Größe, Start- und Endzylinder der eingerichteten Partitionen. Sie
+können dann eine beliebige Partition menugesteuert auswählen und starten oder das
+Betriebssystem kontrolliert abschalten (sog. 'shutup'). Dabei wird der aktuelle System­
+zustand automatisch gesichert.
+
+
+Archivformate bei ATs und Kompatiblen mit zwei Diskettenlauf­
+werken:
+
+Standardmäßig ist der Archivkanal 31 an das Laufwerk 'A:' gebunden, das eine Kapazi­
+tät von 1,2 Megabyte besitzt. Ist jedoch bei Ihrem Gerät ein zweites Diskettenlaufwerk,
+z.B. mit einer Kapazität von 360 Kilobyte eingebaut, dann können Sie auf dieses Lauf­
+werk über den Kanal 30 zugreifen.
+
+Dazu richten Sie unter 'SYSUR' eine Task ein, die Sie z.B. 'ARCHIVE 360' benennen.
+Geben Sie in dieser Task das Kommando 'archive manager (30)'; dann können Sie von
+jeder Benutzertask das Archiv mit dem Kommando 'archive ("Archivname",/ "ARCHIVE
+360")' anmelden. Der Zugriff auf eine Diskette in diesem Laufwerk geschieht z.B. über
+'list(/"ARCHIVE 360")' oder 'save ("Dateiname",/"ARCHIVE 360")'. Eine andere Möglich­
+keit ist ein 3,5" Laufwerk.
+
+
+
+Die einzelnen Schritte der Installation im Überblick:
+
+
+ 1. Die Diskette 'SETUP-EUMEL' in das Laufwerk stecken.
+
+ 2. Rechner einschalten oder Tastatur-RESET
+
+ 3. EUMEL-Partition einrichten.
+
+ 4. Generierung beenden und auf 'ENDE'-Meldung warten.
+
+ 5. Diskette 'SETUP-EUMEL AT (XT)' entnehmen.
+
+ 6. Tastatur-RESET.
+
+ 7. Die Meldung 'Leider keine EUMEL-0-Maschine gefunden' abwarten.
+
+ 8. Hintergrunddiskette ('HG0') einlegen und Taste drücken.
+
+ 9. Nach der Meldung 'HG-ungültig' eine Taste betätigen, um in den Startdialog zu
+ gelangen.
+
+ 10. Menupunkt 2 anwählen: Neuen Hintergrund vom Archiv laden. Hintergrunddis­
+ kette einlegen und 'Alten HG überschreiben?' mit "j" quittieren. Folgedisketten
+ einlegen, sobald entsprechende Meldung ("weiterer Archivträger eingelegt?")
+ erscheint, und "j" eingeben.
+
+ 11. Hintergrunddiskette entnehmen und anschließend Tastatur-RESET ausführen.
+
+ 12. Kanal 1 konfigurieren.
+
+
+
+#ib(9)#1.3. Ausführliche Beschreibung#ie(9)#
+
+
+#ib##ib(9)#System laden#ie##ie(9)#
+
+
+Wie Sie in der Installationsanleitung lesen konnten, geht man beim Systemstart durch
+Eingabe eines Zeichens während des Vortests in das Startmenü und wählt dort "Hin­
+tergrund vom Archiv laden" an. Falls der zu ladende Hintergrund sich über mehrere
+Archiv-Disketten erstreckt, werden die folgenden sukzessive angefordert.
+
+
+
+
+#ib##ib(9)#System sichern#ie##ie(9)#
+
+
+Der aktuelle eigene Hintergrund läßt sich (mit allen Tasks und allen Dateien) durch das
+Kommando
+
+ #ib#save system#ie#
+
+auf Archivdisketten sichern. Dabei wird der Systemzustand zunächst über einen Fix­
+punkt gesichert. Anschließend werden #on("b")##on("i")#formatierte#off("i")##off("b")# Disketten angefordert. Der Hinter­
+grund wird komprimiert gesichert, d.h. nur die belegten Blöcke werden auf das Archiv
+geschrieben.
+
+#on("i")#Anmerkung: Diese Prozedur kann nur von privilegierten Tasks (Nachfahren von
+ "SYSUR"), wie dem OPERATOR, aufgerufen werden.
+ Vor dem Aufruf von 'save system' sollten Sie genügend Disketten for­
+ matiert haben (Überprüfen Sie mit 'storage info', wieviele Disketten Sie
+ benötigen, um den gesammten Hintergrund darauf zu schreiben). #off("i")#
+
+
+
+
+#ib(9)#System gegen Unbefugte schützen#ie(9)#
+
+
+Falls der Benutzerkreis eines Multi-User-Systems nicht "gutartig" ist, sollte man verhin­
+dern, daß jeder Benutzer des Systems Zugang zu #ib#privilegierten Operationen#ie# hat, wie
+Löschen anderer Tasks, Konfiguration ändern und System sichern.
+
+Dies erreichen Sie dadurch, daß Sie #on("b")#alle#off("b")# privilegierten Tasks, das sind 'SYSUR' und alle
+Söhne, Enkel usw. von 'SYSUR', durch #ib#Paßworte#ie# schützen. Damit wird der Zugang zu
+diesen Tasks nur möglich, wenn man das entsprechende Paßwort eingibt. Man de­
+finiert solche #on("i")##on("b")##ib#Task-Paßworte#ie##off("i")##off("b")#, indem man die zu schützende Task mit Hilfe des Super­
+visor-Kommandos "continue" an ein Terminal holt und dann das Kommando
+
+ #ib#task password#ie# ("simsalabim")
+
+gibt. Dabei ist "simsalabim" nur ein Beispiel. Bitte verwenden Sie ein anderes Paß­
+wort! Da die Eigenschaft, privilegiert zu sein, nur davon abhängt, im "SYSUR"-Zweig
+(und nicht im normalen "UR"-Zweig) des Systems zu sein, könnte sich ein gewitzter
+Anwender die Privilegierung einfach erschleichen, indem er eine neue Sohntask von
+"SYSUR" einrichtet. Um auch diese Möglichkeit zu unterbinden, sollte man in #on("b")#jeder#off("b")#
+Task des SYSUR-Zweiges ebenfalls ein #on("i")##on("b")#"begin"-Paßwort#off("i")##off("b")# definieren. Das geschieht mit
+dem Kommando
+
+ #ib#begin password#ie# ("simsalabim")
+
+Bei der Wahl der Paßworte sollte man folgendes bedenken:
+
+ - Ein zu kurzes oder offensichtliches Paßwort (beispielsweise der Name des
+ Systemverwalters) wird von "Hackern" schnell herausgefunden.
+
+ - Oft werden Paßworte bekannt, weil irgendwo ein Zettel mit den Paßworten
+ herumliegt.
+
+ - Der Paßwortschutz ist hart. Wenn man sein Paßwort vergessen hat, gibt es
+ keinen Zugang mehr zu der geschützten Task.
+
+
+
+Beschreibung der Paßwortprozeduren:
+
+#ib#task password#ie#
+ PROC task password (TEXT CONST password)
+ Zweck: Einstellen eines Paßwortes für eine Task im Monitor.
+
+#ib#begin password#ie#
+ PROC begin password (TEXT CONST password)
+ Zweck: Verhindert das unberechtigte Einrichten einer Sohn-Task.
+ Anmerkung: Das 'begin password' vererbt sich auf die später erzeugten Sohn-
+ Tasks.
+
+#ib#family password#ie#
+ PROC family password (TEXT CONST password)
+ Zweck: Setzt oder ändert das Paßwort derjenigen Familienmitglieder, die kein
+ Paßwort oder das gleiche Paßwort wie die aufrufende Task haben.
+ Zu einer Familie gehören die Task in der man sich befindet und die ihr
+ untergeordneten Tasks.
+ Bsp.: Das Kommando 'family password ("EUMEL")' wird in SYSUR
+ gegeben. Dadurch wird das SYSUR-Paßwort und die Paßworte
+ der entsprechenden Tasks unter SYSUR auf "EUMEL" gesetzt.
+
+
+
+#ib##ib(9)#Konfiguration#ie##ie(9)#
+
+Die #ib#Konfiguration#ie# läuft über die Task "#ib#configurator#ie#" ab. Diese Task müssen Sie also für
+die hier aufgeführten Operationen durch das Supervisor-Kommando "continue" an­
+koppeln (Dabei wird das Paßwort überprüft, falls die Task geschützt wurde).
+
+#on("i")#Anmerkung: Man kann die Task "configurator" löschen und dann neu (als Sohn, En­
+ kel,... von SYSUR) wieder einrichten. Danach holt man die Konfigura­
+ tionsdatei (z.B. von std.devices) und gibt das Kommando "#ib#configuration
+ manager#ie#".#off("i")#
+
+
+Der in der Einführung unter "Wie Sie die Konfiguration einstellen" beschriebene Konfi­
+gurationsdialog läßt sich vermittels des Kommandos
+
+ #ib#configurate#ie#
+
+aufrufen. Dabei wird für jeden angewählten Kanal die bis jetzt gültige Einstellung als
+Vorschlag mit ausgegeben. Die Einstellung aller Kanäle, die nicht angesprochen wer­
+den, bleibt unverändert.
+
+Im Menü werden die Namen aller Dateien mit #ib#Gerätetabellen#ie# aufgeführt, die in der
+Task enthalten sind. Daraus folgt, daß nur noch die bei der letzten Konfigurierung
+benutzten Typen aufgeführt werden, wenn vorher auf die Frage "Koennen unbenutzte
+Geraetetypen geloescht werden (j/n)?" mit "j" geantwortet wurde. Löschen Sie also
+nicht alle unbenutzten Gerätetypen, wenn Sie sie später evtl. nochmal bruachen (siehe
+auch "Teil 2, 3. Kanäle und Konfigurierung").
+
+Im Konfigurationsdialog kann folgendes eingestellt werden:
+
+ #ib#Typ#ie# Es werden alle vorhandenen Gerätetabellen durchgegangen, bis
+ eine davon ausgewählt wurde. Diese manchmal etwas langwierige
+ Arbeit kann man durch Eingabe des Zeichens ESC abkürzen:
+ Danach kann man den Typnamen direkt eingeben. #on("i")#Das funktioniert
+ aber nur vernünftig, wenn das eigene Arbeitsterminal bereits richtig
+ konfiguriert worden ist!#off("i")#
+
+ #ib#Baudrate#ie# (nur für V.24-Kanäle von Bedeutung) Es werden alle einstellbaren
+ Baudraten durchgegangen, bis eine davon ausgewählt wurde. Das
+ sind die Werte 50, 75, 110, 134.5, 150, 300, 600, 1200, 1800, 2400,
+ 3600, 4800, 7200, 9600, 19200, 38400 Baud.
+
+ #ib#Bits#ie# (nur für V.24-Kanäle von Bedeutung) Es werden die einstellbaren
+ Zeichengrößen durchgegangen, d.h. 7 oder 8 Bit pro Zeichen.
+
+ #ib#Parität#ie# (nur für V.24-Kanäle von Bedeutung) Möglich sind die Einstellun­
+ gen 'no', 'even' und 'odd'.
+
+ #ib#Stopbits#ie# (nur für V.24-Kanäle von Bedeutung) Stopbits geben die Pause
+ zwischen zwei aufeinanderfolgenden Zeichen an. Möglich sind 1
+ oder 2 Stopbits.
+
+
+ #ib#Protokoll#ie# Terminals u.ä. werden üblicherweise ohne Protokoll angeschlossen.
+ Bei langsamen Geräten wie Druckern bzw. Plottern oder aber bei
+ Rechnerkopplungen bzw. Netzen kann der Empfänger nicht immer
+ so schnell Zeichen annehmen wie sie von der Gegenstation gesen­
+ det werden. In diesem Fall kann man das #ib#XON/XOFF-#ie# oder das
+ #ib#RTS/CTS-Protokoll#ie# einstellen.
+ #on("b")#BEACHTE: Sender und Empfänger müssen auf das gleiche Proto­
+ koll eingestellt sein.#off("b")#
+
+ Manchmal müssen auch Terminals mit Protokoll angeschlossen
+ werden. Üblicherweise wählt man dann aber ein rein ausgabe­
+ seitiges Protokoll, damit SV den EUMEL auf jeden Fall erreicht.
+ Es gibt folgende Protokolle:
+
+ #ib#XON/XOFF-Protokoll#ie#:
+ Rechner und Gerät steuern die Sendungen jeweils über
+ XON/XOFF-Zeichen.
+ #ib#RTS/CTS-Protokoll#ie#:
+ Rechner und Gerät steuern ihre Sendungen jeweils über
+ RTS/CTS- Leitungen.
+ #ib#XON/XOFF-ausgabeseitig#ie#:
+ Das angeschlossene Gerät steuert die Ausgabe über
+ XON/XOFF.Eingaben zum Rechner unterliegen keinem
+ Protokoll.
+ #ib#RTS/CTS-ausgabeseitig#ie#:
+ Das angeschlossene Gerät steuert die Ausgabe über
+ RTS/CTS. Eingaben zum Rechner unterliegen keinem
+ Protokoll.
+ #ib#XON/XOFF-eingabeseitig#ie#:
+ Der EUMEL-Rechner steuert die angeschlossenen
+ Geräte durch XON/XOFF. Die Ausgaben zum Gerät
+ unterliegen keinem Protokoll.
+ #ib#RTS/CTS-eingabeseitig#ie#:
+ Der EUMEL-Rechner steuert die angeschlossenen
+ Geräte durch RTS/CTS. Die Ausgaben zum Gerät unter­
+ liegen keinem Protokoll.
+
+ #ib#Puffer#ie# Terminals und alle Ausgabegeräte (Drucker u.ä.) haben standard­
+ mäßig die normalen "kleinen" Eingabepuffer im System zugeord­
+ net. Bei Rechner-Rechner-Kopplungen, DFÜ oder Netzen kann ein
+ "großer" #ib#Eingabepuffer#ie# von 512 Byte notwendig werden. Dement­
+ sprechend sind #ib#Großpuffer#ie# nur beim Schnittstellentyp 'transparent'
+ möglich.
+
+Im #ib#Konfigurationsdialog#ie# werden bei jedem Kanal nur die dort vorhandenen Möglich­
+keiten angeboten. Dabei wird die vorherige Einstellung immer als erste angeboten. So
+kann man sich verhältnismäßig einfach "durchtasten".
+
+Die Fragen des #ib#Konfigurationsdialog#ie#s werden nach folgendem Schema gestellt:
+
+#linefeed(1.18)#
+ erfrage ("Kanal") ;
+ erfrage ("Typ") ;
+ IF dieses ist ein v24 kanal
+ THEN IF baudrate einstellbar
+ THEN erfrage ("Baudrate")
+ FI ;
+ IF zeichengroesse einstellbar
+ THEN erfrage ("Bits")
+ FI ;
+ IF parität einstellbar
+ THEN erfrage ("Parität")
+ FI ;
+ IF stopbits einstellbar
+ THEN erfrage ("Stopbits")
+ FI ;
+ FI ;
+ erfrage ("Protokoll") ;
+ IF typ ist tranparent
+ THEN erfrage ("Puffer")
+ FI.
+
+#linefeed(1.0)#
+Will man seine eingestellte #ib#Konfiguration sichern#ie#, reicht es, alle Dateien der Task
+"#ib#configurator#ie#" auf ein Archiv zu schreiben. Diese Konfiguration kann man dann bei
+einem neuen Hintergrund einfach vom Archiv laden. Um die Konfigurierung dann auch
+auszuführen, gibt man das Kommando "setup".
+
+
+
+
+#ib##ib(9)#Druckersoftware einrichten#ie##ie(9)#
+
+
+
+Das Standardarchive "std.printer" enthält einige Druckeranpassungen für die Ansteu­
+erung diverser Druckertypen. Soll einer dieser Druckertypen an das EUMEL-System
+angeschlossen werden, so muß zuerst eine Task "#ib#PRINTER#ie#" (als Sohntask von
+"SYSUR" mit dem Supervisorkommando) vorhanden sein bzw. durch
+
+
+ begin ("PRINTER", "SYSUR")
+
+
+eingerichtet werden. In dieser Task müssen dann die folgenden Schritte vollzogen
+werden:
+
+- Anmelden des Archivs:
+
+ archive ("std.printer")
+
+
+- Holen der Druckeranpassung vom Archiv:
+
+ fetch ("druckertyp.inserter", archive)
+
+
+- Insertieren der Druckeranpassung:
+
+ insert ("druckertyp.inserter")
+
+
+
+Beispiel:
+ archive ("std.printer")
+ fetch ("laser.inserter", archive);
+ check off;
+ insert ("laser.inserter")
+
+
+Nach Beendigung der Kompilierung finden Sie sich in einem Menü wieder, daß Ihnen
+die Auswahl Ihres Drucker-Herstellers durch die Eingabe der vor dem Firmennamen
+stehenden Zahl erlaubt. Diese Eingabe schicken Sie mit RETURN ab. Da Hersteller
+mitunter verschiedene Modelle mit verschiedenen Funktionen anbieten, ist es nötig,
+daß Sie Ihr Modell auswählen. Auch diese Eingabe wird durch RETURN abgeschickt.
+Nachdem Sie die Nummer des gewünschten Druckers eingegeben haben, erfolgt noch
+einmal eine Sicherheitsabfrage, ob dieser Drucker installiert werden soll.
+
+Neben den speziell zu dem gewählten Drucker passenden Fragen (z.B. NLQ-Modus
+standardmäßig) ist es erforderlich, den Kanal einzugeben, an dem der Drucker ange­
+schlossen ist (z.B. Kanal 15 für eine parallele Schnittstelle).
+
+Wenn die Generierung beendet ist, muß in allen bestehenden Tasks - insbesondere in
+der Task 'PUBLIC' - die Fonttabelle mit dem fonttable-Kommando eingestellt werden.
+Mit dem Kommando
+
+
+ print ("dateiname")
+
+
+wird dann eine Datei ausgedruckt.
+
+Befindet sich keine passende Druckeranpassung für den anzuschließenden Drucker­
+typ auf dem Standardarchiv "std.printer", so sollte die Druckeranpassung "printer.std"
+benutzt werden. Diese Druckeranpassung ist eine universelle Druckeranpassung für
+alle Drucker, die mit ASCII-Code 13 ein 'Carriage Return' (d.h. Bewegung des Druck­
+kopfes an den linken Rand) und mit ASCII-Code 10 eine Zeilenschaltung von 1/6 Zoll
+vornehmen. Mit ihr kann dann in einem Schrifttyp (entweder 10 oder 12 Zeichen pro
+Zoll, je nachdem welche Fonttabelle eingestellt ist) gedruckt werden. So erhält man
+wenigstens eine Minimalansteuerung des Druckers. Für eine bessere Ansteuerung des
+Drucker muß ein Programm geschrieben werden, das das Druckertreiber-Interface
+erfüllt (siehe Teil 6 "Der EUMEL-Drucker") und eine Fonttabelle erstellt (siehe Teil 7 "Der
+Fontspeicher") werden.
+#page#
+#headeven#
+
+%#center#EUMEL-Systemhandbuch
+
+
+#end#
+#headodd#
+
+#center#2. Hardware und ihre Steuerung#right#%
+
+
+#end#
+
+
+#ib(9)#2. Hardware und ihre Steuerung#ie(9)#
+
+
+
+
+#ib(9)#2.1. Vorwort#ie(9)#
+
+
+Die #ib#Hardware#ie# eines jeden EUMEL-Systems läßt sich in #ib#Rechnerkern#ie# und Peripherie
+einteilen.
+
+
+a) Der #ib#Rechnerkern#ie#
+
+
+In der Regel wird der Rechnerkern aus folgenden Komponenten bestehen:
+
+ - #ib#CPU#ie#
+ - #ib#Vordergrundspeicher#ie# (oft als RAM bezeichnet)
+ - #ib#Hintergrundspeicher#ie# (Floppy, Harddisk, oder auch RAM/ROM)
+
+Alle Daten, Dateien und Programme werden auf dem Hintergrundspeicher abgelegt.
+Der benötigte Platz wird dabei dynamisch nach Bedarf zugewiesen. Jeder Zugriff auf
+Daten, die sich auf dem Hintergrundspeicher befinden, muß über den Vordergrund­
+speicher erfolgen. Zu diesem Zweck verlagert das EUMEL-System automatisch alle
+aktuell benötigten Daten in den Vordergrundspeicher. Das erfolgt nach dem Prinzip
+des #ib#Demand-Paging#ie# (s. Benutzerhandbuch Kap. 1). Die CPU führt die aktiven Pro­
+gramme (unter Benutzung des Speichers) aus. Dabei bearbeitet sie reihum alle re­
+chenwilligen Prozesse.
+Die drei Komponenten des Rechnerkerns werden vollständig vom EUMEL-Betriebs­
+system verwaltet und miteinander verknüpft, so daß der Anwender sich in der Regel
+darum weder kümmern muß noch kann. Ausgenommen davon sind allerdings die
+Diagnose von Hardwarefehlern und Überlegungen zur Systemleistung.
+
+
+b) Die #ib#Peripherie#ie#
+
+
+Alle anderen Geräte oder Gerätekomponenten gehören aus der Sicht des EUMEL-
+Systems zur Peripherie. Wesentliches Kennzeichen ist, daß sie über Kanäle mit dem
+Rechnerkern verbunden sind und von dort aus durch System- und Anwender­
+programm gesteuert werden können. Angeschlossen werden können u.a.
+
+ - #ib#Terminal#ie#s
+ - #ib#Drucker#ie# und #ib#Plotter#ie#
+ - andere #ib#Rechner#ie# bzw. #ib#Rechnernetze#ie#
+ - #ib#Archivgerät#ie#e (z.B. Floppy-Laufwerke)
+
+In der Regel hat jedes EUMEL-System mindestens ein #ib#Terminal#ie# und #ib#Archivlaufwerk#ie#.
+Auch wenn dieses "Terminal 1" und das Floppy-Laufwerk baulich in den Rechner
+integiert sind, gehören sie logisch zur Peripherie. Die entsprechenden Kanäle sind
+dann allerdings Teil des Rechners und brauchen den Anwender nicht zu interessie­
+ren. Die beiden wesentlichen anderen Kanaltypen sind:
+
+ - #ib#serielle Schnittstelle#ie#n (#ib#V.24#ie#)
+ - #ib#Parallelschnittstellen#ie#
+
+Beide führen "echt" aus dem Rechner heraus und sind u.U. hardwaremäßig für den
+Anwender von Bedeutung. Normalerweise sollte zwar der Lieferant der EUMEL-
+Hardware für die Verkabelung und den Anschluß peripherer Geräte sorgen, aber
+Kenntnisse können in Fehlersituationen (z.B. Kabelbruch), bei Umkonfigurierungen
+und bei Kombinationen verschiedener Geräte helfen.
+
+
+
+
+#ib(9)#2.2. #ib#Hardware-Test#ie##ie(9)#
+
+
+
+Der EUMEL-Hardware-Test ist ein rechnerunabhängiger Test und kann demzufolge
+nicht so viel überprüfen wie Testprogramme, die genau auf eine entsprechende Hard­
+ware zugeschnitten sind. Trotzdem sollten die meisten Hardware-Fehler schon mit
+dem EUMEL-#ib#Hardware-Test#ie# gefunden werden.
+
+Bei jedem Systemstart wird der "#ib#Vortest#ie#" durchgeführt. Nachdem er Terminals, Spei­
+cher und Hintergrund angezeigt hat, testet er einmal den Hauptspeicher. Danach wird
+das eigentliche EUMEL-System gestartet.
+
+
+Durch Eingabe eines beliebigen Zeichens während des Vortests (Speichertest:
+*********) kommt man in den ausführlichen #ib#Start-Dialog#ie#. Dort wird u.a. auch die
+Möglichkeit "Hardware-Test" angeboten. Wählt man diese an, werden die verfügbaren
+Tests als Menü aufgelistet. Bei jedem EUMEL-System stehen folgende Testmöglichkei­
+ten zur Verfügung:
+
+ (1) #ib#Speichertest#ie#
+ (2) #ib#Kanaltest#ie#
+ (3) #ib#Hintergrundtest#ie#
+ (4) #ib#Archivtest#ie#
+
+Alle Tests sind dabei Dauertests, d.h. sie beginnen nach jedem Durchlauf von neu­
+em, können aber durch <ESC> abgebrochen werden.
+
+
+
+
+
+#ib##ib(9)#Speichertest#ie##ie(9)#
+
+
+Der #ib#Speichertest#ie# soll den Vordergrundspeicher (#ib#RAM#ie#) des Rechners untersuchen.
+Gerade #ib#Speicherfehler#ie# tendieren aber dazu, nur sporadisch aufzutreten oder wär­
+meabhängig zu sein. Deshalb sollte der Test bei Verdacht auf Speicherfehler längere
+Zeit (einige Stunden) laufen. Leider können auch dann nicht alle Fehler aufgedeckt
+werden, z.B. nicht solche, die nur in ganz speziellen Situationen entstehen, wie Spei­
+cherzugriff mit gleichzeitig anlaufendem Floppymotor und Zeichenausgabe. Generell
+gilt hier (wie für jeden Test), daß das Nichtvorhandensein von Fehlern nie Vollkommen
+sicher nachgewiesen werden kann.
+
+Der Speichertest teilt den Speicher in drei verschiedene Bereiche auf:
+
+ 0 : adresse MOD 3 = 0
+ 1 : adresse MOD 3 = 1
+ 2 : adresse MOD 3 = 2
+
+Der freie Speicher wird nach folgendem Algorithmus geprüft:
+
+ schreibe (1, OLOLOLOL) ; out ("*") ;
+ schreibe (2, OLOLOLOL) ; out ("*") ;
+ schreibe (0, LOLOLOLO) ; out ("*") ;
+ pruefe (1, OLOLOLOL) ; out ("*") ;
+ schreibe (1, LOLOLOLO) ; out ("*") ;
+ pruefe (2, OLOLOLOL) ; out ("*") ;
+ pruefe (0, LOLOLOLO) ; out ("*") ;
+ pruefe (1, LOLOLOLO) ; out ("*") ;
+ schreibe (0, OLOLOLOL) ; out ("*") ;
+ pruefe (0, OLOLOLOL) ; out ("*") ;
+ schreibe (2, LOLOLOLO) ; out ("*") ;
+ pruefe (2, LOLOLOLO) ; out ("*") .
+
+
+Dabei werden durch 'PROC schreibe (INT CONST bereich, BYTE CONST muster)' alle
+Bytes des entsprechenden Bereichs mit dem angegebenen Muster geladen. 'PROC
+pruefe (INT CONST bereich, BYTE CONST soll)' überprüft entsprechend alle Bytes des
+Bereichs darauf, ob sie das Sollmuster enthalten.
+
+Findet der Speichertest Fehler, können u.a. folgende Ursachen vorliegen:
+
+ - Ein Speicherchip ist defekt.
+
+ - Die Versorgungsspannung für den Speicher (meistens +5V) ist zu niedrig,
+ d.h. das Netzteil ist nicht richtig eingestellt bzw. defekt. (Das kann insbeson­
+ dere dann entstehen, wenn ein Rechner so "hochgerüstet" wurde, daß das
+ Netzteil nachgeregelt werden müßte.)
+
+ - Die Kontakte der Speicherkarten sind locker oder oxidiert.
+
+ - Die Speicheransteuerung ist defekt.
+
+
+
+
+
+#ib##ib(9)#Kanaltest#ie##ie(9)#
+
+
+Beim #ib#Kanaltest#ie# werden fortlaufend auf allen #ib#Terminalkanälen#ie# (außer auf Terminal 1)
+die jeweiligen Kanalnummern in der Form "Kanal: n" ausgegeben. Jedes Eingabe­
+zeichen wird in dezimaler Verschlüssung unter Angabe der Kanalnummer auf dem
+Terminal 1 gemeldet.
+
+Mit Hilfe dieses Tests können u.a. Kabel und Geräteeinstellungen überprüft werden.
+Mögliche Fehlerursachen:
+
+ - falsche #ib#Baudrate#ie# eingestellt
+
+ Symptome: Bei Aus- und Eingabe werden vollkommen unsinnige Zeichen
+ angeliefert.
+ Abhilfe: Baudrate am Endgerät oder am Rechner richtig einstellen.
+
+ - falsche #ib#Parität#ie# eingestellt
+
+ Symptome: Einige Zeichen werden richtig übertragen, andere verfälscht. In
+ einigen Fällen können auch alle Zeichen falsch übertragen wer­
+ den.
+ Abhilfe: Parität am Endgerät oder am Rechner richtig einstellen.
+
+ - falsches #ib#Kabel#ie# (z.B. Sende- und Empfangsleitungen fälschlich gekreuzt bzw.
+ nicht gekreuzt, Kabel ohne Flußkontrolle an Schnittstelle mit
+ Flußkontrolle, V.24-Kabel an Parallelschnittstelle oder umge­
+ kehrt):
+
+ Symptome: Keine Ausgabe, keine Eingabe oder andauernder Strom von
+ "Schrottzeichen".
+ Abhilfe: richtiges Kabel nehmen oder Kabel korrigieren.
+
+ - defektes Kabel (Kabelbruch, defekter Stecker o.ä.)
+
+ Symptome: beliebig.
+ Testmöglichkeit: Kabel wechseln.
+
+ - defektes #ib#Endgerät#ie#
+
+ Symptome: beliebig.
+ Testmöglichkeit: Anderes Gerät mit gleicher Einstellung (Baudrate, Parität
+ usw.) anschließen.
+
+ - defekte #ib#Schnittstelle#ie# im Rechner
+
+ Symptome: beliebig
+ Testmöglichkeit: Endgerät mit gleichem Kabel an eine andere Schnittstelle
+ am Rechner anschließen (dazu evtl. die Geräteparameter
+ wie Baudrate anpassen).
+
+
+
+
+
+#ib##ib(9)#Hintergrundtest#ie(9)##ie#
+
+
+Zur Überprüfung des #ib#Hintergrund#ie#es werden drei Tests angeboten:
+
+ (1) #ib#Lesetest#ie#
+ (2) #ib#Lese-/Schreibtest#ie#
+ (3) #ib#Positioniertest#ie#
+
+
+Der #ib##on("i")##on("b")#Lesetest#off("i")##off("b")##ie# prüft, ob alle für EUMEL verfügbaren Blöcke auf der Platte bzw. Floppy
+lesbar sind. Dabei wird der Blockinhalt nicht inspiziert. Sowohl behebbare (soft) als
+auch harte #ib#Lesefehler#ie# werden gemeldet. Der Bediener kann einen Korrekturversuch
+durch Rückschreiben veranlassen. Bei einem #ib#Soft-Error#ie# (Block konnte nach mehreren
+Versuchen doch gelesen werden) wird der gelesene Block neu geschrieben. Der Fehler
+kann jetzt ohne negative Folgen behoben sein, bei defekter Hardware aber auch zu
+Folgefehlern führen.
+Als Korrekturversuch bei harten Fehlern wird ein mit 'FFFD' gefüllter Block geschrie­
+ben. Wird ein solcher Block später vom EUMEL gelesen und als Code angesehen, führt
+das zur Fehlermeldung "#ib#code block unreadable#ie#". Wird FFFD als INT angesehen, liefert
+es den Wert -3, bei REAL oder TEXT können keine Vorhersagen gemacht werden.
+
+
+Bei dem #ib##on("i")##on("b")#Schreib-/Lesetest#off("i")##off("b")##ie# wird jeder Block mit mehreren Bitmustern beschrieben und
+zur Kontrolle wieder gelesen. Der alte Inhalt wird vor dem Test gesichert und nachher
+wieder in den Block geschrieben.
+
+ #on("b")#Achtung: Normalerweise zerstört der Test den EUMEL-Hintergrund nicht. Bei
+ defekter Platte können allerdings Blöcke durch mißlungenes Rück­
+ schreiben zerstört werden. #off("b")#
+
+
+Der #ib##on("i")##on("b")#Positioniertest#off("i")##off("b")##ie# arbeitet ähnlich wie die Leseprüfung. Allerdings wird in der Reihen­
+folge 0, 1, 0, 2, 0, 3, ... gelesen, so daß die Platte für jeden Lesevorgang positionieren
+muß.
+
+ #on("b")#Achtung: Wegen der harten Plattenbelastung sollte dieser Test nicht zu lange
+ laufen.#off("b")#
+
+
+
+
+
+#ib##ib(9)#Archivtest#ie##ie(9)#
+
+
+Der Archivtest arbeitet ähnlich wie der Hintergrundtest - allerdings auf dem Archiv. Er
+kann sowohl zur Überprüfung von Archiv-Datenträgern (#ib#Lesetest#ie#) als auch zum Test
+des #ib#Archivlaufwerks#ie# benutzt werden.
+
+
+
+
+
+#ib(9)#2.3. #ib#Serielle Geräteschnittstelle#ie##ie(9)#
+
+
+#ib##ib(9)#Pinbelegung und Kabel#ie(9)##ie#
+
+
+#on("b")##on("i")#Anmerkung: Dieses Kapitel ist nur für solche Anwender von Bedeutung, die sich selbst
+ mit der Verkabelung ihrer Geräte befassen.#off("i")##off("b")#
+
+Im folgenden werden die wichtigsten Leitungen der offiziellen #ib#V.24-Schnittstelle#ie# (#ib#seriel­
+le Schnittstelle#ie# zum Anschluß von Terminals, Druckern, Fremdrechnern u.ä.) beschrie­
+ben:
+
+ Pin Betriebsrichtung Bedeutung
+
+ 2 out Sendedaten
+ 3 in Empfangsdaten
+
+ 4 out Sendeaufforderung (RTS)
+ 5 in Empfangsbereitschaft (CTS)
+
+ 7 Signalerde
+
+ 8 in Gegenstation bereit (DCD)
+
+ 20 out eigene Station bereit (DTR)
+
+
+Dabei dient das Paar (2,3) zur Übertragung der Daten, mit Hilfe von (4,5) ist #ib#Flußkon­
+trolle#ie# möglich (z.B. kann ein Drucker damit Sendungen vom Rechner "verlangsamen").
+Das Paar (8,20) wird bei manchen Geräten und Rechnern benutzt, um festzustellen, ob
+die Gegenstation eingeschaltet ist.
+
+
+Die meisten Rechner haben die gleiche #ib#Pinbelegung#ie# wie oben aufgeführt. Die Kabel
+müssen dann die folgenden #ib#Pin#ie#s verbinden:
+
+
+Rechner 2 3 4 5 7 8 20 Vollständige Verbindung mit Flußkontrolle.
+
+Gerät 2 3 4 5 7 8 20
+
+
+Rechner 2 3 4 5 7 Reicht für die meisten Anschlüsse mit Flußkontrol­
+ le, z.B. Rechnerkopplung.
+Gerät 2 3 4 5 7
+
+
+Rechner 2 3 5 7 Reicht für die meisten Drucker, Flußkontrolle nur
+ einseitig vom Drucker zum Rechner.
+Gerät 2 3 4 7
+
+
+Rechner 2 3 7 Reicht meistens für Terminals, Flußkontrolle ist
+ dabei überflüssig.
+Gerät 2 3 7
+
+
+Rechner 2 3 4 5 7 Manchmal für Terminals. Rechnerseitig wird Fluß­
+ kontrolle durch die Brücke 4-5 simuliert.
+Gerät 2 3 7
+
+
+Bei manchen Rechnern werden die notwendigen paarweisen Vertauschungen schon
+im Rechner durchgeführt. Es ergibt sich entsprechend:
+
+
+Rechner 2 3 4 5 7 8 20 Vollständige Verbindung mit Flußkontrolle.
+
+Gerät 2 3 4 5 7 8 20
+
+
+Rechner 2 3 4 5 7 Einfacher Anschluß mit Flußkontrolle.
+
+Gerät 2 3 4 5 7
+
+
+Rechner 2 3 4 7 Drucker, einseitige Flußkontrolle.
+
+Gerät 2 3 4 7
+
+
+Rechner 2 3 7 Terminal.
+
+Gerät 2 3 7
+
+
+Rechner 2 3 4 5 7 Terminal mit simulierter Flußkontrolle.
+
+Gerät 2 3 7
+
+
+
+
+
+
+
+#ib(9)#2.4. #ib#Kanäle#ie# und #ib#Konfigurierung#ie##ie(9)#
+
+
+
+Im EUMEL-System dienen #ib#Kanäle#ie# zur Kommunikation mit der Außenwelt, d.h. Kanäle
+sind Verbindungen vom Rechner zu peripheren Geräten wie Terminals, Drucker, Plotter
+und Archiv. Kanäle können für zeichen- und #ib#blockorientierte Ein-/Ausgabe#ie# verwendet
+werden. Ein Kanal heißt #ub##ib#privilegiert#ie(1,"er Kanal")##ue#, wenn er nur von privilegierten Systemtasks (Nach­
+kommen des Supervisors) benutzt werden kann.
+
+#ib#Kanalaufteilung#ie#:
+
+ Kanal Bedeutung
+
+ 1 zeichenorientiert, blockorientiert
+ Dieser Kanal muß mit einem Terminal verbunden sein, da
+ über ihn der Systemstart erfolgt.
+ 2-16 zeichenorientiert, blockorientiert
+ Diese Kanäle werden für weitere Terminals, Drucker, Plot­
+ ter, Rechnerkopplung usw. verwandt.
+
+ 15-23 blockorientiert
+
+ 24-30 blockorientiert, privilegiert
+
+ 31 blockorientiert, privilegiert
+ Dieser Kanal ist der #ib#Standardkanal des Archivsystems#ie#, d.h.
+ üblicherweise wird darüber die Archivfloppy angesprochen.
+
+ 32 blockorientiert, privilegiert
+ Dieses ist ein #ib#interner Kanal#ie#, an den kein externes Gerät
+ angeschlossen werden kann. Er wird zur Konfigurierung
+ der anderen Kanäle benutzt.
+
+Der Supervisor des EUMEL-Systems verwaltet die Kanäle. Jeder Task ist dabei kein
+oder genau ein Kanal zugeordnet. Entsprechend ist jedem Kanal keine oder genau
+eine Task zugeordnet. Solche Zuordnungen können von außen durch den Benutzer
+(nur bei interaktiven Kanälen) über die SV-Kommandos bzw. Prozeduraufrufe 'conti­
+nue' und 'break' (s. Kap. 5) verändert werden. In jedem Fall überprüft der Supervisor
+die Zugriffsberechtigung.
+
+
+
+
+
+#ib##ib(9)#Zeichenorientierte Ein-/Ausgabe#ie##ie(9)#
+
+
+Zeichenorientierte Ein-/Ausgabe kann auf den Kanälen 1 bis 16 benutzt werden. Dafür
+stehen die Basisoperationen
+
+ PROC #ib#out#ie# (TEXT CONST text)
+ PROC #ib#outsubtext#ie# (TEXT CONST source,
+ INT CNST from)
+ PROC outsubtext (TEXT CONST source,
+ INT CONST from, to)9
+ PROC #ib#cursor#ie# (INT CONST x, y)
+ PROC #ib#inchar#ie# (TEXT VAR char)
+ TEXT PROC #ib#incharety#ie#
+ TEXT PROC incharety (INT CONST time limit)
+ PROC #ib#get cursor#ie# (INT VAR x, y)
+
+und alle darauf aufbauenden Operationen (wie 'put', 'get', 'putline', 'getline' usw.) zur
+Verfügung. Diese Kanäle sind 'konfigurierbar' (s.u.) und erlauben den Anruf des
+Systems durch den Benutzer von außen (SV-Taste). In der Regel werden die Kanäle 1
+bis 16 für Terminals, Drucker, Plotter und andere zeichenorientierte Anschlüsse be­
+nutzt.
+Wenn ein Kanal zum Anschluß eines Terminals verwendet wird, müssen die #ib#Standard-
+Steuerzeichen#ie# des EUMEL-Systems (s. Benutzerhandbuch Programmierung, Kap. 3
+"Der Editor", "5.2.4. Der EUMEL-Zeichensatz") auf jedem Terminal die gleiche Semantik
+haben. Das heißt beispielsweise, daß der Code ""2"" auf jedem Terminal bei Ausgabe
+den Cursor um eine Stelle nach rechts verschiebt. Da Datenendgeräte in dieser Hin­
+sicht aber faktisch keiner Norm gehorchen, müssen die EUMEL-Codes in der Regel in
+#ib#terminalspezifische Codes#ie# umgesetzt werden. Diese Umsetzregeln kann man bei der
+Konfigurierung (s.u.) festlegen. Für die meisten Terminaltypen werden allerdings
+fertige Konfigurationssätze mit dem EUMEL-System zusammen ausgeliefert, die man
+bei der Einrichtung des Systems (s. Kap. 1 Installationsanleitung) interaktiv anwählen
+kann.
+
+
+
+
+#ib##ib(9)#Blockorientierte Ein-/Ausgabe#ie##ie(9)#
+
+
+Blockorientiere Ein-/Ausgabe kann auf den Kanälen 1 bis 32 benutzt werden. Dafür
+stehen die Operationen
+
+ PROC #ib#control#ie# (INT CONST code1, code2, code3,
+ INT VAR return code)
+ PROC #ib#blockout#ie# (DATASPACE CONST ds,
+ INT CONST page nr, code1, code2, INT VAR return code)
+ PROC #ib#blockout#ie# (ROW 256 INT CONST block,
+ INT CONST code1, code2, INT VAR return code)
+ PROC #ib#blockin#ie# (DATASPACE VAR ds,
+ INT CONST page nr, code1, code2, INT VAR return code)
+ PROC #ib#blockin#ie# (ROW 256 INT VAR block,
+ INT CONST code1, code2, INT VAR return code)
+
+zur Verfügung. Näheres findet man in Kap. 4.5 dieses Systemhandbuchs.
+
+
+
+
+
+#ib##ib(9)#Konfigurierung von Kanal 1 bis 15#ie(9)##ie#
+
+
+
+Alle #ib#zeichenorientierten Kanäle#ie# können (mittels Block I/O auf Kanal 32) konfiguriert
+werden. Dabei werden im wesentlichen #ib#Umsetzregeln#ie# für Ein- und Ausgabe definiert,
+die den Zweck haben,
+
+ - bei der Ausgabe den EUMEL Zeichensatz auf den Zeichensatz des ange­
+ schlossenen Geräts abzubilden und
+
+ - bei der Eingabe die gerätespezifischen Zeichen auf den EUMEL Zeichensatz
+ abzubilden.
+
+So ist eine geräteunabhängige Programmierung möglich.
+
+Mit Hilfe der Prozedur '#ib#link#ie#' kann man einen der Kanäle 1 bis 16 auf einen bestimm­
+ten Typ setzen. Immer vorhanden sind die Typen:
+
+"#ib#transparent#ie#": Keine Codeumsetzungen (für Drucker usw.) und
+"#ib#psi#ie#" : Keine Codeumsetzungen, jedoch folgende Sonderfunktionen:
+#free(1.0)#
+ Code Funktion
+ 7 (CTLg) SV
+ 17 (CTLq) Stop
+ 23 (CTLw) Weiter
+
+Weitere Typen müssen in Form eines DATASPACE, die nach den Gerätetypen benannt
+sind, in der Task vorliegen, in der das Kommando 'link' gegeben wird.
+
+Neue Terminaltypen können mit den Prozeduren 'new type', 'enter outcode', 'enter
+incode' usw. definiert werden. Im einzelnen stehen folgende Prozeduren zur Verfü­
+gung:
+
+
+#ib#link#ie#
+ PROC link (INT CONST channel, TEXT CONST type)
+ Zweck: Der angegebene Kanal (1 bis 16) wird auf den angegebenen Typ konfi­
+ guriert.
+ Hinweis: Die Prozedur 'link' hat die angegebene Wirkung nur, wenn
+ die Task an Kanal 32 hängt, der nur für Söhne des
+ SUPERVISOR zugänglich ist ('continue (32)').
+
+#ib#y size#ie#
+ PROC y size (INT CONST channel, new size, INT VAR old size)
+ Zweck: Einstellmöglichkeiten für verschiedene Bildschirmgrößen. Diese Proze­
+ dur wirkt nur auf Kanal 32. 'channel' gibt dabei den zu konfigurierenden
+ Kanal an.
+
+#ib#new type#ie#
+ PROC new type (TEXT CONST typ)
+ Zweck: Eröffnet einen neuen Kanaltyp mit dem Namen 'typ'. Die folgenden
+ Aufrufe von 'enter outcode', 'enter incode' usw. beziehen sich dann auf
+ diesen Typ.
+
+#ib#enter outcode#ie#
+ PROC enter outcode (INT CONST eumelcode, zielcode)
+ Zweck: Legt fest, daß der Code 'eumelcode' bei Ausgabe auf dem Terminaltyp
+ in 'zielcode' gewandelt werden soll.
+
+ PROC enter outcode (INT CONST eumelcode, TEXT CONST zeichen)
+ Zweck: Wirkt wie 'enter outcode (eumelcode, code (zeichen))'.
+
+ PROC enter outcode (INT CONST eumelcode, zeit, TEXT CONST seq)
+ Zweck: Hiermit wird festgelegt, daß der Code 'eumelcode' als Mehrzeichenfolge
+ 'seq' ausgegeben werden soll. Jedesmal, wenn diese Folge ausgegeben
+ wurde, verzögert das System die Ausgabe des nächsten Zeichens um
+ mindestens 'zeit' Millisekunden. Dies wird z.B. von den meisten Termi­
+ nals gefordert, wenn sie die Funktion 'Löschen Bildschirm' ausführen
+ sollen.
+
+#ib#enter incode#ie#
+ PROC enter incode (INT CONST eumelcode, TEXT CONST seq)
+ Zweck: Es wird festgelegt, daß eine Eingabezeichenfolge 'seq' an das System
+ als ein (!) Zeichen mit dem Code 'eumelcode' weitergegeben werden
+ soll. Die ganze Sequenz muß dabei innerhalb von ca. 40 Millisekunden
+ eintreffen, andernfalls werden die Zeichen einzeln gemeldet. Diese
+ Logik ist erforderlich, um auch Terminals anzuschließen, die z.B. Cursor­
+ tasten als ESC-Sequenzen melden. Ohne die Zeitüberwachung würde
+ das Betätigen der ESC-Taste sonst die Eingabe blockieren, bis die Folge
+ 'seq' vollständig ist.
+ Folgende Eumelcodes sind für die Sondertasten (SV usw.) anzugeben:
+
+ 17 : STOP
+ 23 : WEITER
+ 7 : SV
+
+ Weitere Codes ('HOP',...) sind im Benutzerhandbuch Programmierung
+ (5 - 29, Der EUMEL-Zeichensatz) angegeben.
+
+ #on("i")#Hinweis: Liefert die SV-Taste eines Terminals von sich aus schon Code
+ 7, so ist dennoch 'enter incode (7, ""7"")' anzugeben. Entspre­
+ chendes gilt für die zwei anderen "Ereignistasten" STOP und
+ WEITER. Bei allen anderen Tasten brauchen jedoch nur echte
+ Umcodierungen vermerkt zu werden.#off("i")#
+
+
+#ib#cursor logic#ie#
+ PROC cursor logic (INT CONST offset, modus, TEXT CONST pre, mid, post)
+ Zweck: Es wird festgelegt, daß der EUMEL-Code 6 (Cursorposition) mit den
+ folgenden beiden Zeichen, deren Codes y und x seien,
+
+ bei modus = 255 als
+ pre + code (offset+y) + mid + code (offset+x) + post
+ und bei modus = 1 als
+ pre + text (offset+y) + mid + text (offset+x) + post
+
+ ausgegeben wird.
+ Hinweis: 'offset' ist üblicherweise 32 (manchmal 0) und
+ mid = post = "".
+
+#ib#cursor logic#ie#
+ PROC cursor logic (INT CONST dist, TEXT CONST pre, mid, post)
+ Zweck: Diese Prozedur wird von den Konfigurationsdateien alter Versionen
+ benutzt.
+
+#ib#ansi cursor#ie#
+ PROC ansi cursor (TEXT CONST pre, mid, post)
+ Zweck: Diese Prozedur ist anstelle von 'cursor logic' zu verwenden, wenn die
+ Cursor-Positionierungen bei dem Terminal so erfolgt, wie im Ansi-
+ Standard definiert wird.
+
+#ib#elbit cursor#ie#
+ PROC elbit cursor
+ Zweck: Diese Prozedur ist bei Elbit-Terminals anstelle von 'cursor logic' zu
+ verwenden.
+
+
+
+
+
+
+#ib##ib(9)#Konfigurations-Manager#ie##ie(9)#
+
+
+Wenn das System gestartet wird, weiß der Urlader noch nicht, welche #ib#Terminaltypen#ie#
+an welchen Kanälen hängen. (Der Vortest kann deshalb auch nicht bildschirmorien­
+tiert arbeiten).
+
+Falls eine Task 'configurator' im System ist, schickt der SUPERVISOR dieser eine Start­
+sendung zu. Diese Task kann daraufhin die nötigen Konfigurierkommandos ('link',...)
+ausführen.
+
+Ansonsten ist 'configurator' ein normaler Fontmanager, der die Fonttabellen verwaltet
+(siehe Kap. 7). Deshalb sollte im System immer eine Task 'configurator' existieren und
+nach Möglichkeit immer im 'wait' stehen. Man kann ihn also auch mit 'continue' an ein
+Terminal holen und dann wie üblich Kommandos geben.
+
+#ib#configurate#ie#
+ PROC configurate
+ Zweck: Führt den Konfigurationsdialog und anschließendes 'setup' durch.
+
+#ib#setup#ie#
+ PROC setup
+ Zweck: Alle Kanäle werden gemäß der im letzten Konfigurationsdialog bestimm­
+ ten Werte konfiguriert (wird automatisch bei jedem Systemstart durch­
+ geführt).
+
+#ib#configuration manager#ie#
+ PROC configuration manager
+ Zweck: Durch Aufruf dieser Prozedur wird die Task zu einem Konfigurations­
+ manager. Man kann also die Task "configurator" löschen, neu als
+ Systemtask einrichten und mit diesem Kommando wieder etablieren.
+ BEACHTE: - Die Task muß 'configurator' heißen.
+ - Alle Terminalanpassungen gehen beim Löschen verloren, d.h.
+ man sollte sie vorher sichern!
+
+
+#on("i")#Hinweis: Es passieren, daß eine Task schon Ausgaben macht, bevor der Kanal
+ konfiguriert ist (z.B. wenn ein 'shutup' bei aktiver Netz-Kommunikation
+ durchgeführt wurde).#off("i")#
+
diff --git a/doc/system/systemhandbuch.2 b/doc/system/systemhandbuch.2
new file mode 100644
index 0000000..c4772f0
--- /dev/null
+++ b/doc/system/systemhandbuch.2
@@ -0,0 +1,1351 @@
+#start(2.5,1.5)#
+#pageblock#
+#block#
+#page (35)#
+#headeven#
+
+%#center#EUMEL-Systemhandbuch
+
+
+#end#
+#headodd#
+
+#center#3. ELAN-Programme#right#%
+
+
+#end#
+
+
+#ib(9)#3. #ib#ELAN-Programme#ie##ie(9)#
+
+
+
+
+#ib(9)#3.1. #ib#Wertebereich#ie#e und #ib#Speicherbedarf#ie##ie(9)#
+
+
+#ib#INT-Objekte#ie#
+
+
+Jedes #ib#Datenobjekt#ie# vom Typ INT belegt im Speicher 2 Bytes. Mögliche INT-Werte sind
+die ganzen Zahlen von -32768 bis +32767 einschließlich.
+
+
+
+
+#ib#REAL-Objekte#ie#
+
+
+Jedes Datenobjekt vom Typ REAL belegt im Speicher 8 Bytes.
+
+REALs haben eine 13-stellige #ib#Mantisse#ie#, die im Rechner dezimal geführt wird. (Das
+heißt, bei Konversionen zwischen interner und TEXT-Darstellung treten keine Run­
+dungsfehler auf.) Der Wertebereich wird durch folgende Eckwerte abgelegt:
+
+ 9.999999999999e+126 größter REAL-Wert
+ 0.000000000001 kleinster positiver REAL-Wert mit x + 1.0 > 1.0
+ 9.999999999999e-126 kleinster positiver REAL-Wert > 0.0
+ -9.999999999999e-126 größter negativer REAL-Wert
+ -9.999999999999e+126 kleinster REAL-Wert
+
+
+
+
+
+#ib#BOOL-Objekte#ie#
+
+
+Jedes Datenobjekt vom Typ BOOL belegt im Speicher 2 Bytes.
+
+
+
+
+
+#ib#TEXT-Objekte#ie#
+
+
+Jedes Datenobjekt vom Typ TEXT besteht aus einem festen Teil von 16 Bytes und
+möglicherweise aus einem flexiblen Teil auf dem #on("i")##on("b")##ib#Heap#ie##off("i")##off("b")#. Im festen Teil werden #ib#Texte bis
+zur Länge von 13 Zeichen#ie# untergebracht. Wenn eine TEXT-Variable einen Wert mit
+mehr als 13 Zeichen Länge annimmt, werden alle Zeichen auf dem Heap unterge­
+bracht. Genauer ergibt sich folgendes Bild:
+
+ kurzer Text (LENGTH <= 13):
+
+ Heap-Link 2 Bytes
+ Textlänge 1 Byte
+ Text 13 Bytes
+
+ langer Text (LENGTH > 13):
+
+ Heap-Link 2 Bytes
+ 255 1 Byte
+ Länge 2 Bytes
+ ungenutzt 11 Bytes
+
+Wenn eine Variable einmal Platz auf dem Heap bekommen hat, behält sie diesen
+vorbeugend auch dann, wenn sie wieder einen kurzen Text als Wert erhält. So muß
+wahrscheinlich kein neuer Platz auf dem Heap zugewiesen werden, wenn sie wieder
+länger wird. Das gilt allerdings nur bis zur nächsten #ib#Garbage Collection#ie# auf den
+TEXT-Heap, denn dabei werden alle Heap-Container minimal gemacht bzw. gelöscht,
+wenn sie nicht mehr benötigt werden. Der Platz auf dem Heap wird in Vielfachen von
+16 Bytes vergeben. In Fremddatenräumen wird in jedem #ib#Container#ie# neben dem eigent­
+lichen Text auch die Containerlänge untergebracht.
+
+Beispiele: TEXT-Länge Speicherbedarf (Byte)
+
+ 0 16
+ 13 16
+ 14 32
+ 15 48
+ 30 48
+ 31 64
+ 46 64
+ 47 80
+ 62 80
+
+
+Die Heapgröße eines Fremddatenraums berechnet sich als:
+
+ 1024 * 1024 - 520 = 1048056 - stat Bytes
+
+'stat' ist dabei die statistische Größe der Datenstruktur, die dem Datenraum aufgeprägt
+wurde. Bei einem BOUND ROW 1000 TEXT ergibt sich also eine Heapgröße von
+
+ 1048056 - (1000 * 16) = 1032056 Bytes.
+
+
+
+
+
+
+#ib#ROW- und STRUCT-Objekte#ie#
+
+
+Bei der Berechnung des Speicherbedarfs von #ib#STRUCT#ie#s und #ib#ROW#ie#s muß man beden­
+ken, daß längere Datenobjekte ausgerichtet werden. Und zwar werden alle Objekte, die
+mindestens die Länge eines REAL-Objektes haben, auf durch 8 teilbare Speichera­
+dressen ausgerichtet. Man bedenke, daß bei ROWs alle Elemente entsprechend ihres
+Elementtyps ausgerichtet sind.
+
+Beispiele: Länge (Byte)
+
+ ROW 2 BOOL 4
+ ROW 4 INT 8
+ ROW 5 INT 16
+ ROW 2 STRUCT (INT, BOOL) 4
+ ROW 100 STRUCT (INT,INT) 400
+ ROW 100 STRUCT (INT,REAL) 1600
+ ROW 100 STRUCT (INT,INT,INT,INT,REAL) 1600
+ ROW 100 STRUCT (REAL, REAL) 1600
+ ROW 100 STRUCT (INT,TEXT) 2400
+ ROW 100 STRUCT (INT,INT,INT,INT,TEXT) 2400
+ ROW 100 STRUCT (INT,TEXT,INT,TEXT) 4800
+ ROW 100 STRUCT (INT,INT,TEXT,TEXT) 4000
+ ROW 100 ROW 3 INT 600
+ ROW 100 ROW 4 INT 800
+ ROW 100 ROW 5 INT 1600
+aber:
+ ROW 500 INT 1000
+
+#on("i")#Anmerkung: Bei der #ib#Speichervergabe#ie# der einfachen Variablen und Konstanten eines
+ Programms spielen Verluste aufgrund von Ausrichtungen in der Regel
+ keine Rolle. Der ELAN-Compiler optimiert dabei soweit möglich.#off("i")#
+#page#
+#headeven#
+
+%#center#EUMEL-Systemhandbuch
+
+
+#end#
+#headodd#
+
+#center#4. Standardpakete für Systemprogrammierer#right#%
+
+
+#end#
+
+
+#ib(9)#4. #ib#Standardpakete für
+ Systemprogrammierer#ie(9)##ie#
+
+
+#ib(9)#4.1. #ib#Fehlerbehandlung#ie##ie(9)#
+
+
+Übersicht
+
+
+#on("italics")#
+ Fehler treten auf, wenn ein Programm eine gewünschte Leistung
+ nicht erbringen kann. Solche Situationen müssen von System-
+ Programmen kontrolliert behandelt werden. Die folgenden Aus­
+ führungen sind somit nur für diejenigen interessant, die "Sy­
+ stem"-Programme schreiben wollen.#off("italics")#
+
+#ib#Fehler#ie# treten in Operationen auf, wenn diese eine geforderte Leistung nicht erbringen
+können (z.B. das Drucken einer nicht vorhandenen Datei). Da folgende Anweisungen
+aber davon ausgehen, daß die gewünschten Leistungen erbracht wurden, ist es nicht
+sinnvoll, die Operation weiter auszuführen. Wir sprechen vom #ib#Abbruch einer Operation#ie#,
+wenn nach einem Fehler keine Anweisungen mehr ausgeführt werden, sondern die
+Operation verlassen wird. Im EUMEL-System kann durch folgende drei Maßnahmen
+ein Abbruch verursacht werden:
+
+- Aufruf der Prozedur '#ib#errorstop#ie#':
+ Die Operation wird mit einer Fehlermeldung abgebrochen, die man dem Aufruf von
+ 'errorstop' als Parameter beifügt werden kann.
+
+- Aufruf der Prozedur '#ib#stop#ie#':
+ Die Operation wird abgebrochen. Wirkt wie 'errorstop' mit der Meldung "stop".
+
+- Umschalten in den Supervisor:
+ Durch Betätigen der Taste SV und Eingabe des Kommandos '#ib#halt#ie#'. Die laufende
+ Operation wird abgebrochen. Wirkt wie ein 'errorstop', der von "außen" in das
+ Programm induziert wird.
+
+Da alle drei Maßnahmen zum Abbruch führen können und somit eine anormale (vor­
+zeitige) Beendigung eines Programms bewirken, werden sie im folgenden zusammen­
+fassend als #ib#Fehler#ie# bezeichnet.
+
+Für solche Fehler bietet das EUMEL-System die Möglichkeit, den Abbruch zu unter­
+drücken. Dies kann notwendig werden, wenn
+
+a) bestimmte Fehlerfälle vom aufrufenden Programm selbst behandelt werden sollen.
+ Beispiel:
+
+ Der EUMEL-Editor wird aufgerufen, um eine Datei zu bearbeiten. Er versucht als
+ erstes, die Datei zu assoziieren. Existiert die Datei nicht, wird die Prozedur
+ (z.B. 'old'), mit der die Datei angemeldet werden soll, normalerweise mit der Feh­
+ lermeldung ' "datei" gibt es nicht' abgebrochen. Diesen Fehlerzustand fängt der
+ Editor jedoch ab und versucht, eine neue Datei einzurichten (Anmerkung: In Wirk­
+ lichkeit fragt der Editor natürlich vor der Assoziierung mit 'exists' ab, ob die Datei
+ existiert).
+
+b) eine Operation die Kontrolle auf jeden Fall behalten soll.
+
+ Dies ist z.B. beim Monitor notwendig. Gleich welche Fehler vom Monitor gerufene
+ Programme produzieren, der Monitor muß in der Lage sein, die weitere Bearbei­
+ tung zu ermöglichen.
+
+c) eine Operation nicht unterbrechbar sein darf.
+
+ Beispielsweise dürfen Programm(teil)e, die Daten transportieren, nicht unterbro­
+ chen werden, da sonst ein Verlust dieser Daten eintreten könnte.
+
+
+
+#ib(9)##ib#Fehlerbehandlung#ie# und #ib#Fängerebenen#ie##ie(9)#
+
+
+Der Aufruf einer der Prozeduren
+
+ #ib#errorstop#ie#
+ #ib#stop#ie#
+ #ib#halt#ie#
+
+(wobei letztere vom Supervisor gegeben werden muß) werden zusammenfassend als
+#ib#Fehler#ie# bezeichnet. Bei einem Fehler wird ein #ib#Fehlerzustand#ie# gesetzt. Im Fehlerzustand
+merkt sich das EUMEL-System, daß ein Fehler vorliegt. Die Prozeduren
+
+ #ib#enable stop#ie#
+ #ib#disable stop#ie#
+
+bestimmen, ob Operationen im Fehlerzustand weiter bearbeitet oder abgebrochen
+werden. Beispiel:
+
+
+ INT VAR x;
+ get (x);
+ ...
+ disable stop;
+ x := x * x;
+ ...
+
+
+Hier wird mit 'disable stop' verhindert, daß ein Abbruch beispielsweise durch 'INT-
+Ueberlauf' auftreten kann. Die Anweisungen nach 'x * x' werden also weiter bearbei­
+tet.
+
+Welchen Wert hat aber nun die Variable 'x', nachdem der Fehler auftrat? Offensicht­
+lich war die den Fehler auslösende Operation '*' nicht in der Lage, den richtigen Wert
+zu errechnen. #ib#Abgebrochene Operationen#ie# liefern in der Regel keinen Wert. Dadurch ist
+der Wert von 'x' in unserem Beispiel nach einem Fehler bei '*' undefiniert. Es ist nun
+ersichtlich, daß mit der Anwendung der 'disable stop'-Prozedur äußerst vorsichtig zu
+verfahren ist, weil u.U. Werte verloren gehen können bzw. mit unerwarteten Werten
+weitergerechnet wird.
+
+Damit Programmierer erfahren können, ob ein Fehler aufgetreten ist, gibt es die Infor­
+mations-Prozedur
+
+ #ib#is error#ie#
+
+über den Fehlerzustand. Die Prozedur liefert den Wert TRUE, wenn ein Fehler vorliegt,
+andernfalls FALSE. Die Prozedur
+
+ #ib#clear error#ie#
+
+"löscht" den Fehlerzustand, d.h. anschließende Abfragen mit 'is error' liefern FALSE.
+(Die "richtige" Reaktion auf den Fehler muß ein Programmierer natürlich selbst be­
+stimmen).
+
+Beispiel:
+
+
+ INT VAR x;
+ get (x);
+ ...
+ disable stop;
+ x := x * x;
+ IF is error
+ THEN put ("'x'-Wert zu groß");
+ x := 0;
+ clear error
+ FI;
+ ...
+
+
+Leider würden jetzt aber auch alle folgenden Anweisungen bei eventuellen Fehlern
+nicht abgebrochen, also auch in Situationen, in denen ein Abbruch erwünscht ist, um
+#ib#Programmierfehler#ie# zu erkennen. Deshalb können durch
+
+ #ib#enable stop#ie#
+
+Abbrüche wieder zugelassen werden. Wenn wir jetzt also schreiben:
+
+
+ INT VAR x;
+ get (x);
+ ...
+ disable stop;
+ x := x * x;
+ IF is error
+ THEN put ("'x'-wert zu gross");
+ x := 0;
+ clear error
+ FI;
+ enable stop;
+ ...
+
+
+dann würden - wie gewünscht - eventuelle Fehler in den Anweisungen nach 'enable
+stop' zu einem Abbruch führen.
+
+Nicht mit '#ib#clear error#ie#' gelöschte Fehler führen bei '#ib#enable stop#ie#' ebenfalls zu einem
+Abbruch. In dem Programmteil
+
+
+ ...
+ disable stop;
+ x := x * x;
+ enable stop;
+ ...
+
+
+würde der eventuell auftretender Fehler 'INT Ueberlauf' nicht abgefangen, sondern nur
+verzögert wirksam, weil er nicht mit 'clear error' gelöscht wurde.
+
+Für die Behandlung von Fehlern durch Benutzer gibt es Prozeduren, die eine adäquate
+Reaktion auf den Fehler erlauben. Mit
+
+ #ib#error message#ie#
+
+können Sie auf die erste Fehlermeldung (eines 'error stop') nach dem letzen 'clear
+error' zugreifen (d.h. Folgefehler verändern nicht die Originalmeldung). Die Prozedur
+
+ #ib#error code#ie#
+
+liefert den #ib#Fehlercode#ie#, der bei der Prozedur 'errorstop' zusätzlich zum #ib#Fehlertext#ie#
+angegeben werden kann.
+
+ #ib#error line#ie#
+
+liefert die Zeilennummer des zuletzt aufgetretenen Fehlers. Mit
+
+ #ib#put error#ie#
+
+kann eine noch anstehende Fehlermeldung ausgegeben werden. Beispiel:
+
+
+ INT VAR x;
+ get (x);
+ ...
+ disable stop;
+ x := x * x;
+ IF is error
+ THEN IF error message = "INT-Ueberlauf"
+ THEN put ("'x'-wert zu gross");
+ ELSE put error
+ FI;
+ clear error
+ FI;
+ enable stop;
+ ...
+
+
+Tritt ein Fehler auf, so wird die den Fehler auslösende Operation entweder abgebro­
+chen oder "normal" weiter bearbeitet, je nachdem, ob 'enable stop' oder 'disable stop'
+gesetzt ist. Auf jeden Fall wird der #ib#Fehlerzustand#ie# an die aufrufende Operation weiter­
+gemeldet, die wiederum abgebrochen oder weiterbearbeitet werden kann usw. Die
+#ib#Weitermeldung#ie# eines Fehlers kann auch über mehrere Stufen erfolgen, solange bis der
+Fehler gelöscht wird. Andererseits gilt 'enable/ disable stop' nicht nur für die aktuelle
+Operation, sondern auch für gerufene Operationen ("Vererbung"). Die gerufenen Ope­
+rationen können allerdings 'enable/disable stop' neu festlegen. Beispiel:
+
+
+ PROC a: PROC b: PROC c:
+ ... ... ROW 10 INT VAR x;
+ disable stop; enable stop; ...
+ b; ... INT VAR i :: 4711;
+ IF is error c; x [i] := ...;
+ THEN ... ... ...
+ clear error END PROC b END PROC c
+ FI;
+ enable stop
+ END PROC a;
+
+
+In der Prozedur 'a' wird die Prozedur 'b' aufgerufen. Diese ruft wiederum eine Prozedur
+'c' auf. Für die Prozedur 'c' gilt nun der Zustand 'enable stop' der Prozedur 'b' (#ib#Verer­
+bung von 'enable stop'#ie#). Tritt jetzt in 'c' der Subskriptions-Fehler auf, wird 'c' abgebro­
+chen. Die Wirkung der fehlerauslösenden Operation ist nicht definiert.
+
+Da aber auch die Prozedur 'b' im 'enable stop' Zustand ist, wird auch die Prozedur 'b'
+abgebrochen. Der Fehler bleibt jedoch erhalten, wird also weitergemeldet. Dies wirkt
+sich so aus, daß die Anweisung 'c' nicht ausgeführt wird. Da die Prozedur 'a' 'disable
+stop' gesetzt hat, werden die auf den Aufruf von 'b' folgenden Anweisungen durchlau­
+fen und somit durch 'clear error' der Fehler gelöscht. In diesem Beispiel "fängt" die
+Prozedur 'a' Fehler auf, die in den Prozeduren 'b' und 'c' entstehen können.
+
+Ein solcher #ib#Fänger#ie# wird durch zwei Prozeduren konstruiert. Der eigentliche Fänger
+(hier: Prozedur 'a') ruft eine ausführende Prozedur (hier: 'b') im 'disable stop'-Zustand
+auf. Die gerufene Prozedur setzt sofort 'enable stop' und führt dann die eigentlichen
+Aktionen aus. So wird die gerufene Prozedur abgebrochen (kann also im Fehlerfall
+nicht zuviel Schaden anrichten). Der Abbruch führt bis zur Fängerprozedur ('a') hinter
+den Aufruf der gerufenen Prozedur ('b'). Nach Löschung eventuell auftretender Fehler
+ist somit sichergestellt, daß der Fänger immer weiterarbeiten kann.
+
+
+
+#ib(9)#Wichtiger Hinweis#ie(9)#
+
+
+
+ 1. #on("italics")##on("bold")#Da im 'disable stop'-Zustand kein Fehler zum Abbruch führt, kann
+ eine Operation in diesem Zustand auch nicht durch 'halt' abge­
+ brochen werden. Einerseits ist das für manche Systemteile wün­
+ schenswert, andererseits können Operationen, die auf Grund von
+ Programmierfehlern nicht terminieren (Endlosschleifen), nicht
+ unter Kontrolle gebracht werden. Also Vorsicht! (Letztes Mittel:
+ Task löschen)#off("italics")##off("bold")#
+
+ 2. #on("i")##on("b")#Es ist nicht (!) garantiert, daß im Fehlerzustand aufgerufene
+ Prozeduren ihre normale Wirkung haben. Garantiert ist dies je­
+ doch für alle Prozeduren und Operatoren, die in diesem Kapi­
+ tel aufgeführt werden.#off("i")##off("b")#
+
+#on("italics")##on("bold")#Merke: Fehler sind im EUMEL-System Aufrufe der Prozeduren 'errorstop',
+ 'stop' oder das Betätigen der SV Taste und dem Supervisor-
+ Kommando 'halt'. Ein Fehler gilt solange, bis er mit Hilfe der
+ Prozedur 'clear error' gelöscht wurde. Die Prozeduren 'enable/
+ disable stop' steuern die Abarbeitung der Operationen im Fehler­
+ fall. Gilt für eine Operation 'enable stop', wird die Operation
+ abgebrochen, d.h. die restlichen Anweisungen der Operation
+ nach der Fehler auslösenden Anweisung werden nicht durchlau­
+ fen. Ist 'disable stop' gesetzt, werden die restlichen Operationen
+ weiterhin abgearbeitet. 'enable/disable stop' gilt für alle - auch
+ indirekt - aufgerufenen Operationen ("Vererbung"), es sei denn, in
+ den gerufenen Operationen wird ein erneutes 'enable/disable
+ stop' gesetzt. Über die Aufrufkette werden ggf. auch die Fehler
+ zurück gemeldet.#off("italics")##off("bold")#
+
+
+ #on("italics")##on("bold")#Eine Fänger-Ebene ist eine Prozedur, die 'disable stop' setzt und
+ dann andere Operationen aufruft. Nach jedem dieser Aufrufe
+ kann eine Fehlerbehandlung mit 'clear error' durchgeführt wer­
+ den. Damit ist gewährleistet, daß Fehler immer von der Fänger-
+ Ebene "aufgefangen" und entsprechend behandelt werden.#off("italics")##off("bold")#
+
+
+
+#ib(9)##ib#Prozeduren zur Fehlerbehandlung#ie##ie(9)#
+
+
+#ib#clear error#ie#
+ PROC clear error
+ Zweck: Löscht den Fehlerzustand. 'is error' liefert anschließend wieder FALSE.
+ 'error message', 'error code' und 'error line' werden nicht gelöscht.
+
+#ib#disable stop#ie#
+ PROC disable stop
+ Zweck: Unterbindet den Abbruch in aufgerufenen Operationen. 'disable stop'
+ gilt für die Prozedur, in der sie aufgerufen wird und in allen folgenden
+ gerufenen Prozeduren, es sei denn, sie wird durch 'enable stop' außer
+ Kraft gesetzt. Wird die Operation verlassen, in der 'disable stop' aufge­
+ rufen wurde, wird der "alte" Zustand wiederhergestellt, der vor dem
+ Aufruf der Operation galt. 'disable stop' kann weiterhin in einer aufge­
+ rufenen Operation durch den Aufruf von 'enable stop' in dieser und den
+ folgenden Operationen außer Kraft gesetzt werden.
+
+#ib#enable stop#ie#
+ PROC enable stop
+ Zweck: Setzt die Wirkung eines Aufrufs von 'disable stop' zurück. Fehler ('error­
+ stop', 'stop' oder 'halt') in der aktuellen Operation oder den folgenden
+ aufgerufenen Operationen führen zum Abbruch. Bisher nicht gelöschte
+ Fehler (siehe 'clear error') führen sofort zum Abbruch.
+
+#ib#error code#ie##--goalpage ("fehlercodes")#
+ INT PROC error code
+ Zweck: Liefert den durch 'errorstop' gesetzten #ib#Fehlercode#ie#. Beispiel:
+
+ PROC test:
+ enable stop;
+ error stop (110, "Dies ist mein Abbruch!");
+ END PROC test;
+
+ ...
+ disable stop;
+ test;
+ put (error code); (* liefert 110 *)
+ clear error;
+ enable stop
+
+
+#ib#error line#ie#
+ INT PROC error line
+ Zweck: Liefert die Zeilennummmer des Fehlers (Voraussetzung : Die Überset­
+ zung erfolgt im 'checkon-Modus).
+
+#ib#error message#ie#
+ TEXT PROC error message
+ Zweck: Liefert die Fehlermeldung als Text. Anhand dieser Meldung kann ent­
+ schieden werden, welcher Fehler vorliegt.
+ Hinweis: Eine Fehlermeldung "" (also: 'error stop ("")') führt zum Fehlerabbruch
+ mit der Bedeutung "Fehlermeldung wurde bereits ausgegeben". Dem­
+ entsprechend erfolgt bei der Fehlermeldung 'niltext' keine Reaktion bei
+ 'put error'.
+
+#ib#errorstop#ie#
+ PROC error stop (TEXT CONST message)
+ Zweck: Bricht ab und setzt die Zeilennummer (wenn man sich im 'checkon'-
+ Modus befindet), in der der Fehler aufgetreten ist, sowie den Text 'mes­
+ sage'. Der Abbruch kann mit 'disable stop' unterbunden werden. 'error­
+ stop' hat keine Wirkung, wenn ein noch nicht gelöschter Fehler vorliegt.
+ Zu einer Fehlermeldung "" siehe auch die Prozedur 'error message'. Als
+ 'error-code' wird 0 gesetzt.
+
+
+ PROC error stop (INT CONST code, TEXT CONST message)
+ Zweck: Analog obiger 'errorstop'-Prozedur, aber mit Angabe des Fehlercodes,
+ der durch die Prozedur 'error code' in einer Fängerebene erfragt wer­
+ den kann.
+
+#ib#is error#ie#
+ BOOL PROC is error
+ Zweck: Informationsprozedur auf das Vorhandensein eines Fehlers.
+
+#ib#put error#ie#
+ PROC put error
+ Zweck: Gibt die durch 'errorstop' gesetzte Fehlermeldung aus, falls ein Fehler
+ noch nicht gelöscht ist (siehe auch: 'error message').
+
+
+
+
+#ib##ib(9)#Fehlercode#ie#s#ie(9)#
+
+
+Einige Fehlercodes sind bereits belegt:
+
+ 0 kein Fehlercode spezifiziert (Standardwert)
+ 1 'halt' vom Terminal
+ 2 Stack-Ueberlauf
+ 3 Heap-Ueberlauf
+ 4 INT-Ueberlauf
+ 5 DIV durch 0
+ 6 REAL-Ueberlauf
+ 7 TEXT-Ueberlauf
+ 8 zu viele DATASPACEs
+ 9 Ueberlauf bei Subskription
+ 10 Unterlauf bei Subskription
+ 11 falscher DATASPACE-Zugriff
+ 12 INT nicht initialisiert
+ 13 REAL nicht initialisiert
+ 14 TEXT nicht initialisiert
+ 15 nicht implementiert
+ 16 Block unlesbar
+ 17 Codefehler
+ 100 Syntax-Fehler beim Übersetzen
+
+
+
+
+
+#ib(9)#4.2. #ib#THESAURUS#ie##ie(9)#
+
+
+
+Ein #ib#Thesaurus#ie# ist ein #ib#Namensverzeichnis#ie#, das bis zu 200 Namen beinhalten kann.
+Dabei muß jeder Namen mindestens ein Zeichen und darf höchstens 100 Zeichen lang
+sein. Steuerzeichen (code < 32) sind in Namen nicht erlaubt.
+
+Ein Thesaurus ordnet jedem eingetragenen Namen einen Index zwischen 1 und 200
+(einschließlich) zu. Diese Indizes bieten dem Anwender die Möglichkeit, Thesauri zur
+Verwaltung benannter Objekte zu verwenden. (Der Zugriff erfolgt dann über den Index
+eines Namens in einem Thesaurus). So werden Thesauri u.a. von der Dateiverwaltung
+benutzt. Sie bilden die Grundlage der ALL- und SOME-Operatoren.
+
+
+
+
+#ib(9)#Grundoperationen#ie(9)#
+
+
+#ib#CONTAINS#ie#
+ BOOL OP CONTAINS (THESAURUS CONST t, TEXT CONST name)
+ Zweck: Liefert genau dann TRUE, wenn 't' den Namen 'name' enthält. Falls
+ 'name=""' oder 'LENGTH name > 100', wird FALSE geliefert.
+
+#ib#delete#ie#
+ PROC delete (THESAURUS VAR t, TEXT CONST name, INT VAR index)
+ Zweck: Falls der Name 'name' im Thesaurus 't' enthalten ist, wird er dort ge­
+ löscht. In 'index' wird dann sein alter Index geliefert, unter dem er im
+ Thesaurus eingetragen war. Ist der Name nicht im Thesaurus enthalten,
+ wird 0 als Index geliefert.
+
+ PROC delete (THESAURUS VAR t, INT CONST index)
+ Zweck: Der Eintrag mit dem angegebenen Index wird aus dem Thesaurus 't'
+ gelöscht.
+
+#ib#empty thesaurus#ie#
+ THESAURUS PROC empty thesaurus
+ Zweck: Für Initialisierungszwecke wird ein leerer Thesaurus geliefert.
+
+#ib#get#ie#
+ PROC get (THESAURUS CONST t, TEXT VAR name, INT VAR index)
+ Zweck: Liefert den "nächsten" Eintrag aus dem Thesaurus 't'. "Nächster" heißt
+ hier, der kleinste vorhandene mit einem Index größer als 'index'. Dabei
+ wird in 'name' der Name und in 'index' der Index des Eintrags geliefert.
+ D.h. 'index' wird automatisch weitergeschaltet. Den ersten Eintrag erhält
+ man entsprechend durch Aufruf mit 'index=0'. Nach dem letzten Ein­
+ trag wird 'name=""' und 'index=0' geliefert. Beispiel:
+
+
+ TEXT VAR name;
+ INT VAR index := 0 ;
+ get (thesaurus, name, index) ;
+ WHILE index > 0 REP
+ putline (name) ;
+ get (thesaurus, name, index)
+ PER
+
+
+#ib#highest entry#ie#
+ INT PROC highest entry (THESAURUS CONST t)
+ Zweck: Liefert den höchsten belegten Index des Thesaurus 't'.
+ Achtung: Das ist nicht die Anzahl der vorhandenen Namen, da durch
+ Löschungen Lücken entstanden sein können.
+
+#ib#insert#ie#
+ PROC insert (THESAURUS VAR t, TEXT CONST name, INT VAR index)
+ Zweck: Der Name 'name' wird als zusätzlicher Eintrag in den Thesaurus 't'
+ eingetragen und der dafür vergebene Index geliefert. Falls der Thesau­
+ rus schon voll ist und der Name nicht mehr eingetragen werden kann,
+ wird 0 als Index geliefert.
+ Achtung: Mehrfacheintragungen sind möglich. Wenn man diese verhin­
+ dern will, muß man entsprechend vermittels
+
+
+ IF NOT t CONTAINS name
+ THEN insert (t, name, index)
+ FI
+
+
+ eintragen.
+ Fehlerfall:
+ * Name unzulaessig
+
+ PROC insert (THESAURUS VAR t, TEXT CONST name)
+ Zweck: s.o. Allerdings wird der Index des Namens nicht geliefert. Ein Thesau­
+ rusüberlauf wird entsprechend als 'errorstop' gemeldet.
+ Fehlerfälle:
+ * Name unzulaessig
+ * THESAURUS-Ueberlauf
+
+#ib#link#ie#
+ INT PROC link (THESAURUS CONST t, TEXT CONST name)
+ Zweck: Liefert den Index des Namens 'name' im Thesaurus 't'. Falls der Name
+ nicht enthalten ist, wird 0 geliefert. Ist der Name mehrfach im Thesau­
+ rus enthalten, ist nicht definiert, welcher der möglichen Indizes geliefert
+ wird.
+
+#ib#name#ie#
+ TEXT PROC name (THESAURUS CONST t, INT CONST index)
+ Zweck: Liefert den Namen des Eintrags mit dem Index 'index' aus dem The­
+ saurus 't'. Falls kein solcher Eintrag im Thesaurus enthalten ist, wird
+ Niltext geliefert.
+
+#ib#rename#ie#
+ PROC rename (THESAURUS VAR t, TEXT CONST old, new)
+ Zweck: Ändert im Thesaurus 't' einen Eintrag mit dem alten Namen 'old' in 'new'
+ um. Falls 'old' nicht im Thesaurus enthalten ist, wird keine Leistung
+ erbracht. Falls 'old' mehrfach in 't' enthalten ist, ist nicht definiert, wel­
+ cher der möglichen Einträge geändert wird.
+ Fehlerfall:
+ * Name unzulaessig
+
+ PROC rename (THESAURUS VAR t, INT CONST index, TEXT CONST new)
+ Zweck: Ändert im Thesaurus 't' den Namen des durch 'index' identifizierten
+ Eintrags in 'new'.
+ Fehlerfall:
+ * Name unzulaessig
+
+#ib#THESAURUS#ie#
+ TYPE THESAURUS
+ Zweck: Bezeichnet Thesaurus-Datenobjekte
+
+:=
+ OP := (THESAURUS VAR dest, THESAURUS CONST source)
+ Zweck: Zuweisung
+
+
+
+
+
+
+#ib(9)#Verknüpfungsoperationen#ie(9)#
+
+Das Paket '#ib#nameset#ie#' bietet die Möglichkeit, Operationen nicht nur auf einzelnen Datei­
+en, sondern auf (geordneten) Mengen ablaufen zu lassen:
+
+#ib#ALL#ie#
+ THESAURUS OP ALL (TASK CONST task)
+ Zweck: Liefert einen Thesaurus, der alle Dateinamen der angegebenen Task
+ enthält.
+
+ THESAURUS OP ALL (TEXT CONST file name)
+ Zweck: Liefert einen Thesaurus, der die in der angegebenen Datei vorhande­
+ nen Namen (jede Zeile ein Name) enthält.
+
+#ib#all#ie#
+ THESAURUS PROC all
+ Zweck: Liefert einen Thesaurus, der alle Dateinamen der eigenen Task enthält.
+ Entspricht 'ALL myself'.
+
+#ib#LIKE#ie#
+ THESAURUS OP LIKE (THESAURUS CONST thesaurus, TEXT CONST muster)
+ Zweck: Alle im Thesaurus enthaltenen Dateien, die dem 'muster' entsprechen
+ sind im Ergebnisthesaurus enthalten.
+ (Die Syntax von 'muster' findet man bei der Beschreibung des Pattern-
+ Matching)
+
+#ib#SOME#ie#
+ THESAURUS OP SOME (THESAURUS CONST thesaurus)
+ Zweck: Bietet den angegebenen Thesaurus im EUMEL-Editor zum Ändern an.
+ Es können nicht erwünschte Namen gestrichen werden.
+
+ THESAURUS OP SOME (TASK CONST task)
+ Zweck: Aufruf von: SOME ALL task.
+
+ THESAURUS OP SOME (TEXT CONST file name)
+ Zweck: Aufruf von: SOME ALL filename.
+
+#ib#FILLBY#ie#
+ OP FILLBY (THESAURUS VAR thesaurus, FILE VAR file)
+ Zweck: Schreibt 'file' in den Thesaurus. Dabei werden Zeilen, die schon im
+ Thesaurus sind, nicht mehr in den Thesaurus geschrieben. Jede Zeile
+ kommt im Thesaurus also nur einmal vor.
+
+ OP FILLBY (FILE VAR file, THESAURUS CONST thesaurus)
+ Zweck: Schreibt den Thesaurus in die Datei 'file'.
+
+ OP FILLBY (TEXT CONST filename,
+ THESAURUS CONST thesaurus)
+ Zweck: Richtet eine Datei mit dem Namen 'filename' ein und schreibt den The­
+ saurus in die Datei.
+
++
+ THESAURUS OP + (THESAURUS CONST left, right)
+ Zweck: Liefert die Vereinigungsmenge von 'left' und 'right'.
+ Achtung: Die Vereinigungsmenge enthält keine Namen mehrfach.
+
+ THESAURUS OP + (THESAURUS CONST left, TEXT CONST right)
+ Zweck: Fügt dem Thesaurus 'right' zu, wenn 'right' noch nicht im Thesaurus
+ enthalten ist.
+
+-
+ THESAURUS OP - (THESAURUS CONST left, right)
+ Zweck: Liefert die Differenzmenge. Achtung: Die Differenzmenge enthält keine
+ Namen mehrfach.
+
+ THESAURUS OP - (THESAURUS CONST left, TEXT CONST right)
+ Zweck: Nimmt den Namen 'right' aus dem Thesaurus.
+
+/
+ THESAURUS OP / (THESAURUS CONST left, right)
+ Zweck: Liefert die Schnittmenge
+ Achtung: Die Schnittmenge enthält keine Namen mehrfach.
+
+#ib#do#ie#
+ PROC do (PROC (TEXT CONST) operate, THESAURUS CONST thesaurus)
+ Zweck: Ruft 'operate' nacheinander mit allen im Thesaurus enthaltenen Namen
+ auf.
+
+ PROC do (PROC (TEXT CONST, TASK CONST) operate,
+ THESAURUS CONST thesaurus, TASK CONST task)
+ Zweck: s.o.
+
+#ib#erase#ie#
+ PROC erase (THESAURUS CONST thesaurus)
+ Zweck: Löscht alle aufgeführten Dateien in der Vater-Task.
+
+ PROC erase (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: Löscht alle aufgeführten Dateien in der Task 'manager'.
+
+#ib#fetch#ie#
+ PROC fetch (THESAURUS CONST thesaurus)
+ Zweck: Holt alle aufgeführten Dateien vom Vater.
+
+ PROC fetch (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: Holt alle aufgeführten Dateien vom 'manager'.
+
+#ib#fetch all#ie#
+ PROC fetch all (TASK CONST manager)
+ Zweck: Holt alle Dateien vom 'manager'. Diese Prozedur entspricht dem Aufruf
+ der Prozedur 'fetch (ALL manager, manager)'.
+
+ PROC fetch all
+ Zweck: Aufruf der Prozedur 'fetch all (father)'.
+
+#ib#forget#ie#
+ PROC forget (THESAURUS CONST thesaurus)
+ Zweck: Löscht alle aufgeführten Dateien in der Benutzer-Task.
+
+#ib#insert#ie#
+ PROC insert (THESAURUS CONST thesaurus)
+ Zweck: Insertiert alle aufgeführten Dateien in der Benutzer-Task.
+
+#ib#remainder#ie#
+ PROC remainder
+ Zweck: Liefert nach einem 'errorstop' die noch nicht bearbeiteten Dateien.
+ Beispiel:
+ 'save all (archive)'
+ kann dazu führen, daß nicht alle Dateien auf das Archiv geschrie­
+ ben werden können. Fehlermeldung:
+ '"....." kann nicht geschrieben werden (Archiv voll)'
+ Nachdem man eine neue Floppy ins Archivlaufwerk gelegt hat,
+ kann man mit
+ 'save (remainder, archive)'
+ den Rest der Dateien auf der Floppy sichern.
+
+#ib#save#ie#
+ PROC save (THESAURUS CONST thesaurus)
+ Zweck: Schickt alle aufgeführten Dateien zur Vater-Task.
+
+ PROC save (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: s.o.
+
+#ib#save all#ie#
+ PROC save all (TASK CONST manager)
+ Zweck: Schickt alle eigenen Dateien zum 'manager'. Diese Prozedur entspricht
+ dem Aufruf der Prozedur 'save (ALL myself, manager)'.
+
+ PROC save all
+ Zweck: Aufruf der Prozedur 'save all (father)'.
+
+
+Beispiele:
+
+ save (ALL myself)
+ forget (ALL myself)
+ forget (all)
+ fetch (SOME father)
+ fetch (ALL father - ALL myself)
+ insert (ALL "gen datei")
+ save (ALL myself - ALL archive, archive)
+
+
+
+
+#ib(9)#4.3. #ib#Kommandos und Dialog#ie(9)##ie#
+
+
+
+#ib##ib(9)#Kommandodialog#ie##ie(9)#
+
+
+Das Paket "#ib#command dialogue#ie#" dient zur zentralen Steuerung und einfachen Durch­
+führung von #ib#Kommando-Dialog#ie#en wie
+
+ "datei" loeschen (j/n)?
+
+Er wird von allen Systemteilen verwandt, die einen Kommandodialog mit dem Benut­
+zer aufnehmen. Anwenderprozeduren mit ähnlichen Problemen sollten genauso damit
+arbeiten.
+
+Der Kommandodialog kann zentral aus- und eingeschaltet werden.
+
+
+
+#ib#command dialogue#ie#
+ BOOL PROC command dialogue
+ Zweck: Liefert den aktuellen Zustand des Kommandodialogs:
+ TRUE - Dialog soll geführt werden!
+ FALSE - Dialog soll nicht geführt werden!
+
+ PROC command dialogue (BOOL CONST status)
+ Zweck: Schaltet den Kommandodialog ein ('status' = TRUE) oder aus ('status'
+ = FALSE). Der alte Zustand wird überschrieben. Soll später wieder in
+ den alten Zustand zurückgeschaltet werden, muß er vorher erfragt und
+ gesichert werden.
+
+#ib#yes#ie#
+ BOOL PROC yes (TEXT CONST question)
+ Zweck: a) Kommandodialog soll geführt werden (command dialogue = TRUE)
+ Der übergebene Fragetext wird durch " (j/n)?" ergänzt auf dem Ter­
+ minal ausgegeben. Als Antwort wird eine der Tasten <j>, <J>,
+ <y>, <Y>, <n>, <N> akzeptiert; jede andere Eingabe führt zu
+ einem akustischen Signal und der Fragewiederholung. Das Resultat
+ der Prozedur ist
+ TRUE bei bejahender Antwort (j,J,y,Y)
+ FALSE bei verneinender Antwort (n,N)
+ b) Kommandodialog soll nicht geführt werden (command dialogue =
+ FALSE)
+ Keine Aktion, das Resultat ist TRUE.
+
+#ib#no#ie#
+ BOOL PROC no (TEXT CONST question)
+ Zweck: a) Kommandodialog soll geführt werden (command dialogue = TRUE)
+ Frage und Antwort wie bei 'yes'. Das Resultat ist
+ TRUE bei verneinender Antwort (n,N)
+ FALSE bei bejahender Antwort (j,J,y,Y)
+ b) Kommandodialog soll nicht geführt werden (command dialogue =
+ FALSE)
+ Keine Aktion, das Resultat ist FALSE.
+
+#ib#say#ie#
+ PROC say (TEXT CONST message)
+ Zweck: IF command dialogue THEN out (text) FI
+
+#ib#last param#ie#
+ TEXT PROC last param
+ Zweck: Liefert den zuletzt gesetzten Parameter-Text (siehe folgende Proze­
+ dur). Falls 'command dialogue' = TRUE und die 'param position' > 0
+ ist, wird der Parametertext als Standardparameter an der angegebenen
+ x-Position eine Zeile höher in der Form ("...") ausgegeben. Diese Proze­
+ dur wird von den parameterlosen Kommandos bzw. Prozeduren wie
+ 'edit', 'run' usw. verwandt, um mit dem Standardparameter weiterzuar­
+ beiten.
+
+ PROC last param (TEXT CONST new)
+ Zweck: Setzt 'last param' auf 'new'. (Das Setzen muß explizit durchgeführt
+ werden und geschieht nicht implizit durch den 'command handler'. 'Last
+ param' wird beispielsweise von den einparametrigen Prozeduren 'edit'
+ und 'run' gesetzt.
+
+#ib#param position#ie#
+ PROC param position (INT CONST x)
+ Zweck: Setzt die Echoposition für 'last param'. Bei x=0 wird ein Echo unter­
+ drückt.
+
+#ib#std#ie#
+ TEXT PROC std
+ Zweck: Liefert wie 'last param' den zuletzt gesetzten Parameter. Im Gegensatz
+ dazu wird der Parameter aber nicht ausgegeben.
+
+
+
+
+
+#ib##ib(9)#Kommandoverarbeitung#ie##ie(9)#
+
+
+Das Paket '#ib#command handler#ie#' stellt Prozeduren zur #ib#Kommandoanalyse#ie# und zum
+Führen des kompletten Kommandodialogs zur Verfügung.
+
+
+#ib#get command#ie#
+ PROC get command (TEXT CONST dialogue text, TEXT VAR command line)
+ Zweck: Falls eine Fehlermeldung aussteht, ('is error' liefert TRUE), wird sie über
+ 'put error' ausgegeben und der Fehlerzustand zurückgesetzt. Der 'dialo­
+ gue text' wird als Dialogaufforderung ausgegeben und der Benutzer
+ kann eine Kommandozeile eingeben. Die letzte Kommandozeile wird
+ ihm dabei automatisch (zum Ändern) angeboten, wenn vorher eine
+ Fehlermeldung anstand. Der Benutzer kann dies ebenfalls erreichen,
+ wenn er zu Beginn <ESC k> gibt. Die Kommandozeile wird dem Auf­
+ rufer in der Variablen 'command line' geliefert.
+
+ PROC get command (TEXT CONST dialogue text)
+ Zweck: s.o. Allerdings wird eine interne Kommandozeile des Pakets 'command
+ handler' als 'command line' verwandt. Dadurch wird es möglich, alle
+ Spuren einer Kommandoeingabe durch 'cover tracks' zu beseitigen.
+
+#ib#analyze command#ie#
+ PROC analyze command (TEXT CONST command list, command line,
+ INT CONST permitted type,
+ INT VAR command index, number of params,
+ TEXT VAR param 1, param 2)
+ Zweck: Die übergebene Kommandozeile ('command line') wird anhand der
+ übergebenen 'command list' analysiert. Sie ist ein TEXT, der aus einer
+ Folge von Kommandospezifikationen besteht. Jede hat die Form
+ K:I.P
+
+ K Kommandotext, Prozedurname nach ELAN-Syntax
+ I Hauptindex, Form eines INT-Denoters
+ P Parameterspezifikation, eine Folge der Ziffern 0, 1 und 2.
+
+ Beispiele:
+ - 'edit:15.012'
+ Das Kommando 'edit' wird in drei verschieden parametrisierten
+ Formen spezifiziert:
+ edit mit 0 Parameter erhält Index 15
+ edit mit 1 Parameter erhält Index 16
+ edit mit 2 Parametern erhält Index 17
+
+ - 'fetch:18.1'
+ Das Kommando 'fetch' wird in einer Form spezifiert:
+ fetch mit 1 Parameter erhält Index 18
+
+ Die Analyse erfolgt gemäß ELAN-Syntaxregeln. Dabei sind als Para­
+ meter Denoter vom Typ TEXT und vom übergebenen ' permitted type'
+ zugelassen. Diese Typen werden wie beim Scanner (s. Benutzerhand­
+ buch Programmierung Kap. 5.6) angegeben:
+
+ 1 tag
+ 2 bold
+ 3 number
+ 4 text
+ 5 operator
+ 6 delimiter
+
+ Falls das Kommando in der Kommandoliste gefunden wird (und die
+ Syntax in Ordnung ist), wird der entsprechende 'command index' zu­
+ rückgemeldet. Die Parameter werden (falls vorhanden) in 'param 1' und
+ 'param 2' abgelegt. Undefinierte oder nicht vorhandene Parameter
+ werden als Niltext geliefert. Wenn ein Kommando vorhanden ist, die
+ Anzahl der Parameter aber nicht stimmt, wird der negative Hauptindex
+ geliefert. Ist es vollkommen unbekannt oder ist die Eingabe zu komplex
+ (mehrere Kommandos, Ausdrücke oder komplexere ELAN-Statements),
+ wird 0 geliefert. Der Anwender kann in solchen Fällen die Analyse mit
+ einer anderen Kommandoliste fortsetzen, das Kommando dem ELAN-
+ Compiler übergeben oder eine Fehlermeldung auslösen (s. 'command
+ error').
+
+ PROC analyze command (TEXT CONST command list,
+ INT CONST permitted type,
+ INT VAR command index, number of params,
+ TEXT VAR param 1, param 2)
+ Zweck: s.o. Allerdings wird die interne Kommandozeile des Pakets 'command
+ handler' als 'command line' verwandt.
+
+#ib#command error#ie#
+ PROC command error
+ Zweck: Falls bei der Kommandoanalyse ein Fehler gefunden wurde, führt er
+ nicht zum 'errorstop', sondern wird nur hinterlegt. (Soll das Kommando
+ dem Compiler übergeben werden, liegt ja evt. überhaupt kein Fehler
+ vor.) Diese hinterlegte Meldung kann mit 'command error' als 'errorstop'
+ gegeben werden. Mögliche Meldungen:
+ "ungueltiger name"
+ ") fehlt"
+ "( fehlt"
+ "Parameter ist kein TEXT ("fehlt)"
+ "Kommando zu schwierig"
+
+#ib#cover tracks#ie#
+ PROC cover tracks
+ Zweck: Die Spuren der letzten Kommandoanalyse werden gelöscht. Das dient
+ u.a. dazu, daß später eingerichtete Sohntasks keine Relikte des Kom­
+ mandos mehr auf dem Textheap vorfinden und evtl. mittels nicht initiali­
+ sierter TEXT VARs herausfinden können. Vollständig können die Spuren
+ aber nur dann gelöscht werden, wenn für die Kommandoanalyse die
+ 'get command'- und 'analyze command'-Prozeduren benutzt wurden,
+ die auf der internen Kommandozeile des Pakets 'command handler'
+ arbeiten.
+
+#ib#do command#ie#
+ PROC do command
+ Zweck: Die interne Kommandozeile des Pakets 'command handler' wird dem
+ ELAN-Compiler zur Ausführung übergeben.
+
+
+
+
+
+#ib(9)#Beispiele zur Kommandoverarbeitung#ie(9)#
+
+
+#ib##ub#Kleiner Monitor#ue##ie#
+
+
+LET command list = "otto:1.12emil:3.012hugo:6.0" ;
+
+LET number = 3 ,
+ text = 4 ;
+
+INT VAR command index, params ;
+TEXT VAR param 1, param 2 ;
+
+PROC monitor :
+
+ disable stop ;
+ command dialogue (TRUE) ;
+ REP get command ("gib kleines kommando:") ;
+ analyze command (command list, text,
+ command index, params,
+ param 1, param 2) ;
+ execute command
+ PER
+
+ENDPROC monitor ;
+
+PROC execute command :
+
+ enable stop ;
+ SELECT command index OF
+ CASE 1 : otto (param 1)
+ CASE 2 : otto (param 1, param 2)
+ CASE 3 : emil
+ CASE 4 : emil (param 1)
+ CASE 5 : emil (param 1, param 2)
+ CASE 6 : hugo
+ OTHERWISE do command line
+ END SELECT
+
+ENDPROC execute command ;
+
+
+
+#ib(9)##ub#Steuerkommando-Analyse#ue##ie(9)#
+
+
+PROC command (TEXT CONST command text) :
+
+ disable stop ;
+ command dialoge (FALSE) ;
+ analyze command (command list, command text, number,
+ command index, params, param 1, param 2) ;
+ execute command ;
+ IF is error
+ THEN put error ;
+ clear error
+ FI
+
+ENDPROC command ;
+
+PROC execute command :
+
+ enable stop ;
+ SELECT command index OF
+ CASE ....
+ OTHERWISE IF command index = 0
+ THEN errorstop ("unbekanntes Kommando") ELSE command error
+ FI
+ END SELECT
+
+ENDPROC execute command ;
+
+
+
+
+
+#ib(9)#4.4. Verschiedenes#ie(9)#
+
+
+#ib(9)##ib#SESSION#ie(9)##ie#
+
+
+Mit Hilfe von 'session' kann man feststellen, ob das System neu gestartet wurde. Dabei
+spielt es keine Rolle, ob es korrekt ('shutup') abgeschaltet wurde, oder ob es sich um
+einen "RERUN" handelt.
+
+#ib#session#ie#
+ INT PROC session
+ Zweck: Liefert eine "Sitzungsnummer". Diese wird automatisch bei jedem
+ Systemstart erhöht.
+
+Beispiel:
+
+
+ REP
+ INT VAR old session := session ;
+ WHILE session = old session REP pause (100) PER ;
+ putline ("Neuer Systemstart")
+ PER.
+
+
+
+
+#ib(9)##ib#INITFLAG#ie##ie(9)#
+
+
+Im Multi-User-System ist es oft notwendig, Pakete beim Einrichten einer neuen Task in
+dieser neu zu initialisieren. Das muß z.B. bei der Dateiverwaltung gemacht werden, da
+die neue Task ja nicht die Dateien des Vaters erbt. Mit Hilfe von INITFLAG-Objekten
+kann man zu diesem Zweck feststellen, ob ein Paket #on("b")##on("i")#in dieser Task#off("b")##off("i")# schon initialisiert
+wurde.
+
+
+#ib#INITFLAG#ie#
+ TYPE INITFLAG
+ Zweck: Erlaubt die Deklaration entsprechender Flaggen.
+
+:=
+ OP := (INITFLAG VAR flag, BOOL CONST flagtrue)
+ Zweck: Erlaubt die Initialisierung von INITFLAGs
+
+#ib#initialized#ie#
+ BOOL PROC initialized (INITFLAG VAR flag)
+ Zweck: Wenn die Flagge in der Task A auf TRUE oder FALSE gesetzt wurde,
+ dann liefert sie beim ersten Aufruf den entsprechenden Wert, danach
+ immer TRUE (in der Task A!).
+ Beim Einrichten von Söhnen wird die Flagge in den Sohntasks automa­
+ tisch auf FALSE gesetzt. So wird erreicht, daß diese Prozedur in den neu
+ eingerichteten Söhnen und Enkeltasks genau beim ersten Aufruf FALSE
+ liefert.
+
+
+Beispiel:
+
+ PACKET stack DEFINES push, pop:
+
+ INITFLAG VAR in this task := FALSE ;
+ INT VAR stack pointer ;
+ ROW 1000 INT VAR stack ;
+
+ PROC push (INT CONST value) :
+
+ initialize stack if necessary ;
+ ....
+
+ ENDPROC push ;
+
+ PROC pop (INT VAR value) :
+
+ initialize stack if necessary ;
+ ....
+
+ ENDPROC pop ;.
+
+ initialize stack if necessary :
+ IF NOT initialized (in this task)
+ THEN stack pointer := 1
+ FI .
+
+ ENDPACKET stack
+
+
+
+
+
+#ib(9)##ib#Bit-Handling#ie##ie(9)#
+
+
+Die #ib#Bit-Operationen#ie# arbeiten auf INT-Objekten. Sie können z.B. für die Systempro­
+grammierung benutzt werden, wenn es um Bitmasken u.ä. geht.
+
+Ein INT besteht aus 16 Bits. Dabei hat das niederwertigste die Nummer 0, das höch­
+stwertige die Nummer 15.
+
+
+#ib#AND#ie#
+ INT OP AND (INT CONST left, right)
+ Zweck: Bitweise UND-Verknüpfung von 'left' mit 'right'.
+
+#ib#OR#ie#
+ INT OP OR (INT CONST left, right)
+ Zweck: Bitweise ODER-Verknüpfung von 'left' mit 'right'.
+
+#ib#XOR#ie#
+ INT OP XOR (INT CONST left, right)
+ Zweck: Bitweise EXCLUSIV-ODER-Verknüpfung von 'left' mit 'right'.
+
+#ib#bit#ie#
+ BOOL PROC bit (INT CONST bits, bit no)
+ Zweck: Liefert TRUE genau dann, wenn das Bit mit der Nummer 'bit no' in dem
+ INT 'bits' gesetzt ist.
+
+#ib#set bit#ie#
+ PROC set bit (INT VAR bits, INT CONST bit no)
+ Zweck: Das Bit mit der Nummer 'bit no' wird in 'bits' auf 1 gesetzt.
+
+#ib#reset bit#ie#
+ PROC reset bit (INT VAR bits, INT CONST bit no)
+ Zweck: Das Bit mit der Nummer 'bit no' wird in 'bits' auf 0 gesetzt.
+
+#ib#rotate#ie#
+ PROC rotate (INT VAR bits, INT CONST number of bits)
+ Zweck: Bits können mit dieser Prozedur zyklisch geschiftet werden.
+ Bsp.: rotate (1,1) ---> 2
+ rotate (1,2) ---> 4
+ rotate (1,-3) ---> 16384
+ rotate (16384,3) ---> 1
+
+#ib#lowest set#ie#
+ INT PROC lowest set (INT CONST bits)
+ Zweck: Liefert die Nummer des niederwertigsten 1-Bits in 'bits'. Ist kein Bit auf 1
+ gesetzt, wird -1 geliefert.
+
+#ib#lowest reset#ie#
+ INT PROC lowest reset (INT CONST bits)
+ Zweck: Liefert die Nummer des niederwertigsten 0-Bits in 'bits'. Ist kein Bit auf 0
+ gesetzt, wird -1 geliefert.
+
+
+
+
+
+#ib(9)#4.5. #ib#Blockorientierte Ein-/Ausgabe#ie##ie(9)#
+
+
+
+Die blockorientierte Ein-/Ausgabe dient dazu, Datenraumseiten (#ib#Blöcke#ie#) oder Teile
+davon über die #ib#Kanäle#ie# zu transferieren. Sie wird vom System u.a. beim Archivzugriff
+und bei der Konfigurierung der Kanäle eingesetzt.
+
+Die Wirkung der blockorientierten Ein-/Ausgabeoperationen kann dabei kanal- und
+rechnerspezifisch unterschiedlich sein.
+Auf dem Archivkanal (31) und allen anderen Block-IO-Kanälen werden bei
+'code 1 = 0' die normalen Blocklese- bzw. -schreiboperationen durchgeführt. 'code 2'
+gibt dabei die Blocknummer an. Andere (positive) Werte von 'code 1' sind zur Zeit
+nicht offiziell definiert. Negative Werte können vom SHard für Spezialaufgaben verge­
+ben werden.
+
+
+
+#ib#blockin#ie#
+ PROC blockin (DATASPACE VAR ds, INT CONST page nr, code1, code2,
+ INT VAR return code)
+ Zweck: Die Seite 'page nr' des Datenraums 'ds' wird "eingelesen". Die Opera­
+ tion kann durch 'code1' und 'code2' näher gesteuert werden.
+
+ PROC blockin (ROW 256 INT VAR block, INT CONST code1, code2,
+ INT VAR return code)
+ Zweck: Wie oben, nur wird der Block direkt als Datenstruktur übergeben.
+
+#ib#blockout#ie#
+ PROC blockout (DATASPACE CONST ds, INT CONST page nr,
+ code1, code2, INT VAR return code)
+ Zweck: Die Seite 'page nr' des Datenraums 'ds' wird "ausgegeben". Die Opera­
+ tion kann durch 'code1' und 'code2' näher gesteuert werden.
+
+ PROC blockout (ROW 256 INT CONST block, INT CONST code1, code2,
+ INT VAR return code)
+ Zweck: Wie oben, nur wird der Block als Datenstruktur übergeben.
+
+#ib#control#ie#
+ PROC control (INT CONST code1, code2, code3, INT VAR return code)
+ Zweck: Diese Prozedur dient zur Kanalsteuerung.
+
+#ib#ds pages#ie#
+ INT PROC ds pages (DATASPACE CONST ds)
+ Zweck: Liefert die Anzahl der belegten Seiten eines Datenraums. (Jede Seite ist
+ 512 Byte groß.)
+
+#ib#next ds page#ie#
+ INT PROC next ds page (DATASPACE CONST ds, INT CONST page nr)
+ Zweck: Liefert die Nummer der nächsten (von 'page nr' an gerechneten) Seite
+ des Datenraums. Die erste belegte Seite erhält man durch
+
+ next ds page (ds, -1)
+
+ #on ("b")#Achtung: Die Seitennummern müssen nicht lückenlos sein.#off ("b")#
+
diff --git a/doc/system/systemhandbuch.3 b/doc/system/systemhandbuch.3
new file mode 100644
index 0000000..3c0a482
--- /dev/null
+++ b/doc/system/systemhandbuch.3
@@ -0,0 +1,1366 @@
+#start(2.5,1.5)#
+#pageblock#
+#block#
+#page (63)#
+#headeven#
+
+%#center#EUMEL-Systemhandbuch
+
+
+#end#
+#headodd#
+
+#center#5. Supervisor, Tasks und Systemsteuerung#right#%
+
+
+#end#
+
+#ib(9)#5. #ib#Supervisor#ie#, #ib#Tasks#ie# und
+ #ib#Systemsteuerung#ie##ie(9)#
+
+
+
+#ib(9)#5.1. #ib#Tasks#ie##ie(9)#
+
+
+
+#ib(9)#Der Datentyp #ib#TASK#ie##ie(9)#
+
+
+Benannte Tasks werden innerhalb eines Rechners vollständig und eindeutig über ihren
+Namen identifiziert. Eine weitere Möglichkeit der Identifikation besteht in der Verwen­
+dung von Datenobjekten vom Typ TASK. Beispiel:
+
+ TASK VAR plotter := task ("PLOTTER 1")
+
+Die Taskvariable 'plotter' bezeichnet jetzt die Task im System, die augenblicklich den
+Namen "PLOTTER 1" hat. Nun sind #ib#Taskvariablen#ie# auch unter Berücksichtigung der Zeit
+und nicht nur im aktuellen Systemzustand eindeutig. Der Programmierer braucht sich
+also keine Sorgen darüber zu machen, daß seine Taskvariable irgendwann einmal eine
+"falsche" Task (nach Löschen von "PLOTTER 1" neu eingerichtete gleichen oder ande­
+ren Namens) identifiziert. Wenn die Task "PLOTTER 1" gelöscht worden ist, bezeichnet
+'plotter' keine gültige Task mehr.
+
+#ib#Unbenannte Tasks#ie# haben alle den Pseudonamen "-". Sie können nur über Taskvari­
+ablen angesprochen werden.
+
+Der #ib#Task-Katalog#ie# wird vom Supervisor geführt; andere Tasks können sich Kopien
+dieses Katalogs besorgen. Einige Prozeduren arbeiten auf dieser taskeigenen Kopie,
+ohne diese automatisch auf den neuesten Stand zu bringen (Effizienzgründe). Das
+muß bei Bedarf explizit geschehen.
+
+
+#ib#TASK#ie#
+ TYPE TASK
+ Zweck: Interner Taskbezeichner
+
+:=
+ OP := (TASK VAR dest, TASK CONST source)
+ Zweck: Zuweisung von internen Taskbezeichnern
+
+=
+ BOOL OP = (TASK CONST left, right)
+ Zweck: Gleichheitsabfrage
+
+<
+ BOOL OP < (TASK CONST left, right)
+ Zweck: Überprüft, ob die Task 'left' ein Sohn, Enkel, Urenkel, ... der Task 'right'
+ ist.
+
+/
+ TASK OP / (TEXT CONST task name)
+ Zweck: Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene
+ Katalog wird automatisch aktualisiert (identisch mit der
+ PROC task (TEXT CONST task name).
+ Fehlerfall:
+ * ... gibt es nicht
+
+ TASK OP / (INT CONST station number, TEXT CONST name)
+ Zweck: Liefert die Task des angegebenen Namen von der Station mit der ange­
+ gebenen Nummer.
+
+#ib#access#ie#
+ PROC access (TASK CONST task)
+ Zweck: Aktualisiert den eigenen Taskkatalog, falls 'task' nicht darin enthalten ist.
+
+#ib#access catalogue#ie#
+ PROC access catalogue
+ Zweck: Aktualisiert den eigenen Taskkatalog, indem die neueste Fassung vom
+ Supervisor geholt wird. Die Prozeduren 'father', 'son', 'brother' arbeiten
+ dann auf dieser neuen Fassung.
+
+#ib#archive#ie#
+ TASK PROC archive
+ Zweck: Liefert den internen Taskbezeichner der aktuellen Task mit Namen
+ "ARCHIVE". Diese Prozedur dient zum schnellen und bequemen An­
+ sprechen der Archivtask.
+
+#ib#brother#ie#
+ TASK PROC brother (TASK CONST task)
+ Zweck: Liefert den nächsten Bruder von 'task'. Falls kein Bruder existiert, wird
+ 'niltask' geliefert. Aktualisiert den eigenen Katalog nicht automatisch!
+
+#ib#canal#ie#
+ TASK PROC canal (INT CONST channel number)
+ Zweck: Diese Prozedur zeigt an, welche Command-Analyser-Task an einem
+ bestimmten Kanal hängt.
+
+#ib#exists#ie#
+ BOOL PROC exists (TASK CONST task)
+ Zweck: Falls 'task' auf der eigenen Station liegt, informiert diese Prozedur, ob
+ die angegebene 'task' noch existiert. Der eigene Taskkatalog wird dabei
+ aktualisiert.
+ Wenn abgefragt werden soll, ob 'task' auf einer anderen Station liegt,
+ muß die Prozedur 'name (task) <> "" ' verwendet werden.
+ Achtung: Diese Prozedur taugt nicht dazu, zu erfragen, ob eine Task
+ mit bestimmtem Namen im System exisiert.
+
+ exists (task ("hugo"))
+
+ Falls die Task "hugo" nicht existiert, führt schon der Aufruf
+ 'task ("hugo")' zum 'errorstop (""hugo" gibt es nicht")'.
+
+#ib#exists task#ie#
+ BOOL PROC exists task (TEXT CONST name)
+ Zweck: Wenn auf der eigenen Station eine Task mit dem Namen 'name' exi­
+ stiert, liefert diese Prozedur 'TRUE'.
+
+#ib#father#ie#
+ TASK PROC father
+ Zweck: Liefert die eigene Vatertask.
+
+ TASK PROC father (TASK CONST task)
+ Zweck: Liefert den Vater von 'task'. Existiert kein Vater (z.B. bei UR), wird niltask
+ geliefert. Aktualisiert den eigenen Katalog nicht automatisch!
+
+#ib#index#ie#
+ INT PROC index (TASK CONST task)
+ Zweck: Liefert einen INT-Wert von 1 bis 125, der 'task' unter allen gleichzeitig (!)
+ existierenden Tasks eindeutig identifiziert.
+
+#ib#is niltask#ie#
+ BOOL PROC is niltask (TASK CONST task)
+ Zweck: task = niltask
+
+#ib#myself#ie#
+ TASK PROC myself
+ Zweck: Liefert eigenen Task-Bezeichner.
+
+#ib#name#ie#
+ TEXT PROC name (TASK CONST task)
+ Zweck: Liefert den Namen von 'task'. Die Task muß noch im System existieren,
+ sonst ist der Name nicht mehr bekannt. Falls die 'task' noch nicht im
+ eigenen Katalog enthalten ist, wird er aktualisiert.
+
+#ib#niltask#ie#
+ TASK CONST niltask
+ Zweck: Bezeichner für "keine Task". So liefern die Prozeduren 'son', 'brother'
+ und 'father' als Resultat 'niltask', wenn keine Sohn-, Bruder- oder Vater­
+ task existiert.
+
+#ib#printer#ie#
+ TASK PROC printer
+ Zweck: Liefert den internen Taskbezeichner der aktuellen Task mit Namen
+ #ib#PRINTER#ie#. Diese Prozedur dient zum schnellen und bequemen Anspre­
+ chen des Druckspoolers.
+
+#ib#public#ie#
+ TASK PROC public
+ Zweck: Liefert den internen Taskbezeichner der Task #ib#PUBLIC#ie#.
+
+#ib#reserve#ie#
+ PROC reserve (TASK CONST task)
+ Zweck: Reservieren einer Task für den ausschließlichen Dialog mit der Task, in
+ der das Kommando gegeben wurde.
+ PROC reserve (TEXT CONST message, TASK CONST task)
+ Zweck: Wie 'reserve (TASK CONST task)' mit Übergabe einer 'message'.
+
+#ib#son#ie#
+ TASK PROC son (TASK CONST task)
+ Zweck: Liefert den ersten Sohn von 'task'. Falls keiner im Katalog vermerkt ist,
+ wird 'niltask' geliefert. Aktualisiert den eigenen Katalog nicht automa­
+ tisch!
+
+#ib#supervisor#ie#
+ TASK PROC supervisor
+ Zweck: Liefert den internen Taskbezeichner des Supervisors.
+
+#ib#task#ie#
+ TASK PROC task (TEXT CONST task name)
+ Zweck: Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene
+ Katalog wird automatisch aktualisiert.
+ Fehlerfall:
+ * ... gibt es nicht
+
+ TASK PROC task (INT CONST channel number)
+ Zweck: Liefert den Namen der Task, die an dem angegebenen Kanal hängt.
+
+
+
+#ib##ib(9)#Inter-Task-Kommunikation#ie##ie(9)#
+
+
+Die #ib#Task-Kommunikation#ie# im EUMEL System ist strikt botschaftsorientiert. Eine #ib#Bot­
+schaft#ie# bzw. "#ib#Sendung#ie#" besteht immer aus einem #ib#Sendungscode#ie# (INT) und einem
+Datenraum (DATASPACE). Damit kann eine Botschaft bis zu 1 Mbyte umfassen!
+
+Kommunikation zwischen zwei Tasks ist nur dann möglich, wenn #ib#Sender#ie# und #ib#Empfän­
+ger#ie# dazu bereit sind. Eine Sendung kann also nur dann korrekt transferiert werden,
+wenn der Empfänger existiert und empfangsbereit ist. Diese Art der Kommunikation
+wurde gewählt, um
+
+ - eine möglichst einfache und effiziente Implementation zu ermöglichen und
+ - mit den vorhandenen Primitiva möglichst flexibel bei der Implementation
+ "höherer" Kommunikationsmethoden (z.B. Warteschlangen) zu sein.
+
+
+#ib#call#ie#
+ PROC call (TASK CONST destination, INT CONST send code,
+ DATASPACE VAR message ds, INT VAR reply code)
+ Zweck: Die eigene Task wartet, bis die Zieltask 'destination' empfangsbereit ist.
+ Dann wird die Sendung ('send code' und 'message ds') transferiert.
+ Anschließend wartet die Sendertask auf eine Antwort von 'destination'.
+ Für Sendungen anderer Tasks ist sie dabei nicht (!) empfangsbereit, nur
+ die Zieltask kann eine Antwortsendung schicken. Nachdem eine solche
+ Antwort eingetroffen ist, wird sie in 'message ds' und 'reply code' gelie­
+ fert und die eigene Task fortgesetzt. Wenn die angesprochene Zieltask
+ nicht existiert, wird -1 als 'reply code' geliefert. 'message ds' ist in
+ diesem Fall unverändert.
+ 'call' hat Ähnlichkeiten mit einem Prozeduraufruf, nur ist es hier der
+ Aufruf einer anderen Task. Störungen können hierbei nicht auftreten, da
+ der Zustand der Zieltask keine Rolle spielt (es wird auf Empfangsbereit­
+ schaft gewartet) und beim Warten auf Antwort auch keine "Querschlä­
+ gersendungen" von anderen Tasks dazwischenfunken können.
+
+#ib#pingpong#ie#
+ PROC pingpong (TASK CONST destination, INT CONST send code,
+ DATASPACE VAR message ds, INT VAR reply code)
+ Zweck: Diese Prozedur wirkt wie die entsprechende 'call'-Prozedur, wartet aber
+ nicht (!), bis die Zieltask empfangsbereit ist. Wenn die Zieltask existiert,
+ aber nicht empfangsbereit ist, wird -2 als 'reply code' geliefert. Der
+ 'message ds' ist dann nicht verändert.
+
+#ib#send#ie#
+ PROC send (TASK VAR destination, INT CONST send code,
+ DATASPACE VAR message ds, INT VAR receipt)
+ Zweck: Wenn die Zieltask existiert und empfangsbereit ist, wird die Sendung
+ ('send code' und 'message ds') transferiert und die Zieltask aktiviert. Als
+ 'receipt' wird 0 (=ack) gemeldet. Diese positive Quittung kommt nicht
+ von der Zieltask, sondern bestätigt nur, daß die Sendung ordnungsge­
+ mäß übertragen wurde. Der Datenraum gehört dann nicht mehr der
+ Sender-, sondern der Zieltask, d.h. die Variable 'message ds' bezeichnet
+ keinen gültigen Datenraum mehr.
+ Im Gegensatz zu 'call' und 'pingpong' läuft die Sendertask ohne Halt
+ weiter und wartet nicht auf eine Antwort von der Zieltask.
+ Falls die Zieltask nicht existiert, wird -1, falls sie nicht empfangsbereit ist,
+ -2 als 'receipt' geliefert. Bei diesen negativen Quittungen bleibt der
+ Datenraum Eigentum der Absendertask, d.h. die Variable 'message ds'
+ bezeichnet immer noch einen gültigen Datenraum.
+
+ PROC send (TASK VAR destination, INT CONST send code,
+ DATASPACE VAR message ds)
+ Zweck: s.o. Negative Quittungen (-1 oder -2) werden jedoch ignoriert. Der Da­
+ tenraum wird entweder transferiert oder gelöscht ('forget'), steht also in
+ keinem Fall mehr zur Verfügung. Die Prozedur sollte nur verwendet
+ werden, wenn der Sender sicher ist, daß die Sendung transferiert wer­
+ den kann, bzw. daß sie im Fehlerfall nicht transferiert zu werden braucht.
+
+#ib#wait#ie#
+ PROC wait (DATASPACE VAR message ds, INT VAR message code,
+ TASK VAR source task)
+ Zweck: Die eigene Task geht in den #ub##ib#offenen Wartezustand#ie##ue# über. Sie ist jetzt
+ gegenüber allen anderen Tasks empfangsbereit. Sie wird erst fortge­
+ setzt, wenn eine Sendung eintrifft. Diese wird in 'message ds' und 'mes­
+ sage code', die Absendertask in 'source task' geliefert.
+
+Der #ub##ib#Sendungscode#ue##ie# muß zwischen den Beteiligten abgesprochen sein und ist also frei
+wählbar. Allerdings sind negative Werte nicht erlaubt, sondern für bestimmte "Pseudo­
+antworten" vom Betriebssystem reserviert:
+
+ -1 "Zieltask existiert nicht"
+
+ -2 "Zieltask ist nicht empfangsbereit"
+
+ -4 "Eingabe vom Kanal" Diese Meldung kann nur (!) beim offenen War­
+ ten ('wait') auftreten, und auch dann nur, wenn die Task gleichzeitig
+ an einen Kanal angekoppelt ist. Auf diese Weise wird mitgeteilt, daß
+ mindestens ein Zeichen vorliegt. Dieses kann im folgenden mit 'in­
+ char', 'incharety', 'blockin' oder darauf aufbauenden Prozeduren
+ gelesen werden.
+
+Weitere Codes werden in Systemroutinen standardmäßig verwandt und sollten auch
+von Anwenderroutinen genauso interpretiert werden:
+
+ 0 "#ib#ack#ie#" positive Quittung
+
+ 1 "#ib#nak#ie#" negative Quittung
+
+ 2 "#ib#error nak#ie#" negative Quittung mit Fehlermeldung.
+ Der gelieferte Datenraum sollte die Struktur eines
+ BOUND TEXTs haben und die Fehlermeldung in
+ diesem TEXT beinhalten.
+
+
+Beispiel: #ub#Kommunikation mit einem Manager#ue#
+
+
+ Auftraggeber Manager
+
+
+ call (....) REP
+ wait (ds, order, order task) ;
+ execute order ;
+ send (order task, reply, ds)
+ PER
+
+Da der Auftraggeber 'call' verwendet, wartet er automatisch so lange, bis der Manager
+für ihn empfangsbereit wird. Dann schickt er die Sendung und geht gleichzeitig (!) in
+den geschlossenen "auf Antwort warten" - Zustand über. Der Manager kann daher
+unbesorgt mit dem "unsicheren" 'send' antworten, da die Empfangsbereitschaft des
+Auftraggebers nur durch Katastrophen wie Löschung der Task oder "halt from terminal"
+gestört werden kann. (In diesen Fällen kann die Antwort ruhig ins Leere gehen.)
+
+Hier sieht man auch den Unterschied zwischen
+
+ call (...) und send (....); wait (....) .
+
+Bei der zweiten Alternative können drei Störfälle eintreten:
+
+
+ a) Der Manager ist nicht empfangsbereit. 'send' versagt, 'wait' wartet ewig.
+
+ b) Da über die zeitlichen Rahmenbedingungen nichts ausgesagt werden kann,
+ ist es möglich, daß der Manager die Antwort schickt, bevor die 'wait'-Opera­
+ tion beim Auftraggeber ausgeführt werden konnte. In unserem Beispiel
+ würde das den Verlust der Rückmeldung und ewiges Warten seitens des
+ Auftraggebers auslösen.
+
+ c) Beim 'wait' kann eine Störsendung einer anderen Task eintreffen.
+
+
+
+
+
+
+
+#ib(9)#5.2. #ib#Supervisor#ie##ie(9)#
+
+
+
+#ib(9)##ib#Verbindung zum Supervisor#ie##ie(9)#
+
+
+#ib#begin#ie#
+ PROC begin (PROC start, TASK VAR new task)
+ Zweck: Es wird eine #ib#unbenannte Task#ie# (Pseudoname "-") als neuer Sohn der
+ aufrufenden eingerichtet und mit der Prozedur 'start' gestartet. Namens­
+ kollision ist nicht möglich, die erzeugte Task kann aber auch nicht na­
+ mensmäßig angesprochen werden. 'new task' identifiziert den neuen
+ Sohn, falls kein Fehler auftrat.
+ Fehlerfälle :
+ * zu viele Tasks
+
+ PROC begin (TEXT CONST son name, PROC start, TASK VAR new task)
+ Zweck: Es wird eine Task mit Namen 'son name' als Sohn der aufgerufenen
+ eingerichtet und mit der Prozedur 'start' gestartet. 'new task' identifi­
+ ziert den neuen Sohn, falls kein Fehler auftrat.
+ Fehlerfälle :
+ * zu viele Tasks
+ * Name unzulaessig (* "" oder LENGTH > 100 *)
+ * ... existiert bereits
+
+#ib#begin password#ie#
+ PROC begin password (TEXT CONST password)
+ Zweck: Bei normalen 'global manager'-Tasks kann man mit dieser Operation
+ das weitere Kreieren von Sohntasks unter Paßwortkontrolle stellen.
+ Wenn dieses Kommando in der Manager-Task gegeben worden ist, wird
+ bei folgenden SV-begin-Kommandos interaktiv das Paßwort verlangt.
+ Dabei gelten die üblichen Paßwort-Konventionen:
+
+ a) "" (Niltext) bedeutet #on("i")#kein Paßwort#off("i")#. Damit kann man durch
+ 'begin password ("")' das Paßwort wieder ausschalten.
+ b) "-" bedeutet #on("i")#jedes eingegebene Paßwort ist ungültig#off("i")#. Damit
+ kann man durch 'begin password ("-")' das Einrichten von
+ Sohntasks von außen (durch SV-Kommando) abschalten.
+
+#ib#break#ie#
+ PROC break
+ Zweck: Die Task koppelt sich von einem evtl. angekoppelten Terminal ab. Bei
+ der Abkopplung wird auf dem Terminal die "Tapete" ("Terminal n...
+ EUMEL Version ..../M...") ausgegeben.
+
+ PROC break (QUIET CONST quiet)
+ Zweck: Die Task koppelt sich von einem evtl. angekoppelten Terminal ab. Dabei
+ wird aber keine "Tapete" ausgegeben.
+
+#ib#channel#ie#
+ INT PROC channel
+ Zweck: Liefert die #ib#Kanalnummer#ie# der eigenen Task. Falls kein Kanal (Terminal)
+ zugeordnet ist, wird 0 geliefert.
+
+ INT PROC channel (TASK CONST task)
+ Zweck: Liefert die Kanalnummer der angegebenen Task. Ist kein Kanal zuge­
+ ordnet, wird 0 geliefert.
+
+#ib#clock#ie#
+ REAL PROC clock (INT CONST index)
+ Zweck: Liefert die über Index spezifizierte #ib#Systemuhr#ie#. Die Zeiteinheit ist 1 sec,
+ die Meßgenauigkeit 0.1 sec.
+ clock (0) : CPU-Zeit der eigenen Task
+ clock (1) : Realzeit des Systems
+
+ REAL PROC clock (TASK CONST task)
+ Zweck: Liefert die CPU-Zeit der angegebenen Task.
+
+ Hinweis: Die CPU-Zeit beginnt mit der Taskkreation zu laufen. Sie gibt also
+ jeweils die gesamte bisher verbrauchte CPU-Zeit an. Die Zeitdauer
+ bestimmter Operationen kann als Differenz zweier 'clock'-Aufrufe
+ gemessen werden. Beim Ende einer Task wird ihr CPU-Zeitverbrauch
+ dem Vater zugeschlagen, um Abrechnungen zu ermöglichen.
+
+#ib#continue#ie#
+ PROC continue (INT CONST channel nr)
+ Zweck: Die Task versucht, sich an den vorgegebenen Kanal anzukoppeln. Falls
+ sie vorher schon an ein Terminal gekoppelt war, wird implizit 'break'
+ durchgeführt, falls die Aktion erfolgreich durchgeführt werden konnte.
+ Ein erfolgreiches 'continue' beinhaltet implizit 'reset autonom'.
+ Anmerkung: Normale Tasks können auf die Kanäle 1-24 zugreifen,
+ Systemtasks dürfen sich auch an die privilegierten Kanäle
+ 25-32 ankoppeln.
+ Fehlerfälle:
+ * ungueltiger Kanal
+ * Kanal belegt
+
+#ib#end#ie#
+ PROC end
+ Zweck: Löscht die eigene Task und alle Söhne. Wenn die Task an ein Terminal
+ angekoppelt ist, wird vorher angefragt, ob wirklich gelöscht werden soll.
+ Anschließend wird die Standard-"Tapete" auf dem Bildschirm ausge­
+ geben.
+
+ PROC end (TASK CONST task)
+ Zweck: Löscht die angegebene 'task'. 'task' muß allerdings die eigene oder eine
+ Sohn- bzw. Enkel-Task der eigenen sein (siehe auch: 'Privilegierte Ope­
+ rationen'). Im Unterschied zur oben aufgeführten parameterlosen Proze­
+ dur 'end' wird nicht angefragt und auch keine "Tapete" ausgegeben.
+ Wenn also die eigene Task ohne Reaktion auf dem Terminal beendet
+ werden soll, kann dies mit 'end (myself)' geschehen.
+ Fehlerfall:
+ * 'end' unzulaessig
+
+#ib#family password#ie#
+ PROC family password (TEXT CONST password)
+ Zweck: Diese Prozedur setzt oder ändert das Paßwort derjenigen Familien­
+ mitglieder, die kein Paßwort oder das gleiche Paßwort wie die aufrufen­
+ de Task haben.
+ Zu einer Familie gehören die Task, in der man sich befindet, und die ihr
+ untergeordneten Tasks.
+ Natürlich gelten auch hier die allgemeinen Paßwortbedingungen (siehe
+ dazu: 'task password').
+ Beispiel: Das Kommando 'family password ("EUMEL")' wird in SYSUR
+ gegeben. Dadurch wird das SYSUR­Paßwort und die Paß­
+ worte der entsprechenden Tasks unter SYSUR auf "EUMEL"
+ gesetzt.
+
+
+#ib#next active#ie#
+ PROC next active (TASK VAR task)
+ Zweck: 'task' wird auf die nächste aktive Task gesetzt. Aktiv sind alle Tasks, die
+ sich im Zustand 'busy' befinden oder auf Ein/Ausgabe warten (i/o) und
+ an einen Kanal angekoppelt sind. Beispiel:
+
+
+ TASK VAR actual task := myself;
+ REP
+ ... ;
+ next active (actual task)
+ UNTIL actual task = myself PER.
+
+
+ Hier werden alle aktiven Tasks durchgemustert (z.B. für Scheduling-
+ Anwendungen). Dieses Verfahren ist sehr viel weniger aufwendig als
+ eine Durchmusterung des ganzen Taskbaumes, liefert aber nur die
+ gerade aktiven Tasks.
+
+#ib#rename myself#ie#
+ PROC rename myself (TEXT CONST new task name)
+ Zweck: Die eigene Task erhält als neuen Tasknamen 'new task name'. Damit
+ kann auch aus einer benannten eine unbenannte Task mit dem Pseu­
+ donamen "-" werden. Umbenennung in die andere Richtung ist eben­
+ falls möglich.
+ Achtung: Durch das Umbenennen der Task werden alle Taskvariablen,
+ die sich auf diese Task beziehen, ungültig (als wäre die Task
+ gelöscht und dann neu eingerichtet).
+ Fehlerfälle:
+ * ... existiert bereits
+ * Name unzulaessig
+
+#ib#reset autonom#ie#
+ PROC reset autonom
+ Zweck: Die eigene Task deklariert sich beim Supervisor als nicht autonom
+ (Normalzustand). Das bedeutet, 'continue'-Aufforderungen über ein
+ 'Supervisor-Kommando' vom Terminal werden vom System ohne Be­
+ nachrichtigung der Task durchgeführt.
+
+#ib#set autonom#ie#
+ PROC set autonom
+ Zweck: Die eigene Task deklariert sich beim Supervisor als #ib#autonom#ie# (üblich für
+ Manager-Tasks). Wenn jetzt ein 'continue'-Supervisor-Kommando auf
+ diese Task von einem Terminal aus gegeben wird, wird der Task über
+ 'send' eine Nachricht zugestellt.
+ Achtung: Im autonomen Zustand ist der Programmierer selbst für die
+ Reaktion der Task verantwortlich. Man kann sie von außen auf
+ keine Weise gewaltsam an ein Terminal koppeln (ermög­
+ licht Paßalgorithmen / Datenschutz).
+ Um die Programmierung etwas zu entschärfen, wird eine
+ Task automatisch aus dem autonomen in den Normalzustand
+ überführt, wenn sie selbst ein 'continue' gibt.
+
+#ib#status#ie#
+ INT PROC status (TASK CONST task)
+ Zweck: Liefert den Status der angegebenen Task:
+
+ 0 -busy- Task ist aktiv.
+ 1 i/o Task wartet auf Beendigung des Outputs oder
+ auf Eingabe.
+ 2 wait Task wartet auf Sendung von einer anderen Task.
+ 4 busy-blocked Task ist rechenwillig, ist aber blockiert.
+ 5 i/o -blocked Task wartet auf I/O, ist aber blockiert.
+ 6 wait-blocked Task wartet auf Sendung, ist aber blockiert.
+ Achtung: Die Task wird beim Eintreffen einer
+ Sendung automatisch entblockiert.
+
+#ib#storage#ie#
+ PROC storage (INT VAR size, used)
+ Zweck: Informiert über den physisch verfügbaren ('size') und belegten ('used')
+ Speicher des Gesamtsystems. Die Einheit ist KByte.
+ Achtung: 'size' gibt den Speicher an, der benutzt werden kann, ohne in
+ eine Engpaßsituation zu kommen. Tatsächlich wird auf dem
+ Hintergrundmedium noch eine gewisse Reserve freigehalten.
+ Wenn diese angebrochen wird, befindet sich das System im
+ #ib#Speicherengpaß#ie#. Dieser Zustand kann mit 'used > size'
+ abgefragt werden.
+
+ INT PROC storage (TASK CONST task)
+ Zweck: Liefert die Größe des Speicherbereichs in KByte, den die angegebene
+ Task augenblicklich belegt.
+ Dabei werden durch Sharing mögliche Optimierungen nicht berücksich­
+ tigt. D.h. eine Task kann physisch erheblich weniger Speicher als logisch
+ belegen. Entsprechend kann die Speichersumme aller Tasks den phy­
+ sisch belegten Speicherbereich des Gesamtsystems beträchtlich über­
+ schreiten.
+
+#ib#task password#ie#
+ PROC task password (TEXT CONST password)
+ Zweck: Das angegebene Paßwort wird beim Supervisor hinterlegt. Bei folgen­
+ den SV-Kommandos 'continue...' auf diese Task wird interaktiv das
+ Paßwort abgefragt. Dabei gelten die üblichen Paßwort-Konventionen:
+
+ a) "" (Niltext) bedeutet #on("i")#kein Paßwort#off("i")#. Damit kann man durch
+ 'task password ("")' das Paßwort wieder ausschalten.
+
+ b) "-" bedeutet #on("i")#jedes eingegebene Paßwort ist ungültig#off("i")#. Damit
+ kann man durch 'task password ("-")' das Ankoppeln an ein
+ Terminal von außen (durch SV-Kommando) unterbinden.
+
+
+
+
+#ib##ib(9)#Privilegierte Operationen#ie(9)##ie#
+
+
+Die im folgenden aufgeführten privilegierten Operationen können #ub#nur#ue# von #ib#System­
+tasks#ie# - das sind direkte oder indirekte Söhne des Supervisors - ausgeführt werden. Um
+Mißbrauch unmöglich zu machen, sollte der Supervisor nach der Einrichtung der
+gewünschten Systemtasks bzgl. der Einrichtung neuer Söhne gesperrt und alle Sy­
+stemtasks durch Paßworte geschützt werden.
+
+
+#ib#block#ie#
+ PROC block (TASK CONST task)
+ Zweck: Die angegebene #ib#Task wird blockiert#ie#, d.h. so lange von der Verarbeitung
+ suspendiert, bis die Blockade durch 'unblock' wieder aufgehoben wird.
+ Diese Operation wird vom Scheduler benutzt. Falls das Packet 'schedu­
+ ler' insertiert ist, sollten andere Tasks die Prozedur 'block' nicht anwen­
+ den, um dem Scheduling nicht entgegenzuwirken.
+
+#ib#collect garbage blocks#ie#
+ PROC collect garbage blocks
+ Zweck: Es wird eine außerplanmäßige Gesamtmüllabfuhr durchgeführt. Plan­
+ mäßig (d.h. ohne Aufruf dieser Prozedur) wird sie alle 15 Minuten und in
+ Engpaßsituationen durchgeführt. Nach Aufruf dieser Prozedur wird der
+ automatische Fixpunkt/ Müllabfuhr-Rhythmus ca. 1 Stunde lang ge­
+ sperrt. Somit kann man z.B. in der Task "scheduler" einen eigenen
+ Fixpunkt/Müllabfuhr-Rhythmus implementieren.
+ Achtung: Diese Operation erfordert starkes Paging und dauert dement­
+ sprechend lange.
+
+#ib#end#ie#
+ PROC end (TASK CONST task)
+ Zweck: Die angegebene Task und alle Söhne, Enkel etc. werden gelöscht.
+ Systemtasks (direkte und indirekte Nachkommen des SUPERVISORs)
+ können beliebige andere Tasks (nicht nur eigene Söhne) löschen.
+
+#ib#fixpoint#ie#
+ PROC fixpoint
+ Zweck: Für das Gesamtsystem wird ein außerplanmäßiger #ib#Fixpunkt#ie# geschrie­
+ ben. Planmäßige Fixpunkte (d.h. ohne Aufruf dieser Prozedur) werden
+ alle 15 Minuten geschrieben. Nach Aufruf dieser Prozedur wird der
+ automatische Fixpunkt/Müllabfuhr-Rhythmus ca. 1 Stunde lang ge­
+ sperrt. Somit kann man z.B. in der Task "scheduler" einen eigenen
+ Fixpunkt/Müllabfuhr-Rhythmus implementieren.
+ Achtung: Diese Operation verursacht starkes Paging (Rückschreiben
+ aller veränderten Seiten auf das Hintergrundmedium) und
+ dauert dementsprechend lange.
+
+#ib#prio#ie#
+ INT PROC prio (TASK CONST task)
+ Zweck: Liefert die augenblickliche #ib#Priorität#ie# der angegebenen Task.
+
+ PROC prio (TASK CONST task, INT CONST new prio)
+ Zweck: Setzt die Priorität der Task.
+
+ Hinweis: 0 ist die höchste, 15 die niedrigste Priorität. Die Prioritäten 0 bis 2
+ werden von EUMEL 0 (fine scheduling) verwaltet. Die restlichen Priori­
+ täten können für 'rough scheduling' (siehe auch im Kapitel Scheduler)
+ eingesetzt werden.
+ Durch 'continue ("name")' wird die Priorität wieder auf 0 gesetzet.
+
+#ib#set date#ie#
+ PROC set date
+ Zweck: #ib#Datum#ie# und #ib#Uhrzeit#ie# können im Dialog gesetzt werden (Form wie beim
+ Start des Systems). Dabei wird gegebenenfalls die Hardware­Uhr gele­
+ sen.
+ Sollte der SHard ein falsches Datum liefern, so muß das Datum mit
+ set clock (date("tt.mm.jj") + time ("hh:mm:ss"))
+ gesetzt werden.
+
+#ib#save system#ie#
+ PROC save system
+ Zweck: Der gesamte Systemhintergrund wird auf Archivdisketten gesichert. Zu
+ diesem Zweck wird das System wie bei 'shutup' heruntergefahren.
+
+#ib#shutup#ie#
+ PROC shutup
+ Zweck: #ib#Kontrolliertes Herunterfahren des Systems#ie#. Beim nächsten Systemstart
+ wird automatisch Datum und Uhrzeit erfragt, wenn der Kommandodial­
+ og eingeschaltet ('command dialogue (TRUE)') und keine Hardwareuhr
+ vorhanden ist. Falls diese Prozedur nicht vor dem Abschalten aufgerufen
+ wurde, findet beim Neustart ein Aufsetzen auf dem letzten Fixpunkt statt
+ (RERUN).
+
+#ib#unblock#ie#
+ PROC unblock (TASK CONST task)
+ Zweck: Eine vorherige Blockierung der Task wird aufgehoben. Ist die Task nicht
+ blockiert, bewirkt 'unblock' nichts. Diese Operation wird vom Scheduler
+ benutzt. Andere Tasks sollten sie normalerweise nicht anwenden, um
+ dem Scheduling nicht entgegenzuwirken.
+
+
+
+
+
+#ib(9)#5.3. #ib#ID ­ Konstanten#ie##ie(9)#
+
+
+Die Informationsprozedur
+
+ INT PROC id (INT CONST no)
+
+liefert folgende Informationen über die Soft­ und Hardware des Rechners:
+
+ Von EUMEL 0 werden geliefert:
+ id (0) --> EUMEL­Version
+ id (1) --> Prozessortyp (1: Z80,
+ 2: Z8001,
+ 3: 8086 und kompatible,
+ 4: 68000
+ 5: 80286)
+ id (2) --> Urlader­Version
+ id (3) --> reserviert
+
+ Vom SHard werden geliefert:
+ id (4) --> Lizenznummer des SHards
+ id (5) --> Installationsnummer des EUMEL­Anwenders
+ id (6) --> SHard­spezifisch
+ id (7) --> SHard­spezifisch
+
+
+
+
+
+#ib(9)#5.4. #ib#Systemverwaltung#ie##ie(9)#
+
+
+#on("i")#Achtung#off("i")#: Dieser Teil des Systemhandbuchs ist nur für solche Multi-User-Installationen
+ von Bedeutung, die erweiterte Systemverwaltungsfunktionen generieren
+ bzw. modifizieren wollen.
+
+ #on("i")#Das EUMEL-System ist in der ausgelieferten minimalen Standardform (ohne
+ die Features) ohne weiteres benutzbar#off("i")#.
+
+
+
+
+
+#ib(9)#Der Systemmanager #ib#SYSUR#ie##ie(9)#
+
+
+Der Systemmanager verhält sich im wesentlichen wie ein normaler Manager, allerdings
+mit folgender Erweiterung:
+
+ - Die Operationen 'list' und 'fetch' können von allen Tasks des Systems und
+ nicht nur von Söhnen durchgeführt werden. Damit kann man Systemverwal­
+ tungsdateien (z.B. "#ib#logbuch#ie#") von allen Tasks aus lesen. 'erase' und 'save' sind
+ jedoch nur von Söhnen bzw. Enkeln - d.h. von privilegierten Systemtasks - aus
+ zulässig.
+
+Das Paket stellt folgende Operationen zusätzlich zur Verfügung:
+
+#ib#generate shutup manager#ie#
+ PROC generate shutup manager
+ Zweck: Es wird eine Sohntask mit Namen "shutup" kreiert. Diese Task ist nicht­
+ (!) paßwortgeschützt, läßt aber keine normalen Kommandos zu, son­
+ dern fragt nur
+
+ shutup (j/n) ?
+
+ So kann jeder das System kontrolliert abschalten und die privilegierten
+ Operationen des OPERATORs wie 'end' sind dennoch geschützt.
+
+#ib#put log#ie#
+ PROC put log (TEXT CONST log record)
+ Zweck: Der angegebene 'log record' wird mit vorangestelltem Tasknamen des
+ Absenders, Datums- und Uhrzeitangabe in die Logbuchdatei "logbuch"
+ in der Task "SYSUR" geschrieben. Der neue Satz wird an die Datei ange­
+ fügt. ("logbuch" wird z.B. vom EUMELmeter verwandt.)
+
+ Hinweis: Bei Verwendung des Logbuchs darf die zwar große, aber doch end­
+ liche Dateikapazität nicht vergessen werden. Nachdem das Logbuch
+ mit 4073 Sätzen voll ist, werden weitere 'put log' Operationen igno­
+ riert. Die Datei "logbuch" sollte deshalb - wenn sie beispielsweise vom
+ EUMELmeter verwandt wird - von Zeit zu Zeit gelöscht werden ('erase'
+ bzw. 'forget')!
+
+
+
+
+#ib(9)##ib#Scheduler#ie##ie(9)#
+
+
+Der Scheduler dient zur Verwaltung der rechenwilligen #ib#Hintergrundtask#ie#s. Will man den
+Scheduler (eventuell abgeändert) insertieren, muß man die Task "scheduler" als Sohn
+von SYSUR einrichten. Dann holt man die Datei "scheduler" vom Archiv und insertiert
+sie. "scheduler" beinhaltet "#ib#eumelmeter#ie#". Es wird beim Start erfragt, ob die Meßrouti­
+nen aktiviert werden sollen oder nicht.
+
+
+
+
+#ib##ib(9)#Funktionsweise des Schedulers#ie(9)##ie#
+
+
+Der Scheduler sammelt in bestimmten Zeitintervallen alle aktiven (rechnenden) Tasks
+ab, die an kein Terminal angekoppelt sind und auch keine Manager sind. Diese Tasks
+werden blockiert und in die Warteschlange der #ib#Standardklasse#ie# eingefügt.
+
+Die Klassen des Schedulers werden durch die #ib#Taskpriorität#ie#en 5 bis 9 definiert. Die
+Standardklasse entspricht der Priorität 7. Die Klassenzugehörigkeit einer Task kann von
+einer Systemtask aus (z.B. von "OPERATOR") mit der Prozedur '#ib#prio#ie#' verändert werden.
+
+Der Scheduler geht nach folgender Strategie vor:
+
+ Anhand der Vordergrund/Hintergrundlast des Systems wird entschieden, ob
+ überhaupt Hintergrundtasks aktiv sein dürfen, welche Klassen aktiv sein dürfen
+ und wieviel #ib#Hintergrundtask#ie#s gleichzeitig rechnen dürfen.
+
+ Die wartenden #ib#Hintergrundtask#ie#s werden im #ib#Round-Robin-Verfahren#ie# aktiviert.
+ Dabei kommt die Klasse n+1 erst dann zum Zug, wenn die Warteschlange der
+ Klasse n leer ist oder weniger Tasks enthält, als gleichzeitig aktiviert werden
+ sollen.
+
+Die implementierte Standardstrategie hat als oberste Maxime, den Vordergrund auf
+keinen Fall zu stören. Dementsprechend wird der Hintergrund nur aktiviert, wenn eine
+der folgenden Bedingungen erfüllt ist:
+
+ - Die Vordergrundlast des Systems liegt unter 3% .
+
+ - Es ist keine normale #ib#Vordergrundtask#ie# (Nachfahre von "UR") an einen Kanal
+ angekoppelt. Man beachte, daß Systemtasks hierbei nicht berücksichtigt
+ werden. Ein aktiver Drucker blockiert die Hintergrundtasks also nicht.
+
+
+
+
+EUMELmeter (Systemstatistik)
+
+
+Die #ib#Meßsoftware#ie# zum #ib#Protokollieren der Systembelastung#ie# befindet sich auf dem Archiv
+'std.zusatz'.
+
+Falls das System keinen #ib#Scheduler#ie# benutzt, muß eine Meßtask als Sohn von "SYSUR"
+eingerichtet werden. In diese Task muß dann die Datei "#ib#eumelmeter#ie#" vom Archiv geholt
+und übersetzt werden.
+
+Falls das System einen Scheduler beinhalten soll, muß bei der Generierung des Sche­
+dulers lediglich auf die Frage "mit eumelmeter (j/n) ?" mit "j" geantwortet werden.
+
+
+
+#ib##ib(9)#EUMELmeter#ie(9)##ie#
+
+
+Das EUMELmeter protokolliert die #ib#Systemlast#ie# in ca. 10 minütigen Abständen in der
+Datei "#ib#logbuch#ie#" in "SYSUR". Für jedes Meßintervall wird eine Zeile angefügt. Die Zeilen
+sind folgendermaßen aufgebaut:
+
+tt.mm.jj hh:mm hg uf ub pw pb cpuf cpub cpus last nutz
+
+
+tt.mm.jj hh:mm Datum und Uhrzeit des Eintrags
+
+hg Größe des aktuell belegten Hintergrundspeichers
+ (in KB)
+
+uf Anzahl der aktiven Vordergrundtasks
+
+ub Anzahl der aktiven Hintergrundtasks
+
+pw #ib#Paginglast#ie# bei wartender CPU (#ib#Paging/Wait#ie#)
+
+pb Paginglast bei aktiver CPU (#ib#Paging/Busy#ie#)
+
+cpuf #ib#CPU-Auslastung#ie# durch Vordergrundtasks
+
+cpub CPU-Auslastung durch Hintergrundtasks
+
+cpus #ib#CPU-Systemlast#ie#
+
+last #ib#Gesamtlast des Systems#ie#:
+ pw + pb + cpuf + cpub+ cpus
+ (Achtung: kann 100% übersteigen, da Platte und CPU über­
+ lappt arbeiten können.)
+
+nutz #ib#Nutzgüte#ie# im Meßintervall: 100% - pw - cpus
+ Die Nutzgüte gibt an, welcher Anteil der Systemarbeit für echte
+ Nutzarbeit verfügbar war. Sie ist die Summe aus der echten
+ Nutzlast 'cpuf+cpub' und der Leerzeit, die ja theoretisch auch
+ für Nutzarbeit hätte verwandt werden können. Sie läßt sich, wie
+ oben angegeben, auch berechnen, indem man den idealerweise
+ überflüssigen Overhead 'cpus' und 'pw' von 100% abzieht.
+#page#
+
+#count per page#
+#headeven#
+%#center#EUMEL-Systemhandbuch
+
+
+#end#
+#headodd#
+#center#6. Der EUMEL-Drucker#right#%
+
+
+#end#
+
+#ib(9)#6. Der #ib#EUMEL-Drucker#ie##ie(9)#
+
+
+
+#ib(9)#6.1. Allgemeine Einführung#ie(9)#
+
+
+Die Ansteuerung eines #ib#Druckers#ie# durch das EUMEL-System geschieht durch zwei
+aufeinanderbauende Komponenten. Die eine Komponete ist der hardwareunabhängi­
+ge #ib#EUMEL-Drucker#ie#, der die #ib#Textverarbeitungsanweisungen#ie# umsetzt und die Druck­
+seite entsprechend aufbereitet, so daß sie im Blocksatz, in Tabellenform oder in Spal­
+ten gedruckt werden kann. Die andere Komponente ist der hardwareabhängige #ib#Druk­
+kertreiber#ie#, der durch ein einfaches Interface zum EUMEL-Drucker, wie z.B. Textausge­
+ben, Positionieren oder Schrifttypen und Modifikationen an- und ausschalten, den
+eigentlichen Druck vornimmt.
+Die hardwareunabhängige Komponente, der EUMEL-Drucker, befindet sich bei den
+ausgelieferten Systemen im priviligierten Ast des Taskbaums, so daß beim Anschluß
+eines Druckers nur noch der hardwareabhängige Druckertreiber insertiert werden muß.
+Auf dem PRINTER-Archiv befinden sich schon einige Druckeranpassungen für diverse
+Druckertypen.
+
+- Implementierung des Druckertreiber-Interface
+ Das Paket mit dem Druckertreiber muß in einer Task "PRINTER" insertiert und
+ ein Spool eingerichtet werden.
+
+- Erstellen einer Fonttabelle für den anzuschießenden Drucker
+ Eine vorhandene Fonttabelle wird dabei in die Task "configurator" gebracht
+ werden. Die Fonttabelle sollte in allen bestehenden Tasks - insbesondere in
+ der Task "PUBLIC" und der Task "PRINTER" - mit dem #on("i")##on("b")#fonttable#off("i")##off("b")#-Kommando
+ eingestellt werden.
+
+
+
+
+#ib(9)#6.2. Das #ib#Druckertreiber-Interface#ie##ie(9)#
+
+
+Da der EUMEL-Drucker vor dem Druckertreiber insertiert ist, aber auf dem Drucker­
+treiber aufbaut, müssen beim Aufruf der 'print'-Prozedur des EUMEL-Druckers die
+Prozeduren des Druckertreibers mit übergeben werden. Aus progammtechnischen
+Gründen sollte ihre Anzahl möglichst gering gehalten werden. Deshalb gibt es die
+folgende drei Prozeduren, die mit einem 'op code' parametrisiert werden. Die Bedeu­
+tung der weiteren Parameter der Interfaceprozeduren hängen von diesem 'op code' ab.
+Die folgende Beschreibung der Prozeduren gibt einen Programmrahmen vor, in dem
+die Parameter durch Refinements entsprechend ihrer Bedeutung umdefiniert sind.
+
+
+
+PROC open (INT CONST op code, INT VAR param 1, param 2) :
+
+ LET document code = 1 ,
+ page code = 2 ;
+
+ SELECT op code OF
+ CASE document code : open document
+ CASE page code : open page
+ END SELECT.
+
+
+ x steps : param1 .
+ y steps : param2 .
+
+ #ib#open document#ie# :
+
+ Zweck: Die Prozedur wird vom EUMEL-Drucker zur Einleitung jedes Ausdrucks
+ aufgerufen. Hier können notwendige Initialisierungen der Hardware
+ durchgeführt werden. In 'x steps' und 'y steps' muß die Breite bzw.
+ Höhe der bedruckbaren Fläche des Papieres in Mikroschritten des
+ Druckers angegeben werden.#u##count#)#e#
+#foot#
+
+#value#) Zur Definition der Mikroschritte siehe Bemerkung 2.
+#end#
+
+
+
+ x start : param1 .
+ y start : param2 .
+
+ #ib#open page#ie# :
+
+ Zweck: Hiermit wird dem Hardware-Interface der Beginn einer neuen Seite
+ mitgeteilt. Die Parameter 'x start' und 'y start' liefern die gewünschte
+ Position der linken oberen Ecke des Schreibfeldes. Das Hardware-In­
+ terface muß in diesen Parametern seine augenblickliche Position auf
+ dem Papier zurückmelden, wobei die Position (0,0) die linke obere
+ Ecke des Papieres ist.
+ Vor der Rückmeldung kann aber auch auf die angegebene Startpo­
+ sition positioniert und diese zurückgemeldet werden. Es ist jedoch
+ darauf zu achten, daß die zurückgemeldete Position den internen
+ Nullpunkt für die Absolutkoordinaten im EUMEL-Drucker definiert.
+ Deswegen muß das Hardware-Interface sicherstellen, daß bei einem
+ "Zeilenrücklauf" die zurückgemeldete Position 'x start' erreicht wird.
+ (Siehe 'carriage return' in der Prozedur 'execute'). Auch gibt es Fälle,
+ bei denen links von der gemeldeten 'x start'-Position positioniert wird.
+ Bei #ib#Druckern mit Einzelblatteinzug#ie#, bei denen das Papier gleich auf die
+ zweite oder dritte Zeile positioniert wird, sollte, um ein korrektes Druck­
+ bild zu erreichen, diese Postion in 'y start' zurückgemeldet werden.
+
+
+END PROC open;
+
+
+PROC close (INT CONST op code, INT CONST param 1) :
+
+ LET document code = 1 ,
+ page code = 2 ;
+
+ SELECT op code OF
+ CASE document code : close document
+ CASE page code : close page
+ END SELECT.
+
+
+ #ib#close document#ie# :
+
+ Zweck: Hiermit wird dem Hardware-Interface das Ende eines Druckvorgangs
+ mitgeteilt.
+
+
+
+ remaining y steps : param 1 .
+
+ #ib#close page#ie# :
+
+ Zweck: Hiermit wird dem Hardware-Interface mitgeteilt, daß der Druck der
+ aktuellen Seite abgeschlossen ist.
+ 'remaining y steps' gibt an, wieviel Mikroschritte das vertikale Papier­
+ ende noch von der aktuellen Druckposition entfernt ist. Die x-Position
+ des Druckers ist bei Aufruf dieser Prozedur immer der linke Rand
+ 'x start'.
+
+
+END PROC close;
+
+
+PROC execute (INT CONST op code, TEXT CONST string,
+ INT CONST param1, param2) :
+
+ LET write text code = 1 ,
+ write cmd code = 2 ,
+ carriage return code = 3 ,
+ move code = 4 ,
+ draw code = 5 ,
+ on code = 6 ,
+ off code = 7 ,
+ type code = 8 ;
+
+ SELECT op code OF
+ CASE write text code : write text
+ CASE write cmd code : write cmd
+ CASE carriage return code : carriage return
+ CASE move code : move
+ CASE draw code : draw
+ CASE on code : on
+ CASE off code : off
+ CASE type code : type
+ END SELECT .
+
+
+ from : param1 .
+ to : param2 .
+
+ #ib#write text#ie# :
+
+ Zweck: Der übergebene Text 'string' muß von der Zeichenposition 'from' bis
+ 'to' (einschließlich) auf dem Drucker ausgegeben werden. Die Über­
+ schreitung der Papierbreite braucht nicht überprüft zu werden.
+
+
+
+ #ib#write cmd#ie# :
+
+ Zweck: Der übergebene Text 'string' enthält zwischen den Positionen 'from'
+ und 'to' ein direkt angegebenes #ib#Druckerkommando#ie# (\#"..."\#). Wenn
+ direkte Druckerkommandos erlaubt sein sollen, müssen sie ausgege­
+ ben werden.
+
+
+
+ x steps to left margin : param 1 .
+
+ #ib#carriage return#ie# :
+
+ Zweck: Der Druckkopf muß (ohne Zeilenvorschub) an den linken Rand be­
+ wegt werden, d.h. an die bei 'open page' vom Druckertreiber gemel­
+ dete Position 'x start'. 'x steps to left margin' gibt an, wieviel Minimal­
+ schritte die augenblickliche Position vom linken Rand entfernt ist.
+
+
+
+ x steps : param 1 .
+ y steps : param 2 .
+
+ #ib#move#ie# :
+
+ Zweck: Die Schreibposition muß um 'x steps' Mikroschritte nach rechts und um
+ 'y steps' Mikroschritte nach unten verschoben werden. Negative
+ Schrittwerte bedeuten dabei die jeweils andere Richtung. Das Über­
+ schreiten des Papiers braucht nicht überprüft zu werden. Bei einer
+ horizontalen Bewegung nach rechts ('x steps' > 0) müssen die einge­
+ schalteten Modifikationen beachtet werden. Wenn z.B. 'underline'
+ eingeschaltet ist, muß die Strecke unterstrichen werden.
+ Kann eine Leistung (z.B. Bewegung nach links) nicht erbracht wer­
+ den, muß ein 'errorstop' ausgelöst werden. Im Fehlerfall bei einer
+ Horizontalbewegung versucht der EUMEL-Drucker nach einem Zei­
+ lenrücklauf nochmals die angestrebte x-Position zu erreichen. Somit
+ brauchen horizontale Bewegungen nach links ('x steps' < 0) nicht
+ unbedingt implementiert zu werden, sondern können mit einem 'error­
+ stop' beantwortet werden. Im Fehlerfall bei einer vertikalen Bewegung
+ wird an der alten Position weitergeschrieben.
+
+
+
+ #ib#draw#ie# :
+ Zweck: Von der aktuellen Schreibposition an (linke untere Ecke der Zeichenposition)
+ soll eine gerade Linie zum Zielpunkt ('x steps' weiter rechts, 'y steps' weiter
+ unten) gezogen werden. Kann eine Leistung (z.B. schräge Linie, Linie nach
+ oben o.ä.) nicht erbracht werden, muß ein 'errorstop' ausgelöst werden.
+ Dieser Fehlerfall wird vom EUMEL-Drucker ignoriert. Das Überschreiten
+ des Schreibfeldes braucht nicht überprüft zu werden.
+
+
+
+ modification : param 1 .
+
+ #ib#on#ie# :
+
+ Zweck: Die #ib#Modifikation#ie# der Nummer 'modification' soll eingeschaltet wer­
+ den, sofern die Hardware es erlaubt. Augenblicklich gibt es folgende
+ Modifikationen:
+
+ 1 underline
+ 2 bold
+ 4 italics
+ 8 reverse
+
+ Die in der Fonttabelle spezifizierte Befehlssequenz, um die entspre­
+ chende Modifikation anzuschalten, kann mit der Prozedur #on("i")#on string
+ (modification)#off("i")# abgefragt werden.
+ Kann eine Leistung nicht erbracht werden, muß ein 'errorstop' aus­
+ gelöst werden. Im Fehlerfall der Modifikation 'underline' versucht der
+ neue EUMEL-Drucker die Zeile mit Hilfe von 'draw' zu unterstreichen.
+ Im Fehlerfall der Modifikation 'bold' wird die Zeile nochmals, um den in
+ der Fonttabelle spezifizierten 'bold offset' verschoben, ausgegeben.
+ Bei den restlichen beiden Modifkationen wird der Fehlerfall ignoriert.
+
+
+
+ #ib#off#ie# :
+
+ Zweck: Die angegebene #ib#Modifikation#ie# 'modification' soll ausgeschaltet wer­
+ den. Die in der Fonttabelle spezifizierte Befehlssequenz, um die ent­
+ sprechende Modifikation auszuschalten, kann mit der Prozedur #on("i")#off
+ string (modification)#off("i")# abgefragt werden. Ein Fehlerfall wird hier igno­
+ riert.
+
+
+
+ font nr : param 1 .
+
+ #ibie# :
+
+ Zweck: Die Druckausgabe soll auf den #ib#Schrifttyp#ie# mit der angegebenen Font­
+ nummer 'font nr' umgeschaltet werden. Diese Nummer bezieht sich auf
+ die eingestellte Fonttabelle. Mit den Prozeduren des Fontspeichers
+ können anhand dieser Nummer die nötigen Informationen beschafft
+ werden. So liefert z.B. die Prozedur #on("i")#font string (font nr)#off("i")# die in der Font­
+ tabelle spezifizierte Befehlssequenz oder die Prozedur #on("i")#font (font nr)#off("i")#
+ den Namen des Fonts. Die Breite des Leerzeichens kann mit #on("i")#char pitch
+ (font nr, " ")#off("i")# bestimmt werden.
+
+
+END PROC execute;
+
+
+
+
+
+#ib(9)#6.3. Prozedur-Schnittstelle des EUMEL-
+ Druckers#ie(9)#
+
+
+
+#ib#print#ie#
+ PROC print (PROC (TEXT VAR) next line, BOOL PROC eof,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST,
+ INT CONST, INT CONST) execute,
+ BOOL CONST elan listing, TEXT CONST file name)
+ Zweck: Solange die Prozedur 'eof' FALSE liefert wird mit der Prozedur 'next
+ line' eine Zeile eingelesen. Dieser Eingabestrom wird für den Druck
+ aufbereitet. Ist die Konstante 'elan listing' auf FALSE gesetzt, so wird
+ der Eingabestrom als Textdatei mit Textkosmetik-Anweisungen aus­
+ gedruckt. Andernfalls wird der Eingabestrom wie ein ELAN-Listing
+ behandelt. In der Textkonstanten 'file name' muß dann der Dateiname
+ der Programmdatei enthalten sein.
+
+
+ PROC print (FILE VAR file,
+ PROC (INT CONST, INT VAR, INT VAR) open
+ PROC (INT CONST, INT CONST) close
+ PROC (INT CONST, TEXT CONST,
+ INT CONST, INT CONST) execute)
+ Zweck: Der Eingabestrom kommt aus der angegebenen Datei. Anhand vorge­
+ gebener Kriterien wird entschieden, ob diese Datei als Textdatei oder
+ als ELAN-Listing ausgedruckt wird.
+
+#ib#with elan listings#ie#
+ PROC with elan listings (BOOL CONST flag)
+ Zweck: Mit dieser Prozedur kann bei der vorangegangenen 'print'-Prozedur
+ gesteuert werden, ob überhaupt irgendwelche Dateien als ELAN-Lis­
+ tings gedruckt werden sollen. Wird damit FALSE eingestellt, so wer­
+ den alle Dateien als Textdateien gedruckt.
+
+ BOOL PROC with elan listings
+ Zweck: Liefert die aktuelle Einstellung.
+
+
+#ib#is elan source#ie#
+ PROC is elan source (FILE VAR file)
+ Zweck: Entscheidet nach vorgebenen Kriterien, ob die angegebene Datei ein
+ ELAN-Listing ist.
+
+
+#ib#bottom label for elan listings#ie#
+ PROC bottom label for elan listings (TEXT CONST label)
+ Zweck: Bei ELAN-Listings wird in der Fußzeile ein Text eingestellt, der durch
+ Schägstrich getrennt vor die Seitennummer geschrieben wird. (z.B. zur
+ Durchnumerierung der Pakete im Quellcode)
+
+ TEXT PROC bottom label for elan listings
+ Zweck: Liefert die aktuelle Einstellung.
+
+
+#ib#material#ie#
+ TEXT PROC material
+ Zweck: Hier kann das Hardware-Interface jeder Zeit den aktuellen Material­
+ wert abfragen, der vom Benutzer mit der 'material'-Anweisung einge­
+ stellt ist.
+
+
+#ib#x pos#ie#
+ INT PROC x pos
+ Zweck: Wird in der Prozedur 'execute' die Funktion 'move' oder 'draw' ange­
+ steuert, so liefert diese Prozedur die absolute Zielposition in x-Rich­
+ tung, wo bei der Nullpunkt durch das zurückgelieferte 'x start' bei 'open
+ page' definiert ist. Diese Prozedur dient zur Unterstützung von Druk­
+ kern, die eine absolute Positionierung in horizontaler Richtung benöti­
+ gen.
+
+
+#ib#y pos#ie#
+ INT PROC y pos
+ Zweck: Wird in der Prozedur 'execute' die Funktion 'move' oder 'draw' an­
+ gesteuert, so liefert diese Prozedur die absolute Zielposition in y-Rich­
+ tung, wo bei der Nullpunkt durch das zurückgelieferte 'y start' bei 'open
+ page' definiert ist. Diese Prozedur dient zur Unterstützung von Druk­
+ kern, die eine absolute Positionierung in vertikaler Richtung benötigen.
+
+
+#ibie#
+ INT PROC linetype
+ Zweck: Wird in der Prozedur 'execute' die Funktion 'draw' angesteuert, so gibt
+ diese Prozedur den gewünschten Linientyp an. Bisher ist nur definiert:
+ 1 underline
+
+ Anmerkung: Bis jetzt benutzt der EUMEL-Druckers die Funktion 'draw' lediglich
+ zum Unterstreichen in Fehlerfall der Modifikation 'underline', d.h.
+ zeichnen mit 'y steps = 0' und 'x steps >= 0' mit 'line type = 1'
+ reicht aus.
+
+
+#ib#y offset index#ie#
+ INT PROC y offset index
+ Zweck: Wurde der Font mit 'y offsets' definiert, so kann hiermit in der bei der
+ Funktion 'write text' in der Prozedur 'execute' der jeweilige Offset-In­
+ dex für den auszugebenden Text abgefragt werden. Der Offset-Index
+ sagt aus, die wievielte Verschiebung nun ausgegeben wird. Dabei
+ werden die Verschiebungen in der Reihenfolge durchnummeriert, in
+ der sie in der Fonttabelle angegeben wurden. Anhand dieses Offset-In­
+ dex muß das Hardware-Interface entscheiden, welche Bitmuster aus­
+ gegeben werden müssen.
+
+
+#ib#pages printed#ie#
+ INT PROC pages printed
+ Zweck: Gibt nach dem Ausdruck an, wieviel Seiten gedruckt wurden.
+
+
+
+
+#ib(9)#6.4. Bemerkungen und Ratschläge#ie(9)#
+
+
+
+1) Für ein Paket, das dieses Interface implementiert, sind folgende Punkte wichtig:
+
+ - Man braucht sich keine Zustände (aktuelle Position o.ä.) zu merken.
+
+ - Rückmeldungen über die Leistungsfähigkeit eines Druckers bzw. seiner An­
+ passung erfolgen über 'errorstop'. Der #ib#EUMEL-Drucker#ie# stellt fest, ob bestimm­
+ te Leistungen (Einschalten der Attribute und Bewegungen des Druckers)
+ verfügbar sind, indem er sie versuchsweise ausführen läßt. Bei den Prozedu­
+ ren 'open', 'close' und den Funktionen 'write text', 'write cmd', 'carriage return'
+ und 'type' der Prozedur 'execute' führt ein 'errorstop' jedoch zum Abbruch des
+ Drucks.
+
+2) Die #on("i")##on("b")##ib#Mikroschritte#ie##off("i")##off("b")# sollten die kleinsten durchführbaren horizontalen bzw. vertikalen
+ Bewegungen des Druckers sein. Oft gibt aber das Handbuch des Druckers keine
+ eindeutige Angabe über die Mikroschritte in horizontaler Richtung, sondern sagt
+ nur, daß es gewisse Schriften mit einer bestimmten Anzahl von Zeichen pro Zoll
+ gibt.#u##count#)#e# Dann ergibt sich die Anzahl von Mikroschritten pro Zoll aus dem kleinsten#foot#
+
+#value#) 1 Zoll = 1 Inch = 2.54 cm
+
+#end#
+ gemeinsamen Vielfachen der Anzahl Zeichen pro Zoll aller Schriften.
+
+ Beispiel:
+ Der Olivetti Drucker PR1470 hat drei Schriften mit 10, 12, und 16.6 Zeichen pro
+ Zoll. Das kleinste gemeinsame Vielfache ist 300. Ein Mikroschritt bei dem Druk­
+ ker PR1470 entspricht also einem 300stel Zoll. Die Breite der einzelnen Schrif­
+ ten läßt sich nun aus der folgenden Tabelle ablesen.
+
+ Anzahl Zeichen pro Zoll Breite in 1/300 Zoll
+ 10 30
+ 12 25
+ 16.6 18
+
+ Wenn der Drucker in diesen theoretischen Mikroschritten nicht positionieren kann,
+ so muß er bei einem #on("i")#move#off("i")#-Befehl so genau wie möglich positionieren. Der Rest
+ sollte abgespeichert und beim nächsten #on("i")#move#off("i")#-Befehl hinzuaddiert werden.
+
+3) Um ein optimales Druckbild zu bekommen, müssen alle Breiten und Höhenanga­
+ ben der Zeichen genau angegeben werden.
+
+4) Die Fonttabelle bietet eine einfache Möglichkeit, Zeichen mit Hilfe der #ib#Ersatzdar­
+ stellung#ie#en umzucodieren. Deshalb sollte der Druckerkanal auch mit der Konfigu­
+ rationstabelle 'transparent' konfiguriert werden.
+
+5) Um den Schrifttyp festzulegen, mit dem #ib#ELAN-Listing#ie#s gedruckt werden sollen,
+ kann in der Fonttabelle einem Font der Name #on("i")##on("b")#"#ib#elanlist#ie#"#off("i")##off("b")# zugeordnet werden, denn
+ der ELAN-Lister versucht auf einen Schrifttyp mit diesem Namen zuschalten. Wenn
+ kein Schrifttyp "elanlist" existiert, dann wird für ELAN-Listings der erste Schrifttyp
+ der Fonttabelle genommen.
+
+6) Nach der Installation des #ib#Druckertreiber#ie#s ist darauf zu achten, daß in der Task
+ "PRINTER" eine Fonttabelle des Druckers eingestellt ist.
+
+7) Der #ib#Druckertreiber#ie# sollte eventuell noch ein Prozedur bereitstellen, mit der die
+ Papierbreite bzw. -höhe eingestellt werden kann, die bei 'open document' dem
+ EUMEL-Drucker gemeldet wird.
+
+
+
+
+#ib(9)#6.5. Arbeitsweise des EUMEL-Druckers#ie(9)#
+
+
+
+Der EUMEL-Drucker arbeitet mit der folgenden Strategie:
+
+Die Datei wird zeilenweise analysiert. Bei der Analyse werden einzelne #ib#Token#ie# be­
+stimmt. Ein Token ist ein Textteil, der zusammenhängend gedruckt werden kann, ohne
+daß es zu Typumschaltungen, Modifkationsänderungen oder Positionierungen in x-
+bzw. y-Richtung kommt. So ist bei einfachem Zeilendruck jede Zeile ein Token, wäh­
+rend im Blocksatz jedes Wort ein Token ist. Ein Token hat also immer
+
+ - einen Text,
+ - die Länge des Textes bei der Ausgabe,
+ - eine absolute x- und y- Position auf dem Papier,
+ - einen Schrifttyp,
+ - Modifikationen für den Text,
+ - Modifikationen für den Zwischenraum vom letzten Token zu diesem Token.
+
+Sind alle Token einer Zeile bestimmt, so werden sie in eine Liste aller bisher erzeug­
+ten, aber noch nicht gedruckten Token der absoluten y-Position nach einsortiert. Diese
+Tokenliste wird erst dann ausgedruckt, wenn sichergestellt ist, daß im weiteren Verlauf
+der Datei kein Token vor das letzte Token der sortierten Liste kommt. Beim Zeilendruck
+ist dies nach jeder Zeile der Fall. Bei Spaltendruck kann jedoch erst dann ausgedruckt
+werden, wenn sich die Analyse in der letzten Spalte befindet. Spätestens bei einem
+Seitenwechsel muß die Tokenliste ausgegeben werden.
+
+Durch diese Strategie lassen sich Spaltendruck oder Indizes und Exponenten sehr
+leicht für alle Drucker implementieren, ohne daß ein Drucker in vertikaler Richtung
+rückwärts positionieren muß.
+
+Bei der Ausgabe der Tokenliste wird jeweils auf die nächst größere y-Position posi­
+tioniert und dort werden alle Token zu dieser y-Position ausgegeben. Die Ausgabe
+eines Tokens erfolgt in der folgenden Reihenfolge:
+
+ - der Schrifttyp wird eingeschaltet,
+ - die Modifikationen für den Zwischenraum werden eingeschaltet,
+ - der Positionsbefehl für horizontale Bewegungen wird gegeben,
+ - die Modifikationen für den Text werden eingeschaltet,
+ - der Text wird ausgegeben.
+
+Die ersten vier Punkte werden nur dann ausgeführt, wenn sie notwendig sind. Über­
+schreitet der Text die Papierbreite, so zeigen Punkte am Ende der Zeile dies an.
+
diff --git a/doc/system/systemhandbuch.4 b/doc/system/systemhandbuch.4
new file mode 100644
index 0000000..e511eb5
--- /dev/null
+++ b/doc/system/systemhandbuch.4
@@ -0,0 +1,1185 @@
+#start(2.5,1.5)#
+#pageblock#
+#block#
+#page (91)#
+#headeven#
+%#center#EUMEL-Systemhandbuch
+
+
+#end#
+#headodd#
+#center#7. Der Fontspeicher#right#%
+
+
+#end#
+
+#ib(9)#7. Der #ib#Fontspeicher#ie##ie(9)#
+
+
+
+#ib(9)#7.1. #ib#Fonttabellen#ie##ie(9)#
+
+
+Damit die Textverarbeitung Dokumente formatieren kann, muß sie über Breiten und
+Höhen der einzelnen Schrifttypen (auch "#ib#Fonts#ie#" genannt) des Druckers, auf dem das
+Dokument gedruckt wird, Bescheid wissen. Auch bei dem Ausdruck des Dokuments
+wird diese Information benötigt. Im EUMEL-System stellt der #ib#Fontspeicher#ie# diese Infor­
+mation den #ib#Formatierprogramm#ie#en (#on("i")#lineform#off("i")# und #on("i")#pageform#off("i")#) und dem #ib#EUMEL-Drucker#ie#
+zur Verfügung.
+
+Da nun der Drucker Angaben zur Positionierung in seinen #ib#Mikroschritten#ie# (kleinste
+Schrittweite in horizontaler oder vertikalter Richtung) benötigt, liefert die Fonttabelle
+die Breiten- und Höhenangaben in Mikroschritten und eine Umrechnungseinheit von
+Schritten in Zentimeter oder umgekehrt. So braucht der EUMEL-Drucker bei Positionie­
+rungen keine Umrechnung vorzunehmen. Allerdings müssen die Formatierprogramme
+auch in Mikroschritten des jeweiligen Druckers rechnen. Dadurch werden jedoch
+Unterschiede durch Rundungsfehler zwischen dem EUMEL-Drucker und den Forma­
+tierprogrammen vermieden.
+
+Bei diesem Konzept können Fonts von verschiedenen Druckern nicht in einer Fontta­
+belle verwaltet werden, denn unterschiedliche Drucker haben meist verschiedene
+Mikroschritte. Somit muß es für jeden Drucker mindestens eine Fonttabelle geben.
+
+Es gibt aber auch Fälle, in denen Fonts auf einem Drucker nicht mit anderen Fonts des
+Druckers zusammengedruckt werden können. Solche Fälle liegen z.B. bei Typenrad­
+druckern vor, die immer nur mit einem Typenrad drucken können und dessen Zei­
+chenbreite hardwaremäßig eingestellt werden muß (z.B. beim Olivetti PR320), bei
+Druckern, die verschiedene Fonts für Längs- und Querformat haben (z.B. beim Agfa
+P400), oder bei Druckern, deren Fonts geladen werden (z.B. beim HP 2686). Eine
+#on("b")##ib#Fonttabelle#ie##off("b")# enthält also alle die Fonts eines Druckers, #on("b")#die auf dem Drucker kompati­
+bel sind#off("b")#. Es kann mehrere Fonttabellen zu einem Drucker geben.
+
+Die verschiedenen Fonttabellen werden von im Multi-User Betrieb von der Task "#ib#confi­
+gurator#ie#" verwaltet. Sie enthält alle Fonttabellen, die auf dem Rechner zur Verfügung
+stehen. Mit dem Kommando
+
+
+ #ib#fonttable#ie# ("Name der Fonttabelle")
+
+
+wird in einer Task die gewünschte Fonttabelle eingestellt. Danach stehen die Fonts
+dieser Tabelle in der Task zur Verfügung. Die Einstellung der Fonttabelle vererbt sich
+auf die Sohntasks, d.h. wird eine Sohntask begonnen, so ist dort die Fonttabelle des
+Vaters eingestellt.
+
+Dazu das folgenden Beispiel:
+
+ Für den Agfa-Drucker P400 gibt es die Fonttabellen "agfa" und "agfaquer", in
+ denen die Fonts für Längsdruck bzw. Querdruck enthalten sind. In der Task
+ #on("i")#PUBLIC#off("i")# wird mit dem Kommando #on("i")#fonttable ("agfa")#off("i")# die Fonttabelle "agfa" ein­
+ gestellt. Alle neuen Sohntasks können sofort ohne weitere Einstellung mit der
+ Textformatierung im Längsformat beginnen. Will nun jemand im Querformat
+ drucken, so muß er in seiner Task mit dem Kommando #on("i")#fonttable ("agfaquer")#off("i")# den
+ Fontspeicher auf die Fonts zum Querdruck umstellen.
+
+Das Kommando
+
+
+ #ib#list fonts#ie#
+
+
+listet die Fonts der eingestellten Fontabelle ins #on("i")#notebook#off("i")# und das Kommando
+
+
+ #ib#list fonttables#ie#
+
+
+informiert über die verfügbaren Fonttabellen.
+
+
+
+
+#ib(9)#7.2. Erstellen einer #ib#Fonttabelle#ie##ie(9)#
+
+
+Die Fonttabelle ist ein Datenraum mit einer eigenen Struktur. Somit kann sie nicht
+mehr mit dem Editor, sondern nur mit einem entsprechenden Programm bearbeitet
+werden. Solch ein Programm befindet sich in der Datei "#ib#font convertor#ie#" auf dem Stan­
+dardarchiv 'std.zusatz'. Diese Datei sollte in einer Systemtask (Sohntask von "SYSUR")
+insertiert werden. Danach stehen entsprechende Kommandos zur Bearbeitung einer
+Fonttabelle zur Verfügung.
+
+Um eine Fonttabelle zu bekommen, muß zuerst eine #on("b")##ib#Fontdatei#ie##off("b")# (d.h. eine editierbare
+Datei mit dem unten beschriebenen Aufbau) angelegt werden. Mit dem Kommando
+
+
+ #ib#create fonttable#ie# ("Name der Fontdatei")
+
+
+werden alle in der Fontdatei spezifizierten Fonttabellen erstellt. Sie liegen als benannte
+Datenräume in der Task vor und können mit dem Kommando #on("i")#save#off("i")# von einer System­
+task an die Task "configurator" gesendet werden. Danach sind diese Fonttabellen in
+allen Task auf dem Rechner verfügbar und können mit dem #on("i")#fonttable#off("i")# - Kommando
+eingestellt werden.
+
+Soll dagegen eine bestehende Fonttabelle geändert werden, so erstellt das Komman­
+do
+
+
+ #ib#create fontfile#ie# ("Name der Fonttabelle", "Name der Fontdatei")
+
+
+aus der angegebenen Fonttabelle eine Fontdatei. Die Fonttabelle muß dazu in der Task
+als benannter Datenraum vorliegen (d.h. sie muß eventuell mit #on("i")#fetch#off("i")# von der Task
+"configurator" geholt werden). In der so erstellten Fontdatei können die Änderungen
+mit dem Editor vorgenommen, mit #on("i")#create fonttable#off("i")# die geänderte Fonttabelle erstellt
+und diese wiederum mit #on("i")#save#off("i")# an die Task "configurator" gesendet werden. Mit dem
+#on("i")#fonttable#off("i")#-Kommando kann dann in den bestehenden Tasks die geänderte Fonttabelle
+eingestellt werden. Alle neuen Tasks erhalten automatisch die geänderte Fonttabelle.
+
+
+
+#ib(9)#Prozedurbeschreibung der Umwand­
+lungs­Kommandos#ie(9)#
+
+
+Nach der Insertierung der Datei "font convertor" stehen die folgenden Kommandos zur
+Umwandlung einer Fontdatei in eine Fonttabelle oder umgekehrt zur Verfügung.
+
+#ib#create fontfile#ie#
+ PROC create fontfile (TEXT CONST fonttable name, fontfile name)
+ Zweck: Aus Fonttabelle 'fonttable name' wird eine Fontdatei mit dem ange­
+ gebenen Name erstellt. Die Fonttabelle muß dabei in der eigenen Task
+ als benannter Datenraum vorliegen.
+
+#ib#create fonttable#ie#
+ PROC create fonttable (TEXT CONST fontfile name)
+ Zweck: Es werden alle Fonttabellen erzeugt, die in der Fontdatei 'fontfile name'
+ angegeben sind. Die Fonttabellen liegen dann als benannte Datenräu­
+ me in der Task vor.
+
+ PROC create fonttable
+ Zweck: Es werden alle Fonttabellen erzeugt, die in der zuletzt bearbeiteten
+ Datei angegeben sind.
+
+
+
+
+#ib(9)#7.3. Aufbau der #ib#Fontdatei#ie##ie(9)#
+
+
+In der Fontdatei können drei Strukturen stehen und zwar Kennungen, Identifkationen
+und Zeichenspezifikationen.#u##count#)#e#
+#foot#
+
+#value#) Beim formalen Aufbau bedeuten eckige Klammern, daß diese Angaben optional sind.
+
+#end#
+
+
+
+#ib(9)##ib#Kennungen#ie##ie(9)#
+
+
+ Formaler Aufbau: <#on("i")#Kennung#off("i")#> : Name 1 [, Name 2] [ ... ] ;
+
+ Eine Kennung leitet eine Definition ein. Für die Namen der Namensliste gelten die
+ folgenden Konventionen:
+
+ - der Name muß als TEXT-Denoter angegeben werden,
+ - der Name muß ungleich #on("i")#niltext#off("i")# sein,
+ - Leerzeichen sind im Namen nicht signifikant (d.h. "agfa quer" wird zu "agfa­
+ quer").
+
+ Eine Kennung kann die folgenden Werte annehmen:
+
+ <#on("i")#Kennung#off("i")#> { FONTTABLE, FONT }
+
+ - #on("b")##ib#FONTTABLE#ie##off("b")#
+ Hiermit wird eine Definition einer Fonttabelle eingeleitet. Es wird nur der erste
+ Name der Namensliste ausgewertet, da die Fonttabelle eindeutig identifiziert
+ sein muß. Alle folgenden Angaben werden dieser Fonttabelle zugeordnet, bis
+ eine neue Kennung FONTTABLE folgt.
+
+ - #on("b")##ib#FONT#ie##off("b")#
+ Hiermit wird eine Definition eines Schrifttyps eingeleitet. Ein Schrifttyp kann
+ mehrere Namen haben. Jedoch darf in einer Fonttabelle jeder Fontname nur
+ einem Font zugeordnet werden.
+
+
+
+#ib(9)##ib#Identifikation#ie#en#ie(9)#
+
+
+ Formaler Aufbau: [ <#on("i")#Identifikation#off("i")#> = <Wert der Identifikation> ; ]
+
+ Mit den Identifikationen werden bestimmte Angaben zu den Kennungen gemacht.
+ Sie müssen unmittelbar nach der entsprechenden Kennung folgen, brauchen aber
+ nur angegeben werden, wenn sie von den Standardwerten abweichen.
+
+
+
+#ib(9)#Identifikationen nach der Kennung #ib#FONTTABLE#ie##ie(9)#
+
+
+ <#on("i")#Identifikation#off("i")#> { x unit, y unit, on string, off string }
+
+ - #on("b")##ib#x unit#ie##off("b")#
+ Hiermit wird die Anzahl der Mikroschritte des Druckers pro Zentimeter in
+ horizontaler (x-) Richtung spezifiziert. Die Einheit muß als REAL-Denoter
+ angegeben werden. Alle weiteren Breitenangaben zu den Fonts dieses Druk­
+ kers beziehen sich auf diese Einheit.
+
+ STD-Wert: 10.0 / 2.54 = 3.937008
+
+ - #on("b")##ib#y unit#ie##off("b")#
+ Hiermit wird die Anzahl der Mikroschritte des Druckers pro Zentimeter in
+ vertikaler (y-) Richtung spezifiziert. Die Einheit muß als REAL-Denoter ange­
+ geben werden. Alle weiteren Höhenangaben zu den Fonts dieses Druckers
+ beziehen sich auf diese Einheit.
+
+ STD-Wert: 6.0 / 2.54 = 2.362205
+
+ - #on("b")##ib#on string#ie##off("b")#
+ Hier müssen vier Textdenoter, durch Komma getrennt, angegeben werden.
+ Die Textdenoter enthalten die Befehlssequenzen, um beim Drucker die Mo­
+ difikationen anzuschalten. Dabei ist die Reihenfolge der Modifikationen
+ underline, bold, italics, reverse.
+ Liegt für eine der Modifikationen keine Befehlssequenz vor, so muß #on("i")#niltext#off("i")#
+ angegeben werden. Die Befehlssequenzen können vom Druckertreiber ab­
+ gefragt werden.
+
+ STD-Wert: #on("i")#niltext#off("i")# für alle Modifikationen
+
+ - #on("b")##ib#off string#ie##off("b")#
+ Hier müssen vier Textdenoter, durch Komma getrennt, angegeben werden.
+ Die Textdenoter enthalten die Befehlssequenzen, um beim Drucker die Mo­
+ difikationen auszuschalten. Dabei ist die Reihenfolge der Modifikationen
+ underline, bold, italics, reverse.
+ Liegt für eine der Modifikationen keine Befehlssequenz vor, so muß #on("i")#niltext#off("i")#
+ angegeben werden. Die Befehlssequenzen können vom Druckertreiber ab­
+ gefragt werden.
+
+ STD-Wert: #on("i")#niltext#off("i")# für alle Modifikationen
+
+
+
+#ib(9)#Identifikationen nach der Kennung #ib#FONT#ie##ie(9)#
+
+
+ <#on("i")#Identifikation#off("i")#> { font lead, font height, font depth, indentation pitch,
+ next larger font, next smaller font,
+ font string, y offsets, bold offset }
+
+ - #on("b")##ib#font lead#ie##off("b")##u##count#)#e#
+ Der Durchschuß eines Fonts gibt den Zwischenraum in vertikaler Richtung
+ zwischen den Zeilen bei einfachem Zeilenvorschub an. Er muß in Mikroschrit­
+ ten der y-Richtung als INT-Denoter angegeben werden.
+
+ STD-Wert: 0
+#foot#
+
+#value#) Für spätere Erweiterungen des EUMEL-Druckers wurde die bisherige Fonthöhe in Durchschuß, Fonthöhe
+ und Fonttiefe aufgespalten. Für alle bis jetzt definierten Leistungen braucht nur wie bisher die Fonthöhe
+ angegeben zu werden. Der Durchschuß und die Fonttiefe werden dann auf Null gesetzt.
+#end#
+
+ - #on("b")##ib#font height#ie##off("b")##u##value#)#e#
+ Die Fonthöhe ist die Distanz von der Basislinie bis zur Oberkante des höch­
+ sten Zeichens. Sie muß in Mikroschritten der y-Richtung als INT-Denoter
+ angegeben werden.
+
+ STD-Wert: 6 Zeilen pro Inch entsprechend der definierten #on("i")#y unit#off("i")#
+
+ - #on("b")##ib#font depth#ie##off("b")##u##value#)#e#
+ Die Fonttiefe ist die Distanz von der Basislinie bis zur Unterkante des tief­
+ sten Zeichens. Sie muß in Mikroschritten der y-Richtung als INT-Denoter
+ angegeben werden.
+
+ STD-Wert: 0
+
+ - #on("b")##ib#indentation pitch#ie##off("b")#
+ Einrückungen oder Aufzählungen werden äquidistant berechnet, d.h. Anzahl
+ der Zeichen mal einer festen Breite. Diese Einrückbreite sollte ein Mittel al­
+ ler Zeichenbreiten sein und braucht nicht der Breite des Leerzeichens zu
+ entsprechen. Sie muß in Mikroschritten der x-Richtung als INT-Denoter an­
+ gegeben werden.
+
+ STD-Wert: 10 Zeichen pro Inch entsprechend der definierten #on("i")#x unit#off("i")#
+
+ - #on("b")##ib#next larger font#ie##off("b")#
+ Hier muß der Name des nächst größeren Fonts als TEXT-Denoter aufgeführt
+ werden. Gibt es keinen nächst größeren Font, so ist #on("i")#niltext#off("i")# anzugeben.
+
+ STD-Wert: #on("i")#niltext#off("i")#
+
+ - #on("b")##ib#next smaller font#ie##off("b")#
+ Hier muß der Name des nächst kleineren Fonts als TEXT-Denoter aufge­
+ führt werden. Gibt es keinen nächst kleineren Font, so ist #on("i")#niltext#off("i")# anzugeben.
+ Bei Indizes oder Exponenten wird automatisch auf diesen nächst kleineren
+ Font umgeschaltet.
+
+ STD-Wert: #on("i")#niltext#off("i")#
+
+
+ - #on("b")##ib#font string#ie##off("b")#
+ Hier kann als TEXT-Denoter eine Befehlssequenz angegeben werden, die
+ den Drucker auf diesen Font umschaltet. Diese Befehlssequenz kann vom
+ Druckertreiber abgefragt werden. Dadurch ist es nicht nötig, daß er die Na­
+ men der Fonts kennt.
+
+ STD-Wert: #on("i")#niltext#off("i")#
+
+ - #on("b")##ib#y offsets#ie##off("b")#
+ Um bei Matrixdruckern Schriften zu erzeugen, die höher als eine Nadelreihe
+ sind, müssen entsprechende Bitmuster des Textes an verschiedenen y-Po­
+ sitionen ausgegeben werden. Um diese Anforderung durch den EUMEL-
+ Drucker zu unterstützen, kann hier eine Liste von Verschiebungen von der
+ Basislinie angegeben werden, an denen der Text ein weiteres Mal ausgege­
+ ben wird. Dabei bedeuten negative Werte eine Verschiebung oberhalb und
+ positive Werte eine Verschiebung unterhalb der Basislinie. Ist der Wert Null,
+ so wird der Text auf der Basislinie ausgegeben. Die Modifikation #on("i")#underline#off("i")#
+ wird bei der Ausgabe des Textes nur an der ersten Verschiebung angestellt.
+ Die Werte für die Verschiebungen müssen in Mikroschritten der y-Richtung
+ als INT-Denoter angegeben und durch Komma getrennt werden.
+
+ STD-Wert: 0
+
+ - #on("b")##ib#bold offset#ie##off("b")#
+ Falls der Drucker die Modifikation #on("i")#bold#off("i")# nicht beherrscht, versucht der
+ EUMEL-Drucker sie durch Doppeldruck zu simulieren. Der 'bold offset' gibt
+ an, ob und wieviel der zweite Durchgang in x-Richtung verschoben werden
+ soll. Dies ergibt insbesondere bei Laserdruckern, die nicht für alle Schriftty­
+ pen einen Bold-Typ haben, einen recht guten Fettdruck. Der Wert muß in
+ Mikroschritten der x-Richtung als INT-Denoter angegeben werden.
+
+ STD-Wert: 0
+
+
+
+#ib(9)##ib#Zeichenspezifikationen#ie##ie(9)#
+
+
+
+ Formaler Aufbau: [ <Zeichen> [, <Breite des Zeichens>]
+ [, <Ersatzdarstellung des Zeichens>] ; ]
+
+
+ Nachdem die Identifikationen zu einer Kennung angegeben wurden, können Zei­
+ chenspezifikationen folgen, d.h. zu einem Zeichen kann die Breite und/oder eine
+ Ersatzdarstellung spezifiziert werden. Dazu muß zuerst das Zeichen selber als
+ TEXT-Denoter angegeben werden.
+
+ - #on("b")##ib#Breite des Zeichens#ie##off("b")#
+ Die Zeichenbreite muß als INT-Denoter in Mikroschritten angegeben werden.
+ Alle Zeichenbreiten werden mit der Einrückbreite vorbesetzt, so daß nur sol­
+ che Zeichen angegeben werden müssen, deren Breite von der Einrückbreite
+ abweichen. Negative Zeichenbreiten sind nicht erlaubt. Die Angabe von Zei­
+ chenbreiten nach der Kennung FONTTABLE wird ignoriert.
+
+ - #on("b")##ib#Ersatzdarstellung des Zeichens#ie##off("b")#
+ Die Ersatzdarstellung wird statt des Zeichens ausgedruckt. Sie muß als
+ TEXT-Denoter angegeben werden. Werden Ersatzdarstellungen nach der
+ Kennung FONTTABLE angegeben, so gelten sie global für alle Fonts dieser
+ Fonttabelle. Sie können jedoch bei der Fontangabe lokal wieder überschrie­
+ ben werden. Eine Ersatzdarstellung darf höchsten 255 Zeichen lang sein. Alle
+ Ersatzdarstellungen eines Fonts dürfen 32767 Zeichen nicht überschreiten.
+
+
+
+#ib(9)##ib#Kommentare in der Fontdatei#ie##ie(9)#
+
+
+ In der Fontdatei dürfen Kommentare eingefügt werden. Sie müssen den Kommen­
+ taren der ELAN-Syntax entsprechen, d.h. mit '(*' beginnen und mit '*)' enden.
+
+
+
+#ib(9)##ib#Deutsche Namen#ie##ie(9)#
+
+
+ Kennungen und Identifikationen dürfen in der Fontdatei auch mit folgenden deut­
+ schen Namen angegeben werden.
+
+ FONTABLE : FONTABELLE
+ FONT : FONT
+
+#free (0.15)#
+ x unit : x einheit
+ y unit : y einheit
+ on string : on sequenz
+ off string : off sequenz
+ indentation pitch : einrueckbreite
+ font lead : durchschuss
+ font height : fonthoehe
+ font depth : fonttiefe
+ next larger font : groesserer font
+ next smaller font : kleinerer font
+ font string : font sequenz
+ y offsets : y verschiebungen
+ bold offset : bold verschiebung
+
+
+
+
+#ib(9)#7.4. Beispiel für eine Fontdatei#ie(9)#
+
+
+In diesem Beispiel einer Fonttdatei sind drei Fonttabellen enthalten, nämlich "agfa" und
+"agfaquer" für den Agfa-Drucker und "epson" für einen Epson-Drucker.
+
+
+FONTTABLE : "agfa" ;
+ x unit = 160.0 ; #right#(* Anzahl der Mikroschritte pro cm *)
+ y unit = 160.0 ;
+ on string = "\UL1;", "\BO1;", "\IT1;", "\CFW;\CBB;" ;
+ off string = "\UL0;", "\BO0;", "\IT0;", "\CFT;\CBT;" ;
+
+#right#(* globale Ersatzdarstellungen für alle Agfa-Fonts *)
+
+ ""214"" , "\!298;" ; #right#(* AE *)
+ ""215"" , "\!299;" ; #right#(* OE *)
+ ""216"" , "\!300;" ; #right#(* UE *)
+ ""217"" , "\!451;" ; #right#(* ae *)
+ ""218"" , "\!452;" ; #right#(* oe *)
+ ""219"" , "\!453;" ; #right#(* ue *)
+ .
+ .
+ .
+
+ FONT : "trium10" ;
+ indentation pitch = 30 ;
+ font lead = 7 ;
+ font heigth = 54 ;
+ font depth = 15 ;
+ next larger font = "trium12" ;
+ next smaller font = "helvetica8" ;
+ font string = "\FO5;" ;
+
+ " " , 20 ; "!" , 16 ;
+ """" , 22 ; "\#" , 31 ;
+ "$" , 31 ; "%" , 55 ;
+ .
+ .
+ .
+ ""217"" , 31 ; #right#(* ae *)
+
+#right#(* lokale Ersatzdarstellungen für Font "trium10" *)
+
+ ""244"" , 43 , "\FO23;\!725;\FO5;" ; #right#(* ungleich *)
+ ""245"" , 31 , "\FO23;\!405;\FO5;" ; #right#(* mal-Zeichen *)
+
+ FONT : "modern12", "elanlist" ; #right#(* Mehrere Namen für einen Font *)
+ indentation pitch = 33 ;
+ font lead = 14;
+ font heigth = 53;
+ font depth = 13;
+ next larger font = "" ;
+ next smaller font = "micro" ;
+ font string = "\FO11;"
+ #right#(* Alle Zeichen haben die gleiche Breite *)
+
+ FONT . . .
+
+
+FONTTABLE : "agfaquer" ;
+ x unit = 160.0 ;
+ y unit = 160.0 ;
+ on string = "\UL1;", "\BO1;", "\IT1;", "\CFW;\CBB;" ;
+ off string = "\UL0;", "\BO0;", "\IT0;", "\CFT;\CBT;" ;
+ .
+ .
+ .
+
+
+FONTTABLE : "epson" ;
+ x unit = 47.24409 ; #right#(* 120.0 / 2.54 *)
+ y unit = 85.03937 ; #right#(* 216.0 / 2.54 *)
+ on string = ""27"-"1"", "", ""27"4", "";
+ off string = ""27"-"0"", "", ""27"5", "";
+
+ ""214"" , ""27"R"2""091""27"R"0"" ; #right#(* AE *)
+ ""215"" , ""27"R"2""092""27"R"0"" ; #right#(* OE *)
+ ""216"" , ""27"R"2""093""27"R"0"" ; #right#(* UE *)
+ ""217"" , ""27"R"2""123""27"R"0"" ; #right#(* ae *)
+ ""218"" , ""27"R"2""124""27"R"0"" ; #right#(* oe *)
+ ""219"" , ""27"R"2""125""27"R"0"" ; #right#(* ue *)
+ ""220"" , "k" ; #right#(* Trenn-k *)
+ ""221"" , "-" ; #right#(* Trennstrich *)
+ ""222"" , "\#" ; #right#(* geschütztes Nummernkreuz *)
+ ""223"" , " " ; #right#(* geschütztes Leerzeichen *)
+ ""251"" , ""27"R"2""126""27"R"0"" ; #right#(* ss *)
+ ""252"" , ""27"R"2""064""27"R"0"" ; #right#(* Paragraph *)
+
+ FONT : "12", "elite", "elite12" ; #right#(* Mehrere Namen für einen Font *)
+ font height = 36 ;
+ indentation pitch = 10 ;
+ next smaller font = "12.klein" ;
+ font string = ""27"!"1""27"p"0""27"T" ;
+ bold offset = 2 ;
+
+ FONT : "12.klein", "elite.klein", "elanlist" ;
+ font height = 20 ;
+ indentation pitch = 10 ;
+ next smaller font = "12.klein" ;
+ font string = ""27"!"1""27"p"0""27"S"1"" ;
+ bold offset = 1 ;
+
+ FONT : "12.hoch" ;
+ font height = 96 ;
+ indentation pitch = 10 ;
+ next smaller font = "12.klein" ;
+ font string = "" ;
+ bold offset = 2 ;
+ y offsets = 12, -12 ;#right#(* der Text wird jeweils 12 Mikroschritte unter-
+ #right# und überhalb der Basislinie ausgegeben *)
+
+ FONT : "prop10", "prop" ;
+ font height = 12 ;
+ indentation pitch = 24 ;
+ next smaller font = "" ;
+ font string = ""27"!"0""27"p"1""27"T" ;
+ bold offset = 2 ;
+
+ "!" , 10 ;
+ """" , 16 ;
+ "(" , 12 ;
+ . . .
+
+
+
+
+
+#ib(9)#7.5. Schnittstelle des #ib#Fontspeicher#ie#s#ie(9)#
+
+
+
+Das Paket #on("i")#font store#off("i")# liefert die folgenden Prozeduren:
+
+#ib#fonttable#ie#
+ PROC fonttable (TEXT CONST fonttable name)
+ Zweck: Stellt die angegebene Fonttabelle in der Task ein. Dabei wird zuerst in
+ der eigenen Task nach der angegebenen Fonttabelle gesucht. Existiert
+ die Fonttabelle in der eigenen Task nicht, so wird die Fonttabelle von
+ der Task "configurator" geholt.
+ Wenn die Fonttabelle eingestellt ist, sind in der Task nur noch die Fonts
+ dieser Fonttabelle bekannt. Die Einstellung vererbt sich auf die Sohn­
+ tasks.
+
+ TEXT PROC fonttable
+ Zweck: Liefert den Name der eingestellten Fonttabelle.
+
+#ib#list fonttables#ie#
+ PROC list fonttables
+ Zweck: Zeigt die Liste der verfügbaren Fonttabellen im #on("i")#notebook#off("i")#.
+
+#ib#list fonts#ie#
+ PROC list fonts
+ Zweck: Listet die Fonts der eingestellten Tabelle ins #on("i")#notebook#off("i")#.
+
+ PROC list fonts (TEXT CONST fonttable name)
+ Zweck: Listet die Fonts der angegebenen Fonttabelle ins #on("i")#notebook#off("i")#. Die vorher
+ eingestellte Fonttabelle bleibt jedoch weiter eingestellt.
+
+#ib#x step conversion#ie#
+ INT PROC x step conversion (REAL CONST cm)
+ Zweck: Rechnet die in Zentimeter angegebene Länge in Mikroschritte der
+ x-Richtung um.
+
+ REAL PROC x step conversion (INT CONST steps)
+ Zweck: Rechnet die in Mikroschritten der x-Richtung angegebene Länge in
+ Zentimeter um.
+
+#ib#y step conversion#ie#
+ INT PROC y step conversion (REAL CONST cm)
+ Zweck: Rechnet die in Zentimeter angegebene Länge in Mikroschritte der
+ y-Richtung um.
+
+ REAL PROC y step conversion (INT CONST steps)
+ Zweck: Rechnet die in Mikroschritten der y-Richtung angegebene Länge in
+ Zentimeter um.
+
+#ib#on string#ie#
+ TEXT PROC on string (INT CONST modification)
+ Zweck: Liefert die in der Fonttabelle spezifizierte Befehlssequenz, um eine
+ Modifikation anzuschalten. Es gibt die folgenden Modifikationen
+ 1 underline
+ 2 bold
+ 4 italics
+ 8 reverse
+
+#ib#off string#ie#
+ TEXT PROC off string (INT CONST modification)
+ Zweck: Liefert die in der Fonttabelle spezifizierte Befehlssequenz, um eine
+ Modifikation auszuschalten. Es gibt die folgenden Modifikationen
+ 1 underline
+ 2 bold
+ 4 italics
+ 8 reverse
+
+#ib#font#ie#
+ INT PROC font (TEXT CONST font name)
+ Zweck: Liefert die interne Fontnummer des Fonts. Mit dieser Fontnummer
+ können die weiteren Informationen über den Font angefordert werden.
+ Existiert kein Font mit diesem Namen, so wird Null geliefert.
+
+ TEXT PROC font (TEXT CONST font nr)
+ Zweck: Liefert den Fontnamen des Fonts mit der angegeben Fontnummer. Hat
+ der Font mehrere Namen, so wird der erste Name der Namensliste aus
+ der Fontdatei geliefert. Existiert kein Font unter dieser Nummer, so wird
+ #on("i")#niltext#off("i")# geliefert.
+
+#ib#font exists#ie#
+ BOOL PROC font exists (TEXT CONST font name)
+ Zweck: Informationsprozedur zur Abfrage der Existenz eines Fonts.
+
+#ib#next smaller font exists#ie#
+ BOOL PROC next smaller font exists (INT CONST font nr,
+ INT VAR next smaller font)
+ Zweck: Informationsprozedur zur Abfrage der Existenz des nächst kleineren
+ Fonts. Wenn er existiert, wird die Fontnummer dieses Fonts zurück­
+ geliefert.
+
+#ib#next larger font exists#ie#
+ BOOL PROC next larger font exists (INT CONST font nr,
+ INT VAR next larger font)
+ Zweck: Informationsprozedur zur Abfrage der Existenz des nächst größeren
+ Fonts. Wenn er existiert, wird die Fontnummer dieses Fonts zurück­
+ geliefert.
+
+#ib#indentation pitch#ie#
+ INT PROC indentation pitch (INT CONST font nr)
+ Zweck: Liefert die Einrückbreite in Mikroschritten der x-Richtung. Sie sollte eine
+ mittlere Breite der Zeichen sein, denn mit ihr werden die Einrückungen
+ und Aufzählungen berechnet.
+
+#ib#font lead#ie#
+ INT PROC font lead (INT CONST font nr)
+ Zweck: Liefert den Durchschuss des Fonts in Mikroschritten der y-Richtung.
+ Der Druchschuß ist der Zwischenraum zwischen den einzelnen Zeilen
+ bei einfachem Zeilenvorschub.
+
+#ib#font height#ie#
+ INT PROC font height (INT CONST font nr)
+ Zweck: Liefert die Höhe des Fonts in Mikroschritten der y-Richtung. Die Fon­
+ thöhe ist die Distanz von der Basislinie bis zur Oberkante des höchsten
+ Zeichens.
+
+#ib#font depth#ie#
+ INT PROC font depth (INT CONST font nr)
+ Zweck: Liefert die Tiefe des Fonts in Mikroschritten der y-Richtung. Die Fonttie­
+ fe ist die Distanz von der Basislinie bis zur Unterkante des tiefsten
+ Zeichens.
+
+#ib#font string#ie#
+ TEXT PROC font string (INT CONST font nr)
+ Zweck: Liefert den Fontstring des Fonts. Der Fontstring enthält die Befehls­
+ sequenz, um den Drucker auf diesen Font umzuschalten.
+
+#ib#y offsets#ie#
+ TEXT PROC y offsets (INT CONST font nr)
+ Zweck: Liefert einen Text mit den y-Verschiebungen von der Basislinie. Die
+ einzelnen Verschiebungen können mit dem Operator 'ISUB' abgefragt
+ werden.
+
+#ib#bold offsets#ie#
+ INT PROC bold offsets (INT CONST font nr)
+ Zweck: Liefert die 'bold'-Verschiebung.
+
+#ib#char pitch#ie#
+ INT PROC char pitch (INT CONST font nr, TEXT CONST char)
+ Zweck: Liefert die Breite des Zeichens in Mikroschritten der x-Richtung.
+
+#ib#replacement#ie#
+ TEXT PROC replacement (INT CONST font nr, TEXT CONST char)
+ Zweck: Falls das Zeichen eine Ersatzdarstellung hat, so wird diese geliefert,
+ anderfalls das Zeichen selbst.
+
+#ib#get font#ie#
+ PROC get font (INT CONST font nr,
+ INT VAR indentation pitch, font lead, font height, font depth,
+ ROW 256 INT VAR pitch table)
+ Zweck: Die Variablen liefern die entsprechenden Informantionen über den
+ Font. Der Eintrag des Codewerts eines Zeichens plus eins in der Brei­
+ tentabelle liefert die Breite dieses Zeichens.
+
+#ib#get replacements#ie#
+ PROC get replacements (INT CONST font nr,
+ TEXT VAR replacements,
+ ROW 256 INT VAR replacement table)
+ Zweck: In der Fonttabelle kann für jedes Zeichen eine Ersatzdarstellung an­
+ gegeben werden. Diese Ersatzdarstellungen werden mit dieser Proze­
+ dur geliefert. Dabei stehen in der Textvariablen 'replacement' die ge­
+ samten Ersatzdarstellungen des Fonts. Die Ersatzdarstellungstabelle
+ enthält Zeiger auf den Text der Ersatzdarstellungen. Die Ersatzdarstel­
+ lung eines Zeichnes bestimmt sich wie folgt:
+
+
+ ersatzdarstellung :
+ INT CONST wert := replacement table (code( zeichen ) + 1);
+ IF wert > 0
+ THEN INT CONST ende := wert + code (replacements SUB wert);
+ subtext (replacements, wert + 1, ende)
+ ELSE zeichen
+ FI.
+
+
+Bei den Prozeduren des Packets #on("i")#font store#off("i")# können die folgenden Fehlerfälle auftreten:
+
+ - Fonttabelle noch nicht eingestellt
+ Es wurde noch keine Fonttabelle in der Task eingestellt.
+
+ - Fonttabelle "fonttable name" gibt es nicht
+ Die angegebene Fonttabelle wurde weder in der eigenen Task, noch in der
+ Task 'configurator' gefunden.
+
+ - Font 'font nr' gibt es nicht
+ Unter der angegebenen Fontnummer gibt es in der eingestellten Font­
+ tabelle keinen Font. Speziell ist das für 'font nr' = 0 der Fall, falls ein Font­
+ name nicht gefunden wurde.
+
+ - unzulaessige Modifikation
+ Die angegebene Modifikation ist ungleich 1, 2, 4 oder 8.
+#page#
+
+#headeven#
+
+%#center#EUMEL-Systemhandbuch
+
+
+#end#
+#headodd#
+
+#center#8. Verschiedenes#right#%
+
+
+#end#
+
+#ib(9)#8. Verschiedenes#ie(9)#
+
+
+
+
+#ib(9)#8.1. Der Spoolmanager#ie(9)#
+
+
+Der "#ib#Spoolmanager#ie#" verwaltet eine #ib#Warteschlange von Datenräumen#ie# (Dateien), die von
+einem "#ib#Server#ie#" abgearbeitet werden sollen. Dabei puffert der Spoolmanager Dateien,
+die von beliebigen Tasks geschickt werden können, in einer Warteschlange und gibt
+sie der Reihe nach dem Server zur eigentlichen Verarbeitung. Ein typischer Einsatzfall
+(aber nicht der einzige) für ein solches System ist der Druck von Dateien in Multi-
+User-Systemen. Unabhängig davon, ob der Drucker gerade aktiv ist und wieviele
+Dateien noch auf den Ausdruck warten, kann jeder seine Datei dem Druckerspool (in
+der Regel die Task "PRINTER") senden und sofort danach weiterarbeiten.
+
+
+
+#ib(9)#Prozeduren des Spoolmanagers#ie(9)#
+
+
+Im privilegierten Ast des Taskbaumes (Söhne von "SYSUR"), stehen die folgenden
+Prozeduren zur Einrichtung eines Spoolmanagers zur Verfügung.
+
+#ib#spool manager#ie#
+ PROC spool manager (PROC server, BOOL CONST with start)
+ Zweck: Die Task, in der die Prozedur aufgerufen wird, wird zum Spoolmanager.
+ Wenn 'with start' auf TRUE gesetzt ist, wird eine Server-Task als unbe­
+ nannter Sohn ("-") eingerichtet und mit der übergebenen 'PROC server'
+ gestartet. Anderfalls muß der Spool durch den Benutzer mit Hilfe der
+ Spoolkommandos (siehe dort) gestartet werden.
+
+ PROC spool manager (PROC server)
+ Zweck: Diese Prozedur ruft die Prozedur 'spool manager' mit 'with start' gleich
+ TRUE auf.
+
+
+Mit Hilfe der folgenden Prozeduren kann der Spool eingestellt werden.
+
+#ib#station only#ie#
+ PROC station only (BOOL CONST flag)
+ Zweck: Wenn flag auf TRUE gesetzt ist, nimmt der Spooler nur Aufträge von
+ Tasks der eigenen Station entgegen.
+ Voreinstellung: 'station only (FALSE)'.
+
+ BOOL PROC station only
+ Zweck: liefert TRUE, wenn der Spooler nur von der eigenen Station benutzt
+ werden darf.
+
+#ib#spool duty#ie#
+ PROC spool duty (TEXT CONST duty)
+ Zweck: Mit dieser Prozedur kann ein Text im Spooler eingestellt werden, der die
+ Aufgabe des Spoolers beschreibt. Dieser wird beim 'list' gemeldet.
+
+ TEXT PROC spool duty
+ Zweck: Liefert die eingestellte Text-Beschreibung der Aufgabe des Spools.
+
+#ib#spool control task#ie#
+ PROC spool control task (TASK CONST task)
+ Zweck: Diese Prozedur gibt der Task 'task' und ihrer Söhne die Berechtigung
+ Spoolkommandos (z.B. 'stop' oder 'start') an den Spoolmanager zusen­
+ den. Dabei muß die Task auf derselben Station wie der Spool sein und
+ in der Task muß die Datei "spool cmd", die sich auf dem Standardar­
+ chiv befindet, insertiert werden.
+ Wird "SUPERVISOR" als Spoolkontrolltask eingestellt, so können alle
+ Tasks der Station, in denen die Datei "spool cmd" insertiert ist, die
+ Spoolkommandos geben.
+
+ TASK PROC spool control task
+ Zweck: Liefert die Taskidentifikation der Spoolkontrolltask.
+
+#ib#server channel#ie#
+ PROC server channel (INT CONST channel)
+ Zweck: Mit Hilfe dieser Prozedur wird im Spoolmanager eine Kanalnummer
+ eingestellt, die der Server mit der Prozedur 'server channel' abfragen
+ kann.
+ Fehlerfall:
+ * falsche Kanalangabe
+ Der angegebene Kanal ist kleiner als 1 oder größerer als 32.
+
+ INT PROC serverchannel
+ Zweck: Liefert die Nummer des Kanals, der im Spool eingestellt ist.
+
+#on("b")#Anmerkung:#off("b")# Soll im nicht-privilegierten Ast des Taskbaums (Söhne von "PUBLIC") ein
+ Spool eingerichtet werden, so muß dort die Datei "spool manager", die
+ sich auf dem Standardarchiv "std.zusatz" befindet, insertiert werden.
+
+
+
+
+#ib(9)##ib#Spoolkommandos#ie##ie(9)#
+
+
+Ein Spool kann zur Verwaltung der Warteschlange wie jede andere Task ans Termi­
+nal gekoppelt werden. Danach stehen die folgenden Spoolkommandos zur Verfügung.
+Diese Kommandos sind keine Prozeduren, sondern werden nur interpretiert. Sie dürfen
+also nur alleine eingegeben werden. Nach Beendigung der Verwaltungsaufgaben muß
+der Spool mit dem Kommando 'break' verlassen werden, da sonst keine weiteren
+Aufträge an den Spool gesendet werden können und auch die Warteschlange nicht
+weiter abgearbeitet wird.
+
+#ib#stop#ie#
+ Zweck: Die Server-Task wird gelöscht und dadurch der Spool deaktiviert. Der
+ Spool empfängt zwar noch weitere Aufträge und sortiert diese in die
+ Warteschlange ein. Die Warteschlange wird aber nicht weiterabgearbei­
+ tet. Ein eventuell von der Server-Task belegter Kanal wird freigegeben.
+ Ist bei einem 'stop' noch ein Auftrag in Bearbeitung, so wird dieser
+ Auftrag abrupt abgebrochen. Es wird jedoch angefragt, ob der Auftrag
+ nochmal neu an die erste Stelle in der Warteschlange eingetragen wer­
+ den soll.
+ Ist ein Spool deaktiviert, so wird dies bei einem 'list' angezeigt,
+
+#ib#halt#ie#
+ Zweck: Der Spool deaktiviert sich nach Abarbeitung des Auftrags, der gerade
+ bearbeitet wird. Bei einem 'list' wird dies vermerkt.
+
+#ib#start#ie#
+ Zweck: Der Spool wird aktiviert, indem eine neue Server-Task begonnen wird. Ist
+ der Spool zuvor nicht gestoppt worden, so wird zuerst ein 'stop' durch­
+ geführt.
+ Wurde mit der Prozedur 'server channel' kein Kanal eingestellt, so wird
+ die Warnung
+ WARNUNG : Serverkanal nicht eingestellt
+ ausgeben. Der Spool wird trotzdem gestartet.
+
+start (kanal nummer)
+ Zweck: Vor dem Start des Spools wird zuerst mit der Prozedur 'server channel'
+ der angegebene Kanal eingestellt.
+
+#ib#first#ie#
+ Zweck: Im Dialog kann ein Auftrag in der Warteschlange auf den ersten Platz
+ vorgezogen werden.
+
+#ib#killer#ie#
+ Zweck: Im Dialog werden alle Aufträge der Warteschlange zum Löschen ange­
+ boten.
+
+#ib#list spool#ie#
+ Zweck: Der aktuelle Zustand des Spools und die Warteschlange werden geli­
+ stet.
+
+Ist nun eine Spoolkontrolltask eingestellt worden (siehe 'spool control task'), so muß in
+ihr die Datei "spool cmd" insertiert werden. Danach stehen die folgenden Prozeduren
+zur Verfügung.
+
+#ib#stop#ie#
+ PROC stop (TASK CONST spool)
+ Zweck: Dem Spool 'spool' wird ein 'stop' zugestellt, was den Spool deaktiviert.
+ Wird noch ein Auftrag bearbeitet, so wird angefragt, ob dieser neu
+ eingetragen werden soll.
+
+#ib#halt#ie#
+ PROC halt (TASK CONST spool)
+ Zweck: Dem Spool 'spool' wird ein 'halt' zugestellt, d.h der Spool deaktiviert
+ sich nach Beendigung des aktuellen Auftrags.
+
+#ib#wait for halt#ie#
+ PROC wait for halt (TASK CONST spool)
+ Zweck: Dem Spool 'spool' wird ein 'halt' zugestellt. Die Task wartet jedoch auf
+ eine Rückantwort, die ihr der Spool sendet, wenn er sich nach Been­
+ digung des aktuellen Auftrags deaktiviert hat.
+ Fehlerfall:
+ * Task "task name" wartet schon auf halt
+ Die angegebene Task wartet schon auf eine Rückantwort des Spools
+ 'spool'.
+
+#ib#start#ie#
+ PROC start (TASK CONST spool)
+ Zweck: Dem Spool 'spool' wird ein 'start' zugestellt, wodurch der Spool sich
+ aktiviert. War der Spool zuvor nicht deaktiviert, so wird er zuerst ge­
+ stoppt.
+
+#ib#first#ie#
+ PROC first (TASK CONST spool)
+ Zweck: Im Dialog kann einer der Aufträge in der Warteschlange des Spools
+ 'spool' auf den ersten Platz vorgezogen werden.
+
+#ib#killer#ie#
+ PROC killer (TASK CONST spool)
+ Zweck: Im Dialog werden die Aufträge der Warteschlange des Spools 'spool'
+ zum Löschen angeboten.
+
+
+
+#ib(9)#Arbeitsweise des #ib#Servers#ie##ie(9)#
+
+
+Der Server wird vom Spoolmanager mit einer Prozedur gestartet, die die Abarbeitung
+der Warteschlange vornimmt. Dabei muß diese Prozedur zuerst den Datenraum mit
+dem 'fetch code' (= 11) holen. Danach kann der Server sich noch mit dem 'fetch
+param code' (= 21) die Dateiparameter (Dateiname, Schreib- und Lesepaßwort, Sen­
+dername und Senderstation) abholen und mit der Bearbeitung des Auftrags beginnen.
+
+Beispiel:
+
+
+LET fetch code = 11,
+ param fetch code = 21;
+BOUND STRUCT (TEXT name, write pass, read pass, sendername,
+ INT senderstation ) VAR msg;
+DATASPACE VAR ds, param ds;
+INT VAR reply;
+
+spool manager (PROC server);
+
+PROC server :
+ disable stop;
+ continue (server channel);
+ REP forget (ds); ds := nilspace;
+ call (father, fetch code, ds, reply);
+ forget (param ds); param ds := nilspace;
+ call (father, param fetch code, param ds, reply);
+ msg := param ds;
+ execute spool;
+ IF is error THEN error treatment FI;
+ PER;
+END PROC server;
+
+PROC execute spool :
+ enable stop;
+ ...
+
+
+
+
+
+#ib(9)#Senden eines Auftrags an den Spool#ie(9)#
+
+
+Jede Task kann jedem Spool durch Aufruf von '#ib#save#ie#' eine Datei senden.
+
+Beispiel:
+
+
+ save ("datei name", task ("spool name"))
+
+
+Dieses 'save'-Kommando funktioniert zweiphasig. Dabei wird in der ersten Phase dem
+Spool die Dateiparameter zugesendet. In der zweiten Phase folgt dann der Datenraum
+selber. Bei Netzübertragung zu einem Spool ist dieses zweiphasige 'save' jedoch
+nachteilig. Deshalb können Dateien vom Typ 'FILE' auch mit einem einphasigen 'save'
+unter dem 'file save code' (= 22) an den Spool gesendet werden. Die #on("i")#'headline'#off("i")# dieser
+Dateien muß jedoch dann auf eine bestimmte Art und Weise aufbereitet werden, so
+daß sie die Dateiparameter enthält. Beim Aufbau der #on("i")#'headline'#off("i")# muß eine Information
+muß mit dem Code 0 beginnen und dem Code 1 enden. Die Dateiparamter müssen
+dann mit der folgenden Reihenfolge in die #on("i")#'headline'#off("i")# eingetragen werden.
+
+ - Dateiname
+ - Schreibepaßwort
+ - Lesepaßwort
+ - Name des Senders
+ - Station des Senders
+
+Beispiel:
+
+
+...
+LET file save code = 22;
+DATASPACE VAR ds := old (file name);
+FILE VAR file := sequential file (input, ds);
+INT VAR reply;
+headline (file, ""0"" + file name +
+ ""1""0"" + write password +
+ ""1""0"" + read password +
+ ""1""0"" + name (myself) +
+ ""1""0"" + text (station (myself)) + ""1"");
+call (spool task, file save code, ds, reply);
+...
+
+
+Der Spoolmanager setzt bei Dateien, die mit dem 'file save code' angeliefert werden
+die #on("i")#'headline'#off("i")# wieder auf den Dateinamen.
+
+Den Benutzer stehen neben dem '#ib#save#ie#'-Kommando zur Übertragung einer Datei zum
+Spool noch die folgenden Kommandos zur Verfügung.
+
+
+ save (ALL myself, task ("spool name"))
+ save (SOME myself, task ("spool name"))
+
+ übertragung aller bzw. einiger Dateien der eigenen Task zum Spool.
+
+
+ #ib#erase#ie# ("datei name", task ("spool name"))
+ erase (ALL task ("spool name"), task ("spool name"))
+
+ Löschen eines bzw. aller eigenen Aufträge in der Warteschlange des Spools
+
+
+ #ib#list#ie# (task ("spool name"))
+
+ Liste des Spools über den aktuellen Zustand und die Warteschlange.
+
+Existiert ein Spool "PRINTER", so gibt es noch die folgenden Befehle.
+
+
+ #ib#print#ie#
+ print ("datei name")
+ print (ALL myself)
+ print (SOME myself)
+
+ Sie entsprechen einem 'save' an die Task "PRINTER"
+
+
+ #ib#printer#ie#
+
+ Liefert den internen Taskbezeichner der Task "PRINTER", d.h. diese Proze­
+ dur entspricht dem Aufruf von 'task ("PRINTER")'.
+
+
+
+
+
+#ib(9)#8.2. #ib#Freie Kanäle#ie(9)##ie#
+
+
+Das Paket '#ib#free channel#ie#' ermöglicht in Multi-User-Systemen die Einrichtung freier
+Kanäle. Freie Kanäle kann man zusätzlich zu dem Terminalkanal, der einem vom
+Supervisor zugeordnet wurde, benutzen. Jeder freie Kanal wird durch eine (benannte)
+Task - dem #ib#Kanalmanager#ie# - implementiert. Er wird danach mit dem Tasknamen ange­
+sprochen und kann von jeder Task belegt und wieder freigegeben werden. Während
+einer Belegung können andere Tasks den Kanal nicht benutzen. Der Kanalmanager
+koppelt sich für jede Belegung an den physikalischen Kanal an und gibt ihn danach
+auch wieder frei. Ein physischer Kanal kann also im Wechsel von mehreren Kanalma­
+nagern oder einem Kanalmanager und "normalen" Tasks belegt werden.
+
+Das Paket 'free channel' muß beim Kanalmanager und allen Benutzern des Kanals
+bzw. bei einem gemeinsamen Vater insertiert sein.
+
+
+#ib#FCHANNEL#ie#
+ Zweck: Der Datentyp FCHANNEL spezifiziert einen freien Kanal. Die Assoziie­
+ rung mit einem realen freien Kanal erfolgt mit der Prozedur 'free chan­
+ nel' und der Zuweisung ':=' (ähnlich wie beim Datentyp FILE).
+
+:=
+ OP := (FCHANNEL VAR dest, FCHANNEL CONST source)
+ Zweck: Zuweisung. Wird insbesondere bei der Assoziation (Assoziation: Verbin­
+ dung zwischen FCHANNEL VAR und Kanal) benötigt.
+
+#ib#close#ie#
+ PROC close (FCHANNEL VAR f)
+ Zweck: Der belegte FCHANNEL wird freigeben.
+
+ PROC close (TEXT CONST channel name)
+ Zweck: Der namentlich spezifizierte Kanal wird freigegeben.
+
+#ib#dialogue#ie#
+ PROC dialogue (FCHANNEL CONST f, TEXT CONST end of dialogue char)
+ Zweck: Der Terminalkanal wird direkt mit dem angegebenen freien Kanal ge­
+ koppelt. (Das Benutzerterminal wird "durchgeschaltet".) Eingaben am
+ Terminal werden auf 'f' ausgegeben, auf 'f' ankommende Daten werden
+ auf dem Benutzerterminal ausgegeben. Der Datenverkehr erfolgt im
+ #ib#Vollduplexmodus#ie#, d.h. der Datenverkehr beider Richtungen läuft unab­
+ hängig voneinander parallel. Hiermit können Terminals dynamisch an
+ andere Rechner gekoppelt werden. Der Dialogzustand wird durch Ein­
+ gabe des 'end of dialogue char' am Benutzerterminal beendet.
+
+#ib#fetch#ie#
+ PROC fetch (FCHANNEL VAR channel, TEXT CONST filename, controlchars)
+ Zweck: Die angegebene datei wird über den Kanal 'channel' eingelesen. Dabei
+ besteht 'control chars' aus zwei bis vier Zeichen
+ (eof + eol + handshake + handshake prompt)
+ eof:
+ Dieses Zeichen wird als Dateiabschluß erwartet.
+ eol:
+ Dieses Zeichen wird als Zeilenende erwartet.
+ handshake, handshake prompt:
+ Falls 'handshake prompt <> "" ' ist, wird bei dem Empfang eines
+ Prompt­Zeichen eine Quittung (Handshake­Zeichen) ausgegeben.
+
+#ib#free channel#ie#
+ FCHANNEL PROC free channel (TEXT CONST channel name)
+ Zweck: Der namentlich spezifizierte Kanal wird belegt und als FCHANNEL
+ geliefert.
+ Fehlerfälle:
+ * task not existing
+ * channel not free
+
+ PROC free channel (INT CONST physical channel number)
+ Zweck: Installiert die eigene Task als Kanalmanager für den angegebenen
+ physikalischen Kanal.
+
+#ib#in#ie#
+ PROC in (FCHANNEL CONST f, TEXT VAR response)
+ Zweck: Es werden die Daten geliefert, die seit dem letzten 'in'­Aufruf bzw. seit
+ der Assoziierung eingetroffenen Daten geliefert. Bei 'niltext' liegen keine
+ Eingabedaten vor.
+
+#ib#open#ie#
+ PROC open (FCHANNEL VAR f)
+ Zweck: Der Kanal wird neu belegt. Die Assoziation erfolgt mit dem gleichen
+ Kanal wie bei der letzten Assoziation.
+ Fehlerfälle:
+ * "task" gibt es nicht
+ * Kanal ist nicht frei
+
+#ib#out#ie#
+ PROC out (FCHANNEL VAR f, TEXT CONST message)
+ Zweck: Der übergebene Text wird auf dem Kanal 'f' ausgegeben.
+
+#ib#save#ie#
+ PROC save (FCHANNEL VAR f, TEXT CONST name, control chars)
+ Zweck: Die übergebene Datei muß eine Textdatei sein (Struktur eines FILEs
+ haben). Sie wird komplett auf dem Kanal 'f' ausgegeben.
+ Dabei bestehen 'control chars' aus bis zu drei Zeichen:
+ (eof char + eol char + handshake option)
+ eof char:
+ Dieses Zeichen wird als Dateiabschluß geschickt.
+ eol char:
+ Dieses zeichen wird als Zeilenabschluß geschickt.
+ handshake option:
+ Falls die 'control chars' drei Zeichen umfassen, wird nach jeder
+ Zeile auf das als drittes definierte Handshake­Zeichen gewartet.
+
+Beispiele:
+
+
+ a) FCHANNEL VAR f := free channel ("otto") ;
+ TEXT VAR antwort ;
+ out (f, "hallo") ;
+ in (f, antwort) ;
+ put (antwort) ;
+ close (f) ;
+
+ b) open (f) ;
+ REP
+ out (f, "hallo ") ;
+ in (f, antwort)
+ UNTIL antwort <> "" PER ;
+ put (antwort) ;
+ close (f) ;
+
+ c) open (f) ;
+ dialogue (f, "§") ;
+ close (f)
+
diff --git a/doc/user/benutzerhandbuch.1 b/doc/user/benutzerhandbuch.1
new file mode 100644
index 0000000..7c8fec7
--- /dev/null
+++ b/doc/user/benutzerhandbuch.1
@@ -0,0 +1,580 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#Benutzerhandbuch
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 1: Einleitung
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+1 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 1 - %
+#tableend##clearpos#
+#end#
+TEIL 1: Einleitung
+#free(1.0)#
+
+1.1. Vorwort
+#free(1.0)#
+
+Dieses Buch bietet Ihnen eine Anleitung zur Handhabung des Betriebssystems
+EUMEL in Hinblick auf die Textverarbeitung. Das Buch wendet sich somit an alle, die
+das leicht erlernbare EUMEL-System zur Erstellung von Texten jeglicher Art und
+jeden Umfangs nutzen wollen.
+
+Die Anleitung erfordert keinerlei Vorkenntnisse, weder von Computern im allgemei­
+nen noch von EUMEL im besonderen. Neulingen auf dem Gebiet der Benutzung eines
+Computers sei empfohlen, dieses erste Kapitel, das sich kurz mit der 'grauen Theorie'
+beschäftigt, mindestens zweimal zu lesen:
+
+- Der erste Durchgang sollte nur einer groben Orientierung dienen. Die Begriffe, die
+ teilweise erst im routinierteren Umgang Sinn gewinnen, sollten Sie 'mal gehört'
+ haben, um die folgenden Kapitel leichter lesen zu können.
+
+- Der zweite Durchgang erscheint uns sinnvoll, wenn Sie sich 'freigeschwommen'
+ haben. Wenn der Umgang mit dem EUMEL-System Ihnen nach einigen Tagen
+ schon vertrauter erscheint, ist es zweckmäßig, sich auf dem Hintergrund der
+ gemachten Erfahrungen die Erklärungen noch einmal durchzulesen. Einige der
+ Begriffe werden erst dann wirklich verständlich und manche Unsicherheit wird
+ beseitigt werden.
+
+Die weiteren Teile des Buches geben dann Anleitung vom ersten Einstieg ins
+EUMEL-System bis hin zur detaillierten Beschreibung der Textverarbeitung. Alle in
+Teil 3 und 4 enthaltenen Beispiele sollten Sie sorgfältig durchgehen und am Bild­
+schirm nachvollziehen. Aus dem Teil 5 können Sie nach eigener Einschätzung zu­
+nächst die Bereiche auswählen, die Sie selbst für besonders wichtig halten. Sie wer­
+den feststellen, daß Sie durch den Umgang mit der EUMEL-Textverarbeitung mit
+fortschreitender Routine immer mehr der gebotenen Möglichkeiten hinzunehmen
+werden.
+#free(1.0)#
+Was ist ein Betriebssystem ?
+
+Ein #ib#Betriebssystem#ie# ist eine Sammlung von Programmen, die dem Benutzer eines
+Computers die Arbeit mit diesem Gerät erst ermöglichen. Die Programme des Be­
+triebssystems stellen die Verbindung zwischen den Bausteinen eines Computers, der
+Hardware, und den Anwendungsprogrammen eines Benutzers her.
+
+Alle Programme, die diese riesige Lücke schließen und z.B. dafür sorgen, daß der
+Befehl: #on("i")#drucke ("diesen brief")#off("i")# tatsächlich dazu führt, daß der eben noch am Bild­
+schirm verfaßte Brief zum Drucker gesendet und dort ausgedruckt wird, sind soge­
+nannte Systemprogramme, Teile des Betriebssystems.
+
+Dieses Benutzerhandbuch zum Betriebssystem EUMEL wird Ihnen schrittweise die
+Befehle erklären, die Sie zur Nutzung aller Möglichkeiten der Textverarbeitung mit
+EUMEL verwenden können, und Ihnen somit einen Teil des Betriebssystems vorstel­
+len.
+#free(1.0)#
+Ist EUMEL anders als andere ?
+
+#on("b")#Ja.#off("b")# Das Betriebssystem EUMEL (#on("b")#E#off("b")#xtendable multi #on("b")#U#off("b")#ser #on("b")#M#off("b")#icroprocessor #on("b")#EL#off("b")#an Sy­
+stem) erklärt durch seinen voll ausgeschriebenen Namen einen wesentlichen Unter­
+schied zu anderen Systemen: "Erweiterbares Mehrbenutzer Mikroprozessor ELAN-
+System."
+
+Während andere auf Mikroprozessoren (und damit auf sogenannte Personal Compu­
+ter) abgestimmte Betriebssysteme #on("u")#einen#off("u")# Benutzer bei seiner Arbeit unterstützen, ist
+EUMEL fähig, #on("u")#mehreren#off("u")# Anwendern gleichzeitig die Benutzung eines Computers zu
+ermöglichen. Natürlich funktioniert EUMEL ebensogut für einen einzigen Benutzer. Es
+gibt aber bei EUMEL die Möglichkeit, durch Ankoppeln weiterer Bildschirme an den
+Rechner und #on("b")#ohne#off("b")# Kosten für zusätzliche Software mehreren Benutzern gleichzeitig
+die Arbeit an diesem Rechner zu ermöglichen.
+
+Zweitens ist EUMEL hardwareunabhängig, das heißt, gleichgültig von welchem Her­
+steller Ihr Computer stammt, die Bedienung und die Kommandosprache ist immer
+gleich. Auch können Disketten, die mit einem XY-Rechner beschrieben wurden, von
+einem ABC-Computer gelesen werden; durchaus keine Selbstverständlichkeit.
+
+Eine weitere Besonderheit des EUMEL-Systems macht alle froh, die damit arbeiten:
+EUMEL ist durchgängig in der Programmiersprache ELAN gehalten. Auch wenn Sie
+(noch) nicht programmieren möchten, erleichtert Ihnen ELAN das Leben dadurch, daß
+Sie schreiben können, was Sie meinen: eine Datei, die einen Geschäftsbrief fix und
+fertig und druckbereit enthält, heißt nicht etwa:
+
+ $TXT.PRT
+
+sondern:
+
+ Angebot an Fa.Müller 1.7.86
+
+
+Ein weiterer wichtiger Unterschied wird Ihnen bewußt werden, wenn Sie ein anderes
+Betriebssystem kennen: Die EUMEL-Textverarbeitung ist kein zusätzliches Programm
+mit eigener Kommandosprache, welches bei Bedarf geladen werden muß, sondern
+steht jederzeit, im wahrsten Sinne des Wortes auf Knopfdruck, zu Ihrer Verfügung.
+#free(1.5)#
+1.2. Wichtige Begriffe
+#free(1.0)#
+- #on("b")#TASK#off("b")#. Eine #ib#Task#ie# ist ein eigenständiger Prozeß innerhalb eines EUMEL-Systems,
+ der entweder zur Verwaltung des EUMEL-Systems oder zu einem Benutzer
+ gehört. Indem jedem Benutzer ein eigener Arbeitsbereich zugewiesen ist, wird
+ verhindert, daß unkontrolliert auf fremde Daten zugegriffen wird. Eine Task hat
+ einen Namen, mit dem sie angesprochen werden kann. Ein EUMEL-System
+ besteht aus mehreren Tasks.
+
+ Ein brauchbarer Vergleich mit einem EUMEL-Tasksystem ist ein Firmengebäude:
+ Es besteht aus vielen Räumen und jeder Raum ( = Task ) ist entweder ein nor­
+ males Arbeitszimmer oder ein Chefzimmer oder eine Werkstatt, in der Dienst­
+ leistungen für andere erledigt werden.
+
+ Eine solche Ordnung zeigt folgendes Tasksystem; der #on("i")#kursiv#off("i")# gesetzte Kommentar
+ zeigt die Benennung der 'Dienstposten' eines vergleichbaren Büros:
+
+
+ SUPERVISOR #on("i")#(* Zimmerverwalter *)#off("i")# -
+ -
+
+ SYSUR #on("i")#(* Werkstattmeister *)#off("i")#
+
+
+ ARCHIVE #on("i")#(* Archivar *)#off("i")#
+
+ configurator #on("i")#(* Elektriker *)#off("i")#
+
+ OPERATOR #on("i")#(* Hausmeister *)#off("i")#
+
+ shutup #on("i")#(* Nachtwächter *)#off("i")#
+
+ UR #on("i")#(* Aufsichtsrat *)#off("i")#
+
+ PUBLIC #on("i")#(* Abteilungsleiter *)#off("i")#
+
+ Meier #on("i")#(* Angestellter *)#off("i")#
+ Müller #on("i")#(* " *)#off("i")#
+ Schulze #on("i")#(* " *)#off("i")#
+
+
+ Bildlich gesprochen stellt eine Task also ein 'Arbeitszimmer' für einen EUMEL-
+ Benutzer dar. Als EUMEL Anwender richten Sie sich Ihre Task selbst ein, indem
+ Sie das Kommando 'begin ("taskname")' geben.
+
+ Nachdem Sie dieses Kommando einmal gegeben haben, existiert diese Task unter
+ dem von Ihnen gewählten Namen.
+
+ In der Task (also sinngemäß im Arbeitszimmer) arbeiten Sie - insbesondere legen
+ Sie Dateien (= Akten) an. Dateien existieren nur innerhalb einer Task.
+
+ Tasks werden durch den SUPERVISOR verwaltet, er regelt den Zugriff auf Tasks.
+ Um Ihre Task zu verlassen, geben Sie das Kommando 'break' an den
+ SUPERVISOR, um sie wieder zu betreten, das Kommando 'continue ("taskna­
+ me")'.
+
+
+- #on("b")#DATEI#off("b")#. Eine #ib#Datei#ie# ist eine Menge von zusammengehörigen Daten. Eine Datei in
+ einer Task entspricht einer Akte in einem Arbeitszimmer. Eine Task kann bis zu
+ 200 Dateien enthalten. Jede Datei in einer Task hat einen eigenen Namen, in ver­
+ schiedenen Tasks dürfen gleichnamige Dateien existieren. Eine Datei ist in Zeilen
+ unterteilt.
+
+ Für die Arbeit in einer Datei am Bildschirm muß auf die Datei mit dem Editor
+ zugegriffen werden: 'edit ("dateiname")', danach kann der Inhalt der Datei am
+ Terminal bearbeitet werden (siehe Kapitel 4 und 5).
+
+
+- #on("b")#KOMMANDO#off("b")#. Ein #ib#Kommando#ie# ist ein Befehl an den Rechner, eine Arbeit zu tun.
+ Welche Kommandos Sie dem Rechner zum jeweiligen Zeitpunkt geben können,
+ hängt davon ab, auf welcher 'Kommandoebene' Sie sich befinden. Als Anhalt gilt:
+
+ - Kommandos auf Supervisor-Ebene betreffen das Tasksystem.
+
+ - Kommandos auf Monitor-Ebene betreffen die eigene Task oder Dateien.
+
+ - Kommandos auf Editor- Ebene betreffen Zeilen, Worte oder einzelne Zeichen
+ der aktuellen Datei.
+
+ Auf welcher Ebene Sie sich befinden, werden Sie nach kurzer Gewöhnung leicht
+ am Bildschirm erkennen (siehe Teil 3).
+
+ Bei manchen Kommandos muß nicht nur gesagt werden, was getan werden soll,
+ sondern auch, womit es getan werden soll. Eine solche Angabe zum Kommando
+ heißt #ib#Parameter#ie#.
+ Kommando Parameter
+ | |
+ Beispiel: Lege neue Task an = begin ("taskname")
+ Drucke Datei = print ("dateiname").
+ Suche das Wort ENDE = down ("ENDE")
+
+ Parameter werden in runde Klammern gesetzt und ggf. durch Kommata voneinan­
+ der getrennt. Textparameter werden zusätzlich in Anführungsstriche gesetzt.
+
+ Ein Kommando kann keinen, einen oder viele Parameter benötigen; die
+ Beschreibung der Kommandos in diesem Buch zeigt jeweils alle Möglichkeiten.
+
+
+- #on("b")#SUPERVISOR#off("b")#. Spezielle Task zur Überwachung eines EUMEL-Systems. Ein
+ Benutzer kann durch die #ib#Supervisor#ie#-Kommandos Leistungen von dieser Task
+ fordern: neue Task einrichten, Task wiederaufnehmen und diverse Informationen.
+
+
+- #on("b")#MONITOR#off("b")#. Befehlsempfänger in einer Task. Jede Arbeit im EUMEL-System
+ findet in einer Task statt. Die Arbeit mit einem Computer besteht in wesentlichen
+ Teilen im Aufruf von Programmen durch Kommandos. Der Empfänger dieser
+ Kommandos in einer Task ist der #ib#Monitor#ie#. Der Monitor ist sichtbar durch eine
+ Zeile, in der 'gib kommando' steht. In diese Zeile werden #ib#Kommando#ie#s und erfor­
+ derliche Parameter eingegeben.
+
+
+- #on("b")#ARCHIVE#off("b")#. Spezielle Task zur Verwaltung des Diskettenlaufwerks. Da für die
+ längerfristige Datenhaltung und zur zusätzlichen Datensicherung Dateien auf
+ Disketten geschrieben werden, besitzt das EUMEL-System für diese Aufgabe
+ eine besondere Task, die die Bedienung vereinfacht und exklusiven Zugriff auf das
+ Laufwerk garantiert.
+
+
+- #on("b")#EDITOR#off("b")#. Programm zur Dateibearbeitung am Bildschirm. Das Programm wird
+ durch das ( Monitor- ) Kommando 'edit' und die Eingabe des Namens der ge­
+ wünschten Datei als Parameter gestartet.
+
+ Da ein Bildschirm normelerweise auf 80 Zeichen Zeilenbreite und 24 Zeilen be­
+ schränkt ist, kann der Editor als Fenster betrachtet werden, das über die mögli­
+ cherweise weitaus größere Datei bewegt wird und durch das der betrachtete Aus­
+ schnitt der Datei bearbeitet werden kann.
+
+
+ +-------------------------------------------------------------------+
+ i i
+ i i
+ +------------------------------------+ i
+ i i i
+ i Der Editor, Fenster zur i i
+ i Dateibearbeitung i i
+ i i i
+ +------------------------------------+ i
+ i i
+ +-------------------------------------------------------------------+
+
+
+
+
+
+
+
+
+
+
+1.3. Die Notation in diesem Buch
+#free(1.0)#
+Im weiteren Text werden Sie schrittweise in die Bedienung des Systems eingeführt.
+Für alle Kommandos und Arbeiten haben wir Beispiele in dieses Buch aufgenommen,
+die Sie direkt am Rechner nachvollziehen sollten.
+
+Beachten Sie dabei bitte folgende Regeln der Aufschreibung:
+
+- Es gibt eine Reihe von Tasten auf einer Computertastatur, die eine besondere
+ Bedeutung haben. Diese sogenannten Funktionstasten werden ebenso wie beson­
+ dere Tastenkombinationen explizit als Tasten dargestellt:
+
+
+ <SV>
+
+ <ESC> <e>
+
+ <CR>
+
+
+- Alles, was Sie am Bildschirm Ihres Rechners schreiben oder lesen sollen, ist in
+ Textbereiche, die einen Bildschirm darstellen, eingefaßt.
+
+ Beispiel:
+
+____________________________________________________________________________
+
+gib kommando:
+edit ("meine datei")
+
+____________________________________________________________________________
+
+
+- Innerhalb des Handbuchs sind in der Aufschreibung die Konventionen der
+ Programmiersprache ELAN, in der alle Programme des Betriebssystems geschrie­
+ ben sind, berücksichtigt. Dabei sind folgende Besonderheiten zu beachten:
+
+ 1) Kommandos werden grundsätzlich klein geschrieben.
+
+ 2) Dateinamen u.ä. werden in Klammern und Anführungsstriche gesetzt. In
+ diesem Buch steht an den Stellen, wo ein Dateiname auftaucht #on("i")# 'dateiname' #off("i")#;
+ den Namen, den Sie tatsächlich verwenden, können Sie frei wählen.
+
+ 3) Falls besondere Begriffe oder Beispiele innerhalb eines normalen Textes
+ auftreten, werden sie in einfache Anführungsstriche gesetzt.
+
+
+Also: Das Kommando 'edit' benötigt als Parameter einen Dateinamen. Wählen Sie
+ einen Namen und geben Sie 'edit ("dateiname")' ein. Falls Sie den Namen #on("i")#
+ "Geschäftsbrief" #off("i")# gewählt haben, müssen Sie am Bildschirm:
+
+
+edit ("Geschäftsbrief")
+
+
+tippen und das Kommando mit der <CR> Taste dem Monitor zur Bearbeitung überge­
+ben:
+
+____________________________________________________________________________
+
+gib kommando :
+edit ("Geschäftsbrief")
+
+____________________________________________________________________________
+
+
+
+
+#on("b")##on("i")#Die Eingabe von <CR> als 'Auslöser' für die Ausführung von
+Kommandos wird im weiteren nicht besonders hervorgehoben.#off("b")##off("i")#
+#page#
+1.4. Voraussetzungen
+
+#free(1.0)#
+Neben dem Computer an sich ist die vollständige Installation eines EUMEL-Systems
+auf diesem Computer Voraussetzung für alle im folgenden beschriebenen Aktivitäten.
+
+Die Beschreibung einer Systeminstallation finden Sie im Anhang I. Im weiteren gehen
+wir davon aus, daß Ihr Rechner sich in einem Zustand befindet, der durch Eingabe
+von <SV> oder <CNTL> <b> (gleichzeitig) die sogenannte EUMEL-Tapete zeigt und
+Supervisor-Kommandos annimmt.
+
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8/M
+
+
+ gib supervisor kommando:
+ begin("meine erste task")
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+
+____________________________________________________________________________
+
+
+
+Weiterführende Information zum Aufbau eines EUMEL-Systems finden Sie im An­
+hang I.
+
+#page#
+Die Funktionstasten des EUMEL-Systems
+
+
+
+Die Lage der EUMEL-Funktionstasten entnehmen Sie bitte der speziellen Installa­
+tionsanleitung zu dem von Ihnen benutzten Gerät. #l pos (0.0)##l pos(4.0)#
+
+
+<,>,v,^ Positionierungstasten
+#table#
+#free(0.5)#
+<SHIFT> Umschalttaste
+#free(0.5)#
+<CR> Eingabe-/ Absatztaste
+#free(0.5)#
+<HOP> Verstärkertaste
+#free(0.5)#
+<RUBOUT> Löschtaste
+#free(0.5)#
+<RUBIN> Einfügetaste
+#free(0.5)#
+<TAB> Tabulatortaste
+#free(0.5)#
+<MARK> Markiertaste
+#free(0.5)#
+<ESC> Kommandotaste
+#free(0.5)#
+<SV> Supervisortaste
+#free(0.5)#
+<STOP> Stoptaste
+#free(0.5)#
+<WEITER> Weitertaste
+#tableend##clear pos#
+
+Task-Organisation
+#free(1.0)#
+
+Zum Verständnis der Handhabung des Systems sollten Sie versuchen, eine Vorstel­
+lung von der Organisation der Teile zu bekommen.
+
+Die einzelnen #ib#Task#ie#s eines EUMEL-Systems 'stehen nicht frei im Raum', sondern
+sind in einer baumartigen Beziehung organisiert:
+
+
+
+SUPERVISOR
+ -
+ SYSUR
+ configurator
+ OPERATOR
+
+ ARCHIVE
+UR
+ PUBLIC
+ Meyer
+ Müller
+ Schulze
+
+
+
+Das System besteht aus zwei Zweigen, die nebeneinander liegen:
+
+Dem Systemzweig mit der Wurzel SUPERVISOR
+
+ und
+
+dem Benutzerzweig mit der Wurzel UR.
+
+Der Systemzweig stellt Ihnen privilegierte Dienstleistungen zur Verfügung, der Benut­
+zerzweig stellt die normale Arbeitsumgebung dar.
+
+Alle unter diesen Wurzeln liegenden Tasks des EUMEL-Systems haben mindestens
+einen Vorgänger, es besteht also eine 'Vater-Sohn Beziehung' zwischen allen Tasks
+des Systems.
+
+Grundsätzlich können Dateien ohne besondere Kommandos zur Vater-Task geschickt
+und von der Vater-Task geholt werden, aber nicht zu beliebigen anderen Tasks.
+
+'Müller' kann eine Datei an '#ib#PUBLIC#ie#' schicken und 'Schulze' kann sie dann dort
+abholen, aber eine direkte Sendung von 'Müller' nach 'Schulze' ist in der Regel nicht
+möglich.
+
+Zur Sprechweise: jede Task, über die diese Art von 'Dateivermittlung' abgewickelt
+werden kann, heißt 'Manager-Task'. Jede Task kann zum '#ib#Manager#ie#' erklärt werden.
+1.5. Eine Beispielsitzung
+#free(1.0)#
+Der Ablauf zur Erstellung eines Schreibens stellt sich im EUMEL-System wie folgt
+dar:
+
+ <SV> SUPERVISOR aufrufen
+
+
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8/M
+
+
+ gib supervisor kommando:
+ begin("meine erste task")
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+
+____________________________________________________________________________
+
+
+Durch das Kommando 'begin ("meine erste task")', welches durch <CR> abgeschlos­
+sen werden muß, wird eine Task mit dem Namen 'meine erste task' im Benutzer­
+zweig, also unterhalb von 'PUBLIC' angelegt. Würde diese Task bereits existieren, so
+könnten Sie sie mit 'continue ("meine erste task")' an das Terminal holen.
+
+____________________________________________________________________________
+
+gib kommando :
+edit ("Rechnung zum 31.12.86")
+
+____________________________________________________________________________
+
+
+In der Task eröffnen Sie eine Datei mit dem Kommando 'edit ("dateiname")'. Falls
+diese Datei neu ist, erfolgt eine Kontrollfrage (zur Kontrolle der gewünschten Schreib­
+weise des Dateinamens), die Sie durch <j> bejahen.
+
+Die Datei ist in diesem Beispiel bereits mit etwas Text gefüllt. Tippen Sie einen belie­
+bigen Text ein und beenden Sie die Bearbeitung dieser ersten Datei durch Drücken
+der Tasten <ESC> <q> (nacheinander!).
+
+
+____________________________________________________________________________
+.................... Rechnung zum 31.12.86 ...................... Zeile 1
+ G M D
+ Sankt Augustin
+ Schloß Birlinghoven
+
+Sehr geehrte Damen und Herren,
+>
+
+
+____________________________________________________________________________
+
+
+
+
+Um die Arbeit in der Task zu beenden, geben Sie auch an dieser Stelle <ESC> <q>
+(nacheinander!) ein.
+
+Nach Verlassen der Task ist wiederum die EUMEL-Tapete auf dem Bildschirm. Jede
+weitere Aktion wird wiederum von hier aus durch <SV> begonnen. Insbesondere zum
+#ib#Ausschalten des Geräts#ie# muß nach <SV> die Task '#ib#shutup#ie#' angestoßen werden (siehe
+auch Anhang I).
+
diff --git a/doc/user/benutzerhandbuch.2 b/doc/user/benutzerhandbuch.2
new file mode 100644
index 0000000..0153fae
--- /dev/null
+++ b/doc/user/benutzerhandbuch.2
@@ -0,0 +1,443 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 2: Der Supervisor
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+2 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 2 - %
+#tableend##clearpos#
+#end#
+
+TEIL 2: Der Supervisor
+#free(1.0)#
+
+#ib(9)#2.1. Steuerkommandos#ie(9)#
+#free(1.0)#
+
+Jegliche Aktivität im EUMEL-System beginnt mit dem Aufruf des SUPERVISOR
+durch Drücken der Taste
+
+ <SV>
+
+
+Dieser Tastendruck koppelt Ihr Terminal an den Rechner an. Dieser Vorgang ist auch
+dann nötig, wenn diese Geräte praktisch eine Einheit bilden.
+
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8/M
+
+
+ gib supervisor kommando:
+
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+
+____________________________________________________________________________
+
+
+Die auf den unteren Informationszeilen angezeigten Kommandos stehen nun zur
+Auswahl. Für alle diese Kommandos gilt, daß sie entweder durch zwei aufeinander­
+folgende Tastendrücke <ESC> und Kennzeichen oder auch durch vollständiges Eintip­
+pen eingegeben werden können und mit <CR> ausgelöst werden.
+
+Die Eingabe eines falschen Zeichens nach <ESC> oder eines falschen Kommandos
+wird abgewiesen. Die Eingabe ist dann zu wiederholen.
+
+
+Bedeutung der Kommandos:
+
+#on("b")#
+1) Steuerkommandos #off("b")#
+
+ #ib#ESC b#ie# #ib#begin#ie# ("taskname") Task einrichten.
+ #ib#ESC c#ie# #ib#continue#ie# ("taskname") Task wieder ankoppeln.
+ #ib#ESC q#ie# #ib#break#ie# Terminal abkoppeln.
+ #ib#ESC h#ie# #ib#halt#ie# Programmlauf abbrechen.
+
+
+
+#on("b")#
+2) Informationskommandos#off("b")# (nur Supervisor)
+
+ #ib#ESC ?#ie# #ib#help#ie# Information.
+ #ib#ESC s#ie# #ib#storage info#ie# Belegten Speicherplatz anzeigen.
+ #ib#ESC t#ie# #ib#task info#ie# Im System befindliche Tasks anzeigen.
+
+#page#
+2.2. Eine Task einrichten
+#free(1.0)#
+
+
+ Mit dem Kommando 'begin' wird eine neue Task eingerichtet.
+
+
+#free(1.0)#
+
+Zunächst koppeln Sie Terminal und Rechner, dann legen Sie eine neue Task an.
+
+ Terminal ankoppeln: <SV>
+
+ <ESC> <b>
+
+Die Tastenkombination 'ESC b' schaltet den Einfügemodus ein und positioniert
+den Cursor passend für die Eingabe des Tasknamens.
+
+____________________________________________________________________________
+
+gib supervisor kommando :
+begin ("")
+
+____________________________________________________________________________
+
+
+
+Dateinamen eintippen:
+
+____________________________________________________________________________
+
+ gib supervisor kommando:
+ begin ("taskname")
+
+____________________________________________________________________________
+
+
+Nachdem Sie den Namen eingegeben haben, betätigen Sie die <CR> Taste. Daraufhin
+meldet sich der Monitor der neuen Task und Sie können beliebige Monitor-
+Kommandos (siehe Teil 3) eingeben.
+
+Wird eine Task in dieser geschilderten Weise neu eingerichtet, so wird sie automa­
+tisch (von der Task SUPERVISOR) als Sohn der Task PUBLIC angelegt.
+
+
+Soll eine Task nicht als Sohn von PUBLIC, sondern als Sohn einer anderen Task
+angelegt werden, so ist das Kommando 'begin' mit zwei Parametern zu geben. Die
+neue Task wird dann als Sohn einer anderen Manager-Task angelegt (siehe Teil 3).
+
+
+____________________________________________________________________________
+
+ gib supervisor kommando:
+ begin ("taskname","name der vatertask")
+
+____________________________________________________________________________
+
+
+
+ACHTUNG: Die Task, die als Vater-Task angegeben wird, muß
+ eine Manager-Task sein, sonst passiert überhaupt nichts!
+ (s. Kap. 3.1.2.)
+
+#page#
+Task wiederankoppeln
+#free(1.0)#
+
+
+ Mit dem Kommando 'continue' wird eine existierende Task an das
+ Terminal angekoppelt.
+
+
+#free(1.0)#
+
+Wenn Sie die Arbeit in einer Task wiederaufnehmen wollen, holen Sie die Task mit
+dem Kommando 'continue' an das Terminal. Dieser Vorgang ähnelt dem Einrichten
+einer neuen Task:
+
+ Terminal ankoppeln: <SV>
+
+ <ESC> <c>
+
+Die Tastenkombination 'ESC c' schaltet den den Einfügemodus ein und positioniert
+den Cursor passend für die Eingabe des Tasknamens.
+
+
+____________________________________________________________________________
+
+ gib supervisor kommando:
+ continue ("taskname")
+
+____________________________________________________________________________
+
+
+Nach dieser Eingabe finden Sie die wiederaufgenommene Task so vor, wie Sie sie
+verlassen haben.
+
+#page#
+Terminal abkoppeln
+#free(1.0)#
+
+
+ Mit dem Kommando 'break' wird das Terminal vom Rechner abgekoppelt.
+
+
+#free(1.0)#
+
+Wenn Sie beispielsweise nach einem Informationskommando (siehe Teil 2.3.ff) das
+Terminal sofort vom Rechner abkoppeln möchten, geben Sie das 'break'-Kommando.
+Nach 'storage info' geht es jedoch nur mit <SV> weiter.
+
+____________________________________________________________________________
+
+ gib supervisor kommando:
+ break
+
+____________________________________________________________________________
+
+
+Nach dieser Eingabe ist das Terminal abgekoppelt. Jede neue Aktivität ist wiederum
+mit <SV> einzuleiten.
+#page#
+Laufendes Programm stoppen
+#free(1.0)#
+
+
+ Mit dem Kommando 'halt' wird ein Programm gestoppt, das am betreffenden Termi­
+ nal läuft.
+
+
+#free(1.0)#
+
+Dieses Kommando ist in besonderen Fehlersituationen von Wichtigkeit. Falls Sie ein
+Programm abbrechen wollen, aber keine regulären Eingaben am Bildschirm mehr
+möglich sind, so geben Sie zunächst <SV> ein.
+
+Sobald der Supervisor-Bildschirm erscheint, drücken Sie die Tasten
+
+#center# <ESC> <h> (oder tippen 'halt' und drücken 'CR').
+
+____________________________________________________________________________
+
+ gib supervisor kommando:
+ halt
+
+____________________________________________________________________________
+
+
+Nach dieser Eingabe wird das an diesem Terminal laufende Programm unterbrochen.
+Nach dem Abbruch kommen Sie wieder auf die Monitor-Ebene (s. Teil 3).
+#page#
+2.3. Informationskommandos
+#free(1.0)#
+
+
+ Mit den Informationskommandos können Informationen zum System abgerufen
+ werden.
+
+#free(1.0)#
+
+Die folgenden Informationskommandos können direkt an den SUPERVISOR gegeben
+werden.
+
+ Terminal ankoppeln: <SV>
+
+ <ESC> <s>
+
+
+beziehungsweise
+
+____________________________________________________________________________
+
+ gib supervisor kommando :
+ storage info
+
+____________________________________________________________________________
+
+
+gibt Auskunft über den belegten Speicherplatz auf dem EUMEL-Hintergrundspeicher.
+
+Das Kommando:
+
+
+____________________________________________________________________________
+
+ gib supervisor kommando :
+ task info
+
+____________________________________________________________________________
+
+
+gibt Auskunft über die Namen der im EUMEL-System befindlichen Tasks und die
+Struktur des Taskbaums. Verzweigungen im Taskbaum sind durch Einrückungen in
+den Ebenen des Taskbaums dargestellt.
+
+
+Alle in dem Schema der Task-Organisation (siehe Teil 1) fettgedruckten Tasks sind
+auch auf jedem Multi-User-Sysrtem zu finden, da sie zum Betrieb nötig sind.
+
+Die unterhalb von PUBLIC gelegenen Tasks werden, falls überhaupt schon vorhan­
+den, häufig nach ihrem 'Besitzer' oder der in ihnen erledigten Arbeit benannt sein.
+
+#page#
+2.4. Übersicht über Supervisor-Kommandos
+#free(1.0)#
+
+
+ In diesem Abschnitt werden alle Supervisor- und Task-Kommandos in der
+ ELAN-Notation dargestellt.
+
+#free(1.0)#
+
+Die Supervisor-Kommandos entsprechen - wie alle anderen Kommandos im
+EUMEL-System - der ELAN-Syntax (Kommando-Namen werden klein geschrie­
+ben, Parameter in Klammern, mehrere Parameter durch Kommata getrennt, TEXT-
+Parameter in Anführungsstrichen usw.).
+#free(1.0)#
+Die ELAN-Notation
+#free(1.0)#
+
+Diese Notation dient der präzisen Beschreibung von Konstrukten der Programmier­
+sprache ELAN. Im Anschluß an die teilweise eher informelle Formulierung innerhalb
+des Kapitels folgt jedem Teil eine Kurzbeschreibung der zu diesem Themenkreis
+gehörigen Konstrukte.
+
+Eine solche Beschreibung hat z.B. die Form:
+
+ PROC edit (TEXT CONST dateiname)
+
+Die klein geschriebenen Benennungen von Prozeduren, Parametern etc. sind hoffent­
+lich selbsterklärend, die groß geschriebenen Begriffe sind sogenannte Schlüsselworte
+und haben folgende Bedeutung:
+
+OP Operator
+ Ein Operator bewirkt eine elementare Operation. Operatoren werden stets
+ durch Großbuchstaben oder Sonderzeichen dargestellt.
+
+ Beispiel: + ( Addition zweier Zahlen)
+
+
+PROC Prozedur
+ Programm, welches unter seinem Namen aufrufbar ist, ggf. unter Anfügung
+ von Parametern. <CR> beendet die Eingabe und läßt das Programm ablaufen.
+
+ Beispiel: 'edit ("dateiname")'
+
+
+CONST Konstante
+ Unveränderbarer Wert.
+
+
+VAR Variable
+ Veränderbarer Wert.
+
+
+BOOL Wahrheitswert
+ Typ, der nur die Werte TRUE oder FALSE annnehmen kann.
+
+
+TEXT Text
+ Typ, der alle Buchstaben, Sonderzeichen, aber auch Ziffern umfaßt. Eine
+ TEXT CONST ist somit eine sogenannte Zeichenkette:
+
+ "meine datei"
+ "$abc123(XYZ)"
+ "abrechnung vom 30.09.86"
+
+
+ Eine im Editor erstellte Datei besteht ausschließlich aus TEXTen. Ein Text
+ wird in Anführungszeichen " " eingeschlossen.
+
+
+INT Integer
+ Ganze Zahl. Ein INT CONST ist also irgendeine ganze Zahl. Falls beschrie­
+ ben ist: 'INT CONST zeilennr', so ist gemeint, daß an dieser Stelle die Zeilen­
+ nummer der gewünschten Zeile der Datei anzugeben ist, also '25' oder '999'.
+
+
+REAL Real
+ Reelle Zahl. Eine REAL CONST bezeichnet eine Zahl mit Dezimalpunkt.
+
+ PROC sin (REAL CONST x) => sin (0.5)
+
+
+
+TASK Task
+ Eine TASK CONST bezeichnet eine existierende Task durch einen internen
+ Task-Bezeichner.
+
+
+
+THESAURUS
+ Ein THESAURUS ist eine Liste von Namen, z.B. eine Liste von Dateinamen.
+
+
+
+#page#
+Folgende Supervisor-Kommandos stehen zur Verfügung:
+
+
+#sy("begin
+ PROC begin (TEXT CONST task name)
+ Richtet eine neue Task als Sohn von PUBLIC ein.
+
+ PROC begin (TEXT CONST task name, father task name)
+ Richtet eine neue Task als Sohn der 'fathertaskname'-Task ein.
+
+
+break
+ PROC break
+ Das Terminal wird vom Rechner abgekoppelt.
+
+
+continue
+ PROC continue (TEXT CONST task name)
+ Eine existierende Task wird an das Terminal des Benutzers angekoppelt.
+
+halt
+ PROC halt
+ Das laufende Programm der dem Terminal aktuell zugeordneten Task wird
+ abgebrochen. Natürlich wird die Task nicht gelöscht.
+
+ Genauer:
+ Es wird der Fehler 'halt from terminal' induziert. Normalerweise wird das
+ Programm dadurch wie durch jeden anderen Fehler abgebrochen. Genaueres
+ findet man im Systemhandbuch unter Fehlerbehandlung.
+
+storage info
+ PROC storage info
+ Informationsprozedur über den Hintergrund-Speicher.
+
+task info
+ PROC task info
+ Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der
+ Vater/Sohn-Beziehungen durch Einrückungen.
+
diff --git a/doc/user/benutzerhandbuch.3 b/doc/user/benutzerhandbuch.3
new file mode 100644
index 0000000..eb1c762
--- /dev/null
+++ b/doc/user/benutzerhandbuch.3
@@ -0,0 +1,2019 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 3: Der Monitor
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+3 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 3 - %
+#tableend##clearpos#
+#end#
+
+TEIL 3: Der Monitor
+#free(1.0)#
+#ib(9)#3.1. Der Monitor#ie(9)#
+#free(1.0)#
+
+
+ Der Monitor nimmt die Kommandos des Benutzers entgegen, die dieser innerhalb
+ seiner Task gibt. In diesem Kapitel sind die gebräuchlichen Kommandos zur Text­
+ verarbeitung beschrieben.
+
+
+#free(1.0)#
+
+Der #ib#Monitor#ie# ist der Empfänger der Kommandos in einer EUMEL-Task. Jede Task
+und somit jeder aktive Benutzer eines EUMEL-Systems verfügt über einen eigenen
+Monitor. Halten Sie sich an dieser Stelle vor Augen:
+#on("i")##on("b")#
+
+
+Der SUPERVISOR ist die Task, die die Aufsicht über
+alle weiteren Tasks des EUMEL-Systems hat.
+
+Der Monitor ist der Befehlsempfänger in Ihrer Task.
+Jede Task hat einen Monitor.
+
+#goalpage("Mon-kdo")#
+Der Monitor in Ihrer Task macht sich direkt bemerkbar durch die Zeile:
+
+____________________________________________________________________________
+
+#ib#gib kommando#ie# :
+____________________________________________________________________________
+
+
+Die Kommandos der Monitor-Ebene, die Sie an dieser Stelle eingeben können,
+lassen sich in Gruppen ordnen:
+#on("b")#
+
+
+Informationskommandos #off("b")#
+
+ #ib#storage info#ie# Belegten Speicherplatz anzeigen.
+ #ib#task info#ie# Im System befindliche Tasks anzeigen.
+ #ib#task status#ie# Zustand der Task anzeigen.
+
+
+#on("b")#
+Kommandos zur Tasksteuerung #off("b")#
+
+ #ib#break#ie# Task abkoppeln.
+ #ib#end#ie# Task löschen.
+ #ib#global manager#ie# Task zum Manager machen, d.h.
+ Sohn-Tasks können eingerichtet
+ werden.
+
+
+#on("b")#
+Kommandos zur Dateibearbeitung #off("b")#
+
+ #ib#copy#ie# ("dateiname","kopie") Datei kopieren.
+ #ib#edit#ie# ("dateiname") Editor aufrufen.
+ #ib#forget#ie# ("dateiname") Datei löschen.
+ #ib#list#ie# Dateien auflisten.
+ #ib#rename#ie# ("dateiname","neu") Datei umbenennen.
+
+#on("b")#
+Transport von Dateien#off("b")#
+
+ #ib#fetch#ie# ("dateiname") Datei von Vater-Task holen.
+ #ib#erase#ie# ("dateiname") Datei in Vater-Task löschen.
+ #ib#save#ie# ("dateiname") Datei zu Vater-Task senden.
+
+
+#on("b")#
+Archiv-Kommandos#off("b")#
+
+ #ib#archive#ie# ("name") Archivlaufwerk reservieren.
+ #ib#fetch#ie# ("dateiname",archive) Datei von Archiv holen.
+ #ib#save#ie# ("dateiname",archive) Datei auf Archiv schreiben.
+ #ib#list (archive)#ie# Inhalt des Archivs listen.
+ #ib#check#ie# ("dateiname",archive) Datei auf Lesbarkeit prüfen.
+ #ib#clear#ie# (archive) Archiv löschen/umbenennen.
+ #ib#format (archive)#ie# Archivdiskette für Benutzung
+ vorbereiten.
+
+#on("b")#
+Textverarbeitung #off("b")#
+
+ #ib#list fonts#ie# Nennt die eingestellten
+ Schrifttypen.
+ #ib#fonttable#ie# Stellt die gewünschte Fonttabelle ein.
+ #ib#lineform#ie# ("dateiname") Zeilenweise formatieren.
+ #ib#autoform#ie# ("dateiname") Automatische Zeilenformatierung.
+ #ib#pageform#ie# ("dateiname") Seitenweise formatieren.
+ #ib#autopageform#ie# ("dateiname") Automatische Seitenformatierung.
+ #ib#index#ie# ("dateiname.p") Stichwortverzeichnis erzeugen.
+ #ib#outline#ie# ("dateiname") Übersicht bzw. Kurzfassung eines
+ Textes erstellen.
+ #ib#print#ie# ("dateiname") Datei drucken.
+
+
+
+#on("b")#
+Passwortschutz #off("b")#
+
+ #ib#task password#ie# ("geheim") Passwort für existierende Task festlegen.
+ #ib#begin password#ie# ("geheim") Passwort für neue Task festlegen.
+ #ib#family password#ie# ("geheim") Passwort für mehrere Tasks
+ festlegen.
+ #ib#enter password#ie# ("geheim") Passwort für Datei festlegen.
+
+#page#
+3.1.1. Informationskommandos
+#free(1.0)#
+
+
+ Mit den Informationskommandos können Informationen zur eigenen Task bzw. zum
+ gesamten System abgerufen werden.
+
+#free(0.5)#
+
+Bereits von Teil 2 bekannt sind die Informationskommandos 'ESC s' und 'ESC t'. Auf
+der Monitor-Ebene ist die abkürzende Schreibweise nicht voreingestellt.
+
+____________________________________________________________________________
+
+gib kommando :
+storage info
+
+____________________________________________________________________________
+
+
+gibt Auskunft über den belegten Speicherplatz auf dem EUMEL-Hintergrundspeicher.
+
+____________________________________________________________________________
+
+gib kommando :
+task info
+
+____________________________________________________________________________
+
+
+gibt Auskunft über die Namen der im EUMEL-System befindlichen Tasks und die
+Struktur des Taskbaums.
+#page#
+Auf Monitor-Ebene kann durch zusätzliche Angabe einer Zahl zwischen 1 und 3
+Zusatzinformation angefordert werden.
+
+____________________________________________________________________________
+
+gib kommando :
+task info (2)
+
+____________________________________________________________________________
+
+liefert:
+
+____________________________________________________________________________
+26.11.86 10:10 CPU PRIO CHAN STATUS
+SUPERVISOR........................... 0001:08:50 0 - wait
+ -................................ 0000:00:08 0 2 i/o
+ -................................ 0000:01:45 0 - wait
+ SYSUR............................ 0000:01:48 0 - wait
+ configurator................. 0000:00:43 0 - wait
+ OPERATOR..................... 0000:00:03 0 - i/o
+ shutup dialog............ 0000:03:08 0 - i/o
+ ARCHIVE...................... 0000:03:03 0 31 wait
+UR................................... 0000:00:43 0 - wait
+ PUBLIC........................... 0000:01:26 0 - i/o
+ agfa......................... 0000:00:11 0 - i/o
+ werner....................... 0000:06:00 0 - -busy-
+
+
+____________________________________________________________________________
+
+
+
+
+'task info (1)' entspricht dabei dem Kommando ohne Parameterangabe, '(2)' liefert
+zusätzlich die verbrauchte CPU-Zeit (=reine Rechenzeit), die Priorität, den Kanal
+(siehe S.#topage("Kanal")#) und den Taskstatus für jede Task des Systems. '(3)' liefert neben diesen
+Angaben auch noch den belegten Speicherplatz jeder Task. Die Ausführung von task
+info (3) ist sehr zeitaufwendig!
+
+Um insbesondere den belegten Speicherplatz der eigenen Task anzusehen, aber auch
+die übrigen der oben erwähnten Angaben, benutzt man das Kommando:
+
+____________________________________________________________________________
+
+ gib kommando :
+ task status
+
+24.12.86 18:30 TASK: wenni
+
+Speicher: 1000K
+CPU-Zeit: 0000.01:11
+Zustand : -busy-, (Prio 1), Kanal 1
+
+ gib kommando :
+
+____________________________________________________________________________
+#page#
+3.2. Tasksteuerung
+#free(1.0)#
+Task abkoppeln
+#free(1.0)#
+
+
+ Mit dem Kommando 'break' wird eine Task vom Terminal abgekoppelt.
+
+
+#free(1.0)#
+
+Durch die Eingabe des Kommandos 'break' auf Monitor-Ebene wird die Task vom
+Terminal abgekoppelt. Dieses Kommando bewirkt ansonsten keine Veränderungen.
+
+____________________________________________________________________________
+
+gib kommando :
+break
+
+____________________________________________________________________________
+
+
+
+Statt 'break' einzutippen, können Sie auch die Tastenkombination
+
+#center#<ESC> <q>
+
+benutzen.
+
+#page#
+
+Eine Manager-Task erzeugen
+#free(1.0)#
+
+
+ Eine Task kann zum #ib#Manager#ie#, d.h. zum Kommunikationspartner anderer Tasks,
+ erklärt werden. Insbesondere zwischen Manager-Tasks und anderen, die
+ zueinander in Vater-Sohn-Beziehung stehen, ist ein einfacher Dateitransfer
+ möglich (siehe S.#topage("Dateitrans")#).
+
+#free(1.0)#
+
+Normalerweise werden Benutzertasks als Sohn der Task PUBLIC eingerichtet. Es
+kann jedoch wünschenswert sein, selbst eine Task-Hierarchie aufzubauen und eine
+vorhandene Task zum Vater einer oder mehrerer in Zukunft einzurichtender Tasks zu
+machen, um somit auch eine Dateihierarchie mit den benötigten Operationen zu
+erhalten. Dazu wird diese Task zum 'Manager' erklärt:#goalpage("globalmanager")#
+
+____________________________________________________________________________
+
+gib kommando:
+global manager
+
+____________________________________________________________________________
+
+
+Durch das '#ib#global manager#ie#'-Kommando wird implizit ein 'break'-Kommando gege­
+ben, so daß Sie nach Eingabe dieses Kommandos wieder ein Supervisor-Kommando
+geben können. Wenn Sie nun zu irgendeinem Zeitpunkt diese (zunächst potentielle)
+Vater-Task wieder ankoppeln ('continue'-Kommando), meldet sich die Task nicht
+wie gewohnt mit 'gib kommando :', sondern mit:
+
+____________________________________________________________________________
+
+maintenance :
+
+____________________________________________________________________________
+
+
+um anzudeuten, daß es sich um eine Manager-Task handelt.
+
+Um eine Sohn-Task unterhalb einer Manager-Task einzurichten, wird zur Erzeu­
+gung dieser neuen Task nicht nur der gewünschte Name, sondern auch der Name der
+Vater-Task angegeben.#u#1)#e#
+#foot#
+#u#1)#e# Falls keine Vater-Task angegeben wird, so ist die neue Task Sohn der
+Manager-Task 'PUBLIC'.
+#end#
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8/M
+
+
+ gib supervisor kommando:
+ begin("sohntask","vatertask")
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+
+____________________________________________________________________________
+
+
+
+
+In dieser Sohn-Task können dann mit einfachen Kommandos Dateien von der
+Vater-Task geholt und zur Vater-Task geschickt werden.
+
+Soll eine Task für alle anderen Tasks, nicht nur für Sohn-Tasks, des Gesamtsystems
+als Kommunikationspartner erreichbar sein, so muß diese Task als freier Manager
+deklariert werden:
+
+____________________________________________________________________________
+
+gib kommando:
+#ib#free global manager#ie#
+
+____________________________________________________________________________
+
+
+Auf eine solche Task kann von #on("u")#jeder#off("u")# anderen Task aus zugegriffen werden, ansonsten
+gilt das für gewöhnliche Manager-Tasks gesagte.
+#page#
+Task löschen
+#free(1.0)#
+
+
+ Eine Task kann mit dem '#ib#end#ie#' Kommando gelöscht werden (und mit ihr alle Daten).
+
+ #free(0.5)#
+Normale Benutzertasks werden meistens zweck- oder themengebunden eingerichtet.
+Sind die Aufgaben im Zusammenhang mit einer solchen Task erledigt, so sollte die
+Task gelöscht werden, nachdem alle Daten von Bedeutung auf Diskette gesichert
+wurden.
+
+____________________________________________________________________________
+
+gib kommando :
+end
+
+____________________________________________________________________________
+
+Wie bei allen Löschungen im EUMEL-System folgt eine Kontrollfrage durch den
+Monitor:
+
+____________________________________________________________________________
+
+gib kommando :
+end
+task "taskname" löschen (j/n) ?
+
+
+____________________________________________________________________________
+
+
+Nur bei der positiven Antwort wird gelöscht, alle Dateien sind unwiderruflich verlo­
+ren. Als positive Antwort auf derartige Abfragen wirken:
+
+#center#<j> <J> <y> <Y>
+
+<n> bzw. <N> unterdrücken die angebotene Aktion, andere Eingaben werden abgewie­
+sen.
+
+#on("b")#
+ACHTUNG: Wird eine Manager-Task gelöscht, so werden alle Sohn- Enkel- etc.
+ Tasks ohne zusätzliche Nachfrage gelöscht, falls die Sicherheitsabfrage
+ mit 'j' beantwortet wurde. #off("b")#
+#page#
+3.3. Dateibearbeitung
+#free(1.0)#
+Datei einrichten
+#free(1.0)#
+
+
+ Mit dem Editoraufruf 'edit' wird eine neue Datei eingerichtet, bzw. eine existierende
+ Datei zur Bearbeitung am Bildschirm gezeigt.
+
+
+
+#free(0.5)#
+
+Eine Datei enthält Texte, die logisch zusammengehören und sie wird über ihren
+Namen eindeutig gekennzeichnet.
+
+Das EUMEL-System speichert einmal geschriebene Texte, bis sie vom Benutzer
+gelöscht werden. In der Regel wird nicht nur ein (langer) Text oder ein Programm­
+text geschrieben, sondern mehrere und unterschiedliche. Um diese auseinanderhalten
+zu können, versehen wir sie jeweils mit einem Namen, der frei gewählt werden kann.
+Beispiele für Namen:
+
+
+ "Brief vom 1.12.86"
+ "1. Kapitel meines Buches"
+
+
+Eine Sammlung von Zeichen (also im Normalfall unsere geschriebenen Texte), die mit
+einem Namen versehen worden ist, nennt man eine #ib##on("b")#Datei#ie##off("b")#. Der Editor erstellt also eine
+Datei, wenn wir einen Text schreiben. Eine Datei kann bis zu 4 000 Zeilen fassen,
+wobei jede bis zu 32 000 Zeichen lang sein darf.
+
+
+Einrichten der ersten #ib#Datei#ie# in Ihrer Task:
+
+Der erste Schritt sollte darin bestehen, daß Sie sich einen vernünftigen Dateinamen
+ausdenken. Das EUMEL-System legt Ihnen praktisch keine Beschränkungen über
+Länge oder Form des Dateinamens auf, deshalb sollten Sie sich angewöhnen, Ihre
+Dateien so zu benennen, daß Sie anhand des Namens auch nach einer Woche oder
+länger noch erahnen können, was diese Datei enthält.
+
+Ein guter Name für die erste Datei wäre zum Beispiel: "meine erste Datei" oder
+"werners test vom 1.12.86". Im weiteren Text steht nur "dateiname" o. ä.. Setzen Sie
+dafür den von Ihnen gewählten Namen ein.
+
+____________________________________________________________________________
+
+gib kommando:
+edit ("dateiname")
+
+____________________________________________________________________________
+
+____________________________________________________________________________
+
+gib kommando:
+edit ("dateiname")
+
+"dateiname" neu einrichten (j/n)?
+
+____________________________________________________________________________
+
+Drücken Sie 'j', so wird eine neue Datei unter dem von Ihnen eingegebenen Namen
+eingerichtet. Die Datei ist zunächst leer:
+
+____________________________________________________________________________
+ ................... dateiname .................... Zeile 1
+
+____________________________________________________________________________
+
+
+
+Welche Möglichkeiten Sie bei der Bedienung des Editors haben, können Sie in Teil 4
+nachschlagen. Schreiben Sie an dieser Stelle nur einige Worte in die Datei, anhand
+derer der Dateiinhalt wiederzuerkennen ist. Sie können die Tastatur genauso benutzen
+wie die einer Schreibmaschine.
+
+____________________________________________________________________________
+ ................... dateiname .................... Zeile 1
+Inhalt der ersten Datei. 1234567890
+
+____________________________________________________________________________
+
+
+Die Datei sollte an dieser Stelle wieder geschlossen werden.
+
+Drücken Sie dazu <ESC> <q>.
+
+Dabei ist gleichgültig, wo der Cursor steht.
+
+Wiederholen Sie das Neuanlegen einer Datei mit einer zweiten Datei "anderer datein­
+ame". Bitte schreiben Sie wiederum einige Zeichen in die Datei.
+
+____________________________________________________________________________
+
+gib kommando :
+edit ("anderer dateiname")
+
+____________________________________________________________________________
+
+
+Vorschlag zur Eingabe:
+
+____________________________________________________________________________
+
+ .............. anderer dateiname ................. Zeile 1
+Halten Sie irgendeine Taste gedrücktttttttttttttttt
+
+____________________________________________________________________________
+
+
+Beenden Sie die Arbeit ebenfalls mit <ESC> <q> .
+
+
+#page#
+Dateinamen auflisten
+#free(1.0)#
+
+
+ Mit dem Kommando 'list' werden die Dateinamen der Dateien in der Task aus­
+ gegeben.
+
+
+#free(1.0)#
+
+Vor jedem Dateinamen wird das Datum der letzten Bearbeitung der Datei angezeigt.
+
+____________________________________________________________________________
+
+gib kommando:
+list
+
+____________________________________________________________________________
+
+bewirkt:
+____________________________________________________________________________
+
+ ..................... list ....................... Zeile 1
+
+01.08.86 "dateiname"
+01.08.86 "anderer dateiname"
+
+____________________________________________________________________________
+
+
+
+Auch bei dieser Auflistung der Dateinamen handelt es sich um eine EUMEL-Datei
+ (allerdings um eine schreibgeschützte), die Ausgabe wird also wie gewohnt durch
+ das Kommando <ESC> <q> beendet.
+#page#
+Datei duplizieren
+#free(1.0)#
+
+
+ Mit dem Kommando 'copy' wird eine existierende Datei dupliziert.
+
+
+#free(1.0)#
+
+Eine existierende Datei kann dupliziert werden durch das Kommando :
+
+____________________________________________________________________________
+
+gib kommando:
+copy ("dateiname","kopiename")
+
+____________________________________________________________________________
+
+
+Durch dieses Kommando wird eine Kopie der Datei "dateiname" unter dem Namen
+"kopiename" angelegt, der Inhalt der beiden Dateien ist zunächst identisch. Kontrol­
+lieren Sie die Richtigkeit dieser Behauptung, indem Sie nachsehen, ob der Inhalt der
+kopierten Datei gleich dem Inhalt der Ursprungsdateiname ist:
+
+____________________________________________________________________________
+
+gib kommando:
+edit ("kopiename")
+
+____________________________________________________________________________
+#page#
+Dateinamen ändern
+#free(1.0)#
+
+
+ Mit dem Kommando 'rename' wird der Name einer Datei geändert.
+
+
+#free(1.0)#
+
+Sollte Ihnen der Name einer Datei nicht gefallen, so besteht die Möglichkeit, den
+Namen zu ändern:
+
+____________________________________________________________________________
+
+gib kommando:
+rename ("dateiname","neuer dateiname")
+
+____________________________________________________________________________
+
+
+#page#
+Datei löschen
+#free(1.0)#
+
+
+ Mit dem Kommando 'forget' wird eine Datei gelöscht.
+
+
+#free(1.0)#
+
+Das Löschen einer Datei wird durch das Kommando:
+
+____________________________________________________________________________
+
+gib kommando:
+forget ("neuer dateiname")
+
+____________________________________________________________________________
+
+eingeleitet. Aus Gründen der Sicherheit erfolgt vor der Ausführung des Kommandos
+jedoch die Abfrage:
+
+____________________________________________________________________________
+
+gib kommando:
+forget ("neuer dateiname")
+
+"dateiname" löschen ? (j/n)
+
+____________________________________________________________________________
+
+Als positive Antwort auf derartige Abfragen wirken: <j> <J> <y> <Y>
+
+<n> bzw. <N> unterdrücken die angebotene Aktion, andere Eingaben werden abgewie­
+sen.
+
+#page#
+Dateien verschicken
+#free(1.0)#
+#goalpage("Dateitrans")#
+
+
+ Dateien können zur Vater-Task geschickt und von der Vater-Task geholt werden.
+
+#free(1.0)#
+
+Die Vereinbarung, daß Dateien in einer Task lokal sind, d.h. daß nur in dieser Task
+Zugriff auf die Daten möglich ist, ist häufig zu einschränkend. So kann es zweck­
+mäßig sein, von mehreren Arbeitsplätzen (= Tasks) aus die wesentlichen Ergebnisse
+an einer zentralen Stelle zu sammeln oder Ergebnisse aus Tasks, die nur kurzzeitig
+für eine spezielle Aufgabe eingerichtet wurden, länger aufzubewahren.
+
+Zu diesem Zweck wird eine Benutzertask zum Manager erklärt (siehe S.#topage("globalmanager")#) und es
+werden Söhne dieser Task eingerichtet.
+#page#
+Datei zur Vater-Task schicken
+#free(1.0)#
+
+
+ Mit dem Kommando 'save' wird die Kopie einer Datei zur Vater-Task geschickt.
+
+
+#free(1.0)#
+
+____________________________________________________________________________
+
+gib kommando:
+save ("dateiname")
+
+____________________________________________________________________________
+
+Wird eine Datei an die Vater-Task gesendet, wird eine Kopie der Ursprungsdateina­
+me unter dem Namen 'dateiname' in der Vater-Task eingerichtet. Danach sind diese
+beiden, zunächst gleichen Dateien unabhängig voneinander. Änderungen, welcher Art
+auch immer, haben keinen Einfluß auf die namensgleiche Kopie in der anderen Task.
+
+Falls in der Vater-Task bereits eine Datei mit dem Namen 'dateiname' existiert, sei
+es durch Zufall oder weil bereits einmal eine 'save'-Operation durchgeführt worden
+ist, erfolgt eine Abfrage:
+
+____________________________________________________________________________
+
+gib kommando:
+save ("dateiname")
+
+"dateiname" überschreiben ? (j/n)
+
+____________________________________________________________________________
+
+Nur wenn die positive Eingabe 'j' erfolgt, wird die Datei in der Vater-Task durch die
+eigene Datei überschrieben.
+#page#
+Datei von der Vater-Task holen
+#free(1.0)#
+
+
+ Mit dem Kommando 'fetch' wird die Kopie einer Datei von der Vater-Task geholt.
+
+
+#free(1.0)#
+
+Entsprechend dem Versenden einer Dateikopie können Sie eine Kopie von der Vater­
+Task holen und ggf., natürlich nach Abfrage, Ihre Datei dieses Namens überschrei­
+ben.
+
+____________________________________________________________________________
+
+gib kommando:
+fetch ("dateiname")
+
+____________________________________________________________________________
+
+#page#
+Datei in der Vater-Task löschen
+#free(1.0)#
+
+
+ Mit dem Kommando 'erase' wird eine Datei in der Vater-Task gelöscht.
+
+
+#free(1.0)#
+
+Soll eine Datei in der Vater-Task gelöscht werden, so kann dieses, dem 'forget'-
+Kommando analoge Kommando, in der Sohn-Task gegeben werden:
+
+____________________________________________________________________________
+
+gib kommando:
+erase ("dateiname")
+
+____________________________________________________________________________
+
+Falls die Datei in der Vater-Task existiert, wird sie nach Kontrollfrage gelöscht.
+
+____________________________________________________________________________
+
+gib kommando:
+erase ("dateiname")
+"dateiname" loeschen (j/n) j
+
+gib kommando :
+
+
+____________________________________________________________________________
+
+
+ Anm: Die Task 'PUBLIC' ist grundsätzlich eine Manager-Task. Da Benut­
+ zer-Tasks als Sohn von '#ib#PUBLIC#ie#' eingerichtet werden, falls Sie nicht als
+ Sohn einer besonderen Manager-Task eingerichtet wurden, beziehen sich
+ 'fetch'-, 'save'- und 'erase'-Kommandos auf 'PUBLIC'.
+#page#
+3.4. Das Archiv
+#free(1.0)#
+
+
+ Das Archiv dient der Speicherung von Dateien auf Disketten (Sicherung).
+
+#free(1.0)#
+
+Das #ib#Archiv#ie# übernimmt im EUMEL-System die Verwaltung der langfristigen Daten­
+haltung. Das Archiv sollen Sie benutzen, um:
+
+- Sicherungskopien wichtiger Dateien außerhalb des Rechners zu besitzen;
+
+- nicht benötigte Dateien außerhalb einer Task zu halten (Speicherplatzersparnis!);
+
+- Dateien auf andere Rechner zu übertragen.
+
+Das Archiv wird im EUMEL-System durch die Task 'ARCHIVE', die das Disketten­
+laufwerk des Rechners verwaltet, realisiert. Die Steuerung durch eine Task hat für Sie
+die erfreuliche Folge, daß die Handhabung des Archivs sich kaum von den schon
+bekannten Dateioperationen unterscheidet. In den Kommandos wird zusätzlich ange­
+geben, daß das Archiv angesprochen werden soll.
+
+#page#
+Archiv-Kommandos
+#free(1.0)#
+
+
+ Der Arbeitsablauf bei Benutzung des Archivs besteht immer aus der Reservierung,
+ dem Lese- oder Schreibzugriff und der Freigabe des Archivs nach Ende der
+ Arbeit. Jede Arbeit mit dem Archiv beginnt mit dem Reservierungskommando.
+
+
+#free(1.0)#
+
+Als ersten Schritt der Archivbenutzung müssen Sie das Archiv reservieren, das heißt
+der Verwaltung Ihres EUMEL-Systems mitteilen, daß Sie die Task 'ARCHIVE', die
+der Steuerung des Diskettenlaufwerks dient, für Ihre Task arbeiten lassen. Solange für
+Ihre Task das Archiv reserviert ist, kann keine andere Task das Archivlaufwerk benut­
+zen.
+
+Für die Reservierung müssen Sie bei Benutzung einer schon vorbereiteten oder sogar
+beschriebenen Diskette den Namen dieser Archivdiskette kennen (er sollte auf dem
+Diskettenaufkleber stehen) oder vor Benutzung einer neuen Diskette einen Namen
+festlegen (und auf dem Aufkleber vermerken). Wie gewohnt gibt es keine Vorschrif­
+ten für die Namensgebung.
+
+Erst nachdem Sie das Reservierungskommando gegeben haben:
+
+____________________________________________________________________________
+
+gib kommando:
+archive ("diskettenname")
+
+____________________________________________________________________________
+
+
+sollten Sie die Diskette in das Laufwerk einschieben, um zu verhindern, daß ein
+anderer Benutzer, der das Archiv bereits für sich reserviert hat, auf Ihrer zufällig
+gleichnamigen Datei arbeitet.
+
+
+Eine Datei wird mit dem Kommando:
+
+____________________________________________________________________________
+
+save ("dateiname",archive)
+
+
+____________________________________________________________________________
+
+
+auf eine Diskette geschrieben und mit dem Kommando:
+
+____________________________________________________________________________
+
+fetch ("dateiname",archive)
+
+____________________________________________________________________________
+
+
+von einer Diskette geholt.
+
+Das Inhaltsverzeichnis einer Diskette erhalten Sie durch:
+
+____________________________________________________________________________
+
+list (archive)
+
+____________________________________________________________________________
+
+#page#
+Benutzung einer neuen Archivdiskette
+#free(1.0)#
+
+
+ Eine neue Diskette muß für die Benutzung vorbereitet (formatiert) werden.
+
+
+
+#free(1.0)#
+Vor der erstmaligen Benutzung einer Archivdiskette muß diese formatiert, d.h. in
+Spuren und Sektoren für die Positionierung des Schreib-/Lesekopfes des Disketten­
+laufwerks eingeteilt werden, um überhaupt ein Beschreiben der Diskette zu ermög­
+lichen. Die Einteilung ist geräteabhängig, häufige Formate sind:
+
+ 40 Spuren zu je 9 Sektoren (360 K)
+ 80 Spuren zu je 9 Sektoren (720 K).
+
+Die #on("b")#Erst#off("b")#benutzung einer #ib#Archivdiskette#ie# erfordert nach der Reservierung des Archivs
+das Kommando:
+
+____________________________________________________________________________
+
+gib kommando:
+format (archive)
+
+____________________________________________________________________________
+
+
+Erst nach einer Kontrollabfrage:
+
+____________________________________________________________________________
+
+gib kommando:
+format (archive)
+
+Archiv "diskettenname" formatieren ? (j/n)
+
+____________________________________________________________________________
+
+wird tatsächlich formatiert und die Diskette steht mit dem Namen "diskettenname" für
+Archivoperationen zur Verfügung.
+
+#on("b")#
+ACHTUNG: Wird eine bereits beschriebene Diskette noch einmal formatiert, so sind
+ alle Daten, die auf der Diskette waren, verloren.#off("b")#
+
+
+Bei einigen Rechnern ist es möglich, die Formatierung zu variieren. Falls beim Forma­
+tieren auf einem solchen Rechner ein anderes als das Standardformat erzeugt werden
+soll, so ist die Codierung des gewünschten Formats mitanzugeben.
+
+
+Beispiel: Für ein Gerät mit 5μ Zoll Disketten wäre z.B. einstellbar:
+ code 0 : Standardformat
+ code 1 : 40 Spuren
+ code 2 : 80 Spuren
+ code 3 : High Density
+
+ 'format (archive)' erzeugt ebenso wie 'format (0,archive)' eine standard­
+ formatierte Diskette, 'format (3,archive)' erzeugt eine High Density
+ Formatierung.
+#page#
+Diskette löschen / umbenennen
+#free(1.0)#
+
+
+ Bereits benutzte Disketten können wieder gelöscht und auch umbenannt werden.
+
+
+#free(1.0)#
+
+Falls Sie den Inhalt einer beschriebenen Archivdiskette löschen oder den Namen einer
+Diskette ändern wollen, müssen Sie das Archiv unter dem gewünschten Namen reser­
+vieren: Falls Sie den Inhalt löschen möchten, tun Sie das unter dem bisherigen und
+bestehenden Namen. Falls Sie die Diskette umbenennen wollen, reservieren Sie das
+Archiv unter dem neuen gewünschten Namen. Beachten Sie, daß durch das Umbe­
+nennen eines Archivs alle darauf befindlichen Dateien gelöscht werden. Anschließend
+geben Sie das Kommando:
+
+____________________________________________________________________________
+
+gib kommando:
+#ib#clear#ie# (archive)
+
+____________________________________________________________________________
+
+Durch die Ausführung des Kommandos erhält die eingelegte Diskette den in der
+Reservierung angegebenen Namen. Das Inhaltsverzeichnis, das sich auf der Diskette
+befindet, wird gelöscht. Damit sind die Daten, die sich eventuell auf dieser Diskette
+befanden, nicht mehr auffindbar. Die Diskette entspricht einer neu formatierten Disket­
+te#u#1)#e#. #foot#
+#u#1)#e# Das Kommando 'format' enthält implizit 'clear'.
+#end#
+Eine Neuformatierung ist demnach bei Wiederverwendung der Diskette nicht notwen­
+dig.
+
+#page#
+Inhaltsverzeichnis der Diskette
+#free(1.0)#
+
+
+ Mit 'list (archive)' werden die Dateien auf der Diskette angezeigt.
+
+
+#free(1.0)#
+
+Eine formatierte Diskette kann nach der Archivanmeldung gelesen oder beschrieben
+werden. Um zu sehen, welche Dateien auf der Diskette zu holen (= lesen) sind bzw.
+wieviel Platz zum Beschreiben vorhanden ist, ist es zweckmäßig, zunächst das In­
+haltsverzeichnis der Diskette zu betrachten.
+
+____________________________________________________________________________
+
+gib kommando:
+list (archive)
+
+____________________________________________________________________________
+
+Beispiel:
+
+____________________________________________________________________________
+
+ ............diskettenname (100 K belegt von 720 K)..............
+
+01.05.86 25 K "rechnungen april"
+01.06.86 23 K "rechnungen mai"
+01.07.86 20 K "rechnungen juni"
+01.08.86 32 K "rechnungen juli"
+
+____________________________________________________________________________
+#page#
+Lesen und Schreiben auf Diskette
+#free(1.0)#
+
+
+ Lesen und Schreiben auf der Diskette entspricht den bekannten Operationen zum
+ Senden und Holen von Dateien.
+
+
+
+#free(1.0)#
+Das Schreiben einer Datei auf Diskette entspricht dem Übersenden einer Datei an die
+Vater-Task. Einziger Unterschied ist, daß Sie das Ziel explizit angeben müssen:
+
+____________________________________________________________________________
+
+gib kommando:
+#ib#save#ie# ("dateiname",archive)
+
+____________________________________________________________________________
+
+Entsprechend funktioniert auch das Lesen einer Datei von der Diskette:
+
+____________________________________________________________________________
+
+gib kommando:
+fetch ("dateiname",archive)
+
+____________________________________________________________________________
+
+Wie auch bei der Kommunikation zwischen Sohn- und Vater-Task werden nur
+Kopien der Dateien geholt bzw. geschrieben.
+#page#
+Wechsel der Archivdiskette
+#free(1.0)#
+Bei Einlegen einer anderen Archivdiskette müssen Sie erneut das Kommando
+
+____________________________________________________________________________
+
+gib kommando:
+archive ("diskettenname")
+
+____________________________________________________________________________
+
+geben, da mit der Archivreservierung zugleich die Prüfung von Diskettenname und
+-Inhaltsverzeichnis vorbereitet wird.
+#page#
+Beenden der Archivreservierung
+#free(1.0)#
+
+
+ Nach Benutzung Archiv freigeben!
+
+
+#free(1.0)#
+
+Wenn Sie alle gewünschten Arbeiten mit dem Archiv fertiggestellt haben, geben Sie
+das Archiv wieder frei.
+
+____________________________________________________________________________
+
+gib kommando:
+#ib#release#ie# (archive)
+
+____________________________________________________________________________
+
+Durch dieses Kommando kann die Task 'ARCHIVE' mit ihren Leistungen von einer
+anderen Task in Anspruch genommen werden. Falls Sie dieses Kommando nicht
+gegeben haben aber seit 5 Minuten keine Archivoperation ausgelöst haben, kann eine
+andere Task durch die Anforderung 'archive("diskettenname")' das Archiv reservieren.
+Durch diese Maßnahme wird verhindert, daß ein vergeßlicher Benutzer bei einem
+System mit mehreren Benutzern das Archiv blockiert.
+#page#
+Fehlermeldungen des Archivs
+#free(1.0)#
+
+
+ Bei Archiv-Operationen kann es zu Fehlersituationen kommen.
+
+#free(1.0)#
+
+Versucht man, eine Datei vom Archiv zu holen, kann es vorkommen, daß das Ar­
+chiv-System
+
+____________________________________________________________________________
+
+#ib#Lese-Fehler (Archiv)#ie#
+
+____________________________________________________________________________
+
+meldet und den Lese-Vorgang abbricht. Dies kann auftreten, wenn die Floppy
+beschädigt oder aus anderen Gründen nicht lesbar ist (z.B. nicht justierte Disket­
+ten-Geräte). In einem solchen Fall vermerkt das Archiv-System intern, daß die Datei
+nicht korrekt gelesen werden kann. Das sieht man z.B. bei 'list (archive)'. Dort ist der
+betreffende Datei-Name mit dem Zusatz 'mit Lese-Fehler' gekennzeichnet. Um
+diese Datei trotzdem zu lesen, muß man sie unter ihrem Dateinamen mit dem Zusatz
+'mit Lese-Fehler' lesen.
+
+____________________________________________________________________________
+
+gib kommando:
+fetch ("dateiname mit Lese-Fehler")
+
+____________________________________________________________________________
+
+Die Datei wird in diesem Fall trotz Lese-Fehler (Informationsverlust!) vom Archiv
+gelesen.
+
+Um solche Fälle möglichst zu vermeiden, sieht das EUMEL-System die Möglichkeit
+vor, Archive bzw. Archiv-Dateien nach Beschreiben zu prüfen. Das erfolgt mit dem
+Kommando
+
+____________________________________________________________________________
+
+gib kommando :
+#ib#check#ie# ("dateiname", archive)
+
+____________________________________________________________________________
+
+
+Durch dieses Kommando werden eventuelle Lese-Fehler gemeldet.
+
+Weitere Fehlermeldungen des Archivs:
+
+* Lesen unmöglich (Archiv)
+ Die Archiv-Diskette ist nicht eingelegt oder die Tür des Laufwerks ist nicht ge­
+ schlossen.
+=> Diskette einlegen bzw. Tür schließen.
+
+* Schreiben unmöglich (Archiv)
+ Die Diskette ist schreibgeschützt.
+=> falls wirklich gewünscht, Schreibschutz entfernen.
+
+* Archiv nicht angemeldet
+ Das Archiv wurde nicht angemeldet
+=> 'archive ("name")' geben.
+
+* Lese-Fehler (Archiv)
+ Siehe Lesen unmöglich
+
+* Schreibfehler (Archiv)
+ Die Diskette kann nicht (mehr) beschrieben werden.
+=> Andere Diskette verwenden.
+
+* Speicherengpass
+ Im System ist nicht mehr genügend Platz, um eine Datei vom Archiv zu laden, ggf.
+=> ggf. Dateien löschen.
+
+* RERUN bei Archiv-Zugriff Das System wurde bei einer Archiv-Operation durch
+ Ausschalten bzw. Reset unterbrochen.
+
+* "dateiname" gibt es nicht
+ Die Datei "dateiname" gibt es nicht auf dem Archiv.
+=> mit 'list(archive)' Archiv prüfen.
+
+* Archiv heißt ...
+ Die eingelegte Diskette hat einen anderen als den eingegebenen Archivnamen.
+=> Kommando 'archive' mit korrektem Namen geben.
+
+* Archiv wird von Task ... benutzt
+ Das Archiv wurde von einem anderen Benutzer reserviert.
+=> Abwarten.
+
+* "dateiname" kann nicht geschrieben werden (Archiv voll)
+ Die Datei ist zu groß für die eingelegte Diskette.
+=> Andere Diskette für diese Datei nehmen.
+
+* Archiv inkonsistent
+ Die eingelegte Diskette hat nicht die Struktur einer Archiv-Diskette.
+=> 'format (archive)' vergessen.
+
+* save/erase wegen Lese-Fehler verboten
+ Bei Archiven mit Lese-Fehler sind Schreiboperationen verboten, weil ein Erfolg
+ nicht garantiert werden kann.
+
+
+
+3.5. Kommandos für mehrere Dateien
+#free(1.0)#
+
+
+ Durch Anwendung der besonderen Operatoren 'ALL' und 'SOME' können Sie
+ mehrere Dateien mit einem Kommando behandeln.
+
+
+#free(1.0)#
+Oft ist es sehr zweckmäßig und erleichternd, einen Befehl für eine ganze Reihe von
+Dateien wirken zu lassen, wie z.B. beim Archivieren, wenn Sie etwa alle während des
+Tages veränderten Dateien mit deren neuen Stand auf Diskette schreiben möchten.
+
+Da Tasks einen Namen haben und jede Task ein Inhaltsverzeichnis ihrer Dateien
+führt, ist es möglich, Listen von Dateien zu benennen.
+#page#
+Interne Tasknamen
+#free(1.0)#
+Wenn Sie eine andere als die eigene oder die Vater-Task ansprechen wollen, ist es
+notwendig, den 'internen Tasknamen' anzugeben. Diese auf den ersten Blick etwas
+undurchsichtige Forderung hat folgenden Hintergrund:
+
+Durch die in der Einleitung vorgestellte Baumstruktur des EUMEL-Systems ist es
+ohne besondere Angaben nur möglich, Kommandos zu geben, die die eigene Task
+('edit'..) oder die Vater-Task ('save'..) betreffen. Beim Archivieren zum Beispiel wäre
+es demzufolge erforderlich, eine Datei über den Vater vom Vater vom Vater... an den
+Sohn des Sohnes... zu schicken, damit die Datei endlich in der Task 'ARCHIVE'
+landet. Statt dessen verwenden Sie eine Prozedur 'archive', die den internen Task­
+bezeichner liefert. Damit wird die gewünschte Task intern identifiziert, ohne daß Sie
+sich darum kümmern müssen.
+
+Wichtige Prozeduren, die interne Taskbezeichner liefern, sind:
+
+ myself Bezeichner der eigenen Task
+ public Bezeichner von PUBLIC
+ father Bezeichner der Vater-Task#u##count##e#
+ archive Bezeichner von ARCHIVE
+ printer Bezeichner von PRINTER #foot#
+#u##value##e# Falls kein besonderer Manager eingerichtet wurde, liefern 'father' und 'public'
+ natürlich dieselbe Task: PUBLIC. #end#
+#page#
+Dateiverzeichnisse
+#free(1.0)#
+Jede Task verfügt über ein Verzeichnis der in ihr befindlichen Dateien. Das Verzeich­
+nis Ihrer eigenen Task können Sie mit dem 'list'-Kommando betrachten. Das Ver­
+zeichnis einer anderen Task sehen Sie beispielsweise durch das Kommando 'list
+(archive)'. In diesem Fall müssen Sie dem eigentlichen Kommando den internen
+Taskbezeichner der gewünschten Task hinzugeben, um das Verzeichnis zu sehen.
+
+Um ein Verzeichnis in Verbindung mit anderen Kommandos benutzen zu können, gibt
+es besondere Operatoren:
+
+ #ib#ALL#ie# liefert das gesamte Verzeichnis
+ #ib#SOME#ie# bietet das Verzeichnis zur Auswahl von Einträgen an.
+
+
+In Verbindung mit einem internen Taskbezeichner wird einer der beiden Operatoren
+einem Monitor-Kommando als Parameter nachgestellt. Das Kommando wirkt dann
+nacheinander auf alle im Verzeichnis enthaltenen Dateien.
+
+
+____________________________________________________________________________
+
+gib kommando:
+fetch (ALL father)
+
+____________________________________________________________________________
+
+Alle Dateien der Vater-Task werden nacheinander geholt, bei Namensgleichheit
+erfolgt die bekannte Kontrollfrage, ob die gleichnamige Datei in der eigenen Task
+überschrieben werden soll.
+
+Falls nur einige Dateien des Verzeichnisses bearbeitet werden sollen, wird der Opera­
+tor 'SOME' dem Taskbezeichner vorangestellt:
+
+____________________________________________________________________________
+
+gib kommando:
+fetch (SOME father)
+
+____________________________________________________________________________
+
+
+Hier wird zunächst das Dateiverzeichnis der Task angeboten. Streichen Sie alle
+Dateien, die auf der Diskette sind, aber nicht in Ihre Task geholt werden sollen, aus
+dem Verzeichnis, indem Sie
+
+- den Dateinamen mit Blanks überschreiben
+
+ oder:
+
+- die Zeile mit <HOP> <RUBOUT> löschen
+
+ oder:
+
+- mehrere Zeilen markieren, indem Sie zu Beginn des zu markierenden Bereichs
+ 'mark' betätigen und mit Hilfe der Cursor-Tasten den Beereich so weit wie benö­
+ tigt ausdehnen. Im Anschluß daran können Sie diese Zeilen durch
+
+ <ESC> <RUBOUT> oder
+
+ <ESC> <p>
+
+ löschen.
+
+
+____________________________________________________________________________
+
+ .............................. .......................... #markoff#
+rechnungen april
+rechnungen mai
+rechnungen juni
+rechnungen juli
+
+
+
+____________________________________________________________________________
+
+
+
+In obigem Beispiel werden nach dem Kommando 'ESC RUBOUT' (=Löschen der
+markierten Zeilen) und dem Kommando 'ESC q' (=editieren beenden) die Dateien
+'rechnungen juni' und 'rechnungen juli' vom Archiv geholt.
+
+Als weitere Vereinfachung gibt es die Prozedur 'all' als Abkürzung für 'ALL myself'.
+
+Beispiel: alle Dateien auf Archivdiskette schreiben.
+
+____________________________________________________________________________
+
+gib kommando:
+save (all,archive)
+
+____________________________________________________________________________
+
+
+Für Fortgeschrittene:
+
+Sie können auch aus den Verzeichnissen mehrerer Tasks ein neues Verzeichnis
+bilden. Zu diesem Zweck sind folgende Mengenoperationen auf Verzeichnisse mög­
+lich:
+
+ #ib#-#ie# Differenzmenge
+ #ib#+#ie# Vereinigungsmenge
+ #ib#/#ie# Schnittmenge
+
+Beispiel:
+
+ fetch (ALL father - ALL myself)
+
+Alle Dateien der Vater-Task, die noch nicht in der eigenen Task sind, werden geholt.
+
+3.7. Passwortschutz
+#free(1.0)#
+
+
+ Das EUMEL- System ermöglicht Passwortschutz für Dateien, einzelne Tasks und
+ ganze Zweige des Taskbaumes.
+
+#free(1.0)#
+
+Falls Sie sicherstellen wollen (oder müssen), daß Teile Ihres EUMEL-Systems vor
+unberechtigter Benutzung geschützt sind, können Sie den Zugriff mit einem Passwort
+regeln.
+
+Als Passwort können Sie jeden beliebigen Text nehmen. Bedenken Sie jedoch, daß
+ein wirklich wirksamer Schutz nur dann gewährleistet ist, wenn Sie weder ein triviales
+Passwort (etwa den eigenen Vornamen) auswählen, noch eines, das Sie selbst nicht
+behalten. #u##count("1")#)#e# #foot#
+#u##value("1")#)#e# Man darf Passwörter nicht vergessen! Durch Passwörter geschützte Tasks kann
+niemand - außer durch die Angabe des korrekten Passworts - wieder ankoppeln.
+Hat man das Passwort vergessen, kann man nur noch die Task löschen.
+#end#
+
+ACHTUNG: Es gibt ein besonderes Passwort im EUMEL-System: "-". Dieses
+ Passwort verhindert, daß die Task in der es gegeben wurde (z.B. UR), an
+ ein Terminal geholt wird, es darf folglich nicht für normale
+ Manager-Tasks gegeben werden.
+#page#
+Eine Task mit Passwort schützen
+#free(1.0)#
+Das Monitor-Kommando '#ib#task password#ie#' sorgt dafür, daß eine Task fortan nur wieder
+mit einem 'continue'-Kommando 'betreten' werden kann, wenn man vorher das
+richtige Passwort angibt.
+
+____________________________________________________________________________
+
+gib kommando:
+task password ("rosebud")
+
+____________________________________________________________________________
+
+Versucht nun ein Benutzer, die mit dem Passwort geschützte Task mit dem 'conti­
+nue'-Kommando an sein Terminal anzukoppeln, wird er zunächst nach dem #ib#Pass­
+wort#ie# gefragt. Nur unter Angabe des Passworts wird die Task angekoppelt.
+
+Bei der Beantwortung des Passworts werden statt der eingegebenen Zeichen Punkte
+auf den Bildschirm geschrieben. Durch Betätigen von ESC können die getippten
+Zeichen lesbar gemacht werden.
+
+____________________________________________________________________________
+
+ gib supervisor kommando:
+ continue("taskname")
+ Passwort: .......
+
+
+____________________________________________________________________________
+
+
+Der Passwortschutz gewährleistet, daß kein unberechtigter Benutzer direkt an die
+Dateien und Programme der Task gelangen kann. Es gibt jedoch noch zwei Situatio­
+nen, die einen unberechtigten Zugang zu Dateien erlauben:
+
+a) Dateien in die Vater-Task schicken:
+ Transportiert man Dateien in die Vater-Task ('save'-Kommando) können Benut­
+ zer auf diese Dateien zugreifen (sofern sie Zugang zu dieser Task haben). Dies
+ kann man verhindern, indem man ein Datei-Passwort angibt. Man beachte, daß
+ das Passwort für Dateien und das oben beschriebene Passwort für Tasks nichts
+ miteinander zu tun haben.
+
+b) Dateien werden in eine Sohn-Task geholt:
+ Ist die Task als Vater-Task eingerichtet ('global manager'-Kommando), dann ist
+ es möglich, von der Sohn-Task Dateien ('fetch'-Kommando) aus der Vater-
+ Task zu holen, die mit einem Passwort geschützt ist. Darum muß man verhindern,
+ daß unberechtigte Benutzer Söhne einer mit Passwort geschützten Task einrich­
+ ten können. Das kann man mit dem Kommando
+
+____________________________________________________________________________
+
+maintenance :
+#ib#begin password#ie# ("geheim")
+
+____________________________________________________________________________
+
+
+ Wird dieses Kommando gegeben, wird man bei dem Versuch, eine Sohn-Task
+ einzurichten, nach einem Passwort gefragt. Beachten Sie, daß das 'begin pass­
+ word' nichts mit dem Task-Passwort und Datei-Passwort zu tun hat.
+
+
+Man kann einen ganzen Zweig eines EUMEL-Systems durch das Kommando 'family
+password' vor unberechtigtem Zugriff schützen. Das Kommando:
+
+____________________________________________________________________________
+
+maintenance:
+family password ("geheim")
+
+____________________________________________________________________________
+
+wird dazu (wie gewohnt als Monitor-Kommando) in der Vater-Task des zu schüt­
+zenden Zweigs des Taskbaumes gegeben. Damit ist das Passwort aller Söhne, Enkel
+usw. dieser Task auf 'geheim' gesetzt, falls sie vorher kein Passwort oder das gleiche
+Passwort wie die aufrufende Task haben. Eine Task in diesem Zweig, die bereits ein
+eigenes, vom 'family password' verschiedenes Passwort besitzt, behält dieses eigene
+Passwort.
+
+Bsp: Für 'PUBLIC' wird das Kommando '#ib#family password#ie# ("geheim")' gege­
+ ben. Dann ist das Passwort von 'PUBLIC' und aller Tasks des Benutzerzweiges
+ auf 'geheim' gesetzt.
+
+
+Es ist zu beachten, daß bei der Vergabe des 'family password' nur die aktuellen
+Söhne der Task berücksichtigt werden. Söhne, die nach der Vergabe des 'family
+password' eingerichtet werden, sind nicht durch dieses Passwort geschützt.
+
+Passwort löschen
+
+
+Um ein Passwort zu löschen, geben Sie das Passwort-Kommando mit "" als Para­
+meter:
+
+____________________________________________________________________________
+
+maintenance:
+begin password("")
+
+____________________________________________________________________________
+
+
+Durch diese Angabe haben Sie den Passwort einen leeren Text als Parameter gege­
+ben, der das bisherige Passwort 'überschreibt'.
+
+#page#
+Dateipasswort
+
+
+Etwas komplizierter gestaltet sich der Passwortschutz für einzelne Dateien einer
+Manager-Task, da in dieser Anwendung eine Unterscheidung nach Schreib- und
+Leseschutz vorgenommen wird.
+
+Da in dieser Anwendung nur einige Dateien der Vater-Task vor Lesen ('fetch'),
+Schreiben ('save','erase') oder beidem geschützt werden sollen, benötigt diese Proze­
+dur Angaben über Dateinamen, Schreibpasswort und Lesepasswort.
+
+____________________________________________________________________________
+
+maintenance :
+enter password ("dateiname","schreibschutz","leseschutz")
+
+____________________________________________________________________________
+
+Falls die Datei nicht gegen Lesen geschützt werden soll, wird (wie beim Löschen
+eines Passworts) '""' als Lesepasswort angegeben.
+
+Falls Schreiben und/oder Lesen für eine Datei gänzlich verboten#u#1)#e# sein soll, so ist
+"-" als entsprechendes Passwort anzugeben.
+#foot#
+1) Natürlich kann die Datei in der Manager-Task, der sie gehört, normal editiert
+ werden.
+#end#
+
+Um von einer Sohn-Task eine Datei mit Passwortschutz in der Vater-Task zu lesen
+oder zu schreiben muß vor dem 'fetch', 'save' oder 'erase' Kommando das 'enter
+password' Kommando eineggeben werden:
+
+____________________________________________________________________________
+
+gib kommando:
+enter password ("schreibpasswort/lesepasswort")
+
+____________________________________________________________________________
+
+In der Sohn-Task wird also nur ein Passwort eingegeben. Falls wie oben ein '/' in
+diesem Passwort enthalten ist, wird der erste Teil vor dem '/' als Schreibpasswort und
+der zweite Teil als Lesepasswort geprüft. Falls kein '/' in dem Passwort enthalten ist,
+wird das Wort sowohl als Schreib- als auch als Lesepasswort interpretiert.
+
+Beispiel:
+In einer Manager-Task wird eine Datei "texte" eingerichtet, die Textvorlagen enthält.
+In einigen Sohn-Tasks soll diese Datei geholt (= gelesen) werden können. Die
+bearbeitete, somit veränderte Datei darf aber nicht zurück in die Vater-Task ge­
+schrieben werden.
+
+In der Vater-Task: enter password ("texte","-","psw")
+
+
+In der Sohn-Task : enter password ("psw")
+
+
+Falls das Passwort in einer Sohn-Task fehlerhaft oder gar nicht eingegeben wurde,
+erscheint die Meldung :
+
+____________________________________________________________________________
+
+ gib kommando :
+ fetch ("geschützte datei")
+FEHLER : Passwort falsch
+
+____________________________________________________________________________
+
+
+Somit kann diese Datei nur von Benutzern, die das Lesepasswort kennen, geholt
+werden. Ein Überschreiben der Datei ist nicht möglich, da das Schreibpasswort nicht
+gegeben werden kann ("-" !).
+#page#
+3.8. Monitor-Kommandos
+#free(1.0)#
+ALL
+ THESAURUS OP ALL (TASK CONST task)
+ Liefert einen Thesaurus#u#1)#e#, der alle Dateinamen der angegebenen Task enthält
+ (auch der Benutzer-Task 'myself').
+#foot#
+1) Ein Thesaurus ist eine Liste, in diesem Zusammenhang eine Liste von Dateien.
+ (Siehe auch 2.4. Die ELAN-Notation
+#end#
+ fetch (ALL father)
+
+ THESAURUS OP ALL (TEXT CONST datei)
+ Liefert einen Thesaurus, der die in 'datei' vorhandenen Dateinamen (jede Zeile ein
+ Name) enthält.
+
+ fetch (ALL "dateiliste")
+
+archive
+ PROC archive (TEXT CONST archivname)
+ Anmeldung von Archiv-Operationen. 'archivname' wird zur Überprüfung für alle
+ folgenden Archiv-Operationen verwandt, um die unberechtigte Benutzung eines
+ Archivs zu verhindern. Die Anmeldung wird abgelehnt, wenn ein anderer Nutzer
+ das Archiv belegt hat.
+
+
+ archive ("textdiskette")
+
+
+ TASK PROC archive
+ Liefert den internen Task-Bezeichner für die Verwendung in Dateikommandos.
+
+
+ save ("dateiname", archive)
+
+
+
+begin password
+ PROC begin password (TEXT CONST geheim)
+ Verhindert das unberechtigte Einrichten einer Sohn-Task.
+
+
+ begin password("gmd")
+
+
+break
+ PROC break
+ Die zum Terminal aktuell zugeordnete Task wird abgekoppelt. Sie wird damit zu
+ einer Hintergrund-Task.
+
+
+brother
+ TASK PROC brother (TASK CONST task)
+ Liefert den internen Task-Bezeichner der angegebenen "Bruder"-Task.
+
+
+ list(brother)
+
+
+check
+ PROC check (TEXT CONST dateiname, TASK CONST task)
+ Überprüft, ob die Datei 'dateiname' auf dem Archiv lesbar ist.
+
+
+ check ("meine datei", archive)
+
+
+ PROC check (THESAURUS CONST t, TASK CONST task)
+ Überprüft, ob die in dem Thesaurus 't' enthaltenen Dateien auf dem Archiv lesbar
+ sind.
+
+
+ check (ALL archive, archive)
+
+
+
+clear
+ PROC clear (TASK CONST task)
+ Löscht alle Dateien der Task 'ARCHIVE'und benennt die Diskette um, falls ein
+ anderer als der bisherige Diskettenname bei der Reservierung angegeben wurde.
+
+
+ archive("disk1"); clear(archive)
+
+
+copy
+ PROC copy (TEXT CONST quelle, ziel)
+ Kopiert die Datei 'quelle' in eine neue Datei mit dem Namen 'ziel' in der
+ Benutzer-Task.
+
+
+ copy("datei","neue datei")
+
+ Fehlerfälle: "ziel" existiert bereits
+ "quelle" gibt es nicht
+ zu viele Dateien
+
+
+edit
+ PROC edit
+ a) Im Monitor:
+ Ruft den Editor mit den zuletzt verwandten Dateinamen auf.
+ b) Im Editor:
+ Der Dateiname wird erfragt.
+ Für jedes 'edit' gilt:
+ Wurde 'edit' zum ersten Mal aufgerufen, nimmt das Fenster den gesamten
+ Bildschirm ein. Bei erneutem 'edit'-Aufruf wird ein Fenster nach rechts unten ab
+ der aktuellen Cursor-Position eröffnet.
+
+ PROC edit (TEXT CONST dateiname)
+ Ruft den Editor mit 'dateiname' auf.
+
+
+ edit("handbuch teil3")
+
+
+
+ PROC edit (TEXT CONST dateiname, x, y, xbreite, yhöhe)
+ Wie obiger 'edit'-Aufruf, jedoch kann das Fenster, in dem 'dateiname' editierbar
+ ist, gesetzt werden. Die Parameter definieren ein Editor-Fenster mit der linken
+ oberen Ecke auf den Bildschirmkoordinaten 'x' und 'y' und einer Zeilenbreite
+ 'xbreite' und 'yhöhe' Zeilen. Wird der Editor mit 'edit ("dateiname")' aufgerufen,
+ wird implizit 'edit ("dateiname", 1, 1, 79, 24)' aufgerufen.
+
+
+ edit("notiz",5,5,44,12)
+
+
+ PROC edit (THESAURUS CONST t)
+ Editieren aller in dem Thesaurus 't' enthaltenen Dateien nacheinander.
+
+
+ edit (ALL father)
+
+
+
+end
+ PROC end
+ Die zum Terminal aktuell gehörende Task wird abgebrochen und gelöscht.
+
+enter password
+ PROC enter password (TEXT CONST datei, schreibpass, lesepass)
+ Die angegebene Datei wird mit Schreib- und Lesepassword versehen. Die
+ Passwörter werden in der eigenen Task nicht berücksichtigt.
+ Falls der Schutz total sein soll, so ist für die verbotene Operation "-" als
+ Passwort anzugeben.
+
+
+ enter password ("daten","sicher","heit")
+
+
+ PROC enter password (TEXT CONST password)
+ Gibt Schreib- und Lesepasswort für den Austausch mit Manager-Task an. Falls
+ zwei verschiedene Passwörter für Lesen und Schreiben vereinbart sind, so sind
+ sie als ein Text durch "/" getrennt einzugeben.
+
+
+ enter password ("lese/schreibpasswort")
+
+
+erase
+ PROC erase (TEXT CONST datei)
+ Löscht eine Datei mit dem Namen 'name' in der unmittelbaren Vater-Task.
+
+
+ erase("alte datei")
+
+
+ Fehlerfälle:
+ "datei" gibt es nicht
+ Passwort falsch
+
+ PROC erase (TEXT CONST name, TASK CONST manager)
+ Löscht eine Datei mit dem Namen 'name' in der Task 'manager'.
+
+
+ erase ("dateiname", father)
+
+
+ PROC erase (THESAURUS CONST thesaurus)
+ Löscht die im 'thesaurus' angegebenen Dateien in der Vater-Task.
+
+
+ erase (ALL myself)
+ (* löscht alle Dateien in der Vater-Task, die in der
+ Benutzer-Task vorhanden sind *)
+
+
+ PROC erase (THESAURUS CONST thesaurus, TASK CONST manager)
+
+
+ erase (all,father)
+ (* löscht alle Dateien in der Vater-Task, die in der
+ Benutzer-Task vorhanden sind *)
+
+
+
+father
+ TASK PROC father
+ Liefert den internen Task-Bezeichner der Vater-Task der Benutzer-Task.
+
+
+ list(father)
+
+
+ TASK PROC father (TASK CONST task)
+ Liefert den internen Task-Bezeichner von 'task'.
+
+
+ save ("dateiname", father (father))
+ (* Kopiert 'dateiname' zum "Großvater" *)
+
+
+
+fetch
+ PROC fetch (TEXT CONST name)
+ Kopieren einer Datei von der Vater-Task in die Benutzer-Task
+
+
+ fetch("sicherungskopie")
+
+ Fehlerfälle:
+ "datei" gibt es nicht
+ Passwort falsch
+ zu viele Dateien
+
+
+ PROC fetch (TEXT CONST name, TASK CONST manager)
+ Kopieren einer Datei in die Benutzer-Task von 'manager'.
+
+
+ fetch ("dateiname", /"global")
+
+
+ PROC fetch (THESAURUS CONST thesaurus)
+ Holt alle im 'thesaurus' enthaltenen Dateien von der Vater-Task.
+
+
+ fetch (ALL)
+
+
+ PROC fetch (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: Holt alle im 'thesaurus' enthaltenen Dateien von der 'manager'-Task.
+
+
+ fetch (ALL /"global", /"global")
+
+
+forget
+ PROC forget (TEXT CONST datei)
+ Löschen einer Datei mit dem Namen 'name' in der Benutzer-Task.
+
+
+ forget ("alte datei")
+
+ Fehlerfälle:
+ "datei" gibt es nicht
+
+ PROC forget (THESAURUS CONST thesaurus)
+ Löscht die im 'thesaurus' enthaltenen Dateien in der Benutzer-Task.
+
+
+ forget (SOME myself)
+
+
+format
+ PROC format (THESAURUS CONST thes)
+ Formatieren von Disketten und Einstellen des Namens.
+
+
+ format(archive)
+
+
+ PROC format (INT CONST art, THESAURUS CONST thes)
+ Formatieren von Disketten im Nichtstandardformat des benutzten Geräts
+
+
+ format(2,archive)
+
+
+global manager
+ PROC global manager
+ Durch den Aufruf der Prozedur wird die Benutzer-Task zu einem Datei-
+ Manager. Danach können Söhne dieser Task eingerichtet werden.
+
+
+list
+ PROC list
+ Listet alle Dateien der Benutzer-Task mit Namen und Datum des letzten Zugriffs
+ auf dem Terminal auf.
+
+ PROC list (TASK CONST task)
+ Listet alle Dateien der angegebenen 'task' mit Namen und Datum der letzten
+ Änderung auf dem Terminal auf.
+
+
+ list (father)
+
+
+
+myself
+ TASK PROC myself
+ Liefert den internen Task-Bezeichner der Benutzer-Task.
+
+
+ save (ALL myself, father)
+
+
+
+public
+ TASK PROC public
+ Liefert den internen Task-Bezeichner von "PUBLIC".
+
+
+ fetch ("dateiname", public)
+
+
+
+rename
+ PROC rename (TEXT CONST altername,neuername)
+ Umbenennen einer Datei von 'altername' in 'neuername'.
+
+
+ rename("altes handbuch","neues handbuch")
+
+
+save
+ PROC save (TEXT CONST dateiname)
+ Datei 'dateiname' wird an die unmittelbare Vater-Task übertragen.
+
+
+ save("neues handbuch")
+
+
+ Fehlerfälle:
+ "neues handbuch" gibt es nicht
+ zu viele Dateien
+ Passwort falsch
+
+ PROC save (TEXT CONST name, TASK CONST task)
+ Datei mit dem Namen 'name' in Task 'task' kopieren
+
+
+ save ("dateiname", /"global")
+
+
+ Fehlerfälle:
+ "dateiname" gibt es nicht
+ zu viele Dateien
+ Passwort falsch
+
+ PROC save (THESAURUS CONST thesaurus)
+ Kopiert die Dateien, die in 'thesaurus' enthalten sind, in die Vater-Task.
+
+
+ save (SOME myself)
+
+
+ PROC save (THESAURUS CONST thesaurus, TASK CONST manager)
+ Kopiert die Dateien, die in 'thesaurus' enthalten sind, in Task 'manager'.
+
+
+ save(SOME myself, /"global")
+
+
+SOME
+ THESAURUS OP SOME (THESAURUS CONST thesaurus)
+ Bietet den angegebenen 'thesaurus' zum Editieren an. Dabei können nicht
+ erwünschte Namen gestrichen werden.
+
+ THESAURUS OP SOME (TASK CONST task)
+ Bietet einen THESAURUS von 'task' zum Editieren an.
+
+ THESAURUS OP SOME (TEXT CONST dateiname)
+ Bietet einen 'thesaurus', der aus 'dateiname' gebildet wird, zum Editieren an.
+
+
+task
+ TASK PROC task (TEXT CONST task name)
+ Liefert den internen Task-Bezeichner von 'task name'.
+
+
+ save ("dateiname", task ("PUBLIC"))
+ = save ("dateiname", public)
+
+
+
+storage info
+ PROC storage info
+ Informationsprozedur über den belegten Hintergrund-Speicher.
+
+
+task info
+ PROC task info
+ Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der
+ Vater/Sohn-Beziehungen (Angabe durch Einrückungen).
+
+ PROC task info (INT CONST art)
+ Informiert über alle Tasks im System. Mit 'art' kann man die Art der Zusatz-
+ Information auswählen. Für 'art' sind zur Zeit folgende Werte zugelassen:
+
+ art=1: entspricht 'task info' ohne Parameter, d.h. es gibt nur die Tasknamen
+ unter Angabe der Vater/Sohn-Beziehungen aus.
+
+ art=2: gibt die Tasknamen aus. Zusätzlich erhalten Sie Informationen über die
+ verbrauchte CPU-Zeit der Task, die Priorität, den Kanal, an dem die
+ Task angekoppelt ist, und den eigentlichen Taskstatus. Hierbei bedeuten:
+
+ 0 -busy- Task ist aktiv.
+ 1 i/o Task wartet auf Beendigung des Outputs oder auf
+ Eingabe.
+ 2 wait Task wartet auf Sendung von einer anderen Task.
+ 4 busy-blocked Task ist rechenwillig, aber blockiert.
+ 5 i/o -blocked Task wartet auf I/O, ist aber blockiert.
+ 6 wait-blocked Task wartet auf Sendung, ist aber blockiert.
+ Achtung: Die Task wird beim Eintreffen einer
+ Sendung automatisch entblockiert.
+
+ art=3: wie 2, aber zusätzlich wird der belegte Speicher angezeigt. (Achtung:
+ Prozedur ist zeitaufwendig!).
+
+
+ task info(2)
+
+
+task status
+ PROC task status
+ Informationsprozedur über den Zustand der eigenen Task. Informiert u.a. über
+ - Name der Task, Datum und Uhrzeit;
+ - verbrauchte CPU-Zeit;
+ - belegten Speicherplatz;
+ - Kanal, an den die Task angekoppelt ist;
+ - Zustand der Task (rechnend u.a.m.);
+ - Priorität.
+
+ PROC task status (TASK CONST t)
+ Wie obige Prozedur, aber über die Task mit dem internen Tasknamen 't'.
+
+
+ task status (father)
+
+
+
+task password
+ PROC task password (TEXT CONST geheim)
+ Einstellen eines Passworts für Benutzertask. Das Kommando 'task password' ist
+ ein Monitor-Kommando. Ist eine Task mit einem Paßwort geschützt, so wird
+ durch den Supervisor nach dem 'continue'-Kommando das Passwort angefragt.
+ Nur nach Eingabe des richtigen Passworts gelangt man in die gewünschte Task.
+ Das Passwort kann durch nochmaligen Aufruf von 'task password' geändert
+ werden, z.B. wenn es in regelmäßigen Abständen geändert werden muß, um
+ personenbezogene Daten zu schützen.
+
+ Es gibt keine Möglichkeit, ein einmal eingestelltes Passwort in Erfahrung zu
+ bringen. Sollte das Passwort vergessen werden, kann somit die Task nur noch
+ gelöscht werden.
+
+ Wird als Passwort ein '-'-Zeichen eingegeben, so wird verhindert, daß die
+ betreffende Task jemals wieder mit dem 'continue'-Kommando angekoppelt
+ werden kann. Dies ist z.B. für Manager-Tasks sinnvoll.
+
+
+ task password("mein geheimnis")
+
+
++
+ THESAURUS OP + (THESAURUS CONST links, rechts)
+ Vereinigungsmenge von 'links' und 'rechts'.
+
+ THESAURUS OP + (THESAURUS VAR thes, TEXT CONST name)
+ Nimmt den TEXT 'name' in den Thesaurus 'thes' auf.
+
+
+ save (SOME father + "rechnung", archive)
+
+
+
+-
+ THESAURUS OP - (THESAURUS CONST links, rechts)
+ Differenzmenge von 'links' und 'rechts'.
+
+ THESAURUS OP - (THESAURUS VAR thes, TEXT CONST name)
+ Liefert einen Thesaurus aus 'thes', aber ohne den Eintrag 'name'.
+
+
+ save (ALL myself - "rechnung", archive)
+
+
+
+/
+ THESAURUS OP / (THESAURUS CONST links, rechts)
+ Zweck: Schnittmenge von 'links' und 'rechts'.
+
+
+ save(ALL myself / ALL father, archive)
+
+
+ TASK OP / (TEXT CONST task name)
+ Liefert aus einem Tasknamen den internen Tasknamen. '/' kann überall dort
+ eingesetzt werden, wo ein interner Taskname verlangt wird.
+
+
+ fetch ("dateiname", /"global")
+
diff --git a/doc/user/benutzerhandbuch.4 b/doc/user/benutzerhandbuch.4
new file mode 100644
index 0000000..c13a091
--- /dev/null
+++ b/doc/user/benutzerhandbuch.4
@@ -0,0 +1,2242 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 4: Der Editor
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+4 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 4 - %
+#tableend##clearpos#
+#end#
+TEIL 4: Der Editor
+#free(1.0)#
+
+4.0. Vorwort
+
+#free(1.0)#
+Mit dem #ib#EUMEL-Editor#ie# schreiben Sie alle Ihre Texte und Daten. Er bietet vielfäl­
+tige Möglichkeiten, um Autoren oder Programmierer bei dem Erstellen, Korrigieren und
+Gestalten von Manuskripten oder Programmen zu unterstützen. Die größte Hilfe beim
+Schreiben besteht (durch die Speicherfähigkeit von Computern) im beliebig häufigen
+Zugriff auf einmal geschriebene Informationen. Im Gegensatz zu einer Schreibmaschi­
+ne können Sie mit dem EUMEL-Editor (beliebig oft) Einfügungen vornehmen, Texte
+korrigieren, löschen und neu gestalten.
+
+Somit ist das Schreiben von Texten mittels des EUMEL-Systems besonders dann
+vorteilhaft und zeitsparend, wenn Texte häufig geändert werden oder wenn sie in
+einer besonders schönen Form gedruckt werden sollen. Weiterhin bietet der Editor
+Hilfen zum Schreiben an, wie z.B. automatischen Wortumbruch am Zeilenende, eine
+Einrückungsautomatik, "Lernen" von Texten u.a.m. Zusätzlich kann der Editor in
+seinen Fähigkeiten erweitert und somit für spezielle Schreibarbeiten angepaßt werden.
+Aber das soll in einem späteren Kapitel beschrieben werden.
+
+Bei der Entwicklung des Editors wurde besonderer Wert auf einfache Bedienung
+gelegt: innerhalb von wenigen Minuten können Sie schon Texte schreiben und Daten
+erfassen und sehen stets auf dem Bildschirm, was mit Ihrem Text passiert. Das
+Schreiben und Korrigieren werden durch einige wenige, aber leistungsstarke Funk­
+tionstasten unterstützt.
+
+Einige Gestaltungsmöglichkeiten für Texte kann man nicht direkt auf dem Terminal
+"sehen", wie z.B. Proportionalschriften, Fettdruck usw. Solche Leistungen können
+durch Anweisungen an die Textkosmetik-Programme und den EUMEL-Drucker
+angefordert werden. Diese Anweisungen müssen in den Text eingefügt werden. Lesen
+Sie hierzu Teil 5 ("Textkosmetik").
+#free(1.0)#
+
+#ib(9)#4.1. #ib#Ein- und Ausschalten des Editors#ie##ie(9)#
+
+#free("1.0")#
+ #on("i")#
+ Hier beschreiben wir, wie der Editor ein- und ausgeschaltet wird und wie der
+ Editor eine Datei einrichtet.
+
+ #off("i")##free(1.0)#
+Wenn in Ihrer Task auf dem Bildschirm die Aufforderung
+
+____________________________________________________________________________
+
+gib kommando :
+
+____________________________________________________________________________
+
+
+erscheint, tippen Sie
+
+____________________________________________________________________________
+
+#ib#edit#ie# ("dateiname")
+
+____________________________________________________________________________
+
+
+und der EUMEL-Editor wird eingeschaltet. Ist die Datei noch nicht vorhanden, d.h.
+kein Text unter dem angegebenen Namen im System gespeichert, folgt eine Anfrage,
+ob eine Datei unter dem eingegebenen Namen neu eingerichtet werden soll:
+
+____________________________________________________________________________
+
+"dateiname" neu einrichten (j/n) ?
+
+____________________________________________________________________________
+
+
+Dies dient zur Kontrolle von Schreibfehlern, die besonders bei ähnlichen Dateina­
+men auftreten. Man kann dann das Einrichten der Datei ablehnen, den Dateinamen
+verbessern und das Kommando erneut geben.
+
+Falls Sie die Datei neu anlegen wollen, bejahen Sie diese Frage mit
+
+#center##taste1(" j ")# #taste1(" J ")# #taste1(" y ")# oder #taste1(" Y ")#
+
+
+Es erscheint ein leerer Editorbildschirm. Die oberste Zeile des Bildschirms ist die
+#ib#Titelzeile#ie#. In ihr kann nicht geschrieben werden. Sie zeigt jedoch verschiedene
+nützliche Dinge an: den Namen der Datei, die Nummer der aktuellen Zeile, in der
+gerade geschrieben wird, Tabulatormarken, Einfügemodus, Lernmodus, Auftrennung
+usw.
+
+____________________________________________________________________________
+
+ ................. dateiname ...................... Zeile 1
+_
+
+
+____________________________________________________________________________
+
+
+In unserem Fall haben Sie eine neue Datei angelegt. Sie enthält noch keinen Text. In
+der Titelzeile sind jedoch schon der Name der Datei und die aktuelle Zeilennummer
+eingetragen. Bei einer neuen Datei ist der Bildschirm unterhalb der Titelzeile leer.
+Dieser Teil dient als "Schreibfläche". Der #ib#Cursor#ie# steht dann direkt unter der Titelzei­
+le. Er zeigt immer die aktuelle #ib# Schreibposition#ie# an. Jetzt kann sofort mit dem Schrei­
+ben begonnen werden, ganz wie mit einer normalen Schreibmaschine.
+
+Rufen Sie eine Datei auf, in die Sie schon Text geschrieben haben, zeigt Ihnen der
+Editor das zuletzt bearbeitete Textstück und Sie können normal weiter schreiben.
+
+Wollen Sie die #ib#Schreibarbeit beenden#ie# und den #ib#Editor ausschalten#ie#, so drücken Sie die
+beiden Tasten
+
+<ESC> <q>
+
+nacheinander. Es erscheint
+
+____________________________________________________________________________
+
+gib kommando:
+
+____________________________________________________________________________
+
+
+und Sie haben damit den #ib#Editor verlassen#ie# und befinden sich wieder im Monitor. #page#
+
+#ib(9)#4.2. Die wichtigsten Tasten des Editors#ie(9)#
+#free(1.0)#
+#ib(9)#4.2.1. Das #ib#Tastenfeld#ie##ie(9)#
+
+#free(1.0)#
+ #on("i")#
+ Auf dem Tastenfeld gibt es einige Tasten, die auf einer Schreibmaschine nicht vor­
+ handen sind.
+
+ #off("i")#
+#free(1.0)#
+Das Tastenfeld eines EUMEL-Terminals entspricht weitgehend dem einer Schreib­
+maschine. Sie finden also die Buchstaben a-z und die Ziffern 0-9 auf Tasten. Mit
+der #ib#SHIFT-Taste#ie# (Umschalttaste) und gleichzeitigem Drücken einer anderen Taste
+können Sie die großen Buchstaben und eine Reihe von speziellen anderen Zeichen,
+die #ib#Sonderzeichen#ie# genannt werden, schreiben. Die "Zwischenraumtaste" oder Leer­
+taste erzeugt immer ein Leerzeichen.
+
+Nun gibt es in der Praxis zwei unterschiedliche Tastaturen. Zum einen existiert die
+#ib#EDV-Tastatur#ie#, die zum Schreiben von Programmen benutzt wird. Sie erkennt man
+daran, daß keine #ib#Umlaute#ie# (ä, ö, ü) und kein ß auf den Tasten abgebildet sind. Dafür
+gibt es Tasten für eckige und geschweifte Klammern. Sollen auf einer solchen Tasta­
+tur die Umlaute geschrieben werden, muß man sich eines Tricks bedienen: mit der
+Taste ESC und nachfolgendem Betätigen einer anderen Taste (z.B. a, o, u) erhalten
+wir den entsprechenden Umlaut.
+
+In der Regel kann man die Umlaute auf dem Bildschirm eines solchen EDV-Ter­
+minals nicht sehen, sondern sie erscheinen als "a", "u", usw. Beim Druck eines
+Textes werden sie aber richtig dargestellt.
+
+Die andere Tastatur entspricht in der #ib#Tastenbelegung#ie# weitgehend einer deutschen
+Schreibmaschine und besitzt Tasten für die Umlaute und ß. Sollen vorwiegend deut­
+sche Texte geschrieben werden, empfiehlt es sich, solch ein Terminal zu verwenden.
+
+
+
+ Tastatur
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Neben diesen "einfachen" Tasten gibt es die Funktionstasten, die zur Bedienung des
+Editors (aber auch anderer Programme) notwendig sind. Wo die Tasten auf Ihrem
+Gerät liegen, hängt von dem jeweiligen Gerätetyp ab. Die Wirkung der Tasten
+erklären wir in den anschließenden Abschnitten. #count("1")#) #foot#
+#value("1")#) Es kann sein, daß die Tasten nicht richtig beschriftet sind. Die Installations­
+ anleitung muß dann die Entsprechungen beschreiben. Zusätzlich zu den im
+ folgenden beschriebenen können sich noch weitere Tasten auf Ihrem Terminal
+ befinden, die aber standardmäßig keine besondere Bedeutung für den Editor
+ haben.
+#end#
+#page#
+Die Funktionstasten des EUMEL-Systems
+#l pos (0.0)##l pos(4.0)#
+
+
+<,>,v,^ Positionierungstasten
+#table#
+#free(0.5)#
+<SHIFT> Umschalttaste
+#free(0.5)#
+<CR> Eingabe-/ Absatztaste
+#free(0.5)#
+<HOP> Verstärkertaste
+#free(0.5)#
+<RUBOUT> Löschtaste
+#free(0.5)#
+<RUBIN> Einfügetaste
+#free(0.5)#
+<TAB> Tabulatortaste
+#free(0.5)#
+<MARK> Markiertaste
+#free(0.5)#
+<ESC> Kommandotaste
+#free(0.5)#
+<SV> Supervisortaste
+#free(0.5)#
+<STOP> Stoptaste
+#free(0.5)#
+<WEITER> Weitertaste
+#tableend##clear pos#
+
+
+#page#
+Die Wirkung der Funktionstasten
+#free(0.5)#
+<SHIFT>
+
+#ib#Umschalttaste#ie#
+
+Wird diese Taste gleichzeitig mit einer anderen betätigt, so wird ein Buchstabe in
+Großschreibung, bei den übrigen Tasten das obere Zeichen, ausgegeben. So wird z.B.
+anstelle der "9" das Zeichen ")" ausgegeben.
+#free(1.5)#
+<CNTL>
+
+#ib#Kontroll-/Steuertaste#ie#
+
+Mit dieser Taste in Kombination mit Zusatztasten können Sonderfunktionen des
+Systems angewählt werden. Für EUMEL sind folgende drei Tastenkombinationen
+(wobei die Tasten gleichzeitig betätigt werden müssen) wichtig:
+
+<CTRL> <a> Anhalten der Bildschirmausgabe
+
+<CTRL> <b> Wirkung der SV-Taste (bei jedem Rechner)
+
+<CTRL> <c> Bildschirmausgabe fortführen
+#l pos (0.0)##l pos(4.0)#
+
+
+#free(1.5)#
+<CR>
+
+#ib#Eingabetaste / Absatztaste#ie#, Carriage Return, kurz: 'CR'
+
+Diese Taste wird im Editor betätigt, um das Ende eines Absatzes zu kennzeichnen.
+Die kontinuierliche Fließtexteingabe wird durch sie unterbrochen und es wird an den
+Beginn der nächsten Zeile positioniert. Einrückungen werden beibehalten. Eine Ab­
+satzmarke ist im Editor an der Inversmarkierung am rechten Bildschirmrand zu erken­
+nen.
+
+Die 'CR'-Taste ist oft mit einem geknicktem Pfeil nach links gekennzeichnet. Im
+Kommandomodus (also bei "gib kommando :") wird durch Betätigung dieser Taste ein
+gegebenes Kommando ausgeführt.
+
+Die sonstige Benutzung dieser Taste außerhalb des Editors wird in der jeweiligen
+Anwendung beschrieben, z.B. Bestätigung eines Trennvorschlags bei der Silbentren­
+nung.
+
+<, >, v, ^
+
+Tasten für die Positionierung
+
+#ib#Positionierung des Cursors#ie# um eine Spalten-/Zeilenposition in die jeweilige Richtung.
+#free(1.5)#
+<HOP>
+
+"#ib#Verstärkertaste#ie#"; wird als Vorschalttaste bedient.
+
+In Kombination mit anderen Funktionstasten wird deren Wirkung verstärkt. (vgl.
+4-#topage("HOP")#)
+
+#on("u")#Beispiel:#off("u")#
+
+
+<HOP> <v>
+
+Steht der Cursor nicht am unteren Bildrand, so wird er dorthin positioniert. Steht er
+am unteren Bildrand, so wird um einen Bildschirminhalt "weitergeblättert".
+
+Auch die Funktionen 'RUBIN'/'RUBOUT' werden in Kombination mit der HOP-Taste
+verstärkt.(vgl. 4-#topage("verstärkt")#ff) #free(1.5)#
+<RUBOUT>
+
+#ib#Löschtaste#ie#
+
+Das Zeichen, auf dem der Cursor steht, wird gelöscht. Wenn der Cursor hinter dem
+letzten Zeichen einer Zeile steht, wie bei fortlaufender Eingabe üblich, wird das letzte
+Zeichen gelöscht.
+
+#on("u")#Beispiel:#off("u")#
+
+____________________________________________________________________________
+ ................. dateiname ...................... Zeile 4
+
+Mit der RUBOUT-Taste ist es möglich, ein
+Zeichen nach dem anderen auf dem Bildschirm
+zu löschen. Steht der Cursor auf einem
+Zeichen, das irrtümlicherweise eingetipp?t
+wurde, kann dieses durch einmaliges
+Betätigen der RUBOUT-Taste aus der Datei
+gelöscht werden.
+
+____________________________________________________________________________
+
+
+Nach Betätigen der <RUBOUT> - Taste:
+
+
+____________________________________________________________________________
+ ................. dateiname ...................... Zeile 4
+
+Mit der RUBOUT-Taste ist es möglich, ein
+Zeichen nach dem anderen auf dem Bildschirm
+zu löschen. Steht der Cursor auf einem
+Zeichen, das irrtümlicherweise eingetippt
+wurde, kann dieses durch einmaliges
+Betätigen der RUBOUT-Taste aus der Datei
+gelöscht werden.
+
+____________________________________________________________________________
+
+#page#
+
+
+<RUBIN>
+
+#ib#Ein- bzw. Ausschalten des Einfügemodus.#ie#
+
+Das Betätigen der Taste schaltet in den Einfügemodus.Der Zustand wird durch das
+Wort "RUBIN" im linken Drittel der Titelzeile der Datei angezeigt. Vor dem Zeichen,
+auf dem der Cursor steht, wird eingefügt. Nochmaliges Betätigen der Taste schaltet
+den Einfügemodus aus.
+
+#on("u")#Beispiel:#off("u")#
+
+
+____________________________________________________________________________
+ ................. dateiname ...................... Zeile 5
+
+Das Betätigen der Taste schaltet in den
+Einfügemodus. Der Zustand wird durch das
+Wort "RUBIN" im linken Drittel der Titelzeile
+angezeigt. Vor dem Zeichen, auf dem der
+Cursor steht, wird ' ' eingefügt.
+Nochmaliges Betätigen der Taste schaltet den
+Einfügemodus aus.
+
+____________________________________________________________________________
+
+
+
+Nach Betätigen der <RUBIN> - Taste und Einfügen des Wortes " jetzt":
+
+____________________________________________________________________________
+ .......RUBIN...... dateiname .....................
+Zeile 5
+Das Betätigen der Taste schaltet in den
+Einfügemodus. Der Zustand wird durch das
+Wort "RUBIN" im linken Drittel der Titelzeile
+angezeigt. Vor dem Zeichen, auf dem der
+Cursor steht, wird jetzt ' ' eingefügt.
+Nochmaliges Betätigen der Taste schaltet den
+Einfügemodus aus.
+
+____________________________________________________________________________
+
+
+
+<TAB>
+
+#ib#Tabulatortaste#ie#
+
+Betätigen Sie die 'TAB'-Taste, um vom linken Bildschirmrand auf den Textbeginn in
+der Zeile bzw. eine Tabellenspalte zu positionieren. Erneutes Betätigen der 'TAB'-
+Taste positioniert den Cursor auf die nächste eingestellte Tabulator-Position. Die
+eingestellten Tabulatorpositionen erkennen Sie an den Tabulatorzeichen (Dachzei­
+chen) in der obersten Bildschirmzeile.
+
+Wenn keine TABs gesetzt sind, werden die beiden Schreibgrenzen, linker Bildschirm­
+rand und Ende der Zeile, als #on("i")#voreingestellte# #off("i")# TABs angesehen.
+#free(1.5)#
+<MARK>
+
+#ib#Ein- bzw. Ausschalten der Markierung#ie#.
+
+Bei Betätigung dieser Taste wird in einen speziellen #ib#Markierzustand#ie# geschaltet. Alles,
+was Sie jetzt schreiben bzw. durch Bewegen des Cursors in Richtung Dateiende
+kennzeichnen, steht als #on("i")#markierter# #off("i")# Bereich für die Bearbeitung zur Verfügung. Zur
+besseren Sichtbarkeit wird der markierte Bereich invers zum übrigen Text dargestellt.
+
+Wird der Cursor in eine Richtung bewegt, wird das gesamte Textstück zwischen
+Einschaltpunkt der Markierung und aktueller Cursorposition markiert. Rückwärtsbewe­
+gungen des Cursors verkürzen den markierten Bereich wieder.
+
+Einen derart markierten Bereich können Sie nun z.B. duplizieren, verschieben, lö­
+schen, durchsuchen oder weiterverarbeiten. (vgl. 4- #topage("mark")# ff).
+
+Durch erneutes Betätigen der MARK-Taste schalten Sie den Markier-Zustand auch
+wieder aus.
+
+#on("u")#Beispiel:#off("u")#
+
+Sie wollen einen Textteil markieren, um ihn an eine andere Stelle zu verschieben
+(evtl. um ihn an dieser Stelle später zu löschen):
+
+Sie positionieren den Cursor auf den Beginn des Textteils, gehen in den Markierzu­
+stand durch Betätigen der MARK-Taste und führen nun den Cursor mit Hilfe der
+Positioniertasten bis zum Ende des zu markierenden Bereichs.
+
+
+____________________________________________________________________________
+ ................. dateiname ...................... Zeile 5
+
+Mit dem Cursor positionieren Sie an die
+Stelle, ab der markiert werden soll und
+betätigen die MARK-Taste. Nun führen Sie den
+Cursor bis zu der Stelle, bis zu der
+markiert werden soll. Der markierte Text wird
+normalerweise "schwarz auf weiss"
+dargestellt.
+
+____________________________________________________________________________
+
+
+
+Mit weiteren Kommandos (vgl. ESC-Taste und Kommando-Verarbeitung, 4- #topage("ESC")#)
+kann der Bereich nun bearbeitet werden.
+#free(1.5)#
+<ESC>
+
+#ib#Kommandotaste#ie#
+
+Mit der ESC-Taste in Kombination mit einer Folgetaste können Sie vordefinierte
+Aktionen anwählen. Es gibt Aktionen, die vorprogrammiert zur Verfügung stehen, und
+Sie selbst können weitere hinzufügen. (vgl. 4-#topage("ESC")# ) #free(1.5)#
+<SV>
+
+#ib#SUPERVISOR-Taste im Mehrbenutzer-Betrieb#ie#
+
+Betätigen Sie diese Taste im Editor, dann unterbrechen Sie Ihre Editierarbeit und
+erhalten die Meldung
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8/M
+
+
+ gib supervisor kommando:
+
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+
+____________________________________________________________________________
+
+
+Wollen Sie nun im Editor fortfahren bzw. haben Sie irrtümlich die SV-Taste betätigt,
+dann geben Sie das Kommando
+
+____________________________________________________________________________
+
+ gib supervisor kommmando :
+ continue ("Sekretariat")
+
+
+____________________________________________________________________________
+
+
+(falls Ihre Task, in der Sie arbeiteten, wirklich "Sekretariat" hieß!)
+
+Um Ihren in Bearbeitung befindlichen Text wieder vollständig auf dem Bildschirm zu
+sehen, betätigen die die Tasten
+
+<ESC> <b>
+
+Sie sind wieder an der Stelle, an der Sie den Text mit der SV-Taste verlassen ha­
+ben, und können normal weiterarbeiten.
+
+#on("u")#Achtung:#off("u")# Die SV-Taste kann, je nach Terminal, durch das Betätigen von zwei
+Tasten gleichzeitig realisiert sein (oft 'CTRL b'). Beachten Sie die Beschreibung Ihrer
+Tastatur!
+#free(1.5)#
+<STOP>
+
+#ib#Unterbrechen einer Ausgabe#ie# (oft auch als CTRL a realisiert).
+
+Haben Sie diese Taste aus Versehen betätigt, erkennen Sie dies daran, daß der
+Editor nicht "reagiert". Betätigen Sie die WEITER-Taste (oft auch CTRL c).
+#free(1.5)#
+<WEITER>
+
+Unterbrochene Ausgabe fortsetzen.
+
+Ein mit der STOP-Taste angehaltene Ausgabe können Sie durch Betätigen der
+#ib#WEITER-Taste#ie# fortsetzen.
+
+
+#on("u")#VORSICHT:#off("u")# Die STOP-Taste unterbricht nur die Ausgabe auf den Bildschirm.
+Zeichen, die während des STOP eingegeben werden, werden gespeichert und nach
+'WEITER' ausgegeben!
+
+
+#page#
+4.2.2 Speicherung von Texten
+#free(1.0)#
+ #on("i")#
+ In diesem Abschnitt wird der Begriff "Datei" erklärt und es wird erläutert, wie
+ unterschiedliche Texte auseinandergehalten werden können.
+ ## #off("i")#
+
+
+
+Das EUMEL-System speichert einmal geschriebene Texte, bis sie vom Benutzer
+gelöscht werden. In der Regel wird nicht nur ein (langer) Text oder ein Programm
+geschrieben, sondern mehrere und unterschiedliche. Um diese auseinanderhalten zu
+können, versehen wir sie jeweils mit einem Namen, der frei gewählt werden kann.
+Beispiele für Namen:
+
+
+ "Brief vom 1.12.86"
+ "1. Kapitel meines Buches"
+
+
+Eine Sammlung von Zeichen (also im Normalfall unsere geschriebenen Texte), die mit
+einem Namen versehen worden ist, nennt man eine #ib##on("bold")#Datei#ie##off("bold")#. Der Editor erstellt also eine
+Datei, wenn wir einen Text schreiben. Eine Datei kann bis zu 4 000 Zeilen fassen,
+wobei jede Zeile bis zu 32 000 Zeichen lang sein darf. Das Produkt aus der Anzahl
+der Zeilen und den Zeichen pro Zeile kann z.Zt. jedoch 1 000 000 Zeichen (=1MB)
+nicht übersteigen. #page#
+
+#ib(9)#4.2.3. #ib#Schreiben von Texten#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Texte werden fortlaufend geschrieben. Absätze werden durch die CR-Taste
+ markiert.
+ # #off("i")#
+
+#free(0.8)#
+
+Nach dieser etwas langen Vorrede können wir endlich losschreiben. Wird ein Zeichen
+geschrieben, rückt der #ib#Cursor#ie# automatisch nach rechts auf die nächste Schreibstelle.
+Durch den automatischen #ib#Wortumbruch#ie# werden angefangene Worte, die über ein
+Zeilenende hinausgehen würden, ohne Silbentrennung in die nächste Zeile gebracht.
+#u##count("6")#)#e#
+#foot#
+#u##value("6")#)#e# Nehmen Sie bitte keine Silbentrennung "per Hand" vor. Eingebrachte Trenn­
+ striche gelten als Bindestrich und bleiben somit auch bei Umformatierungen
+ erhalten, was unerwünscht ist. Für diese mühevolle Aufgabe gibt es in der Text­
+ verarbeitung ein Programm!
+#end#
+
+Die 'CR'-Taste (bei einer Schreibmaschine bedeutet sie "Wagenrücklauf") braucht
+also nur noch betätigt zu werden, wenn eine Zeile vorzeitig beendet werden soll, d.h.
+bei einem #ib#Absatz#ie# oder einer #ib#Leerzeile#ie#. Der Cursor wird dabei an den Anfang der
+nächsten Zeile positioniert. Gleichzeitig erscheint in der vorherigen Zeile am rechten
+Rand des Bildschirms eine Markierung, die anzeigt, daß hier ein Absatz gemacht
+wurde.
+
+Darum ist das Betätigen der 'CR'-Taste bei Tabellenzeilen und Programmtexten
+besonders wichtig, denn hier soll ja jede Zeile separat bleiben. Sie wirkt nur hinter
+dem letzten Zeichen.
+
+Der Editor ist auf das Schreiben von "normalen" Texten eingestellt. Bei normalen
+Texten soll ein Wort, welches über das Ende einer Zeile gehen würde, automatisch in
+die nächste Zeile gebracht werden. Diese Funktion wird "Wortumbruch" genannt.
+
+Ist kein Wortumbruch erwünscht, zum Beispiel bei der Beschreibung von Program­
+men, so geben Sie, bevor Sie den Editor aufrufen, im Monitor das Kommando
+
+____________________________________________________________________________
+gib kommando :
+#ib#word wrap (false)#ie#
+
+____________________________________________________________________________
+
+
+Der Wortumbruch kann durch das Kommando
+
+____________________________________________________________________________
+
+gib kommando :
+#ib#word wrap (true)#ie#
+
+____________________________________________________________________________
+
+
+wieder eingeschaltet werden. Der Editor ist standardmäßig auf "Wortumbruch" einge­
+stellt und Sie sollten nur in Ausnahmefällen diese Benutzungsart ausschalten.
+
+Ein Bildschirm faßt (neben der Titelzeile) üblicherweise 23 Zeilen, die mit Text be­
+schrieben werden können. Ist die letzte Zeile voll und muß eine neue Zeile begonnen
+werden, "rutscht" der Bildschirminhalt automatisch um eine Zeile nach oben. Damit
+ist Platz für eine Leerzeile, die nun ebenfalls beschrieben werden kann, usw. Keine
+Angst: die so verschwundenen Zeilen sind natürlich nicht "weg". Da ein Bildschirm
+immer nur eine beschränkte Anzahl von Zeilen hat, kann der Editor nur einen Aus­
+schnitt aus der Datei zeigen.
+#page#
+Einrückungen
+#free(1.0)#
+ #on("i")#
+ Die #ib#Einrückungautomatik#ie# erlaubt bei fortlaufendem Schreiben, die Einrückung zu
+ erhalten.
+ # #off("i")#
+#free(0.5)#
+Soll ein Text eingerückt werden, so betätigt man entsprechend oft die Leertaste. Die
+in dieser Zeile geschriebene Einrückung wird automatisch in den folgenden Zeilen
+beibehalten, bis sie durch die Cursor-Positionierungstasten wieder aufgehoben wird.
+
+#on("u")#Beispiele für Aufzählungen:#off("u")# Einrückung funktioniert automatisch ohne aktive Eingabe
+von Leerschritten.
+
+____________________________________________________________________________
+ ................. dateiname ...................... Zeile 1
+ - Der erste Typ der Aufzählungsform
+ ist die #ib#Aufzählung#ie# durch Voran­
+ stellen eines Sondersymbols.
+ Als Sondersymbole sind die beiden
+ Zeichen "-" und "*" zugelassen. An
+ ihnen erkennt der Editor eine
+ Aufzählung.
+
+ 12. Weiterhin können Aufzählungen
+ durch Begriffe, gefolgt von
+ einem Punkt oder einer ")", als
+ #ib#Aufzählungskriterium#ie# verwendet
+ werden.
+
+
+ Aufzählung: Auch diese Möglichkeit
+ steht Ihnen zur Verfü­
+ gung. Der Editor er­
+ kennt, daß Sie hier
+ einen Begriff erläutern
+ wollen.
+
+____________________________________________________________________________
+
+#page#
+Wann werden nun Aufzählungen vom Editor erkannt?
+
+Die hier aufgeführten Einzelheiten sollte nur der hieran interessierte Anfänger lesen!
+
+Wenn die Einrückung nicht funktionieren sollte, prüfen Sie die folgenden Punkte, die
+für das Einrücken erfüllt sein müssen:
+
+1) Die Vorgängerzeile hat eine Absatzmarke.
+
+ Wichtig: Innerhalb eines Aufzählungspunktes schaltet die Absatztaste die Aufzäh­
+ lungseinrückung aus!
+
+2) "*" bzw. "-" und mindestes ein Leerzeichen sind die ersten Zeichen in der
+ Zeile.
+
+3) "." bzw. ")" und mindestens ein Leerzeichen nach höchstens sieben Zeichen sind
+ die ersten Zeichen in der Zeile.
+
+4) ":" und mindestens ein Leerzeichen nach höchstens 19 Zeichen sind die ersten
+ Zeichen in der Zeile.
+#page#
+
+#ib(9)#4.2.4. #ib#Positionieren#ie# im Text#ie(9)#
+
+#free(1.0)#
+ #on("i")#
+ Um Korrekturen (Überschreiben, Löschen oder Einfügen) vorzunehmen, muß der
+ #ib#Cursor#ie#, der die aktuelle Schreibposition anzeigt, bewegt werden können. Bei
+ längeren Texten ist es möglich, den Cursor auch auf Zeilen zu positionieren, die
+ (noch nicht) auf dem Bildschirm angezeigt werden. Somit zeigt der Editor nicht nur
+ immer das Ende einer Datei, sondern einen beliebigen Ausschnitt, der auf dem
+ Bildschirm im sogenannten '#ib#Fenster#ie#' sichtbar ist.
+ #off("i")#
+#free(1.0)#
+Ist eine Korrektur notwendig, positionieren Sie den Cursor auf die Stelle, an der die
+Korrektur vorgenommen werden soll. Dazu verwenden Sie die #ib#Positionierungstasten#ie#
+LINKS, RECHTS, OBEN und UNTEN. LINKS und RECHTS bewegen den Cursor
+innerhalb einer Zeile. Stößt man mit RECHTS an das Ende einer Zeile, wird der
+Cursor an den Anfang der nachfolgenden Zeile bewegt.
+
+ v ^
+
+Ein #ib#Zeilenwechsel#ie# kann einfacher mit den Tasten OBEN und UNTEN vorgenommen
+werden. Die Taste OBEN bewegt den Cursor eine Zeile nach oben, die Taste UNTEN
+entsprechend eine Zeile tiefer.
+
+Was passiert nun, wenn Sie den unteren oder den oberen Rand des Bildschirms
+erreicht haben, und Sie positionieren darüber hinaus? In diesem Fall wird der Text
+zeilenweise nach oben oder nach unten verschoben und es erscheint die gewünschte
+Zeile, wobei am anderen Rand einige verschwinden". Wir sehen also, daß wir mit den
+Positionierungstasten den Bildschirm als Fenster über die Datei hinweggleiten lassen
+können. Den Text selbst können wir uns auf einem langen Band geschrieben vorstel­
+len. Die #ib#Zeilennummer#ie#, die die Position des Cursors angibt, wird stets in der Titel­
+zeile angezeigt.
+
+Vermeiden Sie es, den Cursor über das Textende hinaus nach unten laufen zu las­
+sen. Sie verlängern dadurch Ihren Text um Leerzeilen, die Sie beim Weiterschrei­
+ben nicht auffüllen, sondern vor sich herschieben.
+
+Innerhalb einer Zeile ist es etwas anders: Positionieren wir bei einer Zeile, die breiter
+als der Bildschirm ist, nach rechts, wird nicht das Fenster verschoben, sondern die
+Zeile 'gerollt'.(vgl. Sie hierzu das Verschieben des Gesamtfensters mit dem 'mar­
+gin'-Kommando 4-#topage("margin")#)
+4.2.5. Korrigieren im Text
+#free(1.0)#
+
+ #on("i")#
+ Einfache Korrekturen können durch #ib#Überschreiben von Zeichen#ie#, #ib#Löschen von
+ Zeichen#ie# und #ib#Einfügen von Zeichen#ie# vorgenommen werden.
+
+ #off("i")#
+#free(1.0)#
+<RUBOUT>
+
+Die einfachste Möglichkeit der Korrektur ist das #ib#Überschreiben#ie#. Soll z.B. ein Zeichen
+durch ein anderes ersetzt werden, so positioniert man der Cursor genau über dieses
+und tippt das richtige Zeichen ein. Das kann natürlich auch mit mehreren Zeichen
+nacheinander erfolgen.
+
+Korrekturen können Sie gleich beim Schreiben vornehmen, indem Sie die zuletzt
+geschriebenen Zeichen mit der #ib#RUBOUT-Taste#ie# löschen. Häufig bemerkt man aber
+#ib#Schreibfehler#ie# erst etwas später, so daß man diese Fehler nicht so leicht korrigieren
+kann. Für solche Zwecke müssen Sie den Cursor an die Textstelle bewegen, an der
+korrigiert werden soll.
+
+Wollen Sie ein #ib#Zeichen löschen#ie#, so positionieren Sie den Cursor auf dieses Zeichen
+und betätigen die Taste #ib#RUBOUT#ie#. Das Zeichen verschwindet und die Restzeile rückt
+heran. Sollen mehrere Zeichen gelöscht werden, muß die RUBOUT-Taste entspre­
+chend oft gedrückt werden.
+
+Steht der Cursor hinter dem letzten Zeichen der Zeile, wird immer das letzte Zeichen
+der Zeile gelöscht. Man kann also mit dieser Eigenschaft eine Zeile "von hinten
+wegradieren".(vgl. hierzu auch 4- #topage("ESC RUBOUT")#)
+
+
+
+<RUBIN>
+
+Fehlende Zeichen können Sie genauso einfach einfügen. Sie bringen den Cursor auf
+das Zeichen, vor das eingefügt werden soll. Dann drücken Sie die Taste #ib#RUBIN#ie#. Der
+Editor gelangt in den #ib#Einfügemodus#ie#, was in der Titelzeile durch RUBIN angezeigt
+wird. Er fügt alle Zeichen ein, die jetzt getippt werden (anstatt zu überschreiben). Der
+Teil der Zeile rechts vom Cursor rückt jeweils um entsprechend viele Stellen nach
+rechts.
+
+Wichtig ist, daß im RUBIN-Modus der Editor genauso funktioniert wie im Normalzu­
+stand (natürlich mit der Ausnahme, daß eingefügt statt überschrieben wird).
+
+Im eingeschalteten RUBIN-Modus können keine Zeichen verloren gehen. Viele
+Benutzer lassen darum den RUBIN-Modus immer eingeschaltet, um sich vor einem
+unbeabsichtigten Überschreiben von Texten zu schützen. Sie korrigieren, indem Sie
+die Verbesserung einfügen und den alten Text löschen.
+
+Durch erneutes Betätigen der RUBIN-Taste beenden Sie den Einfügemodus. Die
+RUBIN-Taste wirkt wie ein Schalter, der den Einfügemodus ein- und ausschaltet.
+Allerdings können Sie nur so viele Zeichen in eine Zeile einfügen, bis das letzte Wort
+der Zeile an das Zeilenende stößt. Das letzte Wort wird am Anfang der folgenden
+Zeile eingefügt, sofern dort noch Platz ist und es sich nicht offensichtlich um die
+letzte Zeile eines Absatzes handelt. Andernfalls wird automatisch eine neue Zeile für
+das angefangene Wort eingefügt.(vgl. Sie hierzu auch 4- #topage("ESC RUBIN")#) #free(1.5)#
+#page#
+Springen und Zeilen einfügen/löschen
+#free(1.0)#
+ #on("i")#
+ Bewegungen des Cursors sind mit den Positionierungstasten bei größeren "Ab­
+ ständen" etwas mühsam, ebenso bei umfangreichen Löschungen und Einfügun­
+ gen. Die "#ib#Verstärkertaste#ie#" HOP ermöglicht es, diese Operationen auf einfache
+ Weise zu beschleunigen. Mit der #ib#HOP-Taste#ie# kann man das Fenster über der
+ Datei nicht nur zeilenweise, sondern auch um jeweils eine Fensterlänge verschie­
+ ben. Das nennt man #ib#Blättern#ie#.
+
+ #off("i")#
+#free(1.0)#
+#goalpage("HOP")#
+Wird die HOP-Taste vor einer anderen der schon erklärten Funktionstasten gedrückt,
+verstärkt sie deren Wirkung. Die HOP-Taste ist eine "Präfix"-Taste: sie wird vor
+(und nicht gleichzeitig mit, wie z.B. die Umschalttaste SHIFT) einer anderen Taste ge­
+drückt. Zuerst das springende Positionieren:
+#free(1.0)#
+<HOP> <>>
+
+#ib#Sprung an das rechte Bildschirmende#ie#.
+
+Falls die Zeile länger als das Fenster breit ist, wird die Zeile um eine Fensterbreite
+nach links verschoben.
+#free(1.0)#
+<HOP> <<>
+
+#ib#Sprung an den Bildschirmrand links#ie# (ggf. seitlich blätternd).
+#free(1.0)#
+<HOP> <^>
+
+#ib#Sprung auf die erste Zeile des Bildschirms#ie#.
+
+Nochmaliges Betätigen dieser Tastenkombination positioniert den Cursor (und damit
+das Fenster in der Datei) um ein Fenster zurück. ("Blättern")
+#free(1.0)#
+<HOP> <v>
+
+#ib#Sprung auf die letzte Zeile des Bildschirms#ie#.
+
+Das Blättern erfolgt analog HOP OBEN.
+#free(1.0)#
+<HOP> <CR>
+
+Positioniert das Fenster so, daß die aktuelle Zeile zur ersten des Fensters wird.
+#free(1.0)#
+<HOP> <RUBIN>
+
+#ib#Einfügen von Textpassagen#ie#. #goalpage("verstärkt")# Die HOP-Taste in Verbindung mit RUBIN und
+RUBOUT wird zum "verstärkten" Löschen und Einfügen verwendet.
+
+Ab der aktuellen Position des Cursors "verschwindet" der restliche Text. Es kann wie
+bei der anfänglichen Texteingabe fortgefahren werden. Die Anzeige '#ib#REST#ie#' in der
+Titelzeile erinnert daran, daß noch ein Resttext existiert. Dieser erscheint nach einem
+neuerlichen Betätigen der beiden Tasten HOP RUBIN wieder auf dem Bildschirm (die
+Anzeige 'REST' verschwindet dann wieder).
+
+____________________________________________________________________________
+ ................. dateiname ...................... Zeile 4
+
+In diesem Text soll vor dem zweiten Satz
+etwas eingefügt werden. #cursor("H")#ierzu wird der
+Cursor an die Position geführt, an der
+ein beliebiger Text eingefügt werden soll.
+
+____________________________________________________________________________
+
+
+Nach Betätigen der Tasten <HOP> und <RUBIN> sieht der Bildschirm wie folgt
+aus:
+
+____________________________________________________________________________
+ ............... dateiname .........REST.......... Zeile 4
+
+In diesem Text soll vor dem zweiten Satz
+etwas eingefügt werden.
+
+
+____________________________________________________________________________
+
+
+
+Nun kann beliebig viel Text eingefügt werden. Nochmaliges Betätigen von HOP und
+RUBIN führt den Text-Rest wieder bündig heran.
+
+
+<HOP> <RUBOUT>
+
+Löscht die Zeile ab Cursor-Position bis Zeilenende.
+
+
+____________________________________________________________________________
+ ................. dateiname ...................... Zeile 4
+
+Soll eine ganze Zeile oder ein Textrest
+gelöscht werden, so positioniert man an die
+Stelle, ab der gelöscht werden soll. 'R'est löschen....
+Nach HOP RUBOUT ist der Zeilenrest gelöscht.
+
+
+____________________________________________________________________________
+
+
+Nach Betätigen der Tasten <HOP> und <RUBOUT> sieht der Bildschirm wie
+folgt aus:
+
+____________________________________________________________________________
+ ................. dateiname ...................... Zeile 4
+
+Soll eine ganze Zeile oder ein Textrest
+gelöscht werden, so positioniert man an die
+Stelle, ab der gelöscht werden soll.
+Nach HOP RUBOUT ist der Zeilenrest gelöscht.
+
+____________________________________________________________________________
+
+
+
+Steht der Cursor am Zeilenanfang, wird nach HOP RUBOUT dementsprechend die
+ganze Zeile gelöscht und die Lücke durch Nachrücken der Folgezeilen geschlossen
+(HOP RUBOUT betätigen).
+#page#
+Zeilen aufbrechen und Rückumbruch
+
+#free(1.0)#
+ #on("i")#
+ Um grössere Textpassagen einzufügen, betätigt man #ib#HOP RUBIN#ie# nacheinander.
+ Diese Tastenfolge kann benutzt werden, um eine Zeile bzw. eine längere Textpas­
+ sage aufzubrechen). #ib#HOP RUBOUT#ie# am Ende einer Zeile macht einen #ib#Rückum­
+ bruch#ie#.
+
+ #off("i")#
+#free(1.0)#
+<HOP> <RUBIN>
+
+Wie bereits beschrieben, bewirkt #ib#HOP RUBIN#ie# in einer Zeile, daß der Zeilenrest rechts
+des Cursors und alle Zeilen unterhalb der aktuellen Zeile scheinbar verschwinden.
+#ib#REST#ie# in der Titelzeile erinnert daran, daß ein Teil der Datei nicht sichtbar ist.
+
+Wird unmittelbar nach HOP RUBIN wiederum HOP RUBIN betätigt, wird der vorherige
+Zeilenrest als eigenständige Zeile dargestellt. Es ist damit eine Aufspaltung einer Zeile
+in zwei Zeilen vollzogen.
+
+
+<HOP> <RUBOUT>
+
+Der umgekehrte Fall, nämlich zwei Zeilen zu einer zusammenzufassen (sog. #ib# Rück­
+umbruch#ie#), ist durch #ib#HOP RUBOUT#ie# hinter dem letzten Zeichen einer Zeile möglich.
+Hinter das letzte Zeichen einer Zeile kann einfach mit dem Tabulator positioniert
+werden.
+
+Das Aufbrechen einer Zeile und der Rückumbruch zusammen angewandt stellen den
+ursprünglichen Zustand wieder her. Beispiel: Mit HOP RUBIN bricht man eine Zeile
+auf, der Rest der Zeile und nachfolgende Zeilen verschwinden vom Bildschirm. Erneu­
+tes HOP RUBIN stellt den rechten Zeilenteil auf der nächsten Zeile und die nachfol­
+genden Zeilen auf dem Bildschirm wieder dar. Da der Cursor sich noch immer am
+rechten Rand der aufgebrochenen Zeile befindet, kann man mit HOP RUBOUT den
+ursprünglichen rechten Zeilenteil wieder rekombinieren.
+#page#
+
+
+#ib(9)#4.2.6. Der #ib#Tabulator#ie##ie(9)#
+
+#free(1.0)#
+ #on("i")#
+ Eine weitere wichtige #ib#Positionierungshilfe#ie# innerhalb einer Zeile ist die #ib#TAB#ie#-Taste.
+ Sie wird u.a. zum Schreiben von Tabellen benötigt. Wie bei einer Schreibmaschine
+ können #ib#Tabulatormarken#ie# gesetzt bzw. gelöscht werden.
+
+ #off("i")#
+#free(1.0)#
+<TAB>
+
+Der Tabulator hat eine wichtige Funktion für das schnelle Positionieren, auch wenn
+keine Marken eingestellt wurden. #ib#Voreingestellte Tabulatormarken#ie# sind nämlich der
+Textanfang einer Zeile (Einrückung, falls vorhanden) und die Stelle direkt hinter dem
+letzten Zeichen der Zeile. Betätigt man also die Taste TAB, dann springt die Schreib­
+marke an die nächste dieser voreingestellten Positionen. So kann man schnell mit
+dem Cursor an den Anfang oder das Ende einer Zeile gelangen (und z.B. am Zeilen­
+ende Zeichen "von hinten" löschen oder dort weiterschreiben).
+
+<HOP> <TAB>
+
+Nun zum #ib#Setzen des Tabulators#ie#: Sie setzen ihn, indem Sie den Cursor auf die Zei­
+lenposition bringen, in der die Marke plaziert werden soll. Hier betätigen Sie nun #ib#HOP
+TAB#ie#. Die Tabulatorsetzung kann man in der Titelzeile an einer Markierung ("Dach­
+"-Zeichen) sehen, falls sie im Fensterbereich ist und die aktuelle Zeile nicht seitlich
+verschoben ist. Betätigt man nun an irgendeiner Position innerhalb einer Zeile die
+TAB-Taste, wird der Cursor auf die Position der nächsten Tabulatormarkierung (die
+sich rechts von dem Cursor befindet) oder eine der voreingestellten Positionen be­
+wegt.
+
+#ib#Gesetzte Tabulatormarken#ie# können gelöscht werden, indem man mit der TAB-Taste
+die Position der Tabulatormarke einstellt und dann HOP TAB betätigt. Die Marke ist
+dann gelöscht, das Dach verschwindet in der Titelzeile.
+
+Tabulatormarkierungen hinterlassen keine Spuren in der Datei, sondern dienen nur als
+Positionierungshilfen. mit 'HOP TAB' gesetzte Markierungen, die mit 'TAB' ange­
+sprungen werden, wirken beim Schreiben von Zahlen wie Dezimaltabulatoren, vgl. Sie
+dazu 4- #topage("zahlen")#.
+
+#on("u")#Beispiel:#off("u")#
+
+Es soll für den Textbeginn eine Tabulatorposition auf die 12. Spalte gesetzt werden.
+Hierzu wird der Cursor auf die 12. Spalte positioniert und die HOP- und die TAB-
+Taste nacheinander betätigt. Das "Dach"-Zeichen erscheint in der 12. Spalte in der
+Titelzeile und von nun an kann durch Betätigen der TAB-Taste diese Position direkt
+angesteuert werden.
+
+____________________________________________________________________________
+ ..........^....... dateiname ...................... Zeile 4
+
+HOP TAB wurde in der 12. Spalte betätigt.
+ Mit TAB stehen Sie auf der 12.
+ Spalte.
+
+____________________________________________________________________________
+
+
+Werden #ib#Tabulatormarken#ie# gesetzt (HOP TAB), gelten die voreingestellten Tabulator­
+marken (Anfang und Ende einer Zeile) nicht mehr. Dies ist z.B. bei dem Schreiben
+von Tabellen notwendig. Andererseits möchte man beim Schreiben von "normalem"
+Text wieder die voreingestellten Tabulatormarken bedienen können. Mit den Tasten
+
+<ESC> <TAB>
+
+kann man die gesetzten Tabulatormarken (erkenntlich an dem "Dach"-Zeichen in
+der Kopfzeile) vorübergehend verschwinden lassen. Dann gelten wieder die voreinge­
+stellten Marken. Erneutes #ib#ESC TAB#ie# stellt die gesetzten Tabulatormarken wieder her
+usw..
+#free(1.5)#
+Zahlentabellen schreiben: Dezimaltabulator
+#goalpage("zahlen")#
+
+#free(1.0)#
+ #on("i")#
+ Beim Schreiben von #ib#Zahlentabellen#ie# sollen die Zahlen oft rechtsbündig im Text
+ erscheinen. Dazu bietet der Editor den #ib#Dezimaltabulator#ie# an.
+
+ #off("i")#
+#free(1.0)#
+Für jede Zahlenkolonne wird die gewünschte Position der Einerstelle (also der letzten
+Stelle) mit Hilfe eines Tabulators eingestellt. Mit #ib#TAB#ie# wird der Cursor zur jeweils
+nächsten Tabulatormarke vorgerückt. Werden nun Ziffern geschrieben, so schreibt
+man nicht - wie gewohnt - nach rechts, sondern die Ziffern werden nach links
+eingerückt. Etwas genauer: Beim Drücken einer Zifferntaste wird, solange links vor
+der Zahl noch ein Blank, eine Zahl, "+", "-" oder ein Punkt sichtbar ist, diese
+gelöscht und die hierdurch neu entstandene Ziffernfolge rechtsbündig an der Tabula­
+torposition geschrieben. Das Schreiben von rechtsbündigen Zahlenkolonnen ist so
+leicht möglich #count("11")#):
+#foot#
+#value("11")#) Wird eine #ib#Proportionalschrift#ie# (Schrift, bei der die Zeichen unterschiedliche
+ Breiten haben) verwendet, sollte man zwischen den einzelnen Zahlenkolonnen
+ mindestens zwei Leerzeichen schreiben. Andernfalls bekommt man - auf Grund
+ der unterschiedlicher Zeichenbreiten - keine rechtsbündigen Kolonnen gedruckt.
+#end#
+
+
+ 12 12345,78
+ 1 0,23
+ 12345 1234,00
+
+
+
+Es gibt somit vier nützliche Automatiken: neben dem automatischen Dezimaltabulator
+den Wortumbruch, die Einrückautomatik und die Zeileneinfügeautomatik beim ein­
+fügenden Schreiben.
+4.2.7. Lernen im Editor
+
+#free(1.0)#
+
+ Beliebige Folgen von Tastenbetätigungen können gelernt und Tasten zugeordnet
+ werden. Das ist sinnvoll, wenn Sie wiederholt immer die gleichen Tastenbetä­
+ tigungen ausführen müssen, wie z.B. in Tabellenzeilen etwas einfügen oder wenn
+ des öfteren gleiche Texte geschrieben werden müssen, wie z.B. ein Absender,
+ Grußformeln usw.
+ #goalpage("ESC")#
+ #free(1.0)#
+< ESC> <HOP>
+
+Der #ib#Lernmodus#ie# wird durch Betätigen der Tasten #ib#ESC HOP#ie# eingeschaltet, es erscheint
+#ib#LEARN#ie# als Kontrolle rechts in der Titelzeile). Alle Tastenanschläge werden jetzt bis
+zum Ausschalten des Lernmodus gelernt. Auch Tastenanschläge wie 'CR'), so daß
+man kann demnach auch mehrere Zeilen lernen lassen kann.
+
+<ESC> <HOP> <'taste'> z.B. ESC HOP j
+
+Das Beenden oder Ausschalten des Lernmodus erfolgt durch Drücken der drei Tasten
+#ib#ESC HOP 'taste'#ie#. Dabei wird die gelernte Tastenanschlagsfolge, auch #ib#Lernsequenz#ie#
+genannt, der Taste 'taste' zugeordnet.
+
+<ESC> <'taste'> z.B. ESC j
+
+Durch späteres Betätigen der Tastenfolge ESC 'taste' kann der gelernte Text an jeder
+Stelle der Datei geschrieben werden.
+
+#on("u")#Beispiel:#off("u")#
+
+Ein Sachbearbeiter hat jeden Tag 50 mal die Worte 'Gesellschaft für Datenverarbei­
+tung' zu tippen. Er läßt den Editor diese Worte lernen mit
+
+
+ESC HOP Gesellschaft für Datenverarbeitung ESC HOP m
+
+Die Worte liegen jetzt auf der Taste 'm'. Wird 'm' gedrückt, erscheint ein 'm' auf dem
+Bildschirm. Mit ESC 'm' erscheinen die obigen Worte. ESC ist also notwendig, um
+das normale 'm' von der Lernsequenz zu unterscheiden.
+
+Welche Tasten dürfen zum #ib#Lernen#ie# belegt werden? Alle Tasten, außer
+
+- vom System benutzte Tasten, wie SV, CTRL;
+- vom Editor (je nach Anwendung) vorbelegte Tasten, wie die Tasten q oder ESC
+ und HOP;
+- durch Programmierung (siehe dieses Kapitel) fest belegte Tasten.
+
+Praktische Tips: Man sollte die Tastatur nicht mit Lernsequenzen überlasten, weil man
+sich zu viele Tasten nicht merken kann. Besser ist es, einige wenige Tasten fest zu
+belegen und andere für momentane Aufgaben einzusetzen.
+
+Der Einsatz von #ib#Lernsequenz#ie#en ist besonders sinnvoll für das Schreiben von Text­
+kosmetikanweisungen. Anweisungen wie z.B. 'Unterstreichen einschalten', Schrift­
+typ-Anweisungen usw. werden zweckmäßigerweise auf Tasten gelegt.
+
+Hat man sich einmal beim '#ib#Lernen#ie#' verschrieben, so ist das nicht weiter schlimm: es
+kann ohne Bedenken korrigiert werden (z.B. mit der Taste RUBOUT). Solche Tasten­
+anschläge werden dann allerdings auch gelernt, was aber bei der Benutzung der
+Lernsequenzen keine Bedeutung hat.
+4.2.8. Textabschnitte durch Markieren bearbeiten
+
+#free(1.0)#
+ #on("i")#
+ Oft ergibt sich die Notwendigkeit, mehrere Zeilen oder ganze Textpassagen zu
+ löschen oder zu verschieben. Hierbei hilft die Taste #ib#MARK#ie#, mit der man #ib#Texte
+ markieren#ie# (also kennzeichnen) kann. Die so markierten Texte können dann auf
+ verschiedene Weisen als Ganzes verarbeitet werden.
+ #goalpage("ESC")#
+
+ #free(1.0)#
+<MARK>
+
+Durch Drücken der Taste MARK wird die #ib#Markierung#ie# eingeschaltet und - bei erneu­
+ter Betätigung - wieder ausgeschaltet. Der Anfang der Markierung wird "festgehal­
+ten" und man kann nun das Markierende durch die Positionierungstasten und die
+HOP-Taste in Richtung auf das Dateiende verschieben, wobei die dazwischen lie­
+genden Zeichen markiert (in der Regel "schwarz auf weißem Grund" dargestellt)
+werden.
+
+
+<ESC> <RUBOUT>
+
+Ein so markierter Text kann mit #ib#ESC RUBOUT#ie# gelöscht werden. #ib#Markieren und
+löschen#ie# mit ESC RUBOUT ist eine bequeme und sichere Löschmethode, da man
+genau sieht, was gelöscht wird.#goalpage("ESC RUBOUT")#
+
+
+<ESC> <RUBIN>
+#goalpage("ESC RUBIN")#
+
+Der gelöschte Abschnitt ist aber nicht vollständig gelöscht, sondern er kann an ande­
+rer (oder an der gleichen) Stelle im Text durch #ib#ESC RUBIN#ie# wieder eingefügt werden.
+Der vorsichtig gelöschte Text landet in einem #ib#Zwischenspeicher#ie# und kann bei Bedarf
+mit #ib#ESC RUBIN#ie# wieder aufgerufen werden. Wird erneut vorsichtig gelöscht, so wird
+der letzte Text des Zwischenspeichers überschrieben. Im Zwischenspeicher ist nur für
+einen #on("u")#Text#off("u")# Platz. Auf diese Art kann ein Textabschnitt beliebiger Länge an eine
+andere Stelle des Textes sicher, schnell und bequem verschoben werden. Zusätzlich
+ist die nachträgliche Korrektur von fehlerhaften Löschungen möglich, weil der Text
+wieder mit ESC RUBIN reproduziert werden kann.
+
+Mit eingeschalteter Markierung kann auch geschrieben werden. Das #ib#markierende
+Schreiben#ie# ist eine besonders vorsichtige Art der Texterstellung, denn der Textein­
+schub bleibt erst durch Ausschalten der Markierung (MARK) wirklich bestehen. Er
+kann wieder gelöscht (ESC RUBOUT) und an eine andere Stelle gebracht werden
+(ESC RUBIN). Beim markierenden Schreiben wirkt RUBOUT immer auf das Zeichen
+vor der Cursorposition.
+
+Hinweis: Positionierungen sind nur innerhalb der Markierung möglich.
+#page#
+4.2.9. Der Fenstereditor
+#free(1.0)#
+
+ #on("i")#
+ Oft ist es notwendig, mit mehreren Dateien gleichzeitig zu arbeiten, z.B. wenn aus
+ einer Datei etwas in eine andere kopiert werden muß, wenn Fehler durch die
+ Textkosmetik-Programme oder einen Compiler gefunden werden oder wenn man
+ kurz etwas in einer anderen Datei nachschauen will. Zu diesem Zweck bietet der
+ Editor die Möglichkeit, zwei (oder mehr) Dateien zur gleichen Zeit zu bearbeiten. #off("i")#
+
+
+#free(1.0)#
+Der Editor ermöglicht dem Benutzer wie durch ein Fenster auf den zu bearbeitenden
+Text zu schauen. Es ist in diesem Zusammenhang nur natürlich, daß man bei der
+Bearbeitung eines Textes sich die Möglichkeit wünscht, weitere Texte gleichzeitig
+ansehen zu können. Dies kann notwendig sein, um zu vergleichen, Fehler zu entdek­
+ken oder Textteile aus einem Fenster in ein anderes zu übertragen.
+
+Um ein neues Editor-Fenster zu "öffnen", betätigt man im Editor
+
+<ESC> <e>
+
+Betätigt man ESC e ungefähr in der Mitte des Bildschirms, hat man das Fenster auf
+die neue Datei in der unteren Hälfte des Bildschirms und die "alte" Datei in der
+oberen Bildschirmhälfte. Zunächst wird der Dateiname erfragt. Nach dessen Eingabe
+und dem Betätigen der 'CR' Taste wird ein Fenster auf eine andere Datei eröffnet.
+Die obere linke Ecke des Fensters befindet sich an der aktuellen Cursor-Position.
+Dabei darf sich der Cursor nicht zu sehr am rechten oder unteren Rand befinden, weil
+das Fenster sonst zu klein würde. In diesem "Fenster" kann man dann genauso
+arbeiten wie im "normalen" Editor.
+
+
+Mit der Tastenfolge
+
+<ESC> <w>
+
+wechselt man von einem Fenster (zyklisch) in das benachbarte. Es gibt eine Hier­
+archie zwischen den Fenstern in der Reihenfolge, in der eines im anderen einge­
+richtet worden ist. Gibt man
+
+<ESC> <q>
+
+in einem Fenster, so verschwindet dieses und alle darin eingeschachtelten Fenster,
+und man befindet sich im übergeordneten Fenster.
+
+Wir schilderten zuvor, daß man mit ESC RUBOUT und ESC RUBIN Texte verschie­
+ben und löschen kann. Zwischen Dateien im Fenstereditor geht dies folgendermaßen:
+
+Durch
+
+<ESC> <p> oder <ESC> <d>
+
+schreibt man einen markierten Teil in eine temporäre Datei (einen Zwischenspeicher);
+durch ESC p wird ein markierter Text aus der Ursprungsdatei entfernt und in einen
+Zwischenspeicher geschrieben. Im Gegensatz dazu wird er durch ESC d kopiert.
+Durch
+
+<ESC> <g>
+
+fügt man ihn in eine andere (oder dieselbe) Datei ein. Im Unterschied zu ESC RUBIN
+wird die temporäre Datei dadurch nicht entleert.
+
+Die Funktionen ESC d und ESC g leisten auf schnellere Weise dasselbe wie die
+Kommandos 'PUT ""' und 'GET ""'.
+#page#
+4.2.10. Die wichtigsten vorbelegten Tasten
+#free(1.0)#
+
+ #on ("i")#
+ Lernsequenzen und Kommandos (d.h. ELAN-Programme) können Tasten zuge­
+ ordnet werden. Da einige Funktionen häufig benötigt werden, sind diese stan­
+ dardmäßig bestimmten Tasten zugeordnet. #off("i")#
+
+
+
+#free(1.0)#
+#ib#ESC q#ie# Verlassen des Editors bzw. der eingeschachtelten Fenster.
+
+#ib#ESC e#ie# Weiteres Editorfenster einschalten.
+
+#ib#ESC n#ie# Notizbuch "aufschlagen".
+
+#ib#ESC v#ie# Dateifenster auf ganzen Bildschirm vergrößern
+ bzw. Bildschirm rekonstruieren (eingeschachteltes Fenster verlas­
+ sen).
+
+#ib#ESC w#ie# Dateiwechsel beim Fenstereditor.
+
+#ib#ESC f#ie# Nochmalige Ausführung des letzten Kommandos.
+
+#ib#ESC b#ie# Das Fenster wird auf den linken Rand der aktuellen (ggf. verscho­
+ benen) Zeile gesetzt.
+
+ESC > Zum nächsten Wortanfang.
+
+ESC < Zum vorherigen Wortanfang.
+
+#ib#ESC 1#ie# Zum Anfang der Datei.
+
+#ib#ESC 9#ie# Zum Ende der Datei.
+#page#
+Lernen
+
+
+#ib#ESC HOP#ie# Lernen einschalten.
+
+#ib#ESC HOP taste#ie# Lernen ausschalten und Lernsequenz auf 'taste' legen.
+
+#ib#ESC HOP HOP#ie# Gelerntes vergessen. Bedingung ist, daß man die Lernsequenz in
+ der Task löscht, in der man sie hat lernen lassen.
+#free(1.0)#
+Operationen auf Markierungen
+
+#free(1.0)#
+#ib#ESC RUBOUT#ie# Markiertes "vorsichtig" löschen.
+
+#ib#ESC RUBIN#ie# Vorsichtig mit ESC RUBOUT Gelöschtes einfügen.
+
+#ib#ESC p#ie# Markiertes löschen und in die Notiz-Datei schreiben. Kann mit ESC
+ g an anderer Stelle reproduziert werden.
+
+#ib#ESC d#ie# Duplizieren:
+ Markiertes in die Notiz-Datei kopieren (PUT ""), anschließend die
+ Markierung abschalten. Kann mit ESC g beliebig oft reproduziert
+ werden.
+
+#ib#ESC g#ie# MIT ESC p gelöschten oder mit ESC d duplizierten Text an aktuelle
+ Cursor-Stelle schreiben, d.h. Notiz-Datei an aktueller Stelle einfü­
+ gen (GET "").
+#free(1.0)#
+#on("b")#Zeichen schreiben#u#1#e#
+#off("b")#
+#foot#
+1) Diese Tasten sind standardmäßig so vorbelegt wie hier aufgeführt, sie könne aber
+von Benutzern und in Anwenderprogrammen geändert werden.
+#end#
+#free(0.5)#
+#ib#ESC a#ie# Schreibt ein ä.
+#ib#ESC A#ie# Schreibt ein Ä.
+#ib#ESC o#ie# Schreibt ein ö.
+#ib#ESC O#ie# Schreibt ein Ö.
+#ib#ESC u#ie# Schreibt ein ü.
+#ib#ESC U#ie# Schreibt ein Ü.
+#ib#ESC s#ie# Schreibt ein ß.
+#ib#ESC (#ie# Schreibt eine [.
+#ib#ESC )#ie# Schreibt eine ].
+#ib#ESC <#ie# Schreibt eine {.
+#ib#ESC >#ie# Schreibt eine }.
+#ib#ESC \##ie# Schreibt ein \#, das auch gedruckt werden kann.
+#ib#ESC ­#ie# Schreibt einen (geschützten) Trennstrich, siehe Textverarbeitung.
+#ib#ESC k#ie# Schreibt ein (geschütztes) "k", siehe Textverarbeitung.
+#ib#ESC blank#ie# Schreibt ein (geschütztes) Leerzeichen, siehe Textverarbeitung.
+#free(1.0)#
+Kommando auf Taste legen
+
+#free(1.0)#
+#ib#ESC ESC#ie# Kommandodialog einschalten
+
+#ib#ESC ! taste#ie# Im Kommandodialog:
+ Geschriebenes Kommando auf Taste legen.
+
+#ib#ESC ? taste#ie# Im Kommandodialog:
+ Auf 'taste' gelegtes Kommando zum Editieren anzeigen.
+
+#ib#ESC k#ie# Im Kommandodialog:
+ Das zuletzt editierte Kommando (einzeilige ELAN-Programm)
+ anzeigen.
+
+Eine ausführliche Beschreibung des Kommandodialogs finden Sie im folgenden Kapi­
+tel.
+4.3. Die wichtigsten Editor-Kommandos
+#goalpage("ESC")#
+#free(0.5)#
+
+#ib(9)#4.3.1. Der #ib#Kommandodialog#ie##ie(9)#
+
+#free(1.0)#
+ #on("i")#
+ Einige Operationen kann man nur mühselig mit den bis jetzt beschriebenen Tasten
+ durchführen. Z.B. ist es sehr zeitaufwendig, eine bestimmte Textstelle zu finden.
+ Andere Operationen sind mit den im vorigen Kapitel beschriebenen Tasten über­
+ haupt nicht möglich, wie etwa die Zeilenbreite einzustellen oder Programme aufzu­
+ rufen, die die zu editierende Datei verarbeiten. Solche Operationen werden durch
+ Kommandos ermöglicht, die man auf Editorebene geben kann. #off("i")#
+
+
+#free(1.0)#
+Um Kommandos an den Editor geben zu können, schalten wir in den #ib#Kommando­
+zustand#ie#.
+
+<ESC> <ESC>
+
+Durch zweimaliges Betätigen von ESC erfolgt #on("u")#im Editor#off("u")# die Aufforderung
+
+____________________________________________________________________________
+ ................. dateiname ...................... Zeile 4
+
+Mit der ESC-Taste ist es möglich, den Kommandodialog
+gib kommando :
+
+____________________________________________________________________________
+
+
+
+Auf dem Bildschirm erscheint eine #ib#Kommandozeile#ie#, in der der Benutzer
+Kommandos schreiben kann. Durch Betätigen der Taste 'CR' wird das
+Kommando ausgeführt.
+#page#
+
+
+#ib(9)#4.3.2. Zeile und #ib#Textstelle anwählen#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Auf der Kommandoebene des Editors können Sie Kommandos erteilen, um an eine
+ beliebige Stelle in der Datei zu positionieren.#off ("i")#
+
+#free(1.0)#
+Sie haben einen (größeren) Text erstellt und stehen nun vor dem Problem, für die
+Korrektur die entsprechenden Textstellen aufzufinden.
+
+#on("u")#Beispiel:#off("u")#
+
+Bei der Durchsicht eines Ausdrucks Ihres Textes stellen Sie fest, daß Sie sich ver­
+schrieben haben. Anstelle von "diese Zeichen" haben Sie "diese Ziichen" geschrie­
+ben. Um diese Textstelle anzuwählen, gehen Sie wie folgt vor: Sie positionieren an
+den Beginn der Datei und betätigen die Tastenfolge
+
+
+<ESC> <ESC>
+
+
+Auf dem Bildschirm ersceint:
+
+____________________________________________________________________________
+
+gib kommando:
+
+____________________________________________________________________________
+
+
+Sie schreiben nun die zu suchende Textstelle auf:
+
+____________________________________________________________________________
+
+gib kommando: "diese Ziichen"
+
+____________________________________________________________________________
+
+
+Durch die Angabe eines TEXTes in Anführungsstrichen wird nach dem eingeschlosse­
+nen TEXT 'diese Ziichen' ab der aktuellen Cursor-Position gesucht. Wird 'diese
+Ziichen' gefunden, bleibt der Cursor auf dem gesuchten Text stehen. Andernfalls steht
+der Cursor am Ende der letzten Zeile der Datei.
+
+Eine andere Möglichkeit, an eine entferntere Stelle im Text zu kommen, ist die fol­
+gende:
+
+<ESC> <ESC>
+
+
+Es erscheint auf dem Bildschirm:
+
+____________________________________________________________________________
+
+gib kommando:
+
+____________________________________________________________________________
+
+
+Sie geben nun die Textzeile an, die Sie suchen:
+
+____________________________________________________________________________
+
+gib kommando: 134
+
+____________________________________________________________________________
+
+
+Durch dieses Kommando wird auf die 134. Zeile positioniert.
+#page#
+
+#ib(9)#4.3.3. #ib#Suchen und Ersetzen#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Auf der Kommandoebene des Editors können Sie wie auf der Monitor-Ebene
+ beliebige Kommandos geben. Diese können Sie zu (ELAN-) Programmen ver­
+ knüpfen. Zur Erstellung dieser Programme editieren Sie wie gewohnt in der Kom­
+ mandozeile. Für das Positionieren, Suchen und Ersetzen innerhalb Ihres ELAN-
+ Programms stehen Ihnen Kommandos zur Verfügung. Beliebige ELAN-Prog­
+ ramme sind zulässig.#off ("i")#
+
+#free(1.0)#
+Die #ib#Kommandozeile#ie# kann wie eine "normale" Textzeile editiert werden (Positionieren,
+Überschreiben, Einfügen, Löschen und Markieren). Bevor ein Programm eine Aus­
+gabe erzeugt oder fehlerhafte Kommandos Fehlermeldungen hervorrufen, wird der
+Cursor in die linke obere Ecke positioniert. Um die Meldungen festzuhalten, sollte das
+#ib#Kommando 'pause'#ie# folgen. Diese Meldungen werden dann in der ersten Zeile des
+Bildschirms angezeigt. Danach ist man wieder im Editor und kann wie gewohnt
+arbeiten.
+
+Kommandos werden durch ein Semikolon voneinander getrennt.
+
+#on("u")#Beispiel:#off("u")#
+
+____________________________________________________________________________
+
+gib kommando: T1; "Geschäftsführung";fetch("Lieferanten",archive)
+
+____________________________________________________________________________
+
+
+Ihr ELAN-Programm besteht aus zwei Kommandos: zunächst positionieren Sie in die
+erste Zeile und suchen ab dort nach dem Wort "Geschäftsführung". dann lesen Sie
+die Datei "Lieferanten" von der Diskette in den Arbeitsspeicher.
+
+Die beiden beschriebenen Kommandos (Text bzw. eine Zeile anwählen) sind Spezial­
+kommandos und können in dieser Form nicht durch ein Semikolon mit anderen Kom­
+mandos kombiniert werden. Deshalb gibt es für sie eine ELAN-Form, die es erlaubt,
+sie mit anderen Kommandos zusammen zu verwenden:
+
+a) Einen Text ab der aktuellen Cursor-Position suchen (D ist eine Abkürzung für
+ '#ib#DOWN#ie#'):
+
+____________________________________________________________________________
+
+gib kommando: "diese Zeichen"
+
+____________________________________________________________________________
+
+(* Kurzform *)
+
+
+____________________________________________________________________________
+
+gib kommando: #ib#D#ie# "diese Zeichen"
+
+____________________________________________________________________________
+
+(* Allgemeine Version *)
+
+
+
+b) Auf eine Zeile positionieren (#ib#T#ie# ist eine Abkürzung für '#ib#TO LINE#ie#'):
+
+____________________________________________________________________________
+
+gib kommando: 127
+
+____________________________________________________________________________
+
+
+(* Kurzform *)
+
+
+____________________________________________________________________________
+
+gib kommando: T 127
+
+____________________________________________________________________________
+
+
+(* Allgemeine Version *)
+
+
+Mehrere Kommandos können in der Kommandozeile angegeben werden. Die einzel­
+nen Kommandos müssen in diesem Fall mit ';' voneinander getrennt werden.
+
+#on("u")#Beispiel:#off("u")#
+
+<ESC> <ESC>
+
+schaltet in den Kommandomodus
+
+____________________________________________________________________________
+
+gib kommando: T 1; D "noch Zeichen"
+
+____________________________________________________________________________
+
+
+
+Diese zwei Kommandos werden nacheinander ausgeführt. Zuerst wird auf die erste
+Zeile positioniert und dann (von der ersten Zeile ab) nach 'noch Zeichen' gesucht.
+Damit ist es möglich, die Datei nicht nur ab der aktuellen Zeile zu durchsuchen,
+sondern die gesamte Datei. Soll nicht in Richtung auf das Dateiende, sondern in
+Richtung auf den Dateianfang (also nach "oben") gesucht werden, kann man das
+#ib#U-Kommando#ie# (Abkürzung für #ib#UP#ie#) verwenden:
+
+<ESC> <ESC>
+
+____________________________________________________________________________
+
+gib kommando: U "noch ein Text"
+
+____________________________________________________________________________
+
+
+
+Ein weiteres Kommando ist das #ib#C-Kommando#ie# (Abkürzung für '#ib#CHANGE#ie#'), mit
+welchem man einen TEXT sucht und diesen dann ersetzt.
+
+#on("u")#Beispiel:#off("u")#
+
+<ESC> <ESC>
+
+____________________________________________________________________________
+
+gib kommando: "alte Zeichen" C "neue Zeichen"
+
+____________________________________________________________________________
+
+
+Ab der aktuellen Cursor-Position wird nach 'alte Zeichen' gesucht. Wird der TEXT
+gefunden, wird er durch 'neue Zeichen' ersetzt. Der Cursor befindet sich in diesem
+Fall hinter dem ersetzten TEXT. Wird 'alte Zeichen' dagegen nicht in der Datei gefun­
+den, befindet sich der Cursor (wie beim erfolglosen Suchen mit D) am Ende der
+letzten Zeile der Datei.
+
+Wie alle anderen Kommandos kann auch das C-Kommando mit anderen Komman­
+dos verbunden werden.
+
+#on("u")#Beispiel:#off("u")#
+
+<ESC> <ESC>
+
+____________________________________________________________________________
+
+gib kommando: #ib#T#ie# 500; "Schreibfelher" #ib#C#ie# "Schreibfehler"
+
+____________________________________________________________________________
+
+
+
+Hier wird ab der 500. Zeile der Datei nach 'Schreibfelher' gesucht und ggf. ersetzt.
+Soll ein TEXT nicht nur einmal, sondern bei jedem Auftreten ersetzt werden, benutzt
+man das #ib#CA-Kommando#ie# (Abkürzung für #ib#CHANGE ALL#ie#):
+
+<ESC> <ESC>
+
+____________________________________________________________________________
+
+gib kommando: "dieser alte Text" CA "dieser neue Text"
+
+____________________________________________________________________________
+
+
+Dadurch wird 'dieser alte Text' bei jedem Auftreten ab der aktuellen Cursor-Position
+durch 'dieser neue Text' ersetzt.
+Pattern Matcher
+#free(1.0)#
+
+
+ Der #ib#Pattern Matcher#ie# ist ein Werkzeug zur #ib#Mustererkennung#ie#. Er dient zur
+ Beschreibung von Texten, die in verschiedenen Ausprägungen auftreten können.
+ Zum Suchen oder Ersetzen wird nicht ein Text fester Gestalt vorgegeben, sondern
+ eine Beschreibung der gesuchten Struktur.
+
+
+#free(1.0)#
+
+Häufig werden Sie #ib#Texte suchen#ie# oder ersetzen wollen, die in einigen Varianten inner­
+halb eines umfangreicheren Textes auftauchen können.
+
+Beispiel: Gesucht wird 'unser' in verschiedenen Zusammenstellungen, also auch
+ 'unsere' oder 'unserem'. Alle Textstellen, die diesem Muster entsprechen,
+ können in #on("u")#einem#off("u")# Suchverfahren gefunden werden, indem das Muster,
+ welches diese Texte beschreibt, für die Suche benutzt wird:
+
+____________________________________________________________________________
+Suchen nach Begriffen deren genaue Ausprägung unbekannt ist.
+gib kommando:D(" unser" + any + " ")
+
+
+____________________________________________________________________________
+
+
+
+ Leseweise:
+
+ Suche 'unser', gefolgt beliebigen Zeichen plus einem Leerzeichen, oder
+ auch nur einem Leerzeichen.
+
+
+ Dieses Suchkommando liefert Treffer bei 'unser', 'unsere', 'unseres' usw..
+
+#free(1.0)#
+Wie baut man ein Pattern ?
+
+#free(1.0)#
+
+
+ Texte werden durch ihr Konstruktionsmuster aus bekannten und unbekannten
+ Teilen beschrieben
+
+#free(1.0)#
+
+Ein Text, der in seiner konkreten Form nicht bekannt ist, dessen Aufbau jedoch durch
+ein Muster beschrieben werden kann, besteht aus Teilen, die als:
+
+ - bekannte Texte
+ - unbekannte Texte
+
+bezeichnet werden und die mit dem Operatoren:
+
+ '+' Zusammensetzen
+ 'OR' Alternative
+
+kombiniert werden können.
+
+
+Ein bekannter Text ist z.B. ein Stück eines gesuchten Textes, das als fest vorgegeben
+betrachtet werden kann, wie etwa der Wortstamm 'unser' in dem obigen Beispiel. Wie
+gewohnt wird ein solcher bekannter Text, in Anführungsstriche gesetzt, als TEXT
+CONST "text" notiert.
+
+Demgegenüber ist ein unbekannter Text von nicht näher zu beschreibender Gestalt.
+Das Muster, welches einen unbekannten Text beschreibt, steht für irgendeinen einer
+Vielzahl von Texten, die diesem Muster entsprechen.
+
+Mit der Prozedur:
+
+ any
+
+wird das Muster für einen beliebigen Text geliefert.
+
+Im einleitenden Beispiel ist der Wortstamm bekannt, das Teilwort 'unser' kann also im
+'Klartext' angegeben werden. Die Endungen sind je nach dem Zusammenhang in dem
+das gesuchte Wort auftritt verschieden, also zunächst unbekannt.
+Ein solcher unbekannter Text kann entweder durch Aufzählung der möglichen
+Alternativen seiner Erscheinung beschrieben werden oder durch die Prozedur 'any'.
+
+
+ (text + ("er" OR "es" OR "em" OR ..... )
+
+ alternative Verknüpfung durch OR
+
+
+ ("text" + any + .... )
+
+ additive Verknüpfung durch +
+
+Grundsätzlich ist zu beachten, daß der Suchvorgang des Pattern Matcher Zeichenket­
+ten untersucht und nicht etwa einzelne Worte und stets nach dem längstmöglichen
+Muster gesucht wird!
+
+Ein schlecht beschriebener Suchtext kostet somit nicht nur viel Rechenzeit, sondern
+liefert auch unerwünschte Ergebnisse: z.B. sollte der Artikel 'der' mit einem führenden
+Leerzeichen als " der" gesucht werden, da andernfalls jedes Wort, das die Silbe 'der'
+enthält, einen Treffer in der Suche ergibt.
+
+Da die Suche nach unbekannten Texten viele unerwünschte Ergebnisse liefern
+könnte, kann die Prozedur any in zweifacher Weise eingeschränkt werden:
+
+
+D(" d" + any (2) )
+
+ Die Länge der unbekannten Textes wird vorgegeben, indem die Anzahl
+ der Zeichen aus denen der Text besteht, angegeben wird. Die Angabe
+ steht in Klammern hinter 'any'. (In diesem Beispiel genau 2 Zeichen).
+
+
+D(" d" + any ("aeirs"))
+
+
+ Das Alphabet, aus dem der unbekannte Text bestehen darf, wird angege­
+ ben. (In diesem Beispiel darf der Text der einen Treffer ergibt nur aus
+ den Zeichen 'a', 'e', 'i', 'r', 's' bestehen, z.B: der, die, das oder auch
+ dies.)
+
+
+D(" d" + any (2,"aeirs")
+
+
+ Auch die Kombination der Beschränkungen ist möglich. (Jetzt liefern nur
+ noch 'der', 'die','das' etc. Treffer).
+
+
+#on("b")#
+ACHTUNG: Das Zeichen '*' nimmt eine Sonderstellung ein, da es als Abkürzung für
+ 'any' verwandt werden kann. Soll dieses Zeichen im Text gesucht oder
+ ersetzt werden, müssen Sie statt "*" 'any(1,"*")' schreiben.
+
+ Weitere Informationen zum Pattern Matcher finden Sie im EUMEL-
+ Handbuch zur Programmierung.
+#off("b")#
+#free(1.0)#
+4.3.4. Kommandos auf Tasten legen
+
+#free(1.0)#
+ #on("i")#
+ Oft benutzte Kommandos können auf Tasten gelegt werden. Damit ist es möglich,
+ den Editor auf Ihre speziellen Bedürfnisse einzurichten.#off ("i")#
+
+#free(1.0)#
+
+Oft benutzte Kommandos können mit der Drei-Tastenfolge
+
+<ESC> <!> <'taste'> auf eine Taste gelegt werden.
+
+#on("u")#Beispiel:#off("u")#
+
+
+<ESC> <ESC> (* die Kommandozeile erscheint *)
+
+____________________________________________________________________________
+
+gib kommando: save (SOME myself)
+
+____________________________________________________________________________
+
+
+<ESC> <!> <s> (* das Kommando 'save (SOME myself)' ist
+ nun auf die Taste 's' gelegt *)
+
+
+Wird nun die Taste 's' gedrückt, erscheint das Zeichen 's' auf dem Bildschirm. Mit
+#ib#ESC s#ie# wird das 'save'-Kommando ausgeführt. Natürlich können auch kompliziertere
+Kommandos auf Tasten gelegt werden.
+
+Möchten Sie ein Kommando, das auf eine Taste gelegt wurde, verändern, drücken Sie
+im Kommandodialog (!) die Drei-Tastenfolge
+
+<ESC> <?> <'taste'>
+
+
+#on("u")#Beispiel:#off("u")#
+
+<ESC> <ESC> (* in den Kommandodialog gehen *)
+
+
+<ESC> <?> <s> (* es erscheint nun: 'save (SOME myself)' *)
+
+Dieses Kommando kann nun z.B. verändert und ausgeführt (durch 'CR') oder
+wiederum auf die gleiche oder eine andere Taste gelegt werden (durch #ib#ESC ! 'taste'#ie#).
+
+Im Editor kann das letzte im Kommandodialog eingegebene Kommando durch '#ib#ESC f#ie#'
+wiederholt werden.
+#page#
+
+#ib(9)#4.3.5. Texte aus anderen Dateien benutzen#ie(9)#
+#free(1.0)#
+ #on("i")#
+ Manchmal ist es notwendig, einen Text in eine andere Datei zu schreiben (z.B.
+ wenn man diesen Text noch einmal verwenden will) oder einen Text einer anderen
+ Datei in den zu bearbeitenden Text einzufügen. Die '#ib#GET#ie#'- und '#ib#PUT#ie#'-Kom­
+ mandos bieten die Möglichkeit, Texte zwischen Dateien auszutauschen (vergl.
+ auch den Abschnitt über paralleles Editieren).#off ("i")#
+
+#free(1.0)#
+Mit dem #ib#'GET'-Kommando#ie# können wir Texte aus einer anderen Datei an die aktuelle
+Schreibposition kopieren.
+
+____________________________________________________________________________
+
+gib kommando: GET "absender"
+
+____________________________________________________________________________
+
+holt den Text 'absender'. Wenn also des öfteren Briefe geschrieben werden, braucht
+man sich den Absender nur einmalig in die Datei 'absender' zu schreiben und kann
+diesen mit dem Kommando 'GET' (was man auf eine Taste legen kann) u.U. mehr­
+mals an verschiedenen Stellen in die Datei einfügen.
+
+Mit dem #ib#'PUT'-Kommando#ie# können wir zuvor markierte Textteile in eine Datei schrei­
+ben.
+
+____________________________________________________________________________
+
+gib kommando: PUT "adressen"
+
+____________________________________________________________________________
+
+
+schreibt einen markierten Text in die Datei 'adressen'. 'adressen' wird ggf. eingerich­
+tet. Ist die Datei 'adressen' bereits vorhanden, so wird erfragt, ob die Datei gelöscht
+werden kann, um den markierten Text aufzunehmen (überschreiben). Andernfalls wird
+der markierte Text an den bereits vorhandenen Text in 'adressen' angefügt. Es ist
+somit durch mehrmaliges Markieren und das 'PUT'-Kommando möglich, Texte aus
+einer Datei zu sammeln und in eine neue Datei zu geben.
+#page#
+
+#ib(9)#4.3.6. #ib#Breitere Zeilen#ie# bearbeiten#ie(9)##goalpage("margin")#
+#free(1.0)#
+ #on("i")#
+ Der Editor ist auf eine Zeilenbreite von 77 Zeichen eingestellt. Oft ist es notwen­
+ dig, mit einer anderen Zeilenbreite zu schreiben, welche man mit dem #ib#'limit'-
+ Kommando#ie# einstellen kann. Aber auch die Positionierung innerhalb einer Zeile
+ wird dadurch anders, weil breitere Zeilen nicht als Ganzes auf den Bildschirm
+ passen. In diesem Fall wird "#ib#gerollt#ie#".#off ("i")#
+
+#free(1.0)#
+Eine andere Zeilenbreite stellt man durch 'limit' ein. Beachten Sie, daß die eingestell­
+te Zeilenbreite für die gesamte Datei gilt.
+
+#on("u")#Beispiel:#off("u")#
+
+____________________________________________________________________________
+
+gib kommando: limit (180)
+
+____________________________________________________________________________
+
+
+Nun können Sie wie gewohnt schreiben. Allerdings wird die aktuelle Zeile, in der man
+sich befindet, nicht wie gewohnt am Bildschirmende umgebrochen, sondern erst an
+der Spalte 180, sofern sie nicht vorher durch die 'CR'-Taste beendet wird. Wird über
+das rechte Bildschirmende hinaus geschrieben, bleibt die Cursor-Position am Ende
+des Bildschirms erhalten, aber die Zeile wird beim weiteren Schreiben nach links
+verschoben, "rollt" also nach links (der Anfang der Zeile verschwindet scheinbar nach
+links).
+
+Mit der Positionierung verhält es sich ähnlich. Wird mit RECHTS über den rechten
+Bildschirmrand positioniert, wird die Zeile ebenfalls gerollt. #ib#HOP RECHTS#ie# bewirkt ein
+#ib#Blättern#ie# innerhalb einer einzelnen Zeile nach rechts. Analog verläuft es bei verscho­
+bener Zeile, wenn nach links (LINKS bzw. #ib#HOP LINKS#ie#) positioniert wird.
+
+Beim Schreiben von Tabellen kann es sinnvoll sein, das Fenster vorübergehend auf
+eine andere Anfangsposition (als 1) einzustellen. Das kann mit dem
+#ib#'margin'-Kommando#ie# erfolgen.
+
+#on("u")#Beispiel:#off("u")#
+
+____________________________________________________________________________
+
+gib kommando:#ib#margin#ie# (50)
+
+____________________________________________________________________________
+
+
+Das Editorfenster zeigt nun einen Ausschnitt aus der Datei, beginnend ab der Spalte
+50. In der Titelzeile wird "M50" angezeigt.
+#page#
+
+#ib(9)#4.3.7. Die wichtigsten Kommandos#ie(9)#
+#free(1.0)#
+ #on("i")#
+ Einige Kommandos sind speziell für die Textverarbeitung im Editor programmiert.
+ Die wichtigsten werden hier vorgestellt.#off ("i")#
+
+#free(1.0)#
+any
+ TEXT PROC any
+ liefert ein Muster beliebiger Gestalt und Länge (also auch der Länge 0) für
+ Suchoperationen.
+
+
+ " ir" + any + "was"
+
+
+any
+ TEXT PROC any (TEXT CONST alphabet)
+ liefert den längstmöglichen Text, der aus den in 'alphabet' angegebenen Zeichen
+ besteht.
+
+
+ any ("1234567890") (* suche Zahlen *)
+
+
+any
+ TEXT PROC any (INT CONST laenge)
+ liefert ein Muster beliebiger Gestalt und der Länge 'laenge'.
+
+
+ " d" + any (2)
+
+
+any
+ TEXT PROC any (INT CONST laenge, TEXT CONST alphabet)
+ liefert ein Muster der Länge 'laenge', das nur aus Zeichen aus
+ 'alphabet' besteht.
+
+
+ " d" + any (2,"erias")
+
+
+
+C
+ OP C (TEXT CONST muster, ersatz)
+ Ab der aktuellen Positon wird 'muster' in Richtung Dateiende gesucht und durch
+ 'ersatz' ersetzt. Der Cursor steht danach hinter 'ersatz'.
+
+
+ "alt" C "neu"
+
+
+
+CA
+ OP CA (TEXT CONST muster, ersatz)
+ Arbeitet ab der aktuellen Position wie C. Die Aktion wird jedoch bis zum Erreichen
+ des Dateiendes wiederholt. Nach Ausführung ist somit jedes 'muster' durch
+ 'ersatz' ersetzt. Der Cursor steht danach hinter dem letzten Zeichen der Datei.
+
+
+ "alt" CA "neu"
+
+
+
+
+D
+ OP D (INT CONST n)
+ Positioniert das Fenster n Zeilen vorwärts in Richtung auf das Dateiende.
+
+
+ D 50
+
+
+ OP D (TEXT CONST muster)
+ Sucht 'muster' vorwärts in Richtung auf das Dateiende. Die Suche beginnt direkt
+ hinter der aktuellen Cursor-Position. Wird 'muster' nicht gefunden, steht der
+ Cursor hinter dem letzten Zeichen der Datei. Wird 'muster' gefunden, steht der
+ Cursor direkt auf dem ersten Zeichen von 'muster'.
+
+
+ D "muster"
+
+
+
+GET
+ OP GET (TEXT CONST dateiname)
+ Kopiert den Inhalt der Datei mit dem angegebenen Namen vor die aktuelle
+ Cursor-Position. Ist ein Teil der Quelldatei markiert, wird nur der markierte Teil
+ kopiert.
+
+
+ GET "quelldatei"
+
+
+ OP G (TEXT CONST dateiname)
+ Wie GET.
+
+
+limit
+ OP limit (INT CONST limit)
+ Setzt die rechte Schreibgrenze auf 'limit'.
+
+
+ limit (50)
+
+
+
+margin
+ PROC margin (INT CONST anfang)
+ Alle Zeilen erscheinen erst ab Spalte 'anfang' im Sichtfenster.
+
+
+ margin (50)
+
+
+
+OR
+ TEXT OP OR (TEXT CONST texteins,textzwei)
+ Liefert ein Muster, wenn texteins oder textzwei gefunden wird. Die Reihenfolge
+ spielt keine Rolle.
+
+
+ D ("Geschäfts" + ("führung" OR "leitung"))
+
+
+
+PUT
+ OP PUT (TEXT CONST dateiname)
+ Richtet eine Datei mit dem angegebenen Namen ein und kopiert den markierten
+ Textabschnitt in diese.
+
+
+ PUT ("meine hilfsdatei")
+
+
+ OP P (TEXT CONST dateiname)
+ Zweck: Wie PUT.
+
+
+T
+ OP T (INT CONST n)
+ Positioniert auf die Zeile 'n'.
+
+
+ T 999
+
+
+
+type
+ PROC type (TEXT CONST zeichenkette)
+
+ Fügt 'zeichenkette' in die aktuelle Position der editierten Datei ein. Besonders
+ nützlich in Verbindung mit der Prozedur 'code', um nicht auf der Tastatur enthal­
+ tene Zeichen in den Text zu bringen.
+
+
+ type(code(200))
+
+
+
+U
+ OP U (INT CONST n)
+ Positioniert das Fenster n Zeilen rückwärts in Richtung auf den Dateianfang.
+
+
+ U 100
+
+
+ OP U (TEXT CONST muster)
+ Sucht 'muster' rückwärts in Richtung auf den Dateianfang. Die Suche beginnt
+ links neben der aktuellen Cursor-Position. Vergl. D
+
+
+ U "muster"
+
+
+word wrap
+ PROC word wrap (BOOL CONST an)
+ Schaltet den automatischen Wortumbruch an (voreingestellt) bzw. aus.
+
+
+ word wrap (true) (* angeschaltet *)
+ word wrap (false) (* ausgeschaltet *)
+
+4.4. Fehlersituationen und Abhilfe
+
+#free(1.0)#
+ #on("i")#
+ Von Zeit zu Zeit werden Sie als Anfänger in Arbeitssituationen geraten, wo Sie
+ nicht weiterwissen. Hier sind einige Tips, wie Sie sich behelfen können.#off ("i")#
+
+#free(1.0)#
+
+Wie helfe ich mir, wenn...
+
+
+... nach
+ continue("taskname")
+
+ der Monitor #on("u")#nicht#off("u")#
+
+ gib kommando:
+
+ sagt, sondern "schweigt"?
+
+=> Sie haben die Task bei der letzten Benutzung nicht mit dem Kommando
+ 'break' verlassen (evtl. haben Sie SV betätigt?). Sie sind jetzt im Editor, sehen
+ aber den zuletzt bearbeiteten Textausschnitt nicht. Betätigen Sie die Tasten
+
+ ESC b
+
+ und der Text wird neu auf dem Bildschirm ausgegeben.
+#free(1.0)#
+... im Editor kein Tastendruck mehr akzeptiert wird?
+
+=> Sie haben irrtümlich die STOP-Taste (auch oft als CTRL a realisiert, abhängig
+ vom Terminal), d.h. Anhalten der Bildschirmausgabe betätigt.
+
+ Drücken Sie die WEITER-Taste (= CTRL c, d.h. Bildschirmausgabe fortfüh­
+ ren). Alle Tastenanschläge, die zwischenzeitlich zu keiner Reaktion führten,
+ werden jetzt ausgegeben.
+
+ Je nach Tastatur können STOP und WEITER auch auf anderen Tasten liegen. #free(1.0)#
+... der Lernmodus über lange Zeit (ungewollt) eingeschaltet war?
+
+=> a) Sie merken plötzlich, daß über einen unbestimmt langen Zeitraum alle Ihre
+ Tastenanschläge gelernt wurden (zu erkennen an der "LEARN"-Anzeige in
+ der Überschriftzeile).
+
+ #on("u")#Was ist zu tun?#off("u")#
+
+ Mit dem Kommando
+
+ ESC HOP HOP
+
+ vergessen Sie alles Gelernte und schalten den Lernmodus aus.
+
+=> b) Sie beenden den Editor mit ESC q und die Meldung
+
+____________________________________________________________________________
+
+ WARNUNG: Lernmodus nicht ausgeschaltet
+
+____________________________________________________________________________
+
+
+
+ erscheint auf dem Bildschirm.
+
+ #on("u")#Was ist zu tun?#off("u")#
+
+ Sie können mit
+
+ ESC HOP HOP
+
+ das Gelernte sofort vergessen.
+#free(1.0)#
+... Sie zu viele Absatzzeichen in Ihrem Text gesetzt haben und diese entfernen
+ müssen?
+
+=> Sie positionieren in die Zeile, in der die Absatzmarke gelöscht werden soll. Sie
+ betätigen dann die TAB-Taste, um hinter den Text zu positionieren, dann die
+ RUBOUT-Taste. Wenn Sie jetzt die Zeile mit den Cursor-Tasten nach oben
+ oder unter verlassen, verschwindet die Absatzmarkierung.
+#free(1.0)#
+... nach
+
+ save("dateiname","vatertask")
+
+ das Betriebssystem nicht mehr reagiert?
+
+=> Sie haben die Vater-Task nicht mit dem Kommando 'global manager' in
+ jenem Prozeß zum Empfang von Daten aus anderen Prozessen vorbereitet.
+#free(1.0)#
+... Sie in Ihrer Task das Archive mit dem Kommando
+
+ archive("archivname")
+
+ anmelden wollen und das System Ihnen die Meldung
+
+ "Fehler: Archive wird von Task "bib" benutzt"
+
+ zustellt?
+
+=> Es gibt zwei Möglichkeiten:
+ a) Ein anderer Benutzer benötigt das Archiv-Laufwerk in diesem Moment. Sie
+ müssen warten, bis er seine Arbeit beendet hat.
+
+ b) Ein anderer Benutzer (oder Sie selbst) hat vergessen, mit dem Kommando
+
+ release(archive)
+
+ das Archiv in jener Task freizugeben. Falls Sie es selbst waren, holen Sie
+ das nach. Ansonsten kann das Archiv-Kommando wieder erfolgreich gege­
+ ben werden, wenn fünf Minuten nicht auf das Archiv
+ zugegriffen wurde. #free(1.0)#
+... Sie eine (scheinbare oder echte) Endlosschleife auf einer Taste (z.B. Taste "x")
+ gelernt haben und diese (versehentlich oder bewußt) durch 'ESC x' aktivieren?
+
+=> Wie immer, wenn Sie eine endlos laufende Task beenden wollen, gelangen Sie
+ mit der SV-Taste in den Supervisor-Modus und mit dem Kommando
+
+ 'halt'
+
+ beenden Sie die Endlosschleife.
+
+ Mit
+
+ ESC HOP HOP x
+
+ wird danach das Gelernte 'vergessen'!
+#free(1.0)#
+... Sie Ihre Datei verlassen wollen und
+
+ 'ESC q'
+
+ (scheinbar) nicht funktioniert?
+
+=> Sie haben versehentlich den Feststeller für Großbuchstaben (SHIFT LOCK /
+ CAPS LOCK) betätigt und ESC q zeigt keine Wirkung (wie auch andere Tasten­
+ kombinationen mit Großbuchstaben evtl. keine Wirkung zeigen).
+
diff --git a/doc/user/benutzerhandbuch.5a b/doc/user/benutzerhandbuch.5a
new file mode 100644
index 0000000..1e907f0
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5a
@@ -0,0 +1,1446 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 5: Textkosmetik und Druck
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+5 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 5 - %
+#tableend##clearpos#
+#end#
+
+#ib(9)#TEIL 5: Textkosmetik und Druck#ie(9)#
+#free(1.0)#
+#ib(9)#5.0. Vorwort#ie(9)#
+
+#free(1.0)#
+Die #ib#Textkosmetik-Programme#ie# des EUMEL-Systems bieten Ihnen eine einfach zu
+erlernende und zu bedienende Möglichkeit, Texte für den Druck zu gestalten (pro­
+grammtechnisch: #ib#formatieren#ie#) und zu manipulieren.
+
+Die Textkosmetik-Programme bearbeiten Ihre Dateien, die durch den EUMEL-Editor
+erstellt wurden. Darum sollten Sie sich zuerst mit dem EUMEL-Editor vertraut
+machen.
+
+Die Programme sind so konstruiert, daß die meisten Aufgaben durch in den Text
+eingefügte Anweisungen gesteuert werden. Solche Angaben für die Textkosmetik und
+den EUMEL-Drucker nennen wir im folgenden kurz #on("b")##on("i")#'Anweisung' #off("b")##off("i")#. Die Form der
+#ib#Anweisung#ie# ist für die Textkosmetik und den EUMEL-Drucker gleich und entspricht
+der ELAN-Syntax. Beachten Sie den #ib#Unterschied zwischen einem Kommando und
+einer Text-Anweisung#ie#: während ein Kommando direkt ausgeführt wird, wird eine in
+den Text eingebettete Anweisung erst nach dem Aufruf von Textkosmetik- und
+Drucker-Programmen wirksam.
+
+Die Wirkungsweise der Textkosmetik-Anweisungen ist leicht zu erlernen und kann
+vor allen Dingen stufenweise erfolgen. Deshalb ein guter Rat für Anfänger: Lesen Sie
+diesen Teil des Benutzer-Handbuchs erst oberflächlich, so daß Sie ungefähr
+Bescheid wissen, welche Möglichkeiten die Textkosmetik-Programme bieten. Dann
+können Sie diejenigen Teile der Textkosmetik auswählen und bei Bedarf anwenden,
+die Sie für Ihre spezielle Anwendung benötigen.
+#page#
+
+#ib(9)#5.1. Einführung in die Benutzung der
+ #ib#Textkosmetik#ie##ie(9)#
+
+#free(1.0)#
+ #on("i")#
+ In diesem Kapitel erhalten Sie eine Übersicht über die verfügbaren Programme der
+ Textkosmetik.
+
+#off("i")#
+#free(1.3)#
+Schreiben, Gestalten und Drucken von Texten
+
+#free(1.0)#
+ #on("i")#
+ Im EUMEL-System unterscheiden wir zwischen drei Stufen einer Textbehand­
+ lung:#on("b")# Erstellung, Gestaltung#off("b")# und #on("b")#Druck#off("b")#. Die Trennung in verschiedene Arbeits­
+ stufen hat den Vorteil, daß Sie sich zu einem Zeitpunkt nur auf einen Arbeitsschritt
+ konzentrieren müssen.
+ #off("i")#
+#free(1.3)#
+Texterstellung bzw. Textbearbeitung
+
+#free(1.0)#
+Das Schreiben von Texten wird mit Hilfe des Editors erledigt. In dieser Stufe der
+Texterstellung können Sie sich ausschließlich auf das Schreiben und die inhaltliche
+Korrektheit Ihres Textes konzentrieren. Wird ein Text ohne Anweisungen gedruckt,
+dann erscheint er so, wie er mit dem Editor geschrieben wurde. Bei der Erstellung
+des Textes können Sie aber auch bereits Textkosmetik-Anweisungen in den Text
+einfügen.
+
+____________________________________________________________________________
+
+ Es ist wichtig, daß Sie das Kapitel 'Editor'
+ \#on("b")\#sehr\#off("b")\# gründlich lesen.
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+Es ist wichtig, daß Sie das Kapitel 'Editor'
+#on("b")#sehr#off("b")# gründlich lesen.
+
+
+Sie sollten Texte im 'Fließtext'-Modus erstellen, d.h., dann werden Worte, die über
+Zeilengrenzen gehen, ohne Silbentrennung vom Editor in die nächste Zeile gebracht.
+#free(1.5)#
+Textkosmetik bzw. Textgestaltung
+
+#free(1.0)#
+Nachdem Sie einen Text geschrieben haben, können Sie ihn mit #ib#Textkosmetik-
+Programme#ie#n gestalten, ohne ihn inhaltlich zu verändern. Dies kann auch vor oder
+nach eventuellen Korrekturen erfolgen. Die Textkosmetik bietet zur Zeit vier Pro­
+gramme an, die je nach Bedarf eingesetzt werden können:
+
+--- #on("b")#'#ib#lineform'/'autoform#ie#'#off("b")# formatiert einen Text zeilenweise und vollzieht eine
+ Silbentrennung. Weiterhin erlaubt 'lineform'/'autoform' die Verwendung unter­
+ schiedlicher Schrifttypen und Schrifthöhen.
+
+--- #on("b")#'#ib#pageform#ie#'/'#ib#autopageform#ie#'#off("b")# gestattet die Formatierung eines Textes in Seiten
+ (drucktechnisch: "Seitenumbruch"). Dabei berücksichtigt 'pageform'/'auto­
+ pageform' unterschiedliche Schrifthöhen. Es ist mit 'pageform'/ 'autopage­
+ form' u.a. möglich, die Seiteneinteilung zu bestimmen, eine Seite in Spalten
+ zu formatieren ("Zeitungsformat"), Zeilen am Anfang bzw. Ende jeder Seite
+ einfügen zu lassen, eine Seitennumerierung (drucktechnisch: "Paginierung")
+ zu erhalten und Fußnoten zu gestalten.
+
+--- #on("b")#'#ib#index#ie#'#off("b")# erlaubt die Erstellung von Stichwort- und Inhaltsverzeichnissen aus
+ einer mit 'pageform'/'autopageform' bearbeiteten Datei.
+
+--- #on("b")#'#ib#outline#ie#'#off("b")# holt aus einer Datei alle mit Index-Anweisung gekennzeichneten
+ Überschriften und Stichworte. Es erstellt somit eine Übersicht bzw. Kurz­
+ fassung eines Textes.
+#free(1.5)#
+Drucken
+#free(1.0)#
+Zu jedem Zeitpunkt der Texterstellung kann gedruckt werden. Der EUMEL-Drucker
+beachtet die gleichen Anweisungen wie die Textkosmetik-Programme und noch
+einige zusätzliche, die nur für die Druckaufbereitung notwendig sind. Spezielle Druck­
+leistungen, wie z.B. verschiedenartige Schrifttypen, können nur auf besonderen
+Druckern erzeugt werden. Verfügt ein Drucker nicht über eine bestimmte Hardware-
+Eigenschaft, wird die von ihm geforderte Leistung ignoriert. Somit ist es möglich,
+Probedrucke für Korrekturen etc. auch auf preiswerten Druckern herzustellen. (siehe
+hierzu 5.6.1.)
+#page#
+
+ +-------------------------+
+ l Text-Eingabe l
+ l l
+ +->-+ Editor +->-+
+ l l l l
+ l l erstellt Datei l l
+ l +------------+------------+ l
+ l l l
+ l V l
+ l +------------+------------+ l
+ l l lineform l l
+ +-<-+ +->-+
+ l l formatiert Zeilen l l
+ l +------------+------------+ l
+ l l l
+ l V l
+ l +------------+------------+ l
+ l l outline l l +--------------------------+
+ l l l l l E U M E L - Drucker l
+ +-<-+ gibt Übersicht bzw. +->-+ ->--+ l
+ l l Kurzfassung eines Textesl l l Probe- bzw. l
+ l l l l l endgültiger Druck l
+ l l Dateiname + '.outline' l l +--------------------------+
+ l +------------+------------+ l
+ l l l
+ l V l
+ l +------------+------------+ l
+ l l pageform l l
+ l l l l
+ +-<-+ formatiert Seiten +->-+
+ l l l l
+ l l Druckdatei l l
+ l l Dateiname + ".p" l l
+ l +------------+------------+ l
+ l l l
+ l V l
+ l +------------+------------+ l
+ l l index l l
+ l l l l
+ l l erstellt Stichwort- und l l
+ +-<-+ Inhaltsverzeichnisse +->-+
+ l l
+ l Indexdatei(en) l
+ l Dateiname + "i<nummer>" l
+ +-------------------------+
+ #page#
+
+#ib(9)#5.1.1. Anweisungen für die Textkosmetik
+ und den Drucker#ie(9)#
+#free(1.0)#
+ #on("i")#
+ In diesem Abschnitt wird beschrieben, wie Sie #ib#Anweisungen#ie# für die Textkosme­
+ tik- und Druckprogramme in einen Text einfügen können. Beachten Sie, daß jede
+ Anweisung von '\#'-Zeichen eingeschlossen werden muß. Benötigen Sie das
+ '\#'-Zeichen in Ihrem Text, müssen Sie es mit 'ESC' schreiben.
+ #off("i")#
+#free(1.0)#
+Es gibt zwei Arten von Anweisungen:
+
+a) Anweisungen, die das gesamte Aussehen eines Manuskripts verändern (#on("i")##ib#"layout-
+ Anweisungen"#ie##off("i")#). Zu diesen Anweisungen gehören die Anweisungen \#limit (...)\#­
+ (Einstellen der Zeilenbreite), \#linefeed (...)\# (Zeilenabstand), \#page\# (neue Seite)
+ usw. Diese Anweisungen gelten erst ab der nächsten Zeile und Sie sollten sie
+ daher in eine extra Zeile zwischen den Text stellen.
+
+____________________________________________________________________________
+
+\#type ("trium8")\#\#limit (11.0)\#
+\#start(5.0,1.5)\#
+\#pagelength(17.4)\#\#pagenr("%",148)\#\#setcount(1)\#
+\#block\#\#pageblock\#
+\#count per page\#
+\#headeven\#
+\#lpos(0.0)\#\#cpos(5.5)\#\#rpos(11.0)\#
+\#table\#
+ EUMEL-Benutzerhandbuch
+\#fillchar(" ")\#
+\#on("u")\# \#off("u")\#
+\#table end\#\#clear pos\#
+
+\#end\#
+\#headodd\#
+\#lpos(0.0)\#\#cpos(5.5)\#\#rpos(11.0)\#\#fillchar(" ")\#
+\#table\#
+ Teil 5: Textkosmetik und Druck
+\#fillchar(" ")\#
+\#on("u")\# \#off("u")\#
+\#table end\#\#clear pos\#
+
+\#end\#
+
+____________________________________________________________________________
+
+
+ Das Druckbild (das Ergebnis der Anweisungen) sehen Sie im vorliegenden
+ Benutzerhandbuch.
+
+ Anweisungen, die für den Gesamttext gelten sollen, müssen Sie an den Anfang
+ der Datei stellen (noch vor \#head\#).
+
+b) Anweisungen, die unmittelbar auf den nachfolgenden Text wirken sollen, wie z.B.
+ \#type\# (Schrifttyp), \#on\#/\#off\# (Modifikationen wie unterstreichen oder fett druk­
+ ken), \#ib\#/\#ie\# (Markierung von Stichworten) usw. Solche Anweisungen werden
+ unmittelbar beachtet und können überall auf einer Zeile stehen (wie in dem fol­
+ genden Beispiel).
+
+____________________________________________________________________________
+
+ \#on("underline")\#Ausnahmen\#off("underline")\# werden bei der
+ Beschreibung der Anweisungen speziell erwähnt.
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+ #on("u")#Ausnahmen#off("u")# werden bei der
+ Beschreibung der Anweisungen speziell erwähnt.
+
+____________________________________________________________________________
+
+Weitere Beispiele für Textkosmetik-Anweisungen:
+
+____________________________________________________________________________
+
+\#page\#
+\#free(3.0)\#
+\#type("quadrato")\#
+
+____________________________________________________________________________
+
+
+Diese Anweisungen entsprechen - wie alle Kommandos im EUMEL-System - der
+ELAN-Syntax (u.a. müssen sie klein geschrieben werden; Parameter in runden
+Klammern; mehrere Parameter werden durch Kommata getrennt; #ib#TEXT-Parameter#ie# in
+Anführungsstrichen; #ib#REAL-Parameter#ie# mit Dezimalpunkt usw.). Leerzeichen spielen
+(außer in TEXT-Parametern) keine Rolle und können zur besseren Lesbarkeit belie­
+big verwendet werden.
+
+Die Zeichen, aus denen eine Anweisung besteht, werden bei der Formatierung einer
+Zeile oder Seite nicht mitgezählt und vom EUMEL-Drucker nicht gedruckt. Eine
+Zeile, die nur aus Anweisungen besteht, wird ebenso behandelt, auch wenn sie mit
+<CR> abgeschlossen wird.
+#page#
+#on("b")#
+
+#ib(9)#5.1.2. #ib#Aufruf der Textkosmetik-Programme#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ In diesem Abschnitt wird beschrieben, wie Sie die #ib#Textkosmetik-Programme
+ aktivieren#ie# können.
+ #off("i")#
+#free(1.0)#
+Sie rufen die Textkosmetik-Programme durch Kommandos auf (d.h. in der 'gib
+kommando'-Ebene). Sie geben ebenso wie zum Editieren den Namen des Pro­
+gramms und der Datei an.#goalpage("lineform")#
+
+____________________________________________________________________________
+
+ gib kommando:
+ lineform ("dateiname")
+
+____________________________________________________________________________
+
+
+ oder:
+ autoform ("dateiname")
+ pageform ("dateiname")
+ autopageform ("dateiname")
+ outline ("dateiname")
+#mark ("", "")#
+ index ("dateiname")
+
+
+
+
+'lineform'/'autoform' können Sie auch vom EUMEL-Editor aus aufrufen. Zu diesem
+Zweck markieren Sie den zu formatierenden Abschnitt der Datei und geben im
+Kommando-Zustand ( <ESC> <ESC> drücken) 'lineform' bzw. 'autoform' (ohne Para­
+meter).
+#mark ("", "")#
+
+Das Programm 'pageform'/'autopageform' erzeugt aus der Eingabedatei eine #ib#Druck­
+datei#ie#, die den Namen der angegebenen Eingabedatei mit dem Zusatz '.p' bekommt.
+
+____________________________________________________________________________
+
+ gib kommando:
+ pageform ("dateiname")
+
+____________________________________________________________________________
+
+
+Als Ergebnis erhalten Sie: "dateiname.p"
+
+
+
+
+Das Programm 'index' kann nur eine Druckdatei bearbeiten:
+
+____________________________________________________________________________
+
+ gib kommando:
+ index ("dateiname.p")
+
+____________________________________________________________________________
+
+
+und erstellt die angeforderten Verzeichnisse in Dateien, die mit dem Zusatz
+'.i<nummer>' gekennzeichnet werden.
+
+Beispiele: "dateiname.i1", "dateiname.i2" etc.
+
+
+
+
+'#ib#outline#ie#' erstellt ebenfalls eine neue Datei.
+
+____________________________________________________________________________
+
+ gib kommando:
+ outline ("dateiname")
+
+____________________________________________________________________________
+
+
+führt zu dem Ergebnis: "dateiname.outline" #mark ("", "")#
+#page#
+
+#ib(9)#5.1.3. Vorzeitiger #ib#Abbruch#ie# und
+ #ib#Fehlermeldungen#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Sie können alle Textkosmetik-Programme vorzeitig abbrechen. Eventuelle
+ Fehlermeldungen werden Ihnen in einem Fenster angezeigt.
+ #off("i")#
+#free(1.0)#
+Durch die #ib#<ESC>#ie(1,"-Abbruch")##ib##ie(1,"Abbruch mit ESC")#-Taste oder die #ib#<SV> #ie#-Taste und das Supervisor-Kommando 'halt'
+können Sie die Textkosmetik-Programme jederzeit vorzeitig abbrechen. Die Eingabe­
+datei steht Ihnen dann unverändert zur Verfügung. Ein #ib#vorzeitiger Abbruch#ie# kann
+notwendig sein, wenn Sie ein Programm mit einer falschen Datei aufgerufen haben
+oder zu viele Fehler gemeldet wurden.
+#mark ("", "")#
+
+Alle Textkosmetik-Programme melden Fehler, wenn Sie Anweisungen falsch be­
+nutzen. Die Fehlermeldungen werden auf dem Bildschirm angezeigt. Bei Beendigung
+eines Programms wird - falls Fehler entdeckt wurden - automatisch der #ib#Fenster-
+Editor#ie# aufgerufen, wobei die Fehlermeldungen im unteren #ib#Fenster#ie# (das ist das #ib#Notiz­
+buch#ie#) angezeigt werden, während Ihnen im oberen Fenster die Eingabedatei zur
+Korrektur angeboten wird.
+
+____________________________________________________________________________
+
+.......................dateiname.................Zeile 1
+
+ \#corner1("-5.0")\#\#on("i")\#
+ Sie können alle Textkosmetik-Programme vorzeitig abbrechen.
+ Eventuelle Fehlermeldungen werden Ihnen in einem Fenster ange­
+ zeigt.
+ \#box3("T","2","115.0")\#\#off("i")\#
+ #cursor(" ")#
+
+.......................notebook..................Zeile 1
+FEHLER Zeile 1: Unbekannte Anweisung (ignoriert): corner1("-5.0")
+ >>> Bitte Korrigieren
+FEHLER Zeile 5: Unbekannte Anweisung (ignoriert):
+ box3("T","2","115.0")
+ >>> Bitte Korrigieren
+
+____________________________________________________________________________
+
+
+
+
+
+Um von der Eingabedatei zum Notizbuch - und umgekehrt - zu wechseln, betätigen
+Sie <ESC> <w>.
+#page#
+
+#ib(9)#5.2. #ib#Lineform/Autoform#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Die Programme '#ib(1, "ff")#lineform#ie#' oder '#ib(1, "ff")#autoform#ie#' formatieren einen Text zeilenweise (ggf.
+ mit Silbentrennung) unter Berücksichtigung von Schrifttyp und Zeilenbreite.
+ #off("i")#
+#free(1.0)#
+Zur #ib#Zeilenformatierung#ie# werden Ihnen zwei Programme (Kommandos) angeboten, die
+sich nur in ihrem interaktiven Charakter unterscheiden (Behandlung von Silben­
+trennungen):
+
+---- #on("b")##ib#autoform#ie##off("b")#:
+ Zeilenformatierung mit automatischer #ib#Silbentrennung#ie#. Sie sollten 'autoform'
+ nur bei Texten einsetzen, in denen einige wenige Trennfehler nicht von
+ großer Bedeutung sind, z.B. bei Probedrucken.
+
+---- #on("b")##ib#lineform#ie##off("b")#:
+ Zeilenformatierung mit Silbentrennung "per Hand", wobei (nach deutschen
+ Trennregeln) ein sinnvoller Trennvorschlag gemacht wird. Die Trennstelle
+ kann interaktiv soweit verschoben werden, wie das zu trennende Wort noch
+ auf die Zeile paßt.
+
+
+'lineform'/'autoform' hat im wesentlichen vier Aufgaben:
+
+---- #ib#Auffüllen von Zeilen#ie#:
+ 'lineform'/'autoform' kann besonders gut nach Korrekturen eingesetzt wer­
+ den, bei denen - nach Einfügungen oder Löschungen - nicht vollständige
+ oder zu lange Zeilen in der Datei stehenbleiben können.
+
+---- Erstellen von Zeilen mit unterschiedlichen Schrifttypen:
+ Werden in einer Datei mehrere Schriftarten (\#type\#-Anweisung) verwendet,
+ berechnet 'lineform'/'autoform' nach der eingestellten Zeilenbreite die Anzahl
+ der Zeichen, die auf eine Zeile passen.
+
+---- Bearbeitung unterschiedlicher Zeilenbreiten:
+ Manchmal ist es notwendig, die Zeilenbreite zu verändern (\#limit\#-
+ Anweisung). Dies wird von 'autoform'/'lineform' berücksichtigt.
+
+---- Silbentrennung:
+ Automatische ('autoform') und interaktive Silbentrennung ('lineform').
+
+
+'lineform'/'autoform' akzeptiert als Eingabe eine Datei und verändert diese. Dafür wird
+eine (interne) Zwischendatei benötigt. Deshalb müssen Sie darauf achten, daß noch
+ausreichend Platz auf dem System ist, der jedoch nur zwischenzeitlich für den Forma­
+tierungsschritt benötigt wird.
+
+'lineform' und auch 'pageform' sind auf den ersten Schrifttyp der Fonttabelle, auf eine
+Zeilenbreite von 16.0 und eine Seitenhöhe von 25.0 initialisiert. Sind die ersten An­
+weisungen, die das verändern könnten, fehlerhaft, so bleiben diese Werte (wie auch
+sonst bei ignorierten Anweisungen) erhalten.
+
+'lineform'/'autoform'fragt nach dem Kommando an, mit welchem #ib#Schrifttyp#ie# und mit
+welcher #ib#Zeilenbreite#ie# die Datei formatiert werden soll. Dabei erscheinen zuerst die
+voreingestellten Anweisungen. Beispiel:
+
+____________________________________________________________________________
+
+LINEFORM (für ... Zeilen): dateiname
+
+Bitte Schrifttyp: micro
+Zeilenbreite (in cm): 16.0
+
+
+____________________________________________________________________________
+
+
+
+Diese Anweisungen können Sie jetzt durch Ihre gewünschten Anweisungen ersetzen.
+Diese Informationen werden von 'autoform'/'lineform' in Form von \#limit\#- und
+\#type\#-Anweisungen in der Datei vermerkt, so daß die Anfragen bei weiteren
+Datei-Bearbeitungen entfallen.
+
+Bei Zeilen, die länger als die angegebene Zeilenbreite sind, werden diejenigen Worte,
+die über die Zeilenbreite hinausgehen, in die nächste Zeile umgebrochen. Kürzere
+Zeilen werden aus der nachfolgenden Zeile bis zur Zeilenbreite aufgefüllt. Worte
+werden jedoch nicht über Absatzgrenzen hinweg verschoben. Deshalb sollten Sie vor
+Anwendung von 'lineform'/'autoform' darauf achten, daß Absätze richtig markiert
+wurden. Fehlende Markierungen sollten Sie nachträglich einfügen ( <CR> am Ende
+einer Zeile), andernfalls werden Zeilen über Absatzgrenzen zusammengezogen. Dies
+ist besonders bei Tabellenzeilen unangenehm.
+
+#ib#Einrückungen#ie# (Leerzeichen am Anfang einer Zeile) werden von 'lineform'/'autoform'
+ebenfalls bei der Formatierung von Zeilen eingehalten.
+#page#
+
+#ib(9)#5.2.1. #ib#Zeilenweise formatieren#ie##ie(9)#
+#free(1.0)#
+#ib(9)#5.2.1.1. #ib#Interaktive Silbentrennung#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ 'lineform' trennt Silben interaktiv, d.h., es werden Ihnen von 'lineform' #ib#Trennungs­
+ vorschläge#ie# gemacht, die Sie bestätigen oder ablehnen können.
+ #off("i")#
+#free(1.0)#
+Paßt ein Wort nicht mehr ganz auf eine Zeile, dann wird es zur interaktiven Tren­
+nung angeboten. Bei der Trennung werden Anweisungen innerhalb des Wortes ent­
+sprechend berücksichtigt. Die Umgebung dieses Wortes wird zur Erleichterung des
+Trennvorgangs mit angezeigt. Das Trennzeichen erscheint an einer sinnvollen Stelle
+im zu trennenden Wort.
+
+____________________________________________________________________________
+
+ Text vor dem Trennwort; das
+ Trenn-wort steht mit diesem Text in dieser Zeile
+
+____________________________________________________________________________
+
+
+Der Teil des zu trennenden Wortes, der noch auf die Zeile passen würde, wird mar­
+kiert angezeigt. Sie können das Trennzeichen mit Hilfe der Positionierungstasten
+innerhalb des Trennbereichs verschieben. An der gewünschten Trennposition (der
+Wortteil, der noch auf die Zeile kommen soll, steht links vom Trennstrich) kann die
+<CR>-Taste betätigt werden. <CR> zeigt dem Programm 'lineform' an, daß an dieser
+Stelle die Trennung erfolgen soll. 'lineform' fügt an den ersten Teil des Wortes das
+"-"-Zeichen an und schreibt den abgetrennten Wortteil in die nächste Zeile.
+#page#
+Es stehen folgende #ib(1)#Operationen bei der interaktiven Trennung#ie# zur Verfügung:
+#lpos(0.0)# #bpos(4.0, 11.0)# #table#
+
+#on("b")#Taste Bedeutung#off("b")#
+
+<CR> Trennen.
+
+
+<<> Trennzeichen um ein Zeichen nach links verschieben.
+
+
+<>> Trennstelle um ein Zeichen nach rechts verschieben.
+
+
+<HOP> <<> Trennstelle vor das Wort setzen (das Wort wird an
+ dieser Position nicht getrennt).
+
+
+<HOP> <>> Trennstelle an das Ende der Markierung setzen.
+
+
+<BLANK> Trennzeichen wird von "-" auf " " umgeschaltet.
+ Dies kann verwendet werden, um Worte, die nicht
+ zusammengeschrieben werden sollen, beim Trenn­
+ vorgang in zwei Worte aufzuspalten.
+
+
+<-> Schaltet das Trennzeichen von Leerzeichen (" ")
+ wieder auf den Trennstrich ("-") um.
+
+
+<ESC> Abbruch von 'lineform'/'autoform'. Die zu bearbeitende
+ Datei steht unverändert zur Verfügung.
+
+#tableend##clearpos#
+#page#
+Zwei Besonderheiten sind bei der interaktiven Trennung noch zu beachten:
+
+ - Bei Worten mit Bindestrich wird die Trennstelle hinter dem Bindestrich als Leer­
+ zeichen angezeigt.
+
+ - Bei einer Trennposition zwischen den Zeichen "ck" wird das Zeichen "c" in ein
+ "k" umgewandelt.
+
+ Beispiel: Druk-ker
+
+Sofern es für die Zeilenformatierung notwendig ist, macht die Prozedur 'lineform'
+bereits erfolgte Trennungen rückgängig (das Trennzeichen wird entfernt und die
+Wortteile werden wieder zusammengefügt), wenn sich das getrennte Wort (etwa durch
+Korrekturen oder Veränderungen der Zeilenbreite) nicht mehr am Zeilenende befinden
+sollte.
+
+Wenn Sie nicht Ihren Gesamttext mit 'lineform' bearbeiten möchten, haben Sie die
+Möglichkeit, #ib#'lineform' auf einen Textausschnitt#ie# anzuwenden. Hierfür markieren Sie
+den gewünschten Bereich, drücken <ESC> <ESC> und geben im Editor das Kommando
+'lineform'. (siehe S. #topage("lineform")#)
+
+____________________________________________________________________________
+
+...................dateiname................... Zeile 30
+
+
+Wenn Sie nicht Ihren Gesamttext mit 'lineform' bearbeiten
+möchten/brauchen, haben Sie die Möglichkeit,
+'lineform' für einen
+Textausschnitt anzuwenden. Hierfür markieren Sie den gewünschten
+Bereich, drücken 'ESC' 'ESC' und
+geben das Kommando 'lineform'.
+
+
+gib kommando:lineform
+
+
+____________________________________________________________________________
+
+
+#page#
+
+#ib(9)#5.2.1.2. #ib#Automatische Silbentrennung#ie# mit
+ '#ib#autoform#ie#'#ie(9)#
+#free(1.0)#
+ #on("i")#
+ 'autoform' arbeitet wie 'lineform', nur werden die Silbentrennungen automatisch
+ vorgenommen.
+ #off("i")#
+#free(1.0)#
+Ist eine Silbentrennung bei der Formatierung notwendig, übernimmt 'autoform' diese
+automatisch. Die Trennungen werden in das #ib#Notizbuch#ie# eingetragen. Nach Beendigung
+der Formatierung wird die bearbeitete Datei und das Notizbuch zur Kontrolle der
+Silbentrennungen angezeigt. Die automatische Silbentrennung arbeitet mit einer hohen
+#ib#Trenngüte#ie#; allerdings nur für deutsche Texte. Trotzdem kann es vorkommen, daß
+einige Trennungen, insbesondere bei zusammengesetzten Worten, falsch vorgenom­
+men werden. In einem solchen Fall müssen Sie diese nachträglich mit dem Editor
+korrigieren. (vgl. Sie dazu auch 5.8.4.)
+#page#
+
+#ib(9)#5.2.2. #ib#Unterschiedliche Schriften#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ #ib#Unterschiedliche Schrifttypen#ie# (Schriftarten) können Sie mit der \#type ("schrift­
+ name")\#-Anweisung anfordern.
+ #off("i")#
+#free(1.0)#
+Sie haben die Möglichkeit, mit 'lineform' verschiedenartige #ib#Schrifttypen#ie(1, ", unterschiedliche")# (kurz Typen
+genannt) verarbeiten zu lassen. Jede Type hat eine bestimmte Höhe und jedes Zei­
+chen hat eine bestimmte Breite. Alle Typen werden auf einer Grundlinie gedruckt.
+
+Es gibt zwei Arten von Schriften:
+bei#on("b")# #ib#äquidistanten Schriften#ie##off("b")# sind alle Zeichen gleich breit (wie bei einer Schreib­
+maschine).#on("b")# #ib#Proportionalschrift#ie##off("b")# findet man in gedruckten Büchern. Hier haben unter­
+schiedliche Zeichen auch unterschiedliche Breiten. Die Zeichen ".", "i", "!" sind z.B.
+schmaler als die Zeichen "w", "o", "m" usw.
+
+Mit der Anweisung:
+
+____________________________________________________________________________
+
+ \#type ("schriftname")\#
+
+____________________________________________________________________________
+
+
+kann auf einen anderen Schrifttyp umgeschaltet werden (auch mehrmals innerhalb
+einer Zeile). Diese Type gilt solange, bis wieder eine neue \#type ("schriftname")\#-
+Anweisung gegeben wird.
+
+____________________________________________________________________________
+
+
+ \#type ("micro")\#Jetzt schreiben wir mit einem
+ Schrifttyp, der 'micro' heißt. Und jetzt
+ \#type ("modern15")\#schalten wir auf eine an­
+ dere Schriftart um. Nun \#type ("modern12")\#
+ möchten wir mit einer größeren Type schrei­
+ ben. Um wieder zu unserem gewohnten Schrift­
+ typ zu gelangen, schalten wir auf \#type
+ ("trium8")\# zurück.
+
+
+____________________________________________________________________________
+
+
+Druckbild (ohne 'lineform'):
+
+
+Jetzt schreiben wir mit einem
+Schrifttyp, der 'micro' heißt. Und jetzt
+schalten wir auf eine an­
+dere Schriftart um. Nun
+möchten wir mit einer größeren Type schrei­
+ben. Um wieder zu unserem gewohnten Schrift­
+typ zu gelangen, schalten wir auf
+\#type ("trium8")\# zurück.
+
+
+
+Welche Schriftarten Ihnen zur Verfügung stehen, hängt natürlich von dem verfügbaren
+Drucker ab. Sie können die vorhandenen Schrifttypen mit dem Kommando 'list fonts'
+erfragen.
+
+Schrifttypen können modifiziert, d.h. verändert, gedruckt werden (vergl. Sie dazu den
+nächsten Abschnitt). Durch die Angabe einer \#type ("schriftname")\#-Anweisung
+werden alle Modifikationen ausgeschaltet.
+#page#
+#goalpage("on")##goalpage("off")#
+
+#ib(9)#5.2.3. #ib#Veränderung des Schrifttyps#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Mit der #ib#\#on ("..."\#-#ie(1,"Anweisung")# und #ib#\#off ("...")\#-Anweisung#ie# können Sie einen Schrifttyp in
+ seinem Aussehen verändern. Die Schrift wird zwar nicht gewechselt, aber ver­
+ ändert gedruckt. Zur Zeit ist #ib##ie(1,"Unterstreichung")##ib# unterstrichen#ie#, #ib#fett#ie#, #ib#kursiv#ie# und der Druck von#ib# weiß auf
+ schwarz #ie#möglich (abhängig vom eingesetzten Drucker).
+ #off("i")#
+#free(0.7)#
+Die \#on\#/\#off\#-Anweisung wirkt wie ein Schalter, der die gewünschte #ib#Schrifttyp-
+Modifikation#ie# ein- bzw. ausschaltet. Die Anweisung \#on\# schaltet die Modifikation ein,
+\#off\# schaltet sie aus.
+
+____________________________________________________________________________
+
+ Das EUMEL-System ermöglicht es Ihnen,
+
+ \#on ("italic")\#kursiv\#off ("italic")\#
+ \#on ("i")\# \#off ("i")\#
+
+ und
+
+ \#on ("underline")\#unterstrichen\#off ("underline")\#
+ \#on ("u")\# \#off ("u")\#
+
+ und
+
+ \#on ("bold")\#fett\#off ("bold")\#
+ \#on ("b")\# \#off ("b")\#
+
+ und
+
+ \#on ("reverse")\#invers (weiß auf schwarz)\#off ("reverse")\#
+ \#on ("r")\# \#off ("r")\#
+
+ zu schreiben
+
+____________________________________________________________________________
+#page#
+Druckbild:
+
+
+ Das EUMEL-System ermöglicht es Ihnen,
+
+ #on("i")#kursiv#off("i")#
+
+ und
+
+ #on("underline")#unterstrichen#off("underline")#
+
+ und
+
+ #on("b")#fett#off("b")#
+
+ und
+
+ #on("reverse")#invers (weiß auf schwarz)#off("reverse")#
+
+ zu schreiben.
+
+
+
+Dabei sollten Sie folgendes beachten:
+
+a) Ein \#type\#-Anweisung schaltet immer eine vorausgehende Modifikation aus, d.h.
+ ein Schrifttypwechsel macht eventuelle \#off ("b")\#-, \#off ("u")\#-, \#off ("i")\#-
+ und \#off ("r")\#-Anweisungen überflüssig.
+
+b) 'lineform'/'autoform' erzeugt eine Warnung, falls Sie vergessen haben, eine Modi­
+ fikation auszuschalten.
+
+c) Nicht alle Drucker können die hier angegebenen Modifikationen auch drucken.
+ Welche Modifikationen gleichzeitig eingeschaltet werden können, ist ebenfalls
+ druckerabhängig.
+#page#
+
+#ib(9)#5.2.4. #ib#Gesperrt schreiben#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Die Silbentrennung an einem Leerzeichen verhindert man durch Verwendung des
+ geschützten Leerzeichens 'ESC' und 'Leertaste'.
+ #off("i")#
+#free(1.0)#
+Möchten Sie ein Wort g e s p e r r t schreiben, muß natürlich verhindert werden, daß
+dieses Wort beim Formatieren getrennt wird. Andere Worte, wie z.B. in Formeln,
+sollten ebenfalls zusammen auf eine Zeile geschrieben werden (z.B. 'sin (x)'). Dies
+können Sie erreichen, indem Sie nicht das Leerzeichen zwischen die Zeichen schrei­
+ben, denn das Leerzeichen bedeutet für 'autoform'/'lineform' immer das Ende eines
+Wortes. Stattdessen verwenden Sie <ESC> <Leertaste>. Das geschützte Leerzeichen
+erscheint auf dem Bildschirm zur besseren Identifizierung invers dargestellt bzw. als
+ein anderes Zeichen (abhängig von Ihrem Gerät). Beim Drucken wird jedoch wieder
+ein Leerzeichen produziert.
+
+
+
+____________________________________________________________________________
+
+ g e s p e r r t
+
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+ g e s p e r r t
+
+
+
+#page#
+#goalpage("limit")#
+
+#ib(9)#5.2.5. #ib#Zeilenbreite einstellen#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Mit der #ib#\#limit\#-Anweisung#ie# können Sie die Zeilenbreite einstellen.
+ #off("i")#
+#free(1.0)#
+Die \#limit\#-Anweisung gibt in cm an, wie breit die Zeile sein soll. Beachten Sie, daß
+diese Anweisung nichts mit dem Editor-Kommando 'limit' zu tun hat. Dieses gibt an,
+wie viele Zeichen eine Bildschirmzeile lang sein soll.
+
+Die Zeilenbreite wird zusammen mit dem Schrifttyp beim erstmaligen Aufruf von
+'autoform'/'lineform' interaktiv erfragt und als \#limit\#-Anweisung (zusammen mit der
+\#type\#-Anweisung) in die erste Zeile der Datei eingetragen. Sie kann in einer Datei
+mehrmals verändert werden.
+
+Die neue Zeilenbreite gilt immer ab der #on("b")#nächsten#off("b")# Zeile, die der \#limit\#-Anweisung
+folgt. Beachten Sie, daß Sie als Parameter in der \#limit\#-Anweisung eine Zahl mit
+Dezimalpunkt und Nachkommastelle angeben müssen.
+
+____________________________________________________________________________
+
+
+\#limit(9.0)\#
+ Mit der \#limit\#-Anweisung können Sie Para­
+ graphen in einem anderen Format leicht gestal­
+ ten. Die rechte Schreibgrenze wird durch die
+ \#limit\#-Anweisung eingestellt, wobei Sie den
+ linken Rand durch eine entsprechende Ein­
+ rückung gestalten können.
+\#limit(11.0)\#
+
+____________________________________________________________________________
+
+
+Druckbild (mit 'lineform' bearbeitet):
+
+
+ Mit der \#limit\#-Anweisung können Sie Paragraphen in einem
+ anderen Format leicht gestalten. Die rechte Schreibgrenze
+ wird durch die \#limit\#-Anweisung eingestellt, wobei Sie den
+ linken Rand durch eine entsprechende Einrückung gestalten
+ können.
+
+
+
+Die folgende Tabelle gibt sinnvolle #ib#'limit'-Einstellungen#ie# für die am häufigsten ver­
+wendeten Papiergrößen an:
+
+
+ #on("b")#Format 'limit' Verbleibender
+ (Zeilenbreite) Rand#off("b")#
+
+ DIN A4 16.0 cm je 2.50 cm
+
+ DIN A5 12.0 cm je 1.42 cm
+
+ DIN A4 quer 25.0 cm je 2.35 cm
+#page#
+#goalpage("einfache Tabellen")#
+
+#ib(9)#5.2.6. Einfache #ib#Tabellen#ie(1,", einfache")# und #ib#Aufzählungen#ie#
+ schreiben#ie(9)#
+#free(1.0)#
+ #on("i")#
+ Aufzählungen und einfache #ib#Tabellen#ie(1, ", einfache")# werden automatisch richtig formatiert und
+ gedruckt, wenn Sie sich an einige einfache Regeln halten.
+ #off("i")#
+#free(1.0)#
+Verwenden Sie eine #ib#Proportionalschrift#ie# beim Tabellenschreiben, so sind die Spalten in
+der Regel unterschiedlich breit, selbst wenn Sie eine gleiche Anzahl Zeichen in jeder
+Spalte schreiben. Dies können Sie durch das Schreiben von einem "#ib#Doppelblank#ie#"
+("#ib#Mehrfachblank#ie#") vermeiden; für kompliziertere Tabellen gibt es spezielle Tabellen­
+anweisungen. (siehe auch S. #topage("tabellenanw")#)
+
+____________________________________________________________________________
+
+ iiii ooooo
+ mmmm lllll
+
+____________________________________________________________________________
+
+
+
+Druckbild:
+
+
+ iiii ooooo
+ mmmm lllll
+
+Erste und zweite Spalte stehen nicht untereinander.
+
+
+Aber mit Doppelblanks:
+
+____________________________________________________________________________
+
+ iiii ooooo
+ mmmm lllll
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+
+ iiii ooooo
+ mmmm lllll
+
+Erste und zweite Spalte stehen jetzt untereinander.
+
+Das Doppelblank dient 'lineform'/'autoform' und dem Drucker als Zeichen, daß die
+Positionen speziell berechnet und beim Druck berücksichtigt werden müssen. Das gilt
+nur nach einer Absatzzeile. In seltenen Fällen (insbesondere beim Einsatz von Schrift­
+typen, die in der Größe stark voneinander abweichen) kann es vorkommen, daß diese
+Tabellenautomatik nicht funktioniert und Spalten übereinander gedruckt werden. In
+solchen Fällen müssen Sie die Anzahl der trennenden Doppelblanks erhöhen.
+
+#on("b")##on("is")#Praktischer Tip:#off("is")##off("b")#
+Beachten Sie, daß es für das Funktionieren der "#ib#Tabellenautomatik#ie#" erforderlich ist,
+daß jede Tabellenzeile eine Absatzzeile ist. Man sollte diese Zeilen vor dem Druck
+daraufhin überprüfen oder durch 'lineform'/'autoform' die Datei bearbeiten lassen.
+Sollten durch die zeilenweise Formatierung einmal wegen fehlender Absatzkennzeich­
+nung zwei Zeilen zusammengezogen sein, können Sie diese leicht mit dem Editor
+wieder "auseinanderbrechen" ( <HOP> <RUBIN> , <CR> und <HOP> <RUBIN> ).
+
+
+Ähnliches gilt bei Aufzählungen.
+
+____________________________________________________________________________
+
+ 1) Das ist die erste Aufzählung.
+ Dieser Satz wird bündig gedruckt.
+ 2) Hier auch.
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+
+ 1) Das ist die erste Aufzählung.
+ Dieser Satz wird bündig gedruckt.
+ 2) Hier auch.
+
+
+Auch in solchen Fällen wird der gedruckte Text in der Regel richtig eingerückt. Die
+#ib#Tabellenautomatik#ie# wirkt nur nach einem Absatz. Hier aber ein Beispiel für eine
+typische Fehlersituation:
+
+____________________________________________________________________________
+
+ \#type("normal")\#
+ 1. Aufzählung
+ 2. Aufzählung
+ 3. Aufzählung
+
+ \#type("fett")\#M1. Aufzählung
+
+____________________________________________________________________________
+
+
+Die Einrückbreite wird durch den Schrifttyp bestimmt, der vor der Zeile herrscht, und
+den ganzen Absatz über beibehalten.
+
+
+Druckbild:
+
+
+ 1. Aufzählung
+ 2. Aufzählung
+ 3. Aufzählung
+
+ M1. Aufzählung
+
+
+Das Blank zwischen 'M1.' und 'Aufzählung' reicht nicht aus, um eine Überschreibung
+zu verhindern. Diesen Fehler können Sie umgehen, indem Sie die \#type\#-Anweisung
+in eine gesonderte Zeile stellen. Richtig wäre folgendes (gewünschter Schrifttyp vor
+die Zeile!):
+
+____________________________________________________________________________
+
+ \#type("trium8")\#
+ 1. Aufzählung
+ 2. Aufzählung
+ 3. Aufzählung
+
+ \#type("triumb14")\#
+ M1. Aufzählung
+
+____________________________________________________________________________
+
+
+
+Druckbild:
+
+
+ 1. Aufzählung
+ 2. Aufzählung
+ 3. Aufzählung
+
+
+ M1. Aufzählung
+
+
+Die genauen Regeln sind etwas kompliziert, so daß sie hier nicht einzeln aufgeführt
+werden (siehe S. 5-89#topage("block")# unter der Anweisung \#block\#). Treffen Sie auf einen der
+seltenen Fälle, wo die Tabellenautomatik nicht funktioniert, können Sie immer noch
+Tabellen-Anweisungen verwenden.
+#mark ("", "")#
+#page#
+
+#goalpage("tabellenanw")#
+#ib(9)#5.2.6.1. #ib#Tabellenanweisungen#ie##ie(9)#
+#free(1.0)#
+ Mit den Tabellenanweisungen der Textkosmetik können Sie auf einfache Art Tabel­
+ len auch mit Porportionalschriften gestalten.
+#free(1.0)#
+Es ist sehr einfach, eine Tabelle in einer äquidistanten Schrift zu schreiben, denn
+hierbei stimmt das Schriftbild auf dem Terminal weitgehend mit dem späteren Druck
+überein. Bei einer äquidistanten Schrift ist jedes Zeichen gleich breit - Sie können
+also "sehen", an welcher Zeilenposition eine neue Spalte beginnt.
+
+Etwas schwieriger sind Tabellen mit Proportionalschriften, da hier jedes Zeichen eine
+unterschiedliche Breite hat. Sie können somit einer Spaltenbreite nicht direkt "an­
+sehen", wie breit sie beim Druck wirklich wird. "Einfache" Tabellen können Sie mit
+dem Mehrfachblank gestalten (siehe S. 5-27). Bei komplizierteren Tabellen müssen
+Sie die folgenden Tabellenanweisungen benutzen.
+
+Um eine Tabelle zu gestalten, gehen Sie folgendermaßen vor:
+
+- Definieren Sie die Spaltenpositionen der Tabelle mit den folgenden Anweisungen.
+ Für die Punkte bei den Anweisungen müssen Sie entsprechende Parameter
+ einsetzen.
+
+#goalpage("lpos")##goalpage("rpos")##goalpage("cpos")##goalpage("dpos")##goalpage("bpos")#
+#goalpage("fillchar")#
+____________________________________________________________________________
+
+ #ib#\#l pos#ie(1,"-Anweisung")# (...)\# (* linksbündig *)
+ #ib#\#r pos#ie(1,"-Anweisung")# (...)\# (* rechtsbündig *)
+ #ib#\#c pos#ie(1,"-Anweisung")# (...)\# (* zentrierend *)
+ #ib#\#d pos#ie(1,"-Anweisung")# (..., ...)\# (* zentrierend um eine Zeichenkette *)
+ #ib#\#b pos#ie(1,"-Anweisung")# (..., ...)\# (* Blocksatz in einer Spalte *)
+ #ib#\#fillchar#ie(1,"-Anweisung")# (...)\# (* Füllzeichen zwischen Spalten *)
+
+____________________________________________________________________________
+
+
+ Die Zentrierung um eine Zeichenkette ist wie folgt zu verstehen: Die Spalte wird
+ bis zum Anfang der angegebenen Zeichenkette rechtsbündig und ab der Zeichen­
+ kette linksbündig geschrieben.
+
+#goalpage("table")#
+- Schreiben Sie dann die Tabelle. Sie muß von den Anweisungen
+
+____________________________________________________________________________
+
+ #ib#\#table\##ie(1,"-Anweisung")#
+
+
+ #ib#\#table end\##ie(1,"-Anweisung")#
+
+____________________________________________________________________________
+
+
+ eingefaßt werden. Die Spalten in der Tabelle müssen Sie durch mindestens zwei
+ Leerzeichen voneinander trennen. Es müssen alle Spalten in einer Tabelle vor­
+ handen sein. Soll einmal eine Spalte leer bleiben, müssen Sie für diese Spalte ein
+ #ib#geschütztes Leerzeichen#ie# verwenden.
+
+- Da die Spaltenpositionen erhalten bleiben (auch über die Anweisung \#table end\#
+ hinweg), sollten Sie direkt hinter dem Tabellenende die #ib#\#clear pos\#-Anweisung#ie#
+ geben.
+
+- Dann können Sie 'lineform'/'autoform' vornehmen.
+
+____________________________________________________________________________
+
+
+ \#r pos (2.2)\#\#c pos (3.8)\#\#l pos (5.8)\#\#d pos (8.8, ".")\#
+ \#table\#
+ erste Spalte zweite Spalte dritte Spalte vierte Spalte
+ rechtsbündig zentriert linksbündig dezi.mal
+ 1234 1234 1234 12.34
+ 12345 12345 12345 123.45
+ 123456 123456 123456 1234.56
+ \#table end\# \#clear pos\#
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+
+ #r pos (2.2)##c pos (3.8)##l pos (5.8)##d pos (8.8, ".")#
+ #table#
+ erste Spalte zweite Spalte dritte Spalte vierte. Spalte
+ rechtsbündig zentriert linksbündig dezi.mal
+ 1234 1234 1234 12.34
+ 12345 12345 12345 123.45
+ 123456 123456 123456 1234.56
+ #table end##clear pos#
+
+
+
+Solche Tabellen können Sie in \#head\#, \#bottom\# oder innerhalb von Fußnoten schrei­
+ben. Es ist jedoch nicht möglich, eine Fußnote innerhalb dieser Tabelle zu definieren.
+Ausweg: Tabelle um die Fußnote aufspalten.
+#page#
+
+#ib(9)#5.2.6.2. Einstellen der #ib#Tabellenpositionen#ie (1, ", Einstellen von")##ie(9)#
+#free(0.7)#
+ #on("i")#
+ Mit den \#pos\#-Anweisungen können Sie eine bestimmte Position innerhalb der
+ Tabelle einstellen, zugleich aber auch bestimmen, wie die Spalte gedruckt werden
+ soll. #off("i")#
+
+#free(0.7)#
+____________________________________________________________________________
+
+ \#l pos (5.0)\#\#r pos (10.0)\#\#d pos (15.0, ".")\#
+
+____________________________________________________________________________
+
+
+Die Anweisung oben stellt die erste Spalte der Tabelle auf 5 cm vom Rand ein (links­
+bündig). Die zweite Spalte endet 10 cm vom Rand, wobei diese Spalte rechtsbündig
+geschrieben werden soll. Die dritte wird an die Position 15, zentriert um den Dezimal­
+punkt, gedruckt#u##count#)#e#.#foot#
+#u##value#)#e# Spaltenposition < 0.0 und Spaltenposition > 'eingestelltes limit' sind nicht
+ erlaubt.
+#end#
+
+Beachten Sie, daß ein "Überlappen" von Spalten erfolgen kann (in unserem Beispiel
+kann die erste Spalte in die zweite hineinschreiben). 'lineform' bzw. 'autoform' meldet
+bei Spalten-Überschreibungen einen entsprechenden Fehler.
+
+Für jede Spaltenposition nehmen Sie ein Element einer Zeile. Die Elemente müssen
+Sie beim Schreiben im Editor durch mindestens zwei Leerzeichen voneinander tren­
+nen. Auf die erste Spaltenposition wird das erste Element gedruckt, auf die zweite
+Position das zweite Element usw. Für das Drucken der Spalten wird der eingeschal­
+tete Schrifttyp mit möglicherweise einer Modifikation genommen. Der Schrifttyp und
+die Modifikation können innerhalb der Tabelle geändert werden#u##count#)#e#.#foot#
+#u##value#)#e# Die Zwischenräume zwischen den Spalten werden nicht modifiziert (also z.B.
+ nicht unterstrichen).
+#end#
+
+Beachten Sie, daß die Tabellenpositionen so lange erhalten bleiben, bis sie explizit
+gelöscht werden (\#clear pos\#-Anweisung, siehe S. 5-38).
+#page#
+
+#ib(9)#5.2.6.3. #ib#Blocksatz innerhalb einer Spalte#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Für Blocksatz innerhalb einer Spalte verwenden Sie die \#b pos (...)\#-Anweisung.
+ #off("i")#
+#free(1.0)#
+____________________________________________________________________________
+
+\#l pos (0.0)\#\#b pos (2.2, 8.0)\#\#l pos (9.0)\#
+\#table\#
+1. Spalte Die mittlere Spalte wird bis zur Druck­ 3. Spalte
+1. Spalte position '8.0' in Blocksatz gedruckt. Um 3. Spalte
+1. Spalte in dieser Spalte einen Absatz zu bekom­ 3. Spalte
+1. Spalte men, muß ein geschütztes Leerzeichen am 3. Spalte
+1. Spalte Ende der Spalte stehen. #cursor(" ")# 3. Spalte
+\#table end\# \#clear pos\#
+
+____________________________________________________________________________
+
+
+
+Druckbild:
+
+#l pos (0.0)##b pos (2.2, 8.0)##l pos (9.0)#
+#table#
+1. Spalte Die mittlere Spalte wird bis zur Druck­ 3. Spalte
+1. Spalte position '8.0' in Blocksatz gedruckt. Um 3. Spalte
+1. Spalte in dieser Spalte einen Absatz zu bekom­ 3. Spalte
+1. Spalte men, muß ein geschütztes Leerzeichen am 3. Spalte
+1. Spalte Ende der Spalte stehen. 3. Spalte
+#table end##clear pos#
+#page#
+
+#ib(9)#5.2.6.4. #ib#Tabellenspalten auffüllen#ie# (#ib#Füllzeichen#ie#)#ie(9)#
+#free(1.0)#
+ #on("i")#
+ Mit der \#fillchar\#-Anweisung können Sie Spaltenzwischenräume füllen.
+ #off("i")#
+#free(1.0)#
+Angenommen, Sie möchten eine Rechnung erstellen. Die Warenposten sollen links­
+bündig an der Druckposition '0.0' und die Beträge rechtsbündig an der Position '9.0'
+gedruckt werden. Zwischen einem Warenposten und dem dazugehörigen Betrag sollen
+entsprechend viele Punkte ('.') gedruckt werden. Das folgende Druckbild:
+
+#l pos (0.0)##r pos (9.0)##fillchar(".")#
+#table#
+30 Benutzerhandbücher 450,-DM
+10 Systemhandbücher 150,-DM
+
+#table end##clear pos#
+
+wird mit
+
+____________________________________________________________________________
+
+ \#l pos (0.0)\#\#r pos (9.0)\#\#fillchar(".")\#
+ \#table\#
+ 30 Benutzerhandbücher 450,-DM
+ 10 Systemhandbücher 150,-DM
+
+ \#table end\#\#clear pos\#
+
+____________________________________________________________________________
+
+
+erreicht. Mit der Anweisung \##ib#fillchar#ie#\# stellen Sie das/die #ib#Füllzeichen#ie# ein. Somit wer­
+den entsprechend viele Füllzeichen (anstatt der Leerzeichen) von dem Textende einer
+Spalte bis zu dem Textanfang der nächsten Spalte gedruckt. Die Füllzeichen bleiben
+so lange eingestellt, bis erneut die Anweisung \#fillchar\# gegeben wird. Insbesondere
+bleibt das Füllzeichen - genauso wie auch die eingestellten Spaltenpositionen -
+über das Tabellenende erhalten. Die Anweisung \#clear pos\# löscht - zusätzlich zu
+den Tabellenpositionen - auch das eingestellte Füllzeichen (setzt das Zeichen auf ' '
+zurück).
+
+Beachten Sie, daß die Füllzeichen direkt gedruckt werden (also ohne Leerzeichen
+zwischen dem Spaltentext und den Füllzeichen). Möchten Sie einen Zwischenraum
+zwischen dem Spaltentext und den Füllzeichen haben, dann fügen Sie ein geschütz­
+tes Leerzeichen an den Spaltentext an oder setzen eins vor die nachfolgende Spalte.
+
+Die Anweisung \#fillchar\# gilt für Zwischenräume zwischen allen Spalten. Soll nur #on("i")#ein#off("i")#
+Spaltenzwischenraum ausgefüllt werden, müssen Sie die \#fillchar\#-Anweisung in der
+Tabelle entsprechend geben.
+
+____________________________________________________________________________
+
+ \#l pos (1.0)\#\#r pos (5.0)\#\#r pos (10.0)\#
+ \#table\#
+ 1\#fillchar(".")\# 3\#fillchar(" ")\# 4
+ 2\#fillchar(".")\# 17\#fillchar(" ")\# 6
+ \#table end\#
+
+____________________________________________________________________________
+
+
+
+Druckbild:
+
+#l pos (1.0)##r pos (5.0)##r pos(10.0)#
+#table#
+1#fillchar(".")# 3#fillchar(" ")# 4
+2#fillchar(".")# 17#fillchar(" ")# 6
+#tableend##clear pos#
+
+
+
+
+Eingeschaltete Modifikationen gelten in diesem Fall auch für die Spaltenzwischen­
+räume.
+#page#
+
+#ib(9)#5.2.6.5. #ib#Tabellenpositionen löschen#ie##ie(9)#
+#goalpage("clearpos")#
+#free(1.0)#
+ #on("i")#
+ Mit der #ib#\#clear pos\#-Anweisung#ie# löschen Sie alle eingestellten Positionen.
+ #off("i")#
+#free(1.0)#
+Sollen gänzlich neue Positionen eingestellt werden, benutzen Sie die Anweisung
+
+
+____________________________________________________________________________
+
+ \##ib#clear pos#ie(1,"-Anweisung")#\#
+
+____________________________________________________________________________
+
+
+
+ohne Parameter. Sie löscht alle eingestellten Tabellenpositionen. Beachten Sie, daß
+\#clear pos\# auch das Füllzeichen für die \#fillchar\#-Anweisung löscht (es wird wieder
+ein ' ' voreingestellt). Eine einzelne Tabellenposition können Sie z.B. mit
+
+
+____________________________________________________________________________
+
+ \#clear pos (10.0)\#
+
+____________________________________________________________________________
+
+
+löschen.
+#mark ("","")#
+#page#
+
+#goalpage("u")##goalpage("d")#
+#ib(9)#5.2.7. #ib#Indizes#ie# und #ib#Exponenten#ie##ie(9)#
+
+#free(1.0)#
+ #on("i")#
+ Mit den Anweisungen #ib#\#u\##ie(1, "-Anweisung")#, #ib#\#d\##ie(1,"-Anweisung")# und #ib#\#e\##ie(1,"-Anweisung")# können Sie Exponenten und Indizes
+ schreiben.
+ #off("i")#
+#free(1.0)#
+Die Anweisung \#u\# (steht für 'up') schaltet auf eine Exponenten-Schreibweise um
+und zwar so lange, bis die Anweisung \#e\# (steht für 'end') angetroffen wird. Dabei
+wird automatisch auf den nächst kleineren Schrifttyp umgeschaltet (sofern vorhanden).
+
+____________________________________________________________________________
+
+ a\#u\#i,k\#e\#
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+ a#u#i,k#e#
+
+
+
+Die \#d\#-Anweisung ('d' steht für 'down') ist für Indizes gedacht und arbeitet analog
+zur \#u\#-Anweisung.
+
+____________________________________________________________________________
+
+ a\#d\#i,k\#e\#
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+ a#d#i,k#e#
+
+
+Die automatische Umschaltung auf den nächst kleineren Schrifttyp erfolgt nur, wenn
+in der #ib#Fonttabelle#ie# ein nächst kleinerer Schrifttyp angegeben ist. Sonst wird der ein­
+gestellte Schrifttyp für den Exponenten beibehalten.
+
+Nach der \#e\#-Anweisung wird automatisch wieder der Schrifttyp eingestellt, der vor
+der zugehörigen \#u\#-Anweisung galt. Die \#u\#- und \#e\#-Anweisungen bilden also
+Klammern. Innerhalb einer Anweisung kann jede beliebige, sinnvolle Textkosmetik-
+Anweisung stehen. Beachten Sie, daß Anweisungen innerhalb einer Klammer die
+Zeilenhöhe nicht verändern sollen. Wenn Sie beispielsweise eine \#type\#-Anweisung
+in eine Klammer schreiben, wird zwar der Index/Exponent in diesem Schrifttyp ge­
+druckt, aber der Drucker geht davon aus, daß die Zeilenhöhe nicht überschritten wird.
+Deshalb ist es angeraten, nur einen kleineren Schrifttyp innerhalb eines Index/Expo­
+nenten zu verwenden. Wie bereits erwähnt, wird auch in diesem Beispiel nach dem
+Klammerende auf den vorher eingestellten Schrifttyp zurückgestellt.
+
+Die Index/Exponenten-Klammern können auch geschachtelt werden.
+
+____________________________________________________________________________
+
+ a\#u\#um 1 hoch\#u\#noch 1 hoch\#e\#um 1 zurück\#e\# Grundlinie
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+ a#u#um 1 hoch#u#noch 1 hoch#e#um 1 zurück#e# Grundlinie
+
+
+
+Es gelten folgende #on("b")#Einschränkungen#off("b")#:
+
+1. Ein Exponent (Index) wird so positioniert, daß es in der Regel keine Überschrei­
+ bung mit der vorhergehenden (nachfolgenden) Zeile gibt.
+
+2. Bei mehrfachen Exponenten oder Indizes oder bei Umschaltung auf einen anderen
+ Schrifttyp innerhalb eines Exponenten (Index) oder wenn nicht auf einen kleineren
+ Schrifttyp umgeschaltet werden kann, besteht die Möglichkeit, daß der Exponent
+ oder Index über die "normale" Zeile hinausragt. In diesem Fall kann es Über­
+ schreibungen geben, die Sie mit der #ib#\#linefeed\#-Anweisung#ie# ausgleichen können.
+
+3. Eine Exponenten- oder Index-Klammer muß als Ganzes auf einer Zeile stehen.
+
+4. Gleichzeitige Exponenten- und Index-Ausdrücke, die übereinander stehen
+ sollen, sind zur Zeit mit den \#u\#/\#d\#-Anweisungen nicht möglich. Jedoch funk­
+ tioniert folgendes:
+
+
+____________________________________________________________________________
+
+ a\#u\#Exponent\#d\#Index des Exponenten\#e\#\#e\#
+
+____________________________________________________________________________
+
+
+
+ Druckbild:
+
+ a#u#Exponent#d#Index des Exponenten#e##e#
+
+
+
+5. Doppelblanks spielen innerhalb einer solchen Klammer keine Rolle, wirken also
+ wie zwei "normale" Leerzeichen und nicht als implizite Positionierung. Innerhalb
+ einer solchen Klammer werden Blanks, sofern die Anweisung \#block\# gegeben
+ wurde, nicht verbreitert.
+
+6. Indizes oder Exponenten sollten nicht mit den Modifikationen \#underline\# und/oder
+ \#reverse\# zusammen verwendet werden, da z.B. ein Unterstreichen von Indizes
+ und Exponenten innerhalb einer unterstrichenen Zeile zu einem solchen Ergebnis
+ führt:
+
+
+ Druckbild:
+
+ #on("u")#Indizes und Exponenten a#d#i,k#e# a#u#i,k#e# sollten nicht unterstrichen werden!#off("u")#
+#page#
+
diff --git a/doc/user/benutzerhandbuch.5b b/doc/user/benutzerhandbuch.5b
new file mode 100644
index 0000000..748e398
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5b
@@ -0,0 +1,1632 @@
+#start(5.0,1.5)##pagenr("%",42)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 5: Textkosmetik und Druck
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+5 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 5 - %
+#tableend##clearpos#
+#end#
+
+#ib(9)#5.3. #ib#Pageform#ie##ie(9)#
+#free(1.0)#
+#ib(9)#5.3.1. #ib#Seitenweise formatieren#ie##ie(9)#
+#goalpage("pageform")##goalpage ("autopageform")#
+#free(1.0)#
+ #on("i")#
+ 'pageform'/'autopageform' formatiert eine Datei seitenweise und erledigt Routine­
+ arbeiten wie die Plazierung von Fußnoten, Seitennumerierung usw.
+ #off("i")#
+#free(1.0)#
+
+Das Programm 'pageform' können Sie mit dem Kommando
+
+____________________________________________________________________________
+
+ gib kommando:
+ pageform ("dateiname")
+
+____________________________________________________________________________
+
+
+
+aufrufen. 'pageform' erzeugt aus der Eingabedatei (z.B.: "dateiname") eine Druck­
+datei, deren Name durch ein angehängtes '.p' gebildet wird (z.B.: "dateiname.p").
+
+Die von 'pageform' erzeugte Druckdatei besteht aus der Eingabedatei mit ggf. neu
+eingefügten Zeilen. Die eingesetzten Zeilen stammen aus \#head\#-, \#bottom\#- oder
+\#foot\#-Anweisungen. Dadurch erhöht sich die Zeilenanzahl der Datei.
+
+Sie können in Kopf- oder Fußzeilen Seitennummern aufnehmen. Diese Seiten­
+nummern werden von 'pageform'/'autopageform' bei Seitenwechseln automatisch
+erhöht und an eine von Ihnen gekennzeichnete Stelle eingesetzt. Fußnoten können
+auch durch Nummern gekennzeichnet werden. Querverweise sind ebenfalls möglich.
+#page#
+Nachdem 'pageform' eventuelle Kopf-, Fuß- und Fußnotenzeilen eingefügt hat,
+berechnet es die Anzahl von Zeilen, die auf eine Seite passen, aus den Angaben für
+Seitenlänge und Zeilenvorschub und aus der Höhe der eingestellten Schrifttypen
+(\#type\#-Anweisung). Dann zeigt 'pageform' das errechnete Seitenende auf dem Bild­
+schirm an. Das Seitenende kann interaktiv verschoben werden, um es an eine ge­
+wünschte Stelle zu plazieren und es können Leerzeilen eingefügt/gelöscht werden, um
+Seiten gleich lang zu machen. Zusätzlich können Sie Seiten in Spalten ("Zeitungs­
+druck") aufteilen und diese interaktiv formatieren.
+
+Bei mehreren Schrifttypen innerhalb einer Zeile wird als Zeilenhöhe automatisch die
+des größten Schrifttyps genommen. Dabei müssen Sie bedenken, daß zu Beginn der
+Zeile immer der Schrifttyp der vorherigen Zeile eingeschaltet ist.
+#page#
+
+#ib(9)#5.3.1.1. #ib#Automatische Seitenformatierung#ie(9)##ie#
+#free(1.0)#
+
+ #on("i")#
+ 'autopageform' arbeitet wie 'pageform', jedoch werden die Seitenenden automa­
+ tisch plaziert.
+ #off("i")#
+#free(1.0)#
+'autopageform' sucht zuerst das rechnerische Seitenende. Ist dort ein Absatz vor­
+handen, wird die Seite an dieser Stelle beendet. Falls nicht, sucht 'autopageform'
+nach oben in den nächsten vier Zeilen nach einem Absatz. Wird keiner gefunden,
+wird die Seite am rechnerischen Seitenende beendet.
+
+Ist die \#pageblock\#-Anweisung gegeben, wird zuerst nach oben in den vier letzten
+Zeilen nach einem Absatz gesucht, um dort die Seite zu beenden. Ist dort keiner
+vorhanden, wird auch über das rechnerische Seitenende hinweg versucht, die Seiten­
+länge zu plazieren (4 Zeilen). 'autopageform' beachtet in einem solchen Fall die
+'pagelength'-Anweisung, indem der Zeilenabstand gestaucht wird.
+#page#
+
+#ib(9)#5.3.1.2. #ib#Seitenende interaktiv verschieben#ie# #ie(9)#
+#free(1.0)#
+ #on("i")#
+ In diesem Abschnitt wird beschrieben, welche interaktiven Möglichkeiten Ihnen
+ 'pageform' bietet, Seiten zu gestalten.
+ #off("i")#
+#free(1.0)#
+Auf dem Bildschirm wird das von 'pageform' errechnete jeweilige Seitenende unter
+Angabe der aktuellen Seitennummer angezeigt. Das Seitenende erscheint ungefähr in
+der Mitte des Bildschirmes und wird durch eine von 'pageform' erzeugte Zeile ge­
+kennzeichnet, die auch - nach erfolgter Seitenformatierung - in der Druckdatei zu
+sehen ist. Der EUMEL-Drucker druckt diese Zeile nicht.
+
+____________________________________________________________________________
+
+Mehrere Fußnoten innerhalb einer Seite werden von 'pageform'/­
+'autopageform' in der Reihenfolge ihres Auftretens gesammelt und
+am Ende der Seite plaziert. Für eine entsprechende Trennung der
+Fußnoten voneinander (z.B. durch Leerzeilen) müssen Sie selbst
+sorgen.
+\#page\#\#--------------------- Ende Seite 215 --------\#
+Unter Umständen paßt die Fußnote nicht mehr auf die aktuelle
+Seite und muß deshalb von 'pageform'/'autopageform' auf die näch­
+ste Seite gebracht werden. 'pageform'/'autopageform' geht davon
+aus, daß die Kennzeichnung der Fußnote in der Zeile unmittelbar
+vor der Fußnote steht und bringt diese Zeile ebenfalls auf die
+neue Seite.
+
+
+____________________________________________________________________________
+
+
+Über der Markierung erscheinen die letzten Zeilen der bereits verarbeiteten Seite,
+darunter die ersten Zeilen der nächsten Seite. Sie können nun mit Hilfe der Positio­
+nierungstasten die Markierung und damit das Seitenende nach oben verschieben.
+Damit vermeiden Sie, daß ein logisch zusammengehöriger Text auseinandergerissen
+wird und sogenannte "Waisenkinder" entstehen (letzte Zeile eines Abschnittes kommt
+auf die neue Seite).
+
+Bei der interaktiven #ib#Formatierung#ie (1, " für Seiten")# können Sie die Markierung nicht über das errech­
+nete Ende einer Seite nach unten oder über das vorherige, bereits verarbeitete Seiten­
+ende nach oben verschieben.
+
+Haben Sie jedoch zu Beginn die #ib#\#pageblock\##ie(1,"-Anweisung")#-Anweisung (siehe S. 5-91) gegeben,
+ist es erlaubt, die Seitenende-Markierung auch einige Zeilen über das rechnerische
+Seitenende hinaus zu bewegen. Betätigen Sie dann <CR> , wird der Drucker (sofern
+möglich) den Zeilenabstand auf dieser Seite stauchen. In diesem Fall sollten Sie
+darauf achten, daß das Seitenende bei einem Absatz immer #on("b")##on("i")#vor#off("b")##off("i")# eventuell vorhan­
+dene Leerzeilen plaziert wird. Andernfalls werden die Leerzeilen am Ende der Seite
+als Textzeile mitgezählt und es bleibt entsprechender Platz frei!
+
+Innerhalb einer Fußnote kann die Markierung nicht verschoben werden. In diesem Fall
+wird interaktiv angefragt, ob die Fußnote auf der nächsten Seite fortgesetzt werden
+soll. Verneinen Sie die Anfrage, positioniert 'pageform' vor die Fußnote. Von dieser
+Stelle aus können Sie das Seitenende wie gewohnt verschieben.
+
+Bejahen Sie dagegen die Anfrage nach dem Fußnotenumbruch, plaziert 'pageform'
+das Seitende an dieser Stelle innerhalb der Fußnote. Der restliche Teil der Fußnote
+kommt auf die nächste Seite mit einer Anmerkung ('Forts. von letzter Seite')#u##count#)#e#.
+#foot#
+#u##value#)#e# Bei fremdsprachlichen Texten sollten Sie nach 'pageform' diese Anmerkungen
+ in der '.p'-Datei ändern.
+#end#
+
+Entstehen bei der Seitenformatierung am Anfang einer Seite #ib#Leerzeilen#ie(1, " am Seitenanfang")# (z.B. durch
+Plazierung des Seitenendes zwischen zwei Absätzen), so werden diese von 'page­
+form' automatisch aus der Druckdatei entfernt. Möchten Sie #ib#Leerzeilen am Anfang
+einer Seite#ie#, dann sollten Sie die \#free\#-Anweisung in Verbindung mit der \#page\#-
+Anweisung verwenden.
+
+Zusätzlich können Sie Leerzeilen in eine Seite der Druckdatei einfügen und/oder
+beliebige Zeilen löschen (vergl. b).
+#page#
+Folgende Operationen stehen Ihnen bei der interaktiven Seitenformatierung zur Ver­
+fügung:
+
+#on("b")#a) #ib#Seitenende verschieben#ie#:#off("b")#
+
+'pageform' berechnet das "rechnerische" Seitenende und zeigt dieses auf dem Bild­
+schirm durch die Markierung an. Die Markierung kann interaktiv verschoben werden:
+
+ #on("b")#Taste Bedeutung#off("b")#
+
+ <CR> Seitenende an diese Stelle plazieren.
+
+
+ <^> Seitenende eine Zeile nach oben verschieben.
+
+
+ <v> Seitenende eine Zeile nach unten verschieben (wenn
+ vorher nach oben verschoben bzw. wenn \#pageblock\#-
+ Anweisung gegeben ist).
+
+
+ <HOP> <^> Seitenende um einen Bildschirm nach oben verschieben.
+
+
+ <HOP> <v> Seitenende um einen Bildschirm nach unten verschieben.
+
+
+ <ESC> Abbruch der Seitenformatierung.
+
+
+
+#on("b")#b) #ib#Leerzeilen einfügen#ie# und/oder #ib#Zeilen löschen#ie##off("b")#
+
+Ist nach den Berechnungen von 'pageform' der Text ungünstig auf der Seite plaziert,
+können Sie in die Seite (der Druckdatei!) Leerzeilen einfügen und/oder Zeilen löschen.
+Dies kann beispielsweise sinnvoll sein, wenn durch die Löschung einer Zeile ein
+Absatz noch auf die Seite passen würde oder durch die Einfügung von Leerzeilen ein
+Absatz auf der letzten Zeile der Seite endet. Oft ist es auch sinnvoll, daß alle Seiten
+gleich lang sind. In diesem Fall sollten vor Kapiteln und Absätzen Leerzeilen eingefügt
+oder gelöscht werden.
+
+Um Leerzeilen einzufügen und/oder Zeilen zu löschen, müssen Sie die Markierung
+wie unter a) beschrieben an die Stelle plazieren, an der die Änderung vorgenommen
+werden soll.
+
+
+ #on("b")#Taste Bedeutung#off("b")#
+
+
+ <HOP> <RUBIN> Leerzeilen einfügen. Anstatt der Markierung können
+ durch (u.U. mehrmaliges) <CR> Leerzeilen eingefügt
+ werden. <HOP> <RUBIN> beendet den Vorgang (wie
+ Zeileneinfügen im Editor).
+
+ <HOP> <RUBOUT> Zeile löschen. Die Zeile unmittelbar oberhalb der
+ Markierung wird gelöscht.
+
+
+
+Anschließend berechnet 'pageform' die Seite erneut.
+
+
+
+#on("b")#c) #ib(9)##ib#\#page\#-Anweisung bestätigen/löschen#ie(9)##ie##off ("bold")#
+
+Wird von der Prozedur 'pageform' eine #ib#\#page\#-Anweisung#ie# angetroffen, so wird das
+gewünschte Seitenende auf Ihrem Bildschirm angezeigt. Die \#page\#-Anweisung
+können Sie entweder bestätigen oder löschen.
+
+ #on("b")#Taste Bedeutung#off("b")#
+
+
+ <CR> Seitenende bestätigen.
+
+ <RUBOUT> \#page\#-Anweisung ignorieren. Die Prozedur 'pageform'
+ bearbeitet in diesem Fall die Datei weiter, als ob keine
+ \#page\#-Anweisung angetroffen wurde.
+
+ <ESC> Abbruch der Seitenformatierung.
+#page#
+
+#ib(9)#5.3.2. #ib#Seitenlänge einstellen#ie##ie(9)#
+#goalpage("pagelength")#
+#free(0.7)#
+ #on("i")#
+ 'pageform'/'autopageform' ist auf ein Schreibfeld von 25.0 cm eingestellt (ent­
+ spricht einem DIN A4-Schreibfeld). Wünschen Sie eine andere Seitenlänge,
+ müssen Sie die #ib#\#pagelength\#-Anweisung#ie# in den Text einfügen.
+ #off("i")#
+#free(0.7)#
+____________________________________________________________________________
+
+ \#pagelength (20.0)\#
+
+____________________________________________________________________________
+
+
+stellt die Seitenlänge auf 20 cm ein.
+
+Beachten Sie, daß
+
+1. die neu eingestellte Seitenlänge immer erst ab der nächsten Seite gilt (die bislang
+ eingestellte Seitenlänge gilt noch für die aktuelle Seite).
+
+2. die eingestellte Seitenlänge am Anfang der Datei (also vor der ersten Textzeile) für
+ die erste Seite gilt.
+#mark ("", "")#
+
+3. der Dezimalpunkt bei der Seitenlänge mit angegeben werden muß.
+
+Die folgende Tabelle gibt die Seitenlänge für die am häufigsten gewählten Papier­
+größen an:
+
+ #on("b")#Format Seitenlänge oberer und
+ (in cm) unterer Rand#off("b")#
+
+ DIN A4 25.0 je 2.35 cm
+
+ DIN A5 18.0 je 2.15 cm
+
+ DIN A4 quer 16.0 je 2.50 cm
+#page#
+
+#ib(9)#5.3.3. #ib#Zeilenabstand einstellen#ie##ie(9)#
+#goalpage ("linefeed")#
+#free(1.0)#
+ #on("i")#
+ Mit der #ib#\#linefeed\#-Anweisung#ie# stellen Sie einen #ib#Zeilenvorschub#ie# relativ zu der
+ #ib#Schrifthöhe#ie# des eingestellten Schrifttyps ein.
+ #off("i")#
+#free(1.0)#
+'pageform'/'autopageform' berechnet die Anzahl der Zeilen pro Seite immer in Ab­
+hängigkeit von dem eingestellten Schrifttyp. Haben Sie z.B. eine Schrift gewählt, die
+doppelt so hoch wie eine Schreibmaschinenschrift ist, bekommen Sie auch entspre­
+chend weniger Zeilen auf eine Seite. Um diesen Berechnungsvorgang brauchen Sie
+sich in der Regel nicht zu kümmern.
+
+Anders verhält es sich, wenn ein anderer #ib#Zeilenabstand#ie# als der "normale" Abstand
+zwischen Zeilen eingestellt werden soll. In diesem Fall wird die \#linefeed\#-
+Anweisung eingesetzt. Der Parameter gibt an, um welchen Faktor eine Zeilenhöhe #on("i")##on("b")#ab
+der nächsten druckbaren Zeile#off("b")##off("i")# erhöht oder verringert werden soll.
+
+____________________________________________________________________________
+
+ \#linefeed (2.0)\#
+
+____________________________________________________________________________
+
+
+druckt die folgenden Zeilen mit doppeltem Zeilenabstand. Nach Antreffen dieser An­
+weisung wird die Zeilenhöhe durch 2 * eingestellte Schrifttypgröße errechnet. Es wird
+also der Zeilenabstand zwischen den Zeilen entsprechend vergrößert, da die Schrift­
+größe gleich bleibt. Dies entspricht dem zweizeiligen Schreiben bei einer Schreib­
+maschine (wenn man davon absieht, daß auch hier unterschiedliche Schrifthöhen
+möglich sind). Ein 1 1/2 zeiliges Schreiben wäre mit
+
+____________________________________________________________________________
+
+ \#linefeed (1.5)\#
+
+____________________________________________________________________________
+
+
+einzustellen.
+
+____________________________________________________________________________
+
+ \#linefeed (0.5)\#
+
+____________________________________________________________________________
+
+
+stellt die Zeilenhöhe = 1/2 * eingestellte Schrifthöhe ein, so daß die Zeilen teilweise
+ineinander gedruckt werden (was bei manchen Druckern zu nicht lesbaren Resultaten
+führt). Bei \#linefeed (0.0)\# werden Zeilen übereinander gedruckt (druckerabhängig).
+
+Beachten Sie, daß die Angabe in der \#linefeed\#-Anweisung relativ erfolgt. Bei allen
+anderen Anweisungen der Textkosmetik werden Angaben in Zentimetern verlangt. Die
+\#linefeed\#-Anweisung bildet somit eine Ausnahme.
+#page#
+
+#ib(9)#5.3.4. #ib#Platz freihalten#ie# #ie(9)#
+#goalpage ("free")#
+#free(1.0)#
+ #on("i")#
+ Mit der #ib#\#free\#-Anweisung#ie# können Sie einen zusammenhängenden Teil auf einer
+ Seite freihalten.
+ #off("i")#
+#free(1.0)#
+Die \#free\#-Anweisung setzen Sie an solchen Stellen im Text ein, an denen - nach
+dem Druck - Zeichnungen, Tabellen und ähnliches eingeklebt werden sollen. Sie
+können sie auch zwischen Absätzen, Kapiteln usw. einsetzen, wenn der Abstand nicht
+gleich dem Vielfachen der Zeilenhöhe ist. Es wird der in der \#free\#-Anweisung
+angegebene Platz freigehalten.
+
+____________________________________________________________________________
+
+\#free (2.0)\#
+
+____________________________________________________________________________
+
+
+hält zwei Zentimeter frei. Paßt der angeforderte Platz nicht mehr auf die Seite, so wird
+er auf der nächsten Seite reserviert ('pageform'/'autopageform' plaziert das Seiten­
+ende vor die \#free\#-Anweisung).
+
+
+
+#on("i")##on("b")#Praktischer Tip:#off("b")##off("i")#
+Sie sollten eine \#free\#-Anweisung allein auf eine Zeile schreiben, damit Sie sie u.U.
+durch 'pageform' interaktiv entfernen können, wenn die \#free\#-Anweisung ungünstig
+an den Seitenanfang oder das Seitenende kommt.
+#page#
+
+#ib(9)#5.3.5. #ib#Neue Seite beginnen#ie##ie(9)#
+#goalpage("page")#
+#free(1.0)#
+ #on("i")#
+ An einigen Stellen im Text, z.B. zu Beginn eines neuen Kapitels, möchten Sie
+ unbedingt eine neue Seite anfangen. Dies erreichen Sie mit der #ib#\#page\#-
+ Anweisung#ie#.
+ #off("i")#
+#free(1.0)#
+'pageform' meldet in diesem Fall, nach wie vielen Zentimetern auf der Seite die An­
+weisung angetroffen wurde. Sie können nun mit <CR> das Seitenende bestätigen oder
+die Anweisung (in der Druckdatei) löschen. Im letzteren Fall berechnet 'pageform' die
+Seite neu, als ob die \#page\#-Anweisung nicht dagewesen wäre.
+
+Gleichzeitig können Sie mit Hilfe der #ib#\#page\#-Anweisung#ie(1, ", mit neuer Seitenummer")# eine neue Seitennummer
+für die neue Seite einstellen (vergl. Sie dazu die nächsten Abschnitte).
+#page#
+
+#ib(9)#5.3.6. #ib#Kopf- und Fußzeilen#ie##ie(9)#
+#goalpage("head")##goalpage("bottom")#
+#free(1.0)#
+ #on("i")#
+ Mit den #ib#\#head\#-#ie(1, "Anweisung")# und #ib#\#bottom\#-Anweisung#ie#en können Sie Zeilen am Anfang und
+ Ende jeder Seite einfügen.
+ #off("i")#
+#free(1.0)#
+Sie schreiben Zeilen am Anfang ("#ib#Kopfzeilen#ie#") und Ende ("#ib#Fußzeilen#ie#") jeder Seite nur
+einmal und kennzeichnen sie mit Anweisungen. Diese Zeilen fügt 'pageform'/­
+'autopageform' dann an den entsprechenden Stellen ein.
+
+____________________________________________________________________________
+
+ \#head\#
+ Unser EUMEL-Benutzerhandbuch
+
+ \#end\#
+
+____________________________________________________________________________
+
+
+Diese Zeile (also die zwischen den \#head\#- und #ib#\#end\#-Anweisung#ie#en eingeschlos­
+sene Zeile) wird von 'pageform'/'autopageform' an den Anfang jeder Seite in die
+Druckdatei plaziert.
+
+Entsprechendes gilt für Fußzeilen, die zwischen \#bottom\# und \#end\# eingeschlossen
+werden müssen:
+
+____________________________________________________________________________
+
+ \#bottom\#
+
+ Autor: I. Listig
+ \#end\#
+
+____________________________________________________________________________
+
+
+#on("b")#Praktischer Tip#off("b")#:
+
+Fügen Sie mindestens eine Leerzeile am Ende eines \#head\# bzw. am Anfang eines
+\#bottom\# ein, um den eigentlichen Text von den Kopf- bzw. Fußzeilen abzuheben.
+
+
+'pageform'/'autopageform' zählt die Seiten, beginnend mit der Seitennummer '1'. (Wie
+man Seitennummern in die Kopf- und Fußzeilen bekommt, erfahren Sie im nächsten
+Abschnitt). Sie können nun getrennte Kopf- und Fußzeilen für gerade und ungerade
+Seiten gestalten (wie in diesem Benutzerhandbuch). Dies erfolgt mit den Anweisungen
+\#headeven\# und \#headodd\# für Seiten mit geraden und ungeraden Seitennummern;
+ebenso \#bottomeven\# und \#bottomodd\#. Diese Anweisungen müssen ebenfalls jeweils
+mit einer \#end\#-Anweisung beendet werden.
+
+Sie haben die Möglichkeit, Kopf- und Fußzeilen mehrmals innerhalb einer Datei zu
+wechseln, um unterschiedliche Beschriftungen zu erhalten (z.B. kapitelweise). Dies ist
+jedoch nur sinnvoll, wenn es auf einer neuen Seite erfolgt, also unmittelbar #on("b")##on("is")#nach#off("b")##off("is")# einer
+\#page\#-Anweisung.
+
+____________________________________________________________________________
+
+ \#page\#
+ \#head\#
+ Neuer Seitenkopf
+
+ \#end\#
+
+____________________________________________________________________________
+
+
+Kopf- und Fußzeilen sollen überall gleiches Aussehen haben, unabhängig davon,
+welche Anweisungen im restlichen Text gegeben werden. Darum werden die bei der
+Definition einer Kopf- und Fußzeile aktuellen Werte für
+
+
+ limit
+ type
+ linefeed
+
+
+bei dem Einsetzen der Zeilen berücksichtigt. Für Kopf- oder Fußzeilen können Sie
+einen anderen Schrifttyp als im restlichen Text verwenden, indem Sie die \#type\#-
+Anweisung innerhalb eines \#head\#- oder \#bottom\#-Bereiches geben. Beachten Sie,
+daß nach \#head\#-, \#bottom\# und auch \#foot\#-Bereichen die oben genannten An­
+weisungen nicht automatisch zurückgestellt werden. Darum sollten Sie vor der
+\#end\#-Anweisung wieder auf die im übrigen Text verwendeten Werte zurückstellen.
+
+____________________________________________________________________________
+
+ \#bottom\#
+ \#type ("klein")\#
+ Autor: I. Listig
+ (Schrifttyp
+ zurückstellen):
+ \#type ("normal")\#
+ \#end\#
+
+____________________________________________________________________________
+
+
+#page#
+
+#ib(9)#5.3.7. #ib#Seiten numerieren#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ In den Kopf- und Fußzeilen steht das #ib#'%'-Zeichen#ie# für die aktuelle Seiten­
+ nummer.
+ #off("i")#
+#free(1.0)#
+Erscheint das '%'-Zeichen innerhalb eines Kopf- oder Fußbereiches, wird von
+'pageform'/'autopageform' beim Einsetzen dieser Zeilen auf jeder Seite die aktuelle
+#ib#Seitennummer#ie# eingesetzt (sind mehrere '%'-Zeichen vorhanden, wird die Seiten­
+nummer mehrmals eingesetzt).
+
+____________________________________________________________________________
+
+ \#head\#
+ Seite: - % -
+
+ \#end\#
+
+____________________________________________________________________________
+
+
+Wenn Sie die Seitenzahl in der Zeilenmitte oder am rechten Rand plazieren möchten,
+können Sie die Anweisungen \#center\# (siehe S. 5-93) oder \#right\# (siehe S. 5-94)
+verwenden.
+
+Durch das Einrichten eines Fußbereiches können Sie die Seitennummern auch am
+unteren Ende einer Seite erzeugen. Beachten Sie, daß sich bei mehrstelligen Seiten­
+nummern die Zeilenlänge durch das Einsetzen vergrößert.
+
+Um zum Beispiel das #ib#Vorhandensein einer Folgeseite#ie# in einem Fußbereich zu kenn­
+zeichnen, müssen Sie das '%'-Zeichen zweimal direkt hintereinander schreiben.
+
+____________________________________________________________________________
+
+ \#bottom\#
+
+ \#right\# %%
+ \#end\#
+
+____________________________________________________________________________
+
+
+In dem Beispiel oben wird die Seitenzahl rechtsbündig gedruckt.
+
+
+Manchmal ist es notwendig und sinnvoll, einen Text in mehreren Dateien zu halten.
+Bei einer Folgedatei müssen Sie die Seitennummer dann neu setzen. Das erfolgt mit
+der \#pagenr\#- oder der \#page\#-Anweisung.
+
+____________________________________________________________________________
+
+ \#page (4)\#
+
+____________________________________________________________________________
+
+
+bewirkt eine neue Seite. Die Seitennummer der neuen Seite ist '4'.
+
+#goalpage("pagenr")#
+
+Bei einigen Spezialanwendungen benötigen Sie unter Umständen mehr als eine
+Seitennummer. Beispielsweise soll ein Text nicht nur absolut, sondern auch jede Seite
+in jedem Kapitel separat durchgezählt werden.
+
+____________________________________________________________________________
+
+ \#page (4711)\#
+ \#pagenr ("$", 1)\#
+ \#head\#
+ Mein Buch Seite: % Kapitelseite: $
+
+ \#end\#
+
+____________________________________________________________________________
+
+
+Die Anweisung #ib#\#pagenr#ie# ("$",1)\# veranlaßt, daß ab der nächsten Seite eine neue
+Numerierung durchgeführt wird. Dabei steht '$' stellvertretend für die neue Zahl. Die
+'1' bedeutet, daß bei der Numerierung mit '1' begonnen wird. 'pageform'/­
+'autopageform' erhöht bei jeder neuen Seite das Zeichen um '1' und setzt es ggf. in
+die Kopf- und Fußzeilen. Es sind zwei zusätzliche Seitenzeichen (neben dem '%')
+möglich.
+
+Beachten Sie, daß die neuen Seitennummern immer erst ab der nächsten Seite gel­
+ten. Geben Sie die \#page (...)\#- oder die \#pagenr (...,...)\#-Anweisung am Anfang
+der Datei (also vor der ersten Textzeile), gelten die neuen Seitennummern für die
+erste Seite.
+#page#
+
+#ib(9)#5.3.8. #ib#Fußnoten#ie# schreiben#ie(9)#
+#goalpage("foot")#
+#free(1.0)#
+ #on("i")#
+ Fußnoten werden direkt im Text durch die Anweisungen \#foot\# und \#end\#
+ gekennzeichnet. Die Fußnoten plaziert 'pageform'/'autopageform' an das Ende
+ einer Seite.
+ #off("i")#
+#free(1.0)#
+#ib#Fußnoten#ie# schreiben Sie direkt in den Text, am besten an der Stelle, an der später die
+Fußnote aufgerufen werden soll. Die Fußnote wird von 'pageform'/'autopageform' an
+das Ende einer Seite, ggf. vor die Fußzeilen, plaziert. Für die Kennzeichnung von
+Fußnoten und die entsprechende Markierung im Text sind Sie selbst zuständig. Aller­
+dings werden von 'pageform'/'autopageform' bei dem Einsetzen einer Fußnote am
+Ende einer Seite Unterstriche vor die Fußnoten eingefügt, damit Fußnoten vom lau­
+fenden Text abgehoben werden.
+
+____________________________________________________________________________
+
+ \#foot\#
+ *) Das ist die erste Anmerkung auf dieser Seite.
+ \#end\#
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+______
+*) Das ist die erste Anmerkung auf dieser Seite.
+
+
+Mehrere Fußnoten innerhalb einer Seite werden von 'pageform'/'autopageform' in der
+Reihenfolge ihres Auftretens gesammelt und am Ende der Seite plaziert. Für eine
+entsprechende Trennung der Fußnoten voneinander (z.B. durch Leerzeilen) müssen
+Sie selbst sorgen.
+
+Unter Umständen paßt die Fußnote nicht mehr auf die aktuelle Seite und muß deshalb
+von 'pageform'/'autopageform' auf die nächste Seite gebracht werden. 'pageform'/­
+'autopageform' geht davon aus, daß die Kennzeichnung der Fußnote in der Zeile
+unmittelbar vor der Fußnote steht und bringt diese Zeile ebenfalls auf die neue Seite.
+
+____________________________________________________________________________
+
+Es ist auch möglich, eine Fußnote innerhalb eines Abschnitts zu
+schreiben, wie z.B. in dieser Zeile\#u\#*)\#e\#.\#foot\#
+\#u\#*)\#e\# Fußnote in einem Abschnitt!
+\#end\#
+Sie fahren anschließend ohne Unterbrechung mit dem Schreiben
+Ihres Textes fort.
+
+____________________________________________________________________________
+
+
+Druckbild (nach lineform):
+
+Es ist auch möglich, eine Fußnote innerhalb eines Abschnitts zu schreiben, wie z.B.
+in dieser Zeile#u#*)#e#. Sie fahren anschließend ohne Unterbrechung mit dem Schreiben#foot#
+#u#*)#e# Fußnote in einem Abschnitt!
+#end#
+Ihres Textes fort.
+
+
+In diesem Fall ist es wünschenswert, daß 'lineform' die Zeile, die \#foot\# vorausgeht,
+mit der Zeile, die \#end\# folgt, auffüllt. Dies geschieht unter folgenden Bedingungen:
+
+1. Hinter \#foot\# darf nichts mehr stehen, also auch kein Absatzzeichen.
+
+2. Es werden so lange Worte von der Zeile nach \#end\# vor die \#foot\#-Anweisung
+ plaziert, bis die Zeile gefüllt oder die Zeile nach \#end\# leergeräumt ist.
+
+3. Beachten Sie, daß Textkosmetik-Anweisungen ebenfalls mit über die Fußnote
+ genommen werden. Handelt es sich beispielsweise um eine \#type\#-Anweisung,
+ kann sich das Aussehen der Fußnote verändern! Darum ist es angeraten, even­
+ tuelle Anweisungen, die die Fußnote verändern sollen, innerhalb der Fußnote zu
+ plazieren.
+
+Sie sollten vermeiden, umfangreiche Texte in Fußnoten zu schreiben (beispielsweise
+längere Zitate). Aus programmtechnischen Gründen begrenzt 'pageform'/'autopage­
+form' die maximale Länge von Fußnoten auf einer Seite auf 85% des effektiven
+Schreibfeldes (effektives Schreibfeld: Seitenlänge minus Länge von \#head\#- bzw.
+\#bottom\#-Zeilen). Nimmt eine Fußnote einen größeren Raum ein, bricht 'pageform'/
+'autopageform' die Seitenformatierung mit einer Fehlermeldung ab.
+#page#
+
+#ib(9)#5.3.8.1. #ib#Fußnoten numerieren#ie##ie(9)#
+#goalpage("count")##goalpage("value")#
+#free(1.0)#
+ #on("i")#
+ Gleichartige Textteile wie Lehrsätze, Beispiele, Fußnoten usw. werden i. allg.
+ durchnumeriert. Da Sie bei der Abfassung eines längeren Textes ihre genaue
+ Anzahl meist nicht vorausplanen können, übernimmt 'pageform'/'autopageform' die
+ Zählung.
+ #off("i")#
+#free(1.0)#
+Durch die #ib#\#count\#-Anweisung#ie# wird 'pageform'/'autopageform' veranlaßt, einen
+internen Zähler (beginnend bei dem Wert 0) zu erhöhen und diesen Wert statt der
+\#count\#-Anweisungen in den Text einzusetzen.
+
+____________________________________________________________________________
+
+ \#count\#
+
+____________________________________________________________________________
+
+
+setzt den Wert 1 statt der Anweisung ein. Jede weitere \#count\#-Anweisung erhöht
+den internen Zähler und der Zählerwert wird wiederum eingesetzt:
+
+____________________________________________________________________________
+
+ \#count\#
+
+____________________________________________________________________________
+
+
+setzt den Wert 2 ein usw. Dadurch ist es möglich, beliebige Textteile (Kapitel,
+mathematische Sätze u.a.m.) fortlaufend zu numerieren, ohne auf die Numerierung
+beim Schreiben und Ändern des Textes zu achten.
+
+Anmerkung:
+Trifft 'lineform' auf eine \#count\#-Anweisung, so wird die Zeile berechnet, als ob drei
+Ziffern anstatt der Anweisung im Text ständen.
+
+Mit der \#value\#-Anweisung können Sie den #on("b")##on("i")#letzten#off("i")##off("b")# erreichten count-Wert nochmals
+einsetzen. Das ist insbesondere für Fußnoten sinnvoll einsetzbar.
+
+____________________________________________________________________________
+
+ Text ....... (\#count\#)
+ \#foot\#
+ (\#value\#) Text der Fußnote
+ \#end\#
+ Text .......
+
+____________________________________________________________________________
+
+
+Das Resultat sähe folgendermaßen aus:
+
+ Text ....... (3)
+ Text .......
+ ...............
+ ______
+ (3) Text der Fußnote
+
+Beachten Sie, daß in diesem Fall die \#value\#-Anweisung der \#count\#-Anweisung
+folgen muß, ohne daß eine weitere \#count\#-Anweisung dazwischen steht. Das liegt
+- wie bereits oben erwähnt - daran, daß die \#value\#-Anweisung immer den letzten
+\#count\#-Wert einsetzt.
+
+Das können Sie umgehen, indem Sie die \#count\#- und \#value\#-Anweisungen mit
+einem TEXT-Parameter versehen, der als Kennzeichnung dient.
+
+____________________________________________________________________________
+
+ \#count ("Merk1")\#
+
+____________________________________________________________________________
+
+
+\#count ("Merk1")\# arbeitet ebenso wie \#count\# ohne Parameter und setzt für unser
+Kapitel hier den Wert 4 ein. Zusätzlich zu dem fortlaufend gezählten Wert (fortlau­
+fende Numerierung der Fußnoten) vermerkt 'pageform'/'autopageform' einen Wert, der
+bei Bedarf an irgendeiner anderen Stelle im Text durch \#value ("Merk1")\# wieder
+aufgerufen werden kann, zum Beispiel, wenn Sie auf eine andere Fußnote verweisen
+möchten.
+
+____________________________________________________________________________
+
+ \#count\#\#count\#
+ \#value("Merk1")\#
+
+____________________________________________________________________________
+
+
+Die ersten zwei \#count\#-Anweisungen produzieren - in unserem Kapitel - die
+Werte 5 bzw. 6. Die \#value\#-Anweisung dagegen setzt den vermerkten Wert 4 ein.
+
+Dies ist insbesondere sinnvoll, wenn Sie im Text auf eine Fußnote verweisen möch­
+ten.
+
+Beispiel:
+
+Sie schreiben einen mehrseitigen Prospekt über ein neues Produkt. Auf Seite 5 möch­
+ten Sie auf eine Fußnote verweisen, die auf einer anderen Seite steht. Dann fügen Sie
+'siehe auch Anmerkung (\#value("liefertermin")\#) in Ihren Text ein und fahren mit dem
+Schreiben fort. 'pageform'/'autopageform' setzt später die entsprechende Zahl für den
+Verweis ein.
+
+Auf der Seite, auf die Sie Bezug nehmen, sieht das ganze folgendermaßen aus:
+
+____________________________________________________________________________
+
+ Der Textverarbeitungskurs ist ein Lernprogramm für Anfänger.
+ \#(count)("Liefertermin")\#)
+ \#foot\#
+ (\#(value)("Liefertermin")\#)
+ Der Textverarbeitungskurs wird ab August erhältlich sein.
+ \#end\#
+ Das Programm ist auf den neuesten Erkenntnissen der Lehr­
+ forschung aufgebaut. Der Kurs umfaßt Lehrbuch, Arbeitsbuch und
+ sechs Kassetten.
+
+____________________________________________________________________________
+
+
+#page#
+Soll die Zahl für den Verweis bzw. für die Fußnote hochgestellt werden, fügen Sie die
+Anweisungen \#u\# und \#e\# hinzu.
+
+____________________________________________________________________________
+
+ \#u\# (\#value("Liefertermin")\#)\#e\#
+
+____________________________________________________________________________
+
+
+
+
+Im gedruckten Prospekt sähe es (nach 'lineform') wie folgt aus:
+
+Der Textverarbeitungskurs ist ein Lernprogramm für Anfänger#u##count#)#e#.#foot#
+#u##value#)#e#Der Textverarbeitungskurs wird ab August erhältlich sein.
+#end#
+Das Programm ist auf den neuesten Erkenntnissen der Lehrforschung aufgebaut. Der
+Kurs umfaßt Lehrbuch, Arbeitsbuch und sechs Kassetten.
+
+Manchmal ist es notwendig (ebenso wie bei der Seitennummer), den internen Zähler
+neu zu setzen.
+
+____________________________________________________________________________
+
+ \#setcount (13)\#\#count\#
+
+____________________________________________________________________________
+#goalpage("setcount")#
+
+produziert den Wert 13.
+#page#
+
+#ib(9)#5.3.9. #ib#Querverweise#ie# #ie(9)#
+#goalpage("topage")##goalpage("goalpage")#
+#free(1.0)#
+ #on("i")#
+ Mit den Anweisungen #ib#\#topage\##ie(1,"-Anweisung")# und #ib#\#goalpage\##ie(1,"-Anweisung")# sind Querverweise möglich, die
+ von 'pageform'/'autopageform' in die Druckdatei eingefügt werden.
+ #off("i")#
+#free(1.0)#
+Mit Hilfe von Querverweisen soll auf andere Stellen im Text verwiesen werden, was
+nur bei längeren Texten üblich ist. Um dem Leser die mühselige Suche nach der
+Textstelle zu ersparen, gibt man in der Regel die Seitennummer an. Normalerweise
+steht die Seitennummer vor der Fertigstellung des Textes noch nicht fest. Auch in
+diesem Fall kann 'pageform'/'autopageform' helfen. Die \#topage\#-Anweisung ver­
+weist auf eine andere Seite im Text, an der sich eine Anweisung \#goalpage\# befinden
+muß. Statt der Anweisung \#topage\# wird die Seitennummer der Seite eingesetzt, auf
+der sich \#goalpage\# befindet. Damit jedes \#topage\# auch sein entsprechendes \#goal­
+page\# findet, geben Sie bei beiden Anweisungen einen TEXT-Parameter an.
+
+
+____________________________________________________________________________
+
+ ... siehe auch auf Seite \#topage("Funktionstasten")\# ...
+
+
+____________________________________________________________________________
+
+
+Auf einer anderen Seite befindet sich
+
+____________________________________________________________________________
+
+ ... \#goalpage("Funktionstasten")\#
+
+____________________________________________________________________________
+
+
+Nach 'Seite' wird die entsprechende Seitennummer eingesetzt.
+
+Es ist möglich, mehrmals auf die gleiche (Ziel-)Seite zu verweisen. Sie müssen nur
+darauf achten, daß Sie immer das gleiche Merkmal (TEXT-Parameter) verwenden.
+Beachten Sie auch, daß die \#goalpage\#-Anweisungen sich in den Zeilen befinden
+müssen, die tatsächlich gedruckt werden. Setzen Sie sie nicht in die ersten Zeilen
+einer Seite oder eines Textes, die Anweisungen für das Layout enthalten.
+
+Die Zahl der Querverweise darf 300 nicht übersteigen. #page#
+
+#ib(9)#5.3.10. Kombination von Tabellen, Fußnoten
+ und Kopf- bzw. Fußzeilen#ie(9)#
+#free(1.0)#
+ #on("i")#
+ In Fußnoten, \#head\#- oder \#bottom\#-Bereichen können Tabellen untergebracht
+ werden.
+ #off("i")#
+#free(1.0)#
+____________________________________________________________________________
+
+\#head\#
+\#lpos(0.0)\#\#cpos(5.0)\#\#rpos(11.0)\#
+\#table\#
+Korrekturen EUMEL-Benutzerhandbuch S.007
+
+\#table end\#
+\#end\#
+
+
+____________________________________________________________________________
+
+
+
+Die obigen Eingaben schreiben an jeden Seitenanfang folgenden Text:
+
+#lpos(0.0)##cpos(5.0)##rpos(11.0)#
+#table#
+Korrekturen EUMEL-Benutzerhandbuch S.007
+#table end##clear pos#
+
+Die Tabelle sollte also vollständig in den oben erwähnten Bereichen enthalten sein.
+#page#
+
+#ib(9)#5.3.11. #ib#Formatierung von Spalten#ie##ie(9)#
+#goalpage("columns")#
+#free(1.0)#
+ #on("i")#
+ Mit der \#columns\#-Anweisung ist es möglich, einen Text in #ib#Spalten#ie(1,"formatierung")# zu formatie­
+ ren ("Zeitungsdruck").
+ #off("i")#
+#free(1.0)#
+Durch die Angabe der \#columns\#-Anweisung wird 'pageform'/'autopageform' auf­
+gefordert, den Text in Spalten zu formatieren. Die Spaltenbreite müssen Sie mit der #ib#
+\#limit\#-Anweisung#ie (1, " für Spalten")# einstellen.
+
+____________________________________________________________________________
+
+ \#limit (18.0)\#
+ ...
+ \#columns (2, 2.0)\#
+ \#limit (8.0)\#
+ ...
+
+____________________________________________________________________________
+
+
+
+Anfangs schreiben Sie mit einer Zeilenbreite von 18 cm. Dann fordern Sie mit der
+\#columns\#-Anweisung zweispaltigen Druck an (zwischen den Spalten sollen 2 cm
+Abstand sein). Somit muß die \#limit\#-Anweisung (sie gilt für beide Spalten) auf 8 cm
+eingestellt werden.
+
+Die interaktive #ib#Spaltenformatierung#ie# wird von 'pageform' wie gewohnt vorgenommen.
+Auf dem Bildschirm erscheint nun das Spaltenende, wobei die Nummer der Spalte
+angezeigt wird. Fußnoten werden spaltenweise eingeordnet und müssen somit die
+gleiche Zeilenbreite haben wie die restlichen Spalten.
+
+'pageform'/'autopageform' erzeugt in der Druckdatei die Spalten hintereinander. Das
+folgende Beispiel zeigt einen Ausschnitt aus der Druckdatei mit Kopf- und Fußzeilen
+bei einem zweispaltigen Druck:
+
+____________________________________________________________________________
+
+ head-Zeilen
+ xx
+ xx
+ xx
+ bottom-Zeilen
+ \#page\#\#------- Ende Seite 1 Spalte 1 ----\#
+ xx
+ xx
+ xx
+ \#page\#\#------- Ende Seite 1 Spalte 2 ----\#
+
+____________________________________________________________________________
+
+
+Die zweite Spalte erscheint also ohne Kopf- und Fußzeilen, die jedoch bei der
+Berechnung berücksichtigt werden. Beachten Sie, daß die Kopf- und Fußzeilen über
+die Spalten gehen können. Dies erreichen Sie durch geeignete \#limit\#-Anweisungen
+in den genannten Bereichen.
+
+Die meisten Drucker plazieren die zweite Spalte im Druckbild neben die erste. Bei
+einigen wenigen Druckern müssen Sie die Spalten nebeneinander kleben.
+
+Alle Anweisungen funktionieren beim spaltenweisen Formatieren wie üblich. Die
+\#free\#-Anweisung z.B. hält entsprechenden Platz in einer Spalte frei. Eine Aus­
+nahme bildet die #ib#\#page\#-Anweisung#ie (1, " für Spaltenende")#. Sie vollzieht hier ein #ib#Spaltenende#ie#. Die
+\#page\#-Anweisung mit einem Parameter (welcher die Seitennummer der nächsten
+Seite angibt) vollzieht dagegen ein Seitenende.
+
+Die #ib#\#columns end\#-Anweisung#ie# beendet die spaltenweise #ib#Formatierung#ie(1, " spaltenweise")#. Sie wirkt wie
+eine \#page\#-Anweisung.
+
+#ib#Überschriften#ie (1, " in Spalten")# (bzw. Textblöcke) über mehrere Spalten hinweg sind nur auf der ersten
+Seite direkt hinter der \#columns\#-Anweisung möglich.
+
+____________________________________________________________________________
+
+ \#page\#
+ \#limit (10.0)\#
+ Überschriften (bzw. Textblöcke) über mehrere Spalten hinweg
+ sind nur auf der ersten Seite direkt hinter der \#columns\#-
+ Anweisung möglich.
+
+
+ \#columns (2,2.0)\#
+ \#limit (4.0)\#
+ Die erste Spalte soll nur wenige Zeilen beinhalten. Das vor­
+ zeitige Beendigen der Spalte erreicht man mit der \#page\#-
+ Anweisung.
+ \#page\#
+ In der zweiten Spalte kann dann mit dem Schreiben des Textes
+ fortgefahren werden.
+ .....................
+ .....................
+ .....................
+ .....................
+ .....................
+ \#columns end\#
+
+____________________________________________________________________________
+
+
+#page#
+Druckbild (mit 'lineform' bearbeitet):
+
+
+
+ Überschriften (bzw. Textblöcke) über mehrere Spalten hinweg sind nur auf
+ der ersten Seite direkt hinter der \#columns\#-Anweisung möglich.
+ #columns (2,2.0)#
+
+ Die erste Spalte soll nur
+ wenige Zeilen beinhalten.
+ Das vorzeitige Beendigen
+ der Spalte erreicht man mit
+ der \#page\#-Anweisung.
+ #page#
+
+
+ In der zweiten Spalte kann
+ dann mit dem Schreiben
+ des Textes fortgefahren
+ werden.
+ .....................
+ .....................
+ .....................
+
+#columns end#
+
+
+
+
+Die Zeilen für die zweispaltige Überschrift werden berücksichtigt. Dies gilt jedoch nur
+unmittelbar hinter der \#columns\#-Anweisung. Möchten Sie diesen Effekt nochmals
+erzeugen, beenden Sie mit \#columns end\#, schreiben die breite Überschrift und
+schalten die \#columns\#-Anweisung wieder ein (jeweils unter richtiger Setzung von
+\#limit\#).
+#page#
+
+#ib(9)#5.4. #ib#Index#ie##ie(9)#
+#free(1.0)#
+#ib(9)#5.4.1. Stichwort- und/oder#ib#
+ Inhaltsverzeichnis#ie#se erstellen#ie(9)#
+#free(1.0)#
+
+ #on("i")#
+ Mit dem Programm '#ib#index#ie(1, "-Kommando")#' können Sie Stichwort- und Inhaltsverzeichnisse er­
+ stellen. #ib#Stichwortverzeichnis#ie#se können sortiert werden. Mehrere Stichwortverzeich­
+ nisse können Sie durch 'index merge' zusammenführen.
+ #off("i")#
+#free(1.0)#
+Durch den Aufruf von:
+
+____________________________________________________________________________
+
+ gib kommando:
+ index ("dateiname.p")
+
+____________________________________________________________________________
+
+
+
+werden durch #ib#Indexanweisungen#ie# gekennzeichnete Worte in Dateien, den sogenannten
+Indexdateien, gespeichert.
+
+Die Worte, die in einen Index übernommen werden sollen, müssen Sie in der Druck­
+datei für 'index' durch Anweisungen kennzeichnen. Solche #ib(1,"ff")#Indexanweisungen#ie# werden
+von den anderen Textbe- und -verarbeitungs-Programmen ('lineform', 'pageform',
+EUMEL-Drucker) ignoriert. Sie können also bei dem Schreiben mit dem Editor
+gleich festlegen, welche Worte in einen Index aufgenommen werden sollen.
+
+Solche Verzeichnisse von Worten werden im EUMEL-System allgemein als #ib#Index#ie#
+bezeichnet. 'index' kann ebenfalls benutzt werden, um ein #ib#Inhaltsverzeichnis#ie# und/oder
+ein Verzeichnis aller Abbildungen zu erstellen oder Literaturhinweise zu überprüfen.
+
+Nachdem eine oder mehrere Indexdateien aus einer Druckdatei erstellt sind, werden
+die Indexdateien auf Anfrage alphabetisch sortiert. Bei einem Inhaltsverzeichnis sollten
+Sie die Sortierung natürlich ablehnen. Nach der Sortierung werden gleiche Einträge
+automatisch zusammengefaßt und die entsprechenden Seitennummern nacheinander
+aufgeführt.
+
+
+
+#on("b")##on("i")#Praktischer Tip:#off("b")##off("i")#
+Möchten Sie nur eine Sortierung, aber keine Zusammenfassung von Einträgen, dann
+lehnen Sie die Sortieranfrage ab. Anschließend können Sie die Indexdatei mit '#ib#lex sort#ie#
+("indexdateiname")' sortieren. Hierbei bleiben gleiche Einträge erhalten.
+
+
+
+Das Programm
+
+____________________________________________________________________________
+
+ gib kommando:
+ index merge ("dateiname.i1", "dateiname.i2")
+
+____________________________________________________________________________
+
+
+
+erlaubt es Ihnen, zwei durch 'index' erzeugte Verzeichnisse zusammenzuführen und
+- nach Anfrage - wieder zu sortieren.
+#page#
+
+#ib(9)#5.4.1.1. #ib#Worte für 'index' kennzeichnen#ie##ie(9)# #goalpage ("ib")##goalpage("ie")#
+#free(1.0)#
+ #on("i")#
+ Worte, die in einen Index übernommen werden sollen, kennzeichnen Sie mit \#ib\#
+ und \#ie\#.
+ #off("i")#
+#free(1.0)#
+Da in einem Index - neben dem eigentlichen Worteintrag - die #ib#Seitennummer#ie#
+enthalten sein soll, arbeitet das Programm 'index' nur mit einer #ib#Druckdatei#ie#, d.h. einer
+Ausgabedatei von 'pageform'/'autopageform'. Die Indexworte werden in #ib#Indexdateien#ie#
+gesammelt. Die Indexdateien erhalten den Namen der bearbeiteten Datei, an den ".i"
+und die Nummer des Index angefügt wird.
+
+____________________________________________________________________________
+
+ ... Hier wird eine Eigenschaft des \#ib(1)\#EUMEL-
+ Systems\#ie(1)\# beschrieben. ...
+
+____________________________________________________________________________
+
+
+Die durch die Anweisungen #ib#\#ib\##ie(1,"-Anweisung")# und #ib#\#ie\##ie(1,"-Anweisung")# gekennzeichneten Worte werden mit der
+dazugehörigen Seitennummer in die erste Indexdatei geschrieben.
+
+Die Einträge in einer Indexdatei werden von den Seitennummern durch mindestens
+drei Punkte getrennt. Werden diese nicht gewünscht, können Sie sie leicht mit dem
+Editor entfernen.
+
+
+Sie haben die Möglichkeit, bis zu neun unterschiedliche Indexdateien zu erstellen,
+z.B. gehen durch
+
+____________________________________________________________________________
+
+ \#ib (1)\# und \#ie (1)\#
+
+____________________________________________________________________________
+
+
+gekennzeichnete Worte in die Indexdatei mit der Nummer 1, durch
+
+____________________________________________________________________________
+
+ \#ib (9)\# und \#ie (9)\#
+
+____________________________________________________________________________
+
+
+gekennzeichnete Worte gehen in die Indexdatei mit der Nummer 9. Wenn Sie nur
+einen Index erstellen müssen, dürfen die \#ib\#- und \#ie\#-Anweisungen ohne Para­
+meter benutzt werden, was gleichbedeutend ist mit \#ib (1)\# und \#ie (1)\#.
+
+
+
+Die durch \#ib\#- und \#ie\#-Anweisungen gekennzeichneten Worte können auch über
+Zeilengrenzen (mit Silbentrennungen) gehen.
+
+____________________________________________________________________________
+
+ .... \#ib\#viele Index­
+ Anweisungen\#ie\# ...
+
+____________________________________________________________________________
+
+
+'index' zieht getrennte Worte zusammen (hier: 'viele Index-Anweisungen'). Möchten
+Sie einige Worte in verschiedenen Indexdateien haben, dürfen Sie die \#ib\#- und
+\#ie\#-Anweisungen auch "schachteln". Dies können Sie besonders bei Kapitelüber­
+schriften nutzen.
+
+
+
+____________________________________________________________________________
+
+ \#ib(9)\#Eine Anweisung: die '\#ib\#limit\#ie\#'-Anweisung\#ie(9)\#
+
+____________________________________________________________________________
+
+
+In diesem Beispiel wird das Inhaltsverzeichnis in die Indexdatei '9' gebracht, während
+der "allgemeine" Index in der Indexdatei '1' gesammelt wird.
+#page#
+
+#ib(9)#5.4.1.2. #ib#Nebeneinträge erzeugen#ie##ie(9)#
+
+#free(1.0)#
+ #on("i")#
+ Sie haben die Möglichkeit, an die Seitennummer eines Eintrags einen beliebigen
+ Text anfügen zu lassen.
+ #off("i")# #free(1.0)#
+Beispiel:
+
+
+ EUMEL-System ... 27ff.
+ Monitor ........ 13(Def.)
+
+
+
+
+
+Dies wird durch eine weitere Form der \#ib\#-Anweisung ermöglicht:
+
+____________________________________________________________________________
+
+ ... der \#ib(1,"(Kap.4)")\#EUMEL-Editor\#ie\# ist gut
+ geeignet, Texte zu erstellen ...
+
+____________________________________________________________________________
+
+
+
+erzeugt den folgenden Eintrag:
+
+
+
+Druckbild:
+
+ EUMEL-Editor ... 1(Kap.4)
+
+
+An einen Eintrag können Sie einen weiteren Text angefügen, um etwa Untereinträge
+zu bilden:
+
+Druckbild:
+
+ EUMEL-System .................................. 27
+
+ EUMEL-System, komplexes ....................... 29
+
+
+Das wird ebenfalls durch eine andere Form der \#ib\#-Anweisung ermöglicht:
+
+____________________________________________________________________________
+
+ ... ist das \#ib\#EUMEL-System\#ie(1,", benutzerfreundliches")\#
+ wirklich ein benutzerfreundliches System ...
+
+____________________________________________________________________________
+
+
+erzeugt den folgenden Eintrag:
+
+Druckbild:
+
+ EUMEL-System, benutzerfreundliches ............ 28
+
+
+
+Nach der Erstellung einer Indexdatei können - nach interaktiver Anfrage - die
+Einträge sortiert werden. Die Sortierung erfolgt alphabetisch nach DIN 5007, Abschnitt
+1 und 3.2 (Umlaute werden "richtig" eingeordnet).
+
+
+
+Wie bereits erwähnt, können Sie 'index' vielseitig einsetzen:
+
+a) Erstellung von Stichwortverzeichnissen:
+ Wie bereits beschrieben.
+
+b) Erstellung von Inhaltsverzeichnissen:
+ Kapitelüberschriften mit eigenen Indexanweisungen klammern und durch 'index'
+ wie beschrieben verarbeiten.
+
+ ____________________________________________________________________________
+
+ \#ib(9)\#6.1. Eine Datei drucken\#ie(9)\#
+
+ _________________________________________________________________________
+
+
+ Dann sind Sie sicher, daß das Inhaltsverzeichnis bezüglich Seitennummern und
+ Kapitelüberschriften korrekt ist.
+
+c) Erstellung von #ib#Abbildungsverzeichnisse#ie#n:
+ Abbildungsüberschriften- bzw. -unterschriften wie Kapitelüberschriften verarbei­
+ ten.
+
+d) Überprüfung von Literaturhinweisen auf Vollständigkeit:
+ Sie klammern alle Literaturhinweise mit gesonderten Indexanweisungen.
+
+ ____________________________________________________________________________
+
+ \#ib(8)\#/Meier82/\#ie(8)\#)
+
+ _________________________________________________________________________
+
+ und überprüfen dann mit Hilfe dieser Indexdatei die Literaturverweise. So können
+ Sie sichergehen, daß alle Literaturverweise im Text auch in der Literaturaufstellung
+ stehen.
+#page#
+
+#ib(9)#5.4.1.3. #ib#Indexdateien zusammenführen#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Durch das Programm '#ib#index merge#ie(1,"-Kommando")#' können Sie eine Indexdatei in eine zweite
+ "einmischen".
+ #off("i")#
+#free(1.0)#
+Es ist somit möglich, einen Index zu erstellen, der sich über mehrere Dateien er­
+streckt, indem Sie 'index' die Druckdateien dieser Dateien bearbeiten und an­
+schließend die entstandenen Indexdateien mit 'index merge' zusammenfassen lassen.
+Indexdateien können ggf. mit dem Editor bzw. 'lineform' und/oder 'pageform'/­
+'autopageform' bearbeitet und anschließend gedruckt werden.
+
+
+____________________________________________________________________________
+
+ gib kommando:
+ index merge ("1.kapitel.i1", "2.kapitel.i1")
+
+____________________________________________________________________________
+
+
+
+
+Hier wird die Indexdatei des 1. Kapitels in die Indexdatei des 2. Kapitels eingeordnet
+und auf Wunsch sortiert.
+#page#
+
+#ib(9)#5.5. #ib#Outline#ie##ie(9)#
+#goalpage("outline")#
+#free(1.0)#
+#ib(9)#5.5.1. Eine#ib# Strukturübersicht#ie# oder
+ #ib#Zusammenfassung#ie# erstellen#ie(9)#
+#free(1.0)#
+ #on("i")#
+ Das Programm 'outline' erstellt aus einem Text eine Zusammenfassung aller
+ (Kapitel-) Überschriften und Stichworte, sofern diese mit #ib#Index-Anweisungen#ie#
+ gekennzeichnet sind.
+ #off("i")#
+#free(1.0)#
+Manchmal sollen Stichworte oder das Inhaltsverzeichnis aus einem Text herausgeholt
+werden, ohne vorher 'pageform' durchlaufen zu müssen. Das ist dann nützlich, wenn
+Sie
+
+- Stichworte auf Korrektheit und Vollständigkeit überprüfen möchten;
+- die Reihenfolge von Kapiteln überprüfen müssen;
+- eine Übersicht durch Kapitel-Überschriften und Stichworte anfertigen möchten;
+- einen Text auf logische Zusammenstellung überprüfen.
+
+
+In solchen Fällen hilft das Programm 'outline', das mit dem Monitor-Kommando
+
+____________________________________________________________________________
+
+ gib kommando:
+ outline ("dateiname")
+
+____________________________________________________________________________
+
+
+
+aufgerufen wird. 'outline' arbeitet ähnlich wie 'index', indem es alle mit \#ib\# und \#ie\#
+markierten Textteile in eine Datei mit dem Zusatz 'outline' schreibt. Im Unterschied zu
+'index' muß die Eingabe-Datei keine Druckdatei ('.p'-Zusatz) sein.
+
+Das Programm 'outline' fragt zuerst, mit welcher Indexnummer das Inhaltsverzeichnis
+versehen ist. Das ist notwendig, weil die Kapitelüberschriften gegenüber Stichwörtern
+in der 'outline'-Datei hervorgehoben werden (Einrückungen).
+
+Eingabe-Datei ("dateiname"):
+
+____________________________________________________________________________
+
+ ...
+ \#ib(9)\#1. Kapitel\#ie(9)\#
+ ...
+ ...\#ib\#Stichwort 1\#ie\#
+ \#ib\#Stichwort 2\#ie\#...
+
+ \#ib(9)\#1.1. Kapitel\#ie(9)\#
+ ...
+ \#ib\#Stichwort 3\#ie\#
+ usw...
+
+____________________________________________________________________________
+
+
+
+Druckbild der erzeugten Datei ("dateiname.outline"):
+
+ 1. Kapitel
+ Stichwort 1
+ Stichwort 2
+ 1.1. Kapitel
+ Stichwort 3
+
+
+In diesem Beispiel werden alle Indizes mit Ausnahme der Kapitelüberschrift jeweils in
+einer Zeile aufgeführt und gegenüber der Kapitelüberschrift eingerückt. Ein neues
+Kapitel, sofern es dezimal gekennzeichnet ist, wird gegenüber einem Kapitel mit
+höherer Ordnung eingerückt.
+#page#
+
+#ib(9)#5.6. #ib#Print#ie##ie(9)##goalpage("print")#
+#free(1.0)#
+ #on("i")#
+ Der #ib#EUMEL-Drucker#ie#, der mit dem #ib#'print'#ie(1,"-Kommando")#-Kommando angesprochen wird, ist
+ eine Software-Schnittstelle zu einem angeschlossenen Drucker. In diesem Kapitel
+ wird erklärt, wie Sie mit dem EUMEL-Drucker eine Datei drucken können und
+ welche speziellen Anweisungen den Drucker steuern.
+ #off("i")#
+#free(1.0)#
+Jeder Drucker erbringt "hardwaremäßig" unterschiedliche Leistungen (z.B. Typen und
+Modifikationen). Diese Leistungen werden durch Eingabe spezieller Zeichenfolgen
+veranlaßt, die herstellerspezifisch sind.
+
+Um vom EUMEL-System unterschiedliche Drucker auf gleiche Weise ansprechen zu
+können, wurde eine Software-Schnittstelle geschaffen, die #ib#EUMEL-Drucker#ie# ge­
+nannt wird. Der EUMEL-Drucker akzeptiert eine Datei und veranlaßt, daß diese in
+geeigneter Weise gedruckt wird. Weiterhin beachtet der EUMEL-Drucker die An­
+weisungen der Textkosmetik. Die Form der Anweisungen der Textkosmetik und des
+EUMEL-Druckers sind identisch.
+#page#
+
+#ib(9)#5.6.1. #ib#Eine Datei drucken#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Mit dem Kommando '#ib#print#ie#' können Sie dem EUMEL-Drucker eine Datei zum
+ Drucken übergeben.
+ #off("i")#
+#free(1.0)#
+____________________________________________________________________________
+
+ gib kommando:
+ print ("dateiname")
+
+____________________________________________________________________________
+
+
+In der Regel ist im EUMEL-System (Multi-User) ein "Spooler" installiert, so daß Sie
+sofort mit der Arbeit fortfahren können. Der EUMEL-Drucker arbeitet in diesem Fall
+parallel zu Ihren anderen Arbeiten.
+#page#
+
+#ib(9)#5.6.2. #ib#Anweisungen für den EUMEL-Drucker#ie##ie(9)#
+#free(1.0)#
+Ein Text (eine Datei) kann vom Drucker auch ohne Anweisungen gedruckt werden,
+etwa für Probedrucke. Für diesen Fall hat der Drucker vernünftige Voreinstellungen.
+Für einen "normalen" Text brauchen Sie keine speziellen Druckeranweisungen in den
+zu druckenden Text einzufügen, denn die Anweisungen für die Textkosmetik reichen
+zur Druckersteuerung aus. Nur wenn besondere Leistungen verlangt werden, wie z.B.
+Blocksatz oder den gedruckten Text an eine bestimmte Stelle zu plazieren, sind
+Druckeranweisungen notwendig.
+
+Werden vom Drucker Leistungen verlangt, die hardwaremäßig nicht vorhanden sind,
+so sorgt der EUMEL-Drucker dafür, daß eine möglichst äquivalente Leistung erbracht
+wird. Fordern Sie beispielsweise einen nicht vorhandenen Schrifttyp an, wird mit
+dem Standard-Schrifttyp der jeweiligen Installation gedruckt. Damit ist es Ihnen
+möglich, einen Text, der eigentlich für einen anderen Drucker bestimmt ist, auf einem
+Drucker zu drucken, der die geforderte Type nicht kennt.
+
+Wie bereits erwähnt, beachtet der EUMEL-Drucker die gleichen Anweisungen wie
+die Textkosmetik-Programme, aber einige Anweisungen sind nur für den Drucker
+implementiert. Eine #ib#\#type\#-Anweisung#ie# beispielsweise, die einen bestimmten Schrift­
+typ anfordert, wird vom EUMEL-Drucker als Befehlsfolge an den angeschlossenen
+Hardware-Drucker übergeben, sofern der Schrifttyp auf dem Drucker vorhanden ist.
+Wie die Anweisungen geschrieben werden müssen, wurde in der Beschreibung der
+Textkosmetik geschildert.
+
+Anweisungen werden nicht gedruckt. Besteht eine Zeile nur aus Anweisungen, so wird
+diese Zeile vom EUMEL-Drucker nicht gedruckt. Im Gegensatz zu den Programmen
+der Textkosmetik werden unbekannte oder #ib#fehlerhafte Anweisungen#ie# vom EUMEL­
+Drucker ohne Fehlermeldung "verschluckt".
+
+Neben den "normalen" Anweisungen, die nur in "\#"-Zeichen eingeschlossen wer­
+den, gibt es noch eine andere Form:
+
+Kommentar-#ib#Anweisungen#ie(1,", Kommentar-")#:
+
+ Werden in "\#-" und "-\#"-Zeichen eingeschlossen. Solche Anweisungen wer­
+ den ignoriert.
+
+____________________________________________________________________________
+
+ ..........................
+ Text......................
+ ..........................
+ Kommentar-Anweisungen werden
+ beim Drucken ignoriert.
+ \#---- Ende der Seite 1 ---\#
+
+____________________________________________________________________________
+
+
+
+Die letze Zeile erscheint im gedruckten Text nicht.
+#page#
+#goalpage("block")#
+#ib(9)#5.6.3. #ib#Blocksatz#ie# #ie(9)#
+#free(1.0)#
+#ib(9)#5.6.3.1. #ib#Randausgleich#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Die Anweisung #ib#\#block\##ie(1,"-Anweisung")# bewirkt einen Blocksatz beim Druck.
+ #off("i")#
+#free(1.0)#
+Fügen Sie in den Text (meist am Anfang einer Datei) die Anweisung
+
+____________________________________________________________________________
+
+ \#block\#
+
+____________________________________________________________________________
+
+
+ein, druckt der Drucker ab dieser Stelle alle Zeilen, die nicht mit einem Absatzkenn­
+zeichen versehen sind, im #ib#Blocksatz#ie#. Das heißt, daß durch Vergrößern der Wort­
+abstände alle Zeilen an der gleichen Position enden (rechter #ib#Randausgleich#ie#). Preis­
+werte Drucker können dies nur durch Einfügen ganzer Leerzeichen zwischen den
+Worten vornehmen, was sich oft beim Lesen störend bemerkbar macht. Bei qualitativ
+hochwertigen Druckern wird dagegen der Blocksatz durch Einfügen kleinerer Abstän­
+de zwischen den Worten erreicht.
+
+Der Text einer Zeile wird durch Vergrößern der #ib#Wortlücken#ie(1, ", Vergrößern der")# auf die Zeilenlänge, die
+durch die \#limit\#-Anweisung eingestellt ist, verbreitert.
+
+
+a) Es werden nicht verbreitert:
+
+ - Absatzzeilen;
+ - der Text bis zum letzten #ib#Mehrfachblank#ie#;
+ - führende Leerzeichen (#ib#Einrückung#ie#);
+ - ein Leerzeichen hinter einer Aufzählung (siehe dazu b);
+ - geschützte Blanks.
+
+
+
+b) #ib#Aufzählungen#ie# gibt es nur nach einer Absatzzeile:
+
+ - "Spiegelstrich" (Bindestrich und Leerzeichen am Anfang der Zeile);
+ - Doppelpunkt als Ende des ersten Wortes (Position < 20);
+ - schliessende Klammer oder Punkt als Ende des ersten Wortes (Position < 7),
+ z.B. 1) oder 1.
+#page#
+#goalpage ("pageblock")#
+
+#ib(9)#5.6.3.2. #ib#Seitenausgleich#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Mit der #ib#\#pageblock\#-Anweisung#ie# wird der Drucker veranlaßt, einen Seiten­
+ ausgleich (ähnlich wie bei der \#block\#-Anweisung für den rechten Rand­
+ ausgleich) vorzunehmen.
+ #off("i")#
+#free(1.0)#
+Durch die automatische oder interaktive Seitenformatierung oder durch einen Fuß­
+notenumbruch von 'pageform'/'autoform' bleiben oft am Ende einer Seite Zeilen leer.
+Dies können Sie durch die \#pageblock\#-Anweisung verhindern. Sie veranlaßt den
+Drucker, Zwischenräume (Fachbegriff: Durchschuß) zwischen den Zeilen einzufügen,
+so daß alle letzten Zeilen auf allen Seiten auf gleicher Höhe abschließen. Ebenso wie
+beim Randausgleich hängt die Güte des Druckergebnisses jedoch von den Fähig­
+keiten des angeschlossenen Druckers ab.
+
+Beachten Sie jedoch, daß manche Verlage so bearbeitete Seiten nicht wünschen, weil
+bei Verwendung von zu dünnem Papier beim Druck Zeilen "durchscheinen" können,
+so daß das Lesen erschwert wird.
+
+Ist die Anweisung \#pageblock\# gegeben, können Sie in 'pageform' die Seitengrenze
+auch über das rechnerische Seitenende hinaus plazieren. In diesem Fall werden die
+Zeilen vom Drucker gestaucht.
+#mark ("", "")#
+
+
+____________________________________________________________________________
+
+PAGEFORM für x Zeilen: dateiname ---> dateiname.p
+
+____________________________________________________________________________
+
+
+____________________________________________________________________________
+
+ Seitenende verschieben: UP, DOWN / bestaetigen: RETURN / Abbruch: ESC
+
+____________________________________________________________________________
+
+
+#page#
+
+#ib(9)#5.6.4. #ib#Schreibfeld verschieben#ie##ie(9)# #goalpage("start")#
+#free(1.0)#
+ #on("i")#
+ Durch die Anweisung #ib#\#start\# #ie(1,"-Anweisung")#ist es Ihnen möglich, das #ib#Schreibfeld#ie# beim Druck auf
+ dem Papier an eine andere Stelle zu plazieren.
+ #off("i")#
+#free(1.0)#
+Der EUMEL-Drucker plaziert das Schreibfeld auf einem Drucker automatisch derart,
+daß ein genügender Rand verbleibt. Die Wirkung dieser Voreinstellung ist natürlich
+abhängig vom Drucker und der Installation. Mit der \#start\#-Anweisung können Sie
+die automatische Einstellung verändern.
+
+
+____________________________________________________________________________
+
+ \#start (1.0, 2.0)\#
+
+____________________________________________________________________________
+
+
+legt die linke, obere Ecke des Schreibfeldes fest (vom linken Rand 1 cm, vom oberen
+Rand 2 cm). Die standardmäßige Voreinstellung ist \#start (2.54, 2.35)\#. Die \#start
+(...)\#-Anweisung können Sie nur einmal pro Seite geben.
+#page#
+
diff --git a/doc/user/benutzerhandbuch.5c b/doc/user/benutzerhandbuch.5c
new file mode 100644
index 0000000..010cacd
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5c
@@ -0,0 +1,711 @@
+#start(5.0,1.5)##pagenr("%",93)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 5: Textkosmetik und Druck
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+5 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 5 - %
+#tableend##clearpos#
+#end#
+#goalpage("center")#
+#ib(9)#5.6.5. #ib#Zentriert drucken#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Mit der #ib#\#center\#-Anweisung#ie# können Sie einen Text in der Mitte der Zeile drucken
+ lassen.
+ #off("i")#
+#free(1.0)#
+
+Die \#center\#-Anweisung zentriert den Text einer Absatzzeile.
+
+
+____________________________________________________________________________
+
+ \#center\#Diese Zeile wird zentriert gedruckt.
+
+#mark ("", "")#
+
+____________________________________________________________________________
+
+
+Druckbild:
+
+ #center#Diese Zeile wird zentriert gedruckt.
+#page#
+
+#ib(9)#5.6.6. #ib#Rechtsbündig drucken#ie##ie(9)#
+#goalpage("right")#
+#free(1.0)#
+ #on("i")#
+ Mit der #ib#\#right\#-Anweisung#ie# können Sie einen Teil einer Absatzzeile rechtsbündig
+ drucken.
+ #off("i")#
+#free(1.0)#
+
+Die \#right\#-Anweisung veranlaßt, daß der nachfolgende Text rechtsbündig gedruckt
+wird.
+
+____________________________________________________________________________
+
+ \#head\#
+ \#center\#Diese Zeile wird zentriert\#right\#%
+
+ \#end\#
+
+____________________________________________________________________________
+
+
+
+Hierbei wird die Seitenzahl rechtsbündig gedruckt.
+
+Beachten Sie, daß die \#center\#- und die \#right\#-Anweisung zusammen verwendet
+werden können. Beide Anweisungen wirken jedoch nur, wenn sie in einer Absatzzeile
+stehen.
+
+#mark ("", "")#
+#page#
+
+#ib(9)#5.6.7. #ib#Übereinander drucken#ie##ie(9)#
+#goalpage ("b")#
+#free(1.0)#
+ #on("i")#
+ Mit der #ib#\#b\#-Anweisung#ie# können Sie zwei Zeichen übereinander drucken.
+ #off("i")#
+
+#free(1.0)#
+Die \#b\#-Anweisung veranlaßt, daß zwei aufeinanderfolgende Zeichen, die durch die
+\#b\#-Anweisung verbunden sind, übereinander gedruckt werden.
+
+
+____________________________________________________________________________
+
+... 0\#b\#/ ...
+
+____________________________________________________________________________
+
+
+
+
+Druckbild:
+
+... 0#b#/ ...
+
+
+Das Zeichen '/' wird über das Zeichen '0' gedruckt. 'lineform'/'autoform' nimmt für die
+Zeilenberechnung nur ein Zeichen. Beachten Sie, daß direkt vor oder nach der
+\#b\#-Anweisung keine Anweisung oder kein Blank stehen darf.
+#mark ("", "")#
+#page#
+
+#ib(9)#5.7. #ib#Textkosmetik-Makros#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ #ib#Makros#ie# verkürzen Ihren Arbeitsvorgang bei immer wiederkehrenden Textteilen
+ und/oder Anweisungen.
+ #off("i")#
+#free(1.0)#
+Unter 'Makro' verstehen wir eine "große" Anweisung, die aus vielen kleinen besteht
+und die Sie mit Hilfe des Makronamens aufrufen können.
+
+Textkosmetik-Makros kommen zum Einsatz bei:
+
+- immer wiederkehrenden Textteilen;
+- immer wiederkehrenden Anweisungssequenzen;
+- bei der Erstellung von Manuskripten, deren endgültige Form Sie anfänglich noch
+ nicht kennen oder die Sie noch ändern möchten;
+- oder bei Folgen von direkten Drucker-Anweisungen, die bestimmte Leistungen
+ erbringen.
+
+Die Definition von einem oder mehreren #ib#Makros#ie# wird mit dem Editor vorgenommen.
+Diese #ib#Makro-Datei#ie# wird dann geladen. Von diesem Augenblick an "kennen" 'line­
+form'/'autoform' und 'pageform'/'autopageform' die Makros, d.h. die Textzeilen und/
+oder Anweisungen, die sich unter dem #ib#Makronamen#ie# "verbergen".
+
+'lineform'/'autoform' beachtet die Anweisungen, die ggf. in den Makros enthalten sind.
+Sie erscheinen jedoch nicht in der Datei. Erst 'pageform'/'autopageform' setzt diese in
+die Druckdatei ein.
+#page#
+
+#ib(9)#5.7.1. Ein Makro-Beispiel#ie(9)#
+#free(1.0)#
+ #on("is")#
+ Hier wird Ihnen ein einfaches Beispiel für einen Briefkopf gezeigt.
+ #off("is")#
+#free(1.0)#
+Angenommen, Sie schreiben mit dem EUMEL-System Ihre Geschäftsbriefe. Sie
+haben einen Drucker zur Verfügung, mit dem Sie auch die Briefköpfe erstellen kön­
+nen. Für den #ib#Briefkopf#ie# schreiben Sie ein Makro \#kopf\# in eine Datei "macro defini­
+tionen":
+
+____________________________________________________________________________
+
+ \#*kopf\#
+ \#type("fett und gross")\#Firmenname
+ \#type("fett")\#Softwareprodukte
+ \#type("klein")\#Straße
+ Stadt
+ \#type ("normal")\#
+ \#*macro end\#
+
+____________________________________________________________________________
+
+
+Der Name des Makros ist \#kopf\#. Beachten Sie, daß eine #ib#Makro-Definition#ie# mit dem
+Namen des Makros beginnen muß. Der #ib#Makroname#ie# muß dabei mit einem #on("b")#*#off("b")# gekenn­
+zeichnet werden, um ihn von "normalen" Text-Anweisungen unterscheiden zu kön­
+nen. Jedes Makro wird mit einer \#*macro end\#-Anweisung beendet. Sie dürfen
+mehrere Makros hintereinander in die Datei schreiben.
+
+Nun müssen Sie das so definierte Makro 'laden':
+
+____________________________________________________________________________
+
+ gib kommando:
+ #ib#load macros#ie# ("macro definitionen")
+
+____________________________________________________________________________
+#goalpage("load macros")##goalpage("list macros")#
+
+
+Zur Kontrolle können Sie sich die geladenen Makros in das Notizbuch ausgeben
+lassen:
+
+____________________________________________________________________________
+
+ gib kommando:
+ #ib#list macros#ie#
+
+____________________________________________________________________________
+#mark ("", "")#
+
+
+
+Nun haben Sie von jetzt an eine neue Anweisung (mit dem Namen \#kopf\#) zur Ver­
+fügung, mit der Sie einen Briefkopf in jeden Brief drucken können. Sie schreiben nun
+folgenden Brief:
+
+____________________________________________________________________________
+
+ \#kopf\#
+
+ Sehr geehrter Herr ....
+
+ usw.
+
+____________________________________________________________________________
+
+
+Beachten Sie hierbei, daß das Makro in Ihrem Text als Anweisung ohne #on("b")#*#off("b")# steht. Der
+#ib#Aufruf eines Makros#ie#, welches z.B. in einer von 'lineform' zu bearbeitenden Datei
+steht, unterscheidet sich also nicht von einer "normalen" Textanweisung.
+
+Nachdem Sie mit 'lineform' den Brief zeilenweise formatiert haben, kontrollieren Sie
+die formatierte Datei. Hier hat sich noch nichts verändert. Die neue Anweisung \#kopf\#
+steht unverändert in der Datei. 'lineform' beachtet zwar alle Anweisungen und Text­
+zeilen eines Makros, setzt diese jedoch nicht in die Datei ein. Allerdings ist 'lineform'
+nicht in der Lage, die \#type\#- und \#limit\#-Anweisungen eines Makros zu erkennen,
+wenn es an erster Stelle in einer Datei steht und in dessen Definition gleich zu
+Anfang diese Anweisungen korrekt aufgeführt sind. Stattdessen fragt 'lineform' an­
+fangs 'type' und 'limit' an. Das können Sie umgehen, indem Sie mittels 'CR' die
+Abfrage in 'lineform' ignorieren.
+
+Nun formatieren Sie die Datei, die den Brief enthält, mit 'pageform'/'autopageform'. In
+der Druckdatei ist nun die Anweisung \#kopf\# verschwunden. Dort stehen nun die
+Zeilen des #ib#Makrorumpf#ie#es. 'pageform'/'autopageform' setzt die Zeilen des Makros in
+die Druckdatei ein:
+
+____________________________________________________________________________
+
+ \#type("fett und gross")\#Firmenname
+ \#type("fett")\#Softwareprodukte
+ \#type("klein")\#Straße
+ Stadt
+ \#type ("normal")\#
+
+
+ Sehr geehrter Herr ...
+ usw.
+
+
+____________________________________________________________________________
+
+
+
+#on("b")##on("i")#Anmerkung:#off("b")##off("i")#
+Makros, die den gleichen Namen haben, aber sich durch die Anzahl der Parameter
+unterscheiden, sind nicht erlaubt. Es ist auch nicht gestattet, Makros innerhalb einer
+Makro-Definition aufzurufen.
+
+Beachten Sie ferner, daß Makro-Texte so verwendet werden, wie sie mit 'load
+macros' geladen werden.
+
+____________________________________________________________________________
+
+ \#*textanfang\#
+ \#limit(11.0)\#
+ \#block\#
+ \#pageblock\#
+ \#type("trium8")\#
+ \#*macro end\#
+
+____________________________________________________________________________
+
+
+Betätigen Sie in der Makro-Datei nach jeder Zeile die #taste1(" CR ")#-Taste (Absatz), dann
+erhalten Sie nach jedem \#...\# einen Absatz, was zum Beispiel bei Kapitelüberschriften
+wünschenswert ist, nicht jedoch bei kleineren Anweisungen, bei denen dann mitten im
+Satz ein Absatz erschiene. In solchen Anwendungen sollten Sie Makros ohne Absätze
+speichern. Beachten Sie ferner, daß aus programmtechnischen Gründen eine \#foot\#-
+oder die abschließende \#end\#-Anweisung einer Fußnote nicht in einem Makro ent­
+halten sein darf.
+#page#
+
+#ib(9)#5.7.2. Ein Beispiel mit #ib#Makro-Parameter#ie#n#ie(9)#
+#free(1.0)#
+ #on("i")#
+ Makro-Parameter erlauben es Ihnen, immer wiederkehrende Textteile, die sich
+ nur geringfügig voneinander unterscheiden, zu erzeugen.
+ #off("i")#
+#free(1.0)#
+Ihnen fällt nun auf, daß Sie Ihr Makro noch etwas verbessern können. Sie möchten
+das Datum mit in den Briefkopf aufnehmen. Somit editieren Sie Ihre Makro-Datei
+folgendermaßen (beachten Sie die '$'-Zeichen):
+
+____________________________________________________________________________
+
+ \#*kopf ($1)\#
+ \#type("gross")\#Firmenname
+ \#type("fett")\#Softwareprodukte
+ \#type("klein")\#Straße
+ Stadtname
+ \#type ("normal")\#
+
+ Stadtname, den $1
+ \#*macro end\#
+
+____________________________________________________________________________
+
+
+Damit haben Sie dem \#kopf\#-Makro einen Parameter gegeben: '$1'; die Parameter
+werden numeriert. Ein zweiter Parameter würde '$2' heißen usw..
+
+Bei der Erstellung eines Briefes müssen Sie die Anweisung \#kopf\# mit dem jeweiligen
+Datum in einen Brief schreiben:
+
+____________________________________________________________________________
+
+ \#kopf ("20.8.1986")\#
+
+____________________________________________________________________________
+
+
+'pageform'/'autopageform' setzt nun das angegebene Datum direkt hinter 'Stadtname,
+den' in den Briefkopf ein (in der Druckdatei). Beachten Sie, daß alle Parameter einer
+Makro-Anweisung in Anführungszeichen stehen müssen (auch Zahlen).
+#page#
+
+#ib(9)#5.7.3. #ib#Makros für Manuskripte#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ Hier wird gezeigt, wie Sie mit Makros Anweisungen formulieren können, die
+ aussagen, um was es sich bei einem Text handelt, und nicht, in welchem Format
+ er gedruckt wird.
+ #off("i")#
+#free(1.0)#
+Bei Manuskripten für Artikel, Bücher und Manuals wissen Sie oft vorher nicht, in
+welchem Format das Manuskript gedruckt werden wird. Zu diesem Zweck ist es
+ebenfalls nützlich, Makros zu verwenden.
+
+____________________________________________________________________________
+
+ \#*kapitelanfang ($1)\#
+ \#free (2.0)\#
+ \#type ("gross")\#\#ib (9)\#$1\#ie (9)\#\#type ("normal")\#
+
+ \#*macro end\#
+
+____________________________________________________________________________
+
+
+In diesem Beispiel wird ein Makro für den Anfang eines Kapitels definiert. Zwischen
+zwei Kapiteln sollen hier zwei Zentimeter Zwischenraum bleiben, die Kapitel-
+Überschrift (als Parameter) wird in einer größeren Schrift gedruckt. Zusätzlich wird die
+Überschrift für ein Inhaltsverzeichnis in den 9. Index aufgenommen. Nach der Über­
+schrift wird eine Leerzeile eingeschoben, bevor der eigentliche Text anfängt.
+
+Der Anwender dieses Makros schreibt also z.B. folgende Anweisung:
+
+____________________________________________________________________________
+
+ \#kapitelanfang ("Ein Beispiel fuer Manuskripte")\#
+
+____________________________________________________________________________
+
+
+
+Beachten Sie, daß die Kapitel-Überschrift nicht länger als eine Textzeile sein darf.
+Das liegt daran, daß 'lineform'/'autoform' zwar die Zeile bearbeitet, aber nicht in den
+Text einsetzt. 'pageform'/'autopageform' setzt also die unveränderte - nicht umge­
+brochene - Textzeile ein.
+
+Sie können nun Makros für die meisten Textstrukturen definieren. Schreibkräfte
+brauchen dann in der Regel die meisten Text-Anweisungen nicht zu kennen, son­
+dern nur noch eine Anzahl von einfachen Makro-Anweisungen.
+
+Die Makro-Definitionen können jederzeit geändert werden, um wechselnden Bedürf­
+nissen angepaßt zu werden, z.B. wenn ein Verlag ein bestimmtes Schreibformat
+verbindlich vorschreibt. In diesem Fall brauchen nicht alle Text-Dateien geändert zu
+werden, sondern nur die Makro-Definitionen.
+
+Ein weiterer Vorteil einer solchen Vorgehensweise ist, daß die Makro-Anweisungen in
+diesem Fall angeben, #on("i")##on("b")#was#off("i")##off("b")# eine bestimmte Text-Struktur ist, und nicht, #on("i")##on("b")#wie#off("i")##off("b")# die
+Struktur behandelt werden soll.
+
+#on("b")#Anmerkung#off("b")#:
+In eine Makro-Definition sollten Sie ggf. \#limit\#-, \#type\#- und \#linefeed\#-
+Angaben einsetzen, um die Makros unabhängig von der Aufrufstelle zu machen. Ggf.
+sollten Sie auch die Datei vorher mit 'lineform' bearbeiten, um Trennungen vorzu­
+nehmen.
+#page#
+
+#ib(9)#5.8. Textkosmetik für Spezialisten#ie(9)#
+#free(1.0)#
+ #on("i")#
+ In diesem Abschnitt werden Ihnen Kommandos und Anweisungen vorgestellt, die
+ in der Regel nur für Spezialfälle benötigt werden.
+ #off("i")#
+#free(1.0)#
+
+#ib(9)#5.8.1. Schalter-Anweisungen für
+ #ib#Kopf- und Fußbereiche#ie(1, "Schalter-Anweisungen für")##ie(9)#
+#goalpage("head off")##goalpage("bottom off")#
+#free(1.0)#
+
+Mit den Textkosmetik-Anweisungen
+
+____________________________________________________________________________
+
+ #ib#\#head off\##ie#
+
+ #ib#\#bottom off\##ie#
+
+____________________________________________________________________________
+
+
+
+können Sie die Erzeugung von Kopf- oder Fußzeilen abschalten. Mit
+
+
+____________________________________________________________________________
+
+ #ib#\#head on\##ie#
+
+ #ib#\#bottom on\##ie#
+
+____________________________________________________________________________
+
+
+können Sie diese wieder erzeugen. Beachten Sie, daß diese Anweisungen an der
+Stelle beachtet werden, an der sie im Text stehen, d.h. diese Anweisungen gelten
+bereits für die Seite, auf der sie sich bei der 'pageform'-Bearbeitung befinden. Möch­
+ten Sie die Kopfzeilen für eine Seite abschalten, dann sollten Sie an dieser Stelle die
+#ib#\#head off\#-Anweisung#ie# geben. Um die Kopfzeilen für die nächste Seite wieder einzu­
+schalten, sollten Sie die #ib#\#head on\#-Anweisung#ie# an einer Stelle plazieren, von der Sie
+sicher sind, daß sie auf die folgende Seite gelangt (im Zweifelsfall nach einer
+\#page\#-Anweisung).
+#mark ("", "")#
+#page#
+
+#ib(9)#5.8.1.1. #ib#Kopf- und Fußbereiche abstellen#ie##ie(9)#
+#goalpage ("first head")##goalpage("last bottom")#
+#free(1.0)#
+ #on("i")#
+ Mit '#ib#first head#ie#' bzw. '#ib#last bottom#ie#' können Sie Kopf- oder Fußbereiche auf der
+ ersten (letzten) Seite ab- oder wieder anschalten.
+ #off("i")#
+#free(1.0)#
+Manchmal ist es notwendig, die Erzeugung von 'head'-Zeilen auf der ersten Seite
+(z.B. weil dort ein Briefkopf erscheint) und/oder 'bottom'-Zeilen auf der letzten Seite
+(weil keine Folgeseite existiert) zu verhindern. Mit dem Monitor-Kommando
+
+____________________________________________________________________________
+
+ gib kommando:
+ #ib#first head (FALSE)#ie#
+
+____________________________________________________________________________
+
+
+können Sie bei 'pageform' die Erzeugung von 'head'-Zeilen auf der ersten Seite
+jeder Druckdatei abschalten. Die Erzeugung bleibt so lange abgeschaltet, bis sie
+wieder durch
+
+____________________________________________________________________________
+
+ gib kommando:
+ #ib#first head (TRUE)#ie#
+
+____________________________________________________________________________
+
+
+angeschaltet wird. Das gleiche gilt analog für 'bottom'-Zeilen auf der letzten Seite:
+Ein- und Ausschalten durch
+
+____________________________________________________________________________
+
+ gib kommando:
+ #ib#last bottom (FALSE)#ie#
+
+____________________________________________________________________________
+#mark("","")#
+
+bzw.
+
+____________________________________________________________________________
+
+ gib kommando:
+ #ib#last bottom (TRUE)#ie#
+
+____________________________________________________________________________
+#page#
+
+#ib(9)#5.8.2. Textzeilen markieren#ie(9)#
+#goalpage("mark")#
+#free(1.0)#
+Mit der Anweisung
+
+
+____________________________________________________________________________
+
+ \#mark("markierungszeichen links","markierungszeichen rechts")\#
+
+____________________________________________________________________________
+
+
+
+können Sie einen Textabschnitt an den Rändern (außerhalb des Schreibfeldes!) mit
+Texten markieren, wie z.B. im folgenden mit der Anweisung
+
+#mark ("", "")#
+
+____________________________________________________________________________
+
+ \#mark ("> ", " <")\#
+
+____________________________________________________________________________
+
+
+#mark ("> ", " <")#
+Dabei gilt der erste Parameter für den linken und der zweite für den rechten Rand.
+Beachten Sie, daß Sie einen genügenden Zwischenraum zwischen der Markierung
+und dem Rand mit angeben müssen.
+
+Die Markierung ist insbesondere für Manuals interessant, wo Änderungen gegen­
+über der letzten Version hervorgehoben werden. Das Markierungszeichen wird neben
+den linken und rechten Rand gedruckt (also außerhalb des von \#start\# und \#limit\#
+begrenzten Textfeldes). Für das Drucken der Markierung wird der/die Schrifttyp/ Modi­
+fikationen benutzt, die an der Stelle der \#mark\#-Anweisung eingeschaltet ist. Der
+eigentliche Text bleibt selbstverständlich unberührt.
+#mark ("", "")#
+
+Um nur einen Rand zu markieren, kann auch ein leerer Parameter angegeben
+werden.
+
+____________________________________________________________________________
+
+ \#type ("pica")\#\#mark ("", " |")\#\#type ("normal")\#
+
+____________________________________________________________________________
+
+
+
+Mit der speziellen #ib#\#mark\#-Anweisung#ie#
+
+____________________________________________________________________________
+
+ \#mark ("", "")\#
+
+____________________________________________________________________________
+
+
+wird die Markierung ausgeschaltet.
+
+Soll ein Kopf-, Fuß-, Fußnoten- oder Tabellenbereich markiert werden, sollten sich
+die Markierungsein- und ausschalt-Anweisungen vollständig in dem Bereich be­
+finden.
+#page#
+
+#ib(9)#5.8.3. #ib#Fußnoten pro Seite zählen#ie##ie(9)#
+#goalpage("countperpage")#
+#free(1.0)#
+Manchmal wird gewünscht, daß die Fußnoten für jede Seite separat - also für jede
+Seite von 1 ab - gezählt werden. Das können Sie mit der Textkosmetik-Anweisung
+
+
+____________________________________________________________________________
+
+ \#count per page\#
+
+____________________________________________________________________________
+
+
+erreichen. Sie schaltet von einer fortlaufenden Zählung auf eine seitenweise Zählung
+um. Diese Anweisung sollte am Dateianfang stehen. Sie kann für die betreffende
+Datei nicht mehr abgeschaltet werden.
+#page#
+
+#ib(9)#5.8.4. Behandlung falscher #ib#Silbentrennungen#ie(1, ", Behandlung von falschen")#:
+ #ib#Ausnahmelexikon#ie##ie(9)#
+#free(1.0)#
+ #on("i")#
+ In das Ausnahmelexikon können fehlerhaft getrennte Worte aufgenommen
+ werden.
+ #off("i")#
+#free(1.0)#
+Es kann vorkommen, daß das Silbentrenn-Programm der Textkosmetik einige Worte
+immer wieder falsch trennt. Um dies zu vermeiden, können Sie diese Worte in ein
+#on("b")##on("i")#Ausnahmelexikon#off("b")##off("i")# speichern. Die Worte des Ausnahme-Lexikons werden bei einer
+Silbentrennung zuerst durchsucht. Wird ein Wort im Lexikon gefunden, dann wird das
+eigentliche Silbentrenn-Programm nicht mehr ausgeführt.
+
+Die Ausnahmen müssen Sie - wie unten beschrieben - in einer Datei notieren und
+mit dem Monitor-Kommando
+
+____________________________________________________________________________
+
+ gib kommando:
+ #ib#lade ausnahmen#ie# ("dateiname")
+
+____________________________________________________________________________
+#goalpage("lade ausnahmen")#
+
+
+in das Lexikon laden. Die Ausnahmen müssen Sie folgendermaßen in die Datei
+schreiben:
+
+____________________________________________________________________________
+
+ Sprech-stun-de
+ ins-be-son-de-re
+ Raum
+ Bei-spiel
+ ...
+
+____________________________________________________________________________
+
+
+Sie können jederzeit neue Ausnahmen in das Lexikon hinzuladen (wiederum mit 'lade
+ausnahmen'). In diesem Fall wird angefragt, ob das Lexikon überschrieben werden
+soll.
+
+
+
+Um zu kontrollieren, welche oder wie viele Ausnahmen sich im Lexikon befinden,
+können Sie
+
+____________________________________________________________________________
+
+ gib kommando:
+ #ib#entlade ausnahmen#ie# ("dateiname")
+
+____________________________________________________________________________
+ #goalpage("entlade ausnahmen")#
+
+geben. Das Lexikon wird dann in "dateiname" geschrieben. Auch hier können Sie
+weitere Ausnahmen hinzufügen und diese neu laden (aber diesmal überschreiben).
+#mark ("", "")#
+#page#
+
+#ib(9)#5.8.5. #ib#Voreinstellungen ändern#ie#:
+ Einige Monitor-Kommandos#ie(9)#
+#free(1.0)#
+#ib(9)#5.8.5.1. Wenige oder viele #ib#Silbentrennung#ie#en:
+ #ib#Trennpunkt einstellen#ie##ie(9)#
+#goalpage ("hyphenation width")#
+#free(1.0)#
+ #on("i")#
+ Mit dem Kommando 'hyphenation width' können Sie bestimmen, an welchem
+ Punkt Worte zur Trennung angeboten werden. Die Trennbreite können Sie
+ zwischen 4 und 20 Prozent der Zeilenbreite einstellen.
+ #off("i")#
+#free(1.0)#
+Viele Silbentrennungen in einem Text erschweren das Lesen. Nehmen Sie keine
+Silbentrennungen vor, wird der rechte Rand stark "ausgefranst" oder beim Blocksatz
+("rechter Randausgleich") müssen viele Zwischenräume zwischen den Worten ein­
+gefügt werden. Durch das Monitor-Kommando
+
+____________________________________________________________________________
+
+ gib kommando:
+ #ib#hyphenation width#ie# (prozentuale angabe)
+
+____________________________________________________________________________
+
+
+unmittelbar vor dem Aufruf von 'autoform' oder 'lineform' können Sie den Punkt, an
+dem die Silbentrennung einsetzen soll, einstellen. Die Klammern enthalten eine ganze
+Zahl, die für Prozent der Zeilenbreite steht. Minimum sind 4, Maximum 20 Prozent.
+Beispielsweise stellt 'hyphenation width (5)' den Trennpunkt auf 5% der Zeilenbreite
+ein (voreingestellt ist 7). Bei einer Angabe von 20 werden somit sehr wenige Worte
+zur Silbentrennung angeboten, d.h. je größer die Prozentangabe, desto weniger Worte
+werden zur Trennung angeboten. Die Einstellung des Trennpunktes bestimmt also, ab
+wann ein Wort zur Silbentrennung untersucht wird. Andererseits bestimmt die Ein­
+stellung auch, wieviel Zwischenraum zwischen Worten eingefügt werden muß, um
+einen rechten Randausgleich zu erzielen.
+#page#
+
+#ib(9)#5.8.5.2. Anzahl #ib#Leerzeilen vor Fußnoten#ie#
+ einstellen#ie(9)#
+#goalpage("number empty")#
+#free(1.0)#
+ #on("i")#
+ '#ib#number empty lines before foot#ie#' stellt die Anzahl der Leerzeilen vor Fußnoten ein.
+ #off("i")#
+#free(1.0)#
+Die Anzahl der Leerzeilen vor #ib#Fußnoten#ie(1, ", Leerzeilen davor")# (voreingestellt ist eine Leerzeile) können Sie
+durch das Monitor-Kommando 'number empty lines before foot' einstellen.
+
+
+
+____________________________________________________________________________
+
+ gib kommando:
+ number empty lines before foot (3)
+
+____________________________________________________________________________
+
+
+stellt drei Leerzeilen vor dem Fußnotenblock ein. Beachten Sie, daß diese Einstellung
+so lange gilt, bis Sie das Monitor-Kommando erneut geben.
+#mark("","")#
+
diff --git a/doc/user/benutzerhandbuch.5d b/doc/user/benutzerhandbuch.5d
new file mode 100644
index 0000000..8a61f29
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5d
@@ -0,0 +1,211 @@
+#start(5.0,1.5)##pagenr("%",116)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 5: Textkosmetik und Druck
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+5 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 5 - %
+#tableend##clearpos#
+#end#
+
+#ib(9)#5.9. Übersicht über die Anweisungen und
+ Kommandos der EUMEL-Textkosmetik#ie(9)#
+#free(1.0)#
+ #on ("i")#
+ Zuerst werden die am häufigsten benutzten Kommandos/Anweisungen beschrie­
+ ben. Danach sind (durch einen Strich getrennt) Kommandos/Anweisungen auf­
+ geführt, die seltener benötigt werden.
+ #off ("i")#
+#free(1.0)#
+#on("b")#
+#ib#Kommandos#ie##off("b")#
+#free(1.0)#
+ #on("i")#
+ Kommandos werden im Monitor gegeben ('gib kommando :').
+ #off("i")#
+#free(1.0)#
+#lpos(0.0)##lpos(4.6)#
+#table#
+#on("b")#Kommando Bedeutung#off("b")#
+#free(1.0)#
+#clearpos#
+#lpos(0.0)##lpos(4.6)#
+lineform ("x") Formatieren von Zeilen mit interaktiver Silben­
+ trennung.
+autoform ("x") Wie lineform, jedoch werden Silbentrennungen
+ automatisch vorgenommen.
+pageform ("x") Interaktives Formatieren von Seiten, mit Behand­
+ lung von Fußnoten, Kopf- und Fußzeilen, Seiten­
+ numerierung, Seitenquerverweisen usw. Erzeugt
+ eine Druckdatei (Zusatz '.p').
+autopageform ("x") Wie pageform, jedoch werden die Seitengrenzen
+ automatisch plaziert.
+print ("x") Datei drucken.
+print ("x.p") Eine mit 'pageform' bearbeitete Datei drucken.
+---------------- ----------------
+#page#
+index ("x.p") Erstellt aus einer Druckdatei ein Stichwort-
+ und/oder Inhaltsverzeichnis.
+index merge ("a.i1","b.i1") Führt Indexdateien zusammen.
+outline ("x") Erstellt eine Übersicht aus Kapitelüberschriften
+ und Stichworten.
+hyphenation width (int) Stellt die Trennbreite für die Silbentrennung ein.
+load macros ("x") Lädt Makros.
+list macros Zeigt geladene Makros.
+lade ausnahmen ("x") Lädt Wörter, die von der Trennhilfe nicht korrekt
+ getrennt werden, in einen Ausnahme-Speicher.
+entlade ausnahmen ("x") Entlädt die Worte aus dem Ausnahme-Speicher
+ in die angegebene Datei.
+first head (false) Schaltet Kopfzeilen auf erster Seite aus.
+first head (true) Schaltet Kopfzeilen auf erster Seite wieder ein.
+last bottom (false) Schaltet Fußzeilen auf letzter Seite aus.
+last bottom (true) Schaltet Fußzeilen auf letzter Seite wieder ein.
+number empty lines before foot Stellt die Anzahl der Leerzeilen vor einer Fußnote
+before foot ein.
+#tableend##clearpos#
+#page#
+#on("b")#
+#ib#Anweisungen#ie##off("b")#
+#free(1.0)#
+ #on ("i")#
+ Anweisungen werden in die Datei geschrieben. Jede Anweisung muß in Anwei­
+ sungszeichen eingeschlossen werden. Als Parameter (diese werden in Klammern
+ eingeschlossen) kommen in Frage:
+ 'int' bedeutet eine ganze Zahl: 17, 1, 311;
+ 'real' bedeutet eine Zahl mit Dezimalpunkt (meist cm-Angabe): 0.5, 1.25;
+ 'text' bedeutet eine Zeichen-Angabe. Muß in Anführungszeichen eingeschlos­
+ sen werden: "%", "meine datei".
+ #off ("i")#
+#free(1.0)#
+#lpos(0.0)##lpos(4.6)#
+#table#
+#on("b")#Anweisung Bedeutung#off("b")#
+#clearpos#
+#lpos(0.0)##lpos (4.6)#
+
+type (text) Schrifttyp einstellen: \#type("trium8")\#
+limit (real) Zeilenbreite einstellen: \#limit (16.0)\#
+on (text) Modifikation einschalten: \#on("bold")\#. Erlaubt
+ sind: b(bold), r(everse), i(talic), u(nderline)
+off (text) Modifikation ausschalten (siehe 'on').
+block Blocksatz (Randausgleich) einschalten.
+head Kopfzeilen (für Seiten mit geraden/ungeraden
+(bzw. headeven/headodd) Seitennummern) definieren.
+... -%- Platzhalter für Seitenzahl.
+end Kopfzeilen-Ende (pageform).
+bottom Wie oben, jedoch für Fußzeilen.
+(bzw.
+bottomeven/bottomodd)
+...
+end Fußzeilen-Ende
+pagenr (text, int) Seitennummer einstellen bzw. zusätzliches Sei­
+ enzeichen ab nächster Seite einführen:
+ \#pagenr ("%", 17)\#
+foot Fußnoten-Anfang.
+...
+end Fußnoten-Ende.
+free (real) Platz freihalten (in cm): \#free (1.27)\#
+page Neue Seite: \#page\#
+page (int) Neue Seite mit Seitennummer 17: \#page (17)\#
+linefeed (real) Zeilenhöhe relativ zum eingeschalteten Schrifttyp
+ verändern: \#linefeed (1.25)\#
+pagelength (real) Seitenlänge einstellen (ab nächster Seite in cm):
+ \#pagelength (24.0)\# Nachfolgenden Zeilentext
+center zentriert drucken.
+right Nachfolgenden Zeilentext rechtsbündig drucken.
+u ... e (steht für up) Exponent schreiben: \#u\#123\#e\#
+d ... e (steht für down) Index schreiben.
+start (real, real) Schriftfeld (linke obere Ecke) einstellen: \#start
+ (1.0, 2.0)\#
+------------ ------------
+b Zwei Zeichen übereinander drucken.
+bottom off Schaltet Fußzeilen aus.
+bottom on Schaltet Fußzeilen ein.
+bpos (real, real) Der Text zwischen den angegebenen Tabellen­
+ positionen wird im Blocksatz gedruckt.
+clearpos Löscht alle Tabellenpositionen.
+clearpos (real) Löscht die angegebene Tabellenposition.
+columns (int, real) Formatieren von Spalten mit Zwischenraum:
+ \#columns (3, 1.0)\#, 3 Spalten mit 1 cm Zwischen­
+ raum.
+columnsend Beendigung der Spaltenformatierung.
+count Interner Zähler für Fußnoten wird eingesetzt
+ (pageform).
+count (text) Wie oben, aber der Wert des internen Zählers
+ wird vermerkt: \#count ("neue Zahl")\#
+count per page Interner Zähler beginnt bei jeder Seite mit 1.
+cpos (real) Zentrierende Tabellenposition.
+dpos (real, text) Um den angegebenen Text zentrierende Tabel­
+ lenposition, meist Dezimalzeichen:
+ \#dpos (13.0, 2.")\#
+fillchar (text) Zwischenräume zwischen Tabellenpositionen wer­
+ den mit dem angegebenen Text beim Drucken
+ ausgefüllt. Beachten Sie, daß das Ausschalten der
+ Füllzeichen durch 'niltext' erfolgt.
+goalpage (text) Stelle, auf die obige Anweisung verweist: \#goal­
+ page ("1.Kapitel")\#
+head off Schaltet Kopfzeile(n) aus.
+head on Schaltet Kopfzeile(n) ein.
+ib Anfang eines Stichworts oder einer Kapitel­
+ überschrift kennzeichnen (Ablegen in Indexdatei
+ mit Zusatz '.i1'): \#ib\#ein Stichwort oder eine
+ Kapitelüberschrift\#ie\#
+ib (int) Wie oben, jedoch wird Stichwort in angegebener
+ Indexdatei abgelegt.
+ib (int, text) Wie oben, jedoch erhält Eintrag in der Indexdatei
+ den angegebenen Text an die Seiten­
+ nummer angefügt.
+ie Beendigung der Stichwortmarkierung.
+ie (int) Wie oben (int-Angabe muß der in der ib-An­
+ weisung entsprechen).
+ie (int, text) Wie oben, jedoch wird die Textangabe hinter das
+ markierte Stichwort angefügt.
+lpos (real) Linksbündige Tabellenposition.
+mark (text, text) Markierung rechts und links neben der Schreib­
+ fläche ein-/ausschalten.
+pageblock Einschalten des vertikalen Blocksatzes. Falls ein­
+ geschaltet, kann mit 'pageform' auch über das
+ (rechnerische) Seitenende formatiert werden.
+rpos (real) Rechtsbündige Tabellenposition.
+setcount (int) Zählerwert setzen: \#setcount (17)\#
+table Anfang einer Tabelle.
+...
+table end Ende einer Tabelle.
+topage (text) Seitenverweis (die Seitennummer, auf die verwie­
+ sen wird, wird eingesetzt):
+ \#topage ("1.Kapitel")\#
+value Letzter Zählerwert wird eingesetzt.
+value (text) Wie oben, jedoch wird ein vermerkter Zählerwert
+ eingesetzt: \#value ("Vermerk")\#
+#tableend#
+
diff --git a/doc/user/benutzerhandbuch.5e b/doc/user/benutzerhandbuch.5e
new file mode 100644
index 0000000..d515c6a
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5e
@@ -0,0 +1,223 @@
+#start(5.0,1.5)##pagelength(17.4)##pagenr("%",121)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 5: Textkosmetik und Druck
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+5 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 5 - %
+#tableend##clearpos#
+#end#
+
+#ib(9)#5.10. Fehlersituationen und Abhilfe#ie(9)#
+
+#free(1.0)#
+Was können Sie machen, wenn
+
+
+... bestimmte Anweisungen, die den Gesamttext betreffen, erst ab der zweiten
+ Seite wirksam werden?
+
+
+ Textkosmetik-Anweisungen, die ab der ersten Seite für den ganzen Text gelten
+ sollen, müssen Sie als erstes, d.h. in die erste Zeile einer Datei, schreiben. Dies
+ bezieht sich u.a. auf 'pagelength', 'start', 'block', 'pageblock' etc., die noch vor
+ \#head\#- oder \#bottom\#-Anweisungen gesetzt werden müssen.
+
+
+
+
+... sich der Cursor nicht mehr bewegen läßt?
+
+
+ Eine Möglichkeit besteht darin, daß Sie versehentlich die 'STOP' -Taste
+ (='CTRL a' gleichzeitig, d.h. Anhalten der Bildschirmausgabe) betätigt haben.
+ In diesem Fall drücken Sie die 'WEITER' -Taste ('CTRL c' gleichzeitig, d.h.
+ Bildschirmausgabe fortführen). Alle Tastenanschläge, die Sie in der Zwischen­
+ zeit vollzogen haben, werden jetzt ausgeführt.
+
+ Eine andere Möglichkeit wäre, daß Sie Ihre Datei/Task nicht ordnungsgemäß
+ verlassen haben. Versuchen Sie über die 'SV'-Taste und 'ESC h' wieder auf
+ die Monitor-Ebene zu gelangen, so daß Sie dann auf die Aufforderung 'gib
+ kommando' hin, wieder in Ihre Datei gelangen können.
+
+
+
+
+... Sie nur einen Dateiausschnitt löschen, duplizieren oder mit 'lineform' bearbeiten
+ möchten?
+
+
+ Der betreffende Ausschnitt muß markiert werden. Zum Löschen benutzen Sie
+ die Tasten 'ESC RUBOUT'. Der Ausschnitt ist hiermit aber noch nicht 'voll­
+ ständig verschwunden', sondern Sie können ihn mit 'ESC RUBIN' an gleicher
+ oder anderer Stelle wieder hervorbringen, so lange bis Sie die Tasten erneut
+ benutzen.
+
+ Das Duplizieren eines Textbereiches erfolgt nach dem Markieren durch das
+ Betätigen der Tastenfolge 'ESC d'. Hierbei bleibt der Originaltext erhalten und
+ kann beliebig oft dupliziert werden. Den duplizierten Text holen Sie sich mit
+ 'ESC g' an die gewünschte Stelle in Ihrer Datei.
+
+ Möchten Sie 'lineform' nur auf einen Ausschnitt anwenden, markieren Sie
+ diesen und geben nach 'ESC ESC' das Kommando 'lineform'.
+
+
+
+
+... beim Drucken die letzte bzw. die letzten beiden Zeilen auf einer gesonderten
+ Seite ausgedruckt werden?
+
+
+ a) Sie müssen die Fonttabelle noch einrichten.
+
+ oder
+
+ b) Sie setzen die \#pageblock\#-Anweisung zu Beginn des Textes und "stau­
+ chen" um zwei Zeilen.
+
+ oder
+
+ c) Sie wählen eine kleineren Schrifttyp.
+
+
+
+
+... in Ihrer Datei die Meldung
+
+ _______________________________________________________________________
+
+ FEHLER: FILE-Überlauf
+
+ gib kommando:
+ edit ("dateiname")
+
+ _______________________________________________________________________
+
+ erscheint und das Abschicken des Kommandos mittels der 'CR'-Taste aber nur
+ zu einer identischen Meldung (siehe oben) führt?
+
+
+ Wenn Sie auf dem oben dargestellten Weg nach mehrmaligem Versuchen nicht
+ wieder in Ihre Datei gelangen, haben Sie die Möglichkeit, mit dem Kommando
+
+ _______________________________________________________________________
+
+ gib kommando:
+ reorganize ("dateiname")
+
+ _______________________________________________________________________
+
+
+ Ihre Datei neu zu 'organisieren', um 'Lücken', die durch Einfügen oder Löschen
+ entstanden sind, zu eliminieren. Die Datei beansprucht dann in der Regel auch
+ weniger Speicherplatz.
+
+ Sind Sie wieder in Ihrer Datei, empfiehlt es sich, die große Datei in mehrere
+ kleine aufzuteilen. Entweder Sie halbieren oder (besser) Sie dritteln Ihre Text­
+ datei und verteilen den Text auf zwei bis drei Dateien. Zukünftig sollten Sie es
+ sich dann bei umfangreichen Texten zur Regel machen, nur ein logisch
+ zusammenhängendes Kapitel in einer Datei abzulegen. Sie sollten Ihre Datei nur
+ so groß halten, daß Ihnen noch genügend Raum zur Verfügung steht, Proze­
+ duren wie z.B. 'pageform' durchzuführen, durch die sich der Umfang einer Datei
+ (z.T. wesentlich) vergrößert.
+
+
+
+
+... bei Ihrem Text einige Wörter mit extrem großem Zwischenraum gedruckt
+ wurden?
+
+
+ Sie haben in diesem Fall wahrscheinlich vergessen, die Absatzmarkierung zu
+ setzen, so daß aufgrund der \#block\#-Anweisung ein rechter Randausgleich
+ erfolgte, den Sie an dieser Stelle nicht wünschten.
+
+
+
+
+... eine Überschreibung erfolgt ist bzw. wenn 'lineform' eine Überschreibung
+ meldet?
+
+
+ Eine solche Überschreibung kann auftreten, wenn Sie mit einer besonders
+ großen Type in Fettdruck (z.B. triumb14) schreiben (vgl. Sie hierzu auch Kapitel
+ 5.2.6.). Um dies zu verhindern, können Sie zum einen die Anzahl der Blanks
+ zwischen den einzelnen Gliedern erhöhen oder zum anderen auch die
+ \#type\#-Anweisung in die vorhergehende Zeile setzen (n i c h t direkt v o r den
+ betreffenden Text).
+
+
+
+
+... nach der erfolgten Prozedur 'lineform' Ihre Tabellen durcheinander geraten
+ sind?
+
+
+ Wenn Sie Tabellen schreiben, müssen Sie nach jeder Zeile die Absatzmarke
+ setzen. Sollen bei einigen Tabellenpositionen Spalten leer bleiben, müssen Sie
+ für diese Positionen ein geschütztes Blank einsetzen.
+
+
+
+
+... bei der Prozedur 'pageform' das Seitenende nicht interaktiv verschoben werden
+ kann, obwohl am Anfang der Datei eine \#pageblock\#-Anweisung gegeben
+ wurde?
+
+
+ Eine \#page\#-Anweisung im Text bewirkt, daß Sie an dieser Stelle das Seiten­
+ ende nur bestätigen, die Anweisung löschen oder als dritte Möglichkeit, die
+ Seitenformatierung abbrechen können. Für den Fall, daß die \#page\#-
+ Anweisung nicht mehr zutrifft bzw. falsch gesetzt wurde, sollten Sie die Anwei­
+ sung löschen und das Seitenende interaktiv plazieren.
+
+
+
+
+... Sie bei der Erstellung eines Inhaltsverzeichnisses oder eines Indexes keine
+ Füllzeichen zwischen Text und Seitenangabe haben möchten?
+
+
+ In diesem Fall gehen Sie mit 'ESC ESC' in den Kommandozustand und ändern
+ mit Hilfe von CA (Change All) die Füllzeichen in Leerzeichen um. Verwenden
+ Sie nicht nur einen Punkt, da sonst auch die Punkte zwischen den Ziffern der
+ Kapitelnumerierung verschwänden. Es kann bei einer ungeraden Anzahl von
+ Füllzeichen notwendig sein, nachträglich noch einige Punkte entfernen zu
+ müssen.
+
+ _______________________________________________________________________
+
+ gib kommando: ".." CA " "
+
+ _______________________________________________________________________
+
diff --git a/doc/user/benutzerhandbuch.6 b/doc/user/benutzerhandbuch.6
new file mode 100644
index 0000000..5e035d2
--- /dev/null
+++ b/doc/user/benutzerhandbuch.6
@@ -0,0 +1,474 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Teil 6: Spezialitäten
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+6 - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD 6 - %
+#tableend##clearpos#
+#end#
+
+#kap("TEIL 6: Spezialitäten")#
+#free(1.0)#
+
+6.1. Notizbuch
+#free(1.0)#
+ Das Notizbuch erlaubt es u.a., Fehlermeldungen zwischenzeitig zu speichern und
+ am Ende einer Verarbeitung die Fehlermeldungen zusammen mit dem bearbeiteten
+ Text im Fenstereditor anzuzeigen.
+#free(1.0)#
+Das #ib#Notizbuch#ie# wird von den Programmen 'lineform' und 'pageform' zum Sammeln
+von Warnungen und Fehlermeldungen verwendet. Wenn das Fenster des Notizbuches
+an Bildschirm eröffnet ist, können Sie es handhaben wie das gewohnte Editorfenster.
+
+Falls Sie das Notizbuch selbst beim Editieren für Notizen verwenden möchten, drük­
+ken Sie statt <ESC> <e> für den Fenstereditor die Tasten <ESC> <n> an beliebiger
+Stelle des Bildschirms. Durch dieses Kommando wird das Notizbuch statt einer Datei
+gezeigt. Sie sparen somit die Eingabe eines Dateinamens und können direkt mit allen
+vorgestellten Editorfunktionen im Notizbuch arbeiten.
+
+
+#page#
+____________________________________________________________________________
+ ................ handbuch teil6 .............. Zeile 56
+\#kap("6.2. EUMEL-Zeichensatz")\#
+\#free(1.0)\#
+\#zus\#
+ \#corner1("-5.0")\#
+ Das EUMEL-System definiert einen Zeichensatz, der gewähr­
+ auf allen Maschinen überall gleich codiert werden. Dadurch ist
+ Dateien und Programme ohne Konvertierungen zwischen EUMEL-Syst
+ unterschiedlicher Hersteller zu übertragen. Der \#ib\#EUMEL-
+ dem ASCII-Zeichensatz (DIN 66 003) mit Erweiterungen.
+ \#box3("T","2","115.0")\#
+
+ ................. notebook ................... Zeile 1
+FEHLER Zeile 55: Modifikation nicht angeschaltet bei off: b
+ >>> Anweisung in angegebener Zeilennummer überprüfen
+WARNUNG Zeile 55: Umschaltung auf gleichen Schrifttyp: trium8
+ >>> Schrifttyp wurde darum nicht verändert!
+WARNUNG Zeile 75: Überschreibung nach >\#ib(9)\#6.2.< Fehlende
+ >>> Bitte fehlende Leerzeichen einfügen
+
+____________________________________________________________________________
+#page#
+6.2. EUMEL-Zeichensatz
+#free(1.0)#
+
+
+ Das EUMEL-System definiert einen Zeichensatz, der gewährleistet, daß Zeichen
+ auf allen Geräten gleich codiert werden. Dadurch ist es z.B. möglich, Dateien und
+ Programme ohne Konvertierungen zwischen EUMEL-Systemen unterschiedlicher
+ Hersteller zu übertragen. Der #ib#EUMEL-Zeichensatz#ie# beruht auf dem ASCII-
+ Zeichensatz (DIN 66 003) mit Erweiterungen.
+
+#free(1.0)#
+
+Die Darstellung der einzelnen Zeichen hängt vom Endgerät ab. Die hier aufgeführten
+Zeichen sind i.A. auf allen Geräten vorhanden. Ein erweiterter Zeichensatz (mit ma­
+thematischen, diakritischen und griechischen Zeichen) ist nur auf Spezialgeräten
+verfügbar und wird deshalb hier nicht angegeben.
+#page#
+Beispiele zum Lesen der Tabelle:
+
+ code (" ") -> 32
+ code ("m") -> 109
+ | 0 1 2 3 4 5 6 7 8 9
+--+----------------------------------------
+3 | SP ! " \# $ % & '
+ |
+4 | ( ) * + , - . / 0 1
+ |
+5 | 2 3 4 5 6 7 8 9 : ;
+ |
+6 | < = > ? § A B C D E
+ |
+7 | F G H I J K L M N O
+ |
+8 | P Q R S T U V W X Y
+ |
+9 | Z [ ��\� ] ^ _ ` a b c
+ |
+10| d e f g h i j k l m
+ |
+11| n o p q r s t u v w
+ |
+12| x y z | } ~
+ |
+13|
+ .
+ .
+ .
+20|
+ |
+21| Ä Ö Ü ä ö ü
+ |
+22| k ­ \# SP
+ |
+23|
+ |
+24|
+ |
+25| ß
+#page#
+
+
+Anmerkungen:
+
+1) SP bedeutet Leerzeichen ("blank").
+
+2) Die Zeichen 'k', '-' und 'SP' mit den Codes 220, 221, 223 werden für die Zwecke
+ der Textkosmetik benötigt (Trenn-'k' bei der Umwandlung von 'ck' in 'kk'; Trenn­
+ zeichen; geschütztes Leerzeichen).
+
+3) Das Zeichen '\#' (Code 222) ist druckbar, während das Zeichen '\#' (Code 35) nicht
+ druckbar ist (Einleitungszeichen für Anweisungen der Textkosmetik und Drucker).
+
+4) Das Zeichen SP (Code 223) wird zur besseren Identifizierung invers oder als
+ Unterstreichungsstrich auf dem Terminal dargestellt. In einem Ausdruck erscheint
+ es als ein Leerzeichen.
+
+Falls Sie Zeichen ausgeben möchten, die nicht auf der Tastatur sind, müssen Sie den
+Code der gewünschten Zeichen zu Hilfe nehmen.
+
+Bewegen Sie den Cursor dazu an die Stelle der Datei, an die das Sonderzeichen
+geschrieben werden soll und geben Sie nach <ESC> <ESC> ein:
+
+
+____________________________________________________________________________
+ ................. dateiname .................. Zeile 123
+
+ TABELLE 1
+ _____________________
+ | |
+ gib kommando : type(code(124))
+
+
+
+____________________________________________________________________________
+#page#
+6.3. Sortier-Programme
+#free(1.0)#
+
+
+ Es stehen zwei verschiedene Sortier-Programme zur Verfügung: 'sort' (Sortierung
+ nach ASCII-Reihenfolge) und 'lex sort' (Sortierung nach deutschem Alphabet).
+
+#free(1.0)#
+
+Die Sortierprogramme sortieren eine Datei zeilenweise.
+
+Beispiel:
+
+
+____________________________________________________________________________
+ ................. dateiname ................. Zeile 1
+ Berta ist eine Frau.
+ Adam ist ein Mann.
+ ...
+
+____________________________________________________________________________
+
+
+____________________________________________________________________________
+gib kommando :
+#ib#sort#ie# ("dateiname")
+
+____________________________________________________________________________
+
+
+
+
+____________________________________________________________________________
+ ................. dateiname ................. Zeile 1
+ Adam ist ein Mann.
+ Berta ist eine Frau.
+ ...
+
+____________________________________________________________________________
+
+
+
+
+Dabei werden die Zeilen-Anfänge solange zeichenweise miteinander verglichen, bis
+ein Unterschied auftritt und dann ggf. umgeordnet. Werden zwei ungleich lange Zeilen
+(Anzahl Zeichen/Zeile) miteinander verglichen, dann kann man sich die kürzere Zeile
+mit Leerzeichen auf die Länge der längeren Zeile verlängert denken.
+
+Die Reihenfolge, in der die Zeilen sortiert werden, erfolgt nach dem ASCII-
+Zeichensatz in aufsteigender Reihenfolge (vergl EUMEL-Zeichencode):
+
+
+ das Leerzeichen
+ einige Sonderzeichen
+ die Ziffern
+ einige Sonderzeichen
+ große Buchstaben
+ einige Sonderzeichen
+ kleine Buchstaben
+ einige Sonderzeichen
+ die Umlaute und ß
+
+
+Das bedeutet, daß z.B. folgendermaßen sortiert wird:
+
+
+____________________________________________________________________________
+ ................. dateiname ................. Zeile 1
+ Adam
+ Ball
+ Zuruf
+ aber das ist ein Satz
+ niemals
+ Überlauf
+
+____________________________________________________________________________
+
+
+
+
+Um zu erreichen, daß große und kleine Buchstaben gleichwertig behandelt werden,
+kann man das Kommando
+
+____________________________________________________________________________
+gib kommando :
+#ib#lex sort#ie# ("dateiname")
+
+____________________________________________________________________________
+
+
+
+geben.
+
+In diesem Fall würde die sortierte Datei folgendermaßen aussehen:
+
+____________________________________________________________________________
+ ................. dateiname ................. Zeile 1
+ aber das ist ein Satz
+ Adam
+ Ball
+ niemals
+ Überlauf
+ Zuruf
+
+____________________________________________________________________________
+
+
+Man beachte, daß der Umlaut 'Ü' wie 'Ue' behandelt wird (für die restlichen Umlaute
+gilt eine analoge Behandlung; ebenso wird 'ß' wie 'ss' behandelt). Weiterhin werden
+alle Sonderzeichen bei der Sortierreihenfolge ignoriert.
+
+6.4 Fonttabellen
+#free(1.0)#
+
+
+ Eine Fonttabelle enthält Angaben zu den druckbaren Zeichen.
+
+#free(1.0)#
+
+Die Einstellung einer Fonttabelle#u#1)#e# erfolgt automatisch beim Einrichten der Drucker-
+Task (siehe Anhang). Um den Namen der in der Task eingestellten Fonttabelle zu
+erhalten geben Sie ein:
+#foot#
+1) Fonttabelle: Beschreibung der druckbaren Schrifttypen.
+#end#
+
+____________________________________________________________________________
+
+gib kommando:
+put(fonttable)
+
+____________________________________________________________________________
+
+
+Die Ausgabe liefert den Namen der in der Task eingestellten Fonttabelle.
+
+____________________________________________________________________________
+
+gib kommando:
+put(fonttable)
+agfa9
+gib kommando:
+
+____________________________________________________________________________
+
+
+Um eine neue oder andere Fonttabelle einzustellen, etwa weil verschiedene Drucker
+benutzt werden können, geben Sie das 'fonttable' Kommando mit dem Namen der
+gewünschten Fonttabelle als Parameter an:
+
+____________________________________________________________________________
+
+gib kommando:
+fonttable("name der fonttabelle")
+
+____________________________________________________________________________
+
+
+
+Eine weitergehende Beschreibung der eingestellten Fonttabelle erhalten Sie durch das
+Kommando 'list fonts':
+
+____________________________________________________________________________
+
+gib kommando:
+list fonts
+
+____________________________________________________________________________
+
+
+Durch dieses Kommando erhalten Sie in das Notizbuch eine Aufstellung der Schrift­
+typen mit Angaben zu Namen der verfügbaren Schrifttypen in der Fonttabelle,
+Größenangaben zu den Schriftttypen etc.
+
+____________________________________________________________________________
+ ................. notebook .................. Zeile 1
+FONTTABELLE : "agfa9";
+ x einheit = 160.0;
+ y einheit = 160.0;
+
+ FONT : "micro", "elanlist", "bulletin22";
+ einrueckbreite = 20;
+ durchschuss = 7;
+ fonthoehe = 30;
+ fonttiefe = 8;
+ groesserer font = "";
+ kleinerer font = "";
+
+ FONT : "trium10";
+ einrueckbreite = 31;
+ durchschuss = 6;
+ fonthoehe = 54;
+ fonttiefe = 15;
+ groesserer font = "trium12";
+ kleinerer font = "trium8";
+
+____________________________________________________________________________
+
+
+
+Anmerkung:
+ - Falls mehrere Namen für einen Schrifttyp angegeben sind, können Sie
+ einen beliebigen dieser Namen in der \#type\#-Anweisung benutzen.
+
+ - Größenangaben sind in 'Mikroschritten', d.h. den kleinstmöglichen
+ Schritten des jeweiligen Druckers angegeben und nicht etwa in mm.
+
+ - Weitere Informationen entnehmen Sie ggf. dem Systemhandbuch.
+
+#page#
+6.5 Syntax der Kommandos
+#free(1.0)#
+code
+ TEXT PROC code (INT CONST zahl)
+ Wandelt 'zahl' in ein Zeichen um. Falls die Zahl kleiner als 32 oder größer als 254
+ ist, (siehe Codetabelle) muß mit unerwarteten Ergebnissen gerechnet werden.
+
+
+ type(code(92))
+
+
+ INT PROC code (TEXT CONST zeichen)
+ Wandelt 'zeichen' in die zugehörige EUMEL-Codierung um. Falls mehr als ein
+ Zeichen angegeben wird, ist das Resultat '-1'.
+
+
+ put(code(92))
+
+
+
+list fonts
+ PROC list fonts
+ Listet die Fonts der eingestellten Tabelle ins #on("i")#notebook#off("i")#.
+
+ PROC list fonts (TEXT CONST fonttable name)
+ Listet die Fonts der angegebenen Fonttabelle ins #on("i")#notebook#off("i")#. Die vorher eingestellte
+ Fonttabelle bleibt jedoch weiter eingestellt.
+
+
+ list fonts ("fonttab.alternativ")
+
+
+
+lex sort
+ PROC lex sort (TEXT CONST datei)
+
+ Zeilenweise Sortierung nach (deutscher) lexikographischer Reihenfolge nach DIN
+ 5007.
+
+
+ lex sort ("telephonliste")
+
+
+ PROC lex sort (TEXT CONST datei, INT CONST anfang)
+
+ Wie 'lex sort', jedoch wird bei der Sortierung bei 'anfang' jeder Zeile begonnen.
+
+
+ lex sort ("liste",20)
+
+
+sort
+ PROC sort (TEXT CONST datei)
+
+ Die Prozedur 'sort' sortiert die Datei 'datei' zeilenweise. Die Sortierung erfolgt
+ nach der Ordnung, die der EUMEL-Zeichencode vorschreibt. Beispielsweise
+ werden Zeilen ("Sätze"), die mit Ziffern beginnen, vor Sätzen, die mit Buchstaben
+ anfangen, eingeordnet. Sätze, die mit großen Buchstaben beginnen, werden vor
+ Sätzen mit kleinen Buchstaben einsortiert. Weiterhin werden die Umlaute und das
+ "ß" nach allen anderen Buchstaben eingeordnet.
+
+
+ sort ("liste")
+
+
+ PROC sort (TEXT CONST datei, INT CONST anfang)
+
+ Sortiert eine Datei wie obige Prozedur, jedoch wird bei der Sortierung nicht der
+ Anfang eines Satzes beachtet, sondern die Position 'anfang'.
+
+
+ sort ("liste",10)
+
+
+
+type
+ PROC type (TEXT CONST zeichenkette)
+
+ Fügt 'zeichenkette' in die aktuelle Position der editierten Datei ein. Besonders
+ nützlich in Verbindung mit der Prozedur 'code', um nicht auf der Tastatur enthal­
+ tene Zeichen in den Text zu bringen.
+
+
+ type(code(200))
+
diff --git a/doc/user/benutzerhandbuch.anhang b/doc/user/benutzerhandbuch.anhang
new file mode 100644
index 0000000..5a58f95
--- /dev/null
+++ b/doc/user/benutzerhandbuch.anhang
@@ -0,0 +1,484 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+ EUMEL-Benutzerhandbuch
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#headodd#
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")#
+#table#
+ Anhang
+#fillchar(" ")#
+#on("u")# #off("u")#
+#table end##clear pos#
+
+#end#
+#bottomeven#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+A - % GMD
+#tableend##clearpos#
+#end#
+#bottomodd#
+
+#lpos(0.0)##cpos(5.5)##rpos(11.0)#
+#table#
+#fillchar(" ")#
+#on("u")# #off("u")#
+#fillchar(" ")#
+GMD A - %
+#tableend##clearpos#
+#end#
+Aufbau und Installation
+#free(0.5)#
+ Diese Installationsanleitung dient nur als Beispiel und soll nicht die Anleitung zu
+ dem von Ihnen benutzten Gerät ersetzen. Insbesondere die hier beschriebene
+ Möglichkeit der Partitionierung ist kein Standard!
+#free(0.5)#
+Allgemeines über das Betriebssystem EUMEL
+#free(0.5)#
+
+Zum besseren Verständnis des Installierungsvorganges sei hier kurz der Aufbau des
+Betriebssystems EUMEL erläutert (Der EUMEL-Kenner mag diesen Abschnitt über­
+springen) :
+
+Das System besteht im wesentlichen aus den folgenden Komponenten :
+
+ - SHard (#on("i")##on("b")#S#off("b")##off("i")#oftware - #on("i")##on("b")#Hard#off("b")##off("i")#ware Interface)
+ - Systemkern (EUMEL-0)
+ - darauf aufbauende Systemteile
+
+Das #on("b")##ib#SHard#ie##off("b")# ist der #on("u")#hardwareabhängige#off("u")# Teil des Betriebssystems. Dieser Teil ist ver­
+antwortlich für den Informationsfluß zwischen der virtuellen Maschine EUMEL-0 und
+den einzelnen Hardwarekomponenten (Tastatur, Diskettenlaufwerk, Schnittstellen,
+usw.).
+
+Der #on("b")#Systemkern#off("b")# (auch mit EUMEL-0 oder Urlader bezeichnet) ist der #on("u")#prozessorab­
+hängige#off("u")# Teil des Systems. Er bestimmt im wesentlichen die Leistung des Betriebssy­
+stems, da er als virtueller Prozessor den Befehlsumfang für den ELAN-Compiler
+definiert. Dieser Befehlsumfang wird dann auf den tatsächlichen Befehlsvorrat des
+hardwaremäßig vorhandenen Prozessors abgebildet.
+
+Die auf dem Kern (EUMEL-0) #on("b")#aufbauenden Systemteile#off("b")# sind #on("u")#hardware- und prozes­
+sorunabhängig#off("u")#. Sie beinhalten den ELAN-Compiler und alle Tasks, Texte, insertier­
+ten ELAN-Pakete, benannte und unbenannte Datenräume eines EUMEL-Systems.
+Diese Systemteile bilden zusammen mit dem Systemkern EUMEL-0 den #goalpage("v2")##on("b")#EUMEL-
+Hintergrund#off("b")#, d.h. EUMEL-0 ist Teil des #ib#EUMEL-Hintergrundes#ie#. Momentan werden
+je nach Rechnertyp Diskette und Festplatte als Hintergrundspeichermedium für
+EUMEL unterstützt.
+
+Der Begriff EUMEL-Hintergrund (HG) resultiert aus dem Konzept des virtuellen
+Speichers. Bei diesem Konzept wird der RAM-Speicherbereich der Hardware nur als
+Pufferbereich nach dem Demand-Paging-Verfahren benutzt, mit Ausnahme der
+residenten Systemteile (SHard und EUMEL-0). Das macht den Benutzer bezüglich
+seiner Programme und Daten unabhängig von der eigentlichen Größe des RAM-
+Speichers. Diese bestimmt lediglich den Durchsatz (Performance) des Systems, d.h. je
+größer der RAM-Bereich Ihres Rechners ist, desto schneller arbeitet das EUMEL-
+System.
+
+EUMEL-0 befindet sich auf der ersten Hintergrunddiskette. Das Laden von
+EUMEL-0 und des restlichen EUMEL-Hintergrundes kann daher in einem Arbeits­
+gang geschehen.
+
+Der Auslieferungs-Hintergrund ist noch nicht konfiguriert und stellt ausschließlich die
+im Handbuch beschriebenen Leistungen des Betriebssystems zur Verfügung. Er
+besteht im wesentlichen aus insertierten ELAN-Paketen, die den Leistungsumfang
+des Systems bestimmen (Single- oder Multiuser, mit oder ohne Textverarbeitung).
+Steht dieser Hintergrund auf mehreren Disketten (Multiuser-Hintergründe), dann sind
+diese fortlaufend numeriert. Die erste Hintergrunddiskette hat die Nummer 0, um
+daran zu erinnern, daß sich auf dieser Diskette auch der Systemkern EUMEL-0
+befindet.
+
+Ein Hintergrund kann natürlich auch die Systemsicherung eines größeren Systems mit
+z.B. mehreren Megabytes sein. Sollten Sie später einmal Ihr bestehendes System
+durch ein anderes ersetzen wollen (Hintergrund überschreiben), so brechen Sie wäh­
+rend des Hochfahrens beim Speichertest das System durch Tastendruck ab und laden
+durch Anwahl von 2 'neuen Hintergrund vom Archiv laden' im Startdialog das neue
+System.
+
+#on("i")##on("u")#ACHTUNG:#off("u")##off("i")# Dabei gehen alle Daten des alten Systems unwiederbringlich verloren!
+ (Siehe dazu auch 'Laden eines EUMEL-Hintergrundes'.)
+
+Zur besseren Verständlichkeit sollen an dieser Stelle noch die Begriffe 'Systemstart'
+und 'Systemabschaltung' des EUMEL-Systems erläutert werden :
+
+#on("i")##on("b")##ib#Systemstart#ie# :#off("b")##off("i")#
+Wenn ein EUMEL-System gestartet wird (auch 'Hochfahren' genannt), und dies gilt
+auch für kleinere Diskettensysteme wie den 'Generierungseumel' (siehe Seite #topage("v1")#),
+wird zunächst das SHard geladen; dazu erscheint auf dem Bildschirm eine entspre­
+chende Meldung. Das SHard versucht nun den Systemkern vom Archivmedium (in der
+Regel Diskette) zu laden. Ist keine entsprechende Diskette eingelegt, so wird ver­
+sucht, EUMEL-0 vom Hintergrundmedium (Festplatte) zu laden.
+
+Danach wird EUMEL-0 aktiv; auf dem Bildschirm erscheinen Angaben zu verfügba­
+ren Kanälen, RAM- und Hintergrundspeicher-Größe. Dann führt EUMEL-0 einen
+Speichertest durch, was daran zu erkennen ist, daß eine Folge von Sternchen (*) auf
+den Schirm geschrieben wird. Wird währenddessen eine beliebige Taste gedrückt,
+dann gelangt man nach dem Speichertest in den 'Startdialog'.
+
+Nach dem Speichertest bzw. nach Wahl von <1> 'Systemstart' im Startdialog wird der
+Hintergrund aktiviert, was je nach Größe des Systems und Art des Hintergrundmedi­
+ums unterschiedlich lange dauert.
+
+#on("i")##on("b")##ib#Systemabschaltung#ie# :#off("b")##off("i")#
+Bevor man den Rechner ausschaltet, sollte jedes EUMEL-System ordnungsgemäß
+abgeschaltet werden. Das geschieht durch den Befehl 'shutup', den man in der Multi­
+user-Version von EUMEL im privilegierten Zweig des Taskbaumes erteilen muß. Nur
+dann ist gewährleistet, daß der aktuelle Zustand Ihres Systems gesichert ist.
+
+Andernfalls gilt das System als abgebrochen, was daran zu erkennen ist, daß sich das
+System beim nächsten Systemstart mit 'RERUN' meldet. Dann kann nur am letzten
+Fixpunkt wieder aufgesetzt werden, und Ihre in letzter Zeit (normalerweise ca. 15
+Minuten) gesammelten Daten können verloren sein.
+
+Installation des EUMEL-Systems
+#free (1.0)#
+
+#goalpage("a1")#A: Erforderliche Disketten
+
+ - EUMEL-Systemdiskette : "Generierungseumel XY"#u#1)#e#
+ - EUMEL-Hintergrunddisketten : "HG0" ... "HGn"
+ - EUMEL-Archivdisketten : "std..."
+ - EUMEL-Archivdiskette : "XY" (Typabhängig)
+ - MS-DOS-Diskette : "EUMELstart"
+
+#foot#
+1) XY steht für die Typbezeichnung eines Rechners wie: XT, AT, M24 usw.
+ Die Anzahl der ausgelieferten Disketten ist auch typabhängig, da z.B.
+ 'EUMELstart' nur benötigt wird, falls tatsächlich eine Partitionierung möglich ist.
+#end#
+
+Die Diskette #goalpage("v1")##on("u")#"Generierungseumel XY"#off("u")# ist ein kleines, jedoch vollständiges EUMEL-
+System. Auf diesem System laufen nach dem Hochfahren Programme ab, die im
+Dialog mit dem Benutzer die Generierung einer oder mehrerer EUMEL-Partitionen
+ermöglichen, diese Bereiche bezüglich schlechter Spuren untersuchen und das SHard
+auf der jeweiligen Partition installieren. #on("b")#Bei der Generierung darf diese Diskette nicht
+schreibgeschützt sein !#off("b")#
+
+Die #on ("u")#Hintergrunddisketten "HG0" ... "HGn"#off ("u")# beinhalten das eigentliche Betriebssystem
+EUMEL. Es sind dies der Systemkern EUMEL-0 und die darauf aufbauenden Sy­
+stemteile (siehe Seite #topage("v2")#).
+
+Die #on ("u")#Standardarchivdisketten "std..."#off ("u")# beinhalten ELAN-Programmpakete und Fontta­
+bellen, die Sie nach erfolgter Installation des Betriebssytems z.B. zum Zwecke einer
+Druckerinstallation oder erweiterter Rechenfunktionen benötigen werden. Sie finden
+dazu detaillierte Informationen in Ihrem Benutzer- und Systemhandbuch.
+
+Die #on("u")#Archivdiskette "XY"#off ("u")# beinhaltet ELAN-Programmpakete, die Funktionen, die nicht
+zu den Standardleistungen von EUMEL bzw. der vorliegenden SHard-Version zählen.
+
+Die Diskette #on("u")#"EUMELstart"#off("u")# ist eine MS-DOS Diskette und beinhaltet Kommando-
+Dateien. Falls Sie auch eine MS-DOS Partition eingerichtet haben, dann gewährlei­
+sten diese das Aktivieren einer EUMEL Partition mit gleichzeitigem Systemstart von
+MS-DOS aus.
+#free (1.0)#
+
+#goalpage("a2")#B: Partitionieren der Festplatte / Installation des SHard
+
+
+Wenn Sie bereits ein Betriebssystem auf Ihrer Festplatte installiert haben, müssen Sie
+darauf achten, daß noch ausreichend Platz für ein EUMEL-System übrig ist. Da z.B.
+MS-DOS standardmäßig die gesamte Festplatte belegt, muß dieses System gesi­
+chert, mit dem MS-DOS-Kommando 'fdisk' gelöscht und entsprechend kleiner neu
+eingerichtet werden. Sie können auch bei der EUMEL-Installation alle bereits beste­
+henden Systeme löschen; dazu bietet Ihnen der Generierungseumel die Option
+#on("i")#Löschen der gesamten Partitionstabelle #off("i")# an. Dabei gehen jedoch alle bestehenden
+Daten verloren. Achten Sie also darauf, daß sie alle Daten vorher gesichert haben !
+
+#on("u")##on("i")#Hinweis:#off("i")##off("u")# Bei Festplatten mit einer Kapazität über 32 Megabyte kann die Installa­
+ tion des SHard zu Problemen führen (Fehlermeldung #on("i")#Platte kann nicht
+ gelesen werden#off("i")# bei der Suche nach schlechten Spuren). Richten Sie
+ daher Ihre EUMEL-Partition(en) auf den ersten 32 Megabyte ein.
+
+Um nun die Partitionierung für Ihr EUMEL-System vorzunehmen, legen Sie die
+Diskette 'Generierungseumel' in das Boot-Laufwerk. Sollte die Diskette mit einer
+Schreibschutzmarke versehen sein, dann müssen Sie diese vorher entfernen.
+
+Schalten Sie nun den Rechner ein bzw. betätigen Sie den Tastatur-RESET, wenn Ihr
+Gerät bereits eingeschaltet ist, indem Sie die Tasten <CTRL> <ALT> <DEL> gleichzeitig
+betätigen.
+
+Der Generierungseumel meldet sich zunächst mit folgender SHard-Meldung:
+
+
+
+____________________________________________________________________________
+
+Setup - SHard für EUMEL auf XY und Kompatiblen V x.x
+Copyright (C) 1985,86
+EUMEL wird vom Hintergrund geladen
+
+____________________________________________________________________________
+
+
+
+Danach erscheinen die EUMEL-0 Meldungen zu HG-, RAM- und Pufferkapazität,
+bezogen auf den Diskettenhintergrundes des Generierungseumel.
+
+#on("i")##on("u")#ACHTUNG:#off("u")##off("i")# Der Generierungseumel soll während des Speichertests (Sternchen)
+ nicht unterbrochen werden. Geschieht dies versehentlich doch, dann
+ fahren Sie fort, indem Sie im Startdialog die Taste <1> für Systemstart
+ betätigen. Dann wird normal mit der Installation fortgefahren. Wählen
+ Sie keinesfalls <2> 'neuen Hintergrund vom Archive laden', solange sich
+ die Diskette 'Generierungseumel' im Archivlaufwerk befindet.
+
+Nach dem Hochfahren des 'Generierungseumel' wird Ihnen eine Tabelle angezeigt,
+der Sie entnehmen können, ob bereits Partitionen auf der Festplatte eingerichtet und
+wie diese spezifiziert sind.
+
+Angezeigt werden neben Größe, Start- und Endspur der einzelnen Partitionen auch
+eine Typ-Nr.; für EUMEL-Partitionen werden in aufsteigender Reihenfolge die
+Typ-Nummern 69 bis 72, für MS-DOS je nach Größe der eingerichteten Partition
+die Nummer 1 oder 4 vergeben. Die Typ-Nummern der eingerichteten Partitionen
+sollten Sie sich merken, da diese Angaben später von Bedeutung sind, wenn das
+Gesamtsystem für Partitionswechsel vorbereitet wird. Richten Sie mehrere EUMEL-
+Partitionen ein, dann können Sie diese ausschließlich über die Typ-Nummern identi­
+fizieren !
+
+Außerdem wird die gerade aktive Partition durch einen entsprechenden Eintrag in der
+Tabelle kenntlich gemacht. #on("b")#"Aktiv" ist die Partition, die nach dem nächsten Einschal­
+ten des Rechners bzw. nach dem nächsten Tastatur-RESET gebootet würde.#off("b")#
+
+Sie können nun eine der folgenden Funktionen auswählen :
+
+ - Generieren einer EUMEL-Partition
+ - Aktivieren einer Partition
+ - Löschen einer EUMEL-Partition
+ - Löschen der gesamten Partitionstabelle
+ - Generierung beenden
+
+Beim Generieren einer EUMEL-Partition werden lediglich Angaben zu Größe und
+Startzylinder abgefragt. Dafür werden Vorgaben gemacht, die Sie bestätigen können,
+indem Sie die <CR> Taste betätigen.
+
+Beim Neueinrichten orientiert sich die Vorgabe für die Partitionsgröße an dem größten
+zusammenhängenden Freiraum auf Ihrer Platte, die Vorgabe für den Startzylinder
+orientiert sich dann an dem kleinsten zusammenhängenden Freiraum, auf dem eine
+Partition der gewählten Größe eingerichtet werden kann.
+
+#on("i")##on("u")#ACHTUNG:#off("u")##off("i")# Soll eine EUMEL-Version installiert werden, die nur 16 Megabyte
+ verwalten kann (1.7.3 bzw. 1.8.0), dann darf die Partition nicht größer
+ eingerichtet werden. Es kann hier keine generelle Aussage über die
+ Anzahl der zu reservierenden Spuren gemacht werden, da sehr ver­
+ schiedene Plattenaufteilungen angeboten werden. Entnehmen Sie die
+ entsprechenden Angaben bitte dem Festplatten-Handbuch Ihres Hard­
+ wareherstellers.
+
+Das Löschen einer EUMEL-Partition geschieht nur logisch, nicht physisch, das heißt
+es wird nur der Eintrag in der Partitionstabelle gelöscht. Sollten Sie später an gleicher
+Stelle eine neue Partition einrichten und vorher diesen Bereich physisch nicht über­
+schrieben haben, dann würde nach dem Hochfahren des Rechners das alte System
+wieder gestartet. Die Meldung 'kein EUMEL-System gefunden'(siehe unten) erscheint
+dann nicht.
+
+Haben Sie Ihre EUMEL-Partition(en) eingerichtet, dann achten Sie darauf, daß Sie
+Ihren Generierungseumel ordnungsgemäß wieder verlassen, da es sich hier, wie
+bereits erwähnt, um ein vollständiges EUMEL-System mit Fixpoint/Rerun-Logik
+handelt. Das 'shutup' wird automatisch ausgeführt, wenn Sie die Funktion '0. Gene­
+rierung beenden' wählen.
+
+Wenn die Meldung 'ENDE' auf Ihrem Bildschirm erscheint, ist dieser Schritt der
+Installation beendet. Sie haben nun eine (oder mehrere) EUMEL-Partitionen einge­
+richtet und das SHard installiert. Bitte entfernen Sie jetzt die Diskette 'Generierungs­
+eumel' aus dem Diskettenlaufwerk.
+#free (1.0)#
+Laden eines EUMEL-Hintergrundes
+
+#free(1.0)#
+Im nächsten Schritt wird auf Ihrer Festplatte das EUMEL-System installiert, d.h. es
+wird ein Hintergrund auf der Festplatte erzeugt.
+
+Dazu müssen Sie nach dem ordnungsgemäßen Beenden des Generierungseumel und
+Entfernen der Diskette aus dem Laufwerk den Tastatur-RESET betätigen. Dies
+geschieht entweder durch gleichzeitiges Betätigen der Tasten <CNTL> <ALT> <DEL>
+auf der Tastatur oder durch AUS- und wieder EIN-Schalten des Rechners (Bitte
+warten Sie einen Augenblick zwischen dem AUS- und EIN-Schalten).
+
+Das System meldet sich nach kurzer Zeit mit folgender SHard-Meldung:
+
+
+____________________________________________________________________________
+
+SHard für EUMEL auf XY, V x.x
+Copyright (C) 1985,86
+kein EUMEL-System gefunden
+
+____________________________________________________________________________
+
+
+
+Sie legen nun die Hintergrunddiskette HG0 in das Boot-Laufwerk und betätigen eine
+Taste.
+
+Der Systemkern wird nun geladen und es erscheinen die bereits oben erwähnten
+Angaben zu HG-, RAM- und Pufferkapazität, sowie zu den angeschlossenen
+Kanälen, diesmal jedoch bezogen auf die eingerichtete Festplatten-Partition. Wäh­
+rend des Speichertests drücken Sie bitte erneut eine Taste, um in den Startdialog zu
+gelangen und damit zu verhindern, daß EUMEL-0 versucht, das System zu starten.
+Sollten Sie dies versäumen, so erscheint die Meldung 'HG ungültig'. Sie haben dann
+erneut die Möglichkeit, durch Betätigen einer Taste in den Startdialog zu gelangen.
+
+Hier wählen Sie den Menupunkt <2> 'neuen Hintergrund vom Archiv laden' und bestä­
+tigen die Frage 'Alten Hintergrund überschreiben' mit <j> für 'ja'.
+
+Es erscheint ein Zähler auf dem Bildschirm, der die gelesenen Blöcke anzeigt. Verteilt
+sich Ihr Hintergrund auf mehrere Disketten, dann müssen Sie bei bei der Frage
+'Neues HG-Archiv eingelegt' die nächste Diskette einlegen und mit <j># #off("i")# quittieren.
+Bitte beachten Sie dabei genau die Numerierung der HG-Disketten !
+
+Es können bei beschädigten Disketten Lesefehler auftreten; dann gibt das System
+eine der Meldungen 'Harter Lesefehler' bzw. 'Softerror' aus. Bei letzterem konnte der
+entsprechende Sektor nach mehrmaligem Versuch noch gelesen werden. Bei einem
+harten Lesefehler können Sie die Diskette nicht verwenden.
+
+Wenn alle Disketten eingelesen sind, müssen Sie ein letztes mal den Tastatur-
+RESET betätigen, um das System zu starten. Vergessen Sie nicht, vorher die Hinter­
+grunddiskette aus dem Diskettenlaufwerk zu entfernen.
+
+Wenn Sie jetzt während des Hochfahrens keine Taste drücken, dann startet der Lader
+durch und das EUMEL-System meldet sich mit 'System aufgebaut'. Dies dauert
+beim Auslieferungshintergrund wenige Sekunden, kann jedoch bei größeren Systemsi­
+cherungen auch mehrere Minuten in Anspruch nehmen; verlieren Sie dann bitte nicht
+allzu schnell die Geduld.
+
+Da der Auslieferungs-Hintergrund unkonfiguriert ist, gelangt das System beim ersten
+Hochfahren nach der Installation sofort in den 'configurator'. Sie müssen jetzt den
+Kanal 1 entsprechend der vorhandenen Tastatur als "PC.german" oder "PC.ascii"
+konfigurieren. Sollten Sie eine EUMEL-Version 1.7.3 benutzen und diesen Konfigura­
+tionsdatenraum nicht zur Verfügung haben, dann konfigurieren Sie den Kanal 1 als
+"PC" und Terminal. Näheres dazu finden Sie im Systemhandbuch (Teil 1).
+#page#
+ Die einzelnen Schritte der Installation im Überblick
+#free (0.5)#
+#linefeed(1.5)#
+ 1. Die Diskette 'Generierungseumel' in das Laufwerk stecken
+ 2. Rechner einschalten oder Tastatur-RESET mit <CTRL>, <ALT> <DEL>
+ 3. EUMEL-Partition einrichten
+ 4. Generierung beenden und auf 'ENDE'-Meldung warten
+ 5. Diskette 'Generierungseumel' entnehmen
+ 6. Tastatur-RESET
+ 7. Die Meldung 'Kein EUMEL-System gefunden' abwarten. Wenn die Meldung
+ 'EUMEL wird vom Hintergrund geladen' erscheint, dann weiter bei 9.
+ 8. Erste Hintergrunddiskette (HG0) einlegen und Taste drücken
+ 9. Beim Speichertest eine Taste betätigen, um in den Startdialog zu gelangen.
+ 10. Menupunkt <2> anwählen : Neuen Hintergrund vom Archiv laden
+ 11. Eventuell weitere HG-Disketten nach entsprechender Aufforderung einlegen
+ und mit <j> quittieren
+ 12. Tastatur-RESET nach entsprechender Aufforderung
+ 13. Nach dem Hochfahren des Systems Konfiguration lt. Systemhandbuch
+ vornehmen
+ 14. Ggf. in der Task 'SYSUR' ELAN-Pakete für Partitionswechsel insertieren.
+ #linefeed (1.0)#
+ Dazu - Falls eine EUMEL-Version 1.7.3 benutzt wird, zunächst das
+ Kommando #on("i")#free global manager#off("i")# in der Task 'configurator' absetzen
+ - Archivdiskette "XY" einlegen und anmelden : #on("i")#archive �("XY")#off("i")#
+ - Datei "XY install" von Archivdiskette lesen :
+ #on("i")#fetch ("XY install", archive)#off("i")#
+ - Insertierung starten : #on("i")#run#off("i")#
+Druckersoftware einrichten
+
+#free(0.5)#
+Um mit Ihrem EUMEL-System einen Drucker betreiben zu können, müssen Sie
+außer dem Anschluß des Druckers mit einem passenden Kabel auch die passende
+Software für diesen Drucker zur Verfügung stellen. Zu diesem Zweck dienen die
+Druckeranpassungen.
+
+Das Standardarchive "std.printer" enthält Druckeranpassungen für die Ansteuerung
+diverser gebräuchlicher Druckertypen. Soll einer dieser Drucker an das EUMEL-
+System angeschlossen werden, so muß zuerst eine Task "#ib#PRINTER#ie#" als Sohntask
+von "SYSUR" mit dem Supervisorkommando
+
+#linefeed (1.18)#
+ begin ("PRINTER", "SYSUR")
+#linefeed (1.0)#
+
+eingerichtet werden. In dieser Task müssen dann die folgenden Schritte vollzogen
+werden:
+
+- Archiv anmelden:
+#linefeed (1.18)#
+ archive ("std.printer")
+#linefeed (1.0)#
+
+- Druckeranpassung vom Archiv holen:
+#linefeed (1.18)#
+ fetch ("printer.druckertyp", archive)
+#linefeed (1.0)#
+
+- Zeilennummergenerierung bei der Insertierung abschalten:
+#linefeed (1.18)#
+ check off
+#linefeed (1.0)#
+
+- Druckeranpassung insertieren:
+#linefeed (1.18)#
+ insert ("printer.druckertyp")
+#linefeed (1.0)#
+
+Beispiel:
+#linefeed (1.18)#
+ archive ("std.printer")
+ fetch ("printer.epson.fx", archive);
+ check off;
+ insert ("printer.epson.fx")
+#linefeed (1.0)#
+
+Nach der Insertierung wird zuerst nach dem #ib#Druckerkanal#ie# gefragt. Dieser sollte mit
+der Gerätetabelle 'transparent' konfiguriert sein. Dann werden ggf. druckerspezifische
+Fragen zur Papierbreite, Positionierungsart oder ähnlichem gestellt, die mit 'j' oder 'n'
+beantwortet werden müssen. Dabei werden alle Alternativantworten zu der jeweili­
+gen Frage hintereinander angeboten, bis eine Alternative mit 'j' beantwortet wird.
+
+Als letzter Schritt kommt die Aufforderung das Archiv mit der passenden Fonttabelle
+einzulegen. Diese Fonttabelle, eine Beschreibung aller darstellbaren Zeichen in allen
+druckbaren Schrifttypen, ist meistens auf derselben Diskette wie die Druckeranpas­
+sung.
+
+Wenn die Generierung beendet ist, muß im Multi-User Betrieb in allen bestehenden
+Tasks - insbesondere in der Task 'PUBLIC' - die Fonttabelle mit dem fonttable-
+Kommando eingestellt werden.
+
+Beispiel:
+
+#linefeed (1.18)#
+ fonttable("fonttab.epson.fx")
+#linefeed (1.0)#
+
+Von jeder Task aus kann danach mit dem Kommando
+
+#linefeed (1.18)#
+ print ("dateiname")
+#linefeed (1.0)#
+
+wird eine Datei ausgedruckt werden.
+
+Das Einstellene einer Fonttabelle ist insbesondere Voraussetzung für 'lineform', 'page­
+form' etc.
+
+Befindet sich keine passende Druckeranpassung für den anzuschließenden Drucker­
+typ auf dem Standardarchiv "std.printer", so sollte die Druckeranpassung "printer.std"
+benutzt werden. Diese Druckeranpassung ist eine universelle Druckeranpassung für
+alle Drucker, die mit ASCII-Code 13 ein 'Carriage Return' (d.h. Bewegung des
+Druckkopfes an den linken Rand) und mit ASCII-Code 10 eine Zeilenschaltung von
+1/6 Zoll vornehmen. Mit ihr kann dann in einem Schrifttyp (entweder 10 oder 12
+Zeichen pro Zoll, je nachdem welche Fonttabelle eingestellt ist) gedruckt werden. So
+erhält man wenigstens eine Minimalansteuerung des Druckers.
+
+
+
+Druckersoftware im Single-User einrichten
+
+
+Die Installation der Druckersoftware im Single-User erfolgt ähnlich wie die im Mul­
+ti-User. Hier brauchen nur die Schritte durchgeführt zu werden, die im Multi-User
+in der Task "PRINTER" druchgeführt werden müssen. Eine Task "PRINTER" braucht
+nicht eingerichtet zu werden.
+
diff --git a/doc/warenhaus/Anhang Warenhaus b/doc/warenhaus/Anhang Warenhaus
new file mode 100644
index 0000000..9388ceb
--- /dev/null
+++ b/doc/warenhaus/Anhang Warenhaus
@@ -0,0 +1,65 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (100)#
+#headodd#
+#center#gs-Warenhaus#right#%
+
+#end#
+#headeven#
+%#center#gs-Warenhaus
+
+#end#
+#center#1
+
+#center##on("b")##Anhang#off("b")#
+
+#on("b")##center#Muster für Codekarten#off("b")#
+
+ +-------------------+
+ | O O O O O O O O |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ----------------- |
+ +-------------------+
+
+
+
+ +--------------------+
+ | |
+ | O O O O |
+ | |
+ | |
+ |W A R E N K A R T E |
+ | |
+ | |
+ | Artikel |
+ | ---------------- |
+ | |
+ +--------------------+
+
+#page#
+
+
+ +------------------------+
+ | |
+ | O O O O O O |
+ | |
+ | K U N D E N K A R T E |
+ | |
+ | |
+ | Name |
+ | ---------------------- |
+ | |
+ | |
+ +------------------------+
+
+
+
+
+
+
diff --git a/doc/warenhaus/Inhalt Warenhaus b/doc/warenhaus/Inhalt Warenhaus
new file mode 100644
index 0000000..a9b720d
--- /dev/null
+++ b/doc/warenhaus/Inhalt Warenhaus
@@ -0,0 +1,50 @@
+#limit (11.5)##pagelength (16.5)##pageblock#
+#start (1.8,0.0)#
+Inhaltsverzeichnis
+
+
+1 Was kann gs-Warenhaus 1-1
+
+2 Aufbau von gs-Warenhaus 2-1
+
+3 Installation von gs-Warenhaus 3-1
+3.1 Voraussetzungen 3-1
+3.2 Lieferumfang 3-1
+3.3 Installation 3-2
+3.4 Einrichten mehrerer Hauptstellen 3-8
+
+4 Anschluß eines Codekartenlesers 4-1
+4.1 Hardware-Voraussetzungen 4-1
+4.2 Verwendung des MUFI 4-2
+4.2.1 Einstellungen am MUFI 4-3
+4.2.2 MUFI im Terminalkanal 4-5
+4.2.3 MUFI als Endgerät 4-6
+4.3 Verwendung des AKTRONIC-Adapters 4-7
+4.4 Konfiguration der seriellen Schnittstelle 4-8
+4.5 Verbindung der Hardware-Komponenten 4-10
+
+5 Beschreibung der Menufunktionen 5-1
+5.1 Kurzhinweise zur Bedienung des Menus 5-1
+5.2 Menufunktionen zum Oberbegriff 'Info' 5-4
+5.3 Menufunktionen zum Oberbegriff 'Eingabeart' 5-7
+5.4 Menufunktionen zum Oberbegriff 'Kommandos' 5-9
+5.5 Menufunktionen zum Oberbegriff 'Programme' 5-18
+5.6 Menufunktionen zum Oberbegriff 'Filialdaten' 5-24
+5.7 Menufunktionen zum Oberbegriff 'Archiv' 5-28
+
+6 Beschreibung der Programmierschnittstelle 6-1
+6.1 Schreibweisen und Syntaxregeln in GRIN-Programmen 6-4
+6.2 Kontrollstrukturen 6-8
+6.3 Detailbeschreibung der Warenhaus-Grundbefehle 6-13
+
+7 Weitere Kommandos (für Systembetreuer) 7-1
+
+Anhang: Muster für Codekarten
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus handbuch.impressum b/doc/warenhaus/gs-Warenhaus handbuch.impressum
new file mode 100644
index 0000000..3fbb371
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus handbuch.impressum
@@ -0,0 +1,89 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#gs-Warenhaus
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+
+#free (4.0)##on("b")#
+#center#gs-Warenhaus
+
+
+#center#Benutzerhandbuch
+
+
+#center#Version 1.0
+
+
+#off("b")##center#copyright
+#center#Eva Latta-Weber
+#center#Software- und Hardware-Systeme, 1988
+#center#ERGOS GmbH, 1990
+#page#
+#block#
+#center#____________________________________________________________________________
+
+
+Copyright:  ERGOS GmbH   März 1990
+
+ Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+ maschinenlesbare Form sowie das Speichern in Informations­
+ systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+ der ERGOS GmbH gestattet.
+
+
+#center#____________________________________________________________________________
+
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender.
+
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden.
+
+Texterstellung :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+ erstellt und aufbereitet und auf einem Kyocera Laser­
+ drucker gedruckt.
+
+
+
+
+#center#___________________________________________________________________________
+
+
+
+Ergonomic Office Software GmbH
+
+Bergstr. 7 Telefon: (02241) 63075
+5200 Siegburg Teletex: 2627-2241413=ERGOS
+ Telefax: (02241) 63078
+
+
+#center#____________________________________________________________________________
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-1 b/doc/warenhaus/gs-Warenhaus-1
new file mode 100644
index 0000000..ca79094
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-1
@@ -0,0 +1,124 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (3)#
+#headodd#
+#center#gs-warenhaus#right#%
+
+#end#
+#headeven#
+%#center#gs-warenhaus
+
+#end#
+#center#1  Was kann gs-Warenhaus
+
+
+Das Programmpaket #on("b")#gs-Warenhaus#off("b")# entstand auf der Grundlage der projekt­
+orientierten Unterrichtseinheit "WARENHAUS", die vom 'Landesinstitut für Schule
+und Weiterbildung' (LSW) in Soest für den Bereich der 'Informations- und
+kommunikationstechnologischen Grundbildung' (kurz: GRIN) entwickelt wurde.
+
+Unter #on("b")#1.1 Thema und Ziele #off("b")# ist in dem zugehörigen Begleitheft folgendes zu
+finden:
+
+#i1#"Die Schülerinnen und Schüler sollen in dieser Unterrichtseinheit die An­
+wendungen neuer Technologien im Warenhaus kennenlernen und dabei sowohl
+die grundlegenden technologischen Zusammenhänge erarbeiten als auch die
+Auswirkungen reflektieren, die sich durch ihren Einsatz ergeben. Sie werden
+dabei nicht nur die Rolle der Kunden einnehmen, sondern auch die Interessen
+der Angestellten und die der Geschäftsleitung in ihre Beurteilung mit einbe­
+ziehen.
+
+Diese komplexen Zusammenhänge werden den Schülerinnen und Schülern im 8.
+Schuljahr nähergebracht, indem sie veranlaßt werden, in einem Modell-Waren­
+haus selbst schrittweise das Modell eines Warenwirtschaftssystems aufzubauen
+und damit zu arbeiten.
+
+In diesem Modell-Warenhaus kommt dem Umgang mit dem Computer eine
+besondere Bedeutung zu. Mit Hilfe des Rechners, an den ein Codekartenleser
+angeschlossen ist, und des zugehörigen Programms werden die wesentlichen
+Bestandteile eines modernen Kassensystems abgebildet.
+
+Mit dem Codekartenleser kann das Merkmal des automatischen Dateneinlesens
+vereinfacht dargestellt werden. Programmabläufe, Bildschirmausgaben werden
+nicht nur über Tastatureingaben der Benutzer beeinflußt, sondern auch durch
+das Lesen verschlüsselter Informationen. Am Beispiel des Lesegerätes wird zum
+#page#
+einen der Rationalisierungseffekt an der Kasse verdeutlicht, es lassen sich zum
+anderen aber auch Fragen der Zugangsberechtigung durch maschinenlesbare
+Ausweiskarten ansprechen.
+
+Das zur Verfügung stehende Programm erlaubt es, daß die Schülerinnen und
+Schüler schrittweise die zentralen Funktionen eines modernen Warenwirtschafts­
+systems kennenlernen. Neben der maschinellen Datenerfassung mit Hilfe des
+Lesegeräts und der Decodierung von Informationen sind dies z.B.:
+
+- automatische Abrechnung,
+- Speicherung von Warendaten,
+- Kontrolle des Lagerbestandes,
+- Informationen über Verkaufszahlen,
+- automatische Nachbestellung,
+- Speicherung von Kundendaten,
+- Zusammenfassung von Informationen aus verschiedenen Filialen,
+- Erstellen von Übersichten.
+
+Die Schülerinnen und Schüler arbeiten dabei mit einer benutzerfreundlichen
+Programmierumgebung. Diese bietet einerseits die Möglichkeit, die Befehle direkt
+aufzurufen, mit denen alle Funktionen dieses vereinfachten Warenwirtschafts­
+systems ausgeführt werden können, wie etwa Dateien aufbauen, einkaufen und
+Listen erstellen. Andererseits stellt die Programmierumgebung weitere Befehle
+zur Verfügung, mit denen einige dieser Funktionen auch 'programmiert' werden
+können."#off("b")#
+
+Soweit zu Thema und Zielen dieser Unterrichtseinheit. Für weitere didaktisch-
+methodische Informationen zu dieser Reihe verweisen wir auf das entsprechende
+Begleitheft des LSW.
+(Vertrieb: Soester Verlagskontor, Jakobistraße 46, 4770 Soest; Bestellnummer 1710)
+#page#
+Da bei der Software-Entwicklung für GRIN vom LSW das Betriebssystem EUMEL nicht
+mit berücksichtigt wird, erscheint es notwendig, durch Eigeninitiativen wenigstens
+einige GRIN - Projekte unter EUMEL zur Verfügung zu stellen, um den Schulen, die
+mit EUMEL arbeiten, nicht gänzlich den Zugang zu GRIN zu verwehren.
+
+Das Projekt WARENHAUS bietet sich dabei besonders an, weil die Vernetzungen
+innerhalb eines Warenwirtschaftssystems mit einem Mehrplatz-System und der
+Möglichkeit der Intertask-Kommunikation wesentlich wirklichkeitsnäher aufzeigbar
+sind als mit einem reinen Einzelplatz-System wie z.B. MS DOS, bei dem die
+Kommunikation nur über den Transport von Disketten geregelt wird. (Ein Netzwerk
+ist in der Software der LSW nicht vorgesehen.)
+
+#on("b")#gs-Warenhaus#off("b")# umfaßt die wesentlichen Funktionen der vom LSW für MS DOS
+erstellten Programmierumgebung WARENHAUS-2. Es ist jedoch keine genaue 'Nach­
+bildung' dieser Software, sondern eher eine Realisierung des 'Vorbildes' unter
+Berücksichtigung der besonderen Gegebenheiten des EUMEL-Systems, wobei sowohl
+am äußeren Erscheinungsbild als auch inhaltlich Änderungen und Erweiterungen
+vorgenommen wurden. Eingebettet ist #on("b")#gs-Warenhaus#off("b")# in die menüorientierte
+Benutzerschnittstelle #on("b")#gs-DIALOG#off("b")#.
+
+Ein Codekartenleser kann in Verbindung mit einem Interface (z.B. dem MUFI der
+Firma BICOS) verwendet werden, ist für die Nutzung des Programmes aber nicht
+unbedingt erforderlich.
+
+Da zur Zeit der Entstehung dieses Programms GRIN an den Schulen noch nicht
+etabliert ist und man mit (vorerst) nur einem Projekt dem Ansatz von GRIN sicher
+nicht gerecht werden kann, ist #on("b")#gs-Warenhaus#off("b")# flexibel angelegt. Es enthält neben
+einer Programmierumgebung, in der die vom LSW für GRIN entwickelten Befehle und
+Syntaxregeln benutzt werden, eine weitere, in der in gewohnter ELAN-Syntax ge­
+arbeitet werden kann, so daß es z.B. ebenfalls für den Unterricht in Klasse 9/10 (für
+spezielle Fragestellungen evtl. auch in der Sek. II) verwendbar ist.
+#page#
+Natürlich ist #on("b")#gs-Warenhaus#off("b")# #i1#kein#off("b")# Verwaltungsprogramm für 'echte' Warenhäuser
+oder gar ganze Warenwirtschaftssysteme, es ist vielmehr ein Simulationsprogramm,
+das die Vorgänge in solch einem System anhand eines stark vereinfachten Modells
+klarmachen soll. Aus diesem Grunde werden Ihnen beim Umgang mit diesem Pro­
+gramm wahrscheinlich eine ganze Reihe von Erweiterungsmöglichkeiten und
+Funktionen einfallen, die das Programm nicht bietet. Denken Sie dabei bitte aber
+immer daran, daß #on("b")#gs-Warenhaus#off("b")# in erster Linie für den Einsatz in GRIN oder im
+WP-Unterricht konzipiert wurde, vornehmlich also von absoluten 'Anfängern' auf dem
+Gebiet des Umgangs mit Rechnern genutzt wird, die von einer zu großen Fülle von
+Programmfunktionen nur verwirrt würden.
+
+Wir werden Ihnen in den folgenden Kapiteln dieses Handbuchs den Umgang mit den
+Funktionsangeboten von #on("b")#gs-Warenhaus#off("b")# erklären, auf die Umsetzungsmöglichkeiten
+der am Anfang dieses Kapitels erwähnten Ziele im Unterricht gehen wir jedoch nicht
+ein. Beschaffen Sie sich dafür bitte das bereits oben angegebene Begleitheft des LSW.
+
diff --git a/doc/warenhaus/gs-Warenhaus-2 b/doc/warenhaus/gs-Warenhaus-2
new file mode 100644
index 0000000..f3f1284
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-2
@@ -0,0 +1,72 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (5)#
+#headodd#
+#center#gs-warenhaus#right#%
+
+#end#
+#headeven#
+%#center#gs-warenhaus
+
+#end#
+#center##on("b")#2  Aufbau von gs-Warenhaus#off("b")#
+
+#on("b")#gs-Warenhaus#off("b")# bietet die Möglichkeit, nicht nur #us#ein#use# Warenhaus, sondern eine
+Warenhaus-Kette im Modell nachzubilden. Solch eine Warenhauskette besteht hier
+stets aus einer #us#Hauptstelle#use# und einer oder mehrerer (bis zu 10) #us#Filialen#use#. Damit die
+Filialen auf die zentralen Daten der Warenhauskette zugreifen können, verfügt jede
+Hauptstelle über eine #us#Zentrale#use#, die jederzeit angerufen werden kann. Für die
+Kommunikation untereinander gehört zu jeder Filiale eine (Filial-) #us#Verwaltung#use#, bei
+der die aktuellen Filialdaten erfragt werden können.
+
+
+Realisiert wird dieser Aufbau durch verschiedene Tasks und der Möglichkeit der
+Intertask-Kommunikation. Unter einer Task, in der #on("b")#gs-Warenhaus#off("b")# insertiert ist,
+können eine oder mehrere Tasks als Hauptstellen angemeldet werden (siehe '3.3
+Installation' und '7 Weitere Kommandos'). So kann man z.B. für verschiedene
+Klassen gleichzeitig Warenhausketten einrichten. Zu beachten ist, daß verschiedene
+Ketten untereinander völlig unabhängig sind und dadurch #us#nicht#use# miteinander
+kommunizieren können.
+
+
+Jede Hauptstellen-Task richtet sich automatisch eine Sohn-Task als Zentrale ein.
+Werden nun Sohn-Tasks einer Hauptstellen-Task angemeldet, so werden diese zu
+Filialen der entsprechenden Hauptstelle, wobei ihnen automatisch eine Filialnummer
+zugeteilt wird, die identisch ist mit der Kanalnummer des benutzten Terminals.
+(Steht keine Mehrplatzanlage zur Verfügung, so läßt sich nur #us#eine#use# Filiale einrichten;
+die Filialnummer ist dann in der Regel 1.)
+
+
+Die Filial-Tasks ihrerseits legen beim Starten von #on("b")#gs-Warenhaus#off("b")# automatisch jeweils
+eine Sohn-Task als (Filial-) Verwaltung an.
+#page#
+Insgesamt ergibt sich folgender schematischer Aufbau (die Pfeile zeigen die
+Kommunikationsmöglichkeiten an):
+
+
+#on("b")#
+ W A R E N H A U S
+ / | \
+ Hauptstelle A Hauptstelle B Hauptstelle C . . .
+
+ / | \
+Zentrale A Filiale A1 Filiale A2 . . .
+ ^
+ |
+ | Verwaltg.A1 Verwaltg.A2 . . .
+ | ^ ^
+ | | |
+ --------------------------- . . .
+#off("b")#
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-3 b/doc/warenhaus/gs-Warenhaus-3
new file mode 100644
index 0000000..ffef881
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-3
@@ -0,0 +1,309 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (7)#
+#headodd#
+#center#gs-Warenhaus#right#%
+
+#end#
+#headeven#
+%#center#gs-Warenhaus
+
+#end#
+#center#1
+
+#center##on("b")#3  Installation von gs-Warenhaus#off("b")#
+
+
+Bevor Sie #on("b")#gs-Warenhaus#off("b")# auf Ihrem Computer benutzen können, müssen Sie das
+Programm zunächst installieren. Wenn #on("b")#gs-Warenhaus#off("b")# auf Ihrem System schon zur
+Verfügung steht, können Sie dieses Kapitel ruhig überspringen.
+
+
+
+#on("b")#3.1  Voraussetzungen#off("b")#
+
+Um #on("b")#gs-Warenhaus#off("b")# auf Ihrem Computer betreiben zu können, muß das EUMEL-
+Betriebssystem installiert sein. #on("b")#gs-Warenhaus#off("b")# setzt die Multi-User-Version voraus
+und ist lauffähig ab Version 1.8.0. #on("b")#gs-Warenhaus#off("b")# setzt weiterhin voraus, daß auf
+Ihrem Computer bereits das Programm #on("b")#gs-DIALOG#off("b")# (ab Version 1.1) installiert ist.
+
+
+
+#on("b")#3.2  Lieferumfang#off("b")#
+
+#on("b")#gs-Warenhaus#off("b")# wird auf einer Diskette geliefert, die alle notwendigen Programme
+enthält (die Installation von #on("b")#gs-DIALOG#off("b")# wird dabei vorausgesetzt!). Um den Inhalt
+der Diskette feststellen zu können, starten Sie Ihr System und bringen es dazu, daß
+'gib kommando:' erscheint. Dann legen Sie die Diskette ein und geben das
+Kommando:
+
+
+#on("b")#archive("gs-Warenhaus"); list(archive); release(archive) <RETURN>#off("b")#
+#page#
+Anschließend erscheint eine Übersicht der auf dem Archiv vorhandenen Programme.
+Folgende Dateinamen sollten sich in der Übersicht befinden:
+
+ "gs-MENUKARTE:Warenhaus"
+ "gs-Warenhaus 0: ohne Kartenleser"
+ "gs-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter"
+ "gs-Warenhaus 0: mit Kartenleser an MUFI als Endgerät"
+ "gs-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal"
+ "--------------------------------------------"
+ "gs-Warenhaus 1"
+ "gs-Warenhaus 2"
+ "gs-Warenhaus 3"
+ "gs-Warenhaus 4"
+ "gs-Warenhaus 5"
+ "gs-Warenhaus/gen"
+
+Eventuell können noch weitere Namen auf der Diskette vorhanden sein. Wenn Sie den
+Inhalt der Diskette kontrolliert haben und diese Dateien auf der Diskette vorhanden
+sind, können Sie #on("b")#gs-Warenhaus#off("b")# installieren.
+
+Sollten Sie statt der Übersicht eine Fehlermeldung erhalten, überprüfen Sie bitte, ob
+die Diskette das richtige Format besitzt oder ob Ihr Diskettenlaufwerk Probleme
+macht. Sollten dagegen Programme fehlen, so reklamieren Sie die Diskette.
+
+
+
+#on("b")#3.3  Installation#off("b")#
+
+#on("b")#gs-Warenhaus#off("b")# muß in einer Task installiert werden, in der bereits das Programm
+#on("b")#gs-DIALOG#off("b")# zur Verfügung steht. Alle Söhne und Enkel der neuen Task können
+anschließend das Warenhaus-Modell aufrufen. Richten Sie also eine Task als Sohn
+#page#
+der Task ein, in der auf Ihrem Computer bereits #on("b")#gs-DIALOG#off("b")# installiert ist. Wir
+nehmen hier an, daß #on("b")#gs-DIALOG#off("b")# in der Task 'MENU' installiert ist und die neue
+Task den Namen 'WARENHAUS' erhalten soll. (Sie können für die Task auch einen
+beliebigen anderen Namen wählen):
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+
+#off("b")#
+ --> gib supervisor kommando:
+#on("b")#
+ begin ("WARENHAUS","MENU") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+
+(Arbeiten mehrere Personen mit dem Computer, dann ist es sinnvoll, diese Task vor
+unbefugtem Zugriff durch ein Passwort zu schützen. Wie das gemacht wird, können
+Sie in Ihrem EUMEL-Benutzerhandbuch erfahren.)
+
+Legen Sie dann die Archivdiskette ein, auf der sich #on("b")#gs-Warenhaus#off("b")# befindet, und
+geben Sie die folgenden Kommandos:
+
+#on("b")#
+ archive ("gs-Warenhaus") <RETURN>
+
+ fetch (ALL archive, archive) <RETURN>
+
+ release (archive) <RETURN>
+
+ run ("gs-Warenhaus/gen") <RETURN>
+#off("b")#
+
+Sie haben damit das Installationsprogramm gestartet und können die Diskette wieder
+aus dem Laufwerk nehmen. (Natürlich können Sie die Dateien auch mit Hilfe von
+#on("b")#gs-DIALOG#off("b")# von der Diskette holen. Achten Sie dann bitte darauf, daß sie #on("b")#alle#off("b")# oben
+angegebenen Dateien von der Diskette in Ihre Task holen).
+#page#
+Zunächst werden Sie nun aufgefordert, eine Interface-Anpassung für den Codekarten­
+leser auszuwählen. Dazu erscheint das folgende Menu auf dem Bildschirm:
+
++----------------------------------------------------------------------+
+|center#Auswahl einer Interface-Anpassung für den Codekartenleser |
+|center#Wenn kein Kartenleser benutzt wird, <ESC><q> tippen! |
+| |
+| Auswahl  e i n e r  Datei durch Ankreuzen |
+| |
+| ==> � gs-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter |
+| � gs-Warenhaus 0: mit Kartenleser an MUFI als Endgerät |
+| � gs-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal |
+| |
+| |
+| |
+| |
+| Info: <?> Fertig: <ESC><q> Abbrechen: <ESC><h> |
+| |
++-----------------------------------------------------------------------
+Soll kein Kartenleser benutzt werden, tippen Sie einfach <ESC><q>. Sonst fahren
+Sie den Pfeil mit den Cursor-Tasten in die gewünschte Zeile und drücken
+<RETURN>. Welche der angegebenen Anpassung für welchen Zweck die geeignete
+ist, wird in Kapitel 4 ("Anschluß eines Codekartenlesers") genauer beschrieben.
+
+Daraufhin wird die Installation automatisch durchgeführt. Haben Sie die Anpassung
+für den 'AKTRONIC-Adapter' oder für das 'MUFI als Endgerät' ausgewält, so erscheint
+nach der Insertierung dieser Datei die Aufforderung
+
+#center##on("b")#Gib Interface-Kanal:#off("b")#
+
+Hier muß angegeben werden, an welchen Kanal (serielle Schnittstelle) das Interface
+angeschlossen werden soll (vgl. wiederum Kapitel 4). Der Interface-Kanal läßt sich
+auch später noch umstellen (vgl. Kapitel 7).
+
+Wenn der Insertierungs-Vorgang abgeschlossen ist, müssen Sie noch einige Fragen
+beantworten:
+
+#on("b")#Frage 1:#off("b")# #on("b")#Version für GRIN (j/n)?#off("b")#
+
+Tippen Sie hier ein <j>, so werden später in der Programmierumgebung die
+'Soester' Befehle und Syntax-Regeln benutzt, ein <n> liefert die Programmier­
+umgebung für ELAN. Die Versions-Einstellung kann auch noch später geändert
+werden (vgl. Kapitel 7, Befehl 'grin').
+
+#on("b")#Frage 2:#off("b")# #on("b")#Soll diese Task Warenhaus-Hauptstelle sein (j/n)?#off("b")#
+
+Das Tippen von <j> macht Ihre momentan benutzte Task zur (einzigen!) Waren­
+haus-Hauptstelle; Sie können dann (nach Beantwortung mindestens einer weiteren
+Frage, s.u.) in Söhnen dieser Task das Warenhaus-Programm starten. Allerdings ist es
+dann nicht mehr möglich, Sohntasks dieser Task zu Hauptstellen zu machen!
+
+Möchten Sie aber mehrere Hauptstellen (evtl. für verschiedene Lerngruppen) ein­
+richten, so müssen Sie hier ein <n> tippen. In diesem Fall ist die Installation
+zunächst beendet und es erscheint der EUMEL-Eingangsbildschirm. Was Sie dann
+noch tun müssen, erfahren Sie in Kapitel 3.4; die folgenden Ausführungen können
+Sie überschlagen.
+
+#on("b")#Frage 3:#off("b")# #on("b")#Mit Direktstart (j/n)?#off("b")#
+
+Wenn Sie vor dem Benutzer die 'gib kommando:'-Ebene verbergen wollen, können
+Sie das System durch Tippen eines <j> so einstellen, daß sich sofort nach Ein­
+richten einer Sohntask das Menusystem meldet. Für den Anfänger kann das die
+Arbeit durchaus erleichtern. Wenn Sie das nicht möchten, tippen Sie hier ein <n>.
+Haben Sie die Frage mit <j> beantwortet, so erscheint noch eine (letzte) Abfrage:
+
+#on("b")#Frage 4:#off("b")# #on("b")#Mit automatischem Löschen (j/n)?#off("b")#
+
+Durch Tippen eines <j> legen Sie fest, daß in den Sohntasks nach Verlassen des
+Menus die jeweilige Task automatisch gelöscht wird. Tippen Sie ein <n>, dann wird
+nach Verlassen des Menus angefragt, ob die Task gelöscht werden soll. Wird die Frage
+bejaht, wird gelöscht - sonst wird die Task abgekoppelt (break) und kann durch
+'continue' wieder angekoppelt werden.
+
+#on("b")#Anmerkung:#off("b")# In Tasks, in denen Sie die Frage nach dem Direktstart mit <j> beant­
+wortet haben, sollte nicht das Kommando 'monitor' gegeben werden, da Sie durch
+dieses Kommando auch diese Task zu einer Task machen, die sich direkt mit dem
+Menu meldet und ggf. bei Verlassen des Menus automatisch gelöscht wird!
+
+
+Nachdem der EUMEL-Eingangsbildschirm zu sehen ist, können Sie nun #on("b")#gs-Waren­
+haus#off("b")# starten. Nehmen wir an, die Task 'WARENHAUS' sei Hauptstellen-Task. Sie ist
+damit automatisch Managertask, Sie können also Sohntasks anmelden:
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+
+#off("b")#
+ --> gib supervisor kommando:
+#on("b")#
+ begin ("Test","WARENHAUS") <RETURN>
+#off("b")#
+
+Statt 'Test' können Sie der Sohntask natürlich auch einen beliebigen anderen Namen
+geben. Wenn Sie einen Direktstart eingerichtet haben, erscheint nun sofort das
+#on("b")#gs-DIALOG#off("b")#-Emblem.
+
+ +------------------------+
+ | gs-DIALOG |
+ +---------------------------+ |
+ | Version 1.1 | |
+ +-----------------------------+ | |
+ | (C) 1987/88 Eva Latta Weber | | |
+ +-------------------------------+ | |-----+
+ | (C) 1988 ERGOS GmbH | | |
+ | | |---+
+ +------------------------------+ | |
+ | gggggggg ssssssss | |-------+
+ | ggg sss sss | |
+ | ggg sss | --------+
+ | ggg gggg ssssssss |
+ | ggg ggg sss |
+ | ggg ggg sss |
+ | gggggggggg sssssssss |
+ +------------------------------+
+
+ W A R E N H A U S
+
+ Filiale 1
+#off("b")#
+Andernfalls erscheint
+
+#on("b")#
+ gib kommando:
+#off("b")#
+
+Mit dem Kommando
+
+ #on("b")#warenhaus <RETURN>#off("b")#
+
+starten Sie #on("b")#gs-Warenhaus#off("b")# und erhalten zunächst ebenfalls das obige Emblem auf
+dem Bildschirm. Links unten sehen Sie, unter welcher Filialnummer diese Task nun
+von #on("b")#gs-Warenhaus#off("b")# geführt wird. Diese Nummer ist identisch mit der Kanalnummer,
+unter der das EUMEL-System Ihren Arbeitsplatz verwaltet.
+
+Kurze Zeit später erscheint das WARENHAUS-Eingangsmenu. Wie Sie nun weiter mit
+#on("b")#gs-Warenhaus#off("b")# arbeiten können, erfahren Sie in Kapitel 5.
+
+
+
+#on("b")#3.4  Einrichten mehrerer Hauptstellen#off("b")#
+
+Wir gehen hier davon aus, daß Sie die Installation von #on("b")#gs-Warenhaus#off("b")# gemäß den
+Beschreibungen in Kapitel 3.3 bereits durchgeführt und dabei die Frage 2 ("Soll diese
+Task Warenhaus-Hauptstelle sein (j/n)?") mit 'nein' beantwortet haben. (Falls Sie
+Frage 2 mit 'ja' beantwortet haben und nun den Hauptstellen-Status der Task wieder
+rückgängig machen wollen, so lesen Sie zunächst in Kapitel 7 nach.)
+
+Die Task, in der die Installation stattfand (wir nehmen weiterhin an, daß sie den
+Namen 'WARENHAUS' hat), wurde automatisch zur Managertask, das heißt, daß
+Söhne von ihr eingerichtet werden können. Bevor Sie in diesem Fall das Programm
+nutzen können, müssen Sie nun noch mindestens eine Sohntask zur Hauptstelle
+machen. Gehen Sie dabei folgendermaßen vor:
+
+#on("b")#
+ <SV> (Supervisor - Taste)
+
+#off("b")#
+ --> gib supervisor kommando:
+#on("b")#
+ begin ("Hauptstelle A","WARENHAUS") <RETURN>
+#off("b")#
+
+ --> gib kommando:
+
+
+Mit dem Kommando
+
+#center##on("b")#warenhaus hauptstelle (TRUE) <RETURN>#off("b")#
+
+wird die Task 'Hauptstelle A' zur Warenhaus-Hauptstelle.
+
+Zu beantworten sind dabei eine oder zwei Fragen; es sind dieselben, die auftauchen,
+wenn bei der Abfrage 'Soll diese Task Warenhaus-Hauptstelle sein (j/n)?' ein <j>
+getippt wird. Lesen Sie deshalb nun weiter in Kapitel 3.3 bei der Frage 3: 'Mit Direkt­
+start (j/n)?'.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-4 b/doc/warenhaus/gs-Warenhaus-4
new file mode 100644
index 0000000..2c5d7dc
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-4
@@ -0,0 +1,378 @@
+limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (11)#
+#headodd#
+#center#gs-Warenhaus#right#%
+
+#end#
+#headeven#
+%#center#gs-Warenhaus
+
+#end#
+#center#1
+
+#center# #on("b")#4  Anschluß eines Codekartenlesers#off("b")#
+
+
+Ein 'echter' Scanner oder Barcodeleser ist als automatisches Lesegerät für den Ein­
+satz im Unterricht nicht geeignet und kann unter EUMEL/ELAN unseres Wissens nach
+auch nicht angesteuert werden. #on("b")#gs-Warenhaus#off("b")# benutzt stattdessen (ebenso wie die
+Soester Software) den von der Firma AKTRONIC vertriebenen Codekartenleser für
+einfache 8-Bit-Lochkarten (siehe Anhang).
+
+Die Verwendung eines Codekartenlesers ist für die Bedienung des Programms zwar
+nicht unbedingt notwendig, bietet jedoch beim Einsatz von #on("b")#gs-Warenhaus#off("b")# im Unter­
+richt neben den didaktischen Hintergründen (Modell für Scanner-Kasse) auch noch
+mancherlei Vorteile bezüglich des "Datenschutzes" (Änderungen an Kunden- oder
+Artikeldaten sowie Zugriffe auf Auskunftsfunktionen nur mit entsprechender Code­
+karte möglich), so daß sein Anschluß sehr empfohlen werden muß.
+
+Allerdings ist solch ein Gerät nur mittels eines (relativ teuren) Interface-Systems
+anschließbar, dessen Anschaffung sich nur lohnt, wenn das System auch sonst noch
+zum Messen, Steuern, Regeln (= "Prozeßdatenverarbeitung", "PDV") im Unterricht
+genutzt wird. (#on("b")#ERGOS#off("b")# bietet mit #on("b")#"gs-Prozess"#off("b")# auch ein Programmpaket zur PDV
+unter EUMEL/ELAN an!)
+
+
+
+#on("b")#4.1  Hardware-Voraussetzungen#off("b")#
+
+Der Codekartenleser wird an einen Steckplatz des Interface-Systems MODUL-BUS der
+Firma AKTRONIC angeschlossen, wobei ein Einzel- oder Mehrfachsteckplatz mit
+Kombi- oder E/A-Karte oder eine Compact-Box benutzt werden können.
+
+Da Eingaben von externen Geräten unter EUMEL in der Regel nur über eine serielle
+Schnittstelle möglich sind, benötigt man neben dem Kartenleser und dem MODUL-
+#page#
+BUS-Steckplatz noch einen 'Adapter', der die parallelen Signale des MODUL-BUS-
+Systems in serielle Signale wandelt, die der Computer über eine serielle Schnittstelle
+(auch RS232- oder V24-Schnittstelle genannt) empfangen kann. Für erfahrene
+Elektronik-Bastler ist das Erstellen solch eines Adapters sicher eine lösbare Aufgabe,
+unter den fix und fertig kaufbaren Geräten haben wir allerdings nur zwei geeignete
+gefunden: das 'Multifunktionale Interface' (kurz: MUFI) der Firma BICOS und den
+'RS232-Adapter für das MODUL-BUS-System' der Firma AKTRONIC. Diese beiden
+Geräte werden auch von #on("b")#gs-Warenhaus#off("b")# unterstützt.
+
+Die erforderliche Hardware-Konstellation stellt sich im Überblick also folgender­
+maßen dar:
+
+#on("b")#
+ Computer <----> Adapter <----> Interface <----> Kartenleser
+
+ (mit se- ('MUFI' ('MODUL-
+ rieller oder BUS'-
+ Schnitt- 'AKTRONIC- Steck-
+ stelle) Adapter') platz)
+#off("b")#
+
+
+#on("b")#4.2  Verwendung des MUFI#off("b")#
+
+Das MUFI ist speziell für die Arbeit in einem Mehrplatz-System entwickelt worden. Es
+benötigt keine zusätzliche serielle Schnittstelle am Rechner, sondern kann einfach
+zwischen Rechner und Terminal 'in den Terminalkanal gesteckt' werden, sodaß man
+von diesem Terminal aus optimal auf das Interface-System zugreifen kann. Im Ideal­
+fall sollte jeder Arbeitsplatz mit der oben genannten Hardware ausgestattet sein, was
+aber momentan sicher nicht für jede Schule finanzierbar ist. Haben Sie zunächst nur
+ein (oder wenige) MUFI(s) zur Verfügung und möchten von verschiedenen Terminals
+(abwechselnd) auf ein Interface-System zugreifen oder verfügen Sie gar nicht über
+ein Terminal, sondern nur über einen Monitor (z.B. bei IBM-Kompatiblen), so
+können Sie das MUFI auch 'als Endgerät' an einer separaten seriellen Schnittstelle
+nutzen.
+#page#
+Für den Betrieb in einem Terminalkanal sollte das MUFI über eine sog. "Schnitt­
+stellen-Automatik" verfügen, die verhindert, daß das MUFI in ausgeschaltetem
+Zustand oder mit abgezogenem Netzstecker den Datenfluß vom Rechner zum
+Terminal unterbricht. Diese sehr sinnvolle Automatik wird von BICOS #on("b")#nicht#off("b")#
+standardmäßig eingebaut. Sie sollten bei eventuellen Bestellungen darauf achten.
+
+
+#on("b")#4.2.1  Einstellungen am MUFI#off("b")#
+
+Gleichgültig ob Sie das MUFI 'im Terminalkanal' oder 'als Endgerät' benutzen,
+müssen Sie zunächst am MUFI einige Einstellungen per DIP-Schalter im Inneren des
+MUFI vornehmen. Ziehen Sie dazu aber auf alle Fälle den Stecker aus der Steckdose!
+Lösen Sie dann die 4 Schrauben an der Unterseite des Gehäuses, heben das Oberteil
+vorsichtig ab und legen es neben das Unterteil, sodaß die Kabelverbindungen
+zwischen Unter- und Oberteil nicht belastet werden.
+
+ +---------------------------------------------------+
+ | +-------+ +------------+ |
+ | | | | | +---------+ |
+ | +-------+ | | | DIP- | |
+ | +-------+ | | | Schalter| |
+Rück- | | | | | +---------+ | Vorder-
+seite | +-------+ | | +--------------+ | seite
+ | +-------+ | SCN68000 | | | |
+ | | | | | +--------------+ |
+ | +-------+ | | |
+ | +-------+ | | |
+ | | | | | |
+ | +-------+ +------------+ |
+ +---------------------------------------------------+
+
+
+
+#center#Abb.1: MUFI geöffnet
+#page#
+Die kleine Plastikbox mit den DIP-Schaltern trägt die folgende Aufschrift:
+
+#center##on("b")#O N  
+#center#1 2 3 4#off("b")#
+
+Heben Sie den Deckel mit Hilfe eines kleinen Schraubendrehers o.ä. an der rechten
+Seite leicht an und klappen Sie ihn nach links um. Sie können nun die 4 DIP-
+Schalter sehen.
+
+ +---------------------------------------+
+ | +-----+ +-----+ +-----+ +-----+ |
+ | |+++++| | | | | | | |
+ | |+++++| | | | | | | | ON
+ | |+++++| | | | | | | |
+ | |+++++| | | | | | | |
+ | | | | | | | | | |
+ | | | | | | | | | |
+ | | | | | | | | | |
+ | | | |+++++| |+++++| |+++++| |
+ | | | |+++++| |+++++| |+++++| |
+ | | | |+++++| |+++++| |+++++| | OFF
+ | | | |+++++| |+++++| |+++++| |
+ | +-----+ +-----+ +-----+ +-----+ |
+ +---------------------------------------+
+
+ 1 2 3 4
+
+#center#Abb.2: Mögliche DIP-Schalter-Stellung beim MUFI
+
+ Dabei haben die DIP-Schalter folgende Bedeutung:
+
+ 1 ON : Modulbusbetrieb
+ OFF : Parallelportbetrieb
+ 2 ON : RTS/CTS-Hardware-Handshake
+ OFF : XON/XOFF-Protokoll
+ 3 ON : 9600 Baud
+ OFF : 19200 Baud
+ 4 ON : Even Parity
+ OFF : No Parity
+
+In jedem Fall muß der DIP-Schalter 1 in Stellung #on("b")#ON#off("b")# gebracht werden.
+#page#
+Wenn Sie das MUFI im Terminalkanal betreiben wollen, müssen Sie die anderen
+Einstellungen so vornehmen, daß sie zu der Konfiguration des Terminals passen (vgl.
+auch Kapitel 4.4). Beträgt die Übertragungsrate 19200 Baud, so sollten Sie unbedingt
+mit dem XON/XOFF-Protokoll arbeiten - es sei denn, das Terminal unterstützt
+RTS/CTS! Wenn Sie das MUFI an einer separaten seriellen Schnittstelle als Endgerät
+betreiben wollen, #on("b")#muß#off("b")# der Datenaustausch mit dem RTS/CTS-Protokoll abgewickelt
+werden (Schalter 2 auf 'ON'!). Vergewissern Sie sich, daß Ihr Schnittstellen-Kabel
+auch darauf ausgelegt ist! Nach dieser Einstellung der DIP-Schalter ist das MUFI
+betriebsbereit. Fügen Sie die beiden Gehäuseteile wieder zusammen und ver­
+schrauben Sie sie wieder.
+
+
+#on("b")#4.2.2  MUFI im Terminalkanal#off("b")#
+
+Um das MUFI in den Terminalkanal einbauen zu können, müssen Sie zunächst am
+Terminal die Zuleitung vom Rechner lösen. Auf der Rückseite des MUFIs befinden
+sich zwei Stecker, die mit V24/1 und V24/2 bezeichnet sind. Stecken Sie an Stecker
+V24/2 das Kabel, das ursprünglich vom Computer zum Terminal führte. Sie
+benötigen jetzt noch ein weiteres (kurzes) V24-Kabel, um das MUFI mit dem
+Terminal zu verbinden. Dieses wird einerseits auf Stecker V24/1 am MUFI gesteckt
+und andererseits auf den Stecker am Terminal, von dem Sie das ursprüngliche Kabel
+zwischen Rechner und Terminal abgezogen haben.
+
+ +--------------------------+
+ | +----------------------+ |
+ | | V24/1 V24/2 | |
+ | | | | | |
+ | +----|-----------|-----+ |
+ +------|-----------|-------+
+ | |
+ | |
+ ZUM <-----+ +-----> ZUM
+ TERMINAL COMPUTER
+
+
+#center#Abb.3: Einbau des MUFIs in den Terminalkanal
+#page#
+Die Verschaltung der V24-Kabel ist in der Bedienungsanleitung zum MUFI erläutert,
+ggf. können Sie entsprechende Kabel von der Firma BICOS beziehen.
+
+Wenn alle Kabelverbindungen gesteckt sind, sollten Sie auf alle Fälle erst einmal #on("b")#bei
+ausgeschaltetem MUFI#off("b")# prüfen, ob das Terminal sich noch bedienen läßt. Wenn dieses
+keine Reaktion mehr zeigt, obwohl es vorher (ohne MUFI) reibungslos funktioniert
+hat, dann haben Sie entweder ein MUFI ohne "Schnittstellen-Automatik" vor sich
+(vgl. Kapitel 4.2, Seite 15), oder an den Kabelverbindungen stimmt irgendetwas nicht.
+In diesem Fall sollten Sie noch einmal alle Anschlüsse und evtl. auch die interne
+Verschaltung der Kabel überprüfen.
+
+Schalten Sie dann das MUFI ein. Bei ebenfalls eingeschaltetem Terminal können nun
+einige Zeichen auf dem Bildschirm erscheinen, dieser Effekt ist normal. Funktioniert
+Ihr Terminal bei eingeschaltetem MUFI reibungslos, so sind alle Einstellungen richtig
+und Sie brauchen erst bei Kapitel 4.5 weiterzulesen. Andernfalls studieren Sie Kapitel
+4.4 unter Beachtung von Kapitel 4.2.1!
+
+
+#on("b")#4.2.3  MUFI als Endgerät#off("b")#
+
+Wenn Sie das MUFI als Endgerät an einer separaten seriellen Schnittstelle betreiben
+wollen, dann stecken Sie das vom Computer kommende Kabel auf den mit V24/2
+bezeichneten Stecker des MUFI.
+
+Damit ein einwandfreier Betrieb gewährleistet ist, sollten Sie einen sog. 'Kurzschluß­
+stecker' auf den dann freien Stecker V24/1 des MUFIs stecken. Haben Sie einen
+solchen nicht zur Hand, können Sie auch zwei provisorische Drahtbrücken einsetzen:
+Verbinden Sie mit zwei kleinen Drähten einmal Pin (Öffnung) 2 mit Pin 3 und
+außerdem Pin 4 mit Pin 5.
+
+Die Anpassung 'gs-Warenhaus 0: mit Kartenleser an MUFI als Endgerät' unterstützt
+standardmäßig nur den Betrieb von #on("b")#einem#off("b")# MUFI als Endgerät. Wie Sie vorgehen
+müssen, wenn Sie mehrere MUFIs in dieser Betriebsart benutzen wollen, erfahren Sie
+in Kapitel 7.
+#page#
+#on("b")#4.3  Verwendung des AKTRONIC-Adapters#off("b")#
+
+Im Gegensatz zum MUFI ist der AKTRONIC-Adapter #on("b")#nicht#off("b")# für den Einbau in einen
+Terminalkanal geeignet, sondern kann nur als Endgerät an einer separaten seriellen
+Schnittstelle betrieben werden. Bevor Sie den Adapter an eine serielle Schnittstelle an­
+schließen, sollten Sie noch die eingestellte Baud-Rate überprüfen und gegebenenfalls
+neu einstellen.
+
+Öffnen Sie dazu das Gehäuse des Adapters, indem Sie die vier Schrauben an der
+Unterseite lösen. Drehen Sie den Adapter so vor sich, daß die 25-polige D-Sub­
+miniaturbuchse von Ihnen weg zeigt. Vorn rechts sind dann zwei parallele 8-polige
+Pfostensteckerleisten sichtbar.
+
+#center#25-pol. D-Subminiatur-Stecker
+
+ +---------------+
+ | |
+ +---+ +---+
+ | +------+ |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | +------+ |
+ | +------+ |
+ | | | +-------+ |
+ | +------+ | | |
+ | +------+ +-------+ |
+ | | | +-------+ |
+ | +------+ | <-|---------Jumperleiste
+ | +-------+ |
+ +---+ +---+
+ | Baudrate |
+ +---------------+
+
+
+#center#Abb.4: AKTRONIC-Adapter geöffmet
+#page#
+Auf einem Pfostensteckerpaar steckt ein 'Jumper', der gegebenenfalls (passend zu
+der Schnittstellen-Konfiguration im Computer, vgl. Kapitel 4.4) umgesteckt werden
+muß.
+
+ +---------+
+ | ζ ζ | 300
+ | ζ ζ | 600
+ | ζ ζ | 1200
+ | ζ ζ | 2400
+ | ζ ζ | 4800
+ | ζ ζ | 9600
+ Jumper > | ζ ζ | 19200
+ | ζ ζ | 38400
+ +---------+
+ Baudrate
+
+
+#center#Abb.5: Mögliche Jumperposition beim AKTRONIC-Adapter
+
+
+Am Adapter ist ein Kabel mit 25-poligem D-Subminiaturstecker bereits fest montiert.
+Sollte der Stecker nicht an Ihren Rechner passen, so müßten Sie ein entsprechendes
+Adapterkabel basteln oder kaufen.
+
+Die Anpassung 'gs-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter' unterstützt
+standardmäßig nur den Betrieb von #on("b")#einem#off("b")# Adapter. Wie Sie vorgehen müssen, wenn
+Sie mehrere dieser Adapter benutzen wollen, erfahren Sie in Kapitel 7.
+
+
+#on("b")#4.4  Konfiguration der seriellen Schnittstelle#off("b")#
+
+Sie müssen nun noch dafür Sorge tragen, daß die Einstellungen am MUFI bzw. am
+AKTRONIC-Adapter mit den Einstellungen im Computer übereinstimmen.
+#page#
+Koppeln Sie dazu die Task 'configurator' an Ihr Terminal an (mit 'continue
+("configurator") <RETURN>') und geben Sie dann das Kommando 'configurate
+<RETURN>'. Für alle vorhandenen Kanäle werden Sie nun nacheinander gefragt,
+ob Sie eine Konfiguration vornehmen wollen. Bei den "interessanten" Kanälen ant­
+worten Sie mit 'ja' (<j>). Wollen Sie sich nur die aktuelle Konfiguration ansehen, so
+beantworten Sie alle weiterhin gestellten Fragen zu diesem Kanal mit 'ja' (<j>),
+dann bleibt die aktuelle Einstellung erhalten. (Der Konfigurationsdialog ist im
+EUMEL-Systemhandbuch auf den Seiten 6 - 8 detailliert beschrieben.)
+
+Benutzen Sie ein MUFI, so müssen auf alle Fälle #on("b")#8 Datenbits#off("b")# und #on("b")#1 Stopbit#off("b")# einge­
+stellt sein und außerdem je nach DIP-Schalter-Stellung im MUFI (vgl. Kapitel 4.2.1)
+9600 oder 19200 Baud sowie 'no parity' oder 'even parity'.
+
+Benutzen Sie das MUFI im Terminalkanal, so müssen Sie bei einer eventuellen
+Änderung der Konfiguration an diesen Stellen auch das entsprechende Terminal auf
+diese Werte einstellen!
+
+Bei der Verwendung des MUFIs als Endgerät muß der Kanal, an den das MUFI ange­
+schlossen wird, darüberhinaus unbedingt auf die Betriebsarten
+
+#center#transparent und RTS/CTS-Protokoll
+
+eingestellt werden.
+
+Verwenden Sie einen AKTRONIC-Adapter, so müssen für den entsprechenden Kanal
+folgende Konfigurationsmerkmale eingestellt werden:
+
+#center#transparent, 8 Bit, 2 Stopbit, #on("b")#kein#off("b")# Protokoll
+
+Die Baud-Rate ist gemäß der Jumper-Position im Adapter (vgl. Kapitel 4.3) einzu­
+stellen.
+
+
+
+#on("b")#4.5  Verbindung der Hardware-Komponenten#off("b")#
+
+Der Anschluß des Kartenlesers an den MODUL-BUS-Steckplatz ist denkbar einfach:
+Stecken Sie den 8-poligen Platinenstecker des Codekartenlesers in die Buchse des
+Digital-Einganges der Steckkarte bzw. Compact-Box und den 3-poligen Platinen­
+stecker in die passende Spannungsversorgungsbuchse (12 V) am Steckplatz bzw. auf
+der Compact-Box, fertig. Bei eingeschalteter Betriebsspannung muß nun der Code­
+kartenleser beleuchtet sein. (Falls Sie einen Mehrfachsteckplatz benutzen, benötigen
+Sie ein passendes Netzteil für diesen Steckplatz! Achten Sie auch darauf, daß in
+diesem Fall die Kombi- oder E/A-Karte in Steckplatz (Slot) 1 installiert ist.)
+
+Nun müssen Sie noch die Verbindung zu dem verwendeten Adapter herstellen. Dabei
+ist es gleichgültig, ob Sie eine Compact-Box, einen Einzel- oder einen Mehrfachsteck­
+platz benutzen, denn alle diese Geräte verfügen über ein Anschlußkabel mit dem
+gleichen 25-poligen Stecker.
+
+Den AKTRONIC-Adapter können Sie damit direkt an den Steckplatz anschließen,
+denn er verfügt bereits über eine entsprechende 25-polige Buchse. Hier müssen Sie
+dann nur noch die Stromversorgung des Adapters sichern, indem Sie das Kabel mit
+dem 3-poligen Platinenstecker in die passende Spannungsversorgungsbuchse (12 V)
+am Steckplatz oder auf der Compact-Box stecken. (Damit Codekartenleser und
+Adapter hier gleichzeitig versorgt werden können, ist in den Stecker eine Verzweigung
+eingebaut.)
+
+Für das MUFI benötigen Sie ein weiteres Kabel, das an einem Ende einen 36-poligen
+Centronics-Stecker besitzt und an dem anderen einen 25-poligen D-Subminiatur­
+stecker (von der Firma BICOS zu beziehen).
+
+Zum Ausprobieren des Kartenlesers benutzen Sie am besten die Menupunkte
+'Dezimalwert lesen' und 'Bitmuster lesen' unter dem Oberbegriff 'Kommandos' des
+Warenhaus-Menus. Eine Beschreibung dieser Punkte finden Sie in Kapitel 5.4.
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-5 b/doc/warenhaus/gs-Warenhaus-5
new file mode 100644
index 0000000..c1164ad
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-5
@@ -0,0 +1,1468 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (20)#
+#headodd#
+#center#gs-Warenhaus#right#%
+
+#end#
+#headeven#
+%#center#gs-Warenhaus
+
+#end#
+#center#1
+
+#center##on("b")#5  Beschreibung der Menufunktionen#off("b")#
+
+
+Nach Aufruf meldet sich #on("b")#gs-Warenhaus#off("b")# zunächst mit dem #on("b")#gs-DIALOG#off("b")#-Emblem
+(vgl. Kapitel 3.3). Kurze Zeit später erscheint das WARENHAUS-Eingangsmenu auf
+dem Bildschirm:
+
+ +------------------------------------------------------------------------+
+ | WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv|
+ |------------------------------------------------------------------------|
+ | | b  Befehlsvorrat | |
+ | | ------------------ | |
+ | | a  Artikeldaten | |
+ | | k  Kundendaten | |
+ | +--------------------+ |
+ | |
+ | |
+ | |
+ |------------------------------------------------------------------------+
+ | |
+ | Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
+ +------------------------------------------------------------------------+
+
+#off("b")#
+
+
+Bevor wir Ihnen die Bedeutung der einzelnen Menu-Punkte erklären, geben wir erst
+noch einige grundsätzliche Hinweise zur Bedienung des Menus für diejenigen Leser,
+die im Umgang mit Menus unter #on("b")#gs-DIALOG#off("b")# nicht geübt sind.
+
+
+
+#on("b")#5.1  Kurzhinweise zur Bedienung des Menus#off("b")#
+
+Die Bedienung des Menus ist sehr einfach. Eine ausführliche Beschreibung dazu
+finden Sie in den Unterlagen zum Programmsystem #on("b")#gs-DIALOG#off("b")#. An dieser Stelle
+sollen nur die wesentlichen Bedienungsvorgänge beschrieben werden.
+#page#
+- Mit der Tastenfolge <ESC><?> können Sie sich Informationen zur Bedienung
+ des Menusystems in das Menu einblenden lassen
+
+- Mit den Pfeiltasten <rechts> und <links> können Sie zwischen den "Ober­
+ begriffen" in der Kopfzeile wählen. Der aktuelle Oberbegriff ist jeweils invers
+ dargestellt. Das ausgeklappte 'Pull-Down-Menu' bezieht sich auf diesen invers
+ dargestellten Oberbegriff.
+
+- Mit den Pfeiltasten <hoch> und <runter> können Sie zwischen den Menu­
+ funktionen wählen, die Ihnen im aktuellen Pull-Down-Menu zur Auswahl ange­
+ boten werden. Die aktuell angewählte Menufunktion wird jeweils invers darge­
+ stellt. Die Trennlinien, die in einigen Pull-Down-Menus sichtbar sind, dienen nur
+ der optischen Untergliederung; sie können nicht angewählt werden und werden
+ deshalb automatisch übersprungen. Die einzelnen Menupunkte sind "zyklisch
+ miteinander verknüpft", das heißt, man gelangt vom untersten Menupunkt
+ wieder zum obersten und umgekehrt. Menupunkte, vor denen ein Minuszeichen
+ steht ('-'), sind (zur Zeit) nicht aktivierbar; auch sie können nicht angewählt
+ werden und werden einfach übersprungen.
+
+- Durch Tippen der Fragezeichentaste (<?>) können Sie sich jeweils zur
+ aktuellen Menufunktion (invers im Pull-Down-Menu) Informationen in das Menu
+ einblenden lassen.
+
+- Um eine Menufunktion ausführen zu lassen, bewegen Sie sich mit den Pfeiltasten
+ auf die gewünschte Menufunktion im aktuellen Pull-Down-Menu und tippen
+ dann die <RETURN>-Taste. Steht vor dem gewünschten Menupunkt ein
+ einzelner Buchstabe oder eine Ziffer, so kann durch Tippen der entsprechenden
+ Taste diese Menufunktion dadurch direkt aufgerufen werden. Sobald eine Menu­
+ funktion aufgerufen worden ist, erscheint davor ein Stern ('*'). Daraus können
+ Sie entnehmen, daß das System bereits den Auftrag ausführt.
+
+- An verschiedenen Stellen werden Fragen an Sie gerichtet, die Sie mit 'ja' oder
+ 'nein' beantworten müssen. Tippen Sie dazu entsprechend der Entscheidung die
+ Taste <j> (für 'ja') bzw. <n> (für 'nein').
+
+- Werden Ihnen vom Menu aus Dateinamen zur Auswahl angeboten, so können Sie
+ den auf dem Bildschirm sichtbaren Pfeil vor den gewünschten Namen
+#page#
+ positionieren. Mit den Tasten <x> oder <RETURN> können Sie den Namen
+ ankreuzen. Ist die Auswahl mehrerer Dateinamen möglich, so können Sie den
+ Vorgang wiederholen. Mit den Tasten <o> oder <RUBOUT> können Sie auch
+ ein Kreuz vor einem Namen wieder löschen. Daneben gibt es noch einige Tasten­
+ funktionen, die für die Bedienung recht hilfreich sein können. Tippen Sie
+ während der Auswahl die Fragezeichentaste (<?>), so werden Ihnen alle
+ Bedienungsmöglichkeiten auf dem Bildschirm angezeigt. Eine Auswahl, in der
+ mehrere Dateien angekreuzt werden dürfen, wird durch die Tastenfolge
+ <ESC><q> verlassen. Anschließend wird die eingestellte Operation mit den
+ angekreuzten Dateien ausgeführt. Sind Sie versehentlich in eine solche Auswahl
+ gelangt, so können Sie den Vorgang durch die Tastenkombination <ESC><h>
+ abbrechen.
+
+- An einigen Stellen werden Sie aufgefordert, eine Eingabe zu machen (z.B. einen
+ Dateinamen einzugeben). Wird Ihnen hier ein Vorschlag gemacht, den Sie
+ akzeptieren, so brauchen Sie zur Bestätigung nur die <RETURN>-Taste zu
+ tippen. Gefällt Ihnen der Vorschlag nicht oder wird Ihnen kein Vorschlag
+ gemacht, so machen Sie bitte die gewünschte Eingabe. Zum Schreiben stehen
+ Ihnen alle aus dem Editor bekannten Funktionen zur Verfügung. Mit der Taste
+ <RUBOUT> können Sie Buchstaben löschen, mit <RUBIN> einfügen. Die
+ Eingabe wird durch Tippen der <RETURN>-Taste abgeschlossen. Ist der von
+ Ihnen gewünschte Name schon in Ihrer Task vorhanden und steht in der Fußzeile
+ der Hinweis 'Zeigen: <ESC><z>', dann können Sie sich auch alle vor­
+ handenen Namen zur Auswahl anbieten lassen und durch Ankreuzen den beab­
+ sichtigten Namen auswählen.
+
+- Ihnen können auch mehrere Alternativen angeboten werden, zwischen denen Sie
+ wählen müssen. In der untersten Zeile eines solchen Kastens, in denen Ihnen die
+ Alternativen auf dem Bildschirm eingeblendet werden, sind die Möglichkeiten
+ aufgeführt, die darüber beschrieben sind. Mit den Pfeiltasten können sie die
+ Markierung auf die gewünschte Alternative positionieren und dann durch die
+ <RETURN>-Taste zur Ausführung bringen. (Manchmal ist das auch durch
+ Tippen der den Alternativen vorangestellten Buchstaben oder Ziffern möglich).
+#page#
+- Durch die Tastenfolge <ESC><q> kann das Menu insgesamt verlassen
+ werden. Damit das nicht versehentlich geschieht, wird jeweils die Frage gestellt,
+ ob Sie das Menu tatsächlich verlassen wollen. Diese Frage beantworten Sie bitte je
+ nach Wunsch mit 'ja' oder 'nein' durch Tippen der Tasten <j> bzw. <n>.
+
+
+#on("b")#5.2  Menufunktionen zum Oberbegriff 'Info'#off("b")#
+
+Das auf dem Bildschirm sichtbare Pull-Down-Menu ist bereits oben abgebildet.
+
+#on("b")#b Befehlsvorrat#off("b")#
+
+ Mit dieser Funktion können Sie sich die Befehle, die Ihnen von der jeweils
+ eingestellten Programmierumgebung zur Verfügung gestellt werden, auf dem
+ Bildschirm anzeigen lassen. Anhand dieser Informationen können Sie auch
+ feststellen, ob in dem System, das Ihnen zur Verfügung steht, die 'GRIN-
+ Version' oder die 'ELAN-Version' eingestellt ist.
+
+ Je nach Version gelangen Sie zunächst in eines der folgenden beiden Auswahl­
+ menus:
+#on("b")#
+ GRIN-Version:
+
+
+ +-------------------------------------------------+
+ | d   Datei - Bearbeitung |
+ | e   Einkaufen und Auskunft |
+ | k   Kontroll - Strukturen |
+ | |
+ | z   Zurück zum Hauptmenü |
+ | |
+ | Datei   Kaufen/Auskunft   Kontroll   Zurück |
+ | |
+ +-------------------------------------------------+
+#off("b")#
+#page#
+#on("b")#
+ ELAN-Version:
+
+ +-------------------------------------------------+
+ | d   Datei - Bearbeitung |
+ | e   Einkaufen und Auskunft |
+ | s   Sonstige Befehle |
+ | |
+ | z   Zurück zum Hauptmenü |
+ | |
+ | Datei   Kaufen/Auskunft   Sonstige   Zurück |
+ | |
+ +-------------------------------------------------+
+
+#off("b")#
+
+ Von hier aus können Sie zu jedem dort angegebenen Bereich eine Informa­
+ tionstafel abrufen.
+
+ Aus jeder dieser Tafeln gelangen Sie wieder in die Auswahl zurück. Verlassen
+ Sie die Auswahl selbst, gelangen Sie zurück ins Ausgangsmenu.
+
+
+#on("b")#a Artikeldaten#off("b")#
+
+ Bei Aktivierung dieses Menupunktes erhalten Sie eine Kurzinformation über
+ Aufbau und Umfang der Artikeldaten:
+#on("b")#
+ +-------------------------------------------------------+
+ | Ein Satz 'Artikeldaten' besteht aus: |
+ | |
+ | Artikelname |
+ | Preis |
+ | Mindestbestand |
+ | Bestand |
+ | |
+ | Es können Daten für maximal 15 Artikel gespeichert |
+ | werden. Die zugehörigen Artikelnummern sind 1...15. |
+ | |
+ +-------------------------------------------------------+
+
+
+#off("b")#
+
+ In allen Filialen müssen zu einer Artikelnummer stets der Artikelname und
+ Preis identisch sein, Bestand und Mindestbestand können beliebig gewählt
+ werden. Artikeldateien werden nur in den jeweiligen Filialen gehalten und
+ nicht in der Zentrale.
+#page#
+ Gegenüber der Soester Warenhaus-Version sind Artikeldaten um den Punkt
+ 'Mindestbestand' erweitert worden, weil sich damit unserer Meinung nach eine
+ realistischere Nachbestellung realisieren läßt (vgl. auch Kapitel 5.4, 'Nachbe­
+ stellen').
+
+ Sollte Ihnen der Umfang des Warensortiments mit maximal 15 verschiedenen
+ Artikeln sehr gering vorkommen, so denken Sie bitte daran, daß die Artikel­
+ daten an jedem Arbeitsplatz erst einmal eingegeben werden müssen, was bei
+ Computer-Anfängern recht lange dauert. Außerdem kommt es nur bei einem
+ genügend kleinen Sortiment zu den methodisch-didaktisch erwünschten
+ Einkaufshäufungen bei bestimmten Produkten.
+
+
+#on("b")#k Kundendaten#off("b")#
+
+ Bei Aktivierung dieses Menupunktes erhalten Sie eine Kurzinformation über
+ Aufbau und Umfang der Kundendaten:
+#on("b")#
+ +----------------------------------------------------------+
+ | Nachname |
+ | Vorname |
+ | Geschlecht |
+ | |
+ | Es können Daten für maxomal 31 Kunden gespeichert |
+ | werden. Die zugehörigen Kundennummern sind 129...159. |
+ | |
+ +----------------------------------------------------------+
+#off("b")#
+
+ Die Zuordnung Kundennummer ---> Kunde muß in allen Filialen gleich sein.
+ Kundendateien werden von jeder Filiale und von der Zentrale geführt.
+
+ Gegenüber der Soester Warenhaus-Version sind Kundendaten um die Punkte
+ 'Nachname' und 'Geschlecht' erweitert worden, um dem Begriff Kunden#on("b")#daten#off("b")#
+ etwas gerechter zu werden. Die maximale Kundenanzahl von 31 entspricht
+ etwa der Größe einer Klasse.
+#page#
+#on("b")#5.3  Menufunktionen zum Oberbegriff 'Eingabeart'#off("b")#
+
+Die Funktionen unter diesem Oberbegriff sind nur dann für Sie interessant, wenn Sie
+einen Codekartenleser verwenden.
+#on("b")#
++-------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|-------------+-----------------+-----------------------------------------|
+| | *  Anzeigen | |
+| | --------------- | |
+| | k  Kartenleser | |
+| | t  Tastatur | |
+| +-----------------+ |
+| |
+| |
+| +------------------------+ |
+| | Die Eingabeart ist auf | |
+| | | |
+| | Tastatur | |
+| | | |
+| | eingestellt | |
+| +------------------------+ |
+|-------------------------------------------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++-------------------------------------------------------------------------+
+#off("b")#
+
+#on("b")#a Anzeigen#off("b")#
+
+ Es wird die momentan eingestellte Eingabeart angezeigt. Möglich sind die
+ Eingabearten #on("b")#Tastatur#off("b")# und #on("b")#Kartenleser#off("b")#. Die Standardeinstellung ist
+ 'Tastatur'!
+
+
+#on("b")#k Kartenleser#off("b")#
+
+ Die Eingabeart 'Kartenleser' wird eingestellt. Alle Artikelnummern, Kunden­
+ nummern und sonstige Codenummern (für Auskünfte) können danach nur
+ über den Kartenleser eingegeben werden.
+#page#
+ Diese Eingabeart kann nur eingestellt werden, wenn ein Kartenleser mit
+ funktionstüchtigem Interface angeschlossen ist. Sonst erfolgt eine ent­
+ sprechende Fehlermeldung.
+
+ Fehlerfälle:
+
+ - Kein Interface vorhanden!
+ Ursache: Bei der Installation von #on("b")#gs-Warenhaus#off("b")# wurde angegeben, daß
+ kein Kartenleser benutzt werden soll.
+
+ - Interface meldet sich nicht!
+ Abhilfe: Überprüfen, ob der Adapter ordnungsgemäß angeschlossen und
+ eingeschaltet ist (vgl. Kapitel 4). Notfalls Eingabeart auf
+ 'Tastatur' schalten; wenn ein MUFI verwendet wird, MUFI aus-
+ und nach kleiner Pause wieder einschalten; noch einmal die
+ Eingabe 'Kartenleser' anwählen.
+
+ - TASK für Interface ist besetzt!
+ (Kann nur beim Betrieb von MUFI als Endgerät oder bei AKTRONIC-Adapter
+ auftreten.)
+ Abhilfe: Wenn irgendeine andere Task die Eingabeart 'Kartenleser' ein­
+ gestellt hat, dort auf 'Tastatur' umstellen.
+
+ - Interface-Kanal belegt!
+ (Kann nur beim Betrieb von MUFI als Endgerät oder bei AKTRONIC-Adapter
+ auftreten.)
+ Abhilfe: Feststellen, welche Task an den Interface-Kanal angekoppelt ist
+ ('taskinfo (2)'), und diese dann abmelden ('break' oder 'end').
+ Die Nummer des Interface-Kanals kann mit dem Befehl 'put
+ (interfacekanal)' erfragt werden.
+
+ - TASK für Interface existiert nicht!
+ (Kann nur beim Betrieb von MUFI als Endgerät oder bei AKTRONIC-Adapter
+ auftreten.)
+ Abhilfe: Task löschen; in der Vatertask das Kommando 'init interface­
+ channel' geben; Task neu anmelden.
+#page#
+#on("b")#t Tastatur#off("b")#
+
+ Die Eingabeart 'Tastatur' wird eingestellt. Alle Artikelnummern, Kunden­
+ nummern und sonstige Codenummern (für Auskünfte) können danach nur
+ über die Tastatur eingegeben werden. Ein etwa angeschlossener Codekarten­
+ leser ist bei dieser Einstellung nicht mehr ansprechbar.
+
+
+
+#on("b")#5.4  Menufunktionen zum Oberbegriff 'Kommandos'#off("b")#
+
+Dieses ist das zentrale Menu für den Benutzer von #on("b")#gs-Warenhaus#off("b")#. Unter diesem
+Oberbegriff finden Sie alle Funktionen, die notwendig sind, um die Abläufe innerhalb
+des Modell-Warenhauses zu simulieren. (Die angebotenen Menufunktionen ent­
+sprechen etwa den "Direktbefehlen" der Soester Software.)
+#on("b")#
++-------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|---------------------+-------------------------------+-------------------|
+| | w   Warendatei bearbeiten | |
+| | k   Kundendatei bearbeiten | |
+| | -------------------------- | |
+| | e   Einkaufen | |
+| | -------------------------- | |
+| | a   Auskunft einholen | |
+| | n   Nachbestellen | |
+| | -------------------------- | |
+| | -   Dezimalwert lesen | |
+| | -   Bitmuster lesen | |
+| +-------------------------------+ |
+| |
+|-------------------------------------------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>|
++-------------------------------------------------------------------------+
+#off("b")#
+
+Wird im Unterricht kein Kartenleser benutzt, so sind die eingegeben Daten völlig
+ungeschützt. Vor allem bei der Kundendatei muß sichergestellt werden, daß dort
+#page#
+keine unsinnigen Eintragungen oder Änderungen vorgenommen werden, da alle
+Neueintragungen und Änderungen in dieser Datei auch in der Warenhaus-Zentrale
+wirksam werden und von dort aus auf Anfrage jeder Filiale mitgeteilt werden.
+Korrekturen können dadurch sehr mühsam werden. Natürlich sind ohne Kartenleser
+(und dem damit verbundenen 'Ausweis' Codekarte) auch jederzeit Einkäufe mit jeder
+beliebigen Kundennummer möglich. Auch hier sollten Sie etwaigem Mißbrauch
+vorbeugen.
+
+
+#on("b")#w Warendatei bearbeiten#off("b")#
+
+ Hiermit kann die Warendatei der Filiale aufgebaut und verändert werden. Der
+ Bildschirm sieht dabei wie folgt aus:
+#on("b")#
++------------------------------------------------------------------------+
+|WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|-----------------------------------+------------------------------------|
+| | Artikelnummer : 1 |
+| | |
+| | |
+| | Artikelname : Bier (Kasten)|
+| | |
+| | Preis : 16.85 |
+| | |
+| | Mindestbestand : 25 |
+| | |
+| | Bestand : 20 |
+| | |
+| | |
+| | Alles richtig ? |
+| | |
+| | Ja    Nein |
+|-----------------------------------+------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++------------------------------------------------------------------------+
+#off("b")#
+
+ Zunächst muß eine Artikelnummer (1...15) eingegeben werden (je nach
+ Einstellung über die Tastatur oder mittels einer Warenkarte über den Code­
+ kartenleser). Unzulässige Artikelnummern werden dabei nicht akzeptiert.
+#page#
+ Ist unter dieser Nummer bereits ein Artikel gespeichert, so werden die ent­
+ sprechenden Artikeldaten in dem rechten oberen Bildschirmfenster gezeigt
+ und können dort geändert oder einfach übernommen werden. Gibt es noch
+ keinen Artikel mit dieser Nummer, so sind neue Artikeldaten einzugeben.
+
+ Dieser Vorgang wird solange wiederholt, bis bei der Eingabe der Artikelnummer
+ die Tastenfolge <ESC><q> gedrückt wird.
+
+ Achten Sie darauf, daß in jeder Filiale der zu einer Artikelnummer gehörige
+ Artikel stets denselben Artikelnamen und -preis erhält. Bestand und Mindest­
+ bestand können unterschiedlich sein.
+
+
+#on("b")#k Kundendatei bearbeiten#off("b")#
+
+ Hiermit kann die Kundendatei der Filiale aufgebaut und verändert werden.
+ Ähnlich wie bei der Funktion 'Warendatei bearbeiten' erfolgen die Eingaben im
+ rechten oberen Bildschirmfenster.
+
+ Zunächst muß eine Kundennummer (129...159) eingegeben werden (je nach
+ Einstellung über die Tastatur oder mittels einer Kundenkarte über den Code­
+ kartenleser). Unzulässige Kundennummern werden dabei nicht akzeptiert.
+
+ Ist unter dieser Nummer bereits ein Kunde in der Filiale oder in der Zentrale
+ gespeichert, so werden die entsprechenden Kundendaten in dem rechten
+ oberen Bildschirmfenster gezeigt und können dort geändert oder einfach über­
+ nommen werden. Gibt es noch keinen Kunden mit dieser Nummer, so sind
+ neue Kundendaten einzugeben. (Neueingaben und Änderungen werden sofort
+ der Zentrale, aber nicht automatisch den andern Filialen mitgeteilt!)
+
+ Dieser Vorgang wird solange wiederholt, bis bei der Eingabe der Kunden­
+ nummer die Tastenfolge <ESC><q> gedrückt wird.
+#page#
+#on("b")#e Einkaufen#off("b")#
+
+ Zunächst wird eine Kundennummer (129...159) erfragt. Wird die Nummer
+ eines Kunden eingegeben, dessen Daten in der Filiale oder Zentrale bereits
+ gespeichert sind, so erscheint im linken Bildschirmfenster der Rechnungskopf
+ mit dem Namen des Kunden. Ist unter der Nummer noch kein Kunde einge­
+ tragen oder wird die Eingabe der Kundennummer durch die Tastenfolge
+ <ESC><q> abgebrochen, so enthält der Rechnungskopf keinen Kunden­
+ namen.
+
+ Das eigentliche Einkaufen erfolgt nun durch die Eingabe von Artikelnummern
+ (1...15). Der zugehörige Artikelname und der Preis werden daraufhin in die
+ Rechnung eingetragen.
+#on("b")#
++------------------------------------------------------------------------+
+|WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|----------------------------------+-------------------------------------|
+| RECHNUNG für Herrn B. Pollok | Artikelnummer :  1 |
+| | |
+| Bier (Kasten) 16.85 | |
+| Tageszeitung 0.80 | |
+| Pflaster 2.39 | |
+| Mehl 0.79 | |
+| Seife 1.80 | |
+| Weinbrand 12.75 | |
+| Zigaretten 3.80 | |
+| Brot 2.29 | |
+| Schallplatte 19.90 | |
+| Geodreieck 2.35 |-------------------------------------|
+| Videokassette 12.75 | Artikelnummer eingeben |
+| Schulheft 0.85 | |
+| | Stoptaste:  <ESC><q> |
+|----------------------------------+-------------------------------------|
+| Einkaufen |
++------------------------------------------------------------------------+
+#off("b")# |
+
+ Dieser Vorgang wird solange wiederholt, bis die Eingabe einer Artikelnummer
+ durch Tippen der Tastenfolge <ESC><q> abgebrochen wird.
+
+ Abschließend wird der Rechnungsgesamtbetrag ausgegeben und gefragt, ob die
+ Rechnung gedruckt werden soll.
+#page#
+#on("b")#a Auskunft einholen#off("b")#
+
+ Mit Hilfe dieses Kommandos lassen sich nach Einlesen einer Codenummer (je
+ nach Einstellung über Tastatur oder Codekartenleser) verschiedene Auskünfte
+ über die gespeicherten Daten abrufen. Es können #on("b")#Einzelauskünfte#off("b")# oder
+ #on("b")#Listenauskünfte#off("b")# eingeholt werden. Bei Eingabe einer falschen Nummer wird
+ die Auskunft abgebrochen!
+
+
+ #on("b")#Einzelauskünfte:#off("b")#
+
+ Codenummern 1...15 (Artikelnummern):
+ Die zugehörigen Artikeldaten werden im rechten oberen Bild­
+ schirmfenster angezeigt.
+
+ Codenummern 129...159 (Kundennummern):
+ Die zugehörigen Kundendaten werden im rechten oberen
+ Bildschirmfenster angezeigt.
+
+
+ #on("b")#Listenauskünfte:#off("b")#
+
+ Hierbei liefern jeweils 3 benachbarte Codenummern von der Art her ähnliche
+ Auskunfts-Listen, die auf Wunsch auch ausgedruckt werden können. Die
+ mittlere Nummer bezieht die Auskünfte stets auf die eigene Filiale; die beiden
+ anderen sind nur effizient, wenn mehrere Filialen angemeldet sind. Dabei
+ werden bei Eingabe der linken Nummer die jeweiligen Daten #on("b")#aller#off("b")# Filialen
+ 'aufaddiert' und in #on("b")#einer#off("b")# Gesamtliste ausgegeben. Bei Eingabe der rechten
+ Nummer hingegen werden die jeweiligen Listen von allen angeschlossenen
+ Filialen der Reihe nach abgerufen und #on("b")#hintereinander#off("b")# in eine Datei ge­
+ schrieben, sodaß man eine Zusammenstellung der entsprechenden #on("b")#Einzel#off("b")#-
+ Listen der Filialen erhält:
+#page#
+ Codenummern 66, 67, 68:
+ Die bisherigen Verkaufszahlen der einzelnen Waren werden
+ gezeigt; die Listen sind sortiert nach diesen Zahlen ('Ver­
+ kaufs-Hitlisten').
+
+ Codenummern 73, 74, 75:
+ Nach Eingabe einer Artikelnummer wird eine Liste aller
+ Käufer dieses Artikels ausgegeben.
+
+ Codenummern 77, 78, 79:
+ Diese Codes liefern Kundenlisten der Filialen.
+
+ Codenummern 84, 85, 86:
+ Nach Eingabe einer Kundennummer wird eine Liste aller von
+ diesem Kunden gekauften Artikel ausgegeben.
+
+ Codenummern 89, 90, 91:
+ Diese Codes liefern die Lagerbestandslisten der Filialen. Sollte
+ sich bei der Auskunft '90' herausstellen, daß der Bestand
+ mehrerer Artikel unter den Mindestbestand abgesunken ist, ist
+ es sinnvoll, als nächstes den Menupunkt 'Nachbestellen'
+ anzuwählen (s.u.).
+#page#
+ Beispiel: Der Code '90' liefert bei entsprechend eingegebener Warendatei
+ folgende Auskunft:
+#on("b")#
+ +------------------------------------------------------------------------+
+ | ............. Auskunft: Filiale 1 ................... Zeile 1 |
+ | |
+ | Lagerübersicht: |
+ | ---------------------------------------------------------------------- |
+ | ---------------------------------------------------------------------- |
+ | | Art.Nr.| Artikelname | Preis | Min.Best. | Bestand | |
+ | ---+---------+------------------+-------------+-----------+----------+ |
+ | | | | | | | |
+ | | 1 | Bier (Kasten) | 16.85 | 25 | 19 | |
+ | | 2 | Tageszeitung | 0.80 | 15 | 16 | |
+ | | 3 | Pflaster | 2.39 | 14 | 22 | |
+ | | 4 | Mehl | 0.79 | 32 | 58 | |
+ | | 5 | Seife | 1.80 | 27 | 49 | |
+ | | 6 | Weinbrand | 12.75 | 24 | 41 | |
+ | | 7 | Zigaretten | 4 +------------+--------+ | |
+ | | 8 | Brot | 2 | Auskunft drucken ?| | |
+ | | 9 | EMMA | 3 | | | |
+ | | 10 | Schallplatte | 19 | Ja     Nein | | |
+ | | 11 | Geodreieck | 2 +---------------------+ | |
+ | | | | | | |
+ | | | | | | |
+ | | | | | | |
+ |----------------------------------------------------------------------- |
+ | | Ändern: <Pfeile>   Bestätigen: <RETURN> |
+ + -----------------------------------------------------------------------+
+
+#off("b")#
+
+ Hinweis: Nur die zu den jeweils mittleren Codenummern gehörigen Aus­
+ kunftsfunktionen arbeiten mit Daten, die in der eigenen Task
+ gespeichert sind. Bei den übrigen Auskünften müssen Daten aus
+ anderen Filialverwaltungs-Tasks oder der Zentrale geholt werden,
+ so daß die Erstellung solch einer Auskunft recht zeitaufwendig ist.
+ Um zu lange Wartezeiten zu vermeiden, sollten nicht mehrere
+ Filialen gleichzeitig Auskünfte dieser Art einholen.
+#page#
+#on("b")#n Nachbestellen#off("b")#
+
+ Auf dem Bildschirm wird eine Bestelliste ausgegeben, die alle Artikel enthält,
+ deren Bestand innerhalb der Filiale den Mindestbestand unterschritten hat.
+
+ Die Nachbestellung ist so bemessen, daß diese Artikel wieder mit ihrem
+ doppelten Mindestbestand vorrätig sind. Die neuen Bestände werden auto­
+ matisch in die Warendatei der Filiale eingetragen.
+
+ Auf Wunsch kann die Bestelliste ausgedruckt werden.
+
+
+#on("b")#d Dezimalwert lesen#off("b")#
+
+ Der aktuelle Wert, der vom Codekartenleser gelesen wird, wird (ähnlich wie bei
+ 'Bitmuster lesen', s.u.) auf dem Bildschirm ausgegeben, bis <ESC><q>
+ gedrückt wird. Mit Hilfe dieses Kommandos kann man z.B. die Funktion des
+ Codekartenlesers testen und den Zusammenhang zwischen Bitmuster und
+ Dezimalwert klären.
+
+ Dieser Menupunkt ist (ebenso wie der nächste) nur dann aufrufbar, wenn
+ unter #on("b")#Eingabeart#off("b")# der #on("b")#Kartenleser#off("b")# eingestellt ist.
+
+
+#on("b")#b Bitmuster lesen#off("b")#
+
+ Dieser Menupunkt ist nur dann aufrufbar, wenn unter #on("b")#Eingabeart#off("b")# der
+ #on("b")#Kartenleser#off("b")# eingestellt ist (vgl. Kapitel 5.3).
+
+ Ist das der Fall, so wird hier das aktuelle Bitmuster, das vom Codekartenleser
+ gelesen wird, auf dem Bildschirm ausgegeben, bis <ESC><q> gedrückt
+ wird.
+#on("b")#
++-------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|-----------------------------------+-------------------------------------|
+| | |
+| | |
+| | Bitmuster :    0I00III0 |
+| | |
+| | |
+| | |
+| | |
+| | |
+| | |
+| | |
+| | |
+| | |
+| | Lesen beenden mit <ESC><q> |
+| +-------------------------------------|
+| |
+| Bitmuster lesen |
++-------------------------------------------------------------------------+
+#off("b")#
+
+ Ein Bitmuster besteht aus 8 Zeichen (z.B. 'OIOOIIIO'). Dabei zeigt jedes 'I' ein
+ Loch an der entsprechenden Stelle der Codekarte an, die sich gerade im
+ Kartenlesegerät befindet. Dieses Bitmuster entspricht der Dualzahl 01001110
+ (im 'Zweiersystem'); zu ihr gehört die Dezimalzahl
+#on("b")#
+
+ 0 * 128 + 1 * 64 + 0 * 32 + 0 * 16 + 1 * 8 + 1 * 4 + 1 * 2 + 0 * 1 = 78.
+#off("b")#
+
+ Mit Hilfe dieses Kommandos können Sie z.B. die Funktion des Codekarten­
+ lesers testen. Bei voller Beleuchtung aller 8 Sensoren muß das Bitmuster
+ 'IIIIIIII' geliefert werden. Decken Sie einige Sensoren mit den Fingern oder
+ einer Lochkarte ab, so muß sich das Bitmuster auf dem Bildschirm ent­
+ sprechend verändern. Ist das nicht der Fall, so liegt ein Fehler vor.
+
+ Prüfen Sie dann erst einmal, ob der Steckplatz mit Strom versorgt wird (Netz­
+ kabel in der Steckdose? Compact-Box mit Netzteil richtig verbunden?) Ist dort
+ alles in Ordnung, so könnte der Fehler noch in der Verbindung zum Adapter
+ liegen. (Steckplatz ordnungsgemäß mit Adapter verbunden? Richtiges Kabel
+ verwendet?)
+#page#
+ Sollten Sie auf diese Weise nicht zum Erfolg kommen, so verlassen Sie diesen
+ Menupunkt und wählen noch einmal den Oberbegriff 'Eingabeart' an. Stellen
+ Sie dort die Eingabeart zunächst auf 'Tastatur um' und dann wieder auf
+ 'Kartenleser'. Treten hier Fehlermeldungen auf, so lesen Sie in Kapitel 5.3
+ nach. Läßt sich die Umstellung dagegen problemlos vornehmen, so müßte nun
+ auch das 'Bitmuster lesen' wieder funktionieren.
+
+
+#on("b")#5.5  Menufunktionen zum Oberbegriff 'Programme'#off("b")#
+
+#on("b")#
++-------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|---------------------+----------------------+----------------------------|
+| | n  Neu erstellen | |
+| | a  Ansehen/Ändern | |
+| | ------------------ | |
+| | s  Starten | |
+| | w  Wiederholen | |
+| | ------------------ | |
+| | v  Verzeichnis | |
+| | ------------------ | |
+| | l  Löschen | |
+| | d  Drucken | |
+| | ------------------ | |
+| | k  Kopieren | |
+| | u  Umbenennen | |
+| +----------------------+ |
+|-------------------------------------------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++-------------------------------------------------------------------------+
+#off("b")#
+
+#on("b")#n Neu erstellen#off("b")#
+
+ Mit dieser Funktion können Sie eine neue Programmdatei anlegen und
+ beschreiben.
+
+ Sie werden zunächst nach einem Namen für die #on("b")#neue#off("b")# Programmdatei gefragt.
+ Geben Sie einen beliebigen Namen (#on("b")#ohne Anführungszeichen (!)#off("b")#) ein und
+#page#
+ schließen Sie die Eingabe durch <RETURN> ab. Daraufhin wird Ihnen auf
+ dem Bildschirm eine neue Datei zum Beschreiben angeboten.
+
+ Sollte schon eine Programmdatei mit diesem Namen in der Task vorhanden
+ sein, so werden Sie darauf aufmerksam gemacht.
+
+ Sie können sich während des Schreibens die wichtigsten Tastenfunktionen des
+ Editors einblenden lassen. Tippen Sie dazu die Tastenfolge <ESC><?>. Es
+ erscheint dann das folgende Angebot aus dem Sie auswählen können:
+
+#on("b")#
+ +-----------------------------------------------------+
+ | Der EUMEL - Editor |
+ | |
+ | b ... Beschreibung desEditors |
+ | w ... Wichtige Tasten |
+ | p ... Positionieren der Schreibmarke |
+ | k ... Korrigieren im Text (Einfügen/Löschen) |
+ | m ... Markierte Textpassagen bearbeiten |
+ | l ... Lernen im Editor |
+ | a ... Anweisungen im Editor (Kommandodialog) |
+ | |
+ | z ... Zurück in den Schreibmodus |
+ | |
+ | b   w   p   k   m   l   a   z |
+ | |
+ +-----------------------------------------------------+
+#off("b")#
+ Fehlerfälle:
+ - Eine Programm-Datei mit dem vorgeschlagenen Namen existiert schon.
+
+
+#on("b")#a Ansehen/ändern#off("b")#
+
+ Mit dieser Funktion können Sie sich Dateien, die schon in Ihrer Task
+ existieren, ansehen oder auch verändern.
+
+ Sie werden zunächst gefragt, ob Sie #on("b")#die zuletzt bearbeitete Programmdatei#off("b")#
+ ansehen bzw. verändern möchten (sofern Sie schon vorher mit #on("b")#gs-Warenhaus#off("b")#
+ in der Task gearbeitet haben).
+#page#
+ Bejahen Sie diese Frage, dann wird Ihnen diese Programmdatei zur Bear­
+ beitung angeboten. Verneinen Sie die Frage dagegen, so gelangen Sie in die
+ 'Auswahl' (d.h es werden Ihnen alle Programmdateien in der Task zur Auswahl
+ angeboten). Nachdem Sie einen der Namen angekreuzt haben, wird Ihnen die
+ ausgewählte Programmdatei zur Bearbeitung auf dem Bildschirm angeboten.
+
+ Fehlerfälle:
+ - In der Task existiert noch keine Programmdatei.
+
+
+#on("b")#s Starten#off("b")#
+
+ Mit dieser Menufunktion können Sie ein fertiggestelltes Programm übersetzen
+ und ausführen lassen.
+
+ Sie werden zunächst gefragt, ob #on("b")#das zuletzt bearbeitete Programm#off("b")# ausgeführt
+ werden soll. Bejahen Sie die Frage, so wird dieses Programm gestartet; ver­
+ neinen Sie die Frage dagegen, so gelangen Sie in die 'Auswahl'. Nach An­
+ kreuzen des gewünschten Programmnamens wird das ausgewählte Programm
+ ausgeführt.
+
+ Sind im Programm noch Fehler enthalten, so werden das Programm und die
+ Fehlermeldungen gleichzeitig auf dem Bildschirm dargestellt (Paralleleditor)
+ und zur Korrektur angeboten. Für die Programmkorrektur stehen ebenfalls alle
+ Editorfunktionen zur Verfügung.
+
+ Sollte Ihnen beim Programmieren ein Fehler unterlaufen sein (z.B. eine
+ Endlosschleife), so kann mit der Tastenfolge <ESC><h> der Programm­
+ ablauf abgebrochen werden ("Notbremse").
+#page#
+#on("b")#w Wiederholen#off("b")#
+
+ Mit dieser Funktion können Sie den Ablauf des zuletzt ausgeführten
+ Programms wiederholen, ohne daß das Programm neu übersetzt wird.
+
+ Beachten Sie aber bitte, daß Veränderungen am Programmtext, die seit dem
+ letzten Programmlauf vorgenommen wurden, #on("b")#nicht#off("b")# berücksichtigt werden;
+ dazu muß das Programm erneut mit der Menufunktion 'Starten' übersetzt
+ werden.
+
+ Ist die Wiederholung eines Programmlaufs nicht möglich, so erfolgt ein Hin­
+ weis darauf.
+
+
+#on("b")#v Verzeichnis#off("b")#
+
+ Mit dieser Funktion können Sie sich einen Überblick über die in Ihrer Task
+ vorhandenen Programmdateien verschaffen.
+
+ Nach Aufruf dieser Funktion wird eine Liste der Programmdateien auf dem
+ Bildschirm ausgegeben, die sich in Ihrer Task befinden. Da die Liste selbst
+ eine Text-Datei ist, kann Sie mit der Tastenkombination <ESC><q> ver­
+ lassen werden - hierauf wird auch in der letzten Bildschirmzeile hingewiesen.
+ Falls nicht alle Namen auf den Bildschirm passen, können Sie das Fenster mit
+ <HOP><runter> und <HOP><hoch> verschieben.
+
+
+#on("b")#Löschen#off("b")#
+
+ Mit dieser Funktion können Sie Programmdateien, die Sie nicht mehr
+ benötigen, die unnötig Platz belegen, löschen. Aber Vorsicht! Die Dateien
+ verschwinden durch diese Funktion unwiederbringlich!
+
+ Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+ Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+ <ESC><q> verlassen.
+#page#
+ Für jede einzelne Programmdatei wird noch einmal zur Sicherheit gefragt, ob
+ sie auch tatsächlich gelöscht werden soll. Zur Bestätigung tippen Sie bitte die
+ Taste <j> ('ja') - zur Verhinderung <n> ('nein').
+
+ Fehlerfälle:
+ - In der Task exsitiert noch keine Programmdatei
+
+
+#on("b")#d Drucken#off("b")#
+
+ Mit dieser Funktion können Sie Programmdateien über einen angeschlossenen
+ Drucker ausgeben lassen.
+
+ Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+ Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+ <ESC><q> verlassen.
+
+ Die angekreuzten Programmdateien werden anschließend zum Drucker ge­
+ schickt. Der Vorgang wird auf dem Bildschirm protokolliert.
+
+ Fehlerfälle:
+ - In der Task existiert noch keine Programmdatei.
+ - Der Drucker ist nicht funktionsbereit.
+ - Der Drucker wird nicht über die Task 'PRINTER' betrieben.
+ - Auf Ihrem System werden die Druckkosten abgerechnet. Sie müssen sich
+ mit einer Codenummer identifizieren.
+
+
+#on("b")#k Kopieren#off("b")#
+
+ Mit dieser Funktion können Sie sich eine Kopie einer bereits in der Task
+ vorhandenen Programmdatei anlegen. Das ist z.B. dann sinnvoll, wenn Sie sich
+ einen bestimmten 'Stand' aufbewahren wollen oder wenn Sie ein Programm
+ schreiben wollen, das einem bereits vorhandenen ähnelt.
+#page#
+ Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+ wird die Auswahl automatisch verlassen.
+
+ Anschließend wird der angekreuzte Name angezeigt und der Name für die
+ Kopie erfragt. Es muß ein Name eingetragen werden, der in dieser Task noch
+ nicht für eine Programmdatei vergeben wurde; ansonsten erfolgt ein Hinweis
+ darauf und es wird nicht kopiert!
+
+ Da man aber oft für die Kopie einen ähnlichen Namen wie für das Original
+ wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+ aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+ funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+ eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+ Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Programmdatei mit dem gewünschten Namen existiert bereits in der
+ Task.
+
+
+#on("b")#u Umbenennen#off("b")#
+
+ Mit dieser Funktion können Sie einer bereits vorhandenen Programmdatei
+ einen neuen Namen geben.
+
+ Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+ wird die Auswahl automatisch verlassen.
+
+ Anschließend wird dieser Name angezeigt und der zukünftige Name für die
+ Programmdatei erfragt. Es muß ein Name eingetragen werden, der in dieser
+ Task noch nicht für eine Programmdatei vergeben wurde - ansonsten erfolgt
+ ein Hinweis darauf und die Programmdatei wird nicht umbenannt!
+#page#
+ Da man aber oft den 'neuen' Namen in Anlehnung an den 'alten' Namen
+ wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+ aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+ funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+ eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+ Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Programmdatei mit dem gewünschten Namen existiert bereits in der
+ Task.
+
+
+
+#on("b")#5.6  Menufunktionen zum Oberbegriff 'Filialdaten'#off("b")#
+#on("b")#
++-------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|---------------------------------------+--------------------------+------|
+| | e   Eintragen/ergänzen | |
+| | z   Zusammenstellen | |
+| | ----------------------- | |
+| | v   Verzeichnis | |
+| | ----------------------- | |
+| | l   Löschen | |
+| | u   Umbenennen | |
+| +--------------------------+ |
+| |
+| |
+|-------------------------------------------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>|
++-------------------------------------------------------------------------+
+
+#off("b")#
+
+#on("b")#e Eintragen/ergänzen#off("b")#
+
+ Mit diesem Menupunkt können Sie Filialdaten-Dateien, die Sie z.B. von der
+ Vatertask oder von der Diskette geholt haben, in Ihrer Task laden.
+#page#
+ Ihnen werden zunächst alle vorhandenen Filialdaten-Dateien zur Auswahl
+ angeboten. Anschließend werden die angekreuzten Dateien in der Reihenfolge,
+ in der sie angekreuzt wurden, zur Filialverwaltung geschickt und die Daten
+ dort zu den bereits vorhandenen hinzugefügt. Gegebenenfalls wird auch die
+ zentrale Kundendatei ergänzt. Der Vorgang wird auf dem Bildschirm
+ protokolliert.
+
+ Beachten Sie bitte, daß in der Filiale etwa vorhandene Daten dadurch nicht
+ überschrieben, sondern lediglich ergänzt werden. Ein gänzliches Beseitigen von
+ alten Daten gelingt nur durch Löschen der Filialtask.
+
+ Fehlerfälle:
+ - In der Task exsitieren noch keine Filialdaten-Dateien.
+
+
+#on("b")#z Zusammenstellen#off("b")#
+
+ Mit dieser Funktion können Sie eine Datei anlegen, in der die aktuell in der
+ Filiale gehaltenen Daten zusammengestellt werden. Solch eine Datei kann man
+ sich jedoch nicht ansehen!
+
+ Zunächst wird der Name der Datei erfragt, in die die Filialdaten geschrieben
+ werden sollen. Danach werden darin die aktuellen Daten gespeichert und es
+ wird eine 'Vollzugsmeldung' ausgegeben.
+
+ Die Daten können dann später mit Hilfe der Archiv-Funktionen (vgl. Kapitel
+ 5.7) z.B. auf einer Diskette gespeichert werden, damit Sie beim eventuellen
+ Löschen der Filialtask nicht verlorengehen. Eine Verwechselung mit
+ Programmdateien ist nicht möglich, da Namen für Filialdaten-Dateien (intern)
+ automatisch mit dem Präfix 'Filialdaten:' versehen werden.
+
+ Fehlerfälle:
+ - Eine Filialdaten-Datei mit dem gewünschten Namen existiert bereits in der
+ Task.
+#page#
+#on("b")#v Verzeichnis#off("b")#
+
+ Mit dieser Funktion können Sie sich einen Überblick über die in Ihrer Task
+ vorhandenen Filialdaten-Dateien verschaffen.
+
+ Nach Aufruf dieser Funktion wird eine Liste der Filialdaten-Dateien auf dem
+ Bildschirm ausgegeben, die sich in Ihrer Task befinden. Da die Liste eine
+ Text-Datei ist, kann Sie mit der Tastenkombination <ESC><q> verlassen
+ werden - hierauf wird auch in der letzten Bildschirmzeile hingewiesen. Falls
+ nicht alle Namen auf den Bildschirm passen, können Sie das Fenster mit
+ <HOP><runter> und <HOP><hoch> verschieben.
+
+
+#on("b")#l Löschen#off("b")#
+
+ Mit dieser Funktion können Sie Filialdaten-Dateien, die Sie nicht mehr
+ benötigen und die unnötig Platz belegen, löschen. Aber Vorsicht! Die Dateien
+ verschwinden durch diese Funktion unwiederbringlich!
+
+ Nach Aufruf dieser Funktion werden Ihnen alle Filialdaten-Dateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+ Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+ <ESC><q> verlassen.
+
+ Für jede einzelne Datei wird nachgefragt, ob sie auch tatsächlich gelöscht
+ werden soll. Zur Bestätigung tippen Sie bitte die Taste <j> ('ja') - zur Ver­
+ hinderung <n> ('nein').
+
+ Fehlerfälle:
+ - In der Task exsitiert noch keine Filialdaten-Datei.
+#page#
+#on("b")#u Umbenennen#off("b")#
+
+ Mit dieser Funktion können Sie einer bereits vorhandenen Filialdaten-Datei
+ einen neuen Namen geben.
+
+ Nach Aufruf dieser Funktion werden Ihnen alle Filialdaten-Dateien, die sich in
+ Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+ wird die Auswahl automatisch verlassen.
+
+ Anschließend wird dieser Name angezeigt und der zukünftige Name für die
+ Datei erfragt. Es muß ein Name eingetragen werden, der in dieser Task noch
+ nicht für eine Filialdaten-Datei vergeben wurde - ansonsten erfolgt ein Hinweis
+ darauf und die Datei wird nicht umbenannt!
+
+ Da man aber oft den 'neuen' Namen in Anlehnung an den 'alten' Namen
+ wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+ aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+ funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+ eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+ Namen nur an einer Stelle ändern wollen.
+
+ Fehlerfälle:
+ - Eine Filialdaten-Datei mit dem gewünschten Namen existiert bereits in der
+ Task.
+#page#
+#on("b")#5.7  Menufunktionen zum Oberbegriff 'Archiv'#off("b")#
+#on("b")#
++--------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|---------------------------------------------+------------------------+---|
+| | r  Reservieren | |
+| | -  Neue Diskette | |
+| | -------------------- | |
+| | -  Schreiben | |
+| | -  Checken | |
+| | -  Kombination | |
+| | -  Holen/Lesen | |
+| | -  Löschen | |
+| | -------------------- | |
+| | -  Verzeichnis | |
+| | -  Drucken | |
+| | -------------------- | |
+| +-----------------------+ | i  Initialisieren | |
+| | Dateiaustausch mit: | | z  Zieltask einstellen| |
+| | Archiv | +------------------------+ |
+| | Archivname: | |
+| | gs-Warenhaus | |
+| +-----------------------+ |
+|--------------------------------------------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++--------------------------------------------------------------------------+
+#off("b")#
+
+In diesem Kapitel werden alle die Menufunktionen beschrieben, die Ihnen unter dem
+Oberbegriff 'Archiv' im Menu angeboten werden. Mit den Funktionen in diesem Menu
+können Sie aber nicht nur Dateien auf dem Archiv behandeln, sondern auch in
+anderen Tasks im Multi-User-System oder über das EUMEL-Netz sogar auf anderen
+Rechnern!
+
+Wenn Sie dieses Pull-Down-Menu gerade aufgeschlagen haben, sind nicht alle
+Funktionen aktivierbar! Um weitere Funktionen zu aktivieren, muß erst einer der
+aktivierbaren Menupunkte gewählt werden.
+
+Bei der Archivbehandlung werden Ihnen jeweils alle in der Task vorhandenen Dateien
+zur Auswahl angeboten. Das System unterscheidet nicht von sich aus - wie unter den
+#page#
+Oberbegriffen 'Programme' und 'Filialdaten' - zwischen Programm- und Filial­
+daten-Dateien. In den hier gezeigten Listen können Sie aber Filialdaten-Dateien
+daran erkennen, daß ihnen das Präfix 'Filialdaten:' vorangestellt ist.
+
+
+#on("b")#r Reservieren#off("b")# (des Archivlaufwerks)
+
+ Im EUMEL-Multi-User-System haben normalerweise mehrere Personen das
+ Zugriffsrecht auf das Archivlaufwerk. Allerdings muß der Zugriff so geregelt
+ werden, daß sich die Beteiligten dabei nicht gegenseitig "in die Quere
+ kommen". Ein Zugriff auf das Archivlaufwerk erfordert zunächst eine An­
+ meldung. Ist diese Anmeldung erfolgt, kann von den anderen Beteiligten so
+ lange nicht mehr auf das Laufwerk zugegriffen werden, bis es wieder freige­
+ geben worden ist.
+
+ Diese Anmeldung des Archivlaufwerkes erfolgt über die Menufunktion 'r Reser­
+ vieren'. Greift bereits eine andere Task auf das Laufwerk zu, so erhalten Sie
+ darüber einen Hinweis auf dem Bildschirm. Ansonsten wird an Sie die Frage
+ gestellt, ob die Diskette eingelegt und das Laufwerk geschlossen ist.
+
+ Erst zu diesem Zeitpunkt ist sichergestellt, daß Sie den alleinigen Zugriff auf
+ das Laufwerk haben. Deshalb sollten Sie, wenn Sie mit mehreren Personen am
+ Computer arbeiten, erst zum Zeitpunkt der Fragestellung die Diskette ins Lauf­
+ werk einlegen.
+
+ Nachdem Sie die Diskette eingelegt und die Frage bejaht haben, ermittelt das
+ System selbständig den Namen der eingelegten Diskette, zeigt den Namen auf
+ dem Bildschirm (im kleinen Kasten links unten) an und aktiviert die anderen
+ Menupunkte des Pull-Down-Menus.
+
+ Beim Verlassen des Pull-Down-Menus, wenn eine andere Zieltask eingestellt
+ wird oder wenn das Menu gänzlich verlassen wird, wird die Reservierung
+ automatisch aufgehoben!
+#page#
+ Fehlerfälle:
+ - Das Laufwerk ist von einer anderen Task belegt.
+ - Die Diskette ist falsch eingelegt oder das Laufwerk ist nicht richtig ge­
+ schlossen.
+ - Die Diskette ist nicht formatiert bzw. initialisiert.
+ - Die Diskette kann nicht gelesen werden (keine EUMEL-Diskette, Diskette
+ hat ein falsches Format, Diskette ist verschmutzt...).
+
+
+#on("b")#n Neue Diskette#off("b")# (anmelden)
+
+ Der Dateiaustausch mit einer Diskette ist nur dann möglich, wenn der im
+ System eingestellte Diskettenname (auf dem Bildschirm im kleinen Kasten
+ unten links sichtbar) mit dem tatsächlichen Namen der Diskette überein­
+ stimmt. Nach einem Diskettenwechsel ist das aber in der Regel nicht mehr der
+ Fall. Greift man dann auf die neu eingelegte Diskette zu, so erscheint die
+ Fehlermeldung: 'Falscher Archivname! Bitte neue Diskette anmelden!'.
+
+ Das Anmelden einer neuen Diskette - ohne einen neuen Reservierungsvorgang
+ - wird durch diese Menufunktion ermöglicht. Nach Aktivieren dieses Menu­
+ punktes wird der Name der eingelegten Diskette ermittelt, im System eingestellt
+ und auf dem Bildschirm angezeigt.
+
+ Im Gegensatz zur Menufunktion 'r Reservieren' greift das System ohne Anfrage
+ an den Benutzer auf das Archivlaufwerk zu (die Reservierung bleibt ja be­
+ stehen). Ist das Archivlaufwerk reserviert, so ist die Neuanmeldung einer Dis­
+ kette über diese Menufunktion weniger zeitaufwendig.
+
+ Fehlerfälle:
+ - wie unter 'r Reservieren'.
+#page#
+#on("b")#s Schreiben#off("b")# (Kopieren)
+
+ Alle Dateien der eigenen Task werden zur Auswahl angeboten. Wenn Sie die
+ Auswahl durch die Tastenfolge <ESC><q> verlassen, überprüft das System
+ zunächst, ob die Dateien in der eingestellten Zieltask schon vorhanden sind. Ist
+ das der Fall, wird erfragt, ob die dort vorhandenen Dateien überschrieben, d.h.
+ gelöscht werden dürfen (s.u.). Anschließend werden alle angekreuzten Dateien
+ in der Reihenfolge, in der Sie sie angekreuzt haben, in die eingestellte Zieltask
+ kopiert. Der Vorgang wird auf dem Bildschirm protokolliert. Die Original­
+ dateien in der eigenen Task bleiben dabei erhalten.
+
+ Wenn in der Zieltask schon eine Datei existiert, die den gleichen Namen hat
+ wie eine Datei, die Sie dorthin kopieren möchten, so wird angefragt, ob die
+ vorher schon existierende Datei überschrieben (gelöscht!) werden soll. Bejahen
+ Sie diese Frage, so wird die bereits in der Zieltask existierende Datei (un­
+ wiederbringlich) gelöscht und die gewünschte Datei dorthin transportiert. Ein
+ Überschreiben aus Versehen ist nicht möglich, wenn Sie die an Sie gestellte
+ Frage sorgfältig beantworten.
+
+ Verneinen Sie die Frage, so wird die Datei auch nicht hinübertransportiert! Sie
+ können die Datei aber umbenennen (Menufunktion 'u Umbenennen' unter
+ den Oberbegriffen 'Programme' bzw. 'Filialdaten') und anschließend mit
+ anderem Namen hinüberschreiben.
+
+ Beachten Sie, daß beim Überschreiben einer Datei auf einer Archivdiskette der
+ Speicherplatz der alten (überschriebenen) Version im allgemeinen nicht
+ wiederverwendet werden kann. In einem solchen Fall könnte die Diskette voll
+ geschrieben werden, obwohl eigentlich genügend Platz vorhanden wäre. Zur
+ Optimierung wird deshalb zuerst überprüft, ob die angekreuzten Dateien
+ schon in der Zieltask vorhanden sind und löscht diese, wenn Sie Ihr Einver­
+ ständnis geben. Erst anschließend werden die Dateien insgesamt kopiert.
+#page#
+ Normalerweise ist als Zieltask das Archivlaufwerk der eigenen Station einge­
+ stellt. Mit der Menufunktion 'z Zieltask einstellen' kann diese Einstellung aber
+ verändert werden.
+
+ Fehlerfälle:
+ - Die Diskette ist falsch eingelegt oder beschädigt.
+ - Die Diskette kann nicht beschrieben werden (Schreibfehler).
+ - Die Diskette ist voll.
+ - Sehen Sie auch unter 'r Reservieren'
+ 'z Zieltask einstellen'.
+
+
+#on("b")#c Checken#off("b")#
+
+ Diese Menufunktion kann nur ausgeführt werden, wenn der Dateiaustausch
+ mit einem Archiv(manager) erfolgt - ansonsten ist diese Menufunktion auch
+ nicht aktivierbar. Die Menufunktion dient dazu, auf Diskette geschriebene
+ Dateien auf Lesefehler hin zu prüfen. Es empfiehlt sich, diese Prüfroutine auf
+ neu auf die Diskette geschriebene Dateien anzuwenden. Sehen Sie dazu auch
+ 'k Kombination'.
+
+ Alle Dateien der eingestellten Zieltask (Archiv) werden zur Auswahl angeboten.
+ Wenn Sie die Auswahl durch die Tastenfolge <ESC><q> verlassen, werden
+ alle angekreuzten Dateien in der Reihenfolge, in der Sie sie angekreuzt haben,
+ "gecheckt", d.h. auf Lesefehler hin überprüft. Der Vorgang wird auf dem Bild­
+ schirm protokolliert.
+
+ Fehlerfälle:
+ - Lesefehler auf dem Archiv.
+ - Sehen Sie auch unter 'r Reservieren'.
+#page#
+#on("b")#k Kombination#off("b")#
+
+ Diese Menufunktion ist eine Kombination aus den beiden Menufunktionen 's
+ Schreiben' und 'c Checken' (Sehen Sie weitere Informationen auch dort!).
+
+ Alle Dateien der eigenen Task werden zur Auswahl angeboten. Wenn Sie die
+ Auswahl durch die Tastenfolge <ESC><q> verlassen, werden alle ange­
+ kreuzten Dateien in der Reihenfolge, in der Sie sie angekreuzt haben, in die
+ eingestellte Zieltask kopiert (gegebenenfalls müssen bereits vorhandene
+ Dateien gleichen Namens in der Zieltask gelöscht werden). Anschließend
+ werden alle Dateien, die gerade geschrieben wurden, gecheckt, d.h. auf Lese­
+ fehler hin untersucht. Beide Vorgänge werden auf dem Bildschirm
+ protokolliert.
+
+ Da die 'Check' - Operation nur bei Archivmanagern zulässig ist, ist diese Menu­
+ funktionen ebenfalls nur bei Archivmanagern aktivierbar. Zur Erläuterung
+ sehen Sie bitte auch unter 'z Zieltask einstellen'.
+
+
+#on("b")#h Holen/Lesen#off("b")#
+
+ Die Menufunktion dient dazu, Dateien, die bereits auf einer Archivdiskette oder
+ in einer anderen Task existieren, in die eigene Task zu kopieren.
+
+ Alle Dateien der eingestellten Zieltask werden zur Auswahl angeboten. An­
+ schließend werden Kopien der angekreuzten Dateien in der Reihenfolge des
+ Ankreuzens in die eigene Task geholt. Das Original in der Zieltask bleibt dabei
+ unverändert! Der Vorgang wird auf dem Bildschirm protokolliert.
+
+ Sind in der eigenen Task schon Dateien mit gleichem Namen vorhanden, so
+ wird gefragt, ob die 'alten' Dateien überschrieben (gelöscht) werden dürfen.
+ Nur wenn Sie zustimmen, werden die in Ihrer Task existierenden Dateien
+ (unwiederbringlich!) gelöscht und Kopien der gleichnamigen Dateien aus der
+ Zieltask angefertigt.
+#page#
+ Stimmen Sie dem Löschvorgang nicht zu, dann bleiben die bisherigen Dateien
+ in Ihrer Task erhalten - die Dateien aus der Zieltask werden dann aber auch
+ nicht in Ihre Task kopiert! Um dennoch die Kopien zu erhalten, können Sie die
+ namensgleichen Dateien in Ihrer Task umbenennen und dann erst die Dateien
+ aus der anderen Task anfordern.
+
+ Normalerweise werden die Dateien vom Archiv der eigenen Station geholt. Mit
+ dem Menupunkt 'z Zieltask einstellen' kann diese Einstellung verändert
+ werden.
+
+ Fehlerfälle:
+ - Lesefehler auf dem Archiv.
+ - Sehen Sie auch unter 'r Reservieren'
+ 's Schreiben'
+ 'z Zieltask einstellen'.
+
+
+#on("b")#l Löschen#off("b")#
+
+ Die Menufunktion dient dazu, Dateien in der Zieltask (unwiederbringlich!) zu
+ löschen. Dazu werden alle Dateien der eingestellten Zieltask zur Auswahl ange­
+ boten. Anschließend werden die angekreuzten Dateien in der Reihenfolge ihres
+ Ankreuzens gelöscht. Zur Sicherheit muß noch einmal für jede einzelne Datei
+ bestätigt werden, daß sie auch tatsächlich gelöscht werden soll.
+
+ Beachten Sie, daß beim Löschen einer Datei auf einer Archivdiskette der
+ Speicherplatz im allgemeinen nicht wieder verwendet werden kann. In einem
+ solchen Fall könnte die Diskette voll geschrieben werden, obwohl eigentlich
+ genügend Platz vorhanden wäre. Diese Probleme treten bei anderen Tasks, die
+ keine Archivmanager sind, nicht auf, da deren Speicherplatz intelligenter
+ verwaltet wird.
+#page#
+ Normalerweise ist als Zieltask das Archiv der eigenen Station eingestellt. Mit
+ dem Menupunkt 'z Zieltask einstellen' kann diese Einstellung verändert
+ werden.
+
+ Fehlerfälle:
+ - Sehen Sie auch unter 'r Reservieren'
+ 's Schreiben'
+ 'z Zieltask einstellen'.
+
+
+#on("b")#v Verzeichnis#off("b")#
+
+ Mit dieser Menufunktion können Sie sich einen Überblick über die in der
+ Zieltask (z.B. auf dem Archiv) vorhandenen Dateien verschaffen.
+
+ Nach Aufruf der Funktion wird eine Liste der Dateien auf dem Bildschirm
+ ausgegeben, die sich in der Zieltask (z.B. auf dem Archiv) befinden. Ist die
+ Zieltask ein Archiv(manager), so wird auch angezeigt, wieviel Platz auf der
+ Diskette belegt ist. Da die Liste selbst eine Datei ist, kann sie mit der Tasten­
+ kombination <ESC><q> verlassen werden. Falls nicht alle Dateinamen auf
+ den Bildschirm passen, können Sie das Fenster mit <HOP><hoch> und
+ <HOP><runter> verschieben.
+
+ Fehlerfälle:
+ - Sehen Sie unter 'z Zieltask einstellen'.
+
+
+#on("b")#d Drucken#off("b")#
+
+ Das Verzeichnis der Dateien in der Zieltask, das man mit der Menufunktion 'v
+ Verzeichnis' auf dem Bildschirm angezeigt bekommt, kann mit dieser Menu­
+ funktion ausgedruckt werden.
+#page#
+ Zur Sicherheit wird angefragt, ob wirklich ein solches Dateiverzeichnis der
+ Zieltask gedruckt werden soll. Bejaht man die Frage, so wird ein Dateiver­
+ zeichnis erstellt und zum Drucker geschickt.
+
+ Fehlerfälle:
+ - Der Drucker ist nicht funktionsbereit.
+ - Der Drucker wird nicht über die Task 'PRINTER' betrieben.
+ - Auf Ihrem System werden die Druckkosten abgerechnet. Sie müssen sich
+ mit einer Codenummer identifizieren.
+
+
+#on("b")#i Initialisieren#off("b")#
+
+ Diese Menufunktion gestattet es, frische Disketten zu formatieren, zu initiali­
+ sieren bzw. beschriebene Disketten vollständig zu löschen und ggf. dabei
+ umzubenennen. Bei Aufruf dieser Menufunktion wird - sofern noch nicht
+ geschehen - das Archivlaufwerk automatisch reserviert.
+
+ Wenn Sie eine fabrikneue Diskette aus der Verpackung nehmen, müssen Sie
+ diese zunächst #on("b")#formatieren#off("b")#. Dabei wird die Diskette auf ein festgelegtes
+ physikalisches Format eingestellt. Ohne daß diese Operation vorausgegangen
+ ist, kann eine Diskette weder beschrieben noch gelesen werden.
+
+ Prinzipiell braucht eine Diskette nur ein einziges Mal formatiert zu werden. Sie
+ können Sie jedoch jederzeit wieder formatieren - z.B. wenn Sie Disketten
+ haben, von denen Sie nicht genau wissen, für welche Zwecke sie zuvor ver­
+ wendet wurden.
+
+ Wenn Sie diese Menufunktion aktivieren, werden Sie so zunächst gefragt, ob Sie
+ die Diskette auch formatieren wollen. Bejahen Sie die Frage, so werden Ihnen
+ mehrere Formate zur Auswahl angeboten:
+#page#
+#on("b")#
+ +----------------------------------------+
+ | Formatieren einer Diskette |
+ | |
+ | Dies sind die möglichen Formate: |
+ | |
+ | 1 .... 40 Spur - 360 KB |
+ | 2 .... 80 Spur - 720 KB |
+ | 3 .... 5 1/4" - 1,2 MB |
+ | 4 .... 3 1/2" - 1,4 MB |
+ | s .... Standard - Format |
+ | |
+ | |
+ | 1   2   3   4   s |
+ +----------------------------------------+
+
+#off("b")#
+
+ Erkundigen Sie sich bei Ihrem Händler, welches Format Sie bei Ihrem Rechner
+ und den von Ihnen verwendeten Disketten einstellen müssen. Manche Rechner
+ unterstützen diese Operation innerhalb des EUMEL-Systems auch gar nicht,
+ das Formatieren muß dann irgendwie anders außerhalb des EUMEL-Systems
+ geschehen.
+
+ Wenn Sie die Formatierung abgeschlossen oder auch übersprungen haben,
+ beginnt die eigentliche Initialisierung der Diskette. Dabei wird als erstes der
+ Archivname auf die Diskette geschrieben. Alle alten Daten, die sich ggf. auf der
+ Diskette befinden, werden bei diesem Vorgang unwiederbringlich (!) gelöscht.
+
+ Zur Sicherheit überprüft das System in jedem Falle, ob es sich um eine EUMEL
+ - Diskette handelt, und erfragt Ihr Einverständnis, ob die Diskette wirklich
+ initialisiert werden soll. Geben Sie hierzu Ihr Einverständnis, dann wird noch
+ der (neue) Archivname erfragt. Hatte die Diskette schon einen Namen, dann
+ wird dieser zum Überschreiben angeboten. Wollen Sie den alten Archivnamen
+ beibehalten, so brauchen Sie nur die <RETURN>-Taste zu tippen, ansonsten
+ können Sie den Namen auch zuvor verändern oder einen ganz neuen Namen
+ hinschreiben. Anhand des ausgegebenen Namens können Sie auch über­
+ prüfen, ob Sie die richtige Diskette eingelegt haben.
+#page#
+ Das Initialisieren funktioniert natürlich nur, wenn Sie als Zieltask einen
+ Archivmanager eingestellt haben - ansonsten ist diese Menufunktion gesperrt
+ (nicht aktivierbar!).
+
+ Fehlerfälle:
+ - Formatieren ist nicht auf dem System möglich.
+ - Sehen Sie auch unter 'r Reservieren'
+ 'z Zieltask einstellen'.
+
+
+#on("b")#z Zieltask einstellen#off("b")#
+
+ Mit dieser Menufunktion können Sie festlegen, mit welcher Zieltask Sie
+ kommunizieren, d.h. z.B. Dateien austauschen möchten. Normalerweise ist
+ hier das Archiv am eigenen Rechner eingestellt. Das wird auch nach Auf­
+ klappen des Pull-Down-Menus im Kasten links unten angezeigt.
+
+ Diese Menufunktion kann im Unterricht z.B. dazu genutzt werden, um fertig­
+ gestellte Hausaufgaben in eine bestimmte Task zu schicken (Vatertask) oder
+ um von dort z.B. vorgefertigte Programme und/oder Filialdaten-Dateien abzu­
+ holen.
+
+ Sie können aber auch eine andere Task einstellen (z.B. die Vatertask oder die
+ Task 'PUBLIC'), um mit diesen Dateien auszutauschen oder um sich auch nur
+ einen Überblick über die dort vorhandenen Dateien zu verschaffen. Wenn Sie
+ mit Ihrem Rechner in ein EUMEL-Netz integriert sind, können Sie auch auf
+ Tasks anderer Rechner zugreifen oder auch Disketten von Laufwerken anderer
+ Rechner einlesen (z.B. wenn Sie Disketten anderer Formate haben, die von
+ Ihrem Rechner nicht gelesen werden können).
+
+ Dabei werden zwei Anforderungen an die Zieltask gestellt: Sie muß existieren
+ und bereit für den Dateiaustausch sein, d.h es muß eine Managertask sein, auf
+ die Sie Zugriff haben. Versuchen Sie auf andere Tasks zuzugreifen, so erhalten
+ Sie entsprechende (Fehler-)Meldungen.
+#page#
+ Zu beachten ist noch, daß es im EUMEL-System verschiedene Arten von
+ Managertasks gibt - Archivmanager und normale Dateimanager. Der Unter­
+ schied besteht darin, daß ein Archivmanager vom Benutzer vor dem Zugriff
+ reserviert werden muß - anschließend hat nur dieser Benutzer (bis zur Aufga­
+ be der Reservierung) ein Zugriffsrecht auf den Manager. Normale Datei­
+ manager können dagegen von mehreren Benutzern in beliebiger Reihenfolge
+ angesprochen werden.
+
+ Ein Archivmanager kann auch auf bestimmte Diskettenformate spezialisert
+ sein (z.B. auf das Lesen von DOS-Disketten). Manche Rechner haben auch
+ mehrere Archivmanager für verschiedene Laufwerke etc. Durch Einstellen
+ unterschiedlicher Archivmanager können Sie dann auf verschiedenen Lauf­
+ werken archivieren.
+
+ Nach Aktivieren dieses Menupunktes werden Ihnen die folgenden Alternativen
+ angeboten:
+#on("b")#
+ +-------------------------------------------+
+ | Dateiaustausch gewünscht mit: |
+ | |
+ | a ...    Archiv (Eigene Station) |
+ | |
+ | v ...   Vatertask |
+ | |
+ | p ...   'PUBLIC' (Eigene Station) |
+ | |
+ | s ...   Sonstige Task |
+ | |
+ | Archiv   Vatertask   PUBLIC   Sonstige |
+ +-------------------------------------------+
+#off("b")#
+
+ Da der Dateiaustausch mit dem Standardarchiv der eigenen Station (Task:
+ 'ARCHIVE'), mit der Vatertask und der Task 'PUBLIC' recht häufig in Anspruch
+ genommen wird, sind diese drei Optionen unter den Alternativen direkt ange­
+ geben. Entscheiden Sie sich für eine dieser drei Tasks, so nimmt das System
+ alle notwendigen Einstellungen vor. Möchten Sie dagegen in Kontakt mit einer
+#page#
+ anderen Task treten, so wählen Sie die Alternative 's ... Sonstige Task'.
+ In diesem Falle haben Sie noch 3 Angaben zu machen:
+
+ - Zunächst werden Sie nach dem Namen der Zieltask gefragt. Geben Sie den
+ Namen der Zieltask - ohne Anführungsstriche (!) - ein und schließen Sie
+ die Eingabe mit der <RETURN>-Taste ab. (Den ausgegebenen Namen der
+ z.Z. eingestellten Task können Sie dabei verändern bzw. überschreiben.)
+
+ - Dann wird die Nummer der Station im EUMEL-Netz erfragt, auf der sich
+ die Zieltask befindet. Die Nummer Ihrer Station wird als Vorschlag ausge­
+ geben. Wollen Sie mit einer Task auf Ihrem Rechner kommunizieren, so
+ brauchen Sie diesen Vorschlag nur durch Drücken der <RETURN>-Taste
+ bestätigen - ansonsten tragen Sie zuvor die entsprechende Stationsnummer
+ ein. Ist Ihr Rechner nicht in ein EUMEL-Netz integriert, so wird die
+ Stationsnummer 0 (Null) ausgegeben. Bitte bestätigen Sie diese Stations­
+ nummer durch Tippen der <RETURN>-Taste.
+
+ - Zum Abschluß müssen Sie noch angeben, ob die eingestellte Zieltask ein
+ Archivmanager ist oder nicht.
+
+ Das System versucht dann den Kontakt herzustellen. Je nachdem, welche
+ Einstellung Sie vorgenommen haben, sind bestimmte Funktionen innerhalb
+ des Menus nicht aktivierbar. Das System läßt nur die Funktionen zu, die
+ aufgrund Ihrer Einstellungen zulässig sind.
+
+ Im Kasten links unten auf dem Bildschirm wird jeweils angezeigt, welche
+ Zieltask eingestellt ist. Erscheint in diesem Kasten auch ein Hinweis auf den
+ Archivnamen, so haben Sie einen Archivmanager eingestellt. Ist dagegen vor
+ dem Namen der Zieltask noch eine Zahl und ein Schrägstrich angegeben, so
+ haben Sie eine Zieltask auf einem anderen Rechner eingestellt.
+
+ Bedenken Sie, daß Operationen mit Tasks auf anderen Stationen länger an­
+ dauern können - werden Sie nicht ungeduldig!
+#page#
+ Sie können die Einstellung der Zieltask jederzeit wieder verändern!
+
+ Fehlerfälle:
+ - Die eingestellte Zieltask existiert nicht.
+ - Die eingestellte Zieltask existiert zwar, ist aber nicht empfangsbereit, d.h.
+ ein Zugriff von Ihrer Task aus ist nicht möglich!
+ - Das Netz ist nicht funktionsbereit (Collector-Task fehlt).
+ - Die Kommunikation war nicht erfolgreich.
+ - Die gewünschte Operation kann mit der eingestellten Zieltask nicht ausge­
+ führt werden (Zieltask ist z.B. gar kein Archivmanager - Sie aber ver­
+ suchen, das Laufwerk zu reservieren).
+
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-6 b/doc/warenhaus/gs-Warenhaus-6
new file mode 100644
index 0000000..3edf312
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-6
@@ -0,0 +1,589 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (61)#
+#headodd#
+#center#gs-Warenhaus#right#%
+
+#end#
+#headeven#
+%#center#gs-Warenhaus
+
+#end#
+#center#1
+
+#center##on("b")#6  Beschreibung der Programmierschnittstelle#off("b")#
+
+
+In allen GRIN-Projekten soll - zumindest als Erweiterung - der Aspekt des
+"algorithmischen Problemlösens" mit in den Unterricht eingebracht werden. Deshalb
+ist auch in dem Soester Programm zum Projekt WARENHAUS eine Programmier­
+schnittstelle realisiert, die es erlaubt, mit Hilfe eines eng begrenzten Befehlssatzes
+kleine Programme zur Steuerung der Abläufe im Modell-Warenhaus zu schreiben.
+
+Wir haben lange überlegt, ob wir diese Programmierschnittstelle überhaupt nach­
+bilden sollten, weil wir der Meinung sind, daß beim Projekt WARENHAUS das
+algorithmische Problemlösen, wenn überhaupt, nur eine sehr untergeordnete Rolle
+spielt. Als Randproblematik kann man hier vielleicht untersuchen, wie die Menu-
+Funktionen unter dem Oberbegriff 'Kommandos' (vgl. Kapitel 5.4) aufgebaut sind,
+und man kann versuchen, diese in eigenen kleinen Programmen nach- oder umzu­
+bilden.
+
+Unser zweites Problem war, ob wir uns bei einer eventuellen Nachbildung der
+Programmierschnittstelle auch wirklich streng an die Soester Vorgaben halten sollten,
+auch wenn sie unseren Vorstellungen und Konzepten teilweise zuwiderlaufen. Eigent­
+lich sind wir der Meinung, daß uns mit der Programmiersprache ELAN bereits ein
+ausgezeichnetes Hilfsmittel zur Verfügung steht, um auch in der Sekundarstufe I in
+das algorithmische Problemlösen einzuführen. Gerade das Refinementkonzept - die
+Methode der 'schrittweisen Verfeinerung' / der "Modularisierung im Kleinen" -
+scheint uns besonders geeignet, typische Denkweisen des algorithmischen Problem­
+lösens offenzulegen. Lediglich die Konstruktion einer Zählschleife und den Umgang
+mit den Fehlermeldungen des ELAN-Compilers halten wir bei Anfängern für etwas
+problematisch.
+
+Wir haben uns deshalb entschlossen, Ihnen die Programmierschnittstelle in zwei
+Versionen zur Verfügung zu stellen: In der 'ELAN-Version' können Sie in der üblichen
+#page#
+ELAN-Umgebung programmieren; das bietet sich z.B. an, wenn Sie #on("b")#gs-Warenhaus#off("b")#
+im Wahlpflichtbereich bzw. im Differenzierungsbereich 9/10 einsetzen möchten. Es
+ist dann dort nicht nötig, erst eine neue, weniger komfortable "Programmiersprache"
+zu erlernen.
+
+Für den GRIN-Bereich enthält #on("b")#gs-Warenhaus#off("b")# eine weitere Programmierebene
+('GRIN-Version'), die an die Soester Vorgaben angelehnt ist, und die es erlaubt, die
+dort benutzten Schreibweisen von Befehlen und Kontrollstrukturen zu übernehmen.
+Allerdings haben wir dabei eine grundsätzliche Änderung bezüglich der Modularisie­
+rungsmöglichkeit von 'GRIN-Programmen' vorgenommen, auf die wir in Kapitel 6.1
+näher eingehen werden.
+
+Ein 'GRIN-Programm' wird bei der Ausführung des Menupunktes 's Starten' (vgl.
+Kapitel 5.5) zunächst in ein ELAN-Programm übersetzt und dabei auf formale
+Korrektheit überprüft. Werden keine Fehler festgestellt, so wird nun seinerseits das
+ELAN-Programm vom Compiler übersetzt und anschließend ausgeführt. Als Benutzer
+werden Sie dabei nicht mit Fehlermeldungen des Compilers konfrontiert, da der
+#on("b")#gs-Warenhaus#off("b")#-Übersetzer vorher alle formalen Fehler abfängt und zum Korrigieren
+anbietet.
+
+Sollte das System nach erfolgreicher Übersetzung und/oder Compilation bei der
+Ausführung des Programms einen Fehler "bemerken" (z.B. falscher Aufruf eines
+Befehles), so wird das Programm automatisch abgebrochen und die entsprechende
+Fehlermeldung mit der Nummer der Programmzeile, in der der Fehler bemerkt
+wurde, im unteren Teil des Bildschirmes in einem 'notebook' gezeigt. Im oberen Teil
+wird das Programm zum Verbessern angeboten, wobei der Cursor am Anfang der
+fehlerhaften Zeile steht (gilt auch für die 'ELAN-Version').
+
+In beiden Versionen der Programmierschnittstelle ist die Schreibweise der Befehle bis
+auf die Groß- und Kleinschreibung identisch. Folgende Befehle stehen zu Verfügung:
+#page#
+ GRIN-Version | ELAN-Version
+------------------------+------------------------------
+ Artikelnummer lesen | artikelnummer lesen
+ Artikeldaten eingeben | artikeldaten eingeben
+ Kundennummer lesen | kundennummer lesen
+ Kundendaten eingeben | kundendaten eingeben
+ neues Blatt | neues blatt
+ Rechnungskopf | rechnungskopf
+ Artikel kaufen | artikel kaufen
+ Abrechnung | abrechnung
+ Auskunft | auskunft
+ Bildschirm neu | bildschirm neu
+ | nachbestellen
+ | dezimalwert lesen
+ | bitmuster lesen
+ |
+
+
+Die drei letzten Befehle der ELAN-Version haben wir in den GRIN-Befehlssatz nicht
+mit aufgenommen, weil wir hier den Befehlssatz möglichst klein (und damit über­
+sichtlich) halten wollten und diese Befehle bereits unter dem Oberbegriff
+'Kommandos' als Menu-Funktionen zur Verfügung stehen. (Ebenso könnte man bei
+dem Befehl 'Auskunft' argumentieren. Die entsprechende Menu-Funktion 'Auskunft
+einholen' liefert bei jeder Anwahl jedoch immer nur #on("b")#eine#off("b")# Auskunft; in einem
+Programm kann man nun die Ausgabe mehrerer Auskünfte hintereinander
+realisieren.)
+
+Die genaue Wirkung der Befehle werden wir in Kapitel 6.3 noch detailliert
+beschreiben. Sie entsprechen im wesentlichen den Soester Befehlen, die im
+WARENHAUS-Begleitheft des LSW (siehe Anhang) auf den Seiten 99/100 aufgelistet
+sind. (Die anderen dort zu findenden Befehle gehören eigentlich nicht in die Befehls­
+liste der Programmierschnittstelle, weil sie nicht von Programmen aus sondern nur in
+einem 'Direktbefehgs-Modus' als Kommando aufrufbar sind! Diese Befehle sind auch
+#page#
+#on("b")#keine#off("b")# Programmierbefehle im eigentlichen Sinne, sondern entweder "Macros" zum
+"Handling" des Warenhausmodells oder Systemkommandos. #on("b")#gs-Warenhaus#off("b")# stellt
+diese Befehle unter ähnlichen Namen als Menu-Funktionen zur Verfügung.)
+
+
+
+#on("b")#6.1  Schreibweisen und Syntaxregeln in GRIN-Programmen#off("b")#
+
+Die Regeln, die beim Schreiben eines ELAN-Programms zu beachten sind, werden im
+EUMEL/ELAN-Benutzerhandbuch beschrieben; wir werden uns daher hier auf die
+GRIN-Version konzentrieren.
+
+Beginnen wir mit einem Beispiel aus dem WARENHAUS-Begleitheft des LSW. Dort
+finden Sie auf Seite 70 (unten) das folgende Programm:
+
+#on("b")#
+ PROGRAMM Rechnung schreiben
+ neues Blatt
+ Kundennummer lesen
+ WENN nicht Stoptaste gedrückt
+ Rechnungskopf
+ WIEDERHOLE
+ Artikelnummer lesen
+ WENN nicht Stoptaste gedrückt
+ Artikel kaufen
+ ENDE WENN
+ BIS Stoptaste gedrückt
+ Abrechnung
+ ENDE WENN
+ ENDE PROGRAMM #off("b")#
+
+Sie können dieses Programm ohne Änderungen übernehmen und starten,
+#on("b")#gs-Warenhaus#off("b")# wird es ohne Beanstandungen ausführen. Bezüglich der Übersicht­
+lichkeit und des Programmierstils kann man hier sicher geteilter Meinung sein,
+darauf gehen wir später noch ein.
+#page#
+Wir möchten Ihnen zunächst einige Regeln zur Schreibweise und Syntax in 'GRIN-
+Programmen' aufzeigen, die sich im obigen Beispiel-Programm beobachten lassen:
+
+- In jeder Zeile darf nur #on("b")#ein#off("b")# Befehl stehen; Befehgs-Trennzeichen (wie etwa das
+ Semikolon in ELAN) werden deshalb nicht verwendet. Leerzeichen können
+ beliebig gesetzt werden, auch leere Zeilen sind zulässig, nicht jedoch
+ Kommentare.
+
+- Das Arbeiten mit Variablen (gleich welcher Art) ist #on("b")#nicht#off("b")# möglich; alle Befehle
+ sind datentypfrei.
+
+- Schlüsselworte für Kontrollstrukturen (wie z.B. WIEDERHOLE, WENN etc.)
+ werden in GROSSBUCHSTABEN geschrieben, Ausführungsbefehle und
+ Bedingungen hingegen klein und gemäß den Regeln der deutschen Sprache mit
+ großem Anfangsbuchstaben bei Substantiven. Diese Festlegung bezüglich der
+ Groß- und Kleinschreibung ist bei den von #on("b")#gs-Warenhaus#off("b")# zur Verfügung ge­
+ stellten Befehlen #on("b")#verbindlich#off("b")#, d.h. alle Warenhaus-#on("b")#Grund#off("b")#befehle und Kontroll­
+ strukturen müssen (bis auf Leerzeichen) genauso geschrieben werden, wie sie in
+ den Kapiteln 6.2 und 6.3 vorgegeben werden! (In der Soester Software können
+ dagegen Groß- und Kleinbuchstaben beliebig verwendet werden, sodaß dort z.B.
+ neben 'neues Blatt' auch 'neues blatt', "NEueS BlaTT" u.ä. als identisch ange­
+ sehen werden.)
+
+- Jedes 'GRIN-Programm' beginnt mit dem 'Schlüsselwort' <PROGRAMM>,
+ gefolgt von einem Programmnamen, der beliebig gewählt werden kann, jedoch
+ noch in diese Zeile passen muß. Sinnvoll ist es, hier z.B. den Namen der
+ Programmdatei einzutragen.
+
+- Jedes 'GRIN-Programm' endet mit der Zeile <ENDE PROGRAMM>. Nach dieser
+ Zeile dürfen nur noch leere Zeilen folgen, es sei denn zwischen <PROGRAMM
+ Programmname> und <ENDE PROGRAMM> wurden Befehle benutzt, die
+ nicht zum Warenhaus-Grundbefehlssatz gehören. Solche Befehle müssen in einer
+ 'Befehlserklärung' nach Programmende definiert werden.
+#page#
+Das obige Programm befriedigt vom äußeren Erscheinungbild her einen PASCAL-
+Programmierer wahrscheinlich völlig, einen ELAN-Verwöhnten jedoch sicher nicht.
+Die Soester WARENHAUS-Software bietet keinerlei Möglichkeit der Modularisierung
+#on("b")#innerhalb#off("b")# eines Programms (Refinement-/Prozedurkonzept o.ä.). Es gibt dort nur die
+Möglichkeit, fertiggestellte Programme unter dem Programmnamen dem Basis­
+befehlssatz "hinzuzufügen" - ein Vorgang, der dem Insertieren unter EUMEL/ELAN
+ähnelt. Obwohl es unter EUMEL/ELAN ein leichtes gewesen wäre, diese Möglichkeit
+ebenfalls zu realisieren, haben wir davon Abstand genommen, weil auf diese Weise an
+jedem Arbeitsplatz eine "eigene" Programmierumgebung entstehen würde. Wir sind
+der Meinung, daß für Schüler der Sekundarstufe I eine #on("b")#feste Modellumgebung als
+Basis#off("b")# vorhanden sein muß. Außerdem erscheint uns bei der Programmierung "im
+Kleinen" die "Bottom-Up"-Technik unangemessen und für den Anfänger viel zu
+unübersichtlich zu sein; viel eher wäre hier die "Top-Down"-Methode angebracht. Wir
+haben daher die Programmierumgebung in anderer Richtung erweitert und eine
+Modularisierungsmöglichkeit realisiert, die dem Refinementkonzept nachempfunden
+ist und damit unseren didaktisch-methodischen Vorstellungen viel eher entspricht.
+
+Bei #on("b")#gs-Warenhaus#off("b")# werden etwa benutzte 'eigene' Befehle #on("b")#innerhalb derselben#off("b")#
+Programmdatei 'erklärt' und zwar #on("b")#nach#off("b")# dem Ende des eigentlichen 'Haupt­
+programms', d.h. also nach der Zeile <ENDE PROGRAMM>. Mit Hilfe dieser Mög­
+lichkeit könnte das obige Programm besser strukturiert etwa so aussehen:
+
+#on("b")#
+ PROGRAMM Rechnung schreiben
+ neues Blatt
+ Kundennummer lesen
+ WENN nicht Stoptaste gedrückt
+ einkaufen mit Rechnung
+ ENDE WENN
+ ENDE PROGRAMM
+
+ einkaufen mit Rechnung:
+ Rechnungskopf
+ WIEDERHOLE
+ Artikelnummer lesen
+ Artikel eventuell kaufen
+ BIS Stoptaste gedrückt
+ Abrechnung
+#page#
+ Artikel eventuell kaufen:
+ WENN nicht Stoptaste gedrückt
+ Artikel kaufen
+ ENDE WENN
+#off("b")#
+
+
+Sie sehen, das Programm ist so zwar etwas länger, aber erheblich übersichtlicher
+geworden. Für 'neue Befehle' und die zugehörigen 'Befehlserklärungen' gelten
+folgende Grundsätze:
+
+- Die 'Befehlserklärungen' müssen #on("b")#nach#off("b")# <ENDE PROGRAMM> aufgelistet
+ werden. Die Reihenfolge ist beliebig.
+
+- Eine 'Befehlserklärung' besteht aus dem zu erklärenden Befehl in (bis auf Leer­
+ zeichen) völlig identischer Schreibweise (!) und einem nachfolgenden Doppel­
+ punkt (:).
+
+- Ein 'neuer Befehl' darf alle möglichen Zeichen enthalten außer einem Doppel­
+ punkt (:). Außerdem darf solch ein Befehl #on("b")#nicht#off("b")# mit einem 'Schlüsselwort'
+ beginnen (vgl. Kapitel 6.2).
+
+- In 'Befehlserklärungen' können neben den Grundbefehlen auch wieder 'neue
+ Befehle' benutzt werden, die dann wiederum erklärt werden müssen.
+
+- Befehle dürfen nur #on("b")#einmal#off("b")# erklärt werden, auch wenn sie mehrfach benutzt
+ werden.
+
+- Es dürfen nur Befehle erklärt werden, die irgendwo auch wirklich benutzt
+ werden.
+
+- Befehlserklärungen sind nur möglich für #on("b")#Ausführungs-Befehle#off("b")#. Es lassen sich
+ also z.B. keine neuen Bedingungen oder Kontrollstrukturen erklären!
+
+- Es dürfen innerhalb eines Programms maximal 20 verschiedene 'neue Befehle'
+ verwendet werden. (Diese Grenze dürfte in Warenhaus-Programmen kaum ein­
+ mal erreicht werden!)
+#page#
+Formale Verstöße gegen diese Regeln werden bei dem Übersetzungsvorgang sofort
+beim Auftauchen des ersten Fehlers zur Korrektur angeboten. Dabei wird in der
+oberen Bildschirmhälfte das Programm editiert, wobei der Cursor an den Anfang der
+Zeile gesetzt wird, in der sich der (erste) Fehler befindet. In der unteren Bildschirm­
+hälfte wird über den Paralleleditor in einem 'notebook' die Art des Fehlers mit An­
+gabe der Zeilennummer genauer beschrieben.
+
+In der Regel wird hier nur auf #on("b")#einen#off("b")# (nämlich den ersten auftauchenden) Fehler
+hingewiesen, so daß Sie das Programm evtl. mehrfach starten müssen, bis alle Fehler
+erkannt und beseitigt sind. Manchmal tauchen im Fehler-'notebook' aber auch
+mehrere Fehlermeldungen auf (z.B. wenn 'neue Befehle' nicht erklärt oder erklärte
+Befehle nicht benutzt wurden). In Extremfällen kann es dabei dazu kommen, daß
+nicht mehr das ganze Fehler-'notebook' auf dem Bildschirm sichtbar ist. In diesem
+Fall können Sie mit der Tastenfolge <ESC><w> den Cursor zwischen den beiden
+Bildschirmhälften hin- und herschalten und mit den Pfeiltasten evtl. nicht-sichtbare
+Teile des 'notebooks' oder der Programmdatei auf den Bildschirm holen. (Für
+genauere Informationen über den Umgang mit dem EUMEL-Editor lesen Sie bitte im
+EUMEL-Benutzerhandbuch nach.)
+
+
+#on("b")#6.2  Kontrollstrukturen#off("b")#
+
+Sowohl in ELAN-Programmen, als auch in GRIN-Programmen werden Kontroll­
+strukturen durch 'Schlüsselworte' gekennzeichnet, die grundsätzlich in
+GROSSBUCHSTABEN geschrieben werden müssen, um sie deutlich gegenüber Aus­
+führungsbefehlen und Bedingungen abzuheben. In GRIN-Programmen gibt es
+Schlüsselworte für den Anfang und das Ende eines Programms sowie für Schleifen
+und einseitige Abfragen. Wir notieren hier nur die in GRIN-Programmen möglichen
+Kontrollstrukturen und geben, wenn vorhanden, die zugehörige ELAN-Übersetzung in
+Klammern an.
+
+
+#on("b")#Programm-Anfang/Ende:#off("b")#
+
+ #on("b")#PROGRAMM#off("b")# <Programmname>
+ <Anweisung 1>
+ <Anweisung 2>
+ .
+ .
+ #on("b")#ENDE PROGRAMM#off("b")#
+
+
+Jedes GRIN-(Haupt-)Programm beginnt mit dem Schlüsselwort 'PROGRAMM', gefolgt
+von einem frei wählbaren Programmnamen, der jedoch in dieselbe Zeile passen
+muß. Die Zeile 'ENDE PROGRAMM' zeigt das Ende eines GRIN-(Haupt-)Programms
+an. Sowohl 'PROGRAMM', als auch 'ENDE PROGRAMM' dürfen in einer Programm­
+datei nur #on("b")#einmal#off("b")# verwendet werden. Entsprechende Schlüsselworte in ELAN-
+Programmen gibt es nicht.
+
+
+#on("b")#Schleifen:#off("b")#
+
+Schleifen müssen innerhalb des Hauptprogramms oder der Befehlserklärung, in der
+sie geöffnet werden, auch wieder geschlossen werden. Schachtelungen sind zwar
+zulässig, sollten aber aus Gründen der Übersichtlichkeit vermieden werden. Soll
+dennoch innerhalb einer Schleife eine weitere Schleife verwendet werden, so sollte die
+innere Schleife über einen 'neuen Befehl' in eine Befehlserklärung 'ausgelagert'
+werden. Folgende Schleifenarten sind möglich:
+
+a) Zählschleife:
+
+ #on("b")#WIEDERHOLE#off("b")# <n> #on("b")#MAL#off("b")# (ELAN: INT VAR i;
+ <Anweisung 1> FOR i FROM 1 UPTO n REPEAT
+ <Anweisung 2> .
+ . .
+ . .
+ #on("b")#ENDE WIEDERHOLE#off("b")# END REPEAT)
+
+
+Die Anweisungen innerhalb der Schleife werden <n> - mal ausgeführt.
+
+
+b) Schleife mit Ausgangsbedingung:
+
+
+ #on("b")#WIEDERHOLE#off("b")# (ELAN: REPEAT
+ <Anweisung 1> .
+ <Anweisung 2> .
+ . .
+ . .
+ #on("b")#BIS#off("b")# <Bedingung> UNTIL bedingung END REPEAT)
+
+
+Die Anweisungen innerhalb der Schleife werden mindestens einmal ausgeführt und
+dann solange wiederholt, bis die Bedingung erfüllt ist. Bei der Programmierung ist
+darauf zu achten, daß durch die Anweisungen die Bedingung erfüllt werden kann,
+denn sonst ist das Resultat eine 'Endlosschleife', deren Ausführung nur durch einen
+totalen Programmabbruch (<ESC><h>) beendet werden kann.
+
+
+c) Zählschleife mit Ausgangsbedingung:
+
+
+ #on("b")#WIEDERHOLE#off("b")# <n> #on("b")#MAL#off("b")# (ELAN: INT VAR i;
+ <Anweisung 1> FOR i FROM 1 UPTO n REPEAT
+ <Anweisung 2> .
+ . .
+ . .
+ #on("b")#BIS#off("b")# <Bedingung> UNTIL bedingung END REPEAT)
+
+
+Die Anweisungen innerhalb der Schleife werden <n>-mal ausgeführt. Im Gegensatz
+zur reinen Zählschleife können die Wiederholungen jedoch vorzeitig abgebrochen
+werden, nämlich dann, wenn nach irgendeinem Schleifendurchlauf die Bedingung
+erfüllt ist.
+
+
+d) Endlosschleife:
+
+
+ #on("b")#WIEDERHOLE#off("b")# (ELAN: REPEAT
+ <Anweisung 1> .
+ <Anweisung 2> .
+ . .
+ . .
+ #on("b")#ENDE WIEDERHOLE#off("b")# END REPEAT)
+
+
+Die Anweisungen innerhalb der Schleife werden immer wieder ausgeführt. Da keine
+begrenzte Anzahl von Durchläufen und auch keine Abbruchbedingung angegeben ist,
+kann diese Schleife nur durch einen totalen Programmabbruch (<ESC><h>)
+beendet werden.
+
+(Die Schleifenarten c) und d) sind in der Soester WARENHAUS-Software nicht vor­
+ handen, ergaben sich bei der Konstruktion des #on("b")#gs-Warenhaus#off("b")#-Übersetzers wegen
+ der analogen Strukturen in ELAN jedoch quasi "von selbst", so daß wir sie auch
+ zugelassen haben. Schleifen mit Eingangsbedingung (ELAN: WHILE bedingung
+ REPEAT ... END REPEAT) sind für GRIN-Programme jedoch nicht realisiert.)
+
+
+#on("b")#Einseitige Abfragen:#off("b")#
+
+
+ #on("b")#WENN#off("b")# <Bedingung> (ELAN: IF bedingung
+ <Anweisung 1> THEN anweisung 1;
+ <Anweisung 2> anweisung 2;
+ . .
+ . .
+ #on("b")#ENDE WENN#off("b")# END IF)
+
+
+Die Anweisungen werden nur ausgeführt, wenn die Bedingung erfüllt ist. (Eine Ent­
+sprechung zu der in ELAN möglichen 'zweiseitigen Abfrage' (IF ... THEN ... ELSE ...
+END IF) gibt es in der GRIN-Version nicht!)
+
+Eine im Hauptprogramm oder in einer Befehlserklärung begonnene Abfrage ('WENN
+...') muß auch im selben Programmteil wieder beendet werden. Ähnlich wie bei
+Schleifen ist die Schachtelung von Abfragen innerhalb des Hauptprogramms oder
+einer Befehlserklärung zwar zulässig, führt aber zu unübersichtlichen Programmen.
+Auch hier sollte man innerhalb einer Abfrage eventuell notwendige weitere Abfragen
+durch 'neue Befehle' in Befehlserklärungen auslagern.
+
+
+#on("b")#Zulässige Bedingungen:#off("b")#
+
+#on("b")#Stoptaste gedrückt#off("b")# (ELAN: stoptaste gedrückt)
+
+ Die Bedingung ist erfüllt (d.h. liefert den Wert 'wahr'), wenn während des bis­
+ herigen Programmablaufs die Tastenfolge <ESC><q> getippt worden ist;
+ sonst ist sie nicht erfüllt (Wahrheitswert 'falsch'). (Das Tippen von <ESC><q>
+ beim Verlassen einer Datei hat jedoch #on("b")#keinen#off("b")# Einfluß auf den Wahrheitswert der
+ Bedingung!)
+
+ Bei jeder Ausführung der Befehle 'Artikelnummer lesen', 'Kundennummer lesen'
+ und 'Auskunft' wird der Wahrheitswert der Bedingung zunächst immer auf
+ 'falsch' gesetzt (siehe 6.3), so daß die Abfrage der Bedingung nach einem dieser
+ Befehle nur dann 'wahr' liefert, wenn #on("b")#während#off("b")# oder #on("b")#nach#off("b")# der letztmaligen Aus­
+ führung eines der drei Befehle <ESC><q> getippt wurde; ein etwa vorher
+ erfolgtes Tippen dieser Tastenfolge ist somit wirkungslos!
+
+
+#on("b")#nicht Stoptaste gedrückt#off("b")# (ELAN: NOT stoptaste gedrückt)
+
+ Dieses ist das logische Gegenteil von 'Stoptaste gedrückt': 'nicht Stoptaste ge­
+ drückt' ist erfüllt, wenn 'Stoptaste gedrückt' #on("b")#nicht#off("b")# erfüllt ist und umgekehrt.
+
+Um Probleme bei der Arbeit mit Terminals zu vermeiden, die nicht über den
+deutschen Zeichensatz verfügen (Umlaute!), ist bei beiden Bedingungen auch die
+Schreibweise 'gedrueckt' erlaubt.
+
+
+
+#on("b")#6.3  Detailbeschreibung der Warenhaus-Grundbefehle#off("b")#
+
+Wie bereits in 6.1 erwähnt, ist die im folgenden vorgegebene Schreibweise der Grund­
+befehle bezüglich Groß- und Kleinschreibung verbindlich; Leerzeichen dagegen
+können beliebig eingefügt oder auch weggelassen werden. Fett gedruckt steht immer
+der GRIN-Befehl, in Klammern dahinter der zugehörige ELAN-Befehl.
+
+
+#on("b")#Artikelnummer lesen#off("b")# (ELAN: artikelnummer lesen)
+
+ - Der Wahrheitswert der Bedingung 'Stoptaste gedrückt' wird zunächst auf
+ 'falsch' gesetzt.
+ - Der Benutzer wird aufgefordert, eine Artikelnummer einzugeben. Je nach
+ Einstellung der 'Eingabeart' (vgl. Kapitel 5.3) erfolgt die Eingabe durch Ein­
+ tippen einer Zahl über die Tastatur oder durch Einschieben einer Warenkarte
+ in das Lesegerät. Eingaben über die Tastatur sind mit <RETURN> abzu­
+ schließen. Akzeptiert werden nur Werte von 1 bis 15, ansonsten erfolgt eine
+ Warnung, und die Eingabe wird wiederholt.
+ - Durch Tippen der Tastenfolge <ESC><q> kann dieser Befehl abgebrochen
+ werden, ohne daß eine Artikelnummer eingelesen wird. In diesem Falle wird
+ der Wahrheitswert der Bedingung 'Stoptaste gedrückt' auf 'wahr' gesetzt, sonst
+ bleibt der Wert auf 'falsch'.
+ - Durch Tippen der Tastenfolge <ESC><h> wird die Ausführung des
+ gesamten Programms abgebrochen.
+
+
+#on("b")#Artikeldaten eingeben#off("b")# (ELAN: artikeldaten eingeben)
+
+ - Der Befehl setzt voraus, daß zuvor eine Artikelnummer eingelesen wurde,
+ ansonsten erfolgt eine entsprechende Fehlermeldung.
+ - Die Angaben zu einem Artikel (Name, Preis, Mindestbestand, Bestand) können
+ eingegeben bzw. verändert werden.
+ - Alle Eingaben sind mit <RETURN> oder der Tastenfolge <ESC><q>
+ abzuschließen. Durch <ESC><q> wird der Wahrheitswert der Bedingung
+ 'Stoptaste gedrückt' auf 'wahr' gesetzt.
+ - Nach Abschluß der Eingaben werden die Artikeldaten in der Filial-Verwaltung
+ gespeichert, worauf auch kurz hingewiesen wird.
+ - Durch Tippen der Tastenfolge <ESC><h> während der Eingaben wird die
+ Ausführung des gesamten Programms abgebrochen.
+
+
+#on("b")#Kundennummer lesen#off("b")# (ELAN: kundennummer lesen)
+
+ - Der Wahrheitswert der Bedingung 'Stoptaste gedrückt' wird zunächst auf
+ 'falsch' gesetzt.
+ - Der Benutzer wird aufgefordert, eine Kundennummer einzugeben. Je nach
+ Einstellung der 'Eingabeart' (vgl. Kapitel 5.3) erfolgt die Eingabe durch Ein­
+ tippen einer Zahl über die Tastatur oder durch Einschieben einer Kundenkarte
+ in das Lesegerät. Eingaben über die Tastatur sind mit <RETURN> abzu­
+ schließen. Akzeptiert werden nur Werte von 129 bis 159, ansonsten erfolgt eine
+ Warnung, und die Eingabe wird wiederholt.
+ - Durch Tippen der Tastenfolge <ESC><q> kann dieser Befehl abgebrochen
+ werden, ohne daß eine Kundennummer eingelesen wird. In diesem Falle wird
+ der Wahrheitswert der Bedingung 'Stoptaste gedrückt' auf 'wahr' gesetzt, sonst
+ bleibt der Wert auf 'falsch'.
+ - Durch Tippen der Tastenfolge <ESC><h> wird die Ausführung des
+ gesamten Programms abgebrochen.
+
+
+#on("b")#Kundendaten eingeben#off("b")# (ELAN: kundendaten eingeben)
+
+ - Der Befehl setzt voraus, daß zuvor eine Kundennummer eingelesen wurde,
+ ansonsten erfolgt eine entsprechende Fehlermeldung.
+ - Die Angaben zu einem Kunden (Name, Vorname, Geschlecht) können einge­
+ geben bzw. verändert werden.
+ - Alle Eingaben sind mit <RETURN> oder der Tastenfolge <ESC><q>
+ abzuschließen. Durch <ESC><q> wird der Wahrheitswert der Bedingung
+ 'Stoptaste gedrückt' auf 'wahr' gesetzt.
+ - Nach Abschluß der Eingaben werden die Kundendaten sowohl in der Filial-
+ Verwaltung als auch in der Zentrale gespeichert, worauf auch kurz hingewiesen
+ wird.
+ - Durch Tippen der Tastenfolge <ESC><h> während der Eingaben wird die
+ Ausführung des gesamten Programms abgebrochen.
+
+
+#on("b")#neues Blatt#off("b")# (ELAN: neues blatt)
+
+ - Das Rechnungsfenster auf dem Bildschirm wird gelöscht.
+ - Für die Ausgabe der nächsten Rechnung auf dem Drucker wird eine neue
+ Rechnungsdatei bereitgestellt.
+
+
+#on("b")#Rechnungskopf#off("b")# (ELAN: rechnungskopf)
+
+ - Ein Rechnungskopf wird auf dem Bildschirm ausgegeben. Falls zuvor eine
+ Kundenummer eingelesen worden ist, unter der bereits Kundendaten einge­
+ geben wurden, erscheint der Name des betreffenden Kunden im Rechnungs­
+ kopf.
+ - Der Rechnungskopf wird für einen eventuellen späteren Ausdruck in die
+ Rechnungsdatei geschrieben.
+
+
+#on("b")#Artikel kaufen#off("b")# (ELAN: artikel kaufen)
+
+ - Der Befehl setzt voraus, daß zuvor eine Artikelnummer eingelesen worden ist,
+ ansonsten erfolgt eine entsprechende Fehlermeldung.
+ - Artikelname und -preis werden auf den Bildschirm und in die Rechnungsdatei
+ geschrieben.
+ - Der Kauf wird intern in den entsprechenden Filial-Dateien registriert.
+
+
+#on("b")#Abrechnung#off("b")# (ELAN: abrechnung)
+
+ - Die Preise der gekauften Artikel werden addiert.
+ - Die Summe wird auf dem Bildschirm angezeigt und in die Rechnungsdatei
+ geschrieben.
+ - Der Benutzer wird gefragt, ob die Rechnung ausgedruckt werden soll.
+
+
+#on("b")#Auskunft#off("b")# (ELAN: auskunft)
+
+ - Der Wahrheitswert der Bedingung 'Stoptaste gedrückt' wird zunächst auf
+ 'falsch' gesetzt.
+ - Der Benutzer wird aufgefordert, eine Codenummer einzugeben. Je nach Ein­
+ stellung der 'Eingabeart' (vgl. Kapitel 5.3) erfolgt die Eingabe durch Eintippen
+ einer Zahl über die Tastatur oder durch Einschieben einer Codekarte in das
+ Lesegerät. Eingaben über die Tastatur sind mit <RETURN> abzuschließen.
+ Akzeptiert werden nur zulässige Werte, ansonsten erfolgt eine Warnung, und
+ die Eingabe wird wiederholt. Die Bedeutungen der einzelnen Auskunftscodes
+ sind in Kapitel 5.4 unter der Menufunktion 'Auskunft einholen' beschrieben.
+ - Durch Tippen der Tastenfolge <ESC><q> kann der Befehl abgebrochen
+ werden, ohne daß eine Codenummer eingelesen wird. In diesem Falle wird der
+ Wahrheitswert der Bedingung 'Stoptaste gedrückt' auf 'wahr' gesetzt, sonst
+ bleibt der Wert auf 'falsch'.
+ - Durch Tippen der Tastenfolge <ESC><h> wird die Ausführung des
+ gesamten Programms abgebrochen.
+
+
+#on("b")#Bildschirm neu#off("b")# (ELAN: bildschirm neu)
+
+ - Der Programm-Eingangsbildschirm wird neu aufgebaut. Der Befehl wird
+ benötigt, wenn die Fenstereinteilung auf dem Bildschirm wiederhergestellt
+ werden soll (z.B. nach Ausgabe einer Liste bei dem Befehl 'Auskunft').
+ - Der Befehl wird beim Starten eines GRIN-Programms automatisch ausgeführt;
+ bei ELAN-Programmen wird er automatisch am Anfang eines jeden Programms
+ eingefügt, wenn das Programm nicht mit diesem Befehl beginnt.
+
+
+Neben diesen Befehlen stehen für ELAN-Programme noch drei weitere zur Verfügung,
+die nicht zum GRIN-Befehlssatz gehören:
+
+ nachbestellen,
+ dezimalwert lesen,
+ bitmuster lesen.
+
+Diese Befehle entsprechen in ihrer Wirkung den gleichnamigen Menufunktionen
+unter dem Oberbegriff 'Kommandos', die in Kapitel 5.4 beschrieben sind.
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-7 b/doc/warenhaus/gs-Warenhaus-7
new file mode 100644
index 0000000..3a55dfe
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-7
@@ -0,0 +1,235 @@
+#limit (11.0)##pagelength (16.5)##block#
+#start (2.0,0.0)#
+#page (69)#
+#headodd#
+#center#gs-Warenhaus#right#%
+
+#end#
+#headeven#
+%#center#gs-Warenhaus
+
+#end#
+#center#1
+
+#center##on("b")#7  Weitere Kommandos (für Systembetreuer)#off("b")#
+
+
+Wenn Sie #on("b")#gs-Warenhaus#off("b")# installiert haben und mit dem Aufbau des Systems nach
+der automatischen Generierung zufrieden sind, dann ist dieses Kapitel nicht wichtig
+für Sie. Wir erklären Ihnen hier die Befehle, mit denen Sie die Einstellungen, die bei
+der Installation vorgenommen wurden, auch nachträglich noch ändern können.
+Beachten Sie bitte, daß aus Sicherheitsgründen eine Einstellungs#on("b")#änderung#off("b")# i.a. nur in
+der Task möglich ist, in der die entsprechende Einstellung vorgenommen wurde, es
+sei denn, dort wurde eine Einstellung gänzlich aufgehoben. Außerdem werden Ein­
+stellungsänderungen stets nur an Sohntasks weitergegeben ("vererbt"), die #on("b")#nach#off("b")# der
+Änderung angemeldet werden!
+
+Die Standard-Installation sieht z.B. nur die Einrichtung #on("b")#einer#off("b")# Warenhaus-Hauptstelle
+vor. Wenn Sie tatsächlich nur eine Hauptstelle eingerichtet haben, nun aber doch
+mehrere Hauptstellen (für verschiedene Lerngruppen) betreiben wollen, so brauchen
+Sie das Programm nicht erneut zu insertieren! Machen Sie besser in der bisherigen
+Hauptstellen-Task den Hauptstellenstatus mit dem Kommando 'warenhaus haupt­
+stelle (FALSE)' rückgängig und richten Sie in Sohntasks mit dem Kommando 'waren­
+haus hauptstelle (TRUE)' wieder neue Hauptstellen ein. Außerdem können Sie in
+Hauptstellen-Tasks die Version für die Programmierschnittstelle umstellen ('grin
+(TRUE)' bzw. 'grin (FALSE)').
+
+Ähnlich verhält es sich mit dem Betrieb eines Adapters für das Kartenleser-Interface.
+Auch hier ist die Standard-Einstellung u.U. nur für den Betrieb #on("b")#eines#off("b")# Adapters ausge­
+legt. Möchten Sie mehrere Kartenleser anschließen, so sind bei der Verwendung von
+MUFIs im Terminalkanal keine Änderungen nötig, da hier jede Filialtask sowieso nur
+auf das MUFI zugreifen kann, das in den Kanal des Terminals geschaltet ist, an das
+die Task gekoppelt ist. Möchten Sie jedoch mehrere Kartenleser über Adapter an
+separaten seriellen Schnittstellen ansprechen, so müssen Sie dem System mehrere
+Kanalnummern mitteilen, die für verschiedene Filialtasks ja durchaus unterschied­
+lich sein können. Am geschicktesten erscheint es in diesem Fall, unter einer Haupt­
+stelle mehrere "Zwischentasks" einzurichten, in diesen jeweils die Interface-
+Kanalnummern festzulegen und die Filialtasks als Söhne dieser "Zwischentasks"
+anzumelden. Benennen Sie die "Zwischentasks" so, daß die eingestellte Kanal­
+nummer aus dem Namen ersichtlich ist, so ist gleich bei der Anmeldung einer Filial­
+task klar, welcher Kartenleser von dieser Task aus angesprochen werden kann.
+
+Um diesen Aufbau zu realisieren, sollten Sie zunächst in der entsprechenden Haupt­
+stellentask einen etwa eingerichteten Direktstart mit dem Kommando 'warenhaus
+direktstart (FALSE)' aufheben. Ebenfalls in der Hauptstellentask wird dann mit dem
+Kommando 'init interface channel' eine etwa vorhandene Kanaleinstellung gelöscht,
+wenn Sie bei der Aufforderung 'Gib Interface-Kanal:' eine '0' eingeben. Nun richten
+Sie für jeden vorhandenen Adapter (natürlich müssen auch entsprechend viele freie
+serielle Schnittstellen zur Verfügung stehen!) eine "Zwischentask" als Sohn der
+Hauptstellentask ein (z.B. 'Kanal 5', 'Kanal 6' etc.) und geben dort jeweils wieder das
+Kommando 'init interface channel'. Bei der Abfrage 'Gib Interface-Kanal:' geben Sie
+dann die entsprechende Kanalnummer ein (in unserem Beispiel 5 oder 6 etc.). Alle
+Söhne der Zwischentask 'Kanal 5' z.B. können dann (abwechselnd) den Kartenleser
+benutzen, der an den Adapter an Kanal 5 angeschlossen ist. In diesen Zwischentasks
+können Sie, wenn Sie möchten, mit dem Kommando 'warenhaus direktstart (TRUE)'
+einen Direktstart für die neu anzumeldenden Sohntasks (Filialen) einrichten.
+Ansonsten wird #on("b")#gs-Warenhaus#off("b")# in den Sohntasks aus der 'gib Kommando' - Ebene
+mit dem Befehl 'warenhaus' gestartet (vgl. Kapitel 3.3).
+
+Sollten Sie beim Betrieb eines Codekartenlesers feststellen, daß die Wartezeit beim
+Einlesen einer Codekarte zu kurz oder zu lang ist, so können Sie auch diese ändern.
+Da die Wartezeit durch eine Schleife realisiert ist, in der laufend Werte vom Interface
+gelesen werden, ist sie abhängig von der Geschwindigkeit des verwendeten Rechners
+und von der gewählten Interface-Anpassung. Die Veränderung der Wartezeit erfolgt
+mit dem Kommando 'eingabesicherheit (n)', wobei n eine 'Integer'-Zahl sein muß.
+Bei sehr langsamen Systemen hat sich ein Wert von 3 als sinnvoll herausgestellt; bei
+schnellen Rechnern muß n etwa 10 oder noch größer sein. Ermitteln Sie den für
+Ihren Rechner geeigneten Wert bitte durch Ausprobieren. (Standardmäßig eingestellt
+ist n = 5.)
+
+Mit Hilfe von drei Informationsprozeduren können Sie Informationen über den
+Systemzustand einholen: 'put (hauptstellenname)' liefert den Namen der zu­
+ständigen Hauptstellen-Task, 'put (interface anpassung)' zeigt den Namen der bei
+der Installation gewählten Interfaceanpassung für den Kartenleser, und 'put (inter­
+face channel)' liefert die Nummer des Kanals, über den ein Interface an separater
+serieller Schnittstelle angesprochen wird.
+
+
+
+#on("b")#Detailbeschreibung der Befehle#off("b")#:
+
+
+#on("b")#PROC eingabesicherheit (INT CONST n):#off("b")#
+
+ - stellt die Wartezeit beim Einlesen einer Artikel-, Kunden- oder Auskunfts­
+ codenummer in Abhängigkeit vom Absolutbetrag von n ein. Bei langsamen
+ Rechnern sollte abs(n) klein (ca. 3), bei schnellen Rechnern größer (ca. 10)
+ sein.
+ - Standardeinstellung ist 5.
+ - Der Befehl kann in jeder Task gegeben werden, in der #on("b")#gs-Warenhaus#off("b")#
+ insertiert ist.
+
+
+#on("b")#PROC grin (BOOL CONST entscheidung):#off("b")#
+
+ - ist nur in Hauptstellentasks aufrufbar und in Tasks, die keiner Hauptstellen­
+ task untergeordnet sind.
+ - stellt die Version für die Programmierschnittstelle gemäß der 'entscheidung'
+ ein:
+ TRUE ---> GRIN-Version, FALSE ---> ELAN-Version.
+
+ Fehlerfälle:
+ - Dieser Befehl darf nur von der Task '...' aus gegeben werden!
+
+
+#on("b")#TEXT PROC hauptstellenname:#off("b")#
+
+ - liefert den Namen der zuständigen Hauptstellentask.
+ - liefert 'niltext' (""), wenn in diesem Zweig des Taskbaumes noch keine
+ Hauptstelle existiert; es ist dann kein Warenhaus-Betrieb möglich! (vgl.
+ 'PROC warenhaus hauptstelle')
+
+
+#on("b")#PROC init interfacechannel:#off("b")#
+
+ - initialisiert eine unbenannte Sohntask ("-") zum Ansprechen des Interface­
+ systems über eine separate serielle Schnittstelle und existiert deshalb nur bei
+ den Anpassungen für 'MUFI als Endgerät' und 'AKTRONIK-Adapter'.
+ - erfragt zunächst eine Kanalnummer ('Gib Interface-Kanal:'); zulässig sind
+ Eingaben von 0 bis 24.
+ - löscht eine evtl. bereits vorhandene unbenannte Sohntask ("-").
+ - richtet bei Eingabe einer Kanalnummer > 0 eine neue unbenannte Sohntask
+ ein und sperrt dieses Kommando für Sohntasks, die danach angemeldet
+ werden.
+ - hebt eine etwa gesetzte Sperrung bei Eingabe von 0 als Kanalnummer wieder
+ auf.
+
+ Fehlerfälle:
+ - Dieses Kommando kann nur von der Task '...' aus gegeben werden!
+ - Unzulässige Kanalnummer!
+
+
+#on("b")#TEXT PROC interface anpassung:#off("b")#
+
+ - liefert den Namen der bei der Installation ausgewählten Anpassung. Möglich
+ sind zur Zeit:
+
+ "ohne Kartenleser",
+ "mit Kartenleser an AKTRONIC-Adapter",
+ "mit Kartenleser an MUFI als Endgerät",
+ "mit Kartenleser an MUFI im Terminalkanal".
+
+
+#on("b")#INT PROC interface channel:#off("b")#
+
+ - existiert nur bei den Anpassungen für den AKTRONIC-Adapter und MUFI als
+ Endgerät.
+ - liefert die Kanalnummer der seriellen Schnittstelle, über die das Interface­
+ system angesprochen wird.
+ - wird der Wert 0 geliefert, so kann in der Task keine Eingabe über einen
+ Kartenleser erfolgen (siehe 'PROC init interfacechannel').
+
+
+#on("b")#PROC warenhaus:#off("b")#
+
+ - ist nicht in Hauptstellentasks aufrufbar.
+ - startet #on("b")#gs-Warenhaus#off("b")# aus der 'gib Kommando' - Ebene oder wird bei einge­
+ richtetem Direktstart automatisch aufgerufen.
+ - richtet eine Sohntask als Filialverwaltung ein und kennzeichnet damit die
+ eigene Task für das System als 'aktive' Filiale. Der Name dieser Sohntask
+ enthält den Namen der zuständigen Hauptstellentask und die Filialnummer,
+ unter der die Filiale geführt wird. Diese Filialnummer ist identisch mit der
+ Kanalnummer des angekoppelten Terminals.
+ - löscht die Filialverwaltungstask, wenn das Warenhaus-Menu geregelt mit
+ <ESC><q> verlassen wird. Zu Kollisionen bezüglich der Filialnummer
+ kann es somit nur kommen, wenn an einem Arbeitsplatz das WARENHAUS-
+ Menu ungeregelt verlassen wird (z.B. durch Tippen der SV-Taste) und dann
+ an demselben Arbeitsplatz eine neue Filiale angemeldet werden soll. In
+ diesem Fall erhält die neue Task #on("b")#keine#off("b")# Filialverwaltung als Sohntask und ist
+ damit für den Warenhaus-Betrieb nicht brauchbar. Deshalb wird hier nach
+ Ausgabe einer Fehlermeldung sofort gefragt, ob die Task gelöscht werden soll.
+
+ Fehlerfälle:
+ - Dieser Befehl darf nur von Söhnen dieser Task aus gegeben werden!
+ - Keine uebergeordnete Task ist 'warenhaus hauptstelle'!
+ - Filiale <n> ist bereits besetzt durch TASK '...'!
+ Es ist so kein geregelter Warenhaus-Betrieb möglich!
+
+
+#on("b")#PROC warenhaus direktstart (BOOL CONST entscheidung):#off("b")#
+
+ - richtet gemäß dem Wahrheitswert der 'entscheidung' einen Direktstart ein
+ oder hebt ihn wieder auf.
+ Hat 'entscheidung' den Wert 'TRUE', so wird ein Direktstart eingerichtet. Es
+ erscheint zunächst die Frage 'Mit automatischem Löschen (j/n)?'. Durch den
+ Direktstart gelangt man beim Anmelden einer Sohntask nicht in die 'gib
+ Kommando' - Ebene, sondern sofort in das WARENHAUS-Menu. Wird die
+ obige Frage mit <j> beantwortet, so werden Sohntasks nach dem Ausstieg
+ aus dem WARENHAUS-Menu sofort gelöscht; andernfalls wird erst noch ge­
+ fragt, ob gelöscht werden soll. Bei Verneinung erfolgt ein 'break'. Die Ein­
+ richtung eines Direktstarts wird vom System vermerkt und der Befehl darauf­
+ hin in allen untergeordneten Tasks gesperrt. Sowohl der Direktstart als auch
+ die Sperrung sind nur wirksam für Sohntasks, die #on("b")#nach#off("b")# Ausführung dieses
+ Befehls angemeldet werden.
+ Hat 'entscheidung' den Wert 'FALSE', so wird ein etwa eingerichteter Direkt­
+ start und die damit verbundene Sperrung des Befehls für neue Sohntasks
+ wieder aufgehoben. Die Aufhebung ist nur möglich in der Task, von der aus
+ der Direktstart eingerichtet wurde.
+
+ Fehlerfälle:
+ - Der Direktstart kann nur aus der Task '...' geaendert werden!
+
+
+#on("b")#PROC warenhaus hauptstelle (BOOL CONST entscheidung):#off("b")#
+
+ - macht je nach Wahrheitswert der 'entscheidung' eine Task zur Hauptstellen­
+ task ('TRUE') bzw. hebt diesen Status wieder auf ('FALSE'). Eine Task kann
+ nur Hauptstelle werden, wenn noch keine übergeordnete Task Hauptstelle ist.
+ Der Hauptstellenstatus kann danach auch nur in dieser Task wieder aufge­
+ hoben werden.
+ - löscht bei der Einrichtung der Hauptstelle eine etwa bereits vorhandene
+ "Zentrale" und richtet automatisch eine neue "Zentrale" in Form einer Sohn­
+ task ein, die den Namen der Vatertask mit dem Zusatz ".Zentrale" erhält und
+ in der später die zentrale Kundendatei gespeichert wird. Bei Aufhebung des
+ Hauptstellenstatus wird diese Task wieder gelöscht.
+ - fragt bei Einrichtung der Hauptstelle nach, ob ein Direktstart eingerichtet
+ werden soll ('Mit Direktstart (j/n)?') und ruft die Prozedur 'warenhaus
+ direktstart' entsprechend auf.
+ - Hebt bei Löschen des Hauptstellenstatus einen in der Task etwa einge­
+ richteten Direktstart automatisch auf.
+
+ Fehlerfälle:
+ - Hauptstelle ist bereits die Task '...'!
+ - Dieses Kommando darf nur in der Task '...' gegeben werden!
+
+
diff --git a/dos/block i-o b/dos/block i-o
new file mode 100644
index 0000000..554fcca
--- /dev/null
+++ b/dos/block i-o
@@ -0,0 +1,180 @@
+PACKET disk block io DEFINES (* Copyright (C) 1986 *)
+ (* Frank Klapper *)
+ (* 05.01.87 *)
+ read disk block,
+ read disk block and close work if error,
+ read disk cluster,
+ write disk block,
+ write disk block and close work if error,
+ write disk cluster,
+ first non dummy ds page,
+
+ block no dump modus:
+
+BOOL VAR block no dump flag := FALSE;
+
+LET write normal = 0;
+
+INT CONST first non dummy ds page := 2;
+
+INT VAR error;
+
+PROC read disk block (DATASPACE VAR ds,
+ INT CONST ds page no,
+ INT CONST block no):
+ IF block no dump flag THEN dump ("READ ", block no) FI;
+ check rerun;
+ read block (ds, ds page no, eublock (block no), error);
+ IF error > 0
+ THEN lesefehler (error)
+ FI.
+
+END PROC read disk block;
+
+PROC read disk block (DATASPACE VAR ds,
+ INT CONST ds page no,
+ REAL CONST block no):
+ IF block no dump flag THEN dump ("READ ", block no) FI;
+ check rerun;
+ read block (ds, ds page no, eublock (block no), error);
+ IF error > 0
+ THEN lesefehler (error)
+ FI.
+
+END PROC read disk block;
+
+PROC read disk block and close work if error (DATASPACE VAR ds,
+ INT CONST ds page no,
+ INT CONST block no):
+ IF block no dump flag THEN dump ("READ ", block no) FI;
+ check rerun;
+ read block (ds, ds page no, eublock (block no), error);
+ IF error > 0
+ THEN close work;
+ lesefehler (error)
+ FI.
+
+END PROC read disk block and close work if error;
+
+PROC read disk block and close work if error (DATASPACE VAR ds,
+ INT CONST ds page no,
+ REAL CONST block no):
+ IF block no dump flag THEN dump ("READ ", block no) FI;
+ check rerun;
+ read block (ds, ds page no, eublock (block no), error);
+ IF error > 0
+ THEN close work;
+ lesefehler (error)
+ FI.
+
+END PROC read disk block and close work if error;
+
+PROC read disk cluster (DATASPACE VAR ds,
+ INT CONST first ds page no,
+ REAL CONST cluster no):
+ IF block no dump flag THEN dump ("CLUSTER ", cluster no) FI;
+ INT VAR i;
+ FOR i FROM 0 UPTO sectors per cluster - 1 REP
+ read disk block (ds, first ds page no + i, block no + real (i))
+ PER.
+
+block no:
+ begin of cluster (cluster no).
+
+END PROC read disk cluster;
+
+PROC lesefehler (INT CONST fehler code):
+ error stop (fehlertext).
+
+fehlertext:
+ SELECT fehler code OF
+ CASE 1: "Diskettenlaufwerk nicht betriebsbereit"
+ CASE 2: "Lesefehler"
+ OTHERWISE "Lesefehler " + text (fehler code)
+ END SELECT.
+
+END PROC lesefehler;
+
+PROC write disk block (DATASPACE CONST ds,
+ INT CONST ds page no,
+ INT CONST block no):
+ IF block no dump flag THEN dump ("WRITE", block no) FI;
+ check rerun;
+ write block (ds, ds page no, write normal, eublock (block no), error);
+ IF error > 0
+ THEN schreibfehler (error)
+ FI.
+
+END PROC write disk block;
+
+PROC write disk block (DATASPACE CONST ds,
+ INT CONST ds page no,
+ REAL CONST block no):
+ IF block no dump flag THEN dump ("WRITE", block no) FI;
+ check rerun;
+ write block (ds, ds page no, write normal, eublock (block no), error);
+ IF error > 0
+ THEN schreibfehler (error)
+ FI.
+
+END PROC write disk block;
+
+PROC write disk block and close work if error (DATASPACE CONST ds,
+ INT CONST ds page no,
+ INT CONST block no):
+ IF block no dump flag THEN dump ("WRITE", block no) FI;
+ check rerun;
+ write block (ds, ds page no, write normal, eublock (block no), error);
+ IF error > 0
+ THEN close work;
+ schreibfehler (error)
+ FI.
+
+END PROC write disk block and close work if error;
+
+PROC write disk block and close work if error (DATASPACE CONST ds,
+ INT CONST ds page no,
+ REAL CONST block no):
+ IF block no dump flag THEN dump ("WRITE", block no) FI;
+ check rerun;
+ write block (ds, ds page no, write normal, eublock (block no), error);
+ IF error > 0
+ THEN close work;
+ schreibfehler (error)
+ FI.
+
+END PROC write disk block and close work if error;
+
+PROC write disk cluster (DATASPACE CONST ds,
+ INT CONST first ds page no,
+ REAL CONST cluster no):
+ IF block no dump flag THEN dump ("CLUSTER ", cluster no) FI;
+ INT VAR i;
+ FOR i FROM 0 UPTO sectors per cluster - 1 REP
+ write disk block (ds, first ds page no + i, block no + real (i))
+ PER.
+
+block no:
+ begin of cluster (cluster no).
+
+END PROC write disk cluster;
+
+PROC schreibfehler (INT CONST fehler code):
+ error stop (fehlertext).
+
+fehlertext:
+ SELECT fehler code OF
+ CASE 1: "Diskettenlaufwerk nicht betriebsbereit"
+ CASE 2: "Schreibfehler"
+ OTHERWISE "Schreibfehler " + text (fehler code)
+ END SELECT.
+
+END PROC schreibfehler;
+
+PROC block no dump modus (BOOL CONST status):
+ block no dump flag := status
+
+END PROC block no dump modus;
+
+END PACKET disk block io;
+
diff --git a/dos/dir.dos b/dos/dir.dos
new file mode 100644
index 0000000..08456b5
--- /dev/null
+++ b/dos/dir.dos
@@ -0,0 +1,693 @@
+PACKET dir DEFINES (* Copyright (c) 1986, 87 *)
+ (* Frank Klapper *)
+ open dir, (* 02.03.88 *)
+ insert dir entry,
+ delete dir entry,
+ init dir ds,
+ file info,
+ format dir,
+
+ dir list,
+ file exists,
+ subdir exists,
+ all files,
+ all subdirs:
+
+LET max dir entrys = 1000;
+
+(*-------------------------------------------------------------------------*)
+
+INITFLAG VAR dir block ds used := FALSE;
+DATASPACE VAR dir block ds;
+BOUND STRUCT (ALIGN dummy, ROW 64 REAL daten) VAR dir block;
+REAL VAR last read dir block no;
+
+PROC init dir block io:
+ last read dir block no := -1.0;
+ IF NOT initialized (dir block ds used)
+ THEN dir block ds := nilspace;
+ dir block := dir block ds
+ FI.
+
+END PROC init dir block io;
+
+PROC read dir block (REAL CONST block nr):
+ IF last read dir block no <> block nr
+ THEN last read dir block no := -1.0;
+ read disk block and close work if error (dir block ds, 2, block nr);
+ last read dir block no := block nr
+ FI.
+
+END PROC read dir block;
+
+PROC write dir block (REAL CONST block nr):
+ write disk block and close work if error (dir block ds, 2, block nr);
+ last read dir block no := block nr.
+
+END PROC write dir block;
+
+PROC write dir block:
+ IF last read dir block no < 0.0
+ THEN error stop ("Lesefehler")
+ FI;
+ write dir block (last read dir block no)
+
+END PROC write dir block;
+
+PROC get dir entry (TEXT VAR entry buffer, INT CONST block entry no):
+ (* 0 <= block entry no <= 15 *)
+ entry buffer := 32 * ".";
+ INT CONST replace offset := 4 * block entry no;
+ replace (entry buffer, 1, dir block.daten [replace offset + 1]);
+ replace (entry buffer, 2, dir block.daten [replace offset + 2]);
+ replace (entry buffer, 3, dir block.daten [replace offset + 3]);
+ replace (entry buffer, 4, dir block.daten [replace offset + 4]).
+
+END PROC get dir entry;
+
+PROC put dir entry (TEXT CONST entry buffer, INT CONST block entry no):
+ (* 0 <= block entry no <= 15 *)
+ INT CONST offset := 4 * block entry no;
+ dir block.daten [offset + 1] := entry buffer RSUB 1;
+ dir block.daten [offset + 2] := entry buffer RSUB 2;
+ dir block.daten [offset + 3] := entry buffer RSUB 3;
+ dir block.daten [offset + 4] := entry buffer RSUB 4.
+
+END PROC put dir entry;
+
+(*-------------------------------------------------------------------------*)
+
+LET DIRPOS = REAL; (* 16.0 * msdos block nr + entry no *)
+ (* 0 <= entry no <= 15 *)
+
+DIRPOS PROC dirpos (REAL CONST block nr, INT CONST entry nr):
+ block nr * 16.0 + real (entry nr).
+
+END PROC dir pos;
+
+REAL PROC block no (DIRPOS CONST p):
+ floor (p / 16.0)
+
+END PROC block no;
+
+INT PROC entry no (DIRPOS CONST p):
+ int (p MOD 16.0)
+
+END PROC entry no;
+
+PROC incr (DIRPOS VAR p):
+ p INCR 1.0.
+
+END PROC incr;
+
+(*-------------------------------------------------------------------------*)
+
+LET FREELIST = STRUCT (ROW max dir entrys DIRPOS stack,
+ INT stacktop,
+ DIRPOS begin of free area,
+ end of dir,
+ REAL dir root); (* erste Clusterno, 0 für Main Dir *)
+
+PROC init free list (FREELIST VAR flist, REAL CONST root):
+ flist.stacktop := 0;
+ flist.begin of free area := dir pos (9.0e99, 0);
+ flist.end of dir := dir pos (-1.0, 0);
+ flist.dir root := root.
+
+END PROC init free list;
+
+PROC store (FREELIST VAR flist, DIRPOS CONST free pos):
+ flist.stacktop INCR 1;
+ flist.stack [flist.stack top] := free pos.
+
+END PROC store;
+
+PROC store begin of free area (FREELIST VAR flist, DIRPOS CONST begin):
+ flist.begin of free area := begin
+
+END PROC store begin of free area;
+
+PROC store end of dir (FREELIST VAR flist, DIRPOS CONST end):
+ flist.end of dir := end
+
+END PROC store end of dir;
+
+DIRPOS PROC free dirpos (FREELIST VAR flist):
+ enable stop;
+ DIRPOS VAR result;
+ IF flist.stacktop > 0
+ THEN pop
+ ELIF NOT free area empty
+ THEN first of free area
+ ELIF expansion alloweded
+ THEN allocate new dir cluster;
+ result := free dirpos (flist)
+ ELSE error stop ("Directory voll")
+ FI;
+ result.
+
+pop:
+ result := flist.stack [flist.stacktop];
+ flist.stacktop DECR 1.
+
+free area empty:
+ flist.begin of free area > flist.end of dir.
+
+first of free area:
+ result := flist.begin of free area;
+ incr (flist.begin of free area).
+
+expansion alloweded:
+ flist.dir root >= 2.0.
+
+allocate new dir cluster:
+ REAL CONST new dir cluster :: available fat entry;
+ REAL VAR last entry no;
+ search last entry no of fat chain;
+ fat entry (new dir cluster, last fat chain entry);
+ fat entry (last entry no, new dir cluster);
+ write fat;
+ store begin of free area (flist, dir pos (first new block, 0));
+ store end of dir (flist, dir pos (last new block, 15));
+ init new dir cluster.
+
+search last entry no of fat chain:
+ last entry no := flist.dir root;
+ WHILE NOT is last fat chain entry (fat entry (last entry no)) REP
+ last entry no := fat entry (last entry no)
+ PER.
+
+first new block:
+ begin of cluster (new dir cluster).
+
+last new block:
+ begin of cluster (new dir cluster) + real (sectors per cluster - 1).
+
+init new dir cluster:
+ TEXT CONST empty dir entry :: 32 * ""0"";
+ INT VAR i;
+ FOR i FROM 0 UPTO 15 REP
+ put dir entry (empty dir entry, i)
+ PER;
+ disable stop;
+ REAL VAR block no := first new block;
+ WHILE block no <= last new block REP
+ write dir block (block no)
+ PER.
+
+END PROC free dirpos;
+
+(*-------------------------------------------------------------------------*)
+
+LET FILEENTRY = STRUCT (TEXT date and time,
+ REAL size,
+ first cluster,
+ DIRPOS dirpos),
+
+ FILELIST = STRUCT (THESAURUS thes,
+ ROW max dir entrys FILEENTRY entry);
+
+PROC init file list (FILELIST VAR flist):
+ flist.thes := empty thesaurus.
+
+END PROC init file list;
+
+PROC store file entry (FILELIST VAR flist, TEXT CONST entry text, DIRPOS CONST position):
+ INT VAR entry index;
+ insert (flist.thes, file name, entry index);
+ store file entry (flist.entry [entry index], entry text, position).
+
+file name:
+ TEXT CONST name pre :: compress (subtext (entry text, 1, 8)),
+ name post :: compress (subtext (entry text, 9, 11));
+ IF name post <> ""
+ THEN name pre + "." + name post
+ ELSE name pre
+ FI.
+
+END PROC store file entry;
+
+PROC store file entry (FILEENTRY VAR fentry, TEXT CONST entry text, DIRPOS CONST position):
+ fentry.first cluster := real (entry text ISUB 14);
+ fentry.date and time := dos date + " " + dos time;
+ fentry.size := dint (entry text ISUB 15, entry text ISUB 16);
+ fentry.dirpos := position.
+
+dos date:
+ day + "." + month + "." + year.
+
+day:
+ text2 (code (entry text SUB 25) MOD 32).
+
+month:
+ text2 (code (entry text SUB 25) DIV 32 + 8 * (code (entry text SUB 26) MOD 2)).
+
+year:
+ text (80 + code (entry text SUB 26) DIV 2, 2).
+
+dos time:
+ hour + ":" + minute.
+
+hour:
+ text2 (code (entry text SUB 24) DIV 8).
+
+minute:
+ text2 (code (entry text SUB 23) DIV 32 + 8 * (code (entry text SUB 24) MOD 8)).
+
+END PROC store file entry;
+
+TEXT PROC text2 (INT CONST intvalue):
+ IF intvalue < 10
+ THEN "0" + text (intvalue)
+ ELSE text (int value)
+ FI.
+
+END PROC text2;
+
+DIRPOS PROC file entry pos (FILELIST CONST flist, TEXT CONST file name):
+ INT CONST link index :: link (flist.thes, file name);
+ IF link index = 0
+ THEN error stop ("Die Datei """ + file name + """ gibt es nicht")
+ FI;
+ flist.entry [link index].dir pos.
+
+END PROC file entry pos;
+
+PROC delete (FILELIST VAR flist, TEXT CONST file name):
+ INT VAR dummy;
+ delete (flist.thes, file name, dummy).
+
+END PROC delete;
+
+PROC file info (FILELIST CONST flist, TEXT CONST file name, REAL VAR first cluster no, storage):
+ INT CONST link index :: link (flist.thes, file name);
+ IF link index = 0
+ THEN error stop ("Die Datei """ + file name + """ gibt es nicht")
+ FI;
+ first cluster no := flist.entry [link index].first cluster;
+ storage := flist.entry [link index].size
+
+END PROC file info;
+
+BOOL PROC contains (FILELIST VAR flist, TEXT CONST file name):
+ flist.thes CONTAINS file name
+
+END PROC contains;
+
+PROC list (FILE VAR f, FILELIST CONST flist):
+ INT VAR index := 0;
+ TEXT VAR name;
+ get (flist.thes, name, index);
+ WHILE index > 0 REP
+ list file;
+ get (flist.thes, name, index)
+ PER.
+
+list file:
+ write (f, centered name);
+ write (f, " ");
+ write (f, text (flist.entry [index].size, 11, 0));
+ write (f, " Bytes belegt ");
+ write (f, flist.entry [index].date and time);
+(*COND TEST*)
+ write (f, " +++ ");
+ write (f, text (flist.entry [index].first cluster));
+(*ENDCOND*)
+ line (f).
+
+centered name:
+ INT VAR point pos := pos (name, ".");
+ IF point pos > 0
+ THEN name pre + "." + name post
+ ELSE text (name, 12)
+ FI.
+
+name pre:
+ text (subtext (name, 1, point pos - 1), 8).
+
+name post:
+ text (subtext (name, point pos + 1, point pos + 4), 3).
+
+END PROC list;
+
+(*-------------------------------------------------------------------------*)
+
+LET DIRENTRY = REAL,
+
+ DIRLIST = STRUCT (THESAURUS thes,
+ ROW max dir entrys DIRENTRY entry);
+
+PROC init dir list (DIRLIST VAR dlist):
+ dlist.thes := empty thesaurus.
+
+END PROC init dir list;
+
+PROC store subdir entry (DIRLIST VAR dlist, TEXT CONST entry text):
+ INT VAR entry index;
+ insert (dlist.thes, subdir name, entry index);
+ dlist.entry [entry index] := real (entry text ISUB 14).
+
+subdir name:
+ TEXT CONST name pre :: compress (subtext (entry text, 1, 8)),
+ name post :: compress (subtext (entry text, 9, 11));
+ IF name post <> ""
+ THEN name pre + "." + name post
+ ELSE name pre
+ FI.
+
+END PROC store subdir entry;
+
+REAL PROC first cluster of subdir (DIRLIST CONST dlist, TEXT CONST name):
+ INT CONST link index := link (dlist.thes, name);
+ IF link index = 0
+ THEN error stop ("Das Unterverzeichnis """ + name + """ gibt es nicht")
+ FI;
+ dlist.entry [link index].
+
+END PROC first cluster of subdir;
+
+BOOL PROC contains (DIRLIST CONST dlist, TEXT CONST subdir name):
+ dlist.thes CONTAINS subdir name
+
+END PROC contains;
+
+PROC list (FILE VAR f, DIRLIST CONST dlist):
+ INT VAR index := 0;
+ TEXT VAR name;
+ get (dlist.thes, name, index);
+ WHILE index > 0 REP
+ list dir;
+ get (dlist.thes, name, index)
+ PER.
+
+list dir:
+ write (f, centered name);
+ write (f, " <DIR>");
+(*COND TEST*)
+ write (f, " +++ ");
+ write (f, text (dlist.entry [index]));
+(*ENDCOND*)
+ line (f).
+
+centered name:
+ INT VAR point pos := pos (name, ".");
+ IF point pos > 0
+ THEN name pre + "." + name post
+ ELSE text (name, 12)
+ FI.
+
+name pre:
+ text (subtext (name, 1, point pos - 1), 8).
+
+name post:
+ text (subtext (name, point pos + 1, point pos + 4), 3).
+
+END PROC list;
+
+(*-------------------------------------------------------------------------*)
+
+LET DIR = BOUND STRUCT (FILELIST filelist,
+ DIRLIST dirlist,
+ FREELIST freelist,
+ TEXT path);
+
+DIR VAR dir;
+DATASPACE VAR dir ds;
+INITFLAG VAR dir ds used := FALSE;
+
+PROC open dir (TEXT CONST path string):
+ init dir block io;
+ init dir ds;
+ dir.path := path string;
+ load main dir;
+ TEXT VAR rest path := path string;
+ WHILE rest path <> "" REP
+ TEXT CONST sub dir name := next sub dir name (rest path);
+ load sub dir
+ PER.
+
+load main dir:
+ init file list (dir.filelist);
+ init dir list (dir.dirlist);
+ init free list (dir.free list, 0.0);
+ store end of dir (dir.freelist, dirpos (last main dir sector, 15));
+ BOOL VAR was last dir sector := FALSE;
+ REAL VAR block no := first main dir sector;
+ INT VAR i;
+ FOR i FROM 1 UPTO dir sectors REP
+ load dir block (block no, was last dir sector);
+ block no INCR 1.0
+ UNTIL was last dir sector
+ PER.
+
+first main dir sector:
+ real (begin of dir).
+
+last main dir sector:
+ real (begin of dir + dir sectors - 1).
+
+load sub dir:
+ REAL VAR cluster no := first cluster of sub dir (dir.dirlist, sub dir name);
+ was last dir sector := FALSE;
+ init file list (dir.filelist);
+ init dir list (dir.dirlist);
+ init free list (dir.free list, cluster no);
+ WHILE NOT is last fat chain entry (cluster no) REP
+ load sub dir entrys of cluster;
+ cluster no := fat entry (cluster no)
+ UNTIL was last dir sector
+ PER.
+
+load sub dir entrys of cluster:
+ store end of dir (dir.freelist, dirpos (last block no of cluster, 15));
+ block no := begin of cluster (cluster no);
+ FOR i FROM 1 UPTO sectors per cluster REP
+ load dir block (block no, was last dir sector);
+ block no INCR 1.0
+ UNTIL was last dir sector
+ PER.
+
+last block no of cluster:
+ begin of cluster (cluster no) + real (sectors per cluster - 1).
+
+END PROC open dir;
+
+PROC load dir block (REAL CONST block no, BOOL VAR was last block):
+ was last block := FALSE;
+ read dir block (block no);
+ INT VAR entry no;
+ TEXT VAR entry;
+ FOR entry no FROM 0 UPTO 15 REP
+ get dir entry (entry, entry no);
+ process entry
+ UNTIL was last block
+ PER.
+
+process entry:
+ SELECT pos (""0"."229"", entry SUB 1) OF
+ CASE 1: end of dir search
+ CASE 2: (* root des aktuellen directorys oder des übergeordneten, also nichts tun *)
+ CASE 3: free entry
+ OTHERWISE volume label or file entry or subdir entry
+ END SELECT.
+
+end of dir search:
+ was last block := TRUE;
+ store begin of free area (dir.freelist, dir pos (block no, entry no)).
+
+free entry:
+ store (dir.freelist, dir pos (block no, entry no)).
+
+volume label or file entry or subdir entry:
+ INT CONST byte 11 :: code (entry SUB 12);
+ IF (byte 11 AND 8) > 0
+ THEN (* volume label *)
+ ELIF (byte 11 AND 16) > 0
+ THEN sub dir entry
+ ELSE file entry
+ FI.
+
+sub dir entry:
+ store subdir entry (dir.dir list, entry).
+
+file entry:
+ store file entry (dir.file list, entry, dir pos (block no, entry no)).
+
+END PROC load dir block;
+
+TEXT PROC next subdir name (TEXT VAR path string):
+ TEXT VAR subdir name;
+ IF (path string SUB 1) <> "\"
+ THEN error stop ("ungültige Pfadbezeichnung")
+ FI;
+ INT CONST backslash pos :: pos (path string, "\", 2);
+ IF backslash pos = 0
+ THEN subdir name := subtext (path string, 2);
+ path string := ""
+ ELSE subdir name := subtext (path string, 2, backslash pos - 1);
+ path string := subtext (path string, backslash pos)
+ FI;
+ dos name (subdir name, read modus).
+
+END PROC next subdir name;
+
+PROC init dir ds:
+ IF initialized (dir ds used)
+ THEN forget (dir ds)
+ FI;
+ dir ds := nilspace;
+ dir := dir ds.
+
+END PROC init dir ds;
+
+PROC insert dir entry (TEXT CONST name, REAL CONST start cluster, storage):
+ DIRPOS CONST ins pos :: free dirpos (dir.free list);
+ TEXT CONST entry string :: entry name + ""32"" + (10 * ""0"") + dos time +
+ dos date + entry start cluster + entry storage;
+ write entry on disk;
+ write entry in dir ds.
+
+entry name:
+ INT CONST point pos := pos (name, ".");
+ IF point pos > 0
+ THEN subtext (name, 1, point pos - 1) + (9 - point pos) * " " +
+ subtext (name, point pos + 1) + (3 - LENGTH name + point pos) * " "
+ ELSE name + (11 - LENGTH name) * " "
+ FI.
+
+dos time:
+ TEXT CONST akt time :: time of day (clock (1));
+ code ((minute MOD 8) * 32) + code (8 * hour + minute DIV 8).
+
+hour:
+ int (subtext (akt time, 1, 2)).
+
+minute:
+ int (subtext (akt time, 4, 5)).
+
+dos date:
+ TEXT CONST akt date :: date (clock (1));
+ code (32 * (month MOD 8) + day) + code ((year - 80) * 2 + month DIV 8).
+
+day:
+ int (subtext (akt date, 1, 2)).
+
+month:
+ int (subtext (akt date, 4, 5)).
+
+year:
+ int (subtext (akt date, 7, 8)).
+
+entry start cluster:
+ TEXT VAR buffer2 := "12";
+ replace (buffer2, 1, low word (start cluster));
+ buffer2.
+
+entry storage:
+ TEXT VAR buffer4 := "1234";
+ replace (buffer4, 1, low word (storage));
+ replace (buffer4, 2, high word (storage));
+ buffer4.
+
+write entry on disk:
+ read dir block (block no (ins pos));
+ put dir entry (entry string, entry no (ins pos));
+ write dir block.
+
+write entry in dir ds:
+ store file entry (dir.file list, entry string, ins pos).
+
+END PROC insert dir entry;
+
+PROC delete dir entry (TEXT CONST name):
+ TEXT VAR entry;
+ DIRPOS CONST del pos :: file entry pos (dir.filelist, name);
+ read dir block (block no (del pos));
+ get dir entry (entry, entry no (del pos));
+ put dir entry (""229"" + subtext (entry, 2, 32), entry no (del pos));
+ write dir block;
+ delete (dir.filelist, name);
+ store (dir.freelist, del pos).
+
+END PROC delete dir entry;
+
+PROC format dir:
+ init dir block io;
+ init dir ds;
+ build empty dir block;
+ REAL VAR block no := real (begin of dir);
+ disable stop;
+ FOR i FROM 1 UPTO dir sectors REP
+ write dir block (block no);
+ block no INCR 1.0
+ PER;
+ enable stop;
+ dir.path := "";
+ init file list (dir.file list);
+ init dir list (dir.dir list);
+ init free list (dir.free list, 0.0);
+ store begin of free area (dir.free list, dir pos (real (begin of dir), 0));
+ store end of dir (dir.free list, dir pos (last main dir sector, 15)).
+
+build empty dir block:
+ INT VAR i;
+ FOR i FROM 0 UPTO 15 REP
+ put dir entry (32 * ""0"", i)
+ PER.
+
+last main dir sector:
+ real (begin of dir + dir sectors - 1).
+
+END PROC format dir;
+
+PROC file info (TEXT CONST file name, REAL VAR start cluster, size):
+ file info (dir.file list, file name, start cluster, size)
+
+END PROC file info;
+
+THESAURUS PROC all files:
+ THESAURUS VAR t := dir.filelist.thes;
+ t
+
+END PROC all files;
+
+THESAURUS PROC all subdirs:
+ dir.dirlist.thes
+
+END PROC all subdirs;
+
+BOOL PROC file exists (TEXT CONST file name):
+ contains (dir.filelist, file name)
+
+END PROC file exists;
+
+BOOL PROC subdir exists (TEXT CONST subdir name):
+ contains (dir.dirlist, subdir name)
+
+END PROC subdir exists;
+
+PROC dir list (DATASPACE VAR ds):
+ open list file;
+ head line (list file, list file head);
+ list (list file, dir.file list);
+ list (list file, dir.dir list).
+
+open list file:
+ forget (ds);
+ ds := nilspace;
+ FILE VAR list file := sequential file (output, ds);
+ putline (list file, "").
+
+list file head:
+ "DOS" + path string.
+
+path string:
+ IF dir.path <> ""
+ THEN " PATH: " + dir.path
+ ELSE ""
+ FI.
+
+END PROC dir list;
+
+END PACKET dir;
+
diff --git a/dos/disk descriptor.dos b/dos/disk descriptor.dos
new file mode 100644
index 0000000..0b0d7fc
--- /dev/null
+++ b/dos/disk descriptor.dos
@@ -0,0 +1,339 @@
+PACKET dos disk DEFINES (* Copyright (C) 1986, 87 *)
+ (* Frank Klapper *)
+ (* Referenz: 3-22 *) (* 11.09.87 *)
+
+ open dos disk,
+
+ sectors per cluster,
+ fat copies,
+ dir sectors,
+ media descriptor,
+ fat sectors,
+
+ begin of fat,
+ fat entrys,
+ begin of dir,
+ begin of cluster,
+ cluster size,
+
+ bpb exists,
+ write bpb,
+
+ eu block,
+
+ bpb dump modus:
+
+INITFLAG VAR bpb ds initialisiert := FALSE;
+DATASPACE VAR bpb ds;
+BOUND STRUCT (ALIGN dummy, ROW 512 INT daten) VAR bpb;
+
+BOOL VAR bpb dump flag := FALSE;
+
+REAL VAR begin of data area;
+INT VAR sectors per track,
+ heads;
+
+IF exists ("shard interface")
+ THEN load shard interface table
+FI;
+
+TEXT CONST bpb type 254 :: ""00""00""00"" +
+ ""69""85""77""69""76""66""80""66"" +
+ ""00""02"" +
+ ""01"" +
+ ""01""00"" +
+ ""02"" +
+ ""64""00"" +
+ ""64""01"" +
+ ""254"" +
+ ""01""00"" +
+ ""08""00"" +
+ ""01""00"" +
+ ""00""00"",
+ bpb type 255 :: ""00""00""00"" +
+ ""69""85""77""69""76""66""80""66"" +
+ ""00""02"" +
+ ""02"" +
+ ""01""00"" +
+ ""02"" +
+ ""112""00"" +
+ ""128""02"" +
+ ""255"" +
+ ""01""00"" +
+ ""08""00"" +
+ ""02""00"" +
+ ""00""00"";
+
+PROC open dos disk:
+ enable stop;
+ bpb ds an bound koppeln;
+ bpb lesen;
+ IF bpb ungueltig
+ THEN versuche pseudo bpb zu verwenden
+ FI;
+ ueberpruefe bpb auf gueltigkeit;
+ globale variablen initialisieren;
+ IF bpb dump flag
+ THEN dump schreiben
+ FI.
+
+bpb ds an bound koppeln:
+ IF NOT initialized (bpb ds initialisiert)
+ THEN bpb ds := nilspace;
+ bpb := bpb ds
+ FI.
+
+bpb lesen:
+ INT VAR return;
+ check rerun;
+ read block (bpb ds, 2, 0, return);
+ IF return <> 0
+ THEN lesefehler (return)
+ FI.
+
+bpb ungueltig:
+ (* Byte 12 = Byte 13 = ... = Byte 23 <==> Word 6 = ... = Word 11 *)
+ INT VAR word no;
+ FOR word no FROM 6 UPTO 10 REP
+ IF bpb.daten [word no + 1] <> bpb.daten [word no + 2]
+ THEN LEAVE bpb ungueltig WITH FALSE
+ FI
+ PER;
+ TRUE.
+
+versuche pseudo bpb zu verwenden:
+ lies ersten fat sektor;
+ IF fat sektor gueltig und pseudo bpb vorhanden
+ THEN pseudo bpb laden
+ ELSE error stop ("Format unbekannt")
+ FI.
+
+lies ersten fat sektor:
+ (* da der bpb in diesem Fall ungültig, lese ich den fat sektor in den bpb
+ Datenraum *)
+ check rerun;
+ read block (bpb ds, 2, 1, return);
+ IF return <> 0
+ THEN lesefehler (return)
+ FI.
+
+fat sektor gueltig und pseudo bpb vorhanden:
+ TEXT VAR fat start := "1234";
+ replace (fat start, 1, bpb.daten [1]);
+ replace (fat start, 2, bpb.daten [2]);
+ (fat start SUB 2) = ""255"" CAND (fat start SUB 3) = ""255"" CAND
+ pseudo bpb vorhanden.
+
+pseudo bpb vorhanden:
+ pos (""254""255"", fat start SUB 1) > 0.
+
+pseudo bpb laden:
+ INT VAR i;
+ FOR i FROM 1 UPTO 15 REP
+ bpb.daten [i] := bpb puffer ISUB i
+ PER.
+
+bpb puffer:
+ IF pseudo bpb name = ""255""
+ THEN bpb type 255
+ ELSE bpb type 254
+ FI.
+
+pseudo bpb name:
+ fat start SUB 1.
+
+ueberpruefe bpb auf gueltigkeit:
+ IF bytes per sector <> 512
+ THEN error stop ("DOS Format nicht implementiert (unzulässige Sektorgröße)")
+ FI;
+ IF (fat sectors > 64)
+ THEN error stop ("ungültige DOS Disk (BPB)")
+ FI.
+
+globale variablen initialisieren:
+ sectors per track := bpb byte (25) * 256 + bpb byte (24);
+ heads := bpb byte (27) * 256 + bpb byte (26);
+ begin of data area := real (reserved sectors + fat copies * fat sectors + dir sectors).
+
+dump schreiben:
+ dump ("Sektoren pro Cluster", sectors per cluster);
+ dump ("Fat Kopien ", fat copies);
+ dump ("Dir Sektoren ", dir sectors);
+ dump ("Media Descriptor ", media descriptor);
+ dump ("Sektoren pro Fat ", fat sectors);
+ dump ("Fat Anfang (0) ", begin of fat (0));
+ dump ("Fat Einträge ", fat entrys);
+ dump ("Dir Anfang ", begin of dir).
+
+END PROC open dos disk;
+
+PROC lesefehler (INT CONST fehler code):
+ error stop (fehlertext).
+
+fehlertext:
+ SELECT fehler code OF
+ CASE 1: "Diskettenlaufwerk nicht betriebsbereit"
+ CASE 2: "Lesefehler"
+ OTHERWISE "Lesefehler " + text (fehler code)
+ END SELECT.
+
+END PROC lesefehler;
+
+TEXT VAR konvertier puffer := "12";
+
+INT PROC bpb byte (INT CONST byte no):
+ replace (konvertier puffer, 1, bpb.daten [byte no DIV 2 + 1]);
+ code (konvertier puffer SUB puffer pos).
+
+puffer pos:
+ IF even byte no
+ THEN 1
+ ELSE 2
+ FI.
+
+even byte no:
+ (byte no MOD 2) = 0.
+
+END PROC bpb byte;
+
+INT PROC bytes per sector:
+ bpb byte (12) * 256 + bpb byte (11)
+
+END PROC bytes per sector;
+
+INT PROC sectors per cluster:
+ bpb byte (13)
+
+END PROC sectors per cluster;
+
+INT PROC reserved sectors:
+ bpb byte (15) * 256 + bpb byte (14)
+
+END PROC reserved sectors;
+
+INT PROC fat copies:
+ bpb byte (16)
+
+END PROC fat copies;
+
+INT PROC dir sectors:
+ dir entrys DIV dir entrys per sector.
+
+dir entrys:
+ bpb byte (18) * 256 + bpb byte (17).
+
+dir entrys per sector:
+ 16.
+
+END PROC dir sectors;
+
+REAL PROC dos sectors:
+ real (bpb byte (20)) * 256.0 + real (bpb byte (19))
+
+END PROC dos sectors;
+
+INT PROC media descriptor:
+ bpb byte (21)
+
+END PROC media descriptor;
+
+INT PROC fat sectors:
+ bpb byte (23) * 256 + bpb byte (22)
+
+END PROC fat sectors;
+
+INT PROC begin of fat (INT CONST fat copy no):
+ (* 0 <= fat copy no <= fat copies - 1 *)
+ reserved sectors + fat copy no * fat sectors
+
+END PROC begin of fat;
+
+INT PROC fat entrys:
+ anzahl daten cluster + 2.
+
+anzahl daten cluster:
+ int ((dos sectors - tabellen sektoren) / real (sectors per cluster)).
+
+tabellen sektoren:
+ real (reserved sectors + fat copies * fat sectors + dir sectors).
+
+END PROC fat entrys;
+
+INT PROC begin of dir:
+ reserved sectors + fat copies * fat sectors.
+
+END PROC begin of dir;
+
+REAL PROC begin of cluster (REAL CONST cluster no):
+ begin of data area + (cluster no - 2.0) * real (sectors per cluster)
+
+END PROC begin of cluster;
+
+INT PROC cluster size:
+ 512 * sectors per cluster
+
+END PROC cluster size;
+
+BOOL PROC bpb exists (INT CONST no):
+
+ exists ("bpb ds") AND no > 0 AND no < 4.
+
+END PROC bpb exists;
+
+PROC write bpb (INT CONST no):
+ INT VAR return;
+ write block (old ("bpb ds"), no + 1, 0, 0, return);
+ IF return <> 0
+ THEN error stop ("Schreibfehler")
+ FI.
+
+END PROC write bpb;
+
+(* Da DOS-Partitionen maximal 32 MByte groß sein können, können die Blocknummern
+ durch 16 BIT unsigned Integer dargestellt werden. Die Werte die die 'eublock'-
+ Prozeduren liefern sind als solche zu verstehen *)
+
+INT PROC eu block (INT CONST dos block no):
+ IF hd version
+ THEN dos block no
+ ELSE dos block no floppy format
+ FI.
+
+dos block no floppy format:
+ IF page format
+ THEN head * eu sectors per head + trac * eu sectors + sector
+ ELSE head * eu sectors + trac * abs (eu heads) * eu sectors + sector
+ FI.
+
+page format:
+ eu heads < 0.
+
+sector:
+ dos block no MOD sectors per track.
+
+trac:
+ (dos block no DIV sectors per track) DIV heads.
+
+head:
+ (dos block no DIV sectors per track) MOD heads.
+
+eu sectors per head:
+ eu sectors * eu tracks.
+
+eu sectors:
+ eu last sector - eu first sector + 1.
+
+END PROC eu block;
+
+INT PROC eu block (REAL CONST dos block no):
+ eublock (low word (dos block no)).
+
+END PROC eublock;
+
+PROC bpb dump modus (BOOL CONST status):
+ bpb dump flag := status
+
+END PROC bpb dump modus;
+
+END PACKET dos disk;
+
diff --git a/dos/dos hd inserter b/dos/dos hd inserter
new file mode 100644
index 0000000..24be82b
--- /dev/null
+++ b/dos/dos hd inserter
@@ -0,0 +1,41 @@
+IF NOT single user
+ THEN do ("IF name (myself) <> ""DOS HD"" THEN error stop (""Bitte der Task den Namen 'DOS HD' geben und neu starten"") FI");
+FI;
+
+archive ("austausch");
+check off;
+command dialogue (FALSE);
+fetch ("insert.dos", archive);
+fetch ("bpb ds", archive);
+IF single user
+ THEN do (PROC (TEXT CONST) gen s, ALL "insert.dos");
+ gen s ("manager/S.dos")
+ ELSE fetch (ALL "insert.dos", archive);
+ fetch ("manager/M.dos", archive);
+ release (archive);
+ do (PROC (TEXT CONST) gen m, ALL "insert.dos");
+ gen m ("manager/M.dos");
+FI;
+do ("hd version (TRUE)");
+forget ("insert.dos", quiet);
+forget ("dos hd inserter", quiet);
+IF NOT single user
+ THEN do ("dos manager (29)")
+FI.
+
+single user:
+ (pcb (9) AND 255) = 1.
+
+PROC gen m (TEXT CONST name):
+ insert (name);
+ forget (name, quiet)
+
+END PROC gen m;
+
+PROC gen s (TEXT CONST t):
+ fetch (t, archive);
+ insert (t);
+ forget (t, quiet)
+
+END PROC gen s;
+
diff --git a/dos/dos inserter b/dos/dos inserter
new file mode 100644
index 0000000..2f70b28
--- /dev/null
+++ b/dos/dos inserter
@@ -0,0 +1,59 @@
+IF NOT single user
+ THEN do ("IF name (myself) <> ""DOS"" THEN error stop (""Bitte der Task den Namen 'DOS' geben und neu starten"") FI");
+FI;
+
+archive ("austausch");
+check off;
+command dialogue (FALSE);
+hol ("shard interface");
+hol ("bpb ds");
+hol ("insert.dos");
+IF single user
+ THEN do (PROC (TEXT CONST) gen s, ALL "insert.dos");
+ gen s ("manager/S.dos")
+ ELSE do (PROC (TEXT CONST) hol, ALL "insert.dos");
+ hol ("manager/M.dos");
+ release (archive);
+ do (PROC (TEXT CONST) gen m, ALL "insert.dos");
+ gen m ("manager/M.dos");
+ putline ("jetzt mit 'dos manager' bzw. 'dos manager (channnel)' starten");
+FI;
+do ("hd version (FALSE)");
+do ("load shard interface table");
+forget ("shard interface", quiet);
+forget ("insert.dos", quiet);
+forget ("dos inserter", quiet).
+
+single user:
+ (pcb (9) AND 255) = 1.
+
+PROC gen m (TEXT CONST name):
+ insert (name);
+ forget (name, quiet)
+
+END PROC gen m;
+
+PROC gen s (TEXT CONST t):
+ hol (t);
+ insert (t);
+ forget (t, quiet)
+
+END PROC gen s;
+
+PROC hol (TEXT CONST t):
+ IF NOT exists (t)
+ THEN fetch (t, archive)
+ FI
+
+END PROC hol;
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dos/dos-dat-handbuch b/dos/dos-dat-handbuch
new file mode 100644
index 0000000..a1e4fd4
--- /dev/null
+++ b/dos/dos-dat-handbuch
@@ -0,0 +1,650 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#MS-DOS-DAT
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#free(4.5)#
+
+#center#Lesen und Schreiben
+#center#von
+#center#MS-DOS Dateien
+
+#on ("b")##center#MS-DOS-DAT#off ("b")#
+#free(1.5)#
+
+
+#center#Version 2.0
+
+#center#Stand 10.09.87
+#page#
+#pagenr ("%",1)##setcount (1)##block##pageblock##count per page#
+#headeven#
+% #center#MS-DOS-DAT
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#MS-DOS-DAT#right#%
+#center#____________________________________________________________
+
+#end#
+#on("bold")#
+#ib#1. Allgemeines#ie#
+#off ("b")#
+
+Dieses Programm ermöglicht MS-DOS Dateien vom EUMEL aus von Disketten zu
+lesen und auf Disketten zu schreiben. Die Benutzerschnittstelle ist ähnlich der des
+EUMEL-Archivs organisiert. Der Benutzer kommuniziert mit einer Task des
+EUMEL-Systems, nämlich mit der Task 'DOS'. Diese wickelt dann über das Archiv­
+laufwerk die Diskettenzugriffe ab. Der Benutzer meldet die MS-DOS Diskette mit
+'reserve ("...", /"DOS")' an und kann dann mit 'list (/"DOS")', 'fetch ("...", /"DOS")',
+'save ("...", /"DOS")' und weiteren Kommandos auf die MS-DOS Diskette zugreifen.
+Für das Schreiben und Lesen (save, fetch) stehen insgesamt 7 verschiedene Be­
+triebsarten zur Verfügung. Man kann in eine Datei im ASCII Code mit und ohne
+Anpassung der Umlaute, im IBM-ASCII Code, im Atari-ST Code oder ganz ohne
+Codeumsetzung lesen bzw. schreiben. Die Betriebsart selbst wird beim Anmelden der
+MS-DOS Diskette durch den Textparameter des 'reserve'-Kommandos bestimmt.
+
+Die gleiche Benutzerschnittstelle gilt für die Kommunikation mit der Task 'DOS HD'.
+Diese Task liest und schreibt aber nicht auf der Diskette, sondern in der MS-DOS
+Partition der Festplatte (falls vorhanden).
+
+
+#on("bold")#
+#ib#2. Benutzeranleitung #ie#
+#off ("b")#
+Im Normalfall will man als Benutzer eine EUMEL-Textdatei auf eine MS-DOS
+Diskette schreiben oder eine mit z.B. Word-Star erstellte MS-DOS-Textdatei in
+das EUMEL-System einlesen (implementierte Formate siehe Abschnitt 3).
+
+Lesen einer MS-DOS-Datei:
+
+#linefeed (1.25)#
+#on ("b")#
+ reserve ("file ascii german", /"DOS");
+ (* MS-DOS-Diskette ins Laufwerk einlegen *)
+ fetch (filename, /"DOS");
+ release (/"DOS")
+#off ("b")#
+
+Schreiben einer MS-DOS-Datei:
+
+#on ("b")#
+ reserve ("file ascii german", /"DOS");
+ (* MS-DOS-Diskette ins Laufwerk einlegen *)
+ save (filename, /"DOS");
+ release (/"DOS")
+#off("b")#
+#linefeed (1.0)#
+
+
+Sollen statt der Umlaute []{|}\ verwendet werden, so ist statt "file ascii german" "file
+ascii" einzustellen. Eine genaue Beschreibung aller 7 möglichen Betriebsarten wird in
+Abschnitt 6 gegeben. Der Dateiname 'file name' unterliegt den im Abschnitt 4 be­
+schriebenen Einschränkungen.
+
+
+#on("bold")#
+#ib#3. Implementierte Formate#ie#
+#off("b")#
+
+Diese Hardware ermöglicht das Bearbeiten von MS-DOS Disketten mit Hilfe der
+Task /"DOS" und (falls es sich um einen MS-DOS fähigen Rechner mit MS-DOS Parti­
+tion auf der Festplatte handelt) das Bearbeiten von Daten in der MS-DOS Partition
+der Platte.
+
+#on("bold")#
+#ib#3.1 Arbeiten mit der Task /"DOS"#ie#
+#off ("b")#
+
+Die Task /"DOS" verwendet das Archivlaufwerk als MS-DOS Datenträger. Es sind
+alle mit dem IBM-Format der DOS Version 2 und 3 kompatiblen Formate für 5.25
+Zoll und 3.5 Zoll Disketten implementiert, sofern diese 512 Byte große Sektoren
+verwenden und im ersten Sektor einen erweiterten BIOS-Parameterblock (BPB)
+enthalten (hierzu gehören auch mit dem Atari ST bearbeitete Disketten). Weiterhin
+sind die beiden von IBM verwendeten Formate der DOS Version 1 implementiert (5.25
+Zoll, ein- bzw. zweiseitig, 40 Spuren a 8 Sektoren).
+
+Die einzige Hardwarevoraussetzung besteht darin, daß der Hardwareanpassungs­
+modul (SHard) alle von DOS benutzten Sektoren lesen und schreiben können muß.
+
+#on("bold")#
+#ib#3.2 Arbeiten mit der Task /"DOS HD"#ie#
+#off ("b")#
+
+Die Task /"DOS HD" verwendet die MS-DOS Partition der Festplatte als Daten­
+träger (falls eine solche vorhanden ist und das SHard diese ansprechen kann). Hier
+gibt es keine Beschränkungen bezüglich des Plattentyps.
+
+
+#on("bold")#
+#ib#4. Dateibenennung#ie#
+#off ("b")#
+
+Die Namen für MS-DOS Dateien unterliegen bestimmten Regeln. Ein Dateiname
+kann aus
+- einem bis acht Zeichen oder
+- einem bis acht Zeichen gefolgt von einem Punkt und einer Namenserweiterung
+ von einem bis drei Zeichen
+bestehen.
+
+Gültige Zeichen sind
+- die Buchstaben A bis Z
+- die Ziffern 0 bis 9
+- die Sonder- und Satzzeichen $ \# & § ! ( ) { }
+
+Da weitere Sonderzeichen in verschiedenen MS-DOS Versionen in unterschiedlich­
+em Umfang erlaubt sind, ist ihre Verwendung beim Schreiben (save) vom EUMEL aus
+nicht zugelassen. Beim Lesen und Löschen dagegen sind sie erlaubt.
+
+Außerdem sind die Buchstaben a - z erlaubt. Diese werden beim Zugriff auf das
+MS-DOS Inhaltsverzeichnis (Directory) in große Buchstaben konvertiert. Durch das
+Kommando 'fetch ("Test", /"DOS")' wird also die MS-DOS Datei mit dem Namen
+'TEST' in die EUMEL Datei mit dem Namen 'Test' gelesen; 'save ("test", /"DOS")'
+überschreibt dann die MS-DOS-Datei 'TEST' (natürlich nach Anfrage).
+
+
+#on("bold")#
+#ib#5. Beschreibung der Kommandos#ie#
+#off ("b")#
+
+In diesem Abschnitt steht der Begriff Dostask beim Arbeiten mit der Floppy für die
+Task /"DOS" und beim Arbeiten mit der MS-DOS Partition der Platte für die Task
+/"DOS HD". Analog steht der Begriff Dosbereich beim Arbeiten mit der Floppy für die
+Floppy und beim Arbeiten mit der MS-DOS Partition der Platte für diese Partition.
+
+#on("bold")#
+THESAURUS OP ALL (TASK CONST task)
+#off ("b")#
+ Wird der 'ALL'-Operator für die Dostask aufgerufen, so wird ein Thesaurus ge­
+ liefert. In diesem Thesaurus sind alle im Dosbereich vorhandenen Dateien einge­
+ tragen. Die vorhandenen Unterinhaltsverzeichnisse (Subdirectories) werden nicht
+ eingetragen.
+
+
+#on("bold")#
+PROC check (TEXT CONST filename, TASK CONST task)
+#off ("b")#
+ Durch Aufruf dieser Prozedur für die Dostask wird die Datei 'filename' im Dosbe­
+ reich prüfgelesen. Es werden nur die mit Daten belegten Blöcke prüfgelesen. Sollen
+ auch der Einträge im Inhaltsverzeichnis überprüft werden, so erreicht man dies
+ durch vorheriges neues Anmelden mit der Prozedur 'reserve'.
+
+
+#on("bold")#
+PROC clear (TASK CONST task)
+#off ("b")#
+ Durch Aufruf dieser Prozedur für die Task /"DOS" wird die gesamte Diskette ge­
+ löscht. Mit dieser Prozedur können #on ("u")#nur MS-DOS formatierte Disketten#off ("u")# behandelt
+ werden. Soll eine Diskette dagegen für den Gebrauch unter MS-DOS initialisiert
+ werden, so ist sie auf einem MS-DOS-Rechner zu formatieren.
+
+ Der Aufruf dieser Prozedur für die Task /DOS HD" ist aus Sicherheitsgründen nicht
+ erlaubt.
+
+
+#on("bold")#
+PROC erase (TEXT CONST filename, TASK CONST task)
+#off ("b")#
+ Durch Aufruf dieser Prozedur für die Dostask wird die Datei 'filename' im Dosbe­
+ reich gelöscht.
+
+
+#on("bold")#
+BOOL PROC exists (TEXT CONST name, TASK CONST task)
+#off ("b")#
+ Wird diese Prozedur für die Dostask aufgerufen, so liefert sie 'TRUE', falls eine
+ Datei mit dem Namen 'name' im Dosbereich existiert. Andernfalls liefert sie
+ 'FALSE'.
+
+
+#on("bold")#
+PROC fetch (TEXT CONST filename, TASK CONST task)
+#off ("b")#
+ Durch Aufruf dieser Prozedur für die Dostask wird die Datei 'filename' aus dem
+ Dosbereich gelesen. Hierbei wird in der beim Anmelden (reserve ("...", dostask))
+ bestimmten Betriebsart gelesen (siehe Abschnitt 6).
+
+
+#on("bold")#
+PROC list (TASK CONST task)
+#off ("b")#
+ Wird diese Prozedur für die Dostask aufgerufen, so werden alle Dateien des In­
+ haltsverzeichnisses und alle Unterverzeichnisse des Dosbereichs aufgelistet.
+
+
+#on("bold")#
+PROC release (TASK CONST task)
+#off ("b")#
+ Der Aufruf dieser Prozedur für die Task Dostask hebt deren Reservierung auf.
+ Gleichzeitig wird auch der für block i/o benutzte Kanal freigegeben, so daß bei
+ Benutzung der Task /"DOS" der Archivkanal durch das EUMEL-Archiv wieder
+ benutzt werden kann.
+
+ Um möglichst effizient arbeiten zu können, werden Inhaltsverzeichnis und Ket­
+ tungsblock des Dosbereichs als Kopie im EUMEL gehalten. Der hierdurch belegte
+ Speicher wird beim 'release' wieder freigegeben. Dies ist bei kleinen Systemen
+ besonders wichtig.
+
+
+#on("bold")#
+PROC reserve (TEXT CONST mode, TASK CONST task)
+#off ("b")#
+ Durch Aufruf für die Dostask werden Operationen mit dem Dosbereich angemel­
+ det. Gleichzeitig koppelt sich die Dostask an den entsprechenden Kanal an.
+ (/"DOS" an Kanal 31 und /"DOS HD" an Kanal 29). Die Anmeldung wird abge­
+ lehnt, wenn der für die MS-DOS Operationen benötigte Kanal belegt ist (z.B. bei
+ Kanal 31 durch eine Archiv­Operation). Ähnlich wie beim EUMEL-Archiv bleibt
+ diese Reservierung bis 5 Minuten nach dem letzten Zugriff gültig.
+
+ Wird beim Arbeiten mit der Task /"DOS" die MS-DOS Diskette gewechselt, so
+ muß erneut 'reserve ("...", /"DOS")' aufgerufen werden. Nur so ist gewährleistet,
+ daß das Inhaltsverzeichnis der neuen Diskette geladen wird.
+
+ Der Text 'mode' gibt die Betriebsart für das Schreiben und Lesen der Diskette
+ sowie den Pfad für das Bearbeiten von Subdirectories an und nicht wie beim
+ EUMEL-Archiv den Diskettennamen. Es gilt folgende Systax:
+
+ modus :[\directory][\directory]...[\directory]
+
+ Hierbei sind die Angaben in eckigen Klammern optional. Wird kein Pfad angege­
+ ben, so wird mit dem Hauptdirektory der Diskette gearbeitet. Ansonsten wird mit
+ dem Directory gearbeitet, welches durch den hinter dem Doppelpunkt angegeben
+ Pfad bezeichnet wird. Als 'modus' können alle in Abschnitt 6 beschriebenen Be­
+ triebsarten verwendet werden.
+
+
+#on("bold")#
+PROC save (TEXT CONST filename, TASK CONST task)
+#off ("b")#
+ Durch Aufruf dieser Prozedur für die Dostask wird die Datei 'filename' in den
+ Dosbereich geschrieben. Hierbei wird in der beim Anmelden (reserve ("...",
+ dostask)) bestimmten Betriebsart geschrieben (siehe Abschnitt 6).
+
+
+#on("bold")#
+#ib#6. Die Betriebsarten von 'fetch' und 'save'#ie#
+
+#ib#6.1 Betriebsart: file ascii#ie#
+
+#on("bold")#
+fetch ("filename", dostask)
+#off ("b")#
+ Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+ werden von allen Zeichen nur die niederwertigen 7 Bit gemäß DIN 66 003, ASCII
+ Code, internationale Referenzversion interpretiert. Die Datei wird so aufbereitet, daß
+ ein Bearbeiten mit dem EUMEL-Editor möglich ist. Dies geschieht folgenderma­
+ ßen:
+ - Alle im EUMEL darstellbaren Zeichen werden auf diese abgebildet.
+ - Die Zeichenfolgen CR LF, LF CR, LF, CR (CR = carriage return, LF = line­
+ feed) beenden einen Satz in der MS-DOS-Datei. Dementsprechend wird
+ eumelseitig die aktuelle Zeile beendet.
+ - Das Zeichen FF (form feed) beendet eumelseitig die aktuelle Zeile. Außerdem
+ wird ein Satz mit dem Inhalt "\#page\#" eingefügt.
+ - TAB's (Code 9) werden mit Blanks zur nächsten 8ter-Position expandiert.
+ - 'Ctrl z' in der MS-DOS Datei wird als Dateiende interpretiert. Fehlt dieses,
+ so wird bis zum letzten Zeichen des letzten Sektors der Datei gelesen.
+ - Alle anderen Zeichen mit 0 <= code (zeichen) <=  31 (Steuerzeichen)
+ werden durch eine Ersatzdarstellung dargestellt (der Code des Zeichens wird
+ als 3 stellige Dezimalzahl eingeschlossen von \#-Zeichen dargestellt).
+
+
+#on("bold")#
+save ("filename", dostask)
+#off ("b")#
+ Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Unter MS-DOS
+ wird der ASCII Code, internationale Referenzversion gemäß DIN 66 003 verwendet.
+ Dies geschieht folgendermaßen:
+ - Die EUMEL-spezifischen Druckzeichen (Trenn -, Trenn k, Druck \#, ge­
+ schütztes Blank) werden in -, k, \# und Blank umgesetzt.
+ - Alle in der internationalen Referenzversion des ASCII Codes vorhandenen
+ Eumel-Zeichen werden auf diese abgebildet.
+ - Alle in der internationalen Referenzversion des ASCII Codes nicht vorhande­
+ nen Eumel-Zeichen werden durch eine Ersatzdarstellung dargestellt (der
+ Code des Zeichens wird als 3 stellige Dezimalzahl eingeschlossen von
+ \#-Zeichen dargestellt)
+ - Steht in einer Zeile nur das Kommando '\#page\#' so wird dieses in ein Sei­
+ tenvorschubsteuerzeichen (""12"") umgewandelt.
+ - Eine dreistellige Dezimalzahl eingeschlossen von \# Zeichen wird als Ersatz­
+ darstellung für das Zeichen mit dem durch die Dezimalzahl angegebenen
+ Code betrachte. Diese Ersatzdarstellung wird beim Schreiben aufgelöst (d.h.
+ durch das entsprechende Zeichen ersetzt).
+ - Nach jeder Zeile wird 'carriage return' und ' linefeed' angefügt
+ - Am Ende der Datei wird 'ctrl z' angehängt.
+
+
+#on("bold")#
+#ib#6.2 Betriebsart: file ascii german#ie#
+
+fetch ("filename", dostask)
+#off ("b")#
+ Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+ werden von allen Zeichen nur die niederwertigen 7 Bit gemäß DIN 66 003, ASCII
+ Code, deutsche Referenzversion interpretiert. Die Datei wird so aufbereitet, daß ein
+ Bearbeiten mit dem EUMEL-Editor möglich ist. Dies geschieht wie in der Be­
+ triebsart 'file ascii', jedoch stehen statt []{}|\ die Umlaute und ß zur Verfügung.
+
+
+#on("bold")#
+save ("filename", dostask)
+#off ("b")#
+ Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Unter MS-DOS
+ wird der ASCII Code, deutsche Referenzversion gemäß DIN 66 003 verwendet. Dies
+ geschieht wie in der Betriebsart 'file ascii', jedoch stehen statt []{}|\ die Umlaute
+ zur Verfügung.
+
+
+#on("bold")#
+#ib#6.3 Betriebsart: file ibm#ie#
+
+fetch ("filename", dostask)
+#off ("b")#
+ Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+ werden alle Zeichen wie in der von IBM verwendeten Version des ASCII Codes
+ interpretiert. Die Datei wird so aufbereitet, daß ein Bearbeiten mit dem EUMEL-
+ Editor möglich ist. Dies geschieht folgendermaßen:
+ - Alle im EUMEL darstellbaren Zeichen werden auf diese abgebildet.
+ - Die Zeichenfolgen CR LF, LF CR, LF, CR (CR = carriage return, LF = line­
+ feed) beenden einen Satz in der MS-DOS-Datei. Dementsprechend wird
+ eumelseitig die aktuelle Zeile beendet.
+ - Das Zeichen FF (form feed) beendet eumelseitig die aktuelle Zeile. Außerdem
+ wird ein Satz mit dem Inhalt "\#page\#" eingefügt.
+ - TAB's (Code 9) werden mit Blanks zur nächsten 8ter-Position expandiert.
+ - Alle anderen Zeichen mit 0 <= code (zeichen) <=  31 (Steuerzeichen)
+ werden durch eine Ersatzdarstellung dargestellt (der Code des Zeichens wird
+ als 3 stellige Dezimalzahl eingeschlossen von \#-Zeichen dargestellt).
+
+
+#on("bold")#
+save ("filename", dostask)
+#off ("b")#
+ Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Unter MS-DOS
+ wird der ASCII Code in der von IBM verwendeten Version verwendet. Dies ge­
+ schieht folgendermaßen:
+ - Die EUMEL-spezifischen Druckzeichen (Trenn -, Trenn k, Druck \#, ge­
+ schütztes Blank) werden in -, k, \# und Blank umgesetzt.
+ - Alle in der IBM Version des ASCII Codes vorhandenen Eumel-Zeichen
+ werden auf diese abgebildet.
+ - Alle in der IBM Version des ASCII Codes nicht vorhandenen Eumel-Zeichen
+ werden durch eine Ersatzdarstellung dargestellt (der Code des Zeichens wird
+ als 3 stellige Dezimalzahl eingeschlossen von \#-Zeichen dargestellt)
+ - Steht in einer Zeile nur das Kommando '\#page\#' so wird dieses in ein Sei­
+ tenvorschubsteuerzeichen (""12"") umgewandelt.
+ - Eine dreistellige Dezimalzahl eingeschlossen von \# Zeichen wird als Ersatz­
+ darstellung für das Zeichen mit dem durch die Dezimalzahl angegebenen
+ Code betrachte. Diese Ersatzdarstellung wird beim Schreiben aufgelöst (d.h.
+ durch das entsprechende Zeichen ersetzt).
+ - Nach jeder Zeile wird 'carriage return' und ' linefeed' angefügt
+
+
+#on("bold")#
+#ib#6.4 Betriebsart: file atari st#ie#
+
+fetch ("filename", dostask)
+#off ("b")#
+ Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+ werden alle Zeichen wie in der vom Atari ST verwendeten Version des ASCII Codes
+ interpretiert. Die Datei wird so aufbereitet, daß ein Bearbeiten mit dem EUMEL-
+ Editor möglich ist. Dies geschieht folgendermaßen:
+ - Alle im EUMEL darstellbaren Zeichen werden auf diese abgebildet.
+ - Die Zeichenfolgen CR LF, LF CR, LF, CR (CR = carriage return, LF = line­
+ feed) beenden einen Satz in der MS-DOS-Datei. Dementsprechend wird
+ eumelseitig die aktuelle Zeile beendet.
+ - Das Zeichen FF (form feed) beendet eumelseitig die aktuelle Zeile. Außerdem
+ wird ein Satz mit dem Inhalt "\#page\#" eingefügt.
+ - TAB's (Code 9) werden mit Blanks zur nächsten 8ter-Position expandiert.
+ - Alle anderen Zeichen mit 0 <= code (zeichen) <=  31 (Steuerzeichen)
+ werden durch eine Ersatzdarstellung dargestellt (der Code des Zeichens wird
+ als 3 stellige Dezimalzahl eingeschlossen von \#-Zeichen dargestellt).
+
+
+#on("bold")#
+save ("filename", dostask)
+#off ("b")#
+ Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Unter MS-DOS
+ wird der ASCII Code in der vom Atari ST verwendeten Version verwendet. Dies
+ geschieht folgendermaßen:
+ - Die EUMEL-spezifischen Druckzeichen (Trenn -, Trenn k, Druck \#, ge­
+ schütztes Blank) werden in -, k, \# und Blank umgesetzt.
+ - Alle in der vom Atari ST verwendeten Version des ASCII Codes vorhandenen
+ Eumel-Zeichen werden auf diese abgebildet.
+ - Alle in der vom Atari ST verwendeten Version des ASCII Codes nicht
+ vorhandenen Eumel-Zeichen werden durch eine Ersatzdarstellung dargestellt
+ (der Code des Zeichens wird als 3 stellige Dezimalzahl eingeschlossen von
+ \#-Zeichen dargestellt)
+ - Steht in einer Zeile nur das Kommando '\#page\#' so wird dieses in ein Sei­
+ tenvorschubsteuerzeichen (""12"") umgewandelt.
+ - Eine dreistellige Dezimalzahl eingeschlossen von \# Zeichen wird als Ersatz­
+ darstellung für das Zeichen mit dem durch die Dezimalzahl angegebenen
+ Code betrachte. Diese Ersatzdarstellung wird beim Schreiben aufgelöst (d.h.
+ durch das entsprechende Zeichen ersetzt).
+ - Nach jeder Zeile wird 'carriage return' und ' linefeed' angefügt
+
+
+#on("bold")#
+#ib#6.5 Betriebsart: file transparent#ie#
+
+fetch ("filename", dostask)
+#off ("b")#
+ Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+ werden von allen Zeichen alle 8 Bit interpretiert. Es werden keine Zeichen einge­
+ fügt, gelöscht oder gewandelt. Somit stehen dann auch CR und LF Zeichen in der
+ EUMEL-Datei.
+
+ Da eine solche Datei noch Steuerzeichen enthält, ist beim Bearbeiten mit dem
+ Editor Vorsicht geboten.
+
+
+#on("bold")#
+save ("filename", dostask)
+#off ("b")#
+ Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Es werden keine
+ Codeumsetzungen durchgeführt. Insbesondere muß die EUMEL-Datei auch die CR
+ LF Sequenzen für das Zeilenende enthalten.
+
+
+#on("bold")#
+#ib#6.6 Betriebsart: row text#ie#
+#off ("b")#
+
+Diese Betriebsart ist nur für Programmierer interessant. Sie ist für die Umsetzung
+exotischer Codes in den EUMEL-Code mittels ELAN-Programmen gedacht.
+
+#on("bold")#
+fetch ("filename", dostask)
+#off ("b")#
+ Die MS-DOS Datei 'filename' wird in einen Datenraum mit folgender Struktur
+ kopiert:
+
+ STRUCT (INT benutzte texte, ROW 4000 TEXT datensatz)
+
+ Dabei bekommt der Datenraum den Type 1000. Der Integer 'benutzte texte' gibt an,
+ wieviele Elemente des ROW 4000 TEXT benutzt sind. In jedem benutzten Element
+ des ROW 4000 TEXT steht der Inhalt einer logischen Gruppe der MS-DOS Disket­
+ te. (Eine logische Gruppe umfaßt bei einer einseitig beschriebenen MS-DOS
+ Diskette 512 Byte und bei einer zweiseitig beschriebenen 1024 bzw. 2048 Byte). In
+ dieser Betriebsart werden keine Zeichen der MS-DOS Datei konvertiert oder
+ interpretiert, so daß also auch alle Steuerzeichen erhalten bleiben.
+
+
+#on("bold")#
+save ("filename", dostask)
+#off ("b")#
+ Hier bezeichnet 'filename' einen Datenraum der Struktur:
+
+ STRUCT (INT benutzte texte, ROW 4000 TEXT datensatz)
+
+ Dieser Datenraum muß den Type 1000 haben.
+ Es werden die benutzten Texte (1 bis benutzte texte) aneinandergehängt und ohne
+ irgendwelche Konvertierungen bzw. Interpretationen als MS-DOS Datei 'filename'
+ geschrieben. Dies bedeutet, daß die Texte auch alle von MS-DOS benötigten
+ Steuerzeichen (z.B. 'ctrl z' als Dateiendekennzeichen) enthalten müssen.
+
+
+#on("bold")#
+#ib#6.7 Betriebsart: ds#ie#
+#off ("b")#
+Diese Betriebsart ist nur für den Programmierer interessant. Sie ermöglicht das Abbil­
+den von Datenstrukturen zwischen MS-DOS und EUMEL.
+
+#on("bold")#
+fetch ("filename", dostask)
+#off ("b")#
+ Die MS-DOS Datei 'filename' wird blockweise in den Datenraum 'filename' ko­
+ piert. Hierbei wird der erste Block der MS-DOS Datei in die 2. Seite des Daten­
+ raums kopiert. (Die 2. Seite eines Datenraums ist die erste, die von einer Daten­
+ struktur voll überdeckt werden kann).
+
+
+#on("bold")#
+save ("filename", dostask)
+#off ("b")#
+ Der Datenraum 'filename' wird ab seiner 2. Seite in die MS-DOS Datei 'filename'
+ geschrieben. Hierbei werden alle Seiten des Datenraums (auch die nicht allokier­
+ ten) bis einschließlich der letzten allokierten Datenraumseite geschrieben.
+
+
+#on("bold")#
+#ib#7. Installation#ie#
+#off ("b")#
+
+Die Software zur Generierung der Tasks /"DOS" und /"DOS HD" wird auf einem
+EUMEL-Archiv ausgeliefert.
+
+#on("bold")#
+#ib#7.1 Installation der Task /"DOS"#ie#
+
+#ib#7.1.1 Installation im Multi-User#ie#
+#off ("b")#
+
+Die Software muß in einer privilegierten Task mit dem Namen 'DOS' installiert wer­
+den. Dies geschieht folgendermaßen:
+
+
+ begin ("DOS", "SYSUR")
+
+ archive ("austausch");
+ fetch ("dos inserter", archive);
+ run ("dos inserter")
+
+
+Danach stehen die Prozeduren
+
+
+ PROC dos manager
+ PROC dos manager (INT CONST channel)
+
+
+zur Verfügung. Beide Prozeduren machen die aufrufende Task zur Kommunikations­
+task für das Schreiben und Lesen von MS-DOS Disketten. Die erste benutzt dazu
+den Archivkanal (Kanal 31), bei der zweiten ist der Kanal über den Parameter ein­
+stellbar. Eine dieser Prozeduren muß jetzt aufgerufen werden.
+
+#on("bold")#
+#ib#7.1.2. Installation im Single-User#ie#
+#off ("b")#
+
+Die Software wird im Monitor ('gib Kommando'-Modus) durch folgende Kommandos
+installiert:
+
+
+ archive ("austausch");
+ fetch ("dos inserter", archive);
+ run ("dos inserter")
+
+
+Für das Schreiben und Lesen von MS-DOS Disketten wird der Archivkanal (Kanal
+31) benutzt.
+
+
+#on("bold")#
+#ib#7.2 Installation der Task /"DOS HD"#ie#
+#off ("b")#
+
+Die Software muß in einer privilegierten Task mit dem Namen 'DOS HD' installiert
+werden. Dies geschieht folgendermaßen:
+
+
+ begin ("DOS HD", "SYSUR")
+
+ archive ("austausch");
+ fetch ("dos hd inserter", archive);
+ run ("dos hd inserter")
+
+
+Danach steht die Prozedur
+
+
+ PROC dos manager
+
+
+zur Verfügung. Sie macht die aufrufende Task zur Kommunikationstask für das
+Schreiben und Lesen in der MS-DOS Partition der Platte. Sie benutzt dazu den
+Kanal 29, der, wie im Portierungshandbuch für den 8086 beschrieben, implementiert
+sein muß.
+
+#page#
+#headeven#
+#end#
+
+
+
+
+
+Herausgegeben von:
+
+ Gesellschaft für Mathematik und Datenverarbeitung mbH
+ (GMD)
+ Schloß Birlinghoven
+ 5205 Sankt Augustin 1
+
+ und
+
+ Hochschulrechenzentrum der Universität Bielefeld
+ (HRZ)
+ Universitätsstraße
+ 4800 Bielefeld 1
+
+Autor:
+
+ Frank Klapper
+
+überarbeitet von:
+
+ Thomas Müller
+ Hansgeorg Freese (GMD)
+
+Umschlaggestaltung:
+
+ Hannelotte Wecken
+
+
+
+
+
+
diff --git a/dos/dump b/dos/dump
new file mode 100644
index 0000000..5138162
--- /dev/null
+++ b/dos/dump
@@ -0,0 +1,49 @@
+PACKET dump DEFINES
+
+ dump:
+
+TEXT VAR ergebnis := "";
+
+PROC dump (TEXT CONST kommentar, dump text):
+ ergebnis := kommentar;
+ ergebnis CAT ": ";
+ INT VAR i;
+ FOR i FROM 1 UPTO LENGTH dump text REP
+ zeichen schreiben
+ PER;
+ ergebnis schreiben.
+
+zeichen schreiben:
+ INT CONST char code :: code (dump text SUB i);
+ IF char code < 32
+ THEN ergebnis CAT ("$" + text (char code) + "$")
+ ELSE ergebnis CAT code (char code)
+ FI.
+
+END PROC dump;
+
+PROC dump (TEXT CONST kommentar, INT CONST dump int):
+ ergebnis := kommentar;
+ ergebnis CAT ": ";
+ ergebnis CAT text (dump int);
+ ergebnis schreiben.
+
+END PROC dump;
+
+PROC dump (TEXT CONST kommentar, REAL CONST dump real):
+ ergebnis := kommentar;
+ ergebnis CAT ": ";
+ ergebnis CAT text (dump real);
+ ergebnis schreiben.
+
+END PROC dump;
+
+PROC ergebnis schreiben:
+ FILE VAR f := sequential file (output, "logbuch");
+ putline (f, ergebnis);
+ ergebnis := "".
+
+END PROC ergebnis schreiben;
+
+END PACKET dump;
+
diff --git a/dos/eu disk descriptor b/dos/eu disk descriptor
new file mode 100644
index 0000000..5a61367
--- /dev/null
+++ b/dos/eu disk descriptor
@@ -0,0 +1,107 @@
+PACKET eu disk DEFINES (* Copyright (C) 1986, 87 *)
+ (* Frank Klapper *)
+ (* 05.01.87 *)
+ load shard interface table,
+ open eu disk,
+ eu size,
+ eu heads,
+ eu tracks,
+ eu first sector,
+ eu last sector:
+
+LET table length = 15,
+
+ size field = 1,
+ head field = 2,
+ track field = 3,
+ first sector field = 4,
+ last sector field = 5;
+
+ROW table length ROW 5 INT VAR format table;
+
+INT VAR table top := 0,
+ table pointer;
+
+PROC open eu disk:
+ enable stop;
+ init check rerun;
+ IF hd version
+ THEN LEAVE open eu disk
+ FI;
+ INT CONST blocks := archive blocks;
+ IF blocks <= 0
+ THEN error stop ("keine Diskette eingelegt")
+ FI;
+ search format table entry.
+
+search format table entry:
+ IF table top < 1
+ THEN error stop ("SHard-Interfacetabelle nicht geladen")
+ FI;
+ table pointer := 1;
+ WHILE format table [table pointer][size field] <> blocks REP
+ table pointer INCR 1;
+ IF table pointer > table top
+ THEN error stop ("Diskettenformat nicht implementiert")
+ FI
+ PER.
+
+END PROC open eu disk;
+
+PROC load shard interface table:
+ FILE VAR f := sequential file (input, "shard interface");
+ TEXT VAR line;
+ table top := 0;
+ WHILE NOT eof (f) REP
+ get line (f, line);
+ IF (line SUB 1) <> ";"
+ THEN load line
+ FI
+ PER.
+
+load line:
+ table top INCR 1;
+ IF table top > table length
+ THEN error stop ("Shard Interface Tabelle zu groß")
+ FI;
+ INT VAR blank pos := 1;
+ format table [table top][size field] := next int;
+ format table [table top][head field] := next int;
+ format table [table top][track field] := next int;
+ format table [table top][first sector field] := next int;
+ format table [table top][last sector field] := next int.
+
+next int:
+ line := compress (subtext (line, blank pos)) + " ";
+ blank pos := pos (line, " ");
+ int (subtext (line, 1, blank pos - 1)).
+
+END PROC load shard interface table;
+
+INT PROC eu size:
+ format table [table pointer][size field]
+
+END PROC eu size;
+
+INT PROC eu heads:
+ format table [table pointer][head field]
+
+END PROC eu heads;
+
+INT PROC eu tracks:
+ format table [table pointer][track field]
+
+END PROC eu tracks;
+
+INT PROC eu first sector:
+ format table [table pointer][first sector field]
+
+END PROC eu first sector;
+
+INT PROC eu last sector:
+ format table [table pointer][last sector field]
+
+END PROC eu last sector;
+
+END PACKET eu disk;
+
diff --git a/dos/fat.dos b/dos/fat.dos
new file mode 100644
index 0000000..2890b1a
--- /dev/null
+++ b/dos/fat.dos
@@ -0,0 +1,369 @@
+PACKET dos fat DEFINES (* Copyright (C) 1985, 86, 87 *)
+ (* Frank Klapper *)
+ (* 11.09.87 *)
+ read fat,
+ write fat,
+ first fat block ok,
+ clear fat ds,
+ format fat,
+
+ fat entry,
+ last fat chain entry,
+ is last fat chain entry,
+ erase fat chain,
+ available fat entry:
+
+ (* Referenz: 4. *)
+
+LET fat size = 16 384, (* maximal 64 Sektoren a 512 Byte (256 Worte) *)
+ max anzahl fat sektoren = 64;
+
+LET FAT = BOUND STRUCT (ALIGN dummy,
+ ROW 256 INT block row, (* für Kopie des 1. Fatsektors *)
+ ROW fat size INT fat row);
+
+DATASPACE VAR fat ds;
+INITFLAG VAR fat ds used := FALSE;
+FAT VAR fat struktur;
+
+.fat: fat struktur.fat row.
+
+REAL VAR erster moeglicher freier eintrag;
+
+BOOL VAR kleines fat format;
+
+PROC read fat:
+ fat ds initialisieren;
+ fat bloecke lesen;
+ fat format bestimmen;
+ erster moeglicher freier eintrag := 2.0.
+
+fat ds initialisieren:
+ clear fat ds;
+ fat struktur := fat ds.
+
+fat bloecke lesen:
+ LET kein testblock = FALSE;
+ INT VAR block no;
+ FOR block no FROM 0 UPTO fat sectors - 1 REP
+ fat block lesen (block no, kein testblock)
+ PER.
+
+fat format bestimmen:
+ IF fat entrys <= 4086
+ THEN kleines fat format := TRUE
+ ELSE kleines fat format := FALSE
+ FI.
+
+END PROC read fat;
+
+PROC write fat:
+ disable stop;
+ INT VAR block nr;
+ FOR block nr FROM 0 UPTO fat sectors - 1 REP
+ fat block schreiben (block nr)
+ PER.
+
+END PROC write fat;
+
+BOOL PROC first fat block ok:
+ (* überprüft, ob der erste Block der Fat auf Diskette und im Speicher
+ gleich ist *)
+ enable stop;
+ LET testblock = TRUE;
+ fat block lesen (0, testblock);
+ INT VAR i;
+ FOR i FROM 1 UPTO 256 REP
+ vergleiche woerter
+ PER;
+ TRUE.
+
+vergleiche woerter:
+ IF fat [i] <> fat struktur.block row [i]
+ THEN LEAVE first fat block ok WITH FALSE
+ FI.
+
+END PROC first fat block ok;
+
+PROC clear fat ds:
+ IF initialized (fat ds used)
+ THEN forget (fat ds)
+ FI;
+ fat ds := nilspace.
+
+END PROC clear fat ds;
+
+PROC format fat:
+ fat ds initialisieren;
+ fat format bestimmen;
+ erster moeglicher freier eintrag := 2.0;
+ write first four fat bytes;
+ write other fat bytes;
+ vermerke schreibzugriffe;
+ write fat.
+
+fat ds initialisieren:
+ clear fat ds;
+ fat struktur := fat ds.
+
+fat format bestimmen:
+ IF fat entrys <= 4086
+ THEN kleines fat format := TRUE
+ ELSE kleines fat format := FALSE
+ FI.
+
+write first four fat bytes:
+ fat [1] := word (media descriptor, 255);
+ IF kleines fat format
+ THEN fat [2] := word (255, 0)
+ ELSE fat [2] := word (255, 255)
+ FI.
+
+write other fat bytes:
+ INT VAR i;
+ FOR i FROM 3 UPTO 256 * fat sectors REP
+ fat [i] := 0
+ PER.
+
+vermerke schreibzugriffe:
+ FOR i FROM 0 UPTO fat sectors - 1 REP
+ schreibzugriff (i)
+ PER.
+
+END PROC format fat;
+
+(*-------------------------------------------------------------------------*)
+
+REAL PROC fat entry (REAL CONST real entry no):
+ (* 0 <= entry no <= 22 000 *)
+ INT CONST entry no :: int (real entry no);
+ IF kleines fat format
+ THEN construct 12 bit value
+ ELSE dint (fat [entry no + 1], 0)
+ FI.
+
+construct 12 bit value:
+ INT CONST first byte no := entry no + entry no DIV 2;
+ IF entry no MOD 2 = 0
+ THEN real ((right byte MOD 16) * 256 + left byte)
+ ELSE real (right byte * 16 + left byte DIV 16)
+ FI.
+
+left byte:
+ fat byte (first byte no).
+
+right byte:
+ fat byte (first byte no + 1).
+
+END PROC fat entry;
+
+TEXT VAR convert buffer := "12";
+
+INT PROC fat byte (INT CONST no):
+ replace (convert buffer, 1, word);
+ IF even byte no
+ THEN code (convert buffer SUB 1)
+ ELSE code (convert buffer SUB 2)
+ FI.
+
+even byte no:
+ no MOD 2 = 0.
+
+word:
+ fat [no DIV 2 + 1].
+
+END PROC fat byte;
+
+PROC fat entry (REAL CONST real entry no, real value):
+ (* 0 <= entry no <= 22 000 *)
+ INT CONST entry no :: int (real entry no),
+ value :: low word (real value);
+ IF kleines fat format
+ THEN write 12 bit value
+ ELSE fat [entry no + 1] := value;
+ schreibzugriff (entry no DIV 256)
+ FI;
+ update first possible available entry.
+
+write 12 bit value:
+ INT CONST first byte no :: entry no + entry no DIV 2;
+ schreibzugriff (fat block of first byte);
+ schreibzugriff (fat block of second byte);
+ write value.
+
+fat block of first byte:
+ first byte no DIV 512.
+
+fat block of second byte:
+ second byte no DIV 512.
+
+write value:
+ IF even entry no
+ THEN write fat byte (first byte no, value MOD 256);
+ write fat byte (second byte no,
+ (right byte DIV 16) * 16 + value DIV 256)
+ ELSE write fat byte (first byte no,
+ (left byte MOD 16) + 16 * (value MOD 16));
+ write fat byte (second byte no, value DIV 16)
+ FI.
+
+even entry no:
+ entry no MOD 2 = 0.
+
+second byte no:
+ first byte no + 1.
+
+left byte:
+ fat byte (first byte no).
+
+right byte:
+ fat byte (second byte no).
+
+update first possible available entry:
+ IF value = 0
+ THEN erster moeglicher freier eintrag :=
+ min (erster moeglicher freier eintrag, real entry no)
+ FI.
+
+END PROC fat entry;
+
+PROC write fat byte (INT CONST byte no, new value):
+ read old word;
+ change byte;
+ write new word.
+
+read old word:
+ replace (convert buffer, 1, word).
+
+write new word:
+ word := convert buffer ISUB 1.
+
+word:
+ fat [byte no DIV 2 + 1].
+
+change byte:
+ replace (convert buffer, byte pos, code (new value)).
+
+byte pos:
+ byte no MOD 2 + 1.
+
+END PROC write fat byte;
+
+REAL PROC last fat chain entry:
+ IF kleines fat format
+ THEN 4 088.0
+ ELSE 65 528.0
+ FI.
+
+END PROC last fat chain entry;
+
+BOOL PROC is last fat chain entry (REAL CONST value):
+ value >= last fat chain entry
+
+END PROC is last fat chain entry;
+
+PROC erase fat chain (REAL CONST first entry no):
+ REAL VAR next entry no := first entry no,
+ act entry no := 0.0;
+ WHILE next entry exists REP
+ act entry no := next entry no;
+ next entry no := fat entry (act entry no);
+ fat entry (act entry no, 0.0)
+ PER.
+
+next entry exists:
+ NOT is last fat chain entry (next entry no).
+
+END PROC erase fat chain;
+
+REAL PROC available fat entry:
+ (* da die fat weniger als 22 000 Einträge umfaßt, kann ich diese als
+ INTEGER berechnen *)
+ INT VAR i;
+ REAL VAR real i := erster moeglicher freier eintrag;
+ FOR i FROM int (erster moeglicher freier eintrag) UPTO fat entrys - 1 REP
+ IF fat entry (real i) = 0.0
+ THEN erster moeglicher freier eintrag := real i;
+ LEAVE available fat entry WITH erster moeglicher freier eintrag
+ FI;
+ real i INCR 1.0
+ PER;
+ close work;
+ error stop ("MS-DOS Datentraeger voll");
+ 1.0e99.
+
+END PROC available fat entry;
+
+(*-------------------------------------------------------------------------*)
+
+PROC fat block lesen (INT CONST block nr, BOOL CONST test block):
+ (* 0 <= block nr <= fat sectors - 1 *)
+ disable stop;
+ IF NOT test block
+ THEN kein schreibzugriff (block nr)
+ FI;
+ INT VAR kopie nr;
+ FOR kopie nr FROM 0 UPTO fat copies - 1 REP
+ clear error;
+ read disk block (fat ds, ds seiten nr, disk block nr)
+ UNTIL NOT is error
+ PER;
+ IF is error
+ THEN close work
+ FI.
+
+ds seiten nr:
+ IF test block
+ THEN 2
+ ELSE block nr + 2 + 1
+ FI.
+
+disk block nr:
+ begin of fat (kopie nr) + block nr.
+
+END PROC fat block lesen;
+
+PROC fat block schreiben (INT CONST block nr):
+ IF war schreibzugriff (block nr)
+ THEN wirklich schreiben
+ FI.
+
+wirklich schreiben:
+ disable stop;
+ INT VAR kopie nr;
+ FOR kopie nr FROM 0 UPTO fat copies - 1 REP
+ write disk block and close work if error (fat ds, ds seiten nr, disk block nr)
+ PER;
+ kein schreibzugriff (block nr).
+
+ds seiten nr:
+ block nr + 2 + 1.
+
+disk block nr:
+ begin of fat (kopie nr) + block nr.
+
+END PROC fat block schreiben;
+
+(*-------------------------------------------------------------------------*)
+
+ROW max anzahl fat sektoren BOOL VAR schreib zugriff tabelle;
+
+PROC schreibzugriff (INT CONST fat sektor):
+ schreibzugriff tabelle [fat sektor + 1] := TRUE
+
+END PROC schreibzugriff;
+
+PROC kein schreibzugriff (INT CONST fat sektor):
+ schreibzugriff tabelle [fat sektor + 1] := FALSE
+
+END PROC kein schreibzugriff;
+
+BOOL PROC war schreibzugriff (INT CONST fat sektor):
+ schreibzugriff tabelle [fat sektor + 1]
+
+END PROC war schreibzugriff;
+
+(*-------------------------------------------------------------------------*)
+
+END PACKET dos fat;
+
diff --git a/dos/fetch b/dos/fetch
new file mode 100644
index 0000000..7cb7571
--- /dev/null
+++ b/dos/fetch
@@ -0,0 +1,371 @@
+PACKET fetch DEFINES (* Copyright (C) 1985, 86, 87 *)
+ (* Frank Klapper *)
+ (* 27.04.87 *)
+ fetch,
+ check file:
+
+LET ascii = 1,
+ ascii german = 2,
+ transparent = 3,
+ row text = 5,
+ ds = 6,
+ dump = 7,
+ atari st = 10,
+ ibm = 11,
+
+ (*line end chars = ""10""12""13"",*)
+ min line end char = ""10"",
+ max line end char = ""13"",
+ lf = ""10"",
+ cr = ""13"",
+ tab code = 9,
+ lf code = 10,
+ ff code = 12,
+ cr code = 13,
+ ctrl z = ""26"",
+
+ page cmd = "#page#",
+
+ row text length = 4000,
+ row text type = 1000;
+
+BOUND STRUCT (INT size,
+ ROW row text length TEXT cluster row) VAR cluster struct;
+
+FILE VAR file;
+
+TEXT VAR buffer;
+INT VAR buffer length;
+
+PROC fetch (TEXT CONST name, DATASPACE VAR file ds, INT CONST mode):
+
+ SELECT mode OF
+ CASE ascii, ascii german, atari st, ibm, transparent:
+ fetch filemode (file ds, name, mode)
+ CASE row text : fetch row textmode (file ds, name)
+ CASE ds : fetch dsmode (file ds, name)
+ CASE dump : fetch dumpmode (file ds, name)
+ OTHERWISE error stop ("Unzulässige Betriebsart")
+ END SELECT.
+
+END PROC fetch;
+
+PROC fetch filemode (DATASPACE VAR file space, TEXT CONST name,
+ INT CONST code type):
+ enable stop;
+ initialize fetch filemode;
+ open fetch dos file (name);
+ WHILE NOT was last fetch cluster REP
+ get text of cluster;
+ write lines;
+(***************************************)
+ IF lines (file) > 3900
+ THEN putline (file, ">>> FREMDDATEI FUER EUMEL ZU LANG. ES KÖNNEN DATEN FEHLEN <<<");
+ LEAVE fetch filemode
+ FI;
+(***************************************)
+ UNTIL file end via ctrl z
+ PER;
+ write last line if necessary;
+ close fetch dos file.
+
+initialize fetch filemode:
+ buffer := "";
+ buffer length := 0;
+ forget (file space);
+ file space := nilspace;
+ file := sequential file (output, file space);
+ BOOL VAR file end via ctrl z := FALSE.
+
+get text of cluster:
+ cat next fetch dos cluster (buffer);
+ IF ascii code
+ THEN ctrl z is buffer end
+ FI;
+ adapt code (buffer, buffer length + 1, code type);
+ buffer length := length (buffer).
+
+ascii code:
+ (code type = ascii) OR (code type = ascii german).
+
+ctrl z is buffer end:
+ INT CONST ctrl z pos :: pos (buffer, ctrl z, buffer length + 1);
+ file end via ctrl z := ctrl z pos > 0;
+ IF file end via ctrl z
+ THEN buffer := subtext (buffer, 1, ctrl z pos - 1);
+ buffer length := length (buffer)
+ FI.
+
+write lines:
+ INT VAR line begin pos := 1, line end pos;
+ compute line end pos;
+ WHILE line end pos > 0 REP
+ putline (file, subtext (buffer, line begin pos, line end pos));
+ exec (PROC (TEXT CONST, INT CONST) control char conversion, file, code type);
+ line begin pos := line end pos + 1;
+ compute line end pos
+ PER;
+ buffer := subtext (buffer, line begin pos);
+ buffer length := length (buffer);
+ IF buffer length > 5 000
+ THEN putline (file, buffer);
+ exec (PROC (TEXT CONST, INT CONST) control char conversion, file, code type);
+ buffer := "";
+ buffer length := 0
+ FI.
+
+compute line end pos:
+ line end pos := line begin pos;
+ REP
+ line end pos := pos (buffer, min line end char, max line end char, line end pos);
+ INT CONST line end code :: code (buffer SUB line end pos);
+ SELECT line end code OF
+ CASE lf code: look for cr
+ CASE 11 : line end pos INCR 1
+ CASE cr code: look for lf
+ END SELECT
+ UNTIL line end code <> 11
+ PER.
+
+look for cr:
+ IF line end pos = buffer length
+ THEN line end pos := 0
+ ELIF (buffer SUB line end pos + 1) = cr
+ THEN line end pos INCR 1
+ FI.
+
+look for lf:
+ IF line end pos = buffer length
+ THEN line end pos := 0
+ ELIF (buffer SUB line end pos + 1) = lf
+ THEN line end pos INCR 1
+ FI.
+
+write last line if necessary:
+ IF buffer length > 0
+ THEN putline (file, buffer);
+ exec (PROC (TEXT CONST, INT CONST) control char conversion, file, code type);
+ FI.
+
+END PROC fetch filemode;
+
+PROC adapt code (TEXT VAR text buffer, INT CONST start pos, code type):
+ SELECT code type OF
+ CASE ascii : cancel bit 8
+ CASE ascii german: cancel bit 8; ascii german adaption
+ CASE atari st : atari st adaption
+ CASE ibm : ibm adaption
+ (*CASE transparent : do nothing *)
+ END SELECT.
+
+cancel bit 8:
+ INT VAR set pos := pos (text buffer, ""128"", ""255"", start pos);
+ WHILE set pos > 0 REP
+ replace (text buffer, set pos, seven bit char);
+ set pos := pos (text buffer, ""128"", ""255"", set pos + 1)
+ PER.
+
+seven bit char:
+ code (code (text buffer SUB set pos) AND 127).
+
+ascii german adaption:
+ change all by replace (text buffer, start pos, "[", "Ä");
+ change all by replace (text buffer, start pos, "\", "Ö");
+ change all by replace (text buffer, start pos, "]", "Ü");
+ change all by replace (text buffer, start pos, "{", "ä");
+ change all by replace (text buffer, start pos, "|", "ö");
+ change all by replace (text buffer, start pos, "}", "ü");
+ change all by replace (text buffer, start pos, "~", "ß").
+
+atari st adaption:
+ change all by replace (text buffer, start pos, ""142"", "Ä");
+ change all by replace (text buffer, start pos, ""153"", "Ö");
+ change all by replace (text buffer, start pos, ""154"", "Ü");
+ change all by replace (text buffer, start pos, ""132"", "ä");
+ change all by replace (text buffer, start pos, ""148"", "ö");
+ change all by replace (text buffer, start pos, ""129"", "ü");
+ change all by replace (text buffer, start pos, ""158"", "ß").
+
+ibm adaption:
+ change all by replace (text buffer, start pos, ""142"", "Ä");
+ change all by replace (text buffer, start pos, ""153"", "Ö");
+ change all by replace (text buffer, start pos, ""154"", "Ü");
+ change all by replace (text buffer, start pos, ""132"", "ä");
+ change all by replace (text buffer, start pos, ""148"", "ö");
+ change all by replace (text buffer, start pos, ""129"", "ü");
+ change all by replace (text buffer, start pos, ""225"", "ß").
+
+END PROC adapt code;
+
+PROC change all by replace (TEXT VAR string, INT CONST begin pos,
+ TEXT CONST old, new):
+
+ INT VAR p := pos (string, old, begin pos);
+ WHILE p > 0 REP
+ replace (string, p, new);
+ p := pos (string, old, p + 1)
+ PER.
+
+END PROC change all by replace;
+
+PROC control char conversion (TEXT VAR string, INT CONST code type):
+
+ IF code type <> transparent
+ THEN code conversion
+ FI.
+
+code conversion:
+ INT VAR p := pos (string, ""0"", ""31"", 1);
+ WHILE p > 0 REP
+ convert char;
+ p := pos (string, ""0"", ""31"", p)
+ PER.
+
+convert char:
+ INT CONST char code := code (string SUB p);
+ SELECT char code OF
+ CASE tab code: expand tab
+ CASE lf code: change (string, p, p, "")
+ CASE ff code: change (string, p, p, page cmd)
+ CASE cr code: change (string, p, p, "")
+ OTHERWISE ersatzdarstellung
+ END SELECT.
+
+expand tab:
+ change (string, p, p, (8 - (p - 1) MOD 8) * " ").
+
+ersatzdarstellung:
+ TEXT CONST t := text (char code);
+ change (string, p, p, "#" + (3 - length (t)) * "0" + t + "#").
+
+END PROC control char conversion;
+
+PROC fetch rowtextmode (DATASPACE VAR file space,
+ TEXT CONST name):
+ enable stop;
+ open fetch dos file (name);
+ initialize fetch rowtext mode;
+ WHILE NOT was last fetch cluster REP
+ cluster struct.size INCR 1;
+ cluster struct.cluster row [cluster struct.size] := "";
+ cat next fetch dos cluster (cluster struct.cluster row [cluster struct.size])
+ PER;
+ close fetch dos file.
+
+initialize fetch row text mode:
+ forget (file space);
+ file space := nilspace;
+ cluster struct := file space;
+ type (file space, row text type);
+ cluster struct.size := 0.
+
+END PROC fetch rowtext mode;
+
+PROC fetch ds mode (DATASPACE VAR in ds, TEXT CONST name):
+ enable stop;
+ open fetch dos file (name);
+ init fetch dsmode;
+ WHILE NOT was last fetch cluster REP
+ read next fetch dos cluster (in ds, ds block no);
+ PER;
+ close fetch dos file.
+
+init fetch dsmode:
+ forget (in ds);
+ in ds := nilspace;
+ INT VAR ds block no := 2.
+
+END PROC fetch ds mode;
+
+PROC fetch dumpmode (DATASPACE VAR file space, TEXT CONST name):
+ enable stop;
+ open fetch dos file (name);
+ initialize fetch dumpmode;
+ WHILE NOT was last fetch cluster REP
+ TEXT VAR cluster buffer := "";
+ cat next fetch dos cluster (cluster buffer);
+ dump cluster
+ UNTIL offset > 50 000.0
+ PER;
+ close fetch dos file.
+
+initialize fetch dump mode:
+ BOOL VAR fertig := FALSE;
+ REAL VAR offset := 0.0;
+ forget (file space);
+ file space := nilspace;
+ file := sequential file (output, file space).
+
+dump cluster:
+ TEXT VAR dump line;
+ INT VAR line, column;
+ FOR line FROM 0 UPTO (cluster size DIV 16) - 1 REP
+ build dump line;
+ putline (file, dump line);
+ offset INCR 16.0
+ UNTIL fertig
+ PER.
+
+build dump line:
+ TEXT VAR char line := "";
+ dump line := text (offset, 6, 0);
+ dump line := subtext (dump line, 1, 5);
+ dump line CAT " ";
+ FOR column FROM 0 UPTO 7 REP
+ convert char;
+ dump line CAT " "
+ PER;
+ dump line CAT " ";
+ FOR column FROM 8 UPTO 15 REP
+ convert char;
+ dump line CAT " "
+ PER;
+ dump line CAT " ";
+ dump line CAT char line.
+
+convert char:
+ TEXT CONST char :: cluster buffer SUB (line * 16 + column + 1);
+ IF char = ""
+ THEN fertig := TRUE;
+ dump line CAT " ";
+ LEAVE convert char
+ FI;
+ INT CONST char code := code (char);
+ LET hex chars = "0123456789ABCDEF";
+ dump line CAT (hex chars SUB (char code DIV 16 + 1));
+ dump line CAT (hex chars SUB (char code MOD 16 + 1));
+ charline CAT show char.
+
+show char:
+ IF (char code > 31 AND char code < 127)
+ THEN char
+ ELSE "."
+ FI.
+
+END PROC fetch dump mode;
+
+PROC check file (TEXT CONST name):
+ disable stop;
+ DATASPACE VAR test ds := nilspace;
+ enable check file (name, test ds);
+ forget (test ds);
+ IF is error
+ THEN clear error;
+ error stop ("Fehler beim Prüflesen der Datei """ + name + """")
+ FI.
+
+END PROC check file;
+
+PROC enable check file (TEXT CONST name, DATASPACE VAR test ds):
+ enable stop;
+ open fetch dos file (name);
+ WHILE NOT was last fetch cluster REP
+ INT VAR dummy := 2;
+ read next fetch dos cluster (test ds, dummy)
+ PER;
+ close fetch dos file.
+
+END PROC enable check file;
+
+END PACKET fetch;
+
diff --git a/dos/fetch save interface b/dos/fetch save interface
new file mode 100644
index 0000000..27b4925
--- /dev/null
+++ b/dos/fetch save interface
@@ -0,0 +1,70 @@
+PACKET fetch save DEFINES (* Copyright (C) 1986 *)
+ (* Frank Klapper *)
+ save fetch mode, (* 22.04.87 *)
+ path:
+
+LET ascii = 1,
+ ascii german = 2,
+ transparent = 3,
+ row text = 5,
+ ds = 6,
+ dump = 7,
+ atari st = 10,
+ ibm = 11;
+
+INT PROC save fetch mode (TEXT CONST reserve string):
+ TEXT VAR modus;
+ INT CONST p := pos (reserve string, ":");
+ IF p = 0
+ THEN modus := reserve string
+ ELSE modus := subtext (reserve string, 1, p - 1)
+ FI;
+ modus normieren;
+ IF modus = "FILEASCII"
+ THEN ascii
+ ELIF modus = "FILEASCIIGERMAN"
+ THEN asciigerman
+ ELIF modus = "FILEATARIST"
+ THEN atari st
+ ELIF modus = "FILEIBM"
+ THEN ibm
+ ELIF modus = "FILETRANSPARENT"
+ THEN transparent
+ ELIF modus = "ROWTEXT"
+ THEN row text
+ ELIF modus = "DS"
+ THEN ds
+ ELIF modus = "DUMP"
+ THEN dump
+ ELSE error stop ("Unzulässige Betriebsart"); -1
+ FI.
+
+modus normieren:
+ change all (modus, " ", "");
+ INT VAR i;
+ FOR i FROM 1 UPTO LENGTH modus REP
+ INT CONST char code :: code (modus SUB i);
+ IF is lower case
+ THEN replace (modus, i, upper case char)
+ FI
+ PER.
+
+is lower case:
+ char code > 96 AND char code < 123.
+
+upper case char:
+ code (char code - 32).
+
+END PROC save fetch mode;
+
+TEXT PROC path (TEXT CONST reserve string):
+ INT CONST p :: pos (reserve string, ":");
+ IF p = 0
+ THEN ""
+ ELSE subtext (reserve string, p + 1)
+ FI.
+
+END PROC path;
+
+END PACKET fetch save;
+
diff --git a/dos/get put interface.dos b/dos/get put interface.dos
new file mode 100644
index 0000000..1d6de92
--- /dev/null
+++ b/dos/get put interface.dos
@@ -0,0 +1,368 @@
+PACKET dos get put DEFINES (* Copyright (C) 1986, 87 *)
+ (* Frank Klapper *)
+ (* 11.12.87 *)
+ log modus,
+
+ open dos disk,
+ close dos disk,
+ access dos disk,
+
+ open fetch dos file,
+ close fetch dos file,
+ cat next fetch dos cluster,
+ read next fetch dos cluster,
+ was last fetch cluster,
+
+ open save dos file,
+ write next save dos cluster,
+ close save dos file,
+
+ erase dos file,
+
+ all dosfiles,
+ all dossubdirs,
+ dosfile exists,
+ dos list,
+
+ clear dos disk,
+ format dos disk:
+
+BOOL VAR log flag := FALSE;
+
+PROC log modus (BOOL CONST status):
+ log flag := status
+
+END PROC log modus;
+
+(*-------------------------------------------------------------------------*)
+
+LET max cluster size = 8192, (* 8192 * 8 = 64 KB *)
+ reals per sector = 64;
+
+LET CLUSTER = BOUND STRUCT (ALIGN dummy,
+ ROW max cluster size REAL cluster row);
+
+CLUSTER VAR cluster;
+DATASPACE VAR cluster ds;
+INITFLAG VAR cluster ds used := FALSE;
+
+TEXT VAR convert buffer;
+INT VAR convert buffer length;
+
+PROC init cluster handle:
+ IF initialized (cluster ds used)
+ THEN forget (cluster ds)
+ FI;
+ cluster ds := nilspace;
+ cluster := cluster ds;
+ convert buffer := "";
+ convert buffer length := 0.
+
+END PROC init cluster handle;
+
+PROC cat cluster text (REAL CONST cluster no, TEXT VAR destination, INT CONST to):
+ read disk cluster (cluster ds, 2, cluster no);
+ init convert buffer;
+ INT VAR i;
+ FOR i FROM 1 UPTO sectors per cluster * reals per sector REP
+ replace (convert buffer, i, cluster.cluster row [i])
+ PER;
+ destination CAT subtext (convert buffer, 1, to).
+
+init convert buffer:
+ IF convert buffer length < cluster size
+ THEN convert buffer CAT (cluster size - convert buffer length) * "*";
+ convert buffer length := cluster size
+ FI.
+
+END PROC cat cluster text;
+
+PROC write text to cluster (REAL CONST cluster no, TEXT CONST string):
+ IF LENGTH string < cluster size
+ THEN execute write text (text (string, cluster size))
+ ELSE execute write text (string)
+ FI;
+ write disk cluster (cluster ds, 2, cluster no).
+
+END PROC write text to cluster;
+
+PROC execute write text (TEXT CONST string):
+ INT VAR i;
+ FOR i FROM 1 UPTO sectors per cluster * reals per sector REP
+ cluster.cluster row [i] := string RSUB i
+ PER.
+
+END PROC execute write text;
+
+(*-------------------------------------------------------------------------*)
+
+BOOL VAR disk open := FALSE;
+TEXT VAR act path;
+
+REAL VAR last access time;
+
+PROC open dos disk (TEXT CONST path):
+ IF log flag THEN dump ("open dos disk", path) FI;
+ enable stop;
+ close work;
+ init cluster handle;
+ act path := path;
+ disk open := TRUE
+
+END PROC open dos disk;
+
+PROC close dos disk:
+ IF log flag THEN dump ("close dos disk", "") FI;
+ enable stop;
+ disk open := FALSE;
+ close work;
+ init cluster handle; (* Datenraumespeicher freigeben *)
+ clear fat ds;
+ init dir ds.
+
+END PROC close dos disk;
+
+PROC access dos disk:
+ enable stop;
+ IF NOT disk open
+ THEN error stop ("DOS-Arbeit nicht eröffnet")
+ FI;
+ IF work closed COR (last access more than 5 seconds ago CAND disk changed)
+ THEN open eu disk; (* hier wird der RERUN Check initialisiert *)
+ open dos disk;
+ read fat;
+ open dir (act path);
+ last access time := clock (1);
+ open work
+ FI.
+
+last access more than 5 seconds ago:
+ abs (clock (1) - last access time) > 5.0.
+
+disk changed:
+ IF hd version
+ THEN FALSE
+ ELSE last access time := clock (1);
+ NOT first fat block ok
+ FI.
+
+END PROC access dos disk;
+
+(*-------------------------------------------------------------------------*)
+
+REAL VAR next fetch cluster,
+ fetch rest; (* in Bytes *)
+
+PROC open fetch dos file (TEXT CONST file name):
+ IF log flag THEN dump ("open fetch dos file", file name) FI;
+ enable stop;
+ access dos disk;
+ file info (file name, next fetch cluster, fetch rest).
+
+END PROC open fetch dos file;
+
+BOOL PROC was last fetch cluster:
+ IF log flag THEN dump ("was last fetch cluster", "") FI;
+ is last fat chain entry (next fetch cluster) OR fetch rest <= 0.0.
+
+END PROC was last fetch cluster;
+
+PROC cat next fetch dos cluster (TEXT VAR buffer):
+ IF log flag THEN dump ("cat next fetch dos cluster", "") FI;
+ enable stop;
+ IF was last fetch cluster
+ THEN error stop ("fetch nach Dateiende")
+ FI;
+ IF fetch rest < real (cluster size)
+ THEN cat cluster text (next fetch cluster, buffer, int (fetch rest));
+ fetch rest := 0.0
+ ELSE cat cluster text (next fetch cluster, buffer, cluster size);
+ fetch rest DECR real (cluster size)
+ FI;
+ last access time := clock (1);
+ next fetch cluster := fat entry (next fetch cluster).
+
+END PROC cat next fetch dos cluster;
+
+PROC read next fetch dos cluster (DATASPACE VAR read ds, INT VAR start page):
+ IF log flag THEN dump ("read next fetch dos cluster", start page) FI;
+ enable stop;
+ IF was last fetch cluster
+ THEN error stop ("fetch nach Dateiende")
+ FI;
+ read disk cluster (read ds, start page, next fetch cluster);
+ last access time := clock (1);
+ start page INCR sectors per cluster;
+ next fetch cluster := fat entry (next fetch cluster);
+ IF fetch rest < real (cluster size)
+ THEN fetch rest := 0.0
+ ELSE fetch rest DECR real (cluster size)
+ FI.
+
+END PROC read next fetch dos cluster;
+
+PROC close fetch dos file:
+ IF log flag THEN dump ("close fetch dos file", "") FI;
+
+END PROC close fetch dos file;
+
+(*-------------------------------------------------------------------------*)
+
+TEXT VAR save name;
+REAL VAR first save cluster,
+ last save cluster,
+ save size;
+
+PROC open save dos file (TEXT CONST file name):
+ IF log flag THEN dump ("open save dos file", file name) FI;
+ enable stop;
+ access dos disk;
+ IF file exists (file name) OR subdir exists (file name)
+ THEN error stop ("die Datei """ + file name + """ gibt es schon")
+ FI;
+ save name := file name;
+ first save cluster := -1.0;
+ save size := 0.0.
+
+END PROC open save dos file;
+
+PROC write next save dos cluster (TEXT CONST buffer):
+ IF log flag THEN dump ("write next save dos cluster", "") FI;
+ enable stop;
+ REAL CONST save cluster := available fat entry;
+ write text to cluster (save cluster, buffer);
+ last access time := clock (1);
+ save size INCR real (LENGTH buffer);
+ IF first save cluster < 2.0
+ THEN first save cluster := save cluster
+ ELSE fat entry (last save cluster, save cluster)
+ FI;
+ fat entry (save cluster, last fat chain entry);
+ last save cluster := save cluster.
+
+END PROC write next save dos cluster;
+
+PROC write next save dos cluster (DATASPACE CONST save ds, INT VAR start page):
+ IF log flag THEN dump ("write next save dos cluster", start page) FI;
+ enable stop;
+ REAL CONST save cluster := available fat entry;
+ write disk cluster (save ds, start page, save cluster);
+ last access time := clock (1);
+ start page INCR sectors per cluster;
+ save size INCR real (cluster size);
+ IF first save cluster < 2.0
+ THEN first save cluster := save cluster
+ ELSE fat entry (last save cluster, save cluster)
+ FI;
+ fat entry (save cluster, last fat chain entry);
+ last save cluster := save cluster.
+
+END PROC write next save dos cluster;
+
+PROC close save dos file:
+ IF log flag THEN dump ("close save dos file", "") FI;
+ enable stop;
+ IF first save cluster < 2.0
+ THEN LEAVE close save dos file
+ FI;
+ fat entry (last save cluster, last fat chain entry);
+ write fat;
+ insert dir entry (save name, first save cluster, save size);
+ last access time := clock (1).
+
+END PROC close save dos file;
+
+(*-------------------------------------------------------------------------*)
+
+PROC erase dos file (TEXT CONST file name):
+ IF log flag THEN dump ("erase dos file", file name) FI;
+ enable stop;
+ access dos disk;
+ REAL VAR first cluster, size;
+ file info (file name, first cluster, size);
+ delete dir entry (file name);
+ erase fat chain (first cluster);
+ write fat;
+ last access time := clock (1).
+
+END PROC erase dos file;
+
+(*-------------------------------------------------------------------------*)
+
+THESAURUS PROC all dosfiles:
+ IF log flag THEN dump ("all dosfile", "") FI;
+ enable stop;
+ access dos disk;
+ all files.
+
+END PROC all dosfiles;
+
+THESAURUS PROC all dossubdirs:
+ IF log flag THEN dump ("all subdirs", "") FI;
+ enable stop;
+ access dos disk;
+ all subdirs.
+
+END PROC all dossubdirs;
+
+BOOL PROC dos file exists (TEXT CONST file name):
+ IF log flag THEN dump ("dos file exists", file name) FI;
+ enable stop;
+ access dos disk;
+ file exists (file name).
+
+END PROC dos file exists;
+
+PROC dos list (DATASPACE VAR list ds):
+ IF log flag THEN dump ("dos list", "") FI;
+ enable stop;
+ access dos disk;
+ dir list (list ds).
+
+END PROC dos list;
+
+(*-------------------------------------------------------------------------*)
+
+PROC clear dos disk:
+ IF log flag THEN dump ("clear dos disk", "") FI;
+ enable stop;
+ IF hd version
+ THEN error stop ("nicht implementiert")
+ ELSE access dos disk;
+ format dir;
+ format fat;
+ last access time := clock (1)
+ FI.
+
+END PROC clear dos disk;
+
+PROC format dos disk (INT CONST format code):
+
+ IF log flag THEN dump ("format dos disk (" + text (format code) + ")", "") FI;
+ enable stop;
+ IF NOT disk open
+ THEN error stop ("DOS-Arbeit nicht eröffnet")
+ FI;
+ IF hd version
+ THEN error stop ("nicht implementiert")
+ ELSE do format
+ FI.
+
+do format:
+ IF bpb exists (format code)
+ THEN close work;
+ format archive (format code);
+ open eu disk;
+ write bpb (format code);
+ open dos disk;
+ format dir; (* enthält 'open dir' *)
+ format fat; (* enthält 'read fat' *)
+ open work
+ ELSE error stop ("Format unzulässig")
+ FI;
+ last access time := clock (1).
+
+END PROC format dos disk;
+
+END PACKET dos get put;
+
diff --git a/dos/insert.dos b/dos/insert.dos
new file mode 100644
index 0000000..14f98cd
--- /dev/null
+++ b/dos/insert.dos
@@ -0,0 +1,14 @@
+dump
+konvert
+open
+eu disk descriptor
+disk descriptor.dos
+block i/o
+name conversion.dos
+fat.dos
+dir.dos
+get put interface.dos
+fetch save interface
+fetch
+save
+
diff --git a/dos/konvert b/dos/konvert
new file mode 100644
index 0000000..c5c4c43
--- /dev/null
+++ b/dos/konvert
@@ -0,0 +1,75 @@
+PACKET konvert DEFINES (* Copyright (C) 1986 *)
+ (* Frank Klapper *)
+ (* 28.10.86 *)
+ high byte,
+ low byte,
+ word,
+ change low byte,
+ change high byte,
+ dint,
+ high word,
+ low word:
+
+INT PROC high byte (INT CONST value):
+ TEXT VAR x := " ";
+ replace (x, 1, value);
+ code (x SUB 2)
+
+END PROC high byte;
+
+INT PROC low byte (INT CONST value):
+ TEXT VAR x := " ";
+ replace (x, 1, value);
+ code (x SUB 1)
+
+END PROC low byte;
+
+INT PROC word (INT CONST low byte, high byte):
+ TEXT CONST x :: code (low byte) + code (high byte);
+ x ISUB 1
+
+END PROC word;
+
+PROC change low byte (INT VAR word, INT CONST low byte):
+ TEXT VAR x := " ";
+ replace (x, 1, word);
+ replace (x, 1, code (low byte));
+ word := x ISUB 1
+
+END PROC change low byte;
+
+PROC change high byte (INT VAR word, INT CONST high byte):
+ TEXT VAR x := " ";
+ replace (x, 1, word);
+ replace (x, 2, code (high byte));
+ word := x ISUB 1
+
+END PROC change high byte;
+
+REAL PROC dint (INT CONST low word, high word):
+ real low word + 65536.0 * real high word.
+
+real low word:
+ real (low byte (low word)) + 256.0 * real (high byte (low word)).
+
+real high word:
+ real (low byte (high word)) + 256.0 * real (high byte (high word)).
+
+END PROC dint;
+
+INT PROC high word (REAL CONST double precission int):
+ int (double precission int / 65536.0)
+
+END PROC high word;
+
+INT PROC low word (REAL CONST double precission int):
+ string of low bytes ISUB 1.
+
+string of low bytes:
+ code (int (double precission int MOD 256.0)) +
+ code (int ((double precission int MOD 65536.0) / 256.0)).
+
+END PROC low word;
+
+END PACKET konvert;
+
diff --git a/dos/manager-M.dos b/dos/manager-M.dos
new file mode 100644
index 0000000..e27c513
--- /dev/null
+++ b/dos/manager-M.dos
@@ -0,0 +1,211 @@
+PACKET dos manager multi DEFINES (* Copyright (C) 1985, 86, 87 *)
+ (* Frank Klapper *)
+ provide channel, (* 16.10.87 *)
+ dos manager:
+
+LET std archive channel = 31,
+
+ ack = 0,
+ second phase ack = 5,
+ false code = 6,
+
+ fetch code = 11,
+ save code = 12,
+ exists code = 13,
+ erase code = 14,
+ list code = 15,
+ all code = 17,
+ clear code = 18,
+ reserve code = 19,
+ free code = 20,
+ check read code = 22,
+ format code = 23,
+
+ log code = 78,
+
+ quote = """";
+
+BOUND STRUCT (TEXT name, pass) VAR msg;
+
+TASK VAR order task;
+
+INT VAR dos channel;
+
+INT VAR fetch save modus;
+
+REAL VAR last access time := 0.0;
+
+TASK VAR disk owner := niltask;
+
+TEXT VAR save file name;
+
+PROC provide channel (INT CONST channel):
+ dos channel := channel
+
+END PROC provide channel;
+
+IF hd version
+ THEN provide channel (29)
+ ELSE provide channel (std archive channel)
+FI;
+
+PROC dos manager:
+ dos manager (dos channel)
+
+END PROC dos manager;
+
+PROC dos manager (INT CONST channel):
+ dos channel := channel;
+ task password ("-");
+ global manager
+ (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST) dos manager)
+
+END PROC dos manager;
+
+PROC dos manager (DATASPACE VAR ds, INT CONST order code, phase,
+ TASK CONST from task):
+ enable stop;
+ order task := from task;
+ msg := ds;
+ IF NOT (order task = disk owner) AND
+ order code <> free code AND order code <> reserve code
+ THEN errorstop ("DOS nicht angemeldet")
+ FI;
+ IF order task = disk owner
+ THEN last access time := clock (1)
+ FI;
+ SELECT order code OF
+ CASE fetch code : fetch file
+ CASE save code : save file
+ CASE erase code : erase file
+ CASE clear code : clear disk
+ CASE exists code : exists file
+ CASE list code : list disk
+ CASE all code : deliver directory
+ CASE reserve code : reserve
+ CASE free code : free
+ CASE check read code: check
+ CASE format code : format
+ CASE log code : send log
+ OTHERWISE errorstop ("unbekannter Auftrag für Task: " + name (myself))
+ END SELECT.
+
+fetch file:
+ fetch (dos name (msg.name, read modus), ds, fetch save modus);
+ manager ok (ds).
+
+check:
+ check file (dos name (msg.name, read modus));
+ manager message (expanded name (msg.name, read modus) + " ohne Fehler gelesen").
+
+format:
+ IF phase = 1
+ THEN manager question ("Diskette formatieren")
+ ELSE format dos disk (int (msg.name));
+ manager ok (ds)
+ FI.
+
+save file:
+ IF phase = 1
+ THEN save first phase
+ ELSE save second phase
+ FI.
+
+save first phase:
+ save file name := dos name (msg.name, write modus);
+ IF dos file exists (save file name)
+ THEN manager question (expanded name (msg.name, write modus) + " auf der MS-DOS Disk ueberschreiben")
+ ELSE send (order task, second phase ack, ds)
+ FI.
+
+save second phase:
+ IF dos file exists (save file name)
+ THEN erase dos file (save file name)
+ FI;
+ save (save file name, ds, fetch save modus);
+ forget (ds) ;
+ ds := nilspace ;
+ manager ok (ds).
+
+clear disk:
+ IF phase = 1
+ THEN manager question ("Diskette loeschen")
+ ELSE clear dos disk;
+ manager ok (ds)
+ FI.
+
+erase file:
+ IF dos file exists (dos name (msg.name, read modus))
+ THEN IF phase = 1
+ THEN manager question (expanded name (msg.name, TRUE) + " auf der MS-DOS Disk loeschen")
+ ELSE erase dos file (dos name (msg.name, read modus));
+ manager ok (ds)
+ FI
+ ELSE manager message ("die Datei " + expanded name (msg.name, TRUE) + " gibt es nicht auf der MS-DOS Disk")
+ FI.
+
+exists file:
+ IF dos file exists (dos name (msg.name, read modus))
+ THEN manager ok (ds)
+ ELSE send (order task, false code, ds)
+ FI.
+
+list disk:
+ dos list (ds);
+ manager ok (ds).
+
+send log:
+ forget (ds);
+ ds := old ("logbuch");
+ manager ok (ds).
+
+deliver directory:
+ forget (ds);
+ ds := nilspace;
+ BOUND THESAURUS VAR all names := ds;
+ all names := all dos files;
+ manager ok (ds).
+
+reserve:
+ IF reserve or free permitted
+ THEN continue channel (dos channel);
+ disk owner := from task;
+ fetch save modus := save fetch mode (msg.name);
+ open dos disk (path (msg.name));
+ forget ("logbuch", quiet);
+ manager ok (ds)
+ ELSE errorstop ("Archivlaufwerk wird von Task """+ name (disk owner) + """ benutzt")
+ FI.
+
+reserve or free permitted :
+ from task = disk owner OR last access more than five minutes ago
+ OR disk owner = niltask OR NOT
+ (exists (disk owner) OR station(disk owner) <> station (myself)).
+
+last access more than five minutes ago :
+ abs (last access time - clock (1)) > 300.0.
+
+free:
+ IF reserve or free permitted
+ THEN close dos disk;
+ disk owner := niltask;
+ break (quiet);
+ manager ok (ds)
+ ELSE manager message ("DOS nicht angemeldet")
+ FI.
+
+END PROC dos manager;
+
+PROC manager ok (DATASPACE VAR ds):
+ send (order task, ack, ds);
+ last access time := clock (1).
+
+END PROC manager ok;
+
+TEXT PROC expanded name (TEXT CONST name, BOOL CONST status):
+ text (quote + dos name (name, status) + quote, 14)
+
+END PROC expanded name;
+
+END PACKET dos manager multi;
+
diff --git a/dos/manager-S.dos b/dos/manager-S.dos
new file mode 100644
index 0000000..23885e6
--- /dev/null
+++ b/dos/manager-S.dos
@@ -0,0 +1,268 @@
+PACKET dos single DEFINES (* Copyright (C) 1985 *)
+ (* Frank Klapper *)
+ (* 11.09.87 *)
+ /,
+ dos,
+ provide dos channel,
+ archive,
+ reserve,
+ release,
+ save,
+ fetch,
+ erase,
+ check,
+ exists,
+ ALL,
+ SOME,
+ clear,
+ list,
+ format:
+
+LET std archive channel = 31,
+ main channel = 1;
+
+INT VAR dos channel := std archive channel;
+INT VAR fetch save modus;
+
+TYPE DOSTASK = TEXT;
+
+DOSTASK CONST dos := "DOS";
+
+OP := (DOSTASK VAR d, TEXT CONST t):
+ CONCR (d) := t
+
+END OP :=;
+
+DOSTASK OP / (TEXT CONST text):
+ DOSTASK VAR d;
+ CONCR (d) := text;
+ d
+
+END OP /;
+
+BOOL PROC is dostask (DOSTASK CONST d):
+ CONCR (d) = "DOS"
+
+END PROC is dos task;
+
+PROC provide dos channel (INT CONST channel no):
+ dos channel := channel no
+
+END PROC provide dos channel;
+
+DATASPACE VAR space := nilspace;
+forget (space);
+
+PROC reserve (TEXT CONST string, DOSTASK CONST task):
+ IF is dostask (task)
+ THEN fetch save modus := save fetch mode (string);
+ open dos disk (path (string))
+ ELSE error stop ("die angesprochene Task existiert nicht")
+ FI.
+
+END PROC reserve;
+
+PROC archive (TEXT CONST string, DOSTASK CONST task):
+ reserve (string, task)
+
+END PROC archive;
+
+PROC release (DOSTASK CONST task):
+ IF is dos task (task)
+ THEN close dos disk
+ ELSE error stop ("die angesprochene Task existiert nicht")
+ FI.
+
+END PROC release;
+
+PROC fetch (TEXT CONST name, DOSTASK CONST from):
+ IF is dostask (from)
+ THEN fetch from dos disk
+ ELSE error stop ("die angesprochene Task existiert nicht")
+ FI.
+
+fetch from dos disk:
+ IF NOT exists (name) COR overwrite permitted
+ THEN do fetch
+ FI.
+
+overwrite permitted:
+ say ("eigene Datei """) ;
+ say (name) ;
+ yes (""" auf der Diskette ueberschreiben").
+
+do fetch:
+ last param (name);
+ disable stop;
+ continue (dos channel);
+ fetch (dos name (name, read modus), space, fetch save modus);
+ continue (main channel);
+ IF NOT is error
+ THEN forget (name, quiet);
+ copy (space, name)
+ FI;
+ forget (space).
+
+END PROC fetch;
+
+PROC erase (TEXT CONST name, DOSTASK CONST task):
+ IF is dos task (task)
+ THEN do erase dos file
+ ELSE error stop ("die angesprochene Task existiert nicht")
+ FI.
+
+do erase dos file:
+ IF NOT exists (name, /"DOS")
+ THEN error stop ("die Datei """ + name + """ gibt es nicht")
+ ELIF yes ("""" + dos name (name, read modus)+ """ auf Der Diskette loeschen")
+ THEN disable stop;
+ continue (dos channel);
+ erase dos file (dos name (name, read modus));
+ continue (main channel)
+ FI.
+
+END PROC erase;
+
+PROC save (TEXT CONST name, DOSTASK CONST task):
+ IF is dos task (task)
+ THEN save to dos disk
+ ELSE error stop ("die angesprochene Task existiert nicht")
+ FI.
+
+save to dos disk:
+ TEXT CONST save file name :: dos name (name, write modus);
+ disable stop;
+ continue (dos channel);
+ IF NOT dos file exists (save file name) COR overwrite permitted
+ THEN IF dos file exists (save file name)
+ THEN erase dos file (save file name)
+ FI;
+ save (save file name, old (name), fetch save modus);
+ FI;
+ continue (main channel).
+
+overwrite permitted:
+ continue (main channel);
+ BOOL CONST result :: yes ("""" + save file name + """ auf der Diskette ueberschreiben");
+ continue (dos channel);
+ result.
+
+END PROC save;
+
+PROC check (TEXT CONST name, DOSTASK CONST from):
+ IF is dostask (from)
+ THEN disable stop;
+ continue (dos channel);
+ check file (dos name (name, read modus));
+ continue (main channel)
+ ELSE error stop ("die angesprochene Task existiert nicht")
+ FI.
+
+END PROC check;
+
+BOOL PROC exists (TEXT CONST name, DOSTASK CONST task):
+ IF is dos task (task)
+ THEN disable stop;
+ continue (dos channel);
+ BOOL VAR dummy := dos file exists (dos name (name, read modus));
+ continue (main channel);
+ enable stop;
+ dummy
+ ELSE error stop ("die angesprochene Task existiert nicht"); FALSE
+ FI.
+
+END PROC exists;
+
+PROC list (DOSTASK CONST from):
+ forget (space);
+ space := nilspace;
+ FILE VAR list file := sequential file (output, space);
+ list (list file, from);
+ modify (list file);
+ show (list file);
+ forget (space).
+
+ENDPROC list;
+
+PROC list (FILE VAR list file, DOSTASK CONST from):
+ IF is dos task (from)
+ THEN list dos disk
+ ELSE error stop ("die angesprochene Task existiert nicht")
+ FI.
+
+list dos disk:
+ disable stop;
+ continue (dos channel);
+ dos list (space);
+ continue (main channel);
+ enable stop;
+ output (list file);
+ FILE VAR list source := sequential file (output, space);
+ TEXT VAR line;
+ WHILE NOT eof (list source) REP
+ getline (list source, line);
+ putline (list file, line)
+ PER.
+
+END PROC list;
+
+THESAURUS OP ALL (DOSTASK CONST task):
+ IF is dos task (task)
+ THEN disable stop;
+ continue (dos channel);
+ THESAURUS VAR dummy := all dos files;
+ continue (main channel);
+ enable stop;
+ dummy
+ ELSE error stop ("die angesprochene Task existiert nicht"); empty thesaurus
+ FI.
+
+END OP ALL;
+
+THESAURUS OP SOME (DOSTASK CONST task):
+ IF is dos task (task)
+ THEN disable stop;
+ continue (dos channel);
+ THESAURUS VAR dummy := all dos files;
+ continue (main channel);
+ enable stop;
+ SOME dummy
+ ELSE error stop ("die angesprochene Task existiert nicht"); empty thesaurus
+ FI.
+
+END OP SOME;
+
+PROC clear (DOSTASK CONST task):
+ IF is dos task (task)
+ THEN clear disk
+ ELSE error stop ("die angesprochene Task existiert nicht")
+ FI.
+
+clear disk:
+ disable stop;
+ IF yes ("Diskette loeschen")
+ THEN continue (dos channel);
+ clear dos disk;
+ continue (main channel)
+ FI.
+
+END PROC clear;
+
+PROC format (INT CONST format code, DOSTASK CONST task):
+ IF is dos task (task)
+ THEN format disk
+ ELSE error stop ("die angesprochene Task existiert nicht")
+ FI.
+
+format disk:
+ disable stop;
+ IF yes ("Diskette formatieren")
+ THEN continue (dos channel);
+ format dos disk (format code);
+ continue (main channel)
+ FI.
+
+END PROC format;
+
+END PACKET dos single;
+
diff --git a/dos/name conversion.dos b/dos/name conversion.dos
new file mode 100644
index 0000000..e72d838
--- /dev/null
+++ b/dos/name conversion.dos
@@ -0,0 +1,77 @@
+PACKET name conversion DEFINES (* Copyright (C) 1985 *)
+ (* Frank Klapper *)
+ dos name, (* 31.12.86 *)
+
+ read modus,
+ write modus:
+
+BOOL CONST read modus :: TRUE,
+ write modus :: NOT read modus;
+
+LET upper case chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$#&§!()-{}`_",
+ lower case chars = "abcdefghijklmnopqrstuvwxyz";
+
+TEXT PROC dos name (TEXT CONST eu name, BOOL CONST read write modus):
+ enable stop;
+ INT CONST point pos :: pos (eu name, ".");
+ IF name extension exists
+ THEN changed name with extension
+ ELSE changed name without extension
+ FI.
+
+name extension exists:
+ point pos > 0.
+
+changed name with extension:
+ TEXT CONST name pre :: compress (subtext (eu name, 1, point pos - 1)),
+ name post :: compress (subtext (eu name, point pos + 1));
+ IF LENGTH name pre = 0 OR LENGTH name pre > 8 OR LENGTH name post > 3
+ THEN error
+ FI;
+ IF LENGTH name post = 0
+ THEN new name (name pre, read write modus)
+ ELSE new name (name pre, read write modus) + "."
+ + new name (name post, read write modus)
+ FI.
+
+changed name without extension:
+ IF LENGTH eu name > 8 OR LENGTH euname < 1
+ THEN error
+ FI;
+ new name (eu name, read write modus).
+
+error:
+ error stop ("Unzulässiger Name").
+
+END PROC dos name;
+
+TEXT PROC new name (TEXT CONST old name, BOOL CONST read write modus):
+ TEXT VAR new := "";
+ INT VAR count;
+ FOR count FROM 1 UPTO LENGTH old name REP
+ convert char
+ PER;
+ new.
+
+convert char:
+ TEXT CONST char :: old name SUB count;
+ IF is lower case char
+ THEN new CAT (upper case chars SUB string pos)
+ ELIF is upper case char OR read write modus
+ THEN new CAT char
+ ELSE error stop ("Unzulässiger Name")
+ FI.
+
+is lower case char:
+ pos (lower case chars, char) > 0.
+
+is upper case char:
+ pos (upper case chars, char) > 0.
+
+string pos:
+ pos (lower case chars, char).
+
+END PROC new name;
+
+END PACKET name conversion;
+
diff --git a/dos/open b/dos/open
new file mode 100644
index 0000000..518c4b8
--- /dev/null
+++ b/dos/open
@@ -0,0 +1,66 @@
+PACKET open DEFINES (* Copyright (C) 1986 *)
+ (* Frank Klapper *)
+ open work, (* 05.01.87 *)
+ close work,
+ work opened,
+ work closed,
+ init check rerun,
+ check rerun,
+
+ hd version:
+
+BOOL VAR open;
+INT VAR old session;
+
+BOOL VAR hd flag := FALSE;
+
+INITFLAG VAR packet := FALSE;
+
+PROC open work:
+ open := TRUE
+
+END PROC open work;
+
+PROC close work:
+ open := FALSE
+
+END PROC close work;
+
+BOOL PROC work opened:
+ IF NOT initialized (packet)
+ THEN close work
+ FI;
+ open
+
+END PROC work opened;
+
+BOOL PROC work closed:
+ NOT work opened
+
+END PROC work closed;
+
+PROC init check rerun:
+ old session := session
+
+END PROC init check rerun;
+
+PROC check rerun:
+ IF session <> old session
+ THEN close work;
+ error stop ("Diskettenzugriff im RERUN")
+ FI.
+
+END PROC check rerun;
+
+PROC hd version (BOOL CONST status):
+ hd flag := status
+
+END PROC hd version;
+
+BOOL PROC hd version:
+ hd flag
+
+END PROC hd version;
+
+END PACKET open;
+
diff --git a/dos/save b/dos/save
new file mode 100644
index 0000000..7e67e91
--- /dev/null
+++ b/dos/save
@@ -0,0 +1,233 @@
+PACKET save DEFINES (* Copyright (C) 1985, 86, 87 *)
+ (* Frank Klapper *)
+ (* 27.04.87 *)
+ save:
+
+LET ascii = 1,
+ ascii german = 2,
+ transparent = 3,
+ row text = 5,
+ ds = 6,
+ atari st = 10,
+ ibm = 11,
+
+ ff = ""12"",
+ ctrl z = ""26"",
+ cr lf = ""13""10"",
+
+ row text mode length = 4000;
+
+TEXT VAR buffer;
+
+BOUND STRUCT (INT size,
+ ROW row text mode length TEXT cluster row) VAR cluster struct;
+
+PROC save (TEXT CONST file name, DATASPACE CONST file ds, INT CONST mode):
+
+ SELECT mode OF
+ CASE ascii, ascii german, atari st, ibm, transparent:
+ save filemode (file ds, filename, mode)
+ CASE row text : save row textmode (file ds, filename)
+ CASE ds : save dsmode (file ds, filename)
+ OTHERWISE error stop ("Unzulässige Betriebsart")
+ END SELECT.
+
+END PROC save;
+
+PROC save filemode (DATASPACE CONST file space, TEXT CONST name, INT CONST code type):
+
+ enable stop;
+ open save dos file (name);
+ FILE VAR file := sequential file (modify, file space);
+ buffer := "";
+ INT VAR line no;
+ FOR line no FROM 1 UPTO lines (file) REP
+ to line (file, line no);
+ buffer cat file line;
+ WHILE length (buffer) >= cluster size REP
+ write next save dos cluster (subtext (buffer, 1, cluster size));
+ buffer := subtext (buffer, cluster size + 1)
+ PER
+ PER;
+ IF ascii code
+ THEN buffer CAT ctrl z
+ FI;
+ write rest;
+ close save dos file;
+ buffer := "".
+
+buffer cat file line:
+ exec (PROC (TEXT CONST, INT CONST) cat adapted line, file, code type).
+
+ascii code:
+ (code type = ascii) OR (code type = ascii german).
+
+write rest:
+ WHILE buffer <> ""
+ REP write next save dos cluster (subtext (buffer, 1, cluster size));
+ buffer := subtext (buffer, cluster size + 1)
+ PER.
+
+END PROC save filemode;
+
+PROC cat adapted line (TEXT VAR line, INT CONST code type):
+
+ IF code type = transparent
+ THEN buffer CAT line
+ ELSE change esc sequences;
+ change eumel print chars;
+ SELECT code type OF
+ CASE ascii : ascii change
+ CASE ascii german: ascii german change
+ CASE atari st : atari st change
+ CASE ibm : ibm change
+ END SELECT;
+ buffer CAT line;
+ IF (line SUB length (line)) <> ff
+ THEN buffer CAT cr lf
+ FI
+ FI.
+
+change esc sequences:
+ change all (line, "#page#", ff);
+ INT VAR p := pos (line, "#");
+ WHILE p > 0 REP
+ IF is esc sequence
+ THEN change (line, p, p+4, coded char)
+ FI;
+ p := pos (line, "#", p+1)
+ PER.
+
+is esc sequence:
+ LET digits = "0123456789";
+ (line SUB (p+4)) = "#" CAND pos (digits, line SUB p+1) > 0 CAND
+ pos (digits, line SUB p+2) > 0 CAND pos (digits, line SUB p+3) > 0.
+
+coded char:
+ code (int (subtext (line, p+1, p+3))).
+
+change eumel print chars:
+ p := pos (line, ""220"", ""223"", 1);
+ WHILE p > 0 REP
+ replace (line, p, std char);
+ p := pos (line, ""220"", ""223"", p + 1)
+ PER.
+
+std char:
+ "k-# " SUB (code (line SUB p) - 219).
+
+ascii change:
+ change all (line, "ß", "#251#");
+ p := pos (line, "Ä", "ü", 1);
+ WHILE p > 0 REP
+ change (line, p, p, ersatzdarstellung (line SUB p));
+ p := pos (line, "Ä", "ü", p + 1)
+ PER.
+
+ascii german change:
+ change all (line, "[", "#091#");
+ change all (line, "\", "#092#");
+ change all (line, "]", "#093#");
+ change all (line, "{", "#123#");
+ change all (line, "|", "#124#");
+ change all (line, "}", "#125#");
+ change all (line, "~", "#126#");
+ change all (line, "ß", ""126"");
+ p := pos (line, "Ä", "ü", 1);
+ WHILE p > 0 REP
+ replace (line, p, umlaut in ascii german);
+ p := pos (line, "Ä", "ü", p + 1)
+ PER.
+
+umlaut in ascii german:
+ "[\]{|}" SUB (code (line SUB p) - 213).
+
+ibm change:
+ change all (line, "ß", ""225"");
+ p := pos (line, "Ä", "ü", 1);
+ WHILE p > 0 REP
+ replace (line, p, umlaut in ibm);
+ p := pos (line, "Ä", "ü", p + 1)
+ PER.
+
+atari st change:
+ change all (line, "ß", ""158"");
+ p := pos (line, "Ä", "ü", 1);
+ WHILE p > 0 REP
+ replace (line, p, umlaut in ibm);
+ p := pos (line, "Ä", "ü", p + 1)
+ PER.
+
+umlaut in ibm:
+ ""142""153""154""132""148""129"" SUB (code (line SUB p) - 213).
+
+END PROC cat adapted line;
+
+TEXT PROC ersatzdarstellung (TEXT CONST char):
+
+ TEXT CONST t :: text (code (char SUB 1));
+ "#" + (3 - length (t)) * "0" + t + "#"
+
+END PROC ersatzdarstellung;
+
+PROC save rowtextmode (DATASPACE CONST space, TEXT CONST name):
+
+ enable stop;
+ open save dos file (name);
+ init save row textmode;
+ WHILE line no < cluster struct.size REP
+ fill buffer;
+ write next save dos cluster (subtext (buffer, 1, cluster size));
+ remember rest
+ PER;
+ write rest;
+ close save dos file;
+ buffer := "".
+
+init save rowtextmode:
+ cluster struct := space;
+ buffer := "";
+ INT VAR line no := 0.
+
+fill buffer:
+ WHILE line no < cluster struct.size AND NOT buffer full REP
+ line no INCR 1;
+ buffer CAT cluster struct.cluster row [line no]
+ PER.
+
+buffer full:
+ LENGTH buffer >= cluster size.
+
+remember rest:
+ buffer := subtext (buffer, cluster size + 1).
+
+write rest:
+ WHILE buffer <> ""
+ REP write next save dos cluster (subtext (buffer, 1, cluster size));
+ remember rest
+ PER.
+
+END PROC save rowtextmode;
+
+PROC save ds mode (DATASPACE CONST out ds, TEXT CONST name):
+
+ enable stop;
+ open save dos file (name);
+ INT VAR page no := first non dummy ds page;
+ get last allocated ds page;
+ WHILE page no <= last allocated ds page REP
+ write next save dos cluster (out ds, page no);
+ PER;
+ close save dos file.
+
+get last allocated ds page:
+ INT VAR last allocated ds page := -1,
+ i;
+ FOR i FROM 1 UPTO ds pages (out ds) REP
+ last allocated ds page := next ds page (out ds, last allocated ds page)
+ PER.
+
+END PROC save ds mode;
+
+END PACKET save;
+
diff --git a/dos/shard interface b/dos/shard interface
new file mode 100644
index 0000000..20d9b76
--- /dev/null
+++ b/dos/shard interface
@@ -0,0 +1,20 @@
+; ';' in Spalte 1 kennzeichnet eine Kommentarzeile
+; alle Werte müssen durch Blanks getrennt werden
+;
+;heads: Anzahl der Köpfe, positiv für cylinderorientiertes Lesen
+; negativ für seitenorientiertes Lesen
+;
+;size heads tracks first sectors last sector
+;=====================================================
+320 1 40 1 8
+360 1 40 1 9
+640 -2 40 1 8
+720 -2 40 1 9
+800 2 40 1 10
+1440 -2 80 1 9
+1600 2 80 1 10
+2400 -2 80 1 15
+1232 1 77 0 15
+2464 -2 77 0 15
+; END OF FILE
+
diff --git a/dynamo/dyn.33 b/dynamo/dyn.33
new file mode 100644
index 0000000..a17bd55
--- /dev/null
+++ b/dynamo/dyn.33
@@ -0,0 +1,2073 @@
+(**************************************************************************)
+(**************************************************************************)
+(****** ******)
+(****** ******)
+(****** DYNAMO - III - ELAN PRECOMPILER ******)
+(****** ******)
+(****** ******)
+(****** AUTOREN : R. Keil, ******)
+(****** T. Froehlich ******)
+(****** ******)
+(****** VERSION : 3.3.7 ******)
+(****** ******)
+(****** ******)
+(****** AENDERUNGEN: ******)
+(****** 05.10.1983 ******)
+(****** 06.05.1985 Hua&DC: forget("zzdyn.const") ******)
+(****** 08.04.1986 Ley : Anpassung an 1.7.5 ******)
+(****** 02.04.1987 C.Fallis & C.Rensen Einbettung in BOX ******)
+(****** 18.05.1988 dc: Udi Katzirs changes ******)
+(****** should declare vector eingeführt ******)
+(****** 20.05.1988 dc: already used in loop body eingeführt ******)
+(****** Fehlermeldung bei Ref. int index unterdrückt ******)
+(****** weil sie wahrscheinlich selbst ein Fehler ist ******)
+(****** 21.07.1988 Christian Szymanski ******)
+(****** Ausbettung aus BOX ******)
+(****** ******)
+(****** ******)
+(**************************************************************************)
+(**************************************************************************)
+
+
+PACKET dynamo compiler 33 DEFINES init std, dynamo, insert macro,
+ erase, table dump, graphic:
+
+(********************** T A B L E S ********************************)
+
+LET max tab size = 950,
+ max hash size = 300,
+ library = ""15"TAB1"14"",
+ tab name = ""15"TAB2"14"";
+
+BOOL VAR is draw := FALSE;
+
+TYPE TABLE = STRUCT (ROW max tab size TEXT name, init, right part,
+ ROW max tab size INT type, line no, pred, mac,
+ index, index type,
+ ROW max tab size BOOL in use, idef, rdef,
+ already used in loop body,
+ should declare vector,
+ (*18.5.88 dc: Änderung von Udi Katzir *)
+ ROW max hash size INT class,
+ INT tab size,
+ tab beg);
+
+(* already used in loop body: is set to TRUE , if that table-element has been
+ used to generate a line within a loop --> PROC gen loop 20.5.88 dc*)
+
+(* should declare vector : used when rows are declared and indicates if the*)
+(* length of the row is to be taken from the index of the current variable *)
+
+BOUND TABLE VAR tab;
+
+PROC enter (TEXT CONST name, right part, INT CONST type of equ) :
+ INT VAR tab pos;
+ INT CONST hash class := hash (name);
+ search (name, tab pos, lmp, equtype, hash class);
+ table index := tab pos;
+ enter equ.
+
+ enter equ :
+ IF not found OR subscript COR CONCR (tab).type (tabpos) = mac param
+ THEN enter name
+ ELIF type of equ = nequ
+ THEN enter nequ
+ ELIF CONCR (tab).right part (tab pos) = nt
+ THEN complete nequ
+ ELSE err (name, 1)
+ FI.
+
+ equtype :
+ IF subscript
+ THEN type of equ
+ ELSE nil
+ FI.
+
+ enter name :
+ CONCR (tab).tab size INCR 1;
+ tab size := CONCR (tab).tab size;
+ IF tab size > max tab size
+ THEN errorstop ("dynamo table overflow")
+ FI;
+ IF type of equ = nequ
+ THEN CONCR (tab).init (tab size) := right part;
+ CONCR (tab).right part (tab size) := nt
+ ELSE CONCR (tab).init (tab size) := nt;
+ CONCR (tab).right part (tab size) := right part
+ FI;
+ init element.
+
+ init element :
+ CONCR (tab).name (tab size) := name;
+ CONCR (tab).type (tab size) := type of equ;
+ CONCR (tab).line no (tab size) := line no;
+ CONCR (tab).mac (tab size) := lmp;
+ CONCR (tab).index (tab size) := nil;
+ CONCR (tab).index type (tab size) := nil;
+ CONCR (tab).in use (tab size) := FALSE;
+ CONCR (tab).idef (tab size) := FALSE;
+ CONCR (tab).rdef (tab size) := FALSE;
+ CONCR (tab).already used in loop body (tab size) := FALSE;
+ CONCR (tab).pred (tab size) := CONCR (tab).class (hash class);
+ CONCR (tab).class (hash class) := tab size.
+
+ enter nequ :
+ IF CONCR (tab).init (tab pos) <> nt
+ THEN err (name, 2)
+ FI;
+ CONCR (tab).init (tab pos) := right part.
+
+ complete nequ :
+ CONCR (tab).right part (tab pos) := right part;
+ CONCR (tab).type (tab pos) := type of equ;
+ CONCR (tab).line no (tab pos) := line no.
+END PROC enter;
+
+PROC test (TEXT CONST name, INT VAR tab pos, INT CONST last mp, type,
+ err no) :
+ search (name, tab pos, last mp, type);
+ IF not found
+ THEN err (err no)
+ FI
+END PROC test;
+
+PROC search (TEXT CONST name, INT VAR tab pos, INT CONST last mp, type) :
+ search (name, tab pos, last mp, type, hash (name))
+END PROC search;
+
+PROC search (TEXT CONST name, INT VAR tab pos,
+ INT CONST last mp, type, hash class) :
+ not found := TRUE;
+ tab pos := CONCR (tab).class (hash class);
+ WHILE tab pos <> nil CAND name not found REP
+ tab pos := CONCR (tab).pred (tab pos)
+ PER.
+
+ name not found :
+ not found := NOT (CONCR (tab).name (tab pos) = name
+ AND same macro AND type ok);
+ not found.
+
+ same macro :
+ CONCR (tab).mac (tab pos) = last mp.
+
+ type ok :
+ type = nil OR CONCR (tab).type (tab pos) = type.
+END PROC search;
+
+PROC insert macro (TEXT CONST source) :
+ dynamo (source, ""8"", FALSE);
+ kill (""8"");
+ IF errors = nil
+ THEN kill (library);
+ copy (tab name, library)
+ FI
+END PROC insert macro;
+
+PROC init std (TEXT CONST std name) :
+ lmp := nil;
+ kill (library);
+ tab := new (library);
+ FOR i FROM 1 UPTO max hash size REP
+ CONCR (tab).class (i) := nil
+ END REP;
+ CONCR (tab).tab size := nil;
+ enter std procs;
+ CONCR (tab).tab beg := tab size + 1.
+
+enter std procs :
+ FILE VAR std file := sequential file (input, std name);
+ TEXT VAR name, params;
+ WHILE NOT eof (std file) REP
+ get (std file, name);
+ test eof;
+ IF params = "()"
+ THEN params := ""
+ FI;
+ enter (name, params, std p)
+ END REP.
+
+ test eof :
+ IF name = "/*"
+ THEN LEAVE enter std procs
+ ELSE get (std file, params)
+ FI.
+END PROC init std;
+
+PROC next sym :
+ next sym (scan buf, sym, type, scan position)
+END PROC next sym;
+
+PROC next sym (TEXT CONST buf) :
+ next sym (buf, sym, type, scan position)
+END PROC next sym;
+
+PROC test open bracket (TEXT CONST sym) :
+ IF sym <> "("
+ THEN err (sym, 6)
+ FI
+END PROC test open bracket;
+
+PROC test closing bracket (TEXT CONST sym) :
+ IF sym <> ")"
+ THEN err (sym, 58)
+ FI
+END PROC test closing bracket;
+
+PROC test bold (INT CONST err no) :
+ IF type <> bold
+ THEN err (err no)
+ FI
+END PROC test bold;
+
+PROC test equal (INT CONST err no) :
+ IF sym <> "="
+ THEN err (err no)
+ FI
+END PROC test equal;
+
+BOOL OP IN (TEXT CONST pattern, source) :
+ pos (source, pattern) > nil.
+END OP IN;
+
+PROC scan (TEXT CONST buf) :
+ scan buf := buf;
+ scan position := 1
+END PROC scan;
+
+PROC err (TEXT CONST a, INT CONST b) :
+ err (a, b, line no)
+END PROC err;
+
+PROC err (INT CONST i) :
+ err (sym, i, line no)
+END PROC err;
+
+PROC gen (TEXT CONST a) :
+ out buf CAT a
+END PROC gen;
+
+PROC gen (TEXT CONST a, b) :
+ out buf CAT a;
+ out buf CAT b
+END PROC gen;
+
+PROC gen (TEXT CONST a, b, c) :
+ out buf CAT a;
+ out buf CAT b;
+ out buf CAT c
+END PROC gen;
+
+PROC gen (TEXT CONST a, b, c, d) :
+ out buf CAT a;
+ out buf CAT b;
+ out buf CAT c;
+ out buf CAT d
+END PROC gen;
+
+PROC genln (TEXT CONST a, b, c) :
+ gen (a, b, c);
+ lf
+END PROC genln;
+
+PROC lf :
+ putline (target, outbuf);
+ outbuf := nt
+END PROC lf;
+
+PROC gen ln (TEXT CONST t) :
+ outbuf CAT t;
+ putline (target, outbuf);
+ outbuf := nt
+END PROC gen ln;
+
+PROC erase (BOOL CONST b) :
+ erase option := b
+END PROC erase;
+
+PROC dynamo (TEXT CONST s) :
+ TEXT VAR target name := s + ".elan";
+ dynamo (s, target name, TRUE);
+ IF erase option
+ THEN kill (target name)
+ FI;
+ last param (s)
+END PROC dynamo;
+
+PROC dynamo :
+ dynamo (last param)
+END PROC dynamo;
+
+PROC graphic (BOOL CONST mode):
+ is draw := NOT mode
+END PROC graphic;
+
+(********************** C O M P I L E R ************************)
+
+LET bold = 1, number = 2,
+ delimiter = 3, eol = 4,
+ aux = 1, rate = 2,
+ level = 3, nequ = 4,
+ mac name = 6, std p = 7,
+ sub init = 8, table = 9,
+ for = 10, mac param = 11,
+ const = 12, print = 1,
+ plot = 2, global param = 1,
+ none = 3, max print no = 10,
+ supp = 5, any = "ß";
+
+FILE VAR source, target;
+
+ROW max print no TEXT VAR print param;
+
+ROW 10 TEXT VAR plot name, id;
+ROW 10 INT VAR scale pointer;
+ROW 10 TEXT VAR lower bound, upper bound;
+ROW 10 BOOL VAR l fixed scale, u fixed scale;
+
+TEXT VAR buffer, left part, right part, outbuf, print buf,
+ headline, sym, plot buf, asterisk buffer,
+ macro name, noise buffer, constant, run buffer,
+ scan buf;
+
+INT VAR print param no, print line no, tab beg, type, line no,
+ plot line no, scale counter, plot param no,
+ last pos, lmp, index, (* lmp = Last Macro Position *)
+ index type, for index, i, tab size, expansion no,
+ table index, scan position, old tab beg;
+
+BOOL VAR k, kl, is first, fixed scale, in macro,
+ in loop, not found, internal, subscript,
+ erase option := FALSE;
+
+TEXT CONST nt := "";
+
+INT CONST nil := 0;
+
+
+(*$$$$$$$$$$ ZUSATZ C & C 20.2.87 eingefuegt : error listing $$$$$$$$$*)
+(* Diese Prozedur erzeugt einen zweigeteilten Bildschirm, wobei *)
+(* die Datei 'procsource' (d.h. das Dynamo-Quellprogramm) in der *)
+(* oberen Haelfte und die Fehlerdatei 'notebook' in der unteren *)
+(* Haelfte steht. *)
+
+PROC error listing (FILE VAR procsource) : (* C.S. 21.07.88 *)
+ note edit (procsource);
+END PROC error listing;
+(*$$$$$$$$$$$$$$$$$$$$ ENDE ZUSATZ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*)
+
+
+PROC dynamo (TEXT CONST source name, target name, BOOL CONST pass2) :
+ init dynamo;
+ first pass;
+ IF no errors
+ THEN second pass
+ ELSE error listing(source);
+ error stop ("") (* C.S. 21.07.88 *)
+ (* Falls Fehler im ersten Durchlauf gefunden wurden, wird der zweite *)
+ (* Durchlauf erst gar nicht durchgefuehrt, sondern das fehlerhafte *)
+ (* Dynamo-Programm und die Fehlerdatei werden ausgegeben . *)
+ FI.
+
+ first pass :
+ WHILE NOT eof (source) REP
+ read source line;
+ translate line
+ PER;
+ IF NOT pass2
+ THEN LEAVE dynamo
+ FI;
+ end of first pass.
+
+ second pass :
+ generate initializations;
+ generate equations.
+
+ generate initializations :
+ generate rts call;
+ generate noise card;
+ generate table part;
+ generate for variables;
+ generate variable part;
+ generate table init;
+ generate init print;
+ generate init plot;
+ generate init scale;
+ generate asterisk;
+ gen repeat.
+
+ generate equations :
+ generate print line;
+ generate plot line;
+ gen equations (level);
+ gen equations (aux);
+ gen equations (supp);
+ gen equations (rate);
+ gen end repeat;
+ IF no errors
+ THEN run (target name)
+ ELSE error listing(source);
+ error stop ("") (* C.S. 21.07.88 *)
+ (* Falls im zweiten Durchlauf Fehler gefunden wurden, wird das *)
+ (* ELAN-Zielprogramm nicht ausgefuehrt, sondern das fehlerhafte *)
+ (* Dynamo-Quellprogramm und die Fehlerdatei werden ausgegeben . *)
+ FI.
+
+ init dynamo :
+ kill (target name);
+ init tables;
+ source := sequential file (input, source name);
+ target := sequential file (output, target name);
+ print buf := nt;
+ outbuf := nt;
+ plot buf := nt;
+ noise buffer := nt;
+ asterisk buffer := nt;
+ macro name := nt;
+ run buffer := "zzdyn";
+ line no := nil;
+ plot param no := nil;
+ last pos := nil;
+ lmp := nil;
+ index := nil;
+ index type := nil;
+ expansion no := nil;
+ in macro := FALSE;
+ internal := FALSE;
+ in loop := FALSE;
+ is first := TRUE;
+ tab beg := CONCR (tab).tab beg;
+ old tab beg := CONCR (tab).tab size + 1;
+ init errors.
+
+ init tables :
+ kill (tab name);
+ copy (library, tab name);
+ tab := old (tab name).
+
+ read source line :
+ line no INCR 1;
+ getline (source, buffer);
+ cout (line no);
+ scan (buffer);
+ next sym.
+
+ translate line :
+ TEXT VAR start := sym;
+ next sym;
+ WHILE sym = " " REP next sym PER;
+ SELECT
+ pos ("a c l n r print plot note EOL spec * x macro mend for s noise run ",
+ start + " ") OF
+ CASE 1 : enter equ (TRUE, FALSE, aux, 9)
+ CASE 3, 31 : constant equ
+ CASE 5 : enter equ (TRUE, FALSE, level, 11)
+ CASE 7 : enter equ (FALSE, FALSE, nequ, 56)
+ CASE 9 : enter equ (FALSE, TRUE, rate, 12)
+ CASE 11 : print card
+ CASE 17 : plot card
+ CASE 22, 27 : (* comment; empty line *)
+ CASE 36 : gen headline
+ CASE 15 : enter equ (FALSE, FALSE, table, 13)
+ CASE 38 : continuation card
+ CASE 40 : macro card
+ CASE 46 : macro end
+ CASE 51 : for card
+ CASE 55 : enter equ (TRUE, FALSE, supp, 9)
+ CASE 57 : noise card
+ CASE 63 : run card
+ OTHERWISE : err (start, 3)
+ END SELECT.
+
+ macro card :
+ IF in macro
+ THEN err (4)
+ FI;
+ in macro := TRUE;
+ get macro name;
+ get macro param list.
+
+ get macro name :
+ IF type = bold
+ THEN enter (sym, nt, mac name);
+ CONCR (tab).line no (tab size) := nil;
+ macro name := sym;
+ lmp := tab size
+ ELSE err (5)
+ FI.
+
+ get macro param list :
+ next sym;
+ test open bracket (sym);
+ next sym;
+ WHILE sym <> ")" REP
+ IF type = bold
+ THEN enter (sym, nt, mac param)
+ ELSE err (7)
+ FI;
+ next sym;
+ IF sym = ","
+ THEN next sym
+ FI
+ END REP;
+ test closing bracket (sym).
+
+ macro end :
+ lmp := nil;
+ in macro := FALSE.
+
+ constant equ :
+ REP
+ analyze constant equ;
+ enter (left part, constant, const);
+ last pos := tab size
+ UNTIL end of constants PER.
+
+ analyze constant equ :
+ test bold (10);
+ left part := sym;
+ next sym;
+ test equal (21);
+ get constant.
+
+ end of constants :
+ next sym;
+ test delimiter.
+
+ get constant :
+ next sym;
+ IF NOT sym is number (constant)
+ THEN err (37)
+ FI.
+
+ print card :
+ IF print buf = nt
+ THEN print buf := subtext (buffer, scanposition - length (sym));
+ print line no := line no
+ ELSE print buf CAT "," + subtext (buffer, scanposition - length (sym))
+ FI;
+ last pos := print.
+
+ plot card :
+ IF plot buf = nt
+ THEN plot buf := subtext (buffer, scanposition - length (sym));
+ plot line no := line no;
+ ELSE plot buf CAT "/" + subtext (buffer, scanposition - length (sym))
+ FI;
+ last pos := plot.
+
+ gen headline :
+ asterisk buffer := "asterisk (""" + subtext (buffer, 3) + """);".
+
+ generate asterisk :
+ IF asterisk buffer <> nt
+ THEN genln (asterisk buffer)
+ FI.
+
+ continuation card :
+ skip blanks;
+ TEXT CONST tail := subtext (buffer, i);
+ SELECT last pos OF
+ CASE print : print buf CAT "," + tail
+ CASE plot : plot buf CAT "/" + tail
+ CASE none : err (14)
+ OTHERWISE : content CAT tail
+ END SELECT.
+
+ content :
+ IF CONCR (tab).type (last pos) = nequ
+ THEN CONCR (tab).init (last pos)
+ ELSE CONCR (tab).right part (last pos)
+ FI.
+
+ skip blanks :
+ i := 1;
+ REP
+ i INCR 1
+ UNTIL (buffer SUB i) <> " " END REP.
+
+ for card :
+ REP
+ read for variable
+ UNTIL end of forlist END REP.
+
+ end of forlist :
+ IF sym = "/"
+ THEN next sym; FALSE
+ ELSE TRUE
+ FI.
+
+ read for variable :
+ TEXT VAR init; (* left part = name *)
+ test bold (15); (* right part = obere Grenze *)
+ left part := sym; (* init = untere Grenze *)
+ next sym;
+ test equal (16);
+ next sym;
+ pass ranges;
+ enter (left part, right part, for);
+ CONCR (tab).init (tab size) := init.
+
+ pass ranges :
+ test number (init);
+ IF sym <> ","
+ THEN err (18)
+ FI;
+ next sym;
+ test number (right part).
+
+ noise card :
+ IF NOT sym is number (noise buffer)
+ THEN err (66)
+ FI.
+
+ run card :
+ test bold (65);
+ run buffer := sym.
+
+ gen repeat :
+ lf;
+ genln ("WHILE time <= length REP");genln (" cout(int(time));");
+ genln (" set time (time);").
+
+ gen end repeat :
+ genln ("UNTIL " + draw ad + "stop request PER;");
+ IF plot buf <> nt
+ THEN genln (draw ad + "end of program;")
+ FI;
+ genln ("END PROC target program").
+
+ generate rts call :
+ genln ("forget (""zzdyn.const"",quiet);");
+ genln ("run card (""", run buffer, """);");
+ genln ("run time system (PROC target program);");
+ lf;
+ genln ("PROC target program :").
+
+ generate noise card :
+ IF noise buffer <> nt
+ THEN genln (" initialize random (", noise buffer, ");")
+ FI.
+
+ generate plot line :
+ IF plot buf <> nt
+ THEN gen plots
+ FI.
+
+ gen plots :
+ genln (draw ad + " new plot line (time);");
+ FOR i FROM 1 UPTO plot param no REP
+ genln (draw ad + " plot (", plot name (i), ");");
+ genln ("IF " + draw ad + " stop request THEN LEAVE target program " +
+ "END IF;")
+ END REP.
+
+ generate print line :
+ IF print buf <> nt
+ THEN gen prints
+ FI.
+
+ gen prints :
+ genln (" new line (time);");
+ FOR i FROM 1 UPTO print param no REP
+ genln (" print (", printparam (i), ");")
+ END REP.
+
+ generate init plot :
+ INT VAR tab pos;
+ IF plot buf <> nt
+ THEN search ("pltper", tab pos, nil, const);
+ IF not found
+ THEN IF is draw THEN
+ err ("draw", 25, plot line no)
+ ELSE
+ err ("plot", 25, plot line no)
+ END IF
+ ELSE genln (draw ad + "initialize plot (""", plot buf, """);");
+(*$$$$$$$$$$$$$ ZUSATZ Februar87 C&C eingefuegt: pltper INCR 0 $$$$$$$$$*)
+ genln ("pltper INCR 0.0 ;");
+ genln (" (* um Warnung des ELAN-Compilers zu unterdruecken *)")
+(*$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDE ZUSATZ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*)
+ FI
+ FI.
+END PROC dynamo;
+
+PROC test number (TEXT VAR content) :
+ SELECT type OF
+ CASE bold : content := sym
+ CASE number : content := trunc (sym)
+ OTHERWISE err (17)
+ END SELECT;
+ next sym
+END PROC test number;
+
+PROC enter equ (BOOL CONST x, y, INT CONST exp type, err no) :
+ get left part;
+ enter (left part, right part, exp type);
+ set index;
+ test global;
+ IF incorrect time script
+ THEN err (err no)
+ FI.
+
+ incorrect time script :
+ (k XOR x) OR (kl XOR y).
+
+ set index :
+ INT VAR last entry := table position;
+ last pos := last entry;
+ CONCR (tab).index (last entry) := index;
+ CONCR (tab).index type (last entry) := index type.
+
+ table position :
+ IF exp type = nequ AND index type = nil AND NOT not found
+ THEN table index
+ ELSE tab size
+ FI.
+
+ test global :
+ IF in macro AND NOT internal
+ THEN search global
+ FI.
+
+ search global :
+ INT VAR tab pos;
+ search (left part, tab pos, lmp, mac param);
+ IF not found
+ THEN IF left part <> macro name
+ THEN err (left part, 64)
+ FI
+ ELSE CONCR (tab).index (last entry) := tab pos;
+ CONCR (tab).index type (last entry) := -1;
+ CONCR (tab).index type (tab pos) := global param;
+ CONCR (tab).index (tab pos) := last entry
+ FI.
+
+ get left part :
+ get name;
+ get time script;
+ get index.
+
+ get name :
+ internal := sym = "$";
+ IF internal
+ THEN next sym;
+ IF NOT in macro
+ THEN err (19)
+ FI
+ FI;
+ test bold (20);
+ left part := sym; next sym.
+
+ get time script :
+ IF sym = "."
+ THEN process time script
+ ELSE k := FALSE; kl := FALSE
+ FI;
+ subscript := sym = "(".
+
+ get index :
+ IF subscript
+ THEN process index
+ ELSE index := nil;
+ index type := nil
+ FI;
+ right part := subtext (buffer, scanposition);
+ test equal (21).
+
+ process time script :
+ next sym;
+ k := sym = "k"; kl := sym = "kl";
+ next sym.
+
+ process index :
+ next sym;
+ SELECT type OF
+ CASE number : index := int (sym)
+ CASE bold : search for variable
+ OTHERWISE : err (22)
+ END SELECT;
+ index type := type;
+ next sym;
+ test closing bracket (sym);
+ next sym.
+
+ search for variable :
+ test (sym, tab pos, lmp, for, 61);
+ index := tab pos.
+END PROC enter equ;
+
+PROC end of first pass :
+ INT VAR tab pos;
+ init time;
+ search macro calls;
+ search system constants.
+
+ init time :
+ search ("time", tab pos, nil, nequ);
+ IF not found
+ THEN enter ("time", "0.0", nequ)
+ FI;
+ enter ("time", "time.j+dt", level).
+
+ search system constants :
+ sym := nt;
+ test ("dt", tab pos, nil, const, 35);
+ test ("length", tab pos, nil, const, 36).
+
+ search macro calls :
+ INT VAR old tabsize := tabsize;
+ FOR i FROM old tabbeg UPTO old tabsize REP
+ IF is normal equ
+ THEN enter global macro params
+ FI
+ END REP;
+ tab size := old tabsize.
+
+ is normal equ :
+ SELECT CONCR (tab).type (i) OF
+ CASE aux, rate, level, nequ, supp : TRUE
+ OTHERWISE : FALSE
+ END SELECT.
+
+ enter global macro params :
+ enter params (CONCR (tab).right part (i), FALSE);
+ enter params (CONCR (tab).init (i), TRUE).
+END PROC end of first pass;
+
+PROC enter params (TEXT CONST buf, BOOL CONST is init) :
+ TEXT VAR macro name;
+ IF pos (buf, "(") > nil
+ THEN read params
+ FI.
+
+ read params :
+ scan position := 1;
+ REP
+ next sym (buf, macro name, type, scan position);
+ IF type = bold
+ THEN next sym (buf);
+ IF sym = "("
+ THEN parameter list
+ FI
+ FI
+ UNTIL type = eol END REP.
+
+ parameter list :
+ INT VAR act param, tab pos;
+ search (macro name, tab pos, nil, nil);
+ IF NOT not found CAND CONCR (tab).type (tab pos) = mac name
+ THEN read param list
+ FI.
+
+ read param list :
+ CONCR (tab).index type (tab pos) INCR 1;
+ act param := tab pos;
+ REP
+ next sym (buf);
+ act param INCR 1;
+ IF CONCR (tab).type (act param) = mac param
+ THEN test parameter
+ ELSE err (macro name, 53)
+ FI
+ UNTIL end of parameter list END REP.
+
+ test parameter :
+ TEXT VAR param;
+ IF CONCR (tab).index type (act param) = global param
+ THEN get global param
+ ELSE get actual param
+ FI;
+ content CAT param + "%".
+
+ content :
+ IF is init
+ THEN CONCR (tab).init (act param)
+ ELSE CONCR (tab).right part (act param)
+ FI.
+
+ get global param :
+ INT VAR param index;
+ IF type = bold
+ THEN enter param
+ FI.
+
+ enter param :
+ param index := CONCR (tab).index (act param);
+ enter (sym, CONCR (tab).right part (param index),
+ CONCR (tab).type (param index));
+ CONCR (tab).init (tab size) := CONCR (tab).init (param index);
+ CONCR (tab).index (tab size) := act param;
+ param := sym;
+ next sym (buf);
+ get time script.
+
+ get actual param :
+ INT VAR brackets := nil;
+ param := nt;
+ REP
+ param CAT sym;
+ next sym (buf);
+ get time script
+ UNTIL end of param END REP.
+
+ get time script :
+ IF sym = "."
+ THEN param CAT sym;
+ next sym (buf);
+ param CAT any;
+ next sym (buf)
+ FI.
+
+ end of param :
+ IF brackets = nil
+ THEN sym IN ",)"
+ ELIF sym = "("
+ THEN brackets INCR 1;
+ FALSE
+ ELIF sym = ")"
+ THEN brackets DECR 1;
+ TRUE
+ ELSE FALSE
+ FI.
+
+ end of parameter list :
+ SELECT pos (",)", sym) OF
+ CASE 1 : FALSE
+ CASE 2 : TRUE
+ OTHERWISE : err (50); TRUE
+ END SELECT.
+END PROC enter params;
+
+(************************* P A S S 2 ***************************)
+
+PROC generate init print :
+ INT VAR tab pos;
+ IF print buf <> nt
+ THEN test ("prtper", tab pos, nil, const, 24);
+ gen init
+ FI.
+
+ gen init :
+ print param no := nil;
+ headline := nt;
+ scan (print buf);
+ line no := print line no;
+ cout (line no);
+ REP
+ get parameter
+ UNTIL sym <> "," END REP;
+ genln ("initialize print (""", headline, """);");
+ (*$$$$$$$$$$$$$ ZUSATZ Februar87 C&C eingefuegt: prtper INCR 0 $$$$$$$$$$*)
+ genln ("prtper INCR 0.0 ;");
+ genln ("(* Um Warnung des ELAN-Compilers zu unterdruecken *)").
+ (*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDE ZUSATZ $$$$$$$$$$$$$$$$$$$$$$$*)
+ get parameter :
+ next sym;
+ test bold (33);
+ get print param.
+
+ get print param :
+ test (sym, tab pos, nil, nil, 32);
+ enter name.
+
+ enter name :
+ TEXT VAR act param := sym;
+ INT VAR pos := scanposition - length (sym);
+ test subscript (act param, 33);
+ print param no INCR 1;
+ print param (print param no) := act param;
+ headline CAT text (subtext (print buf, pos, scanposition - 1), 13);
+ headline CAT " ".
+END PROC generate init print;
+
+PROC test subscript (TEXT VAR act param, INT CONST err no) :
+ INT VAR tab pos;
+ next sym;
+ IF sym = "("
+ THEN test index
+ FI.
+
+ test index :
+ next sym;
+ act param CAT " SUB ";
+ act param CAT subscript;
+ next sym;
+ test closing bracket (sym);
+ next sym.
+
+ subscript :
+ SELECT type OF
+ CASE number : trunc (sym)
+ CASE bold : search index
+ OTHERWISE : err (err no); nt
+ END SELECT.
+
+ search index :
+ test (sym, tab pos, nil, for, 61);
+ sym.
+END PROC test subscript;
+
+PROC generate init scale :
+ IF plot buf <> nt
+ THEN gen plot card
+ FI.
+
+ gen plot card :
+ scale counter := 1;
+ plot param no := nil;
+ line no := plot line no;
+ cout (line no);
+ scan (plot buf);
+ REP
+ equal scale;
+ different scale
+ UNTIL type = eol OR sym = " " END REP;
+ generate scales.
+
+ equal scale :
+ fixed scale := FALSE;
+ REP
+ next sym;
+ single scale param
+ UNTIL sym <> "," END REP.
+
+ different scale :
+ IF sym = "/"
+ THEN scale counter INCR 1
+ ELIF type <> eol
+ THEN err (sym, 26, plot line no)
+ FI.
+
+ generate scales :
+ clear scales;
+ gen plot scales.
+
+ gen plot scales :
+ FOR i FROM 1 UPTO plot param no REPEAT
+ gen (draw ad + "plot scale (""", id (i), """, ",
+ text (scale pointer (i)));
+ gen (", ", lower scale, ", ", upper scale);
+ gen (", ", text (l fixed scale (i)), ", ", text (u fixed scale (i)));
+ genln (");")
+ END REP.
+
+ lower scale :
+ IF l fixed scale (i)
+ THEN lower bound (i)
+ ELSE "9.0e126"
+ FI.
+
+ upper scale :
+ IF u fixed scale (i)
+ THEN upper bound (i)
+ ELSE "-9.0e126"
+ FI.
+
+ clear scales :
+ FOR i FROM scale counter+1 UPTO plot param no REP
+ lower bound (i) := "0.0";
+ upper bound (i) := "0.0"
+ PER.
+
+ single scale param :
+ test bold (27);
+ enter plot param.
+
+ enter plot param :
+ TEXT VAR param := sym;
+ test subscript (param, 22);
+ plot param no INCR 1;
+ IF plot param no > 10
+ THEN err (64);
+ LEAVE generate init scale
+ FI;
+ plot name (plot param no) := param;
+ scalepointer (plot param no) := scalecounter;
+ set id;
+ set scale.
+
+ set id :
+ IF sym = "="
+ THEN next sym;
+ id (plot param no) := (sym SUB 1);
+ next sym
+ ELSE id (plot param no) := text (plot param no - 1)
+ FI.
+
+ set scale :
+ IF sym = "("
+ THEN get plot scale;
+ fixed scale := TRUE
+ ELIF NOT fixed scale
+ THEN l fixed scale (scale counter) := FALSE;
+ u fixed scale (scale counter) := FALSE;
+ FI.
+
+ get plot scale :
+ IF fixed scale
+ THEN err (28)
+ FI;
+ read scale param (lower bound, l fixed scale, 29);
+ IF sym <> ","
+ THEN err (30)
+ FI;
+ read scale param (upper bound, u fixed scale, 30);
+ test closing bracket (sym);
+ next sym.
+END PROC generate init scale;
+
+PROC read scale param (ROW 10 TEXT VAR bound, ROW 10 BOOL VAR fixed scale,
+ INT CONST err no) :
+ TEXT VAR scale;
+ INT VAR tab pos;
+ next sym;
+ IF type = bold
+ THEN test (sym, tab pos, nil, const, 61);
+ bound (scale counter) := sym;
+ fixed scale (scale counter) := TRUE
+ ELIF sym is number (scale)
+ THEN bound (scale counter) := scale;
+ fixed scale (scale counter) := TRUE
+ ELIF sym = "*"
+ THEN fixed scale (scale counter) := FALSE
+ ELSE err (err no)
+ FI;
+ next sym
+END PROC read scale param;
+
+BOOL PROC sym is number (TEXT VAR constant) :
+ constant := nt;
+ IF sym IN "+-"
+ THEN constant := sym; next sym
+ FI;
+ IF type = number
+ THEN constant CAT sym;
+ TRUE
+ ELSE FALSE
+ FI
+END PROC sym is number;
+
+PROC gen equations (INT CONST equ type) :
+ INT VAR i;
+ gen normal equs;
+ end of init list;
+ gen index equs.
+
+ gen normal equs :
+ FOR i FROM tabbeg UPTO tabsize REP
+ IF is normal equ
+ THEN generate equ
+ FI
+ END REP.
+
+ generate equ :
+ declare variables (i, equ type, FALSE).
+
+ is normal equ :
+ CONCR (tab).type (i) = equ type
+ AND NOT CONCR (tab).rdef (i) AND CONCR (tab).index type (i) <= nil
+ AND NOT CONCR (tab).already used in loop body(i).
+
+ gen index equs :
+ FOR i FROM tabbeg UPTO tabsize REP
+ IF is index equ
+ THEN gen loop (i, equ type)
+ FI
+ END REP.
+
+ is index equ :
+ CONCR (tab).type (i) = equ type AND
+ NOT CONCR (tab).rdef (i) AND CONCR (tab).index type (i) > nil
+ AND NOT CONCR (tab).already used in loop body(i).
+
+END PROC gen equations;
+
+PROC gen loop (INT CONST i, equ type) :
+ for index := CONCR (tab).index (i);
+ TEXT VAR gen buf;
+ SELECT CONCR (tab).index type (i) OF
+ CASE bold : gen for loop
+ CASE number : generate replace
+ END SELECT.
+
+ generate replace :
+ INT VAR k := i;
+ expression (equ type, gen buf, k);
+ gen replace (gen buf, k, text (for index)).
+
+ gen for loop :
+ gen (" FOR ", CONCR (tab).name (for index), " FROM ",
+ CONCR (tab).init (for index));
+ genln (" UPTO ", CONCR (tab).right part (for index), " REP");
+ in loop := TRUE;
+ IF equ type = sub init
+ THEN gen replace (equ type, i)
+ ELSE search equal indices
+ FI;
+ in loop := FALSE;
+ genln (" PER;").
+
+ search equal indices :
+ INT VAR j;
+ FOR j FROM i UPTO tab size REP
+ IF is same index
+ THEN gen replace (equ type, j);
+ CONCR (tab).already used in loop body(j):=TRUE
+ FI
+ END REP.
+
+ is same index :
+ for index = CONCR (tab).index (j)
+ AND CONCR (tab).index type (j) = bold
+ AND CONCR (tab).type (j) = CONCR (tab).type (i)
+ AND NOT CONCR (tab).rdef (j)
+ AND NOT CONCR (tab).already used in loop body(j).
+
+END PROC gen loop;
+
+PROC gen replace (TEXT VAR gen buf, INT CONST table index) :
+ gen replace (gen buf, table index, CONCR (tab).name (for index))
+END PROC gen replace;
+
+PROC gen replace (TEXT VAR gen buf, INT CONST table index, TEXT CONST index):
+ gen (" replace (", CONCR (tab).name (table index), ", ", index);
+ genln (", ", gen buf, ");")
+END PROC gen replace;
+
+PROC gen replace (INT CONST equ type, tabpos) :
+ INT VAR no := tab pos;
+ TEXT VAR gen buf;
+ expression (equ type, gen buf, no);
+ gen replace (gen buf, no)
+END PROC gen replace;
+
+PROC generate for variables :
+ is first := TRUE;
+ FOR i FROM tab beg UPTO tab size REP
+ IF CONCR (tab).type (i) = for
+ THEN gen for var
+ FI
+ END REP;
+ end of init list.
+
+ gen for var :
+ set line no (i);
+ IF is first
+ THEN gen ("INT VAR ");
+ is first := FALSE
+ ELSE continue init list
+ FI;
+ gen (CONCR (tab).name (i)).
+END PROC generate for variables;
+
+PROC generate variable part :
+ generate constants;
+ generate variables;
+ generate missed inits.
+
+ generate constants :
+ INT VAR i;
+ FOR i FROM tab beg UPTO tabsize REP
+ IF CONCR (tab).type (i) = const AND NOT CONCR (tab).idef (i)
+ THEN gen const
+ FI
+ END REP.
+
+ generate variables :
+ FOR i FROM tab beg UPTO tab size REP
+ SELECT CONCR (tab).type (i) OF
+ CASE level, aux, nequ, rate : gen normal equ
+ END SELECT
+ END REP.
+
+ generate missed inits :
+ FOR i FROM tab beg UPTO tab size REP
+ SELECT CONCR (tab).type (i) OF
+ CASE aux, rate : gen missed init
+ END SELECT;
+ END REP;
+ end of init list.
+
+ gen missed init :
+ IF sub init necessary
+ THEN declare variables (i, sub init, TRUE)
+ FI.
+
+ sub init necessary :
+ CONCR (tab).init (i) = nt AND
+ NOT CONCR (tab).idef (i) AND CONCR (tab).index type (i) <= nil.
+
+ gen normal equ :
+ IF equ not yet declared
+ THEN declare variables (i, nequ, TRUE)
+ FI.
+
+ equ not yet declared :
+ NOT CONCR (tab).idef (i) AND CONCR (tab).init (i) <> nt
+ AND CONCR (tab).index type (i) <= nil.
+
+ gen const :
+ gen linefeed;
+ gen (" ");
+ gen zz (i);
+ gen (CONCR (tab).name (i), " := ", "constant (""", CONCR (tab).name (i));
+ gen (""", ", CONCR (tab).right part (i), ")").
+END PROC generate variable part;
+
+PROC end of init list :
+ IF NOT is first
+ THEN is first := TRUE;
+ genln (";")
+ FI
+END PROC end of init list;
+
+PROC gen zz (INT CONST no) :
+ IF CONCR (tab).mac (no) > nil
+ THEN gen ("zz", CONCR(tab).name (CONCR(tab).mac (no)), text (expansion no))
+ FI
+END PROC gen zz;
+
+PROC declare variables (INT CONST no, equ type, BOOL CONST is init) :
+ INT VAR mac no := CONCR (tab).mac (no);
+ IF mac no > nil
+ THEN gen local equs
+ ELSE declare variable (no, equ type, is init)
+ FI.
+
+ gen local equs :
+ INT VAR no of expansions := CONCR (tab).indextype (mac no);
+ FOR expansion no FROM 1 UPTO no of expansions REP
+ declare variable (no, equ type, is init)
+ END REP.
+END PROC declare variables;
+
+PROC declare variable (INT CONST no, exp type, BOOL CONST init) :
+ TEXT VAR gen buf;
+ INT VAR i := no;
+ IF (init AND NOT CONCR (tab).idef (no)) OR
+ (NOT init AND NOT CONCR (tab).rdef (no))
+ THEN gen equ
+ FI.
+
+gen equ :
+ expression (exp type, gen buf, i);
+ IF init
+ THEN gen linefeed
+ FI;
+ gen (" ");
+ gen zz (i);
+ gen (CONCR (tab).name (i), " := ", gen buf);
+ IF NOT init
+ THEN genln (";")
+ FI
+END PROC declare variable;
+
+PROC gen linefeed :
+ IF is first
+ THEN is first := FALSE;
+ gen ("REAL VAR ")
+ ELSE continue init list
+ FI
+END PROC gen linefeed;
+
+PROC set line no (INT CONST index) :
+ line no := CONCR (tab).line no (index);
+ cout (line no)
+END PROC set line no;
+
+PROC continue init list :
+ genln (","); gen (" ");
+END PROC continue init list;
+
+PROC gen tab var :
+ IF is first
+ THEN gen ("TAB VAR "); is first := FALSE
+ ELSE continue init list
+ FI
+END PROC gen tab var;
+
+PROC generate table part :
+ is first := TRUE;
+ FOR i FROM tabbeg UPTO tabsize REP
+ SELECT CONCR (tab).type (i) OF
+ CASE table : gen tab declaration;
+ gen tab init
+ CASE aux, rate, level : IF CONCR (tab).index type (i) = bold
+ THEN
+ IF CONCR(tab).type(i)=aux THEN
+ IF NOT CONCR(tab).should declare vector(i)
+ THEN
+ find maximum index for current variable
+ FI;
+ IF CONCR(tab).should declare vector(i)
+ THEN
+ gen row init
+ FI
+ ELSE
+ gen row init
+ FI (*18.5.88 dc*)
+ FI
+ END SELECT
+ END REP;
+ end of init list.
+
+gen tab declaration :
+ gen tab var;
+ gen (CONCR (tab).name (i), " := vector (", vec length);
+ genln (");");
+ is first := TRUE.
+
+gen tab init :
+ INT VAR elem no := 1;
+ scan (CONCR (tab).right part (i)); next sym;
+ set line no (i);
+ WHILE type is number REP
+ gen ("replace (", CONCR (tab).name (i), ", ", text (elem no));
+ genln (", ", constant, ");");
+ next sym;
+ elem no INCR 1
+ UNTIL end of constant list END REP.
+
+ type is number :
+ IF sym is number (constant)
+ THEN TRUE
+ ELSE err (40); FALSE
+ FI.
+
+ end of constant list :
+ test delimiter.
+
+ vec length :
+ INT VAR p, l := 1;
+ FOR p FROM 2 UPTO length (CONCR (tab).right part (i)) REP
+ IF (CONCR (tab).right part (i) SUB p) IN ",/"
+ THEN l INCR 1
+ FI
+ PER; text (l).
+
+ gen row init :
+ gen tab var;
+ gen (CONCR (tab).name (i), " := vector (", row length, ")").
+
+ row length :
+ set line no (i);
+ CONCR (tab).right part (CONCR (tab).index (i)).
+
+ find maximum index for current variable:
+ INT VAR maximum, place, k;
+ TEXT VAR name::CONCR(tab).name(i);
+ maximum:=int(CONCR(tab).right part(CONCR(tab).index(i)));
+ place:=i;
+ FOR k FROM tabbeg UPTO tabsize REPEAT
+ check maximum of index and change if needed;
+ CONCR(tab).should declare vector(k):=FALSE
+ PER;
+ CONCR(tab).should declare vector(place):=TRUE.
+
+check maximum of index and change if needed:
+ IF same variable CAND need to change
+ THEN
+ maximum:=int(CONCR(tab).right part(CONCR(tab).index(k)));
+ place:=k
+ FI.
+
+need to change:
+ maximum < int(CONCR(tab).right part(CONCR(tab).index(k))).
+
+same variable:
+ name =CONCR(tab).name(k) CAND CONCR(tab).index type(k) = 1.
+
+
+END PROC generate table part;
+
+BOOL PROC test delimiter :
+ SELECT pos ("/, EOL", sym) OF
+ CASE 1, 2 : next sym; FALSE
+ CASE 3, 4 : TRUE
+ OTHERWISE : err (62); TRUE
+ END SELECT
+END PROC test delimiter;
+
+PROC generate table init :
+ INT VAR i, tab pos;
+ FOR i FROM tabbeg UPTO tabsize REP
+ IF CONCR (tab).index type (i) > nil AND NOT CONCR (tab).idef (i)
+ THEN gen tab init
+ FI
+ END REP.
+
+ gen tab init :
+ SELECT CONCR (tab).type (i) OF
+ CASE nequ : gen loop (i, nequ)
+ CASE aux, rate : gen missed table init
+ CASE mac name : CONCR (tab).line no (i) := nil
+ END SELECT.
+
+ gen missed table init :
+ search (CONCR (tab).name (i), tab pos, nil, nequ);
+ IF not found
+ THEN gen loop (i, sub init)
+ FI.
+END PROC generate table init;
+
+PROC sort equ (INT CONST tab pos, equ type) :
+ IF in loop
+ THEN gen replace (equ type, tab pos)
+ ELSE declare variable (tab pos, equ type, equ type = nequ OR
+ equ type = sub init)
+ FI
+END PROC sort equ;
+
+PROC expression (INT CONST equtype, TEXT VAR gen buf, INT VAR no) :
+ TEXT VAR symbol, buf := equation;
+ INT VAR spos := 1, stype, tabpos;
+ gen buf := nt;
+ set line no (no);
+ test global equ;
+ compile equ;
+ IF CONCR (tab).mac (no) = nil
+ COR expansion no >= CONCR (tab).index type (CONCR (tab).mac (no))
+ THEN set def flag
+ FI.
+
+ test global equ :
+ IF CONCR (tab).index type (no) < nil
+ THEN replace global mac param
+ FI.
+
+ replace global mac param :
+ INT CONST param index := CONCR (tab).index (no);
+ search (actual parameter (CONCR (tab).rightpart (paramindex)),
+ tabpos, nil, nil);
+ no := tabpos;
+ expression (type of param, gen buf, no);
+ LEAVE expression.
+
+ type of param :
+ IF equ type = sub init
+ THEN CONCR (tab).type (no)
+ ELSE equ type
+ FI.
+
+ compile equ :
+ IF CONCR (tab).in use (no)
+ THEN err (CONCR (tab).name (no), 43)
+ ELSE pass expression
+ FI.
+
+ pass expression :
+ CONCR (tab).in use (no) := TRUE;
+ expression2 (equtype, no, spos, stype, genbuf, symbol, buf);
+ CONCR (tab).in use (no) := FALSE.
+
+ equation :
+ IF equtype = nequ
+ THEN CONCR (tab).init (no)
+ ELSE CONCR (tab).right part (no)
+ FI.
+
+ set def flag :
+ SELECT equtype OF
+ CASE nequ, sub init : CONCR (tab).idef (no) := TRUE
+ CASE level : test level
+ OTHERWISE : CONCR (tab).rdef (no) := TRUE
+ END SELECT.
+
+ test level :
+ IF CONCR (tab).init (no) = nt AND CONCR (tab).index type (no) = nil
+ THEN err (CONCR (tab).name (no), 39)
+ FI.
+END PROC expression;
+
+PROC expression2 (INT CONST equtype, no, INT VAR spos, stype,
+ TEXT VAR gen buf, symbol, buf) :
+ next sym (buf, symbol, stype, spos);
+ REP
+ factor (equtype, no, spos, gen buf, buf, symbol, stype)
+ UNTIL is no operator END REP.
+
+ is no operator :
+ IF symbol IN "+-*/"
+ THEN gen buf CAT symbol;
+ next sym (buf, symbol, stype, spos);
+ process obelix;
+ FALSE
+ ELSE TRUE
+ FI.
+
+ process obelix :
+ IF symbol = "*"
+ THEN gen buf CAT symbol;
+ next sym (buf, symbol, stype, spos)
+ FI.
+END PROC expression2;
+
+TEXT PROC actual parameter (TEXT CONST params) :
+ INT VAR position := nil, old position;
+ FOR i FROM 1 UPTO expansion no REP
+ old position := position;
+ position := pos (params, "%", position + 1)
+ END REP;
+ subtext (params, old position + 1, position - 1).
+END PROC actual parameter;
+
+PROC factor (INT CONST equtype, no, INT VAR spos, TEXT VAR genbuf,
+ buf, symbol, INT VAR stype) :
+ BOOL VAR dollar := symbol = "$";
+ INT VAR tab pos, mac num := CONCR (tab).mac (no);
+ IF dollar
+ THEN next sym (buf, symbol, stype, spos)
+ FI;
+ SELECT stype OF
+ CASE number : process number
+ CASE bold : process quantity
+ CASE delimiter : process delimiter
+ OTHERWISE : err (symbol, 44)
+ END SELECT.
+
+ process number :
+ gen buf CAT symbol;
+ next sym (buf, symbol, stype, spos).
+
+ process quantity :
+ TEXT VAR name := symbol, time script;
+ INT VAR old spos := spos;
+ next sym (buf, symbol, stype, spos);
+ IF mac num > nil
+ THEN search (name, tab pos, mac num, mac param);
+ IF not found
+ THEN search (name, tab pos, mac num, nil);
+ IF not found
+ THEN search (name, tab pos, nil, nil)
+ FI
+ FI
+ ELSE search (name, tab pos, nil, nil)
+ FI;
+ IF is global param
+ THEN search (name, tab pos, macro number of param, nil)
+ FI;
+ IF not found
+ THEN err (name, 46)
+ ELSE test type
+ FI.
+
+ is global param :
+ not found AND CONCR (tab).index (no) > nil
+ AND CONCR (tab).index type (no) = nil.
+
+ macro number of param :
+ CONCR (tab).mac (CONCR (tab).index (no)).
+
+ test type :
+ INT VAR nop;
+ BOOL VAR is equ := FALSE;
+ search table entry;
+ get time script;
+ type := CONCR (tab).type (tab pos);
+ SELECT type OF
+ CASE std p : std function
+ CASE table : (* nanu *)
+ CASE mac param : replace param
+ CASE mac name : macro expansion
+ CASE const : constant
+ OTHERWISE test quantity
+ END SELECT;
+ IF symbol = "("
+ THEN test index
+ ELIF is equ
+ THEN gen buf CAT name
+ FI.
+
+ search table entry :
+ IF CONCR (tab).index type (tab pos) > nil AND
+ CONCR (tab).type (tab pos) = n equ
+ THEN search correct table;
+ IF not found
+ THEN err (name, 46);
+ LEAVE process quantity
+ FI
+ FI.
+
+ search correct table :
+ not found := TRUE;
+ WHILE tab pos <> nil CAND table not found REP
+ tab pos := CONCR (tab).pred (tab pos)
+ END REP.
+
+ table not found :
+ not found := NOT (CONCR (tab).name (tab pos) = name
+ AND not in macro AND type ok);
+ not found.
+
+ not in macro :
+ CONCR (tab).mac (tab pos) = nil.
+
+ type ok :
+ type := CONCR (tab).type (tab pos);
+ type = aux OR type = rate OR type = level.
+
+ test quantity :
+ IF CONCR (tab).mac (tab pos) > nil
+ THEN name := "zz" + CONCR (tab).name (CONCR (tab).mac (tab pos))
+ + text (expansion no) + name
+ FI;
+ is equ := TRUE;
+ SELECT equtype OF
+ CASE nequ : initialization
+ CASE aux : auxiliary
+ CASE level : level equation
+ CASE sub init: substitute init
+ CASE supp : supplementary
+ OTHERWISE : rate equation
+ END SELECT.
+
+ get time script :
+ time script := nt;
+ IF symbol = "."
+ THEN next sym (buf, time script, stype, spos);
+ next sym (buf, symbol, stype, spos)
+ FI;
+ BOOL VAR is any := time script = any.
+
+ replace param :
+ buf := text (buf, old spos - 2) +
+ actual param + subtext (buf, spos - 1);
+ spos := old spos - 1;
+ next sym (buf, symbol, stype, spos);
+ factor (equtype, no, spos, genbuf, buf, symbol, stype);
+ LEAVE factor.
+
+ actual param :
+ TEXT VAR param := actual parameter (content);
+ IF param contains time script OR is number
+ THEN param
+ ELSE param + "." + any
+ FI.
+
+ param contains time script :
+ (param SUB (length (param))) = any.
+
+ is number :
+ pos ("0123456789", param SUB (length (param))) > 0.
+
+ content :
+ IF type = nequ AND CONCR (tab).index (no) = nil
+ THEN CONCR (tab).init (tab pos)
+ ELSE CONCR (tab).right part (tab pos)
+ FI.
+
+ test index :
+ gen buf CAT "(";
+ gen buf CAT name;
+ next sym (buf, symbol, stype, spos);
+ gen buf CAT " SUB ";
+ SELECT stype OF
+ CASE number : int index
+ CASE bold : var index
+ OTHERWISE : err (symbol, 48)
+ END SELECT;
+ test offset;
+ test closing bracket (symbol);
+ gen buf CAT symbol;
+ next sym (buf, symbol, stype, spos).
+
+ test offset :
+ next sym (buf, symbol, stype, spos);
+ IF symbol IN "+-"
+ THEN pass offset
+ FI.
+
+ pass offset :
+ gen buf CAT symbol;
+ next sym (buf, symbol, stype, spos);
+ gen buf CAT trunc (symbol);
+ IF stype <> number
+ THEN err (symbol, 48)
+ FI;
+ next sym (buf, symbol, stype, spos).
+
+ int index :
+(*IF CONCR (tab).index (no) <> int (symbol)
+ THEN err (symbol, 48);
+ message("Starten Sie trotzdem das übersetzte ELAN Programm") FI;*)
+(*20.5.88 dc: hier kommt eine falsche Fehlermeldung *)
+ gen buf CAT trunc (symbol).
+
+ var index :
+ search (symbol, tab pos, mac num, for);
+ gen buf CAT symbol;
+ IF incorrect index
+ THEN err (symbol, 48)
+ FI.
+
+ incorrect index :
+ not found COR CONCR (tab).name (CONCR (tab).index (no)) <> symbol.
+
+ std function :
+ test open bracket (symbol);
+ nop := length (CONCR (tab).right part (tab pos));
+ gen buf CAT (name + " (");
+ IF nop > nil
+ THEN pass actual params
+ ELSE next sym (buf, symbol, stype, spos);
+ test closing bracket (symbol)
+ FI;
+ next sym (buf, symbol, stype, spos);
+ IF act param <> nop
+ THEN err (symbol, 49)
+ FI.
+
+ pass actual params :
+ INT VAR table pos := tab pos, act param := nil;
+ REP
+ act param INCR 1;
+ IF (CONCR (tab).right part (table pos) SUB act param) = "t"
+ THEN test if param is table
+ ELSE expression2 (equtype, no, spos, stype, gen buf, symbol, buf)
+ FI
+ UNTIL no more params END REP.
+
+ no more params :
+ gen buf CAT symbol;
+ SELECT pos (",)", symbol) OF
+ CASE 1 : FALSE
+ CASE 2 : TRUE
+ OTHERWISE : err (symbol, 50); TRUE
+ END SELECT.
+
+ test if param is table :
+ next sym (buf, symbol, stype, spos);
+ IF s type = bold
+ THEN search (symbol, tab pos, mac num, nil);
+ IF not found
+ THEN err (symbol, 51)
+ ELSE gen table
+ FI
+ ELSE err (symbol, 52)
+ FI.
+
+ gen table :
+ IF CONCR (tab).type (tab pos) = table
+ THEN gen buf CAT symbol;
+ next sym (buf, symbol, stype, spos)
+ ELIF CONCR (tab).index type (tab pos) > nil
+ THEN factor (equtype, no, spos, genbuf, buf, symbol, stype)
+ ELSE err (symbol, 52)
+ FI.
+
+ macro expansion :
+ CONCR (tab).line no (tab pos) INCR 1;
+ gen buf CAT "zz";
+ gen buf CAT name;
+ gen buf CAT text (CONCR (tab).line no (tab pos));
+ gen buf CAT name;
+ get actual parameters.
+
+ get actual parameters :
+ TEXT VAR char;
+ test open bracket (symbol);
+ get macro parameter list;
+ next sym (buf, symbol, stype, spos).
+
+ get macro parameter list :
+ REP
+ get act param
+ UNTIL end of parameter list END REP.
+
+ end of parameter list :
+ SELECT pos (",)", char) OF
+ CASE 1 : FALSE
+ CASE 2 : TRUE
+ OTHERWISE : TRUE
+ END SELECT.
+
+ get act param :
+ INT VAR brackets := nil;
+ char := buf SUB spos;
+ REP
+ spos INCR 1;
+ char := buf SUB spos
+ UNTIL end of param END REP;
+ spos INCR 1.
+
+ end of param :
+ IF brackets = nil
+ THEN char IN ",)"
+ ELIF char = "("
+ THEN brackets INCR 1;
+ FALSE
+ ELIF char = ")"
+ THEN brackets DECR 1;
+ FALSE
+ ELSE FALSE
+ FI.
+
+ constant :
+ is equ := TRUE;
+ CONCR (tab).idef (tab pos) := TRUE.
+
+ initialization :
+ IF time script = nt OR is any
+ THEN IF NOT CONCR (tab).idef (tab pos)
+ THEN IF CONCR (tab).init (tab pos) <> nt
+ THEN sort equ (tab pos, equ type)
+ ELIF is sub init
+ THEN sort equ (tab pos, sub init)
+ ELSE err (symbol, 39)
+ FI
+ FI
+ ELSE err (time script, 56)
+ FI.
+
+ is sub init :
+ CONCR (tab).init (tab pos) = nt AND correct type (type).
+
+ auxiliary :
+ IF time script = aux time script OR is any
+ THEN IF NOT CONCR (tab).rdef (tab pos) AND type = aux
+ THEN sort equ (tab pos, equtype)
+ FI
+ ELSE err (time script, 57)
+ FI.
+
+ aux time script :
+ SELECT type OF
+ CASE aux, level : "k"
+ CASE rate : "jk"
+ OTHERWISE : " "
+ END SELECT.
+
+ level equation :
+ IF time script <> level time script AND NOT is any
+ THEN err (time script, 59)
+ FI.
+
+ level time script :
+ SELECT type OF
+ CASE aux, level : "j"
+ CASE rate : "jk"
+ OTHERWISE : " "
+ END SELECT.
+
+ rate equation :
+ IF time script <> rate time script AND NOT is any
+ THEN err (time script, 60)
+ FI.
+
+ rate time script :
+ SELECT type OF
+ CASE aux, level : "k"
+ CASE rate : "jk"
+ OTHERWISE : " "
+ END SELECT.
+
+ supplementary :
+ IF time script <> supp time script AND NOT is any
+ THEN err (time script, 57)
+ FI.
+
+ supp time script :
+ SELECT type OF
+ CASE aux, level, supp : "k"
+ CASE rate : "jk"
+ OTHERWISE : " "
+ END SELECT.
+
+ substitute init :
+ IF NOT CONCR (tab).idef (tab pos)
+ THEN gen sub init equ
+ FI.
+
+ gen sub init equ :
+ IF CONCR (tab).index type (tab pos) > nil
+ THEN IF CONCR (tab).index type (no) = nil
+ THEN process index equ
+ FI
+ ELIF CONCR (tab).init (tab pos) = nt
+ THEN IF correct type (type)
+ THEN sort equ (tab pos, equtype)
+ FI
+ ELSE sort equ (tab pos, nequ)
+ FI.
+
+ process index equ :
+ INT VAR table type := sub init;
+ IF type <> nequ
+ THEN search nequ
+ FI;
+ IF NOT CONCR (tab).idef (tab pos) AND correct type (type)
+ THEN end of init list;
+ gen loop (tab pos, table type);
+ CONCR (tab).idef (tab pos) := TRUE
+ FI.
+
+ search nequ :
+ search (CONCR (tab).name (tabpos), table pos, nil, nequ);
+ IF NOT (not found CAND CONCR (tab).idef (tab pos))
+ THEN type := nequ;
+ tab pos := table pos;
+ table type := type
+ FI.
+
+ process delimiter :
+ genbuf CAT symbol;
+ SELECT pos ("(+-", symbol) OF
+ CASE 1 : process bracket
+ CASE 2, 3: process monadic operator
+ OTHERWISE err (symbol, 44)
+ END SELECT.
+
+ process bracket :
+ expression2 (equtype, no, spos, stype, genbuf, symbol, buf);
+ test closing bracket (symbol);
+ gen buf CAT symbol;
+ next sym (buf, symbol, stype, spos);
+ IF symbol = "("
+ THEN gen buf CAT "*";
+ factor (equtype, no, spos, gen buf, buf, symbol, stype)
+ FI.
+
+ process monadic operator :
+ next sym (buf, symbol, stype, spos);
+ factor (equtype, no, spos, gen buf, buf, symbol, stype).
+END PROC factor;
+
+BOOL PROC correct type (INT CONST equ type) :
+ SELECT equ type OF
+ CASE aux, rate, nequ : TRUE
+ OTHERWISE : FALSE
+ END SELECT.
+END PROC correct type;
+
+TEXT PROC draw ad:
+ IF is draw THEN "b" ELSE "" END IF
+END PROC draw ad;
+
+(*$$$$$$$$$$$$$$$ ZUSATZ Februar 87 C&C geaendert: Ausgabe "dump" $$$$$$$$*)
+
+(* In dieser Prozedur wird eine Datei 'dump' angelegt, in der alle *)
+(* Dynamo-Standardfunktionen, Macros und die programmspezifischen *)
+(* Variablen und Konstanten eingetragen werden. *)
+
+PROC table dump :
+IF exists ("dump")
+THEN forget("dump",quiet)
+FI;
+FILE VAR dump := sequential file(output, "dump");
+sysout("dump");
+ FOR i FROM 1 UPTO CONCR (tab).tab size REP
+ put (i);
+ put ("NAM :"); put (CONCR (tab).name (i));
+ put ("RP :"); put (CONCR (tab).right part (i));
+ put ("INI :"); put (CONCR (tab).init (i));
+ put ("IND :"); put (CONCR (tab).index (i));
+ put ("IT :"); put (CONCR (tab).index type (i));
+ put ("TYP :"); put (CONCR (tab).type (i));
+ line;
+ END REP;
+sysout("")
+END PROC table dump
+(*$$$$$$$$$$$$$$$$$$$$ ENDE ZUSATZ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*)
+END PACKET dynamo compiler 33
+
diff --git a/dynamo/dyn.abnahme b/dynamo/dyn.abnahme
new file mode 100644
index 0000000..e8c100d
--- /dev/null
+++ b/dynamo/dyn.abnahme
@@ -0,0 +1,19 @@
+NOTE
+NOTE Ein einfaches Modell der Bevoelkerungsentwicklung
+NOTE
+L BEVOELKERUNG.K=BEVOELKERUNG.J+DT*(GEBURTENRATE.JK-STERBERATE.JK)
+N BEVOELKERUNG=1000
+R GEBURTENRATE.KL=BEVOELKERUNG.K*WACHSTUMSFAKTOR
+N GEBURTENRATE=10
+C WACHSTUMSFAKTOR=0.01 das heisst: 1 Prozent
+R STERBERATE.KL=BEVOELKERUNG.K*STERBEFAKTOR
+C STERBEFAKTOR=0.001 das heisst: 1 Promille
+N STERBERATE=10
+NOTE
+NOTE Simulationsparameter
+NOTE
+PLOT BEVOELKERUNG=B(0,2000)/GEBURTENRATE=G(0,40)/STERBERATE=S(0,6)
+C DT=1
+C PLTPER=1
+C LENGTH=68
+
diff --git a/dynamo/dyn.bev b/dynamo/dyn.bev
new file mode 100644
index 0000000..5b759d3
--- /dev/null
+++ b/dynamo/dyn.bev
@@ -0,0 +1,50 @@
+NOTE EIN BEVÖLKERUNGSMODELL DER BUNDESREPUBLIK DEUTSCHLAND
+NOTE
+NOTE ANGABEN DER GEBURTENRATEN (GR) UND STERBEQUOTIENTEN (SQ)
+NOTE AUS DEM STATISTISCHEN JAHRBUCH 1982
+NOTE
+FOR LJ=1,80 LEBENSJAHRE
+FOR LJ2=2,80
+L BEV.K(1)=BEV.J(1)+DT*(GB.J-A.J(1)-S.J(1)) BABIES
+L BEV.K(LJ2)=BEV.J(LJ2)+DT*(A.J(LJ2-1)-A.J(LJ2)-S.J(LJ2)) BEVÖLKERUNG
+A A.K(LJ)=(1-SQ(LJ))*BEV.K(LJ)
+A S.K(LJ)=SQ(LJ)*BEV.K(LJ)
+A GB.K=SCLPRD(BEV.K,15,44,GR,1)/2 Geburten
+A GBEV.K=SUM(BEV.K) Gesamtbevölkerung
+A ZBEV.K=SUMV(BEV.K,16,59) zahlende Bevölkerung (in Rentenversicherung)
+A PRENT.K=SUMV(BEV.K,60,80) potentielle Rentner
+NOTE
+N BEV(LJ)=IBEV(LJ)*1E3
+T IBEV=
+X 584/585/590/609/652/728/780/843/927/980/
+X 1014/1032/1045/1049/1024/1003/986/959/929/903/
+X 884/857/850/845/841/844/854/872/854/810/
+X 756/676/722/826/829/905/1029/1062/1026/968/
+X 934/919/884/783/711/725/763/784/784/768/
+X 742/744/724/700/716/751/765/673/488/385/
+X 397/479/613/690/698/681/664/666/654/630/
+X 603/573/546/510/476/445/402/359/320/1681
+NOTE
+T SQ=
+X .01965/.00123/.00082/.00082/.00082/.00055/.00055/.00055/.00055/.00055/
+X .00033/.00033/.00033/.00033/.00033/.00064/.00064/.00064/.00064/.00064/
+X .00183/.00183/.00183/.00183/.00183/.00131/.00131/.00131/.00131/.00131/
+X .00152/.00152/.00152/.00152/.00152/.00193/.00193/.00193/.00193/.00193/
+X .00302/.00302/.00302/.00302/.00302/.00497/.00497/.00497/.00497/.00497/
+X .00750/.00750/.00750/.00750/.00750/.01220/.01220/.01220/.01220/.01220/
+X .01868/.01868/.01868/.01868/.01868/.03146/.03146/.03146/.03146/.03146/
+X .05206/.05206/.05206/.05206/.05206/.08241/.08241/.08241/.08241/.175
+NOTE
+T GR=
+X .0008/.0041/.0138/.0274/.0453/.0597/.0745/.0861/.0933/.1025/
+X .1067/.1074/.1050/.0963/.0872/.0753/.0642/.0531/.0430/.0360/
+X .0297/.0225/.0184/.0144/.0114/.0087/.0063/.0044/.0031/.0020
+NOTE
+C DT=1
+C PLTPER=1
+C PRTPER=1
+N TIME=1982
+C LENGTH=2000
+NOTE PRINT GB,A(1),S(1),BEV(1),BEV(2),GR(1),GR(15),GR(30)
+PRINT GBEV,BEV(1),BEV(40),BEV(60),BEV(63),BEV(65),ZBEV,PRENT
+
diff --git a/dynamo/dyn.cob b/dynamo/dyn.cob
new file mode 100644
index 0000000..eabb1b8
--- /dev/null
+++ b/dynamo/dyn.cob
@@ -0,0 +1,19 @@
+NOTE COBWEB MODEL 27.11.81
+L PREIS.K=PREIS.J+(DT)*K*(NACHFR.J-ANGEBOT.J)
+L ANGEBOT.K=A+B*PREIS.J
+A NACHFR.K=C-D*PREIS.K
+NOTE B>0, D>0, K>0
+N PREIS=0
+N ANGEBOT=11
+C K=1
+C A=1.
+C B=.9
+C C=12.4
+C D=1.2
+C DT=.1
+C LENGTH=10
+C PRTPER=.1
+C PLTPER=.1
+PLOT PREIS=P/NACHFR=N(1,10)/ANGEBOT=A
+PRINT PREIS,ANGEBOT,NACHFR
+
diff --git a/dynamo/dyn.delaytest b/dynamo/dyn.delaytest
new file mode 100644
index 0000000..c475433
--- /dev/null
+++ b/dynamo/dyn.delaytest
@@ -0,0 +1,8 @@
+NOTE GOODMAN S.248
+A Y.K=DELAY3(X,D)
+C D=50
+R X.KL=TABLE(XT,TIME.K,0,125,25)
+T XT=0/10/0/-10/0/10
+PLOT X=X,Y=Y(-10,10)
+SPEC DT=0.5,LENGTH=125,PLTPER=2
+
diff --git a/dynamo/dyn.errors b/dynamo/dyn.errors
new file mode 100644
index 0000000..64a4f27
--- /dev/null
+++ b/dynamo/dyn.errors
@@ -0,0 +1,68 @@
+gleichung doppelt definiert
+doppelte initialisierung
+falscher zeilentyp
+verschachtelte makro-definition
+makro-name erwartet
+'(' erwartet
+formaler parameter erwartet
+')' nach parameterliste erwartet
+bei auxiliaries nur subskription mit '.k' erlaubt
+bei konstanten-definition name erwartet
+bei levels nur subskription mit '.k' erlaubt
+bei rates nur subskription mit '.kl' erlaubt
+bei table-definition keine subskription erlaubt
+x - befehl hier nicht erlaubt
+bei for-definition name erwartet
+'=' nach for-variable erwartet
+bereichsangabe erwartet
+',' erwartet
+lokale gleichung nur in makro erlaubt
+bei definition name erwartet
+'=' erwartet
+index nicht korrekt
+')' nach indizierung erwartet
+prtper nicht definiert
+pltper nicht definiert
+'/' oder ',' bei plot erwartet
+name als plotparameter erwartet
+doppelte scale-angabe in einer gruppe
+erste scale-angabe erwartet
+zweite scale-angabe erwartet
+')' nach scale-angabe erwartet
+printparameter nicht definiert
+printparameter erwartet
+time darf nur initialisiert werden
+dt nicht definiert
+length nicht definiert
+bei konstanten-definition zahl erwartet
+bei initialisierung konstante erwartet
+levels muessen initialisiert werden
+konstante bei table erwartet
+'/' oder ',' erwartet
+table-definition ohne benutzung
+simultane gleichungen
+faktor erwartet
+time muss mit '.j' oder '.k' subskribiert werden
+symbol nicht definiert
+funktion nicht definiert
+unzulaessige indizierung
+falsche parameteranzahl
+falsches trennsymbol zwischen parametern
+als parameter table erwartet
+falscher parameter in tablefunktion
+zuviele aktuelle parameter
+')' nach makroaufruf fehlt
+rekursiver makroaufruf
+bei n-gleichung keine subskription erwartet
+falsche subskription in auxiliary-gleichung
+')' erwartet
+falsche subskription in level-gleichung
+falsche subskription in rate-gleichung
+for-variable nicht definiert
+konstante erwartet
+falsches real-format
+zu viele plot-parameter
+bei run-befehl dateiname erwartet
+als noise-parameter zahl erwartet
+plot- und draw-Anweiungen dürfen im Programm nicht gemischt werden
+
diff --git a/dynamo/dyn.forest b/dynamo/dyn.forest
new file mode 100644
index 0000000..5075925
--- /dev/null
+++ b/dynamo/dyn.forest
@@ -0,0 +1,47 @@
+NOTE 23.04.1985 english version 22.11.1985
+note forest management model
+note
+note wood standing within the forest
+l wood.k=wood.j+dt*(woodgrowth.jk-harvest.jk)
+n wood=startingwood
+c startingwood=15000 m**3
+r woodgrowth.kl=wood.k*stocksfactor*cultivationfactor.k
+c stocksfactor=0.04 growth in % of wood
+a cultivationfactor.k=tabhl(tclfactor,clstate.k,0,1,0.1)
+t tclfactor=0/.1/.2/.3/.4/.5/.7/.95/1/1.05/1.2
+r harvest.kl=wood.k*harvestpercent.k*0.1
+a harvestpercent.k=tabhl(tharvestpercent,ratio1.k,0.8,1.2,0.1)
+t tharvestpercent=0.1/0.3/0.35/0.4/0.6
+a ratio1.k=wood.k/maxstock
+c maxstock=16000
+note
+note resources
+l resources.k=resources.j+dt*(income.jk-clexpense.jk-draw.jk)
+n resources=startresources
+c startresources=100000 money units
+r income.kl=wood.k*harvestpercent.k*0.1*price
+c price=190 money units per cubic m
+r clexpense.kl=resources.k-constdraw
+r draw.kl=constdraw
+c constdraw=20000
+note
+note cultivationstate (clstate; dimensionless )
+l clstate.k=clstate.j+dt*(clbetter.jk-clworse.jk)
+n clstate=startclstate
+c startclstate=0.8
+r clbetter.kl=clbetterfactor.k*(1-clstate.k)
+a clbetterfactor.k=tabhl(tclbetter,cultivationcost.k,80000,180000,100000)
+t tclbetter=0.0/0.1
+a cultivationcost.k=resources.k-constdraw
+r clworse.kl=clworsefactor.k*clstate.k
+a clworsefactor.k=tabhl(tclworse,cultivationcost.k,0,80000,80000)
+t tclworse=0.2/0
+note
+note
+print wood,resources,clstate
+plot wood=w/resources=r/clstate=c(0,1)
+c dt=1
+c length=50
+c prtper=1
+c pltper=1
+
diff --git a/dynamo/dyn.forst7 b/dynamo/dyn.forst7
new file mode 100644
index 0000000..d767a50
--- /dev/null
+++ b/dynamo/dyn.forst7
@@ -0,0 +1,76 @@
+#papersize(20.5,61.0)#
+#pagelength(59.0)#
+#type("picac")#
+NOTE 25.04.1985 14.30
+note forstbetriebsmodell
+note
+note stehender Holzvorrat
+l holz.k=holz.j+dt*(zuwachs.jk-ernte.jk)
+n holz=startholz
+c startholz=15000 Angabe in Festmetern(fm)
+r zuwachs.kl=holz.k*vorratsfaktor*pflegefaktor.k
+c vorratsfaktor=0.035 Zuwachs in % von holz
+a pflegefaktor.k=tabhl(tpffaktor,pfzustand.k,0,1,0.1)
+t tpffaktor=.7/.7/.7/.7/.7/.8/.9/.95/1/1.05/1.2
+r ernte.kl=ernte1.k
+a ernte1.k=holz.k*ernteproz.k*ernteprozfak.k
+a ernteproz.k=tabhl(ternproz,ratio1.k,0.5,1.2,0.1)
+t ternproz=0.02/0.025/0.03/0.03/0.03/0.035/0.06/0.08
+a ratio1.k=holz.k/maxvorrat
+c maxvorrat=16000
+note
+note resourcen
+l resourcen.k=resourcen.j+dt*(einnahme.jk-eig.jk-pfausgaben.jk)
+n resourcen=startresourcen
+c startresourcen=100000 Geldeinheiten
+c preis=190 Geldeinheiten pro fm
+r einnahme.kl=ernte1.k*preis
+r pfausgaben.kl=resourcen.k-eigenent.k
+r eig.kl=eigenent.k
+a anpassungsfaktor.k=tabhl(tanpass,ratio2.k,0.5,1.5,0.1)
+t tanpass=.5/.55/.6/.7/.9/1/1/1/1.1/1.2/1.3
+l eigenent.k=min(eigenent.j*anpass.jk,resourcen.j)
+r anpass.kl=anpassungsfaktor.k
+n eigenent=eigenentstart
+c eigenentstart=20000
+note
+note arbeitseinheiten
+note
+l arbeit.k=arbeit.j+dt*(pfausgaben.jk/preisae-arbeitsverbrauch.jk)
+n arbeit=startarbeit
+c startarbeit=800
+c preisae=100 ( preis pro arbeitseinheit in geldeinheiten )
+r arbeitsverbrauch.kl=min(arbeit.k,notwarbeit.k)
+a notwarbeit.k=tabhl(tnotwarb,pfzustand.k,0.0,1.0,0.1)
+t tnotwarb=1600/1550/1500/1450/1400/1300/1150/950/800/700/600
+a ratio2.k=arbeit.k/notwarbeit.k
+a ernteprozfak.k=tabhl(ternteprozfak,ratio2.k,0.2,1.6,0.2)
+t ternteprozfak=.4/.5/1/2/1.05/1/.9/.7
+note
+note Pflegezustand (pfzustand; dimensionslose Größe)
+l pfzustand.k=pfzustand.j+dt*(pfverbess.jk-pfversch.jk)
+n pfzustand=startpfzustand
+c startpfzustand=0.8
+r pfverbess.kl=smooth(pfx1.k,pfverzoeg)
+a pfx1.k=pfverbfaktor.k*(1-pfzustand.k)
+a pfverbfaktor.k=tabhl(tpfverb,ratio2.k,.8,1.4,.2)
+t tpfverb=0/0/.1/0.2
+r pfversch.kl=smooth(pfverschfaktor.k*pfzustand.k,pfverzoeg)
+c pfverzoeg=2
+a pfverschfaktor.k=tabhl(tpfversch,ratio2.k,0,.8,.2)
+t tpfversch=.4/.2/.1/.05/0
+note
+note
+note print ratio1,ratio2,eigenent,arbeit,pfzustand
+plot holz=h(1e4,2e4)/eigenent=e(0,2e5)/pfzustand=P(0,1)/ratio2=2(0,5)
+c dt=1
+c length=50
+note prtper=1
+c pltper=1
+run dyn.forst7
+
+
+
+
+
+
diff --git a/dynamo/dyn.gekoppeltependel b/dynamo/dyn.gekoppeltependel
new file mode 100644
index 0000000..3f2a961
--- /dev/null
+++ b/dynamo/dyn.gekoppeltependel
@@ -0,0 +1,19 @@
+NOTE gekoppelte pendel
+L x1.k=x1.j+dt*v1.j
+L x2.k=x2.j+dt*v2.j
+L v1.k=v1.j+dt*(-d0/m1*x1.j-(d/m1)*(x1.j-x2.j))
+L v2.k=v2.j+dt*(-d0/m2*x2.j-(d/m2)*(x2.j-x1.j))
+N x1=a
+N x2=0
+N v1=0
+N v2=0
+C a=3
+C m1=2
+C m2=2
+C d0=9
+C d=2
+C dt=0.1
+C length=50
+C pltper=0.3
+PLOT x1=1(-3,9)/x2=2(-9,3)
+
diff --git a/dynamo/dyn.grashasenfuchs b/dynamo/dyn.grashasenfuchs
new file mode 100644
index 0000000..046a1e1
--- /dev/null
+++ b/dynamo/dyn.grashasenfuchs
@@ -0,0 +1,42 @@
+NOTE
+NOTE Raeuber-Beute-Beziehung nach VOLTERRA am Beispiel Fuchs-Hase
+NOTE Aenderung: mit FUTTER und CLIP-Funktion
+L GRAS.K=CLIP(GRAS.J+DT*(WACHSR.JK-FRESSR.JK),0,GRAS.J,0)
+L HASEN.K=CLIP(HASEN.J+DT*(HGRATE.JK-HSRATE.JK),0,HASEN.J,0)
+L FUECHS.K=CLIP(FUECHS.J+DT*(FGRATE.JK-FSRATE.JK),0,FUECHS.J,0)
+R WACHSR.KL=(GPROZ/100)*GRAS.K GPROZ Wachstumsprozente
+R FRESSR.KL=GFRESS*HASEN.K*GRAS.K GFRESS in: pro Hasen
+R HGRATE.KL=HGK*HASEN.K*GRAS.K
+R HSRATE.KL=TREFF*HASEN.K*FUECHS.K+HSTIRB*HASEN.K
+R FGRATE.KL=FGK*HASEN.K*FUECHS.K
+R FSRATE.KL=FSK*FUECHS.K
+NOTE
+NOTE Gleichgewichtsbedingungen:
+NOTE HASEN=GPROZ/(100*Gfress)
+NOTE
+NOTE Hasengeburtenkoeffizient*GRAS=Trefferwahrscheinlichkeit*Fuechse
+NOTE +Hstirb
+NOTE Fuechsesterbekoeffizient=Fuechsegeburtenkoeffizient*Hasen
+NOTE
+N GRAS=IG
+N HASEN=IH
+N FUECHS=IF
+C GPROZ=3 Graswachstum 3%
+C GFRESS=3E-4 (Grasfressanteil) pro Hasen
+C HGK=1E-3 Hasengeburtskoeff
+C TREFF=4E-2 Trefferwahrscheinlichkeit
+C HSTIRB=0.001 Hasensterbekoeffizient (ohne Fuechse)
+C FGK=0.05 Fuechsegeburtenkoeffizient
+C FSK=5 Fuechsesterbekoeffizient
+C IG=1E+3
+C IH=110
+C IF=25
+NOTE
+NOTE SIMULATIONSPARAMETER
+NOTE
+C DT=0.083
+C PLTPER=.083 monatlich, 0.083=1/12 !
+C LENGTH=5
+PLOT GRAS=G(995,1005)/HASEN=H(85,115)/FUECHS=F(15,35)
+
+
diff --git a/dynamo/dyn.help b/dynamo/dyn.help
new file mode 100644
index 0000000..e4f82c0
--- /dev/null
+++ b/dynamo/dyn.help
@@ -0,0 +1,24 @@
+ Im Dynamo Runtime-System stehen folgende Kommandos
+ zur Verfügung (Verlassen dieser Erklärung mit <ESC> q) :
+
+ run ...................... Ausführen des übersetzten Programms
+
+ c <Konstantenname>=Wert .. Änderung einer oder mehrerer Konstanten
+
+ ? ........................ Anzeige der Konstanten und ihrer Werte
+
+ quit ..................... Verlassen des Runtime-Systems
+
+ help ..................... Zeigt diese Erklärungen
+
+
+ Bei PRINT oder PLOT - Ausgaben sind folgende Kommandos möglich :
+
+ + ....................... Nächster Bildschirm
+
+ o ....................... (Off), keine Unterbrechung der Ausgabe
+
+ e ....................... (End), Zurück zum Runtime-System
+
+ <ESC> .................... Abbruch der Ausgabe
+
diff --git a/dynamo/dyn.inserter b/dynamo/dyn.inserter
new file mode 100644
index 0000000..4b0b9d5
--- /dev/null
+++ b/dynamo/dyn.inserter
@@ -0,0 +1,54 @@
+put line ("DYNAMO 3.3+ wird generiert");
+line;
+WHILE noch nicht alle dateien da REPEAT (* Christian Szymanski *)
+ hole dateien vom archiv (* 10.08.88 *)
+END REPEAT;
+putline ("Die Pakete werden insertiert.");
+putline ("Bitte warten !");
+checkoff;
+IF id(0) < 182
+ THEN insert ("dyn.kleiner182")
+FI ;
+insert ("dyn.tool");
+insert ("dyn.33");
+insert ("dyn.vec");
+insert ("dyn.proc");
+insert ("dyn.rts");
+insert ("dyn.plot+");
+insert ("dyn.plot");
+insert ("dyn.print");
+command dialogue (TRUE);
+do ("init errors (""dyn.errors"")");
+do ("init std (""dyn.std"")");
+do ("insert macro (""dyn.mac"")");
+do ("graphic (yes (""mit CGA-Grafik""))");
+putline ("dynamo-system generiert");
+check on.
+
+noch nicht alle dateien da:
+ THESAURUS VAR alle dateien := empty thesaurus;
+ IF id(0) < 182 THEN
+ insert (alle dateien,"dyn.kleiner182")
+ FI ;
+ insert (alle dateien, "dyn.tool");
+ insert (alle dateien, "dyn.33");
+ insert (alle dateien, "dyn.vec");
+ insert (alle dateien, "dyn.proc");
+ insert (alle dateien, "dyn.rts");
+ insert (alle dateien, "dyn.plot+");
+ insert (alle dateien, "dyn.plot");
+ insert (alle dateien, "dyn.print");
+ highest entry (alle dateien - all) > 0 .
+
+hole dateien vom archiv:
+ IF yes ("DYNAMO-Diskette eingelegt") THEN
+ archive ("dynamo");
+ fetch (ALL archive - all, archive);
+ release (archive)
+ FI.
+
+
+
+
+
+
diff --git a/dynamo/dyn.mac b/dynamo/dyn.mac
new file mode 100644
index 0000000..03a0f9f
--- /dev/null
+++ b/dynamo/dyn.mac
@@ -0,0 +1,44 @@
+macro delay1(in,del)
+a delay1.k=$lv.k/del
+l $lv.k=$lv.j+dt*(in.jk-delay1.j)
+n $lv=del*in
+mend
+macro delay3(in,del)
+a $dl.k=del/3
+l $lv3.k=$lv3.j+dt*($rt2.jk-delay3.j)
+n $lv3=$dl*in
+r $rt2.kl=$lv2.k/$dl.k
+l $lv2.k=$lv2.j+dt*($rt1.jk-$rt2.jk)
+n $lv2=$lv3
+r $rt1.kl=$lv1.k/$dl.k
+l $lv1.k=$lv1.j+dt*(in.jk-$rt1.jk)
+n $lv1=$lv3
+a delay3.k=$lv3.k/$dl.k
+mend
+macro delay3p(in,del,ppl)
+a delay3p.k=$lv3.k/$dl.k
+l $lv3.k=$lv3.j+dt*($rt2.jk-delay3p.j)
+n $lv3=$dl*in
+r $rt2.kl=$lv2.k/$dl.k
+l $lv2.k=$lv2.j+dt*($rt1.jk-$rt2.jk)
+n $lv2=$lv3
+r $rt1.kl=$lv1.k/dl.k
+l $lv1.k=$lv1.j+dt*(in.jk-$rt1.jk)
+n $lv1=$lv3
+a $dl.k=del/3
+a ppl.k=$lv3.k+$lv2.k+$lv1.k
+mend
+macro dlinf3(in,del)
+l dlinf3.k=dlinf3.j+dt*($lv2.j-dlinf3.j)/$dl.j
+n dlinf3=in
+l $lv2.k=$lv2.j+dt*($lv1.j-$lv2.j)/$dl.j
+n $lv2=in
+l $lv1.k=$lv1.j+dt*(in.j-$lv1.j)/$dl.j
+n $lv1=in
+a $dl.k=del/3
+mend
+macro smooth(in,del)
+l smooth.k=smooth.j+dt*(in.j-smooth.j)/del
+n smooth=in
+mend
+
diff --git a/dynamo/dyn.mehreredelays b/dynamo/dyn.mehreredelays
new file mode 100644
index 0000000..6eac8fe
--- /dev/null
+++ b/dynamo/dyn.mehreredelays
@@ -0,0 +1,9 @@
+NOTE GOODMAN S.248
+A Y.K=DELAY3(X,D)
+A Z.K=DELAY3(Y,D)
+C D=50
+R X.KL=TABLE(XT,TIME.K,0,125,25)
+T XT=0/10/0/-10/0/10
+PLOT X=X,Y=Y,Z=Z(-10,10)
+SPEC DT=0.5,LENGTH=125,PLTPER=2
+
diff --git a/dynamo/dyn.natchez b/dynamo/dyn.natchez
new file mode 100644
index 0000000..e62c70d
--- /dev/null
+++ b/dynamo/dyn.natchez
@@ -0,0 +1,14 @@
+NOTE Heiratsregeln der NATCHEZ Indianer
+L SUN.K=SWITCH(0,SUN.J,STINKARD.J)
+L NOBLE.K=SWITCH(0,NOBLE.J+SUN.J,STINKARD.J)
+L HONORED.K=SWITCH(0,HONORED.J+NOBLE.J,STINKARD.J)
+L STINKARD.K=CLIP(STINKARD.J-NOBLE.J,0,STINKARD.J-NOBLE.J,0)
+N SUN=20
+N NOBLE=10
+N HONORED=10
+N STINKARD=3000
+C DT=1
+C LENGTH=17
+C PLTPER=1
+PLOT SUN=*,NOBLE=N,HONORED=H,STINKARD=S
+
diff --git a/dynamo/dyn.oszillator b/dynamo/dyn.oszillator
new file mode 100644
index 0000000..3f1e815
--- /dev/null
+++ b/dynamo/dyn.oszillator
@@ -0,0 +1,26 @@
+NOTE OSZILLATOR
+L X.K=X.J+Y.J*DT
+N X=2
+L Y.K=(Y.J+DT*(F/M-X.J*OMEGANULLQUADRAT.J))/(1+GAMMA.J*DT)
+N Y=3
+C M=5
+NOTE
+NOTE linearer harmonischer Oszillator mit BETA=0 und F=0
+NOTE
+NOTE gedaempfter Oszillator mit BETA<>0 und F=0
+NOTE
+NOTE allgemeiner Oszillator mit BETA<>0 und F=f(TIME)
+C BETA=0.5
+A GAMMA.K=BETA/M
+C F=0
+C K=1
+A OMEGANULLQUADRAT.K=K/M
+NOTE hier heisst eine Konstante"K". DYNAMO verwechselt das nicht mit .K !!
+C DT=0.01
+NOTE DT WIRD EXTRA SO KLEIN GEWAEHLT; DAMIT DIE ANNAEHERUNG GUT IST
+NOTE
+NOTE DAS GEHT AUF KOSTEN DER RECHENZEITEN !!!
+C LENGTH=68
+C PLTPER=1
+PLOT Y
+
diff --git a/dynamo/dyn.plot b/dynamo/dyn.plot
new file mode 100644
index 0000000..fe1228a
--- /dev/null
+++ b/dynamo/dyn.plot
@@ -0,0 +1,235 @@
+PACKET dynamo plotter (* Änder.: C.Szymanski, 21.07.88 *)
+ DEFINES b initialize plot, b new plot line, b plot, b end of program,
+ b plot scale :
+
+LET maxvalue = 200,
+ valuepagelength = 18,
+ max param numb = 10;
+
+TYPE PLOTPARAM = STRUCT (TEXT name, id,
+ INT scale pointer,
+ REAL lower bound, upper bound,
+ BOOL l fixed scale, u fixed scale);
+
+ROW max param numb PLOTPARAM VAR plotparam;(* Enth. Plotparameter *)
+ROW maxvalue REAL VAR value; (* Ausgabepuffer *)
+ROW max param numb ROW 5 REAL VAR scale; (* Enth. errechnete Skalierungen *)
+
+BOOL VAR plt;
+TEXT VAR headline;
+REAL VAR pltper, nextplot;
+INT VAR value no, param no, plot line no,
+ plot param no, line no;
+INT CONST nil := 0;
+
+LET line1 = ".____________.____________.____________.____________.",
+ line2 = ". . . . .";
+
+PROC plot one page :
+ init plot routine;
+ plot values.
+
+ init plot routine :
+ print suppressed output;
+ plot line no := nil.
+
+ plot values :
+ INT VAR act value := 1, i;
+ TEXT VAR plot buf;
+ line;
+ vdt;
+ line;
+ IF b stop request THEN LEAVE plot one page END IF;
+ sys page;
+ plot output (headline);
+ put scales;
+ WHILE act value < value no REP
+ put time;
+ gen line;
+ FOR i FROM 1 UPTO plot param no REP
+ plot single value
+ END REP;
+ plot output (plot buf + line0 + collision);
+ plot line no INCR 1;
+ act value INCR plot param no;
+ act value INCR 1
+ END REP.
+
+ put time :
+ plot buf := text (text (round (value (act value), 2)), 6).
+ (* Erstes Pufferelement enthaelt time *)
+
+ gen line :
+ TEXT VAR line0, collision := "";
+ line0 := act line.
+
+ act line :
+ IF (plot line no MOD 5) = nil (* Prueft, ob gestrichelte oder durch - *)
+ THEN line1 (* gezogene Linie gedruckt wird *)
+ ELSE line2
+ FI.
+
+ plot single value :
+ INT VAR position := int ((x-low)*53.0/(up-low))+1; (*Interpolationsformel*)
+ position := limit;
+ IF pos ("._ ", line0 SUB position) > nil
+ THEN replace (line0, position, plotparam (i).id)
+ ELSE collision CAT plotparam (i).id
+ FI.
+
+ limit :
+ IF position > 53
+ THEN 53
+ ELIF position < 1
+ THEN 1
+ ELSE position
+ FI.
+
+ up :
+ scale (i) (5). (* Oberer Grenzwert (der Skalierung) *)
+
+ low :
+ scale (i) (1). (* Unterer Grenzwert *)
+
+ x :
+ value (act value + i).
+
+ put scales : (* Gibt Skalierung der Variablen aus *)
+ INT VAR j := 1, l, scalecounter;
+ WHILE j <= plot param no REP
+ plot buf := " ";
+ FOR l FROM 1 UPTO 4 REP
+ plot buf CAT text (text (scale (j) (l)), 13)
+ END REP;
+ plot buf CAT text (scale (j) (5));
+ scalecounter := plotparam (j).scalepointer;
+ WHILE scalecounter = plotparam (j).scalepointer REP
+ plot buf CAT plotparam (j).id;
+ j INCR 1
+ UNTIL j > max param numb END REP;
+ plot output (plot buf)
+ END REP.
+END PROC plot one page;
+
+PROC b plot scale (TEXT CONST id, INT CONST scale pointer,
+ REAL CONST lower bound, upper bound,
+ BOOL CONST l fixed scale, u fixed scale) :
+ (* Liest Skalierungen vom Zielprogramm ein *)
+ plot param no INCR 1;
+ plot param (plot param no).id := id; (*Variablenname *)
+ plot param (plot param no).scale pointer := scale pointer;(*Zeiger *)
+ plot param (plot param no).lower bound := lower bound; (*Obere Grenze *)
+ plot param (plot param no).upper bound := upper bound; (*Untere Grenze *)
+ plot param (plot param no).l fixed scale := l fixed scale;(*Fix-Skalierung*)
+ plot param (plot param no).u fixed scale := u fixed scale;
+END PROC b plot scale;
+
+PROC gen scales :
+ INT VAR act param, i; (* Generiert Skalierungen fuer eine Seite *)
+ FOR act param FROM 1 UPTO plot param no REP
+ compute single scale
+ END REP.
+
+ compute single scale :
+ REAL VAR max := plotparam(plot param(act param).scale pointer).upper bound,
+ min := plotparam(plot param(act param).scale pointer).lower bound;
+ IF min > max THEN errorstop ("invalid scale") FI;
+ compute extreme scales;
+ FOR i FROM 1 UPTO 3 REP
+ scale (act param) (i+1) := (scale (act param) (5) - scale (act param) (1))
+ * real (i) / 4.0 + scale (act param) (1)
+ (* Interpolationsformel *)
+ END REP.
+
+ compute extreme scales :
+ (* Wenn die Skalierungen nicht gegeben sind, muessen sie berechnet werden.
+ Zur leichteren Lesbarkeit werden die Skalierungen nach oben bzw. unten
+ um jeweils eine Stelle gerundet *)
+ scale (act param) (5) := upper limit;
+ scale (act param) (1) := lower limit.
+
+ upper limit :
+ IF plot param (plot param (act param).scale pointer).u fixed scale
+ THEN max
+ ELSE round (floor (max) + 0.5, 0)
+ FI.
+
+ lower limit :
+ IF plot param (plot param (act param).scale pointer).l fixed scale
+ THEN min
+ ELSE round (floor (min) - 0.5, 0)
+ FI.
+END PROC gen scales;
+
+PROC b initialize plot (TEXT CONST h) :
+ headline := h;
+ pltper := get pltper;
+ plot line no := value pagelength;
+ nextplot := 0.0;
+ value no := nil;
+ line no := nil;
+ plot param no := nil
+END PROC b initialize plot;
+
+PROC b new plot line (REAL CONST time) :
+ plt := time >= nextplot;
+ IF plt (* Wird vom Zielprogramm aufgerufen, um *)
+ THEN add (time); (* Zeilenvorschub durchzufuehren *)
+ line no INCR 1;
+ param no := nil
+ FI;
+ WHILE time >= nextplot REP (* Ist noetig, weil pltper ungleich dt sein *)
+ nextplot INCR pltper (* kann *)
+ END REP
+END PROC b new plot line;
+
+PROC b end of program : (* Druckt am Schluss evt. noch gepufferte *)
+ IF plot line no = value page length AND NOT stop request (* Werte aus *)
+ THEN gen scales;
+ plot one page
+ FI
+END PROC b end of program;
+
+PROC b plot (REAL CONST r) :
+ IF plt (* Wenn genuegend PLOT-Werte gepuffert *)
+ THEN get extreme value; (* sind, wird eine neue Seite gedruckt *)
+ add (r);
+ IF param no = plot param no AND line no = value pagelength
+ THEN gen scales;
+ plot one page;
+ value no := nil;
+ line no := nil
+ FI
+ FI.
+
+ get extreme value :
+ (* Sucht Maximal bzw. Minimalwert, falls keine festen Skalierungs- *)
+ (* grenzen angegeben wurden (im Quellprogramm)*)
+ param no INCR 1;
+ INT VAR act pointer := plot param (param no).scalepointer;
+ set lower bound;
+ set upper bound.
+
+ set lower bound :
+ IF NOT plot param (act pointer).l fixed scale AND
+ r < plot param (act pointer).lower bound
+ THEN plot param (act pointer).lower bound := r
+ FI.
+
+ set upper bound :
+ IF NOT plot param (act pointer).u fixed scale AND
+ r > plot param (act pointer).upper bound
+ THEN plot param (act pointer).upper bound := r
+ FI.
+END PROC b plot;
+
+PROC add (REAL CONST r) : (* Puffert PLOT-Werte *)
+ value no INCR 1;
+ value (value no) := r
+END PROC add;
+
+END PACKET dynamo plotter;
+
+
+
+
diff --git a/dynamo/dyn.plot+ b/dynamo/dyn.plot+
new file mode 100644
index 0000000..db04dfc
--- /dev/null
+++ b/dynamo/dyn.plot+
@@ -0,0 +1,729 @@
+PACKET graphics DEFINES graphmode,
+ attribut,
+ palette,
+ move,
+ plot,
+ draw line,
+ draw linetype,
+ color,
+ draw to:
+
+
+(* Autor: Giffeler GD *)
+(* Datum: 31.03.1988 *)
+(* Schönbeck SHard *)
+
+INT VAR linie :: -1, farbe :: 1, dummy;
+
+
+PROC attribut (INT CONST nr):
+
+(* 0..15 Vordergrundfarben fuer Textdarstellung
+ 0..7 Hintergrundfarben
+ Attribut fuer blinkende Darstellung (+128) *)
+
+ control (-3, nr, 0, dummy)
+
+END PROC attribut;
+
+
+PROC palette (INT CONST nr):
+
+(* Farbauswahl fuer Grafikmodi *)
+
+ control (-4, 0, nr, dummy)
+
+END PROC palette;
+
+
+PROC graphmode (INT CONST mode):
+
+(* 0 -> TEXT 40*25 monochrom
+ 2 -> 80*25
+ 1 -> 40*25 farbig
+ 3 -> 80*25
+ 7 -> 80*25 Herkules
+ 4 -> GRAFIK 320*200 farbig
+ 5 -> monochrom
+ 6 -> 640*200
+ 64 -> Olivetti 640*400 monochrom
+ 72 -> kleine Schrift
+ 512 -> Herkules 720*348 monochrom *)
+
+ control (-5, mode, 0, dummy)
+
+END PROC graphmode;
+
+
+PROC draw linetype (INT CONST pen, color):
+
+(* Linienschraffur und Zeichenfarbe *)
+
+ linie:= pen;
+ farbe:= color;
+ control (-8, linie, farbe, dummy)
+
+END PROC draw linetype;
+
+
+PROC draw linetype (INT CONST nr):
+
+(* Ausschliessliche Aenderung der Linienschraffur *)
+
+ linie:= nr;
+ control (-8, linie, farbe, dummy)
+
+END PROC draw linetype;
+
+
+PROC color (INT CONST nr):
+
+(* Ausschliessliche Aenderung der Zeichenfarbe *)
+
+ farbe:= nr;
+ control (-8, linie, farbe, dummy)
+
+END PROC color;
+
+
+PROC move (INT CONST x, y):
+
+(* Bewegt Zeichencursor zu Koordinaten (0,0 = Links oben) *)
+
+ control (-7, x, y, dummy)
+
+END PROC move;
+
+
+PROC move (REAL CONST x, y):
+
+ control (-7, int(x+0.5), int(y+0.5), dummy)
+
+END PROC move;
+
+
+PROC draw to (INT CONST x, y):
+
+(* Zeichnet Gerade von momentaner Zeichencursorposition nach x,y *)
+
+ control (-6, x, y, dummy)
+
+END PROC draw to;
+
+
+PROC draw to (REAL CONST x, y):
+
+ control (-6, int(x+0.5), int(y+0.5), dummy)
+
+END PROC draw to;
+
+
+PROC draw line (INT CONST x1, y1, x2, y2):
+
+(* Zieht eine Linie von x1,y1 nach x2,y2 *)
+
+ plot (x1, y1);
+ draw to (x2, y2)
+
+END PROC draw line;
+
+
+PROC draw line (REAL CONST x1, y1, x2, y2):
+
+ plot (x1, y1);
+ draw to (x2, y2)
+
+END PROC draw line;
+
+
+PROC plot (INT CONST x, y):
+
+(* Zeichnet einen Punkt *)
+
+ control (-7, x, y, dummy);
+ control (-6, x, y, dummy)
+
+END PROC plot;
+
+
+PROC plot (REAL CONST x, y):
+
+ control (-7, int(x+0.5), int(y+0.5), dummy);
+ control (-6, int(x+0.5), int(y+0.5), dummy)
+
+END PROC plot;
+
+
+PROC draw to (INT CONST x, y, f):
+
+(* Zeichnet Gerade von momentaner Zeichencursorposition nach x,y *)
+
+ color (f);
+ control (-6, x, y, dummy)
+
+END PROC draw to;
+
+
+PROC draw to (REAL CONST x, y, INT CONST f):
+
+ color (f);
+ control (-6, int(x+0.5), int(y+0.5), dummy)
+
+END PROC draw to;
+
+
+PROC draw line (INT CONST x1, y1, x2, y2, f):
+
+(* Zieht eine Linie von x1,y1 nach x2,y2 *)
+
+ plot (x1, y1, f);
+ draw to (x2, y2)
+
+END PROC draw line;
+
+
+PROC draw line (REAL CONST x1, y1, x2, y2, INT CONST f):
+
+ plot (x1, y1, f);
+ draw to (x2, y2)
+
+END PROC draw line;
+
+
+PROC plot (INT CONST x, y, f):
+
+(* Zeichnet einen Punkt mit der Farbe f (0 = schwarz) *)
+
+ color (f);
+ control (-7, x, y, dummy);
+ control (-6, x, y, dummy)
+
+END PROC plot;
+
+
+PROC plot (REAL CONST x, y, INT CONST f):
+
+ color (f);
+ control (-7, int(x+0.5), int(y+0.5), dummy);
+ control (-6, int(x+0.5), int(y+0.5), dummy)
+
+END PROC plot
+
+
+END PACKET graphics;
+
+
+PACKET dynamo plotter plus DEFINES configurate plot,
+ initialize plot,
+ new plot line,
+ plot,
+ end of program,
+ stop request,
+ plot scale:
+
+(* DYNAMO Grafikausgabe *)
+(* Autor : Giffeler GD *)
+(* Datum : 29.04.1988, 03.06.1988 *)
+(* Änder.: Christian Szymanski *)
+(* 21.07.88 *)
+
+
+LET max value = 330,
+ value page length = 30,
+ max param numb = 10,
+
+ PARAM = ROW value page length REAL,
+ BIG = ROW 300 REAL,
+
+ max devices = 3,
+ SWITCH = STRUCT (TEXT bezeichnung, INT on, off,
+ zeichenbreite, zeichenhoehe,
+ h offset,
+ x, y, breite, hoehe),
+ SIZE = ROW max devices SWITCH;
+
+
+TYPE PLOTPARAM = STRUCT (TEXT name, REAL lower bound, upper bound);
+
+
+ROW max param numb PLOTPARAM VAR plotparam;
+ROW max value REAL VAR value;
+
+BOOL VAR plt, ende;
+REAL VAR pltper, nextplot;
+INT VAR value no, param no, plot line no, mode nr, plot param no, line no,
+ xp, yp;
+
+SIZE CONST table :: SIZE:
+ (SWITCH: ("CGA 640 * 200", 6, 2, 8, 8, 5, 4, 20, 615, 102),
+ SWITCH: ("HGC 720 * 348", 512, 0, 0, 0, 0, 0, 0, 0, 0),
+ SWITCH: ("OLI 640 * 400", 64, 2, 8, 16, 10, 4, 25, 615, 223));
+
+configurate plot; (* Erster Aufruf nach der Insertierung *)
+
+
+PROC plot one page :
+INT VAR loop nr, n, m;
+PARAM VAR x, y;
+BIG VAR xr, yr;
+
+ kopfzeile ("Stuetzstellen: ", TRUE);
+ xp:= 1; yp:= 19;
+ FOR loop nr FROM 1 UPTO plot param no REP
+ werte aus value in x und y uebertragen;
+ koordinatenkreuz (table[mode nr].x, table[mode nr].y,
+ table[mode nr].breite, table[mode nr].hoehe);
+ x raster (table[mode nr].x, table[mode nr].y,
+ table[mode nr].breite, table[mode nr].hoehe, n);
+ zusatzinformationen ausgeben;
+ spline (n, m, 1, x, y, xr, yr);
+ draw picture (table[mode nr].x, table[mode nr].y,
+ table[mode nr].breite, table[mode nr].hoehe,
+ loop nr, m,
+ plot param[loop nr].lower bound,
+ plot param[loop nr].upper bound,
+ xr, yr);
+ legende ausgeben
+ PER;
+ abbruch;
+ graphmode(table[mode nr].off).
+
+werte aus value in x und y uebertragen:
+INT CONST erh :: plot param no + 1;
+INT VAR z :: 1, w :: loop nr + 1;
+
+ FOR n FROM 1 UPTO value no DIV erh REP
+ x[n]:= value[z]; y[n]:= value[w];
+ z INCR erh;
+ w INCR erh
+ PER;
+ n DECR 1;
+ m:= n * 10.
+
+zusatzinformationen ausgeben:
+TEXT CONST xn :: text(x[n]);
+
+ cursor (1, 17); put (x[1]);
+ cursor (81 - LENGTH xn, 17);
+ out (xn);
+ cursor (74, 1).
+
+legende ausgeben:
+INT VAR xph, yph;
+
+ cursor (xp, yp);
+ put (plot param[loop nr].name + "=");
+ put (plot param[loop nr].lower bound);
+ put ("-");
+ put (plot param[loop nr].upper bound);
+ get cursor (xph, yph);
+ draw line (xph * table[mode nr].zeichenbreite - 8,
+ yph * table[mode nr].zeichenhoehe - table[mode nr].h offset,
+ xph * table[mode nr].zeichenbreite + 24,
+ yph * table[mode nr].zeichenhoehe - table[mode nr].h offset);
+ IF xp > 1 THEN line ELSE cursor (40, yph) FI;
+ get cursor (xp, yp).
+
+abbruch:
+TEXT VAR eingabe;
+
+ REP
+ cursor (30, 1);
+ put (39*" "+"(+, p, e)?");
+ inchar (eingabe);
+ SELECT code (eingabe) OF
+ CASE 43 : eingabe:= ""
+ CASE 69, 101: ende:= TRUE; eingabe:= ""
+ CASE 80, 112: phasendiagramm
+ OTHERWISE out(""7"")
+ END SELECT
+ UNTIL eingabe = "" PER
+
+END PROC plot one page;
+
+
+PROC initialize plot (TEXT CONST h) :
+INT VAR c :: 1, typ;
+TEXT VAR sym, num;
+
+ ende:= FALSE;
+ pltper:= get pltper;
+ plot line no:= value page length;
+ nextplot:= 0.0;
+ value no:= 0;
+ line no:= 0;
+ plot param no:= 0;
+ kopfzeile zerlegen.
+
+kopfzeile zerlegen:
+ scan (h);
+ REP
+ next symbol (plot param[c].name);
+ next symbol (sym, typ);
+ IF sym = "(" THEN
+ next symbol (num);
+ next symbol (sym, typ);
+ IF sym = ")" THEN
+ plot param[c].name CAT ("(" + num + ")")
+ FI
+ FI;
+ WHILE typ < 7 CAND NOT (sym = "(" COR sym = ",") REP
+ next symbol (sym, typ)
+ PER;
+ IF typ < 7 CAND sym = "(" THEN
+ REP next symbol (sym)
+ UNTIL sym = "," PER;
+ REP next symbol (sym, typ)
+ UNTIL typ > 6 COR sym = "," COR sym = "/" PER
+ FI;
+ c INCR 1
+ UNTIL typ > 6 PER
+
+END PROC initialize plot;
+
+
+PROC plot scale (TEXT CONST id, INT CONST scale pointer,
+ REAL CONST lower bound, upper bound,
+ BOOL CONST l fixed scale, u fixed scale) :
+
+ plot param no INCR 1;
+ plot param[plot param no].lower bound:= lower bound;
+ plot param[plot param no].upper bound:= upper bound
+
+END PROC plot scale;
+
+
+PROC new plot line (REAL CONST time) :
+
+ plt:= time >= nextplot;
+ IF plt THEN
+ add (time);
+ line no INCR 1;
+ param no:= 0
+ FI;
+ WHILE time >= nextplot REP
+ nextplot INCR pltper
+ PER
+
+END PROC new plot line;
+
+
+PROC plot (REAL CONST r):
+
+ IF plt THEN
+ param no INCR 1;
+ add (r);
+ IF NOT ende CAND param no = plot param no AND
+ line no = value page length THEN
+ plot one page;
+ value no:= 0;
+ line no:= 0
+ FI
+ FI
+
+END PROC plot;
+
+
+PROC add (REAL CONST r):
+
+ IF NOT ende THEN
+ value no INCR 1;
+ value[value no]:= r
+ FI
+
+END PROC add;
+
+
+PROC spline (INT CONST n, m, s, PARAM CONST x, y, BIG VAR xr, yr):
+
+{ Kubische Splineinterpolation 3. Grades; 2 fach Differenzierbar }
+{ Quelle: Rita Schmidt, Hahn-Meitner-Institut für Kernforschung Berlin }
+{ "Spline-Prozeduren" (HMI-B 220) }
+{ Umsetzung & Modifikation: Giffeler GD, 13.04.1988, 22.04.1988 }
+
+{ n = Anzahl der Stützstellen }
+{ m = Anzahl der zu berechnenden Funktionswerte }
+{ s = Index des x-Startpunktes }
+{ x = x-Werte der Stützstellen (linear steigend) }
+{ y = y-Werte der Stützstellen }
+{ xr = x-Werte der Punkte, an denen die Funktion berechnet werden }
+{ soll }
+{ yr = y-Werte der Punkte, an denen die Funktion berechnet werden }
+{ soll }
+
+
+INT CONST nn :: n - 1;
+REAL CONST steps :: (real(nn) * (x[2] - x[1])) / real(m - 1);
+
+PARAM VAR q, au;
+REAL VAR hi, hk, hk1, dij, dim1j;
+INT VAR k, kk, j, m1, m2, m3;
+
+ q[1]:= 0.0;
+ yr[1]:= x[s];
+ FOR j FROM 2 UPTO m REP yr[j]:= yr[j - 1] + steps PER;
+ xr:= yr;
+ block 0;
+ FOR k FROM 2 UPTO nn REP block 1 PER;
+ FOR kk FROM 2 UPTO nn REP block 2 PER;
+ FOR j FROM 1 UPTO m REP block 3 PER.
+
+block 0:
+ au[1]:= (y[3] - y[2] - y[2] + y[1]) / ((x[2] - x[1]) * (x[3] - x[2]));
+ au[n]:= (y[n] - y[nn] - y[nn] + y[n - 2]) /
+ ((x[n] - x[nn]) * (x[nn] - x[n - 2])).
+
+block 1:
+INT CONST km1 :: k - 1, kp1 :: k + 1;
+
+ hk:= x[k] - x[km1];
+ hk1:= x[kp1] - x[k];
+ q[k]:= - hk1 / (hk * (q[km1] + 2.0) + 2.0 * hk1);
+ au[k]:= (hk * au[km1] - 6.0 * ((y[kp1] - y[k]) / hk1 - (y[k] -
+ y[km1]) / hk)) * q[k] / hk1.
+
+block 2:
+ k:= nn - kk + 2;
+ au[k]:= q[k] * au[k + 1] + au[k].
+
+block 3:
+ zeige benutzer das du noch lebst;
+ IF yr[j] < x[1] THEN
+ m1:= 1;
+ m2:= 2
+ ELIF yr[j] > x[n] THEN
+ m1:= n - 1;
+ m2:= n
+ ELSE
+ m1:= 1;
+ m2:= n;
+ wiederholung
+ FI;
+ dij:= x[m2] - yr[j];
+ hi:= x[m2] - x[m1];
+ dim1j:= x[m1] - yr[j];
+ yr[j]:= 1.0 / 6.0 / hi * (au[m1] * dij ** 3 - au[m2] * dim1j ** 3 +
+ (6.0 * y[m1] - hi ** 2 * au[m1]) * dij - (6.0 * y[m2] - hi ** 2
+ * au[m2]) * dim1j).
+
+wiederholung:
+ REP
+ m3:= (m2 + m1) DIV 2;
+ IF yr[j] >= x[m3] THEN m1:= m3 ELSE m2:= m3 FI
+ UNTIL m2 - m1 = 1 PER.
+
+zeige benutzer das du noch lebst:
+ cout (j)
+
+END PROC spline;
+
+
+PROC phasendiagramm:
+REAL VAR l :: maxreal, u :: smallreal;
+BIG VAR x, y;
+INT VAR i, no1, no2;
+
+ IF plot param no > 1 THEN
+ partnerwahl;
+ werte aus value uebertragen;
+ kopfzeile ("Phasendiagramm", TRUE);
+ koordinatenkreuz (table[mode nr].x, table[mode nr].y,
+ table[mode nr].breite, table[mode nr].hoehe+50);
+ draw picture (table[mode nr].x, table[mode nr].y,
+ table[mode nr].breite, table[mode nr].hoehe+50,
+ 1, i-1, l, u, x, y);
+ legende
+ FI.
+
+partnerwahl:
+ kopfzeile ("Phasendiagramm", FALSE);
+ line (2);
+ FOR i FROM 1 UPTO plot param no REP
+ putline (text(i, 3) + " = " + plot param[i].name)
+ PER;
+ REP
+ cursor (1, plot param no +5);
+ put ("X-ACHSE:"); get (no1);
+ cursor (1, plot param no +5);
+ put ("Y-ACHSE:"); get (no2)
+ UNTIL no1 > 0 CAND no1 <= plot param no CAND
+ no2 > 0 CAND no2 <= plot param no CAND
+ no1 <> no2 PER.
+
+werte aus value uebertragen:
+INT CONST erh :: plot param no + 1;
+INT VAR n1 :: no1 + 1, n2 :: no2 + 1;
+
+ FOR i FROM 1 UPTO value no DIV erh REP
+ x[i]:= value[n1];
+ y[i]:= value[n2];
+ n1 INCR erh;
+ n2 INCR erh
+ PER.
+
+legende:
+ cursor (1, 23);
+ putline ("X-Achse: " + plot param[no1].name);
+ out ("Y-Achse: " + plot param[no2].name)
+
+END PROC phasendiagramm;
+
+
+PROC draw picture (INT CONST x, y, xb, yb, schraffur, m,
+ REAL VAR lower bound, upper bound,
+ BIG CONST xr, yr):
+
+{ Ausgabe einer Funktionskurve }
+{ Autor: Giffeler GD, 22.04.1988, 27.04.1988 }
+
+{ x = X-Position (oben links = 0) }
+{ y = Y-Position (oben links = 0) }
+{ xb = Ausgabebreite }
+{ yb = Ausgabehöhe }
+{ schraffur = Linienschraffur (1 - 10) }
+{ m = Anzahl der Funktionswerte }
+{ lower bound = Unterer Grenzwert (maxreal wenn Grenze beliebig) }
+{ upper bound = Oberer Grenzwert (smallreal wenn Grenze beliebig) }
+{ xr = Durch SPLINE erzeugte X-Werte }
+{ yr = Durch SPLINE erzeugte Y-Werte }
+
+
+ROW 10 INT CONST linienarten :: ROW 10 INT: (-1, -256, 3855, -240,
+ 21845, -1, -1, -1, -1, -1);
+
+REAL VAR lbx :: maxreal, ubx :: smallreal;
+INT VAR i;
+
+ minimum und maximum fuer x und y berechnen;
+ abmessungsparameter umwandeln;
+ spannweite errechnen;
+ linienschraffur bestimmen;
+ eine funktion ausgeben.
+
+minimum und maximum fuer x und y berechnen:
+ FOR i FROM 1 UPTO m REP
+ lower bound:= min (lower bound, yr[i]);
+ upper bound:= max (upper bound, yr[i]);
+ lbx:= min (lbx, xr[i]);
+ ubx:= max (ubx, xr[i])
+ PER.
+
+abmessungsparameter umwandeln:
+REAL CONST xpos :: real (x), ypos :: real (y),
+ breite :: real (xb), hoehe :: real (yb).
+
+spannweite errechnen:
+REAL CONST sy :: (upper bound - lower bound) / hoehe,
+ sx :: (ubx - lbx) / breite.
+
+linienschraffur bestimmen:
+ draw linetype (linienarten [abs(schraffur) MOD 10]).
+
+eine funktion ausgeben:
+ move (xpos + (xr[1] - lbx) / sx,
+ ypos + hoehe - (yr[1] - lower bound) / sy);
+ FOR i FROM 2 UPTO m REP
+ drawto (xpos + (xr[i] - lbx) / sx,
+ ypos + hoehe - (yr[i] - lower bound) / sy)
+ PER
+
+END PROC draw picture;
+
+
+PROC koordinatenkreuz (INT CONST nx, ny, breite, hoehe):
+
+ anpassung;
+ rahmen;
+ pfeil oben;
+ pfeil rechts.
+
+anpassung:
+INT CONST x :: nx - 1,
+ y :: ny - 10,
+ b :: breite + 21,
+ h :: hoehe + 11.
+
+rahmen:
+ draw linetype (-1);
+ draw line (x, y, x, y + h);
+ draw to (x + b, y + h).
+
+pfeil oben:
+ draw line (x - 3, y + 4, x, y);
+ draw to (x + 3, y + 4).
+
+pfeil rechts:
+ draw line (x + b - 5, y + h - 2, x + b, y + h);
+ draw to (x + b - 5, y + h + 2)
+
+END PROC koordinatenkreuz;
+
+
+PROC x raster (INT CONST nx, ny, breite, hoehe, anzahl):
+REAL CONST y :: real (ny + hoehe + 2),
+ w :: real (breite) / real (anzahl);
+REAL VAR s :: real (nx);
+INT VAR i;
+
+ FOR i FROM 1 UPTO anzahl REP
+ s INCR w;
+ plot (s, y)
+ PER
+
+END PROC x raster;
+
+
+PROC configurate plot:
+(*
+BOOL CONST cmd :: command dialogue;
+INT VAR i;
+
+ command dialogue (TRUE);
+ REP
+ bildschirmausgabe zur auswahl
+ UNTIL (mode nr <= max devices AND mode nr > 0) CAND
+ yes ("Eingabe richtig") PER;
+ command dialogue (cmd).
+
+bildschirmausgabe zur auswahl:
+ page;
+ putline ("CONFIGURATIONSTABELLE DYNAMO GRAFIK");
+ line (2);
+ FOR i FROM 1 UPTO max devices REP
+ putline (text(i)+" -- "+table[i].bezeichnung)
+ PER;
+ line (2);
+ put ("Modus:");
+ get (mode nr)
+
+*)
+mode nr := 1. (* CGA *)
+END PROC configurate plot;
+
+
+PROC kopfzeile (TEXT CONST message, BOOL CONST grafik):
+
+ IF grafik THEN graphmode (table[mode nr].on)
+ ELSE graphmode (table[mode nr].off) FI;
+ out (""1""); (* C.S. 21.07.88 *)
+ out ("DYNAMO 3.3+");
+ cursor (79 - LENGTH message, 1);
+ out (message)
+
+END PROC kopfzeile;
+
+
+PROC end of program :
+
+ IF NOT ende CAND (value no DIV (plot param no + 1)) > 2 THEN
+ plot one page
+ FI
+
+END PROC end of program;
+
+
+BOOL PROC stop request: ende END PROC stop request
+
+
+END PACKET dynamo plotter plus
+
diff --git a/dynamo/dyn.print b/dynamo/dyn.print
new file mode 100644
index 0000000..36ea279
--- /dev/null
+++ b/dynamo/dyn.print
@@ -0,0 +1,43 @@
+PACKET dynamo printer DEFINES initialize print, new line, print :
+
+BOOL VAR prt;
+TEXT VAR headline;
+REAL VAR prtper, nextprint;
+
+PROC initialize print (TEXT CONST h) :
+ headline := h;
+ prtper := get prtper;
+ nextprint := 0.0
+END PROC initialize print;
+
+PROC new line (REAL CONST time) :
+ IF time >= nextprint
+ THEN do lf
+ ELSE prt := FALSE
+ FI;
+ WHILE time >= nextprint REP
+ nextprint INCR prtper
+ PER.
+
+ do lf :
+ print line;
+ prt := TRUE;
+ IF pagefeed necessary OR NOT was print
+ THEN vdt;
+ sys page;
+ print headline
+ FI;
+ print (time).
+
+ print headline :
+ println ("TIME " + headline).
+END PROC new line;
+
+PROC print (REAL CONST r) :
+ IF prt
+ THEN print output (text (text (round (r, 5)), 13))
+ FI
+END PROC print
+
+END PACKET dynamo printer
+
diff --git a/dynamo/dyn.proc b/dynamo/dyn.proc
new file mode 100644
index 0000000..a291a48
--- /dev/null
+++ b/dynamo/dyn.proc
@@ -0,0 +1,160 @@
+PACKET dynamo prozeduren DEFINES clip,fifge,switch,fifze,table,tabhl,
+ sclprd,sum,sumv,
+ noise,normrn,power,
+ pulse,step,ramp,
+ set time :
+(***************************************************D.Craemer 16. 2.1983 ***)
+(* uses:
+ type TAB (Tabellen), wert, laenge
+ abs
+ random
+
+ globale Variablen simulationtime wird durch das DYNAMO-
+ Programm gesetzt und in
+ den Funktionen, die zeit-
+ lich ausgeloest werden,
+ benutzt
+
+ lastpulse Zeit des letzten Pulses
+
+
+*)
+
+REAL VAR simulation time,last pulse:=0.0;
+
+PROC set time (REAL CONST time) :
+ simulation time := time
+END PROC set time ;
+
+(************************ ab hier Funktionen *******************************)
+(************************ zur Wertauswahl *******************************)
+
+REAL PROC clip(REAL CONST p,q,r,s):
+ IF r>=s THEN p ELSE q FI
+ END PROC clip;
+
+REAL PROC fifge(REAL CONST p,q,r,s):
+ clip(p,q,r,s)
+ END PROC fifge;
+
+(* clip und fifge machen dasselbe, der Name fifge gibt die Funktion besser
+wieder: first if greater or equal
+ = == = = *)
+
+REAL PROC switch (REAL CONST p,q,r):
+ IF r=0.0 THEN p ELSE q FI
+ END PROC switch;
+
+REAL PROC fifze (REAL CONST p,q,r):
+ switch(p,q,r)
+ END PROC fifze;
+
+(* Funktion switch oder fifze: first if zero
+ = == == *)
+
+(************************ ab hier Funktionen *******************************)
+(************************ mit Tabellen *******************************)
+
+REAL PROC table (TAB CONST t, REAL CONST x, xlow, x high, xincr) :
+ IF x < x low OR x > x high
+ THEN putline("TABLE out of range: xlow="+text(xlow)+" x="+text(x)+
+ " xhigh="+text(xhigh)+" xincr="+text(xincr));0.0
+ ELIF x=xhigh
+ THEN wert(t,laenge(t))
+ ELIF x=xlow
+ THEN wert(t,1)
+ ELSE deliver interpolated value
+ FI.
+
+deliver interpolated value:
+ INT VAR index :: int((x-xlow)/xincr)+1;
+ REAL VAR m :: ((wert (t, index + 1) - wert (t, index)) / x incr),
+ b :: wert (t, index);
+
+ m * (x-(xlow+real(index-1)*xincr)) + b.
+END PROC table;
+
+
+REAL PROC tabhl (TAB CONST t, REAL CONST x, xlow, x high, xincr) :
+ IF xlow < x AND x < xhigh
+ THEN table(t,x,xlow,xhigh,xincr)
+ ELIF x <= xlow
+ THEN wert(t,1)
+ ELSE wert(t,laenge(t))
+ FI
+END PROC tabhl ;
+
+REAL PROC sclprd(TAB CONST tab1,REAL CONST erstes1,letztes1,TAB CONST tab2,
+ REAL CONST erstes2):
+INT VAR i;
+REAL VAR summe:=0.0;
+FOR i FROM 0 UPTO int(letztes1-erstes1) REP
+ summe:=summe + wert(tab1,int(erstes1)+i)*wert(tab2,int(erstes2)+i)
+PER;
+summe
+END PROC sclprd;
+
+REAL PROC sumv(TAB CONST tab, REAL CONST erstes,letztes):
+REAL VAR summe:=0.0;
+INT VAR i;
+FOR i FROM int(erstes) UPTO int(letztes) REP
+ summe:=summe+wert(tab,i)
+PER;
+summe
+END PROC sumv;
+
+REAL PROC sum(TAB CONST tab):
+ sumv(tab,1.0,real(laenge(tab)))
+END PROC sum;
+
+(************************ ab hier Funktionen *******************************)
+(************************ mit Zufallszahlen *******************************)
+
+REAL PROC noise(REAL CONST dummy):
+ random-0.5
+END PROC noise;
+
+REAL PROC normrn(REAL CONST mittelwert,stdvar):
+REAL VAR z:=0.0;
+INT VAR i;
+(* Methode nach NAYLOR et al.: Computer Simulation Technique, Wiley,NY 1966*)
+FOR i FROM 1 UPTO 12 REP
+ z:=z+random
+PER;
+z:=z-6.0;
+mittelwert+z*stdvar
+END PROC normrn;
+
+(************************ ab hier Funktionen *******************************)
+(************************ mit Zeitausloesung ******************************)
+
+REAL PROC pulse(REAL CONST height,first,interval):
+IF simulationtime < first THEN lastpulse:=0.0; 0.0
+ ELIF abs(simulationtime-first) < smallreal THEN lastpulse:=simulationtime;
+ height
+ ELIF abs(simulationtime-(lastpulse+interval)) < smallreal THEN
+ lastpulse:=simulationtime;
+ height
+ ELSE 0.0
+END IF
+END PROC pulse;
+
+REAL PROC step(REAL CONST height,steptime):
+ IF simulationtime<steptime THEN 0.0
+ ELSE height
+ FI
+END PROC step;
+
+REAL PROC ramp(REAL CONST slope,start):
+ IF simulationtime<start THEN 0.0
+ ELSE slope*(simulationtime-start)
+ FI
+END PROC ramp;
+
+REAL PROC power(REAL CONST basis,exponent):
+ basis**int(exponent)
+END PROC power
+
+
+END PACKET dynamo prozeduren
+
diff --git a/dynamo/dyn.quadrat b/dynamo/dyn.quadrat
new file mode 100644
index 0000000..fdd553a
--- /dev/null
+++ b/dynamo/dyn.quadrat
@@ -0,0 +1,13 @@
+NOTE HIER BERECHNEN WIR DAS QUADRAT MITTELS ABLEITUNG !
+L F.K=F.J+2*TIME.J*DT
+N F=0
+C DT=0.01
+NOTE DT WIRD EXTRA SO KLEIN GEWAEHLT; DAMIT DIE ANNAEHERUNG GUT IST
+NOTE
+NOTE DAS GEHT AUF KOSTEN DER RECHENZEITEN !!!
+C LENGTH=17
+C PLTPER=1
+PLOT F
+C PRTPER=1
+PRINT F
+
diff --git a/dynamo/dyn.rts b/dynamo/dyn.rts
new file mode 100644
index 0000000..c46684a
--- /dev/null
+++ b/dynamo/dyn.rts
@@ -0,0 +1,376 @@
+PACKET rts
+ DEFINES constant, vdt, get pltper, get prtper, was print,
+ println, print output, plot output, print line,
+ sys page, pagefeed necessary, print suppressed output, asterisk,
+ protokoll, default, set pagelength, run time system, b stop request,
+ scroll, run card :
+ (* Runtime - System *)
+ (* Autor : R. Keil *)
+ (* Datum : 12.07.83 Aenderung: 19.06.84 D. Craemer *)
+ (* 2.Aenderung: 6.05.85 D. Craemer *)
+ (* Änderung auf 1.8.2: Z. 288, Christian Szymanski, 10.08.88 *)
+ (* In der 2. Aenderung wurde dyn.const in zzdyn.const umbenannt*)
+ (* und alle Konstanten-Datenraeume bekommen ".const" angehaengt*)
+ (* Wird im rts das Kommando run name gegeben, so wird der *)
+ (* augenblickliche Konstanten-Datenraum gerettet im Datenraum *)
+ (* mit dem Namen: "name.const" *)
+
+
+
+ LET esc = ""27"",
+ max tab size = 50,
+ bold = 1,
+ number = 2,
+ delimiter = 3;
+
+TYPE CONSTANT = STRUCT (ROW max tab size TEXT name,
+ ROW max tab size REAL value,
+ INT tab size);
+
+BOUND CONSTANT VAR constants;
+
+FILE VAR sysout;
+TEXT VAR print buf, asterisk buffer, sym, const name,
+ const space name::"zzdyn.const";
+REAL VAR dt, length, prtper, pltper;
+INT VAR line no, page no, max pagelength, type;
+
+BOOL VAR vdt on, print, protocoll, terminal stop, is scroll,
+ is not first, run specified;
+
+
+default;
+
+PROC default :
+ protocoll := FALSE;
+ max pagelength := 23;
+ is scroll := TRUE;
+ run specified := FALSE
+END PROC default;
+
+PROC set pagelength (INT CONST i) :
+ max pagelength := i
+END PROC set pagelength;
+
+PROC run card (TEXT CONST run name) :
+ IF exists (actual constants)
+ THEN constants := old (actual constants)
+ ELIF run name="zzdyn"
+ THEN constants := new (actual constants);
+ CONCR (constants).tab size := 0
+ ELSE copy (const space name, actual constants);
+ constants := old (actual constants)
+ FI;
+ const space name := actual constants.
+
+ actual constants:
+ run name + ".const".
+
+END PROC run card;
+
+REAL PROC constant (TEXT CONST name, REAL CONST val) :
+ REAL VAR value;
+ INT VAR tab pos;
+ value := actual value;
+ set system consts.
+
+ actual value :
+ search constant (name, tab pos);
+ IF tab pos > 0
+ THEN CONCR (constants).value (tab pos)
+ ELSE new constant (name, val);
+ val
+ FI.
+
+ set system consts :
+ SELECT pos ("dt length prtper pltper ", name + " ") OF
+ CASE 1 : dt := value
+ CASE 4 : length := value
+ CASE 11 : prtper := value
+ CASE 18 : pltper := value
+ END SELECT;
+ value.
+END PROC constant;
+
+PROC new constant (TEXT CONST name, REAL CONST val) :
+ CONCR (constants).tab size INCR 1;
+ IF CONCR (constants).tab size > max tab size
+ THEN errorstop ("ZUVIELE KONSTANTEN")
+ FI;
+ CONCR (constants).name (CONCR (constants).tab size) := name;
+ CONCR (constants).value (CONCR (constants).tab size) := val
+END PROC new constant;
+
+PROC search constant (TEXT CONST name, INT VAR tab pos) :
+ INT VAR i;
+ FOR i FROM 1 UPTO CONCR (constants).tab size REP
+ IF name = CONCR (constants).name (i)
+ THEN tab pos := i;
+ LEAVE search constant
+ FI
+ END REP;
+ tab pos := 0
+END PROC search constant;
+
+REAL PROC get pltper : (* Reicht 'pltper' (Plotperiode) heraus *)
+ pltper
+END PROC get pltper;
+
+REAL PROC get prtper : (* Reicht 'prtper' (Printperiode) heraus *)
+ prtper
+END PROC get prtper;
+
+PROC scroll (BOOL CONST b) :
+ is scroll := b
+END PROC scroll;
+
+PROC next sym :
+ next sym (sym, type)
+END PROC next sym;
+
+PROC rts err (TEXT CONST err mess) :
+ outline ("FEHLER BEI >>>" + sym + "<<< : " + err mess)
+END PROC rts err;
+
+PROC run time system (PROC target program) :
+ IF protocoll
+ THEN kill ("dyn.out");
+ sysout := sequential file (output, "dyn.out")
+ FI;
+ init rts;
+ REP
+ get command;
+ execute command
+ END REP.
+
+ get command :
+ TEXT VAR command;
+ print suppressed output;
+ line;
+ putline (" dynamo runtime system :");
+ shift;
+ getline (command);
+ printline (command).
+
+ execute command :
+ scanner (command);
+ next sym;
+ TEXT VAR start := sym;
+ skip blanks;
+ SELECT pos ("run rerun quit help c ? EOL ", start + " ") OF
+ CASE 1, 5 : run
+ CASE 11 : quit
+ CASE 16 : show ("dyn.help")
+ CASE 21 : const equ
+ CASE 23 : dump consts
+ CASE 25 :
+ OTHERWISE : rts err ("KOMMANDO UNBEKANNT")
+ END SELECT.
+
+ run :
+ init rts;
+ IF type = bold OR type = delimiter
+ THEN run card (sym)
+ FI;
+ target program.
+
+ quit :
+ IF const space name = "zzdyn.const"
+ THEN kill (const space name)
+ FI;
+ LEAVE runtime system.
+
+ skip blanks :
+ REP
+ next sym
+ UNTIL sym <> " " END REP.
+
+ const equ :
+ REAL VAR value, dummy;
+ INT VAR tab pos;
+ REP
+ analyze constant equ;
+ search constant (const name, tab pos);
+ IF tab pos = 0
+ THEN sym := const name;
+ rts err ("KONSTANTE NICHT DEFINIERT")
+ ELSE CONCR (constants).value (tab pos) := value
+ FI
+ UNTIL end of constants END REP.
+
+ analyze constant equ :
+ IF type <> bold
+ THEN rts err ("NAME ERWARTET")
+ FI;
+ const name := sym;
+ next sym;
+ IF sym <> "="
+ THEN rts err ("^=^ ERWARTET")
+ FI;
+ get constant.
+
+ end of constants :
+ next sym;
+ IF sym = "/" OR sym = ","
+ THEN next sym; FALSE
+ ELSE TRUE
+ FI.
+
+ get constant :
+ next sym;
+ value := 1.0;
+ IF sym = "-"
+ THEN value := -1.0; next sym
+ ELIF sym = "+"
+ THEN next sym
+ FI;
+ IF type = number
+ THEN value := value * real (sym)
+ ELSE rts err ("ZAHL ERWARTET")
+ FI.
+
+ dump consts :
+ INT VAR i;
+ FOR i FROM 1 UPTO CONCR (constants).tab size REP
+ IF (i MOD 2) = 1
+ THEN line; shift
+ FI;
+ out (text (CONCR (constants).name (i), 14), " = ",
+ text (text (CONCR (constants).value (i)), 13))
+ END REP;
+ line.
+END PROC run time system;
+
+PROC shift :
+ out (" ")
+END PROC shift;
+
+PROC init rts :
+ line no := 0;
+ page no := 0;
+ asterisk buffer := "";
+ print buf := "";
+ print := FALSE;
+ terminal stop := FALSE;
+ is not first := FALSE;
+ vdt on := TRUE
+END PROC init rts;
+
+PROC protokoll (BOOL CONST b) :
+ protocoll := b
+END PROC protokoll;
+
+PROC print line :
+ BOOL VAR b := print; (* Druckt Ausgabe - Puffer und *)
+ println (print buf); (* loescht anschliessend den Inhalt *)
+ print buf := "";
+ print := b
+END PROC print line;
+
+PROC print suppressed output :
+ IF print buf <> "" (* Druckt Ausgabe - Puffer, *)
+ THEN println (print buf); (* falls gefuellt *)
+ print buf := ""
+ FI
+END PROC print suppressed output;
+
+PROC print output (TEXT CONST t) :
+ print buf CAT t; (* Fuellt Ausgabe - Puffer *)
+ print buf CAT " "
+END PROC print output;
+
+PROC println (TEXT CONST t) :
+ print := TRUE; (* Verteilt Ausgabe auf Bildschirm *)
+ line no INCR 1; (* und Datei *)
+ outline (t);
+ IF line no = max page length
+ THEN line no := 0
+ FI;
+ IF is getcharety (esc) (* bis einschl. 1.8.1: 'is incharety' *)
+ THEN terminal stop := TRUE
+ FI.
+END PROC println;
+
+PROC outline (TEXT CONST t) :
+ printline (t);
+ putline (actual line).
+
+ actual line :
+ IF LENGTH (t) > 78
+ THEN text (t, 78)
+ ELSE t
+ FI.
+END PROC outline;
+
+PROC printline (TEXT CONST t) :
+ IF protocoll
+ THEN putline (sysout, t)
+ FI
+END PROC print line;
+
+PROC sys page : (* Seitenvorschub auf Bildschirm und Datei *)
+ IF vdt on AND NOT is scroll AND is not first
+ THEN page
+ ELSE is not first := TRUE
+ FI;
+ IF protocoll
+ THEN putline (sysout, "#page#")
+ FI;
+ IF asterisk buffer <> ""
+ THEN page no INCR 1;
+ println ("PAGE " + text (page no, 3) + " : " + asterisk buffer);
+ FI;
+ line no := 0
+END PROC sys page;
+
+BOOL PROC pagefeed necessary :
+ line no = 0 (* Liefert TRUE, wenn Seitenende erreicht *)
+END PROC pagefeed necessary; (* ist *)
+
+PROC plot output (TEXT CONST t) :
+ println (t); (* Ausgabeprozedur fuer das Plot - Programm *)
+ print := FALSE
+END PROC plot output;
+
+BOOL PROC b stop request : (* Liefert TRUE, wenn 'End'-Kommando im VDT *)
+ terminal stop (* - Modus gegeben wird *)
+END PROC b stop request;
+
+BOOL PROC was print : (* Liefert TRUE, falls Druckerprogramm *)
+ print. (* vorher eine Zeile gedruckt hat *)
+END PROC was print;
+
+PROC vdt :
+ IF vdt on AND is not first (* VDT = Video Data Termination *)
+ THEN do vdt (* Verhindert Scrolling des Bildschirms *)
+ FI.
+
+ do vdt :
+ TEXT VAR t;
+ out ("TIPPEN SIE : '+'; 'o'; 'e' : ");
+ inchar (t);
+ out (t);
+ IF t = "+" (* '+' = Seitenvorschub *)
+ THEN
+ ELIF t = "o" (* 'o' = Off; VDT wird abgeschaltet *)
+ THEN vdt on := FALSE
+ ELIF t = "e" (* 'e' = End; Programm wird abgebrochen *)
+ THEN terminal stop := TRUE
+ ELSE out (""13""); vdt
+ FI;
+ line.
+END PROC vdt;
+
+PROC asterisk (TEXT CONST t) :
+ asterisk buffer := t
+END PROC asterisk;
+
+PROC out(TEXT CONST a,b,c) :
+ out(a);
+ out(b);
+ out(c)
+END PROC out;
+
+
+END PACKET rts;
+
diff --git a/dynamo/dyn.ruestungswettlauf b/dynamo/dyn.ruestungswettlauf
new file mode 100644
index 0000000..7b7c6b1
--- /dev/null
+++ b/dynamo/dyn.ruestungswettlauf
@@ -0,0 +1,32 @@
+note ruestungswettlauf nach richardson
+note
+note literatur: thiel "quantitaet oder begriff" S. 436 ff
+note
+l eigenkriegspot.k=eigenkriegspot.j+dt*
+x (k*gegenkriegspot.j-a*eigenkriegspot.j+g)
+l gegenkriegspot.k=gegenkriegspot.j+dt*
+x (l*eigenkriegspot.j-b*gegenkriegspot.j+h)
+note
+note anfangswerte fuer eigenkriegspotential und gegenkriegspotential
+note werden am gleichgewichtspunkt plus etwas mehrpot gegeben
+note
+n eigenkriegspot=(k*h+b*g)/(a*b-k*l)+mehrpot
+n gegenkriegspot=(l*g+a*h)/(a*b-k*l)
+note
+note konstanten
+note
+c k=2 verteidigungskoeffizient
+c l=1 " des gegners
+c a=2 koeffizient fuer aufwand zur kriegsvorbereitung
+c b=3 "
+c g=7 koeffizient fuer aggressive absichten
+c h=9 "
+c mehrpot=3 stoerung des gleichgewichts durch mehr potential
+plot eigenkriegspot=e,gegenkriegspot=g(unten,oben)
+c dt=0.5
+c length=2050
+n time=1985
+c pltper=1
+c unten=-11
+c oben=250
+
diff --git a/dynamo/dyn.simon b/dynamo/dyn.simon
new file mode 100644
index 0000000..b911159
--- /dev/null
+++ b/dynamo/dyn.simon
@@ -0,0 +1,28 @@
+NOTE Simons MODELL der sozialen Gruppe Stand: 08.03.1983
+NOTE
+A INTERAKT.K=A1*FREUNDLICH.K+A2*AKTIV.K
+L FREUNDLICH.K=FREUNDLICH.J+DT*(B1*(INTERAKT.J-beta*FREUNDLICH.J))
+L AKTIV.K=AKTIV.J+DT*(C1*(FREUNDLICH.J-gamma*AKTIV.J)+C2*(EINF-AKTIV.J))
+N INTERAKT=beta*A2*C2*EINF/NENNER
+N AKTIV=C2*(beta-A1)*EINF/NENNER
+N FREUNDLICH=A2*C2*EINF/NENNER+STOERTERM
+N NENNER=-C1*A2+(beta-A1)*(C2+C1*gamma)
+C STOERTERM=0.4
+C EINF=2
+NOTE
+NOTE Konstanten sind alle positiv vorausgesetzt
+NOTE Stabil fuer beta>a1
+C A1=1.0
+C A2=1.5
+C B1=1
+C beta=1.0
+C C1=1.4
+C C2=1.5
+C gamma=1.5
+C DT=0.1
+C LENGTH=60
+C PLTPER=0.5
+PLOT INTERAKT=i,FREUNDLICH=f,AKTIV=a(-10,10)
+PRINT INTERAKT,FREUNDLICH,AKTIV
+C PRTPER=0.5
+
diff --git a/dynamo/dyn.std b/dynamo/dyn.std
new file mode 100644
index 0000000..a87b66d
--- /dev/null
+++ b/dynamo/dyn.std
@@ -0,0 +1,9 @@
+abs r arctan r arctand r cos r cosd r exp r floor r frac r
+initializerandom r random r
+ln r log2 r log10 r
+max rr min rr
+power rr round r
+sin r sind r sqrt r tan r tand r
+clip rrrr fifge rrrr switch rrr fifze rrr noise r normrn rr pulse rrr
+ramp rr sclprd trrtr step rr sumv trr sum t table trrrr tabhl trrrr /*
+
diff --git a/dynamo/dyn.steifedgl b/dynamo/dyn.steifedgl
new file mode 100644
index 0000000..b168fcd
--- /dev/null
+++ b/dynamo/dyn.steifedgl
@@ -0,0 +1,15 @@
+NOTE STIFF EQUATIONS SIEHE: SIMULATION AUGUST 1980, SEITE 38
+L Y1.K=Y1.J+DT*(-21*Y1.J+19*Y2.J-20*Y3.J)
+L Y2.K=Y2.J+DT*(+19*Y1.J-21*Y2.J+20*Y3.J)
+L Y3.K=Y3.J+DT*(+40*Y1.J-40*Y2.J-40*Y3.J)
+N Y1=1
+N Y2=0
+N Y3=-1
+NOTE KONSTANTEN MUESSEN GEEIGNET GEWAEHLT WERDEN: DT SEHR KLEIN
+C LENGTH=20
+C DT=.01
+C PRTPER=1
+C PLTPER=1
+PRINT Y1,Y2,Y3
+PLOT Y1,Y2,Y3
+
diff --git a/dynamo/dyn.tool b/dynamo/dyn.tool
new file mode 100644
index 0000000..65769d8
--- /dev/null
+++ b/dynamo/dyn.tool
@@ -0,0 +1,217 @@
+PACKET io handling DEFINES error listing, err, message, errors, init errors,
+ text, kill, trunc, hash, no errors :
+(* Autor : R. Keil, Version vom 22.07.83, Änderung: C. Szymanski, 21.07.88 *)
+
+LET errmax = 67,
+ max hash size = 300;
+
+ROW errmax TEXT VAR error;
+FILE VAR listfile; (* -> VERSION 3.2 *)
+BOOL VAR list;
+INT VAR errorno, i;
+
+PROC init errors (TEXT CONST fname) :
+ FILE VAR errorfile := sequential file (input, fname);
+ TEXT VAR buffer;
+ FOR i FROM 1 UPTO errmax WHILE NOT eof (errorfile) REP
+ getline (errorfile, buffer);
+ error (i) := buffer
+ END REP
+END PROC init errors;
+
+PROC init errors :
+ errorno := 0
+END PROC init errors;
+
+PROC error listing (TEXT CONST listname) :
+ list := listname <> "nolist";
+ IF list
+ THEN kill (listname);
+ listfile := sequential file (output, listname)
+ FI
+END PROC error listing;
+
+INT PROC errors :
+ error no
+END PROC errors;
+
+PROC err (TEXT CONST s, INT CONST m, line no) :
+ message ("Fehler in Zeile " + text (line no) + " bei >>" + s + "<< : "
+ + error (m));
+ errorno INCR 1
+END PROC err;
+
+BOOL PROC no errors :
+ IF errors = 0
+ THEN TRUE
+ ELSE display (text (error no) + " Fehler gefunden"13""10""); FALSE
+ FI
+END PROC no errors;
+
+PROC message (TEXT CONST m) :
+ IF list
+ THEN putline (list file, m);
+ FI;
+ note (m); (* C.S. 21.07.88 *)
+ note line;
+ display (m);
+ display (""13""10"")
+END PROC message;
+
+TEXT PROC text (BOOL CONST b) :
+ IF b
+ THEN "TRUE"
+ ELSE "FALSE"
+ FI
+END PROC text;
+
+PROC kill (TEXT CONST file name) :
+ command dialogue (FALSE);
+ forget (file name);
+ command dialogue (TRUE)
+END PROC kill;
+
+TEXT PROC trunc (TEXT CONST t) :
+ text (t, length (t) - 2)
+END PROC trunc;
+
+INT PROC hash (TEXT CONST word) :
+ INT VAR qs := 0;
+ FOR i FROM 1 UPTO length (word) REP
+ qs INCR code (word SUB i)
+ END REP;
+ (qs MOD max hash size) + 1.
+END PROC hash
+
+END PACKET io handling;
+
+
+(************************* S C A N N E R **************************)
+
+PACKET scan DEFINES next sym, scanner, scanpos :
+
+
+LET bold = 1, (* Autor : R. Keil, T. Froehlich *)
+ number = 2, (* Version vom 04.07.83 *)
+ delimiter = 3,
+ eol = 4;
+
+TEXT VAR main buf, sym;
+INT VAR position, type, cc, begin pos;
+
+PROC nextsym (TEXT CONST buf, TEXT VAR scan sym,
+ INT VAR scan type, pos) :
+ TEXT VAR char := buf SUB pos;
+ cc := code (char);
+ IF (cc >= 97 AND cc <= 122)
+ THEN process lower case
+ ELIF cc = 46 OR is int
+ THEN process real
+ ELIF (cc >= 65 AND cc <= 90)
+ THEN process upper case
+ ELSE process delimiter
+ FI.
+
+ process upper case :
+ scan type := bold;
+ scan sym := low;
+ next char;
+ WHILE (cc >= 65 AND cc <= 90) OR is int REP
+ scan sym CAT low;
+ next char
+ END REP.
+
+ process lower case :
+ scan type := bold;
+ begin pos := pos;
+ REP
+ next char
+ UNTIL lower case char AND NOT is int END REP;
+ scan sym := subtext (buf, begin pos, pos - 1).
+
+ lower case char :
+ cc < 97 OR cc > 122.
+
+ process real :
+ process base;
+ process exponent;
+ scan type := number.
+
+ process base :
+ IF cc = 46
+ THEN next char;
+ IF is int
+ THEN scan sym := "0.";
+ process int
+ ELSE scan type := delimiter;
+ scan sym := ".";
+ LEAVE process real
+ FI
+ ELSE scan sym := "";
+ process int;
+ IF cc = 46
+ THEN scan sym CAT char;
+ next char;
+ IF is int
+ THEN process int
+ ELSE scan sym CAT "0"
+ FI
+ ELSE scan sym CAT ".0"
+ FI
+ FI.
+
+ process exponent :
+ IF cc = 69 OR cc = 101
+ THEN scan sym CAT "e";
+ next char;
+ IF cc = 43 OR cc = 45
+ THEN scan sym CAT char; next char
+ FI;
+ IF is int
+ THEN process int
+ ELSE err (char, 63, 0)
+ FI
+ FI.
+
+ process int :
+ WHILE is int REP
+ scan sym CAT char;
+ next char
+ END REP.
+
+is int :
+ cc >= 48 AND cc <= 57.
+
+ process delimiter :
+ IF cc = -1
+ THEN scan sym := "EOL"; scan type := eol
+ ELSE scan type := delimiter;
+ scan sym := char
+ FI;
+ pos INCR 1.
+
+ next char :
+ pos INCR 1; char := buf SUB pos; cc := code (char).
+
+ low :
+ IF cc >= 65 AND cc <= 90
+ THEN code (cc + 32)
+ ELSE char
+ FI.
+END PROC next sym;
+
+PROC scanner (TEXT CONST buf) :
+ main buf := buf; position := 1
+END PROC scanner;
+
+PROC next sym (TEXT VAR sym, INT VAR type) :
+ next sym (main buf, sym, type, position)
+END PROC next sym;
+
+INT PROC scanpos :
+ position
+END PROC scanpos
+
+END PACKET scan
+
+
diff --git a/dynamo/dyn.vec b/dynamo/dyn.vec
new file mode 100644
index 0000000..0554215
--- /dev/null
+++ b/dynamo/dyn.vec
@@ -0,0 +1,209 @@
+PACKET vector DEFINES TAB, :=, vector, (* Autor : H.Indenbirken *)
+ SUB, LENGTH, laenge, norm, (* Stand : 24.09.81 *)
+ nilvector, replace, =, <>, wert,
+ +, -, *, /,
+ get, put :
+
+LET n = 4000;
+
+TYPE TAB = STRUCT (INT lng, TEXT elem);
+TYPE INITTAB = STRUCT (INT lng, REAL value);
+
+INT VAR i;
+TEXT VAR t :: "12345678";
+TAB VAR v :: nilvector;
+
+
+REAL PROC wert (TAB CONST t, INT CONST i) :
+ t SUB i
+END PROC wert;
+
+OP := (TAB VAR l, TAB CONST r) :
+ l.lng := r.lng;
+ l.elem := r.elem
+
+END OP :=;
+
+OP := (TAB VAR l, INITTAB CONST r) :
+ l.lng := r.lng;
+ replace (t, 1, r.value);
+ l.elem := r.lng * t
+
+END OP :=;
+
+INITTAB PROC nilvector :
+ vector (1, 0.0)
+
+END PROC nilvector;
+
+INITTAB PROC vector (INT CONST lng, REAL CONST value) :
+ IF lng <= 0
+ THEN errorstop ("PROC vector : lng <= 0") FI;
+ INITTAB : (lng, value)
+
+END PROC vector;
+
+INITTAB PROC vector (INT CONST lng) :
+ vector (lng, 0.0)
+
+END PROC vector;
+
+REAL OP SUB (TAB CONST v, INT CONST i) :
+ test ("REAL OP SUB : ", v, i);
+ v.elem RSUB i
+
+END OP SUB;
+
+INT OP LENGTH (TAB CONST v) :
+ v.lng
+
+END OP LENGTH;
+
+INT PROC laenge (TAB CONST v) :
+ v.lng
+
+END PROC laenge;
+
+REAL PROC norm (TAB CONST v) :
+ REAL VAR result :: 0.0;
+ FOR i FROM 1 UPTO v.lng
+ REP result INCR ((v.elem RSUB i)**2) PER;
+ sqrt (result) .
+
+END PROC norm;
+
+PROC replace (TAB VAR v, INT CONST i, REAL CONST r) :
+ test ("PROC replace : ", v, i);
+ replace (v.elem, i, r)
+
+END PROC replace;
+
+BOOL OP = (TAB CONST l, r) :
+ l.elem = r.elem
+END OP =;
+
+BOOL OP <> (TAB CONST l, r) :
+ l.elem <> r.elem
+END OP <>;
+
+TAB OP + (TAB CONST v) :
+ v
+END OP +;
+
+TAB OP + (TAB CONST l, r) :
+ test ("TAB OP + : ", l, r);
+ v := l;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, (l.elem RSUB i) + (r.elem RSUB i)) PER;
+ v
+
+END OP +;
+
+TAB OP - (TAB CONST a) :
+ v := a;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, - (a.elem RSUB i)) PER;
+ v
+
+END OP -;
+
+TAB OP - (TAB CONST l, r) :
+ test ("TAB OP - : ", l, r);
+ v := l;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, (l.elem RSUB i) - (r.elem RSUB i)) PER;
+ v
+END OP -;
+
+REAL OP * (TAB CONST l, r) :
+ test ("REAL OP * : ", l, r);
+ REAL VAR x :: 0.0;
+ FOR i FROM 1 UPTO l.lng
+ REP x INCR ((l.elem RSUB i) * (r.elem RSUB i)) PER;
+ x
+
+END OP *;
+
+TAB OP * (TAB CONST v, REAL CONST r) :
+ r*v
+
+END OP *;
+
+TAB OP * (REAL CONST r, TAB CONST a) :
+ v := a;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, r*(a.elem RSUB i)) PER;
+ v
+
+END OP *;
+
+TAB OP / (TAB CONST a, REAL CONST r) :
+ v := a;
+ FOR i FROM 1 UPTO v.lng
+ REP replace (v.elem, i, (a.elem RSUB i)/r) PER;
+ v
+
+END OP /;
+
+TEXT VAR error :: "";
+PROC test (TEXT CONST proc, TAB CONST v, INT CONST i) :
+ IF i > v.lng
+ THEN error := proc;
+ error CAT "subscript overflow (LENGTH v=";
+ error CAT text (v.lng);
+ error CAT ", i=";
+ error CAT text (i);
+ error CAT ")";
+ errorstop (error)
+ ELIF i < 1
+ THEN error := proc;
+ error CAT "subscript underflow (i = ";
+ error CAT text (i);
+ error CAT ")";
+ errorstop (error)
+ FI .
+
+END PROC test;
+
+PROC test (TEXT CONST proc, TAB CONST a, b) :
+ IF a.lng <> b.lng
+ THEN error := proc;
+ error CAT "LENGTH a (";
+ IF a.lng <= 0
+ THEN error CAT "undefined"
+ ELSE error CAT text (a.lng) FI;
+ error CAT ") <> LENGTH b (";
+ error CAT text (b.lng);
+ error CAT ")";
+ errorstop (error)
+ FI
+
+END PROC test;
+
+PROC get (TAB VAR v, INT CONST lng) :
+ v.lng := lng;
+ v.elem := lng * "12345678";
+ REAL VAR x;
+ FOR i FROM 1 UPTO lng
+ REP get (x);
+ replace (v.elem, i, x)
+ PER .
+
+END PROC get;
+
+PROC put (TAB CONST v, INT CONST laenge, fracs) :
+ FOR i FROM 1 UPTO v.lng
+ REP put (text (v.elem RSUB i, laenge, fracs)) PER
+
+END PROC put;
+
+PROC put (TAB CONST v) :
+ FOR i FROM 1 UPTO v.lng
+ REP put (text (v.elem RSUB i)) PER
+
+END PROC put;
+
+END PACKET vector;
+
+
+
diff --git a/dynamo/dyn.wachstum b/dynamo/dyn.wachstum
new file mode 100644
index 0000000..9f97bb9
--- /dev/null
+++ b/dynamo/dyn.wachstum
@@ -0,0 +1,19 @@
+NOTE
+NOTE Ein einfaches Modell des Bevoelkerungswachstums
+NOTE
+L BEVOELKERUNG.K=BEVOELKERUNG.J+DT*GEBURTENRATE.JK
+N BEVOELKERUNG=ANFANGSBEVOELKERUNG
+C ANFANGSBEVOELKERUNG=1000
+R GEBURTENRATE.KL=BEVOELKERUNG.K*WACHSTUMSFAKTOR
+N GEBURTENRATE=10
+C WACHSTUMSFAKTOR=0.03 das heisst: 3 Prozent
+NOTE
+NOTE Simulationsparameter
+NOTE
+PLOT BEVOELKERUNG=B(1E3,9E4)/GEBURTENRATE=G(10,9E3)
+C DT=1
+C PLTPER=5
+C LENGTH=300
+
+
+
diff --git a/dynamo/dyn.wasseröko b/dynamo/dyn.wasseröko
new file mode 100644
index 0000000..fe05881
--- /dev/null
+++ b/dynamo/dyn.wasseröko
@@ -0,0 +1,64 @@
+n t=15
+note*** wasserökosystem nach abel und reich
+note*** in: microextra 4/83 seite 34 ff
+note************************************************************************
+note* hilfsgleichung fuer temperatur t
+note* die zeit time in wochen
+
+a t.k=15+4*sin((time.k-10)*2*pi/52) temperatur t; time in wochen
+c pi=3.1415
+note gleichung fuer phytoplankton p
+
+l p.k=p.j+dt*(p.j*(p1*n.j*t.j-p2*z.j)(100-p.j)/100) phytoplankton p
+note gleichung fuer zooplankton z
+
+l z.k=z.j+dt*(z.j*(p3*t.j*p.j+p4*n.j-(p5*f.j+p6*b.j)-1/p.j)(30-z.j)/30)
+note gleichung fuer fische f
+l f.k=f.j+dt*(f.j*(p7*z.j-p8*b.j-p9/(z.j+p.j))(10-f.j)/10)
+
+note gleichung fuer raubfisch barsch b
+
+l b.k=b.j+dt*(b.j*(p10*f.j+p11*z.j-1/(p12*f.j))(0.1-b.j)/0.1)
+
+note **** gleichung fuer naehrstoffmenge n
+
+l n.k=n.j+dt*(p13-n.j*(p14*p.j-p15*z.j))
+note **** anfangswerte ****************************************************
+n p=p0
+n z=z0
+n f=f0
+n b=b0
+n n=n0
+c p0=10
+c z0=3
+c f0=1
+c b0=0.01
+c n0=30 in kg/volumeneinheit bzw. Stück/volumeneinhe�[
+note ***** konstanten ********************************************************
+c p1=0.006
+c p2=1
+c p3=0.006
+c p4=0.03
+c p5=1
+c p6=100
+c p7=0.33
+c p8=100
+c p9=1E-4
+c p10=1
+c p11=1
+c p12=0.25
+c p13=10
+c p14=0.1
+c p15=0.2
+note **** simulationskonstanten *********************************************
+c dt=0.5
+c length=60
+c pltper=1
+note***** outputvariablen****************************************************
+a lp.k=ln(p.k/p0)
+a lz.k=ln(z.k/z0)
+a lf.k=ln(f.k/f0)
+a lb.k=ln(b.k/b0)
+a logn.k=ln(n.k/n0)
+plot lp=p,lz=z,lf=f,lb=b,logn=n(-4,4)
+
diff --git a/dynamo/dyn.welt-forrester b/dynamo/dyn.welt-forrester
new file mode 100644
index 0000000..c3f9789
--- /dev/null
+++ b/dynamo/dyn.welt-forrester
@@ -0,0 +1,124 @@
+note weltmodell in der form fuer eumel dynamo 17.7.1987
+* WORLD DYNAMICS W5
+L p.k=p.j+(dt)*(br.jk-dr.jk)
+N p=pi
+C pi=1.65e9
+R br.kl=(p.k)*(clip(brn,brn1,swt1,time.k))*(brfm.k)*(brmm.k)
+X *(brcm.k)*(brpm.k)
+C brn=.04
+C brn1=.04
+C swt1=1970
+A brmm.k=tabhl(brmmt,msl.k,0,5,1)
+T brmmt=1.2/1/.85/.75/.77/.7
+A msl.k=ecir.k/(ecirn)
+C ecirn=1
+A ecir.k=(cir.k)*(1-ciaf.k)*(nrem.k)/(1-ciafn)
+A nrem.k=table(nremt,nrfr.k,0,1,.25)
+T nremt=0/.15/.5/.85/1
+A nrfr.k=nr.k/nri
+L nr.k=nr.j+(dt)*(-nrur.jk)
+N nr=nri
+C nri=900e9
+R nrur.kl=(p.k)*(clip(nrun,nrun1,swt2,time.k))*(nrmm.k)
+C nrun=1
+C nrun1=1
+C swt2=1970
+NOTE equation 42 connects here from eq. 4 to eq.9
+R dr.kl=(p.k)*(clip(drn,drn1,swt3,time.k))*(drmm.k)*(drpm.k)
+X *(drfm.k)*(drcm.k)
+C drn=.028
+C drn1=.028
+C swt3=1970
+A drmm.k=tabhl(drmmt,msl.k,0,5,.5)
+T drmmt=3/1.8/.8/.7/.6/.53/.5/.5/.5/.5
+A drpm.k=table(drpmt,polr.k,0,60,10)
+T drpmt=.92/1.3/2/3.2/4.8/6.8/9.2
+A drfm.k=tabhl(drfmt,fr.k,0,2,.25)
+T drfmt=30/3/2/1.4/1/.7/.6/.5/.5
+A drcm.k=table(drcmt,cr.k,0,5,1)
+T drcmt=.9/1/1.2/1.5/1.9/3
+A cr.k=(p.k)/(la*pdn)
+C la=135e6
+C pdn=26.5
+A brcm.k=table(brcmt,cr.k,0,5,1)
+T brcmt=1.05/1/.9/.7/.6/.55 <
+A brfm.k=tabhl(brfmt,fr.k,0,4,1)
+T brfmt=0/1/1.6/1.9/2
+A brpm.k=table(brpmt,polr.k,0,60,10)
+T brpmt=1.02/.9/.7/.4/.25/.15/.1
+A fr.k=(fpci.k)*(fcm.k)*(fpm.k)*(clip(fc,fc1,swt7,time.k))/fn
+C fc=1
+C fc1=1
+C fn=1
+C swt7=1970
+A fcm.k=table(fcmt,cr.k,0,5,1)
+T fcmt=2.4/.6/.4/.3/.2
+A fpci.k=tabhl(fpcit,cira.k,0,6,1)
+T fpcit=.5/1/1.4/1.7/1.9/2.05/2.2
+A cira.k=(cir.k)*(ciaf.k)/ciafn
+C ciafn=.3
+A cir.k=(ci.k/p.k)
+L ci.k=ci.j+(dt)*(cig.jk-cid.jk)
+N ci=cii
+C cii=.4e9
+R cig.kl=(p.k)*(cim.k)*(clip(cign,cign1,swt4,time.k))
+C cign=.05
+C cign1=.05
+C swt4=1970
+A cim.k=tabhl(cimt,msl.k,0,5,1)
+T cimt=.1/1/1.8/2.4/2.8/3
+R cid.kl=(ci.k)*(clip(cidn,cidn1,swt5,time.k))
+C cidn=.025
+C cidn1=.025
+C swt5=1970
+A fpm.k=table(fpmt,polr.k,0,60,10)
+T fpmt=1.02/.9/.65/.35/.2/.1/.05
+A polr.k=pol.k/pols
+C pols=3.6e9
+L pol.k=pol.j+(dt)*(polg.jk-pola.jk)
+N pol=poli
+C poli=.2e9
+R polg.kl=(p.k)*(clip(poln,poln1,swt6,time.k))*(polcm.k)
+C poln=1
+C poln1=1
+C swt6=1970
+A polcm.k=tabhl(polcmt,cir.k,0,5,1)
+T polcmt=.05/1/3/5.4/7.4/8
+R pola.kl=pol.k/polat.k
+A polat.k=table(polatt,polr.k,0,60,10)
+T polatt=.6/2.5/8/11.5/15.5/20
+L ciaf.k=ciaf.j+(dt/ciaft)*((cfifr.j*ciqr.j)-ciaf.j)
+N ciaf=ciaf1
+C ciaf1=.2
+C ciaft=15
+A cfifr.k=tabhl(cfifrt,fr.k,0,2,.5)
+T cfifrt=1/.6/.3/.15/.1
+A ql.k=(qls)*(qlm.k)*(qlc.k)*(qlf.k)*(qlp.k)
+C qls=1
+A qlm.k=tabhl(qlmt,msl.k,0,5,1)
+T qlmt=.2/1/1.7/2.3/2.7/2.9
+A qlc.k=table(qlct,cr.k,0,5,.5)
+T qlct=2/1.3/1/.75/.55/.45/.38/.3/.25/.22/.2
+A qlf.k=tabhl(qlft,fr.k,0,4,1)
+T qlft=0/1/1.8/2.4/2.7
+A qlp.k=table(qlpt,polr.k,0,60,10)
+T qlpt=1.04/.85/.6/.3/.15/.05/.02
+NOTE equation 42 located between eq. 4 and 9.
+A nrmm.k=tabhl(nrmmt,msl.k,0,10,1)
+T nrmmt=0/1/1.8/2.4/2.9/3.3/3.6/3.8/3.9/3.95/4
+NOTE input from eqn. 38 and 40 to eqn. 35
+A ciqr.k=tabhl(ciqrt,qlm.k/qlf.k,0,2,.5)
+T ciqrt=.7/.8/1/1.5/2
+NOTE
+NOTE control cards
+NOTE
+C dt=.1
+C length=2100
+N time=1900
+C prtper=4
+C pltper=4
+PLOT p=p(0,8e9)/polr=2(0,40)/ci=c(0,20e9)/ql=q(0,2)/nr=n(0,1e12)
+note PLOT fr=f,msl=m,qlc=4,qlp=5(0,2)/ciaf=a(.2,.6)
+PRINT p,nr,ci,pol,ciaf
+
+
diff --git a/dynamo/dyn.wohnen b/dynamo/dyn.wohnen
new file mode 100644
index 0000000..4e9b8b4
--- /dev/null
+++ b/dynamo/dyn.wohnen
@@ -0,0 +1,105 @@
+note modell des wohnbaus in einer stadt
+note
+note siehe Goodman: Study Notes in System Dynamics, Seite 332 ff
+note
+note Bevölkerungs-Sektor
+note
+L pop.k=pop.j+dt*(imr.jk-omr.jk-ndr.jk)
+N pop=popi
+C popi=30.3
+note
+note pop population (people)
+note popi population initial value
+note imr immigration rate (people/year)
+note omr out-migration rate(people/year)
+note
+R imr.kl=nim*ammp.k*pop.k
+C nim=.145
+note
+note nim normal immigration (fraction/year)
+note ammp attractiveness for migration multiplier perceived (dimensionless)
+note
+A ammp.k=smooth(amm.k,mpt)
+C mpt=5
+note
+note amm attractiveness for migration multiplier (dimensionless)
+note mpt migrant perception time (years)
+note
+A amm.k=table(ammt,hr.k,0,2,.25)
+T ammt=.05/.1/.2/.4/1/1.6/1.8/1.9/2
+note
+note ammt attractiveness for migration multiplier table
+note hr housing ratio (dimensionless)
+note
+A dmm.k=1/amm.k
+note
+note dmm departure migration multiplier (dimensionless)
+note
+R omr.kl=nom*dmm.k*pop.k
+C nom=.02
+note
+note nom normal out migration (fraction/year)
+note
+R ndr.kl=pop.k*drf
+C drf=.025
+note
+note ndr net death rate (people/year)
+note drf death rate factor (fraction/year)
+note*************************************************************************
+note housing sector
+note*************************************************************************
+note
+L h.k=h.j+dt*(hcr.jk-hdr.jk)
+N h=hi
+c hi=10
+note
+note h housing (units)
+note hcr housing construction rate (units/year)
+note hdr housing demolition rate (units/year)
+note hi initial value of houses (units)
+note
+R hcr.kl=nhc*hcm.k*lam.k*h.k
+C nhc=.12
+note
+note nhc normal housing construction (fraction/year)
+note hcm housing construction multiplier (dimensionless)
+note lam land availability multiplier (dimensionless)
+note
+A hcm.k=table(hcmt,hr.k,0,2,.25)
+T hcmt=2.5/2.4/2.3/2/1/.37/.2/.1/.05
+note
+A hr.k=h.k/hd.k
+note
+note hr housing ratio(dimensionless)
+note hd housing desired (units)
+note
+A hd.k=pop.k*upp
+C upp=.33
+note
+note upp units per person (unit/person)
+note
+A lam.k=table(lamt,lfo.k,0,1,.25)
+T lamt=1/.8/.5/.2/0
+note
+note lfo land fraction occupied (dimensionless)
+note
+A lfo.k=H.k*lpu/land
+C lpu=1
+C land=1500
+note
+note lpu land per unit(acres/unit)
+note land (acres)
+note
+R hdr.kl=h.k/alth
+C alth=50
+note
+note alth average lifetime of housing (years)
+note***********************************************************************
+note control statements
+note***********************************************************************
+note
+plot h=h(0,2000)/pop=p(0,8000)/hcr=c,hdr=d(0,100)
+C dt=1
+C length=200
+C pltper=2
+
diff --git a/dynamo/dyn.workfluc b/dynamo/dyn.workfluc
new file mode 100644
index 0000000..8016449
--- /dev/null
+++ b/dynamo/dyn.workfluc
@@ -0,0 +1,44 @@
+NOTE
+NOTE *******************************************************************
+NOTE MODEL OF WORKLOAD FLUCTUATIONS
+NOTE *******************************************************************
+NOTE JOHN HENIZE 5.11.81
+NOTE *******************************************************************
+NOTE
+L MM.K=MM.J+(DT)*(-MTR.J) MANPOWER IN MARKETING
+N MM=4 MEN
+L MP.K=MP.J+(DT)*(MTR.J) MANPOWER IN PRODUCTION
+N MP=6 MEN
+NOTE
+L JIP.K=JIP.J+(DT)*(JS.J-JC.J) JOBS_IN_PROCESS
+N JIP=6 JOBS
+A JM.K=MM.K/MEJ JOBS MARKETED
+C MEJ=2 MAN_MONTHS/JOB MARKETING EFFORT PER JOB
+L JS.K=JS.J+(DT/SD)*(JM.J-JS.J) JOBS SOLD
+N JS=JM
+C SD=2 MONTH SALES DELAY
+A JC.K=MP.K/AJS JOBS COMPLETED
+C AJS=8 MAN_MONTH/JOB
+NOTE
+A MTR.K=(BA.K+PMA.K)*MTC.K MANPOWER TRANSFER RATE
+A BA.K=MMJ*(JIP.K-DJIP) BACKLOG ADJUSTMENT
+C DJIP=6 JOBS DESIRED JOBS IN PROCESS
+C MMJ=.15 MEN PER MONTH PER JOB MEN REALLOCATED PER MONTH PER
+NOTE
+A MTC.K=CLIP(MMC.K,PMC.K,BA.K,0) MANPOWER TRANSFER CONSTRAINT
+A MMC.K=MMR.K MARKETING MANPOWER CONSTRAINT
+A MMR.K=MM.K/(MM.K+MP.K) MARKETING MANPOWER RATIO
+A PMC.K=PMR.K*PMR.K PRODUCTION MANPOWER CONSTRAINT
+A PMR.K=MP.K/(MM.K+MP.K) PRODUCTION MANPOWER RATIO
+NOTE
+A PMA.K=SWITCH(0,PMA1.K,SW) PRODUCTION MANPOWER ADJUSTMENT
+C SW=0
+A PMA1.K=(DMP.K-MP.K)/MAT
+A DMP.K=JS.K*AJS DESIRED MANPOWER IN PRODUCTION
+C MAT=10 MONTHS MANPOWER ADJUSTMENT TIME
+NOTE
+C DT=.2
+C LENGTH=120
+C PLTPER=6
+PLOT MM=M,MP=P(0,10)/JIP=J(0,20)
+
diff --git a/dynamo/dyn.wurzel b/dynamo/dyn.wurzel
new file mode 100644
index 0000000..7f8e6e0
--- /dev/null
+++ b/dynamo/dyn.wurzel
@@ -0,0 +1,14 @@
+note theon von smyrnas verfahren
+note
+l uj.k=u.j
+l u.k=u.j+2*v.j
+l v.k=v.j+uj.j
+n uj=1
+n u=1
+n v=1
+a wurzelzwei.k=u.k/v.k
+print u,v,wurzelzwei
+c dt=1
+c length=20
+c prtper=1
+
diff --git a/dynamo/out.world b/dynamo/out.world
new file mode 100644
index 0000000..39859ce
--- /dev/null
+++ b/dynamo/out.world
@@ -0,0 +1,43 @@
+PAGE 1 : WORLD DYNAMICS W5
+P=P(0,8E9)/POLR=2(0,40)/CI=C(0,20E9)/QL=Q(0,2)/NR=N(0,1000E9)
+ 0.0 2.000000e9 4.000000e9 6.000000e9 8.000000e9p
+ 0.0 10. 20. 30. 40.2
+ 0.0 5.000000e9 1.000000e10 1.500000e10 2.000000e10c
+ 0.0 .5 1. 1.5 2.q
+ 0.0 2.500000e11 5.000000e11 7.500000e11 1.000000e12n
+1900. 2c________p__.__q_________.____________._______n____.
+1902. 2c p . q . . n .
+1908. 2c p . q . . n .
+1914. 2c p . q . . n .
+1920. 2 c p. q . . n .
+1926. 2_c__________p____________q____________.______n_____.
+1932. 2 c .p .q . n .
+1938. 2 c . p .q . n .
+1944. 2 c . p . q . n .
+1950. 2 c . p Ω§Ω§ . n .
+1956. 2______c_____.______p_____.q___________.___n________.
+1962. 2 c . p q . n .
+1968. 2 c . p q. . n .
+1974. .2 c . p. .n .q
+1980. .2 c. q.p n .
+1986. .2___________.c_________q_.__p_______n_.____________.
+1992. . 2 . c q . p n . .
+1998. . 2 . c q . p n . .
+2004. .__2_________.____c_q_____._____np_____.____________.
+2010. . 2 . c . n p . .q
+2016. . 2 . q c . n p . .
+2022. . 2 . q c . n p . .
+2028. . 2 . q c n p . .
+2034. ._____2______.___q____c_n_._______p____.____________.
+2040. . 2 . q cn . p . .
+2046. . 2 . q c . p . .n
+2052. . 2 . q nc . p . .
+2058. . 2 . q n c . p . .
+2064. ._____2______.__q_n__c____.__p_________.____________.
+2070. . 2 . q n c . p . .
+2076. . 2 . qn c .p . .
+2082. . 2 . qn c .p . .
+2088. . 2 . q c p . .n
+2094. .__2_________.qnc________p.____________.____________.
+2100. . 2 .qc p . . .n
+
diff --git a/eudas/Adressen b/eudas/Adressen
new file mode 100644
index 0000000..74f0e3d
--- /dev/null
+++ b/eudas/Adressen
Binary files differ
diff --git a/eudas/dummy.text b/eudas/dummy.text
new file mode 100644
index 0000000..0eb03b0
--- /dev/null
+++ b/eudas/dummy.text
@@ -0,0 +1,14 @@
+PACKET dummy text DEFINES
+ lineform, pageform, autoform, autopageform :
+
+PROC lineform (TEXT CONST datei) : fehler END PROC lineform;
+PROC pageform (TEXT CONST datei) : fehler END PROC pageform;
+PROC autoform (TEXT CONST datei) : fehler END PROC autoform;
+PROC autopageform (TEXT CONST datei) : fehler END PROC autopageform;
+
+PROC fehler :
+ errorstop ("Keine Textverarbeitung installiert")
+END PROC fehler;
+
+END PACKET dummy text;
+
diff --git a/eudas/eudas.1 b/eudas/eudas.1
new file mode 100644
index 0000000..18607c4
--- /dev/null
+++ b/eudas/eudas.1
@@ -0,0 +1,52 @@
+PACKETeudassatzzugriffeDEFINES SATZ,:=,satzinitialisieren,felderzahl,feldlesen,feldbearbeiten,feldaendern,feldindex:LETb0=256,c0=2;LETd0=" ",e0="";LETf0=#101
+#" ist keine Feldnummer";TEXT VARg0:=c0*d0;TYPE SATZ=TEXT;OP:=(SATZ VARh0,SATZ CONSTi0):CONCR(h0):=CONCR(i0)END OP:=;PROCsatzinitialisieren(SATZ VARj0):satzinitialisieren(j0,0)END PROCsatzinitialisieren;PROCsatzinitialisieren(SATZ VARj0,INT CONSTk0):replace(g0,1,2*k0+3);INT VARl0;CONCR(j0):=e0;FORl0FROM1UPTOk0+1REP CONCR(j0)CATg0END REP END PROCsatzinitialisieren;INT PROCfelderzahl(SATZ CONSTj0):INT VARm0:=(CONCR(j0)ISUB1)DIV2;INT CONSTn0:=CONCR(j0)ISUBm0;REPm0DECR1UNTILm0<=0CORo0END REP;m0.o0:(CONCR(j0)ISUBm0)<>n0.END PROCfelderzahl;PROCfeldlesen(SATZ CONSTj0,INT CONSTp0,TEXT VARq0):r0(CONCR(j0),p0);IF NOTiserrorTHENq0:=subtext(CONCR(j0),s0,t0)END IF END PROCfeldlesen;PROCfeldbearbeiten(SATZ CONSTj0,INT CONSTp0,PROC(TEXT CONST,INT CONST,INT CONST)u0):r0(CONCR(j0),p0);IF NOTiserrorTHENu0(CONCR(j0),s0,t0)END IF END PROCfeldbearbeiten;INT VARs0,t0;PROCr0(TEXT CONSTj0,INT CONSTp0):IFv0THENerrorstop(text(p0)+f0)ELIFw0THENs0:=j0ISUBp0;t0:=(j0ISUBp0+1)-1ELSEs0:=1;t0:=0END IF.v0:p0<=0ORp0>b0.
+w0:p0+p0<(j0ISUB1)-1.END PROCr0;TEXT VARx0;PROCfeldaendern(SATZ VARj0,INT CONSTp0,TEXT CONSTq0):INT VARy0;INT CONSTz0:=((CONCR(j0)ISUB1)-2)DIV2;IFa1THENb1ELSEerrorstop(text(p0)+f0)END IF.a1:p0>0ANDp0<=b0.b1:INT CONSTc1:=p0-z0;IFc1<=0THENd1ELIFq0<>e0THENe1END IF.e1:INT CONSTf1:=CONCR(j0)ISUB(z0+1);x0:=subtext(CONCR(j0),g1,f1-1);CONCR(j0):=subtext(CONCR(j0),1,z0+z0);h1(CONCR(j0),1,z0,i1);j1;k1;CONCR(j0)CATx0;CONCR(j0)CATq0.i1:c1+c1.j1:INT CONSTl1:=f1+i1;FORy0FROMz0+1UPTOp0REPm1(CONCR(j0),l1)END REP.k1:m1(CONCR(j0),l1+length(q0)).g1:CONCR(j0)ISUB1.d1:INT CONSTs0:=CONCR(j0)ISUBp0,n1:=CONCR(j0)ISUB(p0+1);IFs0>length(CONCR(j0))THENo1ELSEp1END IF.o1:h1(CONCR(j0),p0+1,z0+1,length(q0));CONCR(j0)CATq0.p1:x0:=subtext(CONCR(j0),n1);CONCR(j0):=subtext(CONCR(j0),1,s0-1);h1(CONCR(j0),p0+1,z0+1,q1);CONCR(j0)CATq0;CONCR(j0)CATx0.q1:length(q0)-r1.r1:n1-s0.END PROCfeldaendern;PROCm1(TEXT VARj0,INT CONSTs1):replace(g0,1,s1);j0CATg0END PROCm1;PROCh1(TEXT VARj0,INT CONSTt1,u1,v1):INT VARy0;FORy0FROMt1UPTOu1
+REPreplace(j0,y0,w1+v1)END REP.w1:j0ISUBy0.END PROCh1;INT PROCfeldindex(SATZ CONSTj0,TEXT CONSTx1):INT VARt1:=(CONCR(j0)ISUB1)-1,y0:=1;REPt1:=pos(CONCR(j0),x1,t1+1);IFt1=0THEN LEAVEfeldindexWITH0END IF;y1UNTILz1CANDa2END REP;y0.y1:WHILE(CONCR(j0)ISUBy0)<t1REPy0INCR1END REP.z1:(CONCR(j0)ISUBy0)=t1.a2:(CONCR(j0)ISUB(y0+1))=t1+length(x1).END PROCfeldindex;END PACKETeudassatzzugriffe;
+PACKETeudasdateienDEFINES EUDAT,oeffne,satznr,dateiende,saetze,aufsatz,weiter,zurueck,satzlesen,satzaendern,satzloeschen,satzeinfuegen,feldlesen,feldaendern,feldbearbeiten,felderzahl,feldnamenlesen,feldnamenaendern,notizenlesen,notizenaendern,feldinfo,automatischerschluessel,dezimalkomma,wertberechnen,reorganisiere,sortiere,sortierreihenfolge,unsortiertesaetze:LETb0=531,c0=121,d0=5000,e0=3243,f0=64,g0=48;LET INTVEC=TEXT,INDEX=STRUCT(INTh0,i0,INTj0,k0,INTVECl0),EINTRAG=STRUCT(INTh0,i0,m0,n0,SATZo0),DATEI=STRUCT(INTfelderzahl,SATZp0,INTVECfeldinfo,TEXTq0,INTr0,s0,t0,INTu0,v0,INTw0,satznr,INTx0,y0,z0,INTa1,b1,ROW3TEXTc1,ROWb0INTd1,ROWc0INDEXindex,ROWd0EINTRAGe1);TYPE EUDAT=BOUND DATEI;LETf1="";LETg1=#201
+#"Datei ist keine EUDAS-Datei",h1=#202
+#"inkonsistente EUDAS-Datei",i1=#203
+#"EUDAS-Datei voll",j1=#204
+#"Nicht erlaubtes Dezimalkomma";TEXT VARk1;TEXT VARl1:=" ";INTVEC CONSTm1:=n1(f0,1);LETo1="";TEXT VARp1;INTVEC PROCn1(INT CONSTlength,q1):replace(l1,1,q1);length*l1END PROCn1;PROCinsert(INTVEC VARr1,INT CONSTpos,q1):INT CONSTbegin:=pos+pos-1;IFbegin<1THENs1ELIFbegin>length(r1)+1THENt1ELSEreplace(l1,1,q1);p1:=subtext(r1,begin);r1:=subtext(r1,1,begin-1);r1CATl1;r1CATp1END IF END PROCinsert;PROCdelete(INTVEC VARr1,INT CONSTpos):INT CONSTbegin:=pos+pos-1;IFbegin<1THENs1ELIFbegin>=length(r1)THENt1ELSEp1:=subtext(r1,begin+2);r1:=subtext(r1,1,begin-1);r1CATp1END IF END PROCdelete;INT PROCpos(INTVEC CONSTr1,INT CONSTq1):replace(l1,1,q1);INT VARbegin:=1;REPbegin:=pos(r1,l1,begin)+1UNTIL(beginAND1)=0ORbegin=1END REP;beginDIV2END PROCpos;PROCu1(INTVEC VARv1,w1,INT CONSTpos):INT CONSTbegin:=pos+pos-1;IFbegin<1THENs1ELIFbegin>length(v1)+1THENt1ELSEw1:=subtext(v1,begin);v1:=subtext(v1,1,begin-1)END IF END PROCu1;PROCx1(INTVEC VARv1,w1,INT CONSTpos):INT CONSTbegin:=pos+pos-1;IFbegin<1THENs1ELIFbegin
+>length(v1)+1THENt1ELSEw1:=subtext(v1,1,begin-1);v1:=subtext(v1,begin)END IF END PROCx1;.t1:errorstop(9,f1).s1:errorstop(10,f1).PROCy1(DATEI VARz1):z1.felderzahl:=0;z1.feldinfo:=o1;satzinitialisieren(z1.p0);z1.q0:=f1;z1.r0:=1;z1.s0:=1;z1.u0:=0;z1.t0:=0;z1.w0:=0;z1.v0:=1;z1.a1:=0;z1.c1(1):=f1;z1.c1(2):=f1;z1.c1(3):=f1;z1.satznr:=1;z1.x0:=1;z1.y0:=1;z1.z0:=1;z1.index(1).l0:=m1;z1.index(1):=INDEX:(0,0,1,1,n1(1,1));INT VARa2;FORa2FROM1UPTOb0REPz1.d1(a2):=0END REP;z1.e1(1):=EINTRAG:(0,0,1,0,b2).b2:z1.p0.END PROCy1;PROCoeffne(EUDAT VARz1,TEXT CONSTc2):enablestop;IF NOTexists(c2)THEN CONCR(z1):=new(c2);y1(CONCR(z1));type(old(c2),e0)ELIFtype(old(c2))=e0THEN CONCR(z1):=old(c2)ELSEerrorstop(g1)ENDIF END PROCoeffne;PROCoeffne(EUDAT VARz1,DATASPACE CONSTd2):IFtype(d2)<0THEN CONCR(z1):=d2;y1(CONCR(z1));type(d2,e0)ELIFtype(d2)=e0THEN CONCR(z1):=d2ELSEerrorstop(g1)END IF END PROCoeffne;PROCfeldlesen(EUDAT CONSTz1,INT CONSTe2,TEXT VARf2):feldlesen(g2,e2,f2).g2:z1.e1(z1.z0).o0.END PROCfeldlesen;PROC
+feldaendern(EUDAT VARz1,INT CONSTe2,TEXT CONSTh2):IFi2THENj2(CONCR(z1));k2;feldaendern(g2,e2,h2)END IF.i2:z1.z0<>1.k2:IFe2=1THENdisablestop;l2(CONCR(z1),m2(h2))END IF.g2:z1.e1(z1.z0).o0.END PROCfeldaendern;INT PROCfelderzahl(EUDAT CONSTz1):z1.felderzahlEND PROCfelderzahl;PROCfeldbearbeiten(EUDAT CONSTz1,INT CONSTe2,PROC(TEXT CONST,INT CONST,INT CONST)n2):feldbearbeiten(g2,e2,PROC(TEXT CONST,INT CONST,INT CONST)n2).g2:z1.e1(z1.z0).o0.END PROCfeldbearbeiten;PROCfeldnamenlesen(EUDAT CONSTz1,SATZ VARo2):o2:=z1.p0END PROCfeldnamenlesen;PROCfeldnamenaendern(EUDAT VARz1,SATZ CONSTp2):z1.p0:=p2;INT CONSTq2:=felderzahl(p2);IFq2>z1.felderzahlTHENr2;z1.felderzahl:=q2END IF.r2:z1.feldinfoCATn1(s2,-1).s2:q2-length(z1.feldinfo)DIV2.END PROCfeldnamenaendern;INT PROCfeldinfo(EUDAT CONSTz1,INT CONSTe2):z1.feldinfoISUBe2END PROCfeldinfo;PROCfeldinfo(EUDAT VARz1,INT CONSTe2,t2):replace(z1.feldinfo,e2,t2);IFpos(z1.q0,code(e2))>0THENz1.a1:=z1.w0END IF END PROCfeldinfo;INT PROCsatznr(EUDAT CONSTz1):z1.
+satznrEND PROCsatznr;BOOL PROCdateiende(EUDAT CONSTz1):z1.satznr>z1.w0END PROCdateiende;INT PROCsaetze(EUDAT CONSTz1):z1.w0END PROCsaetze;PROCu2(DATEI VARz1,INT CONSTx0,k0,satznr):IFx0<1ORx0>z1.s0CORk0<1ORk0>z1.index(x0).j0THENerrorstop(h1)END IF;disablestop;z1.x0:=x0;z1.y0:=k0;z1.satznr:=satznr;z1.z0:=z1.index(x0).l0ISUBk0END PROCu2;PROCaufsatz(EUDAT VARz1,INT CONSTv2):INT VARsatznr;IFv2<1THENsatznr:=1ELIFv2>z1.w0THENsatznr:=z1.w0+1ELSEsatznr:=v2END IF;w2(CONCR(z1),satznr)END PROCaufsatz;PROCaufsatz(EUDAT VARz1,TEXT CONSTx2):aufsatz(z1,1);IFy2THENweiter(z1,x2)END IF.y2:feldlesen(z1,1,k1);k1<>x2.END PROCaufsatz;PROCw2(DATEI VARz1,INT CONSTsatznr):IFz2THENu2(z1,1,1,1)END IF;INT VARx0:=z1.x0,a3:=z1.satznr-z1.y0;IFsatznr>z1.satznrTHENb3ELSEc3END IF;u2(z1,x0,k0,satznr).z2:satznr+satznr<z1.satznr.b3:WHILEd3REPa3INCRj0;x0:=z1.index(x0).i0END REP.d3:INT CONSTj0:=z1.index(x0).j0;a3+j0<satznr.c3:WHILEe3REPx0:=z1.index(x0).h0;a3DECRz1.index(x0).j0END REP.e3:a3>=satznr.k0:satznr-a3.END PROCw2;
+PROCweiter(EUDAT VARz1):f3(CONCR(z1))END PROCweiter;PROCf3(DATEI VARz1):IFg3THENh3END IF.g3:z1.z0<>1.h3:INT VARx0:=z1.x0,k0:=z1.y0;IFk0=index.j0THENx0:=index.i0;k0:=1ELSEk0INCR1END IF;u2(z1,x0,k0,z1.satznr+1).index:z1.index(x0).END PROCf3;PROCzurueck(EUDAT VARz1):i3(CONCR(z1))END PROCzurueck;PROCi3(DATEI VARz1):IFj3THENk3END IF.j3:z1.satznr<>1.k3:INT VARx0:=z1.x0,k0:=z1.y0;IFk0=1THENx0:=m0.h0;k0:=m0.j0ELSEk0DECR1END IF;u2(z1,x0,k0,z1.satznr-1).m0:z1.index(x0).END PROCi3;PROCweiter(EUDAT VARz1,TEXT CONSTx2):f3(CONCR(z1),x2)END PROCweiter;PROCf3(DATEI VARz1,TEXT CONSTx2):l3;WHILEm3CANDn3REPo3END REP;IFm3THENp3(z1,k0)ELSEw2(z1,z1.w0+1)END IF.l3:INT VARq3,k0:=z1.z0;IFn3THENr3(z1,m2(x2),k0,q3)ELSEo3END IF.m3:k0<>0.n3:feldlesen(g2,1,k1);k1<>x2.g2:z1.e1(k0).o0.o3:k0:=z1.e1(k0).i0.END PROCf3;PROCzurueck(EUDAT VARz1,TEXT CONSTx2):i3(CONCR(z1),x2)END PROCzurueck;PROCi3(DATEI VARz1,TEXT CONSTx2):l3;WHILEm3CANDn3REPs3END REP;IFm3THENp3(z1,k0)ELSEw2(z1,1)END IF.l3:INT VARk0:=z1.z0,q3;IFk0=1ORt3THEN
+r3(z1,m2(x2),q3,k0)END IF.m3:k0<>0.n3:k0=z1.z0ORt3.t3:feldlesen(g2,1,k1);k1<>x2.g2:z1.e1(k0).o0.s3:k0:=z1.e1(k0).h0.END PROCi3;PROCp3(DATEI VARz1,INT CONSTk0):INT CONSTu3:=z1.e1(k0).m0;INT VARy0:=1,satznr:=0;WHILEy0<>u3REPsatznrINCRz1.index(y0).j0;y0:=z1.index(y0).i0END REP;y0:=pos(z1.index(u3).l0,k0);satznrINCRy0;u2(z1,u3,y0,satznr).END PROCp3;INT VARindex;PROCv3(TEXT CONSTw3,INT CONSTx3,y3):INT VARz3:=x3;index:=0;IFy3-x3<4THENa4ELSEb4END IF;index:=indexMODb0+1.a4:WHILEz3<=y3REPindex:=index*4;indexINCRcode(w3SUBz3);z3INCR1END REP.b4:WHILEz3<=y3REPindexINCRindex;indexINCRcode(w3SUBz3);IFindex>16000THENindex:=indexMODb0END IF;z3INCR1END REP.END PROCv3;INT PROCm2(TEXT CONSTw3):v3(w3,1,length(w3));indexEND PROCm2;INT PROCm2(SATZ CONSTo0):feldbearbeiten(o0,1,PROC(TEXT CONST,INT CONST,INT CONST)v3);indexEND PROCm2;PROCr3(DATEI CONSTz1,INT CONSTm2,INT VARk0,c4):INT VARx0:=z1.r0;c4:=z1.d1(m2);k0:=0;BOOL VARd4:=TRUE;WHILEd4ANDc4<>0REPe4;o3END REP.e4:IFf4THENg4ELSEh4END IF.f4:z1.e1(c4).m0=z1.x0
+.g4:x0:=z1.x0;INT CONSTi4:=pos(l0,c4);IFi4=0THENerrorstop(h1)ELIFi4<=j4THENd4:=FALSE END IF.l0:z1.index(x0).l0.j4:z1.y0.h4:WHILEx0<>z1.e1(c4).m0REP IFx0=z1.x0THENd4:=FALSE;LEAVEe4ELSEx0:=z1.index(x0).h0END IF END REP.o3:IFd4THENk0:=c4;c4:=z1.e1(k0).h0END IF.END PROCr3;PROCk4(DATEI VARz1,INT CONSTm2):disablestop;INT CONSTk0:=z1.z0,h0:=z1.e1(k0).h0,i0:=z1.e1(k0).i0;IFi0<>0THENz1.e1(i0).h0:=h0ELSEz1.d1(m2):=h0END IF;IFh0<>0THENz1.e1(h0).i0:=i0END IF.END PROCk4;PROCl4(DATEI VARz1,INT CONSTm2,i0,h0):disablestop;INT CONSTk0:=z1.z0;z1.e1(k0).h0:=h0;z1.e1(k0).i0:=i0;IFh0<>0THENz1.e1(h0).i0:=k0END IF;IFi0<>0THENz1.e1(i0).h0:=k0ELSEz1.d1(m2):=k0END IF END PROCl4;PROCsatzlesen(EUDAT CONSTz1,SATZ VARo0):o0:=z1.e1(z1.z0).o0END PROCsatzlesen;PROCsatzaendern(EUDAT VARz1,SATZ CONSTm4):IF NOTdateiende(z1)THENn4END IF.n4:j2(CONCR(z1));disablestop;l2(CONCR(z1),m2(m4));g2:=m4.g2:z1.e1(z1.z0).o0.END PROCsatzaendern;PROCl2(DATEI VARz1,INT CONSTo4):IFp4THENq4END IF.p4:INT CONSTr4:=m2(g2);r4<>o4.q4:s4;t4.s4:
+k4(z1,r4).t4:INT VARh0,i0;r3(z1,o4,h0,i0);l4(z1,o4,h0,i0).g2:z1.e1(z1.z0).o0.END PROCl2;PROCsatzloeschen(EUDAT VARz1):IF NOTdateiende(z1)THENu4END IF.u4:disablestop;v4(CONCR(z1));w4(CONCR(z1));z1.w0DECR1.END PROCsatzloeschen;PROCv4(DATEI VARz1):x4(z1);INT CONSTk0:=z1.z0;k4(z1,m2(g2));z1.e1(k0).i0:=z1.u0;z1.u0:=k0.g2:z1.e1(k0).o0.END PROCv4;PROCsatzeinfuegen(EUDAT VARz1,SATZ CONSTm4):y4(CONCR(z1),m4)END PROCsatzeinfuegen;PROCy4(DATEI VARz1,SATZ CONSTm4):INT VARk0,h0,i0;enablestop;z4;a5;disablestop;z1.w0INCR1;b5(z1,k0);INT CONSTc5:=m2(k1);r3(z1,c5,i0,h0);l4(z1,c5,i0,h0);j2(z1).z4:IFz1.u0<>0THENk0:=z1.u0;z1.u0:=z1.e1(k0).i0ELIFz1.v0=d0THENerrorstop(i1)ELSEz1.v0INCR1;k0:=z1.v0END IF;z1.e1(k0).n0:=0;z1.e1(k0).o0:=m4.a5:feldlesen(m4,1,k1);IFz1.b1>0THEN IFk1=""THENd5;feldaendern(z1.e1(k0).o0,1,k1)END IF END IF.d5:k1:=text(z1.b1);k1:=e5+k1;IFz1.b1>32000THENz1.b1:=1ELSEz1.b1INCR1END IF.e5:(4-length(k1))*"0".END PROCy4;PROCautomatischerschluessel(EUDAT VARf5,BOOL CONSTg5):IFg5ANDf5.b1<0OR NOTg5
+ANDf5.b1>0THENf5.b1:=-f5.b1END IF END PROCautomatischerschluessel;BOOL PROCautomatischerschluessel(EUDAT CONSTf5):f5.b1>0END PROCautomatischerschluessel;INTVEC VARh5;PROCw4(DATEI VARz1):INT CONSTx0:=z1.x0,h0:=index.h0,i0:=index.i0;BOOL VARi5;delete(index.l0,z1.y0);index.j0DECR1;j5(z1,x0,i0,i5);IF NOTi5THENj5(z1,h0,x0,i5)END IF;k5(z1).index:z1.index(x0).END PROCw4;PROCj5(DATEI VARz1,INT CONSTz3,l5,BOOL VARi5):i5:=FALSE;IFz3<>0ANDl5<>0THENm5END IF.m5:INT CONSTn5:=index.j0,o5:=p5.j0;IFq5THENr5;i5:=TRUE END IF.q5:n5+o5<=g0ORn5=0ORo5=0.r5:index.j0INCRp5.j0;s5(z1,p5.l0,z3);index.l0CATp5.l0;t5.t5:index.i0:=p5.i0;IFindex.i0<>0THENz1.index(index.i0).h0:=z3ELSEz1.r0:=z3END IF;p5.i0:=z1.t0;z1.t0:=l5.index:z1.index(z3).p5:z1.index(l5).END PROCj5;PROCk5(DATEI VARz1):INT CONSTg2:=z1.satznr;u2(z1,1,1,1);w2(z1,g2)END PROCk5;PROCs5(DATEI VARz1,INTVEC CONSTl0,INT CONSTz3):INT VARa2;FORa2FROM1UPTOlength(l0)DIV2REPz1.e1(l0ISUBa2).m0:=z3END REP END PROCs5;PROCb5(DATEI VARz1,INT CONSTu5):INT VARx0:=z1.x0;IF
+index.j0>=f0THENv5END IF;index.j0INCR1;insert(index.l0,z1.y0,u5);z1.z0:=u5;z1.e1(u5).m0:=x0.v5:INT VARc5:=0;w5;IFc5<>0THENx5ELSEy5(z1)END IF;k5(z1);x0:=z1.x0.w5:IFz1.t0<>0THENc5:=z1.t0;z1.t0:=p5.i0ELIFz1.s0<c0THENz1.s0INCR1;c5:=z1.s0;p5.l0:=m1END IF.x5:z5;a6;p5.j0:=index.j0-b6;u1(index.l0,p5.l0,b6+1);index.j0:=b6;s5(z1,p5.l0,c5).z5:INT CONSTc6:=index.i0;IFc6<>0THENz1.index(c6).h0:=c5ELSEz1.r0:=c5END IF;p5.i0:=c6;p5.h0:=x0;index.i0:=c5.a6:INT VARb6;IFd6THENb6:=g0ELSEb6:=index.j0DIV2+1END IF.d6:c6=0.index:z1.index(x0).p5:z1.index(c5).END PROCb5;PROCy5(DATEI VARz1):INT VARx0:=1;REPe6;f6END REP.e6:BOOL VARi5;REP INT CONSTi0:=index.i0;j5(z1,x0,i0,i5)UNTIL NOTi5END REP;IFi0=0THEN LEAVEy5ELIFg6THENh6END IF.g6:INT CONSTi6:=g0-index.j0;i6>0.h6:x1(p5.l0,h5,i6+1);p5.j0DECRi6;s5(z1,h5,x0);index.l0CATh5;index.j0:=g0.f6:x0:=i0.index:z1.index(x0).p5:z1.index(i0).END PROCy5;TEXT VARj6:=",";LETk6=1;TEXT PROCdezimalkomma:j6END PROCdezimalkomma;PROCdezimalkomma(TEXT CONSTl6):IFlength(l6)<>1THENerrorstop(
+j1)ELSEj6:=l6ENDIF END PROCdezimalkomma;INT PROCunsortiertesaetze(EUDAT CONSTz1):z1.a1END PROCunsortiertesaetze;TEXT PROCsortierreihenfolge(EUDAT CONSTz1):z1.q0END PROCsortierreihenfolge;PROCj2(DATEI VARz1):IFm6(z1)THENdisablestop;z1.e1(z1.z0).n0INCRk6;z1.a1INCR1END IF END PROCj2;PROCx4(DATEI VARz1):IF NOTm6(z1)THENdisablestop;z1.e1(z1.z0).n0DECRk6;z1.a1DECR1END IF END PROCx4;BOOL PROCm6(DATEI CONSTz1,INT CONSTk0):(z1.e1(k0).n0ANDk6)=0END PROCm6;BOOL PROCm6(DATEI CONSTz1):m6(z1,z1.z0)END PROCm6;INTVEC VARn6;TEXT VARq0;TEXT VARo6,p6;PROCsortiere(EUDAT VARz1):q0:=z1.q0;IFq0=f1THENq6END IF;r6(CONCR(z1)).q6:INT VARa2;FORa2FROM1UPTOz1.felderzahlREPq0CATcode(a2)END REP.END PROCsortiere;PROCsortiere(EUDAT VARz1,TEXT CONSTs6):q0:=s6;r6(CONCR(z1))END PROCsortiere;PROCr6(DATEI VARz1):IFz1.q0<>q0THENz1.q0:=q0;z1.a1:=z1.w0+1ELIFz1.a1=0THEN LEAVEr6END IF;n6:=z1.feldinfo;IFt6THENu6(z1);z1.a1:=0ELSEv6(z1)END IF;w2(z1,1).t6:z1.w0DIVz1.a1<3.END PROCr6;PROCu6(DATEI VARz1):INT VARz0,o0:=1,w6;w2(z1,1);x4(
+z1);z0:=z1.z0;WHILEx6REPy6;z6;cout(o0)END REP;disablestop;y5(z1);u2(z1,1,1,1).x6:o0<z1.w0.y6:o0INCR1;w2(z1,o0);w6:=z0;z0:=z1.z0.z6:IFa7THENb7(z1,o0,z0);z0:=w6ELSEx4(z1)END IF.a7:z1.e1(w6).o0GROESSERz1.e1(z0).o0.END PROCu6;PROCv6(DATEI VARz1):INT VARa2;FORa2FROM1UPTOz1.v0REP IF NOTm6(z1,a2)THENb7(z1,z1.w0+1,a2);cout(a2)END IF END REP END PROCv6;PROCb7(DATEI VARz1,INT CONSTsatznr,z0):c7;d7.c7:INT VARe7:=1,f7:=satznr-1,g7;WHILEh7REPi7;j7END REP.h7:e7<=f7.i7:g7:=(e7+f7)DIV2;INT VARk7;w2(z1,g7);IF NOTm6(z1)THENl7END IF;k7:=z1.z0.l7:WHILEz1.satznr<f7REPf3(z1);IFm7THEN LEAVEl7END IF END REP;WHILEz1.satznr>e7REPi3(z1);IFm7THEN LEAVEl7END IF END REP;LEAVEc7.m7:m6(z1).j7:IFn7GROESSERz1.e1(z0).o0THENf7:=g7-1ELSEe7:=g7+1END IF.n7:z1.e1(k7).o0.d7:p3(z1,z0);IFz1.satznr<e7THENe7DECR1END IF;disablestop;x4(z1);o7;w4(z1);w2(z1,e7);b5(z1,z0);p7.o7:INT CONSTq7:=m2(g2);k4(z1,q7).p7:INT VARh0,i0;r3(z1,q7,h0,i0);l4(z1,q7,h0,i0).g2:z1.e1(z0).o0.END PROCb7;BOOL OP GROESSER(SATZ CONSTr7,s7):t7;u7;SELECTn6ISUBv7
+OF CASE0:w7CASE1:x7CASE2:y7OTHERWISEz7END SELECT.t7:INT VARa8:=1;WHILEa8<length(q0)REP INT CONSTv7:=code(q0SUBa8);feldlesen(r7,v7,o6);feldlesen(s7,v7,p6);SELECTn6ISUBv7OF CASE0:b8CASE1:c8OTHERWISEd8END SELECT;a8INCR2END REP;LEAVE GROESSER WITH FALSE.u7:BOOL VARe8;IF(q0SUB(a8+1))="-"THENe8:=FALSE ELSEe8:=TRUE END IF.c8:REAL VARf8,g8;wertberechnen(o6,f8);wertberechnen(p6,g8);IFf8<>g8THEN LEAVEt7END IF.b8:IF NOT(o6LEXEQUALp6)THEN LEAVEt7END IF.d8:IFo6<>p6THEN LEAVEt7END IF.x7:IFe8THENf8>g8ELSEf8<g8END IF.w7:IFe8THENo6LEXGREATERp6ELSEp6LEXGREATERo6END IF.y7:h8(o6);h8(p6);IFe8THENo6>p6ELSEo6<p6END IF.z7:IFe8THENo6>p6ELSEo6<p6END IF.END OP GROESSER;PROCwertberechnen(TEXT CONSTi8,REAL VARwert):LETj8="0123456789";TEXT VARk8:=j6,text;INT VARk0;INT CONSTl8:=length(i8);m8;WHILEk0<=l8REPn8;k0INCR1END REP;wert:=real(text).m8:k0:=pos(i8,"0","9",1);IFk0=0THENwert:=0.0;LEAVEwertberechnenELIFpos(i8,"-",1,k0)>0THENtext:="-"ELSEtext:=f1END IF;.n8:TEXT CONSTo8:=i8SUBk0;IFpos(j8,o8)>0THENtextCATo8ELIFo8=k8
+THENtextCAT".";k8:=f1END IF.END PROCwertberechnen;PROCh8(TEXT VARp8):IFlength(p8)<>8THENp8:=f1ELSEp8:=subtext(p8,7)+subtext(p8,4,5)+subtext(p8,1,2)END IF END PROCh8;PROCreorganisiere(TEXT CONSTc2):EUDAT VARq8,r8;oeffne(q8,c2);disablestop;DATASPACE VARd2:=nilspace;oeffne(r8,d2);s8(CONCR(q8),r8);IF NOTiserrorTHENforget(c2,quiet);copy(d2,c2)END IF;forget(d2)END PROCreorganisiere;PROCs8(DATEI VARq8,EUDAT VARr8):enablestop;t8;u8(q8,CONCR(r8)).t8:w2(q8,1);aufsatz(r8,1);WHILE NOTdateiendeREPsatzeinfuegen(r8,v8);cout(q8.satznr);f3(q8);weiter(r8)END REP.dateiende:q8.satznr>q8.w0.v8:q8.e1(q8.z0).o0.END PROCs8;PROCu8(DATEI VARq8,r8):r8.felderzahl:=q8.felderzahl;r8.p0:=q8.p0;r8.feldinfo:=q8.feldinfo;r8.q0:=q8.q0;r8.c1(1):=q8.c1(1);r8.c1(2):=q8.c1(2);r8.c1(3):=q8.c1(3)END PROCu8;PROCnotizenlesen(EUDAT CONSTz1,INT CONSTv2,TEXT VARw8):w8:=z1.c1(v2)END PROCnotizenlesen;PROCnotizenaendern(EUDAT VARz1,INT CONSTv2,TEXT CONSTw8):z1.c1(v2):=w8END PROCnotizenaendern;END PACKETeudasdateien;
+PACKETdatenverwaltungDEFINESoeffne,kopple,kette,zugriff,sichere,dateienloeschen,aufkoppeldatei,anzahlkoppeldateien,anzahldateien,aendernerlaubt,inhaltveraendert,eudasdateiname,folgedatei,dateiversion,anzahlfelder,feldnamenlesen,feldnamenbearbeiten,feldnummer,feldinfo,notizenlesen,notizenaendern,feldlesen,feldbearbeiten,feldaendern,satznummer,satzkombination,dateiende,weiter,zurueck,aufsatz,satzeinfuegen,satzloeschen,aenderungeneintragen,suchbedingung,suchbedingunglesen,suchbedingungloeschen,suchversion,satzausgewaehlt,markierungaendern,satzmarkiert,markierungenloeschen,markiertesaetze:LET INTVEC=TEXT,DATEI=STRUCT(TEXTname,SATZb0,INTVECc0,INTd0,INTe0,INTf0,DATASPACEg0,EUDATh0,SATZi0,BOOLj0,BOOLk0,l0,m0,TEXTn0,INTVECo0,INTp0),VERWEIS=STRUCT(INTq0,r0);LETs0="",t0="";LETmaxint=32767,u0=10,v0=256,w0=32;ROWu0DATEI VARx0;INT VARy0:=0,z0:=0,a1,b1:=0,c1,d1:=0,e1,f1,g1,h1:=0;BOOL VARi1:=TRUE,j1,k1;TEXT VARl1;ROWv0VERWEIS VARm1;ROWw0VERWEIS VARn1;INT VARo1;LETp1=#301
+#"Zuviel Dateien geoeffnet",q1=#302
+#"Datei existiert nicht",r1=#303
+#"Nicht moeglich, wenn auf Koppeldatei geschaltet",s1=#304
+#"Zu viele Felder",t1=#305
+#"Zu viele Koppelfelder",u1=#306
+#"keine Koppelfelder vorhanden",v1=#307
+#"kein direkter Dateizugriff bei geketteten oder gekoppelten Dateien",w1=#308
+#"keine Datei geoeffnet",x1=#309
+#"Datei nicht gesichert",y1=#310
+#"Suchmuster zu umfangreich";TEXT VARz1;TEXT VARa2:=" ";INTVEC VARb2;OP CAT(INTVEC VARtext,INT CONSTwert):replace(a2,1,wert);textCATa2END OP CAT;PROCinsert(INTVEC VARc2,INT CONSTd2,wert):INT CONSTe2:=d2+d2-2;b2:=subtext(c2,e2+1);c2:=subtext(c2,1,e2);c2CATwert;c2CATb2END PROCinsert;PROCdelete(INTVEC VARc2,INT CONSTd2):INT CONSTe2:=d2+d2-2;b2:=subtext(c2,e2+3);c2:=subtext(c2,1,e2);c2CATb2END PROCdelete;PROCf2(INTVEC VARc2,INT CONSTg2,h2):INT VARi2;FORi2FROMg2UPTOlength(c2)DIV2-1REPreplace(c2,i2,(c2ISUBi2)+h2)END REP END PROCf2;EUDAT VARj2;SATZ VARk2;PROCl2(TEXT CONSTm2):IFy0=u0THENerrorstop(p1)END IF;IF NOTexists(m2)THENerrorstop(q1)END IF;IFn2THENerrorstop(r1)END IF;oeffne(j2,m2)END PROCl2;PROCo2(DATEI VARq0,TEXT CONSTm2):IFj1THENq0.g0:=old(m2);oeffne(q0.h0,q0.g0)ELSEoeffne(q0.h0,m2)END IF;q0.e0:=0;q0.k0:=FALSE;q0.l0:=FALSE;q0.name:=m2;p2(q0)END PROCo2;PROCq2(INT CONSTr2):INT VARs2:=r2;WHILEx0(s2).e0<>0REPs2:=x0(s2).e0END REP;x0(s2).e0:=y0END PROCq2;PROCt2:IFdateiende(x0(1).h0)THEN
+aufsatz(1)ELSEaufsatz(satznr(x0(1).h0))END IF END PROCt2;PROCu2:c1:=felderzahl(x0(1).h0);d1:=c1;feldnamenlesen(x0(1).h0,x0(1).b0);o1:=0;INT VARi2;FORi2FROM1UPTOd1REPm1(i2).q0:=0END REP END PROCu2;PROCv2:h1INCR1;IFh1>32000THENh1:=-32000END IF END PROCv2;PROCoeffne(TEXT CONSTm2,BOOL CONSTw2):enablestop;dateienloeschen(FALSE);suchbedingungloeschen;l2(m2);j1:=w2;x2;o2(x0(y0),m2);t2;u2.x2:y0:=1;v2;g1:=0.END PROCoeffne;PROCkopple(TEXT CONSTm2):enablestop;IFy0=0THENerrorstop(w1)END IF;l2(m2);y2;z2;a3;o2(x0(y0),m2);b3.y2:feldnamenlesen(j2,k2);INT VARc0:=0;INTVEC VARc3:=t0;WHILEc0<felderzahl(j2)REPfeldlesen(k2,c0+1,z1);INT CONSTindex:=feldindex(x0(1).b0,z1);IFindex>0THENc0INCR1;c3CATindexEND IF UNTILindex=0END REP.z2:IFd1+felderzahl(j2)-c0>v0THENerrorstop(s1)ELIFo1+c0>w0THENerrorstop(t1)ELIFc0=0THENerrorstop(u1)END IF;y0INCR1;x0(y0).b0:=k2;x0(y0).c0:=c3;x0(y0).d0:=c0;INT VARd3:=c0;WHILEd3<felderzahl(j2)REPd1INCR1;d3INCR1;m1(d1).q0:=y0;m1(d1).r0:=d3END REP;FORd3FROM1UPTOc0REPe3END REP.e3:INT
+CONSTf3:=c3ISUBd3;IFm1(f3).q0=0THENg3ELSEh3END IF.g3:o1INCR1;n1(o1).q0:=y0;n1(o1).r0:=d3;m1(f3).q0:=o1;m1(f3).r0:=1.h3:INT CONSTi3:=m1(f3).q0+m1(f3).r0;j3;m1(f3).r0INCR1;n1(i3).q0:=y0;n1(i3).r0:=d3.j3:INT VARk3;FORk3FROMo1DOWNTOi3REPn1(k3+1):=n1(k3)END REP;o1INCR1;FORk3FROM1UPTOc1REP IFm1(k3).q0>=i3THENm1(k3).q0INCR1END IF END REP.a3:z0INCR1;IFb1=0THENb1:=y0ELSEq2(b1)END IF.b3:v2;x0(y0).j0:=FALSE;x0(y0).m0:=FALSE;x0(y0).f0:=satznr(j2);l3(x0(y0)).END PROCkopple;PROCkette(TEXT CONSTm2):enablestop;IFy0=0THENerrorstop(w1)END IF;l2(m2);y0INCR1;o2(x0(y0),m2);q2(1);IFi1THENaufsatz(satznummer)END IF END PROCkette;PROCzugriff(PROC(EUDAT VAR)m3):IFy0>1ORn2THENerrorstop(v1)ELSEaenderungeneintragen;m3(x0(1).h0);v2;t2;u2;x0(1).l0:=TRUE ENDIF END PROCzugriff;PROCsichere(INT CONSTn3,TEXT CONSTm2):aenderungeneintragen;notizenaendern(x0(n3).h0,2,date);IFj1THENforget(m2,quiet);copy(x0(n3).g0,m2)END IF;x0(n3).l0:=FALSE END PROCsichere;PROCdateienloeschen(BOOL CONSTo3):aenderungeneintragen;IFn2THEN
+aufkoppeldatei(0)END IF;p3;q3.p3:z0:=0;b1:=0;x0(1).e0:=0;d1:=0;i1:=TRUE.q3:WHILEy0>0REP IFr3AND NOTo3THENerrorstop(x1);LEAVEdateienloeschenEND IF;forget(x0(y0).g0);y0DECR1END REP.r3:j1ANDx0(y0).l0.END PROCdateienloeschen;INT VARs3,t3,u3,v3,w3,x3,y3,z3;BOOL VARa4;INTVEC VARb4;SATZ VARc4;BOOL VARn2:=FALSE;INT VARd4:=0,e4:=1;BOOL PROCaufkoppeldatei:n2END PROCaufkoppeldatei;PROCaufkoppeldatei(INT CONSTf4):disablestop;v2;IFn2THENg4;n2:=FALSE;h4;i4ELSEj4;n2:=TRUE;k4 END IF.g4:a1:=s3;c1:=t3;d1:=u3;e1:=v3;g1:=x3;b1:=y3;x0(e4).e0:=z3;l4:=d4;k1:=a4;m4:=b4;n4:=c4;IFl4>0THENk8:=1ELSEk8:=-1END IF.
+i4:d4:=0;e4:=1;enablestop;aufsatz(satznummer);WHILEf1<>w3REPweiter(1)END REP.h4:x0(e4).f0:=satznr(x0(e4).h0);IFf4=1AND NOTdateiende(x0(a1).h0)THENo4END IF.o4:INT VARp4;FORp4FROM1UPTOx0(e4).d0REPfeldaendern(x0(a1).h0,q4,r4)END REP;w3:=1.q4:x0(e4).c0ISUBp4.r4:feldlesen(x0(e4).h0,p4,z1);z1.j4:s3:=a1;t3:=c1;u3:=d1;v3:=e1;w3:=f1;x3:=g1;y3:=b1;z3:=x0(f4).e0;a4:=k1;b4:=m4;c4:=n4.k4:a1:=f4;d4:=l4;e4:=f4;c1:=felderzahl(x0(f4).h0);d1:=c1;e1:=0;g1
+:=(length(x0(f4).o0)-1)DIV2;b1:=0;x0(f4).e0:=0;suchbedingungloeschen;aufsatz(x0(f4).f0).END PROCaufkoppeldatei;INT PROCanzahlkoppeldateien:z0END PROCanzahlkoppeldateien;INT PROCanzahldateien:y0END PROCanzahldateien;BOOL PROCaendernerlaubt:j1END PROCaendernerlaubt;BOOL PROCinhaltveraendert(INT CONSTs4):aenderungeneintragen;x0(s4).l0END PROCinhaltveraendert;TEXT PROCeudasdateiname(INT CONSTs4):x0(s4).nameEND PROCeudasdateiname;INT PROCfolgedatei(INT CONSTs4):IFs4=0THENb1ELSEx0(s4).e0END IF END PROCfolgedatei;INT PROCdateiversion:h1END PROCdateiversion;INT PROCanzahlfelder:d1END PROCanzahlfelder;PROCfeldnamenlesen(INT CONSTd3,TEXT VARname):IFd3<=c1THENfeldlesen(x0(e4).b0,d3,name)ELSEfeldlesen(t4,u4,name)END IF.t4:x0(m1(d3).q0).b0.u4:m1(d3).r0.END PROCfeldnamenlesen;PROCfeldnamenbearbeiten(INT CONSTd3,PROC(TEXT CONST,INT CONST,INT CONST)v4):IFd3<=c1THENfeldbearbeiten(x0(e4).b0,d3,PROC(TEXT CONST,INT CONST,INT CONST)v4)ELSEfeldbearbeiten(t4,u4,PROC(TEXT CONST,INT CONST,INT CONST)v4)END IF.
+t4:x0(m1(d3).q0).b0.u4:m1(d3).r0.END PROCfeldnamenbearbeiten;INT PROCfeldnummer(TEXT CONSTw4):INT VARx4:=c1,f4:=feldindex(x0(e4).b0,w4),s2:=b1;WHILEf4=0ANDs2<>0REPf4:=feldindex(x0(s2).b0,w4);y4;s2:=x0(s2).e0END REP;f4.y4:INT CONSTz4:=x0(s2).d0;IFf4=0THENx4INCRfelderzahl(x0(s2).h0);x4DECRz4ELSEf4INCRx4;f4DECRz4END IF.END PROCfeldnummer;INT PROCfeldinfo(INT CONSTd3):IFd3<=c1THENfeldinfo(x0(e4).h0,d3)ELSEfeldinfo(x0(t4).h0,u4)END IF.t4:m1(d3).q0.u4:m1(d3).r0.END PROCfeldinfo;PROCnotizenlesen(INT CONSTf4,TEXT VARa5):notizenlesen(x0(e4).h0,f4,a5)END PROCnotizenlesen;PROCnotizenaendern(INT CONSTf4,TEXT CONSTa5):notizenaendern(x0(e4).h0,f4,a5)END PROCnotizenaendern;PROCfeldlesen(INT CONSTd3,TEXT VARa5):IFd3<=c1THENfeldlesen(x0(a1).h0,d3,a5)ELSEb5END IF.b5:INT CONSTt4:=m1(d3).q0;IFx0(t4).j0THENfeldlesen(x0(t4).i0,u4,a5)ELSEfeldlesen(x0(t4).h0,u4,a5)END IF.u4:m1(d3).r0.END PROCfeldlesen;PROCfeldbearbeiten(INT CONSTd3,PROC(TEXT CONST,INT CONST,INT CONST)v4):IFd3<=c1THENfeldbearbeiten(x0(a1).h0,
+d3,PROC(TEXT CONST,INT CONST,INT CONST)v4)ELSEc5END IF.c5:INT CONSTt4:=m1(d3).q0;IFx0(t4).j0THENfeldbearbeiten(x0(t4).i0,u4,PROC(TEXT CONST,INT CONST,INT CONST)v4)ELSEfeldbearbeiten(x0(t4).h0,u4,PROC(TEXT CONST,INT CONST,INT CONST)v4)END IF.u4:m1(d3).r0.END PROCfeldbearbeiten;PROCfeldaendern(INT CONSTd3,TEXT CONSTa5):INT CONSTt4:=m1(d3).q0;IFd3<=c1THENd5ELSEe5END IF.d5:x0(a1).l0:=TRUE;IFf5CANDg5THENh5END IF;feldaendern(x0(a1).h0,d3,a5).f5:NOTn2CANDt4>0.g5:feldlesen(x0(a1).h0,d3,z1);z1<>a5.h5:INT VARi5:=u4,j5:=t4;REPk5(x0(l5));x0(l5).m0:=TRUE;feldaendern(x0(l5).i0,f3,a5);j5INCR1;i5DECR1UNTILi5=0END REP.e5:k5(x0(t4));IFm5THENx0(t4).k0:=TRUE;feldaendern(x0(t4).i0,u4,a5)END IF.m5:feldlesen(x0(t4).i0,u4,z1);z1<>a5.u4:m1(d3).r0.l5:n1(j5).q0.f3:n1(j5).r0.END PROCfeldaendern;PROCk5(DATEI VARq0):IF NOTq0.j0THENq0.j0:=TRUE;n5END IF.n5:IFdateiende(q0.h0)THENsatzinitialisieren(q0.i0,q0.d0);o5ELSEsatzlesen(q0.h0,q0.i0)END IF.o5:INT VARi2;FORi2FROM1UPTOq0.d0REPfeldlesen(q0.c0ISUBi2,z1);feldaendern(
+q0.i0,i2,z1)END REP.END PROCk5;PROCl3(DATEI VARq0):p5;q5.p5:feldlesen(x0(a1).h0,r5,n0).r5:q0.c0ISUB1.n0:q0.n0.q5:aufsatz(q0.h0,n0);WHILE NOTs5(q0)REPweiter(q0.h0,n0)END REP;IFdateiende(q0.h0)THENk5(q0)ELSEq0.j0:=FALSE END IF.END PROCl3;PROCt5:INT VARs2:=b1;WHILEs2<>0REPl3(x0(s2));s2:=x0(s2).e0END REP;f1:=1END PROCt5;BOOL PROCs5(DATEI CONSTq0):IF NOTdateiende(q0.h0)THENu5END IF;TRUE.u5:INT VARv5;FORv5FROM2UPTOq0.d0REPfeldlesen(x0(a1).h0,c0ISUBv5,z1);feldbearbeiten(q0.h0,v5,PROC(TEXT CONST,INT CONST,INT CONST)w5);IF NOTx5THEN LEAVEs5WITH FALSE END IF END REP.c0:q0.c0.END PROCs5;BOOL VARx5;PROCw5(TEXT CONSTy5,INT CONSTr2,z5):x5:=length(z1)+r2=z5+1CANDpos(y5,z1,r2,z5+1)=r2END PROCw5;LETa6=22101,b6="h",c6=""27"";BOOL VARd6;PROCe6:TEXT VARf6;d6:=FALSE;REPf6:=incharety;type(f6)UNTILf6=s0END REP END PROCe6;PROCg6:IFd6THENtype(c6)END IF END PROCg6;BOOL PROCh6:TEXT VARf6;REPf6:=incharety;IFf6=s0THEN LEAVEh6WITH FALSE ELSEi6END IF END REP;FALSE.i6:IFd6THENd6:=FALSE;j6ELSEk6END IF.j6:IFf6=b6THENl6
+;errorstop(a6,s0);LEAVEh6WITH TRUE ELSEtype(c6);type(f6)END IF.k6:IFf6=c6THENd6:=TRUE ELSEtype(f6)END IF.l6:REP UNTILgetcharety=s0END REP.END PROCh6;PROCweiter(INT CONSTm6):IF NOTi1THENaenderungeneintragen;n6END IF.n6:SELECTm6OF CASE1:o6CASE2:p6CASE3:q6END SELECT.o6:r6(FALSE).p6:e6;REPr6(k1);cout(satznummer)UNTILsatzausgewaehltORi1ORh6END REP;g6.q6:INT VARs6:=satznr(x0(a1).h0);WHILEt6ANDe0<>0REPu6;s6:=1END REP;aufsatz(x0(a1).h0,v6);cout(satznummer);t5;i1:=dateiende(x0(a1).h0);w6.t6:x6(x0(a1),s6+1);INT CONSTv6:=x0(a1).o0ISUBx0(a1).p0;v6<>maxint.e0:x0(a1).e0.END PROCweiter;PROCzurueck(INT CONSTm6):IFsatznummer>1THENaenderungeneintragen;y6END IF.y6:SELECTm6OF CASE1:z6CASE2:a7CASE3:b7END SELECT.z6:c7(FALSE).a7:e6;REPc7(k1);cout(satznummer)UNTILsatzausgewaehltORsatznummer=1ORh6END REP;g6.b7:INT VARs6:=satznr(x0(a1).h0);WHILEt6ANDa1<>1REPd7;s6:=maxint-1END REP;aufsatz(x0(a1).h0,e7);cout(satznummer);t5;i1:=FALSE;w6.t6:INT VARe7;x6(x0(a1),s6);IFx0(a1).p0=1THENe7:=1;TRUE ELSEe7:=x0(a1).o0ISUB(
+x0(a1).p0-1);FALSE END IF.END PROCzurueck;PROCr6(BOOL CONSTf7):g7;IFh7THENo6;t5ELSEf1INCR1END IF;w6.g7:INT VARs2:=b1;WHILEs2>0REPi7;s2:=x0(s2).e0END REP.i7:BOOL VARj7;k7(x0(s2),j7);IFj7THEN LEAVEg7END IF.h7:s2=0.o6:IFf7THENweiter(x0(a1).h0,l1)ELSEweiter(x0(a1).h0)END IF;WHILEdateiende(x0(a1).h0)REPl7UNTILi1END REP.l7:IFx0(a1).e0<>0THENu6;m7ELSEi1:=TRUE END IF.m7:aufsatz(x0(a1).h0,1).END PROCr6;PROCk7(DATEI VARq0,BOOL VARj7):IFdateiende(q0.h0)THENj7:=FALSE ELSEn7END IF.n7:j7:=TRUE;REPweiter(q0.h0,q0.n0);IFdateiende(q0.h0)THENj7:=FALSE;aufsatz(q0.h0,q0.n0)END IF UNTILs5(q0)END REP.END PROCk7;PROCc7(BOOL CONSTf7):WHILEsatznr(x0(a1).h0)=1CANDsatznummer>1REPd7;o7(x0(a1).h0)END REP;IFf7THENzurueck(x0(a1).h0,l1)ELSEzurueck(x0(a1).h0)END IF;i1:=FALSE;t5;w6END PROCc7;PROCu6:e1INCRsaetze(x0(a1).h0);a1:=x0(a1).e0END PROCu6;PROCd7:INT VARp7:=1;WHILEx0(p7).e0<>a1REPp7:=x0(p7).e0END REP;e1DECRsaetze(x0(p7).h0);a1:=p7END PROCd7;PROCaenderungeneintragen:INT VARs2:=b1;WHILEs2<>0REPq7;s2:=x0(s2).e0END
+REP.q7:IFx0(s2).j0THENr7(x0(s2))END IF.END PROCaenderungeneintragen;PROCr7(DATEI VARq0):IFs7AND NOTt7THENu7ELIFv7ANDw7THENx7ELIFt7THENl3(q0)END IF;y7;k0:=FALSE;t7:=FALSE.s7:NOTdateiende(q0.h0)ANDk0.v7:felderzahl(i0)>q0.d0.w7:t7ORk0.x7:l0:=TRUE;feldlesen(i0,1,q0.n0);satzeinfuegen(q0.h0,i0).y7:q0.j0:=FALSE.u7:l0:=TRUE;satzaendern(q0.h0,i0).k0:q0.k0.t7:q0.m0.i0:q0.i0.l0:q0.l0.END PROCr7;PROCo7(EUDAT VARh0):aufsatz(h0,saetze(h0)+1)END PROCo7;PROCaufsatz(INT CONSTsatznr):aenderungeneintragen;a1:=e4;e1:=0;WHILEz7ANDa8REPu6END REP;aufsatz(x0(a1).h0,satznr-e1);t5;i1:=dateiende(x0(a1).h0);w6.z7:satznr-e1>saetze(x0(a1).h0).a8:x0(a1).e0<>0.END PROCaufsatz;INT PROCsatznummer:e1+satznr(x0(a1).h0)END PROCsatznummer;INT PROCsatzkombination:f1END PROCsatzkombination;BOOL PROCdateiende:i1END PROCdateiende;SATZ VARb8;satzinitialisieren(b8);PROCsatzeinfuegen:aenderungeneintragen;c8;satzeinfuegen(x0(a1).h0,b8);x0(a1).l0:=TRUE;d8;i1:=FALSE;w6.c8:x6(x0(a1),satznr(x0(a1).h0));f2(x0(a1).o0,x0(a1).p0,1).d8:f1
+:=1;INT VARs2:=b1;WHILEs2<>0REPo7(x0(s2).h0);s2:=x0(s2).e0END REP.END PROCsatzeinfuegen;PROCsatzloeschen:IF NOTi1THENaenderungeneintragen;e8;satzloeschen(x0(a1).h0);x0(a1).l0:=TRUE;aufsatz(satznummer)END IF.e8:IFsatzmarkiertTHENdelete(x0(a1).o0,x0(a1).p0);g1DECR1END IF;f2(x0(a1).o0,x0(a1).p0,-1).END PROCsatzloeschen;LETf8=100;ROWf8STRUCT(INTr0,g8,h8,i8,TEXTn0)VARj8;SATZ VARn4;INT VARl4,k8,l8:=1;BOOL VARm8,n8;suchbedingungloeschen;INT VARo8;LETp8=1,q8=2,r8=3,s8=4,t8=5,u8=6,v8=7,w8=8,x8=9;PROCw6:IFi1THENn8:=FALSE ELSEy8;n8:=z8END IF.y8:o8:=k8;WHILEo8>0REPa9;feldbearbeiten(b9,PROC(TEXT CONST,INT CONST,INT CONST)c9)END REP.a9:INT VARd9:=j8(o8).g8;IFd9>=256THENe9;f9END IF.e9:feldlesen((d9AND255)+1,z1).f9:IFg9=2THENh9END IF;j8(o8).n0:=z1.b9:j8(o8).r0.z8:o8<0.END PROCw6;PROCc9(TEXT CONSTy5,INT CONSTi9,j9):INT VARd9:=j8(o8).g8;IFd9>=256THENd9:=d9DIV256END IF;IFk9THENo8:=j8(o8).h8ELSEo8:=j8(o8).i8END IF.k9:SELECTd9OF CASEp8:l9CASEq8:m9CASEr8:n9CASEs8:o9CASEt8:p9CASEu8:q9CASEv8:r9CASEw8:s9CASEx8
+:t9OTHERWISE FALSE END SELECT.l9:SELECTg9OF CASE0:u9;z1LEXEQUALn0CASE1:u9;v9=w9OTHERWISElength(n0)=j9-i9+1ANDx9END SELECT.x9:i9>j9CORm9.m9:pos(y5,n0,i9,j9)=i9.n9:pos(y5,n0,j9+1-length(n0),j9)>0.o9:pos(y5,n0,i9,j9)>0.p9:u9;SELECTg9OF CASE0:n0LEXGREATERz1CASE1:v9<w9CASE2:h9;z1<n0OTHERWISEz1<n0END SELECT.q9:u9;SELECTg9OF CASE0:z1LEXGREATEREQUALn0CASE1:v9>=w9CASE2:h9;z1>=n0OTHERWISEz1>=n0END SELECT.r9:i9<=j9.s9:satzmarkiert.t9:TRUE.u9:z1:=subtext(y5,i9,j9).END PROCc9;TEXT PROCn0:j8(o8).n0END PROCn0;PROCh9:IFlength(z1)=8THEN TEXT CONSTy9:=subtext(z1,7,8);replace(z1,7,subtext(z1,1,2));replace(z1,1,y9)ELSEz1:=s0END IF END PROCh9;INT PROCg9:feldinfo(j8(o8).r0)END PROCg9;REAL PROCv9:REAL VARz9;wertberechnen(z1,z9);z9END PROCv9;REAL PROCw9:REAL VARz9;wertberechnen(n0,z9);z9END PROCw9;LETa10=";",b10=",",c10="..",d10="++",e10="--",f10="*";BOOL VARg10,h10,i10;INT VARj10,k10,l10,m10,n10;INTVEC VARm4;PROCsuchbedingung(INT CONSTd3,TEXT CONSTj8):INT VARr2:=1,o10:=0;INT CONSTp10:=length(j8)+1;k10:=0;n10
+:=d3;j10:=l4+1;WHILEr2<p10REPq10;r10;r2:=z5+2END REP;feldaendern(n4,d3,j8).q10:INT VARs10:=pos(j8,b10,r2);IFs10=0THENs10:=p10END IF;IFo10<r2THENt10END IF;INT CONSTz5:=min(s10,o10)-1.t10:k10INCR1;g10:=TRUE;IFk10>1THENk1:=FALSE END IF;o10:=pos(j8,a10,r2);IFo10=0THENo10:=p10END IF.r10:u10;h10:=TRUE;INT CONSTv10:=pos(j8,c10,r2,z5+1);IFw10THENx10(s0,x8,-k10)ELIFv10=0THENy10ELSEz10END IF.u10:IFsubtext(j8,r2,r2+1)=e10THENr2INCR2;i10:=TRUE ELSEi10:=FALSE END IF.w10:r2>z5.y10:IFa11THENb11ELSEc11END IF.a11:r2+1=z5CANDsubtext(j8,r2,z5)=d10.b11:x10(s0,w8,-k10).c11:INT VARd11:=pos(j8,f10,r2,z5+1);IFd11=0THENe11ELIFr2=z5THENf11ELSEg11;REPh11END REP END IF.e11:IFi11THENk1:=TRUE;l1:=j8END IF;x10(subtext(j8,r2,z5),p8,-k10).i11:d3=1ANDr2=1ANDz5=p10-1ANDj11AND NOTn2AND(j8SUB1)<>"&".j11:length(m4)<=2.f11:x10(s0,v8,-k10).g11:INT VARg8;IFd11=r2THENg8:=p8ELSEg8:=q8END IF.h11:IFg8<>p8THENk11END IF;r2:=d11+1;d11:=pos(j8,f10,r2,z5+1);IFd11=0THENd11:=z5+1;g8:=r8ELSEg8:=s8END IF.k11:TEXT CONSTn0:=subtext(j8,r2,
+d11-1);IFi10ORl11THEN IFi10THENh10:=TRUE END IF;x10(n0,g8,-k10);IFl11THEN LEAVEc11END IF ELSEx10(n0,g8,l4+2)END IF.l11:d11>=z5.z10:TEXT CONSTm11:=subtext(j8,r2,v10-1),n11:=subtext(j8,v10+2,z5);IFv10=r2THENx10(n11,t8,-k10)ELIFv10=z5-1THENx10(m11,u8,-k10)ELSEo11END IF.o11:IFi10THENx10(m11,u8,-k10);h10:=TRUE ELSEx10(m11,u8,l4+2)END IF;x10(n11,t8,-k10).END PROCsuchbedingung;PROCx10(TEXT CONSTp11,INT CONSTg8,h8):q11;r11;IFg10THENs11;t11;m10:=l4ELIFh10THENu11END IF;v11;w11.q11:m8:=FALSE;IFl4=d4THENl8INCR1;IFl8>32000THENl8:=1END IF END IF.r11:IFl4=f8THENsuchbedingungloeschen;errorstop(y1)ELSEl4INCR1;k8:=d4+1END IF.s11:IFk10>length(m4)DIV2THENm4CATl4;x11(k8,0,l4)END IF;IFk10=length(m4)DIV2THENl10:=0ELSEl10:=m4ISUB(k10+1)END IF.t11:x11(k8,-k10,l4);g10:=FALSE;h10:=FALSE.u11:x11(m10,l10,l4);m10:=l4;h10:=FALSE.v11:j8(l4).g8:=g8;j8(l4).r0:=n10;IFi10THENj8(l4).h8:=l10;j8(l4).i8:=h8ELSEj8(l4).h8:=h8;j8(l4).i8:=l10END IF.w11:IFy11THENz11ELSEa12END IF.y11:(p11SUB1)="&"CANDb12.b12:INT
+CONSTc12:=feldnummer
+(subtext(p11,2));c12>0.z11:j8(l4).g8:=c12-1+256*g8.a12:INT CONSTd12:=feldinfo(n10);IFd12=2AND(g8=t8ORg8=u8)THENz1:=p11;h9;j8(l4).n0:=z1ELSEj8(l4).n0:=p11END IF.END PROCx10;PROCx11(INT CONSTi9,wert,e12):INT VARi2;FORi2FROMi9UPTOl4-1REP IFj8(i2).h8=wertTHENj8(i2).h8:=e12ELIFj8(i2).i8=wertTHENj8(i2).i8:=e12END IF END REP END PROCx11;PROCsuchbedingunglesen(INT CONSTd3,TEXT VARj8):feldlesen(n4,d3,j8)END PROCsuchbedingunglesen;PROCsuchbedingungloeschen:disablestop;IFn2THENl4:=d4ELSEd4:=0;l4:=0END IF;k8:=-1;m4:=t0;satzinitialisieren(n4);k1:=FALSE;m8:=TRUE;n8:=NOTi1END PROCsuchbedingungloeschen;BOOL PROCsatzausgewaehlt:IF NOTm8THENw6;m8:=TRUE END IF;n8END PROCsatzausgewaehlt;INT PROCsuchversion:IFl4=d4THEN0ELSEl8END IF END PROCsuchversion;PROCx6(DATEI VARq0,INT CONSTy5):IF(q0.o0ISUBq0.p0)<y5THENf12ELSEg12END IF.f12:REPq0.p0INCR1UNTIL(q0.o0ISUBq0.p0)>=y5END REP.g12:WHILEq0.p0>1CAND(q0.o0ISUB(q0.p0-1))>=y5REPq0.p0DECR1END REP.END PROCx6;PROCmarkierungaendern:disablestop;IFsatzmarkiertTHENdelete(
+x0(a1).o0,x0(a1).p0);g1DECR1ELSEinsert(x0(a1).o0,x0(a1).p0,satznr(x0(a1).h0));g1INCR1END IF END PROCmarkierungaendern;BOOL PROCsatzmarkiert:INT CONSTy5:=satznr(x0(a1).h0);x6(x0(a1),y5);y5=(x0(a1).o0ISUBx0(a1).p0)END PROCsatzmarkiert;INT PROCmarkiertesaetze:g1END PROCmarkiertesaetze;PROCmarkierungenloeschen:disablestop;IFn2THENp2(x0(a1))ELSEh12END IF;g1:=0.h12:INT VARs2:=1;REPp2(x0(s2));s2:=x0(s2).e0UNTILs2=0END REP.END PROCmarkierungenloeschen;PROCp2(DATEI VARq0):q0.o0:=s0;q0.o0CATmaxint;q0.p0:=1END PROCp2;END PACKETdatenverwaltung;
+
diff --git a/eudas/eudas.2 b/eudas/eudas.2
new file mode 100644
index 0000000..0048409
--- /dev/null
+++ b/eudas/eudas.2
@@ -0,0 +1,62 @@
+PACKETverarbeitungDEFINESkopiere,stdkopiermuster,verarbeite,trage,eindeutigefelder,pruefe,wertemenge,feldmaske,tragesatz,holesatz,K,V,f,wert,zahltext,textdarstellung:SATZ VARb0,c0,d0;INT VARe0;BOOL VARf0;LETg0="",INTVEC=TEXT;INTVEC VARh0;TEXT VARi0:=" ";OP CAT(INTVEC VARj0,INT CONSTk0):replace(i0,1,k0);j0CATi0END OP CAT;PROCstdkopiermuster(TEXT CONSTl0,FILE VARm0):n0;INT VARo0;p0;q0;INT VARr0;FORr0FROM1UPTOo0REPs0;IFt0THENu0ELSEv0END IF END REP.p0:output(m0);EUDAT VARw0;IFexists(l0)THENoeffne(w0,l0)END IF.q0:IFexists(l0)CANDfelderzahl(w0)>0THENfeldnamenlesen(w0,b0);o0:=felderzahl(w0)ELSEx0;o0:=anzahlfelderEND IF.x0:TEXT VARy0;satzinitialisieren(b0);FORr0FROM1UPTOanzahlfelderREPfeldnamenlesen(r0,y0);feldaendern(b0,r0,y0)END REP.t0:feldnummer(y0)>0.s0:feldlesen(b0,r0,y0);put(m0,textdarstellung(y0)).u0:write(m0,"K f(");write(m0,textdarstellung(y0));putline(m0,");").v0:putline(m0,"K """";").END PROCstdkopiermuster;PROCkopiere(TEXT CONSTl0,FILE VARm0):z0(a1,m0).a1:"kopiere ("+
+textdarstellung(l0)+", ".END PROCkopiere;PROCz0(TEXT CONSTb1,FILE VARc1):d1;write(e1,b1);putline(e1,"PROC programmfunktion);");putline(e1,"PROC programmfunktion:");f1;putline(e1,"END PROC programmfunktion");g1;forget(h1,quiet).d1:TEXT VARh1;INT VARi1:=0;REPi1INCR1;h1:=text(i1)UNTIL NOTexists(h1)END REP;disablestop;FILE VARe1:=sequentialfile(output,h1);headline(e1,j1).f1:TEXT VARk1;input(c1);WHILE NOTeof(c1)REPgetline(c1,k1);putline(e1,k1)END REP.g1:TEXT CONSTl1:=std;run(h1);lastparam(l1).END PROCz0;PROCkopiere(TEXT CONSTl0,PROCm1):enablestop;INT VARn1;o1(n1);IFdateiendeTHENaufsatz(1);LEAVEkopiereELSEp1END IF;WHILE NOTdateiendeREPsatzinitialisieren(d0);e0:=1;m1;q1;satzeinfuegen(w0,d0);weiter(w0);weiter(n1)END REP;aufsatz(1).p1:f0:=TRUE;EUDAT VARw0;oeffne(w0,l0);aufsatz(w0,saetze(w0)+1);feldnamenlesen(w0,c0);h0:=g0.q1:IFf0THENfeldnamenaendern(w0,c0);f0:=FALSE END IF END PROCkopiere;OP K(TEXT CONSTy0,r1):IFf0THENs1;END IF;feldaendern(d0,h0ISUBe0,r1);e0INCR1.s1:INT VARt1:=feldindex(c0,y0);
+IFt1=0THENt1:=felderzahl(c0)+1;feldaendern(c0,t1,y0);END IF;h0CATt1.END OP K;PROCverarbeite(FILE VARu1):z0("verarbeite (",u1)END PROCverarbeite;PROCverarbeite(PROCv1):enablestop;INT VARn1;o1(n1);WHILE NOTdateiendeREPv1;weiter(n1)END REP;aufsatz(1)END PROCverarbeite;OP V(TEXT CONSTy0,r1):INT CONSTw1:=feldnummer(y0);IFw1=0THENx1(y0)ELSEfeldaendern(w1,r1)END IF END OP V;PROCo1(INT VARn1):n0;aufsatz(1);IFmarkiertesaetze>0THENn1:=3;IF NOTsatzmarkiertTHENweiter(n1)END IF ELSEn1:=2;IF NOTsatzausgewaehltTHENweiter(n1)END IF END IF END PROCo1;PROCn0:IFanzahldateien=0THENerrorstop(y1)END IF.END PROCn0;TEXT VARz1,a2;LETb2="""";TEXT PROCf(TEXT CONSTy0):INT CONSTw1:=feldnummer(y0);IFw1=0THENx1(y0);z1:=g0ELSEfeldlesen(w1,z1)END IF;z1END PROCf;REAL PROCwert(TEXT CONSTy0):INT CONSTw1:=feldnummer(y0);IFw1=0THENx1(y0);0.0ELSEfeldlesen(w1,z1);REAL VARc2;wertberechnen(z1,c2);c2END IF END PROCwert;REAL PROCwert(TEXT CONSTy0,INT CONSTd2):round(wert(y0),d2)END PROCwert;TEXT PROCzahltext(REAL CONSTe2,INT
+CONSTd2):REAL CONSTf2:=round(abs(e2),d2);INT VARg2:=h2+d2+2;IFe2<0.0THENa2:="-"ELSEa2:=g0END IF;IFf2<1.0ANDf2<>0.0THENa2CAT"0";g2DECR1ENDIF;a2CATtext(f2,g2,d2);IFd2>0THENchange(a2,".",dezimalkomma)ELSEchange(a2,".",g0)END IF;a2.h2:max(0,decimalexponent(f2)).END PROCzahltext;TEXT PROCzahltext(TEXT CONSTy0,INT CONSTd2):zahltext(wert(y0),d2)END PROCzahltext;TEXT PROCtextdarstellung(TEXT CONSTi2):z1:=i2;changeall(z1,b2,b2+b2);j2;insertchar(z1,b2,1);z1CATb2;z1.j2:INT VARk2:=1;WHILEl2REPchange(z1,k2,k2,m2)END REP.l2:k2:=pos(z1,""0"",""31"",k2);k2>0.m2:b2+text(code(z1SUBk2))+b2.END PROCtextdarstellung;PROCx1(TEXT CONSTy0):errorstop(n2+textdarstellung(y0)+o2)END PROCx1;SATZ VARp2;EUDAT VARq2;LETj1=#501
+#"erzeugtes Programm",y1=#502
+#"keine Datei geoeffnet",r2=#503
+#"Kein Satz zum Tragen vorhanden",s2=#504
+#"Zieldatei hat falsche Felderzahl",t2=#505
+#" existiert nicht",u2=#506
+#" verletzt die Pruefbedingung.",v2=#507
+#" ist in der Zieldatei bereits vorhanden.",o2=#508
+#" ist nicht definiert.",w2=#509
+#" ist nicht in der Wertemenge.",x2=#510
+#" stimmt nicht mit der Maske ueberein.",y2=#511
+#"Satz ",n2=#512
+#"Das Feld ";INT VARz2;FILE VARa3;BOOL VARb3:=FALSE,c3,d3;TEXT VARe3;PROCtrage(TEXT CONSTl0,FILE VARf3,BOOL CONSTg3):disablestop;b3:=g3;IFb3THENa3:=f3;output(a3)END IF;h3(l0);b3:=FALSE END PROCtrage;PROCh3(TEXT CONSTl0):enablestop;INT VARn1;o1(n1);i3(l0);INT VARj3:=0;REP IF NOTk3THENweiter(n1)ELSEcout(satznummer+j3)END IF;IFdateiendeTHENaufsatz(1);LEAVEh3END IF;l3END REP.k3:IFn1=3THENsatzmarkiertELSEsatzausgewaehltEND IF.l3:c3:=TRUE;IFb3THENnotizenlesen(q2,1,e3);do(e3)END IF;IFc3THENm3;IFc3THENsatzloeschen;j3INCR1END IF END IF;IF NOTc3THENweiter(n1)END IF.END PROCh3;PROCi3(TEXT CONSTl0):IFdateiendeTHENerrorstop(r2)END IF;oeffne(q2,l0);z2:=0;IFfelderzahl(q2)=0THENp1ELIFfelderzahl(q2)<>anzahlfelderTHENerrorstop(s2)END IF;aufsatz(q2,saetze(q2)+1).p1:satzinitialisieren(p2,anzahlfelder);INT VARr0;FORr0FROM1UPTOanzahlfelderREPfeldnamenlesen(r0,z1);feldaendern(p2,r0,z1)END REP;feldnamenaendern(q2,p2).END PROCi3;PROCm3:IFz2>0CANDn3THENo3("",v2)ELSEp3;satzeinfuegen(q2,p2);weiter(q2)END IF.p3:
+satzinitialisieren(p2,anzahlfelder);INT VARr0;FORr0FROM1UPTOanzahlfelderREPfeldlesen(r0,z1);feldaendern(p2,r0,z1)END REP.n3:TEXT VARc1;INT CONSTq3:=satznr(q2);feldlesen(1,c1);d3:=FALSE;aufsatz(q2,c1);WHILE NOTdateiende(q2)REPr3;weiter(q2,c1)UNTILd3END REP;aufsatz(q2,q3);d3.r3:INT VARi1;d3:=TRUE;FORi1FROM2UPTOz2REPfeldlesen(q2,i1,z1);feldbearbeiten(i1,PROC(TEXT CONST,INT CONST,INT CONST)s3);IF NOTd3THEN LEAVEr3END IF END REP.END PROCm3;PROCs3(TEXT CONSTt3,INT CONSTu3,v3):IFw3COR(length(z1)>0CANDx3)THENd3:=FALSE END IF.w3:(v3-u3+1)<>length(z1).x3:pos(t3,z1,u3,v3+1)<>u3.END PROCs3;PROCo3(TEXT CONSTy3,z3):IFb3THENa4ELSEerrorstop(z3)END IF.a4:put(a3,y2);put(a3,satznummer);IFy3<>""THENwrite(a3,n2);write(a3,textdarstellung(y3))END IF;putline(a3,z3);c3:=FALSE.END PROCo3;PROCeindeutigefelder(INT CONSTb4):z2:=b4END PROCeindeutigefelder;PROCpruefe(TEXT CONSTy3,BOOL CONSTc4):IF NOTc4THENo3(y3,u2)END IF END PROCpruefe;PROCwertemenge(TEXT CONSTy3,d4):INT CONSTw1:=feldnummer(y3);IFw1=0THENo3(y3,o2)
+ELSEe4END IF.e4:INT VARk2:=0;LETf4=",";feldlesen(w1,z1);IFg4THEN LEAVEe4END IF;z1CATf4;REPk2:=pos(d4,z1,k2+1);IFk2=1ORk2>1CAND(d4SUBk2-1)=f4THEN LEAVEe4END IF UNTILk2=0END REP;o3(y3,w2).g4:INT CONSTh4:=length(d4)-length(z1);(d4SUBh4)=f4ANDpos(d4,z1,h4+1)>0.END PROCwertemenge;PROCfeldmaske(TEXT CONSTy3,i4):INT CONSTw1:=feldnummer(y3);IFw1=0THENo3(y3,o2)ELSEfeldlesen(w1,z1);j4END IF.j4:INT VARk2;TEXT CONSTk4:=code(length(i4)+1);TEXT VARl4:=""1"";FORk2FROM1UPTOlength(z1)REP TEXT CONSTm4:=z1SUBk2;n4UNTILl4=""END REP;IFo4THENo3(y3,x2)END IF.n4:INT VARp4:=1;WHILEp4<=length(l4)REP INT CONSTq4:=code(l4SUBp4);IF(i4SUBq4)="*"THENr4ELIFs4THENreplace(l4,p4,code(q4+1));p4INCR1ELSEdeletechar(l4,p4)END IF END REP.r4:IFq4=length(i4)THEN LEAVEfeldmaskeEND IF;p4INCR1;IFpos(l4,code(q4+1))=0THENinsertchar(l4,code(q4+1),p4)END IF.s4:SELECTpos("9XAa",i4SUBq4)OF CASE1:pos("0123456789",m4)>0CASE2:TRUE CASE3:pos("ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ",m4)>0CASE4:pos("abcdefghijklmnopqrstuvwxyzäöüß",m4)>0OTHERWISE(i4
+SUBq4)=m4END SELECT.o4:(l4=""CORpos(l4,k4)=0)ANDt4.t4:(i4SUBlength(i4))<>"*"ORpos(l4,code(length(i4)))=0.END PROCfeldmaske;PROCtragesatz(TEXT CONSTl0):i3(l0);INT CONSTu4:=satznr(q2);m3;satzloeschen;aufsatz(q2,u4)END PROCtragesatz;PROCholesatz(TEXT CONSTl0):n0;IF NOTexists(l0)THENerrorstop(textdarstellung(l0)+t2)END IF;oeffne(q2,l0);IFfelderzahl(q2)<>anzahlfelderTHENerrorstop(s2)ELIFsaetze(q2)=0THENerrorstop(r2)END IF;aufsatz(q2,saetze(q2));satzlesen(q2,p2);v4;satzloeschen(q2).v4:satzeinfuegen;INT VARr0;FORr0FROM1UPTOfelderzahl(p2)REPfeldlesen(p2,r0,z1);feldaendern(r0,z1)END REP.END PROCholesatz;END PACKETverarbeitung;
+PACKETeudasdruckenDEFINESdrucke,interpretiere,gruppentest,druckdatei,direktdrucken,maxdruckzeilen,gruppenwechsel,lfdnr:LETb0=25,SPEICHER=STRUCT(INTc0,d0,e0,f0,TEXTg0);ROWb0SPEICHER VARh0;INT VARi0;LETj0="",k0=" ",l0=" ";TEXT VARm0;PROCinterpretiere(INT CONSTn0,o0,PROC(INT CONST,TEXT VAR)p0):INT VARq0,r0:=0,s0:=0,t0:=o0;u0(n0);WHILE NOTv0REPw0;IFx0THENr0INCR1ELSEy0;z0END IF END REP.z0:IFa1(q0)THENb1ELSEc1;s0:=0END IF.b1:SELECTq0OF CASEd1:e1CASEf1:g1OTHERWISE LEAVEinterpretiereEND SELECT.y0:WHILEr0>0REPh1(k0);r0DECR1END REP.e1:i1(i0).g1:i1(s0).x0:j1=j0ORj1=k0.c1:INT VARk1:=0,l1:=0;BOOL VARm1:=FALSE;REPn1;k1INCR1;IFi0=3THENm1:=TRUE END IF UNTILo1END REP.o1:IFi0<=2THEN TRUE ELIFs0<>0THENk1=s0ELSEl1=0END IF.n1:INT VARp1:=1,q1:=0,r1:=0,s1:=1,t1:=1;m0:=j0;REP IFu1THENv1END IF;IFw1THENx1END IF;y1;s1INCR1END REP.u1:k1=0.v1:z1(a2.c0,a2.d0,a2.e0);IF NOTb2THENc2END IF.b2:a2.c0>length(j1).c2:INT CONSTd2:=e2(t0);IFd2>0THENfeldlesen(d2,a2.g0)ELSEp0(-d2,a2.g0)END IF;t0INCR1;a2.f0:=0;IFa2.g0<>j0THENl1
+INCR1END IF.w1:a2.e0>=4.a2:h0(s1).y1:INT CONSTreserve:=f2(a2);IFreserve>0THENg2ELSEr1DECRreserveEND IF.g2:q1INCRreserve;IFh2ANDq1>r1THENq1:=r1END IF;IFi2ANDj2THENk2END IF.h2:i0=2ORi0=4.i2:reserve=a2.d0.j2:(a2.e0AND1)=0.k2:IFa2.c0=1COR(j1SUB(a2.c0-1))=k0THEN INT VARl2:=m2(s1);WHILE(j1SUBl2)=k0REPl2INCR1;a2.d0INCR1;q1INCR1END REP END IF.x1:IFs1=1THEN IFb2THENn2END IF ELSEo2END IF.n2:IFm1THENh1(k0)ELSEh1(j1)END IF;LEAVEn1.o2:INT VARp2:=0,q2:=a2.c0;INT CONSTr2:=q2-length(j1);s2;t2;u2;v2.s2:IFr2>0THENq1INCRr2;q2DECR(r2-1)END IF;w2.w2:INT CONSTx2:=m2(s1-1),y2:=pos(j1,l0,x2,q2);IFy2>0THENq2:=y2;z2ELIFr2<0AND(j1SUB(q2-1))<>k0THENq2:=x2END IF.z2:INT VARa3:=q2+1;REPp2INCR1;a3INCR1UNTIL(j1SUBa3)<>k0END REP;q1INCRp2.t2:INT VARb3:=0;WHILEt1<s1REPc3;d3;e3;t1INCR1END REP.c3:INT CONSTc0:=f3.c0,d0:=f3.d0,e0:=f3.e0.d3:g3(p1,c0,m1);p1:=c0+d0.f3:h0(t1).e3:INT CONSTh3:=-f2(f3);IFh3=-d0ANDi3THENj3ELIFh3<=0THENk3ELIFi3ANDl3THENm3ELSEn3END IF.j3:b3INCRh3;IFh2THENo3END IF.o3:IFb3<0THENp3(-b3);b3:=0END IF.k3:IF
+q3THENp3(-h3)END IF;r3(f3);l1DECR1;IFs3THENt3ELSEb3INCRh3;u3END IF.q3:(e0AND2)=2.s3:(e0AND1)=1.t3:IF NOTq3THENp3(-h3)END IF.u3:IFh2ANDb3<0THENp3(-b3);b3:=0END IF.i3:NOTs3.l3:h3<=q1.m3:r3(f3);l1DECR1;b3INCRh3;q1DECRh3.n3:INT VARv3:=0,w3:=f3.f0+1,x3:=w3+d0-1;IFi3THENx3INCRq1END IF;IFq3ANDy3THENz3ELIFa4THENb4END IF;c4;IFi3THENb3INCRq1;q1:=0END IF.z3:INT CONSTd4:=length(f3.g0)-x3;w3INCRd4;x3INCRd4.a4:i0>=3.y3:NOTa4.c4:IFq3THENp3(v3)END IF;e4(f3.g0,w3,x3);IFf4THENp3(v3)END IF.f4:NOTq3.b4:IFpos(f3.g0,k0,w3,x3)>0THENg4END IF;INT CONSTh4:=pos(f3.g0,"!","�",x3+1);IFh4=0THENf3.f0:=length(f3.g0);l1DECR1ELSEf3.f0:=h4-1END IF.g4:x3INCR1;v3DECR1;WHILE(f3.g0SUBx3)<>k0REPx3DECR1;v3INCR1END REP;WHILE(f3.g0SUBx3)=k0REPx3DECR1;v3INCR1UNTILl2<w3END REP.u2:g3(p1,q2,m1);IFb3<0THEN IFq2<=length(j1)THENp3(-b3)END IF;p1:=q2ELSEp1:=q2+min(b3,p2)END IF.v2:IFr2>0THENi4;j4;LEAVEn1ELSEk4END IF.i4:IF NOTm1THENe4(j1,p1,length(j1))END IF.j4:INT VARl4:=length(m0);IF(m0SUBl4)=k0THEN REPl4DECR1UNTIL(m0SUBl4)<>k0END REP;
+m0:=subtext(m0,1,l4)END IF;IFm4THENm0CATk0END IF;h1(m0).m4:(j1SUB LENGTHj1)=k0AND(i0<>3ORl1=0).k4:q1:=0;r1:=0.END PROCinterpretiere;INT PROCm2(INT CONSTn4):h0(n4).c0+h0(n4).d0END PROCm2;INT PROCf2(SPEICHER CONSTo4):o4.d0-length(o4.g0)+o4.f0END PROCf2;LETp4=" ";PROCp3(INT CONSTq4):INT VARr4:=q4;WHILEr4>=10REPm0CATp4;r4DECR10END REP;WHILEr4>0REPm0CATk0;r4DECR1END REP END PROCp3;PROCr3(SPEICHER VARo4):IFo4.f0=0THENm0CATo4.g0ELSEe4(o4.g0,o4.f0+1,length(o4.g0))END IF;o4.f0:=length(o4.g0)END PROCr3;PROCg3(INT CONSTs4,t4,BOOL CONSTm1):IFm1THENp3(t4-s4)ELSEe4(j1,s4,t4-1)END IF END PROCg3;TEXT VARu4;PROCe4(TEXT CONSTv4,INT CONSTs4,t4):u4:=subtext(v4,s4,t4);m0CATu4END PROCe4;FILE VARw4;TEXT VARj1;INT VARx4;LETy4=#401
+#"keine schliessende Klammer in Feldmuster",z4=#402
+#"kein Kommando in Kommandozeile",a5=#403
+#"unbekanntes Kommando";LETb5="&",c5="%",d5="%",e5="<",f5=">";LETg5=#404
+#" "1"VOR "1"VORSPANN "2"WDH "2"WIEDERHOLUNG "3"NACH "3"NACHSPANN "4"ABK "4"ABKUERZUNGEN "5"GRUPPE "6"MODUS "7"MEHR "LETh5=1,i5=2,j5=3,k5=4,l5=5,d1=6,f1=7,m5=100;INT VARn5,o5,p5;BOOL VARv0,q5;.r5:lineno(w4).s5:n5:=maxlinelength(w4).PROCt5(TEXT CONSTu5):REPx4INCR1UNTIL(j1SUBx4)<>u5END REP END PROCt5;PROCz1(INT VARw3,v5,e0):w5;IFb2THENw3:=max(n5,length(j1))+1;v5:=0;e0:=5ELSEw3:=x4;x5END IF.w5:y5(b5,c5).b2:x4>length(j1).x5:TEXT CONSTz5:=j1SUBx4;IFz5=c5THENe0:=0ELSEe0:=4END IF;a6;feldnamenlesen;b6.a6:t5(z5);IFx4-1>w3THENc6END IF.c6:e0INCR3.feldnamenlesen:IF(j1SUBx4)=e5THENd6ELSEe6END IF;IFf6THENz1(w3,v5,e0);LEAVEz1END IF.f6:o5>p5.d6:o5:=x4+1;p5:=pos(j1,f5,o5);IFp5=0THENg6(y4,subtext(j1,x4));p5:=length(j1)ELSEp5DECR1END IF;x4:=p5+2.e6:o5:=x4;y5(k0,c5);INT CONSTh6:=pos(j1,b5,o5,x4);IFh6>0THENx4:=h6END IF;p5:=x4-1.b6:IFi6THENj6;t5(z5)END IF;v5:=x4-w3.i6:(j1SUBx4)=z5.j6:e0:=e0OR1.END PROCz1;PROCz1(TEXT VARname):INT VARk6,v5,l6;z1(k6,v5,l6);IFv5>0THENname:=subtext(j1,o5,p5)ELSEname:=j0END IF
+END PROCz1;PROCy5(TEXT CONSTm6,n6):INT CONSTo6:=pos(j1,m6,x4),p6:=pos(j1,n6,x4);x4:=length(j1)+1;IFo6>0THENx4:=o6END IF;IFp6>0ANDp6<x4THENx4:=p6END IF END PROCy5;PROCu0(INT CONSTq6):toline(w4,q6);q5:=FALSE;v0:=eof(w4)END PROCu0;PROCw0:IFq5THENdown(w4)ELSEq5:=TRUE END IF;readrecord(w4,j1);x4:=1;v0:=lineno(w4)>=lines(w4)END PROCw0;BOOL PROCa1(INT VARq0):x4:=1;IF(j1SUB1)<>d5THEN FALSE ELIF(j1SUB2)<>d5THENr6;s6;TRUE ELSEq0:=m5;TRUE END IF.r6:TEXT VARt6;t5(k0);IFx4>length(j1)THENg6(z4,j1);q0:=0;LEAVEa1WITH TRUE END IF;INT CONSTu6:=pos(j1,k0,x4);IFu6=0THENt6:=subtext(j1,x4);t6CATk0;x4:=length(j1)+1ELSEt6:=subtext(j1,x4,u6);x4:=u6END IF.s6:INT CONSTv6:=pos(g5,t6);IFv6>0CAND(g5SUB(v6-2))=k0THENq0:=code(g5SUB(v6-1))ELSEq0:=0;g6(a5,t6);END IF.END PROCa1;PROCi1(INT VARw6):t5(k0);INT CONSTx6:=x4;WHILEy6REPx4INCR1END REP;IFx4>x6THENw6:=int(subtext(j1,x6,x4-1))ELSEw6:=-1END IF.y6:pos("0123456789",j1SUBx4)>0.END PROCi1;FILE VARz6;TEXT VARa7;BOOL VARb7;PROCc7(TEXT CONSTname):a7:=name;d7("PROC ",name,
+" :")END PROCc7;PROCe7:d7("END PROC ",a7,";")END PROCe7;PROCf7(TEXT CONSTg7):b7:=TRUE;putline(z6,g7)END PROCf7;PROCf7(TEXT CONSTh7,i7,j7):b7:=TRUE;d7(h7,i7,j7)END PROCf7;PROCd7(TEXT CONSTh7,i7,j7):write(z6,h7);write(z6,i7);write(z6,j7);line(z6)END PROCd7;TEXT VARk7;PROCf7(TEXT CONSTh7,INT CONSTl7,TEXT CONSTj7):k7:=subtext(j1,l7);f7(h7,k7,j7)END PROCf7;PROCm7(INT CONSTq6,n7):d7("; interpretiere (",text(q6)+", "+text(n7),", PROC (INT CONST, TEXT VAR) abk);")END PROCm7;LETo7=#405
+#"kein % WIEDERHOLUNG gefunden",p7=#406
+#"Nur GRUPPE-Anweisung erlaubt",q7=#407
+#"keine ELAN-Anweisung im Initialisierungsteil nach Gruppendefinition",r7=#408
+#"illegale Gruppennummer",s7=#409
+#"diese Gruppe wurde schon definiert",t7=#410
+#"diese Abkuerzung ist nicht definiert",u7=#411
+#"dieser Abschnitt wurde schon einmal definiert",v7=#412
+#"falscher Modus",w7=#413
+#"diese Anweisung darf im Musterteil nicht vorkommen",x7=#414
+#"im Abkuerzungsteil darf keine Anweisung auftreten",y7=#415
+#"in dieser Zeile stehen zu viele Feldmuster",z7=#416
+#"das Druckmuster enthaelt zu viele Feldmuster",a8=#417
+#"nach dem ""&"" soll direkt der Name einer Abkuerzung folgen",b8=#418
+#"kein Doppelpunkt nach Abkuerzung",c8=#419
+#"Abkuerzung mehrfach definiert",d8=#420
+#"das Druckmuster enthaelt zu viele Abkuerzungen";LETe8=200,f8=4,g8=250,GRUPPE=STRUCT(BOOLh8,i8,TEXTg0),ABSCHNITT=STRUCT(INTo0,n0,TEXTc7);ROWe8INT VARe2;INT VARj8;ROWf8GRUPPE VARk8;ROW3ABSCHNITT VARl8;SATZ VARp0;TEXT VARm8;INT VARn8;OP CAT(TEXT VARo8,INT CONSTwert):TEXT VARp8:=" ";replace(p8,1,wert);o8CATp8END OP CAT;PROCq8:enablestop;u0(1);r8;s8;WHILE NOTv0REPt8END REP;u8.r8:INT VARq0;INT VARv8;n8:=0;satzinitialisieren(p0);m8:=j0;j8:=0;b7:=FALSE;l8(1):=ABSCHNITT:(0,0,"vorspann");l8(2):=ABSCHNITT:(0,0,"wdh");l8(3):=ABSCHNITT:(0,0,"nachspann");FORv8FROM1UPTOf8REPk8(v8).i8:=FALSE END REP.s8:BOOL VARw8:=FALSE;REP IFv0THENg6(o7);LEAVEq8END IF;w0;IFa1(q0)THENx8END IF END REP.x8:SELECTq0OF CASEm5:y8CASEl5:z8CASEh5,i5,j5:IF NOTw8THENc7("gruppen")END IF;e7;LEAVEs8OTHERWISE IFq0>0THENg6(p7)END IF END SELECT.y8:IFw8THENg6(q7,j1)ELSEreplace(j1,1," ");f7(j1)END IF.z8:IF NOTw8THENc7("gruppen");w8:=TRUE END IF;INT VARa9;i1(a9);IFa9<1ORa9>f8THENg6(r7,j1)ELIFk8(a9).i8THENg6(s7,j1)ELSEk8(a9).i8:=TRUE
+;b9END IF.b9:f7("gruppentest (",text(a9),", ");f7(" ",x4,");").t8:SELECTq0OF CASEh5:c9CASEi5:d9CASEj5:e9END SELECT.c9:f9(l8(1),q0).d9:i1(g9);i1(h9);f9(l8(2),q0).e9:f9(l8(3),q0).u8:IFb7THENi9;j9END IF;k9;IFb7THENl9;m9END IF.k9:FORv8FROM1UPTOn8REP IF(m8ISUBv8)>0THENg6(t7,n9,m8ISUBv8)ELSEo9END IF END REP.n9:TEXT VARp9;feldlesen(p0,v8,p9);p9.i9:FORv8FROM1UPTO3REP IFl8(v8).n0=0THENq9END IF END REP.q9:c7(l8(v8).c7);e7.j9:f7("PROC abk (INT CONST nr, TEXT VAR inhalt) :");IFn8>0THENf7("SELECT nr OF")ELSEf7("inhalt := text (nr)")END IF.o9:TEXT CONSTr9:=text(v8);f7("CASE "+r9," : inhalt := abk",r9).l9:IFn8>0THENf7("END SELECT")END IF;f7("END PROC abk;").m9:f7("drucke (PROC gruppen, PROC vorspann, PROC wdh, PROC nachspann)").END PROCq8;PROCf9(ABSCHNITT VARs9,INT VARq0):BOOL VARt9:=TRUE;c7(s9.c7);u9;v9;w9.u9:IFs9.n0<>0THENg6(u7,j1)END IF;s9.n0:=r5+1;s9.o0:=j8+1.v9:WHILE NOTv0REPw0;IFa1(q0)THENx9ELSEy9;z9END IF END REP;a10;LEAVEf9.x9:SELECTq0OF CASEm5:replace(j1,1," ");f7(j1);t9:=TRUE
+CASEh5,i5,j5:a10;LEAVEf9CASEk5:a10;LEAVEv9CASEd1:y9;INT VARb10;i1(b10);IFb10<1ORb10>4THENg6(v7,j1)END IF CASEf1:y9OTHERWISE IFq0>0THENg6(w7)END IF END SELECT.y9:IFt9THENm7(r5,j8+1);t9:=FALSE END IF.a10:e7.z9:TEXT VARname;INT VARc10:=0;REPz1(name);IFname=j0THEN LEAVEz9END IF;c10INCR1;d10END REP.d10:IFc10>=b0THENg6(y7)END IF;IFj8=e8THENg6(z7)ELSEj8INCR1END IF;e10.e10:INT VARf10:=feldnummer(name);IFf10=0THENf10:=feldindex(p0,name);IFf10=0THENg10(name,r5);e2(j8):=-n8ELSEe2(j8):=-f10END IF ELSEe2(j8):=f10END IF.w9:BOOL VARh10:=TRUE;WHILE NOTv0REPw0;IFa1(q0)THENi10ELIFj10THENk10END IF END REP.i10:SELECTq0OF CASEh5,i5,j5:LEAVEw9OTHERWISE IFq0>0THENg6(x7)END IF END SELECT.k10:IFh10THENf7(".");h10:=FALSE END IF;IFl10THENm10ELSEf7(j1)END IF.l10:(j1SUB1)=b5.m10:TEXT VARn10;z1(n10);IFn10=j0THENg6(a8,j1);LEAVEm10END IF;o10;p10.o10:LETq10=":";x4DECR1;t5(k0);IF(j1SUBx4)=q10THENx4INCR1ELSEg6(b8,j1)END IF.p10:g10(n10,0);f7(r10,x4-1,"").r10:"abk"+text(feldindex(p0,n10)).j10:j1<>j0ANDj1<>k0.END PROCf9;
+PROCg10(TEXT CONSTname,INT CONSTq6):INT CONSTs10:=feldindex(p0,name);IFs10>0THENt10ELSEu10END IF.t10:IF(m8ISUBs10)>0THENreplace(m8,s10,q6)ELIFq6=0THENg6(c8,name)END IF.u10:IFn8=g8THENg6(d8)ELSEn8INCR1END IF;m8CATq6;feldaendern(p0,n8,name).END PROCg10;LETv10=#421
+#"FEHLER in Zeile ",w10=#422
+#" bei >>",x10=#423
+#"<<";PROCg6(TEXT CONSTy10,z10,INT CONSTq6):LETa11=" ";TEXT VARb11:=v10;b11CATtext(q6);IFz10<>j0THENb11CATw10;b11CATz10;b11CATx10END IF;note(b11);noteline;note(a11);note(y10);noteline;IFonlineANDcommanddialogueTHENline;putline(b11);put(a11);putline(y10)END IF END PROCg6;PROCg6(TEXT CONSTy10):g6(y10,j0,r5)END PROCg6;PROCg6(TEXT CONSTy10,z10):g6(y10,z10,r5)END PROCg6;LETc11=#424
+#"erzeugtes Programm",d11=#425
+#"keine Datei geoeffnet",e11=#426
+#"interner Fehler",f11=#427
+#"Druckausgabe steht in",g11=#428
+#"zum Drucker geschickt.",h11=#429
+#"direkt Drucken nicht moeglich",i11=#430
+#".a$";TEXT VARj11,k11;BOOL VARl11,m11,n11,o11;FILE VARp11;INT VARg9,h9,q11,r11,s11,t11:=4000,u11;PROCdrucke:drucke(lastparam)END PROCdrucke;PROCdrucke(TEXT CONSTv11):enablestop;lastparam(v11);w4:=sequentialfile(input,v11);modify(w4);IFanzahldateien=0THENerrorstop(d11)END IF;disablestop;w11;q8;IFanythingnotedTHENnoteedit(w4)ELIFb7THENx11ELSEdrucke(PROCy11,PROCz11,PROCa12,PROCb12)END IF;forget(c12,quiet).w11:TEXT VARc12;INT VARv8:=0;REPv8INCR1;c12:=text(v8)UNTIL NOTexists(c12)END REP;z6:=sequentialfile(output,c12);headline(z6,c11).x11:run(c12);lastparam(v11).END PROCdrucke;PROCy11:END PROCy11;PROCz11:d12(1)END PROCz11;PROCa12:d12(2)END PROCa12;PROCb12:d12(3)END PROCb12;PROCd12(INT CONSTe12):IFl8(e12).n0>0THENinterpretiere(l8(e12).n0,l8(e12).o0,PROC(INT CONST,TEXT VAR)f12)END IF END PROCd12;PROCf12(INT CONSTe12,TEXT VARg0):errorstop(e11);g0:=code(e12)END PROCf12;PROCdrucke(PROCg12,PROCh12,PROCi12,PROCj12):INT VARk12,l12,m12;enablestop;n12;o12;p12;u11:=1;WHILE NOTdateiendeREPq12;cout(
+satznummer);r12;weiter(k12);s12END REP;t12;u12;aufsatz(1).o12:l12:=0;aufsatz(1);IFmarkiertesaetze>0THENk12:=3;IF NOTsatzmarkiertTHENweiter(k12)END IF ELSEk12:=2;IF NOTsatzausgewaehltTHENweiter(k12)END IF END IF.p12:INT VARv8;FORv8FROM1UPTOf8REPk8(v8).g0:=j0END REP.q12:IFl12=0THENg12;v12;w12(PROCh12)ELSEm11:=FALSE;x12;y12END IF;l12:=satznummer;m12:=satzkombination.x12:l11:=FALSE;g12.y12:IFl11THENz12(l12,m12,PROCj12)END IF;u11INCR1;IFl11THENw12(PROCh12)END IF.r12:IFh9<1THENs5ELSEn5:=h9END IF;IFq11<g9THENtoline(p11,r11)ELSEtoline(p11,s11+1);r11:=s11+1;q11:=0END IF;i0:=1;i12;q11INCR1.s12:IFs11>t11THENu12;n12END IF.t12:v12;IFl12=0THENw12(PROCj12)ELSEz12(l12,m12,PROCj12)END IF;u0(1).END PROCdrucke;PROCv12:INT VARv8;FORv8FROM1UPTOf8REPk8(v8).h8:=TRUE END REP;m11:=TRUE;l11:=TRUE END PROCv12;PROCw12(PROCs9):q11:=g9;toline(p11,s11+1);s5;i0:=1;s9END PROCw12;PROCz12(INT CONSTl12,m12,PROCj12):INT CONSTa13:=satznummer,b13:=satzkombination;aufsatz(l12);WHILEsatzkombination<>m12REPweiter(1)END REP;w12
+(PROCj12);aufsatz(a13);WHILEsatzkombination<>b13REPweiter(1)END REP END PROCz12;PROCn12:IFaktuellereditor>0THENc13ELSEd13END IF;e13.c13:p11:=editfile;IFcol>1THENsplitline(p11,col,FALSE);down(p11);col(p11,1)END IF;s11:=lineno(p11)-1.d13:IF NOTn11THENf13END IF;p11:=sequentialfile(modify,k11);maxlinelength(p11,maxlinelength(w4));s11:=lines(p11).f13:INT VARr4:=0;REPr4INCR1;k11:=headline(w4)+i11+text(r4);UNTIL NOTexists(k11)END REP.e13:u0(1);WHILE NOTv0REPg13END REP.g13:w0;INT VARq0;IFa1(q0)THENh13ELSEh1(j1)END IF.h13:IFq0<>m5ANDq0<>l5THEN LEAVEe13END IF.END PROCn12;PROCu12:IFaktuellereditor>0THEN ELIFn11THENn11:=FALSE;ELIFo11THENdisablestop;i13ELSEline;put(f11);putline(textdarstellung(k11));pause(40)END IF.i13:TEXT CONSTw6:=std;lastparam(k11);do("print (std)");IFiserrorTHENclearerror;errorstop(h11)ELSEline;put(textdarstellung(k11));putline(g11);forget(k11,quiet);pause(40)END IF;lastparam(w6).END PROCu12;PROCh1(TEXT CONSTq6):IFq11>=g9ORq11=0THENinsertrecord(p11);writerecord(p11,q6);s11INCR1
+ELSEj13END IF;down(p11).j13:IFeof(p11)THENj11:=j0;insertrecord(p11);s11INCR1ELSEreadrecord(p11,j11)END IF;k13;writerecord(p11,j11).k13:INT CONSTl13:=n5*q11;WHILElength(j11)<l13REPj11CATk0END REP;j11CATq6.END PROCh1;PROCdirektdrucken(BOOL CONSTk12):o11:=k12END PROCdirektdrucken;BOOL PROCdirektdrucken:o11END PROCdirektdrucken;PROCdruckdatei(TEXT CONSTv11):k11:=v11;n11:=TRUE END PROCdruckdatei;TEXT PROCdruckdatei:k11END PROCdruckdatei;PROCmaxdruckzeilen(INT CONSTm13):t11:=m13END PROCmaxdruckzeilen;PROCgruppentest(INT CONSTa9,TEXT CONSTn13):IFn13<>k8(a9).g0THENk8(a9).g0:=n13;k8(a9).h8:=TRUE;l11:=TRUE ELSEk8(a9).h8:=FALSE END IF END PROCgruppentest;BOOL PROCgruppenwechsel(INT CONSTa9):IFa9>0THENk8(a9).h8ELSEm11END IF END PROCgruppenwechsel;TEXT PROClfdnr:text(u11)END PROClfdnr;END PACKETeudasdrucken;
+
diff --git a/eudas/eudas.3 b/eudas/eudas.3
new file mode 100644
index 0000000..98f0fae
--- /dev/null
+++ b/eudas/eudas.3
@@ -0,0 +1,58 @@
+PACKETfensterDEFINES FENSTER,fensterinitialisieren,fenstergroessesetzen,fenstergroesse,fensterveraendert,fensterzugriff,bildschirmneu:TYPE FENSTER=STRUCT(INTb0,c0);LETd0=16,BITVEKTOR=INT,GROESSE=STRUCT(INTe0,f0,g0,h0);ROWd0STRUCT(INTi0,j0,BITVEKTORk0,GROESSEl0)VARm0;INT VARn0:=1;BITVEKTOR VARo0;INT VARp0;FORp0FROM2UPTOd0REPm0(p0).i0:=0END REP;m0(1).i0:=1;m0(1).j0:=0;m0(1).k0:=0;m0(1).l0:=GROESSE:(1,1,79,24);PROCfensterinitialisieren(FENSTER VARf):f.b0:=1;m0(1).i0INCR1;f.c0:=n0;n0INCR1;IFn0>=32000THENn0:=-32000END IF END PROCfensterinitialisieren;PROCfenstergroessesetzen(FENSTER VARf,INT CONSTe0,f0,g0,h0):INT VARq0;r0;IFq0>d0THENs0;t0;u0END IF;v0.r0:q0:=1;WHILEq0<=d0REP IFw0THEN LEAVEr0END IF;q0INCR1END REP.w0:x0.e0=e0ANDx0.f0=f0ANDx0.g0=g0ANDx0.h0=h0.x0:m0(q0).l0.s0:q0:=1;WHILEq0<=d0REP IFm0(q0).i0=0THEN LEAVEs0END IF;q0INCR1END REP;errorstop("zu viele Fenstergroessen");LEAVEfenstergroessesetzen.t0:m0(q0).i0:=0;m0(q0).j0:=0;m0(q0).l0:=GROESSE:(e0,f0,g0,h0);m0(q0).k0:=0.u0:INT VARy0;FOR
+y0FROM1UPTOd0REP IFm0(y0).i0>0THENz0END IF END REP.z0:IFa1(b1,c1)THENsetbit(m0(q0).k0,y0);setbit(m0(y0).k0,q0)ELSEresetbit(m0(y0).k0,q0)END IF.b1:m0(q0).l0.c1:m0(y0).l0.v0:m0(f.b0).i0DECR1;f.b0:=q0;m0(q0).i0INCR1.END PROCfenstergroessesetzen;BOOL PROCa1(GROESSE CONSTa,d1):e1ANDf1.e1:IFa.e0<=d1.e0THENd1.e0<a.e0+a.g0ELSEa.e0<d1.e0+d1.g0END IF.f1:IFa.f0<=d1.f0THENd1.f0<a.f0+a.h0ELSEa.f0<d1.f0+d1.h0END IF.END PROCa1;PROCfenstergroesse(FENSTER CONSTf,INT VARe0,f0,g0,h0):e0:=x0.e0;f0:=x0.f0;g0:=x0.g0;h0:=x0.h0.x0:m0(f.b0).l0.END PROCfenstergroesse;PROCfensterveraendert(FENSTER CONSTf):m0(f.b0).j0:=0;o0:=o0ORg1.g1:m0(f.b0).k0.END PROCfensterveraendert;PROCfensterzugriff(FENSTER CONSTf,BOOL VARh1):h1:=bit(o0,f.b0);IFm0(f.b0).j0<>f.c0THENm0(f.b0).j0:=f.c0;h1:=TRUE END IF;o0:=o0ORg1;resetbit(o0,f.b0).g1:m0(f.b0).k0.END PROCfensterzugriff;PROCbildschirmneu:o0:=-1END PROCbildschirmneu;ROW16INT VARi1:=ROW16INT:(1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,-32767-1);PROCsetbit(BITVEKTOR
+VARj1,INT CONSTq0):j1:=j1ORi1(q0)END PROCsetbit;PROCresetbit(BITVEKTOR VARj1,INT CONSTq0):j1:=j1AND(-1-i1(q0))END PROCresetbit;BOOL PROCbit(BITVEKTOR CONSTj1,INT CONSTq0):(j1ANDi1(q0))<>0END PROCbit;END PACKETfenster;
+PACKETeudasmenuesDEFINES
+##globalmanager,menuemanager,
+##lock,free,menuedateneinlesen,menuenamen,menueloeschen,waehlbar,ausfuehrtaste,menueanbieten,auswahlanbieten,wahl,eschopausfuehren,hilfeanbieten,statusanzeigen,dialogfenster,dialogfensterloeschen,dialog,neuerdialog,ja,editget,fehlerausgeben:ROW8TEXT VARb0:=ROW8TEXT:("MENUE","BILD","FELD","ENDE","AUSWAHL","VORSPANN","HILFE","SEITE");LETc0=1,d0=2,e0=3,f0=4,g0=5,h0=6,i0=7,j0=8;LETk0=2,integer=3,l0=4,m0=7;LETn0=#701
+#"FEHLER in Zeile ";FILE VARo0;TEXT VARp0,q0;PROCr0:IFeof(o0)THENp0:="%DUMMY"ELSEreadrecord(o0,p0);IFp0=s0THENp0:=t0END IF;cout(lineno(o0));down(o0)END IF END PROCr0;BOOL PROCu0:IF(p0SUB1)=v0THENw0ELSE FALSE END IF.w0:INT VARx0;replace(p0,1,t0);scan(p0);replace(p0,1,v0);nextsymbol(q0,x0);IFx0<>k0THENy0(z0);FALSE ELSE TRUE END IF.END PROCu0;BOOL PROCa1(INT CONSTb1):b0(b1)=q0END PROCa1;INT PROCc1:TEXT VARd1;INT VARx0;nextsymbol(d1,x0);IFx0=integerTHENint(d1)ELSE IFx0<>m0THENy0(e1)END IF;-1END IF END PROCc1;TEXT PROCf1:TEXT VARd1;INT VARx0;nextsymbol(d1,x0);IFx0=l0THENd1ELSE IFx0<>m0THENy0(g1)END IF;s0END IF END PROCf1;PROCy0(TEXT CONSTh1):note(n0);note(lineno(o0)-1);noteline;note(h1);noteline;line;putline(h1)END PROCy0;INT VARi1,j1,k1,l1;PROCm1(INT CONSTn1,o1):cursor(k1+n1-1,l1+o1-1)END PROCm1;LETp1=#702
+#"Zeile ist ohne Zusammenhang",q1=#703
+#"K Menuedaten im Speicher";PROCmenuedateneinlesen(TEXT CONSTr1):s1;o0:=sequentialfile(input,r1);modify(o0);toline(o0,1);WHILE NOTeof(o0)REPr0;IFu0THENt1ELIF NOTanythingnotedTHENy0(p1)END IF END REP;u1;IFanythingnotedTHENnoteedit(o0)END IF.t1:IFa1(c0)THENv1ELIFa1(g0)THENw1ELIFa1(i0)THENx1ELIF NOTanythingnotedTHENy0(p1)END IF.u1:IFonlineTHENline;put(y1DIV2);putline(q1)END IF.y1:dspages(z1(1))+dspages(z1(2))+dspages(z1(3)).END PROCmenuedateneinlesen;TYPE MENUE=STRUCT(SATZa2,b2,c2,TEXTd2,e2);BOUND ROW200MENUE VARf2;TEXT VARg2,h2;SATZ VARi2,j2;LETs0="",t0=" ",k2=" ",l2=2,v0="%",m2=""7"",n2=""27"",o2=""5"";LETp2=#704
+#"% BILD erwartet",q2=#705
+#"Feldnummer beim %FELD-Kommando fehlt",r2=#706
+#"% ENDE erwartet",s2=#707
+#"Name fehlt",z0=#708
+#"Kommandozeile enthaelt kein Kommando",e1=#709
+#"Parameter soll eine Zahl sein",g1=#710
+#"Parameter soll ein TEXT sein",t2=#711
+#"Wiederholungszeile fehlt";PROCv1:TEXT VARname:=f1;IFname=s0THENy0(s2)ELSE INT VARindex;u2;v1(f2(index))END IF.u2:index:=link(v2(2),name);IFindex=0THENinsert(v2(2),name,index)END IF.END PROCv1;PROCv1(MENUE VARw2):x2;y2;z2;a3;b3.x2:satzinitialisieren(w2.a2);satzinitialisieren(i2);satzinitialisieren(j2);h2:=s0;g2:=s0.y2:c3;INT VARd3:=1;REPr0;IFu0THEN LEAVEy2ELSEe3;d3INCR1END IF END REP.c3:r0;IF NOT(u0CANDa1(d0))THENy0(p2)END IF.e3:IF(p0SUBl2)=k2THENg2CATcode(d3);replace(p0,l2,t0)END IF;feldaendern(w2.a2,d3,p0).z2:WHILEa1(e0)REPf3END REP.f3:INT VARg3:=c1;IFg3=-1THENy0(q2);g3:=100END IF;h3;i3;j3.h3:feldaendern(i2,g3,f1).i3:TEXT CONSTk3:=f1;INT VARl3;FORl3FROM1UPTOlength(k3)REPh2CATcode(g3);h2CAT(k3SUBl3)END REP.j3:TEXT VARm3:=s0;r0;WHILE NOTu0REPm3CATp0;r0END REP;feldaendern(j2,g3,m3).a3:IF NOTa1(f0)THENy0(r2)END IF.b3:w2.b2:=i2;w2.c2:=j2;w2.d2:=h2;w2.e2:=g2.END PROCv1;LETn3=#712
+#"Kommando wird ausgeführt ..",o3=#713
+#""15"Gib Kommando: ",p3=#714
+#"falsche Ausfuehrtaste",q3=#715
+#" existiert nicht.";LETr3=" ",s3=""15"",t3=""14"",u3="*"8"";INT VARv3:=0,w3,x3;BOOL VARy3,z3;TEXT VARa4,b4,c4:=" "1""2""3""8""10""13""27"",d4,e4:=s0;ROW6TEXT VARf4;FENSTER VARg4;fensterinitialisieren(g4);fenstergroessesetzen(g4,1,1,79,1);PROCwaehlbar(INT CONSTh4,i4,BOOL CONSTj4):IFj4THENk4ELSEl4END IF;y3:=TRUE.k4:IFlength(f4(h4))>=i4THENreplace(f4(h4),i4," ")END IF.l4:WHILElength(f4(h4))<i4REPf4(h4)CAT" "END REP;replace(f4(h4),i4,"-").END PROCwaehlbar;PROCausfuehrtaste(TEXT CONSTm4):IFlength(m4)<>1CORn4THENerrorstop(p3)ELSEreplace(c4,1,m4)END IF.n4:m4<>""13""ANDpos(c4,m4,2)>0.END PROCausfuehrtaste;PROCmenueanbieten(ROW6TEXT CONSTmenuenamen,FENSTER VARf,BOOL CONSTo4,PROC(INT CONST,INT CONST)p4):ROW6INT VARq4,r4,s4;INT VARt4,u4:=0,v4:=1,w4:=0,x4;TEXT VARy4;ROW6TEXT VARz4;s1;a5;b5;disablestop;REPc5;d5;e5END REP.a5:v3INCR1;INT CONSTf5:=v3;y4:=""6""0""0"";g5;h5;y4CATo2.g5:INT VARi5:=pos(menuenamen(1),".");IFi5>0THENy4CATsubtext(menuenamen(1),1,i5-1)END IF;y4CAT": "
+.h5:x4:=0;WHILEx4<6CANDj5REPx4INCR1;k5;s4(x4):=1END REP.j5:menuenamen(x4+1)<>s0.k5:q4(x4):=length(y4);i5:=pos(menuenamen(x4),".");IFi5=0THENy4CATmenuenamen(x4)ELSEy4CATsubtext(menuenamen(x4),i5+1)END IF;y4CAT" ";r4(x4):=length(y4)-1.b5:INT VARl5;FORl5FROM1UPTO6REPf4(l5):=s0END REP;y3:=TRUE;p4(0,0).c5:IFv4>0THENm5;n5;u4:=v4;v4:=0;o5ELIFv3<>f5THENa4:=y4;f4:=z4;v3:=f5ELIFy3THENz4:=f4END IF.m5:IFu4>0THENreplace(y4,q4(u4)," ");replace(y4,r4(u4)," ");IFz3THENp4(u4,-1)END IF END IF.n5:replace(y4,q4(v4),s3);replace(y4,r4(v4),t3);fensterveraendert(g4);a4:=y4;p5.o5:t4:=link(v2(2),menuenamen(u4));IFt4=0THENq5(menuenamen(u4));LEAVEmenueanbietenEND IF;z3:=FALSE;y3:=TRUE;fensterveraendert(f).d5:w4:=u4;r5(f2(t4),f,w4,s4(u4),PROC(INT CONST,INT CONST)p4).e5:SELECTw4OF CASE0:s5CASE1:t5CASE2:u5CASE3:v5CASE4:w5OTHERWISEx5END SELECT.u5:IFu4<x4THENv4:=u4+1ELSEv4:=1END IF.v5:IFu4>1THENv4:=u4-1ELSEv4:=x4END IF.x5:w4:=w4-10;IFw4<=x4THENv4:=w4END IF.t5:IFo4THEN BOOL VARy5:=FALSE;REPz5;a6UNTILb6END REP;IFy5
+THENbildschirmneu;dialogfensterloeschen;p4(u4,-2)END IF END IF.a6:IFc6THENy5:=TRUE;statusanzeigen(n3);cursor(1,2);out(d6);do(d4)END IF.c6:pos(d4,"!","�",1)>0.b6:NOTiserror.s5:IFz3THENp4(u4,-1)END IF;fensterveraendert(f);LEAVEmenueanbieten.w5:IFs4(u4)>0THENp4(t4,s4(u4))ELSEs4(u4):=-s4(u4)END IF.END PROCmenueanbieten;PROCp5:BOOL VARe6;fensterzugriff(g4,e6);IFe6THENout(a4)END IF END PROCp5;PROCr5(MENUE CONSTw2,FENSTER VARf,INT VARf6,wahl,PROC(INT CONST,INT CONST)p4):INT VARg6:=0;h6;i6(f);IFx3=0THENw3:=0END IF;neuerdialog;j6;REPp5;k6;l6END REP.h6:IFwahl>length(w2.e2)THENwahl:=w3;ELIFiserrorTHENfehlerausgeben;p4(f6,-2);END IF.j6:IFy3THENm6;n6;y3:=FALSE END IF.m6:b4:=r3;INT VARl5;FORl5FROM1UPTOlength(f4(f6))REPreplace(b4,code(w2.e2SUBl5),f4(f6)SUBl5)END REP.n6:INT VARo6;FORo6FROM1UPTOlength(w2.e2)REP INT CONSTp6:=code(w2.e2SUBo6);IFp6>x3THEN LEAVEn6END IF;q6(w2.a2,p6)END REP.k6:REPr6;IFiserrorTHENs6ELSE LEAVEk6END IF END REP.r6:TEXT VARt6;BOOL VARu6:=FALSE;WHILEx3<i1REPt6:=getcharety;v6END
+REP;w6;x6(w2,wahl);y6(t6).v6:IFt6=s0THENz6;x3INCR1;a7ELSE LEAVEr6END IF.z6:IF NOTz3ANDx3=0THENp4(f6,0);z3:=TRUE END IF.a7:IFx3=code(w2.e2SUBwahl)THENb7(w2.a2,x3,TRUE);w3:=wahlELSEb7(w2.a2,x3,FALSE)END IF;IFx3=i1THENu6:=TRUE END IF.w6:IFu6AND NOTiserrorTHENp4(f6,-2);IFiserrorTHENclearerrorEND IF END IF.s6:fehlerausgeben;p5;x3:=0.l6:INT VARc7;SELECTg6OF CASE0:d7CASE1:e7CASE2:f7END SELECT.d7:SELECTpos(c4,t6)OF CASE1:g7CASE2:g6:=1CASE3:h7CASE4:i7CASE5:j7CASE6:k7CASE7:l7CASE8:g6:=2OTHERWISEm7END SELECT.e7:SELECTpos(""1""3""10"",t6)OF CASE1:n7CASE2:o7CASE3:p7OTHERWISEout(m2)END SELECT;g6:=0.f7:SELECTpos(""1""27"?qh",t6)OF CASE1:eschopausfuehrenCASE2:q7CASE3:r7CASE4,5:s7OTHERWISEt7END SELECT;g6:=0.h7:w4:=2;LEAVEr5.i7:IFwahl>1THENwahlDECR1ELSEwahl:=length(w2.e2)END IF.j7:w4:=3;LEAVEr5.k7:IFwahl<length(w2.e2)THENwahlINCR1ELSEwahl:=1END IF.l7:k7.m7:IFu7THENv7ELIFw7THENx7ELIFt6<=" "THENpush(n2+t6)END IF.u7:pos("123456",t6)>0.v7:w4:=code(t6)-38;LEAVEr5.w7:c7:=0;REPc7:=pos(w2.d2,t6,c7+1)UNTIL(c7MOD
+2)=0END REP;c7>0ANDy7.y7:code(w2.d2SUBc7-1)<=length(w2.e2).x7:wahl:=code(w2.d2SUBc7-1);x6(w2,wahl);IF(f4(f6)SUBwahl)<>"-"THENz7(w2,wahl,x3);w4:=4;LEAVEr5END IF.n7:wahl:=1.o7:wahl:=1.p7:wahl:=length(w2.e2).t7:IFa8THENwahl:=code(w2.d2SUBc7-1);w4:=4;LEAVEr5ELSEpush(lernsequenzauftaste(t6))END IF.a8:c7:=0;REPc7:=pos(w2.d2,t6,c7+1)UNTIL(c7MOD2)=0CAND(c7=0CORb8)END REP;c7>0.b8:code(w2.d2SUBc7-1)>length(w2.e2).q7:w4:=1;LEAVEr5.r7:TEXT VARc8;feldlesen(w2.b2,wahl,c8);hilfeanbieten(c8,d8);IFiserrorTHENfehlerausgebenEND IF;p4(f6,-2);i6(f).s7:w4:=0;LEAVEr5.g7:IF(f4(f6)SUBwahl)<>"-"THENz7(w2,wahl,x3);w4:=4;LEAVEr5END IF.w4:f6.END PROCr5;PROCi6(FENSTER CONSTf):BOOL VARe6;fensterzugriff(f,e6);fenstergroesse(f,k1,l1,j1,i1);IFe6THENx3:=0;m1(1,1)END IF END PROCi6;PROCx6(MENUE CONSTw2,INT CONSTwahl):INT CONSTe8:=code(w2.e2SUBwahl);IFw3>0THEN IFw3=wahlTHENq6(w2.a2,e8)ELSE INT CONSTf8:=code(w2.e2SUBw3);b7(w2.a2,f8,FALSE);b7(w2.a2,e8,TRUE);w3:=wahlEND IF END IF;m1(1,e8)END PROCx6;PROCy6(TEXT VARg8):
+enablestop;getchar(g8)END PROCy6;PROCz7(MENUE CONSTw2,INT VARwahl,INT CONSTx3):INT CONSTl1:=code(w2.e2SUBwahl);IFh8THENi8END IF;TEXT VARm3;feldlesen(w2.c2,wahl,m3);IFm3<>s0ANDm3<>t0THENdo(m3);bildschirmneu;wahl:=-wahlEND IF.h8:x3>=l1.i8:m1(1,l1);out(u3).END PROCz7;PROCeschopausfuehren:TEXT VARj8:=s0,k8;lernsequenzauftastelegen(""0"",s0);push(""27""1""0""0"");editget(j8,32000,0,""0"","",k8);j8:=lernsequenzauftaste(""0"");IFj8<>s0THENl8ELSEm8END IF.l8:REPgetchar(k8)UNTILpos(""1""2""8""11""12"",k8)=0END REP;lernsequenzauftastelegen(k8,j8).m8:getchar(k8).END PROCeschopausfuehren;INT VARn8,o8,p8;PROCq6(SATZ CONSTa2,INT CONSTq8):m1(1,q8);IF(b4SUBq8)<>t0THENout(b4SUBq8)ELSEfeldbearbeiten(a2,q8,PROC(TEXT CONST,INT CONST,INT CONST)r8)END IF END PROCq6;PROCr8(TEXT CONSTs8,INT CONSTn8,o8):out(s8SUBn8+o8-o8)END PROCr8;PROCb7(SATZ CONSTa2,INT CONSTd3,BOOL CONSTt8):enablestop;IFt8THENq6(a2,d3);out(s3);n8:=3;p8:=1;ELSEm1(1,d3);IF(b4SUBd3)="-"THENout("-");n8:=2ELSEn8:=1END IF;p8:=0END IF;u8(a2,d3)END
+PROCb7;PROCb7(SATZ CONSTa2,INT CONSTd3):n8:=1;p8:=0;u8(a2,d3)END PROCb7;PROCu8(SATZ CONSTa2,INT CONSTd3):IFd3<=felderzahl(a2)THENv8ELSEo8:=0END IF;w8.v8:feldbearbeiten(a2,d3,PROC(TEXT CONST,INT CONST,INT CONST)x8).w8:IFk1+j1>=80ANDp8=0THENout(o2)ELSEj1-o8-p8-1TIMESOUTt0;y8;out(":")END IF.y8:IFp8>0THENout(t3)END IF.END PROCu8;PROCx8(TEXT CONSTz8,INT CONSTa9,b9):INT CONSTc9:=a9-1;n8INCRc9;o8:=min(b9,j1+c9-p8-1);outsubtext(z8,n8,o8);o8DECRc9END PROCx8;PROCz5:LETd9=""27"k";TEXT VARe9;fensterveraendert(g4);f9;g9;REPh9UNTILe9<>d9END REP;IFpos(d4,"!","�",1)>0THENe4:=d4END IF.f9:IFiserrorTHENfehlerausgeben;d4:=e4ELSEd4:=s0END IF.g9:cursor(1,1);out(o3);j1-15TIMESOUTt0;out(t3).h9:cursor(16,1);editget(d4,32000,62,"","kh",e9);IFiserrorTHENclearerrorELIFe9=d9THENd4:=e4ELIFe9=i9THENd4:=s0END IF.END PROCz5;PROCq5(TEXT CONSTr1):errorstop(textdarstellung(r1)+q3)END PROCq5;TYPE AUSWAHL=STRUCT(SATZj9,k9,l9,TEXTm9,n9,o9);BOUND ROW200AUSWAHL VARp9;PROCw1:TEXT VARname:=f1;IFname=s0THENy0(s2)ELSE INT VAR
+index:=link(v2(3),name);IFindex=0THENinsert(v2(3),name,index)END IF;w1(p9(index))END IF END PROCw1;PROCw1(AUSWAHL VARa):x2;IFq9THENr9END IF;y2;s9.x2:satzinitialisieren(a.j9);satzinitialisieren(a.k9);satzinitialisieren(a.l9);a.m9:=s0;a.n9:=s0;a.o9:=s0.q9:r0;u0CANDa1(h0).r9:INT VARd3:=1;REPr0;IFu0THEN LEAVEr9ELSEt9;d3INCR1END IF END REP.t9:feldaendern(a.j9,d3,p0).y2:c3;d3:=1;BOOL VARu9:=TRUE;REPr0;IFu0THENv9;LEAVEy2ELSEe3;d3INCR1END IF END REP.c3:IF NOT(u0CANDa1(d0))THENy0(p2)END IF.v9:IFu9THENy0(t2)END IF.e3:IFu9THENw9ELSEx9END IF.w9:IFpos(p0,k2)>0THENy9;d3:=0;u9:=FALSE ELSEfeldaendern(a.k9,d3,p0)END IF.y9:z9;a.m9:=p0;a10.z9:INT VARb10:=0;REPb10:=pos(p0,k2,b10+1);IFb10>0THENa.n9CATcode(b10)END IF UNTILb10=0END REP.a10:FORb10FROM1UPTOlength(a.n9)-1REPa.o9CATcode(c10-4)END REP;a.o9CAT""0"".c10:code(a.n9SUBb10+1)-code(a.n9SUBb10).x9:feldaendern(a.l9,d3,p0).s9:IF NOTa1(f0)THENy0(r2)END IF.END PROCw1;LETd10=""1""8""10"",e10="+"27"q";LETf10=#716
+#"Fenster zu klein",g10=#717
+#"AUSWAHL: Ankreuzen: 'x' Durchstreichen: 'o' Beenden: ESC q Hilfe: ESC ?";INT VARh10,i10,j10,k10,l10,m10,n10,o10;LET INTVEC=TEXT;INTVEC VARp10;TEXT VARq10;PROCauswahlanbieten(TEXT CONSTname,FENSTER CONSTf,TEXT CONSTr10,PROC(TEXT VAR,INT CONST)s10):s1;INT CONSTindex:=link(v2(3),name);IFindex=0THENq5(name)ELSEr5(p9(index),f,r10,PROC(TEXT VAR,INT CONST)s10)END IF END PROCauswahlanbieten;PROCr5(AUSWAHL CONSTa,FENSTER CONSTf,TEXT CONSTr10,PROC(TEXT VAR,INT CONST)s10):INT VARx3:=0,g6:=0;enablestop;t10;statusanzeigen(g10);u10;v10;w10;REPk6;x10END REP.t10:BOOL VARy10;fensterzugriff(f,y10);fenstergroesse(f,k1,l1,j1,i1).u10:INT VARz10:=1024;h10:=z10;REPz10:=z10DIV2;s10(p0,h10);IFp0=s0THENh10DECRz10ELSEh10INCRz10END IF UNTILz10=1END REP;s10(p0,h10);IFp0=s0THENh10DECR1END IF.w10:INT VARa11:=k10+1,b11:=1,c11:=1;p10:=s0;q10:=a.n9.v10:j10:=felderzahl(a.j9);k10:=j10+felderzahl(a.k9);i10:=length(a.n9);l10:=(h10+i10-1)DIVi10;m10:=k10+l10;n10:=m10+felderzahl(a.l9);o10:=0;IFk10>=i1THENerrorstop(f10)
+END IF.k6:REPr6;IFiserrorTHENclearerror;x3:=0ELSE LEAVEk6END IF END REP.r6:TEXT VARt6;WHILEx3<i1REPt6:=getcharety;v6END REP;x6;y6(t6).v6:IFt6=s0THENx3INCR1;d11ELSE LEAVEr6END IF.d11:INT CONSTe11:=x3+o10;m1(1,x3);IFx3<=j10THENb7(a.j9,x3)ELIFe11<=k10THENb7(a.k9,e11-j10)ELIFe11<=m10THENf11ELSEb7(a.l9,e11-m10)END IF.f11:g11(a,h11,PROC(TEXT VAR,INT CONST)s10).h11:(e11-k10-1)*i10+1.x6:m1(code(q10SUBb11),a11).x10:SELECTg6OF CASE0:d7CASE1:e7CASE2:f7END SELECT.d7:SELECTpos(""1""2""3""8""9""10""13""27" +x-o",t6)OF CASE1:g6:=1CASE2:h7CASE3:i7CASE4:j7CASE5:i11CASE6:k7CASE7:l7CASE8:g6:=2CASE9:j11CASE10,11:k11CASE12,13:l11OTHERWISEm7END SELECT.e7:SELECTpos(""1""2""3""8""10""13"+x-o",t6)OF CASE1:n7CASE2:m11CASE3:o7CASE4:n11CASE5:p7CASE6:o11CASE7,8:p11CASE9,10:q11OTHERWISEout(m2)END SELECT;g6:=0.f7:SELECTpos(""1"19?qh",t6)OF CASE1:eschopausfuehrenCASE2:r11CASE3:s11CASE4:r7CASE5:s7CASE6:errorstop(s0)OTHERWISEt7END SELECT;g6:=0.h7:IFb11<i10ANDc11<h10THENb11INCR1;c11INCR1END IF.i7:IFc11>i10THENa11DECR1;
+c11DECRi10;IFa11<=j10THENa11INCR1;o10DECR1;x3:=j10END IF END IF.j7:IFb11>1THENb11DECR1;c11DECR1END IF.i11:IFb11=i10THENpush(""13"")ELSEpush(""1""2"")END IF.k7:IFc11+i10<=h10THENa11INCR1;c11INCRi10;IFa11>i1THENa11DECR1;o10INCR1;x3:=j10END IF END IF.l7:IFa11+o10<m10THENpush(d10)END IF.j11:push(e10).k11:IFt11(c11)=0ANDc11<=h10THENp10CATc11;IFa11<=x3THENu11(a11,b11,length(p10)DIV2)END IF END IF.l11:INT CONSTv11:=t11(c11);IFv11>0THENw11;x11END IF.w11:change(p10,2*v11-1,2*v11,s0).m7:IFt6<t0THENpush(lernsequenzauftaste(t6))ELSEout(m2)END IF.n7:n11;y11.m11:WHILEc11<h10ANDb11<i10REPc11INCR1;b11INCR1END REP.o7:IFa11=j10+1THENz11ELSEy11END IF.z11:INT VARa12:=min(i1-j10,o10);o10DECRa12;INT CONSTb12:=c12;a11INCRb12;c11DECR(a12-b12)*i10;IFa12>0THENx3:=j10END IF.c12:max(0,k10-j10-o10).y11:WHILEc11>i10ANDa11>j10+1REPa11DECR1;c11DECRi10END REP.n11:c11DECR(b11-1);b11:=1.p7:IFa11=i1THENd12ELSEe12END IF.d12:a12:=min(i1-j10,n10-a11-o10);o10INCRa12;INT CONSTf12:=max(0,a11+o10-m10+g12);a11DECRf12;c11INCR(a12
+-f12)*i10;IFa12>0THENx3:=j10END IF.g12:IFb11-1>h10MODi10THEN1ELSE0END IF.e12:WHILEa11<i1ANDc11+i10<=h10REPa11INCR1;c11INCRi10END REP.o11:o10INCR(a11-j10-1);a11:=j10+1;x3:=j10.p11:INT VARh12;FORh12FROM1UPTOh10REP IFt11(h12)=0THENp10CATh12END IF END REP;x11.q11:p10:=s0;x11.r7:hilfeanbieten(r10,f);statusanzeigen(g10);x3:=0.s7:LEAVEr5.t7:push(lernsequenzauftaste(t6)).r11:a11:=k10+1;c11:=1;b11:=1;o10:=0;x3:=j10.s11:IFm10<=i1THENa11:=m10ELSEa11:=max(j10+1,i1+m10-n10)END IF;o10:=m10-a11;b11:=(h10-1)MODi10+1;c11:=h10;x3:=j10.END PROCr5;PROCx11:INT VARg8,i12,h12;h12:=j12;FORg8FROMk12UPTOl12REP FORi12FROM1UPTOi10REPu11(g8,i12,t11(h12));h12INCR1END REP END REP.j12:max(0,o10-k10+j10)*i10+1.k12:max(j10,k10-o10)+1.l12:min(i1,m10-o10).END PROCx11;TEXT VARm12:="xx";INT PROCt11(INT CONSTn12):replace(m12,1,n12);INT VARl3:=0;REPl3:=pos(p10,m12,l3+1)UNTILl3=0ORl3MOD2=1END REP;(l3+1)DIV2END PROCt11;OP CAT(INTVEC VARo12,INT CONSTwert):replace(m12,1,wert);o12CATm12END OP CAT;PROCg11(AUSWAHL CONSTa,INT CONST
+h11,PROC(TEXT VAR,INT CONST)s10):INT VARl3:=1,n12,i12:=1;FORn12FROMh11UPTOh11+i10-1REPoutsubtext(a.m9,l3,p12-5);q12;s10(p0,n12);INT CONSTr12:=min(s12,length(p0));outsubtext(p0,1,r12);l3:=p12+r12+2;i12INCR1END REP;w8.p12:code(q10SUBi12).q12:INT CONSTt12:=t11(n12);IFt12=0THENout(" o ")ELSEout(text(t12,3));out(" x ")END IF.s12:IFi12=i10THENj1-p12-1ELSEcode(a.o9SUBi12)END IF.w8:outsubtext(a.m9,l3,j1);IFk1+j1>=80THENout(o2)ELSEj1-max(l3,length(a.m9))TIMESOUTt0END IF.END PROCg11;PROCu11(INT CONSTp0,u12,wert):m1(code(q10SUBu12)-4,p0);IFwert=0THENout(" o ")ELSEout(text(wert,3));out(" x ")END IF END PROCu11;INT PROCwahl(INT CONSTv12):IFv12+v12<=length(p10)THENp10ISUBv12ELSE0END IF END PROCwahl;LETw12=200,x12=5000;LET HILFE=STRUCT(INTy12,ROWw12THESAURUSz12,ROWw12SATZa13,ROWx12SATZb13);BOUND HILFE VARc13;INT VARd13,e13,f13,g13;BOOL VARh13:=FALSE;LETi13=#718
+#"Das Hilfsgebiet existiert bereits",j13=#719
+#"Diese Seite ist in der anderen Hilfe nicht vorhanden";PROCx1:TEXT VARname:=f1;BOOL VARk13;IFname=s0THENy0(s2)ELSEl13;m13;n13END IF.l13:INT CONSTo13:=pos(name,"/");TEXT VARp13;IFo13=0THENp13:=nameELSEp13:=subtext(name,1,o13-1)END IF;q13;r13.q13:INT VARs13:=link(v2(1),p13);k13:=FALSE;IFs13=0THENinsert(v2(1),p13,s13);c13.z12(s13):=emptythesaurus;satzinitialisieren(c13.a13(s13));ELIFo13=0THENy0(i13);LEAVEx1ELIFh13THENk13:=TRUE END IF.r13:INT VARt13;TEXT VARu13:=subtext(name,o13+1);IFo13=0THENt13:=1ELSEt13:=link(c13.z12(s13),u13);IFt13=0AND NOTk13THENinsert(c13.z12(s13),u13,t13)END IF END IF.m13:INT VARv13:=c13.y12;IFv13<0THENv13:=0END IF;TEXT VARw13:=s0;r0;WHILEu0CANDa1(j0)REPx13END REP.x13:INT CONSTy13:=c1;TEXT CONSTz13:=f1;IFz13<>s0THENa14;r0ELSEb14END IF.a14:TEXT VARc14;d14(z13,c14);IFy13+y13<=length(c14)THENw13CAT(c14ISUBy13)ELIF NOT(anythingnotedORk13)THENy0(j13)END IF.b14:INT VARd3:=1;IF NOTk13THENv13INCR1;w13CATv13;satzinitialisieren(c13.b13(v13))END IF;REPr0;IFu0THEN LEAVEb14ELIF
+ NOTk13THENfeldaendern(c13.b13(v13),d3,p0);d3INCR1END IF END REP.n13:IF NOTa1(f0)THENy0(r2)END IF;IF NOT(anythingnotedORk13)THENfeldaendern(c13.a13(s13),t13,w13);c13.y12:=v13END IF.END PROCx1;PROCd14(TEXT CONSTname,TEXT VARw13):INT CONSTo13:=pos(name,"/");INT VARp13,t13:=0;IFo13=0THENp13:=link(v2(1),name)ELSEp13:=link(v2(1),subtext(name,1,o13-1));e14END IF;IFt13=0THENt13:=1END IF;IFp13=0THENerrorstop(f14)ELSEfeldlesen(c13.a13(p13),t13,w13)END IF.e14:IFp13>0THENt13:=link(c13.z12(p13),subtext(name,o13+1))END IF.END PROCd14;LETf14=#720
+#"Hilfe existiert nicht",g14=#721
+#"Hilfe ist leer",h14=#722
+#"HILFE: Beenden: ESC q Seite weiter: ESC w Seite zurueck: ESC z";PROChilfeanbieten(TEXT CONSTname,FENSTER CONSTf):enablestop;s1;TEXT VARw13;i14;d14(name,w13);IFw13=s0THENerrorstop(g14)ELSEj14END IF.i14:fensterveraendert(f);fenstergroesse(f,d13,e13,f13,g13).j14:k14;statusanzeigen(h14);INT VARa13:=1;REPl14;m14END REP.l14:INT CONSTn14:=w13ISUBa13;o14(c13.b13(n14)).m14:TEXT VARt6;REPgetchar(t6);IFt6=n2THENgetchar(t6);a6;LEAVEm14ELSEout(m2)END IF END REP.a6:SELECTpos("qwz?"1"",t6)OF CASE1:LEAVEhilfeanbietenCASE2:p14CASE3:q14CASE4:r14CASE5:eschopausfuehrenOTHERWISEout(m2)END SELECT.p14:IF2*a13<length(w13)THENa13INCR1END IF.q14:IFa13>1THENa13DECR1END IF.r14:a13:=1.END PROChilfeanbieten;PROCo14(SATZ CONSTs14):INT VARd3;FORd3FROM1UPTOg13REPcursor(d13,e13+d3-1);feldbearbeiten(s14,d3,PROC(TEXT CONST,INT CONST,INT CONST)t14)END REP;cursor(d13,e13+g13-1)END PROCo14;PROCt14(TEXT CONSTa2,INT CONSTa9,b9):IFb9-a9+1>f13THENo8:=a9+f13-1ELSEo8:=b9END IF;outsubtext(a2,a9,o8);IFd13+f13>=80THENout(
+o2)ELSEf13+a9-o8-1TIMESOUTt0END IF END PROCt14;PROCstatusanzeigen(TEXT CONSTstatus):cursor(1,1);out(status);out(o2);fensterveraendert(g4)END PROCstatusanzeigen;LETd6=""4"",u14=""27"?",v14=""27"q",i9=""27"h";LETw14=#723
+#" ? (j/n) ",x14=#724
+#"jJ",y14=#725
+#"nN",z14=#726
+#"FRAGE: Bejahen: j,J Verneinen: n,N Abbrechen: ESC h Hilfe: ESC ?",a15=#727
+#"EINGABE: Bestätigen: RETURN Abbrechen: ESC h Hilfe: ESC ?",b15=#728
+#"EINGABE: Bestätigen: RETURN Zeigen: ESC z Abbruch: ESC h Hilfe: ESC ?",c15=#729
+#""15"!!! FEHLER !!! "14" Quittieren: ESC q Hilfe zur Meldung: ESC ?";FENSTER VARd8;fensterinitialisieren(d8);INT VARd15,e15,f15,g15,h15;PROCdialogfenster(INT CONSTn1,o1,i15,j15):fenstergroessesetzen(d8,n1,o1,i15,j15);e15:=n1;f15:=o1;g15:=i15;h15:=j15END PROCdialogfenster;PROCneuerdialog:d15:=h15END PROCneuerdialog;PROCdialog:BOOL VARe6;fensterzugriff(d8,e6);d15INCR1;IFd15>h15ORe6THENdialogfensterloeschen;d15:=1END IF;cursor(e15,f15+d15-1).END PROCdialog;PROCdialogfensterloeschen:BOOL CONSTk15:=e15+g15>=80;d15:=0;REPcursor(e15,f15+d15);IFk15THENout(o2)ELSEg15TIMESOUTt0END IF;d15INCR1UNTILd15>=h15END REP.END PROCdialogfensterloeschen;BOOL PROCja(TEXT CONSTl15,r10):REPstatusanzeigen(z14);dialog;out(l15);out(w14);k14;m15END REP;FALSE.m15:TEXT VARt6;REPgetchar(t6);IFpos(x14,t6)>0THENout(t6);LEAVEjaWITH TRUE ELIFpos(y14,t6)>0THENout(t6);LEAVEjaWITH FALSE ELIFt6=n2THENn15ELSEout(m2)END IF END REP.n15:getchar(t6);IFt6="?"THENhilfeanbieten(r10,d8);neuerdialog;LEAVEm15ELIFt6="h"THEN
+errorstop(s0);LEAVEjaWITH FALSE ELIFt6=""1""THENeschopausfuehrenELSEout(m2)END IF.END PROCja;PROCeditget(TEXT CONSTo15,TEXT VARt6,TEXT CONSTp15,r10):TEXT VARe9;q15;dialog;out(o15);out(t0);editget(t6,1000,r15,"","?hq"+p15,e9);IFe9=u14THENhilfeanbieten(r10,d8);neuerdialog;editget(o15,t6,p15,r10)ELIFe9=i9ORe9=v14THENerrorstop(s0)ELIFlength(e9)=2THENt6:=e9END IF.q15:IFpos(p15,"z")>0THENstatusanzeigen(b15)ELSEstatusanzeigen(a15)END IF.r15:g15-length(o15)-1.END PROCeditget;PROCfehlerausgeben:TEXT CONSTh1:=errormessage;IFerrorcode=1THENpage;bildschirmneuEND IF;clearerror;k14;IFh1<>s0THENstatusanzeigen(c15);s15;t15;neuerdialogEND IF.s15:dialog;out(m2);out(">>> ");outsubtext(errormessage,1,g15).t15:TEXT VARt6;getchar(t6);IFt6=n2THENn15END IF.n15:getchar(t6);IFt6="?"THENhilfeanbieten("FEHLER/"+text(errorcode),d8)ELIFt6=""1""THENeschopausfuehrenEND IF.END PROCfehlerausgeben;PROCk14:WHILEgetcharety<>s0REP END REP END PROCk14;LETu15=3,v15=12,w15=14,x15=1070,y15=1068,z15=1069,a16=0,b16=2;ROWu15
+DATASPACE VARz1;ROWu15THESAURUS VARv2;BOOL VARc16:=FALSE;INITFLAG VARd16;PROCs1:IF NOTinitialized(d16)THENe16END IF.e16:BOOL VARb6:=c16;f16;IFb6THENg16ELSEmenueloeschen(FALSE)END IF.f16:INT VARh16;FORh16FROM1UPTOu15WHILEb6REPi16END REP.i16:
+##INT VARj16,k16;FORk16FROM1UPTO10REPforget(z1(h16));z1(h16):=nilspace;pingpong(father,x15+h16,z1(h16),j16);IFj16=a16THEN LEAVEi16ELIFj16<>b16THENpause(15)END IF UNTILj16=b16END REP;forget(z1(h16));z1(h16):=nilspace;
+##b6:=FALSE.END PROCs1;THESAURUS PROCmenuenamen(INT CONSTh16):s1;IFh16<0THENc13.z12(-h16)ELSEv2(h16)END IF END PROCmenuenamen;PROCmenueloeschen(TEXT CONSTname,INT CONSTh16):s1;IFh16<0THENl16(name,c13.z12(-h16))ELSEl16(name,v2(h16))END IF END PROCmenueloeschen;PROCl16(TEXT CONSTname,THESAURUS VARz8):INT CONSTindex:=link(z8,name);IFindex>0THENdelete(z8,index)END IF END PROCl16;PROCmenueloeschen(BOOL CONSTm16):INT VARh16;d16:=TRUE;h13:=m16;FORh16FROM1UPTOu15REPforget(z1(h16));z1(h16):=nilspace;v2(h16):=emptythesaurusEND REP;g16END PROCmenueloeschen;PROCg16:c13:=z1(1);f2:=z1(2);p9:=z1(3)END PROCg16;
+##LETn16=#730
+#"Datei wird von anderer Task geaendert.",o16=#731
+#"Auftrag nur fuer Soehne erlaubt";THESAURUS VARp16:=emptythesaurus;ROW200TASK VARq16;TEXT VARr16;BOUND STRUCT(TEXTname,s16,t16)VARu16;PROCmenuemanager(DATASPACE VARv16,INT CONSTw16,x16,TASK CONSTy16):enablestop;c16:=TRUE;IFw16>=y15ANDw16<=x15+u15THENz16ELSE IFw16=v15ORw16=w15THENa17END IF;freemanager(v16,w16,x16,y16)END IF.z16:IFw16=y15THENb17ELIFw16=z15THENc17ELSEd17END IF.b17:u16:=v16;e17(u16.name,y16);send(y16,a16,v16).c17:u16:=v16;f17(u16.name);send(y16,a16,v16).a17:IFx16=1THENg17ELSEf17(r16)END IF.g17:u16:=v16;r16:=u16.name;IFh17THENerrorstop(n16)END IF.h17:INT VARv12:=link(p16,r16);v12>0CAND NOT(q16(v12)=y16).d17:IFy16<myselfTHENs1;forget(v16);v16:=z1(w16-x15);send(y16,a16,v16)ELSEerrorstop(o16)END IF.END PROCmenuemanager;PROCe17(TEXT CONSTr1,TASK CONSTi17):INT VARl5:=link(p16,r1);IFl5=0THENinsert(p16,r1,l5);j17;q16(l5):=i17ELIFexists(q16(l5))THEN IF NOT(q16(l5)=i17)THENerrorstop(n16)END IF ELSEq16(l5):=i17END IF.j17:IFl5=0THENk17;insert(p16,r1,l5)END IF.k17:TEXT VARl17;l5:=0;
+REPget(p16,l17,l5);IFl5=0THEN LEAVEk17END IF;IF NOTexists(l17)OR NOTexists(q16(l5))THENdelete(p16,l5)END IF END REP.END PROCe17;PROCf17(TEXT CONSTr1):INT VARl5;delete(p16,r1,l5)END PROCf17;PROCglobalmanager:globalmanager(PROC(DATASPACE VAR,INT CONST,INT CONST,TASK CONST)menuemanager)END PROCglobalmanager;
+##PROClock(TEXT CONSTr1,TASK CONSTm17):call(y15,r1,m17)END PROClock;PROCfree(TEXT CONSTr1,TASK CONSTm17):call(z15,r1,m17)END PROCfree;END PACKETeudasmenues;
+
diff --git a/eudas/eudas.4 b/eudas/eudas.4
new file mode 100644
index 0000000..4605022
--- /dev/null
+++ b/eudas/eudas.4
@@ -0,0 +1,150 @@
+PACKETsatzanzeigeDEFINESanzeigefenster,bildausgeben,aendern,einfuegen,suchen,feldauswahl,rollen,exitdurch,exitzeichen:LETb0=256;LETc0=" ",d0="",e0=""5"",f0=""15"",g0=" "14"",h0=" "14" ";ROWb0STRUCT(INTi0,j0)VARk0;INT VARl0,m0,n0:=24,o0:=79,p0:=1,q0:=1,r0,s0,t0:=0,u0:=0,v0:=dateiversion-1,w0:=0;BOOL VARx0:=TRUE,y0:=TRUE,z0:=FALSE,a1;FENSTER VARfenster;fensterinitialisieren(fenster);DATASPACE VARb1,c1;FILE VAReditfile;TEXT VARd1,e1;LETf1=#801
+#"Anzeigefenster zu klein";PROCanzeigefenster(INT CONSTg1,h1,i1,j1):IFi1>=39THENfenstergroessesetzen(fenster,g1,h1,i1,j1);y0:=g1+i1>=80;o0:=i1;n0:=j1;q0:=g1;p0:=h1;x0:=TRUE ELSEerrorstop(f1)END IF END PROCanzeigefenster;PROCk1:BOOL VARfensterveraendert;fensterzugriff(fenster,fensterveraendert);IFfensterveraendertTHENa1:=TRUE END IF END PROCk1;PROCl1:IFm1ORx0THENn1;o1;p1;q1;r1;s1END IF.m1:v0<>dateiversion.n1:l0:=0;WHILEl0<anzahlfelderREPl0INCR1;k0(l0).i0:=l0END REP;m0:=1.o1:INT VARi0;r0:=11;FORi0FROM1UPTOanzahlfelderREPfeldnamenbearbeiten(i0,PROC(TEXT CONST,INT CONST,INT CONST)t1)END REP;r0:=min(r0,o0DIV2);s0:=o0-r0-3.q1:a1:=TRUE.r1:forget(c1);c1:=nilspace;IFm1ANDz0THENforget(b1);z0:=FALSE END IF.s1:v0:=dateiversion;w0:=anzahldateien;x0:=FALSE.END PROCl1;PROCt1(TEXT CONSTu1,INT CONSTv1,w1):r0INCRlength(u1)-length(u1);r0:=max(r0,w1-v1+1)END PROCt1;PROCrollen(INT CONSTx1):m0:=m0+x1;IFm0<1THENm0:=1ELIFm0>y1THENm0:=max(y1,1)END IF;a1:=TRUE.y1:l0-n0+3.END PROCrollen;PROCfeldauswahl(TEXT
+CONSTz1):l1;a2;a1:=TRUE.a2:l0:=length(z1);INT VARb2;FORb2FROM1UPTOl0REPk0(b2).i0:=code(z1SUBb2)END REP;m0:=1.END PROCfeldauswahl;INT VARc2;PROCd2:type(c1,-1);editfile:=sequentialfile(modify,c1);editinfo(editfile,-1);toline(editfile,1);col(editfile,1);maxlinelength(editfile,10000);c2:=1END PROCd2;.e2:c2<=l0.PROCf2(PROC(TEXT CONST,INT CONST)g2):h2;IFeof(editfile)THENg2("",i0)ELIFi2THENj2;k2;g2(e1,i0)ELIFl2THENreadrecord(editfile,e1);k2;g2(e1,i0);down(editfile)ELSEexec(PROC(TEXT CONST,INT CONST)g2,editfile,i0);down(editfile)END IF.h2:INT CONSTv1:=c2,i0:=k0(v1).i0;REPc2INCR1UNTILc2>l0CORm2END REP.m2:k0(c2).i0<>i0.i2:c2-v1>1.j2:e1:="";REPexec(PROC(TEXT CONST,INT CONST)n2,editfile,length(e1));down(editfile)UNTILeof(editfile)ORlineno(editfile)=c2END REP.l2:INT CONSTo2:=len(editfile);subtext(editfile,o2,o2)=c0.END PROCf2;PROCn2(TEXT CONSTp2,INT CONSTq2):IFq2>0CAND(e1SUBq2)<>c0CAND(p2SUB1)<>c0THENe1CATc0END IF;e1CATp2END PROCn2;PROCk2:INT VARo2:=length(e1);WHILE(e1SUBo2)=c0REPo2DECR1END REP;e1
+:=subtext(e1,1,o2)END PROCk2;BOOL VARr2;PROCeinfuegen(PROCs2):enablestop;l1;IFl0>0THENd2;k1;t2(PROCs2);satzeinfuegen;r2:=TRUE;u2END IF END PROCeinfuegen;PROCu2:WHILEe2REPf2(PROC(TEXT CONST,INT CONST)v2)END REP;aenderungeneintragenEND PROCu2;PROCv2(TEXT CONSTw2,INT CONSTi0):IF NOTr2CORw2<>d0THENfeldaendern(i0,w2)END IF END PROCv2;PROCaendern(PROCs2):enablestop;IFdateiendeTHENeinfuegen(PROCs2)ELSEx2END IF.x2:l1;IFl0>0THENd2;k1;y2(a1);z2;t2(PROCs2);r2:=FALSE;u2END IF.z2:a3:=1;WHILEa3<=l0REPfeldbearbeiten(k0(a3).i0,PROC(TEXT CONST,INT CONST,INT CONST)b3);insertrecord(editfile);writerecord(editfile,e1);down(editfile);a3INCR1END REP;toline(editfile,1).END PROCaendern;INT VARa3;PROCb3(TEXT CONSTu1,INT CONSTv1,w1):e1:=subtext(u1,c3,d3).c3:v1+k0(a3).j0.d3:IFe3THENw1ELSEv1+k0(a3+1).j0-1END IF.e3:a3=l0CORk0(a3+1).i0<>k0(a3).i0.END PROCb3;PROCsuchen(PROCs2):enablestop;l1;IFl0>0THENd2;k1;IFsuchversion<>0THENf3END IF;t2(PROCs2);g3END IF.f3:a3:=1;WHILEa3<=l0REPinsertrecord(editfile);h3;down(editfile)
+;a3INCR1END REP;toline(editfile,1).h3:IFk0(a3).j0=0THENsuchbedingunglesen(k0(a3).i0,e1);writerecord(editfile,e1)END IF.g3:suchbedingungloeschen;WHILEe2REPf2(PROC(TEXT CONST,INT CONST)i3)END REP.END PROCsuchen;PROCi3(TEXT CONSTj3,INT CONSTi0):suchbedingung(i0,j3)END PROCi3;PROCbildausgeben(BOOL CONSTk3):enablestop;l1;k1;IFk3ORa1ORl3THENy2(a1);t0:=satznummer;u0:=satzkombination;m3(TRUE)ELSEn3(TRUE)END IF.l3:satznummer<>t0ORu0<>satzkombination.END PROCbildausgeben;INT VARj0;BOOL VARo3;PROCy2(BOOL CONSTp3):INT VARb2:=1,q3:=0;o3:=TRUE;WHILEb2<=l0OR NOTo3REPr3END REP.r3:IFo3CANDk0(b2).i0=q3THENs3ELSE IFt3THENu3END IF;k0(b2).j0:=j0;feldbearbeiten(k0(b2).i0,PROC(TEXT CONST,INT CONST,INT CONST)v3);b2INCR1END IF.s3:IFp3THENw3(b2)ELSEk0(b2).j0:=j0;b2INCR1END IF.t3:b2>l0CORk0(b2).i0<>q3.u3:IFo3THENx3ELSEy3(b2);k0(b2).i0:=q3END IF.x3:q3:=k0(b2).i0;j0:=0.END PROCy2;PROCv3(TEXT CONSTu1,INT CONSTv1,w1):INT CONSTz3:=w1-v1-j0+1;IFz3>s0-2THENj0INCRs0-2;a4;o3:=FALSE ELSEj0INCRz3;o3:=TRUE END IF.a4:INT VAR
+b4:=v1+j0-1;IFc4ANDd4THEN WHILE(u1SUBb4)<>c0REPb4DECR1;j0DECR1END REP END IF.c4:(u1SUBb4)<>c0.d4:pos(u1,c0,b4-s0,b4-1)>0.END PROCv3;PROCy3(INT CONSTb2):INT VARe4;FORe4FROMl0DOWNTOb2REPk0(e4+1):=k0(e4)END REP;l0INCR1;a1:=TRUE END PROCy3;PROCw3(INT CONSTb2):INT VARe4;FORe4FROMb2+1UPTOl0REPk0(e4-1):=k0(e4)END REP;l0DECR1;a1:=TRUE END PROCw3;INT VARf4;TEXT VARg4,h4,i4,j4:="",k4;LETl4=#802
+#""15" Bild verschoben ! ESC 1 druecken ! "14"";LETm4=""3""10"19"11""12"q?hpg";LETn4=1,o4=2,p4=3,q4=4,r4=5,s4=6,t4=7,u4=8,v4=9,w4=10,x4=11;PROCt2(PROCs2):INT VARy4:=m0;lernsequenzauftastelegen("D",date);REPm3(FALSE);z4;a5;b5;c5UNTILd5END REP;toline(editfile,1);col(editfile,1).z4:IFlines(editfile)<l0+1THENoutput(editfile);line(editfile,l0-lines(editfile)+2);modify(editfile)END IF.a5:IFm0<>1THENe5(m0-1,h4)END IF;e5(f5,i4);toline(editfile,y4).f5:min(l0+1,m0+n0-1).b5:openeditor(groesstereditor+1,editfile,TRUE,q0+r0+3,p0,s0,g5);edit(groesstereditor,m4+j4,PROC(TEXT CONST)h5).g5:min(l0-m0+2,n0).c5:y4:=lineno(editfile);i5;SELECTf4OF CASEn4:j5CASEo4:k5CASEp4:l5CASEq4:m5CASEr4:n5CASEs4:o5CASEu4:s2;a1:=TRUE CASEv4:errorstop(d0)CASEw4:p5CASEx4:q5END SELECT.i5:INT CONSTr5:=col(editfile);col(editfile,1);IFm0<>1THENs5(m0-1,h4)END IF;s5(f5,i4);col(editfile,r5).j5:INT VARt5;t5:=y4-m0;rollen(-n0+1);y4:=m0+t5.k5:t5:=y4-m0;rollen(n0-1);y4:=min(m0+t5,l0).l5:rollen(-999);y4:=1.m5:t5:=y4-m0;rollen(999);y4:=
+min(m0+t5,l0).n5:toline(editfile,y4);u5;y3(y4).u5:readrecord(editfile,e1);g4:=subtext(e1,r5);e1:=subtext(e1,1,r5-1);writerecord(editfile,e1);down(editfile);insertrecord(editfile);writerecord(editfile,g4).o5:toline(editfile,y4);IFr5=1AND(v5CANDw5ORx5CANDy5)THENz5ELSEa6END IF.v5:y4<>l0.w5:k0(y4+1).i0=k0(y4).i0.x5:y4<>1.y5:k0(y4-1).i0=k0(y4).i0.z5:deleterecord(editfile);w3(y4).a6:readrecord(editfile,e1);e1:=subtext(e1,1,r5-1);writerecord(editfile,e1).p5:forget(b1);b1:=c1;z0:=TRUE.q5:IFz0THENforget(c1);c1:=b1;editfile:=sequentialfile(modify,c1)END IF.d5:f4=t4.END PROCt2;PROCh5(TEXT CONSTb6):enablestop;setbusyindicator;f4:=pos(m4,b6);IFf4>0THENk4:=b6;quitELIFpos(j4,b6)>0THENf4:=t4;k4:=b6;quitELIFkommandoauftaste(b6)<>d0THENstdkommandointerpreter(b6)ELSEnichtsneuEND IF END PROCh5;PROCe5(INT CONSTb2,TEXT VARc6):toline(editfile,b2);readrecord(editfile,c6);writerecord(editfile,l4)END PROCe5;PROCs5(INT CONSTb2,TEXT CONSTc6):toline(editfile,b2);IFeof(editfile)CORpos(editfile,l4,1)=0THENtoline(
+editfile,1);down(editfile,l4);IFeof(editfile)THENtoline(editfile,b2);insertrecord(editfile)END IF END IF;writerecord(editfile,c6)END PROCs5;PROCexitzeichen(TEXT CONSTd6):j4:=d6END PROCexitzeichen;TEXT PROCexitdurch:k4END PROCexitdurch;INT VARe6;LETf6=#803
+#"ENDE.",g6=#804
+#"SUCH+",h6=#805
+#"SUCH-",i6=#806
+#"MARK+",j6=#807
+#"MARK-",k6=#808
+#" Feld "14" ",l6=#809
+#" Satz ",m6=#810
+#"< KOPPEL >";LETn6=".....",o6=" ";PROCm3(BOOL CONSTp6):INT VARq6:=p0+1,r6:=0;INT CONSTs6:=m0+n0-2;n3(p6);e6:=m0;WHILEe6<=s6REPt6;u6;v6;q6INCR1;e6INCR1END REP;a1:=FALSE.t6:IFa1THENcursor(q0,q6);IFe6<=l0THENw6ELIFe6=l0+1THENx6ELSEy6END IF END IF.w6:out(f0);IFk0(e6).i0=r6THENr0TIMESOUTc0ELSEr6:=k0(e6).i0;feldnamenbearbeiten(r6,PROC(TEXT CONST,INT CONST,INT CONST)z6)END IF;out(g0).x6:out(f0);o0-4TIMESOUT".";out(h0).y6:IFy0THENout(e0)ELSEo0TIMESOUTc0END IF.u6:IFp6ANDe6<=l0THENcursor(q0+r0+3,q6);feldbearbeiten(k0(e6).i0,PROC(TEXT CONST,INT CONST,INT CONST)a7)END IF.v6:IF NOTa1THEN TEXT CONSTinput:=getcharety;IFinput<>d0THENpush(input);IFpos(j4,input)>0THENt0:=0;LEAVEm3END IF END IF END IF.END PROCm3;PROCn3(BOOL CONSTp6):b7;c7;cursor(q0,p0);IF NOTp6THENoutsubtext(d1,1,r0+3);LEAVEn3END IF;replace(d1,r0+7,d7);replace(d1,r0+14,e7);out(d1);cursor(q0+o0-5,p0);out(text(m0)).b7:TEXT VARsatznr;satznr:=text(satznummer);IFanzahlkoppeldateien>0AND NOTaufkoppeldateiTHENsatznrCAT"-";satznrCATtext(
+satzkombination)END IF.c7:replace(d1,7,o6);replace(d1,7,satznr).d7:IFsuchversion=0THENn6ELIFsatzausgewaehltTHENg6ELSEh6END IF.e7:IFdateiendeTHENf6ELIFmarkiertesaetze=0THENn6ELIFsatzmarkiertTHENi6ELSEj6END IF.END PROCn3;PROCz6(TEXT CONSTu1,INT CONSTv1,w1):IFw1-v1>=r0THENoutsubtext(u1,v1,v1+r0-1)ELSEoutsubtext(u1,v1,w1);r0-w1+v1-1TIMESOUTc0END IF END PROCz6;PROCa7(TEXT CONSTu1,INT CONSTv1,w1):INT VARo2;IFe6=l0CORf7THENo2:=w1ELSEo2:=v1+k0(e6+1).j0-1END IF;outsubtext(u1,v1+k0(e6).j0,o2);IFy0THENout(e0)ELSEg7TIMESOUTc0END IF.f7:k0(e6+1).i0<>k0(e6).i0.g7:s0-o2+v1+k0(e6).j0-1.END PROCa7;PROCp1:d1:=text(l6,r0+3);d1CATf0;INT VARe4;INT CONSTh7:=o0-length(d1)-11;FORe4FROM1UPTOh7REPd1CAT"."END REP;d1CATk6;i7.i7:TEXT VARj7;IFaufkoppeldateiTHENj7:=m6ELSEj7:=eudasdateiname(1)END IF;j7:=subtext(j7,1,h7-20);j7CATc0;replace(d1,r0+21,c0);replace(d1,r0+22,j7).END PROCp1;END PACKETsatzanzeige;
+PACKETuebersichtsanzeigeDEFINESuebersicht,uebersichtsfenster:ROW24INT VARb0;ROW24INT VARc0;FENSTER VARfenster;fensterinitialisieren(fenster);INT VARd0:=24,e0:=79,f0:=1,g0:=1,h0,i0:=-1;BOOL VARj0,k0;TEXT VARl0;LETm0="",n0=""15"",o0=""14"",p0=" ",q0=""7"",r0=""5"";LETs0=#901
+#""15"Satznr. ",t0=#902
+#" << DATEIENDE >>",u0=#903
+#"UEBERSICHT: Rollen: HOP OBEN, HOP UNTEN Beenden: ESC q Hilfe: ESC ?";PROCuebersichtsfenster(INT CONSTv0,w0,x0,y0):fenstergroessesetzen(fenster,v0,w0,x0,y0);j0:=v0+x0>=80;d0:=y0;e0:=x0;f0:=w0;g0:=v0END PROCuebersichtsfenster;PROCuebersicht(TEXT CONSTz0,PROCa1):TEXT VARb1;BOOL VARc1;INT VARd1:=1,e1:=0,f1:=1;fensterzugriff(fenster,c1);statusanzeigen(u0);g1;k0:=FALSE;h1;REPi1;j1;k1END REP.g1:IFz0=m0THENl1ELSEl0:=z0;i0:=dateiversionEND IF.l1:IFi0<>dateiversionTHENm1;i0:=dateiversionEND IF.m1:INT VARn1;l0:=m0;FORn1FROM1UPTOanzahlfelderREPl0CATcode(n1)END REP.i1:WHILEe1<d0REPb1:=getcharety;IFb1<>""THEN LEAVEi1END IF;o1;e1INCR1END REP;p1;getchar(b1).o1:IFe1=0THENq1ELIFe1=1THENr1ELSEs1END IF.q1:cursor(g0,f0);out(s0);h0:=e0-10;INT VARfeldindex;FORfeldindexFROM1UPTOlength(l0)WHILEh0>0REPfeldnamenbearbeiten(code(l0SUBfeldindex),PROC(TEXT CONST,INT CONST,INT CONST)t1)END REP;u1;cursor(g0+e0-1,f0);out(o0).r1:v1(1);w1(1);x1.s1:cursor(g0,f0+e1);IFdateiendeTHENb0(e1):=0;h0:=e0;u1ELSEy1;w1(e1);
+x1END IF.y1:weiter(2);z1;b0(e1):=satznummer;c0(e1):=satzkombination.z1:IF NOT(satzausgewaehltORdateiende)THEN LEAVEuebersichtEND IF.j1:IFd1<e1THENw1(d1)END IF;cursor(g0,f0+d1).p1:k0:=TRUE;WHILEb0(d1)=0REPd1DECR1END REP;w1(d1);v1(d1);a2;k0:=FALSE.k1:SELECTf1OF CASE1:b2CASE2:c2CASE3:d2END SELECT.b2:SELECTpos(""3""10""1""27"+-",b1)OF CASE1:e2CASE2:f2CASE3:f1:=2CASE4:f1:=3CASE5:g2CASE6:h2OTHERWISEout(q0)END SELECT.c2:SELECTpos(""3""10""13"",b1)OF CASE1:i2CASE2:j2CASE3:k2OTHERWISEout(q0)END SELECT;f1:=1.d2:SELECTpos("19qh?",b1)OF CASE1:l2CASE2:m2CASE3,4:n2CASE5:o2OTHERWISEout(q0)END SELECT;f1:=1.e2:IFd1>1THENd1DECR1;ELSEp2(1);e1:=1END IF.f2:IF NOTdateiendeTHEN IFd1<d0-1THENd1INCR1ELSEb0(1):=b0(2);c0(1):=c0(2);e1:=1END IF END IF.g2:IF NOTsatzmarkiertTHENmarkierungaendernEND IF.h2:IFsatzmarkiertTHENmarkierungaendernEND IF.i2:IFd1>1THENd1:=1ELSEp2(d0-1);e1:=1END IF.j2:IFd1=d0-1AND NOTdateiendeTHENweiter(2);h1;e1:=1ELSEd1:=d0-1END IF.k2:IFd1<>1THENb0(1):=b0(d1);c0(1):=c0(d1);d1:=1;e1:=1END IF.
+l2:aufsatz(1);IF NOTsatzausgewaehltTHENweiter(2)END IF;h1;d1:=1;e1:=1.m2:aufsatz(32767);h1;p2(d0-2);e1:=1.n2:k0:=true;w1(d1);LEAVEuebersicht.o2:a1;statusanzeigen(u0);e1:=0.END PROCuebersicht;PROCp2(INT CONSTq2):INT VARn1;v1(1);FORn1FROM1UPTOq2WHILEsatznummer>1REPzurueck(2)END REP;h1END PROCp2;PROCv1(INT CONSTr2):aufsatz(b0(r2));WHILEsatzkombination<>c0(r2)REPweiter(1)END REP END PROCv1;PROCh1:b0(1):=satznummer;c0(1):=satzkombinationEND PROCh1;BOOL PROCs2(INT CONSTr2):satznummer=b0(r2)CANDsatzkombination=c0(r2)END PROCs2;PROCt1(TEXT CONSTt2,INT CONSTu2,v2):INT CONSTd0:=min(h0,v2-u2+1);outsubtext(t2,u2,u2+d0-1);h0DECRd0;IFh0>=2THENout(", ");h0DECR2ELIFh0=1THENout(",");h0:=0END IF END PROCt1;PROCw1(INT CONSTr2):cursor(g0,f0+r2);IFk0THENout(n0)ELSEout(p0)END IF;outtext(text(b0(r2)),1,5);IFk0THENout(o0)ELSEout(p0)END IF;h0:=e0-7END PROCw1;PROCu1:IFj0THENout(r0)ELSEh0TIMESOUTp0END IF END PROCu1;PROCx1:IFsatzausgewaehltTHENa2;w2ELIFdateiendeTHENout(t0);h0DECR17ELSEa2;out("<< >>");h0DECR5END
+IF;u1.w2:INT VARfeldindex;FORfeldindexFROM1UPTOlength(l0)WHILEh0>0REPfeldbearbeiten(code(l0SUBfeldindex),PROC(TEXT CONST,INT CONST,INT CONST)t1)END REP.END PROCx1;PROCa2:IFsatzmarkiertTHENout("+ ")ELSEout("- ")END IF;h0DECR2END PROCa2;END PACKETuebersichtsanzeige;
+PACKETeudassteuerungDEFINESeudas,einzelsicherung,suchen,aendern,einfuegen,prueffehlereditieren,feldstruktur,dateiverwaltung,archivverwaltung,edit,dateinamenanfordern,ausfuehrung,einzelausfuehrung:LETb0=1003,c0=3243;LETd0="",e0=" ",f0=""27"z",g0=""4"",h0=""5"";FILE VARi0;DATASPACE VARj0;INT VARk0,l0:=dateiversion-1;FENSTER VARm0,n0,o0,p0;TEXT VARq0;fensterinitialisieren(m0);fensterinitialisieren(n0);fensterinitialisieren(o0);fensterinitialisieren(p0);fenstergroessesetzen(m0,1,2,79,23);fenstergroessesetzen(n0,1,2,15,22);fenstergroessesetzen(o0,16,2,64,22);fenstergroessesetzen(p0,1,24,79,1);dialogfenster(16,2,64,22);anzeigefenster(16,2,64,23);uebersichtsfenster(1,2,79,23);TEXT VARr0;BOOL VARs0:=FALSE;LETt0=#1001
+#"EUDAS.Öffnen",u0=#1002
+#"EUDAS.Einzelsatz",v0=#1003
+#"EUDAS.Gesamtdatei",w0=#1004
+#"EUDAS.Drucken",x0=#1005
+#"EUDAS.Dateien",y0=#1006
+#"EUDAS.Archiv";LETz0=#1007
+#"EUDAS kann nicht unter EUDAS aufgerufen werden",a1=#1008
+#"Suchbedingung einstellen",b1=#1009
+#"Alle Saetze drucken",c1=#1010
+#"Alle markierten Satze drucken",d1=#1011
+#"Aktuellen Satz drucken",e1=#1012
+#"Mit neuer Auswahl noch einmal",f1=#1013
+#"Akt.Datei: ",g1=#1014
+#" Datum: ";PROCh1:cursor(30,6);out("EEEEE U U DDDD A SSSS");cursor(30,7);out("E U U D D A A S");cursor(30,8);out("EEE U U D D AAAAA SSS");cursor(30,9);out("E U U D D A A S");cursor(30,10);out("EEEEE UUU DDDD A A SSSS");cursor(30,12);out("Version 4.3");cursor(30,13);out("Stand: 13.08.87");cursor(30,15);out("(C) COPYRIGHT:");cursor(30,16);out("Thomas Berlage");cursor(30,17);out("Software-Systeme")END PROCh1;PROCeudas:IFaktuellereditor>0THENi1ELIFs0THENerrorstop(z0)ELSEj1END IF.j1:page;bildschirmneu;h1;k0:=heapsize;k1;disablestop;s0:=TRUE;menueanbieten(ROW6TEXT:(t0,u0,v0,w0,x0,y0),n0,TRUE,PROC(INT CONST,INT CONST)l1);s0:=FALSE;enablestop;m1;page;bildschirmneuEND PROCeudas;PROCi1:TEXT VARn1;o1;m1;IFp1THEN LEAVEi1END IF;q1(FALSE);aufsatz(1);r1(n1);REPs1;uebersicht(n1,PROCt1);o1;u1UNTILv1END REP;dateienloeschen(FALSE).p1:INT VARw1;FORw1FROM1UPTOanzahldateienREP IFinhaltveraendert(w1)THEN LEAVEp1WITH TRUE END IF END REP;FALSE.s1:IFja(a1,
+"JA/Suchmuster")THENsuchen;allesneuEND IF.u1:IFmarkiertesaetze=0CANDx1THENdateinamenanfordern(y1);einzelausfuehrung(PROC(TEXT CONST)z1,b0);ELIFmarkiertesaetze>0CANDa2THENdateinamenanfordern(y1);einzelausfuehrung(PROC(TEXT CONST)z1,b0);markierungenloeschenELIFb2THENmarkierungenloeschen;markierungaendern;dateinamenanfordern(y1);einzelausfuehrung(PROC(TEXT CONST)z1,b0);markierungenloeschenEND IF.x1:ja(b1,"JA/alle Satze").a2:ja(c1,"JA/alle markierten").b2:ja(d1,"JA/Einzelsatz drucken").v1:NOTja(e1,"JA/noch einmal").END PROCi1;PROCo1:bildschirmneu;cursor(1,1);out(g0);cursor(15,1);23TIMESOUT(""10":"8"")END PROCo1;PROCz1(TEXT CONSTc2):d2;disablestop;drucke(c2);e2;o1END PROCz1;PROCl1(INT CONSTf2,g2):enablestop;SELECTf2OF CASE0:h2CASE1:i2(g2)CASE2:j2(g2)CASE3:k2(g2)CASE4:l2(g2)CASE5:dateiverwaltung(g2)CASE6:archivverwaltung(g2)END SELECT.h2:IFanzahldateien=0THENm2(FALSE);n2(FALSE)ELIF NOTaendernerlaubtTHENn2(FALSE)END IF;o2;waehlbar(6,6,p2);waehlbar(6,9,NOTp2);IFq2THENwaehlbar(1,8,FALSE);
+waehlbar(6,7,FALSE)END IF.q2:FALSE.END PROCl1;PROCm2(BOOL CONSTr2):INT VARs2;waehlbar(1,4,r2);waehlbar(1,5,r2);waehlbar(1,7,r2);FORs2FROM1UPTO11REPwaehlbar(2,s2,r2)END REP;waehlbar(3,1,r2);waehlbar(3,4,r2);waehlbar(3,6,r2);waehlbar(4,1,r2)END PROCm2;PROCo2:BOOL VARr2:=anzahldateien=1ANDaendernerlaubt;waehlbar(1,6,r2);waehlbar(3,5,r2);r2:=anzahldateien>0ANDanzahldateien<10AND NOTaufkoppeldatei;waehlbar(1,2,r2);waehlbar(1,3,r2)END PROCo2;PROCn2(BOOL CONSTr2):INT VARs2;FORs2FROM7UPTO10REPwaehlbar(2,s2,r2)END REP;waehlbar(3,2,r2);waehlbar(3,3,r2)END PROCn2;PROCk1:fensterveraendert(p0);r0:=""6""23""0"";r0CATf1;IFanzahldateien>0THENr0CAT"""";r0CATeudasdateiname(1);r0CAT""""END IF;IFanzahldateien>1THENr0CAT" .. "END IF;r0CAT""5""6""23"";r0CATcode(79-length(date)-length(g1));r0CATg1;r0CATdateEND PROCk1;PROCt2(TEXT CONSTu2,v2):BOOL VARw2;fensterzugriff(p0,w2);IFw2THENout(r0);cursor(35,24);out(u2);IFv2<>d0THENout("""");outsubtext(v2,1,22-length(u2));out(""" ")END IF END IF END PROCt2;THESAURUS
+VARx2:=emptythesaurus;BOOL VARy2,z2:=FALSE;TASK VARa3;TEXT VARb3:=d0,c3:=d0;LETd3=#1015
+#" Manager: ",e3=#1017
+#"Keine Sicherung noetig.",f3=#1018
+#"Interne Arbeitskopien loeschen",g3=#1019
+#"Arbeitskopie ",h3=#1020
+#" unveraendert.",i3=#1021
+#" veraendert! Sichern",j3=#1022
+#"Alte Version ueberschreiben",k3=#1023
+#"Sondern unter dem Namen:",l3=#1024
+#" ueberschreiben",m3=#1025
+#"Datei wieder sortieren",n3=#1026
+#"Notizen",o3=#1027
+#"Name Managertask:",p3=#1028
+#"Task existiert nicht !",q3=#1029
+#"Wollen Sie etwas veraendern (eine Arbeitskopie anlegen)",r3=#1030
+#"Alle Markierungen gelöscht.",s3=#1032
+#"Pruefbedingungen",t3=#1033
+#"Feldnamen oder Feldtypen aendern",u3=#1034
+#"Feldnamen anfuegen",v3=#1035
+#"Neuer Feldname:",w3=#1036
+#"Neuer Typ (TEXT,DIN,ZAHL,DATUM):",x3=#1037
+#"Neue Feldnamen",y3=#1038
+#"TEXT",z3=#1039
+#"DIN",a4=#1040
+#"ZAHL",b4=#1041
+#"DATUM",c4=#1042
+#"Alte Feldreihenfolge aendern",d4=#1043
+#""7"ACHTUNG: System voll, Dateien loeschen!";PROCi2(INT CONSTg2):SELECTg2OF CASE0:e4CASE1:f4CASE2:g4CASE3:h4CASE4:i4CASE5:j4CASE6:k4CASE7:l4CASE8:m4OTHERWISEn4END SELECT;t2(d3,b3);o4;p4.e4:IFanzahldateien=0THENl1(0,0)END IF.f4:m1;q1(TRUE).g4:disablestop;q4;ausfuehrung(PROC(TEXT CONST)r4,c0);s4;enablestop;o2.h4:disablestop;q4;ausfuehrung(PROC(TEXT CONST)t4,c0);s4;enablestop;o2.i4:IFaendernerlaubtTHENu4ELSEdialog;out(e3);v4END IF;w4.u4:INT VARw1;FORw1FROM1UPTOanzahldateienREPeinzelsicherung(w1)END REP;IFja(f3,"JA/Dateien loeschen")THENx4;dateienloeschen(TRUE)END IF.w4:IFanzahldateien=0THENm2(FALSE);n2(FALSE)END IF;o2;k1.v4:INT CONSTy4:=anzahldateien;dateienloeschen(FALSE);FORw1FROM1UPTOy4REP IFz4(w1)THENa5(eudasdateiname(w1))END IF END REP.j4:b5;dialogfensterloeschen.k4:zugriff(PROC(EUDAT VAR)feldstruktur).l4:c5;dialogfensterloeschen.m4:b3:="";fensterveraendert(p0);editget(o3,b3,"","GET/multi task");IFb3=""THENz2:=FALSE ELIFexists(/b3)THENa3:=task(b3);z2:=TRUE ELSEz2:=FALSE;b3:="";
+errorstop(p3)END IF.p4:IFheapsize-k0>4THENcollectheapgarbage;k0:=heapsizeEND IF.n4:IFg2=-1THENdialogfensterloeschen;fensterveraendert(p0);LEAVEi2END IF.END PROCi2;PROCm1:BOOL VARd5:=FALSE;IFaendernerlaubtTHENe5END IF;IFd5THENdialogEND IF.e5:INT VARw1;FORw1FROM1UPTOanzahldateienREP IFinhaltveraendert(w1)THENeinzelsicherung(w1);d5:=TRUE;f5END IF END REP.f5:IFw1=1CANDstd=eudasdateiname(1)THENlastparam(d0)END IF.END PROCm1;PROCeinzelsicherung(INT CONSTw1):g5;IFinhaltveraendert(w1)THEN IFja(h5,"JA/sichere")THENi5END IF ELSEdialog;out(h5)END IF.g5:TEXT VARh5:=g3;h5CATtextdarstellung(eudasdateiname(w1));IFinhaltveraendert(w1)THENh5CATi3ELSEh5CATh3END IF.i5:TEXT VARname:=eudasdateiname(w1);IFja(j3,"JA/alte version")THENforget(name,quiet)ELIFz4(w1)THENerrorstop(d0)ELSEj5END IF;sichere(w1,name);k5.j5:editget(k3,name,"","GET/Sicherungsname");IFexists(name)THENl5END IF.l5:IFja(textdarstellung(name)+l3,"JA/ueber")THENforget(name,quiet)ELSEeinzelsicherung(w1);LEAVEeinzelsicherungEND IF.k5:EUDAT VAR
+m5;oeffne(m5,name);IFn5CANDo5THENp5;sortiere(m5)END IF.n5:sortierreihenfolge(m5)<>d0CANDunsortiertesaetze(m5)>0.o5:ja(m3,"JA/Sicherungssortierung").END PROCeinzelsicherung;PROCq1(BOOL CONSTq5):IFaendernerlaubtTHENx4END IF;dateienloeschen(TRUE);m2(FALSE);n2(FALSE);forget(j0);disablestop;q4;y2:=q5;einzelausfuehrung(PROC(TEXT CONST)r5,c0);s4;o2;enablestop;IFanzahldateien>0THENm2(TRUE);n2(aendernerlaubt)END IF END PROCq1;PROCq4:IFz2THENx2:=ALLa3END IF END PROCq4;PROCs4:x2:=emptythesaurus;k1END PROCs4;PROCx4:INT VARw1;FORw1FROM1UPTOanzahldateienREP IFz4(w1)THENs5END IF END REP.s5:IFt5THENdisablestop;u5;save(eudasdateiname(w1),a3);v5;enablestop;forget(eudasdateiname(w1),quiet)ELSEfree(eudasdateiname(w1),a3)END IF;w5(w1,FALSE).t5:exists(eudasdateiname(w1)).END PROCx4;PROCx5:IFz4(anzahldateien)ANDaendernerlaubtTHENforget(eudasdateiname(anzahldateien),quiet)END IF END PROCx5;PROCr5(TEXT CONSTc2):BOOL VARy5;z5;oeffne(c2,y5);x5.z5:IFa6ANDy2THENb6(c2);EUDAT VARm5;oeffne(m5,c2);feldstruktur(m5);y5
+:=TRUE ELSEy5:=y2CANDja(q3,"JA/oeffne");c6(c2,y5)END IF.a6:NOTexists(c2)AND NOT(x2CONTAINSc2).END PROCr5;PROCr4(TEXT CONSTc2):c6(c2,aendernerlaubt);kette(c2);x5END PROCr4;PROCt4(TEXT CONSTc2):c6(c2,aendernerlaubt);kopple(c2);x5END PROCt4;PROCc6(TEXT CONSTc2,BOOL CONSTd6):BOOL VARe6:=FALSE;IFz2THENf6END IF;w5(anzahldateien+1,e6).f6:IF(x2CONTAINSc2)CAND(NOTexists(c2)CORg6)THEN IFd6THENlock(c2,a3)END IF;forget(c2,quiet);fetch(c2,a3);e6:=TRUE END IF.g6:ja(textdarstellung(c2)+h6,"JA/fetch").END PROCc6;PROCw5(INT CONSTi6,BOOL CONSTe6):WHILElength(c3)<i6REPc3CATe0END REP;replace(c3,i6,j6).j6:IFe6THEN"-"ELSEe0END IF.END PROCw5;BOOL PROCz4(INT CONSTi6):IFlength(c3)<i6THEN FALSE ELSE(c3SUBi6)<>e0END IF END PROCz4;PROCb5:notizenlesen(3,q0);DATASPACE VARk6:=nilspace;FILE VARf:=sequentialfile(output,k6);disablestop;headline(f,n3);l6(f,q0,m0,"EDIT/Notizen");forget(k6);enablestop;IFaendernerlaubtTHENnotizenaendern(3,q0)END IF END PROCb5;PROCl6(FILE VARf,TEXT VARm6,FENSTER CONSTn6,TEXT CONSTo6):LETp6=
+"#-#";enablestop;q6;r6;s6.q6:INT VARt6:=1,u6;REPu6:=pos(m6,p6,t6);IFu6=0THENputline(f,subtext(m6,t6))ELSEputline(f,subtext(m6,t6,u6-1))END IF;t6:=u6+3UNTILu6=0ORt6>length(m6)END REP.r6:modify(f);edit(f,n6,o6,TRUE).s6:TEXT VARv6;m6:=d0;input(f);WHILE NOTeof(f)REPgetline(f,v6);w6;m6CATv6;m6CATp6END REP.w6:IF(v6SUBlength(v6))=e0THENv6:=subtext(v6,1,length(v6)-1)END IF.END PROCl6;PROCfeldstruktur(EUDAT VARm5):SATZ VARx6;feldnamenlesen(m5,x6);IFy6THENz6END IF;IFja(t3,"JA/Feldaendern")THENa7END IF.y6:IFfelderzahl(x6)>0THENja(u3,"JA/feldnamen")ELSE TRUE END IF.z6:DATASPACE VARk6:=nilspace;FILE VARf:=sequentialfile(output,k6);disablestop;b7(f,x6);forget(k6);enablestop;feldnamenaendern(m5,x6).a7:c7;auswahlanbieten("EUDAS-Felder",o0,"AUSWAHL/Felder",PROC(TEXT VAR,INT CONST)d7);INT VARe7:=1;WHILEwahl(e7)>0REPf7;e7INCR1END REP;feldnamenaendern(m5,x6).c7:satzinitialisieren(g7);FORe7FROM1UPTOfelderzahl(x6)REPfeldlesen(x6,e7,q0);feldaendern(g7,e7,h7+textdarstellung(q0))END REP.h7:"("+i7(feldinfo(m5,
+e7))+") ".f7:TEXT VARj7;feldlesen(x6,wahl(e7),j7);editget(v3,j7,"","GET/feldname");feldaendern(x6,wahl(e7),j7);TEXT VARk7:=i7(feldinfo(m5,wahl(e7)));REPeditget(w3,k7,"","GET/feldtyp")UNTILl7(k7)>=-1END REP;feldinfo(m5,wahl(e7),l7(k7)).END PROCfeldstruktur;PROCc5:enablestop;DATASPACE VARk6:=nilspace;FILE VARf:=sequentialfile(output,k6);headline(f,s3);notizenlesen(1,q0);disablestop;l6(f,q0,m0,"EDIT/Pruefbed");forget(k6);enablestop;IFaendernerlaubtTHENnotizenaendern(1,q0)END IF.END PROCc5;PROCb7(FILE VARf,SATZ VARx6):enablestop;m7;n7.m7:modify(f);headline(f,x3);edit(f,o0,"EDIT/Feldnamen",TRUE).n7:INT VARe7:=felderzahl(x6);input(f);WHILE NOTeof(f)REPgetline(f,q0);w6;e7INCR1;feldaendern(x6,e7,q0)END REP.w6:IF(q0SUBlength(q0))=e0THENq0:=subtext(q0,1,length(q0)-1)END IF.END PROCb7;TEXT PROCi7(INT CONSTk7):SELECTk7+1OF CASE0:y3CASE1:z3CASE2:a4CASE3:b4OTHERWISEd0END SELECT END PROCi7;INT PROCl7(TEXT CONSTo7):IFo7=y3THEN-1ELIFo7=z3THEN0ELIFo7=a4THEN1ELIFo7=b4THEN2ELSE-2END IF END PROCl7;PROCo4:
+INT VARp7,q7;storage(p7,q7);IFq7>p7THENneuerdialog;dialog;out(d4)END IF END PROCo4;BOOL VARr7,s7:=FALSE,t7:=FALSE;LETu7=#1044
+#"SATZ AENDERN: Abbruch: ESC h Beenden: ESC q Hilfe: ESC ?",v7=#1045
+#"SATZ EINFUEGEN: Abbruch: ESC h Beenden: ESC q Hilfe: ESC ?",w7=#1046
+#"SUCHMUSTER EINGEBEN: Abbruch: ESC h Beenden: ESC q Hilfe: ESC ?",x7=#1047
+#"Umschalten auf Koppeldatei ",y7=#1048
+#"Koppelfelder uebernehmen",z7=#1049
+#"Ungueltige Satznummer",a8=#1050
+#"Neue Satznummer:",b8=#1051
+#" Bitte warten.. ",c8=#1052
+#"wzK",d8=#1053
+#"wz";LETe8=""6""23""0" :",f8=""6""23""0" :"5"";PROCj2(INT CONSTg2):SELECTg2OF CASE0:g8CASE1:h8CASE2:i8CASE3:j8CASE4:k8CASE5:l8CASE6:m8CASE7:n8CASE8:o8CASE9:p8CASE10:q8CASE11:r8CASE12:s8CASE13:t8CASE14:u8CASE15:v8CASE16:w8OTHERWISEx8END SELECT;o4.g8:exitzeichen(d8).h8:p5;weiter(2);bildausgeben(FALSE).i8:p5;zurueck(2);bildausgeben(FALSE).k8:suchen;bildausgeben(TRUE).l8:suchbedingungloeschen;bildausgeben(FALSE).j8:TEXT VARy8:=d0;z8;editget(a8,y8,"","GET/auf satz");INT CONSTa9:=int(y8);IFy8=d0THENbildausgeben(FALSE)ELIFlastconversionokTHENaufsatz(a9);bildausgeben(FALSE)ELSEerrorstop(z7)END IF.n8:einfuegen;bildausgeben(TRUE).o8:aendern;bildausgeben(TRUE).m8:markierungaendern;bildausgeben(FALSE).p8:b9;z8;dateinamenanfordern(c9);einzelausfuehrung(PROC(TEXT CONST)d9,c0);bildausgeben(TRUE).q8:b9;z8;dateinamenanfordern(e9);einzelausfuehrung(PROC(TEXT CONST)holesatz,c0);bildausgeben(TRUE).r8:TEXT VARf9;z8;g9(f9);IFf9<>d0THENfeldauswahl(f9)END IF;bildausgeben(TRUE).s8:h9
+;rollen(-23);IFanzahldateien>0THENbildausgeben(FALSE)END IF.t8:h9;rollen(23);IFanzahldateien>0THENbildausgeben(FALSE)END IF.u8:h9;rollen(-9999);IFanzahldateien>0THENbildausgeben(FALSE)END IF.v8:h9;rollen(9999);IFanzahldateien>0THENbildausgeben(FALSE)END IF.w8:IFaufkoppeldateiTHENi9ELSEj9END IF;IFanzahldateien>0THENbildausgeben(TRUE)END IF.i9:IF(t7ORs7)THENk9;l9ELSEaufkoppeldatei(0)END IF;o2.k9:z8;IF NOTdateiendeCANDja(y7,"JA/uebernehmen")THENaufkoppeldatei(1)ELSEaufkoppeldatei(0)END IF.l9:s7:=FALSE;IFt7THENt7:=FALSE;aendernELSEm9(TRUE)END IF.x8:IFg2=-2THEN IFanzahldateien>0THENn9;bildausgeben(FALSE)ELSEz8END IF ELSEdialogfensterloeschen;fensterveraendert(p0)END IF.n9:out(e8).z8:out(f8).END PROCj2;PROCsuchen:disablestop;exitzeichen("");statusanzeigen(w7);suchen(PROCo9);exitzeichen(d8)END PROCsuchen;PROCo9:hilfeanbieten("EDIT/Suchen",o0)END PROCo9;PROCp5:statusanzeigen(b8)END PROCp5;PROCeinfuegen:m9(FALSE)END PROCeinfuegen;PROCm9(BOOL CONSTp9):BOOL VARq9:=p9;r9;REPstatusanzeigen(v7);IFq9
+THENaendern(PROCs9);q9:=FALSE ELSEeinfuegen(PROCs9)END IF;t9;u9END REP.u9:SELECTpos(c8,exitdurch)OF CASE0:IFr7THENsatzloeschenENDIF;LEAVEm9CASE1:IFr7THENsatzloeschenELSEp5;weiter(2)END IF CASE2:IFr7THENsatzloeschenELSEp5;zurueck(2)END IF CASE3:j9;IFaufkoppeldateiTHENs7:=TRUE;LEAVEm9END IF;q9:=TRUE END SELECT.END PROCm9;PROCs9:hilfeanbieten("EDIT/Einfuegen",o0)END PROCs9;PROCr9:IFanzahlkoppeldateien>0AND NOTaufkoppeldateiTHENexitzeichen(c8)ELSEexitzeichen(d8)END IF END PROCr9;PROCaendern:r9;kommandoauftastelegen("F","prueffehler editieren");REPstatusanzeigen(u7);aendern(PROCv9);t9;w9END REP.w9:SELECTpos(c8,exitdurch)OF CASE0:IFr7THENsatzloeschenENDIF;LEAVEaendernCASE1:IFr7THENsatzloeschenELSEp5;weiter(2)END IF CASE2:IFr7THENsatzloeschenELSEp5;zurueck(2)END IF CASE3:j9;IFaufkoppeldateiTHENt7:=TRUE;LEAVEaendernEND IF END SELECT.END PROCaendern;PROCv9:hilfeanbieten("EDIT/Aendern",o0)END PROCv9;PROCprueffehlereditieren:IFl0=dateiversionTHENmodify(i0);edit(i0)END IF END
+PROCprueffehlereditieren;PROCj9:INT VARw1:=folgedatei(0);WHILEw1>0REPout( f8);IFx9THENaufkoppeldatei(w1);o2;LEAVEj9END IF;w1:=folgedatei(w1)END REP.x9:ja(x7+textdarstellung(eudasdateiname(w1)),"JA/umschalten").END PROCj9;PROCy9(TEXT CONSTv6,INT CONSTz9):outsubtext(v6,a10);out(h0).a10:pos(v6,e0,6)+1+z9-z9.END PROCy9;PROCt9:feldbearbeiten(1,PROC(TEXT CONST,INT CONST,INT CONST)b10)END PROCt9;PROCb10(TEXT CONSTx6,INT CONSTt6,u6):r7:=t6<3ORt6>length(x6)+u6-u6END PROCb10;PROCh9:cursor(15,24)END PROCh9;PROCd9(TEXT CONSTc2):IFexists(c2)THENc10ELSEb6(c2)END IF;p5;tragesatz(c2).c10:IFd10(c2)<>0THENerrorstop(e10)END IF.END PROCd9;PROCg9(TEXT VARf9):auswahlanbieten("EUDAS-Anzeigefelder",o0,"AUSWAHL/Anzeigefelder",PROC(TEXT VAR,INT CONST)f10);f9:=d0;INT VARy8:=1;WHILEwahl(y8)>0REPf9CATcode(wahl(y8));y8INCR1END REP END PROCg9;LETr8=#1054
+#"Angezeigte Felder auswaehlen",g10=#1055
+#" aufsteigend sortieren";DATASPACE VARh10;PROCk2(INT CONSTg2):SELECTg2OF CASE1:i10CASE2:j10CASE3:k10CASE4:l10CASE5:m10CASE6:n10OTHERWISEn4END SELECT;o4.j10:b9;dateinamenanfordern(c9);einzelausfuehrung(PROC(TEXT CONST)o10,c0).i10:b9;dateinamenanfordern(c9);einzelausfuehrung(PROC(TEXT CONST)p10,c0);dialogfensterloeschen;t2("","").k10:dateinamenanfordern(q10);ausfuehrung(PROC(TEXT CONST)r10,b0);dialogfensterloeschen;t2("","").l10:TEXT VARs10;r1(s10);uebersicht(s10,PROCt1);dialogfensterloeschen;t2("","").m10:zugriff(PROC(EUDAT VAR)t10).n10:markierungenloeschen;dialog;out(r3).n4:IFg2=-1THENdialogfensterloeschen;fensterveraendert(p0)ELIFg2=-2THENt2("","")END IF.END PROCk2;PROCb9:IFd10(std)<>0THENlastparam(d0)END IF END PROCb9;PROCo10(TEXT CONSTc2):BOOL VARu10;IFexists(c2)THENc10;v10ELSEb6(c2);u10:=FALSE END IF;BOOL CONSTw10:=ja(x10,"JA/sortieren");p5;y10;trage(c2,i0,u10);z10;IFw10THEN EUDAT VARm5;oeffne(m5,c2);sortiere(m5)END IF.c10:IFd10(c2)<>0THENerrorstop(e10)END IF.v10:u10:=ja(a11,
+"JA/testen").y10:IFu10THENforget(j0);j0:=nilspace;i0:=sequentialfile(output,j0);l0:=dateiversionELSEforget(j0);l0:=dateiversion-1END IF.z10:IFu10CANDlines(i0)>0THENdialog;put(lines(i0));put(b11)END IF.END PROCo10;PROCr10(TEXT CONSTc2):IF NOTexists(c2)THENc11(c2,"EDIT/Verarbeite")END IF;d2;FILE VARf:=sequentialfile(input,c2);disablestop;verarbeite(f);e2.END PROCr10;PROCr1(TEXT VARs10):s10:=d0;IFja(r8,"JA/Ub.Felder")THENg9(s10)END IF END PROCr1;PROCt1:hilfeanbieten("UEBERSICHT",m0)END PROCt1;PROCp10(TEXT CONSTc2):disablestop;h10:=nilspace;d11(c2);forget(h10)END PROCp10;PROCd11(TEXT CONSTc2):TEXT VARe11:="";FILE VARf;EUDAT VARm5;BOOL VARw10:=FALSE;enablestop;IFexists(c2)THENf11ELSEb6(c2)END IF;editget(g11,e11,"","GET/kopiermuster");IFexists(e11)THENf:=sequentialfile(input,e11)ELSEh11;stdkopiermuster(c2,f)END IF;modify(f);i11;j11.f11:IFd10(c2)<>0THENerrorstop(e10)END IF;oeffne(m5,c2);IFsortierreihenfolge(m5)<>d0THENw10:=ja(x10,"JA/sortieren")END IF.h11:IFe11=d0THENf:=sequentialfile(output,
+h10)ELSEb6(e11);f:=sequentialfile(output,e11)END IF.i11:edit(f,m0,"EDIT/Kopiermuster",TRUE);d2;kopiere(c2,f).j11:IFw10THENoeffne(m5,c2);sortiere(m5)END IF.END PROCd11;INT PROCd10(TEXT CONSTc2):INT VARw1;FORw1FROM1UPTOanzahldateienREP IFeudasdateiname(w1)=c2THEN LEAVEd10WITHw1END IF END REP;0END PROCd10;PROCc11(TEXT CONSTc2,k11):IF NOTexists(c2)THENb6(c2)END IF;FILE VARf:=sequentialfile(modify,c2);edit(f,m0,k11,TRUE)END PROCc11;PROCd2:p5;cursor(1,2);out(g0);bildschirmneuEND PROCd2;PROCt10(EUDAT VARm5):TEXT VARl11:=sortierreihenfolge(m5);IFl11=d0CORm11THENn11;p5;sortiere(m5,l11)ELSEp5;sortiere(m5)END IF.m11:ja(c4,"JA/Sortierfelder").n11:feldnamenlesen(m5,g7);auswahlanbieten("EUDAS-Sortierfelder",o0,"AUSWAHL/Sortierfelder",PROC(TEXT VAR,INT CONST)d7);INT VARe7:=1;l11:=d0;WHILEwahl(e7)<>0REPl11CATcode(wahl(e7));o11;e7INCR1END REP.o11:feldlesen(g7,wahl(e7),q0);IFja(textdarstellung(q0)+g10,"JA/Sortierrichtung")THENl11CAT"+"ELSEl11CAT"-"END IF.END PROCt10;PROCf10(TEXT VARname,INT CONSTy8):IF
+y8<=anzahlfelderTHENfeldnamenlesen(y8,name)ELSEname:=d0END IF END PROCf10;LETp11=#1056
+#"Ausgabe automatisch zum Drucker",q11=#1057
+#"Ausgabe in bestimmte Datei",r11=#1058
+#"Name Ausgabedatei:",x10=#1059
+#"Zieldatei anschliessend sortieren",a11=#1060
+#"Pruefbedingungen testen",b11=#1061
+#"Prueffehler festgestellt",e10=#1062
+#"Zieldatei darf nicht geoeffnet sein",g11=#1063
+#"Name Kopiermuster (RET=Std):";LETs11=#1093
+#" zeilenweise formatieren",t11=#1094
+#" seitenweise formatieren";BOOL VARu11:=FALSE,v11:=FALSE;PROCl2(INT CONSTg2):SELECTg2OF CASE1:w11CASE2:x11CASE3:y11CASE4:z11CASE5:a12OTHERWISEn4END SELECT;o4.w11:dateinamenanfordern(y1);ausfuehrung(PROC(TEXT CONST)b12,b0);dialogfensterloeschen;t2("","").x11:direktdrucken(ja(p11,"JA/direkt drucken"));IF NOTdirektdruckenCANDja(q11,"JA/Druckdatei")THEN TEXT VARc2:=d0;editget(r11,c2,"","GET/Druckdatei");IFc2<>d0THENdruckdatei(c2)END IF END IF.y11:ausfuehrung(PROC(TEXT CONST)c12,b0);dialogfensterloeschen;t2("","").z11:ausfuehrung(PROC(TEXT CONST)print,b0).a12:ausfuehrung(PROC(TEXT CONST)d12,b0);dialogfensterloeschen;t2("","").n4:IFg2=-1THENdialogfensterloeschen;fensterveraendert(p0)ELIFg2=-2THENt2("","")END IF.END PROCl2;PROCe2:IFe12THENclearerrorEND IF.e12:iserrorCANDerrormessage=d0.END PROCe2;PROCb12(TEXT CONSTc2):IF NOTexists(c2)THENc12(c2)END IF;d2;disablestop;drucke(c2);e2END PROCb12;PROCc12(TEXT CONSTc2):c11(c2,"EDIT/Druckmuster")END PROCc12;PROCprint(TEXT CONSTc2):do("print ("+
+textdarstellung(c2)+")")END PROCprint;PROCd12(TEXT CONSTc2):IFja(textdarstellung(c2)+s11,"JA/zeilenform")THENf12END IF;IFja(textdarstellung(c2)+t11,"JA/seitenform")THENseitenformatierenEND IF.f12:IFu11THENautoform(c2)ELSElineform(c2)END IF;page;bildschirmneu.seitenformatieren:IFv11THENautopageform(c2)ELSEpageform(c2)END IF;bildschirmneu.END PROCd12;PROCg12(BOOL CONSTh12,i12):u11:=h12;v11:=i12END PROCg12;TEXT VARj12;LETk12=#1064
+#" Task: ",l12=#1065
+#"Neuer Name:",m12=#1066
+#"Zieldatei:",n12=#1067
+#" belegt ",o12=#1068
+#"KB.",p12=#1069
+#" existiert nicht.",q12=#1070
+#" in dieser Task loeschen",r12=#1071
+#" neu einrichten";PROCdateiverwaltung(INT CONSTg2):enablestop;SELECTg2OF CASE0:s12CASE1:t12CASE2:u12CASE3:v12CASE4:w12CASE5:x12CASE6:y12OTHERWISEn4END SELECT;o4.s12:j12:=name(myself).y12:ausfuehrung(PROC(TEXT CONST)z12,0).v12:ausfuehrung(PROC(TEXT CONST)a13,0).u12:ausfuehrung(PROC(TEXT CONST)a5,0).t12:disablestop;DATASPACE VARb13:=nilspace;FILE VARf:=sequentialfile(output,b13);list(f);IF NOTiserrorTHENedit(f,o0,"SHOW/Uebersicht",FALSE)END IF;forget(b13);enablestop;c13.w12:ausfuehrung(PROC(TEXT CONST)d13,0).x12:ausfuehrung(PROC(TEXT CONST)e13,0).n4:IFg2=-1THENdialogfensterloeschen;fensterveraendert(p0)ELIFg2=-2THENt2(k12,j12)END IF.END PROCdateiverwaltung;PROCc13:WHILEgetcharety<>d0REP END REP END PROCc13;PROCz12(TEXT CONSTc2):IFtype(old(c2))=c0THENreorganisiere(c2)ELSEreorganize(c2)END IF END PROCz12;PROCa13(TEXT CONSTc2):TEXT VARf13:=c2;IFexists(c2)THENeditget(l12,f13,"","GET/rename")END IF;rename(c2,f13)END PROCa13;PROCa5(TEXT CONSTc2):IFg13THENerrorstop(e10)ELIFexists(c2)CANDh13
+THENforget(c2,quiet)END IF.g13:d10(c2)<>0.h13:ja(textdarstellung(c2)+q12,"JA/forget").END PROCa5;PROCd13(TEXT CONSTc2):TEXT VARi13:=d0;editget(m12,i13,"","GET/copy");copy(c2,i13)END PROCd13;PROCe13(TEXT CONSTc2):dialog;out(textdarstellung(c2));IFexists(c2)THENout(n12);put(dspages(old(c2))DIV2);out(o12)ELSEout(p12)END IF END PROCe13;TEXT VARj13:=d0,k13:="ARCHIVE";INT VARl13:=0;THESAURUS VARm13;BOOL VARn13,p2:=TRUE,o13;LETp13=#1072
+#" Ziel: ",q13=#1073
+#"Archiv heisst ",r13=#1074
+#"Name des Archivs:",s13=#1075
+#"Name Zielarchiv:",t13=#1076
+#"Nr. der Zielstation (od. RETURN):",u13=#1077
+#"Ist das Zielarchiv ein Archivmanager",v13=#1078
+#"Archivdiskette vorher formatieren",w13=#1079
+#"Neuer Archivname:",h6=#1080
+#" im System ueberschreiben",x13=#1081
+#" auf Archiv loeschen",y13=#1082
+#"Archiv ",z13=#1083
+#" ueberschreiben",a14=#1084
+#"Archiv initialisieren",b14=#1085
+#" auf Archiv ueberschreiben";LETc14=#1095
+#"Passwort: ",d14=#1096
+#"Passwort stimmt nicht mit der ersten Eingabe überein",e14=#1097
+#"Passwort zur Kontrolle bitte nochmal eingeben.",f14=#1098
+#"Passwort loeschen",g14=#1099
+#"Unzlaessige Stationsnummer",h14=#1100
+#"Angegebene Task ist kein Manager";PROCarchivverwaltung(INT CONSTg2):enablestop;SELECTg2OF CASE0:i14CASE1:j14CASE2:k14CASE3:l14CASE4:m14CASE5:n14CASE6:o14CASE7:p14CASE8:q14CASE9:r14OTHERWISEs14END SELECT;o4.i14:n13:=FALSE.m14:IFp2THENt14END IF;p5;m13:=ALLu14;ausfuehrung(PROC(TEXT CONST)v14,0).l14:disablestop;w14;p5;m13:=ALLu14;IFx14THENm13:=ALLu14END IF;enablestop;y14(PROC(TEXT CONST)z14).n14:IFp2THENt14END IF;p5;m13:=ALLu14;y14(PROC(TEXT CONST)n14).j14:w14;disablestop;p5;DATASPACE VARb13:=nilspace;f:=sequentialfile(output,b13);list(f,u14);IFx14THENlist(f,u14)END IF;IF NOTiserrorTHENmodify(f);toline(f,1);writerecord(f,headline(f));headline(f,d0);edit(f,o0,"SHOW/Uebersicht",FALSE)END IF;forget(b13);c13;enablestop.k14:w14;a15;FILE VARf:=sequentialfile(output,b15);disablestop;p5;list(f,u14);IFx14THENlist(f,u14)END IF;enablestop;modify(f);insertrecord(f);writerecord(f,headline(f));print(b15);forget(b15,quiet).a15:INT VARs2:=0;TEXT VARb15;REPs2INCR1;b15:="Archivliste "+text(s2)UNTIL NOT
+exists(b15)END REP.o14:w14;IFja(v13,"JA/format")THENc15ELIFd15THEN IFe15THEN LEAVEo14END IF ELSE IFf15THEN LEAVEo14END IF END IF;j5;g15.c15:p5;disablestop;u5;format(u14);v5;enablestop.d15:reserve("",u14);p5;disablestop;m13:=ALLu14;BOOL CONSTh15:=x14;clearerror;enablestop;h15.e15:NOTja(y13+textdarstellung(j13)+z13,"JA/archiv loeschen").f15:NOTja(a14,"JA/archiv init").j5:editget(w13,j13,"","GET/Archivname");reserve(j13,u14).g15:p5;disablestop;u5;clear(u14);v5.p14:TEXT VARi15:=k13;IFn13THENrelease(u14);n13:=FALSE END IF;editget(s13,i15,"","GET/Zielarchiv");IFi15=d0THEN LEAVEp14END IF;j15;p2:=ja(u13,"JA/Zielmanager");k15;waehlbar(6,6,p2);waehlbar(6,9,NOTp2);bildschirmneu;t2(p13,l15+k13).j15:TEXT VARm15:=text(station(myself));IFstation(myself)<>0THENeditget(t13,m15,"","GET/Zielstation")END IF.k15:l13:=int(m15);IF NOTlastconversionokTHENerrorstop(g14)END IF;k13:=i15;n15(u14).l15:IFl13=0THENd0ELSEtext(l13)+"/"END IF.r14:TEXT VARo15:=d0;editget(r13,o15,"","GET/Archivname");reserve(o15,u14);n13
+:=TRUE.s14:IFg2=-1THEN IFn13THENrelease(u14)END IF;dialogfensterloeschen;fensterveraendert(p0)ELIFg2=-2THENt2(p13,l15+k13)END IF.END PROCarchivverwaltung;TASK PROCu14:IFl13=0THENtask(k13)ELSEl13/k13END IF END PROCu14;PROCn15(TASK CONSTo7):INT VARs2;IFstation(o7)=station(myself)THEN FORs2FROM1UPTO5REP IFstatus(o7)=2ORstatus(o7)=6THEN LEAVEn15END IF;pause(10)END REP;errorstop(h14)END IF END PROCn15;PROCt14:TEXT VARw13:=j13;editget(r13,w13,"","GET/Archivname");IF NOTn13ORw13<>j13THENreserve(w13,u14);n13:=TRUE END IF;j13:=w13END PROCt14;PROCw14:IF NOTn13ANDp2THENreserve(j13,u14);n13:=TRUE END IF END PROCw14;BOOL PROCx14:IFp2ANDiserrorTHEN TEXT CONSTp15:=errormessage;IFsubtext(p15,1,14)=q13CANDsubtext(p15,16,20)<>"?????"THENclearerror;q15;LEAVEx14WITH TRUE END IF END IF;FALSE.q15:j13:=subtext(p15,16,length(p15)-1);reserve(j13,u14).END PROCx14;PROCv14(TEXT CONSTc2):disablestop;IF NOT(m13CONTAINSc2)CORr15THENs15;p5;u5;save(c2,u14);v5END IF.r15:ja(textdarstellung(c2)+b14,"JA/save").s15:INT
+CONSTy8:=d10(c2);IFy8>0CANDaendernerlaubtCANDinhaltveraendert(y8)THENeinzelsicherung(y8)END IF.END PROCv14;PROCz14(TEXT CONSTc2):disablestop;IF NOTexists(c2)CORg6THENp5;u5;fetch(c2,u14);v5END IF.g6:ja(textdarstellung(c2)+h6,"JA/fetch").END PROCz14;PROCn14(TEXT CONSTc2):disablestop;IF NOT(m13CONTAINSc2)CORn14THENp5;u5;erase(c2,u14);v5END IF.n14:ja(textdarstellung(c2)+x13,"JA/erase").END PROCn14;PROCu5:o13:=commanddialogue;commanddialogue(FALSE)END PROCu5;PROCv5:commanddialogue(o13)END PROCv5;PROCy14(PROC(TEXT CONST)t15):TEXT VARc2:=d0;editget(u15,c2,"z","GET/Dateiname");IFc2=f0THENv15ELSElastparam(c2);t15(c2)END IF.v15:w15(m13,0);auswahlanbieten("EUDAS-Archivauswahl",o0,"AUSWAHL/Archiv",PROC(TEXT VAR,INT CONST)x15);y15(PROC(TEXT CONST)t15).END PROCy14;PROCq14:BOUND ROW2TEXT VARz15;DATASPACE VARk6:=nilspace;z15:=k6;disablestop;a16(z15(1));IFz15(1)=d0THENb16ELSEc16END IF;forget(k6).b16:IFja(f14,"JA/pw loeschen")THENdialog;dialog;enterpassword(d0)END IF.c16:dialog;out(e14);a16(z15(2));IF
+z15(1)<>z15(2)THENerrorstop(d14)ELSEdialog;dialog;enterpassword(z15(1))END IF.END PROCq14;PROCa16(TEXT VARd16):enablestop;dialog;out(c14);getsecretline(d16)END PROCa16;SATZ VARg7;LETu15=#1086
+#"Name der Datei:",c9=#1087
+#"Name der Zieldatei:",q10=#1088
+#"Name der Verarbeitungsvorschrift:",y1=#1089
+#"Name des Druckmusters:",e9=#1090
+#"Name der Quelldatei:";LETe16=#1101
+#"Keine Datei zur Auswahl vorhanden.";TEXT VARf16:=u15,g16;PROCw15(THESAURUS CONSTo7,INT CONSTk7):i16;h16;j16;k16.h16:g16:=d0;INT VARs2;FORs2FROM1UPTOanzahldateienREP INT CONSTl16:=feldindex(g7,eudasdateiname(s2));IFl16>0THENg16CATcode(l16)END IF END REP.i16:INT VARm16:=1,t6:=0;satzinitialisieren(g7);REPget(o7,q0,t6);IFq0=d0THEN LEAVEi16ELIFk7=0CORtype(old(q0))=k7THENfeldaendern(g7,m16,q0);m16INCR1END IF END REP.j16:t6:=0;REPget(x2,q0,t6);IFq0=d0THEN LEAVEj16ELIF NOT(o7CONTAINSq0)THENfeldaendern(g7,m16,q0);m16INCR1END IF END REP.k16:IFm16=1THENdialog;out(e16);errorstop(d0)END IF.END PROCw15;PROCx15(TEXT VARv2,INT CONSTm16):IFm16<256THENfeldlesen(g7,m16,v2);IFpos(g16,code(m16))>0THENv2:="<!> "+textdarstellung(v2)ELIFv2<>d0THENv2:=textdarstellung(v2)END IF ELSEv2:=d0END IF END PROCx15;PROCy15(PROC(TEXT CONST)t15):INT VARm16:=1;REP IFwahl(m16)=0THEN LEAVEy15ELSEfeldlesen(g7,wahl(m16),q0);dialog;out(text(m16,3));out(". ");out(textdarstellung(q0));lastparam(q0);t15(q0)END IF;m16INCR1END REP END
+PROCy15;PROCausfuehrung(PROC(TEXT CONST)t15,INT CONSTk7):enablestop;TEXT VARc2;dateinamenanfordern(c2,k7);IFc2=f0THENy15(PROC(TEXT CONST)t15)ELSElastparam(c2);t15(c2)END IF END PROCausfuehrung;PROCeinzelausfuehrung(PROC(TEXT CONST)t15,INT CONSTk7):enablestop;TEXT VARc2;dateinamenanfordern(c2,k7);IFc2=f0THEN IFwahl(1)=0THENerrorstop(d0)ELSEfeldlesen(g7,wahl(1),c2)END IF END IF;lastparam(c2);t15(c2)END PROCeinzelausfuehrung;PROCdateinamenanfordern(TEXT CONSTu2):f16:=u2END PROCdateinamenanfordern;PROCdateinamenanfordern(TEXT VARc2,INT CONSTk7):IFexists(std)AND(k7=0CORtype(old(std))=k7)THENc2:=stdELSEc2:=d0END IF;disablestop;editget(f16,c2,"z","GET/Dateiname");f16:=u15;enablestop;IFc2=d0THENerrorstop(d0)ELIFc2=f0THENw15(all,k7);auswahlanbieten("EUDAS-Dateiauswahl",o0,"AUSWAHL/Datei",PROC(TEXT VAR,INT CONST)x15);p5END IF END PROCdateinamenanfordern;PROCd7(TEXT VARv2,INT CONSTm16):IFm16<=256THENfeldlesen(g7,m16,v2)ELSEv2:=d0END IF END PROCd7;PROCb6(TEXT CONSTc2):IF NOTja(textdarstellung(c2)+
+r12,"JA/einrichten")THENerrorstop(d0)END IF END PROCb6;LETn16=#1091
+#"EDITIEREN: Abbruch: ESC h Verlassen: ESC q Hilfe: ESC ?",o16=#1092
+#"ZEIGEN: Blättern: HOP OBEN, HOP UNTEN Ende: ESC q Hilfe: ESC ?";INT VARp16;BOOL VARq16,r16;PROCedit(FILE VARf,FENSTER CONSTfenster,TEXT CONSTk11,BOOL CONSTaendern):INT VARs16,t16,u16,v16;fenstergroesse(fenster,s16,t16,u16,v16);fensterveraendert(fenster);enablestop;w16;q16:=aendern;REPx16;openeditor(groesstereditor+1,f,aendern,s16,t16,u16,v16);edit(groesstereditor,"eqvw19dpgn"9"?hF",PROC(TEXT CONST)y16);z16END REP.w16:IFaendernANDt16<3ANDv16>22ANDs16<14ANDu16>75THENr16:=TRUE ELSEr16:=FALSE END IF.z16:SELECTp16OF CASE0:LEAVEeditCASE1:hilfeanbieten(k11,fenster)CASE2:errorstop(d0)END SELECT.END PROCedit;PROCx16:IFq16THENstatusanzeigen(n16)ELSEstatusanzeigen(o16)END IF END PROCx16;PROCy16(TEXT CONSTa17):p16:=pos("?h",a17);IFp16>0THENquitELIFr16CANDa17="F"THENb17;x16ELSEstdkommandointerpreter(a17);x16;bildschirmneuEND IF END PROCy16;PROCb17:IFanzahlfelder>0THENc17;d17;e17END IF.c17:INT VARe7;satzinitialisieren(g7,anzahlfelder);FORe7FROM1UPTOanzahlfelderREPfeldnamenlesen(e7,q0);
+feldaendern(g7,e7,q0)END REP.d17:auswahlanbieten("EUDAS-Editfelder",o0,"AUSWAHL/Feldnamen",PROC(TEXT VAR,INT CONST)d7).e17:INT VARm16:=1;WHILEwahl(m16)>0REP IFm16>1THENpush(e0)END IF;feldnamenlesen(wahl(m16),q0);push("""");push(q0);push("""");m16INCR1END REP.END PROCb17;END PACKETeudassteuerung;
+
diff --git a/eudas/eudas.generator b/eudas/eudas.generator
new file mode 100644
index 0000000..96269e9
--- /dev/null
+++ b/eudas/eudas.generator
@@ -0,0 +1,86 @@
+INT VAR size, used;
+BOOL VAR einzeln,sparen;
+IF (pcb (9) AND 255) = 1 THEN
+ errorstop ("Nicht für Single-User-Systeme geeignet")
+END IF;
+storage (size, used);
+einzeln := size - used < 500;
+soehne loeschen;
+forget ("eudas.generator", quiet);
+page;
+putline ("EUDAS - automatische Generierung");
+putline ("Version 4.3 vom 31.07.87");
+line;
+sparen := no ("Ausfuehrliche Hilfstexte installieren");
+line;
+disable stop;
+do ("TEXT VARt:=additionalcommands");
+IF is error THEN
+ clear error;
+ enable stop;
+ gen ("dummy.text")
+END IF;
+enable stop;
+IF id (0) < 175 THEN
+ gen ("pos.173")
+END IF;
+IF NOT einzeln THEN
+ holen ("eudas.1");
+ holen ("eudas.2");
+ holen ("eudas.3");
+ holen ("eudas.4");
+ holen ("eudas.init");
+ release (archive)
+END IF;
+check off;
+gen ("eudas.1");
+gen ("eudas.2");
+gen ("eudas.3");
+gen ("eudas.4");
+IF anything noted THEN
+ push (""27"q"); note edit; pause (100)
+END IF;
+holen ("eudas.init");
+IF einzeln THEN
+ release (archive)
+END IF;
+IF sparen THEN do ("menue loeschen (TRUE)") END IF;
+do("menuedaten einlesen (""eudas.init"")");
+forget ("eudas.init", quiet);
+check on;
+do ("global manager");
+
+PROC vom archiv (TEXT CONST datei):
+ out (""""); out (datei); putline (""" wird geholt.");
+ fetch (datei, archive)
+END PROC vom archiv;
+
+PROC holen (TEXT CONST datei) :
+ IF NOT exists (datei) THEN vom archiv (datei) END IF
+END PROC holen;
+
+PROC gen (TEXT CONST datei) :
+ holen (datei);
+ out (""""); out (datei); out (""" wird uebersetzt: ");
+ insert (datei);
+ forget (datei, quiet)
+END PROC gen;
+
+PROC soehne loeschen :
+
+ command dialogue (TRUE);
+ access catalogue;
+ TASK VAR sohn := son (myself);
+ WHILE NOT is niltask (sohn) REP
+ TASK CONST naechster := brother (sohn);
+ IF yes ("Sohntask """ + name (sohn) + """ loeschen") THEN
+ end (sohn)
+ ELIF yes ("Generierung abbrechen") THEN
+ errorstop ("")
+ END IF;
+ sohn := naechster
+ END REP
+
+END PROC soehne loeschen;
+
+
diff --git a/eudas/eudas.init b/eudas/eudas.init
new file mode 100644
index 0000000..54fa28d
--- /dev/null
+++ b/eudas/eudas.init
@@ -0,0 +1,1463 @@
+% MENUE "EUDAS.Öffnen"
+% BILD
+--------------
+EUDAS-Datei
+O Öffnen
+E Ketten
+K Koppeln
+--------------
+Arbeitskopie
+S Sichern
+--------------
+Aktuelle Datei
+N Notizen
+F Feldstrukt.
+P Prüfbeding.
+--------------
+Mehrbenutzer
+M Manager
+--------------
+% FELD 1 "EUDAS/1O" "oO"
+% FELD 2 "EUDAS/1E" "eE"
+% FELD 3 "EUDAS/1K" "kK"
+% FELD 4 "EUDAS/1S" "sS"
+% FELD 5 "EUDAS/1N" "nN"
+% FELD 6 "EUDAS/1F" "fF"
+% FELD 7 "EUDAS/1P" "pP"
+% FELD 8 "EUDAS/1M" "mM"
+% ENDE
+% MENUE "EUDAS.Einzelsatz"
+% BILD
+--------------
+Positionieren
+W Weiter
+Z Zurück
+N Satz.Nr
+--------------
+Suchbedingung
+S Setzen
+L Löschen
+M Markierung
+--------------
+Datensatz
+E Einfügen
+A Ändern
+T Tragen
+H Holen
+--------------
+F Feldauswahl
+--------------
+% FELD 1 "EUDAS/2W" "wW"
+% FELD 2 "EUDAS/2Z" "zZ"
+% FELD 3 "EUDAS/2N" "nN"
+% FELD 4 "EUDAS/2S" "sS"
+% FELD 5 "EUDAS/2L" "lL"
+% FELD 6 "EUDAS/2M" "mM"
+% FELD 7 "EUDAS/2E" "eE"
+% FELD 8 "EUDAS/2A" "aA"
+% FELD 9 "EUDAS/2T" "tT"
+% FELD 10 "EUDAS/2H" "hH"
+% FELD 11 "EUDAS/2F" "fF"
+% FELD 12 "" ""3""
+% FELD 13 "" ""10""
+% FELD 14 "" "1"
+% FELD 15 "" "9"
+% FELD 16 "" "K"
+% ENDE
+% MENUE "EUDAS.Gesamtdatei"
+% BILD
+--------------
+Satzauswahl
+K Kopieren
+T Tragen
+V Verändern
+U Übersicht
+--------------
+Aktuelle Datei
+S Sortieren
+--------------
+Alle Markier.
+L Löschen
+--------------
+% FELD 1 "EUDAS/3K" "kK"
+% FELD 2 "EUDAS/3T" "tT"
+% FELD 3 "EUDAS/3V" "vV"
+% FELD 4 "EUDAS/3U" "uU"
+% FELD 5 "EUDAS/3S" "sS"
+% FELD 6 "EUDAS/3L" "lL"
+% ENDE
+% MENUE "EUDAS.Drucken"
+% BILD
+--------------
+Satzauswahl
+D Drucken
+--------------
+Druckausgabe
+R Richtung
+--------------
+Textdatei
+E Editieren
+A Ausdrucken
+N Nachbearb.
+--------------
+% FELD 1 "EUDAS/4D" "dD"
+% FELD 2 "EUDAS/4R" "rR"
+% FELD 3 "EUDAS/4E" "eE"
+% FELD 4 "EUDAS/4A" "aA"
+% FELD 5 "EUDAS/4N" "nN"
+% ENDE
+% MENUE "EUDAS.Dateien"
+% BILD
+--------------
+Dateien System
+U Übersicht
+--------------
+Datei
+L Löschen
+N Umbenennen
+K Kopieren
+P Platzbedarf
+A Aufräumen
+--------------
+% FELD 1 "EUDAS/5U" "Uu"
+% FELD 2 "EUDAS/5L" "Ll"
+% FELD 3 "EUDAS/5N" "Nn"
+% FELD 4 "EUDAS/5K" "Kk"
+% FELD 5 "EUDAS/5P" "Pp"
+% FELD 6 "EUDAS/5R" "Aa"
+% ENDE
+% MENUE "EUDAS.Archiv"
+% BILD
+--------------
+Dateien Archiv
+U Übersicht
+D Üb. Drucken
+--------------
+Datei
+K Kopieren
+ vom Archiv
+S Schreiben
+ auf Archiv
+L Löschen
+ auf Archiv
+--------------
+Archivdiskette
+I Init
+--------------
+Z Zielarchiv
+P Passwort
+R Reservieren
+--------------
+% FELD 1 "EUDAS/6U" "Uu"
+% FELD 2 "EUDAS/6D" "Dd"
+% FELD 3 "EUDAS/6K" "Kk"
+% FELD 4 "EUDAS/6S" "Ss"
+% FELD 5 "EUDAS/6L" "Ll"
+% FELD 6 "EUDAS/6I" "Ii"
+% FELD 7 "EUDAS/6Z" "Zz"
+% FELD 8 "EUDAS/6P" "Pp"
+% FELD 9 "EUDAS/6R" "Rr"
+% ENDE
+% AUSWAHL "EUDAS-Felder"
+% VORSPANN
+--------------------------------------------------------------
+ Bitte die Felder, die geaendert werden sollen, ankreuzen:
+% BILD
+--------------------------------------------------------------
+  
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Sortierfelder"
+% VORSPANN
+--------------------------------------------------------------
+ Bitte die Felder, nach denen sortiert werden soll, in Reihen-
+ folge ankreuzen:
+% BILD
+--------------------------------------------------------------
+  
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Anzeigefelder"
+% VORSPANN
+--------------------------------------------------------------
+ Bitte die Felder, die angezeigt werden sollen, in Reihenfolge
+ ankreuzen:
+% BILD
+--------------------------------------------------------------
+  
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Editfelder"
+% VORSPANN
+--------------------------------------------------------------
+ Bitte die Felder ankreuzen, die in die Datei übernommen
+ werden sollen:
+% BILD
+--------------------------------------------------------------
+  
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Archivauswahl"
+% VORSPANN
+--------------------------------------------------------------
+ Auswahl der Dateien auf dem Archiv.
+ Gewuenschte Datei(en) bitte ankreuzen:
+% BILD
+--------------------------------------------------------------
+  
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Dateiauswahl"
+% VORSPANN
+--------------------------------------------------------------
+ Auswahl der vorhandenen Dateien.
+ Gewuenschte Datei(en) bitte ankreuzen:
+% BILD
+--------------------------------------------------------------
+  
+--------------------------------------------------------------
+% ENDE
+% HILFE "EUDAS/Allgemein"
+% SEITE 1
+--- MENÜBEDIENUNG ---
+Das Menü dient zur Auswahl von Funktionen. Die Funktionen sind
+durch einen vorangestellten Buchstaben gekennzeichnet. Mit den
+Pfeiltasten können Sie die Markierung zu einer beliebigen
+Position auf und ab bewegen. Diese Funktion können Sie dann
+durch Drücken der Leertaste ausführen. Durch ESC '?' (nachein-
+ander gedrückt) erhalten Sie Informationen zur gerade
+markierten Funktion.
+Funktionen, die im momentanen Zustand nicht ausgeführt werden
+können, sind durch ein Minuszeichen gekennzeichnet.
+In der obersten Bildschirmzeile sind weitere Menüs aufgeführt,
+die Sie aufrufen können. Das aktuelle Menü ist invers
+markiert. Ein anderes Menü wählen Sie durch Drücken der
+Pfeiltasten RECHTS oder LINKS.
+Wollen Sie das Programm wieder verlassen, drücken Sie die
+ESC-Taste und 'q' hintereinander.
+---
+% ENDE
+% HILFE "EUDAS/1O"
+% SEITE 1
+--- Öffnen zum Bearbeiten ---
+Diese Funktion öffnet eine EUDAS-Datei zur anschließenden Bear­
+beitung. Sie können angeben, ob Sie die Datei nur ansehen oder
+auch ändern wollen. Die vorher geöffnete Datei wird ggf. ge­
+sichert. Wenn Sie eine neue Datei angeben, wird diese einge­
+richtet. Dabei müssen Sie die Feldnamen eingeben.
+
+=> Hinweise zur Menübedienung auf der zweiten Seite (ESC 'w')
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/1E"
+% SEITE 1
+--- EUDAS-Datei ketten
+Mit dieser Funktion können Sie eine EUDAS-Datei logisch an die
+bereits geöffnete Datei anketten. Dazu müssen jedoch die beiden
+Dateien in ihrer Feldstruktur übereinstimmen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/1N"
+% SEITE 1
+--- Notizen ansehen/ändern ---
+Mit dieser Funktion können Sie der aktuell geöffneten Datei
+Notizen zuordnen bzw. sich die vorherigen Notizen ansehen. Dazu
+wird der normale Editor verwendet.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/1M"
+% SEITE 1
+--- Manager (Mehrbenutzerbetrieb) ---
+Mit dieser Funktion können Sie die Task festlegen, aus der beim
+Öffnen automatisch EUDAS-Dateien geholt werden können. Dadurch
+können mehrere Benutzer auf die gleiche Datei zugreifen, jedoch
+immer nur einer ändern.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/1F"
+% SEITE 1
+--- Feldstruktur ändern ---
+Mit dieser Funktion können Sie
+
+1. neue Feldnamen anfügen
+ Sie können neue Feldnamen der Datei am Ende anfügen. Sie
+ müssen die Namen untereinander im Editor in der gewünschten
+ Reihenfolge angeben. Vorher werden Sie jedoch gefragt, ob
+ Sie diese Funktion überhaupt ausführen wollen.
+
+2. Feldnamen und Feldtypen ändern
+ In diesem Teil wird Ihnen eine Auswahl aller vorhandenen
+ Felder angeboten, in der jeweils auch der Typ angegeben ist.
+ Wenn Sie diese Funktion nicht ausführen wollen, beenden Sie
+ die Auswahl einfach mit ESC q. Sonst wählen Sie die Felder
+ aus, deren Namen oder Typ Sie ändern wollen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/1P"
+% SEITE 1
+--- Prüfbedingungen ---
+Bei dieser Funktion können Sie im Editor ein Prüfpro­
+gramm eingeben, das mit der Datei gespeichert wird und beim
+Reintragen neuer Sätze ausgeführt wird.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/1K"
+% SEITE 1
+--- EUDAS-Datei koppeln ---
+Mit dieser Funktion können Sie eine Datei angeben, die zu den
+bisher geöffneten Dateien dazugekoppelt wird. Anschließend
+werden zu jedem Satz der existierenden Datei die in den Koppel­
+feldern übereinstimmenden Sätze der Koppeldatei gezeigt.
+Als Koppelfelder werden dabei die ersten Felder der Koppeldatei
+betrachtet, die auch in der geöffneten Datei vorhanden sind.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/3S"
+% SEITE 1
+--- Aktuelle Datei sortieren ---
+Mit dieser Funktion kann die aktuell geöffnete EUDAS-Datei
+sortiert werden. Die Reihenfolge, in der die Felder berücksich­
+tigt werden, kann vorher angegeben werden. Eventuell müssen
+zum richtigen Sortieren Feldtypen vergeben werden (s.
+"Feldstrukt.").
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/1S"
+% SEITE 1
+--- Aktuelle Dateien sichern ---
+EUDAS arbeitet bei Änderungen immer auf Sicherheitskopien der
+Dateien. Wenn Ändern erlaubt ist, müssen geänderte Arbeits­
+kopien mit dieser Funktion gesichert werden. Für eine veränder­
+te Datei kann dabei auch ein neuer Name angegeben werden, damit
+die alte Version erhalten bleibt.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2W"
+% SEITE 1
+--- Satz weiter ---
+Diese Funktion geht zum nächsten Satz und zeigt ihn an. Wenn
+eine Suchbedingung eingestellt ist, werden nicht ausgewählte
+Sätze übersprungen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2Z"
+% SEITE 1
+--- Satz zurück ---
+Diese Funktion geht zum vorigen Satz. Wenn eine Suchbedingung
+eingestellt ist, werden nicht ausgewählte Sätze übersprungen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2S"
+% SEITE 1
+--- Suchbedingung setzen ---
+Mit dieser Funktion kann eine Suchbedingung als Suchmuster
+eingegeben werden, die angibt, welche Sätze bearbeitet werden
+sollen. Die vorher eingestellte Suchbedingung wird automatisch
+gelöscht. Die Bedingungen für die einzelnen Felder können im
+Editor eingegeben werden.
+
+mögliche Bedingungen:
+ Text identisch mit Text.. größergleich
+ *Text endet mit ..Text kleiner
+ Text* beginnt mit Text..Text zwischen
+ *Text* enthält * nicht leer
+
+ --Bed Verneinung
+
+Kombination von Bedingungen:
+ Bedingungen für verschiedene Felder:
+ UND
+ Komma zwischen Bedingungen:
+ lokales ODER (Prio höher als UND)
+ Semikolon zwischen Bedingungen:
+ globales ODER (Prio niedriger als UND)
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2L"
+% SEITE 1
+--- Suchbedingung löschen ---
+Mit dieser Funktion kann eine eingestellte Suchbedingung wieder
+gelöscht werden, so daß wieder alle Sätze sichtbar sind.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2N"
+% SEITE 1
+--- auf Satz Nr. ---
+Mit dieser Funktion kann ein bestimmter Satz direkt angewählt
+werden. Dazu müssen Sie lediglich dessen Satznummer angeben.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2E"
+% SEITE 1
+--- neuen Satz einfügen ---
+Mit dieser Funktion wird vor dem aktuellen Satz ein neuer Satz
+eingefügt. Die Inhalte dieses zunächst leeren Satzes können Sie
+mit Hilfe des Editors neben die einzelnen Feldnamen schreiben.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2A"
+% SEITE 1
+--- Satz ändern ---
+Mit dieser Funktion können Sie die Inhalte des aktuellen Satzes
+verändern. Am Bildschirm können Sie die Daten mit Hilfe des
+Editors ändern, löschen und Neues hinzufügen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2M"
+% SEITE 1
+--- Markierung ein/aus ---
+Mit dieser Funktion können Sie einen Satz markieren, damit
+später nur die markierten Sätze bearbeitet werden. Ist der Satz
+schon markiert, wird die Markierung wieder gelöscht. Wenn min­
+destens ein Satz markiert ist, erscheint die Markierungsinfor­
+mation in der Überschrift.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/3L"
+% SEITE 1
+--- Alle Markierungen loeschen ---
+Mit dieser Funktion werden alle Markierungen in der Datei
+gelöscht. Die Markierungsinformation wird nicht mehr angezeigt.
+Die Markierungen werden auch beim neuen Öffnen gelöscht, da sie
+nicht permanent in der Datei gespeichert sind.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2T"
+% SEITE 1
+--- Einzelsatz tragen ---
+Mit dieser Funktion kann der aktuelle Satz in eine andere Datei
+transportiert werden. Anschließend wird er gelöscht. Der Satz
+wird am Ende der Zieldatei angefügt, wobei diese gegebenenfalls
+eingerichtet wird. Den Namen der Zieldatei können Sie eingeben.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2H"
+% SEITE 1
+--- Einzelsatz holen ---
+Diese Funktion holt den letzten Satz einer anderen Datei und
+fügt ihn vor dem aktuellen Satz ein. Damit wird das letzte
+'Tragen' wieder rückgängig gemacht. Die Dateien müssen gleiche
+Felderzahl haben.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/3U"
+% SEITE 1
+--- Übersicht ---
+Mit dieser Funktion können Sie sich eine Übersicht über mehrere
+Sätze verschaffen. Es werden vom aktuellen Satz an alle durch
+die Suchbedingung spezifizierten Sätze angezeigt, jeder Satz in
+einer Zeile. In dieser Übersicht können Sie blättern und auch
+bestimmte Sätze zur späteren Bearbeitung markieren.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/2F"
+% SEITE 1
+--- Auswahl Felder ---
+Mit dieser Funktion kann gewählt werden, welche Felder in
+welcher Reihenfolge angezeigt werden sollen. Alle Felder
+werden zum Ankreuzen angeboten.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/4D"
+% SEITE 1
+--- Drucken nach Muster ---
+Mit dieser Funktion können die Inhalte der Datei nach einem
+Druckmuster ausgedruckt werden. Das Druckmuster ist eine Text­
+datei und muß vorher erstellt werden. Es gibt die Form des
+Ausdrucks an. Über den Aufbau eines Druckmusters lesen Sie am
+besten das Benutzerhandbuch.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/3T"
+% SEITE 1
+--- Satzauswahl tragen ---
+Diese Funktion trägt alle durch die Suchbedingung oder durch
+Markierung ausgewählten Sätze in eine andere Datei und löscht
+sie danach. Die Zieldatei muß gleiche Felderzahl haben, damit
+keine Information verlorengeht. Beim Tragen können auch die
+Prüfbedingungen der Zieldatei geprüft werden, wenn Sie die
+entsprechende Frage bejahen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/4E"
+% SEITE 1
+--- Textdatei erstellen/aendern ---
+Mit dieser Funktion kann eine Textdatei erstellt, geändert oder
+angesehen werden. Es wird der normale Editor verwendet. Mit
+dieser Funktion werden auch Druckmuster bearbeitet.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/3K"
+% SEITE 1
+--- Satzauswahl kopieren ---
+Diese Funktion kopiert alle durch die Suchbedingung oder durch
+Markierung ausgewählten Sätze in eine andere Datei. Welche
+Felder in welcher Reihenfolge kopiert werden sollen, wird durch
+ein Kopiermuster bestimmt, das nach der Struktur der Zieldatei
+bestimmt wird und dann von Ihnen noch geändert werden kann.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/4R"
+% SEITE 1
+--- Richtung Ausgabe ---
+Mit dieser Funktion können Sie festlegen, ob die Ausgabe des
+Druckvorgangs direkt anschließend ausgedruckt werden soll, oder
+in eine Datei gespeichert wird. Sie können den Namen dieser
+Datei eingeben, anderenfalls wählt sich EUDAS selbst einen
+Namen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/4A"
+% SEITE 1
+--- Textdatei ausdrucken ---
+Mit dieser Funktion wird eine Textdatei direkt ausgedruckt. Die
+Datei kann Anweisungen zur Druckersteuerung enthalten, die Sie
+dem EUMEL-Benutzerhandbuch entnehmen können. Sie können hiermit
+Ausgabedateien des Druckprozesses und das Druckmuster selbst
+ausdrucken.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/3V"
+% SEITE 1
+--- Ändern nach Vorschrift ---
+Diese Funktion ermöglicht es, alle durch die Suchbedingung oder
+durch Markierung ausgewählten Sätze nach einer Vorschrift auto­
+matisch zu ändern. Die Art der Änderungen wird dabei durch ein
+Verarbeitungsmuster festgelegt, das vorher als Textdatei er­
+stellt werden muß. Über die Form des Verarbeitungsmusters s.
+Benutzerhandbuch.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/4N"
+% SEITE 1
+--- Textdatei nachbearbeiten ---
+Mit dieser Funktion können Sie eine Datei zeilenweise und
+seitenweise formatieren (lineform/pageform). Dies dient an
+dieser Stelle zur Bearbeitung von Druckdateien, die
+verschiedene oder Proportionalschriften enthalten. Sie werden
+jeweils für jede der beiden Funktionen gefragt, ob Sie sie
+ausführen wollen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/6S"
+% SEITE 1
+--- Schreiben auf Archiv ---
+Diese Funktion schreibt eine oder mehrere Dateien auf das
+Archiv. Der Archivname muß vorher eingegeben werden. Dann kann
+entweder der Name der gewünschten Datei eingegeben werden oder
+mit ESC 'z' eine Auswahl von Dateien angekreuzt werden.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/5A"
+% SEITE 1
+--- Datei aufräumen ---
+Diese Funktion reorganisiert eine Datei, an der viel geändert
+wurde, zur Platz- und Zeitersparnis.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/5K"
+% SEITE 1
+--- Datei kopieren ---
+Mit dieser Funktion kann eine beliebige Datei logisch kopiert
+werden. Die Kopie ist identisch mit dem Original und belegt den
+gleichen Platz, erst bei Änderungen werden unterschiedliche
+Daten gespeichert.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/5P"
+% SEITE 1
+--- Platzbedarf Datei ---
+Diese Funktion gibt an, wieviel Platz eine Datei im System
+belegt. Dieser Platz kann aber mit anderen Dateien geteilt
+sein.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/6D"
+% SEITE 1
+--- Archivübersicht drucken ---
+Diese Funktion druckt die Übersicht der Archivdateien aus.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/6I"
+% SEITE 1
+--- Archiv initialisieren ---
+Diese Funktion initialisiert einen Archivträger vor dem
+Beschreiben. Sämtliche Daten werden gelöscht. Auf Wunsch kann
+der Datenträger auch formatiert werden (falls vom System
+unterstützt).
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/6Z"
+% SEITE 1
+--- Zielarchiv einstellen ---
+Mit dieser Funktion kann eine Managertask angegeben werden, auf
+die die Archivfunktionen angewendet werden. Dies dient sowohl
+zur Ansteuerung von mehreren Archiven (z.B. über Netz) als auch
+zur Kommunikation mit anderen Managern.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/6P"
+% SEITE 1
+--- Passwort ---
+Mit dieser Funktion können Sie das Passwort einstellen, das
+beim Versenden von Dateien an andere Tasks verwendet wird. Beim
+Schreiben einer Datei wird das Passwort der Datei mitgegeben
+und beim Lesen wird überprüft, ob das Passwort übereinstimmt.
+Das Passwort kann in der Form Schreibpasswort/Lesepasswort
+angegeben werden.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/6R"
+% SEITE 1
+--- Reservieren ---
+Mit dieser Funktion können Sie einen Kanalmanager (z.B.
+DOS-Task) reservieren. Die Reservierung wird beim Verlassen des
+Archivmenüs wieder aufgehoben. Den Parameter zur Reservierung
+(Modus bei DOS-Task) können Sie angeben. Bei normalen Archiv­
+tasks wird die Reservierung automatisch vorgenommen, daher ist
+diese Funktion dann gesperrt.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/6K"
+% SEITE 1
+--- Kopieren vom Archiv ---
+Diese Funktion kopiert eine Datei vom Archiv ins System. Der
+Archivname wird automatisch bestimmt. Sie können dann entweder
+den gewünschten Dateinamen angeben oder mit ESC 'z' eine Aus­
+wahl aller Dateien auf dem Archiv abrufen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/5N"
+% SEITE 1
+--- Datei Namen ändern ---
+Mit dieser Funktion können Sie für eine Datei auf dem System
+einen neuen Namen vergeben. Wenn Sie den neuen Namen eingeben,
+wird Ihnen der alte Name angeboten. Sie können ihn ändern oder
+ganz überschreiben. Dadurch ersparen Sie sich bei kleinen
+Änderungen das Neutippen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/6L"
+% SEITE 1
+--- Löschen auf Archiv ---
+Diese Funktion ermöglicht es, eine Datei auf dem Archiv zu
+löschen. Der Platz dieser Datei wird jedoch nur dann wiederver­
+wendet, wenn keine Dateien mehr dahinter stehen. Der Archivname
+muß eingegeben werden. Sie können bei der Eingabe des Datei­
+namens mit ESC 'z' eine Dateiauswahl abrufen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/5L"
+% SEITE 1
+--- Datei löschen ---
+Diese Funktion löscht eine Datei auf dem System nach Anfrage.
+Sie können den Dateinamen eingeben oder mit ESC 'z' eine Aus­
+wahl aller vorhandenen Dateien abrufen.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/6U"
+% SEITE 1
+--- Übersicht Archiv ---
+Diese Funktion liefert eine Übersicht der Dateien auf dem
+Archiv. Verlassen Sie diese Übersicht mit ESC 'q'.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "EUDAS/5U"
+% SEITE 1
+--- Übersicht Dateien ---
+Diese Funktion liefert eine Übersicht über alle im System vor­
+handenen Dateien. Verlassen Sie diese Übersicht mit ESC 'q'.
+---
+% SEITE 1 "EUDAS/Allgemein"
+% ENDE
+% HILFE "AUSWAHL/Allgemein"
+% SEITE 1
+--- AUSWAHL ---
+Mit Hilfe der Auswahl ist es möglich, aus einem Angebot einen
+Teil auszuwählen. Die gewünschten Namen werden einfach in
+beliebiger Reihenfolge angekreuzt und anschließend in dieser
+Reihenfolge verwendet.
+Die Schreibmarke (Cursor) gibt an, welcher Name gerade ange­
+kreuzt werden kann. Mit den Pfeiltasten kann der Cursor auf den
+Kreisen bewegt werden. 'x' kreuzt einen Namen an, 'o' löscht
+die Ankreuzung wieder.
+Mit ESC 'q' wird die Auswahl verlassen. ESC 'a' bricht die
+Auswahl und die folgende Funktion ab. Falls das Angebot nicht
+auf den Bildschirm paßt, wird es gerollt. ESC '1' positioniert
+immer auf den Anfang und ESC '9' auf das Ende der Auswahl. Mit
+HOP 'x' werden alle noch nicht angekreuzten Namen angekreuzt,
+mit HOP 'o' werden alle Ankreuzungen gelöscht.
+---
+% ENDE
+% HILFE "AUSWAHL/Felder"
+% SEITE 1
+---
+Sie können hier alle Felder ankreuzen, die Sie ändern wollen.
+Ändern können Sie den Feldnamen und den Feldtyp. Wollen Sie
+keine Felder ändern, drücken Sie einfach ESC 'q'.
+---
+% SEITE 1 "AUSWAHL/Allgemein"
+% ENDE
+% HILFE "AUSWAHL/Sortierfelder"
+% SEITE 1
+---
+Kreuzen Sie hier die Felder an, die bei der Sortierung berück­
+sichtigt werden sollen. Die Reihenfolge des Ankreuzens ist
+wichtig. Beim Vergleich zweier Sätze wird erst das als erstes
+angekreuzte Feld verglichen und danach die Einordnung der Sätze
+bestimmt. Ist dieses Feld bei beiden gleich, wird das nächste
+angekreuzte Feld untersucht usw.
+---
+% SEITE 1 "AUSWAHL/Allgemein"
+% ENDE
+% HILFE "AUSWAHL/Anzeigefelder"
+% SEITE 1
+---
+Kreuzen Sie hier alle Felder an, die Sie angezeigt haben möch­
+ten. Die Felder erscheinen in der angekreuzten Reihenfolge. Für
+beide Arten der Anzeige können Sie eine separate Feldauswahl
+einstellen.
+---
+% SEITE 1 "AUSWAHL/Allgemein"
+% ENDE
+% HILFE "AUSWAHL/Feldnamen"
+% SEITE 1
+---
+Durch Blättern in der Auswahl können Sie die Schreibweise der
+Feldnamen ansehen. Die Namen, die Sie ankreuzen, werden danach
+mit Anführungsstrichen in die gerade editierte Datei übernommen.
+---
+% SEITE 1 "AUSWAHL/Allgemein"
+% ENDE
+% HILFE "AUSWAHL/Archiv"
+% SEITE 1
+---
+Diese Auswahl zeigt alle auf dem Archiv vorhandenen Dateien an.
+Kreuzen Sie die Dateien an, die Sie bearbeiten möchten. Die
+Dateien werden in der angekreuzten Reihenfolge verwendet.
+---
+% SEITE 1 "AUSWAHL/Allgemein"
+% ENDE
+% HILFE "AUSWAHL/Datei"
+% SEITE 1
+---
+Diese Auswahl zeigt alle Dateien auf dem System, die Sie ver­
+wenden können. Kreuzen Sie die gewünschte(n) Datei(en) an.
+---
+% SEITE 1 "AUSWAHL/Allgemein"
+% ENDE
+% HILFE "FEHLER/Allgemein"
+% SEITE 1
+--- FEHLERMELDUNGEN ---
+Fehlermeldungen werden von einem Programm abgesetzt, wenn es
+seine Funktion nicht durchführen kann. Der Text der Meldung
+identifiziert die Ursache des Problems. Zur Zeit liegen noch
+keine meldungsspezifischen Informationen vor, schauen Sie ggf.
+in das Benutzerhandbuch.
+---
+% ENDE
+% HILFE "FEHLER/9"
+% SEITE 1
+---
+Diese Fehlermeldung deutet auf einen internen Programmfehler
+(wenn Sie nicht selber ein Programm geschrieben haben). Melden
+Sie diesen Fehler bitte, damit eine Korrektur vorgenommen
+werden kann. Schreiben Sie sich dazu die Begleitumstände auf
+(welche Datei haben Sie benutzt, welche Funktion). Versuchen
+Sie gegebenenfalls, den Fehler zu wiederholen. Es ist nämlich
+z.B. wichtig, ob der Fehler nur bei einer bestimmten Datei
+auftritt oder ganz "zufällig". Wenn Sie vermuten, daß der
+Fehler an einer bestimmten Datei liegt, sichern Sie diese Datei
+bitte auf einer Diskette, um sie eventuell einschicken zu
+können.
+---
+% ENDE
+% HILFE "FEHLER/10"
+% SEITE 1 "FEHLER/9"
+% ENDE
+% HILFE "FEHLER/11"
+% SEITE 1 "FEHLER/9"
+% ENDE
+% HILFE "FEHLER/14"
+% SEITE 1 "FEHLER/9"
+% ENDE
+% HILFE "GET/Allgemein"
+% SEITE 1
+--- EINGABE ---
+Die Eingabe erwartet von Ihnen eine bestimmte Information, die
+Sie eingeben sollen. Die Art der Information wird durch den
+Anforderungstext angegeben. Wenn Sie sich beim Eintippen ver­
+schrieben haben, können Sie mit den Pfeiltasten zurückgehen
+und den Text korrigieren. Eine bereits dastehende Information
+können Sie überschreiben. RUBOUT löscht ein Zeichen, RUBIN
+schaltet in den Einfügemodus (Zeichen werden nicht mehr über­
+schrieben). Beenden Sie die Eingabe mit RETURN. ESC 'h' bricht
+die Eingabe und die folgende Funktion ab. Wenn in der Status­
+zeile angegeben, können Sie mit ESC 'z' eine Auswahl verfüg­
+barer Namen abrufen, die Sie dann Ankreuzen können.
+---
+% ENDE
+% HILFE "GET/Sicherungsname"
+% SEITE 1
+---
+Sie können jetzt den Namen angeben, unter dem die Arbeitskopie
+gespeichert werden soll. Ihnen wird der alte Name zum Über­
+schreiben angeboten. Drücken Sie nur RETURN, wird der alte Name
+genommen und die alte Version überschrieben.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/Dateiname"
+% SEITE 1
+---
+Bitte geben Sie den Namen der Datei ein, mit dem die Operation
+ausgeführt werden soll. Mit ESC 'z' können Sie sich die zur
+Verfügung stehenden Namen auch als Auswahl zeigen lassen.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/feldname"
+% SEITE 1
+---
+Sie können den Namen des angegebenen Feldes ändern, indem Sie
+den alten Namen überschreiben bzw. korrigieren.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/feldtyp"
+% SEITE 1
+---
+Sie können hier einen von vier möglichen Typen eingeben:
+ TEXT normaler Text mit Vergleich nach EUMEL-Code.
+ DIN Text, der nach DIN 5007 verglichen wird (Umlaute rich­
+ tig, Groß-/Kleinschreibung und Sonderzeichen ignoriert).
+ ZAHL Alle nichtnumerischen Zeichen außer Minus und Dezimal­
+ komma werden beim Vergleichen ignoriert.
+ DATUM Datum der Form "tt.mm.jj"
+Die Feldtypen werden beim Sortieren und Suchen beachtet.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/auf Satz"
+% SEITE 1
+---
+Sie können hier die Satznummer des Satzes eingeben, den Sie
+sehen wollen.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/copy"
+% SEITE 1
+---
+ Geben Sie hier den Namen für die logische Kopie der Datei an.
+ Dieser Name darf keine existierende Datei bezeichnen.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/Archivname"
+% SEITE 1
+---
+Geben Sie den Namen des eingelegten Archivs ein (zur Sicher­
+heit). Der zuletzt verwendete Name wird zum Ändern angeboten.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/rename"
+% SEITE 1
+---
+Sie können den alten Namen der Datei durch Überschreiben und
+Korrigieren ändern.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/Druckdatei"
+% SEITE 1
+---
+Geben Sie hier den Namen der Datei ein, in die die Ausgabe des
+Druckprozesses geschrieben werden soll. Diese Datei wird nur
+für den nächsten Druckvorgang verwendet. Sie müssen den Namen
+also jedes Mal wieder neu angeben. Existiert die Datei schon,
+wird die Ausgabe an das Ende angehängt.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/Zielarchiv"
+% SEITE 1
+---
+Geben Sie hier entweder den Namen einer Archivtask ein
+(normalerweise "ARCHIVE") oder einer anderen Managertask. Bei
+Netzbetrieb können Sie auch die Station anschließend angeben.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/Zielstation"
+% SEITE 1
+---
+Geben Sie hier die Stationsnummer der Zieltask ein. Wenn sich
+die Zieltask in Ihrem eigenen System befindet, brauchen Sie nur
+RETURN zu drücken.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/multi task"
+% SEITE 1
+---
+Sie können hier den Namen einer EUDAS-Managertask angeben
+(EUDAS muß in dieser Task insertiert sein). Wenn Sie keinen
+Namen angeben, werden keine entsprechenden Abfragen beim Öffnen
+mehr gemacht.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "GET/kopiermuster"
+% SEITE 1
+---
+Geben Sie den Namen einer Datei ein, in der das Kopiermuster
+stehen soll. Drücken Sie einfach RETURN, wenn Sie das Muster
+nicht aufbewahren wollen. Wenn die Datei noch nicht existiert,
+wird das Standard-Kopiermuster in die Datei geschrieben.
+Anschließend kann das Muster noch im Editor geändert werden.
+---
+% SEITE 1 "GET/Allgemein"
+% ENDE
+% HILFE "JA/Allgemein"
+% SEITE 1
+--- FRAGEN ---
+Das Programm stellt Ihnen eine Frage, die Sie bejahen oder
+verneinen können. Sie bejahen die Frage, indem Sie 'j' drücken
+und verneinen Sie mit 'n' (beides groß oder klein). Mit ESC 'h'
+können Sie die Funktion abbrechen.
+---
+% ENDE
+% HILFE "JA/oeffne"
+% SEITE 1
+---
+Beantworten Sie die Frage mit 'n', wenn Sie die Datei nur anse­
+hen wollen. In diesem Fall wird keine Sicherheitskopie er­
+stellt. Verneinen Sie die Frage, wird eine interen Kopie ange­
+legt, die Sie dann verändern können. Die Kopie muß nach dem
+Ändern gesichert werden.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/alte version"
+% SEITE 1
+---
+Wenn Sie diese Frage bejahen, wird die Arbeitskopie unter dem
+angegebenen Namen gesichert. Die alte Version geht dadurch
+verloren. Wenn Sie die Frage verneinen, haben Sie Gelegenheit,
+einen neuen Namen anzugeben, damit die alte Version erhalten
+bleiben kann.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Datei loeschen"
+% SEITE 1
+---
+Beim Sichern hatten Sie Gelegenheit, alle veränderten Dateien
+zu sichern. Die Sicherheitskopien können damit gelöscht werden.
+Dazu bejahen Sie die Frage. Wenn die Dateien jedoch noch geöff­
+net bleiben sollen, oder Sie eine Datei aus Versehen nicht
+gesichert haben, müssen Sie diese Frage verneinen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/sichere"
+% SEITE 1
+---
+Die interne Arbeitskopie der angegebenen Datei wurde gegenüber
+dem Original verändert. Wenn Sie diese Änderungen behalten
+wollen, müssen Sie die Frage bejahen. Sie haben dann noch die
+Möglichkeit, die geänderte Version unter neuem Namen zu
+sichern, um die alte Version zu behalten. Wenn Sie die Frage
+verneinen, gehen die Änderungen verloren und das Original
+bleibt erhalten.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/ueber"
+% SEITE 1
+---
+Sie haben für die Arbeitskopie einen Namen angegeben, der noch
+existiert. Bejahen Sie die Frage, wird die alte Datei dieses
+Namens überschrieben. Anderenfalls erhalten Sie eine neue Gele­
+genheit, einen Namen einzugeben.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Sicherungssortierung"
+% SEITE 1
+---
+Die angegebene Datei war früher schon einmal sortiert worden.
+Die Sortierung wurde jedoch durch nachfolgende Änderungen
+zerstört. Wenn Sie die Datei wieder sortiert haben wollen,
+beantworten Sie die Frage mit 'j'. Die Sortierung dauert nicht
+lange, wenn nur wenige Sätze verändert wurden.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/feldnamen"
+% SEITE 1
+---
+Falls Sie neue Felder zu den existierenden anfügen wollen,
+müssen Sie diese Frage bejahen. Sie erhalten dann Gelegenheit,
+die neuen Namen im Editor einzugeben.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Sortierfelder"
+% SEITE 1
+---
+Die Reihenfolge, in der die Felder bei der Sortierung berück­
+sichtigt werden, ist in der EUDAS-Datei intern gespeichert.
+Wenn Sie diese Reihenfolge, die beim letzten Sortieren angege­
+ben wurde, ändern möchten, müssen Sie die Frage bejahen. Sie
+können dann die neue Feldreihenfolge auswählen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/sortieren"
+% SEITE 1
+---
+Wenn Sie diese Frage bejahen, wird die Zieldatei nach Ausfüh­
+rung der Funktion in ihrer eingestellten Feldreihenfolge sor­
+tiert.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/forget"
+% SEITE 1
+---
+Wenn Sie diese Frage bejahen, wird die Datei wirklich gelöscht.
+Wenn Sie die Datei irrtümlich gewählt haben, müssen Sie die
+Frage verneinen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/direkt drucken"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, wird das Ergebnis des Druckens am
+Ende des Vorgangs ausgedruckt. Anderenfalls wird das Ergebnis
+in einer Datei zwischengespeichert. Sie können die Ausgabe dann
+noch behandeln, ehe Sie sie ausdrucken.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/einrichten"
+% SEITE 1
+---
+Sie haben eine Datei angegeben, die noch nicht existiert. Wenn
+Sie die Frage bejahen, wird die Datei neu eingerichtet. Ande­
+renfalls wird die Funktion abgebrochen, so daß Sie Gelegenheit
+haben, die Funktion mit einem neuen Namen zu wiederholen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/testen"
+% SEITE 1
+---
+Wenn Sie diese Frage bejahen, werden beim Tragen die Prüfbedin­
+gungen der Zieldatei abgefragt. Sätze, die diese Bedingungen
+nicht erfüllen, werden nicht getragen und können danach geän­
+dert werden. Beim Ändern wird dann jeweils die den Satz betref­
+fende Meldung ausgegeben. Die Prüfbedingungen der Zieldatei
+können Sie mit der Funktion "Feldstruktur aendern" angeben oder
+ändern.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/save"
+% SEITE 1
+---
+Die angegebene Datei befindet sich bereits auf dem Archiv. Wenn
+Sie die Datei überschreiben wollen, müssen Sie die Frage beja­
+hen. Ansonsten wird die Datei nicht auf das Archiv geschrieben
+(keine Wirkung).
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/fetch"
+% SEITE 1
+---
+Die angegebene Datei ist bereits im System vorhanden. Wenn Sie
+diese Datei überschreiben wollen, müssen Sie die Frage bejahen.
+Anderenfalls wird keine Aktion vorgenommen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/erase"
+% SEITE 1
+---
+Zur Sicherheit wird gefragt, ob Sie die angegebene Datei wirk­
+lich auf dem Archiv löschen wollen. Wenn Sie die Frage vernei­
+nen, wird keine Aktion durchgeführt.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Druckdatei"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, können Sie für die Ausgabedatei
+einen bestimmten Namen angeben. Anderenfalls wird ein Name
+"EUDAS-Ausgabe.n" automatisch von EUDAS vergeben.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Zielmanager"
+% SEITE 1
+---
+Ein Archivmanager ist eine Task, die tatsächlich ein
+physikalisches Speichermedium (Diskette) bedient, das für den
+jeweiligen Benutzer reserviert werden muß. Normale Managertasks
+können von mehreren Benutzern gleichzeitig angesprochen werden.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/format"
+% SEITE 1
+---
+Wenn Ihr Rechner dies unterstützt, können Sie Archivdisketten
+vor dem Initialisieren noch physikalisch formatieren. Dies ist
+immer dann notwendig, wenn eine Diskette neu ist (vor der
+ersten Benutzung) oder wenn Schreibfehler aufgetreten sind, die
+sich nicht mehr reparieren lassen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/archiv loeschen"
+% SEITE 1
+---
+Wenn Sie irrtümlich die falsche Diskette eingelegt haben oder
+eine andere Funktion ausführen wollten, können Sie die Funktion
+durch Verneinen der Frage abbrechen. Achten Sie auf den
+angegebenen Archivnamen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/archiv init"
+% SEITE 1
+---
+Wenn Sie aus Versehen die falsche Funktion gewählt haben,
+können Sie die Funktion durch Verneinen der Frage abbrechen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Feld aendern"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, werden Ihnen alle vorhandenen
+Felder zum Ankreuzen angeboten. Sie können dann für die
+angekreuzten Felder die Namen und Feldtypen ändern.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/alle Saetze"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, werden anschließend alle Sätze, die
+in der Übersicht zu sehen waren, gedruckt. Den Namen des
+Druckmusters können Sie dann gleich eingeben. Wenn Sie keinen
+oder nur den aktuellen Satz drucken wollen, müssen Sie die
+Frage verneinen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/alle markierten"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, werden anschließend alle markierten
+Sätze gedruckt. Den Namen des Druckmusters können Sie dann
+gleich eingeben. Wenn Sie keinen oder nur den aktuellen Satz
+drucken wollen, müssen Sie die Frage verneinen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Einzelsatz drucken"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, wird der aktuelle (markierte) Satz
+gedruckt. Den Namen des Druckmusters können Sie dann gleich
+eingeben. Wenn Sie keinen Satz drucken wollen, müssen Sie die
+Frage verneinen.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/noch einmal"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, können Sie noch einmal die Datei
+mit einer neuen Suchbedingung ansehen und erneut drucken. Sonst
+kehren Sie wieder in den Editor zurück.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Ub. Felder"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, können Sie einzelne Felder in einer
+bestimmten Reihenfolge für die Übersichtsanzeige auswählen.
+Anderenfalls werden alle Felder angezeigt.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Suchmuster"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, können Sie eine Suchbedingung für
+die angezeigten Sätze angeben.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/umschalten"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, schalten Sie auf die genannte
+Koppeldatei um. Damit wird diese Datei zeitweise als einzige
+geöffnete betrachtet. Damit können Sie einen bestimmten Satz
+aufsuchen, den Sie später beim Zurückschalten übernehmen
+können. Verneinen Sie die Frage, werden Ihnen weitere mögliche
+Koppeldateien angeboten, oder Sie kehren ohne Schaden zurück.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/uebernehmen"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, werden die Koppelfelder des jetzt
+ausgewählten Satzes in den aktuellen Satz der ersten Datei
+übernommen, an dem Sie dann weiter ändern können.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/Sortierrichtung"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, wird die Datei nach dem genannten
+Feld in aufsteigender Richtung sortiert, anderenfalls in
+absteigender. Für weitere Felder können Sie wieder eine andere
+Richtung angeben.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/zeilenform"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, wird die angegebene Datei
+zeilenweise interaktiv formatiert. Der Text wird unter
+Berücksichtigung der Schrifttypen gleichmäßig auf die Zeilen
+verteilt. Beachten Sie die Wirkung der Absatzmarken!
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/seitenform"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, wird die angegebene Datei
+interaktiv seitenweise formatiert. Der Text wird bis zur
+angegebenen Seitenlänge auf die Seiten verteilt. Dabei werden
+Seitenköpfe und Fußnoten eingefügt. Das Ergebnis steht in der
+Datei "xxx.p".
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "JA/pw loeschen"
+% SEITE 1
+---
+Wenn Sie die Frage bejahen, wird das Passwort gelöscht und das
+leere Passwort eingestellt. Anderenfalls bleibt das alte
+Passwort erhalten.
+---
+% SEITE 1 "JA/Allgemein"
+% ENDE
+% HILFE "EDIT/Allgemein"
+% SEITE 1
+--- EDITOR ---
+Mit dem Editor können Sie einen Text zeilenweise eingeben.
+Dabei können Sie den Cursor mit den Pfeiltasten bewegen. RUBOUT
+löscht ein Zeichen, RUBIN schaltet in den Einfügemodus um. Für
+weitere Informationen zum Editor s. EUMEL-Benutzerhandbuch. ESC
+'q' verläßt den Editor normal. Mit ESC 'h' wird die Funktion
+abgebrochen.
+---
+% ENDE
+% HILFE "EDIT/Feldnamen"
+% SEITE 1
+---
+Sie können hier die neuen Feldnamen in der gewünschten Reihen­
+folge untereinander eingeben. Jeder Feldname muß in einer
+Zeile stehen und ohne Anführungsstriche geschrieben sein.
+---
+% SEITE 1 "EDIT/Allgemein"
+% ENDE
+% HILFE "EDIT/Pruefbed"
+% SEITE 1
+---
+Sie können hier die Prüfbedingungen der Datei eingeben bzw.
+ändern. Die Prüfbedingungen sind ein ELAN-Programm. Da ELAN-
+Programme formatfrei sind, kann es sein, daß Ihr Programm beim
+nächsten Mal anders erscheint, als Sie es eingegeben haben.
+---
+% SEITE 1 "EDIT/Allgemein"
+% ENDE
+% HILFE "EDIT/Notizen"
+% SEITE 1
+---
+Sie können jetzt zu der angegebenen Datei beliebige Notizen
+eingeben bzw. ändern. Sie befinden sich im Editor und können
+die gleichen Funktionen wie bei der normalen Texteingabe
+verwenden.
+---
+% SEITE 1 "EDIT/Allgemein"
+% ENDE
+% HILFE "EDIT/Suchen"
+% SEITE 1
+---
+Sie können jetzt eine Selektionsbedingung einstellen. Dazu
+müssen Sie jeweils neben den Feldnamen eine Bedingung schrei­
+ben. Mögliche Bedingungen sind:
+ Text muß gleich sein
+ Text* muß mit Text anfangen
+ *Text muß mit Text enden
+ *Text* enthält Text
+ Text.. muß größer oder gleich Text sein
+ ..Text muß kleiner als Text sein oder mit Text anfangen
+ Text1..Text2 liegt zwischen den beiden Texten
+"--" verneint eine Bedingung. Weitere Bedingungen und Kombina­
+tion von Bedingungen s. EUDAS-Benutzerhandbuch.
+---
+% SEITE 1 "EDIT/Allgemein"
+% ENDE
+% HILFE "EDIT/Einfuegen"
+% SEITE 1
+---
+Sie können hier die Inhalte eines neuen Satzes eingeben, der
+vor dem aktuellen Satz eingefügt wird.
+Spezielle Tastenkombinationen:
+ ESC RUBOUT Rest der Zeile löschen
+ ESC RUBIN Zeile aufbrechen
+ ESC OBEN nach oben blättern
+ ESC UNTEN nach unten blättern
+ ESC '1' auf erste Zeile
+ ESC '9' auf letzte Zeile
+ ESC 'h' Abbruch, der Satz wird nicht eingefügt
+ ESC 'w' Beenden und gleich den nächsten Satz einfügen
+ ESC 'D' aktuelles Tagesdatum schreiben
+---
+% SEITE 1 "EDIT/Allgemein"
+% ENDE
+% HILFE "EDIT/Aendern"
+% SEITE 1
+---
+Sie können die Inhalte des aktuellen Satzes hier abändern.
+Spezielle Tastenkombinationen:
+ ESC RUBOUT Rest der Zeile löschen
+ ESC RUBIN Zeile aufbrechen
+ ESC OBEN nach oben blättern
+ ESC UNTEN nach unten blättern
+ ESC '1' auf erste Zeile
+ ESC '9' auf letzte Zeile
+ ESC 'h' Abbruch, der Satz bleibt unverändert
+ ESC 'w' Beenden und gleich den nächsten Satz ändern
+ ESC 'D' aktuelles Tagesdatum schreiben
+---
+% SEITE 1 "EDIT/Allgemein"
+% ENDE
+% HILFE "EDIT/Druckmuster"
+% SEITE 1 "EDIT/Allgemein"
+% ENDE
+% HILFE "EDIT/Verarbeite"
+% SEITE 1
+---
+Sie können hier eine Verarbeitungsvorschrift eingeben. Die
+Verarbeitungsvorschrift ist ein ELAN-Programm. Ein Feld wird
+geändert durch den Operator "V":
+ "Feldname" V "neuer Feldinhalt";
+Statt des neuen Feldinhalts kann auch ein beliebiger ELAN-Aus­
+druck angegeben werden. Mit
+ f ("Feldname")
+wird der Inhalt eines Feldes als Text geliefert.
+---
+% SEITE 1 "EDIT/Allgemein"
+% ENDE
+% HILFE "EDIT/Kopiermuster"
+% SEITE 1
+---
+Sie können das hier angegebene Kopiermuster verändern. Sollen
+Felder nicht kopiert werden, brauchen Sie nur die entsprechen­
+den Zeilen zu löschen. Soll eine Feld andere Inhalte bekommen,
+geben Sie in dem Ausdruck
+ "Feldname" K f ("Feldname");
+hinter dem K einen anderen ELAN-Ausdruck ein. Die Reihenfolge
+der K-Ausdrücke bestimmt die Reihenfolge der Feldnamen in der
+Zieldatei, wenn die Zieldatei noch nicht existierte.
+---
+% SEITE 1 "EDIT/Allgemein"
+% ENDE
+% HILFE "UEBERSICHT"
+% SEITE 1
+---
+In diesem Modus können Sie sich alle Sätze der Datei durch
+Blättern ansehen. Der aktuelle Satz ist jeweils markiert. Die
+eingestellte Suchbedingung wird beachtet. Mit den Pfeiltasten
+OBEN und UNTEN bewegen Sie sich vorwärts und rückwärts in der
+Datei. Mit HOP OBEN, HOP UNTEN und HOP RETURN blättern Sie wie
+im Editor. Mit ESC '1' gelangen Sie an den Anfang, mit ESC '9'
+an das Ende der Datei. Mit '+' und '-' können Sie die
+Markierung des aktuellen Satzes für spätere Verarbeitung
+ändern. Verlassen Sie die Übersicht mit ESC 'q'.
+---
+% ENDE
+% HILFE "SHOW/Uebersicht"
+% SEITE 1
+---
+In der gezeigten Dateiübersicht können Sie mit HOP OBEN und HOP
+UNTEN blättern, wenn nicht alle Dateien auf eine Seite passen.
+Verlassen Sie die Übersicht mit ESC 'q'.
+---
+% ENDE
+
diff --git a/eudas/pos.173 b/eudas/pos.173
new file mode 100644
index 0000000..a9706a3
--- /dev/null
+++ b/eudas/pos.173
@@ -0,0 +1,19 @@
+PACKET xpos DEFINES x pos :
+INT PROC x pos (TEXT CONST a, b, INT CONST c, d) :
+ pos (a, b, c, d)
+END PROC x pos;
+END PACKET x pos;
+PACKET pos 173 DEFINES pos:
+INT PROC pos (TEXT CONST a, b, INT CONST c, d) :
+ x pos (a, b, c, d+1)
+END PROC pos;
+END PACKET pos 173;
+PACKET add 173 DEFINES split line, reserve :
+PROC split line (FILE VAR f, INT CONST spalte, BOOL CONST dummy) :
+ split line (f, spalte)
+END PROC split line;
+PROC reserve (TEXT CONST modus, TASK CONST task) :
+ call (19, modus, task)
+END PROC reserve;
+END PACKET add 173;
+
diff --git a/graphic/Beispiel.Kreuz b/graphic/Beispiel.Kreuz
new file mode 100644
index 0000000..e29f24a
--- /dev/null
+++ b/graphic/Beispiel.Kreuz
@@ -0,0 +1,41 @@
+initialisiere picfile;
+zeichne die x achse;
+zeichne die y achse;
+zeichne die z achse;
+stelle das achsenkreuz dar .
+
+initialisiere picfile:
+ PICFILE VAR p :: picture file ("KREUZ") .
+
+zeichne die x achse:
+ PICTURE VAR x achse := nilpicture;
+ move (x achse, -1.0, 0.0, 0.0);
+ draw (x achse, "-X", 0.0, 0.0, 0.0);
+ draw (x achse, 1.0, 0.0, 0.0);
+ draw (x achse, "+X", 0.0, 0.0, 0.0);
+ put picture (p, x achse) .
+
+zeichne die y achse:
+ PICTURE VAR y achse := nilpicture;
+ move (y achse, 0.0, -1.0, 0.0);
+ draw (y achse, "-Y", 0.0, 0.0, 0.0);
+ draw (y achse, 0.0, 1.0, 0.0);
+ draw (y achse, "+Y", 0.0, 0.0, 0.0);
+ put picture (p, y achse) .
+
+zeichne die z achse:
+ PICTURE VAR z achse := nilpicture;
+ move (z achse, 0.0, 0.0, -1.0);
+ draw (z achse, "-Z", 0.0, 0.0, 0.0);
+ draw (z achse, 0.0, 0.0, 1.0);
+ draw (z achse, "+Z", 0.0, 0.0, 0.0);
+ put picture (p, z achse) .
+
+stelle das achsenkreuz dar:
+ viewport (p, 0.0, 1.0, 0.0, 1.0);
+ window (p, -1.1, 1.1, -1.1, 1.1);
+ oblique (p, 0.25, 0.15);
+ plot (p) .
+
+
+
diff --git a/graphic/Beispiel.Sinus b/graphic/Beispiel.Sinus
new file mode 100644
index 0000000..beac7cd
--- /dev/null
+++ b/graphic/Beispiel.Sinus
@@ -0,0 +1,45 @@
+initialisiere picfile;
+zeichne überschrift;
+zeichne achsen;
+zeichne sinuskurve;
+wähle darstellung;
+plot (p) .
+
+initialisiere picfile:
+ PICFILE VAR p :: picture file ("SINUS") .
+
+zeichne überschrift:
+ PICTURE VAR überschrift :: nilpicture;
+ move (überschrift, -pi/2.0, 1.0);
+ draw (überschrift, "sinus (x) [-pi, +pi]", 0.0, 1.0, 0.6);
+ put picture (p, überschrift) .
+
+zeichne achsen:
+ PICTURE VAR achsen :: nilpicture;
+ zeichne x achse;
+ zeichne y achse;
+ put picture (p, achsen) .
+
+zeichne x achse:
+ move (achsen, -pi, 0.0);
+ draw (achsen, pi, 0.0) .
+
+zeichne y achse:
+ move (achsen, 0.0, -1.0);
+ draw (achsen, 0.0, +1.0) .
+
+zeichne sinuskurve:
+ PICTURE VAR sinus :: nilpicture;
+ REAL VAR x :: -pi;
+
+ move (sinus, x, sin (x));
+ REP x INCR 0.1;
+ draw (sinus, x, sin (x))
+ UNTIL x >= pi PER;
+
+ put picture (p, sinus) .
+
+wähle darstellung:
+ window (p, -pi, pi, -1.0, 1.3);
+ viewport (p, 0.0, 0.0, 0.0, 0.0) .
+
diff --git a/graphic/GRAPHIK.Picfile b/graphic/GRAPHIK.Picfile
new file mode 100644
index 0000000..3accf52
--- /dev/null
+++ b/graphic/GRAPHIK.Picfile
@@ -0,0 +1,738 @@
+PACKET picture DEFINES (*Autor: Heiko.Indenbirken *)
+ PICTURE, (*Stand: 12.03.1985 *)
+ :=, CAT, nilpicture, (*Änderung: 20.08.85/10:38 *)
+ draw, draw r, (*Änderung: 05.08.86/12:21 *)
+ move, move r,
+ mark, bar, circle,
+ length, dim, pen, where,
+ extrema, rotate, stretch, translate,
+ picture:
+
+LET draw key = 1,
+ move key = 2,
+ text key = 3,
+ move r key = 4,
+ draw r key = 5,
+ bar 2 key = 6,
+ bar 3 key = 7,
+ circle key = 8,
+ mark key = 9,
+ max length = 31974;
+
+LET overflow = "Picture overflow",
+ pen range = "pen out of range [0-16]",
+ dim 3 = "Picture is 3 dimensional",
+ dim 2 = "Picture is 2 dimensional",
+ dim init = "Picture isn't initialized",
+ wrong key = "wrong key code",
+ nil = "",
+ zero = ""0"";
+
+TYPE PICTURE = STRUCT (INT dim, pen, TEXT points);
+
+
+INT VAR read pos;
+REAL VAR x, y, z;
+TEXT VAR r1 :: 8*zero, r2 :: 16*zero, r3 :: 24*zero, i1 :: 2*zero;
+
+OP := (PICTURE VAR l, PICTURE CONST r) :
+ CONCR (l) := CONCR (r)
+END OP :=;
+
+OP CAT (PICTURE VAR l, PICTURE CONST r) :
+ check dim (l, r.dim);
+ IF length (l.points) > max length - length (r.points)
+ THEN errorstop (overflow) FI;
+
+ l.points CAT r.points
+END OP CAT;
+
+PICTURE PROC nilpicture :
+ PICTURE : (0, 1, nil)
+END PROC nilpicture;
+
+PICTURE PROC nilpicture (INT CONST pen):
+ PICTURE : (0, pen, nil)
+END PROC nilpicture;
+
+PROC draw (PICTURE VAR p, TEXT CONST text, REAL CONST angle, height, bright):
+ write (p.points, text, angle, height, bright, text key)
+END PROC draw;
+
+PROC draw (PICTURE VAR p, REAL CONST x, y, z) :
+ check dim (p, 3);
+ write (p.points, x, y, z, draw key)
+END PROC draw;
+
+PROC draw (PICTURE VAR p, REAL CONST x, y) :
+ check dim (p, 2);
+ write (p.points, x, y, draw key)
+END PROC draw;
+
+PROC draw r (PICTURE VAR p, REAL CONST x, y, z) :
+ check dim (p, 3);
+ write (p.points, x, y, z, draw r key)
+END PROC draw r;
+
+PROC draw r (PICTURE VAR p, REAL CONST x, y) :
+ check dim (p, 2);
+ write (p.points, x, y, draw r key)
+END PROC draw r;
+
+PROC move (PICTURE VAR p, REAL CONST x, y, z) :
+ check dim (p, 3);
+ write (p.points, x, y, z, move key)
+END PROC move;
+
+PROC move (PICTURE VAR p, REAL CONST x, y) :
+ check dim (p, 2);
+ write (p.points, x, y, move key)
+END PROC move;
+
+PROC move r (PICTURE VAR p, REAL CONST x, y, z) :
+ check dim (p, 3);
+ write (p.points, x, y, z, move r key)
+END PROC move r;
+
+PROC move r (PICTURE VAR p, REAL CONST x, y) :
+ check dim (p, 2);
+ write (p.points, x, y, move r key)
+END PROC move r;
+
+PROC bar (PICTURE VAR p, REAL CONST width, height, INT CONST pattern):
+ check dim (p, 2);
+ write (p.points, width, height, pattern, bar 2 key)
+END PROC bar;
+
+PROC bar (PICTURE VAR p, REAL CONST from, to, height, INT CONST pattern):
+ check dim (p, 2);
+ write (p.points, from, to, height, pattern, bar 3 key)
+END PROC bar;
+
+PROC circle (PICTURE VAR p, REAL CONST radius, from, to, INT CONST pattern):
+ check dim (p, 2);
+ write (p.points, radius, from, to, pattern, circle key)
+END PROC circle;
+
+PROC mark (PICTURE VAR p, REAL CONST size, INT CONST no):
+ write (p.points, size, no, mark key)
+END PROC mark;
+
+PROC write (TEXT VAR points, REAL CONST x, y, z, INT CONST key) :
+ IF length (points) < max length
+ THEN points CAT code (key);
+ replace (r3, 1, x);
+ replace (r3, 2, y);
+ replace (r3, 3, z);
+ points CAT r3
+ ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC write (TEXT VAR points, REAL CONST x, y, INT CONST key) :
+ IF length (points) < max length
+ THEN points CAT code (key);
+ replace (r2, 1, x);
+ replace (r2, 2, y);
+ points CAT r2
+ ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC write (TEXT VAR points, REAL CONST x, y, INT CONST n, key) :
+ IF length (points) < max length
+ THEN points CAT code (key);
+ replace (r2, 1, x);
+ replace (r2, 2, y);
+ points CAT r2;
+ replace (i1, 1, n);
+ points CAT i1
+ ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC write (TEXT VAR points, REAL CONST x, y, z, INT CONST n, key) :
+ IF length (points) < max length
+ THEN points CAT code (key);
+ replace (r3, 1, x);
+ replace (r3, 2, y);
+ replace (r3, 3, z);
+ points CAT r3;
+ replace (i1, 1, n);
+ points CAT i1
+ ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC write (TEXT VAR points, TEXT CONST t, REAL CONST angle, height, bright,
+ INT CONST key) :
+ IF max length - length (points) >= length (t)
+ THEN points CAT code (key);
+ replace (i1, 1, length (t));
+ points CAT i1;
+ points CAT t;
+ replace (r3, 1, angle);
+ replace (r3, 2, height);
+ replace (r3, 3, bright);
+ points CAT r3
+ FI;
+END PROC write;
+
+PROC write (TEXT VAR points, REAL CONST size, INT CONST no, key) :
+ IF length (points) < max length
+ THEN points CAT code (key);
+ replace (r1, 1, size);
+ points CAT r1;
+ replace (i1, 1, no);
+ points CAT i1;
+ ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC check dim (PICTURE VAR p, INT CONST dim):
+ IF p.dim = dim
+ THEN
+ ELIF p.dim = 0
+ THEN p.dim := dim
+ ELSE errorstop (dimension) FI .
+
+dimension:
+ IF p.dim = 2
+ THEN dim 2
+ ELIF p.dim = 3
+ THEN dim 3
+ ELSE dim init FI .
+
+END PROC check dim;
+
+INT PROC length (PICTURE CONST p):
+ length (p.points)
+END PROC length;
+
+INT PROC dim (PICTURE CONST pic) :
+ pic.dim
+END PROC dim;
+
+PICTURE PROC pen (PICTURE CONST p, INT CONST pen) :
+ IF pen < 0 OR pen > 16
+ THEN errorstop (pen range) FI;
+
+ PICTURE:(p.dim, pen, p.points)
+END PROC pen;
+
+INT PROC pen (PICTURE CONST p) :
+ p.pen
+END PROC pen;
+
+PROC where (PICTURE CONST p, REAL VAR x, y) :
+ IF p.dim = 0
+ THEN x := 0.0; y := 0.0
+ ELIF p.dim = 3
+ THEN errorstop (dim 3)
+ ELSE x := subtext (p.points, length (p.points)-15, length (p.points)-8) RSUB 1;
+ y := subtext (p.points, length (p.points)-7, length (p.points)) RSUB 1
+ FI
+END PROC where;
+
+PROC where (PICTURE CONST p, REAL VAR x, y, z) :
+ IF p.dim = 0
+ THEN x := 0.0; y := 0.0; z := 0.0
+ ELIF p.dim = 2
+ THEN errorstop (dim 2)
+ ELSE x := subtext (p.points, length (p.points)-23, length (p.points)-16) RSUB 1;
+ y := subtext (p.points, length (p.points)-15, length (p.points)-8) RSUB 1;
+ z := subtext (p.points, length (p.points)-7, length (p.points)) RSUB 1;
+ FI
+END PROC where;
+
+
+PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y max, z min, z max) :
+ x min := max real; x max :=-max real;
+ y min := max real; y max :=-max real;
+ z min := max real; z max :=-max real;
+ read pos := 0;
+ INT CONST pic length := length (p.points);
+ WHILE read pos < pic length
+ REP check position PER .
+
+check position :
+ read pos INCR 1;
+ SELECT code (p.points SUB read pos) OF
+ CASE draw key : calc extrema
+ CASE move key : calc extrema
+ CASE move r key : calc rel extrema
+ CASE draw r key : calc rel extrema
+ CASE text key : read pos INCR next int + 24
+ CASE bar 2 key : read pos INCR 18
+ CASE bar 3 key, circle key : read pos INCR 26
+ CASE mark key: read pos INCR 4
+ OTHERWISE errorstop (wrong key) END SELECT .
+
+calc extrema :
+ x := next real; y := next real; z := next real;
+ x min := min (x min, x); x max := max (x max, x);
+ y min := min (y min, y); y max := max (y max, y);
+ z min := min (z min, z); z max := max (z max, z) .
+
+calc rel extrema :
+ x INCR next real; y INCR next real; z INCR next real;
+ x min := min (x min, x); x max := max (x max, x);
+ y min := min (y min, y); y max := max (y max, y);
+ z min := min (z min, z); z max := max (z max, z) .
+
+next real :
+ read pos INCR 8;
+ subtext (p.points, read pos-7, read pos) RSUB 1 .
+
+next int :
+ read pos INCR 2;
+ subtext (p.points, read pos-1, read pos) ISUB 1 .
+
+END PROC extrema;
+
+PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y max):
+ x min := max real; x max :=-max real;
+ y min := max real; y max :=-max real;
+ read pos := 0;
+ INT CONST pic length := length (p.points);
+ WHILE read pos < pic length
+ REP check position PER .
+
+check position :
+ read pos INCR 1;
+ SELECT code (p.points SUB read pos) OF
+ CASE draw key : calc extrema
+ CASE move key : calc extrema
+ CASE move r key : calc rel extrema
+ CASE draw r key : calc rel extrema
+ CASE text key : read pos INCR next int + 24
+ CASE bar 2 key : read pos INCR 18
+ CASE bar 3 key, circle key : read pos INCR 26
+ CASE mark key: read pos INCR 4
+ OTHERWISE errorstop (wrong key) END SELECT .
+
+calc extrema :
+ x := next real; y := next real;
+ x min := min (x min, x); x max := max (x max, x);
+ y min := min (y min, y); y max := max (y max, y) .
+
+calc rel extrema :
+ x INCR next real; y INCR next real;
+ x min := min (x min, x); x max := max (x max, x);
+ y min := min (y min, y); y max := max (y max, y) .
+
+next real :
+ read pos INCR 8;
+ subtext (p.points, read pos-7, read pos) RSUB 1 .
+
+next int :
+ read pos INCR 2;
+ subtext (p.points, read pos-1, read pos) ISUB 1 .
+
+END PROC extrema;
+
+PROC rotate (PICTURE VAR p, REAL CONST angle) :
+ REAL CONST s :: sind( angle ), c := cosd( angle );
+ transform (p, ROW 4 ROW 3 REAL :
+ (ROW 3 REAL : ( 1.0, 0.0, 0.0 ),
+ ROW 3 REAL : ( 0.0, c , s ),
+ ROW 3 REAL : ( 0.0, -s , c ),
+ ROW 3 REAL : ( 0.0, 0.0, 0.0 )))
+END PROC rotate;
+
+PROC rotate (PICTURE VAR p, REAL CONST phi, theta, lambda ) :
+ REAL CONST s :: sind ( theta ), c :: cosd ( theta ),
+ s p :: sind ( phi ), s l :: sind ( lambda ),
+ ga :: cosd ( phi ), c l :: cosd ( lambda ),
+ be :: s p * s l, al :: s p * c l, c1 :: 1.0 - c;
+ transform (p, ROW 4 ROW 3 REAL :
+ (ROW 3 REAL : ( al*al*c1 + c , be*al*c1+ga*s, ga*al*c1-be*s ),
+ ROW 3 REAL : ( al*be*c1-ga*s, be*be*c1 + c , ga*be*c1+al*s ),
+ ROW 3 REAL : ( al*ga*c1+be*s, be*ga*c1-al*s, ga*ga*c1 + c ),
+ ROW 3 REAL : ( 0.0 , 0.0 , 0.0 )))
+END PROC rotate;
+
+PROC stretch (PICTURE VAR pic, REAL CONST sx, sy) :
+ stretch (pic, sx, sy, 1.0)
+END PROC stretch;
+
+PROC stretch (PICTURE VAR p, REAL CONST sx, sy, sz) :
+ transform (p, ROW 4 ROW 3 REAL :
+ (ROW 3 REAL : ( sx, 0.0, 0.0),
+ ROW 3 REAL : (0.0, sy, 0.0),
+ ROW 3 REAL : (0.0, 0.0, sz),
+ ROW 3 REAL : (0.0, 0.0, 0.0)))
+END PROC stretch;
+
+PROC translate (PICTURE VAR p, REAL CONST dx, dy) :
+ translate (p, dx, dy, 0.0)
+END PROC translate;
+
+PROC translate (PICTURE VAR p, REAL CONST dx, dy, dz) :
+ transform (p, ROW 4 ROW 3 REAL :
+ (ROW 3 REAL : (1.0, 0.0, 0.0),
+ ROW 3 REAL : (0.0, 1.0, 0.0),
+ ROW 3 REAL : (0.0, 0.0, 1.0),
+ ROW 3 REAL : ( dx, dy, dz)))
+END PROC translate;
+
+PROC transform (PICTURE VAR p, ROW 4 ROW 3 REAL CONST a) :
+ INT CONST pic length := length (p.points);
+ INT VAR begin pos;
+ read pos := 0;
+ x := 0.0; y := 0.0; z := 0.0;
+ IF p.dim = 2
+ THEN transform 2 dim pic
+ ELSE transform 3 dim pic FI .
+
+transform 2 dim pic:
+ WHILE read pos < pic length
+ REP transform 2 dim position PER .
+
+transform 2 dim position:
+ read pos INCR 1;
+ SELECT code (p.points SUB read pos) OF
+ CASE draw key : transform 2 dim point
+ CASE move key : transform 2 dim point
+ CASE move r key : transform 2 dim point
+ CASE draw r key : transform 2 dim point
+ CASE text key : read pos INCR next int + 24
+ CASE bar 2 key : read pos INCR 18
+ CASE bar 3 key, circle key : read pos INCR 26
+ CASE mark key: read pos INCR 4
+ OTHERWISE errorstop (wrong key) END SELECT .
+
+transform 2 dim point:
+ begin pos := read pos+1;
+ x := next real; y := next real;
+ transform (a, x, y, z);
+ replace (r2, 1, x);
+ replace (r2, 2, y);
+ replace (p.points, begin pos, r2) .
+
+transform 3 dim pic:
+ WHILE read pos < pic length
+ REP transform 3 dim position PER .
+
+transform 3 dim position :
+ read pos INCR 1;
+ SELECT code (p.points SUB read pos) OF
+ CASE draw key : transform 3 dim point
+ CASE move key : transform 3 dim point
+ CASE move r key : transform 3 dim point
+ CASE draw r key : transform 3 dim point
+ CASE text key : read pos INCR next int + 24
+ CASE bar 2 key : read pos INCR 18
+ CASE bar 3 key, circle key : read pos INCR 26
+ CASE mark key: read pos INCR 4
+ OTHERWISE errorstop (wrong key) END SELECT .
+
+transform 3 dim point:
+ begin pos := read pos+1;
+ x := next real; y := next real; z := next real;
+ transform (a, x, y, z);
+ replace (r3, 1, x);
+ replace (r3, 2, y);
+ replace (r3, 3, z);
+ replace (p.points, begin pos, r3) .
+
+next real :
+ read pos INCR 8;
+ subtext (p.points, read pos-7, read pos) RSUB 1 .
+
+next int :
+ read pos INCR 2;
+ subtext (p.points, read pos-1, read pos) ISUB 1 .
+
+END PROC transform;
+
+PROC transform (ROW 4 ROW 3 REAL CONST a, REAL VAR x, y, z) :
+ REAL CONST ox :: x, oy :: y, oz :: z;
+ x := ox*a(1)(1) + oy*a(2)(1) + oz*a(3)(1) + a(4)(1);
+ y := ox*a(1)(2) + oy*a(2)(2) + oz*a(3)(2) + a(4)(2);
+ z := ox*a(1)(3) + oy*a(2)(3) + oz*a(3)(3) + a(4)(3)
+END PROC transform;
+
+PROC picture (PICTURE CONST pic, TEXT VAR points, INT VAR dim, pen):
+ dim := pic.dim;
+ pen := pic.pen;
+ points := pic.points;
+END PROC picture;
+
+END PACKET picture;
+
+PACKET picfile DEFINES (*Autor: Heiko Indenbirken *)
+ (*Stand: 23.02.1985 *)
+ PICFILE, :=, picture file, (*Änderung: 13.10.89/23:11 *)
+ select pen, selected pen, background,
+ set values, get values,
+ view, viewport, window,
+ oblique, orthographic, perspective,
+ extrema,
+
+ to pic, up, down,
+ eof, picture no, pictures,
+ delete picture, insert picture,
+ read picture, write picture,
+ get picture, put picture:
+
+
+LET no picfile = "dataspace is no PICFILE",
+ pen range = "pen out of range",
+ pos under = "Position underflow",
+ pos over = "Position overflow",
+ pic over = "PICFILE overflow";
+
+LET max pics = 1024,
+ pic dataspace = 1103;
+
+
+TYPE PICFILE = BOUND STRUCT (INT size, pos, background,
+ ROW 16 ROW 3 INT pens,
+ ROW 3 ROW 2 REAL sizes,
+ ROW 2 ROW 2 REAL limits,
+ ROW 4 REAL angles,
+ ROW 2 REAL obliques,
+ ROW 3 REAL perspectives
+ ROW max pics PICTURE pic);
+
+INT VAR i;
+
+OP := (PICFILE VAR l, PICFILE CONST r):
+ EXTERNAL 260
+END OP :=;
+
+OP := (PICFILE VAR p, DATASPACE CONST d) :
+ IF type (d) = pic dataspace
+ THEN CONCR (p) := d
+ ELIF type (d) < 0
+ THEN type (d, pic dataspace) ;
+ CONCR (p) := d ;
+ init picfile dataspace ;
+ ELSE errorstop (no picfile) FI .
+
+init picfile dataspace :
+ r.size := 0;
+ r.pos := 1;
+ r.background := 0;
+ r.sizes := ROW 3 ROW 2 REAL : (ROW 2 REAL : (0.0, 1.0),
+ ROW 2 REAL : (0.0, 1.0),
+ ROW 2 REAL : (0.0, 1.0));
+ r.limits := ROW 2 ROW 2 REAL : (ROW 2 REAL : (0.0, 0.0),
+ ROW 2 REAL : (0.0, 0.0));
+ r.angles := ROW 4 REAL : (0.0, 0.0, 0.0, 0.0);
+ r.obliques := ROW 2 REAL : (0.0, 0.0);
+ r.perspectives := ROW 3 REAL : (0.0, 0.0, 0.0);
+ FOR i FROM 1 UPTO 16
+ REP r.pens [i] := ROW 3 INT : (1, 0, 1) PER .
+
+r : CONCR (CONCR (p)).
+END OP :=;
+
+DATASPACE PROC picture file (TEXT CONST name) :
+ IF exists (name)
+ THEN old (name)
+ ELSE new (name) FI
+END PROC picture file;
+
+PROC select pen (PICFILE VAR p, INT CONST pen, colour, thickness, line type):
+ IF pen < 1 OR pen > 16
+ THEN errorstop (pen range) FI;
+ p.pens [pen] := ROW 3 INT : (colour, thickness, line type)
+END PROC select pen;
+
+PROC selected pen (PICFILE CONST p, INT CONST pen,
+ INT VAR colour, thickness, line type):
+ IF pen < 1 OR pen > 16
+ THEN errorstop (pen range) FI;
+ colour := p.pens [pen][1];
+ thickness := p.pens [pen][2];
+ line type := p.pens [pen][3];
+END PROC selected pen;
+
+INT PROC background (PICFILE CONST p):
+ p.background
+END PROC background;
+
+PROC background (PICFILE VAR p, INT CONST colour):
+ p.background := colour
+END PROC background;
+
+PROC get values (PICFILE CONST p,
+ ROW 3 ROW 2 REAL VAR size,
+ ROW 2 ROW 2 REAL VAR limits,
+ ROW 4 REAL VAR angles,
+ ROW 2 REAL VAR oblique,
+ ROW 3 REAL VAR perspective) :
+ size := p.sizes;
+ limits := p.limits;
+ angles := p.angles;
+ oblique := p.obliques;
+ perspective := p.perspectives;
+
+END PROC get values;
+
+PROC set values (PICFILE VAR p,
+ ROW 3 ROW 2 REAL CONST size,
+ ROW 2 ROW 2 REAL CONST limits,
+ ROW 4 REAL CONST angles,
+ ROW 2 REAL CONST oblique,
+ ROW 3 REAL CONST perspective) :
+ p.sizes := size;
+ p.limits := limits;
+ p.angles := angles;
+ p.obliques := oblique;
+ p.perspectives := perspective;
+
+END PROC set values;
+
+PROC view (PICFILE VAR p, REAL CONST alpha):
+ p.angles [1] := alpha
+END PROC view;
+
+PROC view (PICFILE VAR p, REAL CONST phi, theta):
+ p.angles [2] := sind (theta) * cosd (phi);
+ p.angles [3] := sind (theta) * sind (phi);
+ p.angles [4] := cosd (theta);
+END PROC view;
+
+PROC view (PICFILE VAR p, REAL CONST x, y, z):
+ p.angles [2] := x;
+ p.angles [3] := y;
+ p.angles [4] := z
+END PROC view;
+
+PROC viewport (PICFILE VAR p,REAL CONST hor min,hor max,vert min,vert max) :
+ p.limits := ROW 2 ROW 2 REAL : (ROW 2 REAL : (hor min, hor max),
+ ROW 2 REAL : (vert min, vert max))
+END PROC viewport;
+
+PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max) :
+ window (p, x min, x max, y min, y max, 0.0, 1.0)
+END PROC window;
+
+PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max, z min, z max) :
+ p.sizes := ROW 3 ROW 2 REAL : (ROW 2 REAL : (x min, x max),
+ ROW 2 REAL : (y min, y max),
+ ROW 2 REAL : (z min, z max))
+END PROC window;
+
+PROC oblique (PICFILE VAR p, REAL CONST a, b) :
+ p.obliques := ROW 2 REAL : (a, b);
+ p.perspectives := ROW 3 REAL : (0.0, 0.0, 0.0)
+END PROC oblique;
+
+PROC orthographic (PICFILE VAR p) :
+ p.obliques := ROW 2 REAL : (0.0, 0.0);
+ p.perspectives := ROW 3 REAL : (0.0, 0.0, 0.0)
+END PROC orthographic;
+
+PROC perspective (PICFILE VAR p, REAL CONST cx, cy, cz) :
+ p.obliques := ROW 2 REAL : (0.0, 0.0);
+ p.perspectives := ROW 3 REAL : (cx, cy, cz)
+END PROC perspective;
+
+PROC extrema (PICFILE VAR p, REAL VAR x min, x max, y min, y max) :
+ REAL VAR dummy;
+ extrema (p, x min, x max, y min, y max, dummy, dummy)
+END PROC extrema;
+
+PROC extrema (PICFILE VAR p, REAL VAR x min,x max,y min,y max,z min,z max) :
+ REAL VAR new x min, new x max, new y min, new y max, new z min, new z max;
+ x min := max real; x max := - max real;
+ y min := max real; y max := - max real;
+ z min := max real; z max := - max real;
+ FOR i FROM 1 UPTO p.size
+ REP IF dim (p.pic [i]) = 2
+ THEN extrema (p.pic [i], new x min, new x max, new y min, new y max)
+ ELSE extrema (p.pic [i], new x min, new x max, new y min, new y max,
+ new z min, new z max)
+ FI;
+ x min := min (x min, new x min); x max := max (x max, new x max);
+ y min := min (y min, new y min); y max := max (y max, new y max);
+ z min := min (z min, new z min); z max := max (z max, new z max);
+ PER
+END PROC extrema;
+
+PROC to pic (PICFILE VAR p, INT CONST n):
+ IF n < 1
+ THEN errorstop (pos under)
+ ELIF n <= p.size+1 AND n <= max pics
+ THEN p.pos := n
+ ELSE errorstop (pos over) FI
+END PROC to pic;
+
+PROC up (PICFILE VAR p):
+ to pic (p, p.pos-1)
+END PROC up;
+
+PROC up (PICFILE VAR p, INT CONST n):
+ to pic (p, p.pos-n)
+END PROC up;
+
+PROC down (PICFILE VAR p):
+ to pic (p, p.pos+1)
+END PROC down;
+
+PROC down (PICFILE VAR p, INT CONST n):
+ to pic (p, p.pos+n)
+END PROC down;
+
+BOOL PROC eof (PICFILE CONST p):
+ p.pos >= p.size
+END PROC eof;
+
+INT PROC picture no (PICFILE CONST p):
+ p.pos
+END PROC picture no;
+
+INT PROC pictures (PICFILE CONST p):
+ p.size
+END PROC pictures;
+
+PROC delete picture (PICFILE VAR p) :
+ INT VAR i;
+ FOR i FROM p.pos+1 UPTO p.size
+ REP p.pic [i-1] := p.pic [i] PER;
+
+ p.pic [p.size] := nilpicture;
+ IF p.size > 1
+ THEN p.size DECR 1 FI
+END PROC delete picture;
+
+PROC insert picture (PICFILE VAR p) :
+ INT VAR i;
+ IF p.size >= max pics
+ THEN errorstop (pic over)
+ ELSE p.size INCR 1;
+ FOR i FROM p.size DOWNTO p.pos+1
+ REP p.pic [i] := p.pic [i-1] PER;
+
+ p.pic [p.pos] := nilpicture;
+ FI
+END PROC insert picture;
+
+PROC read picture (PICFILE VAR p, PICTURE VAR pic) :
+ pic := p.pic (p.pos) .
+END PROC read picture;
+
+PROC write picture (PICFILE VAR p, PICTURE CONST pic) :
+ p.pic (p.pos) := pic .
+END PROC write picture;
+
+PROC get picture (PICFILE VAR p, PICTURE VAR pic) :
+ IF p.pos > p.size
+ THEN errorstop (pos over)
+ ELSE pic := p.pic [p.pos];
+ p.pos INCR 1;
+ FI
+END PROC get picture;
+
+PROC put picture (PICFILE VAR p, PICTURE CONST pic) :
+ IF p.pos > max pics
+ THEN errorstop (pic over)
+ ELSE p.pic [p.pos] := pic;
+
+ IF p.pos > p.size
+ THEN p.size INCR 1 FI;
+ p.pos INCR 1
+ FI
+END PROC put picture;
+
+END PACKET picfile
+
diff --git a/graphic/GRAPHIK.Plot b/graphic/GRAPHIK.Plot
new file mode 100644
index 0000000..5087abb
--- /dev/null
+++ b/graphic/GRAPHIK.Plot
@@ -0,0 +1,285 @@
+PACKET basis plot DEFINES (* Autor: Heiko Indenbirken*)
+ (* Stand: 12.04.85 *)
+ (*Änderung: 06.08.86/10:03 *)
+(* ****************** Hardwareunabhängiger Teil ********************* *)
+(* *)
+(* *)
+(* Im Harwareunabhängigen Paket 'basis plot' werden folgende *)
+(* Prozeduren definiert: *)
+(* Procedure : Bedeutung *)
+(* ---------------------------------------------------------------- *)
+(* move : Positioniert auf (x, y,[z]) in Weltkoordinaten*)
+(* draw : Zeichnet eine Linie bis zum Punkt (x, y, [z]).*)
+(* move r : Positioniert (x, y, [z]) weiter *)
+(* draw r : Zeichnet (x, y, [z]) weiter *)
+(* *)
+(* draw : Zeichnet einen Text *)
+(* *)
+(* mark : Marker mit (no, size) *)
+(* bar : Balken mit (width, height, pattern) *)
+(* bar : Balken mit (from, to, width, pattern) *)
+(* circle : Kreis(segment) mit (radius, from, to, pattern)*)
+(* *)
+(* where : Gibt die aktuelle Stiftposition (x, y, [z]) *)
+(* *)
+(*************************************************************************)
+
+ move, draw,
+ move r, draw r,
+ mark, bar, circle,
+ where:
+
+LET POS = STRUCT (REAL x, y, z);
+
+POS VAR pos :: POS : (0.0, 0.0, 0.0);
+INT VAR h :: 0, v :: 0;
+
+PROC move (REAL CONST x, y) :
+ transform (x, y, 0.0, h, v);
+ move (h, v);
+ pos := POS : (x, y, 0.0)
+END PROC move;
+
+PROC move (REAL CONST x, y, z) :
+ transform (x, y, z, h, v);
+ move (h, v);
+ pos := POS : (x, y, z)
+END PROC move;
+
+PROC draw (REAL CONST x, y) :
+ transform (x, y, 0.0, h, v);
+ draw (h, v);
+ pos := POS : (x, y, 0.0)
+END PROC draw;
+
+PROC draw (REAL CONST x, y, z) :
+ transform (x, y, z, h, v);
+ draw (h, v);
+ pos := POS : (x, y, z)
+END PROC draw;
+
+PROC move r (REAL CONST x, y) :
+ transform (pos.x+x, pos.y+y, pos.z, h, v);
+ move (h, v);
+ pos := POS : (pos.x+x, pos.y+y, pos.z)
+END PROC move r;
+
+PROC move r (REAL CONST x, y, z) :
+ transform (pos.x+x, pos.y+y, pos.z+z, h, v);
+ move (h, v);
+ pos := POS : (pos.x+x, pos.y+y, pos.z+z)
+END PROC move r;
+
+PROC draw r (REAL CONST x, y) :
+ transform (pos.x+x, pos.y+y, pos.z, h, v);
+ draw (h, v);
+ pos := POS : (pos.x+x, pos.y+y, pos.z)
+END PROC draw r;
+
+PROC draw r (REAL CONST x, y, z) :
+ transform (pos.x+x, pos.y+y, pos.z+z, h, v);
+ draw (h, v);
+ pos := POS : (pos.x+x, pos.y+y, pos.z+z)
+END PROC draw r;
+
+PROC where (REAL VAR x, y) :
+ x := pos.x; y := pos.y
+END PROC where;
+
+PROC where (REAL VAR x, y, z) :
+ x := pos.x; y := pos.y; z := pos.z
+END PROC where;
+
+PROC draw (TEXT CONST msg, REAL CONST angle, height percent, width percent):
+ draw (msg, angle, height (height percent), width (width percent)) .
+END PROC draw;
+
+PROC mark (REAL CONST size, INT CONST no):
+ marker (h, v, no, diagonal (size))
+END PROC mark;
+
+PROC bar (REAL CONST width, height, INT CONST pattern):
+ INT VAR diff, up, zero x, zero y;
+ transform (0.0, 0.0, 0.0, zero x, zero y);
+ transform (width*0.5, height, 0.0, diff, up);
+ bar (h-(diff-zero x), v, h+(diff-zero x), v+(up-zero y), pattern);
+ move (h, v)
+
+END PROC bar;
+
+PROC bar (REAL CONST from, to, height, INT CONST pattern):
+ INT VAR from h, to h, up;
+ transform (from, height, 0.0, from h, up);
+ transform (to, height, 0.0, to h, up);
+ bar (from h, v, to h, up, pattern);
+ move (h, v)
+
+END PROC bar;
+
+PROC circle (REAL CONST rad, from, to, INT CONST pattern):
+ circle (h, v, diagonal (rad), from, to, pattern) .
+
+END PROC circle;
+
+ENDPACKET basis plot;
+
+PACKET plot DEFINES plot: (*Autor: Heiko Indenbirken *)
+ (*Stand: 13.10.89/22:31 *)
+
+LET draw key = 1,
+ move key = 2,
+ text key = 3,
+ move r key = 4,
+ draw r key = 5,
+ bar 2 key = 6,
+ bar 3 key = 7,
+ circle key = 8,
+ mark key = 9;
+
+LET dim error = "PICTURE not initialized",
+ key error = "wrong key code: ";
+
+TEXT VAR points;
+INT VAR pic length, pic pen, pic dim, read pos;
+PICTURE VAR pic;
+
+PROC plot (PICTURE CONST pic):
+ init plot;
+ IF pic dim = 2
+ THEN plot two dim pic
+ ELIF pic dim = 3
+ THEN plot three dim pic
+ ELIF NOT (pic dim = 0 AND pic length = 0)
+ THEN errorstop (dim error) FI;
+ points := "" .
+
+init plot:
+ picture (pic, points, pic dim, pic pen);
+ pic length := length (points);
+ read pos := 0 .
+
+plot two dim pic:
+ WHILE read pos < pic length
+ REP plot two dim position PER .
+
+plot two dim position :
+ read pos INCR 1;
+ SELECT key OF
+ CASE draw key: draw (next real, next real)
+ CASE move key: move (next real, next real)
+ CASE move r key: move r (next real, next real)
+ CASE draw r key: draw r (next real, next real)
+ CASE text key: draw (next text, next real, next real, next real)
+ CASE bar 2 key: bar (next real, next real, next int)
+ CASE bar 3 key: bar (next real, next real, next real, next int)
+ CASE circle key: circle (next real, next real, next real, next int)
+ CASE mark key: mark (next real, next int)
+ OTHERWISE errorstop (key error + text (key)) END SELECT .
+
+plot three dim pic:
+ WHILE read pos < pic length
+ REP plot three dim position PER .
+
+plot three dim position :
+ read pos INCR 1;
+ SELECT key OF
+ CASE draw key: draw (next real, next real, next real)
+ CASE move key: move (next real, next real, next real)
+ CASE move r key: move r (next real, next real, next real)
+ CASE draw r key: draw r (next real, next real, next real)
+ CASE text key: draw (next text, next real, next real, next real)
+ CASE bar 2 key: bar (next real, next real, next int)
+ CASE bar 3 key: bar (next real, next real, next real, next int)
+ CASE circle key: circle (next real, next real, next real, next int)
+ CASE mark key: mark (next real, next int)
+ OTHERWISE errorstop (key error + text (key)) END SELECT .
+
+key:
+ code (points SUB read pos) .
+
+END PROC plot;
+
+REAL PROC next real:
+ read pos INCR 8;
+ subtext (points, read pos-7, read pos) RSUB 1 .
+END PROC next real;
+
+INT PROC next int:
+ read pos INCR 2;
+ subtext (points, read pos-1, read pos) ISUB 1 .
+END PROC next int;
+
+TEXT PROC next text:
+ INT CONST text length :: next int;
+ read pos INCR text length;
+ subtext (points, read pos-text length+1, read pos) .
+END PROC next text;
+
+PROC plot (TEXT CONST name) :
+ PICFILE VAR p :: old (name);
+ plot (p);
+END PROC plot;
+
+PROC plot (PICFILE VAR p) :
+ set projektion;
+ disable stop;
+ begin plot;
+ clear screen;
+ plot pictures (p);
+ errorcheck;
+ end plot .
+
+set projektion:
+ ROW 3 ROW 2 REAL VAR size;
+ ROW 2 ROW 2 REAL VAR limit;
+ ROW 4 REAL VAR angles;
+ ROW 2 REAL VAR oblique;
+ ROW 3 REAL VAR perspective;
+
+ get values (p, size, limit, angles, oblique, perspective);
+ set values (size, limit, angles, oblique, perspective) .
+
+clear screen:
+ INT VAR x0, y0, x1, y1, h max, v max;
+ REAL VAR x cm, y cm;
+
+ IF background (p) > -1
+ THEN clear
+ ELSE drawing area (x cm, y cm, h max, v max);
+ new values (x cm, y cm, h max, v max, x0, x1 , y0, y1);
+ set range (max (0, x0), max (0, y0), min (h max, x1), min (v max, y1))
+ FI .
+
+errorcheck:
+ IF is error
+ THEN line;
+ put line ("Erorr at PICTURE No " + text (picture no (p)));
+ FI .
+
+END PROC plot;
+
+PROC plot pictures (PICFILE VAR p):
+ INT VAR back :: abs (background (p)), no;
+ enable stop;
+ FOR no FROM 1 UPTO pictures (p)
+ REP to pic (p, no);
+ read picture (p, pic);
+
+ IF this picture is ok
+ THEN set pen of pic;
+ plot (pic)
+ FI
+ PER .
+
+this picture is ok:
+ pen (pic) <> 0 AND length (pic) > 0 .
+
+set pen of pic:
+ INT VAR colour, thick, type;
+ selected pen (p, pen (pic), colour, thick, type);
+ set pen (back, colour, thick, type) .
+
+END PROC plot pictures;
+
+END PACKET plot
+
diff --git a/graphic/GRAPHIK.Plotter b/graphic/GRAPHIK.Plotter
new file mode 100644
index 0000000..a55e515
--- /dev/null
+++ b/graphic/GRAPHIK.Plotter
@@ -0,0 +1,247 @@
+PACKET plotter DEFINES plotter: (*Autor: Heiko Indenbirken *)
+ (*Stand: 13.10.89/22:31 *)
+ (*Änderung: 08.09.86/15:47 *)
+
+LET POS = STRUCT (REAL x, y, z);
+
+POS VAR pos :: POS : (0.0, 0.0, 0.0);
+INT VAR h :: 0, v :: 0;
+
+PROC move (REAL CONST x, y) :
+ transform (x, y, 0.0, h, v);
+ move (h, v);
+ pos := POS : (x, y, 0.0)
+END PROC move;
+
+PROC move (REAL CONST x, y, z) :
+ transform (x, y, z, h, v);
+ move (h, v);
+ pos := POS : (x, y, z)
+END PROC move;
+
+PROC draw (REAL CONST x, y) :
+ transform (x, y, 0.0, h, v);
+ draw (h, v);
+ pos := POS : (x, y, 0.0)
+END PROC draw;
+
+PROC draw (REAL CONST x, y, z) :
+ transform (x, y, z, h, v);
+ draw (h, v);
+ pos := POS : (x, y, z)
+END PROC draw;
+
+PROC move r (REAL CONST x, y) :
+ transform (pos.x+x, pos.y+y, pos.z, h, v);
+ move (h, v);
+ pos := POS : (pos.x+x, pos.y+y, pos.z)
+END PROC move r;
+
+PROC move r (REAL CONST x, y, z) :
+ transform (pos.x+x, pos.y+y, pos.z+z, h, v);
+ move (h, v);
+ pos := POS : (pos.x+x, pos.y+y, pos.z+z)
+END PROC move r;
+
+PROC draw r (REAL CONST x, y) :
+ transform (pos.x+x, pos.y+y, pos.z, h, v);
+ draw (h, v);
+ pos := POS : (pos.x+x, pos.y+y, pos.z)
+END PROC draw r;
+
+PROC draw r (REAL CONST x, y, z) :
+ transform (pos.x+x, pos.y+y, pos.z+z, h, v);
+ draw (h, v);
+ pos := POS : (pos.x+x, pos.y+y, pos.z+z)
+END PROC draw r;
+
+PROC draw (TEXT CONST msg, REAL CONST angle, height percent, width percent):
+ draw (msg, angle, height (height percent), width (width percent)) .
+END PROC draw;
+
+PROC mark (REAL CONST size, INT CONST no):
+ marker (h, v, no, diagonal (size))
+END PROC mark;
+
+PROC bar (REAL CONST width, height, INT CONST pattern):
+ INT VAR diff, up, zero x, zero y;
+ transform (0.0, 0.0, 0.0, zero x, zero y);
+ transform (width*0.5, height, 0.0, diff, up);
+ bar (h-(diff-zero x), v, h+(diff-zero x), v+(up-zero y), pattern);
+ move (h, v)
+
+END PROC bar;
+
+PROC bar (REAL CONST from, to, height, INT CONST pattern):
+ INT VAR from h, to h, up;
+ transform (from, height, 0.0, from h, up);
+ transform (to, height, 0.0, to h, up);
+ bar (from h, v, to h, up, pattern);
+ move (h, v)
+
+END PROC bar;
+
+PROC circle (REAL CONST rad, from, to, INT CONST pattern):
+ circle (h, v, diagonal (rad), from, to, pattern) .
+
+END PROC circle;
+
+
+(* *)
+LET draw key = 1,
+ move key = 2,
+ text key = 3,
+ move r key = 4,
+ draw r key = 5,
+ bar 2 key = 6,
+ bar 3 key = 7,
+ circle key = 8,
+ mark key = 9;
+
+LET dim error = "PICTURE not initialized",
+ key error = "wrong key code: ";
+
+TEXT VAR points;
+INT VAR pic length, pic pen, pic dim, read pos;
+PICTURE VAR pic;
+
+PROC plot (PICTURE CONST pic):
+ init plot;
+ IF pic dim = 2
+ THEN plot two dim pic
+ ELIF pic dim = 3
+ THEN plot three dim pic
+ ELIF NOT (pic dim = 0 AND pic length = 0)
+ THEN errorstop (dim error) FI;
+ points := "" .
+
+init plot:
+ picture (pic, points, pic dim, pic pen);
+ pic length := length (points);
+ read pos := 0 .
+
+plot two dim pic:
+ WHILE read pos < pic length
+ REP plot two dim position PER .
+
+plot two dim position :
+ read pos INCR 1;
+ SELECT key OF
+ CASE draw key: draw (next real, next real)
+ CASE move key: move (next real, next real)
+ CASE move r key: move r (next real, next real)
+ CASE draw r key: draw r (next real, next real)
+ CASE text key: draw (next text, next real, next real, next real)
+ CASE bar 2 key: bar (next real, next real, next int)
+ CASE bar 3 key: bar (next real, next real, next real, next int)
+ CASE circle key: circle (next real, next real, next real, next int)
+ CASE mark key: mark (next real, next int)
+ OTHERWISE errorstop (key error + text (key)) END SELECT .
+
+plot three dim pic:
+ WHILE read pos < pic length
+ REP plot three dim position PER .
+
+plot three dim position :
+ read pos INCR 1;
+ SELECT key OF
+ CASE draw key: draw (next real, next real, next real)
+ CASE move key: move (next real, next real, next real)
+ CASE move r key: move r (next real, next real, next real)
+ CASE draw r key: draw r (next real, next real, next real)
+ CASE text key: draw (next text, next real, next real, next real)
+ CASE bar 2 key: bar (next real, next real, next int)
+ CASE bar 3 key: bar (next real, next real, next real, next int)
+ CASE circle key: circle (next real, next real, next real, next int)
+ CASE mark key: mark (next real, next int)
+ OTHERWISE errorstop (key error + text (key)) END SELECT .
+
+key:
+ code (points SUB read pos) .
+
+END PROC plot;
+
+REAL PROC next real:
+ read pos INCR 8;
+ subtext (points, read pos-7, read pos) RSUB 1 .
+END PROC next real;
+
+INT PROC next int:
+ read pos INCR 2;
+ subtext (points, read pos-1, read pos) ISUB 1 .
+END PROC next int;
+
+TEXT PROC next text:
+ INT CONST text length :: next int;
+ read pos INCR text length;
+ subtext (points, read pos-text length+1, read pos) .
+END PROC next text;
+
+PROC plotter (TEXT CONST name) :
+ PICFILE VAR p :: old (name);
+ plotter (p);
+END PROC plotter;
+
+PROC plotter (PICFILE VAR p) :
+ set projektion;
+ disable stop;
+ begin plot;
+ clear screen;
+ plot pictures (p);
+ errorcheck;
+ end plot .
+
+set projektion:
+ ROW 3 ROW 2 REAL VAR size;
+ ROW 2 ROW 2 REAL VAR limit;
+ ROW 4 REAL VAR angles;
+ ROW 2 REAL VAR oblique;
+ ROW 3 REAL VAR perspective;
+ get values (p, size, limit, angles, oblique, perspective);
+ set values (size, limit, angles, oblique, perspective) .
+
+clear screen:
+ INT VAR x0, y0, x1, y1, h max, v max;
+ REAL VAR x cm, y cm;
+
+ IF background (p) > -1
+ THEN clear
+ ELSE drawing area (x cm, y cm, h max, v max);
+ new values (x cm, y cm, h max, v max, x0, x1 , y0, y1);
+ set range (max (0, x0), max (0, y0), min (h max, x1), min (v max, y1))
+ FI .
+
+errorcheck:
+ IF is error
+ THEN line;
+ put line ("Erorr at PICTURE No " + text (picture no (p)));
+ FI .
+
+END PROC plotter;
+
+PROC plot pictures (PICFILE VAR p):
+ INT VAR back :: abs (background (p)), no;
+ enable stop;
+ FOR no FROM 1 UPTO pictures (p)
+ REP to pic (p, no);
+ read picture (p, pic);
+
+ IF this picture is ok
+ THEN set pen of pic;
+ plot (pic)
+ FI
+ PER .
+
+this picture is ok:
+ pen (pic) <> 0 AND length (pic) > 0 .
+
+set pen of pic:
+ INT VAR colour, thick, type;
+ selected pen (p, pen (pic), colour, thick, type);
+ set pen (back, colour, thick, type) .
+
+END PROC plot pictures;
+
+END PACKET plotter
+
+
diff --git a/graphic/GRAPHIK.Server b/graphic/GRAPHIK.Server
new file mode 100644
index 0000000..dfe5f62
--- /dev/null
+++ b/graphic/GRAPHIK.Server
@@ -0,0 +1,97 @@
+PACKET multi user plotter: (* Autor : Rudolf Ruland *)
+ (* Stand : 24.03.86 *)
+ (*Änderung: 09.09.86/15:32 *)
+
+INT VAR c;
+put ("gib Plotterkanal : "); get (c);
+
+ server channel (c);
+ station only (FALSE) ;
+ spool duty ("Ausgabe mit dem Plotter");
+ spool control task (myself);
+
+LET ack = 0 ,
+
+ fetch code = 11 ,
+ param fetch code = 21 ,
+ picfile type = 1103 ;
+
+INT VAR reply, old heap size, sender station;
+TEXT VAR picfile name, userid, password, sendername;
+PICFILE VAR picfile ;
+
+DATASPACE VAR ds, picfile ds;
+
+BOUND STRUCT (TEXT picfile name, userid, password, sendername, INT station) VAR msg;
+BOUND TEXT VAR error msg ;
+
+spool manager (PROC plotter);
+
+PROC plotter :
+
+ disable stop ;
+ command dialogue (FALSE);
+ ds := nilspace; picfile ds := nilspace;
+ continue (server channel) ;
+ check error ("Kanal belegt");
+
+ old heap size := heap size ;
+ REP
+ execute plot ;
+
+ IF is error
+ THEN put error;
+ clear error;
+ FI ;
+
+ IF heap size > old heap size + 4
+ THEN collect heap garbage ;
+ old heap size := heap size
+ FI
+ PER
+
+ENDPROC plotter ;
+
+
+PROC execute plot :
+
+ enable stop ;
+ forget (picfile ds) ; picfile ds := nilspace ;
+ call (father, fetch code, picfile ds, reply) ;
+ IF reply = ack CAND type (picfile ds) = picfile type
+ THEN get picfile params;
+ plot picfile
+ FI ;
+
+. get picfile params :
+ forget (ds); ds := nilspace;
+ call (father, param fetch code, ds, reply);
+ IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE msg := ds;
+ picfile name := msg. picfile name;
+ userid := msg. userid;
+ password := msg. password;
+ sendername := msg. sender name;
+ sender station := msg. station;
+ FI;
+
+. plot picfile :
+ picfile := picfile ds;
+ plotter (picfile) .
+
+ENDPROC execute plot ;
+
+
+PROC check error (TEXT CONST message) :
+ IF is error
+ THEN clear error;
+ rename myself (message);
+ IF is error THEN clear error; end (myself) FI;
+ pause (18000);
+ end (myself);
+ FI;
+END PROC check error;
+
+ENDPACKET multi user plotter ;
+
diff --git a/graphic/GRAPHIK.Transform b/graphic/GRAPHIK.Transform
new file mode 100644
index 0000000..54690cc
--- /dev/null
+++ b/graphic/GRAPHIK.Transform
@@ -0,0 +1,366 @@
+PACKET transformation DEFINES transform, (* Autor: Heiko Indenbirken*)
+ diagonal, (* Stand: 12.04.85 *)
+ height, width, (*Änderung: 05.08.86/13:14 *)
+ set values, (*Änderung: 17.09.86/19:57 *)
+ get values,
+ new values,
+ projektion,
+ window,
+ viewport,
+ view,
+ oblique,
+ orthographic,
+ perspective:
+(* ******************* Hardwareunabhängiger Teil ********************* *)
+(* transform: Die Prozedur projeziert einen 3-dimensionalen Vektor *)
+(* ---------- (x, y, z) auf einen 2-dimensionalen (h, v) *)
+(* diagonal Die Prozedur berechnet die Pixel als Prozent der *)
+(* ---------- Diagonalen der Zeichenfläche *)
+(* height Die Prozedur berechnet die Pixel als Prozent der *)
+(* ---------- Höhe der Zeichenfläche *)
+(* width Die Prozedur berechnet die Pixel als Prozent der *)
+(* ---------- Breite der Zeichenfläche *)
+(* *)
+(* set values: Mit dieser Prozedur werden die Projektionsparameter *)
+(* ----------- gesetzt. *)
+(* size: Weltkoordinatenbereich *)
+(* ((xmin,xmax),(ymin,ymax),(zmin,zmax)) *)
+(* limits: Zeichenfläche *)
+(* ((h min, h max), (v min, v max)) *)
+(* Bei Werten < 2.0 werden die Werte als *)
+(* Prozente interpretiert, ansonsten als *)
+(* cm-Grössen. *)
+(* get values: Übergibt die aktuellen Werte *)
+(* ----------- *)
+(* new values: Berechnet die neue Projektionsmatrix *)
+(* ----------- *)
+(*=======================================================================*)
+
+BOOL VAR perspective projektion :: FALSE;
+INT VAR hor pixel, vert pixel, i;
+REAL VAR hor cm, vert cm,
+ h min limit, h max limit, v min limit, v max limit;
+ROW 5 ROW 5 REAL VAR p;
+ROW 3 ROW 2 REAL VAR size;
+ROW 2 ROW 2 REAL VAR limits;
+ROW 4 REAL VAR angles;
+ROW 2 REAL VAR obliques;
+ROW 3 REAL VAR perspectives;
+
+(* Initialisieren der Projektionsmatrizen *)
+INT VAR d;
+window (0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
+viewport (0.0, 0.0, 0.0, 0.0);
+view (0.0, 0.0, 1.0);
+view (0.0);
+orthographic;
+new values (27.46, 19.21, 274, 192, d, d, d, d);
+
+PROC projektion (ROW 5 ROW 5 REAL VAR matrix):
+ matrix := p
+END PROC projektion;
+
+PROC oblique (REAL CONST a, b) :
+ set values (size, limits, angles, ROW 2 REAL : (a, b), ROW 3 REAL : (0.0, 0.0, 0.0))
+END PROC oblique;
+
+PROC orthographic :
+ set values (size, limits, angles, ROW 2 REAL : (0.0, 0.0), ROW 3 REAL : (0.0, 0.0, 0.0))
+END PROC orthographic;
+
+PROC perspective (REAL CONST cx, cy, cz) :
+ set values (size, limits, angles, ROW 2 REAL : (0.0, 0.0), ROW 3 REAL : (cx, cy, cz))
+END PROC perspective;
+
+PROC window (REAL CONST x min, x max, y min, y max) :
+ window (x min, x max, y min, y max, 0.0, 1.0)
+END PROC window;
+
+PROC window (REAL CONST x min, x max, y min, y max, z min, z max) :
+ set values (ROW 3 ROW 2 REAL : (ROW 2 REAL : (x min, x max),
+ ROW 2 REAL : (y min, y max),
+ ROW 2 REAL : (z min, z max)),
+ limits, angles, obliques, perspectives)
+END PROC window;
+
+PROC viewport (REAL CONST h min, h max, v min, v max) :
+ set values (size, ROW 2 ROW 2 REAL : (ROW 2 REAL : (h min, h max),
+ ROW 2 REAL : (v min, v max)),
+ angles, obliques, perspectives)
+END PROC view port;
+
+PROC view (REAL CONST alpha) :
+ set values (size, limits, ROW 4 REAL : (alpha, angles(2), angles (3), angles (4)),
+ obliques, perspectives)
+END PROC view;
+
+PROC view (REAL CONST phi, theta):
+ set values (size, limits, ROW 4 REAL : (angles (1), sind (theta) * cosd (phi),
+ sind (theta) * sind (phi), cosd (theta)),
+ obliques, perspectives)
+END PROC view;
+
+PROC view (REAL CONST x, y, z) :
+ set values (size, limits, ROW 4 REAL : (angles (1), x, y, z), obliques, perspectives)
+END PROC view;
+
+PROC get values (ROW 3 ROW 2 REAL VAR act size,
+ ROW 2 ROW 2 REAL VAR act limits,
+ ROW 4 REAL VAR act angles,
+ ROW 2 REAL VAR act obliques,
+ ROW 3 REAL VAR act perspectives) :
+ act size := size;
+ act limits := limits;
+ act angles := angles;
+ act obliques := obliques;
+ act perspectives := perspectives;
+
+END PROC get values;
+
+PROC set values (ROW 3 ROW 2 REAL CONST new size,
+ ROW 2 ROW 2 REAL CONST new limits,
+ ROW 4 REAL CONST new angles,
+ ROW 2 REAL CONST new obliques,
+ ROW 3 REAL CONST new perspectives) :
+ size := new size;
+ limits := new limits;
+ angles := new angles;
+ obliques := new obliques;
+ perspectives := new perspectives
+
+END PROC set values;
+
+PROC new values (INT VAR h min range, h max range, v min range, v max range):
+ new values (hor cm, vert cm, hor pixel, vert pixel,
+ h min range, h max range, v min range, v max range)
+END PROC new values;
+
+PROC new values (REAL CONST size hor, size vert,
+ INT CONST pixel hor, pixel vert,
+ INT VAR h min range, h max range,
+ v min range, v max range):
+ remember screensize;
+ calc views;
+ calc projektion;
+ calc limits;
+ calc projection frame;
+ normalize projektion;
+ set picture range;
+ set perspective mark .
+
+remember screensize:
+ hor cm := size hor;
+ vert cm := size vert;
+ hor pixel := pixel hor;
+ vert pixel := pixel vert .
+
+calc views :
+ calc diagonale;
+ calc projektion;
+ calc angles;
+ calc normale;
+ calc matrix;
+ calc alpha angle .
+
+calc diagonale:
+ REAL VAR diagonale := sqrt (angles [2] * angles [2] +
+ angles [3] * angles [3] +
+ angles [4] * angles [4]) .
+
+calc projektion:
+ REAL VAR projektion := sqrt (angles [2] * angles [2] +
+ angles [4] * angles [4]) .
+
+calc angles:
+ REAL VAR sin p, cos p, sin t, cos t, sin a, cos a;
+
+ IF diagonale = 0.0
+ THEN sin p := 0.0; cos p := 1.0;
+ sin t := 0.0; cos t := 1.0
+ ELIF projektion = 0.0
+ THEN sin p := angles [3] / diagonale;
+ cos p := projektion / diagonale;
+ sin t := 0.0; cos t := 1.0
+ ELSE sin p := angles [3] / diagonale;
+ cos p := projektion / diagonale;
+ sin t := angles [2] / projektion;
+ cos t := angles [4] / projektion
+ FI .
+
+calc normale:
+ REAL VAR sin p sin t := sin p * sin t,
+ sin p cos t := sin p * cos t,
+ cos p sin t := cos p * sin t,
+ cos p cos t := cos p * cos t,
+
+ dx := size [1][2] - size [1][1],
+ dy := size [2][2] - size [2][1],
+ dz := size [3][2] - size [3][1],
+ norm az := obliques [1] ,
+ norm bz := obliques [2] ,
+ norm cx := perspectives [1] / dx,
+ norm cy := perspectives [2] / dy,
+ norm cz := perspectives [3] / dz .
+
+calc matrix:
+p := ROW 5 ROW 5 REAL :
+ (ROW 5 REAL : ( cos t / dx - cos p sin t / dx * norm az ,
+ - sin p sin t / dx - cos p sin t / dx * norm bz,
+ 0.0,
+ - cos p sin t / dx * norm cz,
+ 0.0 ),
+ ROW 5 REAL : ( - sin p / dy * norm az,
+ cos p / dy - sin p / dy * norm bz,
+ 0.0,
+ - sin p / dy * norm cz,
+ 0.0 ),
+ ROW 5 REAL : ( sin t / dz + cos p cos t / dz * norm az,
+ + sin p cos t / dz + cos p cos t / dz * norm bz,
+ 0.0,
+ cos p cos t / dz * norm cz,
+ 0.0 ),
+ ROW 5 REAL : (- norm cx, - norm cy, 0.0, 1.0, 0.0 ),
+ ROW 5 REAL : (0.0, 0.0, 0.0, 0.0, 1.0)) .
+
+calc alpha angle:
+ IF angles (1) = 0.0
+ THEN set alpha as y vertical
+ ELSE sin a := sind (angles (1));
+ cos a := cosd (angles (1))
+ FI .
+
+set alpha as y vertical :
+ REAL VAR r := sqrt (p(2)(1)**2 + p(2)(2)**2);
+ IF r = 0.0
+ THEN sin a := 0.0;
+ cos a := 1.0
+ ELSE sin a :=-p(2)(1)/r;
+ cos a := p(2)(2)/r
+ FI .
+
+calc limits :
+ IF limits as percent
+ THEN calc percent limits
+ ELSE calc centimeter limits FI .
+
+limits as percent:
+ limits [1][2] < 2.0 AND limits [2][2] < 2.0 .
+
+max limits:
+ h min limit := 0.0;
+
+ v min limit := 0.0;
+ v max limit := real (pixel vert) .
+
+calc percent limits:
+ h min limit := real (pixel hor) * limits (1)(1)*size vert / size hor;
+ v min limit := limits (2)(1) * real (pixel vert);
+
+ IF limits [1][2] = 0.0
+ THEN h max limit := real (pixel hor)
+ ELSE h max limit := real (pixel hor) * limits [1][2]*size vert / size hor FI;
+
+ IF limits [2][2] = 0.0
+ THEN v max limit := real (pixel vert)
+ ELSE v max limit := limits (2)(2) * real (pixel vert) FI .
+
+calc centimeter limits:
+ h min limit := real (pixel hor) * (limits (1)(1)/size hor);
+ v min limit := real (pixel vert) * (limits (2)(1)/size vert);
+
+ IF limits [1][2] = 0.0
+ THEN h max limit := real (pixel hor)
+ ELSE h max limit := real (pixel hor) * (limits (1)(2)/size hor) FI;
+
+ IF limits [2][2] = 0.0
+ THEN v max limit := real (pixel vert)
+ ELSE v max limit := real (pixel vert) * (limits (2)(2)/size vert) FI .
+
+calc projection frame:
+ REAL VAR h min := max real, h max :=-max real,
+ v min := max real, v max :=-max real;
+
+ extrema (size [1][1], size [2][1], size [3][1], h min, h max, v min, v max);
+ extrema (size [1][2], size [2][1], size [3][1], h min, h max, v min, v max);
+ extrema (size [1][2], size [2][2], size [3][1], h min, h max, v min, v max);
+ extrema (size [1][1], size [2][2], size [3][1], h min, h max, v min, v max);
+ extrema (size [1][1], size [2][1], size [3][2], h min, h max, v min, v max);
+ extrema (size [1][2], size [2][1], size [3][2], h min, h max, v min, v max);
+ extrema (size [1][2], size [2][2], size [3][2], h min, h max, v min, v max);
+ extrema (size [1][1], size [2][2], size [3][2], h min, h max, v min, v max) .
+
+normalize projektion :
+ REAL VAR sh := (h max limit - h min limit) / (h max - h min),
+ sv := (v max limit - v min limit) / (v max - v min),
+ dh := h min limit - h min*sh,
+ dv := v min limit - v min*sv;
+
+ FOR i FROM 1 UPTO 5
+ REP REAL CONST p i 1 := p (i)(1);
+ p (i)(1) := (p i 1 * cos a - p (i)(2) * sin a) * sh;
+ p (i)(2) := (p i 1 * sin a + p (i)(2) * cos a) * sv
+ PER;
+ p (5)(1) := dh;
+ p (5)(2) := dv .
+
+set picture range:
+ h min range := int (h min limit-0.5);
+ h max range := int (h max limit+0.5);
+ v min range := int (v min limit-0.5);
+ v max range := int (v max limit+0.5) .
+
+set perspective mark:
+ perspective projektion := perspectives [3] <> 0.0 .
+
+END PROC new values;
+
+PROC transform (REAL CONST x, y, z, INT VAR h, v) :
+ IF perspective projektion
+ THEN REAL CONST w :: 1.0/(x*p (1)(4) + y*p (2)(4) + z*p (3)(4) + 1.0);
+ h := int ((x*p (1)(1)+y*p (2)(1)+z*p (3)(1) + p (4)(1))*w + p (5)(1));
+ v := int ((x*p (1)(2)+y*p (2)(2)+z*p (3)(2) + p (4)(2))*w + p (5)(2))
+ ELSE h := int (x*p (1)(1)+y*p (2)(1)+z*p (3)(1) + p (5)(1));
+ v := int (x*p (1)(2)+y*p (2)(2)+z*p (3)(2) + p (5)(2));
+ FI;
+END PROC transform;
+
+PROC extrema (REAL CONST x, y, z, REAL VAR h min, h max, v min, v max):
+ REAL VAR h, v;
+ IF perspective projektion
+ THEN REAL CONST w :: 1.0/(x*p (1)(4) + y*p (2)(4) + z*p (3)(4) + 1.0);
+ h := (x*p (1)(1)+y*p (2)(1)+z*p (3)(1) +p (4)(1))*w;
+ v := (x*p (1)(2)+y*p (2)(2)+z*p (3)(2) +p (4)(2))*w
+ ELSE h := (x*p (1)(1)+y*p (2)(1)+z*p (3)(1));
+ v := (x*p (1)(2)+y*p (2)(2)+z*p (3)(2))
+ FI;
+
+ IF h < h min
+ THEN h min := h
+ ELIF h > h max
+ THEN h max := h FI;
+
+ IF v < v min
+ THEN v min := v
+ ELIF v > v max
+ THEN v max := v FI
+
+END PROC extrema;
+
+INT PROC diagonal (REAL CONST percent):
+ int (percent * 0.01 * diagonale + 0.5) .
+
+diagonale:
+ sqrt ((h max limit-h min limit) ** 2 + (v max limit-v min limit) ** 2) .
+
+END PROC diagonal;
+
+INT PROC height (REAL CONST percent):
+ int (percent * 0.01 * (v max limit-v min limit) + 0.5)
+END PROC height;
+
+INT PROC width (REAL CONST percent):
+ int (percent * 0.01 * (h max limit-h min limit) + 0.5)
+END PROC width;
+
+END PACKET transformation
+
diff --git a/graphic/GRAPHIK.vektor plot b/graphic/GRAPHIK.vektor plot
new file mode 100644
index 0000000..8bef1e4
--- /dev/null
+++ b/graphic/GRAPHIK.vektor plot
@@ -0,0 +1,506 @@
+PACKET clipping DEFINES set range, (*Autor: Heiko Indenbirken *)
+ get range, (*Stand: 27.06.85/12:39 *)
+ clip: (*Änderung: 11.08.86/15:02 *)
+
+INT VAR x min :: 0, x max :: 1024, y min :: 0, y max :: 1024;
+
+PROC set range (INT CONST h min, v min, h max, v max):
+ IF h min >= h max OR v min >= v max
+ THEN errorstop ("Incorrect Range") FI;
+ x min := h min; x max := h max;
+ y min := v min; y max := v max
+END PROC set range;
+
+PROC get range (INT VAR h min, v min, h max, v max):
+ h min := x min; h max := x max;
+ v min := y min; v max := y max
+END PROC get range;
+
+PROC clip (INT CONST from x, from y, to x, to y,
+ PROC (INT CONST, INT CONST) move,
+ PROC (INT CONST, INT CONST) draw):
+ INT VAR x, y;
+ calculate parts of line;
+ IF both points inside
+ THEN draw (to x, to y)
+ ELIF both points outside
+ THEN
+ ELIF first point outside
+ THEN intersection (to x, to y, from x, from y, from part, x, y);
+ move (x, y);
+ draw (x, y); (* Macke im SHARD *)
+ draw (to x, to y)
+ ELIF second point outside
+ THEN intersection (from x, from y, to x, to y, to part, x, y);
+ draw (x, y)
+ ELSE intersection (to x, to y, from x, from y, from part, x, y);
+ move (x, y);
+ draw (x, y); (* Macke im SHARD *)
+ clip (x, y, to x, to y, PROC (INT CONST, INT CONST) move,
+ PROC (INT CONST, INT CONST) draw)
+ FI .
+
+calculate parts of line:
+ INT CONST from part :: part (from x, from y),
+ to part :: part (to x, to y) .
+
+both points inside:
+ from part = 0 AND to part = 0 .
+
+both points outside:
+ (from part AND to part) <> 0 .
+
+first point outside:
+ from part <> 0 AND to part = 0 .
+
+second point outside:
+ to part <> 0 AND from part = 0 .
+
+END PROC clip;
+
+INT PROC part (INT CONST x, y):
+ INT VAR index :: 0;
+ IF x > x max
+ THEN set bit (index, 0)
+ ELIF x < x min
+ THEN set bit (index, 1) FI;
+
+ IF y > y max
+ THEN set bit (index, 2)
+ ELIF y < y min
+ THEN set bit (index, 3) FI;
+
+ index
+
+END PROC part;
+
+PROC intersection (INT CONST from x, from y, to x, to y, to part, INT VAR x, y):
+ SELECT to part OF
+ CASE 1: right side
+ CASE 2: left side
+ CASE 4: up side
+ CASE 5: upright side
+ CASE 6: upleft side
+ CASE 8: down side
+ CASE 9: downright side
+ CASE 10: downleft side
+ OTHERWISE errorstop ("wrong partno.:" + text (to part)) ENDSELECT .
+
+right side:
+ y := from y + int (real (x max-from x)*(dy/dx));
+ x := x max .
+
+left side:
+ y := from y + int (real (x min-from x)*(dy/dx));
+ x := x min .
+
+up side:
+ x := from x + int (real (y max-from y)*(dx/dy));
+ y := y max .
+
+down side:
+ x := from x + int (real (y min-from y)*(dx/dy));
+ y := y min .
+
+upright side:
+ right side;
+ IF y > y max
+ THEN up side FI .
+
+downright side:
+ right side;
+ IF y < y min
+ THEN down side FI .
+
+upleft side:
+ left side;
+ IF y > y max
+ THEN up side FI .
+
+downleft side:
+ left side;
+ IF y < y min
+ THEN down side FI .
+
+dx: real (to x-from x) .
+dy: real (to y-from y) .
+
+END PROC intersection;
+
+END PACKET clipping;
+
+PACKET thick line DEFINES thick: (*Autor: Heiko Indenbirken *)
+ (*Stand: 02.07.85/15:07 *)
+ (*Änderung: 05.08.86/15:52 *)
+PROC thick (INT CONST x0, y0, x1, y1, thick,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ IF is point
+ THEN draw point
+ ELIF is horizontal line
+ THEN horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ x0, y0, x1, y1, thick)
+ ELSE vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ x0, y0, x1, y1, thick)
+ FI .
+
+is point:
+ x0 = x1 AND y0 = y1 .
+
+is horizontal line:
+ abs (x0-x1) >= abs (y0-y1) .
+
+draw point:
+ INT VAR i;
+ FOR i FROM -thick UPTO thick
+ REP line (x0-thick, y0+i, x0+thick, y0+i) PER .
+
+END PROC thick;
+
+PROC horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ INT CONST from x, from y, to x, to y, thick):
+ IF from x > to x
+ THEN horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ to x, to y, from x, from y, thick)
+ ELSE draw line FI .
+
+draw line:
+ INT VAR i;
+ calculate increase;
+ calculate limit points;
+ FOR i FROM -thick UPTO thick
+ REP calculate delta x;
+ line (x start+delta x, y start+i, x end+delta x, y end+i)
+ PER .
+
+calculate increase:
+ REAL VAR increase :: -dy / dx .
+
+calculate limit points:
+ INT CONST x start :: from x - thick,
+ x end :: to x + thick,
+ y start :: from y + int (increase * real (thick)),
+ y end :: to y - int (increase * real (thick)) .
+
+calculate delta x:
+ INT CONST delta x :: int (increase*real (i)) .
+
+dx: real (to x-from x) .
+dy: real (to y-from y) .
+
+END PROC horizontal line;
+
+PROC vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ INT CONST from x, from y, to x, to y, thick):
+ IF from y > to y
+ THEN vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ to x, to y, from x, from y, thick)
+ ELSE draw line FI .
+
+draw line:
+ INT VAR i;
+ calculate increase;
+ calculate limit points;
+ FOR i FROM -thick UPTO thick
+ REP calculate delta y;
+ line (x start+i, y start+delta y, x end+i, y end+delta y)
+ PER .
+
+calculate increase:
+ REAL VAR increase :: -dx / dy .
+
+calculate limit points:
+ INT CONST x start :: from x + int (increase * real (thick)),
+ x end :: to x - int (increase * real (thick)),
+ y start :: from y - thick,
+ y end :: to y + thick .
+
+calculate delta y:
+ INT CONST delta y :: int (increase*real (i)) .
+
+dx: real (to x-from x) .
+dy: real (to y-from y) .
+
+END PROC vertical line;
+
+END PACKET thick line;
+
+PACKET graphik text DEFINES draw char, (*Autor: Heiko Indenbirken *)
+ zeichensatz: (*Stand: 27.06.85/16:03 *)
+ (*Änderung: 28.06.85/19:06 *)
+ (*Änderung: 05.08.86/16:00 *)
+LET ZEICHENSATZ = ROW 255 TEXT;
+ZEICHENSATZ VAR zeichen;
+INT CONST char x :: 6, char y :: 10;
+
+zeichensatz ("ZEICHENSATZ");
+
+PROC zeichensatz (TEXT CONST name):
+ IF exists (name)
+ THEN BOUND ZEICHENSATZ VAR new zeichen :: old (name);
+ zeichen := new zeichen;
+ ELSE errorstop ("Der Zeichensatz """ + name + """ existiert nicht") FI
+END PROC zeichensatz;
+
+PROC draw char (INT CONST char no, INT CONST x, y, x size, y size, direction,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ TEXT CONST character :: zeichen [char no];
+ INT VAR n :: 1, x0, y0, x1, y1;
+ INT CONST len :: length (character);
+ WHILE n < len
+ REP value (character, n, x0, y0, x1, y1);
+ transform (x0, y0, x, y, x size, y size, direction);
+ transform (x1, y1, x, y, x size, y size, direction);
+ line (x0, y0, x1, y1);
+ n INCR 4
+ PER .
+
+END PROC draw char;
+
+PROC value (TEXT CONST char, INT CONST n, INT VAR x0, y0, x1, y1):
+ x0 := val (code (char SUB n)); y0 := val (code (char SUB n+1));
+ x1 := val (code (char SUB n+2)); y1 := val (code (char SUB n+3));
+END PROC value;
+
+INT PROC val (INT CONST n):
+ IF n > 127
+ THEN -256 OR n
+ ELSE n FI
+END PROC val;
+
+PROC transform (INT VAR x, y, INT CONST x0, y0, x size, y size, direction):
+ INT CONST old x :: x, old y :: y;
+ SELECT direction OF
+ CASE 0: x := x0 + x vektor; y := y0 + y vektor
+ CASE 1: x := x0 - y vektor; y := y0 + x vektor
+ CASE 2: x := x0 - x vektor; y := y0 - y vektor
+ CASE 3: x := x0 + y vektor; y := y0 - x vektor
+ ENDSELECT .
+
+x vektor:
+ IF x size = 0
+ THEN old x
+ ELSE (old x*x size) DIV char x FI .
+
+y vektor:
+ IF y size = 0
+ THEN old y
+ ELSE (old y*y size) DIV char y FI .
+
+END PROC transform;
+
+END PACKET graphik text;
+
+PACKET graphik text DEFINES draw text: (*Autor: Heiko Indenbirken *)
+ (*Stand: 03.07.85/11:55 *)
+ (*Änderung: 05.08.86/16:04 *)
+PROC draw text (INT CONST x pos, y pos,
+ TEXT CONST msg, REAL CONST angle, INT CONST height, width,
+ PROC (INT CONST, INT CONST,
+ INT CONST, INT CONST, INT CONST, INT CONST) draw char):
+ INT CONST dir :: int (((angle MOD 360.0)+45.0) / 90.0);
+ INT VAR i;
+ REAL VAR x :: real (x pos), y :: real (y pos),
+ x step :: cosd (angle)*real (width),
+ y step :: sind (angle)*real (width);
+ FOR i FROM 1 UPTO length (msg)
+ REP IF control char
+ THEN execute control char
+ ELSE execute normal char FI
+ PER .
+
+control char:
+ akt char < ""32"" .
+
+execute control char:
+ SELECT code (akt char) OF
+ CASE 1: home
+ CASE 2: right
+ CASE 3: up
+ CASE 7: out (""7"")
+ CASE 8: left
+ CASE 10: down
+ CASE 13: return
+ ENDSELECT .
+
+home:
+ x := real (x pos);
+ y := real (y pos) .
+
+right:
+ x INCR x step; y INCR y step .
+
+up:
+ x INCR y step; y INCR x step .
+
+left:
+ x DECR x step; y DECR y step .
+
+down:
+ x DECR y step; y DECR x step .
+
+return:
+ x := real (x pos) .
+
+execute normal char:
+ draw char (code (akt char), dir, int (x+0.5), int (y+0.5), height, width);
+ x INCR x step;
+ y INCR y step .
+
+akt char:
+ msg SUB i .
+
+END PROC draw text;
+
+END PACKET graphik text;
+
+PACKET comercial plot DEFINES bar, (*Autor: Heiko Indenbirken *)
+ circle: (*Stand: 03.04.1985 *)
+ (*Änderung: 03.07.85/15:37 *)
+PROC bar (INT CONST from x, from y, to x, to y, pattern,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ IF from x > to x
+ THEN bar (to x, from y, from x, to y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ ELIF from y > to y
+ THEN bar (from x, to y, to x, from y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ ELSE draw frame;
+ fill frame with pattern
+ FI .
+
+draw frame:
+ line (from x, from y, from x, to y);
+ line (from x, to y, to x, to y);
+ line (to x, to y, to x, from y);
+ line (to x, from y, from x, from y) .
+
+fill frame with pattern:
+ SELECT pattern OF
+ CASE 1: fill right (from x, to x, from y, to y, 2, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 2: fill hor (from x, to x, from y, to y, 1, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 3: fill hor (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 4: fill vert (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 5: fill hor (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line);
+ fill vert (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 6: fill right (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 7: fill left (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 8: fill right (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line);
+ fill left (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ ENDSELECT .
+
+END PROC bar;
+
+PROC fill hor (INT CONST from x, to x, from y, to y, step,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ INT VAR y :: from y;
+ REP line (from x, y, to x, y);
+ y INCR step
+ UNTIL y > to y PER .
+
+END PROC fill hor;
+
+PROC fill vert (INT CONST from x, to x, from y, to y, step,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ INT VAR x :: from x;
+ REP line (x, from y, x, to y);
+ x INCR step
+ UNTIL x > to x PER .
+
+END PROC fill vert;
+
+PROC fill right (INT CONST from x, to x, from y, to y, step,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ INT CONST width :: to x - from x,
+ height :: to y - from y,
+ length :: width + height,
+ height step :: height + step,
+ width step :: width + step;
+
+ INT VAR t :: step, left :: from x, right :: from x,
+ lower :: from y, upper :: from y;
+(* Ausfüllen von links unten nach rechts oben *)
+ WHILE t < length
+ REP calc start point;
+ calc end point;
+ line (left, upper, right, lower);
+ t INCR step
+ PER .
+
+calc start point:
+ IF t < height
+ THEN upper INCR step
+ ELIF t < height step
+ THEN left := from x + t - height;
+ upper := to y
+ ELSE left INCR step FI .
+
+calc end point:
+ IF t < width
+ THEN right INCR step
+ ELIF t < width step
+ THEN lower := from y + t - width;
+ right := to x
+ ELSE lower INCR step FI .
+
+END PROC fill right;
+
+PROC fill left (INT CONST from x, to x, from y, to y, step,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ INT CONST width :: to x - from x,
+ height :: to y - from y,
+ length :: width + height,
+ height step :: height + step,
+ width step :: width + step;
+
+ INT VAR t :: step, left :: to x, right :: to x,
+ lower :: from y, upper :: from y;
+(* Ausfüllen von rechts unten nach links oben *)
+ WHILE t < length
+ REP calc start point;
+ calc end point;
+ line (right, upper, left, lower);
+ t INCR step
+ PER .
+
+calc start point:
+ IF t < height
+ THEN upper INCR step
+ ELIF t < height step
+ THEN right := to x - t + height;
+ upper := to y
+ ELSE right DECR step FI .
+
+calc end point:
+ IF t < width
+ THEN left DECR step
+ ELIF t < width step
+ THEN lower := from y + t - width;
+ left := from x
+ ELSE lower INCR step FI .
+
+END PROC fill left;
+
+PROC circle (INT CONST x, y, REAL CONST rad, from, to, INT CONST pattern,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ REAL VAR t :: from;
+ INT VAR last x :: x, last y :: y;
+ WHILE t <= to
+ REP calc circle;
+ draw step;
+ t INCR 1.0
+ PER;
+ line (x rad, y rad, x, y) .
+
+draw step:
+ IF pattern = 0
+ THEN line (last x, last y, x rad, y rad);
+ last x := x rad;
+ last y := y rad
+ ELSE line (x, y, x rad, y rad) FI .
+
+calc circle:
+ INT CONST x rad :: int (cosd (t)*rad+0.5)+x,
+ y rad :: int (sind (t)*rad+0.5)+y .
+
+END PROC circle;
+
+END PACKET comercial plot;
+
diff --git a/graphic/HP7475.plot b/graphic/HP7475.plot
new file mode 100644
index 0000000..860dd03
--- /dev/null
+++ b/graphic/HP7475.plot
@@ -0,0 +1,254 @@
+PACKET hp7475 plot DEFINES set range, (*Autor: Heiko Indenbirken *)
+ get range, (*Stand: 03.09.86/15:09 *)
+ drawing area,
+ begin plot,
+ end plot,
+ clear,
+
+ set pen, get pen,
+ move,
+ draw,
+ marker,
+ bar, circle,
+ where:
+
+(* *)
+(* Hardware Anschluß des HP7475A: *)
+(* 9600 Baud, 8 Bit, no parity, RTS/CTS *)
+(* Leitungen 1 ----- 1 *)
+(* gekreuzt: 2 --x-- 3 *)
+(* 3 --x-- 2 *)
+(* *)
+
+
+LET POS = STRUCT (INT x, y);
+LET RANGE = STRUCT (POS min, max);
+LET PEN = STRUCT (INT back, fore, thick, line);
+
+LET width scale = 0.002690217391304,
+ height scale = 0.002728921124206;
+
+LET term = ";",
+ comma = ",",
+ point = ".",
+ zero = "0",
+ nil = "",
+ etx = ""3"";
+
+
+POS VAR old :: POS:(0, 0);
+RANGE VAR area :: RANGE:(POS:(0,0), POS:(11040, 7721));
+PEN VAR pen :: PEN : (0, 1, 0, 1);
+TEXT VAR result;
+
+ROW 16 TEXT VAR mark := ROW 16 TEXT:
+("99,0,2,-2,0,0,-4,4,0,0,4,-2,0;",
+"99,0,2,-1,0,-1,-1,0,-2,1,-1,2,0,1,1,0,2,-1,1,-1,0;",
+"99,0,2,-2,-3,4,0,-2,3;",
+"-99,-2,0,99,4,0,-99,-2,2,99,0,-4;",
+"-99,-2,-2,99,4,4,-99,-4,0,99,4,-4;",
+"99,0,2,-2,-2,2,-2,2,2,-2,2;",
+"-99,0,-2,99,0,4,-2,-2,4,0,-2,2;",
+"-99,-2,0,99,4,0,-99,-2,2,99,0,-4,2,2,-2,2,-2,-2,2,-2;",
+"-99,-2,-2,99,4,4,-4,0,4,-4;",
+"-99,-2,2,99,4,0,-4,-4,4,0;",
+"99,0,-2,-99,-2,4,99,2,-2,2,2;",
+"99,1,1,-2,0,0,-2,2,0,0,2,1,1,-99,-4,0,99,1,-1,-99,0,-2,99,-1,-1,-99,4,0,99,-1,1;",
+"-99,-2,0,99,4,0,-99,-1,1,99,-2,-2,-99,1,-1,99,0,4,-99,-1,-1,99,2,-2;",
+"-99,-2,2,99,4,0,-4,-4,4,0,-4,4;",
+"-99,-2,0,99,4,0;",
+"-99,0,299,0,-4;");
+
+ROW 5 TEXT CONST line pattern := ROW 5 TEXT:("LT;", "LT1;", "LT2;", "LT3;", "LT4;");
+ROW 8 TEXT CONST fill pattern := ROW 8 TEXT:("FT4,25,45;", "FT1,0,0;", "FT3,50,0;",
+ "FT3,50,90;", "FT4,50,0;", "FT3,50,-45;",
+ "FT3,50,45;", "FT4,50,45;");
+
+PROC drawing area (REAL VAR x cm, y cm, INT VAR x pixel, y pixel) :
+ x cm := 29.7; y cm := 21.07;
+ x pixel := 11040; y pixel := 7721;
+END PROC drawing area;
+
+
+PROC set range (INT CONST h min, v min, h max, v max):
+ IF h min >= h max OR v min >= v max
+ THEN errorstop ("Incorrect Range") FI;
+ area := RANGE:(POS:(h min, v min), POS:(h max, v max))
+END PROC set range;
+
+PROC get range (INT VAR h min, v min, h max, v max):
+ h min := area.min.x; v min := area.min.y;
+ h max := area.max.x; v max := area.max.y
+END PROC get range;
+
+PROC begin plot:
+ out ("IN;")
+ENDPROC begin plot;
+
+PROC end plot:
+ TEXT VAR rec;
+ out ("IN;SP;PA22040,7721;DP;");
+ REP pause (10);
+ out ("OS;");
+ input (rec, ""13"", 600)
+ UNTIL enter pressed PER;
+ out ("IN;") .
+
+enter pressed:
+ (int (rec) AND 4) > 0 .
+
+ENDPROC end plot;
+
+PROC clear:
+ new values (29.7, 21.07, 11040, 7721, area.min.x, area.max.x, area.min.y, area.max.y);
+ pen := PEN : (0, 1, 0, 1);
+ old := area.min;
+ out ("DF;IP;"); (* Default *)
+ out ("IW" + text (area.min.x, area.min.y) + ", " + (* Clipping *)
+ text (area.max.x, area.max.y) + term);
+ out ("SP1;"); (* Pen 1 *)
+ out ("LT;"); (* durchgehend *)
+ out ("PU;PA" + text (old.x, old.y)); (* Startpunkt *)
+
+END PROC clear;
+
+PROC set pen (INT CONST back, fore, thick, type):
+ set colour;
+ set linetype .
+
+set colour:
+ IF abs (fore) >= 1 AND abs (fore) <= 6
+ THEN out ("SP" + text (abs (fore)) + term);
+ pen.fore := abs (fore);
+ FI .
+
+set linetype:
+ IF type >= 1 AND type <= 5
+ THEN out (line pattern [type]);
+ pen.line := type
+ ELSE out ("SP;");
+ pen.line := 0
+ FI .
+
+END PROC set pen;
+
+PROC get pen (INT VAR back, fore, thick, line):
+ back := pen.back;
+ fore := pen.fore;
+ thick := pen.thick;
+ line := pen.line
+END PROC get pen;
+
+PROC move (INT CONST x, y) :
+ out ("PU;PA" + text (x, y) + term);
+ old := POS : (x, y)
+END PROC move;
+
+PROC draw (INT CONST x, y):
+ out ("PD;PA" + text (x, y) + term);
+ old := POS : (x, y)
+END PROC draw;
+
+PROC draw (TEXT CONST msg, REAL CONST angle, INT CONST height, width):
+ set angle;
+ set height and width;
+ plot msg .
+
+set angle:
+ out ("DI " + text (cosd (angle), sind (angle)) + term) .
+
+set height and width:
+ IF width = 0 AND height = 0
+ THEN out ("SR;")
+ ELSE out ("SI" + text (real (width) * width scale,
+ real (height) * height scale) + term)
+ FI .
+
+plot msg:
+ out ("LB" + msg + etx) .
+
+END PROC draw;
+
+PROC bar (INT CONST from x, from y, to x, to y, pattern):
+ out ("PU;PA" + text (from x, from y) + term);
+ out ("LT;EA" + text (to x, to y) + term);
+ IF pattern > 0 AND pattern <= 8
+ THEN out (fill pattern [pattern]);
+ out ("RA" + text (to x, to y) + term);
+ FI;
+ out ("PU;PA" + text (old.x, old.y) + term);
+ out (line pattern [pen.line]) .
+
+END PROC bar;
+
+PROC circle (INT CONST x, y, rad, REAL CONST from, to, INT CONST pattern):
+ out ("LT;PU;PA" + text (x, y) + term);
+ IF (from MOD 360.0) = 0.0 AND (to MOD 360.0) = 0.0
+ THEN out ("CI" + text (rad) + term)
+ ELSE out ("EW" + text (rad) + comma + text (from, to-from) + term) FI;
+
+ IF pattern > 0 AND pattern <= 6
+ THEN out (fill pattern [pattern]);
+ out ("WG" + text (rad) + comma + text (from, to-from) + term)
+ FI;
+ out ("PU;PA" + text (old.x, old.y) + term);
+ out (line pattern [pen.line]) .
+
+END PROC circle;
+
+PROC marker (INT CONST x, y, no, size):
+ out ("LT;PU;PA" + text (x, y) + term);
+ out ("DI1,0;");
+ IF size = 0
+ THEN out ("SI0.25,0.5;")
+ ELSE out ("SI" + text (real (size)*0.001, real (size)*0.002) + term) FI;
+ out ("UC" + mark [mark no]);
+ out ("PU;PA" + text (old.x, old.y) + term);
+ out (line pattern [pen.line]) .
+
+mark no:
+ IF no >= 1 AND no <= 16
+ THEN no
+ ELSE 1 FI .
+
+END PROC marker;
+
+PROC where (INT VAR x, y):
+ x := old.x; y := old.y
+END PROC where;
+
+TEXT PROC text (INT CONST x, y):
+ text (x) + comma + text (y)
+END PROC text;
+
+TEXT PROC text (REAL CONST x, y):
+ text (x) + comma + text (y)
+END PROC text;
+
+TEXT PROC text (REAL CONST x):
+ result := compress (text (x, 9, 4));
+
+ IF (result SUB 1) = point
+ THEN insert char (result, zero, 1)
+ ELIF (result SUB LENGTH result) = point
+ THEN result CAT zero FI;
+ result
+END PROC text;
+
+PROC input (TEXT VAR rec, TEXT CONST del, INT CONST time):
+ enable stop;
+ rec := nil;
+ REP TEXT CONST char := incharety (time);
+
+ IF char = nil
+ THEN errorstop ("Timeout after " + text (time))
+ ELIF pos (del, char) > 0
+ THEN LEAVE input
+ ELSE rec CAT char FI
+
+ PER .
+
+END PROC input;
+
+END PACKET hp7475 plot
+
diff --git a/graphic/PC.plot b/graphic/PC.plot
new file mode 100644
index 0000000..712f5ea
--- /dev/null
+++ b/graphic/PC.plot
@@ -0,0 +1,758 @@
+PACKET clipping DEFINES set range, (*Autor: Heiko Indenbirken *)
+ get range, (*Stand: 27.06.85/12:39 *)
+ clip: (*Änderung: 11.08.86/15:02 *)
+
+INT VAR x min :: 0, x max :: 1024, y min :: 0, y max :: 1024;
+
+PROC set range (INT CONST h min, v min, h max, v max):
+ IF h min >= h max OR v min >= v max
+ THEN errorstop ("Incorrect Range") FI;
+ x min := h min; x max := h max;
+ y min := v min; y max := v max
+END PROC set range;
+
+PROC get range (INT VAR h min, v min, h max, v max):
+ h min := x min; h max := x max;
+ v min := y min; v max := y max
+END PROC get range;
+
+PROC clip (INT CONST from x, from y, to x, to y,
+ PROC (INT CONST, INT CONST) move,
+ PROC (INT CONST, INT CONST) draw):
+ INT VAR x, y;
+ calculate parts of line;
+ IF both points inside
+ THEN draw (from x, from y); (* Macke im SHARD *)
+ draw (to x, to y)
+ ELIF both points outside
+ THEN
+ ELIF first point outside
+ THEN intersection (to x, to y, from x, from y, from part, x, y);
+ move (x, y);
+ draw (x, y); (* Macke im SHARD *)
+ draw (to x, to y)
+ ELIF second point outside
+ THEN intersection (from x, from y, to x, to y, to part, x, y);
+ draw (x, y)
+ ELSE intersection (to x, to y, from x, from y, from part, x, y);
+ move (x, y);
+ draw (x, y); (* Macke im SHARD *)
+ clip (x, y, to x, to y, PROC (INT CONST, INT CONST) move,
+ PROC (INT CONST, INT CONST) draw)
+ FI .
+
+calculate parts of line:
+ INT CONST from part :: part (from x, from y),
+ to part :: part (to x, to y) .
+
+both points inside:
+ from part = 0 AND to part = 0 .
+
+both points outside:
+ (from part AND to part) <> 0 .
+
+first point outside:
+ from part <> 0 AND to part = 0 .
+
+second point outside:
+ to part <> 0 AND from part = 0 .
+
+END PROC clip;
+
+INT PROC part (INT CONST x, y):
+ INT VAR index :: 0;
+ IF x > x max
+ THEN set bit (index, 0)
+ ELIF x < x min
+ THEN set bit (index, 1) FI;
+
+ IF y > y max
+ THEN set bit (index, 2)
+ ELIF y < y min
+ THEN set bit (index, 3) FI;
+
+ index
+
+END PROC part;
+
+PROC intersection (INT CONST from x, from y, to x, to y, to part, INT VAR x, y):
+ SELECT to part OF
+ CASE 1: right side
+ CASE 2: left side
+ CASE 4: up side
+ CASE 5: upright side
+ CASE 6: upleft side
+ CASE 8: down side
+ CASE 9: downright side
+ CASE 10: downleft side
+ OTHERWISE errorstop ("wrong partno.:" + text (to part)) ENDSELECT .
+
+right side:
+ y := from y + int (real (x max-from x)*(dy/dx));
+ x := x max .
+
+left side:
+ y := from y + int (real (x min-from x)*(dy/dx));
+ x := x min .
+
+up side:
+ x := from x + int (real (y max-from y)*(dx/dy));
+ y := y max .
+
+down side:
+ x := from x + int (real (y min-from y)*(dx/dy));
+ y := y min .
+
+upright side:
+ right side;
+ IF y > y max
+ THEN up side FI .
+
+downright side:
+ right side;
+ IF y < y min
+ THEN down side FI .
+
+upleft side:
+ left side;
+ IF y > y max
+ THEN up side FI .
+
+downleft side:
+ left side;
+ IF y < y min
+ THEN down side FI .
+
+dx: real (to x-from x) .
+dy: real (to y-from y) .
+
+END PROC intersection;
+
+END PACKET clipping;
+
+PACKET thick line DEFINES thick: (*Autor: Heiko Indenbirken *)
+ (*Stand: 02.07.85/15:07 *)
+ (*Änderung: 05.08.86/15:52 *)
+PROC thick (INT CONST x0, y0, x1, y1, thick,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ IF is point
+ THEN draw point
+ ELIF is horizontal line
+ THEN horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ x0, y0, x1, y1, thick)
+ ELSE vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ x0, y0, x1, y1, thick)
+ FI .
+
+is point:
+ x0 = x1 AND y0 = y1 .
+
+is horizontal line:
+ abs (x0-x1) >= abs (y0-y1) .
+
+draw point:
+ INT VAR i;
+ FOR i FROM -thick UPTO thick
+ REP line (x0-thick, y0+i, x0+thick, y0+i) PER .
+
+END PROC thick;
+
+PROC horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ INT CONST from x, from y, to x, to y, thick):
+ IF from x > to x
+ THEN horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ to x, to y, from x, from y, thick)
+ ELSE draw line FI .
+
+draw line:
+ INT VAR i;
+ calculate increase;
+ calculate limit points;
+ FOR i FROM -thick UPTO thick
+ REP calculate delta x;
+ line (x start+delta x, y start+i, x end+delta x, y end+i)
+ PER .
+
+calculate increase:
+ REAL VAR increase :: -dy / dx .
+
+calculate limit points:
+ INT CONST x start :: from x - thick,
+ x end :: to x + thick,
+ y start :: from y + int (increase * real (thick)),
+ y end :: to y - int (increase * real (thick)) .
+
+calculate delta x:
+ INT CONST delta x :: int (increase*real (i)) .
+
+dx: real (to x-from x) .
+dy: real (to y-from y) .
+
+END PROC horizontal line;
+
+PROC vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ INT CONST from x, from y, to x, to y, thick):
+ IF from y > to y
+ THEN vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+ to x, to y, from x, from y, thick)
+ ELSE draw line FI .
+
+draw line:
+ INT VAR i;
+ calculate increase;
+ calculate limit points;
+ FOR i FROM -thick UPTO thick
+ REP calculate delta y;
+ line (x start+i, y start+delta y, x end+i, y end+delta y)
+ PER .
+
+calculate increase:
+ REAL VAR increase :: -dx / dy .
+
+calculate limit points:
+ INT CONST x start :: from x + int (increase * real (thick)),
+ x end :: to x - int (increase * real (thick)),
+ y start :: from y - thick,
+ y end :: to y + thick .
+
+calculate delta y:
+ INT CONST delta y :: int (increase*real (i)) .
+
+dx: real (to x-from x) .
+dy: real (to y-from y) .
+
+END PROC vertical line;
+
+END PACKET thick line;
+
+PACKET graphik text DEFINES draw char, (*Autor: Heiko Indenbirken *)
+ zeichensatz: (*Stand: 27.06.85/16:03 *)
+ (*Änderung: 28.06.85/19:06 *)
+ (*Änderung: 05.08.86/16:00 *)
+LET ZEICHENSATZ = ROW 255 TEXT;
+ZEICHENSATZ VAR zeichen;
+INT CONST char x :: 6, char y :: 10;
+
+zeichensatz ("ZEICHENSATZ");
+
+PROC zeichensatz (TEXT CONST name):
+ IF exists (name)
+ THEN BOUND ZEICHENSATZ VAR new zeichen :: old (name);
+ zeichen := new zeichen;
+ ELSE errorstop ("Der Zeichensatz """ + name + """ existiert nicht") FI
+END PROC zeichensatz;
+
+PROC draw char (INT CONST char no, INT CONST x, y, x size, y size, direction,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ TEXT CONST character :: zeichen [char no];
+ INT VAR n :: 1, x0, y0, x1, y1;
+ INT CONST len :: length (character);
+ WHILE n < len
+ REP value (character, n, x0, y0, x1, y1);
+ transform (x0, y0, x, y, x size, y size, direction);
+ transform (x1, y1, x, y, x size, y size, direction);
+ line (x0, y0, x1, y1);
+ n INCR 4
+ PER .
+
+END PROC draw char;
+
+PROC value (TEXT CONST char, INT CONST n, INT VAR x0, y0, x1, y1):
+ x0 := val (code (char SUB n)); y0 := val (code (char SUB n+1));
+ x1 := val (code (char SUB n+2)); y1 := val (code (char SUB n+3));
+END PROC value;
+
+INT PROC val (INT CONST n):
+ IF n > 127
+ THEN -256 OR n
+ ELSE n FI
+END PROC val;
+
+PROC transform (INT VAR x, y, INT CONST x0, y0, x size, y size, direction):
+ INT CONST old x :: x, old y :: y;
+ SELECT direction OF
+ CASE 0: x := x0 + x vektor; y := y0 + y vektor
+ CASE 1: x := x0 - y vektor; y := y0 + x vektor
+ CASE 2: x := x0 - x vektor; y := y0 - y vektor
+ CASE 3: x := x0 + y vektor; y := y0 - x vektor
+ ENDSELECT .
+
+x vektor:
+ IF x size = 0
+ THEN old x
+ ELSE (old x*x size) DIV char x FI .
+
+y vektor:
+ IF y size = 0
+ THEN old y
+ ELSE (old y*y size) DIV char y FI .
+
+END PROC transform;
+
+END PACKET graphik text;
+
+PACKET graphik text DEFINES draw text: (*Autor: Heiko Indenbirken *)
+ (*Stand: 03.07.85/11:55 *)
+ (*Änderung: 05.08.86/16:04 *)
+PROC draw text (INT CONST x pos, y pos,
+ TEXT CONST msg, REAL CONST angle, INT CONST height, width,
+ PROC (INT CONST, INT CONST,
+ INT CONST, INT CONST, INT CONST, INT CONST) draw char):
+ INT CONST dir :: int (((angle MOD 360.0)+45.0) / 90.0);
+ INT VAR i;
+ REAL VAR x :: real (x pos), y :: real (y pos),
+ x step :: cosd (angle)*real (width),
+ y step :: sind (angle)*real (width);
+ FOR i FROM 1 UPTO length (msg)
+ REP IF control char
+ THEN execute control char
+ ELSE execute normal char FI
+ PER .
+
+control char:
+ akt char < ""32"" .
+
+execute control char:
+ SELECT code (akt char) OF
+ CASE 1: home
+ CASE 2: right
+ CASE 3: up
+ CASE 7: out (""7"")
+ CASE 8: left
+ CASE 10: down
+ CASE 13: return
+ ENDSELECT .
+
+home:
+ x := real (x pos);
+ y := real (y pos) .
+
+right:
+ x INCR x step; y INCR y step .
+
+up:
+ x INCR y step; y INCR x step .
+
+left:
+ x DECR x step; y DECR y step .
+
+down:
+ x DECR y step; y DECR x step .
+
+return:
+ x := real (x pos) .
+
+execute normal char:
+ draw char (code (akt char), dir, int (x+0.5), int (y+0.5), height, width);
+ x INCR x step;
+ y INCR y step .
+
+akt char:
+ msg SUB i .
+
+END PROC draw text;
+
+END PACKET graphik text;
+
+PACKET comercial plot DEFINES bar, (*Autor: Heiko Indenbirken *)
+ circle: (*Stand: 03.04.1985 *)
+ (*Änderung: 03.07.85/15:37 *)
+PROC bar (INT CONST from x, from y, to x, to y, pattern,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ IF from x > to x
+ THEN bar (to x, from y, from x, to y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ ELIF from y > to y
+ THEN bar (from x, to y, to x, from y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ ELSE draw frame;
+ fill frame with pattern
+ FI .
+
+draw frame:
+ line (from x, from y, from x, to y);
+ line (from x, to y, to x, to y);
+ line (to x, to y, to x, from y);
+ line (to x, from y, from x, from y) .
+
+fill frame with pattern:
+ SELECT pattern OF
+ CASE 1: fill right (from x, to x, from y, to y, 2, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 2: fill hor (from x, to x, from y, to y, 1, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 3: fill hor (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 4: fill vert (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 5: fill hor (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line);
+ fill vert (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 6: fill right (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 7: fill left (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ CASE 8: fill right (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line);
+ fill left (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+ ENDSELECT .
+
+END PROC bar;
+
+PROC fill hor (INT CONST from x, to x, from y, to y, step,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ INT VAR y :: from y;
+ REP line (from x, y, to x, y);
+ y INCR step
+ UNTIL y > to y PER .
+
+END PROC fill hor;
+
+PROC fill vert (INT CONST from x, to x, from y, to y, step,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ INT VAR x :: from x;
+ REP line (x, from y, x, to y);
+ x INCR step
+ UNTIL x > to x PER .
+
+END PROC fill vert;
+
+PROC fill right (INT CONST from x, to x, from y, to y, step,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ INT CONST width :: to x - from x,
+ height :: to y - from y,
+ length :: width + height,
+ height step :: height + step,
+ width step :: width + step;
+
+ INT VAR t :: step, left :: from x, right :: from x,
+ lower :: from y, upper :: from y;
+(* Ausfüllen von links unten nach rechts oben *)
+ WHILE t < length
+ REP calc start point;
+ calc end point;
+ line (left, upper, right, lower);
+ t INCR step
+ PER .
+
+calc start point:
+ IF t < height
+ THEN upper INCR step
+ ELIF t < height step
+ THEN left := from x + t - height;
+ upper := to y
+ ELSE left INCR step FI .
+
+calc end point:
+ IF t < width
+ THEN right INCR step
+ ELIF t < width step
+ THEN lower := from y + t - width;
+ right := to x
+ ELSE lower INCR step FI .
+
+END PROC fill right;
+
+PROC fill left (INT CONST from x, to x, from y, to y, step,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ INT CONST width :: to x - from x,
+ height :: to y - from y,
+ length :: width + height,
+ height step :: height + step,
+ width step :: width + step;
+
+ INT VAR t :: step, left :: to x, right :: to x,
+ lower :: from y, upper :: from y;
+(* Ausfüllen von rechts unten nach links oben *)
+ WHILE t < length
+ REP calc start point;
+ calc end point;
+ line (right, upper, left, lower);
+ t INCR step
+ PER .
+
+calc start point:
+ IF t < height
+ THEN upper INCR step
+ ELIF t < height step
+ THEN right := to x - t + height;
+ upper := to y
+ ELSE right DECR step FI .
+
+calc end point:
+ IF t < width
+ THEN left DECR step
+ ELIF t < width step
+ THEN lower := from y + t - width;
+ left := from x
+ ELSE lower INCR step FI .
+
+END PROC fill left;
+
+PROC circle (INT CONST x, y, rad, REAL CONST from, to, INT CONST pattern,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+ REAL VAR t :: from;
+ INT VAR last x :: x, last y :: y;
+ WHILE t <= to
+ REP calc circle;
+ draw step;
+ t INCR 5.0
+ PER;
+ line (x rad, y rad, x, y) .
+
+draw step:
+ IF pattern = 0
+ THEN line (last x, last y, x rad, y rad);
+ last x := x rad;
+ last y := y rad
+ ELSE line (x, y, x rad, y rad) FI .
+
+calc circle:
+ INT CONST x rad :: int (cosd (t)*real (rad)+0.5)+x,
+ y rad :: int (sind (t)*real (rad)+0.5)+y .
+
+END PROC circle;
+
+END PACKET comercial plot;
+
+PACKET pc plot DEFINES drawing area, (*Autor: Heiko Indenbirken *)
+ begin plot, (*Stand: 20.05.85 *)
+ end plot, (*Änderung: 27.06.85/16:17 *)
+ clear, (*Änderung: 03.07.85/15:59 *)
+ (*Änderung: 06.08.86/10:03 *)
+ graphik,
+ set pen, get pen,
+
+ move,
+ draw,
+ draw line,
+ marker,
+ bar, circle,
+ where:
+
+
+LET POS = STRUCT (INT x, y);
+LET PEN = STRUCT (INT back, fore, thick, line);
+INT CONST back code :: -4,
+ modus code :: -5,
+ draw code :: -6,
+ move code :: -7,
+ pen code :: -8,
+ full line :: -1;
+
+INT VAR d, y, pause time :: 10,
+ resolution :: 4, max x :: 319, max y :: 199;
+BOOL VAR is clear := FALSE;
+POS VAR old :: POS : (0, 0);
+PEN VAR pen :: PEN : (0, 1, 0, full line);
+
+PROC drawing area (REAL VAR x cm, y cm, INT VAR x pixel, y pixel) :
+ x cm := 22.0; y cm := 13.7;
+ x pixel := max x; y pixel := max y;
+END PROC drawing area;
+
+PROC graphik (INT CONST modus, pause):
+ pause time := pause;
+ SELECT modus OF
+ CASE 0: resolution := 3;
+ CASE 1: resolution := 72;
+ max x := 639;
+ max y := 399
+ CASE 2: resolution := 64;
+ max x := 639;
+ max y := 399
+ CASE 3: resolution := 6;
+ max x := 639;
+ max y := 199
+ CASE 4: resolution := 4;
+ max x := 319;
+ max y := 199
+ OTHERWISE errorstop ("Nur Modi 0-4") ENDSELECT;
+
+ set range (0, 0, max x, max y);
+END PROC graphik;
+
+PROC begin plot :
+ control (modus code, resolution, 0, d);
+ is clear := TRUE;
+ENDPROC begin plot ;
+
+PROC end plot :
+ IF pause time > 0
+ THEN indicate end plot FI;
+ control (modus code, 3, 0, d) .
+
+indicate end plot:
+ control (pen code, full line, full line, d);
+ REP set indicator;
+ UNTIL incharety (pause time) <> "" PER .
+
+set indicator:
+ control (move code, 0, max y, d);
+ control (draw code, max x, max y, d) .
+
+ENDPROC end plot ;
+
+PROC clear:
+ INT VAR x0, x1, y0, y1;
+ new values (22.0, 13.7, max x, max y, x0, x1, y0, y1);
+ set range (x0, y0, x1, y1);
+ clear screen;
+ clear pen;
+ clear pos;
+ is clear := FALSE .
+
+clear screen:
+ IF is clear OR full screen
+ THEN control (modus code, resolution, 0, d)
+ ELSE draw frame;
+ clear frame
+ FI .
+
+full screen:
+ x0 < 10 AND x1 > (max x-10) AND
+ y0 < 10 AND y1 > (max y-10) .
+
+draw frame:
+ control (move code, x0, y0, d);
+ control (draw code, x1, y0, d);
+ control (draw code, x1, y1, d);
+ control (draw code, x0, y1, d);
+ control (draw code, x0, y0, d) .
+
+clear frame:
+ control (pen code, full line, 0, d);
+ FOR y FROM max y-y1 UPTO max y-y0
+ REP control (move code, x0, y, d);
+ control (draw code, x1, y, d);
+ PER .
+
+clear pen:
+ pen := PEN : (0, 1, 0, full line);
+ control (pen code, full line, 1, d) .
+
+clear pos:
+ old := POS : (x0, y0);
+ control (move code, x0, max y-y0, d) .
+
+END PROC clear;
+
+PROC set pen (INT CONST back, fore, thick, type):
+ set background;
+ set foreground and linetype;
+ set thickness .
+
+set background:
+ pen.back := back; (*Hintergrund über niederwertiges *)
+ control (back code, 0, back no, d) .(*Byte von colour code *)
+ (*Höherwetiges Byte regelt die *)
+back no: (*Farbpalette *)
+ IF back = 0
+ THEN std background
+ ELSE back FI .
+
+std background:
+ IF resolution = 4
+ THEN 16
+ ELSE 15 FI .
+
+set foreground and linetype: (*0, 1, 2, 3 Farben: löschend,*)
+ pen.fore := possible colour; (*ändernd oder überschreibend *)
+ pen.line := type; (* in allen Linientypen. *)
+ control (pen code, line (type), pen.fore, d) .
+
+possible colour:
+ IF fore <= full line
+ THEN full line
+ ELIF fore > 3 OR (fore > 1 AND resolution <> 4)
+ THEN 1
+ ELSE fore FI .
+
+set thickness:
+ pen.thick := thick DIV 10 .
+
+END PROC set pen;
+
+PROC get pen (INT VAR back, fore, thick, line):
+ back := pen.back;
+ fore := pen.fore;
+ thick := pen.thick;
+ line := pen.line
+END PROC get pen;
+
+INT PROC line (INT CONST type):
+ SELECT type OF
+ CASE 0: 0
+ CASE 1: full line
+ CASE 2: 21845
+ CASE 3: 3855
+ CASE 4: 255
+ CASE 5: 4351
+ OTHERWISE type END SELECT
+END PROC line;
+
+PROC int move (INT CONST x, y):
+ control (move code, x, max y-y, d);
+END PROC int move;
+
+PROC int draw (INT CONST x, y):
+ control (draw code, x, max y-y, d);
+END PROC int draw;
+
+PROC draw line (INT CONST from x, from y, to x, to y):
+ control (move code, from x, max y-from y, d);
+ clip (from x, from y, to x, to y, PROC int move, PROC int draw)
+END PROC draw line;
+
+PROC move (INT CONST x, y) :
+ control (move code, x, max y-y, d);
+ old := POS : (x, y)
+END PROC move;
+
+PROC draw (INT CONST x, y):
+ IF std thickness
+ THEN clip (old.x, old.y, x, y, PROC int move, PROC int draw)
+ ELSE thick (old.x, old.y, x, y, pen.thick, PROC (INT CONST, INT CONST, INT CONST, INT CONST) draw line) FI;
+ old := POS : (x, y) .
+
+std thickness: pen.thick = 0 .
+END PROC draw;
+
+PROC draw (TEXT CONST msg, REAL CONST angle, INT CONST height, width):
+ control (pen code, full line, pen.fore, d);
+ draw text (old.x, old.y, msg, angle, y size, x size,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST, INT CONST, INT CONST) draw char);
+ control (move code, old.x, max y-old.y, d);
+ control (pen code, line (pen.line), pen.fore, d) .
+
+x size: IF width = 0
+ THEN 6
+ ELSE width FI .
+y size: IF height = 0
+ THEN 10
+ ELSE height FI .
+
+END PROC draw;
+
+PROC draw char (INT CONST char, direction, x, y, INT CONST height, width):
+ draw char (char, x, y, width, height, direction,
+ PROC (INT CONST, INT CONST, INT CONST, INT CONST) draw line)
+END PROC draw char;
+
+PROC bar (INT CONST from x, from y, to x, to y, pattern):
+ control (pen code, full line, pen.fore, d);
+ bar (from x, from y, to x, to y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) draw line);
+ control (move code, old.x, max y-old.y, d);
+ control (pen code, line (pen.line), pen.fore, d) .
+END PROC bar;
+
+PROC circle (INT CONST x, y, rad, REAL CONST from, to, INT CONST pattern):
+ control (pen code, full line, pen.fore, d);
+ circle (x, y, rad, from, to, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) draw line);
+ control (move code, old.x, max y-old.y, d);
+ control (pen code, line (pen.line), pen.fore, d) .
+END PROC circle;
+
+PROC marker (INT CONST x, y, no, size):
+ control (pen code, full line, pen.fore, d);
+ draw char (no, 0, x, y, size, size);
+ control (move code, old.x, max y-old.y, d);
+ control (pen code, line (pen.line), pen.fore, d) .
+END PROC marker;
+
+PROC where (INT VAR x, y):
+ x := old.x; y := old.y
+END PROC where;
+
+END PACKET pc plot
+
diff --git a/graphic/ZEICHENSATZ b/graphic/ZEICHENSATZ
new file mode 100644
index 0000000..9866ec2
--- /dev/null
+++ b/graphic/ZEICHENSATZ
Binary files differ
diff --git a/graphic/gen Graphik b/graphic/gen Graphik
new file mode 100644
index 0000000..f70cc66
--- /dev/null
+++ b/graphic/gen Graphik
@@ -0,0 +1,16 @@
+TEXT VAR geraet;
+page;
+out ("Bitte den Namen der Hardwareanpassung (z.B. 'PC.plot') eingeben: ");
+get line (geraet);
+IF NOT exists (geraet)
+THEN errorstop ("Endgerät nicht vorhanden") FI;
+
+insert ("GRAPHIK.Picfile");
+insert ("GRAPHIK.Transform");
+insert (geraet);
+insert ("GRAPHIK.Plot");
+
+
+
+
+
diff --git a/graphic/gen Plotter b/graphic/gen Plotter
new file mode 100644
index 0000000..73d7b2f
--- /dev/null
+++ b/graphic/gen Plotter
@@ -0,0 +1,16 @@
+TEXT VAR geraet;
+page;
+out ("Bitte den Namen der Hardwareanpassung (z.B. 'PC.plot') eingeben: ");
+get line (geraet);
+IF NOT exists (geraet)
+THEN errorstop ("Endgerät nicht vorhanden") FI;
+
+insert ("GRAPHIK.Picfile");
+insert ("GRAPHIK.Transform");
+insert (geraet);
+insert ("GRAPHIK.Plotter");
+insert ("GRAPHIK.Server")
+
+
+
+
diff --git a/graphic/graphik editor b/graphic/graphik editor
new file mode 100644
index 0000000..7aa6e33
--- /dev/null
+++ b/graphic/graphik editor
@@ -0,0 +1,324 @@
+PACKET graphic editor DEFINES graphic, (*Autor: H.Indenbirken *)
+ picfile, picture, (*Stand: 26.02.1985 *)
+
+ neu zeichnen,
+
+ UP, DOWN, T,
+
+ pen, select pen, selected pen, background,
+ extrema pic, extrema picfile:
+
+
+
+LET norm cmd = ""1""27""3""10""9"epb"16"",
+ hop cmd = ""2""10""12""1"",
+ bell = ""7"",
+ esc = ""27"";
+
+PICFILE VAR p;
+PICTURE VAR pic;
+TEXT VAR command :: "", old command :: "", char, headline :: "";
+BOOL VAR within edit :: FALSE, new plot :: FALSE;
+ROW 3 ROW 2 REAL VAR size;
+ROW 2 ROW 2 REAL VAR limits;
+ROW 4 REAL VAR angles;
+ROW 2 REAL VAR oblique;
+ROW 3 REAL VAR perspective;
+
+PROC open graphic (TEXT CONST name, DATASPACE CONST ds):
+ p := ds;
+ get values (p, size, limits, angles, oblique, perspective);
+ head line := ""1""15"LEN ................................ DIM PEN .."14" Picture "15""14"";
+ replace (head line, 32-LENGTH name DIV 2, name);
+ new plot := TRUE;
+ within edit := TRUE
+END PROC open graphic;
+
+PROC graphic:
+ graphic (last param)
+END PROC graphic;
+
+PROC graphic (TEXT CONST name) :
+ IF NOT exists (name)
+ THEN IF yes ("Soll ein neuer Picfile eingerichtet werden")
+ THEN graphic (new (name), name) FI
+ ELSE graphic (old (name), name) FI
+
+END PROC graphic;
+
+PROC graphic (DATASPACE CONST f, TEXT CONST name) :
+ open graphic (name, f);
+ reset;
+ kommandos bearbeiten;
+ within edit := FALSE .
+
+kommandos bearbeiten :
+ REP IF new plot
+ THEN plot (p);
+ new plot := FALSE
+ FI;
+ read picture (p, pic);
+ out head line;
+ inchar (command);
+ do command
+ PER .
+
+out head line:
+ replace (headline, 7, text (length (pic), 5));
+ replace (headline, 50, text (dim (pic), 1));
+ replace (headline, 57, text (pen (pic), 2));
+ replace (headline, 72, text (picture no (p), 4));
+ out (head line) .
+
+do command:
+ SELECT pos (norm cmd, command) OF
+ CASE 1: hop commands
+ CASE 2: escape commands
+ CASE 3: position up
+ CASE 4: position down
+ CASE 5: position direct
+ CASE 6: extrema pic
+ CASE 7: selected pen (pen (pic));
+ CASE 8: out (1, 2, ""15""5"Hintergrundfarbe: " +
+ colour of (background (p)) + " "14"")
+ CASE 9: identify (pic);
+ OTHERWISE out (bell) ENDSELECT .
+
+position up :
+ IF is first picture (p)
+ THEN out (bell);
+ ELSE up (p) FI .
+
+position down :
+ IF eof (p)
+ THEN out (bell)
+ ELSE down (p) FI .
+
+position direct:
+ out (1, 68, "");
+ edit get (command, 4, 4);
+ to pic (p, int (command)) .
+
+hop commands :
+ inchar (command);
+ SELECT pos (hop cmd, command) OF
+ CASE 1: to first pic (p)
+ CASE 2: to eof (p)
+ CASE 3: delete picture (p);
+ IF NOT new plot
+ THEN erase (pic) FI
+ CASE 4: new plot := TRUE
+ OTHERWISE out (bell) ENDSELECT .
+
+escape commands :
+ inchar (command);
+ IF command = "q"
+ THEN LEAVE kommandos bearbeiten
+ ELIF command = "f"
+ THEN do (old command)
+ ELIF command = esc
+ THEN kommandomodus
+ ELSE do (kommando auf taste (command)) FI .
+
+END PROC graphic;
+
+PROC kommandomodus:
+ command := "";
+ disable stop;
+ REP get command;
+ do (command)
+ UNTIL command executed PER;
+
+ IF new values
+ THEN get values (size, limits, angles, oblique, perspective);
+ set values (p, size, limits, angles, oblique, perspective);
+ new plot := new plot OR new values
+ FI .
+
+get command:
+ REP out (1, 2, ""15"Gib Graphikkommando: ");
+ edit get (command, 0, 54, "", "k", char);
+ out (""14"");
+ out (1, 2, ""5"");
+
+ IF char = ""13""
+ THEN LEAVE get command
+ ELIF char = ""27"k"
+ THEN command := old command FI
+ PER .
+
+command executed:
+ IF is error
+ THEN out (1, 1, error message);
+ clear error;
+ FALSE
+ ELSE old command := command;
+ TRUE
+ FI .
+
+END PROC kommandomodus;
+
+PROC out (INT CONST x, y, TEXT CONST t):
+ cursor (x, y);
+ out (t)
+END PROC out;
+
+TEXT PROC colour of (INT CONST colour):
+ SELECT colour OF
+ CASE 0: "löschen"
+ CASE 1: "std"
+ CASE 2: "rot"
+ CASE 3: "blau"
+ CASE 4: "grün"
+ CASE 5: "schwarz"
+ CASE 6: "weiß"
+ OTHERWISE text (colour) ENDSELECT .
+END PROC colour of;
+
+TEXT PROC linetype of (INT CONST linetype):
+ SELECT linetype OF
+ CASE 0: "unsichtbar"
+ CASE 1: "durchgehend"
+ CASE 2: "gepunktet"
+ CASE 3: "kurz gestrichelt"
+ CASE 4: "lang gestrichelt"
+ CASE 5: "strichpunkt"
+ OTHERWISE text (linetype) ENDSELECT .
+END PROC linetype of;
+
+PICFILE PROC picfile :
+ IF NOT within edit
+ THEN errorstop ("Not within editmode") FI;
+ p
+END PROC picfile;
+
+PICTURE PROC picture :
+ IF NOT within edit
+ THEN errorstop ("Not within editmode") FI;
+ pic
+END PROC picture;
+
+PROC neu zeichnen:
+ new plot := TRUE
+END PROC neu zeichnen;
+
+OP UP (INT CONST distance):
+ up (p, distance);
+ read picture (p, pic)
+END OP UP;
+
+OP DOWN (INT CONST distance):
+ down (p, distance);
+ read picture (p, pic)
+END OP DOWN;
+
+OP T (INT CONST n):
+ to pic (p, n);
+ read picture (p, pic)
+END OP T;
+
+PROC pen (INT CONST n):
+ IF NOT new plot
+ THEN erase (pic) FI;
+
+ pen (pic, n);
+ write picture (p, pic);
+
+ IF NOT new plot
+ THEN show (pic) FI
+END PROC pen;
+
+PROC select pen (INT CONST n, colour, thickness, linetype, BOOL CONST hidden):
+ select pen (p, n, colour, thickness, linetype, hidden);
+ new plot := TRUE
+END PROC select pen;
+
+PROC select pen (INT CONST n, colour, thickness, linetype):
+ select pen (p, n, colour, thickness, linetype, FALSE);
+ new plot := TRUE
+END PROC select pen;
+
+PROC selected pen (INT CONST n, INT VAR colour, thickness, linetype,
+ BOOL VAR hidden):
+ selected pen (p, n, colour, thickness, linetype, hidden);
+END PROC selected pen;
+
+PROC selected pen (INT CONST n):
+ INT VAR colour, thickness, linetype;
+ BOOL VAR hidden;
+ selected pen (p, n, colour, thickness, linetype, hidden);
+ out (1, 2, ""5""15"PEN #" + text (n) + ": Farbe: " + colour of (colour) +
+ ", Dicke " + text (thickness) + ", Linientyp " + linetype of (linetype) +
+ hidden text + " "14"") .
+
+hidden text:
+ IF hidden
+ THEN ". "
+ ELSE ", nicht sichtbare Linien werden unterdrückt." FI .
+
+END PROC selected pen;
+
+INT PROC background:
+ background (p)
+END PROC background;
+
+PROC background (INT CONST n):
+ new plot := n <> background (p);
+ background (p, n)
+END PROC background;
+
+PROC extrema pic:
+ REAL VAR x min, x max, y min, y max, z min, z max;
+ IF dim (pic) = 2
+ THEN extrema (pic, x min, x max, y min, y max);
+ out (1, 2, ""5""15"Extrema: [" + text (x min) + "," + text (x max) +
+ "] [" + text (y min) + "," + text (y max) + "] "14"")
+ ELSE extrema (pic, x min, x max, y min, y max, z min, z max);
+ out (1, 2, ""5""15"Extrema: [" + text (x min) + "," + text (x max) +
+ "] [" + text (y min) + "," + text (y max) +
+ "] [" + text (z min) + "," + text (z max) +"] "14"")
+ FI
+END PROC extrema pic;
+
+PROC extrema picfile:
+ REAL VAR x min, x max, y min, y max, z min, z max;
+ extrema (p, x min, x max, y min, y max, z min, z max);
+ out (1, 2, ""5""15"Extrema: [" + text (x min) + "," + text (x max) +
+ "] [" + text (y min) + "," + text (y max) +
+ "] [" + text (z min) + "," + text (z max) +"] "14"")
+END PROC extrema picfile;
+
+PROC identify (PICTURE CONST pic):
+ begin plot;
+ hidden lines (TRUE);
+ pen (background (p), 1, 1, 2);
+ plot (pic);
+ end plot
+END PROC identify;
+
+PROC erase (PICTURE CONST pic):
+ INT VAR colour, thickness, linetype;
+ BOOL VAR hidden;
+
+ selected pen (p, pen (pic), colour, thickness, linetype, hidden);
+ begin plot;
+ hidden lines (TRUE);
+ pen (background (p), 0, thickness, linetype);
+ plot (pic);
+ end plot
+END PROC erase;
+
+PROC show (PICTURE CONST pic):
+ INT VAR colour, thickness, linetype;
+ BOOL VAR hidden;
+
+ selected pen (p, pen (pic), colour, thickness, linetype, hidden);
+ begin plot;
+ hidden lines (TRUE);
+ pen (background (p), colour, thickness, linetype);
+ plot (pic);
+ end plot
+END PROC show;
+
+END PACKET graphic editor;
+
diff --git a/hamster/ls-Herbert und Robbi 1 b/hamster/ls-Herbert und Robbi 1
new file mode 100644
index 0000000..ed19e98
--- /dev/null
+++ b/hamster/ls-Herbert und Robbi 1
@@ -0,0 +1,84 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-Herbert und Robbi 1 **
+ ** **
+ ** Version 1.1 **
+ ** **
+ ** (Stand: 30.03.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls herbert und robbi 1 DEFINES{} sei ein hamster, ist hamster,{} sei ein roboter, ist roboter,{} landschaft, arbeitsfeld,{} vor, links um, nimm, gib,{} korn da, werkstueck da,{} backen leer, behaelter leer,{} vorn frei, lauf,{} hamsterinter, roboterinter,{} geschwindigkeit, taste,{} befehlssatz erweitern,{} befehlssatz ist erweitert,{} drucke landschaft,{} hamster druckerstart einstellen,{} hamster drucker xstart,{}
+ hamster drucker ystart,{} hamster landschaftsschrifttyp einstellen,{} hamster landschaftsschrifttyp,{} druckereinstellung fuer flaechenausdruck,{} landschaftsauskunftstext,{} testauskunftstext 1, testauskunftstext 2,{} befehlsauskunftstext, laufauskunftstext,{} kommandomodus, hamstermodus,{} zeige landschaft, lege landschaft ab:{}TYPE LOCATION = STRUCT (INT x, y);{}LET menukarte = "ls-MENUKARTE:Herbert und Robbi",{} richtung = ""3""8""10""2"",{}
+ erscheinungsform = "A<V>",{} praefix = "Flaeche:",{} flaechentype = 1007,{} neutral = 0,{} erzeuge = 1,{} hamsterlauf = 2,{} interaktiv = 3,{} kommandostufe = 99,{} west = ""8"",{} ost = ""2"",{} cleol = ""5"",{} piep = ""7"",{}
+ mark ein = ""15"",{} mark aus = ""14"",{} escape = ""27"",{} blank = " ",{} niltext = "",{} hindernis = "#",{} korn = "o",{} hinderniskachel = "##",{} blankkachel = " .",{} kornkachel = " o",{} protokollname = "PROTOKOLL";{}LET max x = 40,{}
+ max y = 23;{}LET FLAECHE = ROW max x ROW max y INT;{}LET LANDSCHAFT = STRUCT (INT xpos, ypos, blickrichtung,{} anzahl koerner, FLAECHE flaeche);{}LET HAMSTER = STRUCT (LOCATION stelle, INT koerner, form);{}BOUND LANDSCHAFT VAR aktuelle landschaft;{}FLAECHE VAR land;{}HAMSTER VAR hamster;{}FILE VAR protokoll;{}INT CONST besetzt :: -1,{} frei :: 0;{}
+TEXT CONST kornsymbole ::{} "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";{}INT CONST maxkornzahl :: LENGTH kornsymbole;{}BOOL VAR hamster eingestellt :: TRUE,{} befehlssatz erweitert :: FALSE;{}TEXT VAR eingabezeichen :: niltext,{} archivlandschaftsname :: niltext,{} hinderniszeichen :: "\#\#",{} schrifttyp :: niltext;{}INT VAR verzoegerungsfaktor :: 5,{}
+ modus :: kommandostufe,{} a, b, c, d;{}REAL VAR xstart :: 0.0,{} ystart :: 0.0;{}WINDOW VAR fenster :: window (1, 1, 79, 24);{}INITFLAG VAR in this task :: FALSE;{}OP := (LOCATION VAR l, LOCATION CONST r):{} l.x := r.x; l.y := r.y{}END OP :=;{}PROC initialize hamstersystem:{} IF NOT initialized (in this task){} THEN install menu (menukarte);{} FI{}END PROC initialize hamstersystem;{}
+PROC sei ein hamster:{} hamster eingestellt := TRUE{}END PROC sei ein hamster;{}BOOL PROC ist hamster:{} hamster eingestellt{}END PROC ist hamster;{}PROC sei ein roboter:{} hamster eingestellt := FALSE{}END PROC sei ein roboter;{}BOOL PROC ist roboter:{} NOT hamster eingestellt{}END PROC ist roboter;{}PROC hole landschaft (TEXT CONST name):{} aktuelle landschaft := old (praefix + name);{} land := aktuelle landschaft.flaeche;{} hamster.form := aktuelle landschaft.blickrichtung;{}
+ hamster.stelle.x := aktuelle landschaft.xpos;{} hamster.stelle.y := aktuelle landschaft.ypos;{} hamster.koerner := aktuelle landschaft.anzahl koerner{}END PROC hole landschaft;{}PROC lege landschaft ab (TEXT CONST name):{} IF exists (praefix + name){} THEN forget (praefix + name, quiet){} FI;{} aktuelle landschaft := new (praefix + name);{} aktuelle landschaft.flaeche := land;{} aktuelle landschaft.blickrichtung := hamster.form;{} aktuelle landschaft.xpos := hamster.stelle.x;{}
+ aktuelle landschaft.ypos := hamster.stelle.y;{} aktuelle landschaft.anzahl koerner := hamster.koerner;{} type( old(praefix + name), flaechentype){}END PROC lege landschaft ab;{}PROC hamstermodus:{} modus := neutral{}END PROC hamstermodus;{}PROC kommandomodus:{} modus := kommandostufe{}END PROC kommandomodus;{}PROC erzeugemodus:{} modus := erzeuge{}END PROC erzeugemodus;{}PROC intermodus:{} modus := interaktiv{}END PROC intermodus;{}PROC laufmodus:{} modus := hamsterlauf{}
+END PROC laufmodus;{}BOOL PROC vorn frei:{} kontrolliere modus;{} LOCATION VAR hier :: hamster.stelle;{} SELECT hamster.form OF{} CASE 1: IF hamster.stelle.y < 2 THEN protestiere FI;{} hier.y DECR 1{} CASE 2: IF hamster.stelle.x < 2 THEN protestiere FI;{} hier.x DECR 1{} CASE 3: IF hamster.stelle.y >= max y THEN protestiere FI;{} hier.y INCR 1{} CASE 4: IF hamster.stelle.x >= max x THEN protestiere FI;{} hier.x INCR 1{} OTHERWISE modus := kommandostufe;{}
+ IF ist hamster{} THEN errorstop(nachricht( 7)){} ELSE errorstop(nachricht(14)){} FI{} END SELECT;{} IF modus = erzeuge{} THEN TRUE{} ELSE land[hier.x] [hier.y] <> besetzt{} FI{}END PROC vorn frei;{}BOOL PROC korn da:{} kontrolliere modus;{} kornzahl > 0{}END PROC korn da;{}INT PROC kornzahl:{} land [hamster.stelle.x] [hamster.stelle.y]{}END PROC kornzahl;{}BOOL PROC werkstueck da:{} korn da{}END PROC werkstueck da;{}BOOL PROC backen leer:{}
+ kontrolliere modus;{} hamster.koerner <= 0 AND (modus = hamsterlauf OR modus = interaktiv){}END PROC backen leer;{}BOOL PROC behaelter leer:{} backen leer{}END PROC behaelter leer;{}PROC protestiere:{} IF modus = erzeuge{} THEN out(piep); eins zurueck{} ELSE verzoegere 10 mal; zeige("X"); verzoegere 10 mal;{} kommandomodus;{} IF ist hamster{} THEN errorstop(nachricht( 6)){} ELSE errorstop(nachricht(13)){} FI;{} FI.{} eins zurueck:{}
+ SELECT hamster.form OF{} CASE 1: hamster.stelle.y INCR 1{} CASE 2: hamster.stelle.x INCR 1{} CASE 3: hamster.stelle.y DECR 1{} CASE 4: hamster.stelle.x DECR 1{} OTHERWISE kommandomodus;{} IF ist hamster{} THEN errorstop(nachricht( 7)){} ELSE errorstop(nachricht(14)){} FI;{} END SELECT.{} verzoegere 10 mal:{} INT VAR j;{} FOR j FROM 1 UPTO 10 REP{} verzoegere{} PER{}END PROC protestiere;{}
+PROC verzoegere:{} IF modus <> hamsterlauf{} THEN LEAVE verzoegere{} FI;{} eingabezeichen := incharety (verzoegerungsfaktor);{} IF eingabezeichen = escape{} THEN kommandomodus;{} IF ist hamster{} THEN errorstop(nachricht( 4)){} ELSE errorstop(nachricht(11)){} FI{} ELIF eingabezeichen = "-" THEN verlangsame{} ELIF eingabezeichen = "+" THEN beschleunige{} ELIF eingabezeichen = "?" THEN boxinfo (fenster, laufauskunftstext,{} 5, maxint, a, b, c, d);{}
+ cursor on; zeige landschaft{} ELIF pos ("0123456789", eingabezeichen) > 0{} THEN geschwindigkeit (int (eingabezeichen)){} FI.{} verlangsame:{} IF verzoegerungsfaktor > 31 THEN (* lass es dabei *){} ELIF verzoegerungsfaktor < 1{} THEN verzoegerungsfaktor INCR 1{} ELSE verzoegerungsfaktor INCR verzoegerungsfaktor{} FI.{} beschleunige:{} IF verzoegerungsfaktor < 1{} THEN verzoegerungsfaktor := -1{} ELSE verzoegerungsfaktor := verzoegerungsfaktor DIV 2{}
+ FI{}END PROC verzoegere;{}PROC geschwindigkeit (INT CONST faktor):{} SELECT faktor OF{} CASE 0 : verzoegerungsfaktor := 20000;{} CASE 1 : verzoegerungsfaktor := 50;{} CASE 2 : verzoegerungsfaktor := 20;{} CASE 3 : verzoegerungsfaktor := 10;{} CASE 4 : verzoegerungsfaktor := 8;{} CASE 5 : verzoegerungsfaktor := 5;{} CASE 6 : verzoegerungsfaktor := 2;{} CASE 7 : verzoegerungsfaktor := 1;{} CASE 8 : verzoegerungsfaktor := 0;{} CASE 9 : verzoegerungsfaktor := -1;{}
+ OTHERWISE (*belasse es dabei*){} END SELECT{}END PROC geschwindigkeit;{}PROC vor:{} kontrolliere modus;{} IF vorn frei{} THEN zeige(kachel);{} bilde neue hamsterkoordinaten;{} zeige(erscheinungsform SUB hamster.form);{} verzoegere{} ELSE modus := kommandostufe;{} zeige("X");{} IF ist hamster{} THEN errorstop(nachricht(1)){} ELSE errorstop(nachricht(8)){} FI{} FI.{} kachel:{} INT CONST z :: land [hamster.stelle.x] [hamster.stelle.y];{}
+ IF z = besetzt THEN hinderniskachel{} ELIF z = frei THEN blankkachel{} ELSE kornkachel{} FI.{} bilde neue hamsterkoordinaten:{} SELECT hamster.form OF{} CASE 1 :hamster.stelle.y DECR 1{} CASE 2 :hamster.stelle.x DECR 1{} CASE 3 :hamster.stelle.y INCR 1{} CASE 4 :hamster.stelle.x INCR 1{} OTHERWISE modus:=kommandostufe;{} IF ist hamster{} THEN errorstop(nachricht( 7)){} ELSE errorstop(nachricht(14)){}
+ FI{} END SELECT.{}END PROC vor;{}PROC nimm:{} kontrolliere modus;{} IF korn da{} THEN variiere kornzahl (-1);{} IF kornzahl < 1 THEN zeige (ost + blank) FI{} ELSE modus := kommandostufe;{} zeige("X");{} IF ist hamster{} THEN errorstop(nachricht(2)){} ELSE errorstop(nachricht(9)){} FI{} FI;{} verzoegere{}END PROC nimm;{}PROC gib:{} kontrolliere modus;{} IF backen leer{} THEN modus := kommandostufe;{} zeige ("X");{}
+ IF ist hamster{} THEN errorstop(nachricht( 3)){} ELSE errorstop(nachricht(10)){} FI{} ELSE variiere kornzahl (+1);{} zeige(ost + korn){} FI;{} verzoegere{}END PROC gib;{}PROC links um:{} kontrolliere modus;{} hamster.form := hamster.form MOD 4 + 1;{} (* da hamster.form der Werte 1,2,3,4 faehig ist und linksdreht *){} zeige (subjekt);{} verzoegere.{} subjekt:{} erscheinungsform SUB hamster.form.{}END PROC links um;{}PROC variiere kornzahl (INT CONST delta):{}
+ IF delta * delta <> 1{} THEN LEAVE variiere kornzahl{} FI; (* als delta kommen nur +1 und -1 vor *){} INT VAR k;{} IF kornzahl = -1 AND delta = 1{} THEN k := 1{} ELSE k := kornzahl + delta{} FI;{} IF k <= 0{} THEN land [hamster.stelle.x] [hamster.stelle.y] := frei{} ELSE land [hamster.stelle.x] [hamster.stelle.y] := min (k,maxkornzahl){} FI;{} IF modus = hamsterlauf OR modus = interaktiv{} THEN hamster.koerner DECR delta{} FI{}END PROC variiere kornzahl;{}PROC kontrolliere modus:{}
+ initialize hamstersystem;{} SELECT modus OF{} CASE neutral : erzeugemodus;{} landschaft;{} laufmodus{} CASE erzeuge,{} interaktiv,{} hamsterlauf: (* nichts *){} OTHERWISE kommandomodus;{} line;{} IF ist hamster{} THEN sage(anwendungstext (21));pause(20);{} errorstop(nachricht( 5)){} ELSE sage(anwendungstext (22));pause(20);{}
+ errorstop(nachricht(12)){} FI{} END SELECT{}END PROC kontrolliere modus;{}PROC zeige (TEXT CONST was):{} cursor (2 * hamster.stelle.x - 1, hamster.stelle.y);{} IF hamster.stelle.x >= max x AND hamster.stelle.y > max y{} THEN out ((was SUB 1)); out(west){} ELSE out(was); (LENGTH was) TIMESOUT west{} FI.{}END PROC zeige;{}PROC sage (TEXT CONST aussage):{} cursor(1,24); out(aussage + cleol){}END PROC sage;{}TEXT PROC nachricht (INT CONST nummer):{}
+ inv (text (anwendungstext (nummer), 65)) + piep{}END PROC nachricht;{}TEXT PROC inv (TEXT CONST text):{} TEXT VAR aus :: mark ein + text + blank + mark aus;{} aus{}END PROC inv;{}PROC zeige landschaft:{} initialize hamstersystem;{} INT VAR y;{} FOR y FROM 1 UPTO max y REP{} setze zeile zusammen;{} cursor (1,y); out (zeile){} PER;{} cursor(1,24); out(cleol);{} IF modus = interaktiv{} THEN gib befehlszeile aus{} FI;{} zeige hamster; cursor on.{} setze zeile zusammen:{} TEXT VAR zeile :: niltext;{}
+ INT VAR x;{} FOR x FROM 1 UPTO max x REP{} zeile CAT kachel{} PER.{} kachel:{} INT CONST z :: land [x] [y];{} IF z = besetzt THEN hinderniskachel{} ELIF z = frei THEN blankkachel{} ELSE kornkachel{} FI.{} gib befehlszeile aus:{} cursor(1,1); write(cleol); write (anwendungstext (62)){}END PROC zeige landschaft;{}PROC zeige hamster:{} zeige (erscheinungsform SUB hamster.form){}END PROC zeige hamster;{}PROC landschaft (TEXT CONST kandidat):{}
+ initialize hamstersystem;{} archivlandschaftsname := kandidat;{} IF exists (praefix + kandidat){} CAND type (old (praefix + kandidat)) = flaechentype{} THEN behandle existierende landschaft{} ELIF exists (praefix + kandidat){} THEN forget (praefix + kandidat, quiet);{} behandle neue landschaft{} ELSE behandle neue landschaft{} FI.{} behandle existierende landschaft:{} hole landschaft (kandidat);{} SELECT modus OF{} CASE hamsterlauf,{} interaktiv,{}
+ neutral : zeige landschaft;{} laufmodus{} CASE erzeuge : modifiziere eventuell{} CASE kommandostufe : modifiziere landschaft{} OTHERWISE errorstop (anwendungstext (15)){} END SELECT.{} behandle neue landschaft:{} SELECT modus OF{} CASE hamsterlauf,{} interaktiv,{} neutral,{} erzeuge : erschaffe landschaft;{} modifiziere landschaft;{} zeige landschaft;{}
+ laufmodus{} CASE kommandostufe : erschaffe landschaft;{} modifiziere landschaft;{} OTHERWISE errorstop (anwendungstext (15)){} END SELECT.{} modifiziere eventuell:{} IF ist hamster{} THEN IF boxyes (fenster, anwendungstext (41), 5, a, b, c, d){} THEN cursor on; modifiziere landschaft{} FI{} ELSE IF boxyes (fenster, anwendungstext (42), 5, a, b, c, d){} THEN cursor on; modifiziere landschaft{}
+ FI{} FI;{} zeige landschaft.{} erschaffe landschaft:{} INT VAR j;{} FOR j FROM 1 UPTO max y REP{} INT VAR k;{} FOR k FROM 1 UPTO max x REP{} land [k] [j] := frei{} PER{} PER;{} hamster.form := 4;{} hamster.stelle.x := 20;{} hamster.stelle.y := 12;{} hamster.koerner := 0.{}END PROC landschaft;{}PROC landschaft:{} initialize hamstersystem;{} IF ist hamster{} THEN landschaft (erfragter landschaftsname (anwendungstext (36))){}
+ ELSE landschaft (erfragter landschaftsname (anwendungstext (37))){} FI{}END PROC landschaft;{}TEXT PROC erfragter landschaftsname (TEXT CONST satz):{} TEXT VAR landschaftsname :: archivlandschaftsname;{} REP{} page; line (3); out (satz + cleol); line (2);{} editget (landschaftsname);{} landschaftsname := compress (landschaftsname);{} IF landschaftsname = niltext{} THEN line (2); out (anwendungstext (18) + piep);{} line (2); out (anwendungstext (38)); pause{} FI{}
+ UNTIL landschaftsname <> niltext PER;{} landschaftsname{}END PROC erfragter landschaftsname;{}PROC arbeitsfeld (TEXT CONST kandidat):{} landschaft (kandidat){}END PROC arbeitsfeld;{}PROC arbeitsfeld:{} landschaft{}END PROC arbeitsfeld;{}PROC modifiziere landschaft:{} INT CONST modalibi :: modus;{} erzeugemodus;{} zeige landschaft;{} informiere;{} zeige hamster;{} nimm ein eingabezeichen;{} WHILE nicht endewunsch REP{} erfuelle fortschreibungswunsch;{} nimm ein eingabezeichen{} PER;{}
+ erfrage koernerzahl;{} lege landschaft ab (archivlandschaftsname);{} modus := modalibi.{} nimm ein eingabezeichen:{} inchar (eingabezeichen).{} nicht endewunsch:{} pos ("hH", eingabezeichen) = 0.{} erfuelle fortschreibungswunsch:{} INT CONST r :: pos (richtung, eingabezeichen){} IF r > 0{} THEN IF hamster.form = r{} THEN vor{} ELSE hamster.form := r;{} zeige hamster{} FI{} ELIF eingabezeichen = "?" THEN boxinfo (fenster, landschaftsauskunftstext,{}
+ 5, maxint, a, b, c, d);{} cursor on; zeige landschaft; informiere{} ELIF eingabezeichen = "k" THEN kopiere landschaft;{} zeige landschaft; informiere{} ELIF eingabezeichen = "g" THEN gib{} ELIF eingabezeichen = "n" THEN IF korn da THEN nimm ELSE out (piep) FI{} ELIF eingabezeichen = "z" THEN zeige (text (kornzahl, 2)){} ELIF eingabezeichen = hindernis{} THEN land [hamster.stelle.x] [hamster.stelle.y] := besetzt; vor{}
+ ELIF eingabezeichen = blank{} THEN land [hamster.stelle.x] [hamster.stelle.y] := frei; vor{} ELSE out (piep){} FI.{} kopiere landschaft:{} TEXT VAR kopie;{} IF NOT not empty (alle landschaften){} THEN IF ist hamster{} THEN boxinfo (fenster, anwendungstext (196), 5, maxint){} ELSE boxinfo (fenster, anwendungstext (197), 5, maxint){} FI{} ELSE lasse original auswaehlen{} FI.{} lasse original auswaehlen:{}
+ IF ist hamster{} THEN kopie := boxone (fenster, alle landschaften,{} anwendungstext (23), anwendungstext (24),{} FALSE){} ELSE kopie := boxone (fenster, alle landschaften,{} anwendungstext (25), anwendungstext (26),{} FALSE){} FI;{} cursor on; hole landschaft (kopie).{} alle landschaften:{} ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix).{}
+ erfrage koernerzahl:{} TEXT VAR eingabe; BOOL VAR ist ok; INT VAR zahl;{} cursor (1,23); 79 TIMESOUT waagerecht;{} REP{} ist ok := TRUE;{} IF ist hamster{} THEN eingabe := boxanswer (fenster, anwendungstext (43),{} text (hamster.koerner),{} 5, a, b, c, d){} ELSE eingabe := boxanswer (fenster, anwendungstext (44),{} text (hamster.koerner),{}
+ 5, a, b, c, d){} FI;{} disable stop;{} IF eingabe = "" THEN eingabe := "0" FI;{} zahl := int (eingabe);{} IF zahl < 0 OR zahl > maxint THEN ist ok := FALSE FI;{} IF is error THEN ist ok := FALSE; clear error FI;{} enable stop;{} UNTIL last conversion ok AND ist ok PER;{} cursor on;{} hamster.koerner := zahl.{} informiere:{} cursor (1,1);{} IF ist hamster{} THEN out (anwendungstext (27)){}
+ ELSE out (anwendungstext (28)){} FI{}END PROC modifiziere landschaft;{}PROC lauf (TEXT CONST dateiname):{} initialize hamstersystem;{} IF NOT exists (dateiname){} THEN errorstop (anwendungstext (16) + dateiname + anwendungstext (17)){} FI;{} hamstermodus;{} disable stop;{} run (dateiname);{} kommandomodus;{} cursor (1, 24);{} IF is error{} THEN IF length (errormessage) > 1{} THEN sage (errormessage); pause;{} FI{} ELSE sage (anwendungstext (29)); pause; konserviere landschaft{}
+ FI;{} clear error;{} enable stop{}END PROC lauf;{}PROC lauf:{} lauf (last param){}END PROC lauf;{}PROC konserviere landschaft:{} TEXT VAR neuer landschaftsname;{} IF ist hamster{} THEN stelle landschaftsfrage{} ELSE stelle arbeitsfeldfrage{} FI; cursor on.{} stelle landschaftsfrage:{} IF boxyes (fenster, anwendungstext (45), 5){} THEN bewahre landschaft auf{} FI.{} stelle arbeitsfeldfrage:{} IF boxyes (fenster, anwendungstext (46), 5){} THEN bewahre landschaft auf{}
+ FI.{} bewahre landschaft auf:{} neuer landschaftsname := archivlandschaftsname + ".x";{} lege landschaft ab (neuer landschaftsname);{} gib hinweis auf neuen namen.{} gib hinweis auf neuen namen:{} IF ist hamster{} THEN boxinfo (fenster, anwendungstext (30){} + inv (neuer landschaftsname), 5, maxint, a, b, c, d){} ELSE boxinfo (fenster, anwendungstext (31){} + inv (neuer landschaftsname), 5, maxint, a, b, c, d){} FI{}END PROC konserviere landschaft;{}
+PROC hamsterinter (TEXT CONST landschaftsname):{} initialize hamstersystem;{} sei ein hamster;{} steuere interaktiv (landschaftsname);{} cursor on{}END PROC hamsterinter;{}PROC hamsterinter:{} initialize hamstersystem;{} hamsterinter (erfragter landschaftsname (anwendungstext (39))){}END PROC hamsterinter;{}PROC roboterinter (TEXT CONST landschaftsname):{} initialize hamstersystem;{} sei ein roboter;{} steuere interaktiv (landschaftsname);{} cursor on{}END PROC roboterinter;{}PROC roboterinter:{}
+ initialize hamstersystem;{} roboterinter (erfragter landschaftsname (anwendungstext (40))){}END PROC roboterinter;{}PROC steuere interaktiv (TEXT CONST landschaftsname):{} forget (protokollname, quiet);{} protokoll := sequential file (output, protokollname);{} intermodus;{} landschaft (landschaftsname);{} TEXT VAR befehl :: niltext, letzter befehl :: niltext;{} REP{} arbeiten{} PER.{} arbeiten:{} intermodus;{} hole befehl;{} fuehre befehl aus.{} hole befehl:{} TEXT VAR befehlszeichen;{}
+ TEXT CONST befehlskette :: "vlngpeVLNGPE";{} INT VAR befehlsposition;{} zeige (hamsterform);{} cursor (1,24);{} IF ist hamster{} THEN out (cleol + anwendungstext (32) + letzter befehl){} ELSE out (cleol + anwendungstext (33) + letzter befehl){} FI;{} cursor(24,24);{} inchar (befehlszeichen);{} befehlsposition := pos(befehlskette,befehlszeichen);{} IF befehlsposition = 0{} THEN out(piep);{} LEAVE arbeiten{} FI;{} SELECT befehlsposition OF{}
+ CASE 1, 7: befehl := "vor";{} out("vor");{} letzter befehl := "vor"{} CASE 2, 8: befehl := "links um";{} out("links um");{} letzter befehl := "links um"{} CASE 3, 9: befehl := "nimm";{} out("nimm");{} letzter befehl := "nimm"{} CASE 4,10: befehl := "gib";{} out("gib");{} letzter befehl := "gib"{}
+ CASE 5,11: out("protokoll");{} letzter befehl := "protokoll";{} FILE VAR p :: sequential file (modify,protokollname);{} headline(p, protokollname + " (Verlassen: <ESC><q>)");{} cursor on; show(p); cursor off;{} zeige landschaft; befehl := "";{} output(protokoll);{} LEAVE arbeiten{} CASE 6,12: out("ende"); kommandomodus; befehl := "";{} LEAVE steuere interaktiv{}
+ END SELECT.{} hamsterform:{} erscheinungsform SUB hamster.form.{} fuehre befehl aus:{} BOOL VAR korrekt;{} disable stop;{} do (befehl);{} cursor (1,24);{} korrekt := NOT is error;{} IF is error{} THEN IF errormessage > ""{} THEN out (inv (text (errormessage, 65)) + piep);{} pause(30);{} FI;{} clear error{} FI;{} IF korrekt AND befehl <> ""{} THEN protokolliere (befehl){} FI;{} enable stop;{}
+END PROC steuere interaktiv;{}PROC protokolliere (TEXT CONST befehl):{} putline (protokoll, befehl + ";"){}END PROC protokolliere;{}PROC drucke landschaft (TEXT CONST landschaftsname):{} initialize hamstersystem;{} ROW max y TEXT VAR drucklandschaft;{} BOUND LANDSCHAFT VAR al;{} INT VAR i, hamsterx, hamstery;{} TEXT VAR hamsterzeichen;{} landschaftsdatei holen;{} drucklandschaft erzeugen;{} hamster in drucklandschaft einsetzen;{} druckdatei erzeugen;{} disable stop;{} TEXT VAR datname := std;{}
+ do ("print (""druckdatei"")");{} IF is error{} THEN menuinfo (inv (errormessage));{} clear error;{} FI;{} last param (datname);{} enable stop;{} druckdatei loeschen;{} cursor on.{} landschaftsdatei holen:{} IF exists (praefix + landschaftsname) AND{} (type (old (praefix + landschaftsname)) = flaechentype){} THEN hole landschaft;{} ELSE LEAVE drucke landschaft{} FI.{} hole landschaft:{} al := old (praefix + landschaftsname);{} hamsterx := al.xpos;{}
+ hamstery := al.ypos;{} hamsterzeichen := erscheinungsform SUB al.blickrichtung.{} drucklandschaft erzeugen:{} TEXT VAR zeile; INT VAR x;{} FOR i FROM 1 UPTO max y REP{} zeile := "";{} FOR x FROM 1 UPTO maxx REP{} zeile erzeugen{} PER;{} drucklandschaft[i] := zeile{} PER.{} zeile erzeugen:{} INT CONST zeichen :: al.flaeche [x] [i];{} IF zeichen = besetzt THEN zeile CAT hinderniszeichen{} ELIF zeichen = frei THEN zeile CAT " ."{}
+ ELSE zeile CAT " o"{} FI.{} hamster in drucklandschaft einsetzen:{} change (drucklandschaft [hamstery], hamsterx*2-1, hamsterx*2-1,{} hamsterzeichen).{} druckdatei erzeugen:{} FILE VAR p::sequential file(output, "druckdatei");{} INT VAR blankzahl;{} line(p);{} putline(p,"#type (""" + schrifttyp + """)#");{} putline(p,"#start(" + text(xstart) + "," + text(ystart) + ")#");{} putline(p,"#limit(20.8)#");{} blankzahl := ( 80 - (8 + length (landschaftsname))) DIV 2;{}
+ putline(p, blankzahl * " " + praefix + landschaftsname + " ");{} putline(p, "  ");{} FOR i FROM 1 UPTO maxy REP{} putline(p, drucklandschaft[i] + " "){} PER.{} druckdatei loeschen:{} forget("druckdatei", quiet){}END PROC drucke landschaft;{}PROC drucke landschaft:{} initialize hamstersystem;{} IF ist hamster{} THEN drucke landschaft (erfragter landschaftsname (anwendungstext (36))){} ELSE drucke landschaft (erfragter landschaftsname (anwendungstext (37))){} FI;{} cursor on{}
+END PROC drucke landschaft;{}PROC druckereinstellung fuer flaechenausdruck:{} initialize hamstersystem;{} page;{} IF ist hamster{} THEN putline (center (invers (anwendungstext (71)))){} ELSE putline (center (invers (anwendungstext (72)))){} FI;{} line (3);{} put (anwendungstext (73));{} editget (schrifttyp);{} line (2);{} schrifttyp := compress (schrifttyp);{} putline (anwendungstext (74));{} putline (anwendungstext (75)); line (2);{} putline (anwendungstext (76) + text (xstart) + "," + text (ystart) +{}
+ anwendungstext (77)); line;{} put (anwendungstext (78)); get (xstart); line;{} put (anwendungstext (79)); get (ystart); line (2);{} IF yes (anwendungstext (80) + hinderniszeichen + anwendungstext (81)){} THEN line;{} put (anwendungstext (82)); inchar (hinderniszeichen); line (2);{} hinderniszeichen CAT hinderniszeichen;{} IF hinderniszeichen = "##"{} THEN hinderniszeichen := "\#\#"{} FI{} FI;{} line;{} put (anwendungstext (83)){}END PROC druckereinstellung fuer flaechenausdruck;{}
+PROC hamster druckerstart einstellen (REAL CONST xpos, ypos):{} xstart := xpos; ystart := ypos{}END PROC hamster druckerstart einstellen;{}REAL PROC hamster drucker xstart:{} xstart{}END PROC hamster drucker xstart;{}REAL PROC hamster drucker ystart:{} ystart{}END PROC hamster drucker ystart;{}PROC hamster landschaftsschrifttyp einstellen (TEXT CONST typ):{} schrifttyp := typ{}END PROC hamster landschaftsschrifttyp einstellen;{}TEXT PROC hamster landschaftsschrifttyp:{} schrifttyp{}END PROC hamster landschaftsschrifttyp;{}
+PROC drucke arbeitsfeld (TEXT CONST arbeitsfeldname):{} drucke landschaft (arbeitsfeldname){}END PROC drucke arbeitsfeld;{}PROC drucke arbeitsfeld:{} drucke landschaft{}END PROC drucke arbeitsfeld;{}TEXT PROC taste:{} eingabezeichen{}END PROC taste;{}TEXT PROC landschaftsauskunftstext:{} initialize hamstersystem;{} IF ist hamster{} THEN anwendungstext (52){} ELSE anwendungstext (53){} FI{}END PROC landschaftsauskunftstext;{}TEXT PROC laufauskunftstext:{} initialize hamstersystem;{}
+ anwendungstext (51){}END PROC laufauskunftstext;{}TEXT PROC befehlsauskunftstext:{} initialize hamstersystem;{} IF ist hamster{} THEN anwendungstext (54){} ELSE anwendungstext (55){} FI{}END PROC befehlsauskunftstext;{}TEXT PROC testauskunftstext 1:{} initialize hamstersystem;{} IF befehlssatz erweitert{} THEN langer testauskunftstext{} ELSE kurzer testauskunftstext{} FI.{} kurzer testauskunftstext:{} IF ist hamster{} THEN anwendungstext (56){} ELSE anwendungstext (57){}
+ FI.{} langer testauskunftstext:{} IF ist hamster{} THEN anwendungstext (58){} ELSE anwendungstext (60){} FI.{}END PROC testauskunftstext 1;{}TEXT PROC testauskunftstext 2:{} initialize hamstersystem;{} IF befehlssatz erweitert{} THEN eintragung{} ELSE niltext{} FI.{} eintragung:{} IF ist hamster{} THEN anwendungstext (59){} ELSE anwendungstext (61){} FI{}END PROC testauskunftstext 2;{}PROC befehlssatz erweitern (BOOL CONST status):{} befehlssatz erweitert := status{}
+END PROC befehlssatz erweitern;{}BOOL PROC befehlssatz ist erweitert:{} befehlssatz erweitert{}END PROC befehlssatz ist erweitert;{}END PACKET ls herbert und robbi 1;{}
+
diff --git a/hamster/ls-Herbert und Robbi 2 b/hamster/ls-Herbert und Robbi 2
new file mode 100644
index 0000000..7394932
--- /dev/null
+++ b/hamster/ls-Herbert und Robbi 2
@@ -0,0 +1,31 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-Herbert und Robbi 2 **
+ ** **
+ ** Version 1.1 **
+ ** **
+ ** (Stand: 30.03.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls herbert und robbi 2 DEFINES{} rechts frei,{} links frei,{} hinten frei,{} korn vorn, werkstueck vorn,{} korn links, werkstueck links,{} korn rechts, werkstueck rechts,{} korn hinten, werkstueck hinten:{}BOOL PROC rechts frei:{} rechts um;{} IF vorn frei{} THEN links um; TRUE{} ELSE links um; FALSE{} FI{}END PROC rechts frei;{}BOOL PROC links frei:{} links um;{} IF vorn frei{} THEN rechts um; TRUE{} ELSE rechts um; FALSE{}
+ FI{}END PROC links frei;{}BOOL PROC hinten frei:{} kehrt;{} IF vorn frei{} THEN kehrt; TRUE{} ELSE kehrt; FALSE{} FI{}END PROC hinten frei;{}BOOL PROC korn vorn:{} IF vorn frei{} THEN untersuche feld vor dir{} ELSE FALSE{} FI.{} untersuche feld vor dir:{} vor;{} IF korn da{} THEN mache vorwaertsgehen rueckgaengig; TRUE{} ELSE mache vorwaertsgehen rueckgaengig; FALSE{} FI.{} mache vorwaertsgehen rueckgaengig:{} kehrt; vor; kehrt{}END PROC korn vorn;{}
+BOOL PROC korn links:{} links um;{} IF vorn frei{} THEN untersuche feld links{} ELSE rechts um; FALSE{} FI.{} untersuche feld links:{} vor;{} IF korn da{} THEN mache linkswende rueckgaengig; TRUE{} ELSE mache linkswende rueckgaengig; FALSE{} FI.{} mache linkswende rueckgaengig:{} kehrt; vor; links um{}END PROC korn links;{}BOOL PROC korn rechts:{} rechts um;{} IF vorn frei{} THEN untersuche feld rechts{} ELSE links um; FALSE{} FI.{} untersuche feld rechts:{}
+ vor;{} IF korn da{} THEN mache rechtswende rueckgaengig; TRUE{} ELSE mache rechtswende rueckgaengig; FALSE{} FI.{} mache rechtswende rueckgaengig:{} kehrt; vor; rechts um{}END PROC korn rechts;{}BOOL PROC korn hinten:{} kehrt;{} IF vorn frei{} THEN untersuche feld hinter dir{} ELSE kehrt; FALSE{} FI.{} untersuche feld hinter dir:{} vor;{} IF korn da{} THEN mache kehrtwende rueckgaengig; TRUE{} ELSE mache kehrtwende rueckgaengig; FALSE{} FI.{}
+ mache kehrtwende rueckgaengig:{} kehrt; vor{}END PROC korn hinten;{}PROC kehrt:{} links um; links um{}END PROC kehrt;{}PROC rechts um:{} links um; links um; links um{}END PROC rechts um;{}BOOL PROC werkstueck vorn:{} korn vorn{}END PROC werkstueck vorn;{}BOOL PROC werkstueck links:{} korn links{}END PROC werkstueck links;{}BOOL PROC werkstueck rechts:{} korn rechts{}END PROC werkstueck rechts;{}BOOL PROC werkstueck hinten:{} korn hinten{}END PROC werkstueck hinten;{}END PACKET ls herbert und robbi 2;{}
+befehlssatz erweitern (TRUE){}
+
diff --git a/hamster/ls-Herbert und Robbi 3 b/hamster/ls-Herbert und Robbi 3
new file mode 100644
index 0000000..e5db408
--- /dev/null
+++ b/hamster/ls-Herbert und Robbi 3
@@ -0,0 +1,84 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-Herbert und Robbi 3 **
+ ** **
+ ** Version 1.1 **
+ ** **
+ ** (Stand: 30.03.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls herbert und robbi 3 DEFINES{} hamsterbefehlsauskunft,{} hamsterlaufauskunft,{} hamsterlandschaftsauskunft,{} hamsterlandschaft verzeichnis,{} hamsterlandschaft neu erstellen,{} hamsterlandschaft ansehen,{} hamsterlandschaft drucken,{} hamsterlandschaft kopieren,{} hamsterlandschaft umbenennen,{} hamsterlandschaft loeschen,{} hamsterprogramm verzeichnis,{} hamsterprogramm neu erstellen,{} hamsterprogramm ansehen,{} hamsterprogramm kopieren,{} hamsterprogramm umbenennen,{}
+ hamsterprogramm loeschen,{} hamsterprogramm drucken,{} hamster laufen lassen,{} hamsterinteraktiv laufen lassen,{} hamster, roboter:{}LET menukarte = "ls-MENUKARTE:Herbert und Robbi",{} praefix = "Flaeche:",{} flaechentype = 1007,{} niltext = "",{} maxlaenge = 60,{} maxnamenslaenge = 50;{}TEXT VAR flaechenname :: "",{} programmname :: "";{}INITFLAG VAR in this task :: FALSE;{}PROC initialize hamster:{}
+ IF NOT initialized (in this task){} THEN flaechenname := "";{} programmname := ""{} FI{}END PROC initialize hamster;{}PROC hamster:{} sei ein hamster;{} initialize hamster;{} install menu (menukarte);{} handle menu ("HAMSTER"){}END PROC hamster;{}PROC roboter:{} sei ein roboter;{} initialize hamster;{} install menu (menukarte);{} handle menu ("ROBOTER");{}END PROC roboter;{}PROC hamsterlaufauskunft:{} menuinfo (laufauskunftstext){}END PROC hamsterlaufauskunft;{}PROC hamsterlandschaftsauskunft:{}
+ menuinfo (landschaftsauskunftstext){}END PROC hamsterlandschaftsauskunft;{}PROC hamsterbefehlsauskunft:{} menuinfo (befehlsauskunftstext);{} menuinfo (testauskunftstext 1);{} IF testauskunftstext 2 <> ""{} THEN menuinfo (testauskunftstext 2){} FI{}END PROC hamsterbefehlsauskunft;{}PROC hamsterlandschaft verzeichnis:{} THESAURUS VAR landschaften ::{} ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{} forget ("Interne Thesaurusdateiliste", quiet);{} FILE VAR f :: sequential file (output, "Interne Thesaurusdateiliste");{}
+ f FILLBY landschaften;{} headline (f, anwendungstext (204)); modify (f);{} to line (f, 1); insert record (f); write record (f, kenntext);{} to line (f, 2); insert record (f);{} to line (f, 1); menuwindowshow (f);{} forget ("Interne Thesaurusdateiliste", quiet);{} regenerate menuscreen.{} kenntext:{} IF ist hamster THEN anwendungstext (121) ELSE anwendungstext (151) FI.{}END PROC hamsterlandschaft verzeichnis;{}PROC hamsterprogramm verzeichnis:{} THESAURUS VAR programme :: ALL myself - infix namen (ALL myself, praefix, flaechentype);{}
+ forget ("Interne Thesaurusdateiliste", quiet);{} FILE VAR f :: sequential file (output, "Interne Thesaurusdateiliste");{} f FILLBY programme;{} headline (f, anwendungstext (204)); modify (f);{} to line (f, 1); insert record (f); write record (f, anwendungstext (181));{} to line (f, 2); insert record (f);{} to line (f, 1); menuwindowshow (f);{} forget ("Interne Thesaurusdateiliste", quiet);{} regenerate menuscreen{}END PROC hamsterprogramm verzeichnis;{}PROC hamsterlandschaft neu erstellen:{}
+ hole flaechenname;{} kontrolliere den flaechennamen;{} kommandomodus;{} landschaft (flaechenname);{} regenerate menuscreen.{} hole flaechenname:{} IF ist hamster{} THEN flaechenname := menuanswer (anwendungstext (101) +{} anwendungstext (102), "", 5){} ELSE flaechenname := menuanswer (anwendungstext (131) +{} anwendungstext (132), "", 5){} FI.{} kontrolliere den flaechennamen:{} IF flaechenname = niltext{}
+ THEN LEAVE hamsterlandschaft neu erstellen{} ELIF length (flaechenname) > maxnamenslaenge{} THEN meckere zu langen namen an;{} flaechenname := niltext;{} LEAVE hamsterlandschaft neu erstellen{} ELIF exists (praefix + flaechenname){} THEN meckere existierende flaeche an;{} LEAVE hamsterlandschaft neu erstellen{} FI{}END PROC hamsterlandschaft neu erstellen;{}PROC hamsterprogramm neu erstellen:{} hole programmname;{} kontrolliere den programmnamen;{}
+ command dialogue (FALSE);{} cursor on;{} stdinfoedit (programmname);{} cursor off;{} command dialogue (TRUE);{} regenerate menuscreen.{} hole programmname:{} programmname := menuanswer (anwendungstext (161) +{} anwendungstext (162), "", 5).{} kontrolliere den programmnamen:{} IF programmname = niltext{} THEN LEAVE hamsterprogramm neu erstellen{} ELIF length (programmname) > maxnamenslaenge{} THEN meckere zu langen namen an;{} programmname := niltext;{}
+ LEAVE hamsterprogramm neu erstellen{} ELIF exists (programmname){} THEN meckere existierendes programm an;{} LEAVE hamsterprogramm neu erstellen{} FI{}END PROC hamsterprogramm neu erstellen;{}PROC hamsterlandschaft ansehen:{} IF flaechenname <> niltext CAND exists (praefix + flaechenname){} THEN frage nach dieser flaeche{} ELSE lasse flaeche auswaehlen{} FI;{} kommandomodus;{} landschaft (flaechenname);{} regenerate menuscreen.{} frage nach dieser flaeche:{}
+ IF menuno (ueberschrift + text 1 + name + text 2, 5){} THEN lasse flaeche auswaehlen{} FI.{} ueberschrift:{} IF ist hamster{} THEN center (maxlaenge, invers (anwendungstext (105))) + ""13""13""{} ELSE center (maxlaenge, invers (anwendungstext (135))) + ""13""13""{} FI.{} text 1:{} IF ist hamster THEN anwendungstext (103) ELSE anwendungstext (133) FI.{} name:{} ""13""13" " + invers (flaechenname) + ""13""13"".{} text 2:{} IF ist hamster THEN anwendungstext (104) ELSE anwendungstext (134) FI.{}
+ lasse flaeche auswaehlen:{} THESAURUS VAR verfuegbare;{} verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{} IF NOT not empty (verfuegbare){} THEN noch keine flaeche;{} LEAVE hamsterlandschaft ansehen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} IF ist hamster{} THEN flaechenname := menuone (verfuegbare, anwendungstext (105),{} anwendungstext (106), FALSE){} ELSE flaechenname := menuone (verfuegbare, anwendungstext (135),{}
+ anwendungstext (136), FALSE){} FI;{} IF flaechenname = niltext{} THEN regenerate menuscreen;{} LEAVE hamsterlandschaft ansehen{} FI.{}END PROC hamsterlandschaft ansehen;{}PROC hamsterprogramm ansehen:{} IF programmname <> niltext CAND exists (programmname){} THEN frage nach diesem programm{} ELSE lasse programm auswaehlen{} FI;{} cursor on;{} stdinfoedit (programmname);{} cursor off;{} regenerate menuscreen.{} frage nach diesem programm:{}
+ IF menuno (ueberschrift + anwendungstext (163) + name{} + anwendungstext (164), 5){} THEN lasse programm auswaehlen{} FI.{} ueberschrift:{} center (maxlaenge, invers (anwendungstext (165))) + ""13""13"".{} name:{} ""13""13" " + invers (programmname) + ""13""13"".{} lasse programm auswaehlen:{} THESAURUS VAR verfuegbare;{} verfuegbare := ALL myself - infix namen (ALL myself, praefix, flaechentype);{} IF NOT not empty (verfuegbare){} THEN noch kein programm;{}
+ LEAVE hamsterprogramm ansehen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} programmname := menuone (verfuegbare, anwendungstext (165),{} anwendungstext (166), FALSE);{} IF programmname = niltext{} THEN regenerate menuscreen;{} LEAVE hamsterprogramm ansehen{} FI.{}END PROC hamsterprogramm ansehen;{}PROC hamsterlandschaft drucken:{} lasse flaechen auswaehlen;{} drucke flaechen;{} regenerate menuscreen.{} lasse flaechen auswaehlen:{}
+ THESAURUS VAR verfuegbare;{} verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{} IF NOT not empty (verfuegbare){} THEN noch keine flaeche;{} LEAVE hamsterlandschaft drucken{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} IF ist hamster{} THEN verfuegbare := menusome (verfuegbare, anwendungstext (107),{} anwendungstext (108), FALSE){} ELSE verfuegbare := menusome (verfuegbare, anwendungstext (137),{}
+ anwendungstext (138), FALSE){} FI.{} drucke flaechen:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers (bezeichnung)));{} menuwindowline (2);{} command dialogue (FALSE);{} fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (schlussbemerkung);{} menuwindowstop.{} bezeichnung:{} IF ist hamster THEN anwendungstext (107) ELSE anwendungstext (137) FI.{}
+ schlussbemerkung:{} IF ist hamster THEN anwendungstext (110) ELSE anwendungstext (140) FI.{} fuehre einzelne operationen aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{} IF name (verfuegbare, k) <> ""{} THEN disable stop;{} menuwindowout ( " """ + name (verfuegbare, k) + """ "{} + anwendungstext (201));{} menuwindowline;{} drucke landschaft (name (verfuegbare, k));{} fehlerbehandlung{}
+ FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN menuwindowline (2);{} IF ist hamster{} THEN menuwindowout (anwendungstext (109)){} ELSE menuwindowout (anwendungstext (139)){} FI;{} menuwindowstop;{} regenerate menuscreen;{} LEAVE hamsterlandschaft drucken{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{}
+ ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{} clear error; enable stop;{} LEAVE hamsterlandschaft drucken{} FI.{}END PROC hamsterlandschaft drucken;{}PROC hamsterprogramm drucken:{} lasse programme auswaehlen;{} drucke programme;{} regenerate menuscreen.{} lasse programme auswaehlen:{} THESAURUS VAR verfuegbare;{} verfuegbare := ALL myself - infix namen (ALL myself, praefix, flaechentype);{}
+ IF NOT not empty (verfuegbare){} THEN noch kein programm;{} LEAVE hamsterprogramm drucken{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} verfuegbare := menusome (verfuegbare, anwendungstext (167),{} anwendungstext (168), FALSE).{} drucke programme:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers (anwendungstext (167))));{} menuwindowline (2);{} command dialogue (FALSE);{}
+ fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (anwendungstext (170));{} menuwindowstop.{} fuehre einzelne operationen aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{} IF name (verfuegbare, k) <> ""{} THEN disable stop;{} menuwindowout ( " """ + name (verfuegbare, k) + """ "{} + anwendungstext (201));{} menuwindowline;{}
+ print (name (verfuegbare, k));{} fehlerbehandlung{} FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN menuwindowline (2);{} menuwindowout (anwendungstext (169));{} menuwindowstop;{} regenerate menuscreen;{} LEAVE hamsterprogramm drucken{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){}
+ FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{} clear error; enable stop;{} LEAVE hamsterprogramm drucken{} FI.{}END PROC hamsterprogramm drucken;{}PROC hamsterlandschaft kopieren:{} ermittle alten flaechennamen;{} erfrage neuen flaechennamen;{} kopiere ggf die flaeche.{} ermittle alten flaechennamen:{} IF NOT not empty (bestand){} THEN noch keine flaeche;{} LEAVE hamsterlandschaft kopieren{}
+ ELSE biete auswahl an{} FI.{} biete auswahl an:{} TEXT VAR alter name := menuone ( bestand, text1, text2, TRUE);{} IF alter name = niltext{} THEN LEAVE hamsterlandschaft kopieren{} FI.{} bestand:{} ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix).{} text1:{} IF ist hamster THEN anwendungstext (111) ELSE anwendungstext (141) FI.{} text2:{} IF ist hamster THEN anwendungstext (112) ELSE anwendungstext (142) FI.{} erfrage neuen flaechennamen:{}
+ TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + hinweis auf alt + bisheriger name + aufforderung.{} ueberschrift:{} IF ist hamster{} THEN center (maxlaenge, invers (anwendungstext (111))) + ""13""13""{} ELSE center (maxlaenge, invers (anwendungstext (141))) + ""13""13""{} FI.{} hinweis auf alt:{} IF ist hamster THEN anwendungstext (113) ELSE anwendungstext (143) FI.{} bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{}
+ aufforderung:{} anwendungstext (202).{} kopiere ggf die flaeche:{} IF neuer name = niltext{} THEN menuinfo (invers (anwendungstext (192)));{} LEAVE hamsterlandschaft kopieren{} ELIF exists (praefix + neuer name){} THEN mache vorwurf;{} LEAVE hamsterlandschaft kopieren{} ELSE copy (praefix + alter name, praefix + neuer name){} FI.{} mache vorwurf:{} IF ist hamster{} THEN menuinfo (anwendungstext (193)){} ELSE menuinfo (anwendungstext (194)){}
+ FI.{}END PROC hamsterlandschaft kopieren;{}PROC hamsterprogramm kopieren:{} ermittle alten programmnamen;{} erfrage neuen programmnamen;{} kopiere ggf das programm.{} ermittle alten programmnamen:{} IF NOT not empty (bestand){} THEN noch kein programm;{} LEAVE hamsterprogramm kopieren{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} TEXT VAR alter name := menuone ( bestand, anwendungstext (171),{} anwendungstext (172), TRUE);{}
+ IF alter name = niltext{} THEN LEAVE hamsterprogramm kopieren{} FI.{} bestand:{} ALL myself - infix namen (ALL myself, praefix, flaechentype).{} erfrage neuen programmnamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + anwendungstext (173) + bisheriger name{} + anwendungstext (202).{} ueberschrift:{} center (maxlaenge, invers (anwendungstext (171))) + ""13""13"".{} bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{}
+ kopiere ggf das programm:{} IF neuer name = niltext{} THEN menuinfo (invers (anwendungstext (192)));{} LEAVE hamsterprogramm kopieren{} ELIF exists (neuer name){} THEN mache vorwurf;{} LEAVE hamsterprogramm kopieren{} ELSE copy (alter name, neuer name){} FI.{} mache vorwurf:{} menuinfo (anwendungstext (195)).{}END PROC hamsterprogramm kopieren;{}PROC hamsterlandschaft umbenennen:{} ermittle alten flaechennamen;{} erfrage neuen flaechennamen;{}
+ benenne ggf die flaeche um.{} ermittle alten flaechennamen:{} IF NOT not empty (bestand){} THEN noch keine flaeche;{} LEAVE hamsterlandschaft umbenennen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} TEXT VAR alter name := menuone ( bestand, text1, text2, TRUE);{} IF alter name = niltext{} THEN LEAVE hamsterlandschaft umbenennen{} FI.{} bestand:{} ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix).{} text1:{} IF ist hamster THEN anwendungstext (114) ELSE anwendungstext (144) FI.{}
+ text2:{} IF ist hamster THEN anwendungstext (115) ELSE anwendungstext (145) FI.{} erfrage neuen flaechennamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + hinweis auf alt + bisheriger name + aufforderung.{} ueberschrift:{} IF ist hamster{} THEN center (maxlaenge, invers (anwendungstext (114))) + ""13""13""{} ELSE center (maxlaenge, invers (anwendungstext (144))) + ""13""13""{} FI.{} hinweis auf alt:{} IF ist hamster THEN anwendungstext (116) ELSE anwendungstext (146) FI.{}
+ bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{} aufforderung:{} IF ist hamster THEN anwendungstext (117) ELSE anwendungstext (147) FI.{} benenne ggf die flaeche um:{} IF neuer name = niltext{} THEN menuinfo (invers (anwendungstext (192)));{} LEAVE hamsterlandschaft umbenennen{} ELIF exists (praefix + neuer name){} THEN mache vorwurf;{} LEAVE hamsterlandschaft umbenennen{} ELSE rename (praefix + alter name, praefix + neuer name);{}
+ flaechenname := neuer name{} FI.{} mache vorwurf:{} IF ist hamster{} THEN menuinfo (anwendungstext (193)){} ELSE menuinfo (anwendungstext (194)){} FI.{}END PROC hamsterlandschaft umbenennen;{}PROC hamsterprogramm umbenennen:{} ermittle alten programmnamen;{} erfrage neuen programmnamen;{} benenne ggf das programm um.{} ermittle alten programmnamen:{} IF NOT not empty (bestand){} THEN noch kein programm;{} LEAVE hamsterprogramm umbenennen{} ELSE biete auswahl an{}
+ FI.{} biete auswahl an:{} TEXT VAR alter name := menuone ( bestand, anwendungstext (174),{} anwendungstext (175), TRUE);{} IF alter name = niltext{} THEN LEAVE hamsterprogramm umbenennen{} FI.{} bestand:{} ALL myself - infix namen (ALL myself, praefix, flaechentype).{} erfrage neuen programmnamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + anwendungstext (176) + bisheriger name{} + anwendungstext (177).{}
+ ueberschrift:{} center (maxlaenge, invers (anwendungstext (174))) + ""13""13"".{} bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{} benenne ggf das programm um:{} IF neuer name = niltext{} THEN menuinfo (invers (anwendungstext (192)));{} LEAVE hamsterprogramm umbenennen{} ELIF exists (neuer name){} THEN mache vorwurf;{} LEAVE hamsterprogramm umbenennen{} ELSE rename (alter name, neuer name);{} programmname := neuer name{}
+ FI.{} mache vorwurf:{} menuinfo (anwendungstext (195)).{}END PROC hamsterprogramm umbenennen;{}PROC hamsterlandschaft loeschen:{} lasse flaechen auswaehlen;{} loesche flaechen;{} regenerate menuscreen.{} lasse flaechen auswaehlen:{} THESAURUS VAR verfuegbare;{} verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{} IF NOT not empty (verfuegbare){} THEN noch keine flaeche;{} LEAVE hamsterlandschaft loeschen{} ELSE biete auswahl an{}
+ FI.{} biete auswahl an:{} IF ist hamster{} THEN verfuegbare := menusome (verfuegbare, anwendungstext (118),{} anwendungstext (119), FALSE){} ELSE verfuegbare := menusome (verfuegbare, anwendungstext (148),{} anwendungstext (149), FALSE){} FI.{} loesche flaechen:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers (bezeichnung)));{} menuwindowline (2);{}
+ command dialogue (FALSE);{} fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (schlussbemerkung);{} menuwindowstop.{} bezeichnung:{} IF ist hamster THEN anwendungstext (118) ELSE anwendungstext (148) FI.{} schlussbemerkung:{} IF ist hamster THEN anwendungstext (120) ELSE anwendungstext (150) FI.{} fuehre einzelne operationen aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{} IF name (verfuegbare, k) <> ""{}
+ THEN disable stop;{} IF menuwindowyes (" """ + name (verfuegbare, k) + """ "{} + anwendungstext (203)){} THEN forget (praefix + name (verfuegbare, k), quiet){} FI;{} fehlerbehandlung{} FI{} PER;{} flaechenname := "".{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN menuwindowline (2);{} IF ist hamster{} THEN menuwindowout (anwendungstext (109)){}
+ ELSE menuwindowout (anwendungstext (139)){} FI;{} menuwindowstop;{} regenerate menuscreen;{} LEAVE hamsterlandschaft loeschen{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{} clear error; enable stop;{}
+ LEAVE hamsterlandschaft loeschen{} FI.{}END PROC hamsterlandschaft loeschen;{}PROC hamsterprogramm loeschen:{} lasse programme auswaehlen;{} loesche programme;{} regenerate menuscreen.{} lasse programme auswaehlen:{} THESAURUS VAR verfuegbare;{} verfuegbare := ALL myself - infix namen (ALL myself, praefix, flaechentype);{} IF NOT not empty (verfuegbare){} THEN noch kein programm;{} LEAVE hamsterprogramm loeschen{} ELSE biete auswahl an{} FI.{}
+ biete auswahl an:{} verfuegbare := menusome (verfuegbare, anwendungstext (178),{} anwendungstext (179), FALSE).{} loesche programme:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers (anwendungstext (178))));{} menuwindowline (2);{} command dialogue (FALSE);{} fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (anwendungstext (180));{}
+ menuwindowstop.{} fuehre einzelne operationen aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{} IF name (verfuegbare, k) <> ""{} THEN disable stop;{} IF menuwindowyes (" """ + name (verfuegbare, k) + """ "{} + anwendungstext (203)){} THEN forget (name (verfuegbare, k), quiet){} FI;{} fehlerbehandlung{} FI{} PER;{} programmname := "".{} steige ggf bei leerem thesaurus aus:{}
+ IF NOT not empty (verfuegbare){} THEN menuwindowline (2);{} menuwindowout (anwendungstext (169));{} menuwindowstop;{} regenerate menuscreen;{} LEAVE hamsterprogramm loeschen{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{}
+ clear error; enable stop;{} LEAVE hamsterprogramm loeschen{} FI.{}END PROC hamsterprogramm loeschen;{}PROC hamsterinteraktiv laufen lassen:{} frage nach neuer flaeche;{} cursor on;{} IF ist hamster{} THEN hamsterinter (flaechenname){} ELSE roboterinter (flaechenname){} FI;{} programmname := "PROTOKOLL";{} cursor off;{} regenerate menuscreen.{} frage nach neuer flaeche:{} IF menuyes (ueberschrift + fragetext, 5){} THEN lasse flaeche auswaehlen{} ELSE weise auf landschaftsgestaltung hin;{}
+ LEAVE hamsterinteraktiv laufen lassen{} FI.{} ueberschrift:{} IF ist hamster{} THEN center (laenge, invers (anwendungstext (122))) + ""13""13""{} ELSE center (laenge, invers (anwendungstext (152))) + ""13""13""{} FI.{} fragetext:{} IF ist hamster{} THEN center (laenge, anwendungstext (123)){} ELSE center (laenge, anwendungstext (153)){} FI.{} laenge:{} IF ist hamster{} THEN max (length (anwendungstext (122)),{} length (anwendungstext (123))) + 5{}
+ ELSE max (length (anwendungstext (152)),{} length (anwendungstext (153))) + 5{} FI.{} lasse flaeche auswaehlen:{} THESAURUS VAR verfuegbare;{} verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{} IF ist hamster{} THEN flaechenname := menuone (verfuegbare, anwendungstext (122),{} anwendungstext (106), FALSE){} ELSE flaechenname := menuone (verfuegbare, anwendungstext (152),{} anwendungstext (136), FALSE){}
+ FI;{} IF flaechenname = niltext{} THEN weise auf landschaftsgestaltung hin;{} regenerate menuscreen;{} LEAVE hamsterinteraktiv laufen lassen{} FI.{} weise auf landschaftsgestaltung hin:{} WINDOW VAR mfenster := current menuwindow;{} IF ist hamster{} THEN boxinfo (mfenster, anwendungstext (124), 5, maxint){} ELSE boxinfo (mfenster, anwendungstext (154), 5, maxint){} FI.{}END PROC hamsterinteraktiv laufen lassen;{}PROC hamster laufen lassen:{}
+ programmname ermitteln;{} BOOL VAR namen eingesetzt :: FALSE;{} untersuche programmdatei auf flaechennamen;{} page;{} geschwindigkeit (5);{} cursor on;{} lauf (programmname);{} cursor off;{} IF namen eingesetzt{} THEN entferne flaechennamen aus programmdatei{} FI;{} regenerate menuscreen.{} programmname ermitteln:{} IF programmname <> niltext CAND exists (programmname){} THEN frage nach diesem programm{} ELSE lasse programm auswaehlen{} FI.{} frage nach diesem programm:{}
+ IF menuno (ueberschrift + anwendungstext (163) + name + anwendungstext (164), 5){} THEN lasse programm auswaehlen{} FI.{} ueberschrift:{} IF ist hamster{} THEN center (maxlaenge, invers (anwendungstext (125))) + ""13""13""{} ELSE center (maxlaenge, invers (anwendungstext (155))) + ""13""13""{} FI.{} name:{} ""13""13" " + invers (programmname) + ""13""13"".{} lasse programm auswaehlen:{} THESAURUS VAR verfuegbare;{} verfuegbare := ALL myself - infix namen (ALL myself, praefix, flaechentype);{}
+ IF ist hamster{} THEN programmname := menuone (verfuegbare, anwendungstext (125),{} anwendungstext (166), TRUE){} ELSE programmname := menuone (verfuegbare, anwendungstext (155),{} anwendungstext (166), TRUE){} FI;{} IF programmname = niltext{} THEN LEAVE hamster laufen lassen{} FI.{} untersuche programmdatei auf flaechennamen:{} FILE VAR a :: sequential file (modify, programmname);{} TEXT VAR zeile;{}
+ to line (a, 1);{} REP{} read record (a, zeile);{} zeile := compress (zeile);{} IF NOT eof (a) THEN down (a) FI{} UNTIL zeile <> "" OR eof (a) PER;{} IF pos (zeile, "landschaft") = 0 AND pos (zeile, "arbeitsfeld") = 0{} THEN ermittle flaechennamen;{} setze flaechennamen in datei ein{} FI.{} ermittle flaechennamen:{} IF flaechenname <> ""{} THEN frage nach altem flaechennamen{} ELSE lasse flaeche auswaehlen{} FI.{} frage nach altem flaechennamen:{}
+ IF ist hamster{} THEN frage nach alter landschaft{} ELSE frage nach altem arbeitsfeld{} FI.{} frage nach alter landschaft:{} IF menuno (ueberschrift + anwendungstext (103){} + fname + anwendungstext (104), 5){} THEN lasse flaeche auswaehlen{} FI.{} frage nach altem arbeitsfeld:{} IF menuno (ueberschrift + anwendungstext (133){} + fname + anwendungstext (134), 5){} THEN lasse flaeche auswaehlen{} FI.{} fname:{} ""13""13" " + invers (flaechenname) + ""13""13"".{}
+ lasse flaeche auswaehlen:{} verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{} IF ist hamster{} THEN flaechenname := menuone (verfuegbare, anwendungstext (125),{} anwendungstext (106), FALSE){} ELSE flaechenname := menuone (verfuegbare, anwendungstext (155),{} anwendungstext (136), FALSE){} FI;{} IF flaechenname = niltext{} THEN regenerate menuscreen;{} landschaftsfehler anzeigen;{}
+ LEAVE hamster laufen lassen{} FI.{} landschaftsfehler anzeigen:{} IF ist hamster{} THEN menuinfo (anwendungstext (124)){} ELSE menuinfo (anwendungstext (154)){} FI.{} setze flaechennamen in datei ein:{} to line (a, 1);{} zeile := "landschaft (""" + flaechenname + """);";{} insert record (a);{} write record (a, zeile);{} namen eingesetzt := TRUE.{} entferne flaechennamen aus programmdatei:{} FILE VAR b :: sequential file (modify, programmname);{}
+ to line (b, 1);{} REP{} read record (b, zeile);{} IF pos (zeile, "landschaft") = 0 AND pos (zeile, "arbeitsfeld") = 0{} THEN IF NOT eof (b) THEN down (b) FI{} FI{} UNTIL zeile <> "" OR eof (b) PER;{} IF pos (zeile, "landschaft") > 0 OR pos (zeile, "arbeitsfeld") > 0{} THEN delete record (b){} FI{}END PROC hamster laufen lassen;{}PROC meckere zu langen namen an:{} menuinfo (anwendungstext (191)){}END PROC meckere zu langen namen an;{}PROC meckere existierende flaeche an:{}
+ IF ist hamster{} THEN menuinfo (anwendungstext (193)){} ELSE menuinfo (anwendungstext (194)){} FI{}END PROC meckere existierende flaeche an;{}PROC meckere existierendes programm an:{} menuinfo (anwendungstext (195)){}END PROC meckere existierendes programm an;{}PROC noch keine flaeche:{} IF ist hamster{} THEN menuinfo (anwendungstext (196)){} ELSE menuinfo (anwendungstext (197)){} FI{}END PROC noch keine flaeche;{}PROC noch kein programm:{} menuinfo (anwendungstext (198)){}
+END PROC noch kein programm;{}END PACKET ls herbert und robbi 3;{}
+
diff --git a/hamster/ls-Herbert und Robbi-gen b/hamster/ls-Herbert und Robbi-gen
new file mode 100644
index 0000000..ae21ddb
--- /dev/null
+++ b/hamster/ls-Herbert und Robbi-gen
@@ -0,0 +1,33 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-Herbert und Robbi **
+ ** GENERATORPROGRAMM **
+ ** Version 1.1 **
+ ** **
+ ** (Stand: 30.03.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+LET mm taskname = "ls-MENUKARTEN",{} datei1 = "ls-Herbert und Robbi 1",{} datei2 = "ls-Herbert und Robbi 2",{} datei3 = "ls-Herbert und Robbi 3",{} menukarte = "ls-MENUKARTE:Herbert und Robbi";{}PROC stelle existenz des mm sicher:{} cursor (1, 5); out (""4"");{} IF NOT exists (task (mm taskname)){} THEN errorstop ("Unbedingt erst den 'MENUKARTEN MANAGER' generieren!");{} FI{}END PROC stelle existenz des mm sicher;{}PROC vom archiv (TEXT CONST datei):{} cursor (1,5); out (""4"");{}
+ out (" """); out (datei); putline (""" wird geholt.");{} fetch (datei, archive){}END PROC vom archiv;{}PROC hole (TEXT CONST datei):{} IF NOT exists (datei) THEN vom archiv (datei) FI{}END PROC hole;{}PROC in (TEXT CONST datei):{} hole (datei);{} cursor (1, 5); out (""4"");{} out (" """); out (datei); out (""" wird übersetzt: ");{} insert (datei);{} forget (datei, quiet);{}END PROC in;{}PROC schicke (TEXT CONST datei):{} cursor (1, 5); out (""4"");{} out (" """); out(datei);{} out (""" wird zum MENUKARTEN-MANAGER geschickt!");{}
+ command dialogue (FALSE);{} save (datei, task (mm taskname));{} command dialogue (TRUE);{} forget (datei, quiet){}END PROC schicke;{}INT VAR size, used;{}BOOL VAR einzeln, mit erweiterung :: FALSE;{}storage (size, used);{}einzeln := size - used < 500;{}forget ("ls-Herbert und Robbi/gen", quiet);{}wirf kopfzeile aus;{}stelle existenz des mm sicher;{}hole die dateien;{}insertiere die dateien;{}mache global manager aus der task.{}wirf kopfzeile aus:{} page;{} putline (" "15"ls-Herbert und Robbi - Automatische Generierung "14"");{}
+ line (2);{} putline (" Bitte beantworten Sie noch die folgende Frage:");{} line;{} put(" Sollen neben den 'Standardtests' auch die folgenden 'Tests':");{} line (2);{} putline(" Für den Hamster: Für den Roboter:");{} putline(" links frei links frei");{} putline(" rechts frei rechts frei");{} putline(" hinten frei hinten frei");{} putline(" korn vorn werkstueck vorn");{}
+ putline(" korn links werkstueck links");{} putline(" korn rechts werkstueck rechts");{} putline(" korn hinten werkstueck hinten");{} line;{} IF yes(" zur Verfügung gestellt werden"){} THEN mit erweiterung := TRUE{} FI.{}hole die dateien:{} IF NOT exists (datei 1){} COR NOT exists (datei 3){} COR NOT exists (menukarte){} THEN hole dateien vom archiv; LEAVE hole die dateien{}
+ FI;{} IF mit erweiterung AND NOT exists (datei 2){} THEN hole dateien vom archiv{} FI.{}hole dateien vom archiv:{} cursor (1,3); out (""4"");{} IF yes ("Ist das Archiv angemeldet und die Diskette eingelegt"){} THEN lese ein{} ELSE line (2);{} errorstop ("Ohne die Diskette kann ich das System nicht generieren!"){} FI.{}lese ein:{} cursor (1, 3); out (""4"");{} out (" "15"Bitte die Diskette eingelegt lassen! "14"");{} IF NOT einzeln{} THEN hole (datei 1);{}
+ hole (datei 3);{} hole (menukarte);{} IF mit erweiterung{} THEN hole (datei 2){} FI;{} cursor (1, 3); out(""4"");{} out (" "15"Die Diskette wird nicht mehr benötigt! "14"");{} release (archive){} FI.{}insertiere die dateien:{} check off;{} cursor (1, 3); out(""4"");{} out (" "15"Die Diskette wird nicht mehr benötigt! "14"");{} in (datei 1);{} IF mit erweiterung{} THEN in (datei 2){}
+ FI;{} in (datei 3);{} schicke (menukarte);{} IF einzeln THEN release (archive) FI;{} check on.{}mache global manager aus der task:{} global manager.{}
+
diff --git a/hamster/ls-MENUKARTE:Herbert und Robbi b/hamster/ls-MENUKARTE:Herbert und Robbi
new file mode 100644
index 0000000..2e9629c
--- /dev/null
+++ b/hamster/ls-MENUKARTE:Herbert und Robbi
Binary files differ
diff --git a/lisp/lisp.1 b/lisp/lisp.1
new file mode 100644
index 0000000..32a9c27
--- /dev/null
+++ b/lisp/lisp.1
@@ -0,0 +1,1306 @@
+PACKET lisp heap and oblist management (* Autor: J.Durchholz *)
+ (* Datum: 09.05.1984 *)
+ DEFINES (* Version 1.7.2 *)
+ (* hey 25.2.83 *)
+ initialize lisp system,
+ dump lisp heap,
+ lisp storage,
+ collect lisp heap garbage,
+ SYM,
+ :=,
+ nil,
+ pname,
+ head,
+ set head,
+ tail,
+ set tail,
+ cons,
+ eq,
+ equal,
+ null,
+ atom,
+ is named atom,
+ begin oblist dump,
+ next atom,
+ new atom,
+ create atom,
+ delete atom,
+ begin property list dump,
+ next property,
+ add property,
+ alter property,
+ property,
+ delete property,
+ property exists,
+ add flag,
+ flag,
+ delete flag,
+ text,
+ is text,
+ character,
+ is character,
+ sym character,
+ int 1,
+ int 2,
+ is int pair,
+ sym:
+
+
+(* NOTE: All internal routines are prefixed by x *)
+
+
+(***************************** heap management ****************************)
+
+LET
+ max size = 32767,
+ NODE = STRUCT (INT status,
+ head, tail);
+LET HEAP = STRUCT (INT size,
+ ROW max size NODE node);
+
+
+BOUND HEAP VAR heap;
+
+
+PROC initialize lisp system (DATASPACE CONST ds):
+ IF type (ds) < 0 THEN
+ heap := ds;
+ x initialize oblist and heap size;
+ create atom ("NIL");
+ create atom ("PNAME");
+ ELSE
+ heap := ds
+ FI
+END PROC initialize lisp system;
+
+
+PROC dump lisp heap (FILE VAR f):
+ put line (f, "Groesse :" + text (CONCR (heap).size));
+ line (f);
+ put (CONCR (heap).size);
+ BOOL VAR is char := FALSE;
+ INT VAR i;
+ FOR i FROM 1 UPTO CONCR (heap).size REP
+ cout (i);
+ dump ith node
+ PER.
+
+dump ith node:
+ put (f, text (i, 6));
+ put (f, status);
+ put (f, head);
+ put (f, tail);
+ line (f).
+
+status:
+ SELECT ith node.status OF
+ CASE atomic : "ATOMIC............"
+ CASE non atomic : "NON ATOMIC........"
+ CASE oblist bone : "OBLIST BONE......."
+ CASE property indicator : "PROPERTY INDICATOR"
+ CASE property root : "PROPERTY ROOT....."
+ CASE flag indicator : "FLAG INDICATOR...."
+ CASE text data : "TEXT DATA........."
+ CASE character data : is char := TRUE; "CHARACTER DATA...."
+ CASE int data : "INT DATA.........."
+ OTHERWISE "????." + text (ith node.status, 6) + ".????"
+ END SELECT.
+
+head:
+ maybe a code + text (ith node.head, 6).
+
+maybe a code:
+ IF is char THEN
+ is char := FALSE;
+ IF ith node.head > 31 AND 128 > ith node.head THEN
+ " " + code (ith node.head) + " "
+ ELSE
+ " "
+ FI
+ ELSE
+ " "
+ FI.
+
+tail:
+ text (ith node.tail, 6).
+
+ith node:
+ CONCR (heap).node (i).
+
+END PROC dump lisp heap;
+
+
+PROC lisp storage (INT VAR size, used):
+ size := max size;
+ used := CONCR (heap).size
+END PROC lisp storage;
+
+
+PROC collect lisp heap garbage:
+ mark all used nodes;
+ transfer all used high address nodes to unused low address nodes;
+ adjust all pointers to cleared high address area and unmark all nodes;
+ adjust size.
+
+mark all used nodes:
+ INT VAR i;
+ FOR i FROM 2 UPTO 28 REP
+ x mark (i)
+ PER.
+
+transfer all used high address nodes to unused low address nodes:
+ INT VAR high address :: CONCR (heap).size + 1,
+ low address :: 0;
+ REP
+ find next lower used high address node;
+ IF no used high address node found THEN
+ LEAVE transfer all used high address nodes to unused low address nodes
+ FI;
+ find next higher unused low address node;
+ IF no unused low address node found THEN
+ LEAVE transfer all used high address nodes to unused low address nodes
+ FI;
+ transfer high address node to low address node
+ PER.
+
+find next lower used high address node:
+ REP
+ high address DECR 1
+ UNTIL high address node marked PER.
+
+high address node marked:
+ high address node.status < 0.
+
+no used high address node found:
+ low address = high address.
+
+find next higher unused low address node:
+ REP
+ low address INCR 1
+ UNTIL low address node not marked OR low address = high address PER.
+
+low address node not marked:
+ low address node.status > 0.
+
+no unused low address node found :
+ low address = high address.
+
+transfer high address node to low address node:
+ low address node.status := high address node.status;
+ low address node.head := high address node.head;
+ low address node.tail := high address node.tail;
+ high address node.head := low address.
+
+adjust all pointers to cleared high address area and unmark all nodes:
+ (* 'high address' should now point to the last node of the used area *)
+ FOR low address FROM 1 UPTO high address REP
+ unmark low address node;
+ SELECT low address node.status OF
+ CASE oblist bone: adjust head
+ CASE atomic,
+ non atomic,
+ property indicator,
+ property root,
+ flag indicator: adjust head; adjust tail
+ CASE text data, character data: adjust tail
+ CASE int data:
+ OTHERWISE x lisp error ("Status " + text (low address node.status) +
+ " gefunden bei pointer Justage")
+ END SELECT
+ PER.
+
+unmark low address node:
+ low address node.status := - low address node.status.
+
+adjust head:
+ IF low address node.head > high address THEN
+ low address node.head := node (low address node.head).head
+ FI.
+
+adjust tail:
+ IF low address node.tail > high address THEN
+ low address node.tail := node (low address node.tail).head
+ FI.
+
+adjust size:
+ CONCR (heap).size := high address.
+
+low address node:
+ node (low address).
+
+high address node:
+ node (high address).
+
+node:
+ CONCR (heap).node.
+
+END PROC collect lisp heap garbage;
+
+
+PROC x mark (INT CONST ptr):
+ IF node not yet marked THEN
+ mark node;
+ SELECT - ptr node.status OF
+ CASE oblist bone: x mark (ptr node.head)
+ CASE atomic,
+ non atomic,
+ property indicator,
+ property root,
+ flag indicator: x mark (ptr node.head); x mark (ptr node.tail)
+ CASE text data, character data: x mark (ptr node.tail)
+ CASE int data:
+ OTHERWISE error stop ("Status " + text (- ptr node.status) +
+ " gefunden beim Markieren")
+ END SELECT
+ FI.
+
+
+node not yet marked:
+ ptr node.status > 0.
+
+mark node:
+ ptr node.status := - ptr node.status.
+
+ptr node:
+ CONCR (heap).node (ptr)
+
+END PROC x mark;
+
+
+TYPE SYM = INT;
+
+
+OP := (SYM VAR left, SYM CONST right):
+ CONCR (left) := CONCR (right)
+END OP :=;
+
+
+LET atomic = 1,
+ non atomic = 2,
+ oblist bone = 3,
+ property indicator = 4,
+ property root = 5,
+ flag indicator = 6,
+ text data = 7,
+ character data = 8,
+ int data = 9;
+
+SYM CONST nil :: SYM :(35), (* 'x initialize oblist and heap size' will *)
+ pname :: SYM :(44); (* place the atom NIL at node 35 and PNAME *)
+ (* at node 44 *)
+
+
+(***************************** basic functions ****************************)
+
+
+SYM PROC head (SYM CONST sym):
+ SELECT status of sym OF
+ CASE atomic: error stop ("Atome haben keinen head"); nil
+ CASE non atomic: SYM :(head of sym)
+ CASE oblist bone,
+ property indicator,
+ property root,
+ flag indicator : x lisp error ("Versteckter Knoten, Type:" +
+ text (status of sym));
+ nil
+ CASE text data,
+ character data,
+ int data : error stop ("Daten haben keinen head"); nil
+ OTHERWISE x lisp error ("Illegaler Status " + text (status of sym));
+ nil
+ END SELECT.
+
+status of sym:
+ sym node.status.
+
+head of sym:
+ sym node.head.
+
+sym node:
+ CONCR (heap).node (CONCR (sym))
+
+END PROC head;
+
+
+SYM PROC x head (SYM CONST sym):
+ SYM :(CONCR (heap).node (CONCR (sym)).head)
+END PROC x head;
+
+
+PROC set head (SYM CONST sym, new head):
+ SELECT status of sym OF
+ CASE atomic: errorstop ("Atome haben keinen head")
+ CASE non atomic: head of sym := CONCR (new head)
+ CASE oblist bone,
+ property indicator,
+ property root,
+ flag indicator : x lisp error ("Versteckter Knoten, Type:" +
+ text (status of sym))
+ CASE text data,
+ character data,
+ int data : error stop ("Daten haben keinen head")
+ OTHERWISE x lisp error ("Illegaler Status " + text (status of sym))
+ END SELECT.
+
+status of sym:
+ sym node.status.
+
+head of sym:
+ sym node.head.
+
+sym node:
+ CONCR (heap).node (CONCR (sym)).
+
+END PROC set head;
+
+
+PROC x set head (SYM CONST sym, new head):
+ CONCR (heap).node (CONCR (sym)).head := CONCR (new head)
+END PROC x set head;
+
+
+SYM PROC tail (SYM CONST sym):
+ SELECT status of sym OF
+ CASE atomic: error stop ("Atome haben keinen tail"); nil
+ CASE non atomic: SYM :(tail of sym)
+ CASE oblist bone,
+ property indicator,
+ flag indicator : x lisp error ("Versteckter Knoten:" +
+ text (status of sym));
+ nil
+ CASE text data,
+ character data,
+ int data : error stop ("Daten haben keinen tail"); nil
+ OTHERWISE x lisp error ("Illegaler Status: "+ text (status of sym));
+ nil
+ END SELECT.
+
+status of sym:
+ sym node.status.
+
+tail of sym:
+ sym node.tail.
+
+sym node:
+ CONCR (heap).node (CONCR (sym)).
+
+END PROC tail;
+
+
+SYM PROC x tail (SYM CONST sym):
+ SYM :(CONCR (heap).node (CONCR (sym)).tail)
+END PROC x tail;
+
+
+PROC set tail (SYM CONST sym, new tail):
+ SELECT status of sym OF
+ CASE atomic: error stop ("Atome haben keinen tail")
+ CASE non atomic: tail of sym := CONCR (new tail)
+ CASE oblist bone,
+ property indicator,
+ property root,
+ flag indicator : x lisp error ("Versteckter Knoten, Type: " +
+ text (status of sym))
+ CASE text data,
+ character data,
+ int data : error stop ("Daten tails sind unveraenderbar")
+ OTHERWISE x lisp error ("Illegaler Status: " + text (status of sym))
+ END SELECT.
+
+status of sym:
+ sym node.status.
+
+tail of sym:
+ sym node.tail.
+
+sym node:
+ CONCR (heap).node (CONCR (sym)).
+
+END PROC set tail;
+
+
+PROC x set tail (SYM CONST sym, new tail):
+ CONCR (heap).node (CONCR (sym)).tail := CONCR (new tail)
+END PROC x set tail;
+
+
+SYM PROC cons (SYM CONST head, tail):
+ SYM VAR result;
+ search free node;
+ result node.status := non atomic;
+ result node.head := CONCR (head);
+ result node.tail := CONCR (tail);
+ result.
+
+search free node:
+ IF CONCR (heap).size = max size THEN
+ error stop ("LISP Heap Ueberlauf");
+ LEAVE cons WITH nil
+ ELSE
+ CONCR (heap).size INCR 1;
+ CONCR (result) := CONCR (heap).size; cout(CONCR(result))
+ FI.
+
+result node:
+ CONCR (heap).node (CONCR (result)).
+
+END PROC cons;
+
+
+BOOL PROC eq (SYM CONST sym 1, sym 2):
+ CONCR (sym 1) = CONCR (sym 2)
+END PROC eq;
+
+
+BOOL PROC equal (SYM CONST sym 1, sym 2):
+ eq (sym 1, sym 2) COR have same value.
+
+have same value:
+ IF sym 1 node.status <> sym 2 node.status THEN
+ FALSE
+ ELSE
+ SELECT sym 1 node.status OF
+ CASE atomic: FALSE
+ CASE non atomic: equal (head (sym 1), head (sym 2)) CAND
+ equal (tail (sym 1), tail (sym 2))
+ CASE oblist bone,
+ property indicator,
+ property root,
+ flag indicator: x lisp error ("Versteckter Knoten, Type: " +
+ text (x status (sym 1))); FALSE
+ CASE text data: equal texts
+ CASE character data: sym 1 node.head = sym 2 node.head
+ CASE int data: sym 1 node.head = sym 2 node.head AND
+ sym 1 node.tail = sym 2 node.tail
+ OTHERWISE x lisp error ("Ilegaler Status " + text (x status (sym 1)));
+ FALSE
+ END SELECT
+ FI.
+
+equal texts:
+ equal length CAND equal character sequence.
+
+equal length:
+ eq (x head (sym 1), x head (sym 2)).
+
+equal character sequence:
+ SYM VAR actual sym 1 character :: sym 1,
+ actual sym 2 character :: sym 2;
+ INT VAR i;
+ FOR i FROM 1 UPTO sym 1 node. head REP
+ actual sym 1 character := x tail (actual sym 1 character);
+ actual sym 2 character := x tail (actual sym 2 character);
+ IF eq (actual sym 1 character, actual sym 2 character) THEN
+ LEAVE equal character sequence WITH TRUE
+ FI;
+ IF x status (actual sym 1 character) <> character data OR
+ x status (actual sym 2 character) <> character data THEN
+ x lisp error ("Ungueltiges Zeichen im text");
+ LEAVE equal character sequence WITH FALSE
+ FI;
+ IF CONCR (x head (actual sym 1 character)) <>
+ CONCR (x head (actual sym 2 character)) THEN
+ LEAVE equal character sequence WITH FALSE
+ FI
+ PER;
+ TRUE.
+
+sym 1 node:
+ CONCR (heap).node (CONCR (sym 1)).
+
+sym 2 node:
+ CONCR (heap).node (CONCR (sym 2)).
+
+END PROC equal;
+
+
+BOOL PROC null (SYM CONST sym):
+ CONCR (sym) = CONCR (nil)
+END PROC null;
+
+
+BOOL PROC atom (SYM CONST sym):
+ SELECT x status (sym) OF
+ CASE atomic,
+ text data,
+ character data,
+ int data: TRUE
+ CASE non atomic: FALSE
+ CASE oblist bone,
+ property indicator,
+ property root,
+ flag indicator : x lisp error ("Versteckter Knoten, Type:" +
+ text (x status (sym))); TRUE
+ OTHERWISE x lisp error ("Illegaler Status " +
+ text (x status (sym))); TRUE
+ END SELECT
+END PROC atom;
+
+
+BOOL PROC is named atom (SYM CONST sym):
+ x status (sym) = atomic
+END PROC is named atom;
+
+
+(*------------------- internal heap management routines ------------------*)
+
+
+SYM PROC x new node (INT CONST status, head, tail):
+ IF CONCR (heap).size = max size THEN
+ error stop ("LISP Heap Ueberlauf"); nil
+ ELSE
+ CONCR (heap).size INCR 1;
+ new node.status := status;
+ new node.head := head;
+ new node.tail := tail;
+ SYM :(CONCR (heap).size)
+ FI.
+
+new node:
+ node (CONCR (heap).size).
+
+node:
+ CONCR (heap).node.
+
+END PROC x new node;
+
+
+INT PROC x status (SYM CONST sym):
+ CONCR (heap).node (CONCR (sym)).status
+END PROC x status;
+
+
+(**************************** oblist management ***************************)
+
+
+(* Oblist organization:
+
+(NOTE:
+
+ +-----------------+
+ l <status> l
+ All nodes are represented as +--------+--------+ in all comments
+ l <head> l <tail> l of this packet.
+ +--------+--------+
+
+END OF NOTE)
+
+
+The 'oblist' (object list) is organized as follows:
+
+ +-------------+
+ l oblist bone l
+ +------+------+ +--> list of all atoms whose print names begin with "§"
+ l o l XXXX l l
+ +---+--+------+ l
+ +------------+
+ +-------------+
+ l oblist bone l
+ +------+------+ +--> list of all atoms whose print names begin with "A"
+ l o l XXXX l l
+ +---+--+------+ l
+ +------------+
+ .
+ .
+ .
+
+ +-------------+
+ l oblist bone l
+ +------+------+ +--> list of all atoms whose print names begin with "Z"
+ l o l XXXX l l
+ +---+--+------+ l
+ +------------+
+
+
+These nodes with status 'oblist bone' form the oblist skeleton. As long as
+the lisp heap exists, they are stored contiguously in nodes 2 - 28; they
+cannot be changed directly by the user. This way of storing the oblist
+skeleton allows a hashing scheme to be applied when searching for an atom
+with a given name. The hash width of 27 is the smallest one thas distributes
+all atoms according to their character; with a smaller hash size, two or
+more lists would be merged, with the effect that some of the atom lists
+would contain atoms beginning with different characters.
+
+
+The list of all atoms whose print names begin with a certain character
+is organized as follows:
+
+ +-------------+
+ l atomic l
+ +------+------+
+ l o l o---+--> property list of first atom
+ +---+--+------+
+ l
+ V
+ +-------------+
+ l atomic l
+ +------+------+
+ l o l o---+--> property list of 2nd atom
+ +---+--+------+
+ l
+ V
+ .
+ .
+ .
+
+ l
+ V
+ +-------------+
+ l atomic l
+ +------+------+
+ l o l o---+--> property list of last atom
+ +---+--+------+
+ l
+ V
+ oblist bone where the atom list began
+
+
+These lists cannot be acessed directly by the user, too.
+*)
+
+
+
+PROC x initialize oblist and heap size:
+ node (1).status := text data;
+ node (1).head := 32 (* blank *);
+ node (1).tail := 1;
+ INT VAR i;
+ FOR i FROM 2 UPTO 28 REP
+ node (i).status := oblist bone;
+ node (i).head := i
+ PER;
+ CONCR (heap).size := 28.
+
+node:
+ CONCR (heap).node.
+
+END PROC x initialize oblist and heap size;
+
+
+(*++++++++++++++++++++++++++++++ oblist dump +++++++++++++++++++++++++++++*)
+
+
+SYM VAR actual oblist bone :: SYM :(0),
+ actual atom :: SYM :(0);
+
+
+PROC begin oblist dump:
+ actual oblist bone := SYM :(2);
+ actual atom := SYM :(2)
+END PROC begin oblist dump;
+
+
+SYM PROC next atom:
+ actual atom := x head (actual atom);
+ WHILE no more atoms in this atom list REP
+ try next oblist bone
+ PER;
+ actual atom.
+
+no more atoms in this atom list:
+ (* NIL is given as last atom when 'next atom' is called repeatedly, so *)
+ (* it can serve as a terminator. So NIL "does not count" if it is *)
+ (* encountered during one of the calls. *)
+ IF null (actual atom) THEN
+ actual atom := x head (actual atom)
+ FI;
+ eq (actual atom, actual oblist bone).
+
+try next oblist bone:
+ IF actual oblist bone is last oblist bone THEN
+ actual atom := SYM :(2);
+ LEAVE next atom WITH nil
+ FI;
+ CONCR (actual oblist bone) INCR 1;
+ actual atom := x head (actual oblist bone).
+
+actual oblist bone is last oblist bone:
+ CONCR (actual oblist bone) = 28.
+
+END PROC next atom;
+
+
+(*+++++++++++++++++++++++ atom search and creation +++++++++++++++++++++++*)
+
+
+SYM VAR predecessor, result;
+ (* Variables used for communication between the internal search *)
+ (* procedures and the procedures calling them. *)
+
+
+SYM PROC atom (TEXT CONST name):
+ x search atom (name);
+ IF atom not already existing THEN
+ nil
+ ELSE
+ result
+ FI.
+
+atom not already existing:
+ x status (result) = oblist bone.
+
+END PROC atom;
+
+
+SYM PROC new atom (TEXT CONST name):
+ x search atom (name);
+ IF atom not already existing THEN
+ x create new atom (name);
+ FI;
+ result.
+
+atom not already existing:
+ x status (result) = oblist bone.
+
+END PROC new atom;
+
+
+PROC create atom (TEXT CONST name):
+ x search atom (name);
+ IF atom already existing THEN
+ error stop ("Atom " + name + " existiert bereits")
+ ELSE
+ x create new atom (name)
+ FI.
+
+atom already existing:
+ x status (result) <> oblist bone.
+
+END PROC create atom;
+
+
+PROC delete atom (SYM CONST atom):
+ IF is named atom (atom) THEN
+ IF null (atom) OR eq (atom, pname) THEN
+ error stop ("Dies Atom darf nicht geloescht werden")
+ ELSE
+ search predecessor;
+ delete atom from atom list
+ FI
+ ELSE
+ error stop ("Nur benannte Atome können geloescht werden")
+ FI.
+
+search predecessor:
+ predecessor := x head (atom);
+ WHILE NOT eq (x head (predecessor), atom) REP
+ predecessor := x head (predecessor)
+ PER.
+
+delete atom from atom list:
+ x set head (predecessor, x head (atom)).
+
+END PROC delete atom;
+
+
+PROC x search atom (TEXT CONST name):
+ CONCR (result) := (code (name SUB 1) + 17) MOD 27 + 2;
+ (* This formula places the list of atoms beginning with "§" at the *)
+ (* first oblist bone, the list of atoms beginning with "A" at the *)
+ (* at the second one, and so on. (See also the big comment in lines *)
+ (* 600 - 700) *)
+ REP
+ predecessor := result;
+ result := x head (predecessor);
+ UNTIL end of atom list reached COR right atom found PER.
+
+end of atom list reached:
+ x status (result) = oblist bone.
+
+right atom found:
+ SYM VAR actual character node := property (result, pname);
+ IF NOT is text (actual character node) THEN
+ x lisp error ("Namen erwartet");
+ LEAVE right atom found WITH FALSE
+ FI;
+ IF CONCR (x head (actual character node)) <> length (name) THEN
+ FALSE
+ ELSE
+ INT VAR i;
+ FOR i FROM 1 UPTO length (name) REP
+ to next character node;
+ check wether is character data node;
+ check wether character matches;
+ PER;
+ TRUE
+ FI.
+
+to next character node:
+ actual character node := x tail (actual character node).
+
+check wether is character data node:
+ IF x status (actual character node) <> character data THEN
+ x lisp error ("Zeichenkette erwartet");
+ LEAVE right atom found WITH FALSE
+ FI.
+
+check wether character matches:
+ IF code (name SUB i) <> CONCR (x head (actual character node)) THEN
+ LEAVE right atom found WITH FALSE
+ FI.
+
+END PROC x search atom;
+
+
+PROC x create new atom (TEXT CONST name):
+ (* It is necessary that 'x search atom' has been executed before *)
+ (* calling 'x create new atom' because this procedure relies on the *)
+ (* value of 'predecessor'. *)
+ enable stop;
+ SYM CONST sym name :: sym (name);
+ IF CONCR (heap).size + 3 > max size THEN
+ error stop ("LISP Heap Ueberlauf")
+ FI;
+ result := newly created atom;
+ x set head (predecessor, result).
+
+newly created atom:
+ x new node (atomic, CONCR (oblist bone node), CONCR (property list)).
+
+oblist bone node:
+ x head (predecessor).
+
+property list:
+ x new node (property indicator, CONCR (pname), property root node).
+
+property root node:
+ CONCR (x new node (property root, CONCR (sym name), CONCR (nil))).
+
+END PROC x create new atom;
+
+
+(************************* property list handling *************************)
+
+(*
+The property lists consist of chained units of the structure
+
+ +--------------------+ +---------------+
+ l property indicator l l property root l
+ +----------+---------+ +-------+-------+
+ l o l o----+-->l o l o---+--> . . .
+ +----+-----+---------+ +---+---+-------+
+ l l
+ V V
+ property id property
+
+
+or
+
+ +----------------+
+ l flag indicator l
+ +--------+-------+
+ l o l o---+--> . . .
+ +---+----+-------+
+ l
+ V
+ flag id
+
+
+
+The property lists cannot be altered or read directly, too.
+
+For property list handling there exist procedures that insert, change, read
+and delete properties resp. flags. Thus, the only thing that can be done
+with any property of an atom without using these special procedures, is
+comparing to or 'cons'ing with some other S-expression.
+At any given time the property list of any atom (including 'NIL') contains
+the property 'PNAME' giving the print name of the atom, stored as a list of
+characters. This special property cannot be altered, overwritten by 'add
+property' or deleted.
+*)
+
+
+(*++++++++++++++++++++++++++ property list dump ++++++++++++++++++++++++++*)
+
+
+SYM VAR actual property list node :: nil;
+
+
+PROC begin property list dump (SYM CONST atom):
+ actual property list node := x tail (atom)
+END PROC begin property list dump;
+
+
+PROC next property (SYM VAR property id, property):
+ IF null (actual property list node) THEN
+ property id := nil;
+ property := nil
+ ELSE
+ SELECT x status (actual property list node) OF
+ CASE flag indicator: get flag id
+ CASE property indicator: get property id and property
+ OTHERWISE x lisp error ("Flagge oder Eigenschaft erwartet und nicht: "
+ + text (x status (actual property list node)))
+ END SELECT
+ FI.
+
+get flag id:
+ property id := x head (actual property list node);
+ actual property list node := x tail (actual property list node);
+ property := nil.
+
+get property id and property:
+ property id := x head (actual property list node);
+ actual property list node := x tail (actual property list node);
+ IF x status (actual property list node) = property root THEN
+ property := x head (actual property list node);
+ actual property list node := x tail (actual property list node)
+ ELSE
+ x lisp error ("Eigenschaftswurzel erwartet, nicht:" +
+ text (x status (actual property list node)));
+ property := nil
+ FI.
+
+END PROC next property;
+
+
+(*+++++++++++++++++++++++++++++ properties +++++++++++++++++++++++++++++++*)
+
+
+SYM VAR last atom :: SYM :(0),
+ p list predecessor,
+ p list result;
+
+
+PROC add property (SYM CONST atom, property id, property):
+ IF eq (property id, pname) THEN
+ errorstop ("Der PNAME eines Atoms darf nicht versteckt sein")
+ ELSE
+ IF CONCR (heap).size + 2 > max size THEN
+ error stop ("LISP Heap Ueberlauf");
+ LEAVE add property
+ FI;
+ x set tail (atom, new property plus old property list);
+ IF eq (atom, last atom) AND
+ eq (property id, x head (p list result)) THEN
+ p list predecessor := atom;
+ p list result := x tail (atom)
+ FI
+ FI.
+
+new property plus old property list:
+ x new node (property indicator,
+ CONCR (property id), CONCR (property root plus old property list)).
+
+property root plus old property list:
+ x new node (property root, CONCR (property), CONCR (old property list)).
+
+old property list:
+ x tail (atom)
+
+END PROC add property;
+
+
+PROC alter property (SYM CONST atom, property id, new property):
+ IF eq (property id, pname) THEN
+ error stop ("Namen kann man nicht aendern")
+ ELSE
+ x search property id (atom, property id);
+ IF null (p list result) THEN
+ error stop ("Eigenschaft existiert nicht")
+ ELSE
+ x set head (x tail (p list result), new property)
+ FI
+ FI
+END PROC alter property;
+
+
+SYM PROC property (SYM CONST atom, property id):
+ x search property id (atom, property id);
+ IF null (p list result) THEN
+ nil
+ ELSE
+ x head (x tail (p list result))
+ FI
+END PROC property;
+
+
+PROC delete property (SYM CONST atom, property id):
+ IF eq (property id, pname) THEN
+ errorstop ("Der Name eines Atoms darf nicht geloescht werden")
+ ELSE
+ x search property id (atom, property id);
+ IF NOT null (p list result) THEN
+ x set tail (p list predecessor, x tail (x tail (p list result)));
+ last atom := SYM :(0)
+ FI
+ FI
+END PROC delete property;
+
+
+BOOL PROC property exists (SYM CONST atom, property id):
+ x search property id (atom, property id);
+ NOT null (p list result)
+END PROC property exists;
+
+
+PROC x search property id (SYM CONST atom, property id):
+ IF eq (last atom, atom) AND eq (x head (p list result), property id) THEN
+ LEAVE x search property id
+ FI;
+ last atom := atom;
+ p list predecessor := atom;
+ REP
+ p list result := x tail (p list predecessor);
+ IF end of property list THEN
+ last atom := SYM :(0);
+ LEAVE x search property id
+ FI;
+ SELECT x status (p list result) OF
+ CASE flag indicator: p list predecessor := p list result
+ CASE property indicator: check wether property root node follows;
+ IF correct property id found THEN
+ LEAVE x search property id
+ ELSE
+ p list predecessor := xtail (p list result)
+ FI
+ CASE property root: xlisperror("Unordentliche Eigenschaftwurzel");
+ p list result := nil;
+ last atom := SYM :(0);
+ LEAVE x search property id
+ OTHERWISE x lisp error ("Eigenschaften erwartet und nicht: " +
+ text (x status (p list result)));
+ p list result := nil;
+ last atom := SYM :(0);
+ LEAVE x search property id
+ END SELECT
+ PER.
+
+end of property list:
+ null (p list result).
+
+check wether property root node follows:
+ IF x status (x tail (p list result)) <> property root THEN
+ x lisp error ("Eigenschaftswurzel erwartet");
+ p list result := nil;
+ last atom := SYM :(0);
+ LEAVE x search property id
+ FI.
+
+correct property id found:
+ eq (x head (p list result), property id).
+
+END PROC x search property id;
+
+
+(*++++++++++++++++++++++++++++++++ flags +++++++++++++++++++++++++++++++++*)
+
+
+PROC add flag (SYM CONST atom, flag id):
+ enable stop;
+ x set tail (atom, new flag plus old property list).
+
+new flag plus old property list:
+ x new node (flag indicator, CONCR (flag id), old property list).
+
+old property list:
+ CONCR (x tail (atom))
+
+END PROC add flag;
+
+
+BOOL PROC flag (SYM CONST atom, flag id):
+ x search flag id (atom, flag id);
+ NOT null (result)
+END PROC flag;
+
+
+PROC delete flag (SYM CONST atom, flag id):
+ x search flag id (atom, flag id);
+ IF NOT (is error COR null (result)) THEN
+ x set tail (predecessor, x tail (result))
+ FI
+END PROC delete flag;
+
+
+PROC x search flag id (SYM CONST atom, flag id):
+ predecessor := atom;
+ REP
+ result := x tail (predecessor);
+ IF end of property list THEN
+ LEAVE x search flag id
+ FI;
+ SELECT x status (result) OF
+ CASE property root, property indicator: predecessor := result
+ CASE flag indicator: IF correct flag id found THEN
+ LEAVE x search flag id
+ ELSE
+ predecessor := result
+ FI
+ OTHERWISE x lisp error ("Eigenschaften erwartet und nicht:" +
+ text (x status (result)));
+ result := nil;
+ LEAVE x search flag id
+ END SELECT
+ PER.
+
+end of property list:
+ null (result).
+
+correct flag id found:
+ eq (x head (result), flag id).
+
+END PROC x search flag id;
+
+
+(****** Conversion of non-LISP data to LISP structures and vice versa *****)
+
+
+TEXT PROC text (SYM CONST sym):
+ IF is text (sym) THEN
+ TEXT VAR result := "";
+ SYM VAR actual node :: sym;
+ INT VAR i;
+ FOR i FROM 1 UPTO CONCR (x head (sym)) REP
+ actual node := x tail (actual node);
+ result CAT actual character
+ PER;
+ result
+ ELSE
+ error stop ("ist kein text");
+ ""
+ FI.
+
+actual character:
+ IF x status (actual node) <> character data THEN
+ x lisp error ("Zeichenfolge erwartet");
+ LEAVE text WITH result
+ FI;
+ code (CONCR (x head (actual node))).
+
+END PROC text;
+
+
+BOOL PROC is text (SYM CONST sym):
+ x status (sym) = text data
+END PROC is text;
+
+
+SYM PROC sym (TEXT CONST text):
+ SYM VAR result :: x new node (text data,
+ length (text), CONCR (nil)),
+ actual character node :: result;
+ INT VAR length of text;
+ ignore blanks at end of text;
+ INT VAR i;
+ FOR i FROM 1 UPTO length of text REP
+ x set tail (actual character node, new next character node);
+ actual character node := x tail (actual character node)
+ PER;
+ result.
+
+ignore blanks at end of text:
+ FOR length of text FROM length (text) DOWNTO 0 REP
+ IF (text SUB length of text) <> " " THEN
+ LEAVE ignore blanks at end of text
+ FI
+ PER;
+ length of text := 0.
+
+new next character node:
+ x new node (character data, code (text SUB i), 1).
+
+END PROC sym;
+
+
+INT PROC character (SYM CONST sym):
+ IF x status (sym) = character data THEN
+ CONCR (x head (sym))
+ ELSE
+ error stop ("ist kein Charakter");
+ -1
+ FI
+END PROC character;
+
+
+BOOL PROC is character (SYM CONST sym):
+ x status (sym) = character data
+END PROC is character;
+
+
+SYM PROC sym character (INT CONST char):
+ x new node (character data, char MOD 256, 1)
+END PROC sym character;
+
+
+INT PROC int 1 (SYM CONST sym):
+ IF x status (sym) = int data THEN
+ CONCR (x head (sym))
+ ELSE
+ error stop ("ist keine Zahl");
+ -1
+ FI
+END PROC int 1;
+
+
+INT PROC int 2 (SYM CONST sym):
+ IF x status (sym) = int data THEN
+ CONCR (x tail (sym))
+ ELSE
+ error stop ("ist keine Zahl");
+ -1
+ FI
+END PROC int 2;
+
+
+BOOL PROC is int pair (SYM CONST sym):
+ x status (sym) = int data
+END PROC is int pair;
+
+
+SYM PROC sym (INT CONST int 1, int 2):
+ x new node (int data, int 1, int 2)
+END PROC sym;
+
+
+(********************* internal error routine *****************************)
+
+
+PROC x lisp error (TEXT CONST error message):
+ error stop (""13"LISP SYSTEM FEHLER: " + error message )
+END PROC x lisp error;
+
+
+END PACKET lisp heap and oblist management;
+
+
+
+PACKET name (* Autor: J.Durchholz *)
+ (* Datum: 15.06.1982 *)
+ DEFINES (* Version 1.1.1 *)
+
+ name:
+
+TEXT PROC name (SYM CONST sym):
+ IF is named atom (sym) THEN
+ text (property (sym, pname))
+ ELSE
+ ""15"IST_KEIN_ATOM"14""
+ FI
+END PROC name;
+
+
+END PACKET name;
+
+
+
+PACKET lisp storage info (* Autor: J.Durchholz *)
+ (* Datum: 23.08.1982 *)
+ DEFINES (* Version 1.1.1 *)
+
+ lisp storage info:
+
+
+PROC lisp storage info:
+ INT VAR size, used;
+ lisp storage (size, used);
+ out (""13""10" ");
+ put (used);
+ put ("Knoten von");
+ put (size);
+ put line ("Knoten des LISP-Heaps sind belegt!")
+END PROC lisp storage info;
+
+
+END PACKET lisp storage info;
+
diff --git a/lisp/lisp.2 b/lisp/lisp.2
new file mode 100644
index 0000000..28e6924
--- /dev/null
+++ b/lisp/lisp.2
@@ -0,0 +1,584 @@
+PACKET character buffer (* Autor : J.Durchholz *)
+ (* Datum : 09.05.1984 *)
+ DEFINES (* Version 1.7.2 *)
+ (* 21.2.83. hey 293, 450,97,361 *)
+ get char,
+ line nr,
+ init char buffer:
+
+
+TEXT VAR buffer;
+INT VAR pointer,
+ line;
+
+
+INT PROC line nr:
+ line
+END PROC line nr;
+
+
+PROC init char buffer:
+ buffer := "";
+ pointer := 1;
+ line := 0;
+END PROC init char buffer;
+
+
+PROC get char (FILE VAR f, TEXT VAR char):
+ IF buffer empty THEN
+ try to find nonempty line and put it into buffer;
+ char := " ";
+ pointer := 1
+ ELSE
+ char := buffer SUB pointer;
+ pointer INCR 1
+ FI.
+
+buffer empty:
+ pointer > length (buffer).
+
+try to find nonempty line and put it into buffer:
+ REP
+ IF eof (f) THEN
+ char := "";
+ LEAVE get char
+ FI;
+ get line (f, buffer);
+ line INCR 1
+ UNTIL buffer <> "" PER.
+
+END PROC get char;
+
+
+END PACKET character buffer;
+
+
+
+
+PACKET lisp io (* Autor: J.Durchholz *)
+ (* Datum: 10.09.1982 *)
+ DEFINES (* Version 4.1.3 *)
+ (* Änderung: notebook *)
+ put, note, (* 13.3.86 I. Ley *)
+ verbose lisp output,
+ get,
+ get all:
+
+
+BOOL VAR verbose :: FALSE;
+
+
+PROC verbose lisp output (BOOL CONST b):
+ verbose := b
+END PROC verbose lisp output;
+
+BOOL PROC verbose lisp output:
+ verbose
+END PROC verbose lisp output;
+
+
+PROC put (SYM CONST sym):
+ IF atom (sym) THEN
+ put atom
+ ELSE
+ put structure
+ FI.
+
+put atom:
+ IF is named atom (sym) THEN
+ put (name (sym))
+ ELIF is int pair (sym) THEN
+ put (int 1 (sym))
+ ELIF is text (sym) THEN
+ IF verbose THEN
+ TEXT VAR buffer :: text (sym);
+ change all (buffer, """", """""");
+ buffer CAT """";
+ put ("""" + buffer)
+ ELSE
+ write (text (sym))
+ FI
+ ELIF is character (sym) THEN
+ IF verbose THEN
+ buffer := "'";
+ buffer CAT code (character (sym));
+ buffer CAT "'";
+ put (buffer)
+ ELSE
+ out (code (character (sym)))
+ FI
+ ELSE
+ put (""15"UNBEKANNTER_ATOM_TYP"14"")
+ FI.
+
+put structure:
+ put ("(");
+ SYM VAR actual node := sym;
+ REP
+ put (head (actual node));
+ actual node := tail (actual node)
+ UNTIL atom (actual node) PER;
+ IF NOT null (actual node) THEN
+ put (".");
+ put (actual node)
+ FI;
+ put (")").
+
+END PROC put;
+
+PROC put (FILE VAR f, SYM CONST sym):
+ IF atom (sym) THEN
+ put atom
+ ELSE
+ put structure
+ FI.
+
+put atom:
+ IF is named atom (sym) THEN
+ put (f, name (sym))
+ ELIF is int pair (sym) THEN
+ put (f, int 1 (sym))
+ ELIF is text (sym) THEN
+ IF verbose THEN
+ TEXT VAR buffer :: text (sym);
+ change all (buffer, """", """""");
+ buffer CAT """";
+ put (f, """" + buffer)
+ ELSE
+ put (f, text (sym))
+ FI
+ ELIF is character (sym) THEN
+ IF verbose THEN
+ buffer := "'";
+ buffer CAT code (character (sym));
+ buffer CAT "'";
+ put (f, buffer)
+ ELSE
+ put (f, code (character (sym)))
+ FI
+ ELSE
+ put ( f, ""15"UNBEKANNTER_ATOM_TYP"14"")
+ FI.
+
+put structure:
+ put (f, "(");
+ SYM VAR actual node := sym;
+ REP
+ put (f, head (actual node));
+ actual node := tail (actual node)
+ UNTIL atom (actual node) PER;
+ IF NOT null (actual node) THEN
+ put (f, ".");
+ put (f, actual node)
+ FI;
+ put (f, ")").
+
+END PROC put;
+
+ PROC note (SYM CONST sym):
+ IF atom (sym) THEN
+ note atom
+ ELSE
+ note structure
+ FI.
+
+note atom:
+ IF is named atom (sym) THEN
+ note ( name (sym))
+ ELIF is int pair (sym) THEN
+ note (int 1 (sym))
+ ELIF is text (sym) THEN
+ IF verbose THEN
+ TEXT VAR buffer :: text (sym);
+ change all (buffer, """", """""");
+ buffer CAT """";
+ note ( """" + buffer)
+ ELSE
+ note ( text (sym))
+ FI
+ ELIF is character (sym) THEN
+ IF verbose THEN
+ buffer := "'";
+ buffer CAT code (character (sym));
+ buffer CAT "'";
+ note ( buffer)
+ ELSE
+ note ( code (character (sym)))
+ FI
+ ELSE
+ note ( ""15"UNBEKANNTER_ATOM_TYP"14"")
+ FI.
+
+note structure:
+ note ( "(");
+ SYM VAR actual node := sym;
+ REP
+ note ( head (actual node));
+ actual node := tail (actual node)
+ UNTIL atom (actual node) PER;
+ IF NOT null (actual node) THEN
+ note ( ".");
+ note ( actual node)
+ FI;
+ note ( ")").
+
+END PROC note;
+
+PROC get (FILE VAR f, SYM VAR s):
+ initialize scanner (f);
+ IF NOT get s expression (s) THEN
+ error ("LISP-Ausdruck erwartet")
+ FI;
+ scanner postprocessing (f)
+END PROC get;
+
+
+(**************************** parser for 'get' ****************************)
+
+
+LET end of file type = 0,
+ name type = 1,
+ text type = 2,
+ character type = 3,
+ int type = 4,
+ other char type = 5;
+
+
+BOOL PROC get s expression (SYM VAR s):
+ (* The boolean result indicates wether the error has not occurred that *)
+ (* 'get next symbol' was called, but then the symbol was not expected *)
+ (* and thus could not be processed. *)
+ get next symbol;
+ SELECT symbol type OF
+ CASE end of file type: FALSE
+ CASE name type: s := new atom (symbol); TRUE
+ CASE text type: s := sym (symbol); TRUE
+ CASE character type: s := sym character (code (symbol)); TRUE
+ CASE int type: s := sym (int (symbol), -1); TRUE
+ CASE other char type: get structure
+ OTHERWISE error ("EINLESEFEHLER: unbekannter Symboltyp: " +
+ text (symbol type)); TRUE
+ END SELECT.
+
+get structure:
+ IF symbol <> "(" THEN
+ FALSE
+ ELSE
+ get list;
+ IF symbol type <> other char type OR symbol <> ")" THEN
+ error (">> ) << erwartet");
+ FALSE
+ ELSE
+ TRUE
+ FI
+ FI.
+
+get list:
+ SYM VAR father, son;
+ IF get s expression (son) THEN
+ get list elements;
+ ELSE
+ s := nil
+ FI.
+
+get list elements:
+ father := cons (son, nil);
+ s := father;
+ WHILE get s expression (son) REP
+ set tail (father, cons (son, nil));
+ father := tail (father)
+ PER;
+ IF symbol type = other char type AND symbol = "." THEN
+ IF get s expression (son) THEN
+ set tail (father, son);
+ get next symbol
+ ELSE
+ error ("LISP-Ausdruck nach dem Punkt erwartet")
+ FI
+ FI.
+
+END PROC get s expression;
+
+
+(********************* scanner for 'get x espression' *********************)
+
+
+FILE VAR infile;
+
+
+PROC initialize scanner (FILE CONST f):
+ infile := f;
+ no input errors := TRUE;
+ init char buffer;
+ get char (infile, actual char)
+END PROC initialize scanner;
+
+
+PROC scanner postprocessing (FILE VAR f):
+ f := infile
+END PROC scanner postprocessing;
+
+
+TEXT VAR symbol; INT VAR symbol type;
+
+
+PROC get next symbol:
+ skip blanks;
+ IF actual char = "" THEN
+ symbol := "DATEIENDE";
+ symbol type := end of file type
+ ELIF is letter THEN
+ get name
+ ELIF is digit or sign THEN
+ get integer
+ ELIF is double quote THEN
+ get text
+ ELIF is single quote THEN
+ get character
+ ELSE
+ get other char
+ FI .
+
+is letter:
+ IF "a" <= actual char AND actual char <= "z" THEN
+ actual char := code (code (actual char) - code ("a") + code ("A"));
+ TRUE
+ ELSE
+ "§" <= actual char AND actual char <= "Z"
+ FI.
+
+get name:
+ symbol type := name type;
+ symbol := actual char;
+ REP
+ get char (infile, actual char);
+ IF is neither letter nor digit THEN
+ LEAVE get name
+ FI;
+ symbol CAT actual char
+ PER.
+
+is neither letter nor digit:
+ NOT (is letter OR is digit OR is underscore).
+
+is digit:
+ "0" <= actual char AND actual char <= "9".
+
+is underscore:
+ actual char = "_".
+
+is digit or sign:
+ is digit OR actual char = "+" OR actual char = "-".
+
+get integer:
+ symbol type := int type;
+ IF actual char = "+" THEN
+ get char (infile, actual char);
+ skip blanks;
+ symbol := actual char
+ ELIF actual char = "-" THEN
+ symbol := "-";
+ get char (infile, actual char);
+ skip blanks;
+ symbol CAT actual char
+ ELSE
+ symbol := actual char
+ FI;
+ REP
+ get char (infile, actual char);
+ IF NOT is digit THEN
+ LEAVE get integer
+ FI;
+ symbol CAT actual char
+ PER.
+
+is double quote:
+ actual char = """".
+
+get text:
+ symbol := "";
+ symbol type := text type;
+ REP
+ get char (infile, actual char);
+ IF is double quote THEN
+ get char (infile, actual char);
+ IF NOT is double quote THEN LEAVE get text
+ FI
+ ELIF actual char = "" THEN LEAVE get text (*hey*)
+ FI;
+ symbol CAT actual char
+ PER.
+
+is single quote:
+ actual char = "'".
+
+get character:
+ symbol type := character type;
+ get char (infile, symbol);
+ get char (infile, actual char);
+ IF actual char <> "'" THEN
+ error (">> ' << erwartet")
+ ELSE
+ get char (infile, actual char)
+ FI.
+
+get other char:
+ symbol type := other char type;
+ symbol := actual char;
+ get char (infile, actual char).
+
+END PROC get next symbol;
+
+
+TEXT VAR actual char;
+
+
+PROC skip blanks:
+ INT VAR comment depth :: 0;
+ WHILE is comment OR actual char = " " REP
+ get char (infile, actual char)
+ PER.
+
+is comment:
+ IF actual char = "{" THEN
+ comment depth INCR 1;
+ TRUE
+ ELIF actual char = "}" THEN
+ IF comment depth = 0 THEN
+ error (">> { << fehlt")
+ ELSE
+ comment depth DECR 1
+ FI;
+ TRUE
+ ELSE
+ IF comment depth > 0 THEN
+ IF actual char = "" THEN
+ error ("DATEIENDE im Kommentar");
+ FALSE
+ ELSE
+ TRUE
+ FI
+ ELSE
+ FALSE
+ FI
+ FI.
+
+END PROC skip blanks;
+
+
+BOOL VAR no input errors;
+FILE VAR errors;
+
+
+PROC error (TEXT CONST error message):
+ out ("FEHLER in Zeile ");
+ out (text (line nr));
+ out (" bei >> ");
+ out (symbol);
+ out (" << : ");
+ out (error message);
+ line;
+ IF no input errors THEN
+ no input errors := FALSE;
+ errors := notefile; modify(errors);
+ headline (errors, "Einlesefehler"); output(errors)
+ FI;
+ write (errors, "FEHLER in Zeile ");
+ write (errors, text (line nr));
+ write (errors, " bei >> ");
+ write (errors, symbol);
+ write (errors, " << : ");
+ write (errors, error message);
+ line (errors)
+END PROC error;
+
+
+PROC get (SYM VAR sym): (*hey*)
+ disable stop;
+ FILE VAR in :: sequential file (modify, "LISP INPUT"),
+ out :: notefile; modify (out);
+ headline (out,"LISP OUTPUT");
+ headline (in, "LISP INPUT");
+ noteedit (in);
+ input (in);
+ get (in, sym);
+ WHILE NOT no input errors AND NOT is error REP
+ modify (errors);
+ headline (errors, " LISP-Fehlermeldungen");
+ headline (in, " Bitte KORREKTEN LISP-Ausdruck");
+ noteedit (in);
+ headline (errors, "notebook");
+ input (in);
+ get (in, sym)
+ PER;
+END PROC get;
+
+
+PROC get all (FILE VAR f, SYM VAR sym):
+ get (f, sym);
+ skip blanks;
+ IF NOT eof (infile) THEN
+ error ("Hinter dem letzten Symbol des LISP-Ausdruck stehen noch Zeichen")
+ FI
+END PROC get all;
+
+
+END PACKET lisp io;
+
+
+
+PACKET lisp integer (* Autor: J.Durchholz *)
+ (* Datum: 30.08.1982 *)
+ DEFINES (* Version 1.1.2 *)
+
+ sum,
+ difference,
+ product,
+ quotient,
+ remainder:
+
+SYM PROC sum (SYM CONST summand list):
+ INT VAR result := 0;
+ SYM VAR list rest := summand list;
+ WHILE NOT atom (list rest) REP
+ result INCR int 1 (head (list rest));
+ list rest := tail (list rest)
+ PER;
+ IF NOT null (list rest) THEN
+ error stop ("Summandenliste endet falsch")
+ FI ;
+ sym (result, -1)
+END PROC sum;
+
+
+SYM PROC difference (SYM CONST minuend, subtrahend):
+ sym (int 1 (minuend) - int 1 (subtrahend), -1)
+END PROC difference;
+
+
+SYM PROC product (SYM CONST factor list):
+ INT VAR result := 1;
+ SYM VAR list rest := factor list;
+ WHILE NOT atom (list rest) REP
+ result := result * int 1 (head (list rest));
+ list rest := tail (list rest)
+ PER;
+ IF NOT null (list rest) THEN
+ error stop ("Faktorenliste endet falsch")
+ FI;
+ sym (result, -1)
+END PROC product;
+
+
+SYM PROC quotient (SYM CONST dividend, divisor):
+ sym (int 1 (dividend) DIV int 1 (divisor), -1)
+END PROC quotient;
+
+
+SYM PROC remainder(SYM CONST dividend, divisor):
+ sym (int 1 (dividend) MOD int 1 (divisor), -1)
+END PROC remainder;
+
+
+END PACKET lisp integer;
+
diff --git a/lisp/lisp.3 b/lisp/lisp.3
new file mode 100644
index 0000000..a93463c
--- /dev/null
+++ b/lisp/lisp.3
@@ -0,0 +1,767 @@
+PACKET lisp heap maintenance (* Autor: J.Durchholz *)
+ (* Datum: 09.05.1984 *)
+ DEFINES (* Version 1.7.2 *)
+ (* Testhilfe *)
+ create lisp system, (* hey, 02.3.83 : 121,334,542,732 *)
+ dump oblist:
+
+
+PROC create lisp system (FILE VAR f, DATASPACE CONST new heap):
+ initialize lisp system (new heap);
+ input (f);
+ WHILE NOT eof (f) REP
+ TEXT VAR name;
+ get (f, name);
+ SYM CONST s :: new atom (name);
+ get (f, name);
+ SYM CONST property name :: new atom (name);
+ IF NOT null (property name) THEN
+ SYM VAR property;
+ get (f, property);
+ add property (s, property name, property)
+ FI
+ PER
+END PROC create lisp system;
+
+
+PROC dump oblist (FILE VAR f):
+ begin oblist dump;
+ REP
+ SYM CONST actual atom :: next atom;
+ put line (f, name (actual atom));
+ dump property list
+ UNTIL null (actual atom) PER.
+
+dump property list:
+ begin property list dump (actual atom);
+ REP
+ SYM VAR id, value;
+ next property (id, value);
+ write (f, " ");
+ write (f, name (id));
+ write (f, " ");
+ write (f, name (value));
+ line (f)
+ UNTIL null (id) AND null (value) PER.
+
+END PROC dump oblist;
+
+
+PROC dump oblist:
+ begin oblist dump;
+ REP
+ SYM CONST actual atom :: next atom;
+ put line (name (actual atom));
+ dump property list
+ UNTIL null (actual atom) PER.
+
+dump property list:
+ begin property list dump (actual atom);
+ REP
+ SYM VAR id, value;
+ next property (id, value);
+ out (" ");
+ out (name (id));
+ out (" ");
+ put line (name (value));
+ UNTIL null (id) AND null (value) PER.
+
+END PROC dump oblist;
+
+
+END PACKET lisp heap maintenance;
+
+
+
+PACKET lisp interpreter (* Autor: J.Durchholz *)
+ (* Datum: 27.12.1982 *)
+ DEFINES (* Version 3.1.7 *)
+ evalquote,
+ apply,
+ eval,
+ try:
+
+
+(* SYM-objects used by the interpreter. They all point to constant structure
+ within the heap. As their address may change during garbage collection,
+ it must be possible to correct the references to them made by the
+ SYM-objects. That is the reason why they are declared VAR instead of CONST*)
+SYM VAR lambda constant,
+ label constant,
+ quote constant,
+ function constant,
+ indefinite constant,
+ apval constant,
+ true constant,
+ false constant;
+
+SYM VAR errors;
+BOOL VAR trace :: FALSE;
+
+PROC initialize constants:
+ lambda constant := new atom ("LAMBDA");
+ label constant := new atom ("LABEL");
+ quote constant := new atom ("QUOTE");
+ function constant := new atom ("FUNCTION");
+ indefinite constant := new atom ("INDEFINITE");
+ apval constant := new atom ("APVAL");
+ true constant := new atom ("T");
+ false constant := new atom ("F");
+ errors := new atom ("ERRORS")
+END PROC initialize constants;
+
+
+SYM PROC evalquote (SYM CONST expr): (*hey*)
+ enable stop;
+ initialize constants;
+ x apply ( head (expr), quote (tail (expr)), nil )
+END PROC evalquote;
+
+
+SYM PROC quote (SYM CONST x):
+ IF eq (x,nil) THEN nil
+ ELSE set head (x, new head); set tail (x, quote (tail(x))); x
+ FI .
+new head:
+ cons (quote constant, cons (head(x), nil) )
+END PROC quote;
+
+
+SYM PROC apply (SYM CONST function, argument list, alist):
+ enable stop;
+ initialize constants;
+ x apply (function, argument list, alist)
+END PROC apply;
+
+
+SYM PROC x apply (SYM CONST function, argument list, alist):
+ IF trace THEN line;
+ put ("a p p l y :"); put (function); line;
+ put ("arguments :"); put (argument list); line;
+ FI;
+ SYM VAR new alist;
+ initialize for alist insertion;
+ reduce actual fn to lambda expression;
+ insert parameter evaluated argument pairs in reversed order in new alist;
+ function body evaluation.
+
+reduce actual fn to lambda expression:
+ SYM VAR actual fn :: function;
+ REP
+ IF is named atom (actual fn) THEN
+ get function from property list of actual fn
+ or from functional alist entry
+ ELIF atom (actual fn) THEN
+ error stop ("Eine Funktion darf kein unbenanntes Atom sein")
+ ELSE
+ IF eq (head (actual fn), lambda constant) THEN
+ LEAVE reduce actual fn to lambda expression
+ ELIF eq (head (actual fn), label constant) THEN
+ get function from label expression and update alist
+ ELSE
+ error stop ("Funktion ist weder Atom noch LAMBDA-/LABEL-Ausdruck")
+ FI
+ FI
+ PER.
+
+get function from property list of actual fn or from functional alist entry:
+ IF property exists (actual fn, function constant) THEN
+ get function from property list of actual fn
+ ELSE
+ get function from functional alist entry
+ FI.
+
+get function from property list of actual fn:
+ actual fn := property (actual fn, function constant).
+
+get function from functional alist entry:
+ SYM VAR actual alist entry;
+ begin alist retrieval;
+ REP
+ IF end of alist THEN
+ error stop ("Die Funktion " + name (actual fn) +
+ " ist nicht definiert")
+ FI;
+ search for next functional alist entry;
+ UNTIL eq (head (actual functional alist entry), actual fn) PER;
+ actual fn := tail (actual functional alist entry).
+
+get function from label expression and update alist:
+ actual fn := tail (actual fn);
+ IF atom (actual fn) COR
+ (NOT atom (head (actual fn)) OR atom (tail (actual fn))) COR
+ NOT null (tail (tail (actual fn))) THEN
+ error stop ("Ungueltiger LABEL-Ausdruck")
+ FI;
+ SYM VAR new alist entry;
+ prepare new functional alist entry;
+ set head (new alist entry, head (actual fn));
+ actual fn := head (tail (actual fn));
+ set tail (new alist entry, actual fn).
+
+insert parameter evaluated argument pairs in reversed order in new alist:
+ actual fn := tail (actual fn);
+ IF atom (actual fn) THEN
+ error stop ("Ungueltiger LAMBDA-Ausdruck")
+ FI;
+ SYM VAR parameter list rest :: head (actual fn),
+ argument list rest :: argument list;
+ actual fn := tail (actual fn);
+ WHILE NOT null (parameter list rest) REP
+ add next parameter argument pair to alist
+ PER;
+ check wether no arguments are left over.
+
+add next parameter argument pair to alist:
+ IF atom (parameter list rest) THEN
+ error stop ("Parameterliste endet falsch")
+ FI;
+ SYM VAR param pointer :: head (parameter list rest);
+ parameter list rest := tail (parameter list rest);
+ IF is named atom (param pointer) AND NOT null (param pointer) THEN
+ add parameter evaluated argument pair to alist;
+ advance argument list rest
+ ELIF atom (param pointer) THEN
+ error stop ("Unbenannte Atome und NIL koennen nicht Parameter sein")
+ ELSE
+ IF eq (head (param pointer), indefinite constant) THEN
+ check wether is last param;
+ advance param pointer;
+ IF eq (head (param pointer), quote constant) THEN
+ advance param pointer;
+ move param pointer to parameter;
+ add parameter indefinite quoted argument pair to alist
+ ELSE
+ move param pointer to parameter;
+ add parameter indefinite evaluated argument pair to alist
+ FI;
+ argument list rest := nil
+ ELIF eq (head (param pointer), quote constant) THEN
+ advance param pointer;
+ move param pointer to parameter;
+ add parameter quoted argument pair to alist;
+ advance argument list rest
+ ELIF eq (head (param pointer), function constant) THEN
+ advance param pointer;
+ move param pointer to parameter;
+ add parameter functional argument pair to alist;
+ advance argument list rest
+ ELSE
+ error stop ("Ungueltiger Parameter")
+ FI
+ FI.
+
+advance param pointer:
+ param pointer := tail (param pointer);
+ IF atom (param pointer) THEN
+ error stop ("Ungueltiger Parameter")
+ FI.
+
+move param pointer to parameter:
+ IF NOT null (tail (param pointer)) THEN
+ error stop ("Ungueltiger Parameter")
+ FI;
+ param pointer := head (param pointer);
+ IF NOT atom (param pointer) OR null (param pointer) THEN
+ error stop ("Unbenannte Atome und NIL koennen nicht Parameter sein")
+ FI.
+
+advance argument list rest:
+ argument list rest := tail (argument list rest).
+
+add parameter evaluated argument pair to alist:
+ prepare new alist entry;
+ set head (new alist entry, param pointer);
+ set tail (new alist entry, x eval (actual argument, alist)).
+
+check wether is last param:
+ IF NOT null (parameter list rest) THEN
+ error stop ("Ein INDEFINITE-Parameter muss der letzte sein")
+ FI.
+
+add parameter indefinite quoted argument pair to alist:
+ prepare new alist entry;
+ set head (new alist entry, param pointer);
+ set tail (new alist entry, argument list rest);
+ WHILE NOT atom (argument list rest) REP
+ argument list rest := tail (argument list rest)
+ PER;
+ IF NOT null (argument list rest) THEN
+ error stop ("Argumentliste endet falsch")
+ FI.
+
+add parameter indefinite evaluated argument pair to alist:
+ prepare new alist entry;
+ set head (new alist entry, param pointer);
+ last evaluated argument := new alist entry;
+ WHILE NOT atom (argument list rest) REP
+ set tail (last evaluated argument,
+ cons (x eval (head (argument list rest), alist), nil));
+ last evaluated argument := tail (last evaluated argument);
+ advance argument list rest
+ PER;
+ IF NOT null (argument list rest) THEN
+ error stop ("Argumentliste endet falsch")
+ FI.
+
+last evaluated argument:
+ param pointer.
+(* The value of param pointer is not used further, so the *)
+(* variable can be "reused" in this manner. *)
+
+add parameter quoted argument pair to alist:
+ prepare new alist entry;
+ set head (new alist entry, param pointer);
+ set tail (new alist entry, actual argument).
+
+add parameter functional argument pair to alist:
+ prepare new functional alist entry;
+ set head (new alist entry, param pointer);
+ set tail (new alist entry, actual argument).
+
+actual argument:
+ IF atom (argument list rest) THEN
+ IF null (argument list rest) THEN
+ error stop ("Zuwenig Argumente")
+ ELSE
+ error stop ("Argumentliste endet falsch")
+ FI
+ FI;
+ head (argument list rest).
+
+check wether no arguments are left over:
+ IF NOT null (argument list rest) THEN
+ error stop ("Zuviele Argumente")
+ FI.
+
+function body evaluation:
+ IF is int pair (actual fn) THEN
+ predefined function evaluation
+ ELIF atom (actual fn) COR NOT null (tail (actual fn)) THEN
+ error stop ("Ungueltiger LAMBDA-Ausdruck"); nil
+ ELSE
+ x eval (head (actual fn), new alist)
+ FI.
+
+predefined function evaluation:
+ SELECT int 1 (actual fn) OF
+ CASE 0: call eval cond
+ CASE 1: call begin oblist dump
+ CASE 2: call next atom
+ CASE 3: call add property
+ CASE 4: call alter property
+ CASE 5: call delete property
+ CASE 6: call property exists
+ CASE 7: call property
+ CASE 8: call add flag
+ CASE 9: call flag
+ CASE 10: call delete flag
+ CASE 11: call begin property list dump
+ CASE 12: call next property
+ CASE 13: call apply
+ CASE 14: call eval
+ CASE 15: call try
+ CASE 16: give association list
+ CASE 17: call error stop
+ CASE 18: call head
+ CASE 19: call set head
+ CASE 20: call tail
+ CASE 21: call set tail
+ CASE 22: call cons
+ CASE 23: call eq
+ CASE 24: call get sym
+ CASE 25: call put sym
+ CASE 26: call null
+ CASE 27: call is atom
+ CASE 28: call is named atom
+ CASE 29: call get named atom
+ CASE 30: call put named atom
+ CASE 31: call is text
+ CASE 32: call get text
+ CASE 33: call put text
+ CASE 34: call is character
+ CASE 35: call get character
+ CASE 36: call put character
+ CASE 37: call is int
+ CASE 38: call get int
+ CASE 39: call put int
+ CASE 40: call sum
+ CASE 41: call difference
+ CASE 42: call product
+ CASE 43: call quotient
+ CASE 44: call remainder
+ CASE 45: call equal
+ CASE 46: call trace
+ CASE 47: call define
+ CASE 48: call set
+ OTHERWISE error stop("Es gibt (noch) keine LISP-Funktion mit der Nummer"
+ + text (int 1 (actual fn)) ); nil
+ END SELECT.
+
+call eval cond:
+ x eval condition (arg 1, alist).
+
+call begin oblist dump:
+ begin oblist dump; nil.
+
+call next atom:
+ next atom.
+
+call add property:
+ add property (arg 3, arg 2, arg 1); arg 1.
+
+call alter property:
+ alter property (arg 3, arg 2, arg 1); arg 1.
+
+call delete property:
+ delete property (arg 2, arg 1); nil.
+
+call property exists:
+ IF property exists(arg 2,arg 1) THEN true constant ELSE false constant FI.
+
+call property:
+ property (arg 2, arg 1).
+
+call add flag:
+ add flag (arg 2, arg 1); nil.
+
+call flag:
+ IF flag (arg 2, arg 1) THEN true constant ELSE false constant FI.
+
+call delete flag:
+ delete flag (arg 2, arg 1); nil.
+
+call begin property list dump:
+ begin property list dump (arg 1); nil.
+
+call next property:
+ SYM VAR s1, s2; next property (s1, s2); cons (s1, s2).
+
+call apply:
+ x apply (arg 3, arg 2, arg 1).
+
+call eval:
+ x eval (arg 2, arg 1).
+
+call try:
+ x try (arg 4, arg 3, arg 2, arg 1).
+
+give association list:
+ alist.
+
+call error stop:
+ error stop (text (arg 1)); nil.
+
+call head:
+ head (arg 1).
+
+call set head:
+ set head (arg 2, arg 1); arg 2.
+
+call tail:
+ tail (arg 1).
+
+call set tail:
+ set tail (arg 2, arg 1); arg 2.
+
+call cons:
+ cons (arg 2, arg 1).
+
+call eq:
+ IF eq (arg 2, arg 1) THEN true constant ELSE false constant FI.
+
+call get sym:
+ get (s1); s1.
+
+call put sym:
+ put (arg 1); arg 1.
+
+call null:
+ IF null (arg 1) THEN true constant ELSE false constant FI.
+
+call is atom:
+ IF atom (arg 1) THEN true constant ELSE false constant FI.
+
+call is named atom:
+ IF is named atom (arg 1) THEN true constant ELSE false constant FI.
+
+call get named atom:
+ TEXT VAR t; get (t); new atom (t).
+
+call put named atom:
+ put (name (arg 1)); arg 1.
+
+call is text:
+ IF is text (arg 1) THEN true constant ELSE false constant FI.
+
+call get text:
+ get (t); sym (t).
+
+call put text:
+ put (text (arg 1)); arg 1.
+
+call is character:
+ IF is character (arg 1) THEN true constant ELSE false constant FI.
+
+call get character:
+ inchar (t); sym character (code (t)).
+
+call put character:
+ out (code (character (arg 1))); arg 1.
+
+call is int:
+ IF is int pair (arg 1) THEN true constant ELSE false constant FI.
+
+call get int:
+ INT VAR i; get (i); sym (i, -1).
+
+call put int:
+ put (int 1 (arg 1)); arg 1.
+
+call sum:
+ sum (arg 1).
+
+call difference:
+ difference (arg 2, arg 1).
+
+call product:
+ product (arg 1).
+
+call quotient:
+ quotient (arg 2, arg 1).
+
+call remainder:
+ remainder(arg 2, arg 1).
+
+call equal:
+ IF equal (arg 2, arg 1) THEN true constant ELSE false constant FI.
+
+call trace:
+ trace := NOT trace;
+ IF trace THEN true constant ELSE false constant FI .
+
+call define: (*hey*)
+ define (arg 1) .
+
+call set: (*hey*)
+ add property (new atom ( name (arg 2)), apval constant, arg 1); arg 1 .
+
+arg 1:
+ tail (head (new alist)).
+
+arg 2:
+ tail (head (tail (new alist))).
+
+arg 3:
+ tail (head (tail (tail (new alist)))).
+
+arg 4:
+ tail (head (tail (tail (tail (new alist))))).
+
+END PROC x apply;
+
+SYM PROC define (SYM CONST x): (*hey*)
+ IF eq (x, nil) THEN nil
+ ELSE add property (new atom (name (head (head (x)))),
+ function constant, tail (head (x)) );
+ cons (head (head (x)), define (tail (x)) )
+ FI .
+END PROC define;
+
+SYM VAR old alist :: nil;
+
+SYM PROC eval (SYM CONST expression, alist):
+ enable stop;
+ initialize constants;
+ x eval (expression, alist)
+END PROC eval;
+
+
+SYM PROC x eval (SYM CONST expression, alist): (*hey*)
+ IF trace THEN line;
+ put ("e v a l :"); put (expression); line;
+ IF NOT equal (alist, old alist) THEN
+ put ("bindings :"); old alist := alist; put (alist); line FI
+ FI;
+ IF atom (expression) THEN
+ IF is named atom (expression) THEN
+ value from property list of expression or from alist entry
+ ELSE
+ expression
+ FI
+ ELSE
+ x apply (head (expression), tail (expression), alist)
+ FI.
+
+value from property list of expression or from alist entry:
+ IF property exists (expression, apval constant) THEN
+ value from property list of expression
+ ELSE
+ value from alist entry
+ FI.
+
+value from property list of expression:
+ property (expression, apval constant).
+
+value from alist entry:
+ SYM VAR actual alist entry;
+ begin alist retrieval;
+ REP
+ IF end of alist THEN
+ error stop ("Das Atom " + name (expression) + " hat keinen Wert")
+ FI;
+ search for next alist entry
+ UNTIL eq (head (actual alist entry), expression) PER;
+ tail (actual alist entry).
+
+END PROC x eval;
+
+
+SYM PROC try (SYM CONST expression list, alist,
+ error output, break possible):
+ enable stop;
+ initialize constants;
+ x try (expression list, alist, error output, break possible)
+END PROC try;
+
+
+SYM PROC x try (SYM CONST expression list, alist,
+ error output, break possible):
+ BOOL CONST output :: bool (error output),
+ halt enabled :: bool (break possible);
+ SYM VAR expr list rest :: expression list;
+ REP
+ IF null (expr list rest) THEN
+ LEAVE x try WITH nil
+ ELIF atom (expr list rest) THEN
+ error stop ("Ausdrucksliste fuer 'try' endet falsch")
+ ELSE
+ try evaluation of actual expression
+ FI;
+ expr list rest := tail (expr list rest)
+ PER;
+ nil.
+
+try evaluation of actual expression:
+ disable stop;
+ SYM VAR result :: x eval (head (expr list rest), alist);
+ IF is error THEN
+ IF error message = "halt from terminal" AND halt enabled THEN
+ enable stop
+ ELIF output THEN
+ put error
+ FI;
+ add property (errors, apval constant, sym (error message));
+ clear error
+ ELSE
+ LEAVE x try WITH result
+ FI;
+ enable stop.
+
+END PROC x try;
+
+
+SYM PROC x eval condition (SYM CONST pair list, alist):
+ enable stop;
+ SYM VAR cond pair list rest :: pair list;
+ REP
+ IF atom (cond pair list rest) THEN
+ error stop ("Keine 'T'-Bedingung in bedingtem Ausdruck gefunden")
+ FI;
+ check wether is correct pair;
+ IF true condition found THEN
+ LEAVE x eval condition WITH x eval (head (tail (actual pair)), alist)
+ FI;
+ cond pair list rest := tail (cond pair list rest)
+ PER;
+ nil.
+
+check wether is correct pair:
+ IF atom (actual pair) COR
+ atom (tail (actual pair)) COR
+ NOT null (tail (tail (actual pair))) THEN
+ error stop ("Ungueltiges Paar im bedingten Ausdruck")
+ FI.
+
+true condition found:
+ bool (x eval (head (actual pair), alist)).
+
+actual pair:
+ head (cond pair list rest).
+
+END PROC x eval condition;
+
+
+BOOL PROC bool (SYM CONST sym):
+ IF eq (sym, true constant) THEN
+ TRUE
+ ELIF eq (sym, false constant) THEN
+ FALSE
+ ELSE
+ error stop ("'T' oder 'F' erwartet"); TRUE
+ FI
+END PROC bool;
+
+
+(******* a-list handling refinements used in 'x apply' and 'x eval' *******)
+
+(* declared within 'x apply' and 'x eval': 'actual alist entry' *)
+
+.
+
+initialize for alist insertion:
+ new alist := alist.
+
+begin alist retrieval:
+ SYM VAR actual alist pos :: alist.
+
+search for next alist entry:
+ WHILE NOT end of alist REP
+ IF atom (actual alist pos) THEN
+ error stop ("Bindeliste endet falsch")
+ FI;
+ actual alist entry := head (actual alist pos);
+ actual alist pos := tail (actual alist pos);
+ UNTIL is non functional alist entry PER.
+
+is non functional alist entry:
+ NOT is functional alist entry.
+
+search for next functional alist entry:
+ WHILE NOT end of alist REP
+ IF atom (actual alist pos) THEN
+ error stop ("Bindeliste endet falsch")
+ FI;
+ actual alist entry := head (actual alist pos);
+ actual alist pos := tail (actual alist pos);
+ UNTIL is functional alist entry PER;
+ actual alist entry := tail (actual alist entry).
+
+is functional alist entry:
+ check wether is alist entry;
+ null (head (actual alist entry)).
+
+check wether is alist entry:
+ IF atom (actual alist entry) THEN
+ error stop ("Bindelisteneintrag ist kein Paar")
+ FI.
+
+end of alist:
+ null (actual alist pos).
+
+actual functional alist entry:
+ actual alist entry.
+
+prepare new alist entry:
+ new alist := cons (cons (nil, nil), new alist);
+ new alist entry := head (new alist).
+
+prepare new functional alist entry:
+ new alist := cons (cons (nil, cons (nil, nil)), new alist);
+ new alist entry := tail (head (new alist)).
+
+
+END PACKET lisp interpreter;
+
+
+
diff --git a/lisp/lisp.4 b/lisp/lisp.4
new file mode 100644
index 0000000..0733dcd
--- /dev/null
+++ b/lisp/lisp.4
@@ -0,0 +1,143 @@
+PACKET lisp (* Autor: J.Durchholz , P. Heyderhoff *)
+ (* Datum: 09.05.1984 *)
+ DEFINES (* Version 1.7.2 *)
+ (* Änderung: notebook *)
+ (* 13.3.86 I. Ley *)
+ (* Änderung: start lisp system *)
+ (* 25.3.86 I. Ley *)
+ (* Anpassung an ELAN-Compiler Version 1.7.5 *)
+ (* 8.4.86 I. Ley *)
+ start lisp system,
+ lisp heap,
+ insert lisp,
+ run lisp,
+ run lisp again,
+ lisp,
+ break lisp:
+
+SYM VAR run again pointer :: nil;
+DATASPACE VAR insert heap :: nil space;
+
+PROC start lisp system (DATASPACE CONST heap):
+ enable stop;
+ initialize lisp system (heap);
+ forget (insert heap);
+ insert heap := heap
+END PROC start lisp system;
+
+
+PROC start lisp system (DATASPACE CONST heap, FILE VAR f):
+ enable stop;
+ create lisp system (f, heap);
+ forget (insert heap);
+ insert heap := heap
+END PROC start lisp system;
+
+
+PROC start lisp system (FILE VAR f):
+ create lisp system (f, insert heap)
+END PROC start lisp system;
+
+
+DATASPACE PROC lisp heap:
+ insert heap
+END PROC lisp heap;
+
+
+DATASPACE VAR run heap :: nil space;
+
+
+PROC insert lisp:
+ insert lisp (last param)
+END PROC insert lisp;
+
+
+PROC insert lisp (TEXT CONST file name):
+ interpret (insert heap, file name)
+END PROC insert lisp;
+
+
+PROC run lisp:
+ run lisp (last param)
+END PROC run lisp;
+
+
+PROC run lisp (TEXT CONST file name):
+ forget (run heap);
+ run heap := insert heap;
+ interpret (run heap, file name)
+END PROC run lisp;
+
+
+PROC interpret (DATASPACE CONST heap, TEXT CONST file name):
+ enable stop;
+ FILE VAR f :: sequential file (input, file name);
+ interpret (heap, f)
+END PROC interpret;
+
+
+PROC interpret (DATASPACE CONST heap, FILE VAR f):
+ initialize lisp system (heap);
+ get (f, run again pointer);
+ add property (new atom ("program"), new atom ("APVAL"), run again pointer);
+ put (evalquote (run again pointer))
+END PROC interpret;
+
+PROC run lisp again:
+ put (evalquote (run again pointer))
+END PROC run lisp again;
+
+
+PROC get ausdruck:
+ enable stop; get (ausdruck)
+END PROC get ausdruck;
+
+SYM VAR ausdruck;
+
+PROC lisp:
+
+(* HAUPT TESTPROGRAMM FUER LISP Heyderhoff 25.1.83 *)
+IF NOT exists ("LISP HEAP") THEN
+ FILE VAR bootstrap :: sequential file (input, "lisp.bootstrap");
+ create lisp system (bootstrap, new ("LISP HEAP"));
+ verbose lisp output (TRUE);
+FI;
+SYM VAR work;
+command dialogue(FALSE); forget ("LISP INPUT"); command dialogue(TRUE);
+(* bildlaenge(23); *) (* EUMEL 1.65 *)
+disable stop;
+REP
+ get (ausdruck);
+ IF is error THEN
+ handle error
+ ELSE
+ work := evalquote (ausdruck);
+ IF is error THEN handle error
+ ELSE note (work)
+ FI
+ FI
+PER .
+
+handle error:
+ IF text (error message, 18) = "halt from terminal" THEN
+ enable stop
+ ELSE
+ note (error message);
+ put ( error message); pause(20);
+ clear error;
+ FI .
+END PROC lisp;
+
+PROC break lisp:
+ break;
+ page;
+ quit;
+ FILE VAR in :: sequential file (modify, "LISP INPUT"),
+ out :: notefile; modify (out);
+ headline (out,"LISP OUTPUT");
+ headline (in, "LISP INPUT");
+ noteedit (in);
+END PROC break lisp
+
+END PACKET lisp;
+
diff --git a/lisp/lisp.bootstrap b/lisp/lisp.bootstrap
new file mode 100644
index 0000000..37efbde
--- /dev/null
+++ b/lisp/lisp.bootstrap
@@ -0,0 +1,118 @@
+NIL APVAL
+NIL
+T APVAL
+T
+F APVAL
+F
+COND FUNCTION
+(LAMBDA ((INDEFINITE QUOTE X)) . 0)
+BEGINOBLISTDUMP FUNCTION
+(LAMBDA () . 1)
+NEXTATOM FUNCTION
+(LAMBDA () . 2)
+ADDPROPERTY FUNCTION
+(LAMBDA (X X X) . 3)
+ALTERPROPERTY FUNCTION
+(LAMBDA (X X X) . 4)
+DELETEPROPERTY FUNCTION
+(LAMBDA (X X) . 5)
+PROPERTYEXISTS FUNCTION
+(LAMBDA (X X) . 6)
+PROPERTY FUNCTION
+(LAMBDA (X X) . 7)
+ADDFLAG FUNCTION
+(LAMBDA (X X) . 8)
+FLAG FUNCTION
+(LAMBDA (X X) . 9)
+DELETEFLAG FUNCTION
+(LAMBDA (X X) . 10)
+BEGINPROPERTYLISTDUMP FUNCTION
+(LAMBDA (X) . 11)
+NEXTPROPERTY FUNCTION
+(LAMBDA () . 12)
+APPLY FUNCTION
+(LAMBDA (X X X) . 13)
+EVAL FUNCTION
+(LAMBDA (X X) . 14)
+TRY FUNCTION
+(LAMBDA (X X X X) . 15)
+ASSOCIATIONLIST FUNCTION
+(LAMBDA () . 16)
+ERRORSTOP FUNCTION
+(LAMBDA (X) . 17)
+HEAD FUNCTION
+(LAMBDA (X) . 18)
+SETHEAD FUNCTION
+(LAMBDA (X X) . 19)
+TAIL FUNCTION
+(LAMBDA (X) . 20)
+SETTAIL FUNCTION
+(LAMBDA (X X) . 21)
+CONS FUNCTION
+(LAMBDA (X X) . 22)
+EQ FUNCTION
+(LAMBDA (X X) . 23)
+GET FUNCTION
+(LAMBDA () . 24)
+PUT FUNCTION
+(LAMBDA (X) . 25)
+NULL FUNCTION
+(LAMBDA (X) . 26)
+ATOM FUNCTION
+(LAMBDA (X) . 27)
+NAMEDATOM FUNCTION
+(LAMBDA (X) . 28)
+GETATOM FUNCTION
+(LAMBDA () . 29)
+PUTATOM FUNCTION
+(LAMBDA (X) . 30)
+TEXT FUNCTION
+(LAMBDA (X) . 31)
+GETTEXT FUNCTION
+(LAMBDA () . 32)
+PUTTEXT FUNCTION
+(LAMBDA (X) . 33)
+CHARACTER FUNCTION
+(LAMBDA (X) . 34)
+GETCHARACTER FUNCTION
+(LAMBDA () . 35)
+PUTCHARACTER FUNCTION
+(LAMBDA (X) . 36)
+INT FUNCTION
+(LAMBDA (X). 37)
+GETINT FUNCTION
+(LAMBDA () . 38)
+PUTINT FUNCTION
+(LAMBDA (X) . 39)
+SUM FUNCTION
+(LAMBDA ((INDEFINITE X)) . 40)
+DIFFERENCE FUNCTION
+(LAMBDA (X X). 41)
+PRODUCT FUNCTION
+(LAMBDA ((INDEFINITE X)). 42)
+QUOTIENT FUNCTION
+(LAMBDA (X X).43)
+REMAINDER FUNCTION
+(LAMBDA (X X).44)
+EQUAL FUNCTION
+(LAMBDA (X X) . 45)
+TRACE FUNCTION
+(LAMBDA () . 46 )
+DEFINE FUNCTION
+(LAMBDA ((INDEFINITE X)) . 47 )
+SET FUNCTION
+(LAMBDA (X X) . 48 )
+QUOTE FUNCTION
+(LAMBDA ((QUOTE X)) X)
+LIST FUNCTION
+(LAMBDA ((INDEFINITE X)) X)
+DO FUNCTION
+(LAMBDA ((INDEFINITE X)) NIL)
+PUTLIST FUNCTION
+(LAMBDA ((INDEFINITE X))
+ (COND
+ ((NULL X) NIL)
+ (T (DO (PUT (HEAD X)) (PUTLIST (TAIL X))))
+ )
+)
+
diff --git a/menugenerator/Generatordatei: Archivmenu b/menugenerator/Generatordatei: Archivmenu
new file mode 100644
index 0000000..76393fc
--- /dev/null
+++ b/menugenerator/Generatordatei: Archivmenu
@@ -0,0 +1,323 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-ARCHIV- **
+ ** MENUTAFEL-GENERATOR **
+ ** Version 1.0 **
+ ** **
+ ** (Stand: 30.03.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+TEXT PROC dateiverzeichnistext:
+ " "15" Verzeichnis der vorhandenen Dateien "14""13""13""
+ + " Eine Liste der vorhandenen Dateien wird auf dem "13""
+ + " Bildschirm ausgegeben. "13""13""
+ + " Da die Liste selbst eine Datei ist, kann man sie "13""
+ + " mit der Tastenfolge <ESC> <q> verlassen - das "13""
+ + " wird auch in der Kopfzeile angezeigt. "13""13""
+ + " Innerhalb der Liste kann man sich wie in einer "13""
+ + " Datei bewegen - nicht aber schreiben."
+END PROC dateiverzeichnistext;
+
+TEXT PROC dateiloeschentext:
+ " "15" Dateien löschen "14" "13""13""
+ + " Alle vorhandenen Dateien werden zur Auswahl angebo- "13""
+ + " ten. Anschließend werden die angekreuzten Dateien in "13""
+ + " der Reihenfolge, in der sie angekreuzt wurden, ge- "13""
+ + " löscht. "13""13""
+ + " Zur Sicherheit muß noch einmal für jede einzelne Da- "13""
+ + " tei bestätigt werden, daß sie auch tatsächlich ge- "13""
+ + " löscht werden soll!"
+END PROC dateiloeschentext;
+
+TEXT PROC dateidruckentext:
+ " "15" Dateien drucken "14" "13""13""
+ + " Alle vorhandenen Dateien werden zur Auswahl angebo- "13""
+ + " ten. Anschließend werden die angekreuzten Dateien "13""
+ + " in der Reihenfolge, in der sie angekreuzt wurden, "13""
+ + " zum Drucker geschickt. "13""13""
+ + " Der Vorgang wird auf dem Bildschirm protokolliert."
+END PROC dateidruckentext;
+
+TEXT PROC dateikopierentext:
+ " "15" Datei kopieren "14" "13""13""
+ + " Der Dateiname der Datei, die kopiert werden soll, wird er- "13""
+ + " fragt. Hier kann direkt ein Name eingegeben werden. Mit der "13""
+ + " Tastenfolge <ESC><z> kann man sich auch die vorhandenen Da- "13""
+ + " teien zur Auswahl anbieten lassen und hier einen Namen an- "13""
+ + " kreuzen. Anschließend wird der Name für die Kopie erfragt. "13""13""
+ + " Es muß ein Name eingetragen werden, der noch nicht für eine "13""
+ + " Datei vergeben wurde - ansonsten erfolgt ein Hinweis da- "13""
+ + " rauf und es wird nicht kopiert! "13""
+ + " Da man aber oft für die Kopie einen ähnlichen Namen wie für "13""
+ + " das Original wählt, wird der 'alte' Name vorgeschlagen. Aus "13""
+ + " genannten Gründen muß er aber verändert werden."
+END PROC dateikopierentext;
+
+TEXT PROC dateiumbenennentext:
+ " "15" Datei umbenennen "14" "13""13""
+ + " Der Dateiname der Datei, die umbenannt werden soll, wird er- "13""
+ + " fragt. Hier kann direkt ein Name eingegeben werden. Mit der "13""
+ + " Tastenfolge <ESC><z> kann man sich auch die vorhandenen Da- "13""
+ + " teien zur Auswahl anbieten lassen und dort einen Namen an- "13""
+ + " kreuzen. Anschließend wird der zukünftige Dateiname erfragt. "13""13""
+ + " Es muß ein Name eingetragen werden, der noch nicht für eine "13""
+ + " Datei vergeben wurde - ansonsten erfolgt ein Hinweis und es "13""
+ + " wird nicht umbenannt! "13""
+ + " Da man aber oft den 'neuen' Namen in Anlehnung an den 'alten' "13""
+ + " Namen wählt, wird der 'alte' Name vorgeschlagen. Aus genann- "13""
+ + " ten Gründen muß er aber verändert werden."
+END PROC dateiumbenennentext;
+
+TEXT PROC dateispeicherplatztext:
+ " "15" Datei-Speicherplatz ermitteln "14" "13""13""
+ + " Der Dateiname der Datei, deren Speicherplatz ermittelt "13""
+ + " werden soll, wird erfragt. Hier kann direkt ein Name "13""
+ + " eingegeben werden. Mit der Tastenfolge <ESC><z> kann "13""
+ + " man sich auch die vorhandenen Dateien zur Auswahl an- "13""
+ + " bieten lassen und dort Namen ankreuzen. "13""13""
+ + " Der belegte Speicherplatz der ausgewählten Datei(en) "13""
+ + " wird ermittelt und auf dem Bildschirm angezeigt."
+END PROC dateispeicherplatztext;
+
+TEXT PROC dateiaufraeumtext:
+ " "15" Dateien aufräumen (reorganisieren) "14" "13""13""
+ + " Der Dateiname der Datei, die aufgeräumt (reorganisiert) "13""
+ + " werden soll, wird erfragt. Hier kann direkt ein Name "13""
+ + " eingegeben werden. Mit der Tastenfolge <ESC><z> kann man "13""
+ + " sich auch die vorhandenen Dateien zur Auswahl anbieten "13""
+ + " lassen und dort Namen ankreuzen. "13""13""
+ + " Anschließend werden die ausgewählten Dateien aufgeräumt, "13""
+ + " d.h. die interne Verwaltung der Datei wird optimiert. "13""
+ + " Das führt zumeist dazu, daß die Datei anschließend weni- "13""
+ + " ger Speicherplatz belegt als zuvor. "13""13""
+ + " "15"Achtung! "14" Die Operation ist zeitaufwendig!!!"
+END PROC dateiaufraeumtext;
+
+
+(*------------------------------------------------------------------------*)
+
+
+
+TEXT PROC archivreserviertext:
+ " "15"Reservieren (des Archivlaufwerks) "14" "13""13""
+ + " Das System versucht, auf das Archiv zuzugreifen. Ist das Archiv "13""
+ + " von keiner anderen Task benutzt, dann wird die Frage gestellt, ob "13""
+ + " die Diskette eingelegt ist. Erst zu diesem Zeitpunkt ist sicher- "13""
+ + " gestellt, daß keine andere Task auf das Archiv zugreifen kann!"13""13""
+ + " Nach Bejahen der gestellten Frage ermittelt das System selbstän- "13""
+ + " dig den Namen der eingelegten Diskette, zeigt den Namen auf dem "13""
+ + " Bildschirm an und aktiviert die anderen Menupunkte des Pull-Down- "13""
+ + " Menus. "13""13""
+ + " Beim Verlassen des Pull-Down-Menus oder wenn eine andere Zieltask "13""
+ + " eingestellt wird, wird die Reservierung automatisch aufgehoben!"
+END PROC archivreserviertext;
+
+TEXT PROC neuediskettetext:
+ " "15"Neue Diskette (anmelden) "14" "13""13""
+ + " Der Datenaustausch mit einer Diskette ist nur dann möglich, wenn "13""
+ + " der im System eingestellte Diskettenname (auf dem Bildschirm "13""
+ + " sichtbar) mit dem tatsächlichen Namen der Diskette übereinstimmt. "13""13""
+ + " Nach einem Diskettenwechsel ist das aber zumeist nicht mehr der "13""
+ + " Fall. Nach Aktivieren dieses Menupunktes wird der Name der ein- "13""
+ + " gelegten Diskette ermittelt, im System eingestellt und angezeigt. "13""13""
+ + " Im Gegensatz zum Menupunkt 'Reservieren' greift das System ohne "13""
+ + " Anfrage an den Benutzer auf das Archiv zu (die Reservierung "13""
+ + " bleibt ja bestehen)."
+END PROC neue diskettetext;
+
+TEXT PROC archivschreibtext:
+ " "15"Schreiben (Kopieren) "14" "13""13""
+ + " Alle Dateien der eigenen Task werden zur Auswahl angeboten. An- "13""
+ + " schließend werden Kopien der angekreuzten Dateien in der Reihen- "13""
+ + " folge ihres Ankreuzens in die eingestellte Zieltask geschickt. "13""
+ + " Der Vorgang wird auf dem Bildschirm protokolliert. "13""13""
+ + " Sind in der Zieltask schon Dateien mit gleichem Namen vorhanden, "13""
+ + " so wird erfragt, ob diese dort gelöscht werden sollen. "13""13""
+ + " Normalerweise ist als Zieltask das Archiv der eigenen Station "13""
+ + " eingestellt. Mit dem Menupunkt 'Zieltask einstellen' kann diese "13""
+ + " Einstellung verändert werden."
+END PROC archivschreibtext;
+
+TEXT PROC archivchecktext:
+ " "15"Checken (Prüfen) "14" "13""13""
+ + " Alle Dateien der eingestellten Zieltask (des Archivs) wer- "13""
+ + " den zur Auswahl angeboten. Anschließend werden die ange- "13""
+ + " kreuzten Dateien in der Reihenfolge ihres Ankreuzens 'ge- "13""
+ + " checkt', d.h. daraufhin untersucht, ob sie ohne Fehler ge- "13""
+ + " lesen werden können. Der Vorgang wird auf dem Bildschirm "13""
+ + " protokolliert. "13""13""
+ + " Dieser Menupunkt kann nur ausgeführt werden, wenn der Da- "13""
+ + " teiaustausch mit einem Archiv(manager) erfolgt."
+END PROC archivchecktext;
+
+TEXT PROC archivkombinationstext:
+ " "15"Kombination "14" "13""13""
+ + " Dieser Menupunkt wirkt wie eine Kombination der Menupunkte "13""
+ + " 'Schreiben' und 'Checken' (Weitere Informationen dort). "13""13""
+ + " Alle Dateien der eigenen Task werden zur Auswahl angeboten. "13""
+ + " Die angekreuzten Dateien werden in der Reihenfolge ihres An- "13""
+ + " kreuzens in die eingestellte Zieltask kopiert. Anschließend "13""
+ + " werden alle Dateien, die gerade geschrieben wurden, gecheckt, "13""
+ + " d.h. auf Lesefehler hin untersucht. Beide Vorgänge werden auf "13""
+ + " dem Bildschirm protokolliert. "13""13""
+ + " Dieser Menupunkt kann nur ausgeführt werden, wenn der Datei- "13""
+ + " austausch mit einem Archiv(manager) erfolgt. "
+END PROC archivkombinationstext;
+
+
+TEXT PROC archivholtext:
+ " "15"Holen / Lesen "14" "13""13""
+ + " Alle Dateien der eingestellten Zieltask werden zur Auswahl ange- "13""
+ + " boten. Anschließend werden Kopien der angekreuzten Dateien in der "13""
+ + " Reihenfolge des Ankreuzens in die eigene Task kopiert. Der Vor- "13""
+ + " gang wird auf dem Bildschirm protokolliert. "13""13""
+ + " Sind in der eigenen Task schon Dateien mit gleichem Namen vorhan- "13""
+ + " den, so wird gefragt, ob die 'alten' Dateien überschrieben (ge- "13""
+ + " löscht) werden dürfen. "13""13""
+ + " Normalerweise werden die Dateien vom Archiv der eigenen Station "13""
+ + " geholt. Mit dem Menupunkt 'Zieltask einstellen' kann diese Ein- "13""
+ + " stellung verändert werden."
+END PROC archivholtext;
+
+
+TEXT PROC archivloeschtext:
+ " "15"Löschen "14" "13""13""
+ + " Alle Dateien der eingestellten Zieltask werden zur Auswahl "13""
+ + " angeboten. Anschließend werden die angekreuzten Dateien in "13""
+ + " der Reihenfolge ihres Ankreuzens gelöscht. Zur Sicherheit "13""
+ + " muß noch einmal für jede einzelne Datei bestätigt werden, "13""
+ + " daß sie auch tatsächlich gelöscht werden soll. "13""13""
+ + " Normalerweise ist als Zieltask das Archiv der eigenen Sta- "13""
+ + " tion eingestellt. Mit dem Menupunkt 'Zieltask einstellen' "13""
+ + " kann diese Einstellung verändert werden."
+END PROC archivloeschtext;
+
+TEXT PROC archivverzeichnistext:
+ " "15"Verzeichnis "14" "13""13""
+ + " Eine Liste aller Dateien, die in der Zieltask vorhanden "13""
+ + " sind, wird auf dem Bildschirm ausgegeben. Ist die Ziel- "13""
+ + " task ein Archiv (manager), so wird auch angezeigt, wie- "13""
+ + " viel Platz auf der Diskette belegt ist. "13""13""
+ + " Da die Liste selbt eine Datei ist, kann man sie mit der "13""
+ + " Tastenfolge <ESC> <q> verlassen. Innerhalb der Liste "13""
+ + " kann man sich wie im Editor bewegen."
+END PROC archivverzeichnistext;
+
+TEXT PROC archivdruckentext:
+ " "15"Drucken "14" "13""13""
+ + " Zur Sicherheit fragt das System an, ob ein Datei- "13""
+ + " verzeichnis der Zieltask gedruckt werden soll. Be- "13""
+ + " jaht man diese Frage, so wird ein Dateiverzeichnis "13""
+ + " erstellt und zum Drucker geschickt."
+END PROC archivdruckentext;
+
+TEXT PROC archivinitialisiertext:
+ " "15"Initialisieren (Vollständiges Löschen) "14" "13""13""
+ + " Zunächst erfragt das System, ob die Diskette auch formatiert wer- "13""
+ + " den soll. Bejaht man die Frage, so werden mehrere Formate zur "13""
+ + " Auswahl angeboten - anschließend wird die Diskette formatiert "13""
+ + " (wobei alle Inhalte "15"gelöscht "14" werden). Das Formatieren ist not-"13""
+ + " wendig, wenn man eine 'frische' Diskette verwendet. "13""13""
+ + " In jedem Fall wird dann angefragt, ob die Diskette initialisiert "13""
+ + " bzw. überschrieben werden soll (je nachdem, ob die Diskette schon "13""
+ + " benutzt wurde oder nicht). Nach Bejahen der gestellten Frage wird "13""
+ + " der Name der Diskette erfragt. Bei der Initialisierung erhält die "13""
+ + " Diskette einen (neuen) Namen und wird "15"vollständig gelöscht."14" "13""
+END PROC archivinitialisiertext;
+
+TEXT PROC archivzieltasktext:
+ " "15"Zieltask einstellen "14" "13""13""
+ + " Das System bietet die Alternativen 'Archiv'-'Vatertask'-'PUBLIC' "13""
+ + " und 'Sonstige' zur Auswahl an. Bei der Wahl einer der ersten drei "13""
+ + " Möglichkeiten nimmt das System die vollständige Einstellung vor, "13""
+ + " zeigt den Namen der eingestellten Zieltask an und aktiviert die "13""
+ + " zur Verfügung stehenden Menupunkte. "13""13""
+ + " Als Zieltask kann aber im Prinzip auch jede andere empfangsberei- "13""
+ + " te Task auf der Station oder irgendwo im Netz (wenn installiert) "13""
+ + " gewählt werden. Dazu wählt man die Alternative 'Sonstige'. Nach- "13""
+ + " einander werden der Name der Task und die Stationsnummer erfragt. "13""
+ + " Danach wird erfragt, ob die Zieltask ein Archiv(manager) ist. An- "13""
+ + " schließend verfährt das System wie oben beschrieben."
+END PROC archivzieltasktext;
+
+
+
+
+
+
+
+
+
+oeffne menukarte ("Archiv");
+
+oeffne menu ("ARCHIV", "", "menu archiv reservierung aufgeben");
+
+oberbegriff ("Dateien");
+
+menufunktion ("v", "Verzeichnis", "menu dateien verzeichnis",
+ dateiverzeichnistext);
+trennlinie;
+menufunktion ("l", "Löschen", "menu dateien loeschen",
+ dateiloeschentext);
+menufunktion ("d", "Drucken", "menu dateien drucken",
+ dateidruckentext);
+trennlinie;
+menufunktion ("k", "Kopieren", "menu dateien kopieren",
+ dateikopierentext);
+menufunktion ("u", "Umbenennen", "menu dateien umbenennen",
+ dateiumbenennentext);
+trennlinie;
+menufunktion ("s", "Speicherplatz", "menu dateien speicherplatz",
+ dateispeicherplatztext);
+menufunktion ("a", "Aufräumen", "menu dateien aufraeumen",
+ dateiaufraeumtext);
+
+
+
+oberbegriff ("Archiv", "menu archiv grundeinstellung (4)",
+ "menu archiv reservierung aufgeben");
+
+menufunktion ("r", "Reservieren", "menu archiv reservieren",
+ archivreserviertext);
+menufunktion ("n", "Neue Diskette", "menu archiv neue diskette",
+ neuediskettetext);
+trennlinie;
+menufunktion ("s", "Schreiben", "menu archiv schreiben",
+ archivschreibtext);
+menufunktion ("c", "Checken", "menu archiv checken",
+ archivchecktext);
+menufunktion ("k", "Kombination", "menu archiv schreibcheck",
+ archivkombinationstext);
+menufunktion ("h", "Holen/Lesen", "menu archiv holen",
+ archivholtext);
+menufunktion ("l", "Löschen", "menu archiv loeschen",
+ archivloeschtext);
+trennlinie;
+menufunktion ("v", "Verzeichnis", "menu archiv verzeichnis",
+ archivverzeichnistext);
+menufunktion ("d", "Drucken", "menu archiv verzeichnis drucken",
+ archivdruckentext);
+trennlinie;
+menufunktion ("i", "Initialisieren", "menu archivinitialisieren",
+ archivinitialisiertext);
+menufunktion ("z", "Zieltask einstellen", "menu archiv zieltask einstellen",
+ archivzieltasktext);
+schliesse menu;
+schliesse menukarte;
+
+
diff --git a/menugenerator/fonttab.ls-Menu-Generator b/menugenerator/fonttab.ls-Menu-Generator
new file mode 100644
index 0000000..a5fd613
--- /dev/null
+++ b/menugenerator/fonttab.ls-Menu-Generator
Binary files differ
diff --git a/menugenerator/ls-MENUBASISTEXTE b/menugenerator/ls-MENUBASISTEXTE
new file mode 100644
index 0000000..48ef277
--- /dev/null
+++ b/menugenerator/ls-MENUBASISTEXTE
Binary files differ
diff --git a/menugenerator/ls-Menu-Generator 1 b/menugenerator/ls-Menu-Generator 1
new file mode 100644
index 0000000..b9dfd73
--- /dev/null
+++ b/menugenerator/ls-Menu-Generator 1
@@ -0,0 +1,47 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-Menu-Generator 1 **
+ ** **
+ ** Version 1.0 **
+ ** **
+ ** (Stand: 30.03.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls menu generator 1 DEFINES{} textprozedur,{} textzeile:{}LET maxzeilenzahl = 14,{} maxzeichenzahl = 65,{} zentrierkennung = "%",{} beginmarkkennung = "$",{} endmarkkennung = "&",{} unblockkennung = "�",{} blank = " ",{} dateikennung = ".a";{}LET dateieintrag = "#type (""10"")##limit (16.5)#",{} stdfonttabelle = "fonttab.ls-Menu-Generator";{}ROW 3 TEXT CONST fehlermeldung :: ROW 3 TEXT : ({}"existiert nicht!",{}
+""15"Text ist zu lang - bitte kürzen! "14"",{}""15"Zeilenformatierung mit <ESC> abgebrochen! "14""{});{}ROW 6 TEXT CONST hinweis :: ROW 6 TEXT : ({}"Bitte warten ...",{}"Zulässige Zeilenzahl: ",{}"Tatsächliche Zeilenzahl: ",{}"Textlänge ist in Ordnung!",{}"Textprozedur ist erstellt!",{}"Textzeile ist erstellt!"{});{}PROC textprozedur (TEXT CONST dateiname, prozedurname):{} BOOL VAR mit fehler;{} formatiere (dateiname, mit fehler);{} IF mit fehler{} THEN errorstop (fehlermeldung [3]){} FI;{}
+ bereite den text auf (dateiname);{} erzeuge textprozedur (dateiname, prozedurname);{} out (""7""); out (hinweis [5]);{} last param (dateiname + dateikennung){}END PROC textprozedur;{}PROC textzeile (TEXT CONST dateiname):{} BOOL VAR mit fehler;{} formatiere (dateiname, mit fehler);{} IF mit fehler{} THEN errorstop (fehlermeldung [3]){} FI;{} bereite den text auf (dateiname);{} erzeuge textzeile (dateiname);{} out (""7""); out (hinweis [6]);{} last param (dateiname + dateikennung){}
+END PROC textzeile;{}PROC gib wartehinweis:{} page;{} out (hinweis [1]){}END PROC gib wartehinweis;{}PROC formatiere (TEXT CONST dateiname, BOOL VAR mit fehler):{} TEXT VAR fonttabelle, zeileninhalt;{} kontrolliere existenz;{} stelle fonttabelle ein;{} schreibe font in die datei;{} zeilenformatierung;{} entferne ggf font aus der datei;{} stelle fonttabelle zurueck;{} streiche restleerzeilen weg;{} untersuche ggf datei auf korrektheit.{} kontrolliere existenz:{} IF NOT exists (dateiname){}
+ THEN page; errorstop ("'" + dateiname + "' " + fehlermeldung [1]){} FI.{} stelle fonttabelle ein:{} gib wartehinweis;{} fonttabelle := fonttable;{} fonttable (stdfonttabelle).{} schreibe font in die datei:{} FILE VAR datei :: sequential file (modify, dateiname);{} to line (datei, 1);{} insert record (datei);{} write record (datei, dateieintrag + blank).{} zeilenformatierung:{} disable stop;{} lineform (dateiname);{} IF is error{} THEN clear error;{}
+ mit fehler := TRUE{} ELSE mit fehler := FALSE{} FI;{} enable stop.{} entferne ggf font aus der datei:{} to line (datei, 1);{} read record (datei, zeileninhalt);{} IF pos (zeileninhalt, dateieintrag) > 0{} THEN delete record (datei){} FI.{} stelle fonttabelle zurueck:{} fonttable (fonttabelle).{} streiche restleerzeilen weg:{} REP{} streiche ggf letzte zeile{} UNTIL zeile ist nicht leer PER.{} streiche ggf letzte zeile:{} to line (datei, lines (datei));{}
+ read record (datei, zeileninhalt);{} IF compress (zeileninhalt) = ""{} THEN delete record (datei){} FI.{} zeile ist nicht leer:{} compress (zeileninhalt) <> "".{} untersuche ggf datei auf korrektheit:{} IF NOT mit fehler{} THEN untersuche zeilenzahl{} FI.{} untersuche zeilenzahl:{} IF lines (datei) > maxzeilenzahl{} THEN page;{} out (hinweis [2] + text (maxzeilenzahl)); line;{} out (hinweis [3] + text (lines (datei))); line (2);{} errorstop (fehlermeldung [2]){}
+ ELSE page;{} out (hinweis [4]){} FI.{}END PROC formatiere;{}PROC bereite den text auf (TEXT CONST dateiname):{} INT VAR zaehler;{} TEXT VAR zeileninhalt;{} FILE VAR f :: sequential file (modify, dateiname);{} gib wartehinweis;{} vernichte ggf aufbereitete datei;{} richte datei neu ein;{} uebertrage die zeilen.{} vernichte ggf aufbereitete datei:{} IF exists (dateiname + dateikennung){} THEN forget (dateiname + dateikennung, quiet){} FI.{} richte datei neu ein:{}
+ FILE VAR aus :: sequential file (output, dateiname + dateikennung).{} uebertrage die zeilen:{} FOR zaehler FROM 1 UPTO lines (f) REP{} bereite eine zeile auf{} PER.{} bereite eine zeile auf:{} to line (f, zaehler);{} read record (f, zeileninhalt);{} ersetze alle gaensefuesschen;{} haenge ggf absatzmarke an;{} behandle zeile;{} putline (aus, zeileninhalt).{} ersetze alle gaensefuesschen:{} change all (zeileninhalt, """", "'").{} haenge ggf absatzmarke an:{} IF (zeileninhalt SUB (length (zeileninhalt))) = blank{}
+ THEN IF (zeileninhalt SUB 1) <> zentrierkennung{} THEN zeileninhalt CAT unblockkennung{} FI{} FI.{} behandle zeile:{} IF zeile soll zentriert werden{} THEN zentriere zeile{} ELIF zeile ist leerzeile{} THEN kennzeichne leerzeile{} ELSE blocke zeile auf stdlaenge{} FI.{} zeile soll zentriert werden:{} (zeileninhalt SUB 1) = zentrierkennung.{} zeile ist leerzeile:{} compress (zeileninhalt) = "".{} zentriere zeile:{} zeileninhalt := subtext (zeileninhalt, 2);{}
+ zeileninhalt := anfangsblanks + zeileninhalt;{} zeilenabschluss.{} anfangsblanks:{} ((maxzeichenzahl - length (zeileninhalt)) DIV 2) * blank.{} zeilenabschluss:{} ersetze markierungszeichen;{} setze 13.{} ersetze markierungszeichen:{} change all (zeileninhalt, beginmarkkennung, """15""");{} change all (zeileninhalt, endmarkkennung, """14""").{} setze 13:{} zeileninhalt CAT " ""13""".{} kennzeichne leerzeile:{} zeileninhalt := """13""".{} blocke zeile auf stdlaenge:{}
+ IF zeile darf nicht geblockt werden{} THEN ersetze endezeichen{} ELSE fuehre blockung aus{} FI.{} zeile darf nicht geblockt werden:{} (zeileninhalt SUB length (zeileninhalt)) = unblockkennung.{} ersetze endezeichen:{} zeileninhalt := subtext (zeileninhalt, 1, length (zeileninhalt) - 1);{} ersetze markierungszeichen;{} setze 13.{} fuehre blockung aus:{} ROW maxzeichenzahl INT VAR leerzeichen;{} INT VAR gezaehlte blanks, zu verteilende blanks;{} ordne anfangswerte zu;{}
+ verteile blanks gleichmaessig;{} verteile blanks zufaellig;{} baue zeile zusammen;{} ersetze markierungszeichen;{} setze 13.{} ordne anfangswerte zu:{} bestimme blankanzahl in der zeile;{} bestimme zu verteilende blanks;{} initialisiere die reihung.{} bestimme blankanzahl in der zeile:{} gezaehlte blanks := 0;{} INT VAR zeiger;{} FOR zeiger FROM 1 UPTO length (zeileninhalt) REP{} IF (zeileninhalt SUB zeiger) = blank{} THEN gezaehlte blanks INCR 1{}
+ FI{} PER.{} bestimme zu verteilende blanks:{} zu verteilende blanks := maxzeichenzahl - length (zeileninhalt).{} initialisiere die reihung:{} FOR zeiger FROM 1 UPTO gezaehlte blanks REP{} leerzeichen [zeiger] := 1{} PER.{} verteile blanks gleichmaessig:{} WHILE (zu verteilende blanks DIV gezaehlte blanks) > 0 REP{} schlag je ein blank auf;{} zu verteilende blanks DECR gezaehlte blanks{} PER.{} schlag je ein blank auf:{} FOR zeiger FROM 1 UPTO gezaehlte blanks REP{}
+ leerzeichen [zeiger] INCR 1{} PER.{} verteile blanks zufaellig:{} FOR zeiger FROM 1 UPTO zu verteilende blanks REP{} leerzeichen [random (1, gezaehlte blanks)] INCR 1{} PER.{} baue zeile zusammen:{} TEXT VAR zwischen := zeileninhalt;{} INT VAR aktuelles blank := 0;{} zeileninhalt := "";{} FOR zeiger FROM 1 UPTO length (zwischen) REP{} TEXT VAR aktuelles zeichen :: (zwischen SUB zeiger);{} IF aktuelles zeichen = blank{} THEN aktuelles blank INCR 1;{}
+ zeileninhalt CAT (leerzeichen [aktuelles blank] * blank){} ELSE zeileninhalt CAT aktuelles zeichen{} FI{} PER{}END PROC bereite den text auf;{}PROC erzeuge textprozedur (TEXT CONST dateiname, prozedurname):{} mache aus den zeilen einzeltexte;{} entferne ueberfluessige restzeilen;{} erstelle eine textprozedur.{} mache aus den zeilen einzeltexte:{} INT VAR zeiger;{} FILE VAR ausdatei :: sequential file (modify, dateiname + dateikennung);{} FOR zeiger FROM 1 UPTO lines (ausdatei) REP{}
+ bearbeite eine zeile{} PER.{} bearbeite eine zeile:{} TEXT VAR zeileninhalt;{} to line (ausdatei, zeiger);{} read record (ausdatei, zeileninhalt);{} zeileninhalt := """ " + zeileninhalt + """ +";{} change all (zeileninhalt, "­", "-");{} write record (ausdatei, zeileninhalt).{} entferne ueberfluessige restzeilen:{} REP{} entferne ggf eine zeile{} UNTIL zeileninhalt <> """ ""13"""" +" PER;{} entferne return aus letzter zeile.{} entferne ggf eine zeile:{}
+ IF compress (zeileninhalt) = """ ""13"""" +"{} THEN delete record (ausdatei){} FI.{} entferne return aus letzter zeile:{} to line (ausdatei, lines (ausdatei));{} read record (ausdatei, zeileninhalt);{} zeileninhalt := subtext (zeileninhalt, 1, length (zeileninhalt) - 6);{} write record (ausdatei, zeileninhalt).{} erstelle eine textprozedur:{} schreibe procanfang;{} schreibe procende.{} schreibe procanfang:{} to line (ausdatei, 1);{} insert record (ausdatei);{}
+ write record (ausdatei, "TEXT PROC " + prozedurname + ":").{} schreibe procende:{} to line (ausdatei, lines (ausdatei) + 1);{} insert record (ausdatei);{} write record (ausdatei, "END PROC " + prozedurname + ";").{}END PROC erzeuge textprozedur;{}PROC erzeuge textzeile (TEXT CONST dateiname):{} entferne ueberfluessige restzeilen;{} entferne return aus letzter zeile;{} erstelle eine textzeile.{} entferne ueberfluessige restzeilen:{} TEXT VAR zeileninhalt;{} INT VAR zeiger;{}
+ FILE VAR ausdatei :: sequential file (modify, dateiname + dateikennung);{} REP{} entferne ggf eine zeile{} UNTIL compress (zeileninhalt) <> """13""" PER.{} entferne ggf eine zeile:{} to line (ausdatei, lines (ausdatei));{} read record (ausdatei, zeileninhalt);{} IF compress (zeileninhalt) = """13"""{} THEN delete record (ausdatei){} FI.{} entferne return aus letzter zeile:{} to line (ausdatei, lines (ausdatei));{} read record (ausdatei, zeileninhalt);{} change all (zeileninhalt, """13""", "");{}
+ write record (ausdatei, zeileninhalt).{} erstelle eine textzeile:{} haenge die zeilen aneinander;{} fasse zeile in gaensefuesschen;{} schreibe einzelzeile in ausgabedatei.{} haenge die zeilen aneinander:{} TEXT VAR zeile :: "";{} FOR zeiger FROM 1 UPTO lines (ausdatei) REP{} to line (ausdatei, zeiger);{} read record (ausdatei, zeileninhalt);{} zeile CAT (" " + zeileninhalt){} PER.{} fasse zeile in gaensefuesschen:{} zeile := """" + zeile + """";{} change all (zeile, "­","-").{}
+ schreibe einzelzeile in ausgabedatei:{} forget (dateiname + dateikennung, quiet);{} FILE VAR fertig :: sequential file (modify, dateiname + dateikennung);{} to line (fertig, 1);{} insert record (fertig);{} write record (fertig, zeile){}END PROC erzeuge textzeile;{}END PACKET ls menu generator 1;{}
+
diff --git a/menugenerator/ls-Menu-Generator 2 b/menugenerator/ls-Menu-Generator 2
new file mode 100644
index 0000000..608f680
--- /dev/null
+++ b/menugenerator/ls-Menu-Generator 2
@@ -0,0 +1,72 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-Menu-Generator 2 **
+ ** **
+ ** Version 1.0 **
+ ** **
+ ** (Stand: 30.03.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+PACKET ls menu generator 2 DEFINES{} oeffne menukarte,{} oeffne menu,{} oberbegriff,{} menufunktion,{} trennlinie,{} schliesse menu,{} schliesse menukarte,{} testinstallation:{}LET menutafeltype = 1954,{} kennung = "ls - Menu - Generator",{} mm taskname = "ls-MENUKARTEN",{} menutafelpraefix = "ls-MENUKARTE:",{} menu grundtext = "ls-MENUBASISTEXTE",{} zwischenablagename = "MENU-ZWISCHENABLAGEDATEI INTERN";{}
+LET maxmenus = 6,{} maxmenutexte = 300,{} maxinfotexte = 2000,{} maxhauptmenupunkte = 10,{} maxuntermenupunkte = 15,{} maxmenubreite = 71; (* Breite der Hauptmenüzeile - 2 *){}LET blank = " ",{} cleop = ""4"",{} piep = ""7"",{} trennzeilensymbol = "###",{} bleibt leer symbol = "***",{} hauptmenuluecke = " ";{}LET dummyname = "Dummy für Anwendertexte",{}
+ install finished = "Installation abgeschlossen!",{} card finished = "Menukartengenerierung abgeschlossen!",{} filetype = 1003;{}TYPE MENUPUNKT = STRUCT (TEXT punktkuerzel,{} punktname,{} procname,{} boxtext,{} BOOL aktiv,{} angewaehlt),{} EINZELMENU = STRUCT (INT belegt,{} TEXT ueberschrift,{}
+ INT anfangsposition,{} maxlaenge,{} ROW maxuntermenupunkte MENUPUNKT menupunkt,{} INT aktueller untermenupunkt,{} TEXT startprozedurname,{} leaveprozedurname),{} MENU = STRUCT (TEXT menuname,{} INT anzahl hauptmenupunkte,{} ROW maxhauptmenupunkte EINZELMENU einzelmenu,{}
+ TEXT menueingangsprozedur,{} menuausgangsprozedur,{} menuinfo,{} lizenznummer,{} versionsnummer,{} INT hauptmenuzeiger,{} untermenuanfang,{} untermenuzeiger),{} INFOTEXT = STRUCT (INT anzahl infotexte,{} ROW maxinfotexte TEXT stelle),{}
+ MENUTEXT = STRUCT (INT anzahl menutexte,{} ROW maxmenutexte TEXT platz),{} MENULEISTE = STRUCT (INT belegt, zeigeraktuell, zeigerhintergrund,{} ROW maxmenus MENU menu,{} MENUTEXT menutext,{} INFOTEXT infotext);{}ROW 14 TEXT CONST aussage :: ROW 14 TEXT : ({}"ACHTUNG - Eine Menukarte mit diesem Namen existiert bereits - ACHTUNG",{}"Kann die bereits existierende Menukarte gelöscht werden",{}
+"Dann kann keine neue Menukarte mit diesem Namen erstellt werden!",{}"Zum Weitermachen bitte irgendeine Taste tippen!",{}"Sollen auch Anwendungstexte in die Menukarte aufgenommen werden",{}"Auswahl der Datei, in der die Anwendungstexte stehen.",{}"Bitte die gewünschte Datei ankreuzen!",{}"Durchgang 1 von 2 Durchgängen - in Arbeit ist Zeile: ",{}"Durchgang 2 von 2 Durchgängen - in Arbeit ist Zeile: ",{}"",{}"Einlesen von Texten aus Datei : ",{}"Bearbeitet wird Menu : ",{}"Eingetragen wird Oberbegriff : ",{}
+"Eingetragen wird Menufunktion : "{});{}ROW 22 TEXT CONST fehlermeldung :: ROW 22 TEXT : ({}"Ohne die Datei '",{}"' "13""10""10" ist die Menuerstellung "15"unmöglich "14"!!",{}"Hier muß unbedingt eine Datei angekreuzt werden!",{}"Ausgewählte Datei hat falschen Typ (<> 1003) )",{}"Zu viele Anwendungstexte in der Datei ",{}"Anführungszeichen fehlt am Anfang oder Ende der Zeile ",{}"Anführungszeichen fehlt irgendwo in Zeile ",{}"Die angegebene Datei existiert nicht!",{}"Menukarte noch nicht geöffnet ('oeffne menukarte' fehlt)! ",{}
+"Vorausgehendes Menu nicht geschlossen! ",{}"Zu viele Menus in der Menukarte (> " + text (maxmenus) + ")!",{}"Menuname ist mehrfach vorhanden!",{}"Menu noch nicht geoeffnet ('oeffne menu' fehlt)!",{}"Zu viele Oberbegriffe in einem Menu (> " + text (maxhauptmenupunkte) + ")!",{}"Die Kopfzeile ist zu lang (> " + text (maxmenubreite) + ")!",{}"Menupunkt-Kürzel ist länger als ein Zeichen!",{}"Menupunkt-Kürzel kommt mehrfach vor (nicht eindeutig)!",{}"Menupunkt-Bezeichnung ist zu lang!",{}"Zu viele (> " + text (maxuntermenupunkte) + ") Menupunkte in einem Pull-Down-Menu!",{}
+"Menukarte '",{}"' gibt es nicht in dieser Task!",{}"' hat falsche(n) Typ/Bezeichnung"{});{}TEXT VAR menuinfotextdateiname,{} aktueller menudateiname;{}BOOL VAR menuleiste ist bereit :: FALSE,{} menu ist geoeffnet :: FALSE;{}BOUND MENULEISTE VAR menuleiste;{}BOUND MENUTEXT VAR basistexte;{}BOUND MENU VAR aktuelles menu;{}DATASPACE VAR ds;{}OP := (MENUTEXT VAR ziel, MENUTEXT VAR quelle):{} INT VAR z;{} ziel.anzahl menutexte := quelle.anzahl menutexte;{} FOR z FROM 1 UPTO quelle.anzahl menutexte REP{}
+ ziel.platz [z] := quelle.platz [z]{} PER{}END OP :=;{}OP := (MENU VAR ziel, MENU CONST quelle):{} CONCR (ziel) := CONCR (quelle){}END OP :=;{}OP := (EINZELMENU VAR ziel, EINZELMENU CONST quelle):{} CONCR (ziel) := CONCR (quelle){}END OP :=;{}OP := (MENUPUNKT VAR ziel, MENUPUNKT CONST quelle):{} CONCR (ziel) := CONCR (quelle){}END OP :=;{}PROC oeffne menukarte (TEXT CONST menukartenname):{} gib bildschirmhinweis aus;{} ueberpruefe voraussetzungen;{} erfrage den namen der datei mit den anwendertexten;{}
+ erstelle neue menuleiste.{} gib bildschirmhinweis aus:{} page; out (center (invers (kennung))).{} ueberpruefe voraussetzungen:{} ueberpruefe ob basistexte vorhanden sind;{} ueberpruefe ob menukarte schon vorhanden ist.{} ueberpruefe ob basistexte vorhanden sind:{} IF NOT exists (menu grundtext){} THEN gib hinweis und brich ab{} FI.{} gib hinweis und brich ab:{} disable stop;{} fetch (menu grundtext, /mm taskname);{} IF is error{} THEN clear error;{} enable stop;{}
+ cursor (1, 4); out (cleop);{} errorstop (fehlermeldung [1] + menu grundtext + fehlermeldung [2]){} ELSE clear error;{} enable stop{} FI.{} ueberpruefe ob menukarte schon vorhanden ist:{} IF exists (menukarte){} THEN gib hinweis auf vorhandene menukarte;{} frage ob die alte karte geloescht werden darf{} FI.{} menukarte:{} menutafelpraefix + menukartenname.{} gib hinweis auf vorhandene menukarte:{} cursor (1, 4); out (cleop);{}
+ cursor (1, 4); out (center (menukarte));{} cursor (1, 6); out (center (invers (aussage [1]))).{} frage ob die alte karte geloescht werden darf:{} cursor (2, 9);{} IF yes (aussage [2]){} THEN forget (menukarte, quiet){} ELSE weiterarbeit ist unmoeglich{} FI.{} weiterarbeit ist unmoeglich:{} cursor (1, 12); out (center (invers (aussage [3])));{} cursor (2, 15); out (aussage [4]);{} cursor (2, 16); pause; page;{} errorstop ("").{} erfrage den namen der datei mit den anwendertexten:{}
+ cursor (1, 4); out (cleop);{} IF yes (aussage [5]){} THEN biete dateiauswahl an{} ELSE erzeuge dateidummy{} FI.{} biete dateiauswahl an:{} menuinfotextdateiname := one (2, 6, 77, 19, ALL myself,{} aussage [6], aussage [7]);{} ueberpruefe den dateinamen;{} ueberpruefe den dateityp.{} ueberpruefe den dateinamen:{} IF compress (menuinfotextdateiname) = ""{} THEN page; errorstop (fehlermeldung [3]){} FI.{} ueberpruefe den dateityp:{}
+ IF datei hat falschen typ{} THEN page; errorstop (fehlermeldung [4]){} FI.{} datei hat falschen typ:{} ds := old (menuinfotextdateiname);{} IF type (ds) <> filetype{} THEN forget (ds); TRUE{} ELSE forget (ds); FALSE{} FI.{} erzeuge dateidummy:{} forget (dummyname, quiet);{} FILE VAR datei :: sequential file (modify, dummyname);{} to line (datei, 1);{} menuinfotextdateiname := dummyname.{} erstelle neue menuleiste:{} INT VAR zeiger;{} TEXT VAR zeileninhalt;{}
+ initialisiere werte;{} aktueller menudateiname := menukarte;{} menuleiste := new (aktueller menudateiname);{} type (old (aktueller menudateiname), menutafeltype);{} menuleiste.belegt := 0;{} menuleiste ist bereit := TRUE;{} trage menubasistexte ein;{} trage anwendungstexte ein.{} initialisiere werte:{} menuleiste ist bereit := FALSE;{} menu ist geoeffnet := FALSE.{} trage menubasistexte ein:{} basistexte := old (menu grundtext);{}
+ menuleiste.menutext := basistexte.{} trage anwendungstexte ein:{} konvertiere (menuinfotextdateiname, zwischenablagename,{} menuleiste.infotext.anzahl infotexte);{} ueberpruefe anwendungstextanzahl;{} trage anwendungstexte in die menuleiste.{} ueberpruefe anwendungstextanzahl:{} IF menuleiste.infotext.anzahl infotexte > maxinfotexte{} THEN forget (zwischenablagename, quiet);{} forget (aktueller menudateiname, quiet);{} errorstop (fehlermeldung [5] + "'" + menuinfotextdateiname + "'"){}
+ FI.{} trage anwendungstexte in die menuleiste:{} gib hinweis auf anwendungstexteintrag;{} FILE VAR ein :: sequential file (input, zwischenablagename);{} FOR zeiger FROM 1 UPTO menuleiste.infotext.anzahl infotexte REP{} getline (ein, zeileninhalt);{} menuleiste.infotext.stelle [zeiger] := zeileninhalt;{} cout (zeiger){} PER;{} forget (zwischenablagename, quiet);{} forget (dummyname , quiet).{} gib hinweis auf anwendungstexteintrag:{} cursor (1, 7); out (aussage [9]).{}
+END PROC oeffne menukarte;{}PROC konvertiere (TEXT CONST eingabedatei, ausgabedatei,{} INT VAR anzahl konvertierter saetze):{} loesche ausgabedatei;{} untersuche eingabedatei;{} konvertiere saetze.{} loesche ausgabedatei:{} IF exists (ausgabedatei){} THEN forget (ausgabedatei, quiet){} FI.{} untersuche eingabedatei:{} IF NOT exists (eingabedatei){} THEN errorstop (fehlermeldung [8]){} FI.{} konvertiere saetze:{} gib hinweis;{} konvertiere satzweise.{}
+ gib hinweis:{} cursor (1, 4); out (cleop);{} cursor (1, 4); out (aussage [11] + "'" + eingabedatei + "'");{} cursor (1, 6); out (aussage [ 8]);{} anzahl konvertierter saetze := 0.{} konvertiere satzweise:{} TEXT VAR zeileninhalt :: "";{} FILE VAR eingabe :: sequential file (input, eingabedatei);{} WHILE NOT eof (eingabe) REP{} behandle eine dateizeile{} PER;{} optimiere ausgabedatei.{} behandle eine dateizeile:{} getline (eingabe, zeileninhalt);{} anzahl konvertierter saetze INCR 1;{}
+ cout (anzahl konvertierter saetze);{} untersuche zeile;{} wandle die zeile um;{} FILE VAR aus :: sequential file (output, ausgabedatei);{} write (aus, textausgabe).{} untersuche zeile:{} zeileninhalt := compress (zeileninhalt);{} IF zeileninhalt = ""{} THEN zeileninhalt := """"""{} FI;{} IF (zeileninhalt SUB 1) <> """"{} OR (zeileninhalt SUB length (zeileninhalt)) <> """"{} THEN bereite abgang vor;{} errorstop (fehlermeldung [6] + text (anzahl konvertierter saetze)){}
+ FI.{} wandle die zeile um:{} TEXT VAR textausgabe :: "", codekette;{} zeileninhalt := subtext (zeileninhalt, 2, length (zeileninhalt) - 1);{} WHILE gaensefuesschenposition > 0 REP{} textausgabe CAT subtext (zeileninhalt, 1, gaensefuesschenposition - 1);{} zeileninhalt := subtext (zeileninhalt, gaensefuesschenposition);{} codekette := subtext (zeileninhalt, 1, pos (zeileninhalt, """", 2));{} IF codekette = """7"""{} THEN textausgabe CAT ""7""{}
+ ELIF codekette = """5"""{} THEN textausgabe CAT ""5""{} ELIF codekette = """4"""{} THEN textausgabe CAT ""4""{} ELIF codekette = """10"""{} THEN textausgabe CAT ""10""{} ELIF codekette = """13"""{} THEN textausgabe CAT ""13""{} ELIF codekette = """14"""{} THEN textausgabe CAT ""14""{} ELIF codekette = """15"""{} THEN textausgabe CAT ""15""{} ELIF codekette = """"""{} THEN textausgabe CAT """"{}
+ ELSE errorstop (fehlermeldung [7] +{} text (anzahl konvertierter saetze)){} FI;{} zeileninhalt := subtext (zeileninhalt, 1 + length (codekette)){} PER;{} textausgabe CAT zeileninhalt.{} gaensefuesschenposition:{} pos (zeileninhalt, """").{} bereite abgang vor:{} forget (ausgabedatei, quiet);{} line (2).{} optimiere ausgabedatei:{} FILE VAR ausgabe :: sequential file (modify, ausgabedatei);{} WHILE lines (ausgabe) > 0 CAND letzter satz ist leer REP{}
+ to line (ausgabe, lines (ausgabe));{} delete record (ausgabe);{} anzahl konvertierter saetze DECR 1;{} cout (anzahl konvertierter saetze ){} PER.{} letzter satz ist leer:{} TEXT VAR satz;{} to line (ausgabe,lines (ausgabe));{} read record (ausgabe, satz);{} IF compress (satz) = "" OR compress (satz) = ""13""{} THEN TRUE{} ELSE FALSE{} FI.{}END PROC konvertiere;{}PROC oeffne menu (TEXT CONST name, einstiegsproc, ausstiegsproc,{} itext, ltext, vtext):{}
+ gib hinweis auf geoeffnetes menu;{} ueberpruefe auf ungereimtheiten;{} nimm eintragungen in datenraum vor.{} gib hinweis auf geoeffnetes menu:{} cursor (1, 4); out (cleop);{} out (aussage [12]); out (invers (name));{} cursor (1, 6).{} ueberpruefe auf ungereimtheiten:{} pruefe auf bereits geoeffnete menuliste;{} pruefe auf noch geoeffnetes menu;{} pruefe auf noch freie menuplaetze;{} pruefe auf schon vorhandenen menunamen.{} pruefe auf bereits geoeffnete menuliste:{} IF NOT menuleiste ist bereit{}
+ THEN bereinige eintragungen (9){} FI.{} pruefe auf noch geoeffnetes menu:{} IF menu ist geoeffnet{} THEN bereinige eintragungen (10){} FI.{} pruefe auf noch freie menuplaetze:{} IF menuleiste.belegt = maxmenus{} THEN bereinige eintragungen (11){} FI.{} pruefe auf schon vorhandenen menunamen:{} IF menuname schon vorhanden{} THEN bereinige eintragungen (12){} FI.{} menuname schon vorhanden:{} INT VAR i;{} FOR i FROM 1 UPTO menuleiste.belegt REP{}
+ untersuche einzelnen menunamen{} PER;{} FALSE.{} untersuche einzelnen menunamen:{} IF menuleiste.menu [i].menuname = compress (name){} THEN LEAVE menuname schon vorhanden WITH TRUE{} FI.{} nimm eintragungen in datenraum vor:{} forget (ds);{} ds := nilspace;{} aktuelles menu := ds;{} init (aktuelles menu);{} aktuelles menu.menuname := compress (name);{} aktuelles menu.menueingangsprozedur := compress (einstiegsproc);{}
+ aktuelles menu.menuausgangsprozedur := compress (ausstiegsproc);{} IF itext <> ""{} THEN aktuelles menu.menuinfo := itext;{} aktuelles menu.lizenznummer := ltext;{} aktuelles menu.versionsnummer := vtext{} ELSE aktuelles menu.menuinfo := bleibt leer symbol;{} aktuelles menu.lizenznummer := "";{} aktuelles menu.versionsnummer := ""{} FI;{} menu ist geoeffnet := TRUE.{}END PROC oeffne menu;{}
+PROC oeffne menu (TEXT CONST name, einstiegsproc, ausstiegsproc):{} oeffne menu (name, einstiegsproc, ausstiegsproc, "", "", ""){}END PROC oeffne menu;{}PROC oeffne menu (TEXT CONST name):{} oeffne menu (name, "", "", "", "", ""){}END PROC oeffne menu;{}PROC bereinige eintragungen (INT CONST nummer):{} forget (ds);{} forget (aktueller menudateiname, quiet);{} menuleiste ist bereit := FALSE;{} menu ist geoeffnet := FALSE;{} errorstop (fehlermeldung [nummer]){}END PROC bereinige eintragungen;{}
+PROC init (MENU VAR m):{} m.menuname := "";{} m.hauptmenuzeiger := 1;{} m.untermenuanfang := 0;{} m.untermenuzeiger := 0;{} m.menueingangsprozedur := "";{} m.menuausgangsprozedur := "";{} m.menuinfo := "";{} m.versionsnummer := "";{} m.anzahl hauptmenupunkte := 0;{} belege hauptmenupunkte.{} belege hauptmenupunkte:{} INT VAR i;{} FOR i FROM 1 UPTO maxhauptmenupunkte REP{}
+ aktuelles einzelmenu.belegt := 0;{} aktuelles einzelmenu.ueberschrift := "";{} aktuelles einzelmenu.anfangsposition := 0;{} aktuelles einzelmenu.maxlaenge := 0;{} aktuelles einzelmenu.aktueller untermenupunkt := 1;{} aktuelles einzelmenu.startprozedurname := "";{} aktuelles einzelmenu.leaveprozedurname := "";{} belege untermenuepunkte{} PER.{} belege untermenuepunkte:{}
+ INT VAR j;{} FOR j FROM 1 UPTO maxuntermenupunkte REP{} aktueller menupunkt.punktkuerzel := "";{} aktueller menupunkt.punktname := "";{} aktueller menupunkt.procname := "";{} aktueller menupunkt.boxtext := "";{} aktueller menupunkt.aktiv := TRUE;{} aktueller menupunkt.angewaehlt := FALSE{} PER.{} aktuelles einzelmenu: m.einzelmenu [i].{} aktueller menupunkt: aktuelles einzelmenu.menupunkt [j].{}END PROC init;{}PROC oberbegriff (TEXT CONST punktname, startprocname, leaveprocname):{}
+ gib hinweis auf oberbegriff;{} untersuche ob menu geoeffnet und bereit ist;{} untersuche oberbegriffe;{} trage neuen oberbegriff ein;{} notiere die anfangsposition;{} notiere start und leaveprozedur;{} erhoehe die anzahl der oberbegriffe.{} gib hinweis auf oberbegriff:{} cursor (1, 6); out (cleop);{} cursor (1, 6); out (aussage [13]); out (invers (punktname)); line.{} untersuche ob menu geoeffnet und bereit ist:{} IF NOT menuleiste ist bereit{} THEN bereinige eintragungen ( 9){}
+ FI;{} IF NOT menu ist geoeffnet{} THEN bereinige eintragungen (13){} FI.{} untersuche oberbegriffe:{} IF zu viele oberbegriffe{} THEN bereinige eintragungen (14){} FI;{} IF gesamtlaenge > maxmenubreite{} THEN bereinige eintragungen (15){} FI.{} zu viele oberbegriffe:{} aktuelles menu.anzahl hauptmenupunkte = maxhauptmenupunkte.{} gesamtlaenge:{} gesamtlaenge ohne letzten punkt + length (compress (punktname)).{} gesamtlaenge ohne letzten punkt:{} length (hauptmenuzeile).{}
+ hauptmenuzeile:{} INT VAR zaehler;{} TEXT VAR zeile :: "";{} schreibe menunamen;{} schreibe oberbegriffe;{} zeile.{} schreibe menunamen:{} IF aktuelles menu. menuname <> ""{} THEN zeile CAT aktuelles menu.menuname;{} zeile CAT ":"{} FI.{} schreibe oberbegriffe:{} FOR zaehler FROM 1 UPTO aktuelles menu.anzahl hauptmenupunkte REP{} zeile CAT hauptmenuluecke;{} zeile CAT aktuelles menu. einzelmenu [zaehler].ueberschrift{} PER;{} zeile CAT hauptmenuluecke.{}
+ trage neuen oberbegriff ein:{} neuer menupunkt.ueberschrift := compress (punktname).{} notiere die anfangsposition:{} neuer menupunkt.anfangsposition := gesamtlaenge ohne letzten punkt + 1.{} notiere start und leaveprozedur:{} neuer menupunkt.startprozedurname := compress (startprocname);{} neuer menupunkt.leaveprozedurname := compress (leaveprocname).{} neuer menupunkt:{} aktuelles menu.einzelmenu [aktuelles menu.anzahl hauptmenupunkte + 1].{} erhoehe die anzahl der oberbegriffe:{}
+ aktuelles menu.anzahl hauptmenupunkte INCR 1.{}END PROC oberbegriff;{}PROC oberbegriff (TEXT CONST punktname):{} oberbegriff (punktname, "", ""){}END PROC oberbegriff;{}PROC menufunktionseintrag (TEXT CONST kuerzel,{} punktbezeichnung,{} prozedurname,{} infotext,{} BOOL CONST ist aktiv):{} gib hinweis auf menufunktionseintrag;{} trage menupunkt ein;{} organisiere menu neu.{}
+ gib hinweis auf menufunktionseintrag:{} line;{} out (aussage [14]);{} out ("'" + kuerzelzeichen + "' - " + punktname).{} kuerzelzeichen:{} IF kuerzel = "" THEN " " ELSE kuerzel FI.{} punktname:{} IF punktbezeichnung = trennzeilensymbol{} THEN "----------"{} ELSE punktbezeichnung{} FI.{} trage menupunkt ein:{} ueberpruefe das kuerzel;{} ueberpruefe die punktbreite;{} ueberpruefe die eintragsnummer;{} aktuelles menu.einzelmenu [stelle].belegt INCR 1;{}
+ aktueller menupunkt.punktkuerzel := compress (kuerzel);{} aktueller menupunkt.punktname := normierter menupunkt;{} aktueller menupunkt.procname := compress (prozedurname);{} aktueller menupunkt.boxtext := infotext;{} aktueller menupunkt.aktiv := ist aktiv;{} aktueller menupunkt.angewaehlt := FALSE.{} aktueller menupunkt:{} aktuelles untermenu.menupunkt [aktuelles untermenu.belegt].{} aktuelles untermenu:{} aktuelles menu.einzelmenu [stelle].{}
+ stelle:{} aktuelles menu.anzahl hauptmenupunkte.{} normierter menupunkt:{} blank + compress (punktbezeichnung).{} ueberpruefe das kuerzel:{} TEXT VAR kurz :: compress (kuerzel);{} IF kuerzel ist zu lang{} THEN bereinige eintragungen (16){} ELIF kuerzel ist schon vorhanden{} THEN bereinige eintragungen (17){} FI.{} kuerzel ist zu lang:{} length (kurz) > 1.{} kuerzel ist schon vorhanden:{} (length (kurz) = 1) AND (pos (vorhandene kuerzel, kurz) > 0).{}
+ vorhandene kuerzel:{} TEXT VAR liste :: "";{} INT VAR zeiger;{} FOR zeiger FROM 1 UPTO aktuelles untermenu.belegt REP{} liste CAT aktuelles untermenu.menupunkt [zeiger].punktkuerzel{} PER;{} liste.{} ueberpruefe die punktbreite:{} IF length (compress (punktbezeichnung)) > maxmenubreite - 10{} THEN bereinige eintragungen (18){} FI.{} ueberpruefe die eintragsnummer:{} IF aktuelles untermenu.belegt = maxuntermenupunkte{} THEN bereinige eintragungen (19){}
+ FI.{} organisiere menu neu:{} IF neue punktlaenge > aktuelles untermenu.maxlaenge{} THEN aktuelles untermenu.maxlaenge := neue punktlaenge{} FI.{} neue punktlaenge:{} length (aktueller menupunkt.punktname).{}END PROC menufunktionseintrag;{}PROC menufunktion (TEXT CONST kuerzel, punktbezeichnung,{} prozedurname, infotext):{} menufunktionseintrag (kuerzel, punktbezeichnung, prozedurname, infotext,{} TRUE){}END PROC menufunktion;{}
+PROC trennlinie:{} menufunktionseintrag ("", trennzeilensymbol, "", "", FALSE){}END PROC trennlinie;{}PROC schliesse menu:{} menuleiste. belegt INCR 1;{} menuleiste.menu [menuleiste.belegt] := aktuelles menu;{} menu ist geoeffnet := FALSE{}END PROC schliesse menu;{}PROC schliesse menukarte:{} forget (ds);{} page; out (piep); put (card finished){}END PROC schliesse menukarte;{}PROC testinstallation (TEXT CONST kartenname):{} ueberpruefe menukarte;{} nimm installation vor.{}
+ ueberpruefe menukarte:{} IF NOT exists (kartenname){} THEN errorstop (fehlermeldung [20] + kartenname + fehlermeldung [21]){} ELIF (pos (kartenname, menutafelpraefix) <> 1){} OR (type (old (kartenname)) <> menutafeltype){} THEN errorstop (fehlermeldung [20] + kartenname + fehlermeldung [22]){} FI.{} nimm installation vor:{} TEXT CONST neuer kartenname{} :: kartenname + " von Task '" + name (myself) + "'";{} command dialogue (FALSE);{}
+ rename (kartenname, neuer kartenname);{} save (neuer kartenname,task (mmtaskname));{} forget (neuer kartenname, quiet);{} reset dialog;{} install menu (neuer kartenname, FALSE);{} fetch (neuer kartenname, task (mmtaskname));{} rename (neuer kartenname, kartenname);{} command dialogue (TRUE);{} page; out (piep); put (install finished){}END PROC testinstallation;{}END PACKET ls menu generator 2;{}
+
diff --git a/menugenerator/ls-Menu-Generator-gen b/menugenerator/ls-Menu-Generator-gen
new file mode 100644
index 0000000..9a4c3fc
--- /dev/null
+++ b/menugenerator/ls-Menu-Generator-gen
@@ -0,0 +1,30 @@
+(*
+
+ *********************************************************
+ *********************************************************
+ ** **
+ ** ls-Menu-Generator **
+ ** GENERATORPROGRAMM **
+ ** Version 1.0 **
+ ** **
+ ** (Stand: 30.03.88) **
+ ** **
+ ** **
+ ** Autor: Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 ERGOS GmbH, Siegburg **
+ ** **
+ *********************************************************
+ *********************************************************
+
+ *)
+
+LET mm taskname = "ls-MENUKARTEN",{} datei 1 = "Generatordatei: Archivmenu",{} datei 2 = "ls-MENUBASISTEXTE",{} datei 3 = "ls-Menu-Generator 1",{} datei 4 = "ls-Menu-Generator 2";{}PROC stelle existenz des mm sicher:{} cursor (1, 5); out (""4"");{} IF NOT exists (task (mm taskname)){} THEN errorstop ("Unbedingt erst den 'MENUKARTEN-MANAGER' generieren!");{} FI{}END PROC stelle existenz des mm sicher;{}PROC vom archiv (TEXT CONST datei):{} cursor (1,5); out (""4"");{}
+ out (" """); out (datei); putline (""" wird geholt.");{} fetch (datei, archive){}END PROC vom archiv;{}PROC hole (TEXT CONST datei):{} IF NOT exists (datei) THEN vom archiv (datei) FI{}END PROC hole;{}PROC in (TEXT CONST datei):{} hole (datei);{} cursor (1, 5); out (""4"");{} out (" """); out (datei); out (""" wird übersetzt: ");{} insert (datei);{} forget (datei, quiet);{}END PROC in;{}PROC schicke (TEXT CONST datei):{} cursor (1, 5); out (""4"");{} out (" """); out(datei);{} out (""" wird zum MENUKARTEN-MANAGER geschickt!");{}
+ command dialogue (FALSE);{} save (datei, task (mm taskname));{} command dialogue (TRUE);{} forget (datei, quiet){}END PROC schicke;{}INT VAR size, used;{}BOOL VAR einzeln;{}storage (size, used);{}einzeln := size - used < 500;{}forget ("ls-Menu-Generator/gen", quiet);{}wirf kopfzeile aus;{}stelle existenz des mm sicher;{}hole die dateien;{}insertiere die dateien;{}mache global manager aus der task.{}wirf kopfzeile aus:{} page;{} putline (" "15"ls-Menu-Generator - Automatische Generierung "14"").{}
+hole die dateien:{} IF NOT exists (datei 1) COR NOT exists (datei 2){} COR NOT exists (datei 3) COR NOT exists (datei 4){} THEN hole dateien vom archiv{} FI.{}hole dateien vom archiv:{} cursor (1,3);{} say ("Ist das Archiv angemeldet und die "); line;{} IF yes ("'ls-Menu-Generator'-Diskette eingelegt"){} THEN lese ein{} ELSE line (2);{} errorstop ("Ohne die Diskette kann ich das System nicht generieren!"){} FI.{}lese ein:{} cursor (1, 3); out (""4"");{} out (" "15"Bitte die Diskette eingelegt lassen! "14"");{}
+ IF NOT einzeln{} THEN hole (datei 1);{} hole (datei 2);{} hole (datei 3);{} hole (datei 4);{} cursor (1, 3); out(""4"");{} out (" "15"Die Diskette wird nicht mehr benötigt! "14"");{} release (archive){} FI.{}insertiere die dateien:{} check off;{} schicke (datei 2);{} in (datei 3);{} in (datei 4);{} IF einzeln THEN release (archive) FI;{} check on.{}mache global manager aus der task:{} global manager.{}
+
diff --git a/mp-bap/ls-MENUKARTE:MP-BAP b/mp-bap/ls-MENUKARTE:MP-BAP
new file mode 100644
index 0000000..564b07c
--- /dev/null
+++ b/mp-bap/ls-MENUKARTE:MP-BAP
Binary files differ
diff --git a/mp-bap/ls-MP BAP 1 b/mp-bap/ls-MP BAP 1
new file mode 100644
index 0000000..be7e3d2
--- /dev/null
+++ b/mp-bap/ls-MP BAP 1
@@ -0,0 +1,119 @@
+PACKET ls mp bap 1 DEFINES (*******************************)
+ (* *)
+ stdvoreinstellung der parameter, (* ls-MP BAP 1 *)
+ werkstueckdefinition, (* Version 1.1 *)
+ tastendefinition, (* *)
+ phasendefinition, (* (c) 1987, 1988 *)
+ bewertungsschluessel, (* by Eva Latta-Weber *)
+ werkstueckaufhaenger, (* Bielefeld *)
+ tastenbezeichnung, (* *)
+ piepse, (*******************************)
+
+ mp bap einstellung anzeigen,
+ mp bap standardwerte,
+ mp bap breite des werkstuecks,
+ mp bap hoehe des werkstuecks,
+ mp bap invers normal,
+ mp bap zeichensatz,
+ mp bap fehlerzeichen,
+ mp bap tastenbelegung,
+ mp bap anzahl arbeitsphasen,
+ mp bap dauer einer arbeitsphase,
+ mp bap pausendauer,
+ mp bap wertungsschluessel:
+
+LET maxspalten = 70,{} maxzeilen = 14,{} kleinster wert = 1,{} oben unten return = ""3""10""13"",{} punkt = "+",{} punkt und zurueck = "+"8"",{} piep = ""7"",{} blank = " ";{}INT VAR aktuelle werkstueckbreite,{} aktuelle werkstueckhoehe,{} kleinster aktueller zeichencode,{} groesster aktueller zeichencode,{} aktuelle anzahl der arbeitsphasen,{}
+ aktuelle arbeitsphasendauer in minuten,{} aktuelle pausendauer in minuten;{}TEXT VAR aktuelles fehlerzeichen,{} nach rechts,{} nach links,{} nach oben,{} nach unten,{} ausbesserung,{} naechstes;{}BOOL VAR inversdarstellung;{}ROW 11 REAL VAR bewertung;{}WINDOW VAR w1, w2, w3, w4;{}PROC stdvoreinstellung der parameter:{} aktuelle werkstueckbreite := 15;{} aktuelle werkstueckhoehe := 12;{} kleinster aktueller zeichencode := 65;{}
+ groesster aktueller zeichencode := 90;{} aktuelle anzahl der arbeitsphasen := 3;{} aktuelle arbeitsphasendauer in minuten := 10;{} aktuelle pausendauer in minuten := 2;{} aktuelles fehlerzeichen := "F";{} nach rechts := ""2"";{} nach links := ""8"";{} nach oben := ""3"";{} nach unten := ""10"";{} ausbesserung := ""1"";{}
+ naechstes := ""27"";{} inversdarstellung := FALSE;{} bewertung := ROW 11 REAL : (0.0, 0.1, 0.2, 0.3, 0.4, 0.5,{} 0.6, 0.7, 0.8, 0.9, 1.0){}END PROC stdvoreinstellung der parameter;{}PROC werkstueckdefinition (INT VAR breite, hoehe, kleinster, groesster,{} TEXT VAR fzeichen, BOOL VAR invers):{} breite := aktuelle werkstueckbreite;{} hoehe := aktuelle werkstueckhoehe;{}
+ kleinster := kleinster aktueller zeichencode;{} groesster := groesster aktueller zeichencode;{} fzeichen := aktuelles fehlerzeichen;{} invers := inversdarstellung{}END PROC werkstueckdefinition;{}PROC tastendefinition (TEXT VAR rechts, links, hoch, runter, aus, nach):{} rechts := nach rechts;{} links := nach links;{} hoch := nach oben;{} runter := nach unten;{} aus := ausbesserung;{} nach := naechstes{}END PROC tastendefinition;{}
+PROC phasendefinition (INT VAR aphasenzahl, aphasendauer, pausendauer):{} aphasenzahl := aktuelle anzahl der arbeitsphasen;{} aphasendauer := aktuelle arbeitsphasendauer in minuten;{} pausendauer := aktuelle pausendauer in minuten{}END PROC phasendefinition;{}PROC bewertungsschluessel (ROW 11 REAL VAR schluessel):{} INT VAR zeiger;{} FOR zeiger FROM 1 UPTO 11 REP{} schluessel [zeiger] := bewertung [zeiger]{} PER{}END PROC bewertungsschluessel;{}PROC mp bap einstellung anzeigen:{} aktuellen parameterzustand anzeigen;{}
+ regenerate menuscreen{}END PROC mp bap einstellung anzeigen;{}PROC mp bap standardwerte:{} standardwerte einstellen;{} regenerate menuscreen{}END PROC mp bap standardwerte;{}PROC mp bap breite des werkstuecks:{} breite des werkstuecks einstellen;{} regenerate menuscreen{}END PROC mp bap breite des werkstuecks;{}PROC mp bap hoehe des werkstuecks:{} hoehe des werkstuecks einstellen;{} regenerate menuscreen{}END PROC mp bap hoehe des werkstuecks;{}PROC mp bap invers normal:{} werkstueckdarstellung einstellen;{}
+ regenerate menuscreen{}END PROC mp bap invers normal;{}PROC mp bap zeichensatz:{} zeichensatz einstellen;{} regenerate menuscreen{}END PROC mp bap zeichensatz;{}PROC mp bap fehlerzeichen:{} fehlerzeichen veraendern;{} regenerate menuscreen{}END PROC mp bap fehlerzeichen;{}PROC mp bap tastenbelegung:{} tastaturbelegung einstellen;{} regenerate menuscreen{}END PROC mp bap tastenbelegung;{}PROC mp bap anzahl arbeitsphasen:{} anzahl der arbeitsphasen festlegen;{} regenerate menuscreen{}END PROC mp bap anzahl arbeitsphasen;{}
+PROC mp bap dauer einer arbeitsphase:{} dauer einer arbeitsphase festlegen;{} regenerate menuscreen{}END PROC mp bap dauer einer arbeitsphase;{}PROC mp bap pausendauer:{} pausendauer festlegen;{} regenerate menuscreen{}END PROC mp bap pausendauer;{}PROC mp bap wertungsschluessel:{} wertungsschluessel veraendern;{} regenerate menuscreen{}END PROC mp bap wertungsschluessel;{}PROC aktuellen parameterzustand anzeigen:{} zeige die fenster;{} fuelle die fenster mit inhalt;{} gib hinweis aus.{}
+ zeige die fenster:{} w1 := window ( 2, 2, 37, 20);{} w2 := window (41, 2, 38, 20);{} w3 := window ( 1, 1, 79, 24);{} page; show (w1); show (w2).{} fuelle die fenster mit inhalt:{} zeige inhalt fenster 1;{} zeige inhalt fenster 2.{} zeige inhalt fenster 1:{} zeige eingestellte parameter an (w1).{} zeige inhalt fenster 2:{} gib bewertungsschluessel aus (w2).{} gib hinweis aus:{} out footnote (w3, anwendungstext (2)); pause.{}END PROC aktuellen parameterzustand anzeigen;{}
+PROC zeige eingestellte parameter an (WINDOW VAR w):{} zeige ueberschrift;{} zeige werkstueckdefinition;{} zeige tastenbelegung;{} zeige simulationszeiten.{} zeige ueberschrift:{} cursor (w, 1, 1); out (w, center (w, invers (anwendungstext ( 1)))).{} zeige werkstueckdefinition:{} cursor (w, 2, 3); out (w, anwendungstext ( 6));{} out (w, text (aktuelle werkstueckbreite, 3));{} out (w, anwendungstext (28));{} cursor (w, 2, 4); out (w, anwendungstext ( 7));{}
+ out (w, text (aktuelle werkstueckhoehe, 3));{} out (w, anwendungstext (28));{} cursor (w, 2, 5); out (w, anwendungstext ( 8));{} IF inversdarstellung{} THEN out (w, anwendungstext (29)){} ELSE out (w, anwendungstext (30)){} FI;{} cursor (w, 2, 6); out (w, anwendungstext ( 9));{} out (w, zeichensatz);{} cursor (w, 2, 7); out (w, anwendungstext (10));{}
+ out (blank + aktuelles fehlerzeichen).{} zeige tastenbelegung:{} cursor (w, 2, 9); out (w, anwendungstext (11));{} out (w, tastenbezeichnung (nach rechts));{} cursor (w, 2, 10); out (w, anwendungstext (12));{} out (w, tastenbezeichnung (nach links));{} cursor (w, 2, 11); out (w, anwendungstext (13));{} out (w, tastenbezeichnung (nach oben));{} cursor (w, 2, 12); out (w, anwendungstext (14));{} out (w, tastenbezeichnung (nach unten));{}
+ cursor (w, 2, 13); out (w, anwendungstext (15));{} out (w, tastenbezeichnung (ausbesserung));{} cursor (w, 2, 14); out (w, anwendungstext (16));{} out (w, tastenbezeichnung (naechstes)).{} zeige simulationszeiten:{} cursor (w, 2, 16); out (w, anwendungstext (17));{} out (w, text (aktuelle anzahl der arbeitsphasen, 4));{} cursor (w, 2, 17); out (w, anwendungstext (18));{} out (w, text (aktuelle arbeitsphasendauer in minuten, 4));{}
+ out (w, anwendungstext (51));{} cursor (w, 2, 18); out (w, anwendungstext (19));{} out (w, text (aktuelle pausendauer in minuten, 4));{} out (w, anwendungstext (51));{} cursor (w, 2, 20); out (w, anwendungstext ( 5));{} out (w, gesamtdauerangabe).{} zeichensatz:{} blank + code (kleinster aktueller zeichencode) + "..." +{} code (groesster aktueller zeichencode) + " (" +{} text (groesster aktueller zeichencode{}
+ - kleinster aktueller zeichencode + 1, 2) +{} anwendungstext (28) + ")".{} gesamtdauerangabe:{} text ( arbeitsdauer + pausendauer, 4) + anwendungstext (51).{} arbeitsdauer:{} aktuelle anzahl der arbeitsphasen{} * aktuelle arbeitsphasendauer in minuten.{} pausendauer:{} (aktuelle anzahl der arbeitsphasen - 1){} * aktuelle pausendauer in minuten.{}END PROC zeige eingestellte parameter an;{}PROC gib bewertungsschluessel aus (WINDOW VAR w):{} zeichne koordinatenkreuz;{}
+ trage messwerte ein.{} zeichne koordinatenkreuz:{} cursor (w, 1, 1); out (w, center (w, invers (anwendungstext ( 4))));{} cursor (w, 2, 3); out (w, anwendungstext (20));{} cursor (w, 2, 4); out (w, anwendungstext (21));{} cursor (w, 2, 6); out (w, anwendungstext (23));{} cursor (w, 2, 7); out (w, anwendungstext (22));{} cursor (w, 2, 8); out (w, anwendungstext (22));{} cursor (w, 2, 9); out (w, anwendungstext (22));{} cursor (w, 2, 10); out (w, anwendungstext (22));{}
+ cursor (w, 2, 11); out (w, anwendungstext (24));{} cursor (w, 2, 12); out (w, anwendungstext (22));{} cursor (w, 2, 13); out (w, anwendungstext (22));{} cursor (w, 2, 14); out (w, anwendungstext (22));{} cursor (w, 2, 15); out (w, anwendungstext (22));{} cursor (w, 2, 16); out (w, anwendungstext (25));{} cursor (w, 2, 17); out (w, anwendungstext (26));{} cursor (w, 2, 19); out (w, anwendungstext (27)).{} trage messwerte ein:{} INT CONST abszisse :: 16, ordinate :: 2;{}
+ INT VAR nr;{} FOR nr FROM 1 UPTO 11 REP{} zeichne einen punkt{} PER.{} zeichne einen punkt:{} cursor (w, ordinate + 3 * nr, abszisse - nachkommastelle); out (punkt).{} nachkommastelle:{} int(bewertung [nr] * 10.0).{}END PROC gib bewertungsschluessel aus;{}PROC standardwerte einstellen:{} zeige fenster;{} zeige eingestellte parameter an (w1);{} gib information aus;{} hole bestaetigung ein.{} zeige fenster:{} w1 := window ( 2, 2, 37, 20);{} w2 := window (41, 10, 37, 12);{}
+ w3 := window (41, 2, 37, 6);{} page; show (w1); show (w2); show (w3).{} gib information aus:{} cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (52))));{} cursor (w2, 2, 3); out (w2, anwendungstext (67));{} cursor (w2, 2, 4); out (w2, anwendungstext (68));{} cursor (w2, 2, 7); out (w2, anwendungstext (69));{} cursor (w2, 2, 9); out (w2, anwendungstext (70));{} cursor (w2, 2,10); out (w2, anwendungstext (71));{} cursor (w2, 2,11); out (w2, anwendungstext (72));{}
+ cursor (w2, 2,12); out (w2, anwendungstext (73)).{} hole bestaetigung ein:{} cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (66))));{} cursor (w3, 2, 3);{} IF yes (w3, anwendungstext (66)){} THEN stdvoreinstellung der parameter;{} gib positive rueckmeldung{} FI.{} gib positive rueckmeldung:{} page (w1);{} zeige eingestellte parameter an (w1);{} cleop (w3, 2, 3); out (anwendungstext (221));{} cursor (w3, 2, 5); out (anwendungstext ( 3));{}
+ pause.{}END PROC standardwerte einstellen;{}PROC breite des werkstuecks einstellen:{} zeige die fenster;{} hinweise an den benutzer ausgeben;{} werkstueck zeigen (w3);{} erfrage veraenderung;{} REP{} neuen wert vom bildschirm holen{} UNTIL benutzer ist einverstanden PER.{} zeige die fenster:{} w1 := window ( 2, 2, 26, 6);{} w2 := window (30, 2, 48, 6);{} w3 := window (2, 9, 77, 16);{} page; show (w1); show (w2).{} hinweise an den benutzer ausgeben:{} cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{}
+ cursor (w1, 2, 3); out (w1, anwendungstext (53));{} out (w1, text (kleinster wert, 3));{} cursor (w1, 2, 4); out (w1, anwendungstext (54));{} out (w1, text (maxspalten, 3));{} cursor (w1, 2, 6); out (w1, anwendungstext (55));{} out (w1, text (aktuelle werkstueckbreite, 3)).{} erfrage veraenderung:{} cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (57))));{} cursor (w2, 2, 3);{} IF no (anwendungstext (216)){}
+ THEN LEAVE breite des werkstuecks einstellen{} FI.{} neuen wert vom bildschirm holen:{} cleop (w2, 2, 3); out (w2, anwendungstext (58));{} cursor (w2, 2, 4); out (w2, anwendungstext (59));{} cursor (w2, 2, 6); out (w2, anwendungstext (60));{} aktuelle werkstueckbreite := ermittelter wert (1, maxspalten,{} aktuelle werkstueckbreite).{} benutzer ist einverstanden :{} gib aktuelle infos aus;{} hole bestaetigung.{} gib aktuelle infos aus:{}
+ hinweise an den benutzer ausgeben;{} werkstueck zeigen (w3);{} cleop (w2, 1, 3).{} hole bestaetigung:{} cursor (w2, 2, 3);{} IF yes (w2, anwendungstext (62)){} THEN TRUE{} ELSE FALSE{} FI.{}END PROC breite des werkstuecks einstellen;{}PROC hoehe des werkstuecks einstellen:{} fenster zeigen;{} hinweise an den benutzer ausgeben;{} werkstueck zeigen (w3);{} erfrage veraenderung;{} REP{} neuen wert vom bildschirm holen{} UNTIL benutzer ist einverstanden PER.{}
+ fenster zeigen:{} w1 := window ( 2, 2, 26, 6);{} w2 := window (30, 2, 48, 6);{} w3 := window (2, 9, 77, 16);{} page; show (w1); show (w2).{} hinweise an den benutzer ausgeben:{} cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{} cursor (w1, 2, 3); out (w1, anwendungstext (53));{} out (w1, text (kleinster wert, 3));{} cursor (w1, 2, 4); out (w1, anwendungstext (54));{} out (w1, text (maxzeilen, 3));{} cursor (w1, 2, 6); out (w1, anwendungstext (55));{}
+ out (w1, text (aktuelle werkstueckhoehe, 3)).{} erfrage veraenderung:{} cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (63))));{} cursor (w2, 2, 3);{} IF no (anwendungstext (217)){} THEN LEAVE hoehe des werkstuecks einstellen{} FI.{} neuen wert vom bildschirm holen:{} cleop (w2, 2, 3); out (w2, anwendungstext (58));{} cursor (w2, 2, 4); out (w2, anwendungstext (59));{} cursor (w2, 2, 6); out (w2, anwendungstext (64));{} aktuelle werkstueckhoehe := ermittelter wert (1, maxzeilen,{}
+ aktuelle werkstueckhoehe).{} benutzer ist einverstanden :{} gib aktuelle infos aus;{} hole bestaetigung.{} gib aktuelle infos aus:{} hinweise an den benutzer ausgeben;{} werkstueck zeigen (w3);{} cleop (w2, 1, 3).{} hole bestaetigung:{} cursor (w2, 2, 3);{} IF yes (w2, anwendungstext (65)){} THEN TRUE{} ELSE FALSE{} FI.{}END PROC hoehe des werkstuecks einstellen;{}PROC werkstueckdarstellung einstellen:{} fenster zeigen;{}
+ hinweise an den benutzer ausgeben;{} werkstueck zeigen (w3);{} REP{} bestaetigung einholen;{} hinweise an den benutzer ausgeben;{} werkstueck zeigen (w3){} UNTIL benutzer ist einverstanden PER.{} fenster zeigen:{} w1 := window ( 2, 2, 28, 6);{} w2 := window (32, 2, 46, 6);{} w3 := window ( 2, 9, 77, 16);{} page; show (w1); show (w2).{} hinweise an den benutzer ausgeben:{} cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{} cursor (w1, 2, 3); out (w1, anwendungstext (74));{}
+ out (w1, anwendungstext (76));{} cursor (w1, 2, 4); out (w1, anwendungstext (74));{} out (w1, anwendungstext (77));{} cursor (w1, 2, 6); out (w1, anwendungstext (75));{} IF inversdarstellung{} THEN out (w1, anwendungstext (77)){} ELSE out (w1, anwendungstext (76)){} FI.{} bestaetigung einholen:{} page (w2);{} cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (89))));{}
+ cursor (w2, 2, 3);{} IF yes (w2, anwendungstext (78)){} THEN veraendere darstellungsart{} ELSE LEAVE werkstueckdarstellung einstellen{} FI.{} veraendere darstellungsart:{} IF inversdarstellung{} THEN inversdarstellung := FALSE{} ELSE inversdarstellung := TRUE{} FI.{} benutzer ist einverstanden:{} cleop (w2, 1, 3);{} cursor (w2, 2, 3);{} IF yes (w2, anwendungstext (99)){} THEN TRUE{} ELSE FALSE{} FI.{}END PROC werkstueckdarstellung einstellen;{}
+PROC zeichensatz einstellen:{} zeige fenster;{} gib eingestellten zeichensatz an;{} gib bedienhinweise aus;{} erfrage neueinstellung;{} REP{} erfrage das neue fehlerzeichen;{} ermittle das kleinste zeichen;{} ermittle das groesste zeichen;{} page (w1);{} gib eingestellten zeichensatz an{} UNTIL benutzer ist einverstanden PER.{} zeige fenster:{} w1 := window ( 2, 2, 28, 22);{} w2 := window (32, 10, 46, 14);{} w3 := window (32, 2, 46, 6);{} page; show (w1); show (w2); show (w3).{}
+ gib eingestellten zeichensatz an:{} cursor (w1, 1, 1);{} out (w1, center (w1, invers (anwendungstext (79))));{} gib zeichenkette aus (w1, kleinster aktueller zeichencode,{} groesster aktueller zeichencode,{} code (aktuelles fehlerzeichen)).{} gib bedienhinweise aus:{} cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (52))));{} cursor (w2, 2, 3); out (w2, anwendungstext (80));{} cursor (w2, 2, 4); out (w2, anwendungstext (81));{}
+ cursor (w2, 2, 5); out (w2, anwendungstext (82));{} cursor (w2, 2, 6); out (w2, anwendungstext (83));{} cursor (w2, 2, 8); out (w2, anwendungstext (84));{} cursor (w2, 2, 9); out (w2, anwendungstext (85));{} cursor (w2, 2,10); out (w2, anwendungstext (86));{} cursor (w2, 2,12); out (w2, anwendungstext (87));{} cursor (w2, 2,13); out (w2, anwendungstext (88)).{} erfrage neueinstellung:{} cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (90))));{} cursor (w3, 2, 3);{}
+ IF no (w3, anwendungstext (91)){} THEN LEAVE zeichensatz einstellen{} FI.{} erfrage das neue fehlerzeichen:{} gib vollstaendigen zeichensatz aus;{} gib fehlerzeicheninformationen aus;{} REP{} lasse fehlerzeichen eingeben{} UNTIL fehlerzeichen ist ok PER.{} gib vollstaendigen zeichensatz aus:{} page (w1); page (w2); page (w3);{} cursor (w1, 1, 1);{} out (w1, center (w1, invers (anwendungstext (92))));{} gib zeichenkette aus (w1, 33, 126, 0).{} gib fehlerzeicheninformationen aus:{}
+ cursor (w2, 1, 1);{} out (w2, center (w2, invers (anwendungstext (52))));{} cursor (w2, 2, 3); out (w2, anwendungstext (95));{} cursor (w2, 2, 4); out (w2, anwendungstext (96));{} cursor (w2, 2, 6); out (w2, anwendungstext (97)).{} lasse fehlerzeichen eingeben:{} cursor (w3, 1, 1);{} out (w3, center (w3, invers (anwendungstext (100))));{} cursor (w3, 2, 3);{} out (w3, anwendungstext (101));{} cursor on; inchar (aktuelles fehlerzeichen); cursor off;{} IF fehlerzeichen ist ok{}
+ THEN out (w3, aktuelles fehlerzeichen);{} markiere das fehlerzeichen im ersten fenster;{} ELSE lege beschwerde ein{} FI.{} fehlerzeichen ist ok:{} code (aktuelles fehlerzeichen) >= 33{} AND code (aktuelles fehlerzeichen) <= 126.{} markiere das fehlerzeichen im ersten fenster:{} positioniere cursor in zeichenkette (w1, 33, code (aktuelles fehlerzeichen));{} out (w1, invers (aktuelles fehlerzeichen)).{} lege beschwerde ein:{} piepse;{} cursor (w2, 2, 8); out (w2, anwendungstext (102));{}
+ cursor (w2, 2,10); out (w2, anwendungstext (103));{} cursor (w2, 2,11); out (w2, anwendungstext (104));{} cursor (w2, 2,12); out (w2, anwendungstext (105));{} cursor (w2, 2,13); out (w2, anwendungstext (106));{} cursor (w2, 2,14); out (w2, anwendungstext (107)).{} ermittle das kleinste zeichen:{} page (w2); page (w3);{} gib kleinste zeichencode informationen aus;{} lasse den vorbereich festlegen.{} ermittle das groesste zeichen:{} lasse den nachbereich festlegen.{} gib kleinste zeichencode informationen aus:{}
+ cursor (w2, 1, 1);{} out (w2, center (w2, invers (anwendungstext (52))));{} cursor (w2, 2, 3); out (w2, anwendungstext (111));{} cursor (w2, 2, 4); out (w2, anwendungstext (112));{} cursor (w2, 2, 5); out (w2, anwendungstext (113));{} cursor (w2, 2, 6); out (w2, anwendungstext (114));{} cursor (w2, 2, 8); out (w2, anwendungstext (115));{} cursor (w2, 2, 9); out (w2, anwendungstext (116));{} cursor (w2, 2,10); out (w2, anwendungstext (117));{} cursor (w2, 2,11); out (w2, anwendungstext (118));{}
+ cursor (w2, 2,13); out (w2, anwendungstext (119));{} cursor (w2, 2,14); out (w2, anwendungstext (120)).{} lasse den vorbereich festlegen:{} INT VAR s, z; page (w3); cursor (w3, 1, 1);{} out (w3, center (w3, invers (anwendungstext (121))));{} cursor (w3, 2, 3); out (w3, anwendungstext (122));{} cursor (w3, 2, 4); out (w3, anwendungstext (123));{} cursor (w3, 2, 5); out (w3, anwendungstext (125));{} get cursor (s, z); cursor on;{} kleinster aktueller zeichencode := code (aktuelles fehlerzeichen);{}
+ groesster aktueller zeichencode := code (aktuelles fehlerzeichen);{} kleinster aktueller zeichencode := eingabe mit intervallanzeige ( w1, 33,{} code (aktuelles fehlerzeichen),{} kleinster aktueller zeichencode, s, z);{} cursor off.{} lasse den nachbereich festlegen:{} cursor (w3, 1, 1);{} out (w3, center (w3, invers (anwendungstext (121))));{} cursor (w3, 2, 3); out (w3, anwendungstext (122));{} cursor (w3, 2, 4); out (w3, anwendungstext (124));{}
+ cursor (w3, 2, 5); out (w3, anwendungstext (125));{} get cursor (s, z); cursor on;{} groesster aktueller zeichencode := eingabe mit intervallanzeige ( w1,{} code (aktuelles fehlerzeichen), 126,{} groesster aktueller zeichencode, s, z);{} cursor off.{} benutzer ist einverstanden:{} page (w3); cursor (w3, 1, 1);{} out (w3, center (w3, invers (anwendungstext (90))));{} cursor (w3, 2, 3);{} IF yes (w3, anwendungstext (126)){}
+ THEN TRUE{} ELSE FALSE{} FI.{}END PROC zeichensatz einstellen;{}PROC fehlerzeichen veraendern:{} fenster zeigen;{} gib eingestellten zeichensatz an;{} gib bedienhinweise aus;{} erfrage neueinstellung;{} REP{} lasse fehlerzeichen einstellen{} UNTIL benutzer ist einverstanden PER.{} fenster zeigen:{} w1 := window ( 2, 2, 28, 22);{} w2 := window (32, 10, 46, 14);{} w3 := window (32, 2, 46, 6);{} page; show (w1); show (w2); show (w3).{} gib eingestellten zeichensatz an:{}
+ cursor (w1, 1, 1);{} out (w1, center (w1, invers (anwendungstext (79))));{} gib zeichenkette aus (w1, kleinster aktueller zeichencode,{} groesster aktueller zeichencode,{} code (aktuelles fehlerzeichen)).{} gib bedienhinweise aus:{} cursor (w2, 1, 1);{} out (w2, center (w2, invers (anwendungstext (52))));{} cursor (w2, 2, 3); out (w2, anwendungstext (131));{} cursor (w2, 2, 4); out (w2, anwendungstext (132));{} cursor (w2, 2, 5); out (w2, anwendungstext (133));{}
+ cursor (w2, 2, 7); out (w2, anwendungstext (134));{} cursor (w2, 2, 8); out (w2, anwendungstext (135));{} cursor (w2, 2, 9); out (w2, anwendungstext (136)).{} erfrage neueinstellung:{} cursor (w3, 1, 1);{} out (w3, center (w3, invers (anwendungstext (130))));{} cursor (w3, 2, 3);{} IF no (w3, anwendungstext (137)){} THEN LEAVE fehlerzeichen veraendern{} FI.{} lasse fehlerzeichen einstellen:{} INT VAR s, z, fehlercode :: code (aktuelles fehlerzeichen);{} page (w3); cursor (w3, 1, 1);{}
+ out (w3, center (w3, invers (anwendungstext (138))));{} cursor (w3, 2, 3); out (w3, anwendungstext (139));{} cursor (w3, 2, 4); out (w3, anwendungstext (140));{} cursor (w3, 2, 5); out (w3, anwendungstext (141));{} get cursor (s, z); cursor on;{} fehlercode := eingabe mit elementanzeige (w1,{} kleinster aktueller zeichencode,{} groesster aktueller zeichencode,{} fehlercode, s, z);{}
+ cursor off;{} aktuelles fehlerzeichen := code (fehlercode).{} benutzer ist einverstanden:{} page (w3); cursor (w3, 1, 1);{} out (w3, center (w3, invers (anwendungstext (130))));{} cursor (w3, 2, 3);{} IF yes (w3, anwendungstext (142)){} THEN TRUE{} ELSE FALSE{} FI.{}END PROC fehlerzeichen veraendern;{}PROC tastaturbelegung einstellen:{} ROW 6 TEXT VAR tastenname, taste;{} fenster zeigen;{} REP{} tastaturneubelegung vornehmen{} UNTIL benutzer ist einverstanden PER.{}
+ fenster zeigen:{} w1 := window ( 2, 2, 28, 10);{} w2 := window ( 2, 14, 28, 10);{} w3 := window (32, 10, 46, 14);{} w4 := window (32, 2, 46, 6);{} page; show (w1); show (w2); show (w3); show (w4).{} tastaturneubelegung vornehmen:{} alte tastenbelegung einlesen;{} tastenbelegung anzeigen;{} bedienhinweise ausgeben;{} veraenderung erfragen;{} neue tastenbelegung erfragen;{} hinweis zur bewertung und stand ausgeben.{} alte tastenbelegung einlesen:{} INT VAR z1;{}
+ FOR z1 FROM 1 UPTO 6 REP{} tastenname [z1] := anwendungstext (z1 + 10){} PER;{} taste [1] := nach rechts;{} taste [2] := nach links;{} taste [3] := nach oben;{} taste [4] := nach unten;{} taste [5] := ausbesserung;{} taste [6] := naechstes;{} cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (151)))).{} tastenbelegung anzeigen:{} INT VAR cspa, czei;{} cursor (w1, 2, 3); out (w1, tastenname [1]);{} out (w1, tastenbezeichnung (taste [1]));{}
+ get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{} cursor (w1, 2, 4); out (w1, tastenname [2]);{} out (w1, tastenbezeichnung (taste [2]));{} get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{} cursor (w1, 2, 5); out (w1, tastenname [3]);{} out (w1, tastenbezeichnung (taste [3]));{} get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{} cursor (w1, 2, 6); out (w1, tastenname [4]);{}
+ out (w1, tastenbezeichnung (taste [4]));{} get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{} cursor (w1, 2, 8); out (w1, tastenname [5]);{} out (w1, tastenbezeichnung (taste [5]));{} get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{} cursor (w1, 2,10); out (w1, tastenname [6]);{} out (w1, tastenbezeichnung (taste [6]));{} get cursor (w1, cspa, czei); cleol (w1, cspa, czei).{}
+ bedienhinweise ausgeben:{} cursor (w2, 1, 1); out (center (w2, invers (anwendungstext (152))));{} cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (52))));{} cursor (w3, 2, 3); out (w3, anwendungstext (153));{} cursor (w3, 2, 4); out (w3, anwendungstext (154));{} cursor (w3, 2, 6); out (w3, anwendungstext (155));{} cursor (w3, 2, 7); out (w3, anwendungstext (156));{} cursor (w3, 2, 8); out (w3, anwendungstext (157));{} cursor (w3, 2, 9); out (w3, anwendungstext (158));{}
+ cursor (w3, 2,11); out (w3, anwendungstext (159));{} cursor (w3, 2,12); out (w3, anwendungstext (160));{} cursor (w3, 2,13); out (w3, anwendungstext (161));{} cursor (w3, 2,14); out (w3, anwendungstext (162)).{} veraenderung erfragen:{} cursor (w4, 1, 1); out (w4, center (w4, invers (anwendungstext (163))));{} cursor (w4, 2, 3);{} IF no (w4, anwendungstext (164)){} THEN LEAVE tastaturbelegung einstellen{} FI.{} neue tastenbelegung erfragen:{} INT VAR z2; page (w4);{}
+ cursor (w4, 1, 1); out (w4, center (w4, invers (anwendungstext (163))));{} cursor (w4, 2, 3); out (w4, anwendungstext (165));{} FOR z2 FROM 1 UPTO 6 REP{} gib tastenhinweis;{} hole tastatureingabe;{} tastenbelegung anzeigen{} PER.{} gib tastenhinweis:{} cleol (w4, 2, 5); out (w4, tastenname [z2]).{} hole tastatureingabe:{} INT VAR s, z; get cursor (w4, s, z);{} cursor on; inchar (taste [z2]); cursor off;{} cursor (w4, s, z); out (w4, tastenbezeichnung (taste [z2])).{}
+ hinweis zur bewertung und stand ausgeben:{} IF neue tastenbelegung ist ok{} THEN akzeptiere{} ELSE akzeptiere nicht{} FI.{} neue tastenbelegung ist ok:{} INT VAR zeiger; TEXT VAR tastenkette :: "";{} FOR zeiger FROM 1 UPTO 6 REP{} IF pos (tastenkette, taste [zeiger]) > 0{} THEN LEAVE neue tastenbelegung ist ok WITH FALSE{} ELSE tastenkette CAT taste [zeiger]{} FI{} PER;{} TRUE.{} akzeptiere:{} cursor (w2, 3, 4);{} out (w2, anwendungstext (166));{}
+ cursor (w2, 7, 6);{} out (w2, anwendungstext (167)).{} akzeptiere nicht:{} cursor (w2, 3, 3); out (w2, anwendungstext (168));{} cursor (w2, 3, 4); out (w2, anwendungstext (169));{} cursor (w2, 3, 6); out (w2, anwendungstext (170));{} cursor (w2, 3, 7); out (w2, anwendungstext (171));{} cursor (w2, 3, 9); out (w2, anwendungstext (172));{} cursor (w2, 5,10); out (w2, anwendungstext (173)).{} benutzer ist einverstanden:{} page (w4);{} cursor (w4, 1, 1); out (w4, center (w4, invers (anwendungstext (163))));{}
+ IF neue tastenbelegung ist ok{} THEN gib hinweis auf abspeicherung{} ELSE frage nach neueingabe{} FI.{} gib hinweis auf abspeicherung:{} cursor (w4, 3, 3); out (w4, anwendungstext (174));{} neue tastenbelegung festschreiben;{} cursor (w4, 3, 5); out (w4, anwendungstext ( 2));{} cursor on; pause; cursor off;{} TRUE.{} neue tastenbelegung festschreiben:{} nach rechts := taste [1];{} nach links := taste [2];{} nach oben := taste [3];{} nach unten := taste [4];{}
+ ausbesserung := taste [5];{} naechstes := taste [6].{} frage nach neueingabe:{} cursor (w4, 2, 3);{} IF yes (w4, anwendungstext (175)){} THEN cleop (w2, 1, 3); FALSE{} ELSE alte tastenbelegung einlesen;{} tastenbelegung anzeigen;{} cleop (w4, 2, 3); out (w4, anwendungstext (176));{} cursor (w4, 3, 5); out (w4, anwendungstext ( 2));{} cursor on; pause; cursor off;{} TRUE{} FI.{}END PROC tastaturbelegung einstellen;{}
+PROC simulationszeiten anzeigen (WINDOW VAR w):{} cursor (w, 1, 1); out (w, center (w, invers (anwendungstext (181))));{} cursor (w, 2, 3); out (w, anwendungstext (17));{} out (w, text (aktuelle anzahl der arbeitsphasen, 4));{} cursor (w, 2, 4); out (w, anwendungstext (18));{} out (w, text (aktuelle arbeitsphasendauer in minuten, 4));{} out (w, anwendungstext (51));{} cursor (w, 2, 5); out (w, anwendungstext (19));{} out (w, text (aktuelle pausendauer in minuten, 4));{}
+ out (w, anwendungstext (51));{} cursor (w, 2, 7); out (w, anwendungstext ( 5));{} out (w, gesamtdauerangabe).{} gesamtdauerangabe:{} text ( arbeitsdauer + pausendauer, 4) + anwendungstext (51).{} arbeitsdauer:{} aktuelle anzahl der arbeitsphasen{} * aktuelle arbeitsphasendauer in minuten.{} pausendauer:{} (aktuelle anzahl der arbeitsphasen - 1){} * aktuelle pausendauer in minuten.{}END PROC simulationszeiten anzeigen;{}PROC anzahl der arbeitsphasen festlegen:{}
+ INT CONST minwert :: 2, maxwert :: 20;{} zeige fenster;{} hinweise an den benutzer ausgeben;{} simulationszeiten anzeigen (w2);{} erfrage veraenderung;{} REP{} neuen wert vom bildschirm holen{} UNTIL benutzer ist einverstanden PER.{} zeige fenster:{} w1 := window ( 2, 2, 28, 6);{} w2 := window (22, 12, 37, 7);{} w3 := window (32, 2, 47, 6);{} page; show (w1); show (w2); show (w3).{} hinweise an den benutzer ausgeben:{} cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{}
+ cursor (w1, 2, 3); out (w1, anwendungstext (53));{} out (w1, text (minwert, 2));{} cursor (w1, 2, 4); out (w1, anwendungstext (54));{} out (w1, text (maxwert, 2));{} cursor (w1, 2, 6); out (w1, anwendungstext (55));{} out (w1, text (aktuelle anzahl der arbeitsphasen, 2)).{} erfrage veraenderung:{} cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (182))));{} cursor (w3, 2, 3);{} IF no (anwendungstext (218)){}
+ THEN LEAVE anzahl der arbeitsphasen festlegen{} FI.{} neuen wert vom bildschirm holen:{} cleop (w3, 2, 3); out (w3, anwendungstext ( 58));{} cursor (w3, 2, 4); out (w3, anwendungstext ( 59));{} cursor (w3, 2, 6); out (w3, anwendungstext (183));{} aktuelle anzahl der arbeitsphasen := ermittelter wert (minwert, maxwert,{} aktuelle anzahl der arbeitsphasen).{} benutzer ist einverstanden:{} hinweise an den benutzer ausgeben;{} simulationszeiten anzeigen (w2);{}
+ cleop (w3, 2, 3);{} IF yes (w3, anwendungstext (184)){} THEN TRUE{} ELSE FALSE{} FI.{}END PROC anzahl der arbeitsphasen festlegen;{}PROC dauer einer arbeitsphase festlegen:{} INT CONST minwert :: 1, maxwert :: 60;{} zeige fenster;{} hinweise an den benutzer ausgeben;{} simulationszeiten anzeigen (w2);{} erfrage veraenderung;{} REP{} neuen wert vom bildschirm holen{} UNTIL benutzer ist einverstanden PER.{} zeige fenster:{} w1 := window ( 2, 2, 28, 6);{} w2 := window (22, 12, 37, 7);{}
+ w3 := window (32, 2, 47, 6);{} page; show (w1); show (w2); show (w3).{} hinweise an den benutzer ausgeben:{} cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{} cursor (w1, 2, 3); out (w1, anwendungstext (53));{} out (w1, text (minwert, 2));{} out (w1, anwendungstext (51));{} cursor (w1, 2, 4); out (w1, anwendungstext (54));{} out (w1, text (maxwert, 2));{} out (w1, anwendungstext (51));{}
+ cursor (w1, 2, 6); out (w1, anwendungstext (55));{} out (w1, text (aktuelle arbeitsphasendauer in minuten, 2));{} out (w1, anwendungstext (51)).{} erfrage veraenderung:{} cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (187))));{} cursor (w3, 2, 3);{} IF no (anwendungstext (219)){} THEN LEAVE dauer einer arbeitsphase festlegen{} FI.{} neuen wert vom bildschirm holen:{} INT VAR spa, zei;{} cleop (w3, 2, 3); out (w3, anwendungstext ( 58));{}
+ cursor (w3, 2, 3); out (w3, anwendungstext ( 58));{} cursor (w3, 2, 4); out (w3, anwendungstext ( 59));{} cursor (w3, 2, 6); out (w3, anwendungstext (188));{} get cursor (w3, spa, zei);{} cursor (w3, spa + 3, zei); out (w3, anwendungstext (51));{} cursor (w3, spa, zei);{} aktuelle arbeitsphasendauer in minuten{} := ermittelter wert (minwert, maxwert,{} aktuelle arbeitsphasendauer in minuten).{} benutzer ist einverstanden:{}
+ hinweise an den benutzer ausgeben;{} simulationszeiten anzeigen (w2);{} cleop (w3, 2, 3);{} IF yes (w3, anwendungstext (189)){} THEN TRUE{} ELSE FALSE{} FI.{}END PROC dauer einer arbeitsphase festlegen;{}PROC pausendauer festlegen:{} INT CONST minwert :: 1, maxwert :: 30;{} zeige fenster;{} hinweise an den benutzer ausgeben;{} simulationszeiten anzeigen (w2);{} erfrage veraenderung;{} REP{} neuen wert vom bildschirm holen{} UNTIL benutzer ist einverstanden PER.{}
+ zeige fenster:{} w1 := window ( 2, 2, 28, 6);{} w2 := window (22, 12, 37, 7);{} w3 := window (32, 2, 47, 6);{} page; show (w1); show (w2); show (w3).{} hinweise an den benutzer ausgeben:{} cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{} cursor (w1, 2, 3); out (w1, anwendungstext (53));{} out (w1, text (minwert, 2));{} out (w1, anwendungstext (51));{} cursor (w1, 2, 4); out (w1, anwendungstext (54));{}
+ out (w1, text (maxwert, 2));{} out (w1, anwendungstext (51));{} cursor (w1, 2, 6); out (w1, anwendungstext (55));{} out (w1, text (aktuelle pausendauer in minuten, 2));{} out (w1, anwendungstext (51)).{} erfrage veraenderung:{} cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (191))));{} cursor (w3, 2, 3);{} IF no (anwendungstext (220)){} THEN LEAVE pausendauer festlegen{} FI.{}
+ neuen wert vom bildschirm holen:{} INT VAR spa, zei;{} cleop (w3, 2, 3); out (w3, anwendungstext ( 58));{} cursor (w3, 2, 4); out (w3, anwendungstext ( 59));{} cursor (w3, 2, 6); out (w3, anwendungstext (192));{} get cursor (w3, spa, zei);{} cursor (w3, spa + 3, zei); out (w3, anwendungstext (51));{} cursor (w3, spa, zei);{} aktuelle pausendauer in minuten{} := ermittelter wert (minwert, maxwert,{} aktuelle pausendauer in minuten).{}
+ benutzer ist einverstanden:{} hinweise an den benutzer ausgeben;{} simulationszeiten anzeigen (w2);{} cleop (w3, 2, 3);{} IF yes (w3, anwendungstext (193)){} THEN TRUE{} ELSE FALSE{} FI.{}END PROC pausendauer festlegen;{}PROC wertungsschluessel veraendern:{} INT CONST abszisse :: 16, ordinate :: 2;{} zeige fenster;{} gib bewertungsschluessel aus (w1);{} gib informationen aus;{} stelle frage nach veraenderung;{} REP{} neueinstellung{} UNTIL benutzer ist einverstanden PER.{}
+ zeige fenster:{} w1 := window ( 2, 2, 38, 22);{} w2 := window (42, 10, 37, 14);{} w3 := window (42, 2, 37, 6);{} page; show (w1); show (w2); show (w3).{} gib informationen aus:{} cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (52))));{} cursor (w2, 2, 3); out (w2, anwendungstext (195));{} cursor (w2, 2, 4); out (w2, anwendungstext (196));{} cursor (w2, 2, 6); out (w2, anwendungstext (197));{} cursor (w2, 2, 7); out (w2, anwendungstext (198));{} cursor (w2, 2, 8); out (w2, anwendungstext (199));{}
+ cursor (w2, 2,11); out (w2, anwendungstext (200));{} cursor (w2, 2,12); out (w2, anwendungstext (201));{} cursor (w2, 2,13); out (w2, anwendungstext (202)).{} stelle frage nach veraenderung:{} cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (205))));{} cursor (w3, 2, 3);{} IF no (anwendungstext (206)){} THEN LEAVE wertungsschluessel veraendern{} ELSE gib hinweis auf linkes fenster{} FI.{} gib hinweis auf linkes fenster:{} cleop (w3, 2, 3); out (w3, anwendungstext (211));{}
+ cursor (w3, 2, 4); out (w3, anwendungstext (212));{} cursor (w3, 2, 5); out (w3, anwendungstext (213)).{} neueinstellung:{} INT VAR zeiger;{} cursor an;{} FOR zeiger FROM 1 UPTO 11 REP{} gehe auf aktuelle punktposition;{} lasse verschieben{} PER;{} cursor aus.{} gehe auf aktuelle punktposition:{} cursor (w1, ordinate + 3 * zeiger, abszisse - nachkommastelle).{} nachkommastelle:{} int (bewertung [zeiger] * 10.0).{} lasse verschieben:{} TEXT VAR eingabezeichen; INT VAR position;{}
+ REP{} inchar (eingabezeichen);{} position := pos (oben unten return, eingabezeichen);{} fuehre angemessene reaktion aus{} UNTIL position = 3 PER.{} fuehre angemessene reaktion aus:{} SELECT position OF{} CASE 1: steige auf{} CASE 2: steige ab{} CASE 3: (* tue nichts *){} OTHERWISE piepse{} END SELECT.{} steige auf:{} IF bewertung [zeiger] < 1.0{} THEN loesche alten punkt;{} bewertung [zeiger] INCR 0.1;{} schreibe neuen punkt{}
+ ELSE piepse{} FI.{} steige ab:{} IF bewertung [zeiger] > 0.0{} THEN loesche alten punkt;{} bewertung [zeiger] DECR 0.1;{} schreibe neuen punkt{} ELSE piepse{} FI.{} loesche alten punkt:{} INT VAR tabspalte, tabzeile;{} gehe auf aktuelle punktposition;{} get cursor (w1, tabspalte, tabzeile);{} IF tabspalte = ordinate + 3 OR tabzeile = abszisse{} THEN out (w1, "|"){} ELSE out (w1, blank){} FI.{} schreibe neuen punkt:{} gehe auf aktuelle punktposition;{}
+ out (w1, punkt und zurueck).{} benutzer ist einverstanden:{} cleop (w3, 2, 3);{} IF yes (w3, anwendungstext (207)){} THEN TRUE{} ELSE gib hinweis auf linkes fenster;{} FALSE{} FI.{}END PROC wertungsschluessel veraendern;{}PROC cleol (WINDOW VAR w, INT CONST cursorspalte, cursorzeile):{} cursor (w, cursorspalte, cursorzeile);{} IF remaining lines (w) > 1{} THEN out (w, (areaxsize (w) - cursorspalte + 1) * blank){} ELSE out (w, (areaxsize (w) - cursorspalte) * blank){}
+ FI;{} cursor (w, cursorspalte, cursorzeile){}END PROC cleol;{}PROC cleop (WINDOW VAR w, INT CONST cursorspalte, cursorzeile):{} cleol (w, cursorspalte, cursorzeile);{} INT VAR i;{} FOR i FROM 1 UPTO remaining lines (w) REP{} cleol (w, 1, cursorzeile + i){} PER;{} cursor (w, cursorspalte, cursorzeile){}END PROC cleop;{}PROC cursor an:{} INT VAR spalte, zeile;{} get cursor (spalte, zeile); cursor on; cursor (spalte, zeile){}END PROC cursor an;{}PROC cursor aus:{} INT VAR spalte, zeile;{}
+ get cursor (spalte, zeile); cursor off; cursor (spalte, zeile){}END PROC cursor aus;{}INT PROC eingabe mit intervallanzeige (WINDOW VAR w, INT CONST minwert,{} maxwert, anfangswert, cursorspalte,{} cursorzeile):{} BOOL VAR ist aufsteigend :: minwert = anfangswert;{} INT VAR aktueller wert :: anfangswert, alter wert, eingelesener wert;{} REP{} hole position aus vorgabe (oben unten return, eingelesener wert);{} SELECT eingelesener wert OF{}
+ CASE 1: erniedrige aktuellen wert wenn moeglich{} CASE 2: erhoehe aktuellen wert wenn moeglich{} END SELECT{} UNTIL eingelesener wert = 3 PER;{} aktueller wert.{} erniedrige aktuellen wert wenn moeglich:{} IF aktueller wert > minwert{} THEN alter wert := aktueller wert;{} aktueller wert DECR 1;{} IF ist aufsteigend{} THEN loesche alte markierung{} ELSE markiere neues zeichen{} FI{} ELSE piepse{} FI.{} erhoehe aktuellen wert wenn moeglich:{}
+ IF aktueller wert < maxwert{} THEN alter wert := aktueller wert;{} aktueller wert INCR 1;{} IF ist aufsteigend{} THEN markiere neues zeichen{} ELSE loesche alte markierung{} FI{} ELSE piepse{} FI.{} loesche alte markierung:{} positioniere cursor in zeichenkette (w, 33, alter wert);{} out (w, code (alter wert) + " ");{} cursor (cursorspalte, cursorzeile).{} markiere neues zeichen:{} positioniere cursor in zeichenkette (w, 33, aktueller wert);{}
+ out (w, invers (code (aktueller wert)));{} cursor (cursorspalte, cursorzeile).{}END PROC eingabe mit intervallanzeige;{}INT PROC eingabe mit elementanzeige (WINDOW VAR w, INT CONST minwert,{} maxwert, anfangswert,{} cursorspalte, cursorzeile):{} INT VAR aktueller wert :: anfangswert, alter wert, eingelesener wert;{} REP{} hole position aus vorgabe (oben unten return, eingelesener wert);{} SELECT eingelesener wert OF{}
+ CASE 1: erniedrige aktuellen wert wenn moeglich{} CASE 2: erhoehe aktuellen wert wenn moeglich{} END SELECT{} UNTIL eingelesener wert = 3 PER;{} aktueller wert.{} erniedrige aktuellen wert wenn moeglich:{} IF aktueller wert > minwert{} THEN alter wert := aktueller wert;{} aktueller wert DECR 1;{} loesche alte markierung;{} markiere neues zeichen{} ELSE piepse{} FI.{} erhoehe aktuellen wert wenn moeglich:{} IF aktueller wert < maxwert{}
+ THEN alter wert := aktueller wert;{} aktueller wert INCR 1;{} loesche alte markierung;{} markiere neues zeichen{} ELSE piepse{} FI.{} loesche alte markierung:{} positioniere cursor in zeichenkette (w, minwert, alter wert);{} out (w, code (alter wert) + " ");{} cursor (cursorspalte, cursorzeile).{} markiere neues zeichen:{} positioniere cursor in zeichenkette (w, minwert, aktueller wert);{} out (w, invers (code (aktueller wert)));{}
+ cursor (cursorspalte, cursorzeile).{}END PROC eingabe mit elementanzeige;{}PROC werkstueck zeigen (WINDOW VAR w):{} INT VAR zaehler, spalte, zeile;{} page (w);{} werkstueckaufhaenger (spalte, zeile);{} schreibe werkstueck zeilenweise.{} schreibe werkstueck zeilenweise:{} FOR zaehler FROM 1 UPTO aktuelle werkstueckhoehe REP{} positioniere den cursor;{} bastle eine zeile;{} gib eine zeile aus{} PER.{} positioniere den cursor:{} cursor (w, spalte, zeile + zaehler - 1).{}
+ bastle eine zeile:{} TEXT VAR zeileninhalt := "";{} INT VAR z;{} FOR z FROM 1 UPTO aktuelle werkstueckbreite REP{} zeileninhalt CAT code (random (kleinster aktueller zeichencode,{} groesster aktueller zeichencode)){} PER.{} gib eine zeile aus:{} IF inversdarstellung{} THEN out (w, invers (zeileninhalt)){} ELSE out (w, zeileninhalt){} FI.{}END PROC werkstueck zeigen;{}PROC werkstueckaufhaenger (INT VAR spalte, zeile):{} spalte := ((maxspalten - aktuelle werkstueckbreite) DIV 2) + 3;{}
+ zeile := ((maxzeilen - aktuelle werkstueckhoehe ) DIV 2) + 2;{} IF inversdarstellung THEN spalte DECR 1 FI{}END PROC werkstueckaufhaenger;{}PROC gib zeichenkette aus (WINDOW VAR w,{} INT CONST kleinster, groesster, markiertes):{} INT VAR zaehler;{} FOR zaehler FROM kleinster UPTO groesster REP{} positioniere cursor in zeichenkette (w, kleinster, zaehler);{} IF zaehler = markiertes{} THEN out (w, invers (code (zaehler))){} ELSE out (w, code (zaehler)){}
+ FI{} PER{}END PROC gib zeichenkette aus;{}PROC positioniere cursor in zeichenkette (WINDOW VAR w,{} INT CONST mincode, position):{} cursor (w, 4 + ((position - mincode) DIV 19) * 5,{} 3 + ((position - mincode) MOD 19)){}END PROC positioniere cursor in zeichenkette;{}TEXT PROC tastenbezeichnung (TEXT CONST zeichen):{} IF code (zeichen) >= 33 AND code (zeichen) <= 126{} THEN "<" + zeichen + ">"{} ELSE umgesetzter code{} FI.{} umgesetzter code:{}
+ SELECT code (zeichen) OF{} CASE 1: anwendungstext (31){} CASE 2: anwendungstext (32){} CASE 3: anwendungstext (33){} CASE 8: anwendungstext (34){} CASE 9: anwendungstext (35){} CASE 10: anwendungstext (36){} CASE 11: anwendungstext (37){} CASE 12: anwendungstext (38){} CASE 13: anwendungstext (39){} CASE 16: anwendungstext (40){} CASE 27: anwendungstext (41){} CASE 32: anwendungstext (42){} CASE 214: anwendungstext (43){}
+ CASE 215: anwendungstext (44){} CASE 216: anwendungstext (45){} CASE 217: anwendungstext (46){} CASE 218: anwendungstext (47){} CASE 219: anwendungstext (48){} CASE 251: anwendungstext (49){} OTHERWISE anwendungstext (50){} END SELECT{}END PROC tastenbezeichnung;{}INT PROC ermittelter wert (INT CONST minimum, maximum, startwert):{} INT VAR aktueller wert, eingelesener wert;{} cursor an;{} aktueller wert := startwert;{} REP{} gib dreistellig aus und positioniere zurueck (aktueller wert, FALSE);{}
+ hole position aus vorgabe (oben unten return, eingelesener wert);{} SELECT eingelesener wert OF{} CASE 1: erhoehe aktuellen wert wenn moeglich{} CASE 2: erniedrige aktuellen wert wenn moeglich{} END SELECT{} UNTIL eingelesener wert = 3 PER;{} cursor aus;{} aktueller wert.{} erhoehe aktuellen wert wenn moeglich:{} IF aktueller wert < maximum{} THEN aktueller wert INCR 1{} ELSE piepse{} FI.{} erniedrige aktuellen wert wenn moeglich:{} IF aktueller wert > minimum{}
+ THEN aktueller wert DECR 1{} ELSE piepse{} FI.{}END PROC ermittelter wert;{}PROC gib dreistellig aus und positioniere zurueck (INT CONST wert,{} BOOL CONST mit wertwandel):{} INT VAR spalte, zeile; get cursor (spalte, zeile);{} IF mit wertwandel{} THEN out ("'" + code (wert) + "'"){} ELSE out (text (wert, 3)){} FI;{} cursor (spalte, zeile);{}END PROC gib dreistellig aus und positioniere zurueck;{}PROC hole position aus vorgabe (TEXT CONST vorgabe, INT VAR position):{}
+ TEXT VAR eingabezeichen; INT VAR spa, zei;{} REP{} get cursor (spa, zei); inchar (eingabezeichen); cursor (spa, zei);{} position := pos (vorgabe, eingabezeichen);{} IF position = 0 THEN piepse; cursor (spa, zei) FI{} UNTIL position > 0 PER{}END PROC hole position aus vorgabe;{}PROC piepse:{} INT VAR spa, zei; get cursor (spa, zei); out (piep); cursor (spa, zei){}END PROC piepse;{}END PACKET ls mp bap 1;{}stdvoreinstellung der parameter{}
+
diff --git a/mp-bap/ls-MP BAP 2 b/mp-bap/ls-MP BAP 2
new file mode 100644
index 0000000..0cd66ff
--- /dev/null
+++ b/mp-bap/ls-MP BAP 2
@@ -0,0 +1,126 @@
+PACKET ls mp bap 2 DEFINES (*******************************)
+ (* *)
+ materialpruefung, mp, (* ls-MP BAP 2 *)
+ bildschirmarbeitsplatz, bap, (* Version 1.1 *)
+ (* *)
+ mp bap simulation ausfuehren, (* (c) 1987, 1988 *)
+ mp bap auswertung auf bildschirm, (* by Eva Latta-Weber *)
+ mp bap drucken von auswertungen, (* Bielefeld *)
+ (* *)
+ mp bap protokollumfang festlegen, (*******************************)
+ mp bap kurzauswertung,
+
+ druckereinstellung fuer protokolldatei,
+ stddruckereinstellung fuer protokolldatei:
+
+
+
+LET maxeintraege = 800,
+ protokolldateipraefix = "ls-Protokoll: ",
+ menukarte = "ls-MENUKARTE:MP-BAP",
+ menubezeichnung = "BAP",
+ auswertdateipostfix = " - Auswertung",
+ protokolldateityp = 1955,
+ maxspalten = 70,
+ maxzeilen = 14,{} blank = " ",{} trenn = "|",{} werkstueckendekennung = 1,{} pausenendekennung = 2,{} simulationsendekennung = 3,{} markierung ein = ""15"",{} markierung aus = " "14"",{} stdschrifttyp = "",{}
+ stdxstart = 0.0,{} stdystart = 0.0,{} stdfeldbreite = 21.0,{} stdfeldlaenge = 29.5;{}LET KONTROLLTABELLE = STRUCT (INT letzter eintrag,{} breite, hoehe,{} kleinster code, groesster code,{} anzahl aphasen, aphasendauer,{} pausendauer,{}
+ TEXT datum, uhrzeit, fehlerzeichen,{} nach rechts, nach links,{} nach oben, nach unten,{} ausbesserung, naechstes,{} BOOL inversdarstellung,{} ROW 11 REAL bewertung,{} ROW maxeintraege KONTROLLE tabelle),{} KONTROLLE = STRUCT (INT eintragskennung,{} produktionsfehler,{}
+ anzahl korrekturen,{} anzahl bedienfehler,{} REAL anfang, ende, differenz),{} WERKSTUECK = ROW maxspalten ROW maxzeilen INT;{}INT VAR breite, hoehe, kleinster code, groesster code,{} anzahl aphasen, aphasendauer, pausendauer,{} eckspalte, eckzeile, x, y, xsize, ysize;{}TEXT VAR fehlerzeichen, nach rechts, nach links, nach oben, nach unten,{} ausbesserung, naechstes, datum, uhrzeit;{}
+TEXT VAR protokollschrifttyp :: stdschrifttyp;{}REAL VAR xstart :: stdxstart,{} ystart :: stdystart,{} schreibfeldbreite :: stdfeldbreite,{} schreibfeldlaenge :: stdfeldlaenge;{}ROW 11 REAL VAR bewertung;{}BOOL VAR inversdarstellung,{} kontrolldatei zur vatertask :: TRUE,{} mit kurzprotokoll :: TRUE,{} mit anmerkungen :: TRUE,{} auswertung geht zum drucker :: FALSE;{}WERKSTUECK VAR werkstueck;{}
+PROC bildschirmarbeitsplatz:{} kontrolldatei zur vatertask := FALSE;{} install menu (menukarte);{} handle menu (menubezeichnung);{}END PROC bildschirmarbeitsplatz;{}PROC bap:{} bildschirmarbeitsplatz{}END PROC bap;{}PROC materialpruefung:{} TEXT VAR benutzerkennung :: "", protokollname, alter dateiname :: std;{} install menu (menukarte, FALSE);{} kontrolldatei zur vatertask := TRUE;{} ermittle eingestellte parameter;{} bereite den bildschirm vor;{} ermittle die benutzerkennung;{} gib benutzerhinweise aus;{}
+ arbeitsplatzsimulation ausfuehren (benutzerkennung, protokollname);{} forget (protokollname, quiet);{} last param (alter dateiname).{} bereite den bildschirm vor:{} WINDOW VAR w :: window ( 2, 10, 77, 14);{} page;{} show (w);{} out (w, center (w, anwendungstext (400))).{} ermittle die benutzerkennung:{} benutzerkennung := compress (boxanswer (w, anwendungstext (401), "", 5));{} IF benutzerkennung = ""{} THEN cursor on; page;{} LEAVE materialpruefung{} FI.{}
+ gib benutzerhinweise aus:{} boxinfo (w, anwendungstext (402));{} boxinfo (w, anwendungstext (403));{} boxinfo (w, anwendungstext (404));{} gib bedieninformationen aus (2);{} boxinfo (w, anwendungstext (405));{} boxinfo (w, anwendungstext (406));{} boxinfo (w, anwendungstext (407));{} boxinfo (w, anwendungstext (408)).{}END PROC materialpruefung;{}PROC mp:{} materialpruefung{}END PROC mp;{}PROC mp bap simulation ausfuehren:{} TEXT VAR benutzerkennung :: "", dateiname;{}
+ kontrolldatei zur vatertask := FALSE;{} ermittle eingestellte parameter;{} bereite den bildschirm vor;{} ermittle die benutzerkennung;{} arbeitsplatzsimulation ausfuehren (benutzerkennung, dateiname);{} regenerate menuscreen.{} bereite den bildschirm vor:{} WINDOW VAR w :: window (2,2,77,22);{} page;{} out (w, center (w, anwendungstext (399))).{} ermittle die benutzerkennung:{} benutzerkennung := compress (boxanswer (w, anwendungstext (401), "", 5));{} IF benutzerkennung = ""{}
+ THEN regenerate menuscreen;{} LEAVE mp bap simulation ausfuehren{} FI.{}END PROC mp bap simulation ausfuehren;{}PROC mp bap auswertung auf bildschirm:{} auswertung geht zum drucker := FALSE;{} lasse protokolldateien auswaehlen;{} werte protokolldateien aus;{} regenerate menuscreen.{} lasse protokolldateien auswaehlen:{} THESAURUS VAR verfuegbare;{} verfuegbare := infix namen (ALL myself, protokolldateipraefix,{} protokolldateityp);{}
+ IF NOT not empty (verfuegbare){} THEN noch kein protokoll{} ELSE biete auswahl an{} FI.{} noch kein protokoll:{} regenerate menuscreen;{} menuinfo (anwendungstext (424));{} LEAVE mp bap auswertung auf bildschirm.{} biete auswahl an:{} verfuegbare := menusome (verfuegbare, anwendungstext (421),{} anwendungstext (422), FALSE).{} werte protokolldateien aus:{} INT VAR k;{} steige ggf bei leerem thesaurus aus;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}
+ IF name (verfuegbare, k) <> ""{} THEN disable stop;{} gib hinweis auf auswertung;{} simulationsauswertung (name (verfuegbare, k), TRUE);{} forget (name (verfuegbare, k) + auswertdateipostfix, quiet);{} fehlerbehandlung{} FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN regenerate menuscreen;{} menuinfo (anwendungstext (423));{} LEAVE mp bap auswertung auf bildschirm{}
+ FI.{} gib hinweis auf auswertung:{} page;{} WINDOW VAR fenster :: window ( 2, 2, 77, 22);{} show (fenster);{} cursor (fenster, 1, 9); out (fenster, center (fenster, name (verfuegbare, k)));{} cursor (fenster, 1, 12); out (fenster, center (anwendungstext (274))).{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{} clear error; enable stop;{} LEAVE mp bap auswertung auf bildschirm{} FI.{}
+END PROC mp bap auswertung auf bildschirm;{}PROC mp bap drucken von auswertungen:{} auswertung geht zum drucker := TRUE;{} lasse protokolldateien auswaehlen;{} werte protokolldateien aus;{} regenerate menuscreen.{} lasse protokolldateien auswaehlen:{} THESAURUS VAR verfuegbare;{} verfuegbare := infix namen (ALL myself, protokolldateipraefix,{} protokolldateityp);{} IF NOT not empty (verfuegbare){} THEN noch kein protokoll{} ELSE biete auswahl an{}
+ FI.{} noch kein protokoll:{} regenerate menuscreen;{} menuinfo (anwendungstext (424));{} LEAVE mp bap drucken von auswertungen.{} biete auswahl an:{} verfuegbare := menusome (verfuegbare, anwendungstext (425),{} anwendungstext (422), FALSE).{} werte protokolldateien aus:{} INT VAR k;{} steige ggf bei leerem thesaurus aus;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{} IF name (verfuegbare, k) <> ""{} THEN disable stop;{} gib hinweis auf auswertung;{}
+ simulationsauswertung (name (verfuegbare, k), FALSE);{} print (name (verfuegbare, k) + auswertdateipostfix);{} forget (name (verfuegbare, k) + auswertdateipostfix, quiet);{} fehlerbehandlung{} FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN regenerate menuscreen;{} menuinfo (anwendungstext (423));{} LEAVE mp bap drucken von auswertungen{} FI.{} gib hinweis auf auswertung:{}
+ page;{} WINDOW VAR fenster :: window ( 2, 2, 77, 22);{} show (fenster);{} cursor (fenster, 1, 9); out (fenster, center (fenster, name (verfuegbare, k)));{} cursor (fenster, 1, 12); out (fenster, center (anwendungstext (270))).{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (invers (errormessage));{} clear error; enable stop;{} LEAVE mp bap drucken von auswertungen{} FI.{}END PROC mp bap drucken von auswertungen;{}
+PROC mp bap protokollumfang festlegen:{} page;{} zeige aktuellen protokollumfang an;{} gib erlaeuterungen zum protokollumfang;{} frage nach umfangsaenderung;{} regenerate menuscreen{}END PROC mp bap protokollumfang festlegen;{}PROC mp bap kurzauswertung:{} page;{} zeige aktuelle kurzauswertungseinstellung an;{} gib erlaeuterungen zur kurzauswertung;{} frage nach kurzauswertungsaenderung;{} regenerate menuscreen{}END PROC mp bap kurzauswertung;{}PROC druckereinstellung fuer protokolldatei (TEXT CONST schrifttyp,{}
+ REAL CONST linker rand,{} oberer rand,{} feldbreite,{} feldlaenge):{} protokollschrifttyp := schrifttyp;{} xstart := linker rand;{} ystart := oberer rand;{} schreibfeldbreite := feldbreite;{} schreibfeldlaenge := feldlaenge;{}END PROC druckereinstellung fuer protokolldatei;{}
+PROC stddruckereinstellung fuer protokolldatei:{} protokollschrifttyp := stdschrifttyp;{} xstart := stdxstart;{} ystart := stdystart;{} schreibfeldbreite := stdfeldbreite;{} schreibfeldlaenge := stdfeldlaenge{}END PROC stddruckereinstellung fuer protokolldatei;{} (********************************){}PROC arbeitsplatzsimulation ausfuehren (TEXT CONST kennung,{} TEXT VAR dateiname):{} ermittle eingestellte parameter;{}
+ lege datei mit kennung an (kennung, dateiname);{} cursor on;{} fuehre simulation durch (dateiname);{} schicke ggf protokolldatei zur vatertask;{} gib ggf kurzprotokoll aus.{} schicke ggf protokolldatei zur vatertask:{} IF kontrolldatei zur vatertask{} THEN command dialogue (FALSE);{} save (dateiname);{} command dialogue (TRUE){} FI.{} gib ggf kurzprotokoll aus:{} IF mit kurzprotokoll{} THEN kurzauswertung auf bildschirm (dateiname){} ELSE page; put (anwendungstext (271)){}
+ FI.{}END PROC arbeitsplatzsimulation ausfuehren;{}PROC ermittle eingestellte parameter:{} werkstueckdefinition (breite, hoehe, kleinster code, groesster code,{} fehlerzeichen, inversdarstellung);{} tastendefinition (nach rechts, nach links, nach oben, nach unten,{} ausbesserung, naechstes);{} phasendefinition (anzahl aphasen, aphasendauer, pausendauer);{} bewertungsschluessel (bewertung);{}END PROC ermittle eingestellte parameter;{}PROC lege datei mit kennung an (TEXT CONST kennung, TEXT VAR datname):{}
+ BOUND KONTROLLTABELLE VAR tab;{} TEXT VAR interner name :: protokolldateipraefix;{} interner name CAT kennung;{} lege neue datei an;{} type (old (datname), protokolldateityp).{} lege neue datei an:{} INT VAR i :: 0; TEXT VAR bezeichnung;{} REP{} i INCR 1;{} bezeichnung := interner name + " /" + text (i){} UNTIL NOT exists (bezeichnung) PER;{} tab := new (bezeichnung);{} initialisiere tabelle;{} datname := bezeichnung.{} initialisiere tabelle:{} tab.letzter eintrag := 0.{}
+END PROC lege datei mit kennung an;{}PROC fuehre simulation durch (TEXT CONST dateiname):{} BOUND KONTROLLTABELLE VAR tab :: old (dateiname);{} TEXT CONST moegliche eingabezeichen :: nach rechts + nach links +{} nach oben + nach unten +{} ausbesserung + naechstes;{} treffe vorbereitungen;{} trage grunddaten in tabelle;{} simuliere.{} treffe vorbereitungen:{} initialisierungen;{} WINDOW VAR fenster :: window ( 1, 9, 79, 16);{}
+ page;{} gib bedieninformationen aus (2);{} werkstueckaufhaenger (eckspalte, eckzeile);{} weise auf arbeitsbeginn hin;{} beginn der arbeitsphase := clock (1);{} beginn der bearbeitung := beginn der arbeitsphase;{} arbeitsphasenlaenge := real (aphasendauer * 60).{} initialisierungen:{} INT VAR eintragzaehler :: 0,{} arbeitsphasenzaehler :: 1,{} werkstueckzaehler :: 0,{} bedienfehlerzaehler :: 0,{}
+ korrekturzaehler :: 0,{} produktionsfehler,{} cursorspalte relativ,{} cursorzeile relativ;{} REAL VAR beginn der arbeitsphase,{} beginn der bearbeitung,{} arbeitsphasenlaenge,{} arbeitsphasenueberziehung,{} pausenueberziehung.{} weise auf arbeitsbeginn hin:{} page (fenster);{} boxinfo (fenster, anwendungstext (252), 5, maxint);{} clear buffer.{} trage grunddaten in tabelle:{} tab.datum := date;{}
+ tab.uhrzeit := time of day;{} tab.breite := breite;{} tab.hoehe := hoehe;{} tab.kleinster code := kleinster code;{} tab.groesster code := groesster code;{} tab.anzahl aphasen := anzahl aphasen;{} tab.aphasendauer := aphasendauer;{} tab.pausendauer := pausendauer;{} tab.fehlerzeichen := fehlerzeichen;{} tab.nach rechts := nach rechts;{} tab.nach links := nach links;{} tab.nach oben := nach oben;{}
+ tab.nach unten := nach unten;{} tab.ausbesserung := ausbesserung;{} tab.naechstes := naechstes;{} tab.inversdarstellung := inversdarstellung;{} tab.bewertung := bewertung;{} eintragzaehler := 1.{} simuliere:{} REP{} gib holehinweis;{} hole werkstueck (werkstueck, produktionsfehler);{} zeige werkstueck (werkstueck, fenster);{} lasse werkstueck bearbeiten{} UNTIL simulationsende erreicht PER.{} gib holehinweis:{}
+ page (fenster);{} cursor (fenster, 2, 3); out (fenster, anwendungstext (253)).{} lasse werkstueck bearbeiten:{} initialisiere den relativcursor;{} setze cursor;{} clear buffer;{} bearbeite das werkstueck.{} initialisiere den relativcursor:{} cursorspalte relativ := 1;{} cursorzeile relativ := 1.{} setze cursor:{} IF inversdarstellung{} THEN cursor (fenster, eckspalte + cursorspalte relativ,{} eckzeile + cursorzeile relativ - 1);{}
+ ELSE cursor (fenster, eckspalte + cursorspalte relativ - 1,{} eckzeile + cursorzeile relativ - 1);{} FI.{} bearbeite das werkstueck:{} BOOL VAR werkstueck voll bearbeitet :: FALSE;{} REP{} hole eingabe und werte aus{} UNTIL werkstueck voll bearbeitet PER.{} hole eingabe und werte aus:{} TEXT VAR eingabezeichen := incharety (100);{} SELECT eingabezeichenposition OF{} CASE 1: wenn moeglich nach rechts{} CASE 2: wenn moeglich nach links{}
+ CASE 3: wenn moeglich nach oben{} CASE 4: wenn moeglich nach unten{} CASE 5: wenn moeglich ausbessern{} CASE 6: beende werkstueckbearbeitung{} OTHERWISE entscheide ob gepiepst wird{} END SELECT.{} eingabezeichenposition:{} pos (moegliche eingabezeichen, eingabezeichen).{} wenn moeglich nach rechts:{} IF cursorspalte relativ < breite{} THEN cursorspalte relativ INCR 1;{} setze cursor{} ELSE registriere bedienfehler{} FI.{} wenn moeglich nach links:{}
+ IF cursorspalte relativ > 1{} THEN cursorspalte relativ DECR 1;{} setze cursor{} ELSE registriere bedienfehler{} FI.{} wenn moeglich nach oben:{} IF cursorzeile relativ > 1{} THEN cursorzeile relativ DECR 1;{} setze cursor{} ELSE registriere bedienfehler{} FI.{} wenn moeglich nach unten:{} IF cursorzeile relativ < hoehe{} THEN cursorzeile relativ INCR 1;{} setze cursor{} ELSE registriere bedienfehler{} FI.{}
+ wenn moeglich ausbessern:{} IF werkstueck [cursorspalte relativ][cursorzeile relativ] = code (fehlerzeichen){} THEN werkstueck [cursorspalte relativ][cursorzeile relativ] := code (blank);{} korrekturzaehler INCR 1;{} get cursor (fenster, x, y);{} out (fenster, blank);{} cursor (fenster, x, y);{} ELSE registriere bedienfehler{} FI.{} registriere bedienfehler:{} piepse; bedienfehlerzaehler INCR 1.{} entscheide ob gepiepst wird:{} IF eingabezeichen <> "" THEN piepse FI.{}
+ beende werkstueckbearbeitung:{} IF simulationsende erreicht{} THEN trage simulationsende in tabelle ein{} ELIF arbeitsphasenende erreicht{} THEN trage werkstueckdaten in tabelle ein;{} ermittle ueberziehung der arbeitsphase;{} lege eine pause ein{} ELSE trage werkstueckdaten in tabelle ein{} FI;{} werkstueck voll bearbeitet := TRUE.{} lege eine pause ein:{} nimm pausendaten;{} weise auf pausenanfang hin;{} pausiere;{} weise auf pausenende hin;{}
+ registriere pausenueberziehung.{} nimm pausendaten:{} REAL VAR pausenanfang :: clock (1),{} pausenende :: pausenanfang + real (pausendauer * 60);.{} weise auf pausenanfang hin:{} page (fenster);{} boxnotice (fenster, anwendungstext (255), 5, x, y, xsize, ysize).{} pausiere:{} REP{} pause (int ((pausenende - clock (1)) * 10.0)){} UNTIL clock (1) >= pausenende PER.{} weise auf pausenende hin:{} page (fenster);{} pausenanfang := clock (1);{} piepse;{}
+ clear buffer;{} boxinfo (fenster, anwendungstext (256), 5, maxint);{} pausenende := clock (1).{} registriere pausenueberziehung:{} pausenueberziehung := pausenende - pausenanfang;{} trage pausenueberziehung in tabelle ein.{} trage werkstueckdaten in tabelle ein:{} REAL VAR bearbeitungsende :: clock (1);{} tab.tabelle [eintragzaehler].eintragskennung := werkstueckendekennung;{} tab.tabelle [eintragzaehler].produktionsfehler := produktionsfehler;{} tab.tabelle [eintragzaehler].anzahl korrekturen := korrekturzaehler;{}
+ tab.tabelle [eintragzaehler].anzahl bedienfehler:= bedienfehlerzaehler;{} tab.tabelle [eintragzaehler].anfang := beginn der bearbeitung;{} tab.tabelle [eintragzaehler].ende := bearbeitungsende;{} tab.tabelle [eintragzaehler].differenz := bearbeitungszeit;{} erhoehe eintragzaehler;{} beginn der bearbeitung := clock (1);{} werkstueckzaehler INCR 1;{} bedienfehlerzaehler := 0;{} korrekturzaehler := 0.{} trage pausenueberziehung in tabelle ein:{}
+ tab.tabelle [eintragzaehler].eintragskennung := pausenendekennung;{} tab.tabelle [eintragzaehler].produktionsfehler := 0;{} tab.tabelle [eintragzaehler].anzahl korrekturen := 0;{} tab.tabelle [eintragzaehler].anzahl bedienfehler:= 0;{} tab.tabelle [eintragzaehler].anfang := pausenanfang;{} tab.tabelle [eintragzaehler].ende := pausenende;{} tab.tabelle [eintragzaehler].differenz := pausenueberziehung;{} erhoehe eintragzaehler;{} arbeitsphasenzaehler INCR 1;{}
+ beginn der bearbeitung := clock (1);{} beginn der arbeitsphase := clock (1);{} bearbeitungslaenge bestimmen.{} trage simulationsende in tabelle ein:{} bearbeitungsende := clock (1);{} tab.tabelle [eintragzaehler].eintragskennung := simulationsendekennung;{} tab.tabelle [eintragzaehler].produktionsfehler := produktionsfehler;{} tab.tabelle [eintragzaehler].anzahl korrekturen := korrekturzaehler;{} tab.tabelle [eintragzaehler].anzahl bedienfehler:= bedienfehlerzaehler;{}
+ tab.tabelle [eintragzaehler].anfang := beginn der bearbeitung;{} tab.tabelle [eintragzaehler].ende := bearbeitungsende;{} tab.tabelle [eintragzaehler].differenz := bearbeitungszeit;{} tab.letzter eintrag := eintragzaehler.{} bearbeitungszeit:{} bearbeitungsende - beginn der bearbeitung.{} erhoehe eintragzaehler:{} IF eintragzaehler < maxeintraege{} THEN eintragzaehler INCR 1{} ELSE trage simulationsende in tabelle ein;{}
+ errorstop (anwendungstext (254)){} FI.{} ermittle ueberziehung der arbeitsphase:{} arbeitsphasenueberziehung := clock (1) - beginn der arbeitsphase{} - arbeitsphasenlaenge.{} bearbeitungslaenge bestimmen:{} arbeitsphasenlaenge := real (aphasendauer * 60){} - arbeitsphasenueberziehung{} - pausenueberziehung.{} arbeitsphasenende erreicht:{} clock (1) - beginn der arbeitsphase >= arbeitsphasenlaenge.{}
+ simulationsende erreicht:{} arbeitsphasenzaehler = anzahl aphasen AND arbeitsphasenende erreicht.{}END PROC fuehre simulation durch;{}PROC gib bedieninformationen aus (INT CONST zeile):{} WINDOW VAR f1 :: window ( 2, zeile, 35, 6),{} f2 :: window (40, zeile, 39, 6);{} show (f1); show (f2);{} cursor (f1, 2, 1); out (f1, anwendungstext (11));{} out (f1, tastenbezeichnung ( nach rechts));{} cursor (f1, 2, 2); out (f1, anwendungstext (12));{} out (f1, tastenbezeichnung ( nach links));{}
+ cursor (f1, 2, 3); out (f1, anwendungstext (13));{} out (f1, tastenbezeichnung ( nach oben));{} cursor (f1, 2, 4); out (f1, anwendungstext (14));{} out (f1, tastenbezeichnung ( nach unten));{} cursor (f1, 2, 5); out (f1, anwendungstext (15));{} out (f1, tastenbezeichnung ( ausbesserung));{} cursor (f1, 2, 6); out (f1, anwendungstext (16));{} out (f1, tastenbezeichnung ( naechstes));{} cursor (f2, 2, 1); out (f2, anwendungstext (17));{}
+ out (f2, text (anzahl aphasen, 4));{} cursor (f2, 2, 2); out (f2, anwendungstext (18));{} out (f2, text (aphasendauer, 4));{} out (f2, anwendungstext (51));{} cursor (f2, 2, 3); out (f2, anwendungstext (19));{} out (f2, text (pausendauer, 4));{} out (f2, anwendungstext (51));{} cursor (f2, 2, 4); out (f2, anwendungstext ( 5));{} out (f2, text (gesamtzeit, 4));{} out (f2, anwendungstext (51));{}
+ cursor (f2, 2, 6); out (f2, anwendungstext (251));{} out (f2, 3 * blank);{} out (f2, fehlerzeichen).{}END PROC gib bedieninformationen aus;{}INT PROC gesamtzeit:{} anzahl aphasen * aphasendauer + (anzahl aphasen - 1) * pausendauer{}END PROC gesamtzeit;{}PROC hole werkstueck (WERKSTUECK VAR w, INT VAR anzahl fehler):{} INT VAR spaltenzaehler, zeilenzaehler;{} anzahl fehler := 0;{} FOR zeilenzaehler FROM 1 UPTO hoehe REP{} ermittle eine zeile{} PER.{}
+ ermittle eine zeile:{} FOR spaltenzaehler FROM 1 UPTO breite REP{} ermittle eine position;{} ggf fehler registrieren{} PER.{} ermittle eine position:{} w [spaltenzaehler][zeilenzaehler] := zufallscode.{} zufallscode:{} random (kleinster code, groesster code).{} ggf fehler registrieren:{} IF w [spaltenzaehler][zeilenzaehler] = code (fehlerzeichen){} THEN anzahl fehler INCR 1{} FI.{}END PROC hole werkstueck;{}PROC zeige werkstueck (WERKSTUECK CONST w, WINDOW VAR f):{}
+ INT VAR spaltenzaehler, zeilenzaehler;{} page (f);{} FOR zeilenzaehler FROM 1 UPTO hoehe REP{} zeige eine zeile{} PER.{} zeige eine zeile:{} cursor (f, eckspalte, eckzeile + zeilenzaehler - 1);{} ggf invers einschalten;{} FOR spaltenzaehler FROM 1 UPTO breite REP{} out (f, code (w [spaltenzaehler][zeilenzaehler])){} PER;{} ggf invers ausschalten.{} ggf invers einschalten:{} IF inversdarstellung THEN out (f, markierung ein) FI.{} ggf invers ausschalten:{} IF inversdarstellung THEN out (f, markierung aus) FI.{}
+END PROC zeige werkstueck;{}PROC kurzauswertung auf bildschirm (TEXT CONST dateiname):{} WINDOW VAR fenster :: window ( 2, 10, 77, 13);{} show (fenster);{} clear buffer;{} notiere ueberschrift;{} notiere ergebnis.{} notiere ueberschrift:{} cursor (fenster, 1, 1);{} out (fenster, center (fenster, anwendungstext (275)));{} cursor (fenster, 1, 2);{} out (fenster, center (fenster, anwendungstext (276))).{} notiere ergebnis:{} BOUND KONTROLLTABELLE CONST k := old (dateiname);{} ermittle die simulationsdaten;{}
+ notiere gesamtzahl werkstuecke;{} notiere zeichengesamtzahl;{} notiere bedienfehler;{} notiere benoetigte zeit;{} notiere gesamtausbesserungsrate;{} notiere gesamtbewertungsfaktor;{} notiere gesamtbewertungszahl mit pausenueberziehung;{} cursor (1, 24); out (anwendungstext (2));{} pause.{} ermittle die simulationsdaten:{} INT VAR z, anzahl zeichen pro werkstueck,{} anzahl werkstuecke :: 0,{} anzahl bedienfehler :: 0,{} anzahl produktionsfehler :: 0,{}
+ anzahl korrekturen :: 0;{} REAL VAR gesamtzahl zeichen, anteil korrekturen,{} gesamtzeit :: 0.0,{} pausenueberzug :: 0.0;{} FOR z FROM 1 UPTO k.letzter eintrag REP{} IF k.tabelle [z].eintragskennung = werkstueckendekennung{} THEN anzahl werkstuecke INCR 1;{} anzahl bedienfehler INCR k.tabelle [z].anzahl bedienfehler;{} anzahl produktionsfehler INCR k.tabelle [z].produktionsfehler;{}
+ anzahl korrekturen INCR k.tabelle [z].anzahl korrekturen;{} gesamtzeit INCR k.tabelle [z].differenz;{} ELIF k.tabelle [z].eintragskennung = pausenendekennung{} THEN pausenueberzug INCR k.tabelle [z].differenz;{} FI{} PER;{} anzahl zeichen pro werkstueck := k.breite * k.hoehe;{} gesamtzahl zeichen := real (anzahl werkstuecke){} * real (anzahl zeichen pro werkstueck);{}
+ IF anzahl produktionsfehler = 0{} THEN anteil korrekturen := 1.0{} ELSE anteil korrekturen := real (anzahl korrekturen){} / real (anzahl produktionsfehler){} FI.{} notiere gesamtzahl werkstuecke:{} cursor (fenster, 12, 4); out (fenster, anwendungstext (277));{} out (fenster, text (anzahl werkstuecke, 8)).{} notiere zeichengesamtzahl:{} cursor (fenster, 12, 5); out (fenster, anwendungstext (278));{} out (fenster, zahl aus zeichenkette).{}
+ zahl aus zeichenkette:{} subtext (text (gesamtzahl zeichen, 9, 0), 1, 8).{} notiere bedienfehler:{} cursor (fenster, 12, 6); out (fenster, anwendungstext (279));{} out (fenster, text (anzahl bedienfehler, 8)).{} notiere benoetigte zeit:{} cursor (fenster, 12, 7); out (fenster, anwendungstext (280));{} out (fenster, text (gesamtzeit, 8, 2)).{} notiere gesamtausbesserungsrate:{} cursor (fenster, 12, 9); out (fenster, anwendungstext (281));{}
+ out (fenster, text (anteil korrekturen, 8, 2)).{} notiere gesamtbewertungsfaktor:{} cursor (fenster, 12,10); out (fenster, anwendungstext (282));{} out (fenster, text (bewertungsfaktor, 8, 2)).{} bewertungsfaktor:{} bewertungsmasszahl (anteil korrekturen).{} notiere gesamtbewertungszahl mit pausenueberziehung:{} cursor (fenster, 12, 12); out (fenster, (anwendungstext (283)));{} out (fenster, text (gesamtwertung, 8, 2));{}
+ cursor (fenster, 12, 13); out (fenster, (anwendungstext (284)));{} out (fenster, 8 * "=").{} gesamtwertung:{} IF gesamtzeit = 0.0{} THEN 0.0{} ELSE gesamtzahl zeichen / (gesamtzeit + pausenueberzug){} * bewertungsfaktor{} FI.{}END PROC kurzauswertung auf bildschirm;{}PROC simulationsauswertung (TEXT CONST dateiname, BOOL CONST mit zeigen):{} TEXT CONST auswertdatei :: dateiname + auswertdateipostfix;{} ermittle die kenndaten aus der protokolldatei (dateiname);{}
+ notiere ueberschrift 1 (auswertdatei);{} notiere die kenndaten der simulation (auswertdatei);{} notiere die werkstueckkenndaten (auswertdatei);{} notiere ein beispielwerkstueck (auswertdatei);{} notiere ueberschrift 2 (auswertdatei);{} notiere gesamtergebnisse (auswertdatei, dateiname);{} notiere ueberschrift 3 (auswertdatei);{} notiere tabellenkopf (auswertdatei);{} notiere einzelne werkstueckdaten (auswertdatei, dateiname);{}
+ notiere ggf die anmerkungen;{} zeige ggf auswertung auf bildschirm.{} notiere ggf die anmerkungen:{} IF mit anmerkungen{} THEN notiere anmerkungen (auswertdatei);{} FI.{} zeige ggf auswertung auf bildschirm:{} IF mit zeigen{} THEN cursor on; show (auswertdatei); cursor off{} FI.{}END PROC simulationsauswertung;{}PROC ermittle die kenndaten aus der protokolldatei (TEXT CONST dateiname):{} BOUND KONTROLLTABELLE CONST k := old (dateiname);{} breite := k.breite;{}
+ hoehe := k.hoehe;{} kleinster code := k.kleinster code;{} groesster code := k.groesster code;{} fehlerzeichen := k.fehlerzeichen;{} inversdarstellung := k.inversdarstellung;{} nach rechts := k.nach rechts;{} nach links := k.nach links;{} nach oben := k.nach oben;{} nach unten := k.nach unten;{} ausbesserung := k.ausbesserung;{} naechstes := k.naechstes;{}
+ anzahl aphasen := k.anzahl aphasen;{} aphasendauer := k.aphasendauer;{} pausendauer := k.pausendauer;{} datum := k.datum;{} uhrzeit := k.uhrzeit;{} bewertung := k.bewertung;{}END PROC ermittle die kenndaten aus der protokolldatei;{}PROC notiere ueberschrift 1 (TEXT CONST auswertdatei):{} IF exists (auswertdatei){} THEN forget (auswertdatei, quiet){} FI;{} FILE VAR f :: sequential file (output, auswertdatei);{}
+ IF auswertung geht zum drucker{} THEN schreibe druckeranweisungen{} FI;{} putline (f, center (auswertdatei));{} putline (f, center (length (auswertdatei) * "="));{} put (f, anwendungstext (272)); put (f, datum); put (f, 26 * blank);{} put (f, anwendungstext (273)); putline (f, uhrzeit);{} line (f);{} putline (f, center (anwendungstext (291)));{} putline (f, center (length (anwendungstext (291)) * "=")).{} schreibe druckeranweisungen:{} write (f, "#type (""");{} write (f, protokollschrifttyp);{}
+ write (f, """)##limit (");{} write (f, text (schreibfeldbreite));{} write (f, ")##pagelength (");{} write (f, text (schreibfeldlaenge));{} write (f, ")##start (");{} write (f, text (xstart));{} write (f, ",");{} write (f, text (ystart));{} write (f, ")#"); line (f).{}END PROC notiere ueberschrift 1;{}PROC notiere ueberschrift 2 (TEXT CONST auswertdatei):{} FILE VAR f :: sequential file (output, auswertdatei);{} putline (f, center (anwendungstext (285)));{} putline (f, center (length (anwendungstext (285)) * "=")){}
+END PROC notiere ueberschrift 2;{}PROC notiere ueberschrift 3 (TEXT CONST auswertdatei):{} FILE VAR f :: sequential file (output, auswertdatei);{} line (f, 2);{} putline (f, center (anwendungstext (311)));{} putline (f, center (length (anwendungstext (311)) * "="));{} line (f){}END PROC notiere ueberschrift 3;{}PROC notiere die kenndaten der simulation (TEXT CONST auswertdatei):{} FILE VAR f :: sequential file (output, auswertdatei);{} ROW 6 TEXT VAR ausgabe;{} bestuecke ausgabezeilen;{} schreibe ausgabezeilen.{}
+ bestuecke ausgabezeilen:{} ausgabe [1] := anwendungstext (11){} + gleichlang (tastenbezeichnung (nach rechts ), 23){} + anwendungstext (17){} + text (anzahl aphasen, 4);{} ausgabe [2] := anwendungstext (12){} + gleichlang (tastenbezeichnung (nach links ), 23){} + anwendungstext (18){} + text (aphasendauer, 4) + anwendungstext (51);{} ausgabe [3] := anwendungstext (13){}
+ + gleichlang (tastenbezeichnung (nach oben ), 23){} + anwendungstext (19){} + text (pausendauer, 4) + anwendungstext (51);{} ausgabe [4] := anwendungstext (14){} + gleichlang (tastenbezeichnung (nach unten ), 23){} + anwendungstext ( 5){} + text (simulationsdauer, 4) + anwendungstext (51);{} ausgabe [5] := anwendungstext (15){} + gleichlang (tastenbezeichnung (ausbesserung), 23);{}
+ ausgabe [6] := anwendungstext (16){} + gleichlang (tastenbezeichnung (naechstes ), 23){} + anwendungstext (251){} + (3 * blank) + fehlerzeichen.{} simulationsdauer:{} anzahl aphasen * aphasendauer + (anzahl aphasen - 1) * pausendauer.{} schreibe ausgabezeilen:{} INT VAR i;{} FOR i FROM 1 UPTO 6 REP{} putline (f, ausgabe [i]){} PER;{} line (f).{}END PROC notiere die kenndaten der simulation;{}PROC notiere die werkstueckkenndaten (TEXT CONST auswertdatei):{}
+ FILE VAR f :: sequential file (output, auswertdatei);{} ROW 4 TEXT VAR ausgabe;{} bestuecke ausgabezeilen;{} schreibe ausgabezeilen.{} bestuecke ausgabezeilen:{} ausgabe [1] := anwendungstext (292) + text (breite, 4) +{} anwendungstext (296);{} ausgabe [2] := anwendungstext (293) + text (hoehe, 4) +{} anwendungstext (296);{} ausgabe [3] := anwendungstext (294) + text (breite * hoehe, 4) +{} anwendungstext (296);{}
+ ausgabe [4] := anwendungstext (295) + zeichenumfang.{} zeichenumfang:{} " " + code (kleinster code) + " ... " + code (groesster code) +{} " (" + text (groesster code - kleinster code + 1, 3) +{} anwendungstext (296) + ")".{} schreibe ausgabezeilen:{} INT VAR i;{} FOR i FROM 1 UPTO 4 REP putline (f, ausgabe [i]) PER;{} line (f).{}END PROC notiere die werkstueckkenndaten;{}PROC notiere ein beispielwerkstueck (TEXT CONST auswertdatei):{} FILE VAR f :: sequential file (output, auswertdatei);{}
+ WERKSTUECK VAR beispiel;{} INT VAR beispielfehler;{} hole werkstueck (beispiel, beispielfehler);{} notiere ueberschrift;{} notiere werkstueckzeilen;{} notiere werkstueckleerzeilen.{} notiere ueberschrift:{} putline (f, center (anwendungstext (297)));{} putline (f, center (length (anwendungstext (297)) * "-")).{} notiere werkstueckzeilen:{} INT VAR bs, bz;{} FOR bz FROM 1 UPTO hoehe REP{} notiere eine zeile{} PER.{} notiere eine zeile:{} TEXT VAR beispielzeile :: "";{}
+ konstruiere beispielzeile;{} gib beispielzeile aus.{} konstruiere beispielzeile:{} beispielzeile CAT (((80 - breite) DIV 2) * blank);{} FOR bs FROM 1 UPTO breite REP{} beispielzeile CAT code (beispiel [bs][bz]){} PER.{} gib beispielzeile aus:{} putline (f, beispielzeile).{} notiere werkstueckleerzeilen:{} line (f, maxzeilen - hoehe + 1).{}END PROC notiere ein beispielwerkstueck;{}PROC notiere gesamtergebnisse (TEXT CONST auswertdatei, protokolldatei):{} FILE VAR f :: sequential file (output, auswertdatei);{}
+ BOUND KONTROLLTABELLE CONST k :: old (protokolldatei);{} ermittle die simulationsdaten;{} notiere gesamtzahl werkstuecke;{} notiere anzahl zeichen pro werkstueck;{} notiere zeichengesamtzahl;{} notiere bedienfehler;{} notiere produktionsfehlerzahl;{} notiere fehlerkorrekturen;{} notiere gesamtzeit mit pausenueberziehung;{} notiere zeichenzahl pro sekunde mit;{} notiere gesamtausbesserungsrate;{} notiere gesamtbewertungsfaktor mit;{} notiere gesamtbewertungszahl mit;{}
+ notiere gesamtzeit ohne pausenueberziehung;{} notiere zeichenzahl pro sekunde ohne;{} notiere gesamtbewertungszahl ohne.{} ermittle die simulationsdaten:{} INT VAR z, anzahl zeichen pro werkstueck,{} anzahl werkstuecke :: 0,{} anzahl bedienfehler :: 0,{} anzahl produktionsfehler :: 0,{} anzahl korrekturen :: 0;{} REAL VAR gesamtzahl zeichen, anteil korrekturen,{} gesamtzeit :: 0.0,{}
+ pausenueberzug :: 0.0;{} FOR z FROM 1 UPTO k.letzter eintrag REP{} IF k.tabelle [z].eintragskennung = werkstueckendekennung{} THEN anzahl werkstuecke INCR 1;{} anzahl bedienfehler INCR k.tabelle [z].anzahl bedienfehler;{} anzahl produktionsfehler INCR k.tabelle [z].produktionsfehler;{} anzahl korrekturen INCR k.tabelle [z].anzahl korrekturen;{} gesamtzeit INCR k.tabelle [z].differenz;{}
+ ELIF k.tabelle [z].eintragskennung = pausenendekennung{} THEN pausenueberzug INCR k.tabelle [z].differenz;{} FI{} PER;{} anzahl zeichen pro werkstueck := k.breite * k.hoehe;{} gesamtzahl zeichen := real (anzahl werkstuecke){} * real (anzahl zeichen pro werkstueck);{} IF anzahl produktionsfehler = 0{} THEN anteil korrekturen := 1.0{} ELSE anteil korrekturen := real (anzahl korrekturen){}
+ / real (anzahl produktionsfehler){} FI.{} notiere gesamtzahl werkstuecke:{} put (f, anwendungstext (277)); putline (f, text (anzahl werkstuecke, 8)).{} notiere anzahl zeichen pro werkstueck:{} put (f, anwendungstext (286)); putline (f, text (breite * hoehe, 8)).{} notiere zeichengesamtzahl:{} put (f, anwendungstext (278)); putline (f, zahl aus zeichenkette);{} line (f).{} zahl aus zeichenkette:{} subtext (text (gesamtzahl zeichen, 9, 0), 1, 8).{}
+ notiere produktionsfehlerzahl:{} put (f, anwendungstext (287)); putline (f, text (anzahl produktionsfehler, 8)).{} notiere fehlerkorrekturen:{} put (f, anwendungstext (288)); putline (f, text (anzahl korrekturen, 8)).{} notiere bedienfehler:{} put (f, anwendungstext (279)); putline (f, text (anzahl bedienfehler,8));{} line (f).{} notiere gesamtzeit mit pausenueberziehung:{} put (f, anwendungstext (301)); put (f, text (gesamtzeit mit, 8, 1));{} putline (f, anwendungstext (300)).{}
+ gesamtzeit mit:{} gesamtzeit + pausenueberzug.{} notiere zeichenzahl pro sekunde mit:{} put (f, anwendungstext (302));{} putline (f, text (zeichenpro sec mit, 8, 1));{} line (f).{} zeichen pro sec mit:{} IF gesamtzeit + pausenueberzug > 0.0{} THEN gesamtzahl zeichen / (gesamtzeit + pausenueberzug){} ELSE 0.0{} FI.{} notiere gesamtausbesserungsrate:{} put (f, anwendungstext (281)); putline (f, text (anteil korrekturen, 8, 1)).{} notiere gesamtbewertungsfaktor mit:{}
+ put (f, anwendungstext (282)); putline (f, text (bewertungsfaktor, 8, 1));{} line (f).{} bewertungsfaktor:{} bewertungsmasszahl (anteil korrekturen).{} notiere gesamtbewertungszahl mit:{} put (f, (anwendungstext (283))); putline (f, text (gesamtwertung mit, 8, 1));{} put (f, (anwendungstext (284))); putline (f, 8 * "=").{} gesamtwertung mit:{} IF gesamtzeit = 0.0{} THEN 0.0{} ELSE gesamtzahl zeichen / (gesamtzeit + pausenueberzug){} * bewertungsfaktor{}
+ FI.{} notiere gesamtzeit ohne pausenueberziehung:{} put (f, anwendungstext (303)); put (f, text (gesamtzeit, 8, 1));{} putline (f, anwendungstext (300)).{} notiere zeichenzahl pro sekunde ohne:{} put (f, anwendungstext (302));{} putline (f, text (zeichenpro sec ohne, 8, 1)).{} zeichen pro sec ohne:{} IF gesamtzeit > 0.0{} THEN gesamtzahl zeichen / gesamtzeit{} ELSE 0.0{} FI.{} notiere gesamtbewertungszahl ohne:{} put (f, (anwendungstext (304))); putline (f, text (gesamtwertung ohne, 8, 1));{}
+ put (f, (anwendungstext (284))); putline (f, 8 * "=").{} gesamtwertung ohne:{} IF gesamtzeit = 0.0{} THEN 0.0{} ELSE gesamtzahl zeichen / gesamtzeit * bewertungsfaktor{} FI.{}END PROC notiere gesamtergebnisse;{}PROC notiere tabellenkopf (TEXT CONST auswertdatei):{} FILE VAR f :: sequential file (output, auswertdatei);{} putline (f, anwendungstext (312));{} putline (f, anwendungstext (313));{} putline (f, anwendungstext (314));{} putline (f, anwendungstext (315));{} putline (f, anwendungstext (316));{}
+ putline (f, anwendungstext (317));{} putline (f, anwendungstext (318));{}END PROC notiere tabellenkopf;{}PROC notiere einzelne werkstueckdaten (TEXT CONST auswertdatei, dateiname):{} BOUND KONTROLLTABELLE CONST k :: old (dateiname);{} FILE VAR f :: sequential file (output, auswertdatei);{} INT VAR zeiger, werkstuecknummer :: 0;{} TEXT VAR ausgabezeile :: "";{} FOR zeiger FROM 1 UPTO k.letzter eintrag REP{} notiere bearbeitungszeile{} PER.{} notiere bearbeitungszeile:{} IF k.tabelle [zeiger].eintragskennung = werkstueckendekennung{}
+ THEN werkstuecknummer INCR 1;{} schreibe werkstueckzeile{} ELIF k.tabelle [zeiger].eintragskennung = pausenendekennung{} THEN schreibe pausenzeile{} ELIF k.tabelle [zeiger].eintragskennung = simulationsendekennung{} THEN werkstuecknummer INCR 1;{} schreibe abschluss{} ELSE putline (f, 75 * "?"){} FI.{} schreibe werkstueckzeile:{} konstruiere ausgabezeile;{} putline (f, ausgabezeile).{} konstruiere ausgabezeile:{} ausgabezeile := "";{}
+ ausgabezeile CAT text (werkstuecknummer, 5);{} ausgabezeile CAT 2 * blank;{} ausgabezeile CAT trenn;{} ausgabezeile CAT text (k.tabelle [zeiger].anzahl bedienfehler, 5);{} ausgabezeile CAT 3 * blank;{} ausgabezeile CAT trenn;{} ausgabezeile CAT text (k.tabelle [zeiger].produktionsfehler, 6);{} ausgabezeile CAT 2 * blank;{} ausgabezeile CAT trenn;{} ausgabezeile CAT text (k.tabelle [zeiger].anzahl korrekturen, 6);{} ausgabezeile CAT 2 * blank;{} ausgabezeile CAT trenn;{}
+ ausgabezeile CAT text (k.tabelle [zeiger].differenz, 6, 1);{} ausgabezeile CAT blank;{} ausgabezeile CAT trenn;{} ausgabezeile CAT text (zeichen pro zeiteinheit, 6, 1);{} ausgabezeile CAT blank;{} ausgabezeile CAT trenn;{} ausgabezeile CAT text (einzelausbesserungsrate, 6, 1);{} ausgabezeile CAT blank;{} ausgabezeile CAT trenn;{} ausgabezeile CAT text (bewertungsmasszahl (einzelausbesserungsrate), 6, 1);{} ausgabezeile CAT blank;{} ausgabezeile CAT trenn;{}
+ ausgabezeile CAT text (endbewertungszahl, 6, 1);{} ausgabezeile CAT blank.{} zeichen pro zeiteinheit:{} real (breite * hoehe) / k.tabelle [zeiger].differenz.{} einzelausbesserungsrate:{} IF k.tabelle [zeiger].produktionsfehler = 0{} THEN 0.0{} ELSE real (k.tabelle [zeiger].anzahl korrekturen){} / real (k.tabelle [zeiger].produktionsfehler ){} FI.{} endbewertungszahl:{} real (breite * hoehe) / k.tabelle [zeiger].differenz{} * bewertungsmasszahl (einzelausbesserungsrate).{}
+ schreibe pausenzeile:{} line (f);{} put (f, anwendungstext (320));{} put (f, text (k.tabelle [zeiger].differenz, 6, 1));{} putline (f, anwendungstext (300));{} line (f).{} schreibe abschluss:{} putline (f, anwendungstext (318));{} putline (f, anwendungstext (319));{} line (f);{} konstruiere ausgabezeile;{} ausgabezeile := "(" +{} subtext (ausgabezeile, 2, length (ausgabezeile) - 1) +{} ")";{} putline (f, ausgabezeile).{}
+END PROC notiere einzelne werkstueckdaten;{}PROC notiere anmerkungen (TEXT CONST auswertdatei):{} FILE VAR f :: sequential file (output, auswertdatei);{} line (f);{} schreibe kopf;{} schreibe hinweis auf letztes werkstueck;{} schreibe hinweis auf bedienfehler;{} erlaeutere bewertungsschluessel;{} stelle bewertungsschluessel graphisch dar;{} schreibe rest.{} schreibe kopf:{} putline (f, center (anwendungstext (325)));{} putline (f, center (length (anwendungstext (325)) * "="));{} line (f).{}
+ schreibe hinweis auf letztes werkstueck:{} INT VAR i;{} FOR i FROM 326 UPTO 337 REP{} putline (f, anwendungstext (i)){} PER;{} line (f).{} schreibe hinweis auf bedienfehler:{} FOR i FROM 339 UPTO 341 REP{} putline (f, anwendungstext (i)){} PER;{} line (f).{} erlaeutere bewertungsschluessel:{} FOR i FROM 343 UPTO 372 REP{} putline (f, anwendungstext (i)){} PER.{} stelle bewertungsschluessel graphisch dar:{} putline (f, anwendungstext (374));{} putline (f, anwendungstext (375));{}
+ ermittle die startposition;{} zeichne diagramm;{} trage werte ein.{} ermittle die startposition:{} modify (f);{} INT VAR zeilenpos :: lines (f) + 2, spaltenpos :: 18.{} zeichne diagramm:{} cursor (f, spaltenpos, zeilenpos , anwendungstext (20));{} cursor (f, spaltenpos, zeilenpos + 1, anwendungstext (21));{} cursor (f, spaltenpos, zeilenpos + 3, anwendungstext (23));{} cursor (f, spaltenpos, zeilenpos + 4, anwendungstext (22));{} cursor (f, spaltenpos, zeilenpos + 5, anwendungstext (22));{}
+ cursor (f, spaltenpos, zeilenpos + 6, anwendungstext (22));{} cursor (f, spaltenpos, zeilenpos + 7, anwendungstext (22));{} cursor (f, spaltenpos, zeilenpos + 8, anwendungstext (24));{} cursor (f, spaltenpos, zeilenpos + 9, anwendungstext (22));{} cursor (f, spaltenpos, zeilenpos + 10, anwendungstext (22));{} cursor (f, spaltenpos, zeilenpos + 11, anwendungstext (22));{} cursor (f, spaltenpos, zeilenpos + 12, anwendungstext (22));{} cursor (f, spaltenpos, zeilenpos + 13, anwendungstext (25));{}
+ cursor (f, spaltenpos, zeilenpos + 14, anwendungstext (26));{} cursor (f, spaltenpos, zeilenpos + 15, anwendungstext (27)).{} trage werte ein:{} zeilenpos INCR 13;{} INT VAR bwzeiger;{} FOR bwzeiger FROM 1 UPTO 11 REP{} cursor (f, spaltenpos + 3 * bwzeiger, zeilenpos - konkreter wert, "+"){} PER.{} konkreter wert:{} int (bewertung [bwzeiger] * 10.0).{} schreibe rest:{} output (f);{} line (f, 2);{} FOR i FROM 377 UPTO 387 REP{} putline (f, anwendungstext (i)){}
+ PER;{} haenge an jede zeile ein blank an.{} haenge an jede zeile ein blank an:{} TEXT VAR inhalt;{} INT VAR zeilenzeiger;{} modify (f);{} FOR zeilenzeiger FROM 1 UPTO lines (f) REP{} to line (f, zeilenzeiger);{} read record (f, inhalt);{} inhalt CAT blank;{} write record (f, inhalt){} PER;{} to line (f,1).{}END PROC notiere anmerkungen;{}PROC cursor (FILE VAR f, INT CONST spa, zei, TEXT CONST text):{} positioniere an zeile;{} positioniere an spalte;{}
+ gib text an position aus.{} positioniere an zeile:{} IF zeile noch nicht vorhanden{} THEN schaffe zeile und gehe dorthin{} ELSE to line (f,zei){} FI.{} zeile noch nicht vorhanden:{} zei > lines (f).{} schaffe zeile und gehe dorthin:{} INT VAR zaehler 1;{} IF lines (f) = 0{} THEN to line (f,lines (f));{} insert record (f);{} FI;{} FOR zaehler 1 FROM lines (f) UPTO zei REP{} to line (f,lines (f));{} down (f);insert record (f){} PER;{}
+ to line(f,zei).{} positioniere an spalte:{} TEXT VAR alter satz :: "", neuer satz :: "", restsatz ::"";{} INT VAR satzlaenge;{} read record (f,alter satz);{} satzlaenge := length (alter satz);{} IF satzlaenge = 0{} THEN neuer satz CAT (spa -1) * " "{} ELIF satzlaenge >= spa{} THEN neuer satz := subtext(alter satz,1,spa-1);{} restsatz := subtext(alter satz, spa + length (text));{} ELSE neuer satz := alter satz;{} neuer satz CAT (spa - satzlaenge - 1) * " "{}
+ FI.{} gib text an position aus:{} neuer satz CAT text;{} IF restsatz <> ""{} THEN neuer satz CAT restsatz{} FI;{} write record(f,neuer satz).{} END PROC cursor;{}TEXT PROC gleichlang (TEXT CONST text, INT CONST laenge):{} TEXT VAR intern :: compress (text);{} INT VAR anzahl :: laenge - length (intern);{} IF anzahl < 0{} THEN subtext (intern, 1, laenge){} ELSE intern + (anzahl * blank){} FI{}END PROC gleichlang;{}REAL PROC bewertungsmasszahl (REAL CONST wert):{} REAL VAR interner wert := round (wert, 1);{}
+ IF interner wert > wert{} THEN interner wert DECR 0.1{} FI;{} interpoliere.{} interpoliere:{} REAL VAR unterer wert, oberer wert;{} unterer wert := interner wert;{} IF unterer wert = 1.0{} THEN oberer wert := 1.0{} ELSE oberer wert := unterer wert + 0.1{} FI;{} unterer wert := bewertung (int (unterer wert * 10.0) + 1);{} oberer wert := bewertung (int (oberer wert * 10.0) + 1);{} unterer wert + (oberer wert - unterer wert) * faktor.{} faktor:{} frac (wert * 10.0).{}
+END PROC bewertungsmasszahl;{}PROC zeige aktuellen protokollumfang an:{} WINDOW VAR w :: window (2, 2, 34, 5);{} show (w);{} cursor (w, 1, 1); out (w, center (w, invers (anwendungstext (431))));{} IF mit anmerkungen{} THEN cursor (w, 2, 4); out (w, anwendungstext (432)){} ELSE cursor (w, 2, 4); out (w, anwendungstext (433));{} FI.{}END PROC zeige aktuellen protokollumfang an;{}PROC gib erlaeuterungen zum protokollumfang:{} WINDOW VAR f :: window ( 2, 9, 77, 15);{} show (f);{} cursor (f, 1, 1); out (f, center (f, invers (anwendungstext (434))));{}
+ cursor (f, 5, 3); out (f, anwendungstext (435));{} cursor (f, 5, 4); out (f, anwendungstext (436));{} cursor (f, 5, 5); out (f, anwendungstext (437));{} cursor (f, 5, 6); out (f, anwendungstext (438));{} cursor (f, 5, 8); out (f, anwendungstext (439));{} cursor (f, 5, 9); out (f, anwendungstext (440));{} cursor (f, 5,10); out (f, anwendungstext (441));{} cursor (f, 5,11); out (f, anwendungstext (442));{} cursor (f, 5,13); out (f, anwendungstext (443));{} cursor (f, 5,14); out (f, anwendungstext (444));{}
+END PROC gib erlaeuterungen zum protokollumfang;{}PROC frage nach umfangsaenderung:{} WINDOW VAR fenster :: window (38, 2, 41, 5);{} show (fenster);{} cursor (fenster, 1, 1); out (fenster, center (fenster, invers (anwendungstext (451))));{} cursor (fenster, 4, 3); out (fenster, anwendungstext (452));{} cursor (fenster, 4, 4);{} IF yes (fenster, anwendungstext (453)){} THEN mit anmerkungen := NOT mit anmerkungen{} FI.{}END PROC frage nach umfangsaenderung;{}PROC zeige aktuelle kurzauswertungseinstellung an:{}
+ WINDOW VAR w :: window ( 2, 2, 34, 5);{} show (w);{} cursor (w, 1, 1); out (w, center (w, invers (anwendungstext (431))));{} IF mit kurzprotokoll{} THEN cursor (w, 7, 4); out (w, anwendungstext (461));{} ELSE cursor (w, 7, 4); out (w, anwendungstext (462));{} FI.{}END PROC zeige aktuelle kurzauswertungseinstellung an;{}PROC gib erlaeuterungen zur kurzauswertung:{} WINDOW VAR f :: window ( 2, 9, 77, 15);{} show (f);{} cursor (f, 1, 1); out (f, center (f, invers (anwendungstext (463))));{}
+ cursor (f, 5, 3); out (f, anwendungstext (464));{} cursor (f, 5, 4); out (f, anwendungstext (465));{} cursor (f, 5, 5); out (f, anwendungstext (466));{} cursor (f, 5, 6); out (f, anwendungstext (467));{} cursor (f, 5, 8); out (f, anwendungstext (468));{} cursor (f, 5, 9); out (f, anwendungstext (469));{} cursor (f, 5,10); out (f, anwendungstext (470));{} cursor (f, 5,11); out (f, anwendungstext (471));{} cursor (f, 5,13); out (f, anwendungstext (472));{} cursor (f, 5,14); out (f, anwendungstext (473));{}
+END PROC gib erlaeuterungen zur kurzauswertung;{}PROC frage nach kurzauswertungsaenderung:{} WINDOW VAR fenster :: window (38, 2, 41, 5);{} show (fenster);{} cursor (fenster, 1, 1); out (fenster, center (fenster, invers (anwendungstext (481))));{} cursor (fenster, 5, 3); out (fenster, anwendungstext (482));{} cursor (fenster, 5, 4);{} IF yes (fenster, anwendungstext (483)){} THEN mit kurzprotokoll := NOT mit kurzprotokoll{} FI.{}END PROC frage nach kurzauswertungsaenderung;{}END PACKET ls mp bap 2;{}
+
diff --git a/mp-bap/ls-MP BAP-gen b/mp-bap/ls-MP BAP-gen
new file mode 100644
index 0000000..26a84c3
--- /dev/null
+++ b/mp-bap/ls-MP BAP-gen
@@ -0,0 +1,30 @@
+ (*****************************)
+ (* *)
+ (* ls-MP BAP *)
+ (* GENERATORPROGRAMM *)
+ (* *)
+ (* (c) 1987 (01.09.87) *)
+ (* by Eva Latta *)
+ (* Bielefeld *)
+ (*****************************)
+LET mm taskname = "ls-MENUKARTEN",
+ eigener name = "ls-MP BAP/gen",
+ datei1 = "ls-MP BAP 1",
+ datei2 = "ls-MP BAP 2",
+ menukarte = "ls-MENUKARTE:MP-BAP";
+
+PROC stelle existenz des mm sicher:
+ cursor (1, 5); out (""4"");
+ IF NOT exists (task (mm taskname))
+ THEN errorstop ("Unbedingt erst den 'MENUKARTEN MANAGER' generieren!");
+ FI
+END PROC stelle existenz des mm sicher;
+
+PROC vom archiv (TEXT CONST datei):
+ cursor (1,5); out (""4"");
+ out (" """); out (datei); putline (""" wird geholt.");{} fetch (datei, archive){}END PROC vom archiv;{}PROC hole (TEXT CONST datei):{} IF NOT exists (datei) THEN vom archiv (datei) FI{}END PROC hole;{}PROC in (TEXT CONST datei):{} hole (datei);{} cursor (1, 5); out (""4"");{} out (" """); out (datei); out (""" wird übersetzt: ");{} insert (datei);{} forget (datei, quiet);{}END PROC in;{}PROC schicke (TEXT CONST datei):{} cursor (1, 5); out (""4"");{} out (" """); out(datei);{} out (""" wird zum MENUKARTEN-MANAGER geschickt!");{}
+ command dialogue (FALSE);{} save (datei, task (mm taskname));{} command dialogue (TRUE);{} forget (datei, quiet){}END PROC schicke;{}INT VAR size, used;{}BOOL VAR einzeln;{}storage (size, used);{}einzeln := size - used < 500;{}forget (eigener name, quiet);{}wirf kopfzeile aus;{}stelle existenz des mm sicher;{}hole die dateien;{}insertiere die dateien;{}mache global manager aus der task.{}wirf kopfzeile aus:{} page;{} putline (" "15"ls-MP BAP - Automatische Generierung "14"").{}
+hole die dateien:{} IF NOT exists (datei 1){} COR NOT exists (datei 2){} COR NOT exists (menukarte){} THEN hole dateien vom archiv; LEAVE hole die dateien{} FI.{}hole dateien vom archiv:{} cursor (1,3); out (""4"");{} IF yes ("Ist das Archiv angemeldet und die Diskette eingelegt"){} THEN lese ein{} ELSE line (2);{} errorstop ("Ohne die Diskette kann ich das System nicht generieren!"){} FI.{}lese ein:{} cursor (1, 3); out (""4"");{} out (" "15"Bitte die Diskette eingelegt lassen! "14"");{}
+ IF NOT einzeln{} THEN hole (datei 1);{} hole (datei 2);{} hole (menukarte);{} cursor (1, 3); out(""4"");{} out (" "15"Die Diskette wird nicht mehr benötigt! "14"");{} release (archive){} FI.{}insertiere die dateien:{} check off;{} cursor (1, 3); out(""4"");{} out (" "15"Die Diskette wird nicht mehr benötigt! "14"");{} in (datei 1);{} in (datei 2);{} schicke (menukarte);{} IF einzeln THEN release (archive) FI;{}
+ check on.{}mache global manager aus der task:{} global manager.{}
+
diff --git a/net/basic net b/net/basic net
new file mode 100644
index 0000000..c5e9278
--- /dev/null
+++ b/net/basic net
@@ -0,0 +1,1148 @@
+PACKET basic net DEFINES (* D. Heinrichs *)
+ (* Version 10 (!) *) (* 18.02.87 *)
+ nam, (* 03.06.87 *)
+ max verbindungsnummer, (* *)
+ neuer start,
+ neue routen,
+ packet eingang,
+ neue sendung,
+ zeitueberwachung,
+ verbindung,
+ loesche verbindung:
+
+TEXT PROC nam (TASK CONST t):
+ IF t = collector THEN name (t)
+ ELIF station (t) <> station (myself)
+ THEN "** fremd "+text(station(t))+" **"
+ ELSE name (t)
+ FI
+END PROC nam;
+
+INT PROC tasknr (TASK CONST t):
+ IF t = collector THEN maxtasks
+ ELSE index (t)
+ FI
+END PROC tasknr;
+
+LET
+ maxtasks = 127,
+ maxstat = 127,
+ max strom = 20,
+ max strom 1 = 21,
+ stx = ""2"",
+ code stx = 2,
+ error nak = 2,
+ seiten groesse = 512,
+ dr verwaltungslaenge = 8,
+ dr verwaltungslaenge2=10,
+ openlaenge = 24,
+ vorspannlaenge = 14,
+ ack laenge = 12,
+ min data length = 64,
+ (* Codes der Verbindungsebene *)
+
+ task id code = 6,
+ name code = 7,
+ task info code = 8,
+ routen liefern code = 9,
+
+ (* Typen von Kommunikationsströmen *)
+
+ send wait = 0,
+ zustellung = 1,
+ call pingpong = 2,
+ call im wait = 3,
+ call im abbruch = 4,
+ call in zustellung = 5,
+
+ (*quittungscodes*)
+
+ ok = 0,
+ von vorne = 1,
+ wiederhole = 2,
+ loesche = 3,
+ beende = 4;
+
+LET STEUER =
+ STRUCT (
+ INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ sequenz,
+ seitennummer,
+ TASK quelle,ziel,
+ INT sende code);
+
+BOUND STEUER VAR open block;
+
+BOUND STRUCT (STEUER steuer, INT typ, maxseq) VAR info block;
+
+BOUND STRUCT (
+ INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ sequenz,
+ seitennummer) VAR vorspann ;
+
+LET ACK = STRUCT (
+ INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ code);
+BOUND ACK VAR ack packet ;
+BOUND ACK VAR transmitted ack packet;
+
+BOUND STRUCT (ROW maxstat INT port,
+ ROW maxstat INT zwischen) VAR route;
+
+INT CONST max verbindungsnummer := max strom;
+INT VAR codet,net mode, nutzlaenge := data length,
+ data len via node := data length via node;
+
+TEXT VAR buffer first;
+
+DATASPACE VAR work space := nilspace;
+DATASPACE VAR transmitted ack space := nilspace;
+
+
+INT VAR pakete pro seite,
+ pakete pro seite minus 1,
+ packets per page via node,
+ packets per page via node minus 1,
+ datenpacketlaenge via node,
+ datenpacketlaenge ;
+
+INT VAR strom;
+INT VAR last data := -1;
+INT VAR own:=station (myself) ,
+ quit max := 3,
+ quit zaehler := 3,
+ own256 := 256*own;
+INT CONST stx open := code stx+256*openlaenge,
+ stx quit := code stx+256*acklaenge;
+
+ STEUER VAR opti;
+ ROW maxstrom1 STEUER VAR verbindungen;
+ ROW maxstrom1 DATASPACE VAR netz dr;
+ ROW maxstrom1 INT VAR zeit, typ, open try;
+ FOR strom FROM 1 UPTO maxstrom1 REP vdr := nilspace; forget (vdr) PER;
+ ROW maxstrom INT VAR dr page ;
+ ROW maxtasks INT VAR alter call;
+
+.vx : verbindungen (strom).
+
+vdr: netz dr (strom).
+
+ via node:
+ vx.zielrechner <= 0 OR vx.quellrechner <= 0 OR
+ transmit via node OR receive via node.
+
+ transmit via node:
+ route.zwischen (vx.zielrechner) <> vx.zielrechner AND vx.zielrechner <> own.
+
+ receive via node:
+ route.zwischen (vx.quellrechner) <> vx.quellrechner AND vx.quellrechner <> own.
+
+falsche stromnummer: strom < 1 OR strom > maxstrom.
+
+zielrechner ok: vorspann.zielrechner > 0 AND vorspann.zielrechner <= maxstat.
+
+quellrechner ok: vorspann.quellrechner > 0
+ AND vorspann.quellrechner <= maxstat.
+
+call aufruf: typ(strom) >= call pingpong.
+
+alles raus: vx.seitennummer = -1 AND letztes packet der seite .
+
+letztes packet der seite :
+(vx.sequenz AND packets per page minus 1) = packets per page minus 1.
+
+neue verbindung: code t = open laenge.
+
+PROC neue routen:
+ route := old ("port intern");
+END PROC neue routen;
+
+PROC neuer start (INT CONST empfangsstroeme, mode):
+ net mode := mode;
+ strom := 1;
+ neue routen;
+ transmitted ack space := nilspace;
+ workspace := nilspace;
+ open block := workspace;
+ info block := workspace;
+ nutzlaenge := data length;
+ data len via node := data length via node;
+ pakete pro seite:= seitengroesse DIV nutzlaenge;
+ pakete pro seite minus 1 := pakete pro seite -1;
+ packets per page via node := seitengroesse DIV data len via node;
+ packets per page via node minus 1 := packets per page via node - 1;
+ datenpacketlaenge := vorspannlaenge + nutzlaenge;
+ datenpacketlaenge via node := vorspannlaenge + data len via node;
+ vorspann := workspace;
+ ack packet := workspace;
+ transmitted ack packet := transmitted ack space;
+ FOR strom FROM 1 UPTO maxstrom1 REP
+ vx.strom := 0; forget (vdr)
+ PER;
+ INT VAR i;
+ FOR i FROM 1 UPTO maxtasks REP alter call (i) := 0 PER;
+ quitmax := empfangsstroeme;
+ own:=station (myself);
+ quit zaehler := quit max;
+ own256 := 256*own;
+ reset box (net mode);
+ buffer first := "";
+ flush buffers;
+ INT VAR err;
+ fehlermeldung ruecksetzen.
+
+ fehlermeldung ruecksetzen:
+ control (12,0,0,err).
+
+END PROC neuer start;
+
+DATASPACE PROC verbindung (INT CONST nr):
+ INT VAR memory := strom;
+ strom := nr;
+ infoblock.steuer := verbindungen (nr);
+ infoblock.typ := typ (nr);
+ infoblock.maxseq := dspages (netzdr(nr)) * packets per page;
+ strom := memory;
+ workspace
+END PROC verbindung;
+
+PROC neue sendung (TASK CONST q,z, INT CONST cod,z stat, DATASPACE CONST dr):
+
+ naechste verbindung vorbereiten;
+ forget (vdr); vdr := dr;
+ sendung starten (q, z, z stat, cod)
+END PROC neue sendung;
+
+PROC zeitueberwachung
+ (INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr):
+ snr INCR 1;
+ FOR strom FROM snr UPTO maxstrom REP zeitkontrolle PER;
+ snr := 0.
+
+zeitkontrolle:
+ IF vx.strom <> 0 AND zeit(strom) > 0
+ THEN
+ zeit(strom) DECR 1;
+ IF sendung noch nicht zugestellt
+ THEN
+ IF zeit(strom) = 0
+ THEN
+ empfangsreport ("Nicht zustellbar. ");
+ loesche verbindung (strom)
+ ELSE
+ snr := strom;
+ q := vx.quelle;
+ z := vx.ziel;
+ ant := vx.sendecode;
+ dr := vdr;
+ LEAVE zeitueberwachung
+ FI
+ ELIF zeit(strom) = 0
+ THEN wiederholen
+ FI
+ FI.
+
+sendung noch nicht zugestellt:
+ typ (strom) = zustellung.
+
+wiederholen:
+ IF sendeeintrag
+ THEN
+ sendung wiederholen
+ ELSE
+ empfangseintrag freigeben
+ FI.
+
+sendeeintrag : vx.quellrechner = own .
+
+sendung wiederholen:
+ IF wiederholung noch sinnvoll
+ THEN
+ IF frisch
+ THEN
+ time out bei open
+ ELSE
+ datenteil wiederholen
+ FI
+ ELSE
+ sendung loeschen
+ FI.
+
+wiederholung noch sinnvoll:
+ task noch da AND bei call noch im call.
+
+task noch da: vx.quelle = collector OR exists (vx.quelle).
+
+bei call noch im call:
+ IF call aufruf
+ THEN
+ callee (vx.quelle) = vx.ziel
+ ELSE
+ TRUE
+ FI.
+
+frisch: vx.sequenz = -1.
+
+time out bei open:
+ IF vx.sendecode > -4 OR opentry (strom) > 0
+ THEN
+ open wiederholen ;
+ opentry (strom) DECR 1
+ ELSE
+ nak an quelle senden
+ FI.
+
+nak an quelle senden:
+ dr := nilspace;
+ BOUND TEXT VAR erm := dr;
+ erm := "Station "+text(vx.zielrechner)+" antwortet nicht";
+ snr := strom;
+ q := vx.ziel;
+ z := vx.quelle;
+ ant := error nak;
+ sendung loeschen;
+ LEAVE zeitueberwachung .
+
+open wiederholen:
+ sendereport ("wdh open");
+ IF opentry (strom) > 0 THEN zeit(strom) := 4 ELSE zeit(strom) := 40 FI;
+ openblock := vx;
+ openblock.head := stx open;
+ ab die post.
+
+datenteil wiederholen:
+ sendereport ("wdh data. sqnr "+text (vx.sequenz));
+ senden .
+
+empfangseintrag freigeben:
+ IF antwort auf call
+ THEN
+ weiter warten
+ ELSE
+ empfangsreport ("Empfangseintrag freigegeben");
+ loesche verbindung (strom)
+ FI.
+antwort auf call: callee (vx.ziel) = vx.quelle.
+
+weiter warten: zeit (strom) := 400.
+
+END PROC zeitueberwachung;
+
+PROC sendereport (TEXT CONST txt):
+ report (text (strom)+":"+txt+". Absender: """+nam (vx.quelle)+
+ """. Ziel "+text(vx.zielrechner) + " Taskindex: " +
+ text (index (vx.ziel)));
+END PROC sendereport;
+
+PROC empfangsreport (TEXT CONST txt):
+ report (text (strom)+":"+txt+". Empfänger: """
+ +nam (vx.ziel)+""". Quelle "+text (vx.quellrechner) +
+ " Taskindex: " + text (index (vx.quelle)));
+END PROC empfangsreport ;
+
+PROC sendung loeschen:
+ strom loeschen (tasknr (vx.quelle))
+END PROC sendung loeschen;
+
+PROC strom loeschen (INT CONST tasknr):
+ IF callaufruf CAND alter call (tasknr ) = strom
+ THEN
+ alter call (tasknr ) := 0
+ FI;
+ vx.strom := 0;
+ forget (vdr)
+END PROC strom loeschen;
+
+PROC empfang loeschen:
+ quit zaehler INCR 1;
+ strom loeschen (tasknr (vx.ziel))
+END PROC empfang loeschen;
+
+PROC loesche verbindung (INT CONST nr):
+ strom := nr;
+ IF sendeeintrag
+ THEN
+ sendung loeschen
+ ELSE
+ gegenstelle zum loeschen auffordern;
+ empfang loeschen
+ FI.
+
+gegenstelle zum loeschen auffordern:
+ IF verbindung aktiv THEN quittieren (-loesche) FI.
+
+verbindung aktiv: vx.strom > 0.
+
+sendeeintrag: vx.quellrechner = own .
+
+END PROC loesche verbindung;
+
+PROC weiter senden:
+ IF NOT alles raus
+ THEN
+ sequenz zaehlung;
+ IF neue seite THEN seitennummer eintragen FI;
+ senden
+ FI.
+
+sequenz zaehlung:
+ vx.sequenz INCR 1.
+
+neue seite:
+ IF via node THEN (vx.sequenz AND packets per page via node minus 1) = 0
+ ELSE (vx.sequenz AND pakete pro seite minus 1) = 0
+ FI.
+
+seitennummer eintragen:
+ dr page (strom) := vx.seiten nummer;
+ vx.seitennummer := next ds page (vdr, dr page (strom)).
+
+
+END PROC weiter senden;
+
+.packets per page:
+
+ IF via node THEN packets per page via node
+ ELSE pakete pro seite
+ FI.
+
+packets per page minus 1:
+ IF via node THEN packets per page via node minus 1
+ ELSE pakete pro seite minus 1
+ FI.
+
+used length:
+
+ IF via node THEN data len via node
+ ELSE nutzlaenge
+ FI.
+
+PROC senden:
+ INT VAR nl;
+ zeit(strom) := 6;
+ openblock := vx;
+ nl := used length;
+ transmit header (workspace);
+ vorspann senden;
+ daten senden;
+ transmit trailer.
+
+vorspann senden:
+ blockout (workspace, 1, dr verwaltungslaenge, vorspannlaenge).
+
+daten senden:
+ blockout (vdr,dr page (strom),distanz,nl).
+
+distanz: nl* (vx.sequenz AND packets per page minus 1).
+
+END PROC senden;
+
+PROC naechste verbindung vorbereiten:
+ FOR strom FROM 1 UPTO maxstrom REP
+ UNTIL vx.strom = 0 PER;
+ IF vx.strom <> 0 THEN errorstop ("Verbindungsengpass") FI.
+END PROC naechste verbindung vorbereiten;
+
+PROC sendung starten (TASK CONST quelle, ziel, INT CONST code):
+ sendung starten (quelle,ziel, station(ziel), code)
+END PROC sendung starten;
+
+PROC sendung starten (TASK CONST quelle, ziel, INT CONST ziel station,code):
+ IF ziel station = own
+ THEN
+ report ("Irrläufer: Sendung an eigene Station. Absender:"""+
+ nam (quelle)+""".");
+ vx.strom := 0;
+ forget (vdr)
+ ELSE
+ openblock.ziel := ziel;
+ openblock.quelle :=quelle;
+ openblock.sendecode := code;
+ openblock.zielrechner:= ziel station;
+ openblock.quellrechner :=own;
+ openblock.zwischenziel := route.zwischen (ziel station)+own256;
+ alten call loeschen (quelle);
+ IF call oder ping pong
+ THEN typ (strom) := call pingpong; call merken
+ ELSE typ (strom) := send wait FI;
+ sendung neu starten
+ FI.
+
+call oder pingpong: openblock.ziel = callee (openblock.quelle).
+
+call merken: alter call (tasknr (quelle)) := strom.
+
+END PROC sendung starten;
+
+PROC encode packet length (INT VAR val):
+
+ IF val < 96 THEN
+ ELIF val < 160 THEN val DECR 32
+ ELIF val < 288 THEN val DECR 128
+ ELIF val < 544 THEN val DECR 352
+ ELIF val < 1056 THEN val DECR 832
+ ELIF val < 2080 THEN val DECR 1824
+ FI;
+ rotate (val, 8)
+
+ENDPROC encode packet length;
+
+PROC sendung neu starten:
+ INT VAR value;
+ openblock.head:= stx open;
+ openblock.sequenz := -1;
+ openblock.seitennummer:= next ds page (vdr,-1);
+ openblock.strom := strom;
+ vx := open block;
+ schnelles nak bei routen liefern;
+ ab die post;
+ value := vorspannlaenge + used length;
+ encode packet length (value);
+ vx.head:=code stx+value.
+
+schnelles nak bei routen liefern:
+ IF openblock.sendecode = -routen liefern code
+ THEN
+ openblock.zwischenziel := openblock.zielrechner+own256;
+ zeit(strom) := 2;
+ opentry (strom) := 0
+ ELSE
+ zeit (strom) :=8;
+ opentry (strom) := 2
+ FI.
+
+END PROC sendung neu starten; .
+
+ab die post:
+ transmit header (workspace);
+ block out (work space,1, dr verwaltungslaenge,open laenge);
+ transmit trailer.
+
+PROC alten call loeschen (TASK CONST quelle):
+ IF alter call aktiv
+ THEN
+ INT VAR lstrom := strom;
+ vx:=openblock;
+ strom := alter call (tasknr (quelle));
+ IF in ausfuehrungsphase
+ THEN
+ sendereport ("Call-Löschung vorgemerkt");
+ loeschung vormerken
+ ELSE
+ report ("Call gelöscht."""+nam(quelle)+""". Strom "+text(strom));
+ loesche verbindung (strom)
+ FI;
+ strom := lstrom;
+ openblock := vx
+ FI.
+
+in ausfuehrungsphase:
+ typ(strom) = call im wait OR typ (strom) = call in zustellung.
+
+loeschung vormerken:
+ typ(strom) := call im abbruch;
+ alter call (tasknr (quelle)) := 0.
+
+
+ alter call aktiv:
+ alter call (tasknr (quelle)) > 0.
+
+END PROC alten call loeschen;
+
+PROC packet eingang
+ ( INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr):
+ snr := 0;
+ fehlertest;
+ vorspann holen;
+ IF NOT ring logik THEN daten teil FI.
+
+ring logik: FALSE.
+
+fehlertest:
+#
+ INT VAR c12;
+ control (12,0,0,c12);
+ IF c12 <> 0
+ THEN
+ flush buffers;
+ report ("E/A-Fehler "+text (c12));
+ control (12,0,0,c12);
+ LEAVE packet eingang
+ FI.
+
+ #.
+
+vorspann holen:
+ sync;
+ IF NOT blockin (workspace, 1, dr verwaltungslaenge2, block laenge)
+ THEN LEAVE packeteingang
+ FI.
+
+
+blocklaenge: IF code t > min data length
+ THEN
+ vorspannlaenge-2
+ ELSE
+ code t -2
+ FI.
+
+sync:
+ IF NOT packet start already inspected
+ THEN
+ TEXT VAR skipped, t:= "";
+ skipped := next packet start;
+ IF skipped = "" THEN LEAVE packet eingang FI;
+ t := incharety (1);
+ code t := code (t);
+ ELSE
+ skipped := buffer first;
+ buffer first := "";
+ t := incharety (1);
+ code t := code (t);
+ FI;
+ decode packet length;
+IF skipped=stx AND laenge ok THEN LEAVE sync FI;
+ REP
+ skipped CAT t;
+ t := incharety (1); (* next character *)
+ IF t = "" THEN
+ report ("skipped",skipped);
+ LEAVE packet eingang
+ FI ;
+ codet := code (t);
+ UNTIL blockanfang OR length (skipped) > 200 PER;
+ decode packet length;
+ IF skipped <> stx THEN report ("skipped bei sync:", skipped) FI.
+
+decode packet length:
+
+IF code t < 96 THEN
+ ELIF code t < 128 THEN code t INCR 32
+ ELIF code t < 160 THEN code t INCR 128
+ ELIF code t < 192 THEN code t INCR 352
+ ELIF code t < 224 THEN code t INCR 832
+ ELIF code t < 256 THEN code t INCR 1824
+FI.
+
+packet start already inspected: buffer first <> "".
+
+blockanfang:
+ (skipped SUB length(skipped)) = stx AND laenge ok.
+
+laenge ok:
+ (codet = datenpacketlaenge OR codet = datenpacketlaenge via node
+ OR codet = ack laenge OR code t = openlaenge).
+
+zielnummer: vorspann.zielrechner.
+
+daten teil:
+ IF zielnummer = own
+ THEN
+ ziel erreicht (openblock,snr,q,z,ant,dr)
+ ELSE
+ weiter faedeln
+ FI.
+
+weiter faedeln:
+ INT VAR value;
+ IF zielrechner ok
+ THEN
+ IF neue verbindung
+ THEN
+ IF (openblock.sendecode = -routenlieferncode) OR NOT route ok
+ THEN LEAVE packet eingang
+ FI
+ FI;
+ value := code t;
+ encode packet length (value);
+ vorspann.head := code stx + value;
+ vorspann.zwischenziel := own256 + route.zwischen (vorspann.zielrechner);
+ nutzdaten einlesen;
+ dr := workspace;
+ snr := 1000;
+ ant := zielnummer
+ FI.
+
+nutzdaten einlesen:
+ IF code t > data len via node
+ THEN
+ IF NOT blockin (workspace, 1, drverwaltungslaenge+vorspannlaenge, data len via node)
+ THEN
+ LEAVE packeteingang
+ FI;
+ IF NOT next packet ok THEN LEAVE packeteingang FI
+ FI.
+
+END PROC packet eingang;
+
+PROC ziel erreicht (STEUER CONST prefix,
+ INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr):
+ last data := -1;
+ IF NOT quellrechner ok
+ THEN
+ report ("Quellrechner "+text(prefix.quellrechner));
+ LEAVE ziel erreicht
+ FI;
+ IF neue verbindung
+ THEN
+ IF NOT route ok OR NOT quelltask ok
+ THEN report ("verbotene Route: " + text (prefix.quellrechner));
+ LEAVE ziel erreicht
+ FI;
+ verbindung bereitstellen
+ ELIF quittung
+ THEN
+ strom := ack packet.strom;
+ IF falsche stromnummer THEN report ("Strom falsch in Quittung");
+ LEAVE ziel erreicht FI;
+ IF vx.strom = 0 THEN LEAVE ziel erreicht FI;
+ IF ackpacket.code >= ok THEN weiter senden
+ ELIF NOT route ok THEN
+ sendereport ("verbotene Route bei Quittung");
+ LEAVE ziel erreicht
+ ELIF ackpacket.code = -von vorne THEN
+ sendereport ("Neustart");
+ openblock := vx;
+ sendung neu starten
+ ELIF ackpacket.code = -wiederhole THEN back 16
+ ELIF ackpacket.code = -loesche THEN fremdloeschung
+ ELIF ackpacket.code = -beende AND alles raus THEN strom abschliessen
+ FI
+ ELIF verbindung festgestellt
+ THEN
+ zeit(strom) := 400;
+ opti := vx;
+ datenpacket
+ ELSE
+ strom := maxstrom1;
+ vx:=prefix;
+ report ("Daten ohne Eroeffnung von " +text(prefix.quellrechner)
+ +" Sequenznr "+text(prefix.sequenz));
+ daten entfernen (used length);
+ IF alles raus THEN quittieren (-beende) ELSE quittieren(-von vorne) FI
+ FI.
+
+quelltask ok:
+ prefix.quelle = collector OR antwort auf routen liefern
+ OR station (prefix.quelle) = prefix.quellrechner.
+
+antwort auf routen liefern: prefix.quelle = myself.
+
+verbindung bereitstellen:
+ IF (prefix.sendecode < 0 OR station (prefix.ziel) = own)
+ AND quellrechner ok
+ THEN
+ freie verbindungsnummer;
+ vdr := nilspace;
+ vx := open block;
+ zeit(strom) := 30;
+ quittieren falls genug pufferplatz;
+ vx.sequenz := 0 ;
+ opti := vx;
+ dr page (strom) :=-2;
+ IF abschluss THEN rueckmeldung FI
+ FI.
+
+loeschung vorgemerkt: typ(strom) = call im abbruch.
+
+strom abschliessen:
+ IF call aufruf
+ THEN
+ wdh data vor ablauf der zustellversuche bei der gegenstation;
+ ausfuehrungsphase merken
+ ELSE
+ wdh data sperren
+ FI.
+
+wdh data sperren:
+ zeit (strom) := 12000.
+
+wdh data vor ablauf der zustellversuche bei der gegenstation:
+ zeit (strom) := 80.
+
+ausfuehrungsphase merken: typ(strom) := call in zustellung.
+
+back16:
+ datenraum etwas rueckspulen;
+ opentry (strom) := 2;
+ nicht sofort senden (* wegen vagabundierender Quittungen *).
+
+nicht sofort senden: zeit(strom) := 2.
+
+datenraum etwas rueckspulen:
+ INT VAR pps := packets per page ;
+ sendereport ("etwas rueckgespult");
+ INT VAR vs :=-1;
+ dr page (strom) := -1;
+ INT VAR i;
+ FOR i FROM 1 UPTO vx.sequenz DIV pps - etwas REP
+ vs INCR pps;
+ dr page (strom) := next ds page (vdr, dr page (strom))
+ PER;
+ vx.seiten nummer := next ds page (vdr, dr page (strom)) ;
+ vx.sequenz := vs.
+
+etwas: 3.
+
+fremdloeschung:
+ IF fremdrechner ok und sendung
+ THEN
+ IF typ (strom) = call in zustellung
+ THEN
+ typ (strom) := call im wait
+ ELSE
+ IF NOT alles raus
+ THEN
+ sendereport ("Sendung von Gegenstelle geloescht")
+ FI;
+ sendung loeschen
+ FI
+ FI.
+
+fremdrechner ok und sendung:
+ ackpacket.quellrechner = vx.zielrechner .
+
+
+quittieren falls genug pufferplatz:
+ IF quit zaehler > 0 THEN
+ quit zaehler DECR 1;
+ open quittieren;
+ block vorab quittieren
+ ELSE
+ quittieren (-wiederhole)
+ FI.
+
+open quittieren: quittieren (ok).
+block vorab quittieren:
+ IF prio (myself) < 3 THEN quittieren (ok) FI.
+
+quittung: code t <= ack laenge.
+
+
+verbindung festgestellt:
+ FOR strom FROM maxstrom DOWNTO 1 REP
+ IF bekannter strom
+ THEN LEAVE verbindung festgestellt WITH TRUE FI
+ PER;
+ FALSE.
+
+bekannter strom:
+ vx.strom = prefix.strom AND vom selben rechner.
+
+vom selben rechner:
+ vx.quellrechner = prefix.quellrechner.
+
+daten:
+ IF neue seite da THEN check for valid pagenr;
+ dr page(strom) := prefix.seitennummer;
+ ELIF prefix.seitennummer < dr page(strom)
+ THEN empfangsreport ("Falsche Seitennummer, Soll: " +
+ text(drpage(strom)) + " ist: " +
+ text (prefix.seitennummer)
+ + " bei Sequenznr: " +
+ text(prefix.sequenz));
+ flush buffers;
+ quittieren (- wiederhole);
+ LEAVE ziel erreicht
+ FI;
+ sequenz zaehlung;
+ IF neue seite kommt
+ THEN
+ vx.seiten nummer := prefix.seiten nummer;
+ dr page(strom) := prefix.seitennummer;
+ FI;
+ quittieren(ok);
+ IF NOT blockin (vdr, opti.seiten nummer, distanz, nl)
+ COR NOT next packet ok
+ THEN quittieren (-wiederhole);
+ LEAVE ziel erreicht
+ FI;
+ last data := strom.
+
+check for valid pagenr:
+ IF prefix.seitennummer < dr page(strom) AND prefix.seitennummer > -1
+ THEN report ("Absteigende Seitennummern, alt: " + text(drpage(strom))+
+ " neu: "+ text(prefix.seitennummer) + " Seq.nr: " +
+ text(vx.sequenz) ) ;
+ flush buffers;
+ quittieren (- von vorne);
+ LEAVE ziel erreicht;
+ FI.
+
+datenpacket:
+ INT VAR nl := used length;
+ INT VAR pps1 := packets per page minus 1;
+ IF sendung wartet auf zustellung THEN auffrischen ELSE daten holen FI.
+
+sendung wartet auf zustellung: typ (strom) = zustellung.
+
+auffrischen: zeit (strom) := 200; daten entfernen (nl).
+
+daten holen:
+ IF opti.sequenz >= prefix.sequenz AND opti.sequenz < prefix.sequenz+100
+ AND prefix.sequenz >= 0
+ THEN
+ IF opti.sequenz <> prefix.sequenz
+ THEN empfangsreport ("Sequenzreset von "+text(opti.sequenz)+" auf "+
+ text (prefix.sequenz));
+ vx.sequenz := prefix.sequenz;
+ IF pagenumber ok
+ THEN dr page (strom) := prefix.seitennummer
+ ELSE empfangsreport ("Blocknummer falsch, neu: "+
+ text (prefix.seitennummer) + ", alt : " +
+ text (drpage(strom)) );
+ FI;
+ vorabquittung regenerieren
+ FI;
+ daten ;
+ IF abschluss THEN rueckmeldung FI;
+ ELSE
+ empfangsreport ("Sequenzfehler: soll "+text(vx.sequenz)+" ist "+
+ text(prefix.sequenz));
+ quittieren (-wiederhole);
+ daten entfernen (nl)
+ FI.
+
+pagenumber ok:
+ dr page (strom) >= prefix.seitennummer .
+
+rueckmeldung:
+ snr := strom;
+ q := vx.quelle;
+ z := vx.ziel;
+ ant := vx.sendecode;
+ dr := vdr;
+ LEAVE ziel erreicht.
+
+vorabquittung regenerieren:
+ IF prio (myself) < 3
+ THEN
+ quittieren (ok)
+ FI.
+
+distanz: (opti.sequenz AND pps1 ) * nl.
+
+sequenz zaehlung:
+ vx.sequenz INCR 1.
+
+neue seite da:
+ neue seite kommt.
+
+neue seite kommt:
+(vx.sequenz AND pps1) = 0.
+
+freie verbindungsnummer:
+ INT VAR h strom :=maxstrom1, cstrom := 0;
+ FOR strom FROM 1 UPTO maxstrom REP
+ IF vx.strom = 0 THEN h strom := strom ;
+ typ(strom) := send wait
+ ELIF bekannter strom
+ THEN empfangsreport ("Reopen");
+ quit zaehler INCR 1;
+ IF typ (strom) = zustellung THEN typ (strom) := send wait FI;
+ forget (vdr);
+ LEAVE freie verbindungsnummer
+ ELIF antwort auf call
+ THEN
+ IF loeschung vorgemerkt
+ THEN
+ vx := prefix;
+ loesche verbindung (strom);
+ LEAVE ziel erreicht
+ FI;
+ cstrom := strom;
+ typ (strom) := call pingpong;
+ forget (vdr);
+ FI
+ PER;
+ IF cstrom > 0 THEN strom := cstrom ELSE strom := h strom FI;
+ IF strom = maxstrom1 THEN
+ vx:=prefix;
+ empfangsreport ("Verbindungsengpass");
+ quittieren (-wiederhole);
+ LEAVE ziel erreicht
+ FI.
+
+antwort auf call:
+ prefix.sendecode >= 0 AND
+ call aufruf AND vx.quelle = prefix.ziel AND vx.ziel = prefix.quelle.
+
+END PROC ziel erreicht;
+
+PROC daten entfernen (INT CONST wieviel):
+ BOOL VAR dummy ;
+ dummy:=blockin (workspace, 2, 0, wieviel)
+END PROC daten entfernen;
+
+BOOL PROC route ok:
+ INT VAR zwischenquelle := vorspann.zwischenziel DIV 256,
+ endquelle := vorspann.quellrechner;
+ zwischenquelle abgleichen;
+ endquelle abgleichen;
+ TRUE.
+
+zwischenquelle abgleichen:
+ IF NOT zwischenroute gleich
+ THEN
+ IF NOT zwischenabgleich erlaubt THEN LEAVE route ok WITH FALSE FI;
+ route.port (zwischenquelle) := channel;
+ route.zwischen (zwischenquelle) := zwischenquelle;
+ abgleich (zwischenquelle, zwischenquelle)
+ FI.
+
+zwischenabgleich erlaubt: route.port (zwischenquelle) < 256.
+
+endquelle abgleichen:
+ IF NOT endroute gleich
+ THEN
+ IF NOT endabgleich erlaubt THEN LEAVE route ok WITH FALSE FI;
+ route.port (endquelle) := channel;
+ route.zwischen (endquelle) := zwischenquelle;
+ abgleich (endquelle, zwischenquelle)
+ FI.
+
+endabgleich erlaubt: route.port (endquelle) < 256.
+
+zwischenroute gleich:
+ (route.port (zwischenquelle) AND 255) = channel
+ AND
+ route.zwischen (zwischenquelle) = zwischenquelle.
+
+endroute gleich:
+ (route.port (endquelle) AND 255) = channel
+ AND
+ route.zwischen (endquelle) = zwischenquelle.
+
+END PROC route ok;
+
+BOOL PROC abschluss:
+
+ last data := -1;
+ IF neue seite kommt AND vx.seiten nummer = -1
+ THEN
+ quittieren (-beende);
+ an ziel weitergeben
+ ELSE
+ FALSE
+ FI.
+neue seite kommt:
+(vx.sequenz AND packets per page minus 1) = 0.
+
+an ziel weitergeben:
+ IF tasknummerfrage THEN taskfrage beantworten ;pufferplatz ; FALSE
+ ELIF tasknamenfrage THEN name senden ;pufferplatz ; FALSE
+ ELIF taskinfofrage THEN task info senden;pufferplatz ; FALSE
+ ELIF routenfrage THEN routen senden; pufferplatz; FALSE
+ ELSE senden ; TRUE
+ FI.
+
+pufferplatz : quitzaehler INCR 1 .
+
+senden:
+ IF callaufruf
+ THEN
+ ein versuch (* bei Antwort auf Call muß ein Zustellversuch reichen *)
+ ELSE
+ max 100 versuche;
+ typ (strom) := zustellung
+ FI.
+
+tasknummerfrage:opti.sendecode = -taskid code.
+
+tasknamenfrage: opti.sendecode = -name code.
+
+taskinfofrage: opti.sendecode = -task info code.
+
+routenfrage: opti.sendecode = -routen liefern code.
+
+max 100 versuche: zeit(strom) := 100.
+
+ein versuch: zeit (strom) := 1.
+
+taskfrage beantworten:
+ disable stop;
+ BOUND TEXT VAR tsk := vdr;
+ TEXT VAR save tsk := tsk;
+ forget (vdr); vdr := nilspace;
+ BOUND TASK VAR task id := vdr;
+ task id := task(save tsk);
+ IF is error THEN
+ clear error; enable stop;
+ forget (vdr); vdr := nilspace;
+ BOUND TEXT VAR errtxt := vdr;
+ errtxt := text(own)+"/"""+save tsk+""" gibt es nicht";
+ sendung starten (collector, opti.quelle, 2)
+ ELSE
+ enable stop;
+ sendung starten (collector, opti.quelle, 0)
+ FI.
+
+name senden:
+ quittieren (-loesche);
+ forget (vdr); vdr := nilspace;
+ tsk := vdr;
+ tsk := nam (opti.ziel);
+ sendung starten (collector, opti.quelle, 0).
+
+routen senden:
+ forget (vdr); vdr := old ("port intern");
+ sendung starten (opti.ziel, opti.quelle, 0).
+
+task info senden:
+ disable stop;
+ BOUND INT VAR ti code := vdr;
+ INT VAR ti cd := ti code;
+ forget (vdr); vdr := nilspace;
+ FILE VAR task inf := sequential file (output,vdr);
+ head line (task inf,"Station "+text(own));
+ task info (ti cd, task inf);
+ IF is error
+ THEN
+ forget (vdr); vdr := nilspace;
+ errtxt := vdr;
+ errtxt := errormessage;
+ clear error;
+ sendung starten (collector, opti.quelle, 2)
+ ELSE
+ sendung starten (collector,opti.quelle,0)
+ FI;
+ enable stop
+END PROC abschluss ;
+
+PROC quittieren(INT CONST code) :
+ INT VAR quell := vx.quellrechner ;
+ transmitted ackpacket := ACK:(stx quit, route.zwischen (quell)+own256, quell, own,
+ vx.strom, code);
+ transmit header (transmitted ack space);
+ blockout (transmitted ack space,1,dr verwaltungslaenge, ack laenge);
+ transmit trailer;
+END PROC quittieren;
+
+BOOL PROC next packet ok:
+ buffer first := next packet start;
+ buffer first = "" COR normal packet start.
+
+normal packet start:
+ IF buffer first = stx
+ THEN
+ TRUE
+ ELSE
+ buffer first := ""; flush buffers; FALSE
+ FI.
+
+END PROC next packet ok;
+END PACKET basic net;
+
+
diff --git a/net/net files-M b/net/net files-M
new file mode 100644
index 0000000..ae6f9f3
--- /dev/null
+++ b/net/net files-M
@@ -0,0 +1,5 @@
+net report
+net hardware interface
+basic net
+net manager
+
diff --git a/net/net hardware interface b/net/net hardware interface
new file mode 100644
index 0000000..4e3466a
--- /dev/null
+++ b/net/net hardware interface
@@ -0,0 +1,389 @@
+PACKET net hardware
+
+(************************************************************************)
+(**** Netzprotokoll Anpassung *)
+(**** Komplette Version mit BUS Anpassung 10.06.87 *)
+(**** mit I/0 Controls fuer integrierte Karten *)
+(**** Verschiedene Nutztelegrammgrössen *)
+(**** Version: GMD 2.0 A.Reichpietsch *)
+(************************************************************************)
+
+ DEFINES
+ blockin,
+ blockout,
+ set net mode,
+ net address,
+ mode text,
+ data length,
+ data length via node,
+ decode packet length,
+ next packet start,
+ flush buffers,
+ transmit header,
+ transmit trailer,
+ version,
+ reset box,
+ max mode,
+ net mode:
+
+
+
+
+ LET eak prefix laenge = 6,
+ packet length before stx = 14 (*eth header =14 *),
+ maximum mode nr = 12,
+ stx = ""2"",
+ niltext = "",
+ null = "0",
+ hex null = ""0"",
+ blank = " ",
+ eak prefix = ""0""0""0""0"",
+ typefield = "EU",
+ prefix adresse = "BOX",
+ second prefix adresse = ""0"BOX",
+ second address type bound = 90;
+
+ INT CONST data length via node :: 64;
+ TEXT CONST version :: "GMD 2.0 (10.6.87)";
+
+
+ TEXT VAR own address;
+ INT VAR paketlaenge, eumel paket laenge, mode, rahmenlaenge, actual data length;
+
+BOOL PROC blockin (DATASPACE VAR ds, INT CONST seite, abstand, laenge):
+ INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512;
+ REAL VAR time out := clock (1) + 10.0;
+ REP
+ blockin (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge);
+ UNTIL hilfslaenge = 0 OR clock (1) > time out PER ;
+ IF hilfslaenge <> 0
+ THEN report ("blockin abbruch, fehlende Zeichen: "+text(hilfslaenge));
+ FI;
+ hilfslaenge = 0
+END PROC blockin;
+
+PROC blockout (DATASPACE CONST ds, INT CONST seite, abstand, laenge):
+ INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512;
+ REP
+ blockout (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge);
+ UNTIL hilfslaenge = 0 PER
+END PROC blockout;
+
+PROC set net mode (INT CONST new mode):
+ mode := new mode ;
+ own address := net address (station(myself));
+ SELECT mode OF
+ CASE 1,3 : set data length (64);
+ CASE 2 : std framelength; set data length (64)
+ CASE 4,6 : set data length (128)
+ CASE 5 : std framelength; set data length (128)
+ CASE 7,9 : set data length (256)
+ CASE 8 : std framelength; set data length (256)
+ CASE 10,12 : set data length (512)
+ CASE 11 : std framelength; set data length (512);
+
+ OTHERWISE
+ END SELECT.
+
+ std framelength:
+ rahmenlaenge := eak prefix laenge + packet length before stx.
+
+ENDPROC set net mode;
+
+INT PROC max mode:
+ maximum mode nr
+ENDPROC max mode;
+
+INT PROC net mode:
+ mode
+ENDPROC net mode;
+
+TEXT PROC mode text:
+ mode text (mode)
+ENDPROC mode text;
+
+TEXT PROC mode text (INT CONST act mode):
+ SELECT act mode OF
+ CASE 1: "Modus: (1) EUMEL-Netz 64 Byte"
+ CASE 2: "Modus: (2) ETHERNET via V.24 64 Byte"
+ CASE 3: "Modus: (3) ETHERNET integrated 64 Byte"
+ CASE 4: "Modus: (4) EUMEL-Netz 128 Byte"
+ CASE 5: "Modus: (5) ETHERNET via V.24 128 Byte"
+ CASE 6: "Modus: (6) ETHERNET integrated 128 Byte"
+ CASE 7: "MODUS: (7) EUMEL-Netz 256 Byte"
+ CASE 8: "MODUS: (8) ETHERNET via V.24 256 Byte"
+ CASE 9: "MODUS: (9) ETHERNET integrated 256 Byte"
+ CASE 10: "MODUS: (10) EUMEL-Netz 512 Byte"
+ CASE 11: "MODUS: (11) ETHERNET via V.24 512 Byte"
+ CASE 12: "MODUS: (12) ETHERNET integrated 512 Byte"
+ OTHERWISE errorstop ("Modus " + text(mode) + " gibt es nicht");
+ error message
+ END SELECT
+
+ENDPROC mode text;
+
+PROC set data length (INT CONST new data length):
+ actual data length := new data length
+ENDPROC set data length;
+
+INT PROC data length:
+ actual data length
+ENDPROC data length;
+
+PROC reset box (INT CONST net mode):
+ SELECT net mode OF
+ CASE 1,4,7,10 : eumel net box reset
+ CASE 2,5,8,11 : eak reset
+ OTHERWISE controler reset
+ END SELECT.
+
+ eumel net box reset:
+ out (90*""4"");
+ REP UNTIL incharety (1) = niltext PER.
+
+ eak reset:
+ out ("E0"13"E0"13"").
+
+ controler reset:
+ INT VAR dummy;
+ control (-35, 0,0,dummy);
+ control (22,0,0,dummy).
+
+ENDPROC reset box;
+
+PROC remove frame
+ (TEXT VAR erstes zeichen vom eumel telegramm, BOOL VAR kein telegramm da):
+ kein telegramm da := FALSE;
+ SELECT net mode OF
+ CASE 2,5,8,11 : remove ethernet frame
+ (erstes zeichen vom eumel telegramm, kein telegramm da)
+ OTHERWISE
+ END SELECT;
+ENDPROC remove frame;
+
+PROC remove ethernet frame (TEXT VAR string, BOOL VAR schrott):
+ TEXT VAR speicher, t;
+ INT VAR lg;
+
+ t := string;
+ speicher := niltext;
+ WHILE kein stx da REP
+ lies zeichen ein;
+ teste auf timeout;
+ UNTIL textoverflow PER;
+ melde eingelesene zeichen.
+
+ lies zeichen ein:
+ speicher CAT t;
+ t := incharety (1).
+
+ teste auf timeout:
+ IF t = niltext THEN schrott := (speicher <> niltext)
+ CAND not only fill characters;
+ string := niltext;
+ LEAVE remove ethernet frame
+ FI.
+
+ not only fill characters:
+ pos (speicher, ""1"", ""254"",1) <> 0.
+
+ kein stx da :
+ t <> stx.
+
+ textoverflow:
+ length (speicher) > 1000.
+
+ melde eingelesene zeichen:
+ IF kein stx da
+ THEN kein eumeltelegrammanfang
+ ELSE untersuche ethernet header
+ FI.
+
+ kein eumeltelegrammanfang:
+ report ("skipped ,fehlendes <STX> ,letztes Zeichen:", t);
+ string := t;
+ schrott := TRUE.
+
+ untersuche ethernet header:
+ string := t;
+ IF ethernet header inkorrekt
+ THEN melde fehler
+ FI.
+
+ ethernet header inkorrekt:
+ lg := length (speicher);
+ packet zu kurz COR adresse falsch.
+
+ packet zu kurz:
+ lg < packet length before stx.
+
+ adresse falsch:
+ INT VAR adrpos := pos (speicher, own address);
+ zieladresse falsch COR adresse nicht an der richtigen pos .
+
+ zieladresse falsch:
+ adrpos < 1.
+
+ adresse nicht an der richtigen pos:
+ adrpos <> lg - packet length before stx + 1.
+
+ melde fehler:
+ report ("Header inkorrekt eingelesen: ", speicher + t);
+ string := t;
+ schrott := TRUE.
+
+ENDPROC remove ethernet frame;
+
+TEXT PROC next packet start:
+
+ TEXT VAR t := niltext;
+ BOOL VAR schrott := FALSE;
+
+ t:= incharety (1);
+ IF t = niltext THEN LEAVE next packet start WITH niltext
+ ELSE remove frame (t, schrott)
+ FI;
+ IF schrott THEN no stx or niltext
+ ELSE t
+ FI.
+
+ no stx or niltext:
+ IF t = stx THEN "2"
+ ELIF t = niltext THEN "0"
+ ELSE t
+ FI.
+
+ENDPROC next packet start;
+
+PROC flush buffers:
+ REP UNTIL incharety (5) = niltext PER;
+ report ("buffers flushed");
+ENDPROC flush buffers;
+
+PROC transmit header (DATASPACE CONST w):
+ BOUND INT VAR laengeninformation := w;
+ eumel paket laenge := laengeninformation ;
+ decode packet length (eumel paket laenge);
+ SELECT net mode OF
+ CASE 1,4,7,10 :
+ CASE 2,5,8,11 : eak und eth header senden (w)
+ OTHERWISE : telegrammanfang melden;
+ std ethernet header senden (w)
+ END SELECT;
+
+ENDPROC transmit header;
+
+PROC decode packet length (INT VAR decoded length):
+
+ decoded length DECR 2;
+ rotate (decoded length, 8);
+
+ IF decoded length < 96 THEN
+ ELIF decoded length < 128 THEN decoded length INCR 32
+ ELIF decoded length < 160 THEN decoded length INCR 128
+ ELIF decoded length < 192 THEN decoded length INCR 352
+ ELIF decoded length < 224 THEN decoded length INCR 832
+ ELIF decoded length < 256 THEN decoded length INCR 1824
+ FI;
+
+ENDPROC decode packet length;
+
+PROC transmit trailer:
+ INT VAR dummy;
+ SELECT net mode OF
+ CASE 3,6,9,12 : control (21,0,0,dummy)
+ OTHERWISE
+ END SELECT.
+
+ENDPROC transmit trailer;
+
+PROC std ethernet header senden (DATASPACE CONST x):
+ TEXT VAR eth adresse, ethernet kopf := niltext;
+ INT VAR adresse;
+ BOUND STRUCT (INT head, zwischennummern) VAR header := x;
+ zieladresse holen;
+ zieladresse senden;
+ quelladresse senden;
+ typfeld senden;
+ ausgeben.
+
+ zieladresse holen:
+ adresse := header.zwischennummern AND 255;
+ eth adresse := net address (adresse).
+
+ zieladresse senden:
+ ethernetkopf CAT eth adresse.
+
+ quelladresse senden:
+ ethernetkopf CAT own address.
+
+ typfeld senden:
+ ethernetkopf CAT typefield.
+
+ ausgeben:
+ out (ethernetkopf).
+
+ENDPROC std ethernet header senden;
+
+PROC telegrammanfang melden:
+ INT VAR dummy;
+ control (20,eumel paket laenge + packet length before stx,0, dummy).
+
+ENDPROC telegrammanfang melden;
+
+PROC eak und eth header senden (DATASPACE CONST x):
+ TEXT VAR res:= niltext;
+
+ neue laenge berechnen;
+ eak kopf senden;
+ std ethernet header senden (x).
+
+ neue laenge berechnen:
+ paket laenge := rahmenlaenge + eumel paket laenge.
+
+ eak kopf senden:
+ res := code (paket laenge DIV 256);
+ res CAT (code (paket laenge AND 255));
+ res CAT eak prefix;
+ out(res).
+
+ENDPROC eak und eth header senden;
+
+TEXT PROC net address (INT CONST eumel address):
+ TEXT VAR res ;
+ INT VAR low byte;
+
+SELECT mode OF
+ CASE 1,4,7,10 : eumel net address
+ OTHERWISE ethernet address
+END SELECT.
+
+eumel net address:
+ text(eumel address).
+
+ethernet address:
+ IF second adress kind THEN second eth header
+ ELSE first eth header
+ FI;
+ res.
+
+ second adress kind:
+ eumel address = 34 COR
+ eumel address > second address type bound.
+
+ second eth header:
+ low byte := eumel address AND 255;
+ res := second prefix adresse + code (low byte);
+ res CAT hex null.
+
+ first eth header:
+ res := prefix adresse + text (eumel address, 3);
+ changeall (res, blank, null).
+
+ENDPROC net address;
+
+ENDPACKET net hardware;
+
+
+
+
diff --git a/net/net inserter b/net/net inserter
new file mode 100644
index 0000000..c89d0f0
--- /dev/null
+++ b/net/net inserter
@@ -0,0 +1,145 @@
+(*************************************************************************)
+(*** Insertiert alle notwendigen Pakete, die zum Betrieb des Netzes ***)
+(*** notwendig sind. ***)
+(*** Berücksichtigt nur EUMEL - Versionen ab 1.8.1, sowie ***)
+(*** Multi-User-Version ***)
+(*** ***)
+(*** ***)
+(*** 23.05.87 ar ***)
+(*************************************************************************)
+
+LET netfile = "netz",
+ multi files = "net files/M";
+
+
+INT CONST version :: id (0);
+THESAURUS VAR tesa;
+
+head;
+IF no privileged task
+ THEN errorstop (name (myself) + " ist nicht privilegiert!")
+ ELIF station number wrong
+ THEN errorstop ("'define station' vergessen ")
+FI;
+
+IF version < 181 THEN versionsnummer zu klein
+ ELSE install net
+FI.
+
+no privileged task:
+ NOT (myself < supervisor).
+
+station number wrong:
+ station (myself) < 1.
+
+install net :
+ IF NOT exists (netfile)
+ THEN errorstop ("Datei " + netfile +" existiert nicht")
+ FI;
+ IF is multi THEN insert multi net
+ ELSE errorstop ("Diese Netzversion ist nur für Multi-user Versionen freigegeben")
+ FI;
+ forget ("net install", quiet);
+ net start.
+
+net start :
+ say line (" ");
+ do ("start");
+ do ("global manager (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST)
+ net manager)").
+
+is multi :
+ (pcb(9) AND 255) > 1.
+
+insert multi net :
+ hole dateien vom archiv;
+ insert say and forget (tesa).
+
+hole dateien vom archiv :
+ fetch if necessary (multi files);
+ tesa := ALL (multi files);
+ forget (multi files, quiet);
+ fetch if necessary (tesa - all);
+ say line (" ");
+ say line ("Archiv-Floppy kann entnommen werden.");
+ release (archive).
+
+
+head :
+ IF online THEN page;
+ put center (" E U M E L - Netz wird installiert.");
+ line;
+ put center ("----------------------------------------");
+ line (2)
+ FI.
+
+versionsnummer zu klein :
+ errorstop ("Netzsoftware erst ab Version 1.8.1 insertierbar !").
+
+PROC fetch if necessary (TEXT CONST datei) :
+ IF NOT exists (datei) THEN say line ("Loading """ + datei + """...");
+ fetch (datei, archive)
+ FI.
+END PROC fetch if necessary;
+
+PROC fetch if necessary (THESAURUS CONST tes) :
+ do (PROC (TEXT CONST) fetch if necessary, tes)
+END PROC fetch if necessary;
+
+PROC insert say and forget (TEXT CONST name of packet):
+ IF online THEN INT VAR cx, cy;
+ put ("Inserting """ + name of packet + """...");
+ get cursor (cx, cy)
+ FI;
+ insert (name of packet);
+ IF online THEN cl eop (cx, cy); line FI;
+ forget (name of packet, quiet)
+END PROC insert say and forget;
+
+PROC insert say and forget (THESAURUS CONST tes):
+ do (PROC (TEXT CONST) insert say and forget, tes)
+END PROC insert say and forget;
+
+PROC put center (TEXT CONST t):
+ put center (t, xsize);
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+ put center (zeile, t, xsize);
+END PROC put center;
+
+PROC put center (TEXT CONST t, INT CONST gesamtbreite):
+ INT VAR cy;
+ get cursor (cy, cy);
+ put center (cy, t, gesamtbreite)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t, INT CONST gesamtbreite):
+ cursor ((gesamtbreite - length (t)) DIV 2, zeile);
+ put (t).
+END PROC put center;
+
+PROC cl eol:
+ out (""5"")
+END PROC cl eol;
+
+PROC cl eop:
+ out (""4"")
+END PROC cl eop;
+
+PROC cl eol (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eol
+END PROC cl eol;
+
+PROC cl eop (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eop
+END PROC cl eop;
+
+PROC say line (TEXT CONST t):
+ IF online THEN put line (t) FI
+ENDPROC say line;
+
+
+
diff --git a/net/net manager b/net/net manager
new file mode 100644
index 0000000..05f530e
--- /dev/null
+++ b/net/net manager
@@ -0,0 +1,797 @@
+PACKET net manager DEFINES stop,net manager,frei, routen aufbauen,
+ (* 175 net manager 8 (!) *)
+ start,
+ definiere netz,
+ aktiviere netz,
+ list option,
+ erlaube, sperre, starte kanal, routen:
+
+TEXT VAR stand := "Netzsoftware vom 10.06.87 ";
+ (*Heinrichs *)
+LET
+ maxstat = 127,
+ ack = 0,
+(* nak = 1, *)
+ error nak = 2,
+(* zeichen eingang = 4, *)
+ list code = 15,
+(* fetch code = 11, *)
+ freigabecode = 29,
+ tabellencode = 500,
+ continue code = 100,
+ erase code = 14,
+ report code = 99,
+ abgleichcode = 98,
+ neue routen code = 97,
+ dr verwaltungslaenge = 8,
+
+ (* Codes der Verbindungsebene *)
+
+ task id code = 6,
+ name code = 7,
+ task info code = 8,
+ routen liefern code = 9,
+
+ (* Weitergabecodes für Netzknoten *)
+
+ route code = 1001,
+ out code = 1003,
+
+ (* Typen von Kommunikationsströmen *)
+
+ zustellung = 1,
+ call im wait = 3,
+ call im abbruch = 4,
+ call in zustellung = 5;
+
+LET STEUER =
+ STRUCT (
+ INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ INT sequenz,
+ seiten nummer,
+ TASK quelle,ziel,
+ INT sende code);
+
+LET INFO = STRUCT (STEUER steuer, INT typ,maxseq);
+
+LET PARA = STRUCT (TASK quelle, ziel, INT sendecode, zielstation);
+
+
+TASK VAR sohn;
+INT VAR strom,c,kanalmode, rzaehler := 20;
+BOUND STRUCT (ROW maxstat INT port,
+ ROW maxstat INT zwischen) VAR route;
+
+
+TASK PROC netport (INT CONST ziel):
+ INT VAR kan := route.port (ziel) AND 255;
+ IF kan < 1 OR kan > 15
+ THEN
+ niltask
+ ELSE
+ IF NOT exists (nettask (kan))
+ THEN
+ access catalogue;
+ nettask (kan) := task (kan);
+ IF NOT (nettask (kan) < father) THEN nettask (kan) := niltask FI;
+ FI;
+ nettask (kan)
+ FI
+END PROC netport;
+
+PROC frei (INT CONST stat,lvl):
+ DATASPACE VAR ds := nilspace;
+ BOUND STRUCT (INT x,y) VAR msg := ds;
+ msg.x := stat; msg.y := lvl;
+ INT VAR return;
+ call (netport (stat), freigabecode, ds, return) ;
+ forget (ds)
+END PROC frei;
+
+PROC net manager (DATASPACE VAR ds, INT CONST order, phase, TASK CONST
+ ordertask):
+
+ IF order = report code AND ordertask < myself
+ THEN
+ IF storage (old("report")) > 20 THEN forget ("report", quiet) FI;
+ FILE VAR rp := sequential file (output, "report");
+ BOUND TEXT VAR rpt := ds;
+ putline (rp, rpt);
+ send (ordertask, ack, ds)
+ ELIF order = abgleichcode AND ordertask < myself
+ THEN
+ BOUND STRUCT (INT ende, zwischen) VAR x := ds;
+ route.port (x.ende) := channel (ordertask);
+ route.zwischen (x.ende) := x.zwischen;
+ send (ordertask, ack, ds)
+ ELIF order = neue routen code AND ordertask < myself
+ THEN
+ forget ("port intern");
+ copy (ds,"port intern");
+ route := old ("port intern");
+ send (ordertask, ack, ds)
+ ELIF station (ordertask) = station (myself)
+ THEN
+ IF ordertask < myself
+ OR order = list code
+ OR order > continue code
+ THEN
+ IF order = list code
+ THEN
+ enable stop;
+ forget (ds); ds := old ("report");
+ FILE VAR ff := sequential file (output,ds);
+ putline (ff,"bekannte Stationen:");
+ stationen; line (ff); putline (ff,"--------");
+ putline (ff,"Eingestellte Netzmodi:");
+ kanaele ;
+ paketgroessen;
+ line (ff); putline (ff,"********");
+ putline (ff,stand);
+ putline (ff,"Rechner "+text(station(myself))+" um "+time of day);
+ send (ordertask, ack, ds)
+ ELSE
+ free manager (ds,order,phase,order task)
+ FI
+ ELSE
+ errorstop ("nur 'list' ist erlaubt")
+ FI
+ FI .
+
+stationen:
+INT VAR stat;
+INT VAR mystation := station (myself);
+FOR stat FROM 1 UPTO maxstat REP
+ IF route.port (stat) > 0 AND stat <> mystation
+ THEN
+ put (ff,text(stat)+"("+text (route.port (stat) AND 255)+","+
+ text(route.zwischen(stat))+")")
+ FI
+PER.
+
+paketgroessen:
+
+ line(ff);
+ put (ff, "Nutzlaenge bei indirekter Verbindung "+
+ text (data length via node) + " Byte "); line (ff).
+
+kanaele:
+ INT VAR portnummer;
+ TASK VAR tsk;
+ FOR portnummer FROM 1 UPTO 15 REP
+ tsk := task (portnummer);
+ IF tsk < myself THEN beschreibe kanal FI;
+ PER.
+
+beschreibe kanal:
+ putline (ff, name (tsk) + " haengt an Kanal " + text (channel (tsk))
+ + ", " + mode text (netz mode (portnummer))).
+
+END PROC net manager;
+
+TASK VAR cd,stask;
+ROW maxstat INT VAR erlaubt;
+
+PROC communicate:
+ enable stop;
+ INT VAR scode, merken :=0;
+ DATASPACE VAR dr := nilspace;
+ neuer start (quit max, kanalmode);
+REP
+ forget (dr);
+ telegrammfreigabe;
+ wait (dr, scode, stask);
+ cd := collected destination;
+ IF weiterleitung steht noch aus
+ THEN
+ send (netport (merken), out code, mds, reply);
+ IF reply <> -2 THEN forget (mds); merken := 0 FI
+ FI;
+ IF zeichen da OR zeit abgelaufen
+ THEN
+ packet
+ ELIF cd = myself
+ THEN
+ netz info und steuerung
+ ELSE
+ sendung untersuchen (stask, cd, scode, dr)
+ FI
+PER.
+
+telegrammfreigabe:
+ INT VAR dummy;
+ control (22,0,0,dummy).
+
+zeichen da: scode < 0 .
+
+zeit abgelaufen: scode = ack AND cd = myself.
+
+packet:
+ INT VAR snr, ant,err;
+ TASK VAR quelle, ziel;
+ snr := 0;
+ IF NOT zeichen da THEN routen erneuern FI;
+ REP
+ IF NOT zeichen da
+ THEN
+ forget (dr);
+ zeitueberwachung (snr, quelle, ziel, ant, dr);
+ ELIF NOT weiterleitung steht noch aus
+ THEN
+ packet eingang (snr, quelle, ziel, ant, dr);
+ FI;
+ IF snr = 1000
+ THEN
+ packet weiterleiten
+ ELIF snr > 0
+ THEN
+ IF ant > 6 AND erlaubt(station (quelle)) < 0
+ THEN unerlaubt
+ ELSE
+ send (quelle,ziel,ant,dr,err);
+ fehlerbehandlung ;
+ FI
+ FI
+ UNTIL snr = 0 OR zeichen da PER.
+
+routen erneuern:
+ rzaehler DECR 1;
+ IF rzaehler = 0
+ THEN
+ rzaehler := 20;
+ neue routen holen
+ FI.
+
+weiterleitung steht noch aus: merken <> 0.
+
+packet weiterleiten:
+ INT VAR reply;
+ IF NOT ((route.port (ant) AND 255) = channel OR route.port (ant) < 0)
+ THEN
+ send (netport (ant), out code, dr, reply);
+ IF reply = -2
+ THEN
+ merken := ant;
+ DATASPACE VAR mds := dr
+ FI
+ ELSE
+ report ("Weiterleitung nicht möglich für "+text(ant))
+ FI.
+
+fehlerbehandlung:
+ IF ok oder ziel nicht da THEN loesche verbindung (snr) FI.
+
+ok oder ziel nicht da: err=0 OR err=-1.
+
+netz info und steuerung:
+ IF scode = list code THEN list status
+ ELIF scode = erase code THEN strom beenden
+ ELIF scode = freigabe code AND stask = father THEN freigabelevel
+ ELIF scode >= route code THEN weitergaben
+ ELIF scode > tabellencode THEN routen ausliefern
+ ELSE forget (dr); ablehnen ("nicht möglich")
+ FI.
+
+weitergaben:
+ IF stask < father
+ THEN
+ IF scode = out code
+ THEN
+ BOUND INT VAR stx lng := dr;
+ INT VAR decoded lng := stx lng;
+ decode packet length (decoded lng);
+ transmit header (dr);
+ blockout (dr,1,drverwaltungslaenge,decoded lng);
+ transmit trailer
+ ELIF scode = route code
+ THEN
+ BOUND PARA VAR parah := dr;
+ PARA VAR para := parah;
+ pingpong (stask, ack, dr, reply);
+ neue sendung (para.quelle, para.ziel, para.sendecode,
+ para.zielstation, dr);
+ forget (dr); dr := nilspace;
+ send (stask, ack, dr)
+ FI
+ ELSE
+ forget (dr);
+ ablehnen ("nicht Sohn von "+name(father))
+ FI.
+
+routen ausliefern:
+ neue sendung (stask, myself, -routen liefern code, scode-tabellencode,dr).
+
+freigabelevel:
+ BOUND STRUCT (INT stat,lvl) VAR lv := dr;
+ IF lv.stat > 0 AND lv.stat <= maxstat THEN erlaubt (lv.stat) := lv.lvl FI;
+ send (stask,ack,dr).
+
+unerlaubt:
+ report ("Fremdzugriff von "+text(station (quelle))+" auf "+nam(ziel)
+ +" code "+text(ant));
+ loesche verbindung (snr);
+ forget (dr); dr := nilspace;
+ BOUND TEXT VAR errtxt := dr;
+ errtxt:="Kein Zugriff auf Station "+text (station (myself));
+ neue sendung (ziel, quelle, error nak, station (quelle), dr).
+
+strom beenden:
+ BOUND TEXT VAR stromtext := dr;
+ INT VAR erase strom := int (stromtext);
+ forget (dr);
+ strom := erase strom;
+ IF falsche stromnummer THEN ablehnen ("Strom gibt es nicht")
+ ELSE
+ BOUND INFO VAR v := verbindung (strom);
+ IF
+ stask < supervisor OR stask = vx.quelle OR stask = vx.ziel
+ THEN
+ loeschen
+ ELSE ablehnen ("Nur Empfänger/Absender darf löschen")
+ FI
+ FI.
+
+loeschen:
+ IF sendeeintrag THEN
+ IF callee (vx.quelle) = vx.ziel THEN absender warnen FI;
+ loesche verbindung (strom)
+ ELSE
+ IF callee (vx.ziel) = vx.quelle THEN warnen FI;
+ loesche verbindung (strom)
+ FI;
+ dr := nilspace;
+ send (stask,ack,dr).
+
+absender warnen:
+ dr := nilspace;
+ send(vx.ziel,vx.quelle,1,dr,err) .
+
+warnen:
+ dr := nilspace;
+errtxt := dr; errtxt:= "Station antwortet nicht";
+send (vx.quelle,vx.ziel,error nak, dr, err).
+
+falsche stromnummer: strom < 1 OR strom > max verbindungsnummer.
+sendeeintrag: vx.quellrechner = station (myself).
+vx: v.steuer.
+END PROC communicate;
+
+PROC list option:
+ begin ("net list",PROC list net, sohn)
+END PROC list option;
+
+PROC list net:
+ disable stop;
+ DATASPACE VAR ds ;
+ INT VAR scode;
+ REP
+ wait (ds, scode, stask);
+ forget (ds); ds := nilspace;
+ FILE VAR f := sequential file (output, ds);
+ list (f, father);
+ list netports;
+ IF is error THEN clear error;
+ forget(ds);
+ ds := nilspace;
+ f := sequential file (output, ds);
+ output (f); putline (f,errormessage);
+ clear error
+ FI;
+ send (stask, ack, ds)
+ PER.
+
+list netports:
+ INT VAR k;
+ FOR k FROM 1 UPTO 15 REP
+ TASK VAR tsk := task (k);
+ IF tsk < father
+ THEN
+ putline (f, name (tsk));
+ list (f,tsk)
+ FI
+ PER.
+
+END PROC list net;
+
+PROC neue routen holen:
+ forget ("port intern", quiet);
+ fetch ("port intern");
+ route := old ("port intern");
+ neue routen
+END PROC neue routen holen;
+
+PROC sendung untersuchen (TASK CONST q, z, INT CONST cod, DATASPACE VAR dr):
+ IF z = collector
+ THEN
+ verbindungsebene
+ ELIF station (z) <> 0
+ THEN
+ sendung (q,z,cod,station (z),dr)
+ ELSE
+ ablehnen ("Station 0")
+ FI.
+
+verbindungsebene:
+ IF cod = 256 THEN name von fremdstation
+ ELIF cod > 256
+ THEN
+ taskinfo fremd
+ ELIF callee (q) = z (* gegen errornak an collector *)
+ THEN
+ task id von fremd
+ FI.
+
+taskinfo fremd: sendung (q, collector, -task info code,cod-256,dr).
+
+task id von fremd: sendung (q, collector, -task id code, zielstation, dr) .
+
+name von fremdstation:
+ BOUND TASK VAR tsk := dr;
+ TASK VAR tsk1 := tsk;
+ forget (dr);
+ dr := nilspace;
+ sendung (q, tsk1, -name code, station (tsk1), dr).
+
+zielstation: cod.
+END PROC sendung untersuchen;
+
+PROC sendung (TASK CONST q, z, INT CONST code, z stat, DATASPACE VAR dr):
+ IF z stat < 1 OR z stat > maxstat
+ THEN
+ ablehnen ("ungültige Stationsnummer");
+ LEAVE sendung
+ FI;
+ INT VAR reply;
+ INT VAR rp := route.port (z stat) AND 255;
+ IF rp = 255 THEN neue routen holen ;rp := route.port (z stat) AND 255 FI;
+ IF rp = channel
+ THEN
+ sendung selbst betreiben
+ ELIF rp > 0 AND rp < 16
+ THEN
+ sendung weitergeben
+ ELSE
+ ablehnen ("Station "+text(z stat)+" gibt es nicht")
+ FI.
+
+sendung selbst betreiben:
+ neue sendung (q, z, code, z stat, dr).
+
+sendung weitergeben:
+ DATASPACE VAR ds := nilspace;
+ BOUND PARA VAR p := ds;
+ p.quelle := q;
+ p.ziel := z;
+ p.zielstation := z stat;
+ p.sendecode := code;
+ call (netport (z stat), route code, ds, reply);
+ forget (ds);
+ pingpong (netport (z stat), 0, dr, reply);
+ forget (dr);
+ IF reply < 0 THEN ablehnen ("netport "+text(route.port(zstat)AND255)
+ + " fehlt") FI
+END PROC sendung;
+
+PROC ablehnen (TEXT CONST t):
+ DATASPACE VAR vdr := nilspace;
+ BOUND TEXT VAR errtxt := vdr;
+ INT VAR err;
+ errtxt := t;
+ send (cd,stask, error nak, vdr,err);
+ forget (vdr).
+END PROC ablehnen;
+
+PROC stop:
+ access catalogue;
+ IF exists task ("net timer")
+ THEN
+ TASK VAR nets := father (/"net timer");
+ ELSE
+ nets := myself
+ FI;
+ nets := son (nets);
+ WHILE NOT (nets = niltask) REP
+ IF text (name (nets),3) = "net" OR name (nets) = "router"
+ THEN
+ end (nets)
+ FI;
+ nets := brother (nets)
+ PER
+END PROC stop;
+
+PROC list status:
+
+ DATASPACE VAR ds := nilspace;
+ FILE VAR f:=sequential file (output, ds);
+ line(f);
+ FOR strom FROM 1 UPTO max verbindungsnummer REP
+ IF strom > 0 THEN
+ BOUND INFO VAR v := verbindung (strom);
+ IF vx.strom <> 0 THEN info FI
+ FI;
+ PER;
+ send (stask, ack, ds).
+
+info:
+ put (f,"Strom "+text(strom));
+ put (f,"(sqnr"+text(vx.sequenz)+"/"+text (v.maxseq)+")");
+ IF sendeeintrag THEN sendeinfo ELSE empfangsinfo FI;
+ line (f).
+
+sendeeintrag: vx.quellrechner = station(myself) .
+
+sendeinfo:
+ IF v.typ = call im wait THEN put (f,"erwartet Antwort von")
+ ELIF v.typ = call in zustellung THEN put (f,"Ziel busy. Zielstation:")
+ ELIF v.typ = call im abbruch THEN put (f,"wird gelöscht bei Antwort von")
+ ELSE put (f,"sendet an")
+ FI;
+ put (f,vx.zielrechner);
+ put (f,". Absender ist """+nam (vx.quelle)+""".").
+
+empfangsinfo:
+ IF v.typ = zustellung THEN
+ put (f,"Sendung noch nicht zustellbar")
+ ELSE
+ put (f,"empfängt von");
+ put (f,vx.quellrechner);
+ FI;
+ put (f,". Empfaenger ist """+nam (vx.ziel)+""".").
+
+vx: v.steuer.
+END PROC list status;
+
+INT VAR quitmax := 3;
+
+ROW 15 TASK VAR net task;
+ROW 15 INT VAR netz mode;
+
+PROC erlaube (INT CONST von, bis):
+ IF ein kanal gestartet
+ THEN
+ putline ("Warnung: 'erlaube' muß vor 'starte kanal'")
+ FI;
+ test (von); test (bis);
+ INT VAR i;
+ FOR i FROM von UPTO bis REP erlaubt (i) := 0 PER
+END PROC erlaube;
+
+PROC sperre (INT CONST von, bis):
+ IF ein kanal gestartet
+ THEN
+ putline ("Warnung: 'sperre' muß vor 'starte kanal'")
+ FI;
+ test (von); test (bis);
+ INT VAR i;
+ FOR i FROM von UPTO bis REP erlaubt (i) :=-1 PER
+END PROC sperre ;
+
+BOOL VAR alte routen, ein kanal gestartet;
+
+PROC definiere netz:
+ stop;
+ INT VAR i;
+ FOR i FROM 1 UPTO 15 REP net task (i) := niltask PER;
+ ein kanal gestartet := FALSE;
+ FILE VAR s := sequential file (output,"report");
+ putline (s," N e u e r S t a r t " + date + " " + time of day );
+ alte routen := exists ("port intern");
+ IF alte routen
+ THEN
+ route := old ("port intern")
+ ELSE
+ route := new ("port intern");
+ initialize routes
+ FI.
+
+ initialize routes:
+ FOR i FROM 1 UPTO maxstat REP
+ route.zwischen(i) := i
+ PER.
+
+END PROC definiere netz;
+
+PROC starte kanal (INT CONST k,modus,stroeme):
+ ein kanal gestartet := TRUE;
+ IF exists (canal (k)) THEN end (canal (k)) FI;
+ IF stroeme <= 0 THEN errorstop ("3.Parameter negativ") FI;
+ quitmax := stroeme;
+ c := k;
+ IF c < 1 OR c > 15 THEN errorstop ("unzulässiger Kanal:"+text(c)) FI;
+ kanalmode := modus;
+ IF kanalmode < 1 OR kanalmode > max mode
+ THEN errorstop ("unzulässiger Netzbetriebsmodus:"+text(kanalmode))
+ ELSE netz mode (c) := kanalmode
+ FI;
+ IF NOT exists task ("net port")
+ THEN
+ begin ("net port",PROC net io, net task (c));
+ define collector (/"net port")
+ ELSE
+ begin ("net port "+text (c),PROC net io, net task (c))
+ FI.
+END PROC starte kanal;
+
+PROC routen (INT CONST von, bis, kanal, zw):
+ INT VAR i;
+ IF kanal < 0 OR kanal > 15 THEN errorstop ("Kanal unzulässig") FI;
+ test (von); test (bis);
+ FOR i FROM von UPTO bis REP
+ route.port (i) := kanal+256;
+ IF zw=0
+ THEN
+ route.zwischen (i) := i
+ ELSE
+ test (zw);
+ route.zwischen (i) := zw
+ FI
+ PER.
+END PROC routen;
+
+PROC routen (INT CONST von, bis, kanal):
+ routen (von, bis, kanal, 0)
+END PROC routen;
+
+PROC test (INT CONST station):
+ IF station < 1 OR station > maxstat
+ THEN
+ errorstop (text (station) + " als Stationsnummer unzulässig")
+ FI
+END PROC test;
+
+PROC aktiviere netz:
+vorgegebene routen pruefen;
+IF existstask ("net timer") THEN end (/"net timer") FI;
+begin ("net timer",PROC timer,sohn);
+IF NOT alte routen
+THEN
+ routen aufbauen
+ELSE
+ IF online THEN break FI
+FI.
+
+vorgegebene routen pruefen:
+ INT VAR i;
+ FOR i FROM 1 UPTO maxstat REP
+ INT VAR s := route.port (i) AND 255;
+ IF s > 0 AND s <= 15 CAND nettask (s) = niltask
+ THEN
+ errorstop ("Kanal "+text(s)+" nicht gestartet, steht aber in Routen")
+ FI
+ PER.
+END PROC aktiviere netz;
+
+
+PROC routen aufbauen:
+ alte routen := TRUE;
+ c := channel;
+ break (quiet);
+ begin ("router", PROC rout0, sohn).
+END PROC routen aufbauen;
+
+PROC rout0:
+ disable stop;
+ rout;
+ IF is error
+ THEN
+ put error
+ FI;
+ end (myself)
+END PROC rout0;
+
+PROC rout:
+ IF c>0 THEN continue (c) FI;
+ clear error; enable stop;
+ fetch ("port intern");
+ route := old ("port intern");
+ routen aufbauen;
+ ds := old ("port intern");
+ call (father, neue routen code, ds, reply).
+
+routen aufbauen:
+ access catalogue;
+ TASK VAR port := brother (myself);
+ WHILE NOT (port = niltask) REP
+ IF text (name (port),8) = "net port" THEN nachbarn FI;
+ port := brother (port)
+ PER;
+ IF online THEN putline ("Fertig. Weiter mit SV !") FI.
+
+aenderbar: route.port (st) < 256.
+
+nachbarn:
+ INT VAR st,reply;
+ FOR st FROM 1 UPTO maxstat REP
+ IF erlaubt (st) >= 0 AND st <> station (myself) AND aenderbar
+ THEN
+ IF online THEN put (name (port)); put (st) FI;
+ DATASPACE VAR ds := nilspace;
+ call (port, tabellencode+st, ds, reply);
+ IF reply = ack
+ THEN
+ BOUND STRUCT (ROW maxstat INT port,
+ ROW maxstat INT zwischen) VAR fremd := ds;
+ route.port (st) := channel(port);
+ route.zwischen (st) := st;
+ indirekte ziele
+ ELIF reply < 0
+ THEN
+ errorstop ("netz läuft nicht (Kanalnummer falsch)")
+ ELSE
+ BOUND TEXT VAR xt := ds;
+ IF online THEN put (xt) FI;
+ FI;
+ IF online THEN line FI;
+ forget (ds)
+ FI
+ PER.
+
+indirekte ziele:
+ INT VAR kanal := fremd.port (station (myself)) AND 255;
+ INT VAR ind;
+ FOR ind FROM 1 UPTO maxstat REP
+ IF ind bei st bekannt AND NOT ((fremd.port (ind) AND 255) = kanal)
+ AND route.port (ind) < 256
+ THEN
+ route.port (ind) := channel (port);
+ route.zwischen (ind) := st
+ FI
+ PER.
+
+ind bei st bekannt: NOT (fremd.port (ind) = -1).
+
+END PROC rout;
+
+
+PROC timer:
+ disable stop;
+ access catalogue;
+ INT VAR old session := 1;
+ REP
+ IF session <> old session
+ THEN
+ define collector (/"net port");
+ old session := session
+ FI;
+ clear error;
+ pause (30);
+ sende tick an alle ports
+ PER.
+
+sende tick an alle ports :
+ TASK VAR fb := son (father);
+ REP
+ IF NOT exists (fb) THEN access catalogue;LEAVE sende tick an alle portsFI;
+ IF channel (fb) > 0
+ THEN
+ DATASPACE VAR ds := nilspace;
+ send (fb, ack, ds);
+ pause (10)
+ FI;
+ fb := brother (fb)
+ UNTIL fb = niltask PER.
+
+END PROC timer;
+
+PROC net io:
+ disable stop;
+ set net mode (kanalmode);
+ fetch ("port intern");
+ route := old ("port intern");
+ commanddialogue (FALSE);
+ continue (c);
+ communicate;
+ TEXT VAR emsg := "++++++ "+error message +" Zeile "+text(errorline);
+ clear error;
+ report (emsg);
+ end (myself)
+END PROC net io;
+
+PROC start: run ("netz") END PROC start;
+
+END PACKET net manager;
+
diff --git a/net/net report b/net/net report
new file mode 100644
index 0000000..ddc19d2
--- /dev/null
+++ b/net/net report
@@ -0,0 +1,41 @@
+PACKET net report DEFINES report, abgleich:
+(* Version 3 (!) *)
+
+LET reportcode = 99, abgleichcode = 98;
+
+PROC abgleich (INT CONST ende, zwischen):
+ DATASPACE VAR ds := nilspace;
+ BOUND STRUCT (INT ende, zwischen) VAR x := ds;
+ x.ende := ende;
+ x.zwischen := zwischen;
+ call (father, abgleichcode, ds, rep);
+ INT VAR rep;
+ forget (ds)
+END PROC abgleich;
+
+PROC report (TEXT CONST x):
+ report(x,"")
+END PROC report;
+
+PROC report (TEXT CONST txt, info):
+ DATASPACE VAR net report := nilspace;
+ BOUND TEXT VAR rinfo := net report;
+ rinfo := date;
+ rinfo CAT " "+time of day +" ";
+ rinfo CAT name(myself)+":";
+ rinfo CAT txt;
+ INT VAR i;
+ FOR i FROM 1 UPTO length (info) REP
+ INT VAR z := code (infoSUBi) ;
+ IF z < 32 OR z > 126
+ THEN rinfo CAT "%"+text(z)+" "
+ ELSE rinfo CAT (infoSUBi)+" "
+ FI
+ PER;
+ call (father, report code , net report, reply);
+ INT VAR reply;
+ forget (net report);
+END PROC report;
+
+END PACKET net report;
+
diff --git a/net/netz b/net/netz
new file mode 100644
index 0000000..c237ba2
--- /dev/null
+++ b/net/netz
@@ -0,0 +1,20 @@
+IF exists ("port intern") THEN forget ("port intern") FI;
+definiere netz;
+list option;
+erlaube(1,127);
+sperre (1,9);
+sperre (15,32);
+sperre (37,37);
+sperre (42,42);
+sperre (46,47);
+sperre (49,127);
+routen (1, 32,8);
+routen (33,43, 9);
+routen (34,34,8);
+routen (35,48,9);
+starte kanal (9,11,10);
+starte kanal (8,1,10);
+aktiviere netz;
+
+
+
diff --git a/net/netzhandbuch b/net/netzhandbuch
new file mode 100644
index 0000000..7083462
--- /dev/null
+++ b/net/netzhandbuch
@@ -0,0 +1,2045 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#Netzsoftware
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#pagenr ("%",1)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Inhalt
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right# GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+
+#center#Inhalt
+
+#clear pos##lpos(1.0)##rpos(9.5)#
+#table#
+
+1. Einleitung #topage("0")#
+
+Teil 1: Netz einrichten und benutzen #topage("1")#
+
+
+1.1. Hardwarevoraussetzungen #topage("1.1")#
+1.2. Einrichten des Netzes #topage("1.2")#
+1.3. Benutzung des Netzes #topage("1.3")#
+1.4. Informationsmöglichkeiten #topage("1.4")#
+1.5. Eingriffsmöglichkeiten #topage("1.5")#
+1.6. Fehlerbehebung im Netz #topage("1.6")#
+1.7. Sicherheit im Netz #topage("1.7")#
+
+
+
+Teil 2: Arbeitsweise der Netzsoftware #topage("2")#
+
+
+2.1. Die Netztask #topage("2.1")#
+2.2. Protokollebenen #topage("2.2")#
+2.3. Stand der Netzsoftware #topage("2.3")#
+
+
+
+Teil 3: Netz-Hardware-Interface #topage("3")#
+
+
+3.1. Einführung #topage("3.1")#
+3.2. Arbeitsweise des Netz-Hardware-Interfaces #topage("3.2")#
+3.3. Netztreiber #topage("3.3")#
+3.4. Prozedurschnittstelle des EUMEL-Netzes #topage("3.4")#
+
+
+
+Anhang #topage("A")#
+
+
+1. Fehlermeldungen #topage("A.1")#
+2. Literaturhinweise #topage("A.2")#
+3. Index #topage("A.3")#
+
+#table end#
+#clear pos#
+
+#page#
+#pagenr ("%", 2)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Einleitung
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+
+1. Einleitung
+
+#goalpage("0")#
+Das EUMEL-Netz dient dazu, mehrere EUMEL-Rechner (sog. #ib#Station#ie#en) miteinan­
+der zu koppeln. Diese Kopplung wird vom Betriebssystem dazu benutzt, das Sen­
+dungskonzept [1] so auszudehnen, daß Tasks verschiedener Stationen einander
+Datenräume zusenden können. Auf dem #ib#Sendungskonzept#ie# aufbauende Konzepte
+nutzen daher automatisch das Netz aus: So ist es z.B. möglich
+
+- von einer Station aus auf einer anderen zu drucken,
+
+- in die Task PUBLIC einer anderen Station #ib#Datei#ie#en zu sichern (save), vorausge­
+ setzt, daß PUBLIC dort ein #on("b")#free global manager#off("b")# ist,
+
+- auf einer anderen Station zu archivieren (z.B. wenn das eigene Archivlaufwerk
+ defekt ist oder ein anderes Format hat).
+
+Diese #ib#Netzversion#ie# kann ab EUMEL-Version 1.8.1 eingesetzt werden.
+
+Diese Netzbeschreibung besteht aus drei Teilen. In Teil 1 wird beschrieben, wie das
+EUMEL-Netz benutzt und eingerichtet wird. Als Benutzer eines EUMEL-
+Rechners, der vernetzt ist, ist nur dieser Teil der Netzbeschreibung für Sie wichtig.
+Teil 2 erklärt die Funktionsweise der #ib#Netzsoftware#ie#, im dritten Teil wird die Schnitt­
+stelle für die Anpassung anderer #ib#Netzhardware#ie# definiert.
+
+Hinweis:
+
+Zur erstmaligen #ib#Installation#ie# des EUMEL-Netzes ist außer dieser Beschreibung noch
+die Netzsoftware (auf Floppy) und die EUMEL-Netz-#ib#Installationsanleitung#ie#, die mit
+der Software geliefert wird, notwendig.
+
+In der vorliegenden Netzbeschreibung wird das EUMEL-Netz möglichst "hardware
+unabhängig" beschrieben. Wenn hardwareabhängige Beispiele gegeben werden, so
+ist die dort beschriebene Hardware stets die #ib#Datenbox#ie#.
+#pagenr ("%", 3)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#cneter#____________________________________________________________
+
+#end#
+#headodd#
+#center#Teil 1 : Netz einrichten und benutzen
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#page#
+
+Teil 1: Netz einrichten und benutzen
+#goalpage("1")#
+
+
+
+1.1. Hardwarevoraussetzungen
+#goalpage("1.1")#
+
+
+Zwei Stationen
+
+Sie können zwei #ib#Station#ie# miteinander vernetzen, wenn Sie dafür an jeder Station eine
+#ib#V.24#ie#-#ib#Schnittstelle#ie# zur Verfügung stellen.
+
+Diese beiden Schnittstellen verbinden Sie mit einem Kabel zur #ib#Rechnerkopplung#ie# [2].
+
+
+Mehrere Stationen
+
+Wenn Sie mehr als zwei Stationen vernetzen wollen, stehen Ihnen zwei Konzepte zur
+Verfügung: das Anlegen von #ib#Netzknoten#ie# bzw. das Verwenden eines #ib#Strang#ie#es. Die
+Konzepte können gemischt eingesetzt werden.
+
+Ein Strang besteht aus einer Anzahl von #ib#Netzbox#ie#en (z.B. KHW-Box oder Ethernet­
+anschluß).
+
+Jede Box besitzt eine #ib#Schnittstelle#ie# (z.B. #ib#V.24#ie#) zum Anschluß an einen der Kanäle
+1...15 der zugeordneten #ib#Station#ie# und eine weitere Schnittstelle zur #ib#Verbindung#ie# der
+Boxen untereinander.
+
+Ein #ib#Knoten#ie# ist eine Station, bei der der Netzbetrieb über mehrere Kanäle läuft.
+
+Da die #ib#Netzsoftware#ie# pro #ib#Kanal#ie# eines Knotens eine Task generiert, ist das Knoten­
+konzept dem Strangkonzept hinsichtlich des #ib#Durchsatz#ie#es unterlegen. Preisgünstiger
+ist jedoch das #ib#Knotenkonzept#ie#, weil dabei #ib#Netzbox#ie#en überflüssig werden.
+
+Beim Knotenkonzept wird eine #ib#Vermaschung#ie# nicht zur Optimierung benutzt (Ver­
+maschung heißt, daß eine #ib#Zielstation#ie# über verschiedene Knoten erreichbar ist). Daher
+sollte man keine Vermaschung vorsehen.
+
+#ib#Nachbarn#ie# sind Stationen, die an denselben #ib#Netzstrang#ie# angeschlossen oder direkt
+über ein #ib#V.24#ie#-Kabel verbunden sind.
+
+Bei der Entscheidung, welche Stationen man zu #ib#Knoten#ie# macht, sollte beachtet wer­
+den, daß (a) Stationen, zwischen denen hoher Verkehr besteht, Nachbarn werden und
+daß (b) besonders leistungsfähige Rechner #ib#Knoten#ie#stationen sein sollten.
+#page#
+
+1.2. Einrichten des Netzes
+#goalpage("1.2")#
+
+
+Hinweis: Dieses Kapitel ist nur für Systembetreuer wichtig.
+
+a) Legen Sie für die am Netz beteiligten Rechner #ib#Stationsnummer#ie#n fest (von 1 an
+ aufsteigend).
+
+ Die Boxen haben ebenfalls Stationsnummern. Die Stationsnummern der Box und
+ des zugeordneten Rechners müssen übereinstimmen.
+
+
+b) Holen Sie an jeder #ib#Station#ie# die Task #on("bold")#configurator#off("bold")# an ein Terminal und geben Sie
+ das Kommando #on("bold")##ib#define station#ie# (x)#off("bold")#, wobei #on("bold")#x#off("bold")# die gewählte Stationsnummer ist.
+
+ Hinweis: Taskkommunikationen, die zu diesem Zeitpunkt laufen, führen zu feh­
+ lerhaftem Verhalten. Dies liegt daran, daß durch #on("bold")#define station#off("bold")# alle
+ #ib#Task-Id#ie#'s geändert werden müssen, weil eine #ib#Task-Id#ie# u.a. die
+ Stationsnummer der eigenen Station enthält (siehe 1.3). TASK-
+ Variablen, die noch Task-Id's mit keiner oder falscher Stationsnum­
+ mer enthalten, können nicht mehr zum Ansprechen einer Task ver­
+ wendet werden.
+
+ Beispiel: Der #ib#Spoolmanager#ie# [3] richtet beim Kommando #on("bold")#start#off("bold")# einen #ib#Worker#ie# ein
+ und merkt sich dessen #ib#Task-Id#ie# in einer TASK-Variablen, um sicher­
+ zustellen, daß nur der Worker #ib#Datei#ie#en zum Drucken abholt. Wird jetzt
+ das Kommando #on("bold")# define station#off("bold")# gegeben, kann der Spoolmanager
+ seinen Worker nicht mehr identifizieren, weil der Worker eine neue
+ Task-Id erhalten hat. Man muß daher vor #on("b")#define station#off("b")# den Worker
+ löschen und ihn danach mit dem Kommando #on("bold")##ib#start#ie##off("bold")# im Spoolmanager
+ wieder neu einrichten.
+
+
+ Sinnvollerweise gibt man #on("bold")#define station#off("bold")# sofort nachdem man ein frisches System
+ vom Archiv geladen hat.
+
+ Zum Anschluß einer #ib#Datenbox#ie# #ib#konfigurieren#ie# Sie mit dem Kommando #on("bold")##ib#configurate#ie##off("bold")#
+ den für das Netz vorgesehenen #ib#Kanal#ie# auf
+
+ - transparent
+ - 9600 #ib#Baud#ie# (Standardeinstellung der Boxen)
+ - #ib#RTS/CTS#ie#-#ib#Protokoll#ie#
+ - großen Puffer
+ - 8 bit
+ - even parity
+ - 1 stopbit.
+
+ Falls diese Einstellungen nicht alle angeboten werden, klären Sie mit Ihrem
+ Rechnerlieferanten, ob und wie diese Einstellungen erreicht werden können.
+
+ Hinweis: Notfalls kann auf das #ib#RTS/CTS#ie#-Protokoll verzichtet werden, wenn der
+ Eingabepuffer der #ib#Station#ie# groß genug ist. Die Anzahl simultan laufen­
+ der Netzkommunikationen ist dann auf
+
+ puffergröße DIV 150
+
+ begrenzt (bei Z80, 8086: 3; bei M20: 10).
+
+ Hinweis: Es können auch andere #ib#Baud#ie#raten (2400, 4800, 19200) an der Box
+ eingestellt werden.
+
+
+c) Achten Sie bei der #ib#Verbindung#ie# von der Station zur #ib#Netzbox#ie# (bzw. zur Gegen­
+ station bei einem Zweistationennetz ohne Boxen) darauf, daß neben den Emp­
+ fangs- und Sendeleitungen auch die Leitungen RTS und CTS verdrahtet wer­
+ den, also ein 5-poliges Kabel verwendet wird [2]. Die #ib#Pin-Belegung#ie# der Boxen
+ entspricht der eines Kabels zur Rechner-Rechner-Kopplung.
+
+ Beispiel:
+
+ Verbindung eines BICOS-Systems mit der Box:
+
+ Stecker Stecker
+ Pin Pin
+
+ 2 <---------> 3
+ 3 <---------> 2
+ 4 <---------> 5
+ 5 <---------> 4
+ 7 <---------> 7
+
+
+d) Richten Sie eine Task #on("bold")##ib#net#ie##off("bold")# unter #on("bold")#SYSUR#off("bold")# ein und legen Sie eine #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# an, die
+ Ihre #ib#Netzkonfiguration#ie# enthält, oder ändern Sie die mitgelieferte Datei ent­
+ sprechend ab (siehe auch 1.5.).#goalpage("sperre")#
+
+
+ Dem bisherigen Netz entspricht eine Datei #on("b")#netz#off("b")# mit folgendem Inhalt:
+
+ definiere netz;
+ routen (1,127,k);
+ starte kanal (k,1,x);
+ aktiviere netz.
+
+ k: ihr netzkanal.
+ x: IF yes ("#ib#Flußkontrolle#ie#") THEN 10 ELSE 3 FI.
+
+
+
+ Laden Sie die Datei #on("b")##ib#net install#ie##off("b")# vom Archiv #on("b")#net#off("b")# und übersetzen Sie diese. Je nach­
+ dem, welche EUMEL-Version auf der Maschine installiert ist, werden die notwen­
+ digen Programmdateien insertiert.
+
+ Es sind dies
+
+ net report
+ net hardware interface
+ basic net
+ net manager
+
+
+ Das Netz wird dabei gestartet.
+
+
+ Hinweis: Obwohl die Task #on("b")#net#off("b")# sich noch mit #on("bold")##ib#continue#ie##off ("bold")# an ein Terminal holen
+ läßt, sollte man dies nur kurzzeitig tun, da der Netzverkehr solange
+ blockiert ist.
+
+ In der #ib#Datei#ie# #on("b")#netz#off("b")# sollte der #ib#Kanal#ie#, über den der meiste Verkehr erwar­
+ tet wird, zuerst gestartet werden. Für ihn wird die Task #on("b")##ib#net port#ie##off("b")# gene­
+ riert, für jeden weiteren Kanal wird eine Task #on("b")##ib#net port#ie# k#off("b")# (k=Kanal­
+ nummer) generiert.
+#page#
+
+1.3. Benutzung des Netzes
+#goalpage("1.3")#
+
+
+Zur Benutzung des Netzes stehen folgende Operatoren und Prozeduren zur Verfü­
+gung:
+
+
+
+TASK OP #ib#/#ie# (INT CONST station, TEXT CONST taskname)
+
+liefert die Task #on("bold")#taskname#off("bold")# von der #ib#Station#ie# #on("bold")#station#off("bold")#.
+
+
+#ib#Fehlerfälle#ie#:
+
+ - #ib(4)#Task "...." gibt es nicht#ie(4)#
+
+ Die angeforderte Task gibt es auf der #ib#Zielstation#ie# nicht.
+
+ - #ib(4)##ib#Collectortask#ie# fehlt#ie(4)#
+
+ die Task #on("b")##ib#net port#ie##off("b")# existiert nicht (siehe 6).
+
+ Hinweis: #on("b")#net port#off("b")# wird bei jedem Start des Netzes neu generiert und beim
+ Auftreten eines nicht vorhergesehenen #ib#Fehler#ie#s beendet. Die Feh­
+ lermeldung steht im #on("b")##ib#report#ie##off("b")# (siehe 4).
+
+ - #ib(4)#Station x antwortet nicht#ie(4)#
+
+ Eine nicht vorhandene oder abgeschaltete Station wurde angesprochen.
+
+ Hinweis: Dieser #ib#Fehler#ie# wird angenommen, wenn eine Überwachungszeit von
+ ca. 30 Sekunden verstrichen ist, ohne daß Station x die Taskidenti­
+ fikation angeliefert hat.
+
+ - #ib(4)#Station x gibt es nicht#ie(4)#
+
+ #ib#Station#ie# x steht nicht in den #ib#Routentabelle#ie#n.
+
+ Diese Meldung kann auch erscheinen, wenn Station x erst kürzlich an das Netz
+ angeschlossen wurde. Sie steht dann noch nicht in den Routentabellen (siehe
+ auch 5.3.).
+
+ Beispiel:
+
+ list (5/"PUBLIC")
+
+ Die Dateiliste von PUBLIC der Station 5 wird angefordert.
+
+
+
+TASK OP #ib#/#ie# (INT CONST station, TASK CONST task)
+
+liefert
+
+station / name (task)
+
+Beispiel:
+
+ list (4/public)
+
+
+Fehlerfall:
+
+ "......" #ib(4)#gibt es nicht#ie(4)#
+
+ Auf der eigenen Station gibt es die Task #on("b")#task#off("b")# nicht.
+ Der Taskname wird auf der eigenen Station bestimmt, wenn es dort die Task
+ nicht gibt, führt dies zur obigen Fehlermeldung.
+
+Abhilfe:
+
+ Statt list(4/public) das Kommando list (4/"PUBLIC") verwenden.
+
+
+
+INT PROC #ib#station#ie# (TASK CONST task)
+
+liefert die #ib#Stationsnummer#ie# der Task #on("bold")#task#off("bold")#.
+
+Beispiel:
+
+ put (station (myself))
+
+ gibt die eigene Stationsnummer aus.
+
+
+
+
+PROC #ib#reserve#ie# (TEXT CONST archivename, TASK CONST archivetask)
+
+dient dazu, das Archiv auf der #ib#Station#ie# #on("bold")#station#off("bold")# anzumelden.
+
+Beispiel:
+
+ reserve ("std", 4/"ARCHIVE"); #ib#list#ie# (4/"ARCHIVE")
+
+ gibt das Inhaltsverzeichnis der Archivfloppy im Laufwerk der Station 4 aus.
+
+ Hinweis: Vergessen Sie bei solchen #ib#Querarchivierungen#ie# nicht die Stationsangabe
+ bei jedem einzelnen Archivkommando (z.B fetch ("xxx", #on("bold")#4/#off("bold")#
+ "ARCHIVE")).
+
+ Hinweis: Querarchivieren ist langsam. Verwenden Sie es nur, wenn Sie Floppy­
+ formate umsetzen wollen.
+
+
+
+
+PROC #ib#free global manager#ie#
+
+dient dazu, die eigene Task über das Netz ansprechbar zu machen. Jede andere
+Task im Netz kann dann die üblichen #ib#Manager#ie#aufrufe (#on("bold")##ib#save#ie##off ("bold")#, #on("bold")##ib#fetch#ie##off ("bold")#, usw.) an die
+eigene Task machen, sofern diese nicht an ein Terminal gekoppelt ist.
+
+Die Task wird (wie bei #on("bold")#break#off ("bold")#) abgekoppelt und meldet sich in Zukunft mit #on("bold")#mainte­
+nance#off ("bold")# statt mit #on("bold")#gib kommando#off ("bold")#.
+
+Beispiel:
+
+ An Station 4 ruft man in der Task "hugo" das Kommando #on("bold")#free global manager#off("bold")#
+ auf. Anschließend kann man von jeder Station aus z.B. #on("bold")#list (4/"hugo")#off ("bold")# usw. auf­
+ rufen.
+
+
+
+
+TEXT PROC #ib#name#ie# (TASK CONST t)
+
+Diese (schon immer vorhandene) Prozedur wurde dahingehend erweitert, daß der
+Name einer auf einer anderen Station existierenden Task über Netz angefordert wird.
+
+Existiert die Task nicht, so wird #on("bold")##ib#niltext#ie##off ("bold")# geliefert.
+
+Hinweis: Die Prozedur #on("bold")##ib#exists#ie##off ("bold")# wurde nicht auf das Netz ausgedehnt, da sie in Situa­
+ tionen eingesetzt wird, wo es auf eine sehr schnelle Antwort ankommt.
+ Daher liefert #on("bold")#exists#off ("bold")# für eine stationsfremde Task immer FALSE. Will man
+ wissen, ob eine solche Task existiert, verwende man die Abfrage
+
+ #on("bold")#IF name (task) <> "" THEN ... #off ("bold")#.
+
+#ib#Fehlerfall#ie#:
+
+ - #ib(4)#Station x antwortet nicht#ie(4)#
+
+ - #ib(4)##ib#Station#ie# x gibt es nicht#ie(4)#
+
+#page#
+
+1.4. Informationsmöglichkeiten
+
+#goalpage("1.4")#
+
+In der Task #on("bold")#net#off("bold")# wird eine #ib#Datei#ie# #on("bold")##ib#report#ie##off("bold")# geführt, in der #ib#Fehlersituationen#ie# des Netzes
+verzeichnet werden. Diese Datei kann in jeder anderen Task auf derselben Station mit
+#on("bold")##ib#list#ie# (/"#ib#net#ie#")#off("bold")# angesehen werden. Eine Erklärung der wichtigsten Meldungen finden Sie
+im Anhang.
+
+In jeder Task kann durch das Kommando #on("bold")##ib#list#ie# (/"#ib#net port#ie#")#off("bold")# eine Übersicht über die
+momentan laufenden #ib#Netzübertragungen#ie# der eigenen #ib#Station#ie# erhalten werden (nur für
+den #ib#Kanal#ie#, an dem #on("b")##ib#net port#ie##off("b")# hängt). Entsprechendes gilt für die weiteren Netports der
+eigenen Station.
+
+Mit #on("bold")##ib#list#ie# (/"#ib#net list")#ie##off("bold")# erhält man die Informationen, die man mit #on("b")#list (/"net")#off("b")# und #on("b")##ib#list#ie##off("b")# auf
+alle Netports bekommt, sofern #on("b")##ib#listoption#ie##off("b")# (siehe S. #topage("listop")#) beim Generieren des Netzes
+aufgerufen wurde. Dieser Aufruf funktioniert auch bei fremden Stationen (z.B. #on("b")#list
+(5/"net list")#off("b")#).
+
+#page#
+
+1.5. Eingriffsmöglichkeiten
+
+#goalpage("1.5")#
+
+- Jede Task kann #ib#Sende#ie(1,"ströme")#- und #ib#Empfangsströme#ie#, die bei #on("bold")#list (/"net port")#off("bold")# gemel­
+ det worden sind und die eigene Task betreffen, abbrechen. Hierzu ist das Kom­
+ mando #on("bold")##ib#erase#ie# ("x", /"#ib#net port#ie#")#off ("bold")# zu geben, wobei x die #ib#Stromnummer#ie# (aus dem #on("bold")#list#off ("bold")#)
+ ist.
+ Unberechtigte #ib#Löschversuche#ie# werden abgewiesen.
+ Von privilegierten Tasks aus können jedoch mit #on("b")##ib#erase#ie##off("b")# beliebige Ströme abge­
+ brochen werden.
+
+
+- Durch das Kommando #on("bold")##ib#start#ie##off("bold")# kann von der Task #on("b")##ib#net#ie##off("b")# aus das Netz neu gestartet
+ werden. Dies setzt eine gültige #ib#Datei#ie# #on("bold")#netz#off("bold")# voraus. Es wird ein #on("bold")##ib#run#ie##off("bold")# auf diese Datei
+ gegeben. Das Kommando #on("b")##ib#start#ie##off("b")# ist nur noch aus Kompatibilitätsgründen zum alten
+ Netz vorhanden.
+
+
+- Durch das Kommando #on("bold")##ib#routen aufbauen#ie##off("bold")# in der Task #on("b")##ib#net#ie##off("b")# werden die #ib#Routentabelle#ie#n
+ neu aufgebaut. Dies kann notwendig werden, wenn eine neue #ib#Station#ie# ans Netz
+ angeschlossen wurde (#ib#Fehlermeldung#ie# '#ib(4)#Station x gibt es nicht#ie(4)#'). #on("bold")#routen aufbauen#off ("bold")#
+ muß zuvor auch an allen dazwischenliegenden #ib#Knotenstation#ie#en gegeben werden.
+
+ #on("bold")#routen aufbauen#off ("bold")# erzeugt eine Task #on("b")##ib#router#ie##off("b")#, die sich an das Terminal koppelt (die
+ Task #on("b")#net#off("b")# koppelt sich ab) und ein #ib#Protokoll#ie# ausgibt. Sind die #ib#Route#ie#n aufgebaut,
+ beendet sich die Task #on("b")#router#off("b")# mit der Meldung #on("b")#fertig#off("b")#. Es werden nur Stationen
+ bearbeitet, die nicht #ib#gesperrt#ie# (siehe S. #topage("sperre")#), und für die keine festen Routen
+ vereinbart sind. Der Vorgang dauert ca. 5 Sek. pro nicht gesperrter Station und
+ #ib#Netzkanal#ie#. Die #ib#Route#ie#n werden in einem #ib#Datenraum#ie# #on("b")##ib#port intern#ie##off("b")# hinterlegt.
+
+
+- Der Aufruf #on("bold")##ib#definiere netz#ie##off("bold")# leitet eine #ib#Netzdefinition#ie# in der #ib#Datei#ie# #on("bold")##ib#netz#ie##off("bold")# ein. Dabei
+ werden alle augenblicklichen Netzkommunikationen gelöscht. Die Tasks #on("b")##ib#net port#ie#
+ (k)#off("b")#, wobei #on("b")#k#off("b")# die #ib#Kanalnummer#ie# ist, und #on("b")##ib#net timer#ie##off("b")# werden gelöscht.
+
+ Dieser Aufruf muß vor den Aufrufen von #on("bold")##ib#starte kanal#ie#, #ib#erlaube#ie#, #ib#sperre#ie#, #ib#routen#ie#,
+ #ib#aktiviere netz#ie# und #ib#list option#ie##off("bold")# erfolgen.
+
+
+- PROC #ib#sperre#ie# (INT CONST a,z)
+ bewirkt, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# keine Manageraufrufe an Tasks dieser Station
+ geben dürfen (Genauer gesagt werden sendecodes > 6 nicht weitergeleitet, son­
+ dern ein errornak mit dem Text "#ib(4)#kein Zugriff auf Station#ie(4)#" zurückgeschickt).
+
+ Dieser Aufruf muß vor dem ersten #on("bold")##ib#starte kanal#ie##off("bold")# erfolgen.
+
+
+- PROC #ib#erlaube#ie# (INT CONST a,z)
+ bewirkt, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# Manageraufrufe an Tasks dieser Station geben
+ dürfen.
+
+ Dieser Aufruf muß vor dem ersten #on("bold")##ib#starte kanal#ie##off("bold")# erfolgen.
+
+ Beispiel: Alle Stationen außer 8 und 10 sollen #ib#gesperrt#ie# sein:
+
+ #ib#sperre#ie# (1,127); erlaube (8,8); erlaube (10,10)
+
+ Hinweis: 127 ist z.Zt. die maximale #ib#Stationsnummer#ie(1," maximale")#.
+
+
+- PROC #ib#routen#ie# (INT CONST a,z,k)
+ legt fest, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# an #ib#Kanal#ie# #on("bold")#k#off("bold")# direkt angeschlossen sind. Sen­
+ dungen dieser Stationen werden nur bearbeitet, wenn sie über diesen Kanal her­
+ einkommen (siehe 1.7.). Fehlt für eine Station ein entsprechender Routenaufruf, so
+ darf sie über einen beliebigen #ib#Netzkanal#ie# angeschlossen sein. Dies wird dann von
+ #on("bold")##ib#routen aufbauen#ie##off("bold")# ermittelt.
+
+ PROC routen (INT CONST a,z,k,zw)
+ legt fest, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# indirekt über die #ib#Knotenstation#ie# #on("bold")#zw#off("bold")# angeschlos­
+ sen sind, und #on("b")#zw#off("b")# am Kanal #on("bold")#k#off("bold")# hängt.
+
+
+- PROC #ib#starte kanal#ie# (INT CONST k,m,q)
+ startet eine #ib#Netztask#ie# am #ib#Kanal#ie# #on("bold")#k#off("bold")# im Modus #on("bold")#m#off("bold")# [4]. Dabei wird mit #on("bold")#q#off("bold")# die Anzahl
+ paralleler #ib#Empfangsströme#ie# festgelegt. Dadurch kann erreicht werden, daß der
+ #ib#Empfangspuffer#ie# nicht überläuft, indem nicht mehr als #on("b")#q#off("b")# Ströme quittiert werden.
+ Bei #ib#V.24#ie#-#ib#Schnittstelle#ie#n gebe man 3 (ohne #ib#Flußkontrolle#ie#) bzw. 10 (mit Flußkon­
+ trolle) an.
+
+
+- PROC #ib#aktiviere netz#ie#
+ muß als Abschluß in der Datei #on("bold")##ib#netz#ie##off("bold")# aufgerufen werden. Dabei wird die Task vom
+ Terminal abgekoppelt. Falls es bei #on("bold")##ib#definere netz#ie##off("bold")# den #ib#Datenraum#ie# #on("b")##ib#port intern#ie##off("b")#, der
+ die #ib#Route#ie#n enthält, nicht gab, wird #on("bold")##ib#routen aufbauen#ie##off("bold")# aufgerufen.
+
+
+- PROC #ib#listoption#ie##goalpage("listop")#
+ erzeugt eine Task #on("b")##ib#net list#ie##off("b")#, die bei #on("bold")#list#off("bold")# den #ib#Fehlermeldung#ie#sreport und den Zustand
+ aller Netports liefert. Diese Task ist auch über Netz ansprechbar. In der Regel
+ sollte man #on("b")#listoption#off("b")# in der Datei #on("b")#netz#off("b")# aufrufen, es sei denn, das System ist sehr
+ klein.
+
+#page#
+
+1.6. #ib#Fehlersuche#ie# im Netz
+
+#goalpage("1.6")#
+
+#ib#Fehler#ie# im Netz können sich verschiedenartig auswirken. Im folgenden wird auf einige
+Beispiele eingegangen:
+
+Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung '#ib(4)#Station#ie(4, " x antwortet nicht")# 4 antwortet nicht'.
+
+
+#ib#Fehler#ie#möglichkeiten:
+
+ - #ib#Station#ie# 4 ist nicht eingeschaltet.
+ Abhilfe: Station 4 einschalten. Kommando erneut geben.
+
+
+ - #ib#Netztask#ie# an Station 4 ist nicht arbeitsfähig.
+ Abhilfe: Kommando #on("bold")##ib#start#ie##off ("bold")# in der Task "net" auf Station 4.
+
+
+ - Stationsnummern und Boxnummern stimmen nicht überein.
+ Abhilfe: Mit #on("bold")#define station#off ("bold")# #ib#Stationsnummer#ie#n korrigieren (siehe 3.2).
+
+
+ - #ib#Verbindung#ie# Rechner/Box am eigenen Rechner oder an Station 4 fehlt.
+ Abhilfe: Verbindungen überprüfen. Durch Ansprechen einer dritten Station
+ kann oft schnell geklärt werden, welche Rechner/Box-Verbindung
+ defekt sein muß.
+
+
+ - Verbindung der Boxen untereinander defekt.
+ Abhilfe: Fehlende Verbindung, #ib#Masseschluß#ie# und #ib#Dreher#ie# (keine 1:1 Verbin­
+ dung) überprüfen und beheben.
+
+ Hinweis: Liegt z.B. ein Masseschluß vor, so kann es durchaus sein, daß
+ Boxen, die nicht in der Nähe des Masseschlusses stehen, noch
+ miteinander arbeiten können. Man kann aus der Tatsache, daß zwei
+ Boxen miteinander arbeiten können, also nicht schließen, daß man
+ nicht nach diesem Fehler suchen muß.
+
+
+
+Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt keine Reaktion.
+
+
+ - Station 4 ist während dieser Sendung zusammengebrochen.
+ Abhilfe: Station 4 wieder starten. Die Bearbeitung des #on("bold")##ib#list#ie##off ("bold")#-Kommandos wird
+ automatisch wieder aufgenommen.
+
+
+ - PUBLIC auf Station 4 ist nicht im Managerzustand.
+ Abhilfe: PUBLIC in den Managerzustand versetzen.
+
+
+ - #ib#Fehler#ie# in der #ib#Netzhardware#ie#.
+ Überprüfen Sie, ob
+
+ - die Boxen eingeschaltet sind,
+ - die Bereitlampe blinkt (wenn nicht: #ib#RESET#ie# an der Box),
+ - die #ib#V.24#ie#-Kabel richtig stecken,
+ - die Boxen untereinander verbunden sind (1 zu 1 Verbindungen der 5 poli­
+ gen Diodenbuchsen).
+
+
+ - Fehler bei der #ib#Netzinstallation#ie#.
+ Überprüfen Sie, ob
+
+ - alle Stationen an einem #ib#Strang#ie# gleiche oder kompatible Netzmodi einge­
+ stellt haben [4],
+ - alle Stationen an einem #ib#Netzstrang#ie# auf die gleiche #ib#Nutzdatenlänge#ie# einge­
+ stellt sind,
+ - bei der #ib#Kommunikation#ie# über #ib#Knoten#ie# alle Stationen die gleiche Nutzdaten­
+ länge bei indirekten Sendungen eingestellt haben,
+ - die #ib#Route#ie#n auf allen beteiligten Stationen korrekt eingestellt sind.
+
+
+
+Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung '#ib(4)##ib#Collectortask#ie# fehlt#ie(4)#'.
+
+ - Das Kommando #on("b")##ib#start#ie##off("b")# (bzw #on("b")##ib#aktiviere netz#ie##off("b")# in der #ib#Datei#ie# #on("b")#netz#off("b")#) wurde nicht gege­
+ ben. Somit existiert #on("b")##ib#net port#ie##off("b")# nicht.
+ Abhilfe: Kommando #on("bold")#start#off ("bold")# in der Task #on("b")#net#off("b")# geben.
+
+
+ - Die #ib#Netzsoftware#ie# ist auf einen nicht vorhergesehenen #ib#Fehler#ie# gelaufen. Dieser
+ wird im #ib#Report#ie# vermerkt. #on("b")##ib#net port#ie##off("b")# wird dabei gelöscht.
+ Abhilfe: Geben Sie in der Task #on("bold")#net#off("bold")# das Kommando #on("bold")#start#off("bold")#. Dadurch wird die
+ Netzsoftware neu gestartet. Alle Netzkommunikationen dieser Station
+ gehen verloren.
+
+
+
+Beispiel:
+
+ Nach #on("bold")##ib#fetch#ie# ("hugo",4/public)#off("bold")# sind Teile der Datei "hugo" verfälscht.
+
+ - Die #ib#V.24#ie#-#ib#Verbindung#ie# zur Box ist nicht in Ordnung.
+ Abhilfe: Abstand zwischen Rechner und Box verkürzen; #ib#Baud#ie#rate ernie­
+ drigen; durch Wechseln der #ib#V.24#ie#-#ib#Schnittstelle#ie# feststellen, ob diese
+ defekt ist.
+ Hinweis: Die Verbindung zwischen den Boxen ist durch #ib#Prüfsummen#ie# abge­
+ sichert (Hardware).
+
+#page#
+
+1.7. Sicherheit im Netz
+
+#goalpage("1.7")#
+
+Bei Benutzung eines Rechnernetzes tauchen neue #ib#Sicherheitsprobleme#ie# auf. Um sie
+verstehen und eingrenzen zu können, muß man sich mit dem #ib#Sicherheitskonzept#ie# des
+Betriebssystems EUMEL vertraut machen:
+
+Eine Task im EUMEL kann nur manipuliert werden, wenn man sie entweder an ein
+Terminal koppelt oder ihr Sendungen zustellt.
+
+Das Ankoppeln kann über #ib#Paßwort#ie# abgesichert werden. Nach dem Ankoppeln kann
+die Task außerdem selbst bestimmen, wie sie die dann möglichen Eingaben behan­
+delt. So kann z.B. noch ein komplizierter Paßalgorithmus zu durchlaufen sein, bis
+man auf einer offenen Programmierumgebung landet.
+
+Sendungen können eine Task auch nur mit ihrem Einverständnis beeinflussen, da
+eine Sendung nur zugestellt wird, wenn die Task in der Prozedur #on("b")##ib#wait#ie##off("b")# steht. Insbe­
+sondere kann die Task den Absender einer Sendung überprüfen und gewisse Opera­
+tionen nur bei gewissen Absendern zulassen. So lehnt ein #on("b")##ib#global manager#ie##off("b")# z.B. alle
+Dateimanagerkommandos ab, die nicht von Nachkommen (z.B. Söhnen) der Task
+kommt. #on("b")##ib#free global manager#ie##off("b")# hingegen läßt Operationen wie #on("b")##ib#save#ie##off("b")# oder #on("b")##ib#erase#ie##off("b")# von
+beliebigen Tasks, auch von fremden #ib#Station#ie#en, zu. Will man nur bestimmte Fremd­
+stationen zulassen, kann man z.B. folgendes Schema verwenden:
+
+ PROC my #ib#manager#ie#
+ (DATASPACE VAR ds, INT CONST code, phase, TASK CONST source):
+
+ IF station (source) = station (myself) OR station (source) = 10
+ THEN
+ free manager (ds, code, phase, source)
+ ELSE
+ errorstop ("kein Zugriff")
+ FI
+
+ END PROC my manager;
+
+ global manager (PROC my manager)
+#page#
+Hier werden nur #on("b")#save#off("b")# usw. von Tasks der eigenen Station und der Station 10 zuge­
+lassen. Der Rest erhält die #ib#Fehlermeldung#ie# "kein Zugriff".
+
+Dieses Verfahren gewährt nur dann Sicherheit, wenn es nicht möglich ist, daß eine
+beliebige Station sich als Station 10 ausgibt.
+
+Damit das Netz diese Sicherheit garantieren kann, müssen natürlich gewisse phy­
+sische Voraussetzungen erfüllt sein. Wenn z.B. die Station 10 über eine #ib#V.24#ie# ange­
+schlossen ist, aber jeder die Möglichkeit hat, an diese #ib#Schnittstelle#ie# seinen eigenen
+Rechner anzuschliessen, dann kann das Netz natürlich nicht erkennen, ob es mit der
+echten Station 10 verkehrt.
+
+Es muß also sichergestellt sein, daß an Kanälen für das Netz nicht manipuliert werden
+kann. Bei einem #ib#Strang#ie# (Anschluß über #ib#Netzbox#ie#en) heißt das für die Boxen, daß sie
+nur #ib#Telegramm#ie#e weitervermitteln, die die eingestellte #ib#Quellstationsnummer#ie# enthalten.
+Sonst könnte jemand, der an denselben Strang wie #ib#Station#ie# 10 angeschlossen ist,
+#ib#Telegramm#ie#e erzeugen, die so aussehen, als kämen sie von 10.
+
+Die #ib#Netzsoftware#ie# ihrerseits darf nur Telegramme auswerten, die über die richtige
+#ib#Route#ie# (#ib#Kanal#ie# und #ib#Knotenstation#ie#) einlaufen.
+
+Leider hat dies die unangenehme Konsequenz, daß man automatisches Aufbauen und
+Ändern von Routen verbieten muß, wodurch die Wartung der #ib#Netzkonfiguration#ie#
+erschwert wird.
+
+Diese Version der #ib#Netzsoftware#ie# bietet den folgenden Kompromiß an: Nur für sicher­
+heitsrelevante #ib#Stationen#ie(1,", sicherheitsrelevante")# (im Beispiel Station 10) muß in der #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# die Route
+angegeben werden. Dies muß in allen Stationen geschehen, für die die Station
+sicherheitsrelevant ist, und in allen #ib#Knoten#ie# dazwischen.
+
+Für nicht sicherheitsrelevante Stationen werden #ib#Routeninformationen#ie# automatisch
+aufgebaut und geändert.
+
+Hinweis:
+Man wird oft ohne sicherheitsrelevante Stationen auskommen, indem man auf Ebenen
+oberhalb der Netzebene Paßwortkontrollen einführt. So ist es z.B. ja möglich, Dateien
+durch Paßworte zu schützen. Ein weiteres Beispiel ist ein #ib#Printerserver#ie#, der nur
+ausdruckt, wenn eine mitgegebene Abrechnungskennung stimmt. Dabei ist es sogar
+wünschenswert, daß die #ib#Station#ie# irrelevant ist, die den Druckauftrag gibt.
+#pagenr ("%",21)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Teil 2 : Arbeitsweise der Netzsoftware
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#page#
+
+Teil 2: Arbeitsweise der Netzsoftware
+#goalpage("2")#
+
+
+
+2.1. Die Netztask
+#goalpage("2.1")#
+
+
+In diesem Kapitel wird beschrieben, wie eine #ib#Netztask#ie# in das System eingebettet ist
+und welche Aufgaben sie hat. Unter Einhaltung dieser Konzepte kann die ausgeliefer­
+te Netzsoftware so geändert werden, daß sie beliebige andere #ib#Netzhardware#ie# unter­
+stützt. Die Netzsoftware ist so gegliedert, daß i.allg. nur eine hardwareabhängige
+Komponente ausgetauscht werden muß (siehe Teil 3).
+
+Die Kommunikation zwischen Tasks im EUMEL-Betriebssystem basiert auf einem
+#ib#Rendezvouskonzept#ie#: Die #ib#Zieltask#ie# einer Sendung muß empfangsbereit sein, wenn die
+#ib#Quelltask#ie# sendet.
+
+Die Kommunikationsprozeduren auf der niedrigsten Ebene sind #on("bold")##ib#send#ie##off ("bold")# (Senden) und
+#on("bold")##ib#wait#ie##off ("bold")# (Warten auf Empfang). Bei der Kommunikation werden ein Integer #on("bold")#code#off ("bold")# und ein
+#ib#Datenraum#ie# #on("bold")#dr#off ("bold")# übergeben. #on("bold")#code#off ("bold")# muß >= 0 sein, da negative Codes systemintern ver­
+wandt werden. Ist die empfangende Task an einen #ib#Kanal#ie# gekoppelt (#on("bold")##ib#continue#ie##off ("bold")#), so
+führt eine Zeicheneingabe auf diesem Kanal dazu, daß eine Sendung mit dem Code
+-4 ankommt. Die Eingabedaten müssen mit den üblichen #ib#Eingabeprozeduren#ie# (#on("bold")##ib#inchar#ie##off ("bold")#
+usw.) abgeholt werden. Der übermittelte #ib#Datenraum#ie# und die Absendertask sind dabei
+ohne Bedeutung und dürfen nicht interpretiert werden.
+
+Die Prozedur #on("bold")#send#off ("bold")# hat einen #ib#Rückmeldeparameter#ie#, der besagt, ob die Sendung
+übermittelt wurde. Gibt es die Zieltask nicht oder steht sie nicht im #on("bold")#wait#off ("bold")#, so kann die
+Sendung nicht übermittelt werden.
+
+Ein Entwicklungskriterium für das EUMEL-Netz war es, möglichst wenig Unterstüt­
+zung von der virtuellen EUMEL-Maschine (#ib#EUMEL0#ie#) zu fordern, damit weitgehend in
+ELAN programmiert werden kann. Dadurch ist es möglich, eine (privilegierte) Task mit
+der Netzabwicklung zu betrauen.
+#page#
+Zunächst wird auf die #ib#EUMEL0#ie#-Unterstützung eingegangen:
+
+a) Es gibt die Prozedur #on("bold")##ib#define collector#ie##off ("bold")#, mit der die für das Netz verantwortliche
+ Task der EUMEL0-Maschine bekannt gemacht wird. Diese Task wird im fol­
+ genden #ib#Collector#ie# genannt.
+
+b) Es gibt die Prozedur #on("bold")##ib#define station#ie##off ("bold")#, die für den Rechner eine #ib#Stationsnummer#ie#
+ einstellt. Anhand dieser Nummer werden die Rechner eines Netzes unterschie­
+ den. Das Einstellen bewirkt, daß für alle Tasks die Stationsnummer in ihre
+ #ib#Task-Id#ie# eingetragen wird (Task-Id's sind die Werte, die der Typ TASK anneh­
+ men kann).
+
+c) Der Befehl #on("bold")##ib#station#ie# (task)#off ("bold")# liefert die Stationsnummer der #on("bold")#task#off ("bold")#. So liefert z.B.
+ #on("bold")##ib#station#ie# (myself)#off ("bold")# die #ib#Stationsnummer#ie# des eigenen Rechners.
+
+d) Eine Sendung, deren #ib#Zieltask#ie# auf einem anderen Rechner liegt (also station (ziel)
+ <> station (myself)), wird auf die #ib#Collectortask#ie# geleitet.
+
+e) Es gibt eine Prozedur #on("bold")##ib#collected destination#ie##off ("bold")#, die es dem Collector erlaubt, die
+ eigentliche Zieltask einer auf ihn geleiteten Sendung zu erfahren.
+
+f) Es gibt eine Variante der Prozedur #on("bold")##ib#send#ie##off ("bold")#, die es dem Collector gestattet, der
+ #ib#Zieltask#ie# eine andere Task als Absender vorzutäuschen.
+
+g) Es gibt eine spezielle #ib#Task-Id#ie# #on("bold")##ib#collector#ie##off ("bold")#, durch die der augenblicklich eingestell­
+ te #ib#Collector#ie# erreicht wird. Diese wird als Zieltask beim Aufruf der Vermittlungs­
+ dienste angegeben (siehe S. #topage("collector")#). Eine Sendung an #on("bold")#collector#off ("bold")# wird von EUMEL0
+ an den derzeitig eingestellten Collector geschickt.
+
+Ein Collector kann also auf drei Wegen von den übrigen Tasks desselben Rechners
+Sendungen erhalten:
+
+ 1. Über ein normales #on("b")#send#off("b")# (z.B. bei #on("bold")#list (/"net port")#off ("bold")#, wenn #on("b")#net port#off("b")# der derzeitige
+ #ib#Collector#ie# ist),
+
+ 2. über ein #on("b")#send#off("b")# an die Task #on("bold")#collector#off ("bold")# (s.u.) und
+
+ 3. als umgeleitete Sendung (z.B. bei #on("bold")#list#off ("bold")# an eine Task auf einem anderen
+ Rechner).
+
+Der Collector kann diese Fälle anhand von #on("bold")#collected destination#off ("bold")# unterscheiden.
+
+Die Punkte d) bis f) dienen dazu, den Collector für über Netz kommunizierende Tasks
+unsichtbar zu machen: Der Collector taucht nicht als Ziel oder #ib#Quelle#ie# von Sendungen
+auf. Das ist notwendig, damit normale Tasks sich nicht darum kümmern müssen, ob
+eine Sendung übers Netz geht oder im eigenen Rechner bleibt.
+
+Wenn ein #ib#Datenraum#ie# an einen anderen Rechner geschickt wird, muß der gesamte
+Inhalt (z. Zt. max. 1 MB) übertragen werden. Dies macht bei der üblichen Netzhard­
+ware eine Zerlegung in #ib#Paket#ie#e nötig [5]. Bei der Zerlegung eines Datenraumes in
+Pakete (#ib#Telegramm#ie#e) gelten folgende Einschränkungen:
+
+ - Ein Paket kann maximal eine #ib#Datenraumseite#ie# als #ib#Nutzdaten#ie# enthalten.
+
+ - Die #ib#Nutzdatenlänge#ie# ist für einen #ib#Übertragungsweg#ie# konstant.
+
+ - Alle Stationen eines #ib#Netzstrang#ie#s senden mit gleicher Nutzdatenlänge (#on("b")##ib#data
+ length#ie##off("b")#).
+
+ - Bei indirekter #ib#Kommunikation#ie(1,"indirekte")# (über #ib#Knoten#ie#) muß die Nutzdatenlänge für in­
+ direkte Verbindungen (#on("b")##ib#data length via node#ie##off("b")#) auf allen beteiligten Stationen
+ gleich eingestellt sein.
+
+
+Für Netze stehen spezielle Blockbefehle zur Verfügung:
+
+
+g) #ib#blockin#ie# / #ib#blockout#ie# (dr,seite,512+abstand,anzahl,rest)
+
+ Es werden maximal #on("bold")#anzahl#off ("bold")# Bytes transferiert. In #on("bold")#rest#off ("bold")# wird zurückgemeldet, wie
+ viele Bytes nicht bearbeitet wurden (z.B. weil der #ib#Kanal#ie# nichts anliefert). Bear­
+ beitet werden die Bytes
+
+ #on("bold")#seite#off ("bold")# * 512 + #on("bold")#abstand#off ("bold")#
+
+ bis maximal
+
+ #on("bold")#seite#off ("bold")# * 512 + #on("bold")#abstand#off ("bold")# + #on("bold")#anzahl#off ("bold")# - 1
+
+ Der Kanal, an den die Task gekoppelt ist, wird dabei über #ib#Stream-IO#ie# (d.h.
+ #on("bold")##ib#incharety#ie##off ("bold")#, bei #on("bold")#blockin#off ("bold")# bzw. #on("bold")#out#off ("bold")# bei #on("bold")#blockout#off ("bold")#) angesprochen.
+
+ Hinweis: Die Anforderung darf nicht über #ib#Seitengrenze#ie# gehen, d.h.
+
+ #on("bold")#abstand#off ("bold")# + #on("bold")#anzahl#off ("bold")# <= 512
+
+ muß erfüllt sein.
+
+
+Eine Netzsendung läuft wie folgt ab:
+
+Die Task q auf Rechner rq mache ein #on("bold")##ib#send#ie##off ("bold")# an die Task z auf Rechner rz.
+
+1. Die Prozedur #on("bold")#send#off ("bold")# ist ein #ib#EUMEL0#ie#-Befehl. Die EUMEL0-Ebene erkennt, daß die
+ Sendung an die #ib#Station#ie# rz geht, da die #ib#Stationsnummer#ie# in der #ib#Task-Id#ie# enthalten
+ ist. Daher wird die Sendung zum #ib#Collector#ie# umgeleitet, den EUMEL0 wegen der
+ Einstellung durch #on("bold")##ib#define collector#ie##off ("bold")# kennt, umgeleitet.
+
+2. Die Task Collector empfängt über #on("bold")##ib#wait#ie##off ("bold")# den #ib#Datenraum#ie#, den #ib#Sendecode#ie# und die
+ Absendertask q. Die #ib#Zieltask#ie# z erfährt sie durch #on("bold")##ib#collected destination#ie##off ("bold")#.
+
+3. Der Collector nimmt Kontakt mit dem Collector des Rechners #on("b")#rz#off("b")# auf, dessen Sta­
+ tionsnummer ja #on("bold")##ib#station#ie#(z)#off ("bold")# ist, und übermittelt diesem Sendecode, #ib#Quelltask#ie# (q),
+ eigentliche Zieltask (z) und den #ib#Datenraum#ie#. Da die Collectoren in ELAN geschrie­
+ ben sind, können sie an beliebige #ib#Netzhardware#ie# und #ib#Protokoll#ie#e angepaßt werden.
+
+4. Der #ib#Collector#ie# auf Rechner #on("b")#rz#off("b")# verwendet das spezielle #on("bold")#send#off ("bold")#, um der Zieltask die
+ Sendung zuzustellen. Dadurch erscheint nicht der Collector, sondern die Task #on("b")#q#off("b")#
+ als Absender der Sendung.
+
+Zur Abwicklung der #ib#Vermittlungsebene#ie# (siehe S. #topage("vermittlung")#) muß der Collector noch spe­
+zielle Funktionen beherrschen. Diese sind
+
+ der #on("b")##ib#/#ie#-Operator#off("b")# (Taskname in #ib#Task-Id#ie# wandeln) und
+ die #on("b")##ib#name#ie##off("b")#-Prozedur (Task-Id in Namen wandeln).
+
+Der #on("b")#/#off("b")#-Operator macht eine Sendung an den #on("bold")##ib#collector#ie##off ("bold")#, wobei im #ib#Datenraum#ie# der Name
+der Task steht und der #ib#Sendecode#ie# gleich der Stationsnummer ist (siehe [6] ). Der
+#ib#Collector#ie# setzt sich mit dem Collector dieser Station in Verbindung, damit dieser die
+Task-Id ermittelt und zurückschickt. Der eigene Collector schickt dann dem #on("b")#/#off("b")#-Oper­
+ator als Antwort einen Datenraum, der die #ib#Task-Id#ie# enthält.
+
+Umgekehrt läuft #on("bold")##ib#name#ie##off ("bold")# ab: Wenn die Task-Id von einer fremden Station ist, schickt
+#on("bold")#name#off ("bold")# eine Sendung an den #on("bold")##ib#collector#ie##off ("bold")#, wobei im Datenraum die Task-Id steht und
+Sendecode = 256 ist. Der Collector entnimmt die #ib#Stationsnummer#ie# der Task aus der
+Task-Id und läßt sich vom entsprechenden Collector den Tasknamen geben. Dieser
+wird der #on("bold")#name#off ("bold")#-Prozedur im Antwortdatenraum übergeben.
+
+Netztasks bauen sich #ib#Routentabellen#ie# auf (#ib#Datei#ie#name #on("b")##ib#port intern#ie##off("b")#). Aufgrund dieser
+Tabellen weiß jede #ib#Netztask#ie#, über welchen #ib#Kanal#ie# und welche #ib#Nachbarstation#ie# eine
+#ib#Zielstation#ie# erreichbar ist. Wenn der #ib#Collector#ie# einen Sendeauftrag erhält, prüft er, ob
+die Zielstation über seinen Kanal erreichbar ist. Wenn nicht, leitet er Parameter und
+#ib#Datenraum#ie# der Sendung an die geeignete Netztask weiter.
+#page#
+
+2.2. Ebenen
+
+#goalpage("2.2")#
+
+In diesem Kapitel werden die #ib#Protokollebenen#ie# für das Netz beschrieben, wie sie die
+ausgelieferte Netzsoftware benutzt und erwartet. Bei anderer Netzhardware als Daten­
+boxen müssen die Ebenen a) bis c) ausgetauscht werden [4]. Unter Einhaltung der im
+vorigen Kapitel beschriebenen Randbedingungen können auch die höheren Ebenen
+geändert werden.
+
+
+a) Physikalische Ebene
+
+ - #ib#Station#ie# <--> Box
+
+ #ib#V.24#ie#-#ib#Schnittstelle#ie# mit #ib#RTS/CTS#ie#-Handshake. Vollduplex.
+
+ - Box <--> Box
+
+ #ib#RS422#ie# über 2 verdrillte Leitungspaare (Takt und Daten).
+
+
+b) Verbindungsebene
+
+ - Station <--> Box
+
+ Asynchron
+ 8 Bit
+ Even Parity
+ 2400/4800/9600/19200 #ib#Baud#ie# einstellbar über Lötbrücken)
+
+ - Box <--> Box
+
+ #ib#SDLC#ie#
+ 400 KBaud
+#page#
+c) #ib#Netzebene#ie#
+#goalpage("quelle")#
+
+ - Station <--> Box
+
+ #ib#Telegrammformat#ie#: #ib#STX#ie#, <n>, <ziel>, <#ib#quelle#ie#>, <(n-4) byte>
+
+ <n> ist #ib#Längenangabe#ie# ( 8 <= n <= 160)
+ <ziel>, <quelle> sind #ib#Stationsnummer#ie#n. Diese müssen an den jeweiligen
+ Boxen eingestellt sein.
+
+ Box --> Station:
+
+ Ein #ib#Telegramm#ie# kommt nur bei der #ib#Station#ie# an, bei deren Box die Nummer
+ <ziel> eingestellt ist. Dadurch ist ein Mithören fremder #ib#Übertragung#ie# nicht
+ möglich (Datenschutz).
+
+ Zwischen Telegrammen können #ib#Fehlermeldung#ie#en der Box (Klartext) übermittelt
+ werden (z.B. 'skipped x', wenn ein #ib#STX#ie# von der Box erwartet wurde, aber 'x'
+ von der Station ankommt).
+
+ Station --> Box:
+
+ Ein Telegramm wird nur abgeschickt, wenn <#ib#quelle#ie#> mit der eingestellten
+ Nummer übereinstimmt (Datenschutz: Man kann nicht vorschwindeln, eine
+ beliebige Station zu sein, es sei denn, man hat physischen Zugriff zur Box und
+ stellt dort die Stationsnummer um).
+
+ - Box <--> Box
+
+ #ib#Telegrammformat#ie#:
+ FRAME, <ziel>, <#ib#quelle#ie#>, <daten>, <CRC-Code>
+
+ Eine #ib#Längenangabe#ie# ist nicht nötig, da #ib#SDLC#ie# eine Rekonstruktion der Länge
+ erlaubt.
+
+ Telegramme mit falschen #ib#CRC-Code#ie# werden vernichtet. Auf höheren Ebenen
+ muß dies durch #ib#Zeitüberwachung#ie# erkannt und behandelt werden.
+
+#page#
+d) Transportebene
+
+ Diese Ebene wickelt das Rendezvous zwischen einer Task, die #on("bold")##ib#send#ie##off ("bold")# macht, und
+ einer Task, die im #on("bold")##ib#wait#ie##off ("bold")# steht, ab [1].
+
+ Der im #on("bold")#send#off ("bold")# angegebene #ib#Datenraum#ie# wird als Folge von #ib#Seiten#ie# (im EUMEL-
+ Sinne: Pagingeinheit und Allokiereinheit) übermittelt, wobei jede Seite ggf. noch in
+ n Byte große Stücke zerlegt wird. Es werden nur echt allokierte Seiten übermit­
+ telt. Um nicht jedes #ib#Telegramm#ie# voll qualifizieren zu müssen, wird zunächst eine
+ Art virtuelle #ib#Verbindung#ie# durch ein #ib#OPEN#ie#-Telegramm eröffnet. Danach folgen
+ variabel viele #ib#DATA#ie#-Telegramme. Beide Sorten werden durch #ib#QUIT#ie#-Tele­
+ gramme quittiert, um folgende Funktionen zu ermöglichen:
+
+ #ib#Flußkontrolle#ie# (z.B. Zielrechner langsam),
+ Wiederaufsetzen (verlorene Telegramme),
+ Abbruch (z.B. weil Zieltask inzwischen beendet).
+
+ Ein #ib#CLOSE#ie#-Telegramm ist nicht nötig, da das letzte DATA-Telegramm als
+ solches erkannt werden kann (siehe unten).
+#page#
+ - #ib#OPEN#ie#-Telegramm
+
+#clear pos#
+ 0 1 2 3 4 5 6 7 8 9. Byte
++------+------+------+------+-------------+-------------+-------------------+
+I STX I 24 I Ziel IQuelleI Endziel I Endquelle I Strom I
++------+------+------+------+-------------+-------------+-------------------+
+
+ 10 11 12 13 14 15 16 17
++-------------+-------------+---------------------------+
+I Sequenz I Seite I Quelltask I
++-------------+-------------+---------------------------+
+
+ 18 19 20 21 22 23
++---------------------------+-------------+
+I Zieltask I Code I
++---------------------------+-------------+
+
+
+
+ <#ib#ziel#ie#>, <#ib#quelle#ie#> siehe S. #topage("quelle")#
+
+ <#ib#endziel#ie#> Eigentliche #ib#Zielstation#ie#. Ist <ziel> = <endziel>, so ist
+ das #ib#Telegramm#ie# angekommen. Andernfalls muß die Station
+ <ziel> den #ib#Nachbarn#ie# zum Erreichen des <endziel> als
+ neues <ziel> einsetzen und das Telegramm an diesen
+ Nachbarn weiterleiten.
+
+ <#ib#endquelle#ie#> Eigentliche #ib#Absenderstation#ie#. <quelle> ist dagegen immer
+ die Nummer der sendenden #ib#Nachbarstation#ie#.
+
+ <#ib#strom#ie#> Die #ib#Stromnummer#ie# identifiziert die virtuelle #ib#Verbindung#ie#. Sie
+ muß in den #ib#QUIT#ie#-Telegrammen angegeben werden.
+
+ <#ib#sequenz#ie#> -1 (Kennzeichen für OPEN)
+
+ <#ib#seite#ie#> Nummer der ersten echt allokierten #ib#Seite#ie# des #ib#Datenraum#ie#s
+ (=-1, falls Nilspace)
+
+ <#ib#quelltask#ie#> #ib#Task-Id#ie# der sendenden Task
+
+ <#ib#zieltask#ie#> Task-Id der empfangenden Task
+
+ <code> Wert des im #on("bold")##ib#send#ie##off ("bold")# angegebenen Codes
+#page#
+ - #ib#DATA#ie#-Telegramm
+
+
+
+
+
+ 0 1 2 3 4 5 6 7 8 9. Byte
++------+------+------+------+-------------+-------------+-------------------+
+I STX I LängeI Ziel IQuelleI Endziel I Endquelle I Strom I
++------+------+------+------+-------------+-------------+-------------------+
+
+ 10 11 12 13 14
++-------------+-------------+-----------------------------------------------+
+I Sequenz I Seite I n Byte Daten (Länge = 14 + n) I
++-------------+-------------+-----------------------------------------------+
+
+
+ <#ib#laenge#ie#> Gesamtlänge des Telegramms.
+ #on("b")#laenge#off("b")# = #on("b")##ib#nutzlaenge#ie##off("b")# + 14.
+ Für #on("b")#nutzlaenge#off("b")# sind nur die Werte 64,128,256 und 512
+ zugelassen (siehe 1). #on("b")#laenge#off("b")# wird codiert dargestellt (siehe
+ Teil 3).
+
+
+ <#ib#sequenz#ie#> wird von Telegramm zu Telegramm hochgezählt. Sie dient
+ der Überwachung bzgl. verlorengegangener Telegramme
+ bzw. durch #ib#Zeitüberwachung#ie# verdoppelter Telegramme.
+
+ <#ib#seite#ie#> Nummer der x-ten echt allokierten Seite des #ib#Datenraum#ie#s
+ (x = ((<sequenz> DIV anzahl pakete pro seite) + 2)
+
+ <n byte> #ib#Nutzinformation#ie#. Diese gehört zur #ib#Adresse#ie# a des Daten­
+ raums.
+
+ a =
+ N (<sequenz> DIV anzahl pakete pro seite + 1) * 512
+ + (<sequenz> MOD anzahl pakete pro seite) * n
+
+ wobei N (x) die Nummer der x-ten Seite und
+ n die #ib#Nutzdatenlänge#ie# ist.
+
+ Aus den Formeln ergibt sich, daß diese Nummer schon in
+ einem vorhergehenden DATA/OPEN-Telegramm über­
+ mittelt wurde (im Feld <seite>).
+
+ - #ib#QUIT#ie#-Telegramm
+
+
+ 0 1 2 3 4 5 6 7 8 9. Byte
++------+------+------+------+-------------+-------------+-------------------+
+I STX I 12 I Ziel IQuelleI Endziel I Endquelle I Strom I
++------+------+------+------+-------------+-------------+-------------------+
+
+ 10 11
++-------------+
+I Quit I
++-------------+
+
+
+
+ <#ib#strom#ie#> muß die #ib#Stromnummer#ie# sein, die in dem #ib#OPEN#ie#/#ib#DATA#ie#­
+ Telegramm stand, das quittiert wird.
+
+ <quit> 0 : ok. Nächstes Telegramm schicken.
+
+ -1: #ib#Übertragung#ie# neu starten (mit #ib#OPEN#ie#), weil die Emp­
+ fangsstation das OPEN nicht erhalten hat.
+
+ -2: Übertragung ca. 20 Telegramme zurücksetzen.
+
+ -3: Übertragung abbrechen.
+
+ -4: #ib#Quittung#ie# für letztes Telegramm einer Sendung.
+
+
+e) #ib#Vermittlungsebene#ie##goalpage("vermittlung")# #goalpage("collector")#
+
+ Diese Ebene ist dafür zuständig, Namen von Tasks auf anderen Stationen in
+ #ib#Task-Id#ie#'s (Werte des Typs TASK) zu wandeln und umgekehrt. Hierzu wird im
+ entsprechenden #ib#OPEN#ie#-Telegramm der Code -6 (bzw. -7) als <code> ein­
+ getragen. Die #ib#Netzempfangstask#ie# erkennt diese #ib#Codes#ie# und wickelt die Aufgaben
+ selbst ab, so daß es dabei nicht nötig ist, irgendeine Task-Id der #ib#Zielstation#ie# zu
+ kennen.
+
+ Dieses Verfahren ist möglich, weil im #on("bold")##ib#send#ie##off ("bold")# nur positive Codes erlaubt sind.
+#page#
+f) #ib#Höhere Ebenen#ie#
+
+ Höhere Ebenen sind nicht mehr netzspezifisch. Sie basieren alle auf dem Send/
+ Wait-Konzept des EUMEL. So gibt es z.B. den #on("bold")##ib#global manager#ie##off ("bold")#, der Aufbewah­
+ rung und Zugriff von #ib#Datei#ie#en in einer Task regelt. Dabei darf diese Task (bei der
+ Variante #on("bold")##ib#free global manager#ie##off ("bold")#) auf einer beliebigen #ib#Station#ie# im Netz liegen. Wegen
+ des #ib#Rendezvous-Konzept#ie#s können beliebige Sicherheitsstrategien benutzt werden
+ (z.B.: keine Dateien an Station 11 ausliefern). Von großem Wert ist z.B., daß
+ man ohne weiteres das Archiv (Floppylaufwerk) einer anderen Station anmelden
+ und benutzen kann, wodurch eine einfache Konvertierung von Floppyformaten
+ möglich ist. Dies ist möglich, weil auch die Archiv-Task der Stationen sich an
+ das Globalmanagerprotokoll halten.
+
+
+
+
+
+Bemerkungen
+
+#ib#Fehlerbehandlung#ie# besteht bis Ebene c) darin, fehlerhafte #ib#Telegramm#ie#e einfach zu
+entfernen. Die Ebene d) überwacht den Netzverkehr sowieso über #ib#Timeout#ie#s, die eine
+Wiederholung eines Telegrammes bewirken, wenn die #ib#Quittung#ie# ausbleibt.
+
+Da bei der sendenden #ib#Station#ie# der ganze #ib#Datenraum#ie# zur Verfügung steht, ist eine
+#ib#Fenstertechnik#ie# (wie bei #ib#HDLC#ie#) nicht nötig. Es kann zu jedem Zeitpunkt um beliebig
+viele Telegramme zurückgesetzt werden.
+
+Da im EUMEL eine #ib#Textdatei#ie# ein #ib#Datenraum#ie# mit sehr komplexer Struktur ist (wegen
+der Insert/Delete-Möglichkeiten, ohne den Rest der #ib#Datei#ie# zu verschieben), ist es ein
+hoher Aufwand, von einem fremden Betriebssytem aus eine Textdatei in das
+EUMEL-Netz zu senden. Für solche Zwecke muß noch eine einfachere Dateistruktur
+definiert und entsprechende Dateikonverter erstellt werden.
+#page#
+
+2.3. Stand der Netzsoftware
+
+#goalpage("2.3")#
+
+Das EUMEL-System wickelt die Prozedur #on("bold")##ib#send#ie##off("bold")# über das Netz ab, wenn die Sta­
+tionsnummer der #ib#Zieltask#ie# ungleich der eigenen #ib#Stationsnummer#ie# ist. Umgekehrt kann
+man der von der Prozedur #on("bold")##ib#wait#ie##off("bold")# gelieferten Absendertask die #ib#Absenderstation#ie# entneh­
+men (siehe Prozedur #on("bold")##ib#station#ie##off("bold")# in Teil 1).
+
+Anders als bei einem #on("bold")##ib#send#ie##off("bold")# innerhalb einer Station meldet ein #on("bold")#send#off("bold")# an eine Task einer
+fremden Station immer 0 zurück (Task gibt es und Task war im wait), obwohl dies
+nicht der Fall sein muß. Ist die Sendung vollständig zur Zielstation übertragen, so
+versucht der dortige #ib#Collector#ie# diese hundertmal im Sekundenabstand zuzustellen.
+Bleibt das erfolglos, wird die Sendung vernichtet.
+#pagenr ("%", 33)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Teil 3 : Netz Hardware Interface
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#page#
+
+Teil 3: Netz-Hardware-Interface
+
+
+#goalpage("3")#
+
+
+3.1. Einführung
+
+ #goalpage("3.1")#
+
+In diesem Teil der Netzbeschreibung wird die #ib#Schnittstelle#ie# beschrieben, über die
+#ib#Netzhardware#ie# (also #ib#Datenbox#ie#en, #ib#Netzbox#ie#en oder Netzkarten) an die EUMEL-Netz­
+Software angepaßt werden kann. Dieser Teil der Beschreibung ist also nur für Netz­
+implementatoren wichtig.
+
+Das EUMEL-Netz wurde dazu konzipiert, zwei oder mehr EUMEL-Rechner über
+#ib#V.24#ie#-Leitungen oder Datenboxen miteinander zu vernetzen. Dem heutigen Stand der
+Technik entsprechend, werden auf dem Markt eine Reihe von Möglichkeiten ange­
+boten, um PC's zu vernetzen. Diese Netze unterscheiden sich auch dadurch, daß
+unterschiedliche Medien zur Datenübertragung benutzt werden. Das #ib#EUMEL-
+Datenboxen-Netz#ie# benutzt Telefonkabel, #ib#Ethernet#ie# beispielsweise Koax-Kabel. Auch
+Lichtleiter werden zur Datenübertragung benutzt. Entsprechend gibt es eine ganze
+Menge Hardware (#ib#Treiber#ie#, Netzzugangsgeräte, Datenboxen, Anschlußkarten), die die
+Kopplung zwischen einem #ib#I/O-Kanal#ie# eines Rechners und dem Übertragungsmedium
+(Kabel) übernimmt. Das Netz-Hardware-Interface soll als #ib#Schnittstelle#ie# zwischen der
+Netz­Software und dem Treiber dienen. Damit wird es möglich, mehrere EUMEL-
+Rechner über verschiedene (Teil-) Netze (in dieser Beschreibung Stränge genannt)
+und unterschiedliche #ib#Netzhardware#ie# (Treiber) miteinander zu verbinden. Für den
+EUMEL-Benutzer soll dabei kein Unterschied in der Benutzung des EUMEL-Netzes
+feststellbar sein.
+#page#
+Neben unterschliedlichen Übertragungsmedien und Treibern gibt es weitere Unter­
+schiede zwischen Netzen:
+
+ - in der Netztopologie (Bus-, Ring- oder Sternnetze),
+
+ - in den Netzzugangsverfahren (Token passing, time slice token, slotting oder
+ CSMA/CD),
+
+ - in der #ib#Übertragungsgeschwindigkeit#ie#,
+
+ - im Aufbau der einzelnen #ib#Pakete#ie(1,", Aufbau der")# (#ib#Netztelegramm#ie#e).
+
+Alles, was mit den ersten drei Punkten zusammenhängt, wird von den Netzzugangs­
+geräten behandelt.
+
+Der Paketaufbau aber muß zumeist im Rechner geschehen und kann in den seltens­
+ten Fällen ganz vom Treiber übernommen werden. Ebenso kann der Treiber aus den
+empfangenen Paketen nicht immer die Teile herausfiltern, die von der EUMEL-
+#ib#Netzsoftware#ie# gebraucht werden. Diese Aufgaben übernimmt das #ib#Netz-Hardware-
+Interface#ie#. Das Netz-Hardware-Interface stellt die #ib#Verbindung#ie# zwischen EUMEL-
+#ib#Netzsoftware#ie# und den verschiedenen Netzhardwarearten dar. Ähnlich wie bei den
+Drucker- und Terminal-Anpassungen wurde ein hardwareabhängiger Teil aus der
+Netzsoftware abgetrennt und in einem eigenen #ib#Paket#ie# zusammengefaßt. Beim Start
+des Netzes wird durch Angabe des entsprechenden #ib#Netzmodus#ie# für den jeweiligen
+#ib#Kanal#ie# die entsprechende Anpassung für den benutzten Treiber ausgewählt. Wenn
+andere, neue Treiber angepaßt werden sollen, so müssen lediglich in dem Paket #on("b")##ib#net
+hardware interface#ie##off("b")# die entsprechenden Prozeduren hinzugefügt und die #ib#Sprungleisten#ie#
+(#ib#SELECT#ie#-Statements) erweitert werden.
+
+Durch das #ib#Knotenkonzept#ie# in der #ib#Netzsoftware#ie# ist es möglich, über einen #ib#Knoten­
+rechner#ie# Teilnetze (Stränge), die mit unterschiedlicher #ib#Netzhardware#ie# arbeiten, mitein­
+ander zu verbinden. Es sind dann beispielsweise Verbindungen zwischen Rechnern,
+die über #ib#Ethernet#ie# vernetzt sind, und Rechnern auf dem EUMEL-Datenboxen-Netz
+möglich. Es ist auch möglich, mit einem Rechner Zugang zu einem Netz zu erhalten,
+für das spezielle #ib#Netzhardware#ie# erforderlich ist (Datenboxen, Ethernet-Anschluß). Man
+kann den Rechner über eine Rechner-Rechner-Kopplung (#ib#V.24#ie#) mit einem Rechner
+verbinden, der bereits ans Netz angeschlossen ist, und so (allerdings auf Kosten der
+Leistung des #ib#Knotenrechner#ie#s) Netzhardware einsparen.
+#page#
+
+3.2. Arbeitsweise des
+ Netz-Hardware-Interfaces
+
+
+
+
+
+ #goalpage("3.2")#
+
+Grob vereinfacht kann man sich die Arbeitsweise der #ib#EUMEL-Netz-Software#ie# so vor­
+stellen:
+
+ reset box;
+ REP
+ IF zeichen da THEN lies telegramm ein
+ ELIF telegramm auszugeben THEN gib telegramm aus
+ FI
+ PER .
+
+(Es ist nur der Teil der Software beschrieben, der die Kanalbehandlung betrifft).
+
+
+Das Zusammenspiel zwischen EUMEL-Netz und Netz-Hardware-Interface ge­
+schieht auf folgende Weise:
+
+
+ #on("b")#reset box;#off("b")#
+ REP
+ IF zeichen da THEN #on("b")#next packet start#off("b")#;
+ lies telegramm ein
+ ELIF telegramm auszugeben THEN gib telegramm aus
+ FI
+ PER.
+
+ gib telegramm aus:
+ #on("b")#transmit header#off("b")#;
+ gib eumelnetztelegramm aus;
+ #on("b")#transmit trailer #off("b")#.
+
+Die fett gedruckten Programmteile werden im Netz-Hardware-Interface realisiert, die
+anderen Teile stecken in den darüberliegenden Teilen der EUMEL-Netz-Software.
+#page#
+Beim Senden eines #ib#Telegramm#ie#s wird von der #ib#Netzsoftware#ie# zuerst der #ib#Vorspann#ie# in
+einem #ib#Datenraum#ie# an das Hardware-Interface übergeben (#on("b")##ib#transmit header#ie##off("b")#). Im Hard­
+ware-Interface können aus dem Vorspann die entsprechenden Informationen (Tele­
+grammlänge, #ib#Zielstation#ie# usw.) entnommen werden. Dann wird von der Netzsoftware
+das Telegramm (inklusive Vorspann) per #on("b")##ib#blockout#ie##off("b")# übergeben. Danach wird #on("b")##ib#transmit
+trailer#ie##off("b")# aufgerufen, um dem Hardware-Interface das Ende des Telegramms zu mel­
+den. Beim Empfang ruft die Netzsoftware zuerst die #ib#I/O Control#ie# #ib#Telegrammfreigabe#ie#
+auf [7]. Danach wird das erste #ib#Zeichen#ie# des Telegramms angefordert (#on("b")##ib#next packet
+start#ie##off("b")#). Falls ein #ib#STX#ie# geliefert wurde, wird das Telegramm per #on("b")##ib#blockin#ie##off("b")# eingelesen. Falls
+#ib#Niltext#ie# zurückgeliefert wird, wird von der Netzsoftware #ib#Timeout#ie# angenommen. Alle
+anderen Zeichen werden so interpretiert, als ob Störungen aufgetreten wären. Die
+Netzsoftware übernimmt die #ib#Fehlerbehandlung#ie#. Dazu wird u. U. ein Leerlesen des
+Puffers vom Hardware-Interface verlangt (#on("b")##ib#flush buffers#ie##off("b")#).
+
+Bei der Einstellung der #ib#Nutzdatenlänge#ie# (#on("b")##ib#data length#ie##off("b")#) ist zu beachten, daß
+
+a) alle #ib#Station#ie#en, die an einem #ib#Strang#ie# hängen, auf die gleiche Nutzdatenlänge
+ eingestellt sein müssen.
+
+b) Wenn mehrere Stränge über #ib#Knoten#ie# miteinander verbunden sind, muß die Nutz­
+ länge für Sendungen über Knoten (#on("b")##ib#data length via node#ie##off("b")#) auf allen Stationen des
+ gesamten Netzes gleich eingestellt sein. Die Zusammenfassung oder Aufteilung
+ von #ib#Telegramm#ie#en in Knoten ist nicht möglich.
+
+c) Als mögliche Nutzdatenlänge sind folgende Werte erlaubt:
+
+ 64, 128, 256 und 512 Byte.
+
+ Größere Nutzdatenlängen sind zur Zeit nicht möglich.
+
+d) Je größer die #ib#Nutzdatenlänge#ie# ist, desto geringer ist der Overhead an #ib#Zeichen#ie#,
+ die auf den Rechnern verarbeitet werden müssen. Allerdings muß der Rechner
+ leistungsfähig genug sein, die ankommenden Blöcke schnell genung zu verarbei­
+ ten, und die Netztreiber müssen entsprechend große Puffer haben.
+
+
+Alle implementierten Netzanpassungen sollen in einem Netz-Hardware-Interface
+zusammengefaßt werden. Dies ist notwendig, um über #ib#Knotenrechner#ie# Netzstränge
+verbinden zu können, die mit unterschiedlicher #ib#Netzhardware#ie# arbeiten. So können
+zum Beispiel ein #ib#Strang#ie#, der mit Datenboxen aufgebaut ist, und ein #ib#Ethernet#ie#-#ib#Strang#ie#
+über einen Knotenrechner miteinander verkoppelt werden.
+#page#
+Aus diesem Grund wurden #on("b")#Netzmodi#off("b")# eingeführt. Man kann dadurch, daß die Netz­
+modi, genau wie die #ib#Kanal#ie#angaben, in der #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# niedergelegt sind, ohne Aus­
+tausch einer Softwarekomponente die Netzhardware wechseln. Es gibt auch die
+Möglichkeit, durch verschiedene Netzmodi unterschiedliche Treiber an ein und das­
+selbe Netz anzuschließen. Beispielsweise gibt es für einige Rechnertypen Steckkarten,
+mit denen der Rechner an das Ethernet angeschlossen werden kann. Man kann,
+wenn diese Karten angepaßt sind, den #ib#Ethernet#ie#-Zugang über verschiedene Netz­
+anschlußkarten realisieren.
+
+Das Netz-Hardware-Interface muß folgende Aufgaben übernehmen:
+
+ Bei der Ausgabe an den Treiber:
+
+ - Generieren und Ausgeben des #ib#Paket#ie#headers,
+ - Umsetzen von logischen Stationsadressen (#ib#Stationsnummer#ie#n) in phy­
+ sische #ib#Adresse#ie#n,
+ - Ausgeben der Daten (EUMEL-Netz-#ib#Telegramm#ie#e),
+ - Generieren und Ausgeben des Trailers und evtl. Auffüllen des Pakets mit
+ #ib#Füllzeichen#ie#, falls auf dem Netz eine Mindestlänge für Pakete gefordert
+ wird.
+
+ Bei der Eingabe vom Treiber:
+
+ - Weglesen von #ib#Füllzeichen#ie#,
+ - Prüfen der #ib#Adresse#ie#n,
+ - Weglesen von #ib#Paket#ie#teilen, die in der EUMEL-Netz-Software nicht
+ gebraucht werden.
+
+ Weiterhin können Funktionen wie
+
+ - Reset des Treibers,
+ - Prüfung, ob Stationsadresse und #ib#Adresse#ie# im Treiber übereinstimmen,
+ - Statistik und Service
+
+ durch das Netz-Hardware-Interface übernommen werden.
+
+Dazu wird ein Satz von Prozeduren über die #ib#DEFINES#ie#-#ib#Schnittstelle#ie# des Netz-
+Hardware-Interfaces zur Verfügung gestellt. Wenn neue Treiber oder Netzarten
+implementiert werden sollen, so muß an diesem Interface nichts geändert werden. Die
+herausgereichten Prozeduren realisieren #ib#Sprungleisten#ie# (#ib#SELECT#ie#-Statements), über
+die durch Erweiterung (#ib#CASE#ie#) die Prozeduren erreicht werden können, die den ent­
+sprechenden #ib#Netzmodus#ie# realisieren. Außerdem werden Informationsprozeduren für die
+darüberliegenden Programmteile zur Verfügung gestellt.
+#page#
+
+3.3. Netztreiber
+
+ #goalpage("3.3")#
+Unter #ib#Netztreiber#ie#n versteht man die Einheiten, die den Anschluß des Rechners an ein
+Netz realisieren. Das können #ib#Netzbox#ie#en sein, die mit dem Rechner über eine #ib#V.24#ie#-
+Leitung verbunden sind, aber auch Anschlußkarten, die direkt auf den Datenbus des
+Rechners gehen. Falls die #ib#Schnittstelle#ie# der Treiber-Hardware eine andere als die
+serielle #ib#V.24#ie# ist, muß in der Regel eine Anpassung für die Hardware im #ib#SHard#ie# vorge­
+nommen werden.
+
+Falls der Treiber über eine serielle #ib#V.24#ie#-#ib#Schnittstelle#ie# mit dem Rechner verbunden
+ist, wie das auch bei der direkten Kopplung oder dem Datenboxennetz der Fall ist,
+wird die hohe #ib#Übertragungsgeschwindigkeit#ie# auf dem eigentlichen Netz durch die
+relativ geringe Übertragungsgeschwindigkeit auf der #ib#V.24#ie#-#ib#Schnittstelle#ie# zwischen
+Rechner und Treiber (Box) gebremst. Über andere Schnittstellen im Rechner, wenn
+sie mit #ib#Stream I/O#ie# [7] betrieben werden, kann man dies vermeiden. Diese Schnitt­
+stellen müssen vom SHard bedient werden.
+
+Wenn in den Rechner integrierte Netztreiber (Netzanschlußkarten) benutzt werden
+sollen, so muß in der Regel die Behandlung dieser Netzanschlußkarte im SHard
+durchgeführt werden.
+
+Um effizient implementieren zu können, sollte darauf geachtet werden, daß möglichst
+wenig zusätzliche #ib#Zeichen#ie# von der #ib#Netzsoftware#ie# bzw. dem Netz-Hardware-Inter­
+face bearbeitet werden müssen. Das Auffüllen von Paketen auf eine Mindestlänge
+sollte möglichst vom Treiber gemacht werden, ebenso wie das Weglesen dieser
+Zeichen.
+
+Um einen sicheren und effektiven Netzbetrieb zu garantieren, sollten die Treiber
+folgende Eigenschaften haben:
+
+ - Die #ib#Stationsadresse#ie# ist im Treiber festgelegt, sie soll nicht ohne weiteres
+ verändert werden können (Datenschutz).
+ - Der Treiber reicht nur #ib#Paket#ie#e mit richtiger #ib#Zieladresse#ie#, keine #ib#Broad- oder
+ Multicasts#ie# an die Netzsoftware weiter.
+ - Der Treiber sendet nur #ib#Paket#ie#e mit richtiger #ib#Absenderadresse#ie# bzw. setzt die
+ Absenderadresse selbst ein.
+ - Die am Treiber eingestellte #ib#Adresse#ie# kann abgefragt werden, oder es wird,
+ wenn ein Paket mit falscher #ib#Absenderadresse#ie# vom Rechner kommt, eine
+ #ib#Fehlermeldung#ie# an den Rechner gegeben. Die Fehlermeldung muß durch das
+ Netz-Hardware-Interface in den #on("b")##ib#report#ie##off("b")# eingetragen werden.
+ - Falls Pakete mit #ib#Füllzeichen#ie# aufgefüllt werden müssen, sollten die Füll­
+ zeichen durch den Treiber generiert und beim Empfang wieder entfernt
+ werden.
+ - Falls mehrere Betriebsmodi möglich sind, so sollten sie softwaremäßig
+ einstellbar sein.
+ - Falls die Treiber über eine serielle #ib#Schnittstelle#ie# an den Rechner angeschlos­
+ sen werden, so sollte der Treiber konfigurierbar sein. In jedem Fall sollte die
+ serielle Schnittstelle mit #ib#Flußkontrolle#ie# (#ib#RTS/CTS#ie#) implementiert werden.
+
+Zusätzlich ist ein Transparent-Modus als #ib#Netzmodus#ie# von Vorteil:
+
+ - Der Modus (transparent) kann zu Testzwecken benutzt werden. Beispiels­
+ weise um auch mit Rechnern kommunizieren zu können, die über Netz
+ erreichbar sind, aber kein EUMEL-Netz-#ib#Protokoll#ie# benutzen.
+
+ Modus n: transparent.
+
+ Ausgabeseitig: Das #ib#Paket#ie# wird unverändert ausgegeben.
+ #ib#Adresse#ie#n usw. müssen schon im Paket vor­
+ handen sein. Es wird nicht mit #ib#Füllzeichen#ie#
+ aufgefüllt.
+ Eingabeseitig: Das Paket wird unverändert an die Netzsoft­
+ ware weitergegeben.
+
+#page#
+
+3.4. Prozedurschnittstelle
+ des EUMEL-Netzes
+
+
+
+
+
+ #goalpage("3.4")#
+Im PACKET #on("b")##ib#net hardware interface#ie##off("b")# sind folgende Prozeduren untergebracht:
+
+
+
+ BOOL PROC #ib#blockin#ie#
+ (DATASPACE VAR ds, INT CONST seite, abstand, länge):
+
+ Versucht, #on("b")#länge#off("b")# Zeichen vom #ib#Kanal#ie# einzulesen. Liefert TRUE, wenn alle
+ Zeichen eingelesen wurden, FALSE, wenn innerhalb einer bestimmten
+ Zeit nicht alle #on("b")#länge#off("b")# Zeichen eingelesen werden konnten (z.B. weil der
+ Kanal nicht mehr Zeichen anliefert). Die eingelesenen Zeichen werden im
+ #ib#Datenraum#ie# #on("b")#ds#off("b")# in #ib#Seite#ie# #on("b")#seite#off("b")# ab #on("b")#abstand#off("b")# bis #on("b")#abstand#off("b")# + #on("b")#länge#off("b")# - 1 abge­
+ legt.
+
+ #ib#Fehlerfall#ie#:
+
+ #on("b")#blockin Abbruch#off("b")#
+
+ Es werden weniger #ib#Zeichen#ie# innerhalb einer festgelegten Zeitspanne über
+ den Kanal angeliefert, als mit #on("b")#länge#off("b")# gefordert.
+
+ Passiert z.B., wenn die Kabel während einer Netzübertragung unter­
+ brochen werden, oder wenn die Gegenstelle abgeschaltet wird. Das
+ #ib#Telegramm#ie# wird vernichtet, die Prozedur liefert FALSE, es wird eine
+ entsprechende Meldung im #on("b")##ib#report#ie##off("b")# erzeugt.
+
+ PROC #ib#blockout#ie#
+ (DATASPACE CONST ds, INT CONST seite, abstand, länge):
+
+ Der Inhalt von Seite #on("b")#seite#off("b")# des #ib#Datenraum#ie#s #on("b")#ds#off("b")# wird von #on("b")#abstand#off("b")# bis
+ #on("b")#abstand#off("b")# + #on("b")#länge#off("b")# - 1 ausgegeben.
+#page#
+ PROC #ib#set net mode#ie# (INT CONST mode):
+
+ Es wird der #ib#Netzmodus#ie# #on("b")#mode#off("b")# eingestellt. Im Netz-Hardware-Interface
+ müssen alle Initialisierungen und Einstellungen vorgenommen werden,
+ damit die mit #on("b")#mode#off("b")# geforderte #ib#Netzhardware#ie# unterstützt wird. Diese
+ Prozedur wird bei jedem #on("b")##ib#start#ie##off("b")#-Kommando in der Netztask aufgerufen.
+ Kann als Initialisierungsprozedur für dieses PACKET verwendet werden.
+ Übergibt den in der #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# für diesen #ib#Kanal#ie# verlangten Netzmodus an
+ das Netz-Hardware-Interface. Nach Aufruf dieser Prozedur müssen die
+ wertliefernden Prozeduren #on("b")##ib#net mode#ie#, #ib#mode text#ie#, #ib#data length#ie##off("b")# und #on("b")##ib#data
+ length via node#ie##off("b")# korrekt initialisiert sein. Der Aufruf von #on("b")##ib#net addess#ie##off("b")# muß
+ die korrekten (physikalischen) #ib#Adresse#ie# der #ib#Station#ie#en liefern.
+
+ TEXT PROC net address (INT CONST stationsnummer):
+
+ Liefert die (Hardware-) Netz-#ib#Adresse#ie#, über die der EUMEL-Rechner
+ mit der Stationsnummer #on("b")##ib#stationsnummer#ie##off("b")# beim aktuell für diesen Kanal
+ eingestellten #ib#Netzmodus#ie# erreichbar ist. Auf diese #ib#Adresse#ie# muß der Treiber
+ des entsprechenden Rechners eingestellt sein. Auch die eigene Netz-
+ Adresse muß mit der im Treiber eingestellten #ib#Adresse#ie# übereinstimmen.
+ Insbesondere müssen alle Stationen, die auf dem Netz arbeiten, dieselbe
+ Netz-Adresse für eine #ib#Stationsnummer#ie# errechnen.
+
+ TEXT PROC #ib#mode text#ie#:
+
+ Liefert den Text (Namen) des eingestellten #ib#Netzmodus#ie#. Wird in #on("b")##ib#net
+ manager#ie##off("b")# benutzt, um den Netzmodus im #on("b")##ib#report#ie##off("b")# anzugeben.
+
+ TEXT PROC mode text (INT CONST mode):
+
+ Liefert den Text (Namen) zu dem #ib#Netzmodus#ie# #on("b")#mode#off("b")#.
+
+ INT PROC #ib#data length#ie# (INT CONST mode):
+
+ Liefert die #ib#Nutzdatenlänge#ie# (#ib#Länge#ie# der Nettodaten des Eumel-
+ Telegramms) im Netz. Wird von #on("b")##ib#basic net#ie##off("b")# beim Neustart aufgerufen. Muß
+ in einem Netz auf allen Stationen eines #ib#Strang#ie#s denselben Wert liefern.
+
+ Erlaubte Werte: 64, 128, 256 und 512.
+#page#
+ INT CONST #ib#data length via node#ie#:
+
+ Liefert die #ib#Nutzdatenlänge#ie# für Sendungen, die über #ib#Knoten#ie# gehen.
+ Muß auf allen Stationen des Netzes gleich sein.
+
+ Erlaubte Werte: 64, 128, 256 und 512.
+
+ PROC #ib#decode packet length#ie# (INT VAR value):
+
+ Die #ib#Länge#ie# eines Netztelegramms ist im #ib#Telegramm#ie# codiert enthalten. Mit
+ dieser Prozedur wird aus dem Telegrammkopf die Telegrammlänge ermit­
+ telt:
+
+ Falls beim Aufruf dieser Prozedur in #on("b")#value#off("b")# der Wert des Feldes #on("b")#head#off("b")# aus
+ der Struktur #on("b")#vorspann#off("b")#, die in #on("b")#ds#off("b")# per #on("b")##ib#transmit header#ie##off("b")# übergeben wurde,
+ enthalten ist, so wird in #on("b")#value#off("b")# die Länge des EUMEL-Netztelegramms
+ zurückgeliefert.
+
+ PROC #ib#flush buffers#ie#:
+
+ Liest den Eingabepuffer des #ib#Netzkanal#ie#s leer. Die eingelesenen Zeichen
+ werden vernichtet. Wird nach Erkennen von #ib#Übertragungsfehler#ie#n aufge­
+ rufen.
+
+ TEXT PROC #ib#next packet start#ie#:
+
+ Liefert genau ein #ib#Zeichen#ie# (in der Regel das erste Zeichen des EUMEL-
+ Netztelegramms). Wird von der Netzsoftware immer dann aufgerufen,
+ wenn ein neues #ib#Paket#ie# erwartet wird.
+
+ Bedeutung des gelieferten Zeichens für die #ib#Netzsoftware#ie#:
+
+ #ib#STX#ie#: korrekter #ib#Telegrammanfang#ie# (ist das erste Zeichen des
+ EUMEL-Netztelegramms). Der Rest des EUMEL-Netztele­
+ gramms steht im Eingabepuffer, ist also über #ib#blockin#ie# lesbar.
+ Vorher wurden nur Zeichen eingelesen, die zum verwendeten
+ #ib#Netzprotokoll#ie# gehören (z.B. #ib#Ethernet#ie#-#ib#Adresse#ie#n, #ib#Füllzeichen#ie#
+ usw.).
+ niltext: kein neues Telegramm da
+
+ jedes andere Zeichen:
+ Fehler. Entweder wurden Störzeichen eingelesen oder es
+ gingen Zeichen verloren. #ib#Fehlerbehandlung#ie# erfolgt durch die
+ Netzsoftware.
+#page#
+ PROC #ib#transmit header#ie# (DATASPACE CONST ds):
+
+ Wird vor Ausgabe eines jeden #ib#Telegramm#ie#s aufgerufen. In dem #ib#Datenraum#ie#
+ #on("b")#ds#off("b")# wird von der EUMEL-Netz-Software der #on("b")##ib#Vorspann#ie##off("b")# übergeben. Über
+ den jeweiligs eingestellten #ib#Netzmodus#ie# kann für jede implementierte Netz­
+ art über eine #ib#Sprungleiste#ie# (#ib#SELECT#ie#) die Prozedur angesprungen werden,
+ die den #ib#Header#ie# für den eingestellten Netzmodus erstellt und ausgibt.
+ Struktur des von der EUMEL-Netz-Software benutzten Headers:
+
+ BOUND STRUCT
+ (INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ sequenz,
+ seitennummer ) VAR vorspann.
+
+ Aus dem Inhalt des Feldes #on("b")#head#off("b")# kann mittels #on("b")##ib#decode packet length#ie##off("b")# die
+ Gesamtlänge des EUMEL-Netztelegramms errechnet werden.
+
+ PROC #ib#transmit trailer#ie#:
+
+ Wird nach Ausgabe eines jeden Telegramms aufgerufen. Evtl. notwendige
+ Nachspänne können ausgegeben werden. Die notwenigen Informationen
+ wurden in #on("b")##ib#transmit header#ie##off("b")# übergeben und müssen aufbewahrt werden,
+ falls sie im Trailer mitgeliefert werden müssen. Kann auch dazu benutzt
+ werden, den unter diesem Packet liegenden Schichten (#ib#SHard#ie# oder Hard­
+ ware) das Ende des Telegramms mitzuteilen. Notwendige #ib#Füllzeichen#ie#
+ können in dieser Prozedur in das #ib#Paket#ie# eingebaut werden.
+
+ PROC #ib#reset box#ie# (INT CONST net mode):
+
+ Kann zur Initialisierung der #ib#Netzhardware#ie# benutzt werden. Wird von #on("b")##ib#basic
+ net#ie##off("b")# beim jedem Neustart aufgerufen.
+
+ INT PROC #ib#max mode#ie#:
+
+ Liefert den Wert des größten erlaubten (implementierten) #ib#Netzmodus#ie#.
+
+ INT PROC #ib#net mode#ie#:
+
+ Liefert den eingestellten Netzmodus.
+#page#
+#pagenr ("%", 45)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Anhang
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#clear pos##lpos(1.0)##rpos(9.5)##goalpage("A")#
+
+Anhang: Netz-Meldungen#goalpage("A.1")#
+
+Mit dem Kommando #on("b")##ib#list#ie# (/"net list")#off("b")# (siehe Teil 1) erhalten Sie eine temporäre #ib#Datei#ie#
+auf den Bildschirm. Diese Datei könnte ungefähr so aussehen:
+
+____________________________________________________________________________
+
+ N e u e r S t a r t 12:44 Stationsnummer : 38
+ 01.06.87 12:55 net port 8:20:Nicht zustellbar. . Empfänger: "net dok". Quelle 34 Taskindex: 255
+ 02.06.87 06:30 net port 8:1:wdh data. sqnr 7. Absender: "net dok". Ziel 34 Taskindex: 255
+ 02.06.87 07:03 net port:20:Sequenzfehler: soll 13 ist 14. Empfänger: "POST". Quelle 33 Taskindex:
+ 02.06.87 07:03 net port:blockin abbruch
+ 02.06.87 07:03 net port:20:Sequenzreset von 13 auf 10. Empfänger: "POST". Quelle 33 Taskindex: 29
+ 02.06.87 07:36 net port:Call gelöscht."net dok". Strom 1
+ 02.06.87 07:43 net port 8:verbotene Route: 34
+ 02.06.87 07:50 net port:Header inkorret eingelesen: %0 %2
+ 02.06.87 07:50 net port:buffers flushed
+ 02.06.87 07:52 net port:Weiterleitung nicht möglich für 34
+ 02.06.87 07:53 net port 8:skipped0 6 G O 1 0 . 0 %13 %10 2 8 0 6 0 6 G O 1 0 . 0 %13 %10 2 8 0
+ 02.06.87 08:14 net port 8:skipped%13 %10 S p e c . R e c e i v e E r r o r C 2
+ 02.06.87 08:21 net port:20:Reopen. Empfänger: "WÜFE". Quelle 40 Taskindex: 22
+ 02.06.87 09:25 net port:1:etwas rueckgespult. Absender: "-". Ziel 33 Taskindex: 51
+ 02.06.87 09:25 net port:1:wdh data. sqnr 20. Absender: "-". Ziel 33 Taskindex: 51
+ 02.06.87 09:54 net port:20:Blocknummer falsch, neu: 192, alt : -1. Empfänger: "WÜFE". Quelle 44
+ 02.06.87 10:12 net port:Daten ohne Eroeffnung von 40 Sequenznr 7
+ 02.06.87 10:23 net port:Header inkorret eingelesen: O X 0 3 8 B O X 0 4 4 E U %2
+ 02.06.87 10:23 net port:buffers flushed
+ 02.06.87 10:49 net port:1:wdh open. Absender: "-". Ziel 33 Taskindex: 255
+ 02.06.87 10:49 net port:2:wdh open. Absender: "net dok". Ziel 33 Taskindex: 255
+ 02.06.87 10:53 net port:1:Sequenzfehler: soll 2 ist 3. Empfänger: "net dok". Quelle 33 Taskindex:
+ 02.06.87 10:54 net port:1:Sequenzreset von 8 auf 5. Empfänger: "net dok". Quelle 33 Taskindex: 11
+ 02.06.87 10:56 net port:2:etwas rueckgespult. Absender: "-". Ziel 33 Taskindex: 51
+ bekannte Stationen:
+ 1(8,1) 2(8,2) 3(8,3) 4(8,4) 5(8,5) 6(8,6) 7(8,7) 8(8,8) 9(8,9) 10(8,10)
+ 11(8,11) 12(8,12) 13(8,13) 14(8,14) 15(8,15) 16(8,16) 17(8,17) 18(8,18)
+ 19(8,19) 20(8,20) 21(8,21) 22(8,22) 23(8,23) 24(8,24) 25(8,25) 26(8,26)
+ 27(8,27) 28(8,28) 29(8,29) 30(8,30) 31(8,31) 32(8,32) 33(9,33) 34(8,34)
+ 35(9,35) 36(9,36) 37(9,37) 39(9,39) 40(9,40) 41(9,41) 42(9,42) 43(9,43)
+ 44(9,44) 45(9,45) 46(9,46) 47(9,47) 48(9,48)
+ --------
+ Eingestellte Netzmodi:
+ net port 8 haengt an Kanal 8, Modus: (1) EUMEL-Netz 64 Byte
+ net port haengt an Kanal 9, MODUS: (11) ETHERNET via V.24 512 Byte
+
+ Nutzdatenlänge 512 Byte
+ Nutzdatenlänge bei indirekter Verbindung: 64 Byte
+ ********
+ Netz-Software vom 23.05.87
+ Rechner 38 um 11:11
+ net port 8
+
+ Strom 1 (sqnr7/8) sendet an 34 . Absender ist "net dok".
+ net port
+
+ Strom 1 (sqnr45/45) empfaengt von 40 . Empfaenger ist "PUBLIC".
+
+____________________________________________________________________________
+#page#
+Die Datei enthält den aktuellen #on("b")##ib#report#ie##off("b")#, in dem #ib#Fehlermeldung#ie#en der einzelnen Tasks
+gesammelt werden. Außerdem wird der Zustand aller Verbindungen (Ströme) von allen
+#on("b")##ib#net port#ie##off("b")#'s angezeigt. Im #on("b")#report#off("b")#-Teil kann man drei Informationsblöcke unterscheiden:
+
+a) den Block mit den Fehlermeldungen. Es werden jeweils Datum, Uhrzeit, der Name
+ des betroffenen #on("b")#net port#off("b")# und, wenn notwendig, die #ib#Stromnummer#ie# angegeben.
+ Darauf folgt der Meldungstext, der auch Informationen über Absender und Emp­
+ fänger enthalten kann.
+
+ <Datum> <Zeit> <Name der #ib#Kanaltask#ie#> : [<#ib#Stromnummer#ie#> : ] <Meldung>
+
+
+b) den Block mit der Liste der bekannten #ib#Station#ie#en. Ein Eintrag in dieser Liste ent­
+ hält jeweils die Stationsnummer der bekannten Station und in Klammern dahin­
+ ter die Nummer des Kanals auf diesem Rechner, über den die Station erreichbar
+ ist und die Nummer der nächsten #ib#Zwischenstation#ie#.
+
+ <Zielstation> (<Kanalnr>,<Zwischenstation>)
+
+ Bei direkt erreichbaren Stationen ist Zwischenstation gleich #ib#Zielstation#ie#.
+
+ Hinweis: Auch #ib#gesperrt#ie#e Stationen erscheinen in dieser Liste.
+
+
+c) den Block, der Auskunft über die Netzinstallation gibt. Es werden für jeden Netz­
+ kanal die eingestellten Netzmodi angegeben. Des weiteren werden die beiden
+ Größen #on("b")##ib#data length#ie##off("b")# (#ib#Nutzdatenlänge#ie#) und #on("b")##ib#data length via node#ie##off("b")# (Nutzdatenlänge bei
+ indirekter Verbindung) angegeben. Zusätzlich erscheinen noch die #ib#Netzversion#ie# und
+ die genaue Uhrzeit, zu der dieser #on("b")#report#off("b")# erstellt wurde.
+
+#page#
+Für jeden #on("b")##ib#net port#ie##off("b")# wird pro aktivem #ib#Strom#ie# folgende Meldung generiert:
+
+Strom <Stromnr> (sqnr<akt Seqnr>/<max Seqnr>) <Zustand> <Partner>
+
+
+<Stromnr> #ib#Stromnummer#ie#
+
+<akt Seqnr> #ib#Sequenznummer#ie# des gerade bearbeiteten #ib#Telegramm#ie#s
+
+<max Seqnr> Bei #ib#Sendeströme#ie#n die Nummer der letzten zu übertragenden
+ #ib#Sequenz#ie#, bei Empfangsströmen in der Regel die Nummer der
+ letzten Sequenz der gerade übertragenen #ib#Datenraumseite#ie#.
+
+<#ib#Zustand#ie#> Hier wird die Aktion (senden, empfangen usw.) und die Partner­
+ station angegeben.
+
+<#ib#Partner#ie#> Der Name der Task mit der kommuniziert wird.
+
+
+Die Meldungen, die in der #ib#Datei#ie# #on("b")##ib#report#ie##off("b")# protokolliert werden, kann man in verschiedene
+Gruppen einordnen. Die eine Gruppe beschreibt Störungen durch #ib#Zeichenverluste#ie#
+oder ­verfälschungen, eine andere Gruppe protokolliert besondere Situationen, bei­
+spielsweise den Abbruch von #ib#Übertragung#ie#en, und die letzte Gruppe befasst sich mit
+#ib#Fehlermeldung#ie#en, die ein Eingreifen von aussen notwendig machen. Je nachdem, ob
+die Station, auf der die Meldung protokolliert wird, Empfänger oder Absender ist, wird
+bei den Meldungen #ib#Stationsnummer#ie# und Taskname des Kommunikationspartners mit
+angegeben.
+
+Zur ersten Gruppe gehören:
+
+#ib(4)##ib#skipped#ie##ie(4)#
+ 'skipped' oder skipped mit einem Zusatztext erscheint, wenn Zei­
+ chen eingelesen wurden, die zu keinem gültigen #ib#Telegramm#ie# ge­
+ hören. Dies kann passieren, wenn auf der Leitung zwischen
+ Rechner und Box #ib#Zeichen#ie# verlorengegangen sind. Auch nach dem
+ Einschalten oder nach einem Reset auf Box oder Rechner kann
+ diese Meldung kommen. Mindestens ein Teil der eingelesenen
+ Daten wird mit ausgegeben, wobei Steuerzeichen durch % und den
+ Code des Steuerzeichens dargestellt werden. Die einzelnen Zeichen
+ werden durch ein Blank voneinander getrennt.
+#page#
+#ib(4)##ib#Sequenzfehler#ie##ie(4)#
+ Die #ib#Sequenznummer#ie# ist zu groß, es fehlen also Telegramme. Die
+ Gegenstation wird aufgefordert, ab einem früheren Telegramm zu
+ wiederholen.
+
+#ib(4)#wdh data#ie(4)#
+ Das letzte Telegramm wird erneut geschickt. Passiert, wenn die
+ #ib#Quittung#ie# für dieses Telegramm nach einer bestimmten Zeit nicht
+ angekommen ist.
+
+#ib(4)##ib#Sequenzreset#ie##ie(4)#
+ Die #ib#Sequenznummer#ie# des empfangenen Telegramms ist kleiner als
+ die Sequenznummer des vorher empfangenen Telegramms. Die
+ Verbindung wird bei der zuletzt empfangenen Sequenznummer
+ fortgesetzt.
+
+#ib(4)#Blocknummer falsch#ie(4)#
+ Die #ib#Seitennummer#ie# in dem #ib#Telegramm#ie# ist falsch.
+
+#ib(4)#etwas rueckgespult#ie(4)#
+ Auf Anforderung der Gegenseite werden die letzten drei #ib#Datenraum­
+ seite#ie#n erneut übertragen.
+
+#ib(4)#Daten ohne Eroeffnung#ie(4)#
+ Es werden Telegramme mit einer #ib#Stromnummer#ie# empfangen, zu der
+ vorher kein OPEN-Telegramm empfangen wurde. In diesem Fall
+ wird die Gegenstation aufgefordert, die #ib#Übertragung#ie# von vorn zu
+ beginnen. Diese Meldung kann auch kommen, wenn das Netz neu
+ gestartet wurde.
+
+#ib(4)#wdh open#ie(4)#
+ Die Übertragung wird mit dem #ib#OPEN#ie#-Telegramm von vorn begon­
+ nen. Passiert auf Aufforderung durch die Gegenstation oder wenn
+ das erste OPEN-Telegramm nicht quittiert wurde.
+
+#ib(4)##ib#buffers flushed#ie##ie(4)#
+ Alle bereits eingelesenen, aber noch nicht bearbeiteten Zeichen
+ wurden gelöscht (der #ib#Eingabepuffer#ie# wurde komplett gelöscht). Verur­
+ sacht durch schwere Störungen (#ib#Zeichenverluste#ie# oder -verfäl­
+ schungen).
+#page#
+#ib(4)#blockin abbruch#ie(4)#
+ Es wurden nicht alle Zeichen eines Telegramms innerhalb eines
+ bestimmten Zeitraums angeliefert.
+
+#ib(4)#Header inkorrekt eingelesen#ie(4)#
+ Es wurde ein Fehler in dem Teil des Netztelegramms gefunden, der
+ nicht zum EUMEL-Netz gehört.
+
+#ib(4)#Strom falsch in Quittung#ie(4)#:
+ In der #ib#Quittung#ie# wurde eine nicht zulässige #ib#Stromnummer#ie# festge­
+ stellt. Zulässig sind Stromnummern zwischen 1 und 20.
+
+#ib(4)#Neustart#ie(4)#
+ Die Gegenstation hat die #ib#Verbindung#ie# von vorne begonnen.
+
+#ib(4)#Falsche Seitennummer#ie(4)#
+ Die #ib#Seitennummer#ie# in dem empfangenen Telegramm ist falsch.
+ Einige Telegramme werden wiederholt.
+
+#ib(4)#Absteigende Seitennummern#ie(4)#
+ Die Seitennummer in dem empfangenen Telegramm ist kleiner als
+ die Seitennummer im vorigen #ib#Telegramm#ie#. Es müssen einige Tele­
+ gramme wiederholt werden.
+
+
+Die folgenden Meldungen beschreiben Situationen, die nicht durch #ib#Zeichenverluste#ie#
+entstehen, mit denen die #ib#Netzsoftware#ie# selbst fertig wird:
+
+
+#ib(4)#Sendung von Gegenstelle gelöscht#ie(4)#
+ Die Verbindung wurde von der Gegenstelle abgebrochen.
+
+#ib(4)#Empfangseintrag freigegeben#ie(4)#
+ Die Verbindung wurde von der empfangenden #ib#Station#ie# gelöscht, weil
+ seit dem Eintreffen des letzten Telegramms zuviel Zeit vergangen ist
+ (#ib#Timeout#ie#).
+
+#ib(4)#Irrläufer#ie(4)#
+ Eine #ib#Intertaskkommunikation#ie# innerhalb der eigenen Station wurde
+ fälschlicherweise über den #on("b")##ib#Collector#ie##off("b")# abgewickelt. Dieser Vorgang
+ wird abgebrochen.
+#page#
+#ib(4)#Call-Löschung vorgemerkt#ie(4)#
+ Sobald der Call abgewickelt ist, wird diese Verbindung gelöscht.
+ Beispielsweise führt ein vom Benutzer abgebrochenes #on("b")##ib#name#ie##off("b")# zu
+ dieser Meldung.
+
+#ib(4)#Call gelöscht#ie(4)#
+ Die #ib#Verbindung#ie# wurde auf Anforderung durch den Auftraggeber
+ gelöscht.
+
+#ib(4)#Quellrechner#ie(4)#
+ Als #ib#Quellrechnernummer#ie# wurde ein unzulässiger Wert festgestellt.
+ Zulässig sind Zahlen zwischen 1 und 127.
+
+#ib(4)#Nicht zustellbar#ie(4)#
+ Innerhalb eines bestimmten Zeitraums war die #ib#Zieltask#ie# nicht emp­
+ fangsbereit. Die Verbindung wird abgebrochen.
+
+Bei diesen Meldungen sollten die #ib#Routenanweisungen#ie# überprüft werden:
+
+#ib(4)#Verbotene Route bei Quittung#ie(4)#
+ Die #ib#Quittung#ie# kommt auf einer nicht erlaubten #ib#Route#ie# an. Dies kann
+ bei #ib#Vermaschung#ie# passieren, oder aber, wenn eine Station versucht,
+ sich für eine andere Station auszugeben.
+
+#ib(4)#Verbotene Route#ie(4)#
+ Die danach bezeichnete Station versucht, auf einer anderen Route
+ mit diesem Rechner zu kommunizieren, als auf der Route, die für
+ diesen Rechner in der Datei #on("b")##ib#netz#ie##off("b")# festgelegt wurde.
+
+ Abhilfe:
+ #ib#Routentabellen#ie# der beiden (oder, falls die Meldung auf einer
+ #ib#Knotenstation#ie# erscheint, auf allen beteiligten) Stationen abgleichen.
+
+#ib(4)#Weiterleitung nicht möglich#ie(4)#
+ Die #ib#Routeninformationen#ie# auf dem #ib#Knotenrechner#ie#, wo diese Meldung
+ erscheint, und der sendenden #ib#Station#ie# stimmen nicht überein. Die
+ angegebene Station ist von dieser Station aus nicht erreichbar.
+
+ Abhilfe:
+ #ib#Routentabellen#ie# der Stationen überprüfen.
+
+#ib(4)#Fremdzugriff#ie(4)#
+ Eine #ib#gesperrt#ie#e Station hat versucht, auf diesen Rechner mit #ib#Sende­
+ codes#ie# > 6 zuzugreifen.
+
+
+Folgende Meldungen betreffen '#ib#harte Fehler#ie#'. Diese Fehler werden von der Netzsoft­
+ware nicht abgefangen. In jedem Fall muß das Netz nach einer solchen #ib#Fehler­
+meldung#ie# neu gestartet werden.
+
+#ib(4)#++++++#ie(4)#
+ Meldungen dieser Form sind 'harte' Fehler. Der aufgetretene Fehler
+ wird mit angegeben. Das Netz muß neu gestartet werden, da die
+ Task, in welcher der Fehler aufgetreten ist, gelöscht wird.
+
+#ib(4)#Verbindungsengpaß#ie(4)#
+ Es sind mehr Verbindungen festgestellt worden, als zulässig sind.
+ Nach dieser Meldung wurde der entsprechende Netport gelöscht.
+
+
+Literaturverzeichnis
+
+
+#goalpage("A.2")#
+
+#clear pos#
+#lpos(1.0)##lpos(2.5)#
+#table#
+[1] EUMEL-Systemhandbuch, Teil 5, Intertaskkommunikation
+ GMD St. Augustin, 1986
+[2] EUMEL-Systemhandbuch, Teil 2, Hardware und ihre Steuerung
+[3] EUMEL-Systemhandbuch, Teil 8, Spooler
+[4] EUMEL-Netz Installationsanweisung
+ GMD St. Augustin, 1987
+[5] EUMEL-Systemhandbuch, Teil 4, Blockorientierte Ein/Ausgabe
+[6] EUMEL-Quellcode, Packet #on("b")#tasks#off("b")#
+ GMD St. Augustin, 1986
+[7] EUMEL-Portierungshandbuch 8086, Version 8
+ GMD St. Augustin, 1987
+
+#table end#
+
+
diff --git a/net/netzhandbuch.anhang b/net/netzhandbuch.anhang
new file mode 100644
index 0000000..17d1ece
--- /dev/null
+++ b/net/netzhandbuch.anhang
@@ -0,0 +1,58 @@
+#pagenr ("%", 51)##setcount##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Anhang
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#clear pos##lpos(0.0)##rpos(11.0)##fillchar(".")#
+Anhang: Netz-Fehlermeldungen
+
+#table#
+++++++ 50
+Absteigende Seitennummern 48
+blockin abbruch 48
+Blocknummer falsch 47
+buffers flushed 47
+Call gelöscht 49
+Call-Löschung vorgemerkt 49
+Collectortask fehlt 8, 18
+Daten ohne Eroeffnung 47
+Empfangseintrag freigegeben 48
+etwas rueckgespult 47
+Falsche Seitennummer 48
+Fremdzugriff 50
+Header inkorrekt eingelesen 48
+Irrläufer 48
+kein Zugriff auf Station 14
+Neustart 48
+Nicht zustellbar 49
+Quellrechner 49
+Sendung von Gegenstelle gelöscht 48
+Sequenzfehler 47
+Sequenzreset 47
+skipped 46
+Station x antwortet nicht 8, 11, 16
+Station x gibt es nicht 9, 11, 13
+Strom falsch in Quittung 48
+Task "..." gibt es nicht 8
+Verbindungsengpaß 50
+Verbotene Route 49
+Verbotene Route bei Quittung 49
+wdh data 47
+wdh open 47
+Weiterleitung nicht möglich 49
+#table end#
+
diff --git a/net/netzhandbuch.index b/net/netzhandbuch.index
new file mode 100644
index 0000000..01d8a0f
--- /dev/null
+++ b/net/netzhandbuch.index
@@ -0,0 +1,259 @@
+#pagenr ("%", 52)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Anhang
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#clear pos##lpos(0.0)##rpos(11.0)##fillchar(".")#
+Anhang: Index
+
+#table#
+/ 8, 9, 24
+Absenderadresse 39
+Absenderstation 28, 32
+Adresse 29, 37, 39, 41, 42
+aktiviere netz 14, 15, 18
+basic net 41, 43
+Baud 6, 18, 25
+blockin 23, 36, 40, 42
+blockout 23, 36, 40
+Broad- oder Multicasts 38
+buffers flushed 47
+CASE 37
+CLOSE 27
+collected destination 22, 24
+Collector 22, 24, 32, 48
+Collectortask 8, 18, 22
+configurate 6
+continue 7, 21
+CRC-Code 26
+DATA 27, 29, 30
+data length 23, 36, 41, 45
+data length via node 23, 36, 41, 42, 45
+Datei 2, 5, 7, 12, 13, 14, 18, 20, 24, 31, 37, 41, 44, 46
+Datenbox 2, 6, 33
+Datenraum 13, 15, 21, 23, 24, 27, 28, 29, 31, 36, 40, 43
+Datenraumseite 23, 46, 47
+decode packet length 42, 43
+define collector 22, 24
+definere netz 15
+DEFINES 37
+define station 5, 22
+definiere netz 14
+Dreher 16
+Durchsatz 3
+Eingabeprozeduren 21
+Eingabepuffer 47
+Empfangspuffer 15
+Empfangsströme 13, 15
+endquelle 28
+endziel 28
+erase 13, 19
+erlaube 14
+Ethernet 33, 34, 36, 37, 42
+EUMEL0 21, 22, 24
+EUMEL-Datenboxen-Netz 33
+EUMEL-Netz-Software 35
+exists 11
+Fehler 8, 16, 17, 18
+Fehlerbehandlung 31, 36, 42
+Fehlerfälle 8
+Fehlerfall 11, 40
+Fehlermeldung 13, 15, 20, 26, 39, 45, 46, 50
+Fehlersituationen 12
+Fehlersuche 16
+Fenstertechnik 31
+fetch 10, 18
+flush buffers 36, 42
+Flußkontrolle 7, 15, 27, 39
+free global manager 10, 19, 31
+Füllzeichen 37, 39, 42, 43
+gesperrt 13, 14, 45, 50
+global manager 19, 31
+harte Fehler 50
+HDLC 31
+Header 43
+Höhere Ebenen 31
+inchar 21
+incharety 23
+Installation 2
+Installationsanleitung 2
+Intertaskkommunikation 48
+I/O Control 36
+I/O-Kanal 33
+Kanal 3, 6, 7, 12, 14, 15, 20, 21, 23, 24, 34, 37, 40, 41
+Kanalnummer 14
+Kanaltask 45
+Knoten 3, 4, 17, 20, 23, 36, 42
+Knotenkonzept 3, 34
+Knotenrechner 34, 36, 49
+Knotenstation 13, 14, 20, 49
+Kommunikation 17
+Kommunikationindirekte 23
+konfigurieren 6
+Länge 29, 41, 42
+Längenangabe 26
+list 10, 12, 17, 44
+listoption 12, 14, 15
+Löschversuche 13
+Manager 10, 19
+Masseschluß 16
+max mode 43
+mode text 41
+Nachbarn 4, 28
+Nachbarstation 24, 28
+name 11, 24, 49
+net 7, 12, 13
+net addess 41
+net hardware interface 34, 40
+net install 7
+net list 12, 15
+net manager 41
+net mode 41, 43
+net port 7, 8, 12, 13, 18, 45, 46
+net timer 14
+netz 7, 14, 15, 20, 37, 41, 49
+Netzbox 3, 6, 20, 33, 38
+Netzdefinition 14
+Netzebene 26
+Netzempfangstask 30
+Netzhardware 2, 17, 21, 24, 33, 34, 36, 41, 43
+Netz-Hardware-Interface 34
+Netzinstallation 17
+Netzkanal 13, 14, 42
+Netzknoten 3
+Netzkonfiguration 7, 20
+Netzmodus 34, 37, 39, 41, 43
+Netzprotokoll 42
+Netzsoftware 2, 3, 18, 20, 34, 36, 38, 42, 48
+Netzstrang 4, 17, 23
+Netztask 15, 16, 21, 24
+Netztelegramm 34
+Netztreiber 38
+Netzübertragungen 12
+Netzversion 2, 45
+next packet start 36, 42
+niltext 11, 36
+Nutzdaten 23
+Nutzdatenlänge 17, 23, 29, 36, 41, 42, 45
+Nutzinformation 29
+nutzlaenge 29
+OPEN 27, 28, 30, 47
+Paket 23, 34, 37, 38, 39, 42, 43
+Pakete, Aufbau der 34
+Partner 46
+Paßwort 19
+Pin-Belegung 6
+port intern 13, 15, 24
+Printerserver 20
+Protokoll 6, 13, 24, 39
+Protokollebenen 25
+Prüfsummen 18
+Quelle 23, 26, 28
+Quellrechnernummer 49
+Quellstationsnummer 20
+quelltask 21, 24, 28
+Querarchivierungen 10
+QUIT 27, 28, 30
+Quittung 30, 31, 47, 48, 49
+Rechnerkopplung 3
+Rendezvouskonzept 21, 31
+report 8, 12, 18, 39, 40, 41, 45, 46
+reserve 10
+RESET 17
+reset box 43
+Route 13, 15, 17, 20, 49
+routen 14
+Routenanweisungen 49
+routen aufbauen 13, 14, 15
+Routeninformationen 20, 49
+Routentabelle 9, 13
+Routentabellen 24, 49
+router 13
+RS422 25
+RTS/CTS 6, 25, 39
+Rückmeldeparameter 21
+run 13
+save 10, 19
+Schnittstelle 3, 15, 18, 20, 25, 33, 37, 38, 39
+SDLC 25, 26
+seite 28, 29, 40
+Seiten 27
+Seitengrenze 23
+Seitennummer 47, 48
+SELECT 34, 37, 43
+send 21, 22, 24, 27, 28, 30, 32
+Sendecode 24
+Sendecodes 50
+Sendeströme 13, 46
+Sendungskonzept 2
+sequenz 28, 29, 46
+Sequenzfehler 47
+Sequenznummer 46, 47
+Sequenzreset 47
+set net mode 41
+SHard 38, 43
+Sicherheitskonzept 19
+Sicherheitsprobleme 19
+skipped 46
+sperre 14
+Spoolmanager 5
+Sprungleiste 43
+Sprungleisten 34, 37
+start 5, 13, 16, 18, 41
+starte kanal 14, 15
+station 2, 5, 8, 10, 12, 13, 16, 19, 20, 22, 24, 26, 31, 32, 36, 41, 45, 48, 49
+Stationen, sicherheitsrelevante 20
+Stationsadresse 38
+Stationsnummer 5, 10, 16, 22, 24, 26, 32, 37, 41, 46
+Stationsnummer maximale 14
+Strang 3, 17, 20, 36, 41
+Stream I/O 23, 38
+strom 28, 30, 46
+Stromnummer 13, 28, 30, 45, 46, 47, 48
+STX 26, 36, 42
+Task-Id 5, 22, 24, 28, 30
+Telegramm 20, 23, 26, 27, 28, 31, 36, 37, 40, 42, 43, 46, 47, 48
+Telegrammanfang 42
+Telegrammformat 26
+Telegrammfreigabe 36
+Textdatei 31
+Timeout 31, 36, 48
+transmit header 36, 42, 43
+transmit trailer 36, 43
+Treiber 33
+Übertragung 26, 30, 46, 47
+Übertragungsfehler 42
+Übertragungsgeschwindigkeit 34, 38
+Übertragungsweg 23
+V24 3, 4, 15, 17, 18, 20, 25, 33, 34, 38
+Verbindung 3, 6, 16, 18, 27, 28, 34, 48, 49
+Vermaschung 4, 49
+Vermittlungsebene 24, 30
+Vorspann 36, 43
+wait 19, 21, 24, 27, 32
+Worker 5
+Zeichen 36, 38, 40, 42, 46
+Zeichenverluste 46, 47, 48
+Zeitüberwachung 26, 29
+ziel 28
+Zieladresse 38
+Zielstation 4, 8, 24, 28, 30, 36, 45
+Zieltask 21, 22, 24, 28, 32, 49
+Zustand 46
+Zwischenstation 45
+#table end#
+
diff --git a/net/port server b/net/port server
new file mode 100644
index 0000000..46c647f
--- /dev/null
+++ b/net/port server
@@ -0,0 +1,164 @@
+PACKET port server: (* Autor : R. Ruland *)
+ (* Stand : 21.03.86 *)
+
+INT VAR port station;
+TEXT VAR port := "PRINTER";
+
+put ("gib Name des Zielspools : "); editget (port); line;
+put ("gib Stationsnummer des Zielspools : "); get (port station);
+
+server channel (15);
+spool duty ("Verwalter fuer Task """ + port +
+ """ auf Station " + text (port station));
+
+LET max counter = 10 ,
+ time slice = 300 ,
+
+ ack = 0 ,
+ fetch code = 11 ,
+ param fetch code = 21 ,
+ file save code = 22 ,
+ file type = 1003 ,
+
+ begin char = ""0"",
+ end char = ""1"";
+
+
+INT VAR reply, old heap size;
+TEXT VAR file name, write pass, read pass, sendername, buffer;
+FILE VAR file;
+
+DATASPACE VAR ds, file ds, send ds;
+
+BOUND STRUCT (TEXT file name, write pass, read pass, sendername, INT station) VAR msg;
+BOUND TEXT VAR error msg ;
+
+spool manager (PROC save file);
+
+PROC save file :
+
+ disable stop ;
+ command dialogue (FALSE);
+ ds := nilspace; file ds := nilspace; send ds := nil space;
+ old heap size := heap size;
+
+ REP
+ execute save file;
+
+ IF is error THEN save error (error message) FI;
+
+ IF heap size > old heap size + 4
+ THEN collect heap garbage ;
+ old heap size := heap size
+ FI;
+
+ PER
+
+ENDPROC save file;
+
+
+PROC execute save file :
+
+enable stop;
+forget (file ds) ; file ds := nilspace;
+call (father, fetch code, file ds, reply);
+IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE save file ds
+FI;
+
+. save file ds :
+ IF type (file ds) = file type
+ THEN get file params;
+ insert file params;
+ call station (port station, port, file save code, file ds);
+ ELSE errorstop ("Datenraum hat falschen Typ")
+ FI;
+
+. get file params :
+ forget (ds); ds := nilspace;
+ call (father, param fetch code, ds, reply);
+ IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE msg := ds;
+ file name := msg. file name;
+ write pass := msg. write pass;
+ read pass := msg. read pass;
+ sendername := msg. sender name;
+ FI;
+
+. insert file params :
+ buffer := "";
+ in headline (filename);
+ in headline (write pass);
+ in headline (read pass);
+ in headline (sendername);
+ file := sequential file (input, file ds) ;
+ headline (file, buffer);
+
+END PROC execute save file;
+
+
+PROC call station (INT CONST order task station, TEXT CONST order task name,
+ INT CONST order code, DATASPACE VAR order ds) :
+
+ INT VAR counter := 0;
+ TASK VAR order task;
+ disable stop;
+ REP order task := order task station // order task name;
+ IF is error CAND pos (error message, "antwortet nicht") > 0
+ THEN clear error;
+ counter := min (max counter, counter + 1);
+ pause (counter * time slice);
+ ELSE enable stop;
+ forget (send ds); send ds := order ds;
+ call (order task, order code, send ds, reply);
+ disable stop;
+ IF reply = ack
+ THEN forget (order ds); order ds := send ds;
+ forget (send ds);
+ LEAVE call station
+ ELSE error msg := send ds;
+ errorstop (error msg);
+ FI;
+ FI;
+ PER;
+
+END PROC call station;
+
+
+TASK OP // (INT CONST station, TEXT CONST name) :
+
+ enable stop;
+ station / name
+
+END OP //;
+
+
+PROC in headline (TEXT CONST information) :
+ IF pos (information, begin char) <> 0
+ OR pos (information, end char) <> 0
+ THEN errorstop ("Name darf nicht Code 0 oder Code 1 enthalten") FI;
+ buffer CAT begin char;
+ buffer CAT information;
+ buffer CAT end char;
+END PROC in headline;
+
+
+PROC save error (TEXT CONST message) :
+ clear error;
+ file name CAT ".";
+ file name CAT sender name;
+ file name CAT ".ERROR";
+ file := sequential file (output, file name);
+ putline (file, " ");
+ putline (file, "Uebertragung nicht korrekt beendet ");
+ putline (file, " ");
+ put (file, "ERROR :"); put (file, message);
+ save (file name, public);
+ clear error;
+ forget(file name, quiet);
+END PROC save error;
+
+ENDPACKET port server;
+
diff --git a/net/printer server b/net/printer server
new file mode 100644
index 0000000..b1a30bc
--- /dev/null
+++ b/net/printer server
@@ -0,0 +1,99 @@
+PACKET multi user printer : (* Autor : Rudolf Ruland *)
+ (* Stand : 24.03.86 *)
+
+INT VAR c;
+put ("gib Druckerkanal : "); get (c);
+
+ server channel (c);
+ station only (FALSE) ;
+ spool duty ("Ausgabe mit dem Drucker");
+ spool control task (myself);
+
+LET ack = 0 ,
+
+ fetch code = 11 ,
+ param fetch code = 21 ,
+ file type = 1003 ;
+
+INT VAR reply, old heap size, sender station;
+TEXT VAR file name, userid, password, sendername;
+FILE VAR file ;
+
+DATASPACE VAR ds, file ds;
+
+BOUND STRUCT (TEXT file name, userid, password, sendername, INT station) VAR msg;
+BOUND TEXT VAR error msg ;
+
+spool manager (PROC printer);
+
+PROC printer :
+
+ disable stop ;
+ command dialogue (FALSE);
+ ds := nilspace; file ds := nilspace;
+ continue (server channel) ;
+ check error ("Kanal belegt");
+
+ old heap size := heap size ;
+ REP
+ execute print ;
+
+ IF is error
+ THEN put error;
+ clear error;
+ FI ;
+
+ IF heap size > old heap size + 4
+ THEN collect heap garbage ;
+ old heap size := heap size
+ FI
+ PER
+
+ENDPROC printer ;
+
+
+PROC execute print :
+
+ enable stop ;
+ forget (file ds) ; file ds := nilspace ;
+ call (father, fetch code, file ds, reply) ;
+ IF reply = ack CAND type (file ds) = file type
+ THEN get file params;
+ print file
+ FI ;
+
+. get file params :
+ forget (ds); ds := nilspace;
+ call (father, param fetch code, ds, reply);
+ IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE msg := ds;
+ file name := msg. file name;
+ userid := msg. userid;
+ password := msg. password;
+ sendername := msg. sender name;
+ sender station := msg. station;
+ FI;
+
+. print file :
+ file := sequential file (input, file ds);
+ print (file,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+ENDPROC execute print ;
+
+
+PROC check error (TEXT CONST message) :
+ IF is error
+ THEN clear error;
+ rename myself (message);
+ IF is error THEN clear error; end (myself) FI;
+ pause (18000);
+ end (myself);
+ FI;
+END PROC check error;
+
+ENDPACKET multi user printer ;
+
diff --git a/net/spool cmd b/net/spool cmd
new file mode 100644
index 0000000..b44e799
--- /dev/null
+++ b/net/spool cmd
@@ -0,0 +1,112 @@
+PACKET spool cmd (* Autor: R. Ruland *)
+ (* Stand: 01.04.86 *)
+ DEFINES killer,
+ first,
+ start,
+ stop,
+ halt,
+ wait for halt :
+
+LET error nak = 2 ,
+
+ entry line code = 23 ,
+ killer code = 24 ,
+ first code = 25 ,
+ start code = 26 ,
+ stop code = 27 ,
+ halt code = 28 ,
+ wait for halt code = 29 ;
+
+DATASPACE VAR ds;
+
+BOUND STRUCT (TEXT entry line, INT index) VAR control msg;
+BOUND TEXT VAR error msg ;
+
+INT VAR reply;
+
+INITFLAG VAR in this task := FALSE;
+
+
+PROC control spool (TASK CONST spool, INT CONST control code,
+ TEXT CONST question, BOOL CONST leave) :
+
+ enable stop;
+ initialize control msg;
+ WHILE valid spool entry
+ REP IF control question THEN control spool entry FI PER;
+
+ . initialize control msg :
+ IF NOT initialized (in this task) THEN ds := nilspace FI;
+ forget (ds); ds := nilspace; control msg := ds;
+ control msg. entry line := "";
+ control msg. index := 0;
+ say (""13""10"");
+
+ . valid spool entry :
+ call (spool, entry line code, ds, reply);
+ IF reply = error nak
+ THEN error msg := ds;
+ errorstop (error msg);
+ FI;
+ control msg. index <> 0
+
+ . control question :
+ say (control msg. entry line);
+ yes (question)
+
+ . control spool entry :
+ call (spool, control code, ds, reply);
+ IF reply = error nak
+ THEN error msg := ds;
+ errorstop (error msg);
+ FI;
+ IF leave THEN LEAVE control spool FI;
+
+END PROC control spool;
+
+
+PROC killer (TASK CONST spool) :
+
+ control spool (spool, killer code, " loeschen", FALSE)
+
+END PROC killer;
+
+
+PROC first (TASK CONST spool) :
+
+ control spool (spool, first code, " als erstes", TRUE)
+
+END PROC first;
+
+
+PROC start (TASK CONST spool) :
+
+ call (stop code, "", spool);
+ call (start code, "", spool);
+
+END PROC start;
+
+
+PROC stop (TASK CONST spool) :
+
+ call (stop code, "", spool);
+
+END PROC stop;
+
+
+PROC halt (TASK CONST spool) :
+
+ call (halt code, "", spool);
+
+END PROC halt;
+
+
+PROC wait for halt (TASK CONST spool) :
+
+ call (wait for halt code, "", spool);
+
+END PROC wait for halt;
+
+
+END PACKET spool cmd;
+
diff --git a/net/spool manager b/net/spool manager
new file mode 100644
index 0000000..e711ab4
--- /dev/null
+++ b/net/spool manager
@@ -0,0 +1,915 @@
+PACKET spool manager DEFINES (* Autor: J. Liedtke *)
+ (* R. Nolting *)
+ (* R. Ruland *)
+ (* Stand: 22.07.86 *)
+
+ spool manager ,
+
+ server channel ,
+ spool duty,
+ station only,
+ spool control task :
+
+LET que size = 101 ,
+
+ ack = 0 ,
+ nak = 1 ,
+ error nak = 2 ,
+ message ack = 3 ,
+ question ack = 4 ,
+ second phase ack = 5 ,
+ false code = 6 ,
+
+ fetch code = 11 ,
+ save code = 12 ,
+ exists code = 13 ,
+ erase code = 14 ,
+ list code = 15 ,
+ all code = 17 ,
+ param fetch code = 21 ,
+ file save code = 22 ,
+ entry line code = 23 ,
+ killer code = 24 ,
+ first code = 25 ,
+ start code = 26 ,
+ stop code = 27 ,
+ halt code = 28 ,
+ wait for halt code = 29 ,
+
+ continue code = 100 ,
+
+ file type = 1003 ;
+
+LET begin char = ""0"",
+ end char = ""1"";
+
+LET PARAMS = STRUCT (TEXT name, userid, password, sendername, INT station),
+ ENTRY = STRUCT (PARAMS ds params, TEXT entry line, DATASPACE space);
+
+ROW que size ENTRY VAR que ;
+
+PARAMS CONST empty params := PARAMS : ("", "", "", "", -1);
+
+PARAMS VAR save params, file save params;
+
+ENTRY VAR fetch entry;
+
+FILE VAR file;
+
+INT VAR order, last order, phase, reply, old heap size, first, last, list index,
+ begin pos, end pos, order task station, sp channel, counter;
+
+TEXT VAR order task name, buffer, sp duty, start time;
+
+BOOL VAR server is waiting, stop command pending, stat only, valid fetch entry;
+
+TASK VAR order task, last order task, server, calling parent, task in control;
+
+INITFLAG VAR in this task := FALSE;
+
+DATASPACE VAR ds;
+
+BOUND STRUCT (TEXT name, userid, password) VAR msg;
+BOUND STRUCT (TEXT entry line, INT index) VAR control msg;
+BOUND PARAMS VAR fetch msg;
+BOUND THESAURUS VAR all msg;
+BOUND TEXT VAR error msg ;
+
+
+. first entry : que (first)
+. list entry : que (list index)
+. last entry : que (last)
+
+. que is empty : first = last
+. que is full : first = next (last)
+.;
+
+sp channel := 0;
+sp duty := "";
+stat only := FALSE;
+task in control := myself;
+
+PROC server channel (INT CONST channel nr) :
+ IF channel nr <= 0 OR channel nr >= 33
+ THEN errorstop ("falsche Kanalangabe") FI;
+ sp channel := channel nr;
+END PROC server channel;
+
+INT PROC server channel :
+ sp channel
+END PROC server channel;
+
+
+PROC station only (BOOL CONST flag) :
+ stat only := flag
+END PROC station only;
+
+BOOL PROC station only :
+ stat only
+END PROC station only;
+
+
+PROC spool duty (TEXT CONST duty) :
+ sp duty := duty;
+END PROC spool duty;
+
+TEXT PROC spool duty :
+ sp duty
+END PROC spool duty;
+
+
+PROC spool control task (TASK CONST task id):
+ task in control := task id;
+END PROC spool control task;
+
+TASK PROC spool control task :
+ task in control
+END PROC spool control task;
+
+
+PROC spool manager (PROC server start) :
+
+ spool manager (PROC server start, TRUE)
+
+END PROC spool manager;
+
+
+PROC spool manager (PROC server start, BOOL CONST with start) :
+
+ set autonom ;
+ break ;
+ disable stop ;
+ initialize spool manager ;
+ REP forget (ds) ;
+ wait (ds, order, order task) ;
+ IF order <> second phase ack
+ THEN prepare first phase ;
+ spool (PROC server start);
+ ELIF order task = last order task
+ THEN prepare second phase ;
+ spool (PROC server start);
+ ELSE send nak
+ FI ;
+ send error if necessary ;
+ collect heap garbage if necessary
+ PER
+
+ . initialize spool manager :
+ initialize if necessary;
+ stop;
+ erase fetch entry;
+ IF with start THEN start (PROC server start) FI;
+
+ . initialize if necessary :
+ IF NOT initialized (in this task)
+ THEN FOR list index FROM 1 UPTO que size
+ REP list entry. space := nilspace PER;
+ fetch entry. space := nilspace;
+ ds := nilspace;
+ last order task := niltask;
+ server := niltask;
+ calling parent := niltask;
+ server is waiting := FALSE;
+ stop command pending := FALSE;
+ old heap size := 0;
+ clear spool;
+ FI;
+
+ . prepare first phase :
+ IF order = save code OR order = erase code OR order = stop code
+ THEN phase := 1 ;
+ last order := order ;
+ last order task := order task ;
+ FI;
+
+ . prepare second phase :
+ phase INCR 1 ;
+ order := last order
+
+ . send nak :
+ forget (ds) ;
+ ds := nilspace ;
+ send (order task, nak, ds);
+
+ . send error if necessary :
+ IF is error
+ THEN forget (ds) ;
+ ds := nilspace ;
+ error msg := ds ;
+ CONCR (error msg) := error message;
+ clear error;
+ send (order task, error nak, ds)
+ FI;
+
+ . collect heap garbage if necessary :
+ IF heap size > old heap size + 2
+ THEN collect heap garbage;
+ old heap size := heap size;
+ FI;
+
+END PROC spool manager;
+
+
+PROC spool (PROC server start):
+
+ command dialogue (FALSE);
+ enable stop;
+ IF station only CAND station (ordertask) <> station (myself)
+ THEN errorstop ("kein Zugriffsrecht auf Task " + text (station(myself))
+ + "/""" + name(myself) + """")
+ FI;
+
+ SELECT order OF
+
+ CASE fetch code : out of que
+ CASE param fetch code : send fetch params
+ CASE save code : new que entry
+ CASE file save code : new file que entry
+ CASE exists code : exists que entry
+ CASE erase code : erase que entry
+ CASE list code : send spool list
+ CASE all code : send owners ds names
+
+ OTHERWISE :
+
+ IF order >= continue code AND order task = supervisor
+ THEN forget (ds);
+ spool command (PROC server start)
+
+ ELIF spool control allowed by order task
+ THEN SELECT order OF
+ CASE entry line code : send next entry line
+ CASE killer code : kill entry
+ CASE first code : make to first
+ CASE start code : start server
+ CASE stop code : stop server
+ CASE halt code : halt server
+ CASE wait for halt code : wait for halt
+ OTHERWISE : errorstop ("falscher Auftrag fuer Task """
+ + name(myself) + """")
+ END SELECT
+
+ ELSE errorstop ("falscher Auftrag fuer Task """
+ + name(myself) + """")
+ FI;
+ END SELECT;
+
+
+. spool control allowed by order task :
+ (order task = spool control task OR order task < spool control task
+ OR spool control task = supervisor)
+ AND station (order task) = station (myself)
+.
+ out of que :
+ IF NOT (order task = server)
+ THEN errorstop ("keine Servertask")
+ ELIF stop command pending
+ THEN forget (ds);
+ stop;
+ erase fetch entry;
+ ELIF que is empty
+ THEN forget (ds) ;
+ erase fetch entry;
+ server is waiting := TRUE;
+ ELSE send first entry;
+ FI;
+
+.
+ send fetch params :
+ IF order task = server
+ THEN send params
+ ELSE errorstop ("keine Servertask")
+ FI;
+
+ . send params :
+ forget(ds); ds := nilspace; fetch msg := ds;
+ fetch msg := fetch entry. ds params;
+ send (order task, ack, ds);
+
+.
+ new que entry :
+ IF phase = 1
+ THEN prepare into que
+ ELSE into que
+ FI;
+
+.
+ prepare into que :
+ msg := ds ;
+ save params. name := msg.name;
+ save params. userid := msg.userid;
+ save params. password := msg.password;
+ save params. sendername := name (order task);
+ save params. station := station (order task);
+ forget (ds); ds := nilspace;
+ send (order task, second phase ack, ds);
+
+.
+ new file que entry :
+ IF type (ds) <> file type
+ THEN errorstop ("Datenraum hat falschen Typ");
+ ELSE get file params;
+ into que;
+ FI;
+
+ . get file params :
+ file := sequential file (input, ds);
+ end pos := 0;
+ next headline information (file save params. name);
+ next headline information (file save params. userid);
+ next headline information (file save params. password);
+ next headline information (file save params. sendername);
+ next headline information (buffer);
+ file save params. station := int (buffer);
+ IF NOT last conversion ok
+ THEN file save params. station := station (order task) FI;
+ IF file save params. sendername = ""
+ THEN file save params. sendername := name (order task) FI;
+ IF file save params. name = ""
+ THEN IF headline (file) <> ""
+ THEN file save params. name := headline (file);
+ ELSE errorstop ("Name unzulaessig")
+ FI;
+ ELSE headline (file, file save params. name);
+ FI;
+
+.
+ exists que entry :
+ msg := ds ;
+ order task name := name (order task);
+ order task station := station (order task);
+ to first que entry;
+ WHILE next que entry found
+ REP IF is entry from order task (msg. name)
+ THEN send ack;
+ LEAVE exists que entry
+ FI;
+ PER ;
+ forget (ds); ds := nilspace;
+ send (order task, false code, ds)
+
+.
+ erase que entry :
+ msg := ds ;
+ order task name := name (order task);
+ order task station := station (order task);
+ IF phase = 1
+ THEN ask for erase
+ ELSE erase entry from order task
+ FI;
+
+ . ask for erase :
+ to first que entry;
+ WHILE next que entry found
+ REP IF is entry from order task (msg. name)
+ THEN manager question ("""" + msg.name + """ loeschen");
+ LEAVE erase que entry
+ FI;
+ PER ;
+ manager message ("""" + msg.name + """ existiert nicht");
+
+ . erase entry from order task :
+ IF is entry from order task (msg. name)
+ THEN delete que entry;
+ LEAVE erase que entry
+ ELSE to first que entry;
+ WHILE next que entry found
+ REP IF is entry from order task (msg. name)
+ THEN delete que entry;
+ LEAVE erase que entry
+ FI ;
+ PER ;
+ manager message ("""" + msg.name + """ existiert nicht");
+ FI;
+
+ . delete que entry :
+ erase entry (list index) ;
+ send ack;
+
+.
+ send owners ds names:
+ order task name := name (order task);
+ order task station := station (order task);
+ forget (ds); ds := nilspace; all msg := ds;
+ all msg := empty thesaurus;
+ to first que entry;
+ WHILE next que entry found
+ REP IF is entry from order task ("")
+ THEN insert (all msg, list entry. ds params. name)
+ FI;
+ PER;
+ send (order task, ack, ds)
+
+.
+ send spool list :
+ list spool;
+ send (order task, ack, ds);
+
+.
+ send next entry line :
+ control msg := ds;
+ get next entry line (control msg. entry line, control msg. index);
+ send (order task, ack, ds);
+
+.
+ kill entry :
+ control msg := ds;
+ list index := control msg. index;
+ IF is valid que entry (list index)
+ THEN erase entry (list index)
+ FI;
+ send (order task, ack, ds);
+
+.
+ make to first :
+ control msg := ds;
+ list index := control msg. index;
+ IF is valid que entry (list index)
+ THEN new first (list entry);
+ erase entry (list index);
+ FI;
+ send (order task, ack, ds);
+
+.
+ start server :
+ IF exists (server) THEN errorstop ("Spool muß zuerst gestoppt werden") FI;
+ start (PROC server start);
+ IF server channel <= 0 OR server channel >= 33
+ THEN manager message ("WARNUNG : Serverkanal nicht eingestellt");
+ ELSE send ack
+ FI;
+
+.
+ stop server:
+ IF phase = 1
+ THEN stop;
+ IF valid fetch entry
+ THEN valid fetch entry := FALSE;
+ manager question (""13""10"" +
+ fetch entry. entry line + " neu eintragen");
+ ELSE erase fetch entry;
+ send ack;
+ FI;
+ ELSE IF fetch entry. entry line <> "" THEN new first (fetch entry) FI;
+ erase fetch entry;
+ send ack;
+ FI;
+
+.
+ halt server :
+ stop command pending := TRUE;
+ IF NOT exists (server) OR server is waiting
+ THEN stop;
+ erase fetch entry;
+ FI;
+ send ack;
+
+.
+ wait for halt :
+ IF exists (calling parent)
+ THEN errorstop ("Task """ + name (calling parent) + """ wartet schon auf halt")
+ ELSE calling parent := order task;
+ stop command pending := TRUE;
+ forget (ds);
+ IF NOT exists (server) OR server is waiting
+ THEN stop;
+ erase fetch entry;
+ FI;
+ FI;
+
+END PROC spool;
+
+
+PROC send first entry :
+
+ forget (ds); ds := first entry. space;
+ send (server, ack, ds, reply) ;
+ IF reply = ack
+ THEN server is waiting := FALSE;
+ start time := time of day;
+ start time CAT " am ";
+ start time CAT date;
+ erase fetch entry;
+ fetch entry := first entry;
+ erase entry (first);
+ valid fetch entry := TRUE;
+ ELSE forget (ds);
+ FI;
+
+END PROC send first entry;
+
+
+PROC into que :
+
+ IF que is full
+ THEN errorstop ("Spool ist voll")
+ ELSE make new entry;
+ send ack;
+ awake server if necessary
+ FI;
+
+ . make new entry :
+ IF order = save code
+ THEN last entry. ds params := save params;
+ save params := empty params;
+ ELSE last entry. ds params := file save params;
+ file save params := empty params;
+ FI;
+ last entry. space := ds;
+ counter INCR 1;
+ build entry line;
+ last := next (last) ;
+
+ . build entry line :
+ IF LENGTH last entry. ds params. sender name > 16
+ THEN buffer := subtext (last entry. ds params. sender name, 1, 13);
+ buffer CAT "...""";
+ ELSE buffer := last entry. ds params. sender name;
+ buffer CAT """";
+ buffer := text (buffer, 17);
+ FI;
+ last entry. entry line := entry station text;
+ last entry. entry line CAT "/""";
+ last entry. entry line CAT buffer;
+ last entry. entry line CAT " : """ ;
+ last entry. entry line CAT last entry. ds params. name;
+ last entry. entry line CAT """ (" ;
+ last entry. entry line CAT text (storage (last entry. space));
+ last entry. entry line CAT " K)";
+
+ . entry station text :
+ IF last entry. ds params. station = 0
+ THEN " "
+ ELSE text (last entry. ds params. station, 3)
+ FI
+
+ . awake server if necessary :
+ IF server is waiting THEN send first entry FI;
+
+END PROC into que;
+
+
+PROC list spool :
+
+ forget (ds); ds := nilspace;
+ file := sequential file (output, ds) ;
+ max line length (file, 1000);
+ headline(file, station text + "/""" + name (myself) + """");
+ put spool duty;
+ put current job;
+ put spool que;
+
+ . station text :
+ IF station(myself) = 0
+ THEN ""
+ ELSE text (station(myself))
+ FI
+
+ . put spool duty :
+ IF spool duty <> ""
+ THEN write (file, "Aufgabe: ");
+ write (file, spool duty );
+ line (file, 2);
+ FI;
+
+ . put current job :
+ IF valid fetch entry AND exists (server)
+ THEN write (file, "In Bearbeitung seit ");
+ write (file, start time);
+ write (file, ":");
+ line (file, 2);
+ putline (file, fetch entry. entry line);
+ IF stop command pending
+ THEN putline (file, "Spool wird nach diesem Auftrag deaktiviert");
+ FI;
+ line (file);
+ ELSE write (file, "kein Auftrag in Bearbeitung");
+ IF NOT exists (server)
+ THEN write (file, ", da Spool deaktiviert");
+ ELIF que is empty
+ THEN write (file, ", da Warteschlange leer");
+ LEAVE list spool;
+ FI;
+ line (file, 2);
+ FI;
+
+ . put spool que :
+ IF que is empty
+ THEN putline (file, "Warteschlange ist leer");
+ ELSE write (file, "Warteschlange (");
+ write (file, text (counter));
+ write (file, " Auftraege):");
+ line (file, 2);
+ to first que entry ;
+ WHILE next que entry found
+ REP putline (file, list entry. entry line) PER;
+ FI;
+
+END PROC list spool ;
+
+
+PROC clear spool :
+
+ first := 1;
+ last := 1;
+ counter := 0;
+ FOR list index FROM 1 UPTO que size
+ REP list entry. ds params := empty params;
+ list entry. entry line := "";
+ forget (list entry. space)
+ PER;
+
+END PROC clear spool;
+
+(*********************************************************************)
+(* Hilfsprozeduren zum Spoolmanager *)
+
+BOOL PROC is valid que entry (INT CONST index) :
+
+ que (index). entry line <> ""
+
+END PROC is valid que entry;
+
+
+INT PROC next (INT CONST index) :
+
+ IF index < que size
+ THEN index + 1
+ ELSE 1
+ FI
+
+END PROC next;
+
+
+PROC to first que entry :
+
+ list index := first - 1;
+
+ENDPROC to first que entry ;
+
+
+BOOL PROC next que entry found :
+
+ list index := next (list index);
+ WHILE is not last que entry
+ REP IF is valid que entry (list index)
+ THEN LEAVE next que entry found WITH TRUE FI;
+ list index := next (list index);
+ PER;
+ FALSE
+
+ . is not last que entry :
+ list index <> last
+
+ENDPROC next que entry found ;
+
+
+PROC get next entry line (TEXT VAR entry line, INT VAR index) :
+
+ IF index = 0
+ THEN list index := first - 1
+ ELSE list index := index
+ FI;
+ IF next que entry found
+ THEN entry line := list entry. entry line;
+ index := list index;
+ ELSE entry line := "";
+ index := 0;
+ FI;
+
+END PROC get next entry line;
+
+
+PROC new first (ENTRY VAR new first entry) :
+
+ IF que is full
+ THEN errorstop ("Spool ist voll")
+ ELSE first DECR 1 ;
+ IF first = 0 THEN first := que size FI;
+ first entry := new first entry;
+ counter INCR 1;
+ FI;
+
+END PROC new first;
+
+
+PROC erase entry (INT CONST index) :
+
+ entry. ds params := empty params;
+ entry. entry line := "";
+ forget (entry.space) ;
+ counter DECR 1;
+ IF index = first
+ THEN inc first
+ FI ;
+
+ . entry : que (index)
+
+ . inc first :
+ REP first := next (first)
+ UNTIL que is empty OR is valid que entry (first) PER
+
+END PROC erase entry;
+
+
+PROC erase fetch entry :
+
+ fetch entry. ds params := empty params;
+ fetch entry. entry line := "";
+ forget (fetch entry. space);
+ valid fetch entry := FALSE;
+
+END PROC erase fetch entry;
+
+
+BOOL PROC is entry from order task (TEXT CONST file name) :
+
+ correct order task CAND correct filename
+
+ . correct order task :
+ order task name = list entry. ds params. sendername
+ AND order task station = list entry. ds params. station
+
+ . correct file name :
+ file name = "" OR file name = list entry. ds params. name
+
+END PROC is entry from order task;
+
+
+PROC start (PROC server start):
+
+ begin (PROC server start, server);
+
+END PROC start;
+
+
+PROC stop :
+
+ stop server;
+ send calling parent reply if necessary;
+
+ . stop server:
+ IF exists (server) THEN end (server) FI;
+ server := niltask;
+ server is waiting := FALSE;
+ stop command pending := FALSE;
+
+ . send calling parent reply if necessary :
+ IF exists (calling parent)
+ THEN forget (ds); ds := nilspace;
+ send (calling parent, ack, ds);
+ calling parent := niltask;
+ FI;
+
+END PROC stop;
+
+
+PROC next headline information (TEXT VAR t):
+
+ begin pos := pos (headline (file), begin char, end pos + 1);
+ IF begin pos = 0
+ THEN begin pos := LENGTH headline (file) + 1;
+ t := "";
+ ELSE end pos := pos (headline (file), end char, begin pos + 1);
+ IF end pos = 0
+ THEN end pos := LENGTH headline (file) + 1;
+ t := "";
+ ELSE t := subtext (headline (file), begin pos+1, end pos-1)
+ FI
+ FI
+
+END PROC next headline information;
+
+
+PROC send ack :
+
+ forget (ds); ds := nilspace;
+ send (order task, ack, ds)
+
+END PROC send ack;
+
+
+PROC manager question (TEXT CONST question) :
+
+ forget (ds); ds := nilspace; error msg := ds ;
+ error msg := question ;
+ send (order task, question ack, ds)
+
+ENDPROC manager question ;
+
+
+PROC manager message (TEXT CONST message) :
+
+ forget (ds); ds := nilspace; error msg := ds ;
+ error msg := message ;
+ send (order task, message ack, ds)
+
+ENDPROC manager message ;
+
+(*********************************************************************)
+(* Spool - Kommandos *)
+
+INT VAR command index , params ;
+TEXT VAR command line, param 1, param 2 ;
+
+LET spool command list =
+"break:1.0start:2.01stop:4.0halt:5.0first:6.0killer:7.0listspool:8.0
+clearspool:9.0spoolcontrolby:10.1";
+
+PROC spool command (PROC server start) :
+
+ enable stop ;
+ continue (order - continue code) ;
+ disable stop ;
+ REP command dialogue (TRUE) ;
+ get command ("gib Spool-Kommando:", command line);
+ analyze command (spool command list, command line, 3, command index,
+ params, param1, param2);
+ execute command (PROC server start);
+ UNTIL NOT online PER;
+ command dialogue (FALSE);
+ break (quiet);
+ set autonom;
+
+END PROC spool command;
+
+
+PROC execute command (PROC server start) :
+
+ enable stop;
+ SELECT command index OF
+ CASE 1 : break
+ CASE 2 : start server
+ CASE 3 : start server with new channel
+ CASE 4 : stop server
+ CASE 5 : halt server
+ CASE 6 : first cmd
+ CASE 7 : killer cmd
+ CASE 8 : show spool list
+ CASE 9 : clear spool
+ CASE 10 : spool control task (task (param1))
+ OTHERWISE do (command line)
+ END SELECT;
+
+ . start server :
+ IF server channel <= 0 OR server channel >= 33
+ THEN line;
+ putline ("WARNUNG : Serverkanal nicht eingestellt");
+ FI;
+ stop server;
+ start (PROC server start);
+
+ . start server with new channel:
+ INT VAR i := int (param1);
+ IF last conversion ok
+ THEN server channel (i);
+ start server;
+ ELSE errorstop ("falsche Kanalangabe")
+ FI;
+
+ . stop server :
+ disable stop;
+ stop;
+ IF valid fetch entry CAND
+ yes (""13""10"" + fetch entry. entry line + " neu eintragen")
+ THEN new first (fetch entry) FI;
+ erase fetch entry;
+ enable stop;
+
+ . halt server :
+ stop command pending := TRUE;
+ IF NOT exists (server) OR server is waiting
+ THEN stop server;
+ erase fetch entry;
+ FI;
+
+ . first cmd :
+ line ;
+ to first que entry ;
+ WHILE next que entry found
+ REP say (list entry. entry line) ;
+ IF yes (" als erstes")
+ THEN new first (list entry);
+ erase entry (list index);
+ LEAVE first cmd
+ FI ;
+ PER;
+
+ . killer cmd :
+ line ;
+ to first que entry ;
+ WHILE next que entry found
+ REP say (list entry. entry line) ;
+ IF yes (" loeschen") THEN erase entry (list index) FI ;
+ PER;
+
+ . show spool list :
+ list spool;
+ disable stop;
+ show (file);
+ forget (ds);
+
+ENDPROC execute command ;
+
+ENDPACKET spool manager;
+
diff --git a/printer/dotmatrix24/beschreibungen24 b/printer/dotmatrix24/beschreibungen24
new file mode 100644
index 0000000..e3d2fa9
--- /dev/null
+++ b/printer/dotmatrix24/beschreibungen24
@@ -0,0 +1,62 @@
+
+(*************************************************************************)
+(* Stand : 3. 1.89 *)
+(* Beschreibungen-Datei für 24-Nadel-Drucker Version : 0.9 *)
+(* Autor : hjh *)
+(*************************************************************************)
+
+$necp5p7$
+begin;headnecp5p7;declarations;feed;
+open;opendoch;opendocp5p7;openpagep5-7;close;closepage;
+execute;cmdp5-7;crs;move;movep5-7;onoff;typep5-7;end
+
+$necp6$
+begin;headnecp6;declarations;feed;
+open;opendoch;opendocp6;openpagep5-7;close;closepage;
+execute;cmdp5-7;crs;move;movep5-7;onoff;typep5-7;end
+
+$necp6+$
+begin;headnecp6+;declarations;speed;topmargin;typefacep6+;feed;
+open;opendoch;initspeed;opendocp6+;openpage;close;closepage;
+execute;cmdp6+;crs;move;stdmove;onoff;typep6+;end
+
+$epsonlq850$
+begin;headlq850;declarations;speed;topmargin;typefacelq850;feed;
+open;opendoch;initspeed;opendoclq850;openpage;close;closepage;
+execute;cmdlq850;crs;move;stdmove;onoff;typeplq850;end
+
+$epsonlq1500$
+printerlq1500;end
+
+$oki390/391$
+begin;headoki390/391;declarations;speed;topmargin;typefaceoki;feedschacht;
+open;opendoch;initspeed;opendocokieps;openpage;close;closepage;
+execute;cmdoki;crs;move;stdmove;onoff;typeokieps;end
+
+$oki393/393Ceps$
+begin;headoki393/393Ceps;declarations;speed;topmargin;typefaceoki;feedschacht;
+open;opendoch;initspeed;opendocokieps;openpage;close;closepage;
+execute;cmdoki;crs;move;stdmove;onoff;typeokieps;end
+
+$oki393/393Cibm$
+begin;headoki393/393Cibm;declarations;speed;topmargin;typefaceoki;feedschacht;
+open;opendoch;initspeed;opendocokiibm;openpage;close;closepage;
+execute;cmdoki;crs;move;stdmove;onoff;typeokiibm;end
+
+$toshp321$
+begin;headtoshp321;declarations;speed;feed;
+open;opendochtosh;initspeed;opendoctosh;openpagetosh;close;closepagetosh;
+execute;cmdtosh;crs;move;stdmove;onoff;typetosh;end
+
+$starnb24$
+begin;headstarnb24;declarations;speed;topmargin;typefacestar;feedschacht;
+open;opendoch;initspeed;opendocstar;openpage;close;closepage;
+execute;cmdstar;crs;move;stdmove;onoff;typestar;end
+
+$brotherm1724l$
+begin;headbrotherm1724l;declarations;speed;topmargin;feed;
+open;opendoch;initspeed;opendocbrother;openpage;close;closepage;
+execute;cmdtosh;crs;move;stdmove;onoff;typebrother;end
+
+
+
diff --git a/printer/dotmatrix24/fonttab.brother b/printer/dotmatrix24/fonttab.brother
new file mode 100644
index 0000000..2251e18
--- /dev/null
+++ b/printer/dotmatrix24/fonttab.brother
Binary files differ
diff --git a/printer/dotmatrix24/fonttab.epson.lq1500 b/printer/dotmatrix24/fonttab.epson.lq1500
new file mode 100644
index 0000000..1b4c6a6
--- /dev/null
+++ b/printer/dotmatrix24/fonttab.epson.lq1500
Binary files differ
diff --git a/printer/dotmatrix24/fonttab.epson.lq850 b/printer/dotmatrix24/fonttab.epson.lq850
new file mode 100644
index 0000000..7a6d2f0
--- /dev/null
+++ b/printer/dotmatrix24/fonttab.epson.lq850
Binary files differ
diff --git a/printer/dotmatrix24/fonttab.nec.p5 b/printer/dotmatrix24/fonttab.nec.p5
new file mode 100644
index 0000000..9910da6
--- /dev/null
+++ b/printer/dotmatrix24/fonttab.nec.p5
Binary files differ
diff --git a/printer/dotmatrix24/fonttab.nec.p5.new b/printer/dotmatrix24/fonttab.nec.p5.new
new file mode 100644
index 0000000..9804bd5
--- /dev/null
+++ b/printer/dotmatrix24/fonttab.nec.p5.new
Binary files differ
diff --git a/printer/dotmatrix24/fonttab.nec.p6+ b/printer/dotmatrix24/fonttab.nec.p6+
new file mode 100644
index 0000000..b209e81
--- /dev/null
+++ b/printer/dotmatrix24/fonttab.nec.p6+
Binary files differ
diff --git a/printer/dotmatrix24/fonttab.oki b/printer/dotmatrix24/fonttab.oki
new file mode 100644
index 0000000..2251e18
--- /dev/null
+++ b/printer/dotmatrix24/fonttab.oki
Binary files differ
diff --git a/printer/dotmatrix24/fonttab.toshiba.p321 b/printer/dotmatrix24/fonttab.toshiba.p321
new file mode 100644
index 0000000..452afca
--- /dev/null
+++ b/printer/dotmatrix24/fonttab.toshiba.p321
Binary files differ
diff --git a/printer/dotmatrix24/inserter b/printer/dotmatrix24/inserter
new file mode 100644
index 0000000..442075d
--- /dev/null
+++ b/printer/dotmatrix24/inserter
@@ -0,0 +1,793 @@
+
+(*************************************************************************)
+(* Installationsprogramm für Stand : 3. 1.89 *)
+(* 24-Nadel Drucker Version : 0.9 *)
+(* Autor : hjh *)
+(*************************************************************************)
+
+PACKET driver inst 24
+
+
+ DEFINES treiber einrichten:
+
+
+LET up = ""3""13""5"",
+
+ generator name = "printer.24.nadel",
+
+ description file name = "beschreibungen24",
+ module file name = "module24";
+
+
+INT VAR pr channel,
+ quality,
+ paper format number,
+ service option;
+TEXT VAR fonttab name :: "",
+ driver name :: "";
+TEXT VAR inp;
+BOOL VAR was esc;
+
+treiber einrichten
+
+PROC treiber einrichten:
+
+ treiber einrichten (0)
+END PROC treiber einrichten;
+
+PROC treiber einrichten (INT CONST service opt):
+
+ ask for print channel;
+ main menu;
+ IF installed
+ THEN generate printer spool
+ ELSE inform about restart
+ FI.
+
+ ask for printchannel:
+ inits;
+ page;
+ headline ("Druckerkanal - Einstellung");
+ cursor (1, 15);
+ putline ("Hinweis: Die Druckerkanalnummer kann auch nachträglich mit");
+ putline (" 'serverchannel (Kanalnummer)' in der Task """ +
+ name (myself) + """");
+ putline (" verändert werden.");
+ REP
+ cursor (1, 10);
+ put (""5"EUMEL-Kanalnummer des Druckerkanals:");
+ get (pr channel);
+ disable stop;
+ serverchannel (pr channel);
+ BOOL VAR no error :: NOT is error;
+ clear error;
+ no error := no error CAND
+ (pr channel <> channel (myself)) CAND
+ (pr channel > 1) CAND
+ (pr channel < 17);
+
+ IF NOT no error
+ THEN cursor (1, 7);
+ put error;
+ putline ("Eingabe korrigiert wiederholen!")
+ FI;
+ enable stop
+ UNTIL no error PER;
+ IF exists task ("canal " + text (pr channel))
+ THEN end (/ ("canal " + text (pr channel)));
+ FI;
+
+. inits:
+ line;
+ IF single task
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+ FI;
+ command dialogue (TRUE);
+ IF name (myself) <> "PRINTER"
+ THEN putline ("Diese Task heißt nicht ""PRINTER"", sondern """ +
+ name (myself) + """ !");
+ IF yes ("Soll die Task in ""PRINTER"" umbenannt werden ?")
+ THEN rename myself ("PRINTER")
+ FI
+ FI;
+ INT VAR choice;
+ service option := service opt.
+
+ single task: (pcb (9) AND 255) = 1.
+
+ main menu:
+ BOOL VAR installed :: FALSE;
+ REP
+ show main menu;
+ get choice;
+ treat choice
+ UNTIL was esc OR installed PER.
+
+ show main menu:
+ page;
+ headline("Hauptmenü 24-Nadel-Drucker");
+ putline (" 1. Brother");
+ putline (" 2. Epson");
+ putline (" 3. NEC");
+ putline (" 4. OKI");
+ putline (" 5. Toshiba").
+
+ get choice:
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Installation abbrechen");
+ ask user (5).
+
+ treat choice:
+ SELECT int (inp) OF
+ CASE 1: brother menu
+ CASE 2: epson menu
+ CASE 3: nec menu
+ CASE 4: oki menu
+ CASE 5: toshiba menu
+ END SELECT.
+
+
+ brother menu:
+ page;
+ headline ("brother - Menü");
+ putline (" 1. M-1724 L");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (1);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ brother m1724l inst
+ FI.
+
+ brother m1724l inst:
+ putline ("brother M-1724 L");
+ line;
+ putline ("Wählen Sie folgende DIP-Schalter Optionen:");
+ putline ("Emulationsmodus IBM Proprinter XL ");
+ putline ("Automatischer Zeilenvorschub Nein ");
+ show control options ("paperfeed, std speed, top margin");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.brother");
+ generate ("brotherm1724l");
+ adjust papersize;
+ adjust quality;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+
+ toshiba menu:
+ page;
+ headline ("TOSHIBA - Menü");
+ putline (" 1. P 321");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (1);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ toshiba p321 inst
+ FI.
+
+ toshiba p321 inst:
+ putline ("TOSHIBA P 321");
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("S3-8 S3-7 S3-5 übrige Schalter");
+ putline ("OFF OFF *) egal ");
+ putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug");
+ show control options ("std speed, paper feed");
+ show material options("slow, fast");
+ show command options ("nlq, draft");
+ ask for quality;
+ ask for papersize;
+ IF all right
+ THEN get fonttable ("fonttab.toshiba.p321");
+ generate ("toshp321");
+ adjust papersize;
+ adjust quality;
+ do ("papersize(21.0,30.48)");
+ installed := TRUE;
+ FI.
+
+
+ epson menu:
+ page;
+ headline ("Epson - Menü");
+ putline (" 1. LQ 850");
+ putline (" 2. LQ 1050");
+ putline (" 3. LQ 1500");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (3);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ SELECT choice OF
+ CASE 1 : lq850 inst
+ CASE 2 : lq850 inst
+ CASE 3 : lq1500 inst
+ END SELECT
+ FI.
+
+ lq850 inst:
+ IF choice = 1
+ THEN putline ("Epson LQ 850")
+ ELSE putline ("Epson LQ 1050")
+ FI;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8");
+ putline ("egal egal egal egal egal egal *1) OFF ");
+ putline ("*1) ON: Einzelblatteinzug, OFF: kein Einzug"); line;
+ putline ("SW2-1 SW2-2 SW2-3 SW2-4 SW2-5 SW2-6 SW2-7 SW2-8");
+ putline ("egal egal *2) OFF OFF");
+ putline ("*2) SW2-2 bis SW2-6 müssen je nach Art der Schnittstelle ");
+ putline (" gesetzt werden (Druckerhandbuch)");
+ show control options ("std speed, top margin, std typeface, paperfeed");
+ show material options ("slow, fast, draft, nlq, roman, sansserif");
+ show command options ("draft, nlq, roman, sansserif");
+ ask for quality;
+ ask for papersize;
+ IF all right
+ THEN get fonttable ("fonttab.epson.lq850");
+ generate ("epsonlq850");
+ adjust quality;
+ adjust papersize;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ lq1500 inst:
+ putline ("EPSON LQ-1500");
+ show control options ("");
+ show material options ("draft, nlq");
+ show command options ("draft, nlq");
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.epson.lq1500");
+ generate ("epsonlq1500");
+ adjust quality;
+ installed := TRUE
+ FI.
+
+ nec menu:
+ page;
+ headline ("NEC - Menü");
+ putline (" 1. PINWRITER P5 ");
+ putline (" 2. PINWRITER P6 ");
+ putline (" 3. PINWRITER P7 ");
+ putline (" 4. PINWRITER P6 PLUS");
+ putline (" 5. PINWRITER P7 PLUS");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (5);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ SELECT choice OF
+ CASE 1 : necp5p7 inst
+ CASE 2 : necp6 inst
+ CASE 3 : necp5p7 inst
+ CASE 4 : necp6plus inst
+ CASE 5 : necp6plus inst
+ END SELECT
+ FI.
+
+ necp5p7 inst:
+ IF choice = 1
+ THEN putline ("NEC PINWRITER P5")
+ ELSE putline ("NEC PINWRITER P7")
+ FI;
+ show control options ("paper feed");
+ show material options ("draft, nlq");
+ show command options ("draft, nlq");
+ ask for quality;
+ ask for papersize;
+ IF all right
+ THEN get fonttable ("fonttab.nec.p5.new");
+ generate ("necp5p7");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE
+ FI.
+
+ necp6 inst:
+ putline ("NEC PINWRITER P6 ");
+ show control options ("paper feed");
+ show material options ("draft, nlq");
+ show command options ("draft, nlq");
+ ask for quality;
+ ask for papersize;
+ IF all right
+ THEN get fonttable ("fonttab.nec.p5.new");
+ generate ("necp6");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE
+ FI.
+
+ necp6plus inst:
+ IF choice = 4
+ THEN putline ("NEC PINWRITER P6 PLUS")
+ ELSE putline ("NEC PINWRITER P7 PLUS")
+ FI;
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:");
+ putline ("CR FUNCTION CR ONLY ");
+ show control options ("std speed, top margin, std typeface, paperfeed");
+ show material options ("slow, fast, draft, nlq, courier, souvenir");
+ show command options ("draft, nlq, courier, souvenir");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.nec.p6+");
+ generate ("necp6+");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE;
+ IF choice = 5 THEN do ("papersize (34.544, 30.48)") FI;
+ FI.
+
+ oki menu:
+ page;
+ headline ("OKI - Menü");
+ putline (" 1. MICROLINE 390 IBM-/EPSON-kompatibel");
+ putline (" 2. MICROLINE 391 IBM-/EPSON-kompatibel");
+ putline (" 3. MICROLINE 393/393C EPSON-kompatibel");
+ putline (" 4. MICROLINE 393/393C IBM-kompatibel");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (4);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ SELECT choice OF
+ CASE 1 : oki ml390 inst
+ CASE 2 : oki ml390 inst
+ CASE 3 : oki ml393eps inst
+ CASE 4 : oki ml393ibm inst
+ END SELECT
+ FI.
+
+ oki ml390 inst:
+ IF choice = 1
+ THEN putline ("OKI Microline 390") ;
+ ELSE putline ("OKI Microline 391") ;
+ FI;
+ line;
+ putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:");
+ putline ("EMULATION MODE EPSON LQ ");
+ putline ("AUTO LF NO ");
+ show control options ("paperfeed, std speed, top margin");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq, courier, kassette");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.oki");
+ generate ("oki390/391");
+ adjust papersize;
+ adjust quality;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+
+ oki ml393eps inst:
+ putline ("OKI Microline 393 EPSON-kompatibel");
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:");
+ putline ("AUTO LF NO ");
+ show control options ("paperfeed, std speed, top margin, std typeface");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq, courier, kassette, schwarz, rot, blau, violett, gelb, orange, grün");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.oki");
+ generate ("oki393/393Ceps");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE
+ FI.
+
+ oki ml393ibm inst:
+ putline ("OKI Microline 393 IBM-kompatibel");
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:");
+ putline ("EMULATION MODE ASCII ");
+ putline ("AUTO LF NO ");
+ show control options ("paperfeed, std speed, top margin, std typeface");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq, courier, kassette, schwarz, rot, blau, violett, gelb, orange, grün");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.oki");
+ generate ("oki393/393Cibm");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE
+ FI.
+
+
+
+generate printer spool:
+ IF service opt = 0
+ THEN forget (generator name, quiet);
+ forget (driver name, quiet)
+ FI;
+ eumel must advertise;
+ cursor (1, 10);
+(* putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+ putline ("die Fonttabelle mit dem Kommando");
+ line;
+ putline (" font table (""" + font tab name + """)");
+ line;
+ putline ("eingestellt werden!!!");
+ line (2);
+ putline ("Hinweis: Dieses Installationsprogramm kann in der Task """ + name (myself) + """");
+ putline (" mit 'treiber einrichten' aufgerufen werden, wenn ein anderer");
+ putline (" Drucker eingesetzt werden soll.");
+ line (2);
+*)
+(* put ("Generierung beendet, weiter mit 'SV'");
+ break (quiet);
+*)
+ putline (" Generierung beendet.");
+ putline (" Weiter: Bitte Taste drücken");
+ WHILE incharety <> "" REP ENDREP;
+ REP UNTIL incharety <> "" ENDREP;
+ break;
+ do ("spool manager (PROC printer)").
+
+ inform about restart:
+ page;
+ putline ("Es ist kein Druckertreiber installiert worden!");
+ line;
+ putline ("Dieses Installationsprogramm kann in der Task """ + name (myself) + """");
+ putline ("mit 'treiber einrichten' erneut aufgerufen werden.");
+ line;
+ pause(50);
+ break.
+
+END PROC treiber einrichten;
+
+PROC headline (TEXT CONST header):
+
+ cursor (13,1);
+ putline ("E U M E L - Druckertreiber - Installations - Programm");
+ cursor (40 - LENGTH header DIV 2, 2);
+ put (header);
+ line (2)
+END PROC headline;
+
+PROC ask user (INT CONST max choice):
+
+ TEXT VAR exit;
+ inp := "";
+ REP
+ cursor (1,23);
+ IF inp = ""
+ THEN put ("Ihre Wahl (Nummer eingeben):")
+ ELSE put ("FEHLER! Eingabe korrigieren:")
+ FI;
+ editget (inp, ""27"", "", exit);
+ was esc := exit = ""27"";
+ UNTIL was esc OR ok PER.
+
+ ok:
+ int (inp) > 0 AND int (inp) <= max choice AND last conversion ok.
+END PROC ask user;
+
+PROC show control options (TEXT CONST options):
+
+ line;
+ putline ("Steuerprozeduren in der Task """ + name (myself) + """:");
+ write ("papersize, std quality");
+ IF options <> ""
+ THEN put (",");
+ putline (options)
+ FI
+END PROC show control options;
+
+PROC show material options (TEXT CONST options):
+
+ line;
+ putline ("Mögliche Materialwerte (#material(""..."")#):");
+ putline (options)
+END PROC show material options;
+
+PROC show command options (TEXT CONST options):
+
+ line;
+ putline ("Mögliche direkte Druckeranweisungen (#""...""#):");
+ putline (options)
+END PROC show command options;
+
+PROC ask for quality:
+
+ line (1);
+ putline ("Standard - Druckqualität:");
+ line;
+ REP out (up);
+ IF yes ("Draft Quality (schneller, aber nicht so schön)")
+ THEN quality := 1; LEAVE ask for quality
+ FI;
+ out (up);
+ IF yes ("Near Letter Quality (schöner, aber langsamer)")
+ THEN quality := 2; LEAVE ask for quality
+ FI;
+ PER
+END PROC ask for quality;
+
+PROC adjust quality:
+
+ IF quality = 1
+ THEN do ("std quality (""draft"")")
+ ELSE do ("std quality (""nlq"")")
+ FI
+END PROC adjust quality;
+
+PROC ask for papersize :
+LET up = ""3""13""5"";
+
+ paper format number := paper format ;
+
+ . paper format :
+ line (1);
+ putline ("Papierformat:");
+ line;
+ REP out (up);
+ IF yes ("Endlospapier, 8 Zoll breit")
+ THEN LEAVE paper format WITH 1 FI;
+ out (up);
+ IF yes ("Endlospapier, 13.2 Zoll breit")
+ THEN LEAVE paper format WITH 2 FI;
+ out (up);
+ IF yes ("Einzelblatteinzug, DINA 4")
+ THEN LEAVE paper format WITH 3 FI;
+ PER;
+ 0
+END PROC ask for papersize;
+
+
+PROC adjust papersize:
+
+ SELECT paper format number OF
+ CASE 1 : do("papersize ( 8.0 * 2.54, 12.0 * 2.54)");
+ do ("paper feed (""tractor"")")
+ CASE 2 : do("papersize (13.2 * 2.54, 12.0 * 2.54)");
+ do ("paper feed (""tractor"")")
+ CASE 3 : do("papersize (21.0, 29.7)");
+ do ("paper feed (""sheet"")")
+ END SELECT
+
+END PROC adjust papersize;
+
+BOOL PROC all right:
+
+ line (3);
+ cursor (1,23);
+ yes ("Soll der ausgewählte Druckertreiber installiert werden")
+END PROC all right;
+
+PROC get fonttable (TEXT CONST name):
+
+ fonttab name := name;
+ from archive ((description file name & module file name & fonttab name)
+ - all);
+ fonttable (fonttab name);
+ command dialogue (FALSE);
+ save (fonttab name, /"configurator");
+ IF service option = 0
+ THEN forget (fonttab name)
+ FI;
+ command dialogue (TRUE);
+END PROC get fonttable;
+
+PROC from archive (THESAURUS CONST files):
+
+ IF highest entry (files) > 0
+ THEN fetch from archive;
+ release (archive);
+ putline ("Archiv abgemeldet !")
+ FI.
+
+ fetch from archive:
+ THESAURUS VAR thes :: files;
+ REP
+ ask for archive;
+ reserve archive;
+ fetch (thes / ALL archive, archive);
+ thes := thes - all
+ UNTIL highest entry (thes) = 0 PER.
+
+ask for archive:
+ TEXT VAR buffer;
+(*line;
+ putline ("Bitte Archiv mit den Dateien");
+ INT VAR index :: 0;
+ REP
+ get (thes, buffer, index);
+ putline (" " + buffer)
+ UNTIL index = 0 PER;
+ putline ("einlegen !");
+ line;
+ putline ("Wenn eingelegt: Taste drücken !");
+ inchar (buffer)*).
+
+reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ disable stop;
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI;
+ enable stop.
+
+END PROC from archive;
+
+THESAURUS OP & (TEXT CONST left, right):
+ THESAURUS VAR result := empty thesaurus;
+ insert (result, left);
+ insert (result, right);
+ result
+END OP &;
+
+THESAURUS OP & (THESAURUS CONST left, TEXT CONST right):
+ THESAURUS VAR result := left;
+ insert (result, right);
+ result
+END OP &;
+
+PROC generate (TEXT CONST name):
+
+ open files;
+ read description;
+ build programme;
+ insert programme;
+ forget files.
+
+ open files:
+ line (5);
+ cursor (1, 20);
+ putline (""4"Bitte warten !");
+ putline (" - Der Treiber wird generiert.");
+ driver name := "printer." + name + "(generiert)";
+ IF exists (driver name)
+ THEN forget (driver name, quiet)
+ FI;
+ FILE VAR des file :: sequential file (modify, description file name),
+ mod file :: sequential file (modify, module file name),
+ driver file :: sequential file (output, driver name).
+
+ read description:
+ to line (des file, 1);
+ col (des file, 1);
+ downety (des file, "$" + name + "$");
+ IF eof (des file)
+ THEN errorstop ("Beschreibung von """ + name + """ nicht im"13""10"" +
+ "Descriptions-File enthalten")
+ FI;
+ TEXT VAR description :: "",
+ record;
+ BOOL VAR done :: FALSE;
+ read record (des file, record);
+ record := subtext (record, col (des file) + LENGTH name + 2);
+ WHILE NOT eof (des file) AND NOT done REP
+ treat record
+ PER.
+
+ treat record:
+ INT VAR dollar pos :: pos (record, "$");
+ IF dollar pos = 0
+ THEN description CAT compress (record);
+ down (des file);
+ read record (des file, record)
+ ELSE description CAT compress (subtext (record, 1, dollar pos - 1));
+ col (des file, dollar pos);
+ done := TRUE;
+ FI.
+
+ build programme:
+ get module name;
+ WHILE still modules REP
+ find module;
+ transfer module;
+ get module name
+ PER.
+
+ get module name:
+ INT VAR semicol pos :: pos (description, ";");
+ TEXT VAR module name;
+ IF semicol pos > 0
+ THEN module name := subtext (description, 1, semicol pos - 1);
+ description := subtext (description, semicol pos + 1)
+ ELSE module name := description;
+ description := ""
+ FI.
+
+ still modules:
+ module name <> "" OR description <> "".
+
+ find module:
+ to line (mod file, 1);
+ col (mod file, 1);
+ downety (mod file, "$" + module name + "$");
+ IF eof (mod file)
+ THEN errorstop ("Modul """ + module name + """ nicht im"13""10"" +
+ "Modul-File enthalten")
+ FI.
+
+ transfer module:
+ done := FALSE;
+ read record (mod file, record);
+ record := subtext (record, col (mod file) + LENGTH module name + 2);
+ WHILE NOT eof (mod file) AND NOT done REP
+ transfer record
+ PER.
+
+ transfer record:
+ dollar pos := pos (record, "$");
+ IF dollar pos = 0
+ THEN write (driver file, compress (record));
+ line (driver file);
+ down (mod file);
+ read record (mod file, record)
+ ELSE write (driver file, compress (subtext (record, 1,
+ dollar pos - 1)));
+ col (mod file, dollar pos);
+ done := TRUE;
+ cout (line no (mod file))
+ FI.
+
+ insert programme:
+ IF online
+ THEN putline (" - Der Treiber wird insertiert.")
+ FI;
+ check off;
+ insert (driver name).
+
+ forget files:
+ IF service option = 0
+ THEN forget (description file name, quiet);
+ forget (module file name, quiet)
+ FI .
+END PROC generate;
+
+END PACKET driver inst 24
+
diff --git a/printer/dotmatrix24/module24 b/printer/dotmatrix24/module24
new file mode 100644
index 0000000..a4957c2
--- /dev/null
+++ b/printer/dotmatrix24/module24
@@ -0,0 +1,1554 @@
+
+(*************************************************************************)
+(* Stand : 03. 1.89 *)
+(* Module-Datei für 24-Nadel-Drucker Version : 0.9 *)
+(* Autor : hjh *)
+(*************************************************************************)
+
+$begin$
+PACKET printer driver
+
+ DEFINES printer,
+ open,
+ close,
+ execute,
+ paper size,
+ std quality,
+
+$headnecp6$ paper feed:
+(* Treiber fuer NEC P6, automatisch generiert *)
+LET underline linetype = 1;
+INT VAR factor 1, factor 2, draft factor 1, draft factor 2;
+
+$headnecp5p7$ paper feed:
+(* Treiber fuer NEC P5, P7 , automatisch generiert *)
+LET underline linetype = 1;
+INT VAR factor 1, factor 2, draft factor 1, draft factor 2;
+
+$headnecp6+$ std speed,
+ top margin,
+ paper feed,
+ std typeface:
+(* Treiber für NEC P6 plus/P7 plus ,automatisch generiert *)
+
+
+$headlq850$ std speed,
+ top margin,
+ paper feed,
+ std typeface:
+(* Treiber für EPSON LQ-850/1050 ,automatisch generiert *)
+
+$headbrotherm1724l$
+ std speed,
+ top margin,
+ paper feed:
+INT VAR vertical factor := 1;
+(* Treiber für BROTHER M-1724L in IBM-Emulation, automatisch generiert *)
+
+$headoki390/391$
+ std speed,
+ top margin,
+ paper feed,
+ std typeface:
+INT VAR vertical factor := 1;
+(* Treiber für OKI MIKROLINE 390/391 ,automatisch generiert *)
+
+$headoki393/393Ceps$
+ std speed,
+ top margin,
+ paper feed,
+ std typeface:
+INT VAR vertical factor := 1;
+(* Treiber für OKI MIKROLINE 393/393C EPSON-kompatibel, automatisch generiert *)
+
+$headoki393/393Cibm$
+ std speed,
+ top margin,
+ paper feed,
+ std typeface:
+INT VAR vertical factor := 1;
+(* Treiber für OKI MIKROLINE 393/393C IBM-kompatibel, automatisch generiert *)
+
+$headtoshp321$ std speed,
+ paper feed:
+(* Treiber für TOSHIBA P321, automatisch generiert *)
+
+$headstarnb24$
+ std speed,
+ top margin,
+ paper feed,
+ std typeface:
+(* Treiber für STAR NB 24-10/15 in Standard Betriebsart automatisch generiert *)
+
+$declarations$
+INT VAR font nr, font bits, modification bits,
+ blankbreite, x rest, high, low, steps;
+REAL VAR x size, y size;
+TEXT VAR buffer :: "";
+BOOL VAR is nlq ;
+TEXT VAR font text :: "";
+TEXT VAR std quality name :: "draft";
+
+. is pica : font bits = 0
+. is elite : font bits = 1
+.;
+
+
+PROC paper size (REAL CONST x, y) :
+
+ x size := x;
+ y size := y;
+END PROC paper size;
+
+papersize (20.32, 30.48);
+
+PROC paper size :
+
+ line;
+ putline ("Papierbreite = " + text (x size, 5, 2) + " cm = " + text (x size / 2.54, 5, 2) + " Zoll");
+ putline ("Papierlaenge = " + text (y size, 5, 2) + " cm = " + text (y size / 2.54, 5, 2) + " Zoll");
+END PROC paper size;
+
+
+
+PROC std quality (TEXT CONST quality) :
+
+ IF quality = "nlq" OR quality = "draft"
+ THEN std quality name := quality
+ ELSE errorstop ("unzulässige Qualitätsbezeichnung")
+ FI
+END PROC std quality;
+
+TEXT PROC std quality :
+
+ std quality name
+END PROC std quality;
+
+
+$topmargin$
+REAL VAR y margin := 0.0 ;
+
+PROC top margin (REAL CONST margin):
+
+ y margin := margin
+END PROC top margin;
+
+REAL PROC top margin:
+
+ y margin
+END PROC top margin;
+
+
+$speed$
+BOOL VAR is slow :: TRUE;
+TEXT VAR std speed name :: "slow";
+
+PROC std speed (TEXT CONST speed) :
+
+ IF speed = "fast" OR speed = "slow"
+ THEN std speed name := speed
+ ELSE errorstop ("unzulässige Geschwindigkeit")
+ FI
+END PROC std speed;
+
+TEXT PROC std speed :
+
+std speed name
+END PROC std speed;
+
+
+$typefacelq850$
+TEXT VAR act typeface name :: "";
+TEXT VAR std typeface name :: "";
+
+. is roman:
+ act typeface name = "roman".
+. is sansserif:
+ act typeface name = "sansserif"
+.;
+
+PROC std typeface (TEXT CONST typeface) :
+
+ IF typeface = "" OR typeface = "roman" OR typeface = "sansserif"
+ THEN std typeface name := typeface
+ ELSE errorstop ("unzulässige Schriftart")
+ FI
+END PROC std typeface;
+
+TEXT PROC std typeface :
+
+ std typeface name
+END PROC std typeface;
+
+
+
+$typefacep6+$
+BOOL VAR is courier :: TRUE;
+TEXT VAR std typeface name :: "courier";
+
+PROC std typeface (TEXT CONST typeface) :
+
+ IF typeface = "courier" OR typeface = "souvenir"
+ THEN std typeface name := typeface
+ ELSE errorstop ("unzulässige Schriftart")
+ FI
+END PROC std typeface;
+
+TEXT PROC std typeface :
+
+ std typeface name
+END PROC std typeface;
+
+$typefaceoki$
+BOOL VAR is courier ;
+TEXT VAR std typeface name :: "";
+
+PROC std typeface (TEXT CONST typeface) :
+
+ IF typeface = "" OR typeface = "courier" OR typeface = "kassette"
+ THEN std typeface name := typeface
+ ELSE errorstop ("unzulässige Schriftart")
+ FI
+END PROC std typeface;
+
+TEXT PROC std typeface :
+
+ std typeface name
+END PROC std typeface;
+
+$typefacestar$
+BOOL VAR is roman ;
+TEXT VAR std typeface name :: "";
+
+PROC std typeface (TEXT CONST typeface) :
+
+ IF typeface = "" OR typeface = "roman" OR typeface = "font1"
+ THEN std typeface name := typeface
+ ELSE errorstop ("unzulässige Schriftart")
+ FI
+END PROC std typeface;
+
+TEXT PROC std typeface :
+
+ std typeface name
+END PROC std typeface;
+
+$feed$
+BOOL VAR is sheet feed :: FALSE;
+
+PROC paper feed (TEXT CONST feeder) :
+
+ IF feeder = "sheet"
+ THEN is sheet feed := TRUE
+ ELIF feeder = "tractor"
+ THEN is sheet feed := FALSE
+ ELSE errorstop ("unzulässige Einzugsart")
+ FI
+END PROC paper feed;
+
+TEXT PROC paper feed:
+ IF is sheet feed
+ THEN "sheet"
+ ELSE "tractor"
+ FI
+END PROC paper feed;
+
+$feedschacht$
+BOOL VAR is sheet feed :: FALSE;
+TEXT VAR feeder name :: "tractor";
+
+PROC paper feed (TEXT CONST feeder) :
+
+ IF feeder = "tractor"
+ THEN feeder name := "tractor";
+ is sheet feed := FALSE
+ ELIF feeder = "sheet" OR feeder = "schacht1"
+ THEN feeder name := "schacht1" ;
+ is sheet feed := TRUE
+ ELIF feeder = "schacht2"
+ THEN feeder name := "schacht2" ;
+ is sheet feed := TRUE
+ ELSE errorstop ("unzulässige Einzugsart")
+ FI
+END PROC paper feed;
+
+TEXT PROC paper feed: feeder name END PROC paper feed;
+
+$open$
+PROC open (INT CONST op code, INT VAR param1, param2):
+
+ SELECT op code OF
+ CASE 1: open document(param1,param2)
+ CASE 2: open page (param1,param2)
+ END SELECT.
+END PROC open ;
+
+
+$opendoch$
+PROC open document (INT VAR x steps,y steps):
+ modification bits := 0;
+ x steps := x step conversion ( x size );
+ y steps := y step conversion ( y size );
+ y steps := (y steps DIV 30) * 30;
+
+$opendochtosh$
+PROC open document (INT VAR x steps,y steps):
+ modification bits := 0;
+ x steps := x step conversion ( x size );
+ y steps := y step conversion ( y size );
+ y steps := (y steps DIV 36) * 36;
+
+$initspeed$
+ IF pos (material, "slow") <> 0
+ THEN is slow := TRUE;
+ ELIF pos (material, "fast") <> 0
+ THEN is slow := FALSE;
+ ELSE is slow := std speed name = "slow"
+ FI;
+
+$opendocp6+$
+ out (""24""27""64""); (* Reset des Druckers *)
+ out (""27"t"1""27"6"27"R"0""); (* Zeichentabelle 4 (Grafik) *)
+ out (""27"O");
+ out (""27"2" + ""27"C" + code (y steps DIV 30)); (* Formularlaenge *)
+ out (""27"x"0""); (* Entwurfsqualität *)
+ IF is sheet feed
+ THEN out (""27""25"4"); (* Sheetmode ein *)
+ FI;
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+ IF pos (material, "courier") <> 0
+ THEN is courier := TRUE ;
+ ELIF pos (material, "souvenir") <> 0
+ THEN is courier := FALSE ;
+ ELSE is courier := std typeface name = "courier"
+ FI;
+END PROC open document ;
+
+$opendocp5p7$
+ out (""24""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""); (* Amerikanischer Zeichensatz *)
+ out (""27"C" + code (y steps DIV 30)); (* Formularlaenge *)
+ out (""27"x"0""); (* Entwurfsqualität *)
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+ IF is sheet feed
+ THEN out (""27""25"4"); (* Sheetmode ein *)
+ center paper ;
+ FI;
+
+ . center paper :
+ INT CONST x steps in chars := x steps DIV x step conversion (2.54 / 10.0),
+ left margin := (136 - x steps in chars) DIV 2;
+ out (""27"P");
+ out (""27"l"); out (code (left margin + 1));
+END PROC open document ;
+
+$opendocp6$
+ out (""24""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""); (* Amerikanischer Zeichensatz *)
+ out (""27"C" + code (y steps DIV 30)); (* Formularlaenge *)
+ out (""27"x"0""); (* Entwurfsqualität *)
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+ IF is sheet feed
+ THEN out (""27""25"4"); (* Sheetmode ein *)
+ FI;
+END PROC open document ;
+
+$opendoclq850$
+ out (""24""27""64""); (* Reset des Druckers *)
+ out (""27"t"1""27"6"27"R"0""); (* Zeichentabelle 4 (Grafik) *)
+ out (""27"O");
+ out (""27"2" + ""27"C" + code (y steps DIV 30)); (* Formularlaenge *)
+ out (""27"x"0""); (* Entwurfsqualität *)
+ IF is sheet feed
+ THEN out (""27""25"4"); (* Sheetmode ein *)
+ FI;
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+ IF pos (material, "roman") <> 0
+ THEN act typeface name := "roman"
+ ELIF pos (material, "sansserif") <> 0
+ THEN act typeface name := "sansserif"
+ ELSE act typeface name := std typeface name
+ FI;
+END PROC open document ;
+
+$opendocokieps$
+ out (""24""27""64""); (* Reset des Druckers *)
+ out (""27"t"1""27"6"27"R"0""); (* Zeichentabelle 4 (Grafik) *)
+ out (""27"O");
+ out (""27"2" + ""27"C" + code (y steps DIV 30)); (* Formularlaenge *)
+ out (""27"x"0""); (* Entwurfsqualität *)
+ IF is sheet feed
+ THEN IF feeder name = "schacht2"
+ THEN out (""27""25"2")
+ ELSE out (""27""25"1")
+ FI
+ FI; (* Sheetmode ein *)
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+ IF pos (material, "courier") <> 0
+ THEN is courier := TRUE ;
+ ELIF pos (material, "kassette") <> 0
+ THEN is courier := FALSE ;
+ ELSE is courier := std typeface name = "courier"
+ FI;
+END PROC open document ;
+
+$opendoctosh$
+ out (""24""27"5"0""27"4"27"O"); (* Reset des Druckers *)
+ out (""27"6"); (* Zeichensatz *)
+ out (""27"A"12""27"2") ;
+ out (""27"C" + code (y steps DIV 36)); (* Formularlaenge *)
+ out (""27"x"0""); (* Entwurfsqualität *)
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+END PROC open document ;
+
+$opendocbrother$
+ out (""24""27"5"0""27"4"27"O"); (* Reset des Druckers *)
+ out (""27"6" + ""27"R"0""); (* Zeichensatz II ascii *)
+ out (""27"A"10""27"2") ; (* Zeilenabstand *)
+ out (""27"C" + code (y steps DIV 36)); (* Formularlaenge *)
+ IF is sheet feed
+ THEN out (""27""25"4")
+ FI; (* Sheetmode ein *)
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+END PROC open document ;
+
+$opendocokiibm$
+ out (""24""27"5"0""27"4"27"O"); (* Reset des Druckers *)
+ out (""27"6" + ""27"!"64""); (* Zeichensatz II ascii *)
+ out (""27""91""92""4""0""0""0""180""); (* 1/180 *)
+ out (""27"A"12""27"2") ; (* Zeilenabstand *)
+ out (""27"C" + code (y steps DIV 36)); (* Formularlaenge *)
+ IF is sheet feed
+ THEN IF feeder name = "schacht2"
+ THEN out (""27""25"2")
+ ELSE out (""27""25"1")
+ FI
+ FI; (* Sheetmode ein *)
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+ IF pos (material, "courier") <> 0
+ THEN is courier := TRUE ;
+ ELIF pos (material, "kassette") <> 0
+ THEN is courier := FALSE ;
+ ELSE is courier := std typeface name = "courier"
+ FI;
+END PROC open document ;
+
+$opendocstar$
+ out (""24""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""); (* amerikanischer Zeichensatz *)
+ out (""27"O");
+ out (""27"2" + ""27"C" + code (y steps DIV 30)); (* Formularlaenge *)
+ out (""27"x"0""); (* Entwurfsqualität *)
+ IF is sheet feed
+ THEN IF feeder name = "schacht2"
+ THEN out (""27""25"2")
+ ELSE out (""27""25"1")
+ FI
+ FI; (* Sheetmode ein *)
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+ IF pos (material, "roman") <> 0
+ THEN is roman := TRUE ;
+ ELIF pos (material, "font1") <> 0
+ THEN is roman := FALSE ;
+ ELSE is roman := std typeface name = "roman"
+ FI;
+END PROC open document ;
+
+$openpagetosh$
+PROC open page (INT VAR x start , y start):
+
+ x start := 0;
+ IF is sheet feed
+ THEN y start := y step conversion (2.54) (* 1 Inch *)
+ ELSE y start := 0;
+ FI;
+ x rest := 0;
+ out (""13"");
+END PROC open page;
+
+$openpage$
+PROC open page (INT VAR x start , y start):
+
+ x start := 0 ;
+ y start := y step conversion (y margin) ;
+ x rest := 0;
+ out (""13"").
+END PROC open page;
+
+$openpagep5-7$
+PROC open page (INT VAR x start , y start):
+
+ x start := 0;
+ IF is sheet feed
+ THEN y start := y step conversion (8.466667e-1) (* 2/6 Inch *)
+ ELSE y start := 0;
+ FI;
+ x rest := 0;
+ out (""13"");
+END PROC open page;
+
+$close$
+
+PROC close (INT CONST op code, INT CONST param1) :
+
+ SELECT op code OF
+ CASE 1: close document
+ CASE 2: close page (param1)
+ END SELECT.
+
+close document :
+.
+END PROC close ;
+
+$closepage$
+PROC close page (INT CONST remaining y steps) :
+ IF remaining y steps > 0
+ THEN out (""12"")
+ ELIF is sheet feed
+ THEN out (""27""25"R")
+ FI;
+END PROC close page;
+
+$closepagetosh$
+PROC close page (INT CONST remaining y steps) :
+ IF is sheet feed
+ THEN out (""12"")
+ ELIF remaining y steps > 0
+ THEN out (""12"")
+ FI;
+END PROC close page;
+
+$execute$
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+
+SELECT op code OF
+ CASE 1: write text
+ CASE 2: write cmd
+ CASE 3: carriage return
+ CASE 4: move
+ CASE 5: draw
+ CASE 6: on
+ CASE 7: off
+ CASE 8: type
+END SELECT.
+
+from : param1.
+to : param2.
+
+ write text :
+ out subtext (string, from, to).
+
+$cmdp6+$
+ write cmd :
+ buffer := subtext (string, from, to);
+ IF buffer = "nlq"
+ THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+ ELIF buffer = "draft"
+ THEN IF is nlq THEN is nlq := FALSE; switch to draft FI;
+ ELIF buffer = "courier"
+ THEN IF NOT is courier THEN is courier := TRUE; switch to courier FI;
+ ELIF buffer = "souvenir"
+ THEN IF is courier THEN is courier := FALSE; switch to souvenir FI;
+ ELIF buffer = "schwarz"
+ THEN out (""27"r0")
+ ELIF buffer = "rot"
+ THEN out (""27"r1")
+ ELIF buffer = "blau"
+ THEN out (""27"r2")
+ ELIF buffer = "violett"
+ THEN out (""27"r3")
+ ELIF buffer = "gelb"
+ THEN out (""27"r4")
+ ELIF buffer = "orange"
+ THEN out (""27"r5")
+ ELIF buffer = "grün"
+ THEN out (""27"r6")
+ ELSE out (buffer)
+ FI.
+
+$cmdp5-7$
+ write cmd :
+ buffer := subtext (string, from, to);
+ IF buffer = "nlq"
+ THEN IF NOT is nlq THEN switch to nlq FI;
+ is nlq := TRUE;
+ ELIF buffer = "draft"
+ THEN IF is nlq THEN switch to draft FI;
+ is nlq := FALSE;
+ ELSE out (buffer);
+ FI;.
+
+$cmdlq850$
+ write cmd :
+ buffer := subtext (string, from, to);
+ IF buffer = "nlq"
+ THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+ ELIF buffer = "draft"
+ THEN IF is nlq THEN is nlq := FALSE; switch to draft FI;
+ ELIF buffer = "roman"
+ THEN IF NOT is roman THEN act typeface name := "roman" ;
+ switch to roman FI;
+ ELIF buffer = "sansserif"
+ THEN IF NOT is sansserif THEN act typeface name := "sansserif";
+ switch to sansserif FI;
+ ELSE out (buffer)
+ FI.
+
+$cmdoki$
+ write cmd :
+ buffer := subtext (string, from, to);
+ IF buffer = "nlq"
+ THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+ ELIF buffer = "draft"
+ THEN IF is nlq THEN is nlq := FALSE; switch to draft FI;
+ ELIF buffer = "courier"
+ THEN IF NOT is courier THEN is courier := TRUE; switch to courier FI;
+ ELIF buffer = "kassette"
+ THEN IF is courier THEN is courier := FALSE; switch to kassette FI;
+ ELIF buffer = "schwarz"
+ THEN out (""27"r0")
+ ELIF buffer = "rot"
+ THEN out (""27"r1")
+ ELIF buffer = "blau"
+ THEN out (""27"r2")
+ ELIF buffer = "violett"
+ THEN out (""27"r3")
+ ELIF buffer = "gelb"
+ THEN out (""27"r4")
+ ELIF buffer = "orange"
+ THEN out (""27"r5")
+ ELIF buffer = "grün"
+ THEN out (""27"r6")
+ ELSE out (buffer)
+ FI.
+
+$cmdtosh$
+ write cmd :
+ buffer := subtext (string, from, to);
+ IF buffer = "nlq"
+ THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+ ELIF buffer = "draft"
+ THEN IF is nlq THEN is nlq := FALSE; switch to draft FI;
+ ELSE out (buffer);
+ FI;.
+
+$cmdstar$
+ write cmd :
+ buffer := subtext (string, from, to);
+ IF buffer = "nlq"
+ THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+ ELIF buffer = "draft"
+ THEN IF is nlq THEN is nlq := FALSE; switch to draft FI;
+ ELIF buffer = "roman"
+ THEN IF NOT is roman THEN is roman := TRUE; switch to roman FI;
+ ELIF buffer = "font1"
+ THEN IF is roman THEN is roman := FALSE; switch to font1 FI;
+ FI.
+
+$crs$
+ carriage return :
+ x rest := 0;
+ out (""13"").
+
+$move$
+x steps : param1.
+y steps : param2.
+
+move :
+ IF x steps < 0 OR y steps < 0 THEN stop FI;
+ IF x steps > 0 THEN x move FI;
+ IF y steps > 0 THEN y move FI.
+
+$stdmove$
+x move :
+ x rest INCR x steps;
+ high := (x rest) DIV blankbreite;
+ x rest := (x rest) MOD blankbreite;
+ steps := x rest DIV 3;
+ IF high > 0 THEN high TIMESOUT " " FI;
+ IF steps > 0 AND is slow
+ THEN IF is underline THEN out (" "8"") FI;
+ out (""27"Y" + code (steps) + ""0""); (* 1/360 *)
+ steps TIMESOUT ""0"";
+ x rest := x rest MOD 3
+ FI.
+
+is underline:
+ bit (modification bits,7).
+
+y move :
+ IF y steps > 0
+ THEN high := y steps DIV 255;
+ low := y steps MOD 255;
+ IF high > 0 THEN high TIMESOUT ""27"J"255"" FI; (* 1/180 *)
+ IF low > 0 THEN out (""27"J" + code (low)) FI;
+ FI.
+
+draw :
+ IF x steps < 0 OR y steps <> 0 OR linetype <> 1
+ THEN stop
+ ELIF x steps > 0
+ THEN x draw
+ FI.
+
+x draw :
+ x rest INCR x steps ;
+ steps := x steps DIV 3 ;
+ IF steps > 0 THEN
+ x rest := x steps MOD 3 ;
+ out (""27"Y");
+ out (code (steps MOD 256));
+ out (code (steps DIV 256));
+ steps TIMESOUT ""1"";
+ FI.
+
+$movep5-7$
+ x move :
+ x rest INCR x steps;
+ IF not is underline
+ THEN simple x move
+ ELSE underline x move
+ FI;
+
+ . not is underline :
+ NOT bit (modification bits, 7)
+
+ . simple x move :
+ high := x rest DIV factor 1;
+ x rest := x rest MOD factor 1;
+ out (""27"\");
+ out (code (high MOD 256));
+ out (code (high DIV 256));
+
+ . underline x move :
+ high := x rest DIV factor 2;
+ x rest := x rest MOD factor 2;
+ IF high < blankbreite
+ THEN stop
+ ELSE low := high MOD 127;
+ high := high DIV 127;
+ IF low >= blankbreite
+ THEN low DECR blankbreite;
+ ELSE high DECR 1;
+ low DECR (blankbreite - 127);
+ FI;
+ IF high > 0
+ THEN out (""27" ");
+ out (code (127 - blankbreite));
+ high TIMESOUT " ";
+ FI;
+ out (""27" ");
+ out (code (low));
+ out (" "27" "0"");
+ FI;
+. y move:
+
+ low := y steps MOD 255;
+ high := y steps DIV 255;
+ IF high > 0 THEN high TIMESOUT (""27"J"255"") FI;
+ IF low > 0 THEN out (""27"J" + code (low)) FI;
+
+. draw :
+ IF x steps < 0 OR y steps <> 0
+ THEN stop
+ ELIF x steps > 0
+ THEN x draw
+ FI;
+
+ . x draw :
+ x rest INCR x steps;
+ steps := x rest DIV 4;
+ x rest := x rest MOD 4;
+ IF steps > 0
+ THEN low := steps MOD 256;
+ high := steps DIV 256;
+ out (""27"*"39"");
+ out (code (low));
+ out (code (high));
+ steps TIMESOUT dot;
+ FI;
+
+ . dot :
+ IF linetype = underline linetype
+ THEN ""000""000""001""
+ ELSE ""000""000""048""
+ FI.
+
+
+$onoff$
+ modification : param1
+.
+ on :
+ buffer := on string (modification);
+ IF buffer <> ""
+ THEN modification bits := modification bits OR code (buffer);
+ switch to font;
+ ELSE stop
+ FI
+
+.
+ off :
+ buffer := off string (modification);
+ IF buffer <> ""
+ THEN modification bits := modification bits XOR code (buffer);
+ switch to font;
+ ELSE stop
+ FI.
+
+$typep6+$
+ type :
+ font nr := param1 ;
+ buffer := font string (font nr);
+ font bits := code (buffer SUB 3);
+ font text := subtext (buffer, 4);
+ blankbreite := char pitch (font nr, " ") ;
+ IF is courier
+ THEN switch to courier
+ ELSE switch to souvenir
+ FI ;
+ switch to font;
+ IF is nlq
+ THEN switch to nlq
+ ELSE switch to draft
+ FI;
+
+. switch to font :
+ out (""27"!");
+ out (code (font bits OR modification bits));
+ out (font text);
+
+. switch to nlq :
+ out (""27"x"1"");
+
+. switch to draft :
+ out (""27"x"0"");
+
+. switch to courier :
+ out (""27"k"0"") ;
+
+. switch to souvenir :
+ out (""27"k"15"") ;
+END PROC execute;
+
+$typeplq850$
+ type :
+ font nr := param1 ;
+ buffer := font string (font nr);
+ font bits := code (buffer SUB 3);
+ font text := subtext (buffer, 4);
+ blankbreite := char pitch (font nr, " ") ;
+ IF is roman
+ THEN switch to roman
+ ELSE switch to sansserif
+ FI ;
+ switch to font;
+ IF is nlq
+ THEN switch to nlq
+ ELSE switch to draft
+ FI;
+
+. switch to font :
+ out (""27"!");
+ out (code (font bits OR modification bits));
+ out (font text);
+
+. switch to nlq :
+ out (""27"x"1"");
+
+. switch to draft :
+ out (""27"x"0"");
+
+. switch to roman :
+ out (""27"k"0"") ;
+
+. switch to sansserif :
+ out (""27"k"1"") ;
+END PROC execute;
+
+$typeokieps$
+ type :
+ font nr := param1 ;
+ buffer := font string (font nr);
+ font bits := code (buffer SUB 3);
+ vertical factor := code (buffer SUB 1);
+ font text := subtext (buffer, 4);
+ blankbreite := char pitch (font nr, " ") ;
+ IF is courier
+ THEN switch to courier
+ ELSE switch to kassette
+ FI ;
+ switch to font;
+ IF is nlq
+ THEN switch to nlq
+ ELSE switch to draft
+ FI;
+
+. switch to font :
+ out (""27"!");
+ out (code (font bits OR modification bits));
+ IF vertical factor = 2
+ THEN out (""27"w"1"")
+ ELSE out (""27"w"0"")
+ FI;
+ out (font text);
+
+. switch to nlq :
+ out (""27"x"1"");
+
+. switch to draft :
+ out (""27"x"0"");
+
+. switch to courier :
+ out (""27"k"0"") ;
+
+. switch to kassette :
+ out (""27"k"127"") ;
+END PROC execute;
+
+$typep5-7$
+ type :
+ font nr := param1;
+ buffer := font string (font nr);
+ factor 1 := code (buffer SUB 1); (* 720 / Mikroschritte pro Inch mit ESC \ *)
+ factor 2 := code (buffer SUB 2); (* 720 / Mikroschritte pro Inch mit ESC Blank *)
+ font bits := code (buffer SUB 3);
+ font text := subtext (buffer, 4);
+ blankbreite := char pitch (font nr, " ") DIV factor 2;
+ switch to font;
+ IF is nlq THEN switch to nlq FI;
+
+END PROC execute;
+
+
+PROC switch to font :
+
+ out (""27"!");
+ out (code (font bits OR modification bits));
+ out (font text);
+
+END PROC switch to font;
+
+
+PROC switch to nlq :
+
+ IF is pica OR is elite
+ THEN draft factor 1 := factor 1;
+ factor 1 := 4;
+ draft factor 2 := factor 2;
+ IF is pica
+ THEN factor 2 := 4 * factor 2 DIV 6;
+ blankbreite := char pitch (font nr, " ") DIV factor 2;
+ FI;
+ out (""27"x"1"");
+ ELSE out (""27"x"0"");
+ FI;
+
+END PROC switch to nlq;
+
+
+PROC switch to draft :
+
+ IF is pica OR is elite
+ THEN factor 1 := draft factor 1;
+ factor 2 := draft factor 2;
+ out (""27"x"0"");
+ FI;
+
+END PROC switch to draft;
+
+$typetosh$
+ type :
+ font nr := param1 ;
+ buffer := font string (font nr);
+ font bits := code (buffer SUB 3);
+ font text := subtext (buffer, 4);
+ blankbreite := char pitch (font nr, " ") ;
+ IF is nlq
+ THEN switch to nlq
+ ELSE switch to draft
+ FI;
+ switch to font;
+
+. switch to font :
+ INT VAR master select bits := font bits OR modification bits ;
+ IF bit (master select bits,0)
+ THEN out (""27":")
+ ELSE out (""18"")
+ FI;
+ IF bit (master select bits,1)
+ THEN out (""27"I"2""27"P"1"")
+ ELSE out (""27"P"0"")
+ FI;
+ IF bit (master select bits,2)
+ THEN out (""27""15"")
+ FI;
+ IF bit (master select bits,3)
+ THEN out (""27"E")
+ ELSE out (""27"F")
+ FI;
+ IF bit (master select bits,4)
+ THEN out (""27"G")
+ ELSE out (""27"H")
+ FI;
+ IF bit (master select bits,5)
+ THEN out (""27"W"1"")
+ ELSE out (""27"W"0"")
+ FI;
+ IF bit (master select bits,6)
+ THEN
+ ELSE
+ FI;
+ IF bit (master select bits,7)
+ THEN out (""27"-"1"")
+ ELSE out (""27"-"0"")
+ FI;
+ out (font text);
+
+
+. switch to nlq :
+ out (""27"I"2"");
+
+. switch to draft :
+ out (""27"I"1"");
+
+END PROC execute;
+
+$typeokiibm$
+ type :
+ font nr := param1 ;
+ buffer := font string (font nr);
+ vertical factor := code (buffer SUB 1);
+ font bits := code (buffer SUB 3);
+ font text := subtext (buffer, 4);
+ blankbreite := char pitch (font nr, " ") ;
+ IF is courier
+ THEN switch to courier
+ ELSE switch to kassette
+ FI ;
+ IF is nlq
+ THEN switch to nlq
+ ELSE switch to draft
+ FI;
+ switch to font;
+
+. switch to font :
+ INT VAR master select bits := font bits OR modification bits ;
+ IF bit (master select bits,0)
+ THEN out (""27":")
+ ELSE out (""18"")
+ FI;
+ IF bit (master select bits,1)
+ THEN out (""27"I"2""27"P"1"")
+ ELSE out (""27"P"0"")
+ FI;
+ IF bit (master select bits,2)
+ THEN out (""27""15"")
+ FI;
+ IF bit (master select bits,3)
+ THEN out (""27"E")
+ ELSE out (""27"F")
+ FI;
+ IF bit (master select bits,4)
+ THEN out (""27"G")
+ ELSE out (""27"H")
+ FI;
+ IF bit (master select bits,5)
+ THEN out (""27"W"1"")
+ ELSE out (""27"W"0"")
+ FI;
+ IF bit (master select bits,6)
+ THEN out(""27"%G")
+ ELSE out(""27"%H")
+ FI;
+ IF bit (master select bits,7)
+ THEN out (""27"-"1"")
+ ELSE out (""27"-"0"")
+ FI;
+ IF vertical factor = 2
+ THEN out (""27""91""64""4""0""0""0""2""0"")
+ ELSE out (""27""91""64""4""0""0""0""1""0"")
+ FI;
+ out (font text);
+
+
+. switch to nlq :
+ out (""27"I"2"");
+
+. switch to draft :
+ out (""27"I"0"");
+
+. switch to courier :
+ out (""27"k"0"") ;
+
+. switch to kassette :
+ out (""27"k"127"") ;
+END PROC execute;
+
+$typebrother$
+ type :
+ font nr := param1 ;
+ buffer := font string (font nr);
+ vertical factor := code (buffer SUB 1);
+ font bits := code (buffer SUB 3);
+ font text := subtext (buffer, 4);
+ blankbreite := char pitch (font nr, " ") ;
+ IF is nlq
+ THEN switch to nlq
+ ELSE switch to draft
+ FI;
+ switch to font;
+
+. switch to font :
+ INT VAR master select bits := font bits OR modification bits ;
+ IF bit (master select bits,0)
+ THEN out (""27":")
+ ELSE out (""18"")
+ FI;
+ IF bit (master select bits,1)
+ THEN out (""27"I"2""27"P"1"")
+ ELSE out (""27"P"0"")
+ FI;
+ IF bit (master select bits,2)
+ THEN out (""27""15"")
+ FI;
+ IF bit (master select bits,3)
+ THEN out (""27"E")
+ ELSE out (""27"F")
+ FI;
+ IF bit (master select bits,4)
+ THEN out (""27"G")
+ ELSE out (""27"H")
+ FI;
+ IF bit (master select bits,5)
+ THEN out (""27"W"1"")
+ ELSE out (""27"W"0"")
+ FI;
+ IF bit (master select bits,6)
+ THEN
+ ELSE
+ FI;
+ IF bit (master select bits,7)
+ THEN out (""27"-"1"")
+ ELSE out (""27"-"0"")
+ FI;
+ IF vertical factor = 2
+ THEN out (""27""91""64""4""0""0""0""2""0"")
+ ELSE out (""27""91""64""4""0""0""0""1""0"")
+ FI;
+ out (font text);
+
+. switch to nlq :
+ out (""27"I"2"");
+
+. switch to draft :
+ out (""27"I"0"");
+
+END PROC execute;
+
+$typestar$
+ type :
+ font nr := param1 ;
+ buffer := font string (font nr);
+ font bits := code (buffer SUB 3);
+ font text := subtext (buffer, 4);
+ blankbreite := char pitch (font nr, " ") ;
+ IF is roman
+ THEN switch to roman
+ ELSE switch to font1
+ FI ;
+ switch to font;
+ IF is nlq
+ THEN switch to nlq
+ ELSE switch to draft
+ FI;
+
+. switch to font :
+ out (""27"!");
+ out (code (font bits OR modification bits));
+ out (font text);
+
+. switch to nlq :
+ out (""27"x"1"");
+
+. switch to draft :
+ out (""27"x"0"");
+
+. switch to roman :
+ out (""27"k"0"") ;
+
+. switch to font1 :
+ out (""27"k"1"") ;
+END PROC execute;
+
+
+
+$printerlq1500$
+PACKET printer driver
+
+(**************************************************************************)
+(* Stand : 29.07.86 *)
+(* EPSON LQ-1500 Version : 4 *)
+(* Autor : Rudolf Ruland *)
+(* geändert am 15.12.88 hjh *)
+(**************************************************************************)
+
+ DEFINES printer,
+ open,
+ close,
+ execute,
+
+ paper size,
+ std quality:
+
+LET
+(* underline = 1,
+ bold = 2,
+ italics = 4,
+ reverse = 8, *)
+
+ underline linetype = 1,
+
+ c document = 1,
+ c page = 2,
+
+ c write text = 1,
+ c write cmd = 2,
+ c carriage return = 3,
+ c move = 4,
+ c draw = 5,
+ c on = 6,
+ c off = 7,
+ c type = 8;
+
+INT VAR rest, high, low, factor;
+BOOL VAR is nlq, factor was 6, condensed;
+REAL VAR x size, y size;
+TEXT VAR std quality name, buffer;
+
+(*********************************************************************)
+
+paper size (13.6 * 2.54, 12.0 * 2.54);
+std quality ("draft");
+
+PROC paper size (REAL CONST x, y) :
+
+ x size := x;
+ y size := y;
+
+END PROC paper size;
+
+PROC paper size :
+
+ line;
+ putline ("Papierbreite = " + text (x size, 5, 2) + " cm = " + text (x size / 2.54, 5, 2) + " Zoll");
+ putline ("Papierlaenge = " + text (y size, 5, 2) + " cm = " + text (y size / 2.54, 5, 2) + " Zoll");
+
+END PROC paper size;
+
+
+PROC std quality (TEXT CONST quality) :
+
+ IF quality = "nlq" OR quality = "draft"
+ THEN std quality name := quality;
+ ELSE errorstop ("unzulaessige Betriebsart")
+ FI;
+
+END PROC std quality;
+
+TEXT PROC std quality : std quality name END PROC std quality;
+
+(*********************************************************************)
+
+PROC open (INT CONST op code, INT VAR param1, param2) :
+
+SELECT op code OF
+ CASE c document : open document
+ CASE c page : open page
+END SELECT;
+
+
+. x steps : param1
+. y steps : param2
+.
+ open document :
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+ factor := 0;
+ factor was 6 := FALSE;
+ condensed := FALSE;
+ x steps := x step conversion ( x size );
+ y steps := y step conversion ( y size );
+ y steps := (y steps DIV 30) * 30;
+ out (""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""); (* Amerikanischer Zeichensatz *)
+ out (""27"C" + code (y steps DIV 30)); (* Formularlaenge *)
+ out (""27"x"0""); (* Entwurfsqualität *)
+
+
+. x start : param1
+. y start : param2
+.
+ open page :
+ x start := 0;
+ y start := 0;
+ rest := 0;
+ out (""13"");
+
+END PROC open;
+
+
+PROC close (INT CONST op code, INT CONST param1) :
+
+SELECT op code OF
+ CASE c document : close document
+ CASE c page : close page
+END SELECT;
+
+.
+ close document :
+
+
+. remaining y steps : param1
+.
+ close page :
+ IF remaining y steps > 0 THEN out (""12"") FI
+
+END PROC close;
+
+
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+
+SELECT op code OF
+ CASE c write text : write text
+ CASE c write cmd : write cmd
+ CASE c carriage return : carriage return
+ CASE c move : move
+ CASE c draw : draw
+ CASE c on : on
+ CASE c off : off
+ CASE c type : type
+END SELECT
+
+
+. from : param1
+. to : param2
+.
+ write text :
+ out subtext (string, from, to)
+
+.
+ write cmd :
+ buffer := subtext (string, from, to);
+ IF buffer = "nlq"
+ THEN is nlq := TRUE;
+ near letter quality;
+ ELIF buffer = "draft"
+ THEN is nlq := FALSE;
+ draft quality;
+ ELSE out (buffer);
+ FI;
+
+ . near letter quality :
+ IF factor = 6
+ THEN factor was 6 := TRUE;
+ factor := 4;
+ ELSE factor was 6 := FALSE;
+ FI;
+ IF condensed
+ THEN out (""27"x"0"")
+ ELSE out (""27"x"1"")
+ FI;
+
+ . draft quality :
+ IF factor was 6
+ THEN factor was 6 := FALSE;
+ factor := 6;
+ FI;
+ out (""27"x"0"");
+
+
+(*. x steps to left margin : param1*)
+.
+ carriage return :
+ rest := 0;
+ out (""13"");
+
+
+. x steps : param1
+. y steps : param2
+.
+ move :
+ IF x steps < 0 OR y steps < 0
+ THEN stop
+ ELIF x steps > 0
+ THEN x move
+ ELIF y steps > 0
+ THEN y move
+ FI;
+
+ . x move :
+ high := (x steps + rest) DIV factor;
+ rest := (x steps + rest) MOD factor;
+ out (""27"\");
+ out (code (high MOD 256));
+ out (code (high DIV 256));
+
+ . y move :
+ high := y steps DIV 255;
+ low := y steps MOD 255;
+ IF high > 0 THEN high TIMESOUT ""27"J"255"" FI;
+ IF low > 0 THEN out (""27"J"); out (code (low)) FI;
+
+.
+ draw :
+ IF x steps < 0 OR y steps <> 0 OR linetype <> underline linetype
+ THEN stop
+ ELIF x steps > 0
+ THEN x draw
+ FI;
+
+ . x draw :
+ high := (x steps + rest) DIV 6;
+ rest := (x steps + rest) MOD 6;
+ IF high > 0
+ THEN low := high MOD 255;
+ high := high DIV 255;
+ out (""27"V");
+ out (code (low));
+ out (""27"*"1""1""0""1""27"V"0"");
+ FOR low FROM 1 UPTO high
+ REP out (""27"V"255""27"*"1""1""0""1""27"V"0"") PER;
+ FI;
+
+
+. modification : param1
+.
+ on :
+ IF on string (modification) <> ""
+ THEN out (on string (modification))
+ ELSE stop
+ FI
+
+.
+ off :
+ IF off string (modification) <> ""
+ THEN out (off string (modification))
+ ELSE stop
+ FI
+
+
+. font nr : param1
+.
+ type :
+ buffer := font string (font nr);
+ out (buffer);
+ factor := pitch factor;
+ IF is nlq THEN near letter quality FI;
+
+ . pitch factor : (* Mikroschritt *)
+ INT CONST font bits := code (buffer SUB 3);
+ IF bit (font bits, 1)
+ THEN condensed := FALSE; 2 (* proportional 1/360 Inch *)
+ ELIF pos (buffer, ""27"x"1"") <> 0
+ THEN condensed := FALSE; 4 (* near letter 1/180 Inch *)
+ ELIF bit (font bits, 2)
+ THEN condensed := TRUE; 3 (* condensed 1/240 Inch *)
+ ELIF bit (font bits, 0)
+ THEN condensed := FALSE; 4 (* elite 1/180 Inch *)
+ ELSE condensed := FALSE; 6 (* pica 1/120 Inch *)
+ FI
+
+END PROC execute;
+
+
+$end$
+INT VAR reply; DATASPACE VAR ds; FILE VAR file;
+
+PROC printer:
+
+ disable stop;
+ continue (server channel);
+ check error (error message);
+ ds := nilspace;
+ REP forget (ds);
+ execute print;
+ IF is error AND online THEN put error; clear error; FI;
+ PER;
+END PROC printer;
+
+PROC execute print:
+
+ LET ack = 0, fetch code = 11, file type = 1003;
+ enable stop;
+ ds := nilspace;
+ call (father, fetch code, ds, reply);
+ IF reply = ack CAND type (ds) = file type
+ THEN file := sequential file (input, ds);
+ print (file,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+END PROC execute print;
+
+PROC check error(TEXT CONST message):
+
+ IF is error
+ THEN clear error; rename myself (message);
+ IF is error THEN end(myself) FI;
+ pause (9000); end(myself);
+ FI;
+END PROC check error;
+
+END PACKET printerdriver
+
+
diff --git a/printer/dotmatrix24/printer.24.nadel b/printer/dotmatrix24/printer.24.nadel
new file mode 100644
index 0000000..579f67f
--- /dev/null
+++ b/printer/dotmatrix24/printer.24.nadel
@@ -0,0 +1,776 @@
+
+(*************************************************************************)
+(* Installationsprogramm für Stand : 3. 1.89 *)
+(* 24-Nadel Drucker Version : 0.9 *)
+(* Autor : hjh *)
+(*************************************************************************)
+
+PACKET driver inst 24
+
+
+ DEFINES treiber einrichten:
+
+
+LET up = ""3""13""5"",
+
+ generator name = "printer.24.nadel",
+
+ description file name = "beschreibungen24",
+ module file name = "module24";
+
+
+INT VAR pr channel,
+ quality,
+ paper format number,
+ service option;
+TEXT VAR fonttab name :: "",
+ driver name :: "";
+TEXT VAR inp;
+BOOL VAR was esc;
+
+treiber einrichten
+
+PROC treiber einrichten:
+
+ treiber einrichten (0)
+END PROC treiber einrichten;
+
+PROC treiber einrichten (INT CONST service opt):
+
+ ask for print channel;
+ main menu;
+ IF installed
+ THEN generate printer spool
+ ELSE inform about restart
+ FI.
+
+ ask for printchannel:
+ inits;
+ page;
+ headline ("Druckerkanal - Einstellung");
+ cursor (1, 15);
+ putline ("Hinweis: Die Druckerkanalnummer kann auch nachträglich mit");
+ putline (" 'serverchannel (Kanalnummer)' in der Task """ +
+ name (myself) + """");
+ putline (" verändert werden.");
+ REP
+ cursor (1, 10);
+ put (""5"EUMEL-Kanalnummer des Druckerkanals:");
+ get (pr channel);
+ disable stop;
+ serverchannel (pr channel);
+ BOOL VAR no error :: NOT is error;
+ IF is error
+ THEN cursor (1, 7);
+ put error;
+ putline ("Eingabe korrigiert wiederholen!")
+ FI;
+ clear error;
+ enable stop
+ UNTIL no error PER.
+
+ inits:
+ line;
+ IF single task
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+ FI;
+ command dialogue (TRUE);
+ IF name (myself) <> "PRINTER"
+ THEN putline ("Diese Task heißt nicht ""PRINTER"", sondern """ +
+ name (myself) + """ !");
+ IF yes ("Soll die Task in ""PRINTER"" umbenannt werden ?")
+ THEN rename myself ("PRINTER")
+ FI
+ FI;
+ INT VAR choice;
+ service option := service opt.
+
+ single task: (pcb (9) AND 255) = 1.
+
+ main menu:
+ BOOL VAR installed :: FALSE;
+ REP
+ show main menu;
+ get choice;
+ treat choice
+ UNTIL was esc OR installed PER.
+
+ show main menu:
+ page;
+ headline("Hauptmenü 24-Nadel-Drucker");
+ putline (" 1. Brother");
+ putline (" 2. Epson");
+ putline (" 3. NEC");
+ putline (" 4. OKI");
+ putline (" 5. Toshiba").
+
+ get choice:
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Installation abbrechen");
+ ask user (5).
+
+ treat choice:
+ SELECT int (inp) OF
+ CASE 1: brother menu
+ CASE 2: epson menu
+ CASE 3: nec menu
+ CASE 4: oki menu
+ CASE 5: toshiba menu
+ END SELECT.
+
+
+ brother menu:
+ page;
+ headline ("brother - Menü");
+ putline (" 1. M-1724 L");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (1);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ brother m1724l inst
+ FI.
+
+ brother m1724l inst:
+ putline ("brother M-1724 L");
+ line;
+ putline ("Wählen Sie folgende DIP-Schalter Optionen:");
+ putline ("Emulationsmodus IBM Proprinter XL ");
+ putline ("Automatischer Zeilenvorschub Nein ");
+ show control options ("paperfeed, std speed, top margin");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.brother");
+ generate ("brotherm1724l");
+ adjust papersize;
+ adjust quality;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+
+ toshiba menu:
+ page;
+ headline ("TOSHIBA - Menü");
+ putline (" 1. P 321");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (1);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ toshiba p321 inst
+ FI.
+
+ toshiba p321 inst:
+ putline ("TOSHIBA P 321");
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("S3-8 S3-7 S3-5 übrige Schalter");
+ putline ("OFF OFF *) egal ");
+ putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug");
+ show control options ("std speed, paper feed");
+ show material options("slow, fast");
+ show command options ("nlq, draft");
+ ask for quality;
+ ask for papersize;
+ IF all right
+ THEN get fonttable ("fonttab.toshiba.p321");
+ generate ("toshp321");
+ adjust papersize;
+ adjust quality;
+ do ("papersize(21.0,30.48)");
+ installed := TRUE;
+ FI.
+
+
+ epson menu:
+ page;
+ headline ("Epson - Menü");
+ putline (" 1. LQ 850");
+ putline (" 2. LQ 1050");
+ putline (" 3. LQ 1500");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (3);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ SELECT choice OF
+ CASE 1 : lq850 inst
+ CASE 2 : lq850 inst
+ CASE 3 : lq1500 inst
+ END SELECT
+ FI.
+
+ lq850 inst:
+ IF choice = 1
+ THEN putline ("Epson LQ 850")
+ ELSE putline ("Epson LQ 1050")
+ FI;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8");
+ putline ("egal egal egal egal egal egal *1) OFF ");
+ putline ("*1) ON: Einzelblatteinzug, OFF: kein Einzug"); line;
+ putline ("SW2-1 SW2-2 SW2-3 SW2-4 SW2-5 SW2-6 SW2-7 SW2-8");
+ putline ("egal egal *2) OFF OFF");
+ putline ("*2) SW2-2 bis SW2-6 müssen je nach Art der Schnittstelle ");
+ putline (" gesetzt werden (Druckerhandbuch)");
+ show control options ("std speed, top margin, std typeface, paperfeed");
+ show material options ("slow, fast, draft, nlq, roman, sansserif");
+ show command options ("draft, nlq, roman, sansserif");
+ ask for quality;
+ ask for papersize;
+ IF all right
+ THEN get fonttable ("fonttab.epson.lq850");
+ generate ("epsonlq850");
+ adjust quality;
+ adjust papersize;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ lq1500 inst:
+ putline ("EPSON LQ-1500");
+ show control options ("");
+ show material options ("draft, nlq");
+ show command options ("draft, nlq");
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.epson.lq1500");
+ generate ("epsonlq1500");
+ adjust quality;
+ installed := TRUE
+ FI.
+
+ nec menu:
+ page;
+ headline ("NEC - Menü");
+ putline (" 1. PINWRITER P5 ");
+ putline (" 2. PINWRITER P6 ");
+ putline (" 3. PINWRITER P7 ");
+ putline (" 4. PINWRITER P6 PLUS");
+ putline (" 5. PINWRITER P7 PLUS");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (5);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ SELECT choice OF
+ CASE 1 : necp5p7 inst
+ CASE 2 : necp6 inst
+ CASE 3 : necp5p7 inst
+ CASE 4 : necp6plus inst
+ CASE 5 : necp6plus inst
+ END SELECT
+ FI.
+
+ necp5p7 inst:
+ IF choice = 1
+ THEN putline ("NEC PINWRITER P5")
+ ELSE putline ("NEC PINWRITER P7")
+ FI;
+ show control options ("paper feed");
+ show material options ("draft, nlq");
+ show command options ("draft, nlq");
+ ask for quality;
+ ask for papersize;
+ IF all right
+ THEN get fonttable ("fonttab.nec.p5.new");
+ generate ("necp5p7");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE
+ FI.
+
+ necp6 inst:
+ putline ("NEC PINWRITER P6 ");
+ show control options ("paper feed");
+ show material options ("draft, nlq");
+ show command options ("draft, nlq");
+ ask for quality;
+ ask for papersize;
+ IF all right
+ THEN get fonttable ("fonttab.nec.p5.new");
+ generate ("necp6");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE
+ FI.
+
+ necp6plus inst:
+ IF choice = 4
+ THEN putline ("NEC PINWRITER P6 PLUS")
+ ELSE putline ("NEC PINWRITER P7 PLUS")
+ FI;
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:");
+ putline ("CR FUNCTION CR ONLY ");
+ show control options ("std speed, top margin, std typeface, paperfeed");
+ show material options ("slow, fast, draft, nlq, courier, souvenir");
+ show command options ("draft, nlq, courier, souvenir");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.nec.p6+");
+ generate ("necp6+");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE;
+ IF choice = 5 THEN do ("papersize (34.544, 30.48)") FI;
+ FI.
+
+ oki menu:
+ page;
+ headline ("OKI - Menü");
+ putline (" 1. MICROLINE 390 IBM-/EPSON-kompatibel");
+ putline (" 2. MICROLINE 391 IBM-/EPSON-kompatibel");
+ putline (" 3. MICROLINE 393/393C EPSON-kompatibel");
+ putline (" 4. MICROLINE 393/393C IBM-kompatibel");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (4);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ SELECT choice OF
+ CASE 1 : oki ml390 inst
+ CASE 2 : oki ml390 inst
+ CASE 3 : oki ml393eps inst
+ CASE 4 : oki ml393ibm inst
+ END SELECT
+ FI.
+
+ oki ml390 inst:
+ IF choice = 1
+ THEN putline ("OKI Microline 390") ;
+ ELSE putline ("OKI Microline 391") ;
+ FI;
+ line;
+ putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:");
+ putline ("EMULATION MODE EPSON LQ ");
+ putline ("AUTO LF NO ");
+ show control options ("paperfeed, std speed, top margin");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq, courier, kassette");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.oki");
+ generate ("oki390/391");
+ adjust papersize;
+ adjust quality;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+
+ oki ml393eps inst:
+ putline ("OKI Microline 393 EPSON-kompatibel");
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:");
+ putline ("AUTO LF NO ");
+ show control options ("paperfeed, std speed, top margin, std typeface");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq, courier, kassette, schwarz, rot, blau, violett, gelb, orange, grün");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.oki");
+ generate ("oki393/393Ceps");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE
+ FI.
+
+ oki ml393ibm inst:
+ putline ("OKI Microline 393 IBM-kompatibel");
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:");
+ putline ("EMULATION MODE ASCII ");
+ putline ("AUTO LF NO ");
+ show control options ("paperfeed, std speed, top margin, std typeface");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq, courier, kassette, schwarz, rot, blau, violett, gelb, orange, grün");
+ ask for papersize;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.oki");
+ generate ("oki393/393Cibm");
+ adjust papersize;
+ adjust quality;
+ installed := TRUE
+ FI.
+
+
+
+generate printer spool:
+ IF service opt = 0
+ THEN forget (generator name, quiet);
+ forget (driver name, quiet)
+ FI;
+ eumel must advertise;
+ cursor (1, 10);
+ putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+ putline ("die Fonttabelle mit dem Kommando");
+ line;
+ putline (" font table (""" + font tab name + """)");
+ line;
+ putline ("eingestellt werden!!!");
+ line (2);
+ putline ("Hinweis: Dieses Installationsprogramm kann in der Task """ + name (myself) + """");
+ putline (" mit 'treiber einrichten' aufgerufen werden, wenn ein anderer");
+ putline (" Drucker eingesetzt werden soll.");
+ line (2);
+ put ("Generierung beendet, weiter mit 'SV'");
+ break (quiet);
+ do ("spool manager (PROC printer)").
+
+ inform about restart:
+ page;
+ putline ("Es ist kein Druckertreiber installiert worden!");
+ line;
+ putline ("Dieses Installationsprogramm kann in der Task """ + name (myself) + """");
+ putline ("mit 'treiber einrichten' erneut aufgerufen werden.");
+ line.
+
+END PROC treiber einrichten;
+
+PROC headline (TEXT CONST header):
+
+ cursor (13,1);
+ putline ("E U M E L - Druckertreiber - Installations - Programm");
+ cursor (40 - LENGTH header DIV 2, 2);
+ put (header);
+ line (2)
+END PROC headline;
+
+PROC ask user (INT CONST max choice):
+
+ TEXT VAR exit;
+ inp := "";
+ REP
+ cursor (1,23);
+ IF inp = ""
+ THEN put ("Ihre Wahl (Nummer eingeben):")
+ ELSE put ("FEHLER! Eingabe korrigieren:")
+ FI;
+ editget (inp, ""27"", "", exit);
+ was esc := exit = ""27"";
+ UNTIL was esc OR ok PER.
+
+ ok:
+ int (inp) > 0 AND int (inp) <= max choice AND last conversion ok.
+END PROC ask user;
+
+PROC show control options (TEXT CONST options):
+
+ line;
+ putline ("Steuerprozeduren in der Task """ + name (myself) + """:");
+ write ("papersize, std quality");
+ IF options <> ""
+ THEN put (",");
+ putline (options)
+ FI
+END PROC show control options;
+
+PROC show material options (TEXT CONST options):
+
+ line;
+ putline ("Mögliche Materialwerte (#material(""..."")#):");
+ putline (options)
+END PROC show material options;
+
+PROC show command options (TEXT CONST options):
+
+ line;
+ putline ("Mögliche direkte Druckeranweisungen (#""...""#):");
+ putline (options)
+END PROC show command options;
+
+PROC ask for quality:
+
+ line (1);
+ putline ("Standard - Druckqualität:");
+ line;
+ REP out (up);
+ IF yes ("Draft Quality (schneller, aber nicht so schön)")
+ THEN quality := 1; LEAVE ask for quality
+ FI;
+ out (up);
+ IF yes ("Near Letter Quality (schöner, aber langsamer)")
+ THEN quality := 2; LEAVE ask for quality
+ FI;
+ PER
+END PROC ask for quality;
+
+PROC adjust quality:
+
+ IF quality = 1
+ THEN do ("std quality (""draft"")")
+ ELSE do ("std quality (""nlq"")")
+ FI
+END PROC adjust quality;
+
+PROC ask for papersize :
+LET up = ""3""13""5"";
+
+ paper format number := paper format ;
+
+ . paper format :
+ line (1);
+ putline ("Papierformat:");
+ line;
+ REP out (up);
+ IF yes ("Endlospapier, 8 Zoll breit")
+ THEN LEAVE paper format WITH 1 FI;
+ out (up);
+ IF yes ("Endlospapier, 13.2 Zoll breit")
+ THEN LEAVE paper format WITH 2 FI;
+ out (up);
+ IF yes ("Einzelblatteinzug, DINA 4")
+ THEN LEAVE paper format WITH 3 FI;
+ PER;
+ 0
+END PROC ask for papersize;
+
+
+PROC adjust papersize:
+
+ SELECT paper format number OF
+ CASE 1 : do("papersize ( 8.0 * 2.54, 12.0 * 2.54)");
+ do ("paper feed (""tractor"")")
+ CASE 2 : do("papersize (13.2 * 2.54, 12.0 * 2.54)");
+ do ("paper feed (""tractor"")")
+ CASE 3 : do("papersize (21.0, 29.7)");
+ do ("paper feed (""sheet"")")
+ END SELECT
+
+END PROC adjust papersize;
+
+BOOL PROC all right:
+
+ line (3);
+ cursor (1,23);
+ yes ("Soll der ausgewählte Druckertreiber installiert werden")
+END PROC all right;
+
+PROC get fonttable (TEXT CONST name):
+
+ fonttab name := name;
+ from archive ((description file name & module file name & fonttab name)
+ - all);
+ fonttable (fonttab name);
+ command dialogue (FALSE);
+ save (fonttab name, /"configurator");
+ IF service option = 0
+ THEN forget (fonttab name)
+ FI;
+ command dialogue (TRUE);
+END PROC get fonttable;
+
+PROC from archive (THESAURUS CONST files):
+
+ IF highest entry (files) > 0
+ THEN fetch from archive;
+ release (archive);
+ putline ("Archiv abgemeldet !")
+ FI.
+
+ fetch from archive:
+ THESAURUS VAR thes :: files;
+ REP
+ ask for archive;
+ reserve archive;
+ fetch (thes / ALL archive, archive);
+ thes := thes - all
+ UNTIL highest entry (thes) = 0 PER.
+
+ask for archive:
+ line;
+ putline ("Bitte Archiv mit den Dateien");
+ TEXT VAR buffer;
+ INT VAR index :: 0;
+ REP
+ get (thes, buffer, index);
+ putline (" " + buffer)
+ UNTIL index = 0 PER;
+ putline ("einlegen !");
+ line;
+ putline ("Wenn eingelegt: Taste drücken !");
+ inchar (buffer).
+
+reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ disable stop;
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI;
+ enable stop.
+
+END PROC from archive;
+
+THESAURUS OP & (TEXT CONST left, right):
+ THESAURUS VAR result := empty thesaurus;
+ insert (result, left);
+ insert (result, right);
+ result
+END OP &;
+
+THESAURUS OP & (THESAURUS CONST left, TEXT CONST right):
+ THESAURUS VAR result := left;
+ insert (result, right);
+ result
+END OP &;
+
+PROC generate (TEXT CONST name):
+
+ open files;
+ read description;
+ build programme;
+ insert programme;
+ forget files.
+
+ open files:
+ line (5);
+ cursor (1, 20);
+ putline (""4"Bitte warten !");
+ putline (" - Der Treiber wird generiert.");
+ driver name := "printer." + name + "(generiert)";
+ IF exists (driver name)
+ THEN forget (driver name, quiet)
+ FI;
+ FILE VAR des file :: sequential file (modify, description file name),
+ mod file :: sequential file (modify, module file name),
+ driver file :: sequential file (output, driver name).
+
+ read description:
+ to line (des file, 1);
+ col (des file, 1);
+ downety (des file, "$" + name + "$");
+ IF eof (des file)
+ THEN errorstop ("Beschreibung von """ + name + """ nicht im"13""10"" +
+ "Descriptions-File enthalten")
+ FI;
+ TEXT VAR description :: "",
+ record;
+ BOOL VAR done :: FALSE;
+ read record (des file, record);
+ record := subtext (record, col (des file) + LENGTH name + 2);
+ WHILE NOT eof (des file) AND NOT done REP
+ treat record
+ PER.
+
+ treat record:
+ INT VAR dollar pos :: pos (record, "$");
+ IF dollar pos = 0
+ THEN description CAT compress (record);
+ down (des file);
+ read record (des file, record)
+ ELSE description CAT compress (subtext (record, 1, dollar pos - 1));
+ col (des file, dollar pos);
+ done := TRUE;
+ FI.
+
+ build programme:
+ get module name;
+ WHILE still modules REP
+ find module;
+ transfer module;
+ get module name
+ PER.
+
+ get module name:
+ INT VAR semicol pos :: pos (description, ";");
+ TEXT VAR module name;
+ IF semicol pos > 0
+ THEN module name := subtext (description, 1, semicol pos - 1);
+ description := subtext (description, semicol pos + 1)
+ ELSE module name := description;
+ description := ""
+ FI.
+
+ still modules:
+ module name <> "" OR description <> "".
+
+ find module:
+ to line (mod file, 1);
+ col (mod file, 1);
+ downety (mod file, "$" + module name + "$");
+ IF eof (mod file)
+ THEN errorstop ("Modul """ + module name + """ nicht im"13""10"" +
+ "Modul-File enthalten")
+ FI.
+
+ transfer module:
+ done := FALSE;
+ read record (mod file, record);
+ record := subtext (record, col (mod file) + LENGTH module name + 2);
+ WHILE NOT eof (mod file) AND NOT done REP
+ transfer record
+ PER.
+
+ transfer record:
+ dollar pos := pos (record, "$");
+ IF dollar pos = 0
+ THEN write (driver file, compress (record));
+ line (driver file);
+ down (mod file);
+ read record (mod file, record)
+ ELSE write (driver file, compress (subtext (record, 1,
+ dollar pos - 1)));
+ col (mod file, dollar pos);
+ done := TRUE;
+ cout (line no (mod file))
+ FI.
+
+ insert programme:
+ IF online
+ THEN putline (" - Der Treiber wird insertiert.")
+ FI;
+ check off;
+ insert (driver name).
+
+ forget files:
+ IF service option = 0
+ THEN forget (description file name, quiet);
+ forget (module file name, quiet)
+ FI .
+END PROC generate;
+
+END PACKET driver inst 24
+
diff --git a/printer/dotmatrix24/readme b/printer/dotmatrix24/readme
new file mode 100644
index 0000000..d526aa3
--- /dev/null
+++ b/printer/dotmatrix24/readme
@@ -0,0 +1,320 @@
+#type("nlq10")##limit(18.0)##start(1.5,1.0)#
+#head#
+Treiber-Installations-Programm #right#Seite %
+für 24-Nadel-Matrixdrucker #right#23.12.1988
+
+
+#end#
+#on("u")#Dokumentation zum Treiber-Installations-Programm für 24-Nadel-
+Matrixdrucker#off("u")#
+
+#on("u")#Inhalt:#off("u")#
+
+1. Installations- und Gebrauchsanleitung
+2. Druckertreiber-Auswahl
+3. Steuerungsmöglichkeiten und Spezialfeatures
+4. Weitere Hinweise
+
+
+#on("b")#1. Installations- und Gebrauchsanleitung#off("b")#
+
+#on("u")#Einrichten#off("u")#
+So wird das Treiber-Installationsprogramm eingerichtet:
+
+ SV drücken
+
+ nach 'gib supervisor kommando:'
+
+ begin("PRINTER","SYSUR")
+
+ in der Task "PRINTER" (nach 'gib kommando'):
+
+ archive ("std.printer")
+ fetch ("printer.24.nadel",archive)
+ check off
+ insert ("printer.24.nadel")
+
+Das Programm wird dann insertiert.
+
+#on("u")#Druckerkanal#off("u")#
+Hiernach wird die Kanalnummer des Druckers erfragt. Wenn der Drucker
+über Parallelschnittstelle betrieben wird, ist die Kanalnummer
+meistens 15.
+
+#on("u")#Menüsystem#off("u")#
+Das Installationsprogramm zeigt nun eine Liste von Druckerherstellern.
+Wählen Sie den Hersteller Ihres Druckers aus! Hiernach wird eine Liste
+der unterstützten Drucker dieses Herstellers gezeigt. Wählen Sie hier
+den passenden Typ aus!
+Das Installationsprogramm zeigt nun einige Informationen zu dem ange­
+wählten Drucker. Besonders zu beachten sind hierbei #on("u")#Angaben zur Konfi­
+guration des Druckers#off("u")# (z.B. DIP-Schalter). Der Drucker muß unbedingt
+wie angegeben konfiguriert werden, wenn er mit dem ausgewählten Trei­
+ber betrieben werden soll.
+
+Hinweise zu Konfigurationsangaben:
+1. Die Angabe 'egal' bedeutet, daß die Einstellung für die Funktion
+ des Treibers keine Bedeutung hat. Dennoch solte der Anwender darauf
+ achten, welche Funktion die Schalter haben (Druckerhandbuch!). So
+ ist es zum Beispiel immer empfehlenswert, den Papierende-Sensor zu
+ aktivieren, damit der Drucker nach Papierende nicht auf der Walze
+ weiterdruckt.
+2. Die Konfigurationsangaben beziehen sich immer auf genau den ausge­
+ wählten Druckertyp. Wenn Sie den Treiber mit einem anderen Drucker
+ als den ausgewählten verwenden, dann beachten Sie folgende Regeln
+ für die Konfiguration:
+ - Der Drucker muß auf eine passende Emulation konfiguriert werden.
+ - Der Drucker darf bei einem Carriage Return (Code 13) keinen Zei­
+ lenvorschub durchführen.
+ - Der Drucker darf die Perforation #on("u")#nicht#off("u")# automatisch überspringen.
+
+ - Auf Seitenlängen und internationale Zeichensätze müssen Sie nicht
+ achten.
+
+(Hinweise zur Auswahl des richtigen Treibers gibt Abschnitt 2)
+
+Nach den Konfigurationsangaben werden Steuerungsmöglichkeiten des
+ausgewählten Treibers angezeigt. (Siehe hierzu Abschnitt 3)
+
+Falls der Treiber bestimmte grundsätzliche Betriebsmöglichkeiten er­
+laubt (z.B. DRAFT/NLQ, Einzelblatteinzug), werden Sie danach gefragt,
+welche Möglichkeit standardmäßig gewählt werden soll. diese Vorein­
+stellungen können nachträglich in der Task "PRINTER" mit den entspre­
+chenden Steuerprozeduren neu gesetzt werden. Außerdem können bestimmte
+Einstellungen noch für jedes einzelne Dokument (d.h. für jede Druck­
+datei) gewählt ('material'-Anweisung) oder sogar innerhalb eines Doku­
+ments verändert werden (direkte Druckeranweisung \#"..."\#).
+Über die Steuerungsmöglichkeiten informiert Abschnitt 3 ausführlicher.
+
+
+#on("b")#2. Druckertreiber-Auswahl#off("b")#
+
+#on("u")#Verwendung nicht im Menü enthaltener Drucker#off("u")#
+Für den Fall, daß Sie genau Ihren Drucker im Menü nicht finden, soll­
+ten Sie zunächst versuchen, ob ein Treiber für einen anderen Drucker
+des gleichen Herstellers mit Ihrem Drucker korrekt arbeitet.
+Falls dies nicht funktioniert oder der Hersteller überhaupt nicht im
+Menü erscheint, müssen Sie herausfinden (Druckerhandbuch, -händler!),
+welchen Drucker Ihr Drucker emuliert oder welchem er ähnlich ist.
+(Viele Drucker verfügen über EPSON LQ-1000 oder IBM Grafikdrucker bzw.
+Proprinter-Eumulationen.)
+Eine der beiden Anpassungen 'EPSON LQ-1050' oder 'OKI ML-393
+IBM-kompatibel' müßte immer einen (Minimal-) Betrieb ermöglichen (wobei die
+Verwendung der Proportionalschrift bzw. der doppelt hohen Schriften u. U.
+nicht funktioniert).
+
+
+#on("b")#3. Steuerungsmöglichkeiten und Spezialfeatures#off("b")#
+
+Einige Treiber bieten bestimmte Einstellungsmöglichkeiten (z.B.
+DRAFT/NLQ) und/oder Spezialfeatures (z.B. Farbdruck).
+Die Einstellungen können über
+- Steuerprozeduren
+- Materialanweisungen bzw.
+- direkte Druckeranweisungen
+vorgenommen werden.
+
+#on("u")#Steuerprozeduren#off("u")#
+setzen Einstellungen, die für alle Dokumente (Druckdateien) gelten
+sollen. Die Prozeduren müssen in der Druckspooltask (meist: "PRINTER")
+aufgerufen werden. #on("b")#Gültig werden die Änderungen erst, wenn danach in
+der Druckspooltask das Kommando 'start' gegeben wird!#off("b")#
+
+PROC papersize (REAL CONST breite, länge)
+ Dient zur Einstellung der Größe der physikalisch beschreibbaren
+ Fläche.
+ Beispiel: papersize (20.32, 30.48)
+ (Standardeinstellung für Endlospapier 8 Zoll breit und
+ 12 Zoll lang)
+
+PROC papersize
+ Informationsprozedur
+
+PROC top margin (REAL CONST margin)
+ Falls der Drucker es nicht erlaubt, direkt am Blattanfang zu druk­
+ ken (zum Beispiel wegen eines Einzelblatteinzugs), muß mit dieser
+ Prozedur die Länge des oberen Randes, den der Drucker nicht be­
+ drucken kann, in cm angegeben werden.
+ Beispiel: top margin (2.0)
+ (Teilt dem Druckertreiber mit, daß die ersten 2 cm
+ nicht bedruckbar sind.)
+
+REAL PROC top margin
+ Informationsprozedur
+
+PROC std speed (TEXT CONST speed)
+ Parameter: slow, fast
+ Wahl zwischen Positionierung in Mikroschritten (slow) oder in
+ Blanks (fast).
+ Beispiel: std speed ("slow")
+
+TEXR PROC std speed
+ Informationsprozedur
+
+PROC std quality (TEXT CONST quality)
+ übliche Parameter: draft, nlq
+ Wahl zwischen Datenverarbeitungs-Qualität und Schönschrift-
+ Qualität
+ Beispiel: std quality ("draft")
+
+TEXT PROC std quality
+ Informationsprozedur
+
+PROC std typeface (TEXT CONST typeface)
+ übliche Parameter: roman, sansserif, courier
+ Wahl zwischen verschiedenen NLQ-Schriftarten (nur sichtbar im
+ NLQ-Modus, das heißt 'std typeface' schaltet nicht auf NLQ).
+ Beispiel: std typeface ("roman")
+
+TEXT PROC std typeface
+ Informationsprozedur
+
+PROC paper feed (TEXT CONST name)
+ übliche Parameter: tractor, sheet, schacht1, schacht2
+ Wählt Endlospapier oder Einzelblatteinzug und ggf. Schachtnummer.
+ Beispiel: paper feed ("sheet")
+
+TEXT PROC paper feed
+ Informationsprozedur
+
+
+#on("u")#Materialanweisungen \#material("...")\##off("u")#
+müssen in der Druckdatei vor dem ersten druckbaren Zeichen stehen und
+setzen Einstellungen für eine ganze Datei. (Materialanweisungen haben
+für die jeweilige Datei Vorrang vor den durch Steuerprozeduren einge­
+stellten Standardwerten. Diese werden durch die Materialanweisung aber
+nicht geändert.)
+
+Beispiel: \#material("nlq")\#
+ sorgt bei entsprechendem Treiber dafür, daß das gesamte
+ Dokument in Schönschrift-Qualität ausgedruckt wird, egal
+ wie 'std quality' eingestellt ist.
+
+#on("b")#Es darf in einer Datei nur eine Materialanweisung stehen!#off("b")# Sollen meh­
+rere Einstellungen vorgenommen werden, müssen sie in einer Anweisung
+erscheinen. Beispiel: \#material("sheet;draft")\#
+
+
+#on("u")#direkte Druckeranweisungen \#"..."\##off("u")#
+gelten ab der Position, an der sie in der Datei auftreten. Sie haben
+(sofern sie erlaubt sind,) Vorrang vor Standardeinstellungen und
+Materialeinstellungen.
+
+Beispiel: \#"draft"\#
+ schaltet (bei entsprechendem Treiber) auf Datenverar­
+ beitungs-Qualität, egal welche Standardeinstellung vorliegt
+ und welche Materialanweisung gegeben wurde.
+
+#on("b")#In einer Druckeranweisung darf nur eine Einstellung vorgenommen
+werden.#off("b")# Also: \#"nlq"\#\#"sansserif"\#
+
+
+#on("u")#Wichtig#off("u")#
+- Achten Sie bei Materialanweisungen und direkten Druckeranweisungen
+ besonders auf korrekte Schreibweise! Es werden nur Kleinbuchstaben
+ berücksichtigt! Also: \#"nlq"\# und keinesfalls \#"NLQ"\#!!!
+- Direkte Druckeranweisungen werden vom EUMEL-Drucker ignoriert und
+ nur vom Druckertreiber in eine Kommando-Sequenz umgesetzt. Es kann
+ daher vorkommen, daß (z.B. bei Spaltendruck) unerwartete Ergebnisse
+ erscheinen, weil der EUMEL-Drucker dann den Text in einer anderen
+ Reihenfolge an den Drucker sendet, als er in der Datei steht, die
+ mit dem direkten Druckerkommando gesetzte Modifikation aber (z.B.
+ für beide Spalten) unerwünscht erhalten bleibt.
+
+
+#on("u")#Tabelle#off("u")#
+Die Tabelle soll einen Anhaltspunkt dafür geben, wie welche Einstel­
+lungen erfolgen können.
+
+#type("17")#
+ Steuerprozeduren Materialanweisungen direkte Druckeranweisungen
+
+#on("u")#                                                                                          #off("u")#
+
+Positionierung std speed slow, fast ------
+ slow, fast
+
+Qualität std quality z.B. draft, nlq z.B. draft, nlq
+ z.B. draft, nlq
+
+Schriftart std typeface z.B. roman, z.B. roman,
+(nur bei NLQ) z.B. roman, sansserif, courier sansserif, courier
+ sansserif, courier
+
+Einzelblatt- paper feed z.B. schacht1, z.B. schacht1,
+einzug z.B. tractor, schacht2 schacht2
+ sheet,
+ schacht1, schacht2
+
+Farbdruck ------ ------ z.B. schwarz,
+ rot, blau,
+ violett, gelb
+ orange, grün
+
+
+
+#type("nlq10")##on("b")#4. Weitere Hinweise#off("b")#
+
+#on("u")#Zeichensatzänderungen gegenüber früheren Versionen#off("u")#
+In den Fonttabellen früherer Druckertreiber-Versionen wurden oberhalb
+des Codes 127 einige internationale Zeichen zur Verfügung gestellt
+(und zwar in Anlehnung an den Agfa-Laserdrucker-Zeichensatz).
+Bei den Treibern der vorliegenden Version gilt folgendes:
+- Wie bisher wird der volle im Benutzerhandbuch festgelegte EUMEL-
+ Zeichensatz (sofern möglich) unterstützt.
+- Der Code 252 liefert das Paragraphzeichen.
+- Alle übrigen (vom EUMEL-Zeichensatz nicht definierten) Zeichencodes
+ oberhalb 127 liefern, sofern möglich, die entsprechenden Zeichen des
+ IBM-Grafikzeichensatzes.
+
+
+#on("u")#Hinweis zu Proportionalschriften#off("u")#
+Bei Proportionalschriften kann die Modifikation \#on("i")\# zu Problemen
+führen (z.B. beim Blocksatz), wenn die kursiven Zeichen andere
+Proportionalbreiten haben.
+
+#on("u")#Hinweis zur Modifikation on/off("b") bzw. on/off("r")#off("u")#
+Die meisten 24-Nadel Drucker verfügen sowohl über einen horizontalen als
+auch über einen vertikalen Schattendruck. Diese beiden Druckarten können
+mit der Modifikation on("b") (bold) bzw. on("r") (eigentlich für reverse
+gedacht) eingeschaltet werden.
+
+#on("u")#Hinweis zur Benutzung von Einzelblatteinzügen#off("u")#
+Bei der Benutzung von Einzelblatteinzügen müssen folgende Einstel­
+lungen vorgenommen werden (vgl. auch Abschnitt 3!):
+
+ Am Drucker:
+1. Sie müssen Ihren Drucker auf die Option Einzelblatteinzug
+ schalten (siehe Druckerhandbuch!).
+
+ In der Druckspooltask (meist 'PRINTER'):
+2. Falls der Druckertreiber die Steuerprozedur 'paper feed' zur Verfü­
+ gung stellt, müssen Sie mit 'paperfeed ("sheet")' oder (für
+ 2-Schacht-Einzüge) mit 'paperfeed ("schacht1")' bzw. 'paperfeed
+ ("schacht2")' den Druckertreiber auf Einzelblatteinzug umschalten.
+3. Falls Sie eine andere Papierlänge als 12 Zoll (=30.48 cm) verwen­
+ den, müssen Sie die neuen Papiermaße mit 'papersize' in cm einstel­
+ len.
+ Beispiel: papersize (21.0, 29.7)
+ (für DIN A4-Blätter)
+4. Falls der Drucker mit dem Einzelblatteinzug nicht direkt am Blatt­
+ anfang drucken kann, sondern ein gewisser oberer Rand bleibt, muß
+ mit 'top margin' die Länge des nicht bedruckbaren Randes in cm dem
+ Druckertreiber mitgeteilt werden.
+ Beispiel: top margin (1.5)
+ (Wie groß der obere Rand ist, kann festgestellt werden, indem eine
+ Datei mit \#start(0.0,0.0)\# ausgedruckt wird.)
+
+ Wurde mit 'top margin' dem Treiber die Größe der nicht bedruckbaren
+ Fläche mitgeteilt, so ist darauf zu achten, daß in den Druckdateien
+ ein genügend großer y-Wert für die Startposition eingestellt wird
+ ('start'-Anweisung). Andernfalls kommt es bei der Ausgabe in der
+ ersten Zeile zu Überschreibungen.
+
+
+#on("b")#5. Die Änderungen, die Sie in der Druckspooltask vorgenommen haben
+ werden erst wirksam, wenn das Spool-Kommando 'start' gegeben wird.#off("b")#
+
+
+
+
diff --git a/printer/dotmatrix9/beschreibungen9 b/printer/dotmatrix9/beschreibungen9
new file mode 100644
index 0000000..6a74b88
--- /dev/null
+++ b/printer/dotmatrix9/beschreibungen9
@@ -0,0 +1,97 @@
+
+(*************************************************************************)
+(* Stand : 01.10.88 *)
+(* Beschreibungen-Datei für 9-Nadel-Drucker Version : 0.9 *)
+(* Autoren : mov/hjh *)
+(*************************************************************************)
+
+$fx85$
+head;hfx85;decl;speed;openh;opendoch;initspeed;opendocfx85;openpge;betwoc;
+clpge;betwce;cmd;crs;moh;mofx85;ymodr;onoff;tyfx85;end
+
+$fx800$
+head;hfx800;decl;quality;typeface;openh;opendoch;opendocfx800;openpge;betwoc;
+clpge;betwce;cmdfx800;crs;moh;mofx800;ymodr;onoff;tyfx800;end
+
+$mx$
+head;hmx;decl;speed;openh;opendoch;initspeed;opendocmx;openpge;betwoc;clpge;
+betwce;cmd;crs;moh;modrmx;onoff;tymx;end
+
+$lx800$
+head;hlx800;decl;speed;quality;typeface;openh;opendoch;initspeed;
+opendocfx800;openpge;betwoc;clpge;betwce;cmdfx800;crs;moh;mofx85;ymodr;onoff;
+tyfx800;end
+
+$ibmgp$
+head;hgp;decl;speed;openh;opendoch;initspeed;opendocgp;openpge;betwoc;
+clpge;betwce;cmd;crs;moh;mogp;ymodr;onoff;tyfx85;end
+
+$ibmpp$
+head;hpp;decl;speed;quality;openh;opendoch;initspeed;opendocpp;openpge;
+betwoc;clpge;betwce;cmdpp;crs;moh;mofx85;ymodr;onoffpp;tyfx85;end
+
+$okiml182i$
+head;hml182i;decl;speed;quality;openh;opendoch;initspeed;opendocml182i;
+opendocgp;openpge;betwoc;clpge;betwce;cmdml182i;crs;moh;mogp;ymodr;onoff;
+tyohnesmall;end
+
+$okiml192el$
+head;hml192el;decl;speed;feed;openh;opendoch;initspeed;opendocml192el;
+openpgemlsf;betwoc;clmlsf;betwce;cmd;crs;moh;moml192el;ymodr;onoff;tyml192el;
+end
+
+$okiml292el$
+head;hml292el;decl;quality;typeface292;feed;openh;opendoch;opendocml292el;
+openpgemlsf;betwoc;clmlsf;betwce;cmdml292el;crs;moh;mofx800;ymodr;onoff;
+tyml292el;end
+
+$okiml294i$
+head;hml294i;decl;speed;quality;feed;openh;opendoch;initspeed;opendocml294i;
+openpgemlsf;betwoc;clmlsf;betwce;cmdml294i;crs;moh;mofx85;ymodr;ontyml294i;end
+
+$okiml320$
+head;hml320;decl;speed;openh;opendoch;initspeed;opendocml320;
+openpge;betwoc;clpge;betwce;cmd;crs;moh;moml192el;ymodr;onoff;tyml192el;
+end
+
+$starlc10$
+head;hlc10;decl;quality;typefacelc10;openh;opendoch;opendoclc10;openpge;
+betwoc;clpge;betwce;cmdlc10;crs;moh;mofx800;ymodr;onoff;tyfx800;end
+
+$dmp4000$
+head;hdmp4000;decl;speed;openh;opendoch;initspeed;opendocdmp4000;openpge;
+betwoc;clpge;betwce;cmd;crs;moh;mofx85;ymodr;onoff;tyfx85;end
+
+$starnx15$
+head;hnx15;decl;speed;openh;opendoch;initspeed;opendocnx15;openpge;betwoc;
+clpge;betwce;cmd;crs;moh;mofx85;ymodr;onoff;tyfx85;end
+
+$mt230$
+head;hmt230;decl;speed;feedschacht;openh;opendoch;initspeed;opendocmt;
+openpgemtsf;betwoc;clmtsf;betwce;cmdmt230;crs;moh;mofx85;ymodr;onoff;
+tyfx85;end
+
+$mt340$
+head;hmt340;decl;speed;feedschacht;openh;opendoch;initspeed;opendocmt;
+openpgemtsf;betwoc;clmtsf;betwce;cmdmt230;crs;moh;moml192el;ymodr;onoff;
+tyml192el;end
+
+$citi120d$
+head;h120d;decl;openh;opendoch;opendoc120d;openpge;betwoc;
+clpge;betwce;cmd;crs;moh;mofx800;ymodr;onoff;tyfx85;end
+
+$citohc310cxp$
+head;hc310;decl;speed;feedschacht;openh;opendoch;initspeed;opendocc310;
+openpgec310sf;betwoc;clc310sf;betwce;cmdc310;crs;moh;mofx85;ymodr;onoff;
+tyfx85;end
+
+$citohci3500$
+head;hci3500;decl;speed;openh;opendoch;initspeed;opendocgp;openpge;betwoc;
+clpge;betwce;cmd;crs;moh;mogp;ymodr;onoff;tyfx85;end
+
+$fujdx2100$
+head;hdx2100;decl;speed;feed;openh;opendoch;initspeed;opendocdx2100;
+openpge;betwoc;clpge;betwce;cmddx2100;crs;moh;moml192el;ymodr;onoff;tyml192el;
+end
+
+
diff --git a/printer/dotmatrix9/fonttab.1 b/printer/dotmatrix9/fonttab.1
new file mode 100644
index 0000000..b5d17e6
--- /dev/null
+++ b/printer/dotmatrix9/fonttab.1
Binary files differ
diff --git a/printer/dotmatrix9/fonttab.10 b/printer/dotmatrix9/fonttab.10
new file mode 100644
index 0000000..6a13c49
--- /dev/null
+++ b/printer/dotmatrix9/fonttab.10
Binary files differ
diff --git a/printer/dotmatrix9/fonttab.20 b/printer/dotmatrix9/fonttab.20
new file mode 100644
index 0000000..7cf0aaf
--- /dev/null
+++ b/printer/dotmatrix9/fonttab.20
Binary files differ
diff --git a/printer/dotmatrix9/fonttab.20.lc b/printer/dotmatrix9/fonttab.20.lc
new file mode 100644
index 0000000..ddf4535
--- /dev/null
+++ b/printer/dotmatrix9/fonttab.20.lc
Binary files differ
diff --git a/printer/dotmatrix9/fonttab.20.lx b/printer/dotmatrix9/fonttab.20.lx
new file mode 100644
index 0000000..1ce0940
--- /dev/null
+++ b/printer/dotmatrix9/fonttab.20.lx
Binary files differ
diff --git a/printer/dotmatrix9/fonttab.7 b/printer/dotmatrix9/fonttab.7
new file mode 100644
index 0000000..676b9a0
--- /dev/null
+++ b/printer/dotmatrix9/fonttab.7
Binary files differ
diff --git a/printer/dotmatrix9/fonttab.7.cxp b/printer/dotmatrix9/fonttab.7.cxp
new file mode 100644
index 0000000..0a996f3
--- /dev/null
+++ b/printer/dotmatrix9/fonttab.7.cxp
Binary files differ
diff --git a/printer/dotmatrix9/fonttab.7.fuj b/printer/dotmatrix9/fonttab.7.fuj
new file mode 100644
index 0000000..1ed83be
--- /dev/null
+++ b/printer/dotmatrix9/fonttab.7.fuj
Binary files differ
diff --git a/printer/dotmatrix9/fonttab.7.mt b/printer/dotmatrix9/fonttab.7.mt
new file mode 100644
index 0000000..c816646
--- /dev/null
+++ b/printer/dotmatrix9/fonttab.7.mt
Binary files differ
diff --git a/printer/dotmatrix9/module9 b/printer/dotmatrix9/module9
new file mode 100644
index 0000000..65de1ee
--- /dev/null
+++ b/printer/dotmatrix9/module9
@@ -0,0 +1,1099 @@
+
+(*************************************************************************)
+(* Stand : 01.10.88 *)
+(* Module-Datei für 9-Nadel-Drucker Version : 0.9 *)
+(* Autoren : mov/hjh *)
+(*************************************************************************)
+
+$head$
+PACKET printer driver
+
+ DEFINES printer,
+ open,
+ close,
+ execute,
+ paper size,
+ top margin,
+
+$hfx85$ std speed:
+(* Treiber für EPSON FX85/105, automatisch generiert *)
+
+$hfx800$ std quality,
+ std typeface:
+(* Treiber für EPSON FX800/1000, automatisch generiert *)
+BOOL VAR was tall font;
+
+$hmx$ std speed:
+(* Treiber für EPSON MX80/100, Typ III *)
+(* Treiber automatisch generiert *)
+BOOL VAR is condensed, is small;
+
+$hlx800$ std speed,
+ std quality,
+ std typeface:
+(* Treiber für EPSON LX800/1000, automatisch generiert *)
+BOOL VAR was tall font;
+
+$hgp$ std speed:
+(* Treiber für IBM-Grafikdrucker *)
+(* Treiber automatisch generiert *)
+
+$hpp$ std speed,
+ std quality:
+(* Treiber für IBM-Proprinter *)
+(* Treiber automatisch generiert *)
+
+$hml182i$ std speed,
+ std quality:
+(* Treiber für OKI ML182/183 IBM-kompatibel *)
+(* Treiber automatisch generiert *)
+
+$hml192el$ paper feed,
+ std speed:
+(* Treiber für OKI ML192/193 Elite *)
+(* Treiber automatisch generiert *)
+BOOL VAR prop font;
+
+$hml292el$ std quality,
+ std typeface,
+ paper feed:
+(* Treiber für OKI ML292/293 Elite *)
+(* Treiber automatisch generiert *)
+BOOL VAR was tall font;
+
+$hml294i$ std speed,
+ paper feed,
+ std quality:
+(* Treiber für OKI ML294 IBM-kompatibel *)
+(* Treiber automatisch generiert *)
+
+$hml320$ std speed:
+(* Treiber für OKI ML320 IBM/EPSON-kompatibel *)
+(* Treiber automatisch generiert *)
+BOOL VAR prop font;
+
+$hlc10$ std quality,
+ std typeface:
+(* Treiber für Star LC-10 oder LC-10 Colour *)
+(* Treiber automatisch generiert *)
+BOOL VAR was tall font;
+
+$hdmp4000$ std speed:
+(* Treiber für Schneider DMP4000, automatisch generiert *)
+
+$hnx15$ std speed:
+(* Treiber für Star NX-15, ND-10, ND-15, NR-10 und NR-15 *)
+(* Treiber automatisch generiert *)
+
+$hmt230$ paper feed,
+ std speed:
+(* Treiber für Mannesmann-Tally MT 230 *)
+(* Treiber automatisch generiert *)
+
+$hmt340$ paper feed,
+ std speed:
+(* Treiber für Mannesmann-Tally MT 340 *)
+(* Treiber automatisch generiert *)
+BOOL VAR prop font := FALSE;
+
+$h120d$ :
+(* Treiber für Citizen 120-D *)
+(* Treiber automatisch generiert *)
+
+$hc310$ paper feed,
+ std speed:
+(* Treiber für C. Itoh C 310/315 CXP *)
+(* Treiber automatisch generiert *)
+
+$hci3500$ std speed:
+(* Treiber für C. Itoh CI-3500 *)
+(* Treiber automatisch generiert *)
+
+$hdx2100$ paper feed,
+ std speed:
+(* Treiber für Fujitsu DX 2100 *)
+(* Treiber automatisch generiert *)
+BOOL VAR prop font := FALSE ;
+
+$decl$
+INT VAR blankbreite, x rest, y rest, high, low, small, modifikations;
+REAL VAR x size, y size, y margin;
+TEXT VAR buffer :: "";
+
+PROC paper size (REAL CONST x, y) :
+
+ x size := x;
+ y size := y;
+END PROC paper size;
+
+PROC paper size :
+
+ line;
+ putline ("Papierbreite = " + text (x size, 5, 2) + " cm = " + text (x size / 2.54, 5, 2) + " Zoll");
+ putline ("Papierlaenge = " + text (y size, 5, 2) + " cm = " + text (y size / 2.54, 5, 2) + " Zoll");
+END PROC paper size;
+
+papersize (20.32, 30.48);
+
+PROC top margin (REAL CONST margin):
+
+ y margin := margin
+END PROC top margin;
+
+REAL PROC top margin: y margin END PROC top margin;
+
+top margin (0.0);
+
+$speed$
+BOOL VAR is slow;
+TEXT VAR std speed name :: "slow";
+
+PROC std speed (TEXT CONST speed) :
+
+ IF speed = "fast" OR speed = "slow"
+ THEN std speed name := speed
+ ELSE errorstop ("unzulässige Geschwindigkeit")
+ FI
+END PROC std speed;
+
+TEXT PROC std speed : std speed name END PROC std speed;
+
+$quality$
+TEXT VAR std quality name :: "draft";
+
+PROC std quality (TEXT CONST quality) :
+
+ IF quality = "nlq" OR quality = "draft"
+ THEN std quality name := quality
+ ELSE errorstop ("unzulässige Qualitätsbezeichnung")
+ FI
+END PROC std quality;
+
+TEXT PROC std quality : std quality name END PROC std quality;
+
+$typeface$
+TEXT VAR std typeface name :: "";
+
+PROC std typeface (TEXT CONST typeface) :
+
+ IF typeface = "" OR typeface = "roman" OR typeface = "sansserif"
+ THEN std typeface name := typeface
+ ELSE errorstop ("unzulässige Schriftart")
+ FI
+END PROC std typeface;
+
+TEXT PROC std typeface : std typeface name END PROC std typeface;
+
+$typeface292$
+TEXT VAR std typeface name :: "";
+
+PROC std typeface (TEXT CONST typeface) :
+
+ IF typeface = "" OR typeface = "courier" OR typeface = "sansserif"
+ THEN std typeface name := typeface
+ ELSE errorstop ("unzulässige Schriftart")
+ FI
+END PROC std typeface;
+
+TEXT PROC std typeface : std typeface name END PROC std typeface;
+
+$typefacelc10$
+TEXT VAR std typeface name :: "";
+
+PROC std typeface (TEXT CONST typeface) :
+
+ IF typeface = "" OR typeface = "courier" OR typeface = "sansserif"
+ OR typeface = "orator1" OR typeface = "orator2"
+ THEN std typeface name := typeface
+ ELSE errorstop ("unzulässige Schriftart")
+ FI
+END PROC std typeface;
+
+TEXT PROC std typeface : std typeface name END PROC std typeface;
+
+$feed$
+TEXT VAR feeder name :: "tractor";
+
+PROC paper feed (TEXT CONST feeder) :
+
+ IF feeder = "sheet" OR feeder = "tractor"
+ THEN feeder name := feeder
+ ELSE errorstop ("unzulässige Einzugsart")
+ FI
+END PROC paper feed;
+
+TEXT PROC paper feed: feeder name END PROC paper feed;
+
+$feedschacht$
+TEXT VAR act feeder :: "",
+ feeder name :: "tractor";
+
+PROC paper feed (TEXT CONST feeder) :
+
+ IF feeder = "tractor" OR feeder = "schacht1" OR feeder = "schacht2"
+ THEN feeder name := feeder
+ ELIF feeder = "sheet"
+ THEN feeder name := "schacht1"
+ ELSE errorstop ("unzulässige Einzugsart")
+ FI
+END PROC paper feed;
+
+TEXT PROC paper feed: feeder name END PROC paper feed;
+
+$openh$
+PROC open (INT CONST op code, INT VAR param1, param2) :
+
+SELECT op code OF
+ CASE 1: open document
+ CASE 2: open page
+END SELECT.
+
+$opendoch$
+ open document :
+ modifikations := 0;
+ param 1 := x step conversion ( x size );
+ param 2 := y step conversion ( y size );
+$initspeed$
+ IF pos (material, "slow") <> 0
+ THEN is slow := TRUE;
+ ELIF pos (material, "fast") <> 0
+ THEN is slow := FALSE;
+ ELSE is slow := std speed name = "slow"
+ FI;
+$opendocfx85$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""27"2"27"6");
+ out (""27"C" + code (param 2 DIV 36)). (* Formularlaenge *)
+
+$opendocfx800$
+ param 2 := (param 2 DIV 36) * 36;
+ was tall font := TRUE;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"t"1""27"6"); (* Zeichentabelle 4 (Grafik) *)
+ out (""27"R"0""27"9"27"O"27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ IF pos (material, "nlq") <> 0
+ THEN out (""27"x"1"")
+ ELIF pos (material, "draft") <> 0
+ THEN out (""27"x"0"")
+ ELIF std quality name = "nlq"
+ THEN out (""27"x"1"")
+ ELSE out (""27"x"0"")
+ FI;
+ IF pos (material, "roman") <> 0
+ THEN out (""27"k"0"")
+ ELIF pos (material, "sansserif") <> 0
+ THEN out (""27"k"1"")
+ ELIF std typeface name = "roman"
+ THEN out (""27"k"0"")
+ ELIF std typeface name = "sansserif"
+ THEN out (""27"k"1"")
+ FI.
+
+$opendocmx$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27"R"0""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ out (""27"9"27"O").
+
+$opendocgp$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27"6"); (* Zeichensatz 2 *)
+ out (""18""27"F"27"H"27"W"0""27"T"27"-"0""); (* Modifikationen rücksetzen *)
+ out (""27"9"27"O"27"A"12""27"2");
+ out (""27"C" + code (param 2 DIV 36)). (* Formularlaenge *)
+
+$opendocpp$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27"6"); (* Zeichensatz 2 *)
+ out (""18""27"F"27"W"0""27"T"27"-"0""); (* Modifikationen rücksetzen *)
+ out (""27"9"27"O"27"A"12""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ IF pos (material, "nlq") <> 0
+ THEN out (""27"G")
+ ELIF pos (material, "draft") <> 0
+ THEN out (""27"H")
+ ELIF std quality name = "nlq"
+ THEN out (""27"G")
+ ELSE out (""27"H")
+ FI.
+
+$opendocml182i$
+ IF pos (material, "nlq") <> 0
+ THEN out (""27"I3")
+ ELIF pos (material, "draft") <> 0
+ THEN out (""27"I1")
+ ELIF std quality name = "nlq"
+ THEN out (""27"I3")
+ ELSE out (""27"I1")
+ FI;
+ out (""27"N"0""); (* Kein Sprung über Perf. *)
+
+$opendocml192el$
+ param 2 := (param 2 DIV 36) * 36;
+ prop font := FALSE;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ out (""27"6"); (* Erweiterung des Zeichensatzes *)
+ out (""27"9"27"O"27"x"0"").
+
+$opendocml292el$
+ param 2 := (param 2 DIV 36) * 36;
+ was tall font := TRUE;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"t"1""27"6"); (* Zeichentabelle 4 (Grafik) *)
+ out (""27"R"0""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ out (""27"9"27"O"27"r0");
+ IF pos (material, "nlq") <> 0
+ THEN out (""27"x"1"")
+ ELIF pos (material, "draft") <> 0
+ THEN out (""27"x"0"")
+ ELIF std quality name = "nlq"
+ THEN out (""27"x"1"")
+ ELSE out (""27"x"0"")
+ FI;
+ IF pos (material, "courier") <> 0
+ THEN out (""27"k"0"")
+ ELIF pos (material, "sansserif") <> 0
+ THEN out (""27"k"1"")
+ ELIF std typeface name = "courier"
+ THEN out (""27"k"0"")
+ ELIF std typeface name = "sansserif"
+ THEN out (""27"k"1"")
+ FI.
+
+$opendocml294i$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27"6"); (* Zeichensatz 2 *)
+ out (""18""27"F"27"W0"27"T"27"-0"27"%H"); (* Modifikationen rücksetzen *)
+ out (""27"9"27"O"27"A"12""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ IF pos (material, "nlq") <> 0
+ THEN out (""27"G")
+ ELIF pos (material, "draft") <> 0
+ THEN out (""27"H")
+ ELIF std quality name = "nlq"
+ THEN out (""27"G")
+ ELSE out (""27"H")
+ FI.
+
+$opendocml320$
+ param 2 := (param 2 DIV 36) * 36;
+ prop font := FALSE;
+ out (""27"{"99""27"{"40""); (* Umschaltung auf EPSON-Emulation *)
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ out (""27"6"); (* Erweiterung des Zeichensatzes *)
+ out (""27"9"27"O"27"x"0"").
+
+$opendoclc10$
+ param 2 := (param 2 DIV 36) * 36;
+ was tall font := TRUE;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"t"1""27"6"); (* Zeichentabelle 4 (Grafik) *)
+ out (""27"R"0""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ out (""27"9"27"r"0"");
+ IF pos (material, "nlq") <> 0
+ THEN out (""27"x"1"")
+ ELIF pos (material, "draft") <> 0
+ THEN out (""27"x"0"")
+ ELIF std quality name = "nlq"
+ THEN out (""27"x"1"")
+ ELSE out (""27"x"0"")
+ FI;
+ IF pos (material, "courier") <> 0
+ THEN out (""27"k"0"")
+ ELIF pos (material, "sansserif") <> 0
+ THEN out (""27"k"1"")
+ ELIF pos (material, "orator1") <> 0
+ THEN out (""27"k"2"")
+ ELIF pos (material, "orator2") <> 0
+ THEN out (""27"k"3"")
+ ELIF std typeface name = "courier"
+ THEN out (""27"k"0"")
+ ELIF std typeface name = "sansserif"
+ THEN out (""27"k"1"")
+ ELIF std typeface name = "orator1"
+ THEN out (""27"k"2"")
+ ELIF std typeface name = "orator2"
+ THEN out (""27"k"3"")
+ FI.
+
+$opendocnx15$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ out (""27"6"); (* Erweiterung des Zeichensatzes *)
+ out (""27"9"27"x"0"").
+
+$opendocdmp4000$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"m"0""27"R"0""27"9"27"O"27"2"27"6");
+ out (""27"C" + code (param 2 DIV 36)). (* Formularlaenge *)
+
+$opendocmt$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ out (""27"O"27"x"0""27"r"0""27"6");
+ IF feeder name = "tractor"
+ THEN act feeder := feeder name;
+ out (""27"[5{")
+ ELSE out (""27"[0{");
+ IF pos (material, "schacht1") <> 0
+ THEN act feeder := "schacht1"
+ ELIF pos (material, "schacht2") <> 0
+ THEN act feeder := "schacht2"
+ ELSE act feeder := feeder name
+ FI
+ FI.
+
+$opendocdx2100$
+param 2 := (param 2 DIV 36) * 36;
+out (""24""27""64""); (* Reset des Druckers *)
+out (""27"R"0""); (* US-Zeichensatz *)
+out (""27"2" + ""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+out (""27"N"0""); (* skip perforation *)
+out (""27"x"0"" + ""27"r"0""). (* draft und black *)
+
+
+$opendoc120d$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""27"9"27"O"27"x0"27"2");
+ out (""27"C" + code (param 2 DIV 36)). (* Formularlaenge *)
+
+$opendocc310$
+ param 2 := (param 2 DIV 36) * 36;
+ out (""27""64""27""64""); (* Reset des Druckers *)
+ out (""27"R"0""27"2");
+ out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+ out (""27"O"27"x"0""27"r"0""27"6");
+ IF feeder name = "tractor"
+ THEN act feeder := feeder name;
+ ELSE IF pos (material, "schacht1") <> 0
+ THEN act feeder := "schacht1"
+ ELIF pos (material, "schacht2") <> 0
+ THEN act feeder := "schacht2"
+ ELSE act feeder := feeder name
+ FI
+ FI.
+
+$openpge$
+ open page :
+ param 1 := 0;
+ param 2 := y step conversion (y margin);
+ x rest := 0;
+ y rest := 0;
+ small := 0;
+ out (""13"").
+$openpgemlsf$
+ open page :
+ param 1 := 0;
+ param 2 := 0;
+ x rest := 0;
+ y rest := 0;
+ small := 0;
+ IF feeder name = "sheet" THEN out (""12"") FI;
+ out (""13"").
+$openpgemtsf$
+ open page :
+ param 1 := 0;
+ param 2 := 0;
+ x rest := 0;
+ y rest := 0;
+ small := 0;
+ IF feeder name = "schacht1"
+ THEN out (""27"[21{"12"")
+ ELIF feeder name = "schacht2"
+ THEN out (""27"[22{"12"")
+ FI;
+ out (""13"").
+
+$openpgec310sf$
+ open page :
+ param 1 := 0;
+ param 2 := 0;
+ x rest := 0;
+ y rest := 0;
+ small := 0;
+ IF feeder name = "schacht1"
+ THEN out (""27""25"1"12"")
+ ELIF feeder name = "schacht2"
+ THEN out (""27""25"2"12"")
+ FI;
+ out (""13"").
+
+$betwoc$
+END PROC open;
+
+PROC close (INT CONST op code, INT CONST param1) :
+
+SELECT op code OF
+ CASE 1: close document
+ CASE 2: close page
+END SELECT.
+close document :
+$clpge$
+. close page :
+ IF param 1 > 0 THEN out (""12"") FI.
+$clmlsf$
+.close page :
+ IF feeder name = "sheet"
+ THEN out (""27""25""3"")
+ ELIF param 1 > 0
+ THEN out (""12"")
+ FI.
+$clmtsf$
+.close page :
+ IF feeder name <> "tractor"
+ THEN out (""27"[2J")
+ ELIF param 1 > 0
+ THEN out (""12"")
+ FI.
+$clc310sf$
+.close page :
+ IF feeder name = "sheet"
+ THEN out (""27""25"R")
+ ELIF param 1 > 0
+ THEN out (""12"")
+ FI.
+
+$betwce$
+END PROC close;
+
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+
+SELECT op code OF
+ CASE 1: write text
+ CASE 2: write cmd
+ CASE 3: carriage return
+ CASE 4: move
+ CASE 5: draw
+ CASE 6: on
+ CASE 7: off
+ CASE 8: type
+END SELECT.
+
+is underline: bit (modifikations, 0).
+is bold : bit (modifikations, 1).
+is italics : bit (modifikations, 2).
+
+ write text :
+ out subtext (string, param 1, param 2).
+$cmd$
+ write cmd :
+ out subtext (string, param 1, param 2).
+$cmdfx800$
+ write cmd :
+ buffer := subtext (string, param 1, param 2);
+ IF buffer = "draft"
+ THEN out (""27"x"0"")
+ ELIF buffer = "nlq"
+ THEN out (""27"x"1"")
+ ELIF buffer = "roman"
+ THEN out (""27"k"0"")
+ ELIF buffer = "sansserif"
+ THEN out (""27"k"1"")
+ ELSE out (buffer)
+ FI.
+$cmdpp$
+ write cmd :
+ buffer := subtext (string, param 1, param 2);
+ IF buffer = "draft"
+ THEN out (""27"H")
+ ELIF buffer = "nlq"
+ THEN out (""27"G")
+ ELSE out (buffer)
+ FI.
+$cmdml182i$
+ write cmd :
+ buffer := subtext (string, param 1, param 2);
+ IF buffer = "draft"
+ THEN out (""27"I1")
+ ELIF buffer = "nlq"
+ THEN out (""27"I3")
+ ELSE out (buffer)
+ FI.
+$cmdml292el$
+ write cmd :
+ buffer := subtext (string, param 1, param 2);
+ IF buffer = "draft"
+ THEN out (""27"x"0"")
+ ELIF buffer = "nlq"
+ THEN out (""27"x"1"")
+ ELIF buffer = "courier"
+ THEN out (""27"k"0"")
+ ELIF buffer = "sansserif"
+ THEN out (""27"k"1"")
+ ELIF buffer = "schwarz"
+ THEN out (""27"r0")
+ ELIF buffer = "rot"
+ THEN out (""27"r1")
+ ELIF buffer = "blau"
+ THEN out (""27"r2")
+ ELIF buffer = "violett"
+ THEN out (""27"r3")
+ ELIF buffer = "gelb"
+ THEN out (""27"r4")
+ ELIF buffer = "orange"
+ THEN out (""27"r5")
+ ELIF buffer = "grün"
+ THEN out (""27"r6")
+ ELSE out (buffer)
+ FI.
+$cmdml294i$
+ write cmd :
+ buffer := subtext (string, param 1, param 2);
+ IF buffer = "draft"
+ THEN out (""27"H")
+ ELIF buffer = "nlq"
+ THEN out (""27"G")
+ ELIF buffer = "schwarz"
+ THEN out (""27"r0")
+ ELIF buffer = "rot"
+ THEN out (""27"r1")
+ ELIF buffer = "blau"
+ THEN out (""27"r2")
+ ELIF buffer = "violett"
+ THEN out (""27"r3")
+ ELIF buffer = "gelb"
+ THEN out (""27"r4")
+ ELIF buffer = "orange"
+ THEN out (""27"r5")
+ ELIF buffer = "grün"
+ THEN out (""27"r6")
+ ELSE out (buffer)
+ FI.
+$cmdlc10$
+ write cmd :
+ buffer := subtext (string, param 1, param 2);
+ IF buffer = "draft"
+ THEN out (""27"x"0"")
+ ELIF buffer = "nlq"
+ THEN out (""27"x"1"")
+ ELIF buffer = "courier"
+ THEN out (""27"k"0"")
+ ELIF buffer = "sansserif"
+ THEN out (""27"k"1"")
+ ELIF buffer = "orator1"
+ THEN out (""27"k"2"")
+ ELIF buffer = "orator2"
+ THEN out (""27"k"3"")
+ ELIF buffer = "schwarz"
+ THEN out (""27"r"0"")
+ ELIF buffer = "rot"
+ THEN out (""27"r"1"")
+ ELIF buffer = "blau"
+ THEN out (""27"r"2"")
+ ELIF buffer = "violett"
+ THEN out (""27"r"3"")
+ ELIF buffer = "gelb"
+ THEN out (""27"r"4"")
+ ELIF buffer = "orange"
+ THEN out (""27"r"5"")
+ ELIF buffer = "grün"
+ THEN out (""27"r"6"")
+ ELSE out (buffer)
+ FI.
+$cmdmt230$
+ write cmd :
+ buffer := subtext (string, param 1, param 2);
+ IF feeder name <> "tractor"
+ THEN IF buffer = "schacht1" OR buffer = "schacht2"
+ THEN act feeder := buffer
+ FI
+ ELIF buffer = "schwarz"
+ THEN out (""27"r"0"")
+ ELIF buffer = "magenta"
+ THEN out (""27"r"1"")
+ ELIF buffer = "cyan"
+ THEN out (""27"r"2"")
+ ELIF buffer = "blau"
+ THEN out (""27"r"3"")
+ ELIF buffer = "gelb"
+ THEN out (""27"r"4"")
+ ELIF buffer = "rot"
+ THEN out (""27"r"5"")
+ ELIF buffer = "grün"
+ THEN out (""27"r"6"")
+ ELSE out (buffer)
+ FI.
+
+$cmdc310$
+ write cmd :
+ buffer := subtext (string, param 1, param 2);
+ IF feeder name <> "tractor"
+ THEN IF buffer = "schacht1" OR buffer = "schacht2"
+ THEN act feeder := buffer
+ FI
+ ELIF buffer = "schwarz"
+ THEN out (""27"r"0"")
+ ELIF buffer = "rot"
+ THEN out (""27"r"1"")
+ ELIF buffer = "blau"
+ THEN out (""27"r"2"")
+ ELIF buffer = "violett"
+ THEN out (""27"r"3"")
+ ELIF buffer = "gelb"
+ THEN out (""27"r"4"")
+ ELIF buffer = "orange"
+ THEN out (""27"r"5"")
+ ELIF buffer = "grün"
+ THEN out (""27"r"6"")
+ ELSE out (buffer)
+ FI.
+
+$cmddx2100$
+ write cmd :
+ buffer := subtext (string, param 1, param 2);
+ IF buffer = "schwarz"
+ THEN out (""27"r"0"")
+ ELIF buffer = "rot"
+ THEN out (""27"r"1"")
+ ELIF buffer = "blau"
+ THEN out (""27"r"2"")
+ ELIF buffer = "violett"
+ THEN out (""27"r"3"")
+ ELIF buffer = "gelb"
+ THEN out (""27"r"4"")
+ ELIF buffer = "orange"
+ THEN out (""27"r"5"")
+ ELIF buffer = "grün"
+ THEN out (""27"r"6"")
+ ELSE out (buffer)
+ FI.
+
+$crs$
+ carriage return :
+ y rest INCR small;
+ x rest := 0;
+ small := 0;
+ out (""13"").
+$moh$
+x steps : param1.
+y steps : param2.
+
+move :
+ IF x steps < 0 OR y steps < 0 THEN stop FI;
+ IF x steps > 0 THEN x move FI;
+ IF y steps > 0 THEN y move FI.
+
+$mofx85$
+x move :
+ high := (x steps + x rest) DIV blankbreite;
+ x rest := (x steps + x rest) MOD blankbreite;
+ IF high > 0 THEN high TIMESOUT " " FI;
+ IF x rest > 0 AND is slow
+ THEN IF is underline THEN out (" "8"") FI;
+ out (""27"Y"+ code (x rest) + ""0"");
+ x rest TIMESOUT ""0"";
+ x rest := 0
+ FI.
+
+
+$mofx800$
+x move :
+ IF is underline
+ THEN underline x move
+ ELSE simple x move
+ FI.
+
+underline x move:
+ high := (x steps + x rest) DIV blankbreite;
+ low := (x steps + x rest) MOD blankbreite;
+ IF high > 0 THEN high TIMESOUT " " FI;
+ IF low > 0
+ THEN out (" "8""27"\"+ code (low) + ""0"")
+ FI.
+
+simple x move:
+ out (""27"\");
+ out (code (x steps MOD 256));
+ out (code (x steps DIV 256)).
+
+$modrmx$
+x move :
+ high := (x steps + x rest) DIV blankbreite;
+ low := (x steps + x rest) MOD blankbreite;
+ IF high > 0 THEN high TIMESOUT " " FI;
+ IF low > 0 AND is slow
+ THEN IF is underline THEN out ("_"8"") FI;
+ IF is condensed
+ THEN high := low;
+ low := 0;
+ out (""27"L"+ code (high) + ""0"");
+ ELSE high := low DIV 2;
+ low := low MOD 2;
+ out (""27"K"+ code (high) + ""0"");
+ FI;
+ high TIMESOUT ""0"";
+ IF is small
+ THEN out (""27"S"1"");
+ small DECR 1;
+ FI;
+ FI;
+ x rest := low.
+
+y move :
+ y rest INCR y steps;
+ IF y rest > 0
+ THEN high := y rest DIV 255;
+ low := y rest MOD 255;
+ IF high > 0 THEN high TIMESOUT ""27"J"255"" FI;
+ IF low > 0 THEN out (""27"J"); out (code (low)) FI;
+ y rest := 0
+ FI.
+
+draw :
+ IF x steps < 0 OR y steps <> 0 OR linetype <> 1
+ THEN stop
+ ELIF x steps > 0
+ THEN x draw
+ FI.
+
+x draw :
+ out (""27"L");
+ out (code (x steps MOD 256));
+ out (code (x steps DIV 256));
+ x steps TIMESOUT ""1"";
+ IF is small THEN out (""27"S"1"") FI.
+
+$mogp$
+x move :
+ high := (x steps + x rest) DIV blankbreite;
+ x rest := (x steps + x rest) MOD blankbreite;
+ IF high > 0 THEN high TIMESOUT " " FI;
+ IF x rest > 0 AND is slow
+ THEN IF is underline
+ THEN out (" "13""27"Y");
+ out (code (x pos MOD 256));
+ out (code (x pos DIV 256));
+ x pos TIMESOUT ""0""
+ ELSE out (""27"Y"+ code (x rest) + ""0"");
+ x rest TIMESOUT ""0""
+ FI;
+ x rest := 0
+ FI.
+
+$moml192el$
+x move :
+ high := (x steps + x rest) DIV blankbreite;
+ x rest := (x steps + x rest) MOD blankbreite;
+ IF high > 0 THEN high TIMESOUT " " FI;
+ IF x rest > 0 AND is slow
+ THEN IF is underline THEN
+ IF prop font THEN
+ out (""27"p"0"" + " "8"" + ""27"p"1"")
+ ELSE
+ out (" "8"")
+ FI;
+ FI;
+ out (""27"Y"+ code (x rest) + ""0"");
+ x rest TIMESOUT ""0"";
+ x rest := 0
+ FI.
+
+$ymodr$
+y move :
+ y rest INCR y steps;
+ IF y rest > 0
+ THEN high := y rest DIV 255;
+ low := y rest MOD 255;
+ IF high > 0 THEN high TIMESOUT ""27"J"255"" FI;
+ IF low > 0 THEN out (""27"J"); out (code (low)) FI;
+ y rest := 0
+ FI.
+
+draw :
+ IF x steps < 0 OR y steps <> 0 OR linetype <> 1
+ THEN stop
+ ELIF x steps > 0
+ THEN x draw
+ FI.
+
+x draw :
+ out (""27"Y");
+ out (code (x steps MOD 256));
+ out (code (x steps DIV 256));
+ x steps TIMESOUT ""1"".
+
+$onoff$
+ on :
+ IF on string (param 1) <> ""
+ THEN out (on string (param 1));
+ modifikations := modifikations OR param 1
+ ELSE stop
+ FI.
+
+ off :
+ IF off string (param 1) <> ""
+ THEN out (off string (param 1));
+ modifikations := modifikations AND (param 1 XOR -1)
+ ELSE stop
+ FI.
+
+$onoffpp$
+ on :
+ IF on string (param 1) <> "" AND param 1 <> 2
+ THEN out (on string (param 1));
+ modifikations := modifikations OR param 1
+ ELSE stop
+ FI.
+
+ off :
+ IF off string (param 1) <> "" AND param 1 <> 2
+ THEN out (off string (param 1));
+ modifikations := modifikations AND (param 1 XOR -1)
+ ELSE stop
+ FI.
+
+$tyfx85$
+ type :
+ buffer := font string (param 1);
+ out (buffer);
+ restore modifikations;
+ blankbreite := char pitch (param 1, " ");
+ IF pos (buffer, ""27"S") <> 0 THEN small DECR 1 FI.
+
+$tyfx800$
+ type :
+ buffer := font string (param 1);
+ IF was tall font
+ THEN out (""27"w"0"")
+ FI;
+ out (buffer);
+ restore modifikations;
+ blankbreite := char pitch (param 1, " ");
+ was tall font := pos (buffer, ""27"w"1"") <> 0.
+
+$tymx$
+ type :
+ buffer := font string (param 1);
+ blankbreite := char pitch (param 1, " ");
+ is condensed := pos (buffer, ""15"") <> 0;
+ IF pos (buffer, ""27"S") <> 0
+ THEN small DECR 1;
+ is small := TRUE;
+ ELSE is small := FALSE;
+ FI;
+ out (buffer);
+ restore modifikations.
+
+$tyohnesmall$
+ type :
+ buffer := font string (param 1);
+ out (buffer);
+ restore modifikations;
+ blankbreite := char pitch (param 1, " ").
+
+$tyml192el$
+ type :
+ buffer := font string (param 1);
+ out (buffer);
+ restore modifikations;
+ blankbreite := char pitch (param 1, " ");
+ prop font := pos (buffer, ""27"p"1"") <> 0;
+ IF pos (buffer, ""27"S") <> 0 THEN small DECR 1 FI.
+
+$tyml292el$
+ type :
+ buffer := font string (param 1);
+ IF was tall font
+ THEN out (""27""31"0"27"U0")
+ FI;
+ was tall font := pos (buffer, ""27"w"1"") <> 0;
+ change all (buffer, ""27"w"0"", ""27""31"0"27"U0");
+ change all (buffer, ""27"w"1"", ""27""31"1"27"U1");
+ out (buffer);
+ restore modifikations;
+ blankbreite := char pitch (param 1, " ").
+
+$ontyml294i$
+ on :
+ IF on string (param 1) <> "" AND param 1 <> 2
+ THEN out (on string (param 1));
+ modifikations := modifikations OR param 1
+ ELIF param 1 = 4
+ THEN out (""27"%G");
+ modifikations := modifikations OR param 1
+ ELSE stop
+ FI.
+
+ off :
+ IF off string (param 1) <> "" AND param 1 <> 2
+ THEN out (off string (param 1));
+ modifikations := modifikations AND (param 1 XOR -1)
+ ELIF param 1 = 4
+ THEN out (""27"%H");
+ modifikations := modifikations AND (param 1 XOR -1)
+ ELSE stop
+ FI.
+
+ type :
+ buffer := font string (param 1);
+ out (buffer);
+ IF is underline THEN out (on string (1)) FI;
+ IF is bold THEN out (on string (2)) FI;
+ IF is italics THEN out (""27"%G") FI;
+ blankbreite := char pitch (param 1, " ");
+ IF pos (buffer, ""27"S") <> 0 THEN small DECR 1 FI.
+
+$end$
+ restore modifikations:
+ IF is underline THEN out (on string (1)) FI;
+ IF is bold THEN out (on string (2)) FI;
+ IF is italics THEN out (on string (4)) FI.
+
+END PROC execute;
+
+INT VAR reply; DATASPACE VAR ds; FILE VAR file;
+
+PROC printer:
+
+ disable stop;
+ continue (server channel);
+ check error (error message);
+ ds := nilspace;
+ REP forget (ds);
+ execute print;
+ IF is error AND online THEN put error; clear error; FI;
+ PER;
+END PROC printer;
+
+PROC execute print:
+
+ LET ack = 0, fetch code = 11, file type = 1003;
+ enable stop;
+ ds := nilspace;
+ call (father, fetch code, ds, reply);
+ IF reply = ack CAND type (ds) = file type
+ THEN file := sequential file (input, ds);
+ print (file,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+END PROC execute print;
+
+PROC check error(TEXT CONST message):
+
+ IF is error
+ THEN clear error; rename myself (message);
+ IF is error THEN end(myself) FI;
+ pause (9000); end(myself);
+ FI;
+END PROC check error;
+
+END PACKET printerdriver
+
+
diff --git a/printer/dotmatrix9/printer.neun.nadel b/printer/dotmatrix9/printer.neun.nadel
new file mode 100644
index 0000000..00f698b
--- /dev/null
+++ b/printer/dotmatrix9/printer.neun.nadel
@@ -0,0 +1,1129 @@
+PACKET driver inst 9 (* Autoren : mov/hjh *)
+ (* Stand : 01.10.88 *)
+
+ DEFINES druckerkanal,
+ treiber einrichten:
+
+
+LET up = ""3""13""5"",
+
+ generator name = "printer.neun.nadel",
+
+ description file name = "beschreibungen9",
+ module file name = "module9";
+
+
+INT VAR pr channel,
+ positioning,
+ quality,
+ sheet feeder,
+ service option;
+TEXT VAR fonttab name :: "",
+ driver name :: "";
+TEXT VAR inp;
+BOOL VAR was esc;
+
+
+PROC druckerkanal (INT CONST channel) :
+
+ serverchannel (channel)
+
+END PROC druckerkanal;
+
+INT PROC druckerkanal : pr channel END PROC druckerkanal;
+
+
+PROC treiber einrichten:
+
+ treiber einrichten (0)
+END PROC treiber einrichten;
+
+PROC treiber einrichten (INT CONST service opt):
+
+ ask for print channel;
+ main menu;
+ IF installed
+ THEN generate printer spool
+ ELSE inform about restart
+ FI.
+
+ ask for printchannel:
+ inits;
+ page;
+ headline ("Druckerkanal - Einstellung");
+ cursor (1, 15);
+ putline ("Hinweis: Die Druckerkanalnummer kann auch nachträglich mit");
+ putline (" 'druckerkanal (Kanalnummer)' in der Task """ +
+ name (myself) + """");
+ putline (" verändert werden.");
+ REP
+ cursor (1, 10);
+ put (""5"EUMEL-Kanalnummer des Druckerkanals:");
+ get (pr channel);
+ disable stop;
+ druckerkanal (pr channel);
+ BOOL VAR no error :: NOT is error;
+ IF is error
+ THEN cursor (1, 7);
+ put error;
+ putline ("Eingabe korrigiert wiederholen!")
+ FI;
+ clear error;
+ enable stop
+ UNTIL no error PER.
+
+ inits:
+ line;
+ IF single task
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+ FI;
+ command dialogue (TRUE);
+ IF name (myself) <> "PRINTER"
+ THEN putline ("Diese Task heißt nicht ""PRINTER"", sondern """ +
+ name (myself) + """ !");
+ IF yes ("Soll die Task in ""PRINTER"" umbenannt werden ?")
+ THEN rename myself ("PRINTER")
+ FI
+ FI;
+ INT VAR choice;
+ service option := service opt.
+
+ single task: (pcb (9) AND 255) = 1.
+
+ main menu:
+ BOOL VAR installed :: FALSE;
+ REP
+ show main menu;
+ get choice;
+ treat choice
+ UNTIL was esc OR installed PER.
+
+ show main menu:
+ page;
+ headline ("Hauptmenü 9-Nadel-Drucker");
+ putline (" 1. Brother");
+ putline (" 2. Citizen");
+ putline (" 3. C. Itoh");
+ putline (" 4. Epson");
+ putline (" 5. Fujitsu");
+ putline (" 6. IBM");
+ putline (" 7. Mannesmann - Tally");
+ putline (" 8. OKI");
+ putline (" 9. Schneider");
+ putline ("10. Star").
+
+ get choice:
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Installation abbrechen");
+ ask user (10).
+
+ treat choice:
+ SELECT int (inp) OF
+ CASE 1: brother menu
+ CASE 2: citizen menu
+ CASE 3: c itoh menu
+ CASE 4: epson menu
+ CASE 5: fujitsu menu
+ CASE 6: ibm menu
+ CASE 7: mannesmann menu
+ CASE 8: oki menu
+ CASE 9: schneider menu
+ CASE 10: star menu
+ END SELECT.
+
+
+ brother menu:.
+
+ citizen menu:
+ page;
+ headline ("Citizen - Menü");
+ putline (" 1. 120-D");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (1);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ citi120d inst
+ FI.
+
+ citi120d inst:
+ putline ("Citizen 120-D");
+ line;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("S1 S2 S3 S4 S5 S6 S7 S8");
+ putline ("egal OFF OFF egal egal egal egal egal");
+ show control options ("");
+ IF all right
+ THEN get fonttable ("fonttab.7");
+ generate ("citi120d");
+ installed := TRUE
+ FI.
+
+ c itoh menu:
+ page;
+ headline ("C. Itoh - Menü");
+ putline (" 1. C 310 CXP");
+ putline (" 2. C 315 CXP");
+ putline (" 3. CI-3500");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (3);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ IF choice = 3
+ THEN ci3500 inst
+ ELSE c310 inst
+ FI
+ FI.
+
+ c310 inst:
+ IF choice = 1
+ THEN putline ("C. Itoh C 310 CXP")
+ ELSE putline ("C. Itoh C 315 CXP")
+ FI;
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):");
+ putline ("- 00: Epson-Modus (02)");
+ putline ("- 22: nur Wagenrücklauf (01)");
+ show control options ("std speed, paperfeed");
+ show material options ("slow, fast, schacht1, schacht2");
+ show command options ("schacht1, schacht2, schwarz, rot, blau, violett, gelb, orange, grün");
+ ask for positioning;
+ ask for paper feed;
+ IF all right
+ THEN get fonttable ("fonttab.7.cxp");
+ generate ("citohc310cxp");
+ adjust positioning;
+ adjust paper feed;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ ci3500 inst:
+ putline ("C. Itoh CI-3500");
+ line;
+ putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):");
+ putline ("- 26: nur Wagenrücklauf (1)");
+ putline ("- 49: 17,1 Zeichen pro Zoll (17)");
+ show control options ("std speed");
+ show material options ("slow, fast");
+ ask for positioning;
+ IF all right
+ THEN get fonttable ("fonttab.10");
+ generate ("citohci3500");
+ adjust positioning;
+ installed := TRUE
+ FI.
+
+ epson menu:
+ page;
+ headline ("Epson - Menü");
+ putline (" 1. MX 80 Typ III");
+ putline (" 2. MX 100 Typ III");
+ putline (" 3. LX 800");
+ putline (" 4. LX 1000");
+ putline (" 5. FX 85");
+ putline (" 6. FX 105");
+ putline (" 7. FX 800 oder FX 850");
+ putline (" 8. FX 1000 oder FX 1050");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (8);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ SELECT choice OF
+ CASE 1, 2: mx80 inst
+ CASE 3, 4: lx800 inst
+ CASE 5, 6: fx85 inst
+ CASE 7, 8: fx800 inst
+ END SELECT
+ FI.
+
+ mx80 inst:
+ IF choice = 1
+ THEN putline ("Epson MX 80 Typ III")
+ ELSE putline ("Epson MX 100 Typ III")
+ FI;
+ show control options ("std speed");
+ show material options ("slow, fast");
+ ask for positioning;
+ IF all right
+ THEN get fonttable ("fonttab.1");
+ generate ("mx");
+ adjust positioning;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ lx800 inst:
+ IF choice = 3
+ THEN putline ("Epson LX 800")
+ ELSE putline ("Epson LX 1000")
+ FI;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8 SW2-1 SW2-2 SW2-3 SW2-4");
+ putline ("egal egal egal egal egal egal egal egal egal *) OFF OFF");
+ putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug");
+ show control options ("std speed, std quality, std typeface");
+ show material options ("slow, fast, draft, nlq, roman, sansserif");
+ show command options ("draft, nlq, roman, sansserif");
+ ask for positioning;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.20.lx");
+ generate ("lx800");
+ adjust positioning;
+ adjust quality;
+ IF choice = 4 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ fx85 inst:
+ IF choice = 5
+ THEN putline ("Epson FX 85")
+ ELSE putline ("Epson FX 105")
+ FI;
+ line;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8 SW2-1 SW2-2 SW2-3 SW2-4");
+ putline ("egal egal egal ON egal egal egal egal egal egal OFF OFF");
+ show control options ("std speed");
+ show material options ("slow, fast");
+ ask for positioning;
+ IF all right
+ THEN get fonttable ("fonttab.7");
+ generate ("fx85");
+ adjust positioning;
+ IF choice = 6 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ fx800 inst:
+ IF choice = 7
+ THEN putline ("Epson FX 800 oder FX 850")
+ ELSE putline ("Epson FX 1000 oder FX 1050")
+ FI;
+ line;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8 SW2-1 SW2-2 SW2-3 SW2-4");
+ putline ("egal egal egal ON egal egal egal egal egal *) OFF OFF");
+ putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug");
+ show control options ("std quality, std typeface");
+ show material options ("draft, nlq, roman, sansserif");
+ show command options ("draft, nlq, roman, sansserif");
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.20");
+ generate ("fx800");
+ adjust quality;
+ IF choice = 8 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ fujitsu menu:
+ page;
+ headline ("Fujitsu - Menü");
+ putline (" 1. DX 2100");
+ putline (" 2. DX 2200");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (2);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ SELECT choice OF
+ CASE 1,2 : dx2100 inst
+ END SELECT
+ FI.
+
+ dx2100 inst:
+ IF choice = 1
+ THEN putline ("Fujitsu DX 2100")
+ ELSE putline ("Fujitsu DX 2200")
+ FI;
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8 SW2-1 SW2-2 SW2-3 SW2-4");
+ putline ("egal egal egal egal egal egal egal egal egal *) OFF OFF");
+ putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug");
+ show control options ("std speed, paper feed");
+ show material options ("slow, fast");
+ show command options ("schwarz, rot, blau, violett, gelb, rot, grün");
+ ask for positioning;
+ ask for paper feed;
+ IF all right
+ THEN get fonttable ("fonttab.7.fuj");
+ generate ("fujdx2100");
+ adjust positioning;
+ adjust paper feed;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+
+
+ ibm menu:
+ page;
+ headline ("IBM - Menü");
+ putline (" 1. Grafikdrucker (""80 Zeichen breit"")");
+ putline (" 2. Grafikdrucker (""136 Zeichen breit"")");
+ putline (" 3. Proprinter/Grafikdrucker II (""80 Zeichen breit"")");
+ putline (" 4. Proprinter/Grafikdrucker II (""136 Zeichen breit"")");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (4);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ IF choice = 1 OR choice = 2
+ THEN ibmgp inst
+ ELSE ibmpp inst
+ FI
+ FI.
+
+ ibmgp inst:
+ IF choice = 1
+ THEN putline ("IBM Grafikdrucker (""80 Zeichen breit"")")
+ ELSE putline ("IBM Grafikdrucker (""136 Zeichen breit"")")
+ FI;
+ show control options ("std speed");
+ show material options ("slow, fast");
+ ask for positioning;
+ IF all right
+ THEN get fonttable ("fonttab.10");
+ generate ("ibmgp");
+ adjust positioning;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ ibmpp inst:
+ IF choice = 3
+ THEN putline ("IBM Proprinter/Grafikdrucker II (""80 Zeichen breit"")")
+ ELSE putline ("IBM Proprinter/Grafikdrucker II (""136 Zeichen breit"")")
+ FI;
+ show control options ("std speed, std quality");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq");
+ ask for positioning;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.10");
+ generate ("ibmpp");
+ adjust positioning;
+ adjust quality;
+ IF choice = 4 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ mannesmann menu:
+ page;
+ headline ("Mannesmann - Tally - Menü");
+ putline (" 1. MT 230");
+ putline (" 2. MT 340");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (2);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ IF choice = 1
+ THEN mt230 inst
+ ELSE mt340 inst
+ FI
+ FI.
+
+ mt230 inst:
+ putline ("Mannesmann-Tally MT 230");
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Der Drucker muß auf den ANSI+EPSON - Modus eingestellt werden.");
+ putline ("(Siehe: MT 230 Anwenderhandbuch, S. 4-145)");
+ show control options ("std speed, paperfeed");
+ show material options ("slow, fast, schacht1, schacht2");
+ show command options ("schacht1, schacht2, schwarz, magenta, cyan, blau, gelb, rot, grün");
+ ask for positioning;
+ ask for paper feed;
+ IF all right
+ THEN get fonttable ("fonttab.7");
+ generate ("mt230");
+ adjust positioning;
+ adjust paper feed;
+ do ("papersize (39.37, 30.48)");
+ installed := TRUE
+ FI.
+
+ mt340 inst:
+ putline ("Mannesmann-Tally MT 340");
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Der Drucker muß auf den ANSI+EPSON - Modus eingestellt werden.");
+ putline ("(Siehe: MT 340 Anwenderhandbuch, S. 4-104)");
+ show control options ("std speed, paperfeed");
+ show material options ("slow, fast, schacht1, schacht2");
+ show command options ("schacht1, schacht2, schwarz, magenta, cyan, blau, gelb, rot, grün");
+ ask for positioning;
+ ask for paper feed;
+ IF all right
+ THEN get fonttable ("fonttab.7.mt");
+ generate ("mt340");
+ adjust positioning;
+ adjust paper feed;
+ do ("papersize (39.37, 30.48)");
+ installed := TRUE
+ FI.
+
+ oki menu:
+ page;
+ headline ("OKI - Menü");
+ putline (" 1. MICROLINE 182 IBM-kompatibel");
+ putline (" 2. MICROLINE 183 IBM-kompatibel");
+ putline (" 3. MICROLINE 192 ELITE");
+ putline (" 4. MICROLINE 193 ELITE");
+ putline (" 5. MICROLINE 292 ELITE");
+ putline (" 6. MICROLINE 293 ELITE");
+ putline (" 7. MICROLINE 294 IBM-kompatibel");
+ putline (" 8. MICROLINE 320");
+ putline (" 9. MICROLINE 321");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (9);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ SELECT choice OF
+ CASE 1, 2: ml182i inst
+ CASE 3, 4: ml192el inst
+ CASE 5, 6: ml292el inst
+ CASE 7 : ml294i inst
+ CASE 8, 9: ml320 inst
+ END SELECT
+ FI.
+
+ ml182i inst:
+ IF choice = 1
+ THEN putline ("OKI Microline 182 IBM-kompatibel")
+ ELSE putline ("OKI Microline 183 IBM-kompatibel")
+ FI;
+ line;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("S-1 S-2 S-3 S-4 S-5 S-6 S-7 S-8");
+ putline ("egal egal OFF egal egal OFF egal OFF");
+ show control options ("std speed, std quality");
+ show material options ("slow, fast, draft, nlq");
+ show command options ("draft, nlq");
+ ask for positioning;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.10");
+ generate ("okiml182i");
+ adjust positioning;
+ adjust quality;
+ IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ ml192el inst:
+ IF choice = 3
+ THEN putline ("OKI Microline 192 ELITE (IBM/EPSON-kompatibel)")
+ ELSE putline ("OKI Microline 193 ELITE (IBM/EPSON-kompatibel)")
+ FI;
+ line;
+ putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):");
+ putline ("- 13: Automatic Line Feed: Nein");
+ putline ("- 18: Compatibility: EPSON FX");
+ putline ("(Außerdem: Jumper SP5 in Position 'B')");
+ show control options ("std speed, paperfeed");
+ show material options ("slow, fast");
+ ask for positioning;
+ ask for paper feed;
+ IF all right
+ THEN get fonttable ("fonttab.7");
+ generate ("okiml192el");
+ adjust positioning;
+ adjust paper feed;
+ IF choice = 4 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ ml292el inst:
+ IF choice = 5
+ THEN putline ("OKI Microline 292 ELITE (IBM/EPSON-kompatibel)")
+ ELSE putline ("OKI Microline 293 ELITE (IBM/EPSON-kompatibel)")
+ FI;
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):");
+ putline ("- Automatic Line Feed: NO");
+ putline ("- Compatibility: EPSON EX");
+ putline ("(Außerdem: Jumper SP5 in Position 'B')");
+ show control options ("paperfeed, std quality, std typeface");
+ show material options ("draft, nlq, courier, sansserif");
+ show command options ("draft, nlq, courier, sansserif");
+ putline ("schwarz, rot, blau, violett, gelb, orange, grün");
+ ask for paper feed;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.20");
+ generate ("okiml292el");
+ adjust paper feed;
+ adjust quality;
+ IF choice = 6 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ ml294i inst:
+ putline ("OKI Microline 294 IBM-kompatibel");
+ putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem");
+ putline ("Farbband.");
+ line;
+ putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):");
+ putline ("- Proportional Spacing: NO");
+ putline ("- Automatic Line Feed: NO");
+ putline ("- Compatibility: PROPRINTER XL");
+ show control options ("paperfeed, std quality");
+ show material options ("draft, nlq");
+ show command options ("draft, nlq, schwarz, rot, blau, violett, gelb, orange, grün");
+ ask for paper feed;
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.10");
+ generate ("okiml294i");
+ adjust paper feed;
+ adjust quality;
+ do ("papersize (34.544, 30.48)");
+ installed := TRUE
+ FI.
+
+ ml320 inst:
+ IF choice = 8
+ THEN putline ("OKI Microline 320 IBM/EPSON-kompatibel")
+ ELSE putline ("OKI Microline 321 IBM/EPSON-kompatibel")
+ FI;
+ line;
+ putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):");
+ putline ("- Automatic Line Feed: Nein");
+ show control options ("std speed");
+ show material options ("slow, fast");
+ ask for positioning;
+ IF all right
+ THEN get fonttable ("fonttab.7");
+ generate ("okiml320");
+ adjust positioning;
+ IF choice = 9 THEN do ("papersize (34.544, 30.48)") FI;
+ installed := TRUE
+ FI.
+
+ schneider menu:
+ page;
+ headline ("Schneider - Menü");
+ putline (" 1. DMP 4000");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (1);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ dmp4000 inst
+ FI.
+
+ dmp4000 inst:
+ putline ("Schneider DMP 4000");
+ line;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("DS1-4 übrige Schalter");
+ putline (" OFF egal");
+ show control options ("std speed");
+ show material options ("slow, fast");
+ ask for positioning;
+ IF all right
+ THEN get fonttable ("fonttab.7");
+ generate ("dmp4000");
+ adjust positioning;
+ do ("papersize (39.37, 30.48)");
+ installed := TRUE
+ FI.
+
+ star menu:
+ page;
+ headline ("Star - Menü");
+ putline (" 1. LC-10 (auch LC-10 Colour)");
+ putline (" 2. NX-15");
+ putline (" 3. ND-10");
+ putline (" 4. ND-15");
+ putline (" 5. NR-10");
+ putline (" 6. NR-15");
+ cursor (1,24);
+ put ("CR: Eingabe ESC: Zurück zum Hauptmenü");
+ ask user (6);
+ page;
+ choice := int (inp);
+ IF was esc
+ THEN was esc := FALSE
+ ELSE headline ("");
+ putline ("Druckertyp:");
+ IF choice = 1
+ THEN lc10 inst
+ ELIF choice = 2
+ THEN nx15 inst
+ ELSE nd10 inst
+ FI
+ FI.
+
+ lc10 inst:
+ putline ("Star LC-10 oder LC-10 Colour");
+ line;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("S1-1 S1-2 S1-3 S1-4 S1-5 S1-6 S1-7 S1-8 S2-1 S2-2 S2-3 S2-4");
+ putline ("egal egal egal *) egal EIN egal EIN egal egal egal egal");
+ putline ("*) AUS: Einzelblatteinzug, EIN: kein Einzug");
+ show control options ("std quality, std typeface");
+ show material options ("draft, nlq, courier, sansserif, orator1, orator2");
+ show command options ("draft, nlq, courier, sansserif, orator1, orator2");
+ putline ("schwarz, rot, blau, violett, gelb, orange, grün");
+ ask for quality;
+ IF all right
+ THEN get fonttable ("fonttab.20.lc");
+ generate ("starlc10");
+ adjust quality;
+ do ("papersize (21.0, 30.48)");
+ installed := TRUE
+ FI.
+
+ nx15 inst:
+ putline ("Star NX-15");
+ line;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("S1-4 S1-8 S2-5 übrige Schalter");
+ putline ("EIN EIN EIN egal");
+ show control options ("std speed");
+ show material options ("slow, fast");
+ ask for positioning;
+ IF all right
+ THEN get fonttable ("fonttab.7");
+ generate ("starnx15");
+ adjust positioning;
+ do ("papersize (36.0, 30.48)");
+ installed := TRUE
+ FI.
+
+ nd10 inst:
+ IF choice = 3
+ THEN putline ("Star ND-10");
+ ELIF choice = 4
+ THEN putline ("Star ND-15");
+ ELIF choice = 5
+ THEN putline ("Star NR-10");
+ ELSE putline ("Star NR-15");
+ FI;
+ line;
+ putline ("Die DIP-Schalter müssen so eingestellt sein:");
+ putline ("S1-5 S1-6 S2-2 übrige Schalter");
+ putline ("EIN EIN EIN egal");
+ show control options ("std speed");
+ show material options ("slow, fast");
+ ask for positioning;
+ IF all right
+ THEN get fonttable ("fonttab.7");
+ generate ("starnx15");
+ adjust positioning;
+ IF choice = 3 OR choice = 5
+ THEN do ("papersize (21.0, 30.48)")
+ ELSE do ("papersize (36.0, 30.48)")
+ FI;
+ installed := TRUE
+ FI.
+
+generate printer spool:
+ IF service opt = 0
+ THEN forget (generator name, quiet);
+ forget (driver name, quiet)
+ FI;
+ eumel must advertise;
+ cursor (1, 10);
+ putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+ putline ("die Fonttabelle mit dem Kommando");
+ line;
+ putline (" font table (""" + font tab name + """)");
+ line;
+ putline ("eingestellt werden!!!");
+ line (2);
+ putline ("Hinweis: Dieses Installationsprogramm kann in der Task """ + name (myself) + """");
+ putline (" mit 'treiber einrichten' aufgerufen werden, wenn ein anderer");
+ putline (" Drucker eingesetzt werden soll.");
+ line (2);
+ put ("Generierung beendet, weiter mit 'SV'");
+ break (quiet);
+ do ("spool manager (PROC printer)").
+
+ inform about restart:
+ page;
+ putline ("Es ist kein Druckertreiber installiert worden!");
+ line;
+ putline ("Dieses Installationsprogramm kann in der Task """ + name (myself) + """");
+ putline ("mit 'treiber einrichten' erneut aufgerufen werden.");
+ line.
+
+END PROC treiber einrichten;
+
+PROC headline (TEXT CONST header):
+
+ cursor (13,1);
+ putline ("E U M E L - Druckertreiber - Installations - Programm");
+ cursor (40 - LENGTH header DIV 2, 2);
+ put (header);
+ line (2)
+END PROC headline;
+
+PROC ask user (INT CONST max choice):
+
+ TEXT VAR exit;
+ inp := "";
+ REP
+ cursor (1,23);
+ IF inp = ""
+ THEN put ("Ihre Wahl (Nummer eingeben):")
+ ELSE put ("FEHLER! Eingabe korrigieren:")
+ FI;
+ editget (inp, ""27"", "", exit);
+ was esc := exit = ""27"";
+ UNTIL was esc OR ok PER.
+
+ ok:
+ int (inp) > 0 AND int (inp) <= max choice AND last conversion ok.
+END PROC ask user;
+
+PROC show control options (TEXT CONST options):
+
+ line;
+ putline ("Steuerprozeduren in der Task """ + name (myself) + """:");
+ write ("papersize, top margin");
+ IF options <> ""
+ THEN put (",");
+ putline (options)
+ FI
+END PROC show control options;
+
+PROC show material options (TEXT CONST options):
+
+ line;
+ putline ("Mögliche Materialwerte (#material(""..."")#):");
+ putline (options)
+END PROC show material options;
+
+PROC show command options (TEXT CONST options):
+
+ line;
+ putline ("Mögliche direkte Druckeranweisungen (#""...""#):");
+ putline (options)
+END PROC show command options;
+
+PROC ask for positioning:
+
+ line (2);
+ putline ("Positionierung in x-Richtung:");
+ line;
+ REP out (up);
+ IF yes ("in Mikroschritten (genauer, aber langsamer)")
+ THEN positioning := 1; LEAVE ask for positioning
+ FI;
+ out (up);
+ IF yes ("in Blanks (schneller, aber ungenauer)")
+ THEN positioning := 2; LEAVE ask for positioning
+ FI;
+ PER
+END PROC ask for positioning;
+
+PROC ask for quality:
+
+ line (2);
+ putline ("Standard - Druckqualität:");
+ line;
+ REP out (up);
+ IF yes ("Draft Quality (schneller, aber nicht so schön)")
+ THEN quality := 1; LEAVE ask for quality
+ FI;
+ out (up);
+ IF yes ("Near Letter Quality (schöner, aber langsamer)")
+ THEN quality := 2; LEAVE ask for quality
+ FI;
+ PER
+END PROC ask for quality;
+
+PROC ask for paper feed:
+
+ line (2);
+ putline ("Einzelblatteinzug:");
+ line;
+ REP out (up);
+ IF yes ("kein Einzelblatteinzug vorhanden")
+ THEN sheet feeder := 0; LEAVE ask for paper feed
+ FI;
+ out (up);
+ IF yes ("Einzelblatteinzug vorhanden")
+ THEN sheet feeder := 1; LEAVE ask for paper feed
+ FI;
+ PER
+END PROC ask for paper feed;
+
+BOOL PROC all right:
+
+ line (3);
+ cursor (1,23);
+ yes ("Soll der ausgewählte Druckertreiber installiert werden")
+END PROC all right;
+
+PROC get fonttable (TEXT CONST name):
+
+ fonttab name := name;
+ from archive ((description file name & module file name & fonttab name)
+ - all);
+ fonttable (fonttab name);
+ command dialogue (FALSE);
+ save (fonttab name, /"configurator");
+ IF service option = 0
+ THEN forget (fonttab name)
+ FI;
+ command dialogue (TRUE);
+END PROC get fonttable;
+
+PROC from archive (THESAURUS CONST files):
+
+ IF highest entry (files) > 0
+ THEN fetch from archive;
+ release (archive);
+ putline ("Archiv abgemeldet !")
+ FI.
+
+ fetch from archive:
+ THESAURUS VAR thes :: files;
+ REP
+ ask for archive;
+ reserve archive;
+ fetch (thes / ALL archive, archive);
+ thes := thes - all
+ UNTIL highest entry (thes) = 0 PER.
+
+ask for archive:
+ line;
+ putline ("Bitte Archiv mit den Dateien");
+ TEXT VAR buffer;
+ INT VAR index :: 0;
+ REP
+ get (thes, buffer, index);
+ putline (" " + buffer)
+ UNTIL index = 0 PER;
+ putline ("einlegen !");
+ line;
+ putline ("Wenn eingelegt: Taste drücken !");
+ inchar (buffer).
+
+reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ disable stop;
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI;
+ enable stop.
+
+END PROC from archive;
+
+THESAURUS OP & (TEXT CONST left, right):
+ THESAURUS VAR result := empty thesaurus;
+ insert (result, left);
+ insert (result, right);
+ result
+END OP &;
+
+THESAURUS OP & (THESAURUS CONST left, TEXT CONST right):
+ THESAURUS VAR result := left;
+ insert (result, right);
+ result
+END OP &;
+
+PROC generate (TEXT CONST name):
+
+ open files;
+ read description;
+ build programme;
+ insert programme;
+ forget files.
+
+ open files:
+ line (5);
+ cursor (1, 20);
+ putline (""4"Bitte warten !");
+ putline (" - Der Treiber wird generiert.");
+ driver name := "printer." + name + "(generiert)";
+ IF exists (driver name)
+ THEN forget (driver name, quiet)
+ FI;
+ FILE VAR des file :: sequential file (modify, description file name),
+ mod file :: sequential file (modify, module file name),
+ driver file :: sequential file (output, driver name).
+
+ read description:
+ to line (des file, 1);
+ col (des file, 1);
+ downety (des file, "$" + name + "$");
+ IF eof (des file)
+ THEN errorstop ("Beschreibung von """ + name + """ nicht im"13""10"" +
+ "Descriptions-File enthalten")
+ FI;
+ TEXT VAR description :: "",
+ record;
+ BOOL VAR done :: FALSE;
+ read record (des file, record);
+ record := subtext (record, col (des file) + LENGTH name + 2);
+ WHILE NOT eof (des file) AND NOT done REP
+ treat record
+ PER.
+
+ treat record:
+ INT VAR dollar pos :: pos (record, "$");
+ IF dollar pos = 0
+ THEN description CAT compress (record);
+ down (des file);
+ read record (des file, record)
+ ELSE description CAT compress (subtext (record, 1, dollar pos - 1));
+ col (des file, dollar pos);
+ done := TRUE;
+ FI.
+
+ build programme:
+ get module name;
+ WHILE still modules REP
+ find module;
+ transfer module;
+ get module name
+ PER.
+
+ get module name:
+ INT VAR semicol pos :: pos (description, ";");
+ TEXT VAR module name;
+ IF semicol pos > 0
+ THEN module name := subtext (description, 1, semicol pos - 1);
+ description := subtext (description, semicol pos + 1)
+ ELSE module name := description;
+ description := ""
+ FI.
+
+ still modules:
+ module name <> "" OR description <> "".
+
+ find module:
+ to line (mod file, 1);
+ col (mod file, 1);
+ downety (mod file, "$" + module name + "$");
+ IF eof (mod file)
+ THEN errorstop ("Modul """ + module name + """ nicht im"13""10"" +
+ "Modul-File enthalten")
+ FI.
+
+ transfer module:
+ done := FALSE;
+ read record (mod file, record);
+ record := subtext (record, col (mod file) + LENGTH module name + 2);
+ WHILE NOT eof (mod file) AND NOT done REP
+ transfer record
+ PER.
+
+ transfer record:
+ dollar pos := pos (record, "$");
+ IF dollar pos = 0
+ THEN write (driver file, compress (record));
+ line (driver file);
+ down (mod file);
+ read record (mod file, record)
+ ELSE write (driver file, compress (subtext (record, 1,
+ dollar pos - 1)));
+ col (mod file, dollar pos);
+ done := TRUE;
+ cout (line no (mod file))
+ FI.
+
+ insert programme:
+ IF online
+ THEN putline (" - Der Treiber wird insertiert.")
+ FI;
+ check off;
+ insert (driver name).
+
+ forget files:
+ IF service option = 0
+ THEN forget (description file name, quiet);
+ forget (module file name, quiet)
+ FI.
+END PROC generate;
+
+PROC adjust positioning:
+
+ IF positioning = 1
+ THEN do ("std speed (""slow"")")
+ ELSE do ("std speed (""fast"")")
+ FI
+END PROC adjust positioning;
+
+PROC adjust quality:
+
+ IF quality = 1
+ THEN do ("std quality (""draft"")")
+ ELSE do ("std quality (""nlq"")")
+ FI
+END PROC adjust quality;
+
+PROC adjust paper feed:
+
+ IF sheet feeder = 1
+ THEN do ("paper feed (""sheet"")")
+ ELSE do ("paper feed (""tractor"")")
+ FI
+END PROC adjust paperfeed;
+
+treiber einrichten
+
+END PACKET driver inst 9
+
diff --git a/printer/dotmatrix9/readme b/printer/dotmatrix9/readme
new file mode 100644
index 0000000..2047abe
--- /dev/null
+++ b/printer/dotmatrix9/readme
@@ -0,0 +1,324 @@
+#type("nlq10")##limit(18.0)##start(1.5,1.0)#
+#head#
+Treiber-Installations-Programm #right#Seite %
+für 9-Nadel-Matrixdrucker #right#23.06.1988
+
+
+#end#
+#on("u")#Dokumentation zum Treiber-Installations-Programm für 9-Nadel-
+Matrixdrucker#off("u")#
+
+#on("u")#Inhalt:#off("u")#
+
+1. Installations- und Gebrauchsanleitung
+2. Druckertreiber-Auswahl
+3. Steuerungsmöglichkeiten und Spezialfeatures
+4. Weitere Hinweise
+
+
+#on("b")#1. Installations- und Gebrauchsanleitung#off("b")#
+
+#on("u")#Einrichten#off("u")#
+So wird das Treiber-Installationsprogramm eingerichtet:
+
+ SV drücken
+
+ nach 'gib supervisor kommando:'
+
+ begin("PRINTER","SYSUR")
+
+ in der Task "PRINTER" (nach 'gib kommando'):
+
+ archive ("std.printer")
+ fetch ("printer.neun.nadel",archive)
+ check off
+ insert ("printer.neun.nadel")
+
+Das Programm wird dann insertiert.
+
+#on("u")#Druckerkanal#off("u")#
+Hiernach wird die Kanalnummer des Druckers erfragt. Wenn der Drucker
+über Parallelschnittstelle betrieben wird, ist die Kanalnummer
+meistens 15.
+
+#on("u")#Menüsystem#off("u")#
+Das Installationsprogramm zeigt nun eine Liste von Druckerherstellern.
+Wählen Sie den Hersteller Ihres Druckers aus! Hiernach wird eine Liste
+der unterstützten Drucker dieses Herstellers gezeigt. Wählen Sie hier
+den passenden Typ aus!
+Das Installationsprogramm zeigt nun einige Informationen zu dem ange­
+wählten Drucker. Besonders zu beachten sind hierbei #on("u")#Angaben zur Konfi­
+guration des Druckers#off("u")# (z.B. DIP-Schalter). Der Drucker muß unbedingt
+wie angegeben konfiguriert werden, wenn er mit dem ausgewählten Trei­
+ber betrieben werden soll.
+
+Hinweise zu Konfigurationsangaben:
+1. Die Angabe 'egal' bedeutet, daß die Einstellung für die Funktion
+ des Treibers keine Bedeutung hat. Dennoch solte der Anwender darauf
+ achten, welche Funktion die Schalter haben (Druckerhandbuch!). So
+ ist es zum Beispiel immer empfehlenswert, den Papierende-Sensor zu
+ aktivieren, damit der Drucker nach Papierende nicht auf der Walze
+ weiterdruckt.
+2. Die Konfigurationsangaben beziehen sich immer auf genau den ausge­
+ wählten Druckertyp. Wenn Sie den Treiber mit einem anderen Drucker
+ als den ausgewählten verwenden, dann beachten Sie folgende Regeln
+ für die Konfiguration:
+ - Der Drucker muß auf eine passende Emulation konfiguriert werden.
+ - Der Drucker darf bei einem Carriage Return (Code 13) keinen Zei­
+ lenvorschub durchführen.
+ - Der Drucker darf die Perforation #on("u")#nicht#off("u")# automatisch überspringen.
+
+ - Auf Seitenlängen und internationale Zeichensätze müssen Sie nicht
+ achten.
+
+(Hinweise zur Auswahl des richtigen Treibers gibt Abschnitt 2)
+
+Nach den Konfigurationsangaben werden Steuerungsmöglichkeiten des
+ausgewählten Treibers angezeigt. (Siehe hierzu Abschnitt 3)
+
+Falls der Treiber bestimmte grundsätzliche Betriebsmöglichkeiten er­
+laubt (z.B. DRAFT/NLQ, Einzelblatteinzug), werden Sie danach gefragt,
+welche Möglichkeit standardmäßig gewählt werden soll. diese Vorein­
+stellungen können nachträglich in der Task "PRINTER" mit den entspre­
+chenden Steuerprozeduren neu gesetzt werden. Außerdem können bestimmte
+Einstellungen noch für jedes einzelne Dokument (d.h. für jede Druck­
+datei) gewählt ('material'-Anweisung) oder sogar innerhalb eines Doku­
+ments verändert werden (direkte Druckeranweisung \#"..."\#).
+Über die Steuerungsmöglichkeiten informiert Abschnitt 3 ausführlicher.
+
+
+#on("b")#2. Druckertreiber-Auswahl#off("b")#
+
+#on("u")#Verwendung nicht im Menü enthaltener Drucker#off("u")#
+Für den Fall, daß Sie genau Ihren Drucker im Menü nicht finden, soll­
+ten Sie zunächst versuchen, ob ein Treiber für einen anderen Drucker
+des gleichen Herstellers mit Ihrem Drucker korrekt arbeitet.
+Falls dies nicht funktioniert oder der Hersteller überhaupt nicht im
+Menü erscheint, müssen Sie herausfinden (Druckerhandbuch, -händler!),
+welchen Drucker Ihr Drucker emuliert oder welchem er ähnlich ist.
+(Viele Drucker verfügen über EPSON FX-85 bzw. FX-800-Emulationen oder
+IBM Grafikdrucker bzw. Proprinter-Eumulationen.)
+Eine der beiden Anpassungen 'EPSON MX' oder 'IBM-Grafikdrucker' müßte
+immer einen (Minimal-) Betrieb ermöglichen.
+
+#on("u")#Hinweise zu den Treibern für FX-80/85-kompatilble Drucker#off("u")#
+Die Treiber für FX-80-bzw. FX-85-kompatible Geräte, die oft auch IBM-
+kompatibel sind, basieren üblicherweise auf den Treibern für EPSON-
+Drucker, weil so einige Schrifttypen (z.B. Proportionalschrift) und
+Modifikationen leichter ausgenutzt werden können. Ein Nachteil liegt
+aber darin, daß beim FX-80 und FX-85 noch die alten EPSON-Zeichensätze
+benutzt werden, die nicht die IBM-üblichen Grafik- und Sonderzeichen
+enthalten.
+Falls für Sie die Benutzung dieser Zeichen vordringlich ist, sollten
+Sie Ihren Drucker (nachdem er auf IBM-Emulation konfiguriert wurde)
+zusammen mit dem Treiber für IBM-Grafikdrucker bzw. -Proprinter ver­
+wenden.
+
+
+#on("b")#3. Steuerungsmöglichkeiten und Spezialfeatures#off("b")#
+
+Einige Treiber bieten bestimmte Einstellungsmöglichkeiten (z.B.
+DRAFT/NLQ) und/oder Spezialfeatures (z.B. Farbdruck).
+Die Einstellungen können über
+- Steuerprozeduren
+- Materialanweisungen bzw.
+- direkte Druckeranweisungen
+vorgenommen werden.
+
+#on("u")#Steuerprozeduren#off("u")#
+setzen Einstellungen, die für alle Dokumente (Druckdateien) gelten
+sollen. Die Prozeduren müssen in der Druckspooltask (meist: "PRINTER")
+aufgerufen werden. #on("b")#Gültig werden die Änderungen erst, wenn danach in
+der Druckspooltask das Kommando 'start' gegeben wird!#off("b")#
+
+PROC papersize (REAL CONST breite, länge)
+ Dient zur Einstellung der Größe der physikalisch beschreibbaren
+ Fläche.
+ Beispiel: papersize (20.32, 30.48)
+ (Standardeinstellung für Endlospapier 8 Zoll breit und
+ 12 Zoll lang)
+
+PROC papersize
+ Informationsprozedur
+
+PROC top margin (REAL CONST margin)
+ Falls der Drucker es nicht erlaubt, direkt am Blattanfang zu druk­
+ ken (zum Beispiel wegen eines Einzelblatteinzugs), muß mit dieser
+ Prozedur die Länge des oberen Randes, den der Drucker nicht be­
+ drucken kann, in cm angegeben werden.
+ Beispiel: top margin (2.0)
+ (Teilt dem Druckertreiber mit, daß die ersten 2 cm
+ nicht bedruckbar sind.)
+
+REAL PROC top margin
+ Informationsprozedur
+
+PROC std speed (TEXT CONST speed)
+ Parameter: slow, fast
+ Wahl zwischen Positionierung in Mikroschritten (slow) oder in
+ Blanks (fast).
+ Beispiel: std speed ("slow")
+
+TEXR PROC std speed
+ Informationsprozedur
+
+PROC std quality (TEXT CONST quality)
+ übliche Parameter: draft, nlq
+ Wahl zwischen Datenverarbeitungs-Qualität und Schönschrift-
+ Qualität
+ Beispiel: std quality ("draft")
+
+TEXT PROC std quality
+ Informationsprozedur
+
+PROC std typeface (TEXT CONST typeface)
+ übliche Parameter: roman, sansserif, courier
+ Wahl zwischen verschiedenen NLQ-Schriftarten (nur sichtbar im
+ NLQ-Modus, das heißt 'std typeface' schaltet nicht auf NLQ).
+ Beispiel: std typeface ("roman")
+
+TEXT PROC std typeface
+ Informationsprozedur
+
+PROC paper feed (TEXT CONST name)
+ übliche Parameter: tractor, sheet, schacht1, schacht2
+ Wählt Endlospapier oder Einzelblatteinzug und ggf. Schachtnummer.
+ Beispiel: paper feed ("sheet")
+
+TEXT PROC paper feed
+ Informationsprozedur
+
+
+#on("u")#Materialanweisungen \#material("...")\##off("u")#
+müssen in der Druckdatei vor dem ersten druckbaren Zeichen stehen und
+setzen Einstellungen für eine ganze Datei. (Materialanweisungen haben
+für die jeweilige Datei Vorrang vor den durch Steuerprozeduren einge­
+stellten Standardwerten. Diese werden durch die Materialanweisung aber
+nicht geändert.)
+
+Beispiel: \#material("nlq")\#
+ sorgt bei entsprechendem Treiber dafür, daß das gesamte
+ Dokument in Schönschrift-Qualität ausgedruckt wird, egal
+ wie 'std quality' eingestellt ist.
+
+#on("b")#Es darf in einer Datei nur eine Materialanweisung stehen!#off("b")# Sollen meh­
+rere Einstellungen vorgenommen werden, müssen sie in einer Anweisung
+erscheinen. Beispiel: \#material("sheet;draft")\#
+
+
+#on("u")#direkte Druckeranweisungen \#"..."\##off("u")#
+gelten ab der Position, an der sie in der Datei auftreten. Sie haben
+(sofern sie erlaubt sind,) Vorrang vor Standardeinstellungen und
+Materialeinstellungen.
+
+Beispiel: \#"draft"\#
+ schaltet (bei entsprechendem Treiber) auf Datenverar­
+ beitungs-Qualität, egal welche Standardeinstellung vorliegt
+ und welche Materialanweisung gegeben wurde.
+
+#on("b")#In einer Druckeranweisung darf nur eine Einstellung vorgenommen
+werden.#off("b")# Also: \#"nlq"\#\#"sansserif"\#
+
+
+#on("u")#Wichtig#off("u")#
+- Achten Sie bei Materialanweisungen und direkten Druckeranweisungen
+ besonders auf korrekte Schreibweise! Es werden nur Kleinbuchstaben
+ berücksichtigt! Also: \#"nlq"\# und keinesfalls \#"NLQ"\#!!!
+- Direkte Druckeranweisungen werden vom EUMEL-Drucker ignoriert und
+ nur vom Druckertreiber in eine Kommando-Sequenz umgesetzt. Es kann
+ daher vorkommen, daß (z.B. bei Spaltendruck) unerwartete Ergebnisse
+ erscheinen, weil der EUMEL-Drucker dann den Text in einer anderen
+ Reihenfolge an den Drucker sendet, als er in der Datei steht, die
+ mit dem direkten Druckerkommando gesetzte Modifikation aber (z.B.
+ für beide Spalten) unerwünscht erhalten bleibt.
+
+
+#on("u")#Tabelle#off("u")#
+Die Tabelle soll einen Anhaltspunkt dafür geben, wie welche Einstel­
+lungen erfolgen können.
+
+#type("17")#
+ Steuerprozeduren Materialanweisungen direkte Druckeranweisungen
+
+#on("u")#                                                                                          #off("u")#
+
+Positionierung std speed slow, fast ------
+ slow, fast
+
+Qualität std quality z.B. draft, nlq z.B. draft, nlq
+ z.B. draft, nlq
+
+Schriftart std typeface z.B. roman, z.B. roman,
+(nur bei NLQ) z.B. roman, sansserif, courier sansserif, courier
+ sansserif, courier
+
+Einzelblatt- paper feed z.B. schacht1, z.B. schacht1,
+einzug z.B. tractor, schacht2 schacht2
+ sheet,
+ schacht1, schacht2
+
+Farbdruck ------ ------ z.B. schwarz,
+ rot, blau,
+ violett, gelb
+ orange, grün
+
+
+
+#type("nlq10")##on("b")#4. Weitere Hinweise#off("b")#
+
+#on("u")#Zeichensatzänderungen gegenüber früheren Versionen#off("u")#
+In den Fonttabellen früherer Druckertreiber-Versionen wurden oberhalb
+des Codes 127 einige internationale Zeichen zur Verfügung gestellt
+(und zwar in Anlehnung an den Agfa-Laserdrucker-Zeichensatz).
+Bei den Treibern der vorliegenden Version gilt folgendes:
+- Wie bisher wird der volle im Benutzerhandbuch festgelegte EUMEL-
+ Zeichensatz (sofern möglich) unterstützt.
+- Der Code 252 liefert das Paragraphzeichen.
+- Alle übrigen (vom EUMEL-Zeichensatz nicht definierten) Zeichencodes
+ oberhalb 127 liefern, sofern möglich, die entsprechenden Zeichen des
+ IBM-Grafikzeichensatzes.
+
+
+#on("u")#Hinweis zu Proportionalschriften#off("u")#
+Bei Proportionalschriften sollte die Modifikation \#on("i")\# nicht
+benutzt werden, da die kursiven Zeichen andere Proportionalbreiten
+haben. Stattdessen sollte auf den schrägen Typ umgeschaltet werden
+(z.B. von "prop10" auf "prop10i").
+
+
+#on("u")#Hinweis zur Benutzung von Einzelblatteinzügen#off("u")#
+Bei der Benutzung von Einzelblatteinzügen müssen folgende Einstel­
+lungen vorgenommen werden (vgl. auch Abschnitt 3!):
+
+ Am Drucker:
+1. Sie müssen Ihren Drucker auf die Option Einzelblatteinzug konfigu­
+ rieren (siehe Druckerhandbuch!).
+
+ In der Druckspooltask (meist 'PRINTER'):
+2. Falls der Druckertreiber die Steuerprozedur 'paper feed' zur Verfü­
+ gung stellt, müssen Sie mit 'paperfeed ("sheet")' oder (für
+ 2-Schacht-Einzüge) mit 'paperfeed ("schacht1")' bzw. 'paperfeed
+ ("schacht2")' den Druckertreiber auf Einzelblatteinzug umschalten.
+3. Falls Sie eine andere Papierlänge als 12 Zoll (=30.48 cm) verwen­
+ den, müssen Sie die neuen Papiermaße mit 'papersize' in cm einstel­
+ len.
+ Beispiel: papersize (21.0, 29.7)
+ (für DIN A4-Blätter)
+4. Falls der Drucker mit dem Einzelblatteinzug nicht direkt am Blatt­
+ anfang drucken kann, sondern ein gewisser oberer Rand bleibt, muß
+ mit 'top margin' die Länge des nicht bedruckbaren Randes in cm dem
+ Druckertreiber mitgeteilt werden.
+ Beispiel: top margin (1.5)
+ (Wie groß der obere Rand ist, kann festgestellt werden, indem eine
+ Datei mit \#start(0.0,0.0)\# ausgedruckt wird.)
+
+ Wurde mit 'top margin' dem Treiber die Größe der nicht bedruckbaren
+ Fläche mitgeteilt, so ist darauf zu achten, daß in den Druckdateien
+ ein genügend großer y-Wert für die Startposition eingestellt wird
+ ('start'-Anweisung). Andernfalls kommt es bei der Ausgabe in der
+ ersten Zeile zu Überschreibungen.
+
+
+#on("b")#5. Die Änderungen, die Sie in der Druckspooltask vorgenommen haben
+ werden erst wirksam, wenn das Spool-Kommando 'start' gegeben wird.#off("b")#
+
diff --git a/printer/laser/fonttab.apple.laserwriter b/printer/laser/fonttab.apple.laserwriter
new file mode 100644
index 0000000..bee2d6a
--- /dev/null
+++ b/printer/laser/fonttab.apple.laserwriter
Binary files differ
diff --git a/printer/laser/fonttab.canon.lbp-8 b/printer/laser/fonttab.canon.lbp-8
new file mode 100644
index 0000000..45314ac
--- /dev/null
+++ b/printer/laser/fonttab.canon.lbp-8
Binary files differ
diff --git a/printer/laser/fonttab.epson.sq b/printer/laser/fonttab.epson.sq
new file mode 100644
index 0000000..a3f7af3
--- /dev/null
+++ b/printer/laser/fonttab.epson.sq
Binary files differ
diff --git a/printer/laser/fonttab.hp.laserjet b/printer/laser/fonttab.hp.laserjet
new file mode 100644
index 0000000..4082e46
--- /dev/null
+++ b/printer/laser/fonttab.hp.laserjet
Binary files differ
diff --git a/printer/laser/fonttab.kyocera.f-1010 b/printer/laser/fonttab.kyocera.f-1010
new file mode 100644
index 0000000..9c3fbda
--- /dev/null
+++ b/printer/laser/fonttab.kyocera.f-1010
Binary files differ
diff --git a/printer/laser/fonttab.nec.lc-08 b/printer/laser/fonttab.nec.lc-08
new file mode 100644
index 0000000..f032953
--- /dev/null
+++ b/printer/laser/fonttab.nec.lc-08
Binary files differ
diff --git a/printer/laser/genfont.kyocera.f-1010.dynamic1 b/printer/laser/genfont.kyocera.f-1010.dynamic1
new file mode 100644
index 0000000..fae8c09
--- /dev/null
+++ b/printer/laser/genfont.kyocera.f-1010.dynamic1
@@ -0,0 +1,30 @@
+#"!"82"! "#
+#"CMNT 'dyn1.6 '; GENF 10220, 'DYNAMIC1', 22, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "#
+#"CMNT 'dyn1.6.i '; GENF 10224, 'DYNAMIC1', 22, 32, 126, 32, 0.94, 0.3, 0, 0, 0.0, 0.0; "#
+#"CMNT 'dyn1.8 '; GENF 10280, 'DYNAMIC1', 28, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "#
+#"CMNT 'dyn1.8.i '; GENF 10284, 'DYNAMIC1', 28, 32, 126, 32, 0.94, 0.3, 0, 0, 0.0, 0.0; "#
+#"CMNT 'dyn1.10 '; GENF 10340, 'DYNAMIC1', 34, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "#
+#"CMNT 'dyn1.10.i'; GENF 10344, 'DYNAMIC1', 34, 32, 126, 32, 0.94, 0.3, 0, 0, 0.0, 0.0; "#
+#"CMNT 'dyn1.12 '; GENF 10420, 'DYNAMIC1', 42, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "#
+#"CMNT 'dyn1.12.i'; GENF 10424, 'DYNAMIC1', 42, 32, 126, 32, 0.94, 0.3, 0, 0, 0.0, 0.0; "#
+#"CMNT 'dyn1.14 '; GENF 10500, 'DYNAMIC1', 50, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "#
+#"CMNT 'dyn1.14.b'; GENF 10502, 'DYNAMIC1', 50, 32, 126, 32, 1.04, 0.0, 0, 0, 5.0, 3.0; "#
+#"CMNT 'dyn1.18.b'; GENF 10682, 'DYNAMIC1', 68, 32, 126, 32, 1.04, 0.0, 0, 0, 5.0, 3.0; "#
+#"CMNT 'dyn1.24.b'; GENF 10922, 'DYNAMIC1', 92, 32, 126, 32, 1.04, 0.0, 0, 0, 5.0, 3.0; "#
+#"CMNT 'dyn1.36.b'; GENF 11322, 'DYNAMIC1', 132, 32, 126, 32, 1.04, 0.0, 0, 0, 5.0, 3.0; "#
+#"MAP 0, 0; EXIT;"#
+
+#type ("dyn1.6") #\#type("dyn1.6")\#
+#type ("dyn1.6.i") #\#type("dyn1.6.i")\#
+#type ("dyn1.8") #\#type("dyn1.8")\#
+#type ("dyn1.8.i") #\#type("dyn1.8.i")\#
+#type ("dyn1.10") #\#type("dyn1.10")\#
+#type ("dyn1.10.i")#\#type("dyn1.10.i")\#
+#type ("dyn1.12") #\#type("dyn1.12")\#
+#type ("dyn1.12.i")#\#type("dyn1.12.i")\#
+#type ("dyn1.14") #\#type("dyn1.14")\#
+#type ("dyn1.14.b")#\#type("dyn1.14.b")\#
+#type ("dyn1.18.b")#\#type("dyn1.18.b")\#
+#type ("dyn1.24.b")#\#type("dyn1.24.b")\#
+#type ("dyn1.36.b")#\#type("dyn1.36.b")\#
+
diff --git a/printer/laser/genfont.kyocera.f-1010.dynamic2 b/printer/laser/genfont.kyocera.f-1010.dynamic2
new file mode 100644
index 0000000..f425a7f
--- /dev/null
+++ b/printer/laser/genfont.kyocera.f-1010.dynamic2
@@ -0,0 +1,30 @@
+#"!"82"! "#
+#"CMNT 'dyn2.6 '; GENF 20200, 'DYNAMIC2', 20, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "#
+#"CMNT 'dyn2.6.i '; GENF 20204, 'DYNAMIC2', 20, 32, 126, 32, 0.94, 0.3, 0, 0, 2.0, 0.0; "#
+#"CMNT 'dyn2.8 '; GENF 20260, 'DYNAMIC2', 26, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "#
+#"CMNT 'dyn2.8.i '; GENF 20264, 'DYNAMIC2', 26, 32, 126, 32, 0.94, 0.3, 0, 0, 2.0, 0.0; "#
+#"CMNT 'dyn2.10 '; GENF 20320, 'DYNAMIC2', 32, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "#
+#"CMNT 'dyn2.10.i'; GENF 20324, 'DYNAMIC2', 32, 32, 126, 32, 0.94, 0.3, 0, 0, 2.0, 0.0; "#
+#"CMNT 'dyn2.12 '; GENF 20400, 'DYNAMIC2', 40, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "#
+#"CMNT 'dyn2.12.i'; GENF 20404, 'DYNAMIC2', 40, 32, 126, 32, 0.94, 0.3, 0, 0, 2.0, 0.0; "#
+#"CMNT 'dyn2.14 '; GENF 20480, 'DYNAMIC2', 48, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "#
+#"CMNT 'dyn2.14.b'; GENF 20482, 'DYNAMIC2', 48, 32, 126, 32, 0.99, 0.0, 0, 0, 5.0, 3.0; "#
+#"CMNT 'dyn2.18.b'; GENF 20662, 'DYNAMIC2', 66, 32, 126, 32, 0.99, 0.0, 0, 0, 5.0, 3.0; "#
+#"CMNT 'dyn2.24.b'; GENF 20902, 'DYNAMIC2', 90, 32, 126, 32, 0.99, 0.0, 0, 0, 5.0, 3.0; "#
+#"CMNT 'dyn2.36.b'; GENF 21302, 'DYNAMIC2', 130, 32, 126, 32, 0.99, 0.0, 0, 0, 5.0, 3.0; "#
+#"MAP 0, 0; EXIT;"#
+
+#type ("dyn2.6") #\#type("dyn2.6")\#
+#type ("dyn2.6.i") #\#type("dyn2.6.i")\#
+#type ("dyn2.8") #\#type("dyn2.8")\#
+#type ("dyn2.8.i") #\#type("dyn2.8.i")\#
+#type ("dyn2.10") #\#type("dyn2.10")\#
+#type ("dyn2.10.i")#\#type("dyn2.10.i")\#
+#type ("dyn2.12") #\#type("dyn2.12")\#
+#type ("dyn2.12.i")#\#type("dyn2.12.i")\#
+#type ("dyn2.14") #\#type("dyn2.14")\#
+#type ("dyn2.14.b")#\#type("dyn2.14.b")\#
+#type ("dyn2.18.b")#\#type("dyn2.18.b")\#
+#type ("dyn2.24.b")#\#type("dyn2.24.b")\#
+#type ("dyn2.36.b")#\#type("dyn2.36.b")\#
+
diff --git a/printer/laser/laser.inserter b/printer/laser/laser.inserter
new file mode 100644
index 0000000..c28766f
--- /dev/null
+++ b/printer/laser/laser.inserter
@@ -0,0 +1,275 @@
+PACKET laserdrucker inserter DEFINES treiber einrichten :
+
+(**************************************************************************)
+(* Installationsprogramm Stand : 12.12.88 *)
+(* für Tintenstrahl- Version : 0.9 *)
+(* und Laserdrucker Autor : hjh *)
+(**************************************************************************)
+
+LET anzahl firmen = 6 ;
+LET apple = "APPLE" ,
+ canon = "CANON" ,
+ epson = "EPSON" ,
+ hp = "HEWLETT PACKARD" ,
+ kyo = "KYOCERA" ,
+ nec = "NEC" ;
+
+THESAURUS VAR firmen := empty thesaurus ;
+
+INT VAR i ;
+ROW anzahl firmen THESAURUS VAR drucker ;
+FOR i FROM 1 UPTO anzahl firmen REP
+ drucker (i) := empty thesaurus
+PER ;
+ROW anzahl firmen THESAURUS VAR printer ;
+FOR i FROM 1 UPTO anzahl firmen REP
+ printer (i) := empty thesaurus
+PER ;
+ROW anzahl firmen THESAURUS VAR fonttables ;
+FOR i FROM 1 UPTO anzahl firmen REP
+ fonttables (i) := empty thesaurus
+PER ;
+
+liste (apple,"LASERWRITER","printer.apple.laserwriter","fonttab.apple.laserwriter");
+liste (canon , "LBP-8" ,"printer.canon.lbp-8" ,"fonttab.canon.lbp-8");
+liste (epson , "SQ 2500" ,"printer.epson.sq" ,"fonttab.epson.sq");
+liste (hp , "HP LASERJET" ,"printer.hp.laserjet" ,"fonttab.hp.laserjet");
+liste (hp , "HP LASERJET+" ,"printer.hp.laserjet" ,"fonttab.hp.laserjet");
+liste (kyo , "F-1010" ,"printer.kyocera.f-1010" ,"fonttab.kyocera.f-1010");
+liste (kyo , "F-2200" ,"printer.kyocera.f-1010" ,"fonttab.kyocera.f-1010");
+liste (nec , "SILENTWRITER LC-08" ,"printer.nec.lc-08"
+,"fonttab.nec.lc-08");
+
+treiber einrichten;
+
+PROC liste (TEXT CONST firmenname, druckername ,
+ printername, fonttabname ) :
+ INT VAR firmnum ;
+ IF firmen CONTAINS firmenname
+ THEN firmnum := link (firmen,firmenname)
+ ELSE insert (firmen,firmenname,firmnum)
+ FI;
+ insert (drucker(firmnum), druckername) ;
+ insert (printer(firmnum), printername) ;
+ insert (fonttables(firmnum), fonttabname) ;
+END PROC liste ;
+
+PROC treiber einrichten :
+ INT VAR menu phase := 1 ;
+ BOOL VAR installed := FALSE ;
+ BOOL VAR was esc ;
+ INT VAR firmnum, druckernum ;
+ TEXT VAR firmenname, druckername, printername, fonttabname ;
+
+ pre menu ;
+ REP
+ SELECT menu phase OF
+ CASE 1 : menu ("Hauptmenü Tintenstrahl und Laserdrucker", firmen,
+ "CR: Eingabe ESC : Installation abrechen",
+ firmnum, was esc ) ;
+ IF was esc
+ THEN menu phase := 0
+ ELSE menu phase := 2 ;
+ firmenname := name (firmen,firmnum) ;
+ FI ;
+
+ CASE 2 : menu (firmenname + " - Menü", drucker(firmnum),
+ "CR: Eingabe ESC : Zurück zum Hauptmenü",
+ druckernum, was esc) ;
+ IF was esc
+ THEN menu phase := 1
+ ELSE menu phase := 3 ;
+ druckername := name (drucker(firmnum),druckernum);
+ printername := name (printer(firmnum),druckernum);
+ fonttabname := name (fonttables(firmnum),druckernum);
+ FI;
+
+ CASE 3 : inst (druckername, printername, fonttabname, installed) ;
+ IF NOT installed THEN menu phase := 1 FI;
+ END SELECT
+ UNTIL installed OR abbruch PER ;
+ post menu.
+
+ abbruch:
+ menu phase < 1 .
+
+ pre menu:
+ line;
+ IF is single task system
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+ FI;
+ IF NOT is system task (myself)
+ THEN errorstop ("Die Druckertask muß im Systemzweig angelegt werden")
+ FI;
+ command dialogue (TRUE);
+ IF name (myself) <> "PRINTER"
+ THEN putline ("Diese Task heißt nicht ""PRINTER"", sondern """ +
+ name (myself) + """ !");
+ IF yes ("Soll die Task in ""PRINTER"" umbenannt werden ?")
+ THEN rename myself ("PRINTER")
+ FI
+ FI.
+
+ is single task system: (pcb (9) AND 255) = 1.
+
+ post menu:
+ IF NOT installed
+ THEN page;
+ putline ("Es ist kein Druckertreiber installiert worden!");
+ line;
+ putline ("Wenn dieses Installationsprogramm insertiert wurde,");
+ putline ("kann es in der Task """ + name (myself) + """ ");
+ putline ("mit 'treiber einrichten' erneut aufgerufen werden.");
+ line;
+ FI.
+
+END PROC treiber einrichten ;
+
+PROCEDURE menu (TEXT CONST header, THESAURUS CONST items, TEXT CONST bottom,
+ INT VAR choice, BOOL VAR was esc) :
+ INT VAR anzahl ;
+ page;
+ headline (header) ;
+ show list (items,anzahl) ;
+ bottomline (bottom) ;
+ ask user (anzahl,choice,was esc);
+END PROC menu ;
+
+PROC headline (TEXT CONST header):
+ cursor (13,1);
+ putline ("E U M E L - Druckertreiber - Installations - Programm");
+ cursor (40 - LENGTH header DIV 2, 2);
+ IF header <> "" THEN put (header) FI ;
+ line (2)
+END PROC headline;
+
+PROC bottomline (TEXT CONST bottom):
+ cursor (1,24);
+ IF bottom <> "" THEN put (""5"" + bottom) FI ;
+END PROC bottomline;
+
+PROC show list (THESAURUS CONST items , INT VAR anzahl ) :
+ INT VAR i ;
+ anzahl := highest entry (items);
+ FOR i FROM 1 UPTO anzahl REP
+ putline ( text(i) + ". " + name (items,i) ) ;
+ PER;
+END PROC show list ;
+
+PROC ask user (INT CONST max choice, INT VAR choice, BOOL VAR was esc):
+ TEXT VAR exit;
+ TEXT VAR inp := "";
+ REP
+ cursor (1,23);
+ IF inp = ""
+ THEN put ("Ihre Wahl (Nummer eingeben):")
+ ELSE put ("FEHLER! Eingabe korrigieren:")
+ FI;
+ editget (inp, ""27"", "", exit);
+ was esc := exit = ""27"";
+ UNTIL was esc OR ok PER.
+
+ ok:
+ choice := int (inp) ;
+ last conversion ok CAND ( choice > 0 AND choice <= max choice) .
+END PROC ask user;
+
+BOOL PROC is system task (TASK CONST task):
+ TASK VAR tsk := task ;
+ WHILE NOT (tsk = supervisor OR tsk = niltask) REP
+ tsk := father (tsk) ;
+ PER;
+ tsk = supervisor
+END PROC is system task ;
+
+PROC inst (TEXT CONST druckername, printername, fonttabname,
+ BOOL VAR success) :
+ page ;
+ headline (druckername) ;
+ fetch from archive if necessary ((empty thesaurus
+ + printer name + fonttab name) - all ,success);
+ IF success AND ok
+ THEN page ;
+ putline ("Der Drucker wird insertiert");
+ insert (printer name) ;
+ ELSE success := FALSE ;
+ FI.
+
+ok:
+ bottomline (" ");
+ yes ("Soll der ausgewählte Drucker insertiert werden").
+
+END PROC inst ;
+
+PROC fetch from archive if necessary (THESAURUS CONST files,
+ BOOL VAR success ):
+ BOOL VAR was esc ;
+ THESAURUS VAR thes :: files;
+
+ WHILE highest entry (thes) > 0 REP
+ ask for archive;
+ IF NOT was esc
+ THEN disable stop ;
+ bottomline ("Bitte warten ! ");
+ reserve archive;
+ IF NOT is error
+ THEN IF highest entry (thes / ALL archive) > 0
+ THEN fetch (thes / ALL archive, archive);
+ ELSE fehler ("Dateien nicht gefunden")
+ FI;
+ thes := thes - all;
+ FI;
+ IF is error
+ THEN fehler (errormessage);
+ clear error
+ FI;
+ command dialogue (FALSE);
+ release (archive);
+ command dialogue (TRUE);
+ enable stop ;
+ FI;
+ UNTIL was esc PER;
+ success := highest entry (thes) = 0.
+
+ask for archive:
+ headline ("") ;
+ putline ("Bitte Archiv mit den Dateien");
+ TEXT VAR buffer;
+ INT VAR index :: 0;
+ REP
+ get (thes, buffer, index);
+ putline (" " + buffer)
+ UNTIL index = 0 PER;
+ putline ("einlegen !");
+ bottomline ("CR: Wenn Archiv eingelegt ESC : Zurück zum Hauptmenü");
+ cursor (1,24);
+ REP
+ inchar (buffer) ;
+ UNTIL buffer = ""13"" OR buffer = ""27"" PER ;
+ was esc := buffer = ""27"".
+
+reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI.
+
+END PROC fetch from archive if necessary ;
+
+PROC fehler (TEXT CONST fehlermeldung):
+ bottomline (""7"" + fehlermeldung + " Bitte eine Taste drücken") ;
+ pause ;
+ bottomline (" ") ;
+END PROC fehler;
+
+END PACKET laserdrucker inserter;
+
diff --git a/printer/laser/printer.apple.laserwriter b/printer/laser/printer.apple.laserwriter
new file mode 100644
index 0000000..d4c6adf
--- /dev/null
+++ b/printer/laser/printer.apple.laserwriter
@@ -0,0 +1,770 @@
+PACKET apple laser writer printer
+
+(**************************************************************************)
+(* Stand : 24.02.88 *)
+(* APPLE LaswerWriter (PostScript) Verison : 4 *)
+(* Autor : Rudolf Ruland *)
+(**************************************************************************)
+
+ DEFINES open,
+ close,
+ execute,
+
+ paper size,
+ paper x size,
+ paper y size,
+
+ load positioning procs,
+ load underline procs,
+ load italics procs,
+ load encoding,
+
+ read ps input,
+
+ box commands,
+ insert box command,
+ delete box command,
+
+ print error,
+ :
+
+LET
+(* underline = 1,
+ bold = 2,
+ italics = 4,
+ reverse = 8,
+*)
+ underline linetype = 1,
+
+ c document = 1,
+ c page = 2,
+
+ c write text = 1,
+ c write cmd = 2,
+ c carriage return = 3,
+ c move = 4,
+ c draw = 5,
+ c on = 6,
+ c off = 7,
+ c type = 8,
+
+ ps input name = "PostScript.input",
+ ps error = 999,
+
+ tag type = 1;
+
+INT VAR paper length, font no, underline no, symbol type;
+REAL VAR x size, y size;
+BOOL VAR is landscape;
+TEXT VAR record, char, command, symbol;
+FILE VAR ps input;
+THESAURUS VAR box cmds := empty thesaurus;
+
+(*********************************************************************)
+
+paper size (21.0, 29.7);
+
+PROC paper size (REAL CONST x, y) :
+
+ x size := x;
+ y size := y;
+
+END PROC paper size;
+
+PROC paper size :
+
+ line;
+ putline ("Papierbreite = " + text (x size, 5, 2) + " cm = " + text (x size / 2.54, 5, 2) + " Zoll");
+ putline ("Papierlaenge = " + text (y size, 5, 2) + " cm = " + text (y size / 2.54, 5, 2) + " Zoll");
+
+END PROC paper size;
+
+REAL PROC paper x size : x size END PROC paper x size;
+
+REAL PROC paper y size : y size END PROC paper y size;
+
+
+THESAURUS PROC box commands : box cmds END PROC box commands;
+
+PROC insert box command (TEXT CONST new command) :
+
+ command := new command;
+ change all (command, " ", "");
+ insert (box cmds, command)
+
+END PROC insert box command;
+
+PROC delete box command (TEXT CONST old command) :
+
+ INT VAR dummy;
+ command := old command;
+ change all (command, " ", "");
+ delete (box cmds, command, dummy)
+
+END PROC delete box command;
+
+(*********************************************************************)
+
+PROC open (INT CONST op code, INT VAR param1, param2) :
+
+SELECT op code OF
+ CASE c document : open document
+ CASE c page : open page
+END SELECT;
+
+
+. x steps : param1
+. y steps : param2
+.
+ open document :
+ IF pos (material, "landscape") > 0 OR pos (material, "quer") > 0
+ THEN is landscape := TRUE;
+ x steps := x step conversion ( y size );
+ y steps := y step conversion ( x size );
+ ELSE is landscape := FALSE;
+ x steps := x step conversion ( x size );
+ y steps := y step conversion ( y size );
+ FI;
+ forget (ps input name, quiet);
+ ps input := sequential file (output, ps input name);
+ paper length := y steps;
+ font no := 0;
+ underline no := 0;
+ disable stop;
+ out (""4"");
+ read ps input (ps input, 18000, ""4"");
+ clear error;
+ enable stop;
+ out ("initgraphics erasepage statusdict /waittimeout 3000 put ");
+ load positioning procs;
+ load underline procs;
+ load italics procs;
+ load encoding;
+ read ps input (ps input, 0, "");
+
+. x start : param1
+. y start : param2
+.
+ open page :
+ x start := 0;
+ y start := 0;
+ IF pos (material, "tray") > 0
+ THEN out ("statusdict /manualfeed false put ");
+ ELIF pos (material, "manual") > 0
+ THEN out ("statusdict /manualfeed true put statusdict /manualfeedtimeout 3600 put ");
+ FI;
+ IF material contains a number
+ THEN out ("/#copies "); out (number); out ("def ");
+ FI;
+ IF is landscape
+ THEN out (paper length);
+ out ("ys 0 translate 90 rotate ");
+ FI;
+ read ps input (ps input, 0, "");
+
+ . material contains a number :
+ INT VAR number := pos (material, "0", "9", 1);
+ IF number = 0
+ THEN FALSE
+ ELSE number := max (1, int (subtext (material, number, number + 1)));
+ TRUE
+ FI
+
+END PROC open;
+
+
+PROC close (INT CONST op code, INT CONST param1) :
+
+SELECT op code OF
+ CASE c document : close document
+ CASE c page : close page
+ OTHERWISE : put (param1)
+END SELECT;
+
+.
+ close document :
+ disable stop;
+ out (""4"");
+ read ps input (ps input, 18000, ""4"");
+
+
+(*. remaining y steps : param1*)
+.
+ close page :
+ outline ("showpage");
+ read ps input (ps input, 0, "");
+
+END PROC close;
+
+
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+
+SELECT op code OF
+ CASE c write text : write text
+ CASE c write cmd : write cmd
+ CASE c carriage return : carriage return
+ CASE c move : move
+ CASE c draw : draw
+ CASE c on : on
+ CASE c off : off
+ CASE c type : type
+END SELECT
+
+
+. from : param1
+. to : param2
+.
+ write text :
+ out ("(");
+ out subtext (string, from, to);
+ out (") show ");
+.
+ write cmd :
+ command := subtext (string, from, to);
+ IF is box cmd
+ THEN disable stop;
+ do (command);
+ clear error;
+ ELSE out (command);
+ out (" ");
+ FI;
+
+ . is box cmd :
+ scan (command);
+ next symbol (symbol, symbol type);
+ (symbol type = tag type) CAND (box cmds CONTAINS symbol)
+
+
+(*. x steps to left margin : param1*)
+.
+ carriage return :
+ move to (0, y pos);
+ line;
+ read ps input (ps input, 0, "");
+
+
+. x steps : param1
+. y steps : param2
+
+.
+ move :
+ move to (x pos, y pos);
+
+.
+ draw :
+ IF y steps <> 0 COR x steps < 0 COR linetype <> underline linetype
+ THEN stop
+ ELSE IF underline no <> font no THEN out ("lu ") FI;
+ out (x steps);
+ out ("ul ");
+ FI;
+
+
+. modification : param1
+.
+ on :
+ IF on string (modification) <> ""
+ THEN out (on string (modification));
+ out (" ");
+ ELSE stop
+ FI
+
+.
+ off :
+ IF off string (modification) <> ""
+ THEN out (off string (modification));
+ out (" ");
+ ELSE stop
+ FI
+
+
+. font nr : param1
+.
+ type :
+ font no := font nr;
+ out (fontstring (font nr));
+ out (" /af exch def af setfont ");
+
+END PROC execute;
+
+
+PROC move to (INT CONST x, y) :
+
+ out (x); out ("xs ");
+ out (paper length - y); out ("ys moveto ");
+
+END PROC move to;
+
+
+PROC line : out (""13""10"") END PROC line;
+
+PROC outline (TEXT CONST string) : out (string); out (""13""10"") END PROC outline;
+
+PROC out (INT CONST value) : out (text (value)); out (" ") END PROC out;
+
+PROC out (REAL CONST value) : out (text (value)); out (" ") END PROC out;
+
+
+PROC load positioning procs :
+
+ out ("/xs {"); out (72.0 / 2.54 * x step conversion (1)); out ("mul} def ");
+ out ("/ys {"); out (72.0 / 2.54 * y step conversion (1)); out ("mul} def ");
+
+END PROC load positioning procs;
+
+
+PROC load underline procs :
+
+ out ("/ul {xs ut setlinewidth 0 up rmoveto dup gsave 0 rlineto stroke grestore up neg rmoveto} def ");
+ out ("/lu {af /FontMatrix get 3 get af /FontInfo get 2 copy /up 3 1 roll /UnderlinePosition get mul 3 mul def /ut 3 1 roll /UnderlineThickness get mul def} def ");
+
+END PROC load underline procs;
+
+
+PROC load italics procs :
+
+ out ("/iton {/m matrix def m 2 12 sin 12 cos div put af m makefont setfont} def ");
+ out ("/itoff {af setfont} def ");
+
+END PROC load italics procs;
+
+
+PROC load encoding :
+
+ out ("/reencsmalldict 12 dict def ");
+ out ("/ReEncodeSmall {reencsmalldict begin ");
+ out ("/newcodesandnames exch def /newfontname exch def /basefontname exch def ");
+ out ("/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def ");
+ out ("basefontdict {exch dup /FID ne {dup /Encoding eq {exch dup length array copy newfont 3 1 roll put} {exch newfont 3 1 roll put} ifelse} {pop pop} ifelse} forall ");
+ out ("newfont /FontName newfontname put newcodesandnames aload pop newcodesandnames length 2 idiv {newfont /Encoding get 3 1 roll put} repeat ");
+ out ("newfontname newfont definefont pop ");
+ out ("end} def ");
+ out ("/eumelencoding[10#128 /Ccedilla 10#129 /udieresis 10#128 /Ccedilla 10#129 /udieresis ");
+ out ("10#130 /eacute 10#131 /acircumflex 10#132 /adieresis 10#133 /agrave 10#134 /aring 10#135 /ccedilla 10#136 /ecircumflex 10#137 /edieresis 10#138 /egrave 10#139 /idieresis ");
+ out ("10#140 /icircumflex 10#141 /igrave 10#142 /Adieresis 10#143 /Aring 10#144 /Eacute 10#145 /ae 10#146 /AE 10#147 /ocircumflex 10#148 /odieresis 10#149 /ograve ");
+ out ("10#150 /ucircumflex 10#151 /ugrave 10#152 /ydieresis 10#153 /Odieresis 10#154 /Udieresis 10#155 /cent 10#156 /sterling 10#157 /yen 10#158 /currency 10#159 /florin ");
+ out ("10#160 /aacute 10#161 /iacute 10#162 /oacute 10#163 /uacute 10#164 /ntilde 10#165 /Ntilde 10#166 /ordfeminine 10#167 /ordmasculine 10#168 /questiondown 10#169 /quotedblleft ");
+ out ("10#170 /quotedblright 10#171 /guilsinglleft 10#172 /guilsinglright 10#173 /exclamdown 10#174 /guillemotleft 10#175 /guillemotright 10#176 /atilde 10#177 /otilde 10#178 /Oslash 10#179 /oslash ");
+ out ("10#180 /oe 10#181 /OE 10#182 /Agrave 10#183 /Atilde 10#184 /Otilde 10#185 /section 10#186 /daggerdbl 10#187 /dagger 10#188 /paragraph 10#189 /space ");
+ out ("10#190 /space 10#191 /space 10#192 /quotedblbase 10#193 /ellipsis 10#194 /perthousand 10#195 /bullet 10#196 /endash 10#197 /emdash 10#198 /space 10#199 /Aacute ");
+ out ("10#200 /Acircumflex 10#201 /Egrave 10#202 /Ecircumflex 10#203 /Edieresis 10#204 /Igrave 10#205 /Iacute 10#206 /Icircumflex 10#207 /Idieresis 10#208 /Ograve 10#209 /Oacute ");
+ out ("10#210 /Ocircumflex 10#211 /Scaron 10#212 /scaron 10#213 /Ugrave 10#214 /Adieresis 10#215 /Odieresis 10#216 /Udieresis 10#217 /adieresis 10#218 /odieresis 10#219 /udieresis ");
+ out ("10#220 /k 10#221 /hyphen 10#222 /numbersign 10#223 /space 10#224 /grave 10#225 /acute 10#226 /circumflex 10#227 /tilde 10#228 /dieresis 10#229 /ring ");
+ out ("10#230 /cedilla 10#231 /caron 10#232 /Lslash 10#233 /Oslash 10#234 /OE 10#235 /ordmasculine 10#236 /Uacute 10#237 /Ucircumflex 10#238 /Ydieresis 10#239 /germandbls ");
+ out ("10#240 /Zcaron 10#241 /zcaron 10#242 /fraction 10#243 /ae ");
+ out ("10#251 /germandbls 10#252 /section] def ");
+ out ("/Helvetica /EHelvetica eumelencoding ReEncodeSmall ");
+ out ("/Helvetica-Bold /EHelvetica-Bold eumelencoding ReEncodeSmall ");
+ out ("/Helvetica-Oblique /EHelvetica-Oblique eumelencoding ReEncodeSmall ");
+ out ("/Helvetica-BoldOblique /EHelvetica-BoldOblique eumelencoding ReEncodeSmall ");
+ out ("/Times-Roman /ETimes-Roman eumelencoding ReEncodeSmall ");
+ out ("/Times-Bold /ETimes-Bold eumelencoding ReEncodeSmall ");
+ out ("/Times-Italic /ETimes-Italic eumelencoding ReEncodeSmall ");
+ out ("/Times-BoldItalic /ETimes-BoldItalic eumelencoding ReEncodeSmall ");
+ out ("/Courier /ECourier eumelencoding ReEncodeSmall ");
+ out ("/Courier-Oblique /ECourier-Oblique eumelencoding ReEncodeSmall ");
+ out ("/Courier-BoldOblique /ECourier-BoldOblique eumelencoding ReEncodeSmall ");
+ out ("/Courier-Bold /ECourier-Bold eumelencoding ReEncodeSmall ");
+ line;
+
+END PROC load encoding;
+
+
+PROC read ps input (FILE VAR input file, INT CONST timeout, TEXT CONST ok) :
+
+ BOOL VAR was cr;
+ record := "";
+ was cr := FALSE;
+ char := incharety (timeout);
+ REP IF char = ""10"" CAND was cr
+ THEN put record;
+ was cr := FALSE;
+ ELIF char = ""13"" CAND NOT was cr
+ THEN was cr := TRUE;
+ ELSE IF was cr
+ THEN record CAT """13""";
+ was cr := FALSE;
+ FI;
+ IF char = ""4""
+ THEN IF record <> "" THEN put record FI;
+ putline (input file, "-- EOF --");
+ line (input file);
+ ELIF char >= " "
+ THEN record CAT char
+ ELIF char >= ""0""
+ THEN record CAT """";
+ record CAT text (code (char));
+ record CAT """";
+ ELSE IF record <> "" THEN put record FI;
+ LEAVE read ps input;
+ FI;
+ FI;
+ IF pos (ok, char) > 0
+ THEN IF record <> "" THEN put record FI;
+ LEAVE read ps input;
+ FI;
+ cat input (record, char);
+ IF char = "" THEN char := incharety (min (5, time out)) FI;
+ PER;
+
+ . put record :
+ putline (input file, record);
+ IF NOT is error CAND pos (record, "%%[ Error:") > 0
+ THEN errorstop (ps error, record) FI;
+ record := "";
+
+END PROC read ps input;
+
+
+PROC print error (TEXT CONST error message, INT CONST error line) :
+
+ REAL CONST pl := y size * 72.0 / 2.54,
+ ys := 56.69291,
+ xs := 51.02362,
+ h := 12.0;
+ REAL VAR x := xs, y := ys + h;
+ outline ("/Courier findfont 10 scalefont setfont");
+ move to x and y;
+ out ("(FEHLER : ");
+ out (error message);
+ IF error line > 0
+ THEN out (" in Zeile ");
+ out (error line);
+ FI;
+ outline (") show");
+ IF exists (ps input name)
+ THEN ps input := sequential file (input, ps input name);
+ y INCR 3.0 * h;
+ move to x and y;
+ outline ("(PostScript - Input :) show");
+ y INCR h;
+ WHILE NOT eof (ps input)
+ REP getline (ps input, record);
+ y INCR h;
+ move to x and y;
+ out ("(");
+ out (record);
+ outline (") show");
+ PER;
+ output (ps input);
+ FI;
+ outline ("showpage");
+ out (""4"");
+ read ps input (ps input, 18000, ""4"");
+
+ . move to x and y :
+ out (x); out (pl - y); out ("moveto ");
+
+END PROC print error;
+
+
+END PACKET apple laser writer printer;
+
+
+PACKET apple laserwriter box commands
+
+(**************************************************************************)
+(* *)
+(* Kommandos zum Zeichen von Boxen, Linien und Schraffuren *)
+(* für den Apple LaserWriter *)
+(* *)
+(* Autor : Rudolf Ruland *)
+(* Stand : 24.02.88 *)
+(**************************************************************************)
+
+ DEFINES line,
+ x line,
+ y line,
+
+ box,
+ box frame,
+ box shade,
+
+ cake,
+ cake frame,
+ cake shade,
+ :
+
+INT VAR x, y, h, w;
+
+WHILE highest entry (box commands) > 0
+ REP delete box command (name (box commands, highest entry (box commands))) PER;
+insert box command ("line");
+insert box command ("xline");
+insert box command ("yline");
+insert box command ("box");
+insert box command ("boxshade");
+insert box command ("boxframe");
+insert box command ("cake");
+insert box command ("cakeshade");
+insert box command ("cakeframe");
+
+
+PROC line (REAL CONST x offset, y offset, width, height, line width) :
+
+ IF line width > 0.0
+ THEN graph on (x offset, y offset, width, height);
+ out (text (line width / 300.0 * 72.0));
+ out (" setlinewidth ");
+ out (text (w));
+ out (" xs ");
+ out (text (-h));
+ out (" ys rlineto stroke ");
+ graph off;
+ FI;
+
+END PROC line;
+
+PROC x line (REAL CONST x offset, y offset, width, line width) :
+
+ line (x offset, y offset, width, 0.0, line width);
+
+END PROC x line;
+
+PROC y line (REAL CONST x offset, y offset, height, line width) :
+
+ line (x offset, y offset, 0.0, height, line width);
+
+END PROC y line;
+
+
+PROC box (REAL CONST x offset, y offset, width, height, line width, pattern):
+
+ box shade (x offset, y offset, width, height, pattern);
+ box frame (x offset, y offset, width, height, line width);
+
+END PROC box;
+
+
+PROC box shade (REAL CONST x offset, y offset, width, height, pattern) :
+
+ graph on (x offset, y offset, width, height);
+ box path;
+ out (text (pattern));
+ out (" setgray fill ");
+ graph off;
+
+END PROC box shade;
+
+
+PROC box frame (REAL CONST x offset, y offset, width, height, line width) :
+
+ IF line width <> 0.0
+ THEN graph on (x offset, y offset, width, height);
+ box path;
+ out (text (line width / 300.0 * 72.0));
+ out (" setlinewidth stroke ");
+ graph off;
+ FI;
+
+END PROC box frame;
+
+
+PROC box path :
+
+ out (text (w));
+ out (" xs 0 rlineto 0 ");
+ out (text (-h));
+ out (" ys rlineto ");
+ out (text (-w));
+ out (" xs 0 rlineto closepath ");
+
+END PROC box path;
+
+
+
+PROC cake (REAL CONST x offset, y offset, radius, start angle, sweep angle, line width, pattern) :
+
+ cake shade (x offset, y offset, radius, start angle, sweep angle, pattern);
+ cake frame (x offset, y offset, radius, start angle, sweep angle, line width);
+
+END PROC cake;
+
+
+PROC cake shade (REAL CONST x offset, y offset, radius, start angle, sweep angle, pattern) :
+
+ graph on (x offset, y offset, radius, 0.0);
+ cake path (start angle, sweep angle);
+ out (text (pattern));
+ out (" setgray fill ");
+ graph off;
+
+END PROC cake shade;
+
+
+PROC cake frame (REAL CONST x offset, y offset, radius, start angle, sweep angle, line width) :
+
+
+ IF line width <> 0.0
+ THEN graph on (x offset, y offset, radius, 0.0);
+ cake path (start angle, sweep angle);
+ out (text (line width / 300.0 * 72.0));
+ out (" setlinewidth stroke ");
+ graph off;
+ FI;
+
+END PROC cake frame;
+
+
+PROC cake path (REAL CONST start angle, sweep angle) :
+
+ out (text (start angle));
+ out (" rotate ");
+ out ("currentpoint ");
+ out (text (w));
+ out (" xs 0 ");
+ out (text (sweep angle));
+ out (" ");
+ IF sweep angle < 360.0
+ THEN out ("2 setlinejoin arc closepath ");
+ ELSE out (text (w));
+ out (" xs 0 rmoveto arc ");
+ FI;
+
+END PROC cake path;
+
+
+PROC graph on (REAL CONST x offset, y offset, width, height) :
+
+ x := x step conversion (x offset);
+ y := y step conversion (y offset);
+ w := x step conversion (width);
+ h := y step conversion (height);
+ out ("gsave ");
+ out (text (x));
+ out (" xs ");
+ out (text (-y));
+ out (" ys rmoveto ");
+
+END PROC graph on;
+
+PROC graph off :
+
+ out ("grestore ");
+
+END PROC graph off;
+
+
+END PACKET apple laserwriter box commands;
+
+
+
+#page#
+(******************************************************************)
+(*** ***)
+(*** Generierung des Printers ***)
+(*** ***)
+(******************************************************************)
+(*
+LET up = ""3""13""5"";
+*)
+LET printer name = "printer.apple.laserwriter";
+TEXT VAR fonttab name := "fonttab.apple.laserwriter";
+
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+
+INT VAR pr channel;
+TEXT VAR buffer;
+
+command dialogue (TRUE);
+IF NOT multi user
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+FI;
+ask for print channel;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+command dialogue (TRUE);
+check on;
+.
+ ask for print channel :
+ line;
+ put ("gib Druckerkanal:");
+ get (pr channel);
+ do ("serverchannel(" + text (pr channel) + ")" ) ;
+ line;
+.
+ load font table :
+ IF NOT exists (fonttab name)
+ THEN REP line (2);
+ putline ("Bitte Archiv mit der Fonttabelle """ +
+ fonttab name + """ einlegen!");
+ line;
+ UNTIL yes ("Archiv eingelegt") PER;
+ reserve archive;
+ fetch (fonttab name, archive);
+ release (archive);
+ FI;
+ font table (fonttab name);
+ IF multi user
+ THEN command dialogue (FALSE);
+ do ("save(""" + font tab name + """,task(""configurator""))")
+ FI;
+ forget (fonttab name, quiet);
+
+ . reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ disable stop;
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI;
+ enable stop;
+
+. generate printer spool :
+ eumel must advertise;
+ cursor (1, 12);
+ putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+ putline ("die Fonttabelle mit dem Kommando");
+ line;
+ putline (" font table (""" + font tab name + """)");
+ line;
+ putline ("eingestellt werden!!!");
+ line (4);
+ putline ("Generierung beendet, weiter mit 'SV'");
+ generate printer server;
+ do (buffer);
+
+. generate printer server :
+ buffer := "break (quiet);";
+ buffer CAT "spool manager (PROC printer);";
+ buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+ buffer CAT "PROC printer:";
+ buffer CAT " disable stop;";
+ buffer CAT " continue (server channel);";
+ buffer CAT " check error (error message);";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " REP forget (ds);";
+ buffer CAT " execute print;";
+ buffer CAT " IF is error AND online THEN clear error; print error (error message, 0); clear error FI;";
+ buffer CAT " PER;";
+ buffer CAT "END PROC printer;";
+ buffer CAT "PROC execute print:";
+ buffer CAT " LET ack = 0, fetch code = 11, file type = 1003;";
+ buffer CAT " enable stop;";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " call (father, fetch code, ds, reply);";
+ buffer CAT " IF reply = ack CAND type (ds) = file type";
+ buffer CAT " THEN file := sequential file (input, ds);";
+ buffer CAT " print (file,";
+ buffer CAT " PROC (INT CONST, INT VAR, INT VAR) open,";
+ buffer CAT " PROC (INT CONST, INT CONST) close,";
+ buffer CAT " PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC execute print;";
+ buffer CAT "PROC check error(TEXT CONST message):";
+ buffer CAT " IF is error";
+ buffer CAT " THEN clear error; rename myself (message);";
+ buffer CAT " IF is error THEN end(myself) FI;";
+ buffer CAT " pause (9000); end(myself);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC check error;";
+
diff --git a/printer/laser/printer.canon.lbp-8 b/printer/laser/printer.canon.lbp-8
new file mode 100644
index 0000000..4dfe9f8
--- /dev/null
+++ b/printer/laser/printer.canon.lbp-8
@@ -0,0 +1,327 @@
+PACKET canon lbp 8 printer
+
+(*************************************************************************)
+(* Stand : 29.07.86 *)
+(* CANON LBP-8 A1/A2 Version : 4 *)
+(* Autor : Rudolf Ruland *)
+(*************************************************************************)
+
+
+ DEFINES open,
+ close,
+ execute,
+
+ paper size :
+
+LET underline = 1,
+(* bold = 2,
+ italics = 4,
+ reverse = 8,
+
+ underline linetype = 1, *)
+
+ csi = ""155"",
+
+ c document = 1,
+ c page = 2,
+
+ c write text = 1,
+ c write cmd = 2,
+ c carriage return = 3,
+ c move = 4,
+ c draw = 5,
+ c on = 6,
+ c off = 7,
+ c type = 8;
+
+REAL VAR x size, y size;
+BOOL VAR is underline;
+
+(*********************************************************************)
+
+paper size (21.0, 29.7);
+
+PROC paper size (REAL CONST x, y) :
+
+ x size := x;
+ y size := y;
+
+END PROC paper size;
+
+PROC paper size :
+
+ line;
+ putline ("Papierbreite = " + text (x size, 5, 2) + " cm = " + text (x size / 2.54, 5, 2) + " Zoll");
+ putline ("Papierlaenge = " + text (y size, 5, 2) + " cm = " + text (y size / 2.54, 5, 2) + " Zoll");
+
+END PROC paper size;
+
+(*********************************************************************)
+
+PROC open (INT CONST op code, INT VAR param1, param2) :
+
+SELECT op code OF
+ CASE c document : open document
+ CASE c page : open page
+END SELECT;
+
+
+. x steps : param1
+. y steps : param2
+.
+ open document :
+ is underline := FALSE;
+ x steps := x step conversion ( x size - 0.8043333 );
+ y steps := y step conversion ( y size - 0.508);
+ out (""27":"27"P"13""); (* Enable - Prop.Type *)
+ out (""27";"27"<"155"11h"); (* Reset des Druckers *)
+ out (""27"(B"); (* ACSII-Zeichensatz *)
+ out (""155"1;4 D"); (* Char.Satz 1 = PICA *)
+
+. x start : param1
+. y start : param2
+.
+ open page :
+ x start := x step conversion (0.4064 );
+ y start := y step conversion (0.508 + 0.6345);
+ out (""13"");
+
+END PROC open;
+
+
+PROC close (INT CONST op code, INT CONST param1) :
+
+SELECT op code OF
+ CASE c document : close document
+ CASE c page : close page
+ OTHERWISE : put (param1)
+END SELECT;
+
+.
+ close document :
+ (* out(""155"0q") von Standard-Cassette Papier holen *)
+
+(*. remaining y steps : param1*)
+.
+ close page :
+ out (""13""12"");
+
+END PROC close;
+
+
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+
+SELECT op code OF
+ CASE c write text : write text
+ CASE c write cmd : write cmd
+ CASE c carriage return : carriage return
+ CASE c move : move
+ CASE c draw : draw
+ CASE c on : on
+ CASE c off : off
+ CASE c type : type
+END SELECT
+
+
+. from : param1
+. to : param2
+.
+ write text :
+ INT VAR new from, new to;
+ IF is underline
+ THEN IF pos (string, " ", from, from) <> 0
+ THEN out ("_");
+ new from := from + 1;
+ ELSE new from := from;
+ FI;
+ IF from < to AND pos (string, " ", to, to) <> 0
+ THEN new to := to - 1;
+ ELSE new to := to;
+ FI;
+ out subtext (string, new from, new to);
+ IF to <> new to THEN out ("_") FI;
+ ELSE out subtext (string, from, to)
+ FI;
+
+.
+ write cmd :
+ out subtext (string, from, to)
+
+
+(*. x steps to left margin : param1*)
+.
+ carriage return :
+ out (""13"")
+
+
+. x steps : param1
+. y steps : param2
+.
+ move :
+ IF x steps > 0
+ THEN out (csi); out (text ( x steps)); out ("a")
+ ELIF x steps < 0
+ THEN out (csi); out (text (- x steps)); out ("j")
+ FI;
+ IF y steps > 0
+ THEN out (csi); out (text ( y steps)); out ("e")
+ ELIF y steps < 0
+ THEN out (csi); out (text (- y steps)); out ("k")
+ FI;
+
+.
+ draw :
+ stop
+
+
+. modification : param1
+.
+ on :
+ IF on string (modification) <> ""
+ THEN out (on string (modification));
+ IF modification = underline THEN is underline := TRUE FI;
+ ELSE stop
+ FI
+
+.
+ off :
+ IF off string (modification) <> ""
+ THEN out (off string (modification));
+ IF modification = underline THEN is underline := FALSE FI;
+ ELSE stop
+ FI
+
+
+. font nr : param1
+.
+ type :
+ out (font string (font nr));
+
+END PROC execute;
+
+
+END PACKET canon lbp 8 printer;
+
+
+
+#page#
+(******************************************************************)
+(*** ***)
+(*** Generierung des Printers ***)
+(*** ***)
+(******************************************************************)
+
+LET printer name = "printer.canon.lbp-8";
+
+TEXT VAR fonttab name := "fonttab.canon.lbp-8";
+
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+
+INT VAR pr channel;
+TEXT VAR buffer;
+
+command dialogue (TRUE);
+IF NOT multi user
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+FI;
+ask for print channel;
+ask for font cartridge;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+check on;
+.
+ ask for print channel :
+ line;
+ put ("gib Druckerkanal:");
+ get (pr channel);
+ do ("serverchannel(" + text (pr channel) + ")" ) ;
+ line;
+.
+ ask for font cartridge :
+.
+ load font table :
+ IF NOT exists (fonttab name)
+ THEN command dialogue (TRUE);
+ REP line (2);
+ putline ("Bitte Archiv mit der Fonttabelle """ +
+ fonttab name + """ einlegen!");
+ line;
+ UNTIL yes ("Archiv eingelegt") PER;
+ reserve archive;
+ fetch (fonttab name, archive);
+ release (archive);
+ FI;
+ font table (fonttab name);
+ IF multi user
+ THEN command dialogue (FALSE);
+ do ("save(""" + font tab name + """,task(""configurator""))")
+ FI;
+ forget (fonttab name, quiet);
+
+ . reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ disable stop;
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI;
+ enable stop;
+
+. generate printer spool :
+ eumel must advertise;
+ cursor (1, 12);
+ putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+ putline ("die Fonttabelle mit dem Kommando");
+ line;
+ putline (" font table (""" + font tab name + """)");
+ line;
+ putline ("eingestellt werden!!!");
+ line (4);
+ putline ("Generierung beendet, weiter mit 'SV'");
+ generate printer server;
+ do (buffer);
+
+. generate printer server :
+ buffer := "break (quiet);";
+ buffer CAT "spool manager (PROC printer);";
+ buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+ buffer CAT "PROC printer:";
+ buffer CAT " disable stop;";
+ buffer CAT " continue (server channel);";
+ buffer CAT " check error (error message);";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " REP forget (ds);";
+ buffer CAT " execute print;";
+ buffer CAT " IF is error AND online THEN put error; clear error; FI;";
+ buffer CAT " PER;";
+ buffer CAT "END PROC printer;";
+ buffer CAT "PROC execute print:";
+ buffer CAT " LET ack = 0, fetch code = 11, file type = 1003;";
+ buffer CAT " enable stop;";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " call (father, fetch code, ds, reply);";
+ buffer CAT " IF reply = ack CAND type (ds) = file type";
+ buffer CAT " THEN file := sequential file (input, ds);";
+ buffer CAT " print (file,";
+ buffer CAT " PROC (INT CONST, INT VAR, INT VAR) open,";
+ buffer CAT " PROC (INT CONST, INT CONST) close,";
+ buffer CAT " PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC execute print;";
+ buffer CAT "PROC check error(TEXT CONST message):";
+ buffer CAT " IF is error";
+ buffer CAT " THEN clear error; rename myself (message);";
+ buffer CAT " IF is error THEN end(myself) FI;";
+ buffer CAT " pause (9000); end(myself);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC check error;";
+
diff --git a/printer/laser/printer.epson.sq b/printer/laser/printer.epson.sq
new file mode 100644
index 0000000..63e474f
--- /dev/null
+++ b/printer/laser/printer.epson.sq
@@ -0,0 +1,585 @@
+PACKET epson sq printer
+
+(**************************************************************************)
+(* Stand : 03.12.86 *)
+(* EPSON SQ-2500 Version : 4 *)
+(* Autor : Rudolf Ruland *)
+(**************************************************************************)
+
+ DEFINES open,
+ close,
+ execute,
+
+ paper size,
+ (* paper feed, *) (* <-- nicht getestet *)
+ std typeface,
+ std quality:
+
+LET
+(* underline = 1,
+ bold = 2,
+ italics = 4,
+ reverse = 8, *)
+
+ underline linetype = 1,
+
+ c document = 1,
+ c page = 2,
+
+ c write text = 1, cmd draft = 1,
+ c write cmd = 2, cmd nlq = 2,
+ c carriage return = 3, cmd roman = 3,
+ c move = 4, cmd sansserif = 4,
+ c draw = 5, cmd courier = 5,
+ c on = 6, cmd prestige = 6,
+ c off = 7, cmd script = 7,
+ c type = 8;
+
+INT VAR font nr, x rest, high, low, font bits, modification bits, blank pitch,
+ factor 1, factor 2, steps;
+BOOL VAR is nlq, sheet feed;
+REAL VAR x size, y size;
+TEXT VAR std quality name, std typeface name, buffer, symbol, font text;
+THESAURUS VAR commands := empty thesaurus;
+
+insert (commands, "draft");
+insert (commands, "nlq");
+insert (commands, "roman");
+insert (commands, "sansserif");
+insert (commands, "courier");
+insert (commands, "prestige");
+insert (commands, "script");
+
+. is prop : bit (font bits, 1)
+. is double : bit (font bits, 5)
+.;
+
+(*********************************************************************)
+
+paper size (13.6 * 2.54, 12.0 * 2.54);
+paper size ( 8.0 * 2.54, 12.0 * 2.54);
+paper feed ("tractor");
+std typeface ("roman");
+std quality ("draft");
+
+PROC paper size (REAL CONST x, y) :
+
+ x size := x;
+ y size := y;
+
+END PROC paper size;
+
+PROC paper size :
+
+ line;
+ putline ("Papierbreite = " + text (x size, 5, 2) + " cm = " + text (x size / 2.54, 5, 2) + " Zoll");
+ putline ("Papierlaenge = " + text (y size, 5, 2) + " cm = " + text (y size / 2.54, 5, 2) + " Zoll");
+
+END PROC paper size;
+
+
+PROC paper feed (TEXT CONST paper) :
+
+ IF pos (paper, "sheet") <> 0
+ THEN sheet feed := TRUE;
+ ELIF pos (paper, "tractor") <> 0
+ THEN sheet feed := FALSE;
+ ELSE errorstop ("unzulaessige Papiereinfuehrung")
+ FI;
+
+END PROC paper feed;
+
+TEXT PROC paper feed :
+
+ IF sheet feed
+ THEN "sheet"
+ ELSE "tractor"
+ FI
+
+END PROC paper feed;
+
+
+PROC std typeface (TEXT CONST typeface) :
+
+ buffer := typeface;
+ changeall (buffer, " ", "");
+ IF link (commands, buffer) >= cmd roman
+ THEN std typeface name := buffer
+ ELSE errorstop ("unzulaessige Schriftart")
+ FI;
+
+END PROC std typeface;
+
+TEXT PROC std typeface : std typeface name END PROC std typeface;
+
+
+PROC std quality (TEXT CONST quality) :
+
+ IF quality = "nlq" OR quality = "draft"
+ THEN std quality name := quality;
+ ELSE errorstop ("unzulaessige Betriebsart")
+ FI;
+
+END PROC std quality;
+
+TEXT PROC std quality : std quality name END PROC std quality;
+
+(*********************************************************************)
+
+PROC open (INT CONST op code, INT VAR param1, param2) :
+
+SELECT op code OF
+ CASE c document : open document
+ CASE c page : open page
+END SELECT;
+
+
+. x steps : param1
+. y steps : param2
+.
+ open document :
+ x steps := x step conversion ( x size );
+ y steps := y step conversion ( y size );
+ y steps := (y steps DIV 30) * 30;
+ modification bits := 0;
+ out (""24""27""64""); (* Reset des Druckers *)
+ out (""27"C" + code (y steps DIV 30)); (* Formularlaenge *)
+ out (""27"x"0""); (* Entwurfsqualität *)
+ out (""27"R"0""); (* Amerikanischer Zeichensatz *)
+ out (""27"t"1""27"6"); (* Erweiterung des Zeichensatzes *)
+ IF sheet feed THEN out (""27""25"4") FI; (* Sheetmode ein *)
+ IF pos (material, "roman") <> 0
+ THEN out (""27"k"0"")
+ ELIF pos (material, "sansserif") <> 0
+ THEN out (""27"k"1"")
+ ELIF pos (material, "courier") <> 0
+ THEN out (""27"k"2"")
+ ELIF pos (material, "prestige") <> 0
+ THEN out (""27"k"3"")
+ ELIF pos (material, "script") <> 0
+ THEN out (""27"k"4"")
+ ELSE out (""27"k" + code (link (commands, std typeface) - cmd roman));
+ FI;
+ IF pos (material, "nlq") <> 0
+ THEN is nlq := TRUE;
+ ELIF pos (material, "draft") <> 0
+ THEN is nlq := FALSE;
+ ELSE is nlq := std quality = "nlq"
+ FI;
+
+
+. x start : param1
+. y start : param2
+.
+ open page :
+ x start := 0;
+ IF sheet feed
+ THEN y start := y step conversion (8.466667e-1) (* 2/6 Inch *)
+ ELSE y start := 0;
+ FI;
+ x rest := 0;
+ out (""13"");
+
+END PROC open;
+
+
+PROC close (INT CONST op code, INT CONST param1) :
+
+SELECT op code OF
+ CASE c document : close document
+ CASE c page : close page
+END SELECT;
+
+.
+ close document :
+
+
+. remaining y steps : param1
+.
+ close page :
+ IF sheet feed
+ THEN out (""27""25"R")
+ ELIF remaining y steps > 0
+ THEN out (""12"")
+ FI;
+
+END PROC close;
+
+
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+
+SELECT op code OF
+ CASE c write text : write text
+ CASE c write cmd : write cmd
+ CASE c carriage return : carriage return
+ CASE c move : move
+ CASE c draw : draw
+ CASE c on : on
+ CASE c off : off
+ CASE c type : type
+END SELECT
+
+
+. from : param1
+. to : param2
+.
+ write text :
+ out subtext (string, from, to)
+
+.
+ write cmd :
+ buffer := subtext (string, from, to);
+ scan (buffer);
+ next symbol (symbol);
+ SELECT link (commands, symbol) OF
+ CASE cmd draft : IF is nlq THEN switch to draft FI; is nlq := FALSE;
+ CASE cmd nlq : IF NOT is nlq THEN switch to nlq FI; is nlq := TRUE;
+ CASE cmd roman : out (""27"k"0"")
+ CASE cmd sansserif : out (""27"k"1"")
+ CASE cmd courier : out (""27"k"2"")
+ CASE cmd prestige : out (""27"k"3"")
+ CASE cmd script : out (""27"k"4"")
+ OTHERWISE : out (buffer);
+ END SELECT;
+
+
+(*. x steps to left margin : param1*)
+.
+ carriage return :
+ x rest := 0;
+ out (""13"");
+
+
+. x steps : param1
+. y steps : param2
+.
+ move :
+ IF x steps < 0 OR y steps < 0
+ THEN stop
+ ELSE IF x steps > 0 THEN x move FI;
+ IF y steps > 0 THEN y move FI;
+ FI;
+
+ . x move :
+ x rest INCR x steps;
+ IF not is underline
+ THEN simple x move
+ ELSE underline x move
+ FI;
+
+ . not is underline :
+ NOT bit (modification bits, 7)
+
+ . simple x move :
+ high := x rest DIV factor 1;
+ x rest := x rest MOD factor 1;
+ out (""27"\");
+ out (code (high MOD 256));
+ out (code (high DIV 256));
+
+ . underline x move :
+ high := x rest DIV factor 2;
+ x rest := x rest MOD factor 2;
+ IF high < blank pitch
+ THEN stop
+ ELSE low := high MOD 127;
+ high := high DIV 127;
+ IF low >= blank pitch
+ THEN low DECR blankpitch;
+ ELSE high DECR 1;
+ low DECR (blankpitch - 127);
+ FI;
+ IF high > 0
+ THEN out (""27" ");
+ out (code (127 - blankpitch));
+ high TIMESOUT " ";
+ FI;
+ out (""27" ");
+ out (code (low));
+ out (" "27" "0"");
+ FI;
+
+ . y move :
+ low := y steps MOD 255;
+ high := y steps DIV 255;
+ IF high > 0 THEN high TIMESOUT (""27"J"255"") FI;
+ IF low > 0 THEN out (""27"J"); out (code (low)) FI;
+.
+ draw :
+ IF x steps < 0 OR y steps <> 0 OR linetype <> underline linetype
+ THEN stop
+ ELIF x steps > 0
+ THEN x draw
+ FI;
+
+ . x draw :
+ x rest INCR x steps;
+ steps := x rest DIV 6;
+ x rest := x rest MOD 6;
+ IF steps > 0
+ THEN low := steps MOD 256;
+ high := steps DIV 256;
+ out (""27"L");
+ out (code (low));
+ out (code (high));
+ steps TIMESOUT ""1"";
+ FI;
+
+
+. modification : param1
+.
+ on :
+ buffer := on string (modification);
+ IF buffer <> ""
+ THEN modification bits := modification bits OR code (buffer);
+ switch to font;
+ ELSE stop
+ FI
+
+.
+ off :
+ buffer := off string (modification);
+ IF buffer <> ""
+ THEN modification bits := modification bits XOR code (buffer);
+ switch to font;
+ ELSE stop
+ FI
+
+.
+ type :
+ font nr := param1;
+ buffer := font string (font nr);
+ font bits := code (buffer SUB 1);
+ font text := subtext (buffer, 2);
+ IF is prop
+ THEN factor 1 := 4;
+ factor 2 := 4;
+ ELSE factor 1 := 6;
+ factor 2 := 6;
+ FI;
+ IF is double THEN factor 2 INCR factor 2 FI;
+ blank pitch := char pitch (font nr, " ") DIV factor 2;
+ switch to font;
+ IF is nlq THEN switch to nlq FI;
+
+END PROC execute;
+
+
+PROC switch to font :
+
+ out (""27"!");
+ out (code (font bits OR modification bits));
+ out (font text);
+
+END PROC switch to font;
+
+
+PROC switch to nlq :
+
+ IF NOT is prop
+ THEN factor 1 := 4;
+ factor 2 := (4 * factor 2) DIV 6;
+ blankpitch := (6 * blankpitch) DIV 4;
+ out (""27"x"1"");
+ ELSE out (""27"x"0"");
+ FI;
+
+END PROC switch to nlq;
+
+
+PROC switch to draft :
+
+ IF NOT is prop
+ THEN factor 1 := 6;
+ factor 2 := (6 * factor 2) DIV 4;
+ blankpitch := (4 * blankpitch) DIV 6;
+ out (""27"x"0"");
+ FI;
+
+END PROC switch to draft;
+
+
+END PACKET epson sq printer;
+
+
+
+#page#
+(******************************************************************)
+(*** ***)
+(*** Generierung des Printers ***)
+(*** ***)
+(******************************************************************)
+
+LET printer name = "printer.epson.sq",
+ up = ""3""13""5"";
+
+TEXT VAR fonttab name := "fonttab.epson.sq";
+
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+
+INT VAR pr channel;
+TEXT VAR buffer;
+
+command dialogue (TRUE);
+IF NOT multi user
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+FI;
+ask for print channel;
+ask for paper format;
+ask for typeface;
+ask for print quality;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+check on;
+.
+ ask for print channel :
+ line;
+ put ("gib Druckerkanal:");
+ get (pr channel);
+ do ("serverchannel(" + text (pr channel) + ")" ) ;
+ line;
+.
+ ask for paper format :
+ SELECT paper format OF
+ CASE 1 : papersize ( 8.0 * 2.54, 12.0 * 2.54)
+ CASE 2 : papersize (13.6 * 2.54, 12.0 * 2.54)
+ CASE 3 : papersize (21.0, 29.7)
+ END SELECT
+
+ . paper format :
+ line;
+ REP out (up);
+ IF yes ("Papierformat : endlos, 8 Zoll breit")
+ THEN LEAVE paper format WITH 1 FI;
+ out (up);
+ IF yes ("Papierformat : endlos, 13.6 Zoll breit")
+ THEN LEAVE paper format WITH 2 FI;
+ out (up);
+ IF yes ("Papierformat : DINA 4")
+ THEN LEAVE paper format WITH 3 FI;
+ PER;
+ 0
+.
+ ask for typeface :
+ line;
+ std typeface (typeface)
+
+ . typeface :
+ REP out (up);
+ IF yes ("standardmäßige Schriftart : roman")
+ THEN LEAVE typeface WITH "roman" FI;
+ out (up);
+ IF yes ("standardmäßige Schriftart : sansserif")
+ THEN LEAVE typeface WITH "sansserif" FI;
+ out (up);
+ IF yes ("standardmäßige Schriftart : courier")
+ THEN LEAVE typeface WITH "courier" FI;
+ out (up);
+ IF yes ("standardmäßige Schriftart : prestige")
+ THEN LEAVE typeface WITH "prestige" FI;
+ out (up);
+ IF yes ("standardmäßige Schriftart : script")
+ THEN LEAVE typeface WITH "script" FI;
+ PER;
+ ""
+.
+ ask for print quality :
+ line;
+ std quality (quality);
+
+ . quality :
+ REP out (up);
+ IF yes ("standardmäßige Druckqualität : draft quality")
+ THEN LEAVE quality WITH "draft" FI;
+ out (up);
+ IF yes ("standardmäßige Druckqualität : near letter quality")
+ THEN LEAVE quality WITH "nlq" FI;
+ PER;
+ ""
+.
+ load font table :
+ IF NOT exists (fonttab name)
+ THEN command dialogue (TRUE);
+ REP line (2);
+ putline ("Bitte Archiv mit der Fonttabelle """ +
+ fonttab name + """ einlegen!");
+ line;
+ UNTIL yes ("Archiv eingelegt") PER;
+ reserve archive;
+ fetch (fonttab name, archive);
+ release (archive);
+ FI;
+ font table (fonttab name);
+ IF multi user
+ THEN command dialogue (FALSE);
+ do ("save(""" + font tab name + """,task(""configurator""))")
+ FI;
+ forget (fonttab name, quiet);
+
+ . reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ disable stop;
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI;
+ enable stop;
+
+. generate printer spool :
+ eumel must advertise;
+ cursor (1, 12);
+ putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+ putline ("die Fonttabelle mit dem Kommando");
+ line;
+ putline (" font table (""" + font tab name + """)");
+ line;
+ putline ("eingestellt werden!!!");
+ line (4);
+ putline ("Generierung beendet, weiter mit 'SV'");
+ generate printer server;
+ do (buffer);
+
+. generate printer server :
+ buffer := "break (quiet);";
+ buffer CAT "spool manager (PROC printer);";
+ buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+ buffer CAT "PROC printer:";
+ buffer CAT " disable stop;";
+ buffer CAT " continue (server channel);";
+ buffer CAT " check error (error message);";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " REP forget (ds);";
+ buffer CAT " execute print;";
+ buffer CAT " IF is error AND online THEN put error; clear error; FI;";
+ buffer CAT " PER;";
+ buffer CAT "END PROC printer;";
+ buffer CAT "PROC execute print:";
+ buffer CAT " LET ack = 0, fetch code = 11, file type = 1003;";
+ buffer CAT " enable stop;";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " call (father, fetch code, ds, reply);";
+ buffer CAT " IF reply = ack CAND type (ds) = file type";
+ buffer CAT " THEN file := sequential file (input, ds);";
+ buffer CAT " print (file,";
+ buffer CAT " PROC (INT CONST, INT VAR, INT VAR) open,";
+ buffer CAT " PROC (INT CONST, INT CONST) close,";
+ buffer CAT " PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC execute print;";
+ buffer CAT "PROC check error(TEXT CONST message):";
+ buffer CAT " IF is error";
+ buffer CAT " THEN clear error; rename myself (message);";
+ buffer CAT " IF is error THEN end(myself) FI;";
+ buffer CAT " pause (9000); end(myself);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC check error;";
+
diff --git a/printer/laser/printer.hp.laserjet b/printer/laser/printer.hp.laserjet
new file mode 100644
index 0000000..152ee8e
--- /dev/null
+++ b/printer/laser/printer.hp.laserjet
@@ -0,0 +1,417 @@
+PACKET hp laserjet printer
+
+(**************************************************************************)
+(* Stand : 03.02.88 *)
+(* HP 2686A LaserJet / LaserJet+ Verison : 4 *)
+(* Autor : Rudolf Ruland *)
+(**************************************************************************)
+
+ DEFINES open,
+ close,
+ execute,
+
+ paper size,
+ printer type :
+
+LET
+(* underline = 1,
+ bold = 2,
+ italics = 4,
+ reverse = 8,
+
+ underline linetype = 1, *)
+
+ c document = 1,
+ c page = 2,
+
+ c write text = 1,
+ c write cmd = 2,
+ c carriage return = 3,
+ c move = 4,
+ c draw = 5,
+ c on = 6,
+ c off = 7,
+ c type = 8;
+
+INT VAR abs x pos
+REAL VAR x size, y size;
+BOOL VAR is laser jet plus, is landscape;
+
+(*********************************************************************)
+
+paper size (21.0, 29.7);
+printer type ("LaserJet");
+
+PROC paper size (REAL CONST x, y) :
+
+ x size := x;
+ y size := y;
+
+END PROC paper size;
+
+PROC paper size :
+
+ line;
+ putline ("Papierbreite = " + text (x size, 5, 2) + " cm = " + text (x size / 2.54, 5, 2) + " Zoll");
+ putline ("Papierlaenge = " + text (y size, 5, 2) + " cm = " + text (y size / 2.54, 5, 2) + " Zoll");
+
+END PROC paper size;
+
+PROC printer type (TEXT CONST type) :
+
+ is laser jet plus := pos (type, "+") <> 0
+
+END PROC printer type;
+
+TEXT PROC printer type :
+
+ IF is laser jet plus
+ THEN "LaserJet+"
+ ELSE "LaserJet"
+ FI
+
+END PROC printer type;
+
+(*********************************************************************)
+
+PROC open (INT CONST op code, INT VAR param1, param2) :
+
+SELECT op code OF
+ CASE c document : open document
+ CASE c page : open page
+END SELECT;
+
+
+. x steps : param1
+. y steps : param2
+.
+ open document :
+ out (""27"E"); (* Reset des Druckers *)
+ out (""27"&s1C"); (* 'end of line wrap' aus *)
+ out (""27"&l0L"); (* 'perforation skip' aus *)
+ out (""27"&l1X"); (* eine Kopie *)
+ out (""27"&l1H"); (* upper tray *)
+ IF pos (material, "landscape") > 0 OR pos (material, "quer") > 0
+ THEN is landscape := TRUE;
+ x steps := x step conversion ( y size );
+ y steps := y step conversion ( x size );
+ out (""27"&l1O");
+ ELSE is landscape := FALSE;
+ x steps := x step conversion ( x size );
+ y steps := y step conversion ( y size );
+ FI;
+
+. x start : param1
+. y start : param2
+.
+ open page :
+ IF is landscape
+ THEN x start := x step conversion (0.508); (* 0.200*2.54 *)
+ y start := y step conversion (1.693333); (* 0.500*2.54 + 2.54/6.0 *)
+ ELSE x start := x step conversion (0.39878); (* 0.157*2.54 *)
+ y start := y step conversion (1.693333); (* 0.500*2.54 + 2.54/6.0 *)
+ FI;
+ IF pos (material, "lower tray") > 0 COR pos (material, "lowertray") > 0
+ THEN out (""27"&l4H");
+ ELIF pos (material, "tray") > 0 COR pos (material, "upper tray") > 0 COR pos (material, "uppertray") > 0
+ THEN out (""27"&l1H");
+ ELIF pos (material, "manual") > 0
+ THEN out (""27"&l2H");
+ ELIF pos (material, "envelope") > 0
+ THEN out (""27"&l3H");
+ FI;
+ IF material contains a number
+ THEN out (""27"&l" + text (number) + "X");
+ FI;
+ out (""13"");
+
+ . material contains a number :
+ INT VAR number := pos (material, "0", "9", 1);
+ IF number = 0
+ THEN FALSE
+ ELSE number := max (1, int (subtext (material, number, number + 1)));
+ TRUE
+ FI
+
+END PROC open;
+
+
+PROC close (INT CONST op code, INT CONST param1) :
+
+SELECT op code OF
+ CASE c document : close document
+ CASE c page : close page
+ OTHERWISE : put (param1)
+END SELECT;
+
+.
+ close document :
+
+
+(*. remaining y steps : param1*)
+.
+ close page :
+ out (""12"")
+
+END PROC close;
+
+
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+
+SELECT op code OF
+ CASE c write text : write text
+ CASE c write cmd : write cmd
+ CASE c carriage return : carriage return
+ CASE c move : move
+ CASE c draw : draw
+ CASE c on : on
+ CASE c off : off
+ CASE c type : type
+END SELECT
+
+
+. from : param1
+. to : param2
+.
+ write text :
+ out subtext (string, from, to)
+
+.
+ write cmd :
+ out subtext (string, from, to)
+
+
+(*. x steps to left margin : param1*)
+.
+ carriage return :
+ out (""13"")
+
+
+. x steps : param1
+. y steps : param2
+.
+ move :
+ IF x steps <> 0
+ THEN x move
+ ELIF y steps > 0
+ THEN out (""27"&a+" + text (y steps) + "V");
+ ELIF y steps < 0
+ THEN out (""27"&a" + text (y steps) + "V");
+ FI;
+
+ . x move :
+ IF is laser jet plus
+ THEN laser jet plus x move
+ ELSE laser jet x move
+ FI;
+
+ . laser jet plus x move :
+ IF x steps >= 0
+ THEN out (""27"*p+" + text (x steps) + "X");
+ ELSE out (""27"*p" + text (x steps) + "X");
+ FI;
+
+ . laser jet x move :
+ abs x pos := x pos;
+ IF abs x pos >= 0
+ THEN out (""27"&a");
+ out (text ((abs x pos DIV 5) * 12 + ((abs x pos MOD 5) * 12 + 4) DIV 5));
+ out ("H");
+ ELSE stop
+ FI;
+
+.
+ draw :
+ stop
+
+
+. modification : param1
+.
+ on :
+ IF on string (modification) <> ""
+ THEN out (on string (modification))
+ ELSE stop
+ FI
+
+.
+ off :
+ IF off string (modification) <> ""
+ THEN out (off string (modification))
+ ELSE stop
+ FI
+
+
+. font nr : param1
+.
+ type :
+ out (font string (font nr));
+
+END PROC execute;
+
+
+END PACKET hp laserjet printer;
+
+
+#page#
+(******************************************************************)
+(*** ***)
+(*** Generierung des Printers ***)
+(*** ***)
+(******************************************************************)
+
+LET printer name = "printer.hp.laserjet",
+ up = ""3""13""5"";
+
+TEXT VAR fonttab name := "fonttab.hp.laserjet";
+
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+
+INT VAR pr channel;
+TEXT VAR buffer;
+
+command dialogue (TRUE);
+IF NOT multi user
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+FI;
+ask for print channel;
+ask for printer type;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+check on;
+.
+ ask for print channel :
+ line;
+ put ("gib Druckerkanal:");
+ get (pr channel);
+ do ("serverchannel(" + text (pr channel) + ")" ) ;
+ line;
+.
+ ask for printer type :
+ printer type (laser jet);
+
+ . laser jet :
+ line;
+ REP out (up);
+ IF yes ("Druckertyp : HP LaserJet")
+ THEN LEAVE laser jet WITH "LaserJet" FI;
+ out (up);
+ IF yes ("Druckertyp : HP LaserJet+")
+ THEN LEAVE laser jet WITH "LaserJet+" FI;
+ PER;
+ ""
+.
+ load font table :
+ line (2);
+ write (""13""4"");
+ putline ("Die Fonttabelle """ + fonttab name +
+ """ enthält die Schrifttypen der");
+ putline ("Font Cartriges:");
+ putline (" 92286A Courier 1");
+ putline (" 92286C International 1");
+ putline (" 92286D Prestige Elite");
+ putline (" 92286E Letter Gothic");
+ putline (" 92286F TMS Proportional 2");
+ putline (" 92286L Courier P&L");
+ putline (" 92286M Prestige Elite P&L");
+ putline (" 92286N Letter Gothic P&L");
+ putline (" 92286P TMS RMN P&L");
+ putline (" 92286Q Memo 1");
+ line;
+ putline ("Für ein korrektes Druckbild dürfen immer nur die Schrifttypen angesprochen");
+ putline ("werden, deren Cartrige eingeschoben ist!");
+ IF printer type = "LaserJet"
+ THEN line;
+ putline ("ELAN-Listings können nur gedruckt werden, wenn ein Cartrige mit dem");
+ putline ("Schrifttyp 'LINE PRINTER' eingeschoben ist!");
+ FI;
+ line (2);
+ putline ("Weiter nach Eingabe einer Taste");
+ pause;
+ IF NOT exists (fonttab name)
+ THEN command dialogue (TRUE);
+ REP line (2);
+ putline ("Bitte Archiv mit der Fonttabelle """ +
+ fonttab name + """ einlegen!");
+ line;
+ UNTIL yes ("Archiv eingelegt") PER;
+ reserve archive;
+ fetch (fonttab name, archive);
+ release (archive);
+ FI;
+ font table (fonttab name);
+ IF multi user
+ THEN command dialogue (FALSE);
+ do ("save(""" + font tab name + """,task(""configurator""))")
+ FI;
+ forget (fonttab name, quiet);
+
+ . reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ disable stop;
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI;
+ enable stop;
+
+. generate printer spool :
+ eumel must advertise;
+ cursor (1, 12);
+ putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+ putline ("die Fonttabelle mit dem Kommando");
+ line;
+ putline (" font table (""" + font tab name + """)");
+ line;
+ putline ("eingestellt werden!!!");
+ line (4);
+ putline ("Generierung beendet, weiter mit 'SV'");
+ generate printer server;
+ do (buffer);
+
+. generate printer server :
+ buffer := "break (quiet);";
+ buffer CAT "spool manager (PROC printer);";
+ buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+ buffer CAT "PROC printer:";
+ buffer CAT " disable stop;";
+ buffer CAT " continue (server channel);";
+ buffer CAT " check error (error message);";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " REP forget (ds);";
+ buffer CAT " execute print;";
+ buffer CAT " IF is error AND online";
+ buffer CAT " THEN out (""""27""(8U""27""(s0p10h12v0s0b3T"");";
+ buffer CAT " put error; clear error; out (""""12"""");";
+ buffer CAT " FI;";
+ buffer CAT " PER;";
+ buffer CAT "END PROC printer;";
+ buffer CAT "PROC execute print:";
+ buffer CAT " LET ack = 0, fetch code = 11, file type = 1003;";
+ buffer CAT " enable stop;";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " call (father, fetch code, ds, reply);";
+ buffer CAT " IF reply = ack CAND type (ds) = file type";
+ buffer CAT " THEN file := sequential file (input, ds);";
+ buffer CAT " print (file,";
+ buffer CAT " PROC (INT CONST, INT VAR, INT VAR) open,";
+ buffer CAT " PROC (INT CONST, INT CONST) close,";
+ buffer CAT " PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC execute print;";
+ buffer CAT "PROC check error(TEXT CONST message):";
+ buffer CAT " IF is error";
+ buffer CAT " THEN clear error; rename myself (message);";
+ buffer CAT " IF is error THEN end(myself) FI;";
+ buffer CAT " pause (9000); end(myself);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC check error;";
+
diff --git a/printer/laser/printer.kyocera.f-1010 b/printer/laser/printer.kyocera.f-1010
new file mode 100644
index 0000000..a46f7b3
--- /dev/null
+++ b/printer/laser/printer.kyocera.f-1010
@@ -0,0 +1,373 @@
+PACKET kyocera f 1010 printer
+
+(**************************************************************************)
+(* Stand : 03.12.86 *)
+(* KYOCERA F - 1010 Verison : 4 *)
+(* Autor : Rudolf Ruland *)
+(**************************************************************************)
+
+(**************************************************************************)
+(* Hinweis : Die 'time-out' Zeit, nach der der Eingabepuffer ausgegeben *)
+(* wird, wenn keine Eingabe mehr erfolgt, sollte moeglichst *)
+(* gross gewaehlt werden, *)
+(* z.B. mit FRPO H9, 60; wird sie auf 5 Min. gesetzt *)
+(**************************************************************************)
+
+
+ DEFINES open,
+ close,
+ execute,
+
+ paper size :
+
+LET underline = 1,
+(* bold = 2,
+ italics = 4,
+ reverse = 8,
+
+ underline linetype = 1, *)
+
+ c document = 1,
+ c page = 2,
+
+ c write text = 1,
+ c write cmd = 2,
+ c carriage return = 3,
+ c move = 4,
+ c draw = 5,
+ c on = 6,
+ c off = 7,
+ c type = 8;
+
+INT VAR blankpitch, high, low;
+REAL VAR x size, y size;
+BOOL VAR is landscape, is underline;
+
+(*********************************************************************)
+
+paper size (21.0, 29.7);
+
+PROC paper size (REAL CONST x, y) :
+
+ x size := x;
+ y size := y;
+
+END PROC paper size;
+
+PROC paper size :
+
+ line;
+ putline ("Papierbreite = " + text (x size, 5, 2) + " cm = " + text (x size / 2.54, 5, 2) + " Zoll");
+ putline ("Papierlaenge = " + text (y size, 5, 2) + " cm = " + text (y size / 2.54, 5, 2) + " Zoll");
+
+END PROC paper size;
+
+(*********************************************************************)
+
+PROC open (INT CONST op code, INT VAR param1, param2) :
+
+SELECT op code OF
+ CASE c document : open document
+ CASE c page : open page
+END SELECT;
+
+
+. x steps : param1
+. y steps : param2
+.
+ open document :
+ out ("!"82"! RES; UNIT D; EXIT;"); (* Reset des Druckers *)
+ IF pos (material, "landscape") > 0 OR pos (material, "quer") > 0
+ THEN is landscape := TRUE;
+ x steps := x step conversion ( y size );
+ y steps := y step conversion ( x size );
+ out (""27"&l1O");
+ ELSE is landscape := FALSE;
+ x steps := x step conversion ( x size );
+ y steps := y step conversion ( y size );
+ FI;
+ is underline := FALSE;
+ IF y size < 29.7 OR x size < 21.0
+ THEN out ("!"82"! SLM ");
+ IF is landscape
+ THEN out (text (x step conversion (29.7 - y size)));
+ out ("; STM ");
+ out (text (y step conversion ((21.0 - x size) * 0.5)));
+ ELSE out (text (x step conversion ((21.0 - x size) * 0.5)));
+ FI;
+ out ("; EXIT;");
+ FI;
+
+. x start : param1
+. y start : param2
+.
+ open page :
+ out ("!"82"! MZP 0, 0; EXIT;"); (* Positionierung zum Nullpunkt *)
+ IF is landscape
+ THEN x start := x step conversion (0.19);
+ y start := y step conversion (0.70);
+ ELSE x start := x step conversion (0.56);
+ y start := y step conversion (0.60);
+ FI;
+ IF pos (material, "tray") > 0
+ THEN out (""27"&l1H");
+ ELIF pos (material, "manual") > 0
+ THEN out (""27"&l2H");
+ FI;
+ out (""13"");
+
+END PROC open;
+
+
+PROC close (INT CONST op code, INT CONST param1) :
+
+SELECT op code OF
+ CASE c document : close document
+ CASE c page : close page
+ OTHERWISE : put (param1)
+END SELECT;
+
+.
+ close document :
+
+
+(*. remaining y steps : param1*)
+.
+ close page :
+ out (""12"");
+
+END PROC close;
+
+
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+
+SELECT op code OF
+ CASE c write text : write text
+ CASE c write cmd : write cmd
+ CASE c carriage return : carriage return
+ CASE c move : move
+ CASE c draw : draw
+ CASE c on : on
+ CASE c off : off
+ CASE c type : type
+END SELECT
+
+
+. from : param1
+. to : param2
+.
+ write text :
+ out subtext (string, from, to)
+
+.
+ write cmd :
+ out subtext (string, from, to)
+
+
+(*. x steps to left margin : param1*)
+.
+ carriage return :
+ out (""13"")
+
+
+. x steps : param1
+. y steps : param2
+.
+ move :
+ IF x steps > 0
+ THEN IF is underline
+ THEN underline x move
+ ELSE out (""27"*p+" + text (x steps) + "X");
+ FI;
+ ELIF x steps < 0
+ THEN out (""27"*p" + text (x steps) + "X");
+ ELIF y steps > 0
+ THEN out (""27"*p+" + text (y steps) + "Y");
+ ELIF y steps < 0
+ THEN out (""27"*p" + text (y steps) + "Y");
+ FI;
+
+ . underline x move :
+ high := x steps DIV blankpitch;
+ low := x steps MOD blankpitch;
+ IF high > 0 THEN high TIMESOUT " " FI;
+ IF low > 0 THEN out (" "27"*p" + text (low - blank pitch) + "X") FI;
+
+.
+ draw :
+ stop
+
+
+. modification : param1
+.
+ on :
+ IF on string (modification) <> ""
+ THEN out (on string (modification));
+ IF modification = underline THEN is underline := TRUE FI;
+ ELSE stop
+ FI
+
+.
+ off :
+ IF off string (modification) <> ""
+ THEN out (off string (modification));
+ IF modification = underline THEN is underline := FALSE FI;
+ ELSE stop
+ FI
+
+
+. font nr : param1
+.
+ type :
+ out (font string (font nr));
+ blankpitch := char pitch (font nr, " ");
+
+END PROC execute;
+
+
+END PACKET kyocera f 1010 printer;
+
+
+
+#page#
+(******************************************************************)
+(*** ***)
+(*** Generierung des Printers ***)
+(*** ***)
+(******************************************************************)
+
+LET printer name = "printer.kyocera.f-1010";
+
+TEXT VAR fonttab name := "fonttab.kyocera.f-1010";
+
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+
+INT VAR pr channel;
+TEXT VAR buffer;
+
+command dialogue (TRUE);
+IF NOT multi user
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+FI;
+ask for print channel;
+dynamic font hint;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+check on;
+command dialogue (TRUE);
+.
+ ask for print channel :
+ line;
+ put ("gib Druckerkanal:");
+ get (pr channel);
+ do ("serverchannel(" + text (pr channel) + ")" ) ;
+ line;
+.
+ dynamic font hint :
+ line (3);
+ putline (""4"Hinweis zur Benutzung der dynamischen Schrifttypen:");
+ line;
+ putline (" In der Fonttabelle """ + fonttab name + """ sind einige dynamische");
+ putline (" Schrifttypen angepaßt. Diese müssen nach jedem Einschalten des");
+ putline (" Druckers neu generiert werden.");
+ putline (" Zur Generierung dieser Schrifttypen befinden sich auf dem Standard-");
+ putline (" archive die folgenden Dateien:");
+ line;
+ putline (" ""genfont.kyocera.f-1010.dynamic1""");
+ putline (" ""genfont.kyocera.f-1010.dynamic2""");
+ line;
+ putline (" Nach Einschalten des Druckers müssen diese Dateien zuerst ausgedruckt");
+ putline (" werden.");
+ putline (" Die Generierung benötigt pro Schriftart etwa 15 Minuten.");
+ line (2);
+ putline ("Weiter nach Eingabe einer Taste");
+ pause;
+.
+ load font table :
+ IF NOT exists (fonttab name)
+ THEN REP line (2);
+ putline ("Bitte Archiv mit der Fonttabelle """ +
+ fonttab name + """ einlegen!");
+ line;
+ UNTIL yes ("Archiv eingelegt") PER;
+ reserve archive;
+ fetch (fonttab name, archive);
+ release (archive);
+ FI;
+ font table (fonttab name);
+ IF multi user
+ THEN command dialogue (FALSE);
+ do ("save(""" + font tab name + """,task(""configurator""))")
+ FI;
+ forget (fonttab name, quiet);
+
+ . reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ disable stop;
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI;
+ enable stop;
+
+. generate printer spool :
+ eumel must advertise;
+ cursor (1, 12);
+ putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+ putline ("die Fonttabelle mit dem Kommando");
+ line;
+ putline (" font table (""" + font tab name + """)");
+ line;
+ putline ("eingestellt werden!!!");
+ line (4);
+ putline ("Generierung beendet, weiter mit 'SV'");
+ generate printer server;
+ do (buffer);
+
+. generate printer server :
+ buffer := "break (quiet);";
+ buffer CAT "spool manager (PROC printer);";
+ buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+ buffer CAT "PROC printer:";
+ buffer CAT " disable stop;";
+ buffer CAT " continue (server channel);";
+ buffer CAT " check error (error message);";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " REP forget (ds);";
+ buffer CAT " execute print;";
+ buffer CAT " IF is error AND online";
+ buffer CAT " THEN out (""""27""(8U""27""(s0p10h12v0s0b3T"");";
+ buffer CAT " put error; clear error; out (""""12"""");";
+ buffer CAT " FI;";
+ buffer CAT " PER;";
+ buffer CAT "END PROC printer;";
+ buffer CAT "PROC execute print:";
+ buffer CAT " LET ack = 0, fetch code = 11, file type = 1003;";
+ buffer CAT " enable stop;";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " call (father, fetch code, ds, reply);";
+ buffer CAT " IF reply = ack CAND type (ds) = file type";
+ buffer CAT " THEN file := sequential file (input, ds);";
+ buffer CAT " print (file,";
+ buffer CAT " PROC (INT CONST, INT VAR, INT VAR) open,";
+ buffer CAT " PROC (INT CONST, INT CONST) close,";
+ buffer CAT " PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC execute print;";
+ buffer CAT "PROC check error(TEXT CONST message):";
+ buffer CAT " IF is error";
+ buffer CAT " THEN clear error; rename myself (message);";
+ buffer CAT " IF is error THEN end(myself) FI;";
+ buffer CAT " pause (9000); end(myself);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC check error;";
+
diff --git a/printer/laser/printer.nec.lc-08 b/printer/laser/printer.nec.lc-08
new file mode 100644
index 0000000..9ee2837
--- /dev/null
+++ b/printer/laser/printer.nec.lc-08
@@ -0,0 +1,626 @@
+PACKET nec lc 08 printer
+
+(**************************************************************************)
+(* Stand : 29.01.88 *)
+(* NEC Silentwriter LC-08 Verison : 4 *)
+(* Autor : Rudolf Ruland *)
+(**************************************************************************)
+
+ DEFINES open,
+ close,
+ execute,
+
+ box commands,
+ insert box command,
+ delete box command,
+
+ paper size,
+ paper x size,
+ paper y size:
+
+LET
+(* underline = 1,
+ bold = 2,
+ italics = 4,
+ reverse = 8,
+
+ underline linetype = 1, *)
+
+ c document = 1,
+ c page = 2,
+
+ c write text = 1,
+ c write cmd = 2,
+ c carriage return = 3,
+ c move = 4,
+ c draw = 5,
+ c on = 6,
+ c off = 7,
+ c type = 8,
+
+ tag type = 1;
+
+INT VAR symbol type;
+REAL VAR x size, y size;
+BOOL VAR is landscape, was cr;
+TEXT VAR bold buffer, mod string, command, symbol;
+THESAURUS VAR box cmds := empty thesaurus;
+
+(*********************************************************************)
+
+paper size (21.0, 29.7);
+
+PROC paper size (REAL CONST x, y) :
+
+ x size := x;
+ y size := y;
+
+END PROC paper size;
+
+PROC paper size :
+
+ line;
+ putline ("Papierbreite = " + text (x size, 5, 2) + " cm = " + text (x size / 2.54, 5, 2) + " Zoll");
+ putline ("Papierlaenge = " + text (y size, 5, 2) + " cm = " + text (y size / 2.54, 5, 2) + " Zoll");
+
+END PROC paper size;
+
+REAL PROC paper x size : x size END PROC paper x size;
+REAL PROC paper y size : y size END PROC paper y size;
+
+
+THESAURUS PROC box commands : box cmds END PROC box commands;
+
+PROC insert box command (TEXT CONST new command) :
+
+ command := new command;
+ change all (command, " ", "");
+ insert (box cmds, command)
+
+END PROC insert box command;
+
+PROC delete box command (TEXT CONST old command) :
+
+ INT VAR dummy;
+ command := old command;
+ change all (command, " ", "");
+ delete (box cmds, command, dummy)
+
+END PROC delete box command;
+
+(*********************************************************************)
+
+PROC open (INT CONST op code, INT VAR param1, param2) :
+
+SELECT op code OF
+ CASE c document : open document
+ CASE c page : open page
+END SELECT;
+
+
+. x steps : param1
+. y steps : param2
+.
+ open document :
+ out (""28"Cz"); (* Diablo 630 Emulation *)
+ out (""27""13"P"); (* Reset *)
+ out (""28"$"); (* Formatlaenge loeschen *)
+ out (""28"Ca"27"6"28"Cz"); (* Zeichensatz 2 *)
+ out (""28"Ra"); (* USA-Zeichensatz *)
+ out (""27""25"1"); (* Sheet 1 *)
+ is landscape := pos (material, "landscape") > 0;
+ IF is landscape
+ THEN x steps := x step conversion ( y size );
+ y steps := y step conversion ( x size );
+ out (""28")"128""0""); (* Landscape-Mode *)
+ ELSE x steps := x step conversion ( x size );
+ y steps := y step conversion ( y size );
+ out (""28")"001""0""); (* Portait -Mode *)
+ FI;
+ was cr := FALSE;
+ bold buffer := "";
+
+. x start : param1
+. y start : param2
+.
+ open page :
+ IF is landscape
+ THEN x start := x step conversion (0.45);
+ y start := y step conversion (0.9);
+ ELSE x start := x step conversion (0.7);
+ y start := y step conversion (0.9);
+ FI;
+ IF pos (material, "sheet1") > 0
+ THEN out (""27""25"1")
+ ELIF pos (material, "sheet2") > 0
+ THEN out (""27""25"2")
+ ELIF pos (material, "manual") > 0
+ THEN out (""27""25"E")
+ FI;
+ out (""28"'a"0""0""28"&a"0""0""); (* Positionierung auf den Nullpunkt *)
+
+END PROC open;
+
+
+PROC close (INT CONST op code, INT CONST param1) :
+
+SELECT op code OF
+ CASE c document : close document
+ CASE c page : close page
+ OTHERWISE : put (param1)
+END SELECT;
+
+.
+ close document :
+
+
+(*. remaining y steps : param1*)
+.
+ close page :
+ out (""12"")
+
+END PROC close;
+
+
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+
+SELECT op code OF
+ CASE c write text : write text
+ CASE c write cmd : write cmd
+ CASE c carriage return : carriage return
+ CASE c move : move
+ CASE c draw : draw
+ CASE c on : on
+ CASE c off : off
+ CASE c type : type
+END SELECT
+
+
+. from : param1
+. to : param2
+.
+ write text :
+ IF was cr
+ THEN was cr := FALSE;
+ out (bold buffer);
+ FI;
+ out subtext (string, from, to)
+
+.
+ write cmd :
+ IF was cr
+ THEN was cr := FALSE;
+ out (bold buffer);
+ FI;
+ command := subtext (string, from, to);
+ IF is box cmd
+ THEN disable stop;
+ do (command);
+ clear error;
+ ELSE out (command);
+ FI;
+
+ . is box cmd :
+ scan (command);
+ next symbol (symbol, symbol type);
+ (symbol type = tag type) CAND (box cmds CONTAINS symbol)
+
+
+(*. x steps to left margin : param1*)
+.
+ carriage return :
+ out (""13"");
+ was cr := TRUE;
+
+
+. x steps : param1
+. y steps : param2
+.
+ move :
+ IF x steps <> 0 THEN x move FI;
+ IF y steps <> 0 THEN y move FI;
+
+ . x move :
+ IF x steps > 0 THEN out (""28"&c") ELSE out (""28"&d") FI;
+ out (x steps low);
+ out (x steps high);
+
+ . x steps low : code (abs (x steps) MOD 256)
+ . x steps high : code (abs (x steps) DIV 256)
+
+ . y move :
+ IF y steps > 0 THEN out (""28"'c") ELSE out (""28"'d") FI;
+ out (y steps low);
+ out (y steps high);
+
+ . y steps low : code (abs (y steps) MOD 256)
+ . y steps high : code (abs (y steps) DIV 256)
+.
+ draw :
+ stop
+
+
+. modification : param1
+.
+ on :
+ mod string := on string (modification);
+ IF mod string <> ""
+ THEN out (mod string);
+ IF pos (""27"W"27"O", mod string) > 0
+ THEN bold buffer CAT mod string;
+ FI;
+ ELSE stop
+ FI
+
+.
+ off :
+ mod string := off string (modification);
+ IF mod string <> ""
+ THEN out (mod string);
+ IF pos (""27"&", mod string) > 0
+ THEN bold buffer := subtext (bold buffer, 1, LENGTH bold buffer - 2);
+ out (bold buffer);
+ FI;
+ ELSE stop
+ FI
+
+
+. font nr : param1
+.
+ type :
+ out (""28")"); (* Font Identifikation *)
+ command := font string (font nr);
+ IF is landscape
+ THEN out subtext (command, 3, 4);
+ ELSE out subtext (command, 1, 2);
+ FI;
+ out (""28"E"); (* Zeilenvorschub (VMI) *)
+ out (code (font height (font nr) + font depth (font nr) + font lead (font nr)));
+ out (""28"F"); (* Zeichenabstand (HMI) *)
+ out (code (char pitch (font nr, " ")));
+ out (""27"P"); (* proportional ein *)
+ out subtext (command, 5);
+
+END PROC execute;
+
+END PACKET nec lc 08 printer;
+
+
+PACKET nec lc 08 box commands
+
+(**************************************************************************)
+(* *)
+(* Kommandos zum Zeichen von Boxen, Linien und Schraffuren *)
+(* für den NEC Laserdrucker LC-08 *)
+(* *)
+(* Autor : Rudolf Ruland *)
+(* Stand : 29.01.88 *)
+(**************************************************************************)
+
+ DEFINES line,
+ x line,
+ y line,
+
+ box,
+ box frame,
+ box shade,
+
+ cake,
+ cake frame,
+ cake shade,
+ :
+
+INT VAR x, y, h, w;
+
+WHILE highest entry (box commands) > 0
+ REP delete box command (name (box commands, highest entry (box commands))) PER;
+insert box command ("line");
+insert box command ("xline");
+insert box command ("yline");
+insert box command ("box");
+insert box command ("boxshade");
+insert box command ("boxframe");
+insert box command ("cake");
+insert box command ("cakeshade");
+insert box command ("cakeframe");
+
+
+PROC line (REAL CONST x offset, y offset, width, height, INT CONST line width) :
+
+ IF line width > 0
+ THEN graph on (x offset, y offset, width, height);
+ out ("LW" + text (line width) + ";");
+ out ("PR;");
+ out ("PD" + text (+w) + "," + text (-h) + ";");
+ graph off;
+ FI;
+
+END PROC line;
+
+PROC x line (REAL CONST x offset, y offset, width, INT CONST line width) :
+
+ IF line width > 0
+ THEN graph on (x offset, y offset, width, 0.0);
+ out ("LW" + text (line width) + ";");
+ out ("PR;");
+ out ("PD" + text (+w) + "," + "0;");
+ graph off;
+ FI;
+
+END PROC x line;
+
+PROC y line (REAL CONST x offset, y offset, height, INT CONST line width) :
+
+ IF line width > 0
+ THEN graph on (x offset, y offset, 0.0, height);
+ out ("LW" + text (line width) + ";");
+ out ("PR;");
+ out ("PD0," + text (-h) + ";");
+ graph off;
+ FI;
+
+END PROC y line;
+
+
+PROC box (REAL CONST x offset, y offset, width, height,
+ INT CONST pattern type, line width) :
+
+ IF pattern type = 0
+ THEN box frame (x offset, y offset, width, height, line width)
+ ELIF line width = 0
+ THEN box shade (x offset, y offset, width, height, pattern type)
+ ELSE graph on (x offset, y offset, width, height);
+ out ("LW" + text (line width) + ";");
+ set pattern (pattern type);
+ out ("ER" + text (+w) + "," + text (-h) + ";");
+ graph off;
+ FI;
+
+END PROC box;
+
+
+PROC box shade (REAL CONST x offset, y offset, width, height,
+ INT CONST pattern type) :
+
+ IF pattern type <> 0
+ THEN graph on (x offset, y offset, width, height);
+ set pattern (pattern type);
+ out ("RR" + text (+w) + "," + text (-h) + ";");
+ graph off;
+ FI;
+
+END PROC box shade;
+
+
+PROC box frame (REAL CONST x offset, y offset, width, height,
+ INT CONST line width) :
+
+ IF line width <> 0
+ THEN graph on (x offset, y offset, width, height);
+ out ("LW" + text (line width) + ";");
+ out ("PR;");
+ out ("PD");
+ out (text (+w) + "," + "0,");
+ out ( "0," + text (-h) + ",");
+ out (text (-w) + "," + "0,");
+ out ( "0," + text (+h) + ";");
+ graph off;
+ FI;
+
+END PROC box frame;
+
+
+PROC cake (REAL CONST x offset, y offset, radius, start angle, sweep angle,
+ INT CONST pattern type, line width) :
+
+ IF pattern type = 0
+ THEN cake frame (x offset, y offset, radius, start angle, sweep angle, line width)
+ ELIF line width = 0
+ THEN cake shade (x offset, y offset, radius, start angle, sweep angle, pattern type)
+ ELSE graph on (x offset, y offset, radius, 0.0);
+ out ("LW" + text (line width) + ";");
+ set pattern (pattern type);
+ out ("EW" + text (+w) + "," + text (start angle) + "," + text (sweep angle) + ";");
+ graph off;
+ FI;
+
+END PROC cake;
+
+
+PROC cake shade (REAL CONST x offset, y offset, radius, start angle, sweep angle,
+ INT CONST pattern type) :
+
+ IF pattern type > 0 CAND w > 0
+ THEN graph on (x offset, y offset, radius, 0.0);
+ set pattern (pattern type);
+ out ("WG" + text (+w) + "," + text (start angle) + "," + text (sweep angle) + ";");
+ graph off;
+ FI;
+
+END PROC cake shade;
+
+
+PROC cake frame (REAL CONST x offset, y offset, radius, start angle, sweep angle,
+ INT CONST line width) :
+
+
+ IF line width <> 0
+ THEN REAL CONST xs := real (x) + cos (start angle*pi/180.0) * real (w),
+ ys := real (y) + sin (start angle*pi/180.0) * real (w);
+ graph on (x offset, y offset, radius, 0.0);
+ out ("LW" + text (line width) + ";");
+ out ("MA"+ text (xs) + "," + text (ys) + ";");
+ out ("FA"+ text ( x) + "," + text ( y) + "," + text (sweep angle) + ";");
+ out ("MA"+ text ( x) + "," + text ( y) + ";");
+ graph off;
+ FI;
+
+END PROC cake frame;
+
+
+PROC graph on (REAL CONST x offset, y offset, width, height) :
+
+ x := x pos + x step conversion (x offset);
+ y := plot y size - (y pos + y step conversion (y offset));
+ w := x step conversion (width);
+ h := y step conversion (height);
+ out (""28"Aa");
+ out ("DF;");
+ out ("MA"+ text (x) + "," + text (y) + ";");
+
+ . plot y size : 3389 - y step conversion (1.0)
+
+END PROC graph on;
+
+PROC graph off :
+
+ out (""28"Az");
+
+END PROC graph off;
+
+
+PROC set pattern (INT CONST pattern type) :
+
+ out ("XX1;");
+ out (pattern);
+
+ . pattern :
+ SELECT pattern type OF
+ CASE 1 : "FT2,1,0;"
+ CASE 2 : "FT2,1,90;"
+ CASE 3 : "FT2,1,45;"
+ CASE 4 : "FT3,1,0;"
+ CASE 5 : "FT3,1,45;"
+ CASE 6 : "FT2,100,0;"
+ CASE 7 : "FT2,100,90;"
+ CASE 8 : "FT2,100,45;"
+ CASE 9 : "FT3,100,0;"
+ CASE 10 : "FT3,100,45;"
+ OTHERWISE : "FT1;"
+ END SELECT
+
+END PROC set pattern;
+
+
+END PACKET nec lc 08 box commands;
+
+
+
+#page#
+(******************************************************************)
+(*** ***)
+(*** Generierung des Printers ***)
+(*** ***)
+(******************************************************************)
+
+LET printer name = "printer.nec.lc-08";
+
+TEXT VAR fonttab name := "fonttab.nec.lc-08";
+
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+
+INT VAR pr channel;
+TEXT VAR buffer;
+
+command dialogue (TRUE);
+IF NOT multi user
+ THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL")
+FI;
+ask for print channel;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+command dialogue (TRUE);
+check on;
+.
+ ask for print channel :
+ line;
+ put ("gib Druckerkanal:");
+ get (pr channel);
+ do ("serverchannel(" + text (pr channel) + ")" ) ;
+ line;
+.
+ load font table :
+ IF NOT exists (fonttab name)
+ THEN REP line (2);
+ putline ("Bitte Archiv mit der Fonttabelle """ +
+ fonttab name + """ einlegen!");
+ line;
+ UNTIL yes ("Archiv eingelegt") PER;
+ reserve archive;
+ fetch (fonttab name, archive);
+ release (archive);
+ FI;
+ font table (fonttab name);
+ IF multi user
+ THEN command dialogue (FALSE);
+ do ("save(""" + font tab name + """,task(""configurator""))")
+ FI;
+ forget (fonttab name, quiet);
+
+ . reserve archive :
+ INT VAR p1, p2;
+ archive (" "31" ");
+ disable stop;
+ list (archive);
+ IF is error
+ THEN buffer := errormessage;
+ p1 := pos (buffer, """", 1 ) + 1;
+ p2 := pos (buffer, """", p1) - 1;
+ IF p1 > 0 AND p2 > 0
+ THEN clear error;
+ buffer := subtext (buffer, p1, p2);
+ archive (buffer);
+ FI;
+ FI;
+ enable stop;
+
+. generate printer spool :
+ eumel must advertise;
+ cursor (1, 12);
+ putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+ putline ("die Fonttabelle mit dem Kommando");
+ line;
+ putline (" font table (""" + font tab name + """)");
+ line;
+ putline ("eingestellt werden!!!");
+ line (4);
+ putline ("Generierung beendet, weiter mit 'SV'");
+ generate printer server;
+ do (buffer);
+
+. generate printer server :
+ buffer := "break (quiet);";
+ buffer CAT "spool manager (PROC printer);";
+ buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+ buffer CAT "PROC printer:";
+ buffer CAT " disable stop;";
+ buffer CAT " continue (server channel);";
+ buffer CAT " check error (error message);";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " REP forget (ds);";
+ buffer CAT " execute print;";
+ buffer CAT " IF is error AND online THEN put error; clear error; FI;";
+ buffer CAT " PER;";
+ buffer CAT "END PROC printer;";
+ buffer CAT "PROC execute print:";
+ buffer CAT " LET ack = 0, fetch code = 11, file type = 1003;";
+ buffer CAT " enable stop;";
+ buffer CAT " ds := nilspace;";
+ buffer CAT " call (father, fetch code, ds, reply);";
+ buffer CAT " IF reply = ack CAND type (ds) = file type";
+ buffer CAT " THEN file := sequential file (input, ds);";
+ buffer CAT " print (file,";
+ buffer CAT " PROC (INT CONST, INT VAR, INT VAR) open,";
+ buffer CAT " PROC (INT CONST, INT CONST) close,";
+ buffer CAT " PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC execute print;";
+ buffer CAT "PROC check error(TEXT CONST message):";
+ buffer CAT " IF is error";
+ buffer CAT " THEN clear error; rename myself (message);";
+ buffer CAT " IF is error THEN end(myself) FI;";
+ buffer CAT " pause (9000); end(myself);";
+ buffer CAT " FI;";
+ buffer CAT "END PROC check error;";
+
diff --git a/printer/laser/readme b/printer/laser/readme
new file mode 100644
index 0000000..019d75c
--- /dev/null
+++ b/printer/laser/readme
@@ -0,0 +1,155 @@
+Treiber-Installations-Programm für Laserdrucker 21. 2.1989
+
+
+1. Installations- und Gebrauchsanleitung
+
+Einrichten
+So wird das Treiber-Installationsprogramm eingerichtet:
+
+ Richten Sie die Task PRINTER als Sohn von SYSUR ein :
+
+ begin ("PRINTER", "SYSUR")
+
+ Geben Sie in der Task PRINTER nacheinander folgende Kommandos
+ ein, die Sie jeweils mit der ENTER-Taste bestätigen:
+
+ archive ("std.printer")
+ fetch("laser.inserter",archive)
+ insert ("laser.inserter")
+
+Das Programm wird dann insertiert.
+
+
+Menüsystem
+Das Installationsprogramm zeigt nun eine Liste von Druckerherstellern.
+Wählen Sie den Hersteller Ihres Druckers aus! Hiernach wird eine Liste
+der unterstützten Drucker dieses Herstellers gezeigt. Wählen Sie hier
+den passenden Typ aus!
+Das Installationsprogramm fragt nun nach der Art der Druckerschnittstelle.
+Die Druckerhardware muß wie hier angegeben konfiguriert sein, wenn sie
+mit dem ausgewählten Treiber betrieben werden soll.
+
+Das Installationsprogramm kann mit 'treiber einrichten' erneut aufgerufen
+werden. Die Druckerschnittstelle kann mit 'printer setup' nachträglich
+umkonfiguriert werden.
+
+2. Druckertreiber-Auswahl
+
+Verwendung nicht im Menü enthaltener Drucker
+Für den Fall, daß Sie genau Ihren Drucker im Menü nicht finden,
+müssen Sie herausfinden (Druckerhandbuch, -händler!),
+welchen Drucker Ihr Drucker emuliert oder welchem er ähnlich ist.
+(Die meisten Laserdrucker verfügen über eine HP-Laserjet Emulation).
+
+
+3. Steuerungsmöglichkeiten und Spezialfeatures
+
+Einige Treiber bieten bestimmte Einstellungsmöglichkeiten.
+Die Einstellungen können über
+- Steuerprozeduren
+- Materialanweisungen bzw.
+- direkte Druckeranweisungen
+vorgenommen werden.
+
+Steuerprozeduren
+setzen Einstellungen, die für alle Dokumente (Druckdateien) gelten
+sollen. Die Prozeduren müssen in der Druckspooltask (meist: "PRINTER")
+aufgerufen werden. Vor Aufruf der Prozeduren muß das Spoolkommando
+'stop spool' gegeben werden!
+
+
+
+PROC papersize (REAL CONST breite, länge)
+ Dient zur Einstellung der Größe der physikalisch beschreibbaren
+ Fläche.
+ Beispiel: papersize (21.0, 29.7)
+ (Standardeinstellung für DIN A4 Format)
+
+PROC papersize
+ Informationsprozedur
+
+Die Änderungen, die Sie in der Druckspooltask vorgenommen haben
+werden erst wirksam, nachdem das Spool-Kommando 'start spool' ge­
+geben und die Druckspooltask verlassen wurde.
+
+
+
+Materialanweisungen \#material("...")\#
+müssen in der Druckdatei vor dem ersten druckbaren Zeichen stehen und
+setzen Einstellungen für eine ganze Datei. (Materialanweisungen haben
+für die jeweilige Datei Vorrang vor den durch Steuerprozeduren einge­
+stellten Standardwerten. Diese werden durch die Materialanweisung aber
+nicht geändert.)
+
+Beispiel: \#material("landscape")\# oder \#material("quer")\#
+ Der Druckertreiber stellt sich auf Querdruck ein. Für das
+ Papierformat werden die
+ durch papersize eingestellten Werte vertauscht angenommen.
+ Es sollten nur Schrifttypen verwendet werden, die auch im
+ Landscape-Modus vorhanden sind.
+
+
+- Es darf in einer Datei nur eine Materialanweisung stehen! Sollen meh­
+ rere Einstellungen vorgenommen werden, müssen sie in einer Anweisung
+ erscheinen. Beispiel: \#material("quer;2")\#
+
+- Achten Sie bei Materialanweisungen
+ besonders auf korrekte Schreibweise! Es werden nur Kleinbuchstaben
+ berücksichtigt! Also: \#"quer"\# und keinesfalls \#"QUER"\#!!!
+
+- Bei Laserdruckern gebräuchliche Materialanweisungen sind:
+ - landscape (quer)
+ - manual
+ - tray
+
+direkte Druckeranweisungen \#"..."\#
+gelten ab der Position, an der sie in der Datei auftreten. Sie haben
+(sofern sie erlaubt sind,) Vorrang vor Standardeinstellungen und
+Materialeinstellungen.
+
+
+- Direkte Druckeranweisungen werden vom EUMEL-Drucker ignoriert und
+ nur vom Druckertreiber in eine Kommando-Sequenz umgesetzt. Es kann
+ daher vorkommen, daß (z.B. bei Spaltendruck) unerwartete Ergebnisse
+ erscheinen, weil der EUMEL-Drucker dann den Text in einer anderen
+ Reihenfolge an den Drucker sendet, als er in der Datei steht, die
+ mit dem direkten Druckerkommando gesetzte Modifikation aber (z.B.
+ für beide Spalten) unerwünscht erhalten bleibt. Direkte
+ Druckeranweisungen, die das Schriftformat verändern,
+ sollten grundsätzlich nicht gegeben werden.
+
+
+4. Spezialfeatures:
+
+Die Druckertreiber für die Drucker APPLE-Laserwriter und NEC LC-08
+verfügen über Anweisungen zum Zeichnen einer Linie, Box oder eines Kuchen-
+stücks, die als direkte Druckeranweisungen in ELAN-Syntax gegeben werden
+müssen.
+Folgende Anweisungen stehen zur Verfügung:
+
+PROC line (REAL CONST x offset, y offset, width, height, line width) :
+
+PROC x line (REAL CONST x offset, y offset, width, line width) :
+
+PROC y line (REAL CONST x offset, y offset, height, line width) :
+
+PROC box (REAL CONST x offset, y offset, width, height, line width, pattern):
+
+PROC box shade (REAL CONST x offset, y offset, width, height, pattern) :
+
+PROC box frame (REAL CONST x offset, y offset, width, height, line width) :
+
+PROC cake (REAL CONST x offset, y offset, radius, start angle, sweep angle,
+ line width, pattern) :
+
+PROC cake shade (REAL CONST x offset, y offset, radius, start angle,
+ sweep angle, pattern) :
+
+PROC cake frame (REAL CONST x offset, y offset, radius, start angle,
+ sweep angle, line width) :
+
+
+
+
+
+
diff --git a/prolog/calc b/prolog/calc
new file mode 100644
index 0000000..0ed11af
--- /dev/null
+++ b/prolog/calc
@@ -0,0 +1,32 @@
+{ CALC evaluates arithmetic expressions with store }
+
+calc:- eval ([], RS), write (result store), write (RS), nl.
+
+eval (SI, SO):-
+ read (CALC), nonvar (CALC), eval member (CALC, SI, SO).
+
+eval member (CALC, SI, SO):-
+ member (CALC, [stop,end,bye,eof]), SO=SI;
+ eval (CALC,I,SI,ST), write (I), eval (ST,SO);
+ write (error in), write (CALC), nl, eval (SI, SO).
+
+eval (I, I, S, S):- integer (I).
+eval (N, I, S, S):- atom (N), eval atom (N, I, S).
+
+eval atom (N, I, S):-
+ member (N=I, S);
+ write ("error: Cell"), write (N),
+ write("not found in store. 0 substituted."), nl, I=0.
+
+eval ( L+R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J+K.
+eval ( L-R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J-K.
+eval ( L*R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J*K.
+eval ( L/R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J/K.
+
+eval (N=O, I, SI, SO):-
+ atom (N), eval (O,I,SI,ST), eval repl (N,I,ST,SO).
+
+eval repl (N, I, [], [=(N,I)]).
+eval repl (N, I, [=(N,_)|S], [=(N,I)|S]).
+eval repl (N, I, [=(M,J)|SI], [=(M,J)|SO]):- eval repl (N, I, SI, SO).
+
diff --git a/prolog/family b/prolog/family
new file mode 100644
index 0000000..8419cc6
--- /dev/null
+++ b/prolog/family
@@ -0,0 +1,29 @@
+
+mann(jürgen). mann(detlef). mann (frank). mann (peter). mann(jochen).
+frau(gaby). frau(yvonne). frau(sinha). frau(rita). frau(viktoria).
+frau(adelheid).
+vater(gaby, peter). vater(yvonne, peter). vater(frank, peter).
+mutter(gaby, rita). mutter(yvonne, rita). mutter(frank, rita).
+mutter(rita,viktoria).
+vater(jürgen, heinz). mutter(jürgen, natalie).
+vater(kalle, heinz). mutter(kalle, natalie).
+mann(gaby, jürgen). mann(yvonne, detlef). mann(sinha,frank).
+mann(rita, peter). mann(adelheid, jochen).
+frau(X,Y) :- mann (Y,X).
+großmutter(X,Y):- mutter(X,H), mutter(H,Y); vater(X,H), mutter(H,Y).
+sohn(X,Y):- vater(Y,X), mann(Y); mutter(Y,X), mann(Y) .
+tochter(X,Y):- vater(Y,X), frau(Y); mutter(Y,X), frau(Y).
+geschwister(X,Y):-vater(X,A),vater(Y,A),mutter(X,B),mutter(Y,B),<>(X,Y).
+bruder(X,Y):- geschwister(X,Y), mann(Y).
+schwester(X,Y):- geschwister(X,Y), frau(Y).
+schwager(X,Y):- mann(X,Z), bruder(Z,Y); frau(X,Z), bruder(Z,Y).
+schwägerin(X,Y):-mann(X,Z),schwester(Z,Y);frau(X,Y),schwester(Z,Y).
+freund (X,Y):- mann(Y), mann(X), <>(X,Y);
+ mann(Y), frau(X), mann(Z,Y), <>(X,Z);
+ mann(Y), frau(X), !, mann(Z,Y), [];
+ mann(Y), frau(X).
+freundin (X,Y):- frau(Y), frau(X), <>(X,Y);
+ frau(Y), mann(X), mann(Y,Z), <>(X,Z);
+ frau(Y), mann(X), !, mann(Y,Z), [];
+ frau(Y), mann(X).
+
diff --git a/prolog/permute b/prolog/permute
new file mode 100644
index 0000000..54f8fee
--- /dev/null
+++ b/prolog/permute
@@ -0,0 +1,15 @@
+permute ([], []).
+permute ([E|X], Z):-
+ permute (X, Y), insert (E, Y, Z).
+insert (E, X, [E|X]).
+insert (E, [F|X], [F|Y]):-
+ insert (E, X, Y).
+marquise(RESULT):-
+ permute (["beautiful marquise",
+ "your beautiful eyes",
+ "make me",
+ "die",
+ "of love"
+ ],
+ RESULT).
+
diff --git a/prolog/prieks b/prolog/prieks
new file mode 100644
index 0000000..372ec9d
--- /dev/null
+++ b/prolog/prieks
@@ -0,0 +1,58 @@
+
+ist priek (bo priek).
+ist priek (ki priek).
+ist priek (bla priek).
+
+WER GNASELT WEN :- population (B),
+ member ([WEN, WER, _], B),
+ bedingungen (B).
+
+WER KNAUDERT WEN:- population (B),
+ member ([WER, _, WEN], B),
+ bedingungen (B).
+
+population (B):- sind prieks (U, V, W),
+ sind knauderarten (R, S, T),
+ B = [ [drausla puemfe, U, R],
+ [glessla puemfe, V, S],
+ [hapla puemfe, W, T] ].
+
+sind prieks (X,Y,Z):- ist priek (G),
+ ist priek (H), H<>G,
+ ist priek (I), I<>G, I<>H, !,
+ permute ([G,H,I], [X,Y,Z]).
+
+sind knauderarten (X,Y,Z):- ist knauderart (G),
+ ist knauderart (H), H<>G,
+ ist knauderart (I), I<>G, I<>H, !,
+ permute ([G,H,I],[X,Y,Z]).
+
+ist knauderart (an).
+ist knauderart (ab).
+ist knauderart (ueber).
+
+bedingungen (B):- not member ([hapla puemfe,ki priek,_],B) ,
+ not member ([hapla puemfe,_,ueber],B) ,
+ not member ([drausla puemfe,bo priek,_],B) ,
+ not member ([_,bo priek,ab],B) ,
+ noch ne bedingung (B) ,
+ weitere bedingungen (B) , !.
+
+weitere bedingungen (B):- not member([_,ki priek,ueber],B),
+ not member([_,bo priek,ueber],B)
+ ;
+ member([drausla puemfe,_,an],B).
+
+noch ne bedingung (B):- not member ([drausla puemfe,ki priek,_],B)
+ ;
+ not member ([glessla puemfe,_,ueber],B).
+
+permute ([], []).
+permute (X, [Y|Z]):- delete (Y ,X, E), permute (E, Z).
+delete (X, [X|Z], Z).
+delete (X, [Y|Z], [Y|E]):- delete (X, Z, E).
+member (X, [X|Z]).
+member (X, [Y|Z]):- member (X, Z).
+not member (X, []).
+not member (X, [Y|Z]):- X <> Y, not member (X,Z).
+
diff --git a/prolog/prolog b/prolog/prolog
new file mode 100644
index 0000000..7ac2e6a
--- /dev/null
+++ b/prolog/prolog
@@ -0,0 +1,2488 @@
+PACKET prolog (* Autor: P.Heyderhoff *)
+DEFINES (* Date: 03.07.1987 *)
+ prolog, prolog again:
+
+{ GLOBALS }
+
+LET { Stacksize parameter }
+ limit = 800;
+
+LET { nil-POINTER }
+ nil = 0;
+
+LET { bootstrap rules }
+ boot = """|"".""!"".""MOD"".""-"".""+"".""*"".""/"".bye.listing.
+call(X).write(X).writeq(X).read(X).get(X).get0(X).put(X).incr(X).
+assertz(X).asserta(X).retract(X).var(X).
+X IS Y.X=X.X<>Y.X<=Y.X==Y.X=..Y.clause(X,_).name(X,Y).
+arg(X,Y,Z).functor(X,Y,Z).elan(X).elan(X,Y)";
+
+LET { bootstrap symbols, see: boot }
+ cons=1, cut=2, mod=3, {TOKEN: minus=4, plus=5, times=6, slash=7}
+ bye=8, list=9, call=10, xpar=11,
+ writ=12, wriq=13, read=14, get=15, get0=16, put0=17,
+ incr=18, ass=19, assa=20, retr=21, vari=22,
+ is=23, ypar=24, dif=26, leq=27, eq=28, univ=29, clau=30, claupar=31,
+ nam=32, argi=33, zpar=34, func=35,
+ elan=36, build ins=33;
+
+LET { TOKENS }
+ stroke=1, exclamation=2, colon=3, minus=4, plus=5, times=6, slash=7,
+ underscore=8, less=9, equal=10, uneq=11, grt=12, eqeq=13,
+ eqdotdot=14, period=15, comma=17, semicolon=18,
+ open paren=19, close paren=20, open bracket=21, close bracket=22,
+ end of input=23, boldvar=24, number=25, identifier=26;
+
+LET { SYMBOLTYPES }
+ tag=1, bold=2, num=3, tex=4, operator=5, delimiter=6, end of file=7,
+ within com=8, within tex=9;
+
+INT CONST integer:= -1, var:= -2;
+
+LET TOKEN = INT;
+
+LET SYMBOLTYPE = INT;
+
+LET SYMBOL = INT;
+LET SYMBOLTABLE = THESAURUS;
+
+LET TERMS = INT;
+{ LET TERMSCELL = STRUCT (TERM first,
+ TERMS rest); }
+LET TERM = STRUCT (SYMBOL symbol,
+ TERMS arguments,
+ INT arity);
+
+LET CLAUSES = INT;
+{ LET CLAUSESCELL = STRUCT (TERMS first,
+ CLAUSES rest); }
+LET FRAME = INT;
+LET FRAMECELL = STRUCT (TERM call,
+ FRAME father,
+ TERMS subgoals, { remaining }
+ ENVIRONMENT environment,
+ EXPRESSIONS reset,
+ CLAUSES rest { potential rules },
+ FRAME level );
+
+LET ENVIRONMENT = INT;
+LET ENVIRONMENTCELL = STRUCT (SUBSTITUTION first,
+ ENVIRONMENT rest);
+LET SUBSTITUTION = STRUCT (TERM variable,
+ TERM substitute,
+ FRAME others);
+
+LET FRAMESTACK = STRUCT (FRAME frame, goalframe, removed goal,
+ INT last tp, last kp, last fp, last np);
+
+LET EXPRESSIONS = INT;
+
+LET EXPRESSION = STRUCT (TERM term,
+ FRAME index);
+
+TEXT VAR tcsymbol, tcarguments, tcarity, tcrest; INT VAR tp;
+
+TEXT VAR kcfirst, kcrest; INT VAR kp;
+
+ROW limit FRAMECELL VAR fc; INT VAR fp;
+
+ROW limit ENVIRONMENTCELL VAR nc; INT VAR np;
+
+ROW limit FRAMESTACK VAR fsc; INT VAR fsp;
+
+ROW limit EXPRESSION VAR ec; INT VAR ep;
+
+ROW limit CLAUSES VAR freec; INT VAR freep;
+
+SYMBOL VAR look ahead value;
+TEXT VAR look ahead symbol, ahead symbol;
+BOOL VAR look ahead empty, ahead empty;
+INT VAR look ahead token, ahead symboltype;
+
+SYMBOL VAR pattern;
+
+TERMS VAR ts;
+
+TERM VAR t, t2, t3;
+
+CLAUSES VAR k, kl, knowledge base, candidates;
+
+FRAME VAR root, cut level, res frame;
+
+SYMBOLTABLE VAR symboltable, reset symboltable;
+
+FILE VAR file;
+
+BOOL VAR from file, tracing, testing, found, quoting, free of errors, finish;
+
+INT VAR i, j, reset tp, reset kp, reset freep, anonym value,
+ inference level, inference count, rule count;
+
+TEXT VAR command;
+
+REAL VAR start time:= 0.0;
+
+PROC init globals:
+ tp := nil; kp:= nil;
+ tracing:= FALSE;
+ testing:= FALSE;
+ symboltable:= empty thesaurus;
+ reset symboltable:= symboltable;
+ reset tp:= nil;
+ reset kp:= nil;
+ reset freep:= nil;
+ knowledge base:= nil;
+ from file:= FALSE;
+ inference count:= 0;
+ tcsymbol:="";
+ tcarguments:="";
+ tcarity:="";
+ tcrest:="";
+ kcfirst:="";
+ kcrest:="";
+ quoting:= TRUE
+ENDPROC init globals;
+
+PROC init prooftree:
+ root := nil;
+ freep:= reset freep;
+ fp:= nil; fsp:= nil; np:= nil; ep:= nil; tp:= reset tp; kp:= reset kp;
+ symboltable:= reset symboltable;
+ free of errors:= TRUE;
+ candidates:= nil;
+ new (fp, root);
+ fc(root):= FRAMECELL:(t, nil, nil, nil, nil, nil, 0);
+ anonym value:= 0;
+ collect heap garbage;
+ finish:= FALSE
+ENDPROC init proof tree;
+
+PROC prolog (TEXT CONST knowledge):
+ line;
+ last param (knowledge);
+ init globals;
+ bootstrap;
+ IF exists (knowledge) THEN consult (knowledge) FI;
+ IF free of errors
+ THEN prolog again
+ FI;
+ last param (knowledge).
+
+ bootstrap:
+ TERMS VAR clauses:= nil;
+ init proof tree;
+ look ahead empty:= TRUE; ahead empty:= TRUE;
+ scan (boot);
+ WHILE look ahead <> end of input
+ REP read clause;
+ assertz (clauses);
+ clauses:= nil
+ PER;
+ reset tp:= tp;
+ reset kp:= kp;
+ reset symboltable:= symboltable.
+
+ read clause:
+ TERM VAR term;
+ read term (term);
+ IF look ahead = period
+ THEN remove token
+ FI;
+ insert term in clauses.
+
+ insert term in clauses:
+ TERMS VAR tmp;
+ new tp (tmp);
+ replace(tcsymbol,tmp,term.symbol);
+ replace(tcarguments,tmp,term.arguments);
+ replace(tcarity,tmp,term.arity);
+ replace(tcrest,tmp, clauses);
+ clauses:= tmp.
+
+ remove token:
+ look ahead empty:= TRUE.
+
+ENDPROC prolog;
+
+BOOL PROC prolog (TEXT CONST query, TEXT VAR answer):
+ disable stop;
+ init prooftree;
+ read goals;
+ BOOL VAR result:= NOT prove;
+ answer is value of last variable;
+ result .
+
+ read goals:
+ scan (query);
+ look ahead empty:= TRUE; ahead empty:= TRUE;
+ from file:= FALSE;
+ fc(root).subgoals:= nil;
+ read terms (fc(root).subgoals);
+ IF look ahead = period
+ THEN remove token
+ FI;
+ IF look ahead <> end of input
+ THEN syntax error ("unexpected characters after last goal")
+ FI.
+
+ answer is value of last variable:
+ IF fc(root).environment <> nil
+ THEN
+ value (nc(fc(root).environment).first.variable, t, root);
+ file:= sequential file (output, "$$");
+ sysout ("$$");
+ write term backward (t);
+ sysout ("");
+ input (file);
+ getline (file, answer);
+ forget ("$$", quiet)
+ ELSE answer:= ""
+ FI .
+
+ remove token:
+ look ahead empty:= TRUE.
+
+ENDPROC prolog;
+
+PROC prolog again:
+ disable stop;
+ lernsequenz auf taste legen ("q","bye"13"");
+ write (""13""10""5"?- ");
+ REP
+ init proof tree;
+ initiate read terms (fc(root).subgoals, "-");
+ read goals;
+ prove goals;
+ UNTIL finish
+ PER;
+ lernsequenz auf taste legen ("q","break"13"").
+
+ read goals:
+ IF is error
+ THEN c:= "?"
+ ELIF look ahead = open bracket
+ THEN remove token;
+ read consult list
+ ELSE read terms (fc(root).subgoals);
+ IF look ahead = period
+ THEN remove token
+ FI;
+ IF look ahead <> end of input
+ THEN syntax error ("unexpected characters after last goal")
+ FI
+ FI.
+
+ prove goals:
+ IF tracing THEN inference level:= 0; line FI;
+ inference count:= 0;
+ start time:= clock (0);
+ REP
+ IF c <> "?" CAND prove
+ THEN IF tracing THEN line FI;
+ write (" no"13""10""5"?- ");
+ LEAVE prove goals
+ ELSE IF tracing THEN inference level:= 0 FI;
+ get cursor (i,j); IF i > 1 THEN line FI;
+ IF is error
+ THEN put error; clear error; putline (""4""{cleop});
+ free of errors:= FALSE;
+ sysout (""); sysin ("");
+ putline ("type '?' to get explanations");
+ putline ("type ';' to try next alternative");
+ putline ("type any other key to stop")
+ ELSE write answers
+ FI;
+ get cursor (i, j);
+ write (""10""10""13""5"?- ");
+ getchar (c);
+ TEXT VAR c;
+ SELECT pos ("?;",c) OF
+ CASE 1: write ("?");
+ inform
+ CASE 2: write (""13""5""3""3"");
+ get cursor (j, k);
+ cursor (i, k);
+ putline (";");
+ OTHERWISE IF c >= " " COR c = ""27"" THEN push (c) FI;
+ LEAVE prove goals
+ END SELECT;
+ IF tracing THEN line FI;
+ IF is error
+ THEN put error; clear error; putline (""4""{cleop})
+ FI
+ FI
+ PER.
+
+ write answers:
+ write (" ");
+ IF fc(root).environment = nil
+ THEN IF free of errors THEN put ("yes") ELSE put ("no") FI
+ ELSE write environment list (root)
+ FI.
+
+ remove token:
+ look ahead empty:= TRUE.
+
+ENDPROC prolog again;
+
+PROC prolog: prolog (last param) ENDPROC prolog;
+
+BOOL PROC prove:
+ enable stop;
+ initialize prove;
+ find potential candidates.
+
+ handle remaining subgoals:
+ { all subgoals to the left are solved }
+ IF subgoals remain
+ THEN get candidates
+ ELSE LEAVE prove WITH FALSE
+ FI.
+
+ find potential candidates:
+ REP try one candidate PER; TRUE.
+
+ try one candidate:
+ { all candidates tried do not unify with the current goal }
+ IF head of one candidate unifies with the current goal
+ THEN push frame;
+ handle remaining subgoals
+ ELSE backtrack to the parent of the current goal
+ FI.
+
+ backtrack to the parent of the current goal:
+ { none of the candidates unify with the current goal }
+ IF prooftree exhausted
+ THEN LEAVE prove WITH TRUE
+ ELSE pop frame
+ FI.
+
+ prooftree exhausted: fsp = 1.
+
+ initialize prove:
+ TERM VAR curr call;
+ FRAME VAR curr frame, top frame;
+ EXPRESSIONS VAR last ep;
+ IF fsp = nil
+ THEN curr frame:= root;
+ push frame;
+ handle remaining subgoals
+ ELSE IF tracing THEN line FI;
+ backtrack to the parent of the current goal
+ FI.
+
+ head of one candidate unifies with the current goal:
+ son { curr frame is the resulting next son }.
+
+ subgoals remain:
+ select frame {(curr frame, curr call)}.
+
+ push frame:
+ fsp INCR 1;
+ fsc(fsp).frame:= curr frame;
+ fsc(fsp).goalframe:= nil;
+ fsc(fsp).last tp:= tp;
+ fsc(fsp).last kp:= kp;
+ fsc(fsp).last fp:= fp;
+ fsc(fsp).last np:= np.
+
+ pop frame:
+ { fsp <> nil }
+ top frame:= fsc(fsp).frame;
+ curr frame:= fc(top frame).father;
+ reinsert current call as subgoal;
+ curr call:= fc(top frame).call;
+ candidates:= fc(top frame).rest;
+ cut level:= fc(top frame).level;
+ tp:= fsc(fsp).last tp;
+ kp:= fsc(fsp).last kp;
+ fp:= fsc(fsp).last fp;
+ np:= fsc(fsp).last np;
+ fsp DECR 1;
+ IF tracing CAND inference level > 0 CAND NOT testing
+ THEN write (""13""5""3""5""); inference level DECR 1
+ FI;
+ undo bindings (fc(top frame).reset).
+
+ reinsert current call as subgoal:
+ IF fsc(fsp).goalframe <> nil
+ THEN fc(fsc(fsp).goalframe).subgoals:= fsc(fsp).removed goal
+ FI.
+
+ select frame:
+ REP
+ IF next call
+ THEN LEAVE select frame WITH TRUE
+ FI;
+ curr frame:= fc(curr frame).father
+ UNTIL curr frame = nil PER;
+ FALSE.
+
+ next call:
+ ts:= fc(curr frame).subgoals;
+ IF ts = nil
+ THEN FALSE
+ ELSE remove subgoals; TRUE
+ FI.
+
+ remove subgoals:
+ curr call:= TERM:(tcsymbolISUBts, tcargumentsISUBts, tcarityISUBts);
+ fc(curr frame).subgoals:= (tcrestISUB(ts)) ;
+ fsc(fsp).goalframe:= curr frame;
+ fsc(fsp).removed goal:= ts.
+
+ get candidates:
+ initialize clauses;
+ WHILE more knowledge
+ REP find next clause candidate in knowledge base PER
+ { candidates = a list of clauses which may be unifiable with curr call } .
+
+ initialize clauses:
+ fc(curr frame).level:= cut level;
+ cut level:= curr frame;
+ IF curr call.arity = var
+ THEN IF bound (curr call, curr frame, curr call, ts) THEN FI;
+ IF curr call.arity = var
+ THEN take goal itself as candidate; LEAVE get candidates
+ FI
+ FI;
+ k:= knowledge base;
+ found:= FALSE;
+ candidates:= nil.
+
+ take goal itself as candidate:
+ new kp (candidates);
+ replace (kcfirst, candidates, goal itself);
+ replace (kcrest, candidates, nil).
+
+ goal itself:
+ new tp (ts);
+ replace(tcsymbol,ts,curr call.symbol);
+ replace(tcarguments,ts, curr call.arguments);
+ replace(tcarity,ts, curr call.arity);
+ replace(tcrest,ts, nil);
+ ts.
+
+ find next clause candidate in knowledge base:
+ IF (tcsymbolISUB((kcfirstISUB(k)) )) = curr call.symbol
+ THEN found:= TRUE;
+ IF (tcarityISUB((kcfirstISUB(k)) )) = curr call.arity
+ THEN insert clause in candidates
+ FI
+ ELIF found
+ THEN LEAVE get candidates
+ FI;
+ k:= (kcrestISUB(k)) .
+
+ more knowledge: k <> nil.
+
+ insert clause in candidates:
+ kl:= candidates;
+ new kp (candidates);
+ replace(kcfirst,candidates,kcfirstISUBk);
+ replace(kcrest, candidates, kl).
+
+ son:
+ { If rules has n sons, then this refinement will return TRUE the first
+ n times, it is called and FALSE forever after.
+ IF son then curr frame has become a frame for the next son.
+ So this refinement helps to construct the prooftree.
+ }
+
+ IF candidates = nil
+ THEN FALSE
+ ELSE create next son
+ FI.
+
+ create next son:
+ initialize son;
+ REP try to unify curr call with candidates
+ UNTIL candidates exhausted PER;
+ { not unified }
+ forget son.
+
+ initialize son:
+ last ep:= ep;
+ new (fp, res frame);
+ fc(res frame).environment:= nil.
+
+ try to unify curr call with candidates:
+ k:= (kcfirstISUB(candidates)) ;
+ IF
+ unify (curr call,
+ curr frame,
+ TERM:(tcsymbolISUBk, tcargumentsISUBk, tcarityISUBk),
+ res frame)
+ THEN
+ IF tracing THEN trace unification results FI;
+ apply rule;
+ fill result frame
+ ELSE remove curr call from candidates
+ FI.
+
+ candidates exhausted: candidates = nil.
+
+ forget son:
+ fp DECR 1; FALSE.
+
+ fill result frame:
+ ts:= (kcfirstISUB(candidates)) ;
+ fc(res frame):= FRAMECELL:(curr call,
+ curr frame,
+ tcrestISUBts,
+ fc(res frame).environment,
+ last ep,
+ (kcrestISUB(candidates)) ,
+ cut level);
+ curr frame:= res frame;
+ LEAVE son WITH TRUE.
+
+ remove curr call from candidates:
+ candidates:= (kcrestISUB(candidates)) ;
+ LEAVE try to unify curr call with candidates.
+
+ apply rule:
+ SELECT curr call.symbol OF
+ CASE cons: {cons, to construct lists, see PROC unify}
+ CASE cut: fc(res frame):= FRAMECELL:(curr call, curr frame, nil,
+ fc(res frame).environment, last ep, nil, cut level);
+ curr frame:= res frame;
+ FOR ts FROM fp DOWNTO cut level
+ REP fc(ts).rest:= nil PER;
+ LEAVE son WITH TRUE
+ CASE bye: IF curr call.arity = 0
+ THEN push (""13"");
+ finish:= TRUE
+ FI
+ CASE list: IF curr call.arity = 0 COR curr call.arity = 1
+ THEN found:= TRUE;
+ IF curr call.arity = 0
+ THEN pattern:= cut
+ ELSE value (argfirst, t, curr frame);
+ pattern:= t.symbol
+ FI;
+ write knowledgebase (knowledge base)
+ FI
+ CASE call: undo bindings (last ep);
+ new tp (ts);
+ replace(tcrest,ts, fc(curr frame).subgoals);
+ fc(curr frame).subgoals:= ts;
+ value (argfirst, t, curr frame);
+ t.arguments:= revers (t.arguments);
+ replace(tcsymbol,ts, t.symbol);
+ replace(tcarguments,ts, t.arguments);
+ replace(tcarity,ts, t.arity);
+ LEAVE son WITH TRUE
+ CASE xpar: {X parameter of call}
+ CASE writ: IF curr call.arity = 1
+ THEN value (argfirst, t, curr frame);
+ quoting:= FALSE;
+ write term backward (t); write (" ");
+ quoting:= TRUE
+ FI
+ CASE wriq: IF curr call.arity = 1
+ THEN value (argfirst, t, curr frame);
+ write term backward (t); write (" ")
+ FI
+ CASE read: IF curr call.arity <> 1
+ THEN
+ ELIF argfirst.arity = var
+ THEN initiate read terms (ts,
+ name (symboltable,argfirst.symbol));
+ read term (t);
+ nc(fc(curr frame).environment).first.substitute:= t
+ ELSE syntax error ("read parameter must be variable")
+ FI
+ CASE get0, get:
+ IF curr call.arity <> 1
+ THEN
+ ELIF argfirst.arity = var
+ THEN getchar (command);
+ WHILE curr call.symbol = get
+ CAND code(command) < 32
+ REP getchar (command) PER;
+ t.arity:= integer;
+ t.arguments:= nil;
+ t.symbol:= code (command);
+ nc(fc(curr frame).environment).first.substitute:= t
+ ELSE syntax error ("get parameter must be variable")
+ FI
+ CASE put0: value (argfirst, t, curr frame);
+ IF curr call.arity = 1 CAND t.arity = integer
+ THEN write (code (t.symbol))
+ FI
+ CASE incr: IF curr call.arity = 1
+ THEN
+ value(argfirst, t, curr frame);
+ t.symbol INCR 1;
+ IF t.arity = integer
+ CAND argfirst.arity = var
+ THEN k:= fc(curr frame).environment;
+ nc(k).first.substitute:= t;
+ ELSE syntax error ("integer variable expected")
+ FI FI
+ CASE ass: IF curr call.arity = 1
+ THEN value (argfirst,t,currframe);
+ IF t.symbol = nil
+ CAND t.arguments > nil
+ THEN assertz (t.arguments);
+ IF free of errors
+ THEN reset tp:= tp;
+ reset kp:= kp;
+ reset symboltable:= symboltable
+ FI
+ ELSE syntax error ("parameter must be a list")
+ FI FI
+ CASE assa: IF curr call.arity = 1
+ THEN value (argfirst,t,currframe);
+ IF t.symbol = nil
+ CAND t.arguments > nil
+ THEN asserta (t.arguments);
+ IF free of errors
+ THEN reset tp:= tp;
+ reset kp:= kp;
+ reset symboltable:= symboltable
+ FI
+ ELSE syntax error ("parameter must be a list")
+ FI FI
+ CASE retr: IF curr call.arity = 1
+ THEN value (argfirst,t,currframe);
+ IF t.symbol = nil
+ CAND t.arguments > nil
+ THEN i:= rule count;
+ retract (t.arguments);
+ IF i <> rule count
+ THEN remove curr call from candidates
+ FI
+ ELSE syntax error ("parameter must be a list")
+ FI FI
+ CASE vari: IF curr call.arity = 1
+ THEN value (argfirst, t, curr frame);
+ IF t.arity <> var
+ THEN remove curr call from candidates
+ FI
+ FI
+ CASE is: IF curr call.arity = 2
+ THEN disable stop;
+ t.symbol:= arith (TERM:(tcsymbolISUBargrest,
+ tcargumentsISUBargrest,
+ tcarityISUBargrest),
+ curr frame);
+ IF is error THEN put error; clear error FI;
+ enable stop;
+ t.arity := integer;
+ t.arguments:= nil;
+ IF unify (argfirst, curr frame, t, curr frame)
+ THEN LEAVE apply rule
+ FI FI;
+ remove curr call from candidates
+ CASE ypar: {Y parameter of is}
+ CASE dif: IF curr call.arity = 2 CAND
+ unify (argfirst,
+ curr frame,
+ TERM:(tcsymbolISUBargrest,
+ tcargumentsISUBargrest,
+ tcarityISUBargrest),
+ curr frame)
+ THEN remove curr call from candidates
+ FI
+ CASE leq: IF curr call.arity = 2
+ THEN get operands;
+ IF t.arity = integer
+ THEN IF t.symbol <= t2.symbol
+ THEN LEAVE apply rule
+ FI
+ ELIF name (symboltable, t.symbol) <=
+ name (symboltable, t2.symbol)
+ THEN LEAVE apply rule
+ FI FI;
+ remove curr call from candidates
+ CASE eq: IF curr call.arity = 2
+ THEN get operands;
+ IF NOT ( t = t2 )
+ THEN remove curr call from candidates
+ FI FI
+ CASE univ: IF curr call.arity = 2
+ CAND np > fsc(fsp).last np
+ THEN
+ get operands;
+ IF t2.arity = var CAND t.arity >= 0
+ THEN new tp (ts);
+ replace (tcsymbol,ts,t.symbol);
+ replace (tcarguments, ts, nil);
+ replace (tcarity,ts,0);
+ replace (tcrest,ts,revers(t.arguments));
+ nc(np).first.substitute.arguments:= ts;
+ nc(np).first.substitute.symbol:= nil;
+ nc(np).first.substitute.arity:= t.arity + 1
+ ELIF t.arity = var CAND t2.arity > 0
+ CAND t2.symbol <= cons
+ THEN np DECR 1;
+ t2. arguments:= revers(t2.arguments);
+ nc(np).first.substitute.symbol:=
+ tcsymbol ISUB t2.arguments;
+ nc(np).first.substitute.arguments:=
+ tcrest ISUB t2.arguments;
+ nc(np).first.substitute.arity:= t2.arity - 1;
+ np INCR 1
+ ELSE syntax error ("wrong parameter after =..")
+ FI FI
+ CASE clau: get operands;
+ IF curr call.arity = 2
+ THEN
+ IF t.arity < 0
+ THEN syntax error ("clause with wrong parameter")
+ ELSE find clause;
+ k:= tcrest ISUB (kcfirstISUBk);
+ t3.symbol:= nil;
+ t3.arguments:= k;
+ t3.arity:= no of terms (k);
+ IF NOT unify (t2, res frame,
+ t3, curr frame)
+ THEN remove curr call from candidates
+ FI
+ FI
+ FI
+ CASE claupar: { anonymous parameter of clause }
+ CASE nam: IF curr call.arity = 2
+ THEN get operands;
+ IF t.arity = var
+ CAND t2.symbol = nil
+ THEN command:= "";
+ k:= t2.arguments;
+ REP command:= code (tcsymbolISUBk) + command;
+ k:= tcrestISUBk
+ UNTIL k <= nil PER;
+ t.symbol:= link (symboltable, command);
+ IF t.symbol = 0
+ THEN insert (symboltable, command, t.symbol);
+ FI;
+ t.arity:= 0;
+ t.arguments:= nil;
+ nc(fc(curr frame).environment).first.substitute:= t
+ ELIF t2.arity = var
+ CAND t.arity = 0
+ THEN command:= name (symboltable, t.symbol);
+ ts:= nil;
+ FOR k FROM 1 UPTO length(command)
+ REP new tp (i);
+ IF ts = nil
+ THEN ts:= i
+ ELSE replace (tcrest, j, i)
+ FI;
+ j:= i;
+ replace (tcrest, i, nil);
+ replace (tcarity, i, integer);
+ replace (tcarguments, i, nil);
+ replace (tcsymbol, i, code (command SUB k))
+ PER;
+ t3.arity:= length(command);
+ t3.arguments:= ts;
+ t3.symbol:= nil;
+ IF unify (t2, res frame, t3, curr frame) THEN FI
+ ELSE syntax error ("name insufficient parameters")
+ FI FI
+ CASE argi: get operands;
+ IF curr call.arity = 3
+ THEN k:= argrest;
+ value (TERM:(tcsymbolISUB(tcrestISUB(k)),
+ tcargumentsISUB(tcrestISUB(k)),
+ tcarityISUB(tcrestISUB(k))),
+ t3,
+ curr frame);
+ IF t.arity <> integer COR t2.arity <= 0
+ COR t.symbol <= 0 COR t.symbol > t2.arity
+ THEN syntax error ("arg with wrong parameter")
+ ELSE
+ FOR k FROM t2.arity DOWNTO ( t.symbol + 1)
+ REP IF t2.arguments <= nil
+ THEN syntax error ("out of range");
+ LEAVE apply rule
+ FI;
+ t2.arguments:= tcrestISUB(t2.arguments)
+ PER;
+ IF t3.arity = var
+ THEN nc(fc(curr frame).environment).first.substitute
+ := TERM:(tcsymbolISUBt2.arguments,
+ tcargumentsISUBt2.arguments,
+ tcarityISUBt2.arguments)
+ ELIF NOT unify (TERM:(tcsymbolISUBt2.arguments,
+ tcargumentsISUBt2.arguments,
+ tcarityISUBt2.arguments),
+ curr frame,
+ t3,
+ curr frame)
+ THEN remove curr call from candidates
+ FI
+ FI
+ FI
+ CASE zpar: {z parameter of arg}
+ CASE func: IF curr call.arity = 3
+ THEN
+ get operands;
+ k:= argrest;
+ value (TERM:(tcsymbolISUB(tcrestISUB(k)),
+ tcargumentsISUB(tcrestISUB(k)),
+ tcarityISUB(tcrestISUB(k))),
+ t3,
+ curr frame);
+ IF t2.arity = var
+ THEN IF t3.arity = var
+ THEN
+ t2.symbol:= argfirst.symbol;
+ t2.arity := 0;
+ nc(nc(fc(curr frame).environment).rest).first.
+ substitute:= t2;
+ k:= tcrestISUB(k);
+ t3.symbol:= argfirst.arity;
+ t3.arity := integer;
+ nc(fc(curr frame).environment).first.
+ substitute:= t3
+ ELIF t3.arity = integer
+ CAND t.arity = t3.symbol
+ THEN t.arity:= 0;
+ t.arguments:= nil;
+ nc(fc(curr frame).environment).first.
+ substitute:= t
+ ELSE remove curr call from candidates
+ FI
+ ELIF ( t.arity = var)
+ CAND (t2.arity = 0)
+ CAND (t3.arity = integer)
+ THEN t2.arity:= t3.symbol;
+ FOR k FROM 1 UPTO t3.symbol
+ REP new tp (ts);
+ replace (tcarity, ts, var);
+ anonym value DECR 1;
+ replace (tcsymbol, ts, anonym value);
+ replace (tcarguments, ts, nil);
+ replace (tcrest, ts, t2.arguments);
+ t2.arguments:= ts
+ PER;
+ nc(fc(curr frame).environment).first.
+ substitute:= t2
+ ELIF t2.arity <= 0
+ THEN IF t.symbol = t2.symbol
+ THEN IF t.arity = t3.symbol
+ CAND t3.arity = integer
+ THEN
+ ELIF t3.arity = var
+ THEN t3.arity := integer;
+ t3.symbol:= t.arity;
+ nc(fc(curr frame).environment).first.
+ substitute:= t3
+ ELSE remove curr call from candidates
+ FI
+ ELSE remove curr call from candidates
+ FI
+ ELSE syntax error ("wrong functor parameters")
+ FI FI
+ CASE elan: disable stop;
+ lernsequenz auf taste legen ("q","break"13"");
+ SELECT
+ pos("consult,reconsult,sysout,sysin,forget,trace,line,abolish,"
+ ,name (symboltable, argfirst.symbol) + ",") OF
+ CASE 01: consult (arg1)
+ CASE 09: reconsult (arg1)
+ CASE 19: sysout (arg1)
+ CASE 26: sysin (arg1)
+ CASE 32: forget (arg1, quiet)
+ CASE 39: trace (arg1)
+ CASE 45: line
+ CASE 50: value (TERM:(tcsymbolISUBargrest,
+ tcargumentsISUBargrest,
+ tcarityISUBargrest),
+ t,
+ curr frame);
+ abolish (t.symbol)
+ OTHERWISE do (elan command)
+ ENDSELECT;
+ lernsequenz auf taste legen ("q","bye"13"");
+ IF is error THEN put error; clear error FI;
+ enable stop
+ END SELECT.
+
+ get operands:
+ value (argfirst, t, curr frame);
+ value (TERM:(tcsymbolISUBargrest,
+ tcargumentsISUBargrest,
+ tcarityISUBargrest),
+ t2,
+ curr frame).
+
+ argfirst:TERM:(tcsymbolISUBcurr call.arguments,
+ tcargumentsISUBcurr call.arguments,
+ tcarityISUBcurr call.arguments).
+
+ argrest: tcrestISUBcurr call.arguments.
+
+ arg1: value (TERM:(tcsymbolISUBargrest,
+ tcargumentsISUBargrest,
+ tcarityISUBargrest),
+ t,
+ curr frame);
+ name(symboltable, t.symbol).
+
+find clause:
+ k:= knowledgebase;
+ WHILE k <> nil
+ REP
+ ts:= kcfirstISUBk;
+ IF TERM:(tcsymbolISUBts,tcargumentsISUBts,tcarityISUBts) = t
+ THEN LEAVE find clause
+ FI;
+ k:= kcrestISUBk
+ PER;
+ remove curr call from candidates;
+ LEAVE apply rule.
+
+ elan command:
+ command:= "";
+ ts:= curr call.arguments;
+ WHILE ts <> nil
+ REP value (TERM:(tcsymbolISUBts,
+ tcargumentsISUBts,
+ tcarityISUBts),
+ t,
+ curr frame);
+ command CAT name (symboltable, t.symbol);
+ found:= ts = curr call.arguments;
+ ts:= tcrestISUB(ts);
+ IF found
+ THEN IF ts > nil THEN command CAT "(""" FI
+ ELIF ts = nil
+ THEN command CAT """)"
+ ELSE command CAT ""","""
+ FI
+ PER;
+ command.
+
+ trace unification results:
+ inference level INCR 1;
+ write term (curr call); write ("=");
+ value (TERM:(tcsymbolISUB(kcfirstISUB(candidates)) ,
+ tcargumentsISUB(kcfirstISUB(candidates)) ,
+ tcarityISUB(kcfirstISUB(candidates)) ), t, res frame);
+ write term backward (t);
+ IF testing
+ THEN ts:= ep;
+ IF ts > last ep THEN write (" with ") FI;
+ list expressions
+ FI;
+ line.
+
+ list expressions:
+ WHILE ts > last ep
+ REP k:= fc(ec(ts).index).environment;
+ WHILE nc(k).first.variable.symbol <> ec(ts).term.symbol
+ REP k:= nc(k).rest PER;
+ write term (ec(ts).term); write ("=");
+ write term (nc(k).first.substitute); write (" ");
+ ts DECR 1
+ PER.
+
+ENDPROC prove;
+
+BOOL PROC unify (TERM CONST t1, FRAME CONST f1,
+ TERM CONST t2, FRAME CONST f2):
+
+ { Unifies the expressions <t1,f1^.environment> and <t2,f2^.environment>,
+ If unification succeeds, both environments are updated. }
+
+{}{inference count INCR 1;}
+ IF f1 = f2 CAND t1 = t2
+ THEN TRUE
+ ELIF t1.arity = var
+ THEN TERM VAR t;
+ FRAME VAR f;
+ IF bound (t1, f1, t, f)
+ THEN unify (t, f, t2, f2)
+ { ELIF occurs (t1, f1, t2, f2) THEN FALSE }
+ ELSE bind expression 1;
+ push expression 1;
+ TRUE
+ FI
+ ELIF t2.arity = var
+ THEN IF bound (t2, f2, t, f)
+ THEN unify (t, f, t1, f1)
+ { ELIF occurs (t2, f2, t1, f1) THEN FALSE }
+ ELSE bind expression 2;
+ push expression 2;
+ TRUE
+ FI
+ ELIF t1.symbol = t2.symbol
+ CAND t1.arity = t2.arity
+ THEN constant or compound term
+ ELIF t1.symbol = cons CAND t2.symbol = nil
+ CAND t1.arity = 2 CAND t2.arguments > nil
+ CAND unify (TERM:(tcsymbolISUBt1.arguments,
+ tcargumentsISUBt1.arguments,
+ tcarityISUBt1.arguments),
+ f1,
+ TERM:(tcsymbolISUBt2.arguments,
+ tcargumentsISUBt2.arguments,
+ tcarityISUBt2.arguments),
+ f2)
+ THEN construct list 1
+ ELIF t2.symbol = cons CAND t1.symbol = nil
+ CAND t2.arity = 2 CAND t1.arguments > nil
+ CAND unify (TERM:(tcsymbolISUBt2.arguments,
+ tcargumentsISUBt2.arguments,
+ tcarityISUBt2.arguments),
+ f2,
+ TERM:(tcsymbolISUBt1.arguments,
+ tcargumentsISUBt1.arguments,
+ tcarityISUBt1.arguments),
+ f1)
+ THEN construct list 2
+ ELSE FALSE
+ FI.
+
+constant or compound term:
+ { arguments of t1 and t2 are properly instantiated by the parser }
+ EXPRESSIONS VAR last ep:= ep;
+ TERMS VAR x:= t1.arguments, y:= t2.arguments;
+ WHILE x <> nil
+ REP IF unify (TERM:(tcsymbolISUBx, tcargumentsISUBx, tcarityISUBx),
+ f1,
+ TERM:(tcsymbolISUBy, tcargumentsISUBy, tcarityISUBy),
+ f2)
+ THEN x:= tcrestISUB(x);
+ y:= tcrestISUB(y)
+ ELSE undo bindings (last ep);
+ LEAVE unify WITH FALSE
+ FI
+ PER;
+ TRUE.
+
+ construct list 1:
+ last ep:= ep;
+ IF t2.symbol = cons
+ THEN TERM VAR tail:= TERM:(tcsymbolISUB(tcrestISUB(t2.arguments)),
+ tcargumentsISUB(tcrestISUB(t2.arguments)),
+ tcarityISUB(tcrestISUB(t2.arguments)));
+ ELSE tail:= TERM: (nil, (tcrestISUB(t2.arguments)) ,
+ no of terms (t2.arguments) - 1);
+ FI;
+ IF bound (TERM:(tcsymbolISUB(tcrestISUB(t1.arguments)) ,
+ tcargumentsISUB(tcrestISUB(t1.arguments)) ,
+ tcarityISUB(tcrestISUB(t1.arguments)) ),
+ f1,
+ t,
+ f)
+ THEN IF unify (t, f, tail, f2)
+ THEN TRUE
+ ELSE undo bindings (last ep); FALSE
+ FI
+ ELSE bind tail 1;
+ push tail 1;
+ TRUE
+ FI.
+
+ construct list 2:
+ last ep:= ep;
+ IF t1.symbol = cons
+ THEN tail:= TERM:(tcsymbolISUB(tcrestISUB(t1.arguments)) ,
+ tcargumentsISUB(tcrestISUB(t1.arguments)) ,
+ tcarityISUB(tcrestISUB(t1.arguments)) );
+ ELSE tail:= TERM: (nil, tcrestISUB(t1.arguments),
+ no of terms (t1.arguments) - 1);
+ FI;
+ IF bound (TERM:(tcsymbolISUB(tcrestISUB(t2.arguments)) ,
+ tcargumentsISUB(tcrestISUB(t2.arguments)) ,
+ tcarityISUB(tcrestISUB(t2.arguments)) ),
+ f2,
+ t,
+ f)
+ THEN IF unify (t, f, tail, f1)
+ THEN TRUE
+ ELSE undo bindings (last ep); FALSE
+ FI
+ ELSE bind tail 2;
+ push tail 2;
+ TRUE
+ FI.
+
+ bind expression 1:
+ { bind the expression <t1, f1> to <t2, f2> in the environment <f1> }
+ new environment n;
+ nc(n).first:= SUBSTITUTION:(t1, t2, f2);
+ nc(n).rest :=fc(f1).environment;
+ fc(f1).environment:= n.
+
+ bind expression 2:
+ new environment n;
+ nc(n).first:= SUBSTITUTION:(t2, t1, f1);
+ nc(n).rest :=fc(f2).environment;
+ fc(f2).environment:= n.
+
+ bind tail 1:
+ new environment n;
+ nc(n).first:= SUBSTITUTION:(
+ TERM:(tcsymbolISUB(tcrestISUB(t1.arguments)),
+ tcargumentsISUB(tcrestISUB(t1.arguments)) ,
+ tcarityISUB(tcrestISUB(t1.arguments)) ),
+ tail,
+ f2);
+ nc(n).rest :=fc(f1).environment;
+ fc(f1).environment:= n.
+
+ bind tail 2:
+ new environment n;
+ nc(n).first:= SUBSTITUTION:(
+ TERM:(tcsymbolISUB(tcrestISUB(t2.arguments)) ,
+ tcargumentsISUB(tcrestISUB(t2.arguments)) ,
+ tcarityISUB(tcrestISUB(t2.arguments)) ),
+ tail,
+ f1);
+ nc(n).rest :=fc(f2).environment;
+ fc(f2).environment:= n.
+
+ push expression 1:
+ ep INCR 1;
+ ec(ep):= EXPRESSION:(t1, f1).
+
+ push expression 2:
+ ep INCR 1;
+ ec(ep):= EXPRESSION:(t2, f2).
+
+ push tail 1:
+ ep INCR 1;
+ ec(ep):= EXPRESSION:(TERM:(tcsymbolISUB(tcrestISUB(t1.arguments)) ,
+ tcargumentsISUB(tcrestISUB(t1.arguments)) ,
+ tcarityISUB(tcrestISUB(t1.arguments)) ),
+ f1).
+
+ push tail 2:
+ ep INCR 1;
+ ec(ep):= EXPRESSION:(TERM:(tcsymbolISUB(tcrestISUB(t2.arguments)) ,
+ tcargumentsISUB(tcrestISUB(t2.arguments)) ,
+ tcarityISUB(tcrestISUB(t2.arguments)) ),
+ f2).
+
+ new environment n:
+ ENVIRONMENT VAR n;
+ IF np = limit THEN pegeloverflow ELSE np INCR 1; n:= np FI
+ENDPROC unify;
+
+BOOL OP = (TERM CONST t1, t2): { INLINE; }
+ { Two terms are equal iff their printed representations are
+ indistinguishable. Don't confuse with equal expressions. }
+
+ IF ( t1.symbol = t2.symbol )
+ CAND ( t1.arity = t2.arity )
+ THEN IF t1.arguments = 0
+ THEN terms are variables or constants
+ ELSE terms are compound
+ FI
+ ELSE FALSE
+ FI.
+
+ terms are variables or constants: TRUE.
+
+ terms are compound:
+ TERMS VAR x:= t1.arguments,
+ y:= t2.arguments;
+ WHILE x <> nil
+ REP IF recursive equal (TERM:(tcsymbolISUBx,
+ tcargumentsISUBx,
+ tcarityISUBx),
+ TERM:(tcsymbolISUBy,
+ tcargumentsISUBy,
+ tcarityISUBy))
+ THEN x:= tcrestISUB(x);
+ y:= tcrestISUB(y)
+ ELSE LEAVE = WITH FALSE
+ FI
+ PER; TRUE.
+ENDOP =;
+
+BOOL PROC recursive equal (TERM CONST t1, t2): t1=t2
+ENDPROC recursive equal;
+
+PROC undo bindings (EXPRESSIONS CONST last ep):
+ { Remove the binding for each of the expressions }
+ WHILE ep > last ep
+ REP remove matching substitutions;
+ remove expression
+ PER.
+
+ remove matching substitutions:
+ { with variable equal to term t from environment env }
+ TERM VAR t:= ec(ep).term;
+ ENVIRONMENT VAR n:= env, last:= nil;
+ WHILE n <> nil
+ REP IF nc(n).first.variable.symbol = t.symbol
+ THEN forget n
+ ELSE last:= n
+ FI;
+ n:= nc(n).rest
+ PER.
+
+ forget n:
+ IF last = nil
+ THEN env := nc(n).rest
+ ELSE nc(last).rest:= nc(n).rest
+ FI;
+ IF n = np THEN np DECR 1 FI.
+
+ env: fc(ec(ep).index).environment.
+
+ remove expression:
+ { Removes the first expression from e recovering the space used }
+ ep DECR 1.
+
+END PROC undo bindings;
+
+PROC consult (TEXT CONST knowledge):
+ { asserts the clauses from the file into knowledge base }
+{} enable stop;
+ IF NOT exists (knowledge)
+ THEN syntax error ("consulting file not existing"); LEAVE consult
+ FI;
+ last param (knowledge);
+ TERMS VAR clauses;
+ BOOL VAR single:= TRUE;
+ rule count:= 0;
+ initiate read terms (knowledge, clauses);
+ WHILE look ahead <> end of input
+ REP rule count INCR 1;
+ cout (rule count);
+ read clause;
+ assertz (clauses);
+ clauses:= nil
+ PER;
+ remove token;
+ IF anything noted
+ THEN modify (file);
+ note edit (file)
+ FI;
+ IF free of errors
+ THEN reset tp:= tp;
+ reset kp:= kp;
+ reset symboltable:= symboltable;
+ put (rule count)
+ ELSE put (0); from file:= FALSE
+ FI;
+ putline ("rules inserted.");
+ line .
+
+ read clause:
+ TERM VAR term;
+ IF single
+ THEN read term (term);
+ IF term.arity = var
+ THEN syntax error ("clause starts with variable")
+ ELIF name (symboltable, term.symbol) = ":-"
+ THEN read terms (clauses);
+ call terms (clauses);
+ LEAVE consult
+ FI;
+ IF look ahead = colon
+ THEN remove token;
+ read terms (clauses)
+ FI
+ ELIF look ahead = semicolon
+ THEN remove token;
+ read terms (clauses)
+ FI;
+ IF look ahead = semicolon
+ THEN single:= FALSE
+ ELIF look ahead = period
+ THEN single:= TRUE;
+ remove token
+ ELSE syntax error ("period or semicolon expected")
+ FI;
+ insert term in clauses.
+
+ insert term in clauses:
+ TERMS VAR tmp;
+ new tp (tmp);
+ replace(tcsymbol,tmp,term.symbol);
+ replace(tcarguments,tmp,term.arguments);
+ replace(tcarity,tmp,term.arity);
+ replace(tcrest,tmp, clauses);
+ clauses:= tmp.
+
+ remove token:
+ look ahead empty:= TRUE.
+
+END PROC consult;
+
+PROC reconsult (TEXT CONST knowledge):
+ { asserts the clauses from the file into knowledge base }
+{} enable stop;
+ IF NOT exists (knowledge)
+ THEN syntax error ("reconsulting file not existing"); LEAVE reconsult
+ FI;
+ last param (knowledge);
+ TERMS VAR clauses;
+ BOOL VAR single:= TRUE;
+ rule count:= 0;
+ initiate read terms (knowledge, clauses);
+ WHILE look ahead <> end of input
+ REP rule count INCR 1;
+ cout (rule count);
+ read clause;
+ abolish (tcsymbol ISUB clauses);
+ clauses:= nil
+ PER;
+ remove token;
+ consult (knowledge).
+
+ read clause:
+ TERM VAR term;
+ IF single
+ THEN read term (term);
+ IF term.arity = var
+ THEN syntax error ("clause starts with variable")
+ ELIF name (symboltable, term.symbol) = ":-"
+ THEN read terms (clauses);
+ call terms (clauses);
+ LEAVE reconsult
+ FI;
+ IF look ahead = colon
+ THEN remove token;
+ read terms (clauses)
+ FI
+ ELIF look ahead = semicolon
+ THEN remove token;
+ read terms (clauses)
+ FI;
+ IF look ahead = semicolon
+ THEN single:= FALSE
+ ELIF look ahead = period
+ THEN single:= TRUE;
+ remove token
+ ELSE syntax error ("period or semicolon expected")
+ FI;
+ insert term in clauses.
+
+ insert term in clauses:
+ TERMS VAR tmp;
+ new tp (tmp);
+ replace(tcsymbol,tmp,term.symbol);
+ replace(tcarguments,tmp,term.arguments);
+ replace(tcarity,tmp,term.arity);
+ replace(tcrest,tmp, clauses);
+ clauses:= tmp.
+
+ remove token:
+ look ahead empty:= TRUE.
+
+END PROC reconsult;
+
+PROC assertz (TERMS CONST clause):
+ { Inserts the clause into the knowledge base before the first clause
+ beginning with the same functor.
+ Clauses beginning with the same functor are assumed to be listed
+ consecutively.
+ }
+ CLAUSES VAR c1, c2, c3;
+ IF free of errors
+ THEN IF freep > nil
+ THEN c3:= freec(freep);
+ freep DECR 1;
+ IF reset freep > freep THEN reset freep:= freep FI
+ ELSE new kp (c3)
+ FI;
+ replace(kcfirst,c3, clause);
+ IF knowledge base = nil
+ COR (tcsymbolISUB((kcfirstISUB(knowledgebase)) )) =
+ (tcsymbolISUB(clause))
+ THEN insert on top
+ ELSE c1:= knowledge base;
+ REP find and insert clause PER
+ FI
+ FI.
+
+ find and insert clause:
+ c2:= (kcrestISUB(c1)) ;
+ IF c2 = nil
+ THEN insert on top
+ ELIF (tcsymbolISUB((kcfirstISUB(c2)) )) = (tcsymbolISUB(clause))
+ THEN insert before
+ FI;
+ c1:= c2.
+
+ insert on top:
+ replace(kcrest,c3, knowledge base);
+ knowledge base:= c3;
+ LEAVE assertz.
+
+ insert before:
+ replace(kcrest,c3, c2);
+ replace(kcrest,c1, c3);
+ LEAVE assertz.
+
+ENDPROC assertz;
+
+PROC asserta (TERMS CONST clause):
+ { Inserts the clause into the knowledge base after the last clause
+ beginning with the same functor.
+ Clauses beginning with the same functor are assumed to be listed
+ consecutively.
+ }
+ CLAUSES VAR c1, c2, c3;
+ IF free of errors
+ THEN IF freep > nil
+ THEN c3:= freec(freep);
+ freep DECR 1;
+ IF reset freep > freep THEN reset freep:= freep FI
+ ELSE new kp (c3)
+ FI;
+ replace(kcfirst,c3, clause);
+ IF knowledge base = nil
+ THEN replace(kcrest,c3, knowledge base);
+ knowledge base:= c3
+ ELSE c1:= knowledge base;
+ REP find and insert clause PER
+ FI
+ FI.
+
+ find and insert clause:
+ c2:= (kcrestISUB(c1)) ;
+ IF c2 = nil
+ THEN append after c1
+ ELIF (tcsymbolISUB((kcfirstISUB(c2)) )) = (tcsymbolISUB(clause))
+ THEN insert behind
+ FI;
+ c1:= c2.
+
+ append after c1:
+ replace(kcrest,c1, clause);
+ LEAVE asserta.
+
+ insert behind:
+ REP c1:= c2;
+ c2:= (kcrestISUB(c1)) ;
+ UNTIL (tcsymbolISUB((kcfirstISUB(c2)) )) <> (tcsymbolISUB(clause))
+ PER;
+ replace(kcrest,c3, c2);
+ replace(kcrest,c1, c3);
+ LEAVE asserta.
+
+ENDPROC asserta;
+
+PROC retract (TERMS CONST clause):
+ { Retracts the clause from the knowledge base. }
+ CLAUSES VAR c1:= knowledge base, c2;
+ IF free of errors
+ THEN IF c1 = nil
+ THEN rule count DECR 1
+ ELIF c1 > build ins CAND terms eq ((kcfirstISUB(c1)) , clause)
+ THEN retract top
+ ELSE REP find and retract clause PER
+ FI
+ FI.
+
+ find and retract clause:
+ c2:= (kcrestISUB(c1)) ;
+ IF c2 = nil
+ THEN rule count DECR 1;
+ LEAVE retract
+ ELIF c2 > build ins CAND terms eq ((kcfirstISUB(c2)) , clause)
+ THEN retract c2
+ FI;
+ c1:= c2.
+
+ retract top:
+ freep INCR 1;
+ reset freep:= freep;
+ freec(freep):= knowledge base;
+ knowledge base:= (kcrestISUB(knowledge base)) ;
+ LEAVE retract.
+
+ retract c2:
+ replace(kcrest,c1, (kcrestISUB(c2)) );
+ freep INCR 1;
+ reset freep:= freep;
+ freec(freep):= c2;
+ LEAVE retract.
+
+ENDPROC retract;
+
+PROC abolish (SYMBOL CONST clause):
+ { Retracts all the clauses with this name from the knowledge base. }
+{} enable stop;
+ CLAUSES VAR c1:= knowledge base, c2;
+ IF free of errors
+ THEN REP
+ IF c1 = nil
+ THEN rule count DECR 1;
+ LEAVE abolish
+ ELIF c1 = knowledgebase CAND c1 > build ins
+ CAND (tcsymbol ISUB(kcfirstISUBc1)) = clause
+ THEN retract top;
+ c1:= knowledgebase
+ ELSE find and retract clause
+ FI
+ PER
+ FI.
+
+ find and retract clause:
+ c2:= kcrestISUBc1 ;
+ IF c2 = nil
+ THEN rule count DECR 1;
+ LEAVE abolish
+ ELIF c2 > build ins
+ CAND (tcsymbol ISUB(kcfirstISUBc2)) = clause
+ THEN retract c2
+ ELSE c1:= c2
+ FI.
+
+ retract top:
+ freep INCR 1;
+ reset freep:= freep;
+ freec(freep):= knowledge base;
+ knowledge base:= (kcrestISUB(knowledge base)).
+
+ retract c2:
+ replace(kcrest,c1, (kcrestISUB(c2)) );
+ freep INCR 1;
+ reset freep:= freep;
+ freec(freep):= c2.
+
+ENDPROC abolish;
+
+BOOL PROC terms eq (TERMS CONST a, b):
+ IF a = b
+ THEN TRUE
+ ELIF a = 0 COR b = 0
+ THEN FALSE
+ ELIF TERM:(tcsymbolISUBa,
+ tcargumentsISUBa,
+ tcarityISUBa) =
+ TERM:(tcsymbolISUBb,
+ tcargumentsISUBb,
+ tcarityISUBb)
+ THEN terms eq ((tcrestISUB(a)) , (tcrestISUB(b)) )
+ ELSE FALSE
+ FI
+ENDPROC terms eq;
+
+PROC value (TERM CONST t, TERM VAR r, FRAME CONST f):
+ { sets r to the value of t in f^.environment }
+{} enable stop;
+ IF t.arguments = 0
+ THEN IF t.arity = var
+ THEN variable term
+ ELSE constant term
+ FI
+ ELSE compound term
+ FI.
+
+ constant term: r:= t.
+
+ variable term:
+ TERM VAR t1, t2;
+ FRAME VAR f1;
+ IF bound (t, f, t1, f1)
+ THEN value (t1, r, f1)
+ ELSE r:= t
+ FI.
+
+ compound term:
+ INT VAR step:= 3;
+ TERMS VAR ts:= t.arguments;
+ r.arguments:= nil;
+ WHILE ts <> nil
+ REP value (TERM:(tcsymbolISUBts,
+ tcargumentsISUBts,
+ tcarityISUBts),
+ t1,
+ f);
+ IF stepping
+ CAND step = 1 CAND t.symbol = cons CAND t1.symbol = nil
+ THEN step:= 0;
+ value (t1, t2, f);
+ ts:= t2.arguments
+ ELSE ts:= tcrestISUB(ts);
+ push term in arguments
+ FI;
+ PER;
+ IF step = 0
+ THEN r.symbol:= nil
+ ELSE r.symbol:= t.symbol
+ FI;
+ r.arity:= no of terms (r.arguments).
+
+ stepping:
+ IF step > 1 THEN step DECR 1; TRUE ELSE FALSE FI.
+
+ push term in arguments:
+ TERMS VAR term;
+ new tp (term);
+ replace(tcsymbol,term, t1.symbol);
+ replace(tcarguments,term, t1.arguments);
+ replace(tcarity,term, t1.arity);
+ replace(tcrest,term, r.arguments);
+ r.arguments:= term.
+ENDPROC value;
+
+BOOL PROC bound (TERM CONST t1, FRAME CONST f1,
+ TERM VAR t2, FRAME VAR f2):
+ { returns TRUE iff the expression <t1, f1^.environment> is bound and
+ assigns <t2, f2^.environment> the expression to which it is bound. }
+ ENVIRONMENT VAR n:= fc(f1).environment;
+ SUBSTITUTION VAR sub;
+ WHILE n <> nil
+ REP sub:= nc(n).first;
+ IF t1.symbol = sub.variable.symbol
+ THEN t2:= sub.substitute;
+ f2:= sub.others;
+ LEAVE bound WITH TRUE
+ ELSE n:= nc(n).rest
+ FI
+ PER;
+ FALSE
+ENDPROC bound;
+
+PROC append term (TERM CONST appendix, TERMS VAR list):
+ TERMS VAR term, last term;
+ IF list = nil
+ THEN new tp (term);
+ list:= term
+ ELSE term:= list;
+ REP last term:= term;
+ term:= tcrestISUB(term)
+ UNTILterm = nil PER;
+ new tp (term);
+ replace(tcrest,last term, term);
+ FI;
+ replace(tcsymbol,term,appendix.symbol);
+ replace(tcarguments,term,appendix.arguments);
+ replace(tcarity,term,appendix.arity);
+ replace(tcrest,term, nil)
+END PROC append term;
+
+TERMS PROC revers (TERMS CONST ts):
+ IF ts <= nil
+ THEN ts
+ ELSE TERMS VAR reverted:= revers ((tcrestISUB(ts)) );
+ append term (TERM:(tcsymbolISUBts,
+ revers (tcargumentsISUBts),
+ tcarityISUBts),
+ reverted);
+ reverted
+ FI
+ENDPROC revers;
+
+PROC call terms (TERMS VAR ts):
+ TEXT VAR old:= sysout;
+ forget ("$sysin$",quiet);
+ sysout ("$sysin$");
+ WHILE ts > nil
+ REP write term (TERM:(tcsymbolISUBts,
+ tcargumentsISUBts,
+ tcarityISUBts));
+ line;
+ ts:= tcrestISUB(ts)
+ PER;
+ write ("elan(sysin,()).");
+ sysout (old);
+ sysin ("$sysin$")
+ENDPROC call terms;
+
+PROC write environment list (FRAME CONST frame):
+ write environment list (frame, fc(frame).environment);
+ENDPROC write environment list;
+
+PROC write environment list (FRAME CONST frame, ENVIRONMENT CONST en):
+ IF en <> nil
+ THEN write environment list (frame, nc(en).rest);
+ write term (nc(en).first.variable); write (" = ");
+ value (nc(en).first.variable, t, frame);
+ write term backward (t);
+ IF en <> fc(frame).environment THEN write (", ") FI
+ FI
+ENDPROC write environment list;
+
+PROC write knowledge base (CLAUSES CONST k):
+ TERMS VAR t:= (kcfirstISUB(k)) ;
+ IF t > nil CAND k <= reset kp CAND k > build ins
+ CAND (pattern = cut COR pattern = (tcsymbolISUB(t))
+ )
+ THEN found:= FALSE;
+ IF (kcrestISUB(k)) > nil
+ THEN write knowledge base ((kcrestISUB(k)) )
+ FI;
+ write term (TERM:(tcsymbolISUBt, tcargumentsISUBt, tcarityISUBt));
+ t:= (tcrestISUB(t)) ;
+ IF t > nil
+ THEN write (":- ");
+ write terms
+ FI;
+ write (".");
+ line
+ ELIF (found COR k <= build ins) CAND (kcrestISUB(k)) > nil
+ THEN write knowledge base ((kcrestISUB(k)) )
+ FI.
+
+ write terms:
+ BOOL VAR once:= FALSE;
+ WHILE t <> nil
+ REP IF once THEN write (", ") ELSE once:= TRUE FI;
+ write term (TERM:(tcsymbolISUBt, tcargumentsISUBt, tcarityISUBt));
+ t:= (tcrestISUB(t)) ;
+ PER.
+ENDPROC write knowledge base;
+
+PROC write symbol (TERM CONST t):
+ TEXT VAR w1, w2:= name (symboltable, t.symbol);
+ IF quoting
+ THEN scan (w2);
+ next symbol (w1, i); INT VAR i;
+ IF w1 = w2 CAND i <> num
+ THEN write (w2)
+ ELSE write (""""); write (w2); write ("""")
+ FI
+ ELSE write (w2)
+ FI
+ENDPROC write symbol;
+
+PROC write term backward (TERM CONST t):
+ IF t.arity = integer
+ THEN write (text (t.symbol))
+ ELIF t.symbol <= cons
+ THEN IF t.symbol < 0
+ THEN write ("_"+text(-t.symbol))
+ ELSE write ("[");
+ write subterms backward (t, t.arguments); write ("]")
+ FI
+ ELSE
+ write symbol (t);
+ IF t.arguments <> nil
+ THEN compound term
+ FI
+ FI.
+
+ compound term:
+ write ("("); write subterms backward (t, t.arguments); write (")").
+
+ENDPROC write term backward;
+
+PROC write subterms backward (TERM CONST t, TERMS CONST ts):
+ IF ts = nil
+ THEN
+ ELSE write subterms backward (t, (tcrestISUB(ts)) );
+ write term backward (
+ TERM:(tcsymbolISUBts, tcargumentsISUBts, tcarityISUBts));
+ IF ts <> t.arguments
+ THEN IF t.symbol = cons THEN write ("|") ELSE write (",") FI
+ FI
+ FI
+ENDPROC write subterms backward;
+
+PROC write term (TERM CONST t):
+ IF t.arity = integer
+ THEN write (text (t.symbol))
+ ELIF t.symbol <= cons
+ THEN IF t.symbol < 0
+ THEN write ("_"+text(-t.symbol))
+ ELSE write ("["); write terms; write ("]")
+ FI
+ ELSE
+ write symbol (t);
+ IF t.arguments <> nil
+ THEN compound term
+ FI
+ FI.
+
+ compound term:
+ write ("("); write terms; write (")").
+
+ write terms:
+ TERMS VAR ts:= t.arguments;
+ WHILE ts <> nil
+ REP write term (
+ TERM:(tcsymbolISUBts, tcargumentsISUBts, tcarityISUBts));
+ ts:= tcrestISUB(ts);
+ IF ts <> nil
+ THEN IF t.symbol = cons THEN write ("|") ELSE write (",") FI
+ FI
+ PER.
+
+ENDPROC write term;
+
+PROC read consult list:
+ TERM VAR t;
+ TERMS CONST old tp:= tp;
+ WHILE filename read REP PER;
+ IF look ahead <> close bracket
+ THEN syntax error ("closing bracket expected")
+ FI;
+ remove token;
+ reset symboltable:= symboltable;
+ TERMS CONST ts:= tp;
+ tp:= old tp;
+ consult list (ts);
+ from file:= FALSE.
+
+ filename read:
+ BOOL VAR was minus:= FALSE;
+ IF look ahead = minus
+ THEN remove token;
+ was minus:= TRUE
+ FI;
+ IF look ahead = identifier
+ THEN new tp (tp);
+ read term (t);
+ replace(tcsymbol,tp, t.symbol);
+ replace(tcarguments,tp, t.arguments);
+ replace(tcarity,tp, t.arity);
+ IF was minus THEN replace(tcarity,tp, var);
+ FI;
+ IF NOT exists (name (symboltable, (tcsymbolISUB(tp))
+ ))
+ THEN syntax error ("file does not exist"); FALSE
+ ELIF look ahead = comma THEN remove token; TRUE
+ ELSE TRUE
+ FI
+ ELSE FALSE
+ FI .
+
+ remove token:
+ look ahead empty:= TRUE.
+ENDPROC read consult list;
+
+PROC consult list (TERMS CONST ts):
+ IF ts > tp
+ THEN TERM VAR term:=
+ TERM:(tcsymbolISUBts, tcargumentsISUBts, tcarityISUBts);
+ consult list (ts-1);
+ IF free of errors
+ THEN TEXT VAR fname:= name (symboltable, term.symbol);
+ IF term.arity = var
+ THEN put ("reconsulting"); putline (fname); reconsult (fname)
+ ELSE put ( "consulting"); putline (fname); consult (fname)
+ FI
+ FI
+ FI
+ENDPROC consult list;
+
+PROC initiate read terms (TERMS VAR ts, TEXT CONST prompter):
+ enable stop;
+ look ahead empty:= TRUE; ahead empty:= TRUE;
+ from file:= FALSE;
+ TEXT VAR inputline;
+ IF prompter = "-"
+ THEN inputline:= ""
+ ELSE inputline:= ""13""
+ FI;
+ REP
+ WHILE sysin = "" CAND is escape
+ REP write (""13""15"gib kommando: ");
+ get command;
+ IF inputline = ""
+ THEN write (""14""3""3"")
+ ELSE write (""14""13""10"");
+ IF prompter = "-"
+ THEN lernsequenz auf taste legen ("k", inputline);
+ FI;
+ disable stop;
+ lernsequenz auf taste legen ("q","break"13"");
+ do (inputline);
+ lernsequenz auf taste legen ("q","bye"13"");
+ IF is error
+ THEN put (errormessage); clear error
+ FI;
+ enable stop;
+ FI;
+ write (""13""10""5"?");
+ write (prompter);
+ write (" ")
+ PER;
+ getline (inputline);
+ IF inputline <> ""
+ CAND (inputline SUB length (inputline)) <> "."
+ THEN inputline CAT "."
+ FI;
+ scan (inputline);
+ ts:= nil
+ UNTIL inputline <> "" PER;
+ IF prompter = "-"
+ THEN lernsequenz auf taste legen ("k", inputline)
+ FI.
+
+ is escape:
+ REP IF inputline = ""13""
+ THEN write (""13""10""5"?");
+ write (prompter);
+ write (" ")
+ ELIF inputline = "?"
+ THEN putline ("?"); inform; push (""13"")
+ FI;
+ getchar (inputline)
+ UNTIL pos ("?"13"", inputline) = 0
+ PER;
+ IF inputline = ""27""
+ THEN getchar (inputline);
+ IF inputline = ""27""
+ THEN TRUE
+ ELSE push (inputline); push (""27""); FALSE
+ FI
+ ELSE push (inputline); FALSE
+ FI.
+
+ get command:
+ getchar (inputline);
+ IF inputline = ""27""
+ THEN getchar (inputline);
+ IF inputline = ""27""
+ THEN inputline:= "";
+ line
+ ELSE push (inputline);
+ push (""27"");
+ getline (inputline)
+ FI
+ ELSE push (inputline);
+ getline (inputline)
+ FI.
+
+ENDPROC initiate read terms;
+
+PROC initiate read terms (TEXT CONST knowledge, TERMS VAR ts):
+ look ahead empty:= TRUE; ahead empty:= TRUE;
+ file:= sequential file (input, knowledge);
+ from file:= TRUE;
+ scan (file);
+ ts:= nil
+ENDPROC initiate read terms;
+
+PROC read terms (TERMS VAR ts):
+ { the actual parameter for ts should be initiated < ts:=nil >
+ at top level of recursion
+ }
+ TERM VAR t;
+ WHILE look ahead <> close paren CAND look ahead <> close bracket
+ CAND look ahead <> period
+ REP read term (t);
+ append term (t, ts)
+ UNTIL end of list PER.
+
+ end of list:
+ IF look ahead = comma
+ THEN remove comma;
+ FALSE
+ ELSE TRUE
+ FI.
+
+ remove comma: look ahead empty:= TRUE.
+
+ENDPROC read terms;
+
+PROC read term (TERM VAR t):
+ IF look ahead = open paren
+ THEN remove token;
+ read term (t);
+ transform infix to prefix (t, 0);
+ IF look ahead = close paren
+ THEN remove token
+ ELSE syntax error ("closing parentheses missing")
+ FI
+ ELSE read prefix term (t);
+ transform infix to prefix (t, 0)
+ FI .
+
+ remove token: look ahead empty:= TRUE .
+ENDPROC read term;
+
+PROC transform infix to prefix (TERM VAR t, INT CONST last prio):
+ SELECT look ahead OF
+ CASE minus, plus, times, slash, less, equal, uneq, grt, eqeq, eqdotdot,
+ boldvar:
+ operator:= look ahead value;
+ IF last prio <= priority (operator)
+ THEN
+ remove token;
+ IF look ahead = open paren
+ THEN read term (t2);
+ ELSE read prefix term (t2);
+ FI;
+ IF last prio < priority (operator)
+ THEN transform infix to prefix (t2, priority (operator));
+ FI;
+ form result;
+ transform infix to prefix (t, last prio)
+ FI
+ ENDSELECT.
+
+ form result:
+ second operand;
+ first operand;
+ prefix.
+
+second operand:
+ TERMS VAR p2;
+ TERM VAR t2;
+ new tp (p2);
+ replace(tcsymbol, p2, t2.symbol);
+ replace(tcarguments, p2, t2.arguments);
+ replace(tcarity, p2, t2.arity);
+ replace(tcrest, p2, nil).
+
+first operand:
+ TERMS VAR p1;
+ new tp (p1);
+ replace(tcsymbol, p1, t.symbol);
+ replace(tcarguments, p1, t.arguments);
+ replace(tcarity, p1, t.arity);
+ replace(tcrest, p1, p2).
+
+prefix:
+ INT VAR operator;
+ t.symbol:= operator;
+ t.arguments:= p1;
+ t.arity:= 2.
+
+ remove token:
+ look ahead empty:= TRUE.
+
+ENDPROC transform infix to prefix;
+
+INT PROC priority (INT CONST operator):
+ SELECT operator OF
+ CASE times, slash, mod: 7
+ CASE minus, plus: 6
+ CASE 9,10,11,12,13: 5
+ OTHERWISE 2
+ ENDSELECT
+ENDPROC priority;
+
+PROC read prefix term (TERM VAR t):
+ SELECT look ahead OF
+ CASE exclamation: term is cut
+ CASE bold var: term is a variable
+ CASE underscore: term is anonym
+ CASE number: term is number
+ CASE identifier,
+ minus, plus, times, slash, less, equal, uneq, grt, eqeq, eqdotdot:
+ IF look ahead = minus
+ THEN remove token;
+ IF look ahead = number {monadic minus}
+ THEN look ahead value:= - look ahead value;
+ term is number;
+ LEAVE read prefix term
+ FI
+ ELSE remove token
+ FI;
+ term is identifier;
+ IF look ahead = open paren
+ THEN term is compound
+ { ELSE term is a constant }
+ FI
+ CASE open bracket: term is list
+ CASE colon: term is colon
+ OTHERWISE syntax error ("wrong expression");
+ t:= TERM:(nil, nil, 0)
+ ENDSELECT.
+
+ term is cut:
+ remove token;
+ t:= TERM:(cut, nil, 0).
+
+ term is a variable:
+ remove token;
+ t:= TERM:(look ahead value, nil, var).
+
+ term is anonym:
+ remove token;
+ anonym value DECR 1;
+ t:= TERM:(anonym value, nil, var).
+
+ term is number:
+ remove token;
+ t:= TERM:(look ahead value, nil, integer).
+
+ term is identifier:
+ t:= TERM:(look ahead value, nil, 0).
+
+ term is list:
+ remove token;
+ t:= TERM:(nil, nil, 0);
+ IF look ahead = close bracket
+ THEN remove token
+ ELSE non empty list
+ FI.
+
+ non empty list:
+ TERM VAR t1;
+ read term (t1);
+ append term (t1, t.arguments);
+ IF look ahead = close bracket
+ THEN remove token;
+ t.arity:= 1
+ ELSE list with more than one element
+ FI.
+
+ list with more than one element:
+ IF look ahead = stroke
+ THEN t.symbol:= cons
+ ELIF look ahead <> comma CAND look ahead <> colon
+ THEN syntax error ("comma missing")
+ FI;
+ term is compound list.
+
+ term is compound list:
+ remove token;
+ read terms (t.arguments);
+ t.arity:= no of terms (t.arguments);
+ IF look ahead = close bracket
+ THEN remove token
+ ELSE syntax error ("closing bracket missing")
+ FI.
+
+ term is compound:
+ remove token;
+ read terms (t.arguments);
+ t.arity:= no of terms (t.arguments);
+ IF look ahead = close paren
+ THEN remove token
+ ELSE syntax error ("closing parentheses missing")
+ FI.
+
+ term is colon:
+ remove token;
+ INT VAR i:= link (symboltable, ":-");
+ IF i = 0
+ THEN insert (symboltable, ":-", i)
+ FI;
+ t:= TERM:(i, nil, 0).
+
+ remove token:
+ look ahead empty:= TRUE.
+
+ENDPROC read prefix term;
+
+INT PROC no of terms (TERMS CONST ts):
+ INT VAR i:= 0, t:=ts;
+ WHILE t <> nil
+ REP t:= (tcrestISUB(t)) ;
+ i INCR 1
+ PER;
+ i
+ENDPROC no of terms;
+
+INT PROC arith (TERM CONST term, FRAME CONST curr frame):
+ TERM VAR t;
+ IF term.arity = var
+ THEN value (term, t, curr frame)
+ ELSE t:= term
+ FI;
+ IF t.arity = integer
+ THEN t.symbol
+ ELIF t.arity = var
+ THEN syntax error ("free variable in arith expression"); 0
+ ELIF t.arity = 1
+ THEN SELECT t.symbol OF
+ CASE plus: arith (t1, curr frame)
+ CASE minus: - arith (t1, curr frame)
+ OTHERWISE syntax error ("unknown arith operator"); 0
+ ENDSELECT
+ ELIF t.arity = 2
+ THEN SELECT t.symbol OF
+ CASE plus: arith (t1, curr frame) + arith (t2, curr frame)
+ CASE minus: arith (t1, curr frame) - arith (t2, curr frame)
+ CASE times: arith (t1, curr frame) * arith (t2, curr frame)
+ CASE slash: arith (t1, curr frame) DIV arith (t2, curr frame)
+ CASE mod: arith (t1, curr frame) MOD arith (t2, curr frame)
+ OTHERWISE syntax error ("unknown arith operator"); 0
+ ENDSELECT
+ ELSE syntax error ("wrong arith expression"); 0
+ FI.
+
+ t1: TERM:(tcsymbolISUBt.arguments,
+ tcargumentsISUBt.arguments,
+ tcarityISUBt.arguments) .
+
+ t2: TERM:(tcsymbolISUB(tcrestISUB(t.arguments)) ,
+ tcargumentsISUB(tcrestISUB(t.arguments)) ,
+ tcarityISUB(tcrestISUB(t.arguments)) ) .
+
+ENDPROC arith;
+
+TOKEN PROC look ahead :
+ { Returns the token in the look ahead.
+ If the look ahead is empty it calls the scanner
+ to get the next symbol,
+ which is then placed into the look ahead.
+ }
+ SYMBOLTYPE VAR symboltype;
+ IF look ahead empty
+ THEN look ahead empty:= FALSE;
+ get next symbol;
+ store the symbol
+ FI;
+ look ahead token.
+
+ get next symbol:
+ IF ahead empty
+ THEN IF from file
+ THEN next symbol (file, look ahead symbol, symboltype)
+ ELSE next symbol (look ahead symbol, symboltype)
+ FI
+ ELSE ahead empty:= TRUE;
+ look ahead symbol:= ahead symbol;
+ symboltype:= ahead symboltype
+ FI.
+
+ store the symbol:
+ SELECT symboltype OF
+ CASE tag,tex: look ahead token:= identifier;
+ IF look ahead symbol = ""
+ THEN look ahead value:= 0;
+ ELSE install
+ FI
+ CASE num: look ahead token:= number;
+ look ahead value:= int(look ahead symbol)
+ CASE bold: look ahead token:= bold var;
+ install
+ CASE operator: look ahead token:=
+ pos ("|!:-+*/_<=<>==..", look ahead symbol);
+ IF look ahead token = equal
+ THEN get next symbol;
+ IF symboltype = operator
+ CAND look ahead symbol = "="
+ THEN look ahead token:= eqeq;
+ look ahead symbol:= "=="
+ ELIF look ahead symbol = "."
+ THEN get next symbol;
+ IF look ahead symbol = "."
+ THEN look ahead token:= eqdotdot;
+ look ahead symbol:= "=.."
+ ELSE syntax error ("second period missing")
+ FI
+ ELSE ahead symbol:= look ahead symbol;
+ ahead symboltype:= symboltype;
+ ahead empty:= FALSE;
+ look ahead symbol:= "=";
+ look ahead token := equal
+ FI
+ FI;
+ IF look ahead token > 3
+ THEN install
+ FI
+ CASE delimiter: look ahead token:=
+ pos ("|!:-+*/_<=<>==..,;()[]", look ahead symbol);
+ SELECT look ahead token OF
+ CASE colon: minus must follow
+ CASE 0: syntax error ("wrong delimiter")
+ ENDSELECT
+ CASE endoffile: look ahead token:= end of input
+ CASE within com: look ahead token:= end of input;
+ syntax error ("within comment")
+ CASE within tex: look ahead token:= end of input;
+ syntax error ("within text")
+ ENDSELECT.
+
+ minus must follow:
+ get next symbol;
+ IF look ahead symbol <> "-"
+ THEN syntax error ("minus after colon expected") FI.
+
+ install:
+ look ahead value:= link (symboltable, look ahead symbol);
+ IF look ahead value = 0
+ THEN insert(symboltable,look ahead symbol,look ahead value)
+ FI.
+ENDPROC look ahead;
+
+PROC inform:
+ enable stop;
+ put (" ");
+ put (clock(0) - start time); put ("SEC");
+ IF inference count > 0 CAND clock(0) > start time
+ THEN
+ put (inference count); put ("inferences");
+ put (int (real (inference count) / (clock(0) - start time)));
+ put ("LIPS")
+ FI;
+ FOR k FROM 2 UPTO fsp
+ REP line;
+ FRAME CONST f:= fsc(k).frame;
+ INT CONST ind:= fc(f).level;
+ IF ind <= 40
+ THEN write (ind*" ")
+ ELSE write (text(ind) + ": ")
+ FI;
+ value (fc(f).call, t, fc(f).father);
+ write term backward (t)
+ PER;
+ IF testing
+ THEN put(tp); put(kp); put(fp); put(fsp); put(np); put(ep)
+ FI;
+ line
+ENDPROC inform;
+
+PROC syntax error (TEXT CONST message):
+ free of errors:= FALSE;
+ write ("!- ");
+ write note (message);
+ write note (" at '");
+ write note (look ahead symbol);
+ write note ("' ");
+ IF from file
+ THEN write note ("in rule "); write note (rule count);
+ write note ("line "); write note (lineno(file) - 1)
+ FI;
+ look ahead empty:= TRUE;
+ line; note line
+ENDPROC syntax error;
+
+PROC write note (TEXT CONST t):
+ write (t);
+ IF from file THEN note (t) FI
+ENDPROC write note;
+
+PROC write note (INT CONST i):
+ put (i);
+ IF from file THEN note (i) FI
+ENDPROC write note;
+
+PROC trace (TEXT CONST on):
+ testing:= test on;
+ tracing:= trace on.
+ trace on: pos (on, "on") > 0.
+ test on : pos (on, "test") > 0
+ENDPROC trace;
+
+PROC new kp (INT VAR pointer):
+ kp INCR 1; pointer:= kp;
+ IF length (kcfirst) < 2*kp
+ THEN IF kp > 15990
+ THEN pegel overflow
+ ELSE kcfirst CAT "1234567890123456";
+ kcrest CAT "1234567890123456";
+ FI FI
+ENDPROC new kp;
+
+PROC new tp (INT VAR pointer):
+ tp INCR 1; pointer:= tp;
+ IF length (tcsymbol) < 2*tp
+ THEN IF tp = 15990
+ THEN pegel overflow
+ ELSE tcsymbol CAT "1234567890123456";
+ tcarguments CAT "1234567890123456";
+ tcarity CAT "1234567890123456";
+ tcrest CAT "1234567890123456"
+ FI FI
+ENDPROC new tp;
+
+PROC new (INT VAR pegel, pointer):
+ IF pegel = limit
+ THEN pegel overflow
+ ELSE pegel INCR 1; pointer:= pegel
+ FI
+ENDPROC new;
+
+PROC pegeloverflow: line; write (" ");
+ put(tp); put(kp); put(fp); put(fsp); put(np); put(ep);
+ errorstop ("pegeloverflow")
+ENDPROC pegeloverflow;
+
+
+{
+Programmtransformation:
+
+ PASCAL mit Pointer ==> ELAN
+
+
+1. Rekursive Datentypen:
+
+ type t = ^tcell; ==> LET T = INT;
+
+ { schwache Datenabstraktion mit LET ist besser,
+ weil keine neuen Zugriffsprozeduren erforderlich.
+
+ GLOBAL:
+ }
+ LET nil = 0, limit <= 500;
+ ROW limit TCELL VAR tc; { t cell }
+ INT VAR tp:= nil; { t pegel }
+
+
+2. Deklaration:
+
+ var x : t; ==> T VAR x; { Type checking selber machen ! }
+
+
+3. Pointer-Initialisierung:
+
+ x:= nil; ==> x:= nil;
+
+
+4. Allokation:
+
+ new (x); ==> new (tp,x);
+
+ dispose (x); ==> kommt nicht vor
+
+
+5. Applikation:
+
+ x^.feld ==> TERMSCELL:(TERM:(tcsymbolISUBx, tcargumentsISUBx, tcarityISUBx), tcrestISUBx).feld
+
+ WITH ==> Refinement verwenden
+
+{ Programmtransformation ROW limit TERMSCELL VAR tc => TEXT VAR }
+ T1;
+ "new (tp, " CA "new tp (";
+ T1;
+ REP
+ col(1);
+ D "tc(";
+ IF at ("tc(tc(")
+ THEN D "tc(";
+ attest;
+ col(1);
+ D "tc("
+ FI;
+ attest
+ UNTIL eof PER
+.
+attest:
+IF at ("tc("+any**1+").first."+any**2+":="+any**3+";"+any**4)
+THEN C ("replace(tc"+match(2)+","+match(1)+","+match(3)+");"+match(4))
+ELIF at ("tc("+any**1+").rest:="+any**3+";"+any**4)
+THEN C ("replace(tcrest,"+match(1)+","+match(3)+");"+match(4))
+ELIF at ("tc("+any**1+").first:="+any**3+";"+any**4)
+THEN C ("replace(tcsymbol,"+match(1)+","+match(3)+
+ ".symbol); replace(tcarguments,"+match(1)+","+match(3)+
+ ".arguments); replace(tcarity,"+match(1)+","+match(3)+
+ ".arity);"+match(4))
+ELIF at ("tc("+any**1+").first."+any**2+" "+any**4)
+THEN C ("(tc"+match(2)+"ISUB("+match(1)+")) "+match(4))
+ELIF at ("tc("+any**1+").rest"+any**4)
+THEN C ("(tcrestISUB("+match(1)+")) "+match(4))
+ELIF at ("tc("+any**1+").first).first"+any**4)
+THEN C ("TERM:(tcsymbolISUB"+match(1)+
+ ").first, tcargumentsISUB"+match(1)+
+ ").first, tcarityISUB"+match(1)+").first)"+match(4))
+ELIF at ("tc("+any**1+").first"+any**4)
+THEN C ("TERM:(tcsymbolISUB"+match(1)+
+ ", tcargumentsISUB"+match(1)+", tcarityISUB"+match(1)+")"+match(4))
+ELIF at ("tc("+any**1+"):= TERMSCELL:("+any**2+","+any**3+")"+any**4)
+THEN C ("replace(tcsymbol,"+match(1)+","+match(2)+
+ ".symbol); replace(tcarguments,"+match(1)+","+match(2)+
+ ".arguments); replace(tcarity,"+match(1)+","+match(2)+
+ ".arity); replace(tcrest,"+match(1)+","+match(3)+")"+match(4))
+ELIF at ("tc("+any**1+")"+any**4)
+THEN C ("TERMSCELL:(TERM:(tcsymbolISUB"+match(1)+
+ ", tcargumentsISUB"+match(1)+", tcarityISUB"+match(1)
+ +"), tcrestISUB"+match(1)+")" +match(4))
+ELIF NOT eof
+THEN stop
+FI;
+col(col-1); D("*"); C ""
+.
+
+}
+
+END PACKET prolog;
+
+{ TEST }
+lernsequenz auf taste legen ("7",""124"");
+lernsequenz auf taste legen ("ü",""91"");
+lernsequenz auf taste legen ("+",""93"");
+
diff --git a/prolog/prolog installation b/prolog/prolog installation
new file mode 100644
index 0000000..cc674fa
--- /dev/null
+++ b/prolog/prolog installation
@@ -0,0 +1,117 @@
+(*************************************************************************)
+(*** Insertiert die für PROLOG benötigten Pakete und holt die ***)
+(*** Beispiele vom Archiv. ***)
+(*** ***)
+(*** Autor : W. Metterhausen Stand : 03.12.87 ***)
+(*************************************************************************)
+
+erste bildschirmmeldung;
+
+
+IF yes("Prolog insertieren?")
+
+ THEN
+ hole sourcen vom archiv;
+ insertiere alle pakete;
+ hole beispiele vom archiv;
+ forget ("prolog installation", quiet);
+ type("push(""bye""13""prolog again"");prolog(""standard"")"13"");
+FI.
+
+
+insertiere alle pakete :
+ insert and say ("thesaurus");
+ insert and say ("prolog").
+
+erste bildschirmmeldung :
+ page;
+ put center (" Generator für Prolog gestartet."); line;
+ put center ("--------------------------------------------------");line;
+ put center (" Prolog kann nur in einer Task aufgebaut werden, ");line;
+ put center (" die nicht bereits umfangreiche insertierte Pakete ");line;
+ put center (" enthält! Gegebenenfalls sollte Prolog in ");line;
+ put center (" einer Task direkt unter ""UR"" angelegt werden. ");line;
+ line (2).
+
+hole sourcen vom archiv :
+ TEXT VAR datei;
+ datei := "thesaurus"; hole wenn noetig;
+ datei := "prolog"; hole wenn noetig;
+ line.
+
+hole beispiele vom archiv :
+ datei := "standard"; hole wenn noetig;
+ datei := "sum"; hole wenn noetig;
+ datei := "permute"; hole wenn noetig;
+ datei := "family"; hole wenn noetig;
+ datei := "puzzle"; hole wenn noetig;
+ datei := "calc"; hole wenn noetig;
+ datei := "prieks"; hole wenn noetig;
+ datei := "topographie"; hole wenn noetig;
+ datei := "quicksort"; hole wenn noetig;
+ datei := "prolog dokumentation";
+ hole wenn noetig;
+ release(archive);
+ line.
+
+hole wenn noetig :
+ IF NOT exists (datei) THEN
+ put line (""""+ datei + """ wird vom Archiv geholt");
+ fetch (datei, archive)
+ FI.
+
+PROC insert and say (TEXT CONST datei) :
+
+ INT VAR cx, cy;
+ put line ("Inserting """ + datei + """...");
+ get cursor (cx, cy);
+ checkoff;
+ insert (datei);
+ checkon;
+ cl eop (cx, cy); line;
+ forget (datei, quiet).
+
+END PROC insert and say;
+
+TEXT PROC inverse (TEXT CONST t):
+ ""15"" + t + " " + ""14""
+END PROC inverse;
+
+PROC put center (TEXT CONST t):
+ put center (t, 80)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+ put center (zeile, t, 80)
+END PROC put center;
+
+PROC put center (TEXT CONST t, INT CONST gesamtbreite):
+ INT VAR cy;
+ get cursor (cy, cy);
+ put center (cy, t, gesamtbreite)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t, INT CONST gesamtbreite):
+ cursor ((gesamtbreite - length (t)) DIV 2, zeile);
+ put (t).
+END PROC put center;
+
+PROC cl eol:
+ out (""5"")
+END PROC cl eol;
+
+PROC cl eop:
+ out (""4"")
+END PROC cl eop;
+
+PROC cl eol (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eol
+END PROC cl eol;
+
+PROC cl eop (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eop
+END PROC cl eop;
+
+
diff --git a/prolog/puzzle b/prolog/puzzle
new file mode 100644
index 0000000..648beb6
--- /dev/null
+++ b/prolog/puzzle
@@ -0,0 +1,24 @@
+ {Solution: 9,5,6,7,0,8,2}
+puzzle:- repeat, permute ((9,8,7,6,5,2,0), SENDMORY),
+ write (SENDMORY),
+ puzzle (SENDMORY, SEND, MORE, MONEY),
+ elan (line),
+ write (SEND), write (+),
+ write (MORE), write (=),
+ write (MONEY).
+
+puzzle([S,E,N,D,O,R,Y], SEND, MORE, MONEY):-
+ SEND IS ((S * 10 + E) * 10 + N) * 10 + D,
+ MORE IS ((10 + O) * 10 + R) * 10 + E,
+ MONEY IS (((10 + O) * 10 + N) * 10 + E) * 10 + Y,
+ MONEY IS SEND + MORE.
+
+permute ([], []).
+permute ([E|X], Z):- permute (X, Y), insert (E, Y, Z).
+
+insert (E, X, [E|X]).
+insert (E, [F|X], [F|Y]):- insert (E, X, Y).
+
+repeat.
+repeat:- repeat.
+
diff --git a/prolog/quicksort b/prolog/quicksort
new file mode 100644
index 0000000..79276c0
--- /dev/null
+++ b/prolog/quicksort
@@ -0,0 +1,14 @@
+(* quicksort algorithm nach Clocksin-Mellish *)
+
+(* Example : quicksort ([1,3,2,4], [1,2,3,4], []) *)
+
+quicksort ([H|T], S, X) :-
+ split (H, T, A, B),
+ quicksort (A, S, [H|Y]),
+ quicksort (B, Y, X).
+quicksort ([], X, X).
+
+split (H, [A|X], [A|Y], Z) :- A <= H, split (H, X, Y, Z).
+split (H, [A|X], Y, [A|Z]) :- split (H, X, Y, Z).
+split (_, [], [], []).
+
diff --git a/prolog/standard b/prolog/standard
new file mode 100644
index 0000000..bc983ca
--- /dev/null
+++ b/prolog/standard
@@ -0,0 +1,35 @@
+abolish (X) :- elan (abolish, X).
+append ([], X, X) :- !.
+append ([X|Y], Z, [X|W]) :- append (Y, Z, W).
+atom (X) :- functor (X, Y, 0).
+atomic (X) :- atom (X); integer (X).
+consult (X) :- elan (consult, X).
+end :- bye.
+fail :- [].
+findall (X, Y, Z) :- tell ("$$"), write ("[ "), findall (X,Y);
+ write (" ]"), told, see ("$$"), read (Z),
+ seen, elan (forget, "$$").
+findall (X, Y) :- call (Y), writeq (X), write (","), [].
+integer (X) :- functor (X, Y, -1).
+listing (X).
+member (X, [X|Z]).
+member (X, [Y|Z]) :- member (X, Z).
+nl :- elan (line).
+non var (X) :- var (X), !, []; .
+not (X) :- call (X), !, []; .
+notrace :- elan (trace, off).
+reconsult (X) :- elan (reconsult, X).
+repeat.
+repeat :- repeat.
+see (X) :- elan (sysin, X).
+seen :- elan (sysin, "").
+tab (X) :- tab(X,1).
+tab (X,Y) :- Y<=X, !, put (32), incr(Y), tab(X,Y);.
+tell (X) :- elan (sysout, X).
+told :- elan (sysout, "").
+trace :- elan (trace, on).
+true.
+< (X, Y) :- <= (X, Y), <> (X, Y).
+> (X, Y) :- <= (Y, X).
+>= (X, Y) :- < (Y, X).
+
diff --git a/prolog/sum b/prolog/sum
new file mode 100644
index 0000000..e1b6b13
--- /dev/null
+++ b/prolog/sum
@@ -0,0 +1,13 @@
+suc (0, 1). suc (1, 2). suc (2, 3). suc (3, 4). suc (4, 5).
+suc (5, 6). suc (6, 7). suc (7, 8). suc (8, 9).
+sum (0, X, X).
+sum (X, Y, Z):- suc (V, X), sum (V, Y, W), suc (W, Z).
+plus (X, [0,0], X):- !.
+plus (X, Y, Z):- plus one (V, Y), plus (X, V, W), !, plus one (W, Z).
+plus one ([X, Y], [V, W]):- suc (Y, W), X = V, !;
+ Y = 9, suc (X, V), W = 0.
+treereverse (X,Y):- rev (X,Y), !; rev (Y,X), !.
+rev ([], []).
+rev ([X|Y], Z):- X <> [H|T], rev (Y, W), !, append (W, [X], Z);
+ rev (X, V), rev (Y, W), !, append (W, [V], Z).
+
diff --git a/prolog/thesaurus b/prolog/thesaurus
new file mode 100644
index 0000000..4694981
--- /dev/null
+++ b/prolog/thesaurus
@@ -0,0 +1,360 @@
+(* ------------------- VERSION 2 19.01.87 ------------------- *)
+PACKET thesaurus handling (* Autor: J.Liedtke *)
+
+ DEFINES THESAURUS ,
+ := ,
+ empty thesaurus ,
+ insert, (* fuegt ein Element ein *)
+ delete, (* loescht ein Element falls vorhanden *)
+ rename, (* aendert ein Element falls vorhanden *)
+ CONTAINS , (* stellt fest, ob enthalten *)
+ link , (* index in thesaurus *)
+ name , (* name of entry *)
+ decode invalid chars ,(* Steuerzeichen dekodieren *)
+ get , (* get next entry ("" is eof) *)
+ highest entry : (* highest valid index of thes *)
+
+
+TYPE THESAURUS = TEXT ;
+
+LET nil = 0 ,
+ niltext = "" ,
+ max name length = 80 ,
+ begin entry char = ""0"" ,
+ end entry char = ""255"" ,
+ nil entry = ""0""255"" ,
+ nil name = "" ,
+ quote = """" ;
+
+TEXT VAR entry ,
+ dummy ;
+INT VAR cache index := 0 ,
+ cache pos ;
+
+
+TEXT PROC decode (INT CONST number) :
+
+ dummy := " " ;
+ replace (dummy, 1, number) ;
+ dummy .
+
+ENDPROC decode ;
+
+INT PROC decode (TEXT CONST string, INT CONST position) :
+
+ subtext (string, position, position + 1) ISUB 1 .
+
+ENDPROC decode ;
+
+PROC access (THESAURUS CONST thesaurus, TEXT CONST name) :
+
+ construct entry ;
+ IF NOT cache identifies entry
+ THEN search through thesaurus list
+ FI ;
+ IF entry found
+ THEN cache index := decode (list, cache pos - 2)
+ ELSE cache index := 0
+ FI .
+
+construct entry :
+ entry := begin entry char ;
+ entry CAT name ;
+ decode invalid chars (entry, 2) ;
+ entry CAT end entry char .
+
+search through thesaurus list :
+ cache pos := pos (list, entry) .
+
+cache identifies entry :
+ cache pos <> 0 AND
+ pos (list, entry, cache pos, cache pos + LENGTH entry) = cache pos .
+
+entry found : cache pos > 0 .
+
+list : CONCR (thesaurus) .
+
+ENDPROC access ;
+
+PROC access (THESAURUS CONST thesaurus, INT CONST index) :
+
+ IF cache identifies index
+ THEN cache index := index ;
+ construct entry
+ ELSE cache pos := pos (list, decode (index) + begin entry char) ;
+ IF entry found
+ THEN cache pos INCR 2 ;
+ cache index := index ;
+ construct entry
+ ELSE cache index := 0 ;
+ entry := niltext
+ FI
+ FI .
+
+construct entry :
+ entry := subtext (list, cache pos, pos (list, end entry char, cache pos)) .
+
+cache identifies index :
+ subtext (list, cache pos-2, cache pos) = decode (index) + begin entry char .
+
+entry found : cache pos > 0 .
+
+list : CONCR (thesaurus) .
+
+ENDPROC access ;
+
+
+
+THESAURUS PROC empty thesaurus :
+
+ THESAURUS : (""1""0"")
+
+ENDPROC empty thesaurus ;
+
+
+OP := (THESAURUS VAR dest, THESAURUS CONST source ) :
+
+ CONCR (dest) := CONCR (source) .
+
+ENDOP := ;
+
+TEXT VAR insert name ;
+
+PROC insert (THESAURUS VAR thesaurus, TEXT CONST name, INT VAR index) :
+
+ insert name := name ;
+ decode invalid chars (insert name, 1) ;
+ insert name if possible .
+
+insert name if possible :
+ IF insert name = "" OR LENGTH insert name > max name length
+ THEN index := nil ; errorstop ("Name unzulaessig")
+ ELIF overflow
+ THEN index := nil
+ ELSE insert element
+ FI .
+
+overflow :
+ LENGTH CONCR (thesaurus) + LENGTH insert name + 4 > max text length .
+
+insert element :
+ search free entry ;
+ IF entry found
+ THEN insert into directory
+ ELSE add entry to directory if possible
+ FI .
+
+search free entry :
+ access (thesaurus, nil name) .
+
+insert into directory :
+ change (list, cache pos + 1, cache pos, insert name) ;
+ index := cache index .
+
+add entry to directory if possible :
+ INT CONST next free index := decode (list, LENGTH list - 1) ;
+ add entry to directory .
+
+add entry to directory :
+ list CAT begin entry char ;
+ cache pos := LENGTH list ;
+ cache index := next free index ;
+ list CAT insert name ;
+ list CAT end entry char + decode (next free index + 1) ;
+ index := cache index .
+
+entry found : cache index > 0 .
+
+list : CONCR (thesaurus) .
+
+ENDPROC insert ;
+
+PROC decode invalid chars (TEXT VAR name, INT CONST start pos) :
+
+ INT VAR invalid char pos := pos (name, ""0"", ""31"", start pos) ;
+ WHILE invalid char pos > 0 REP
+ change (name, invalid char pos, invalid char pos, decoded char) ;
+ invalid char pos := pos (name, ""0"", ""31"", invalid char pos)
+ PER ;
+ change all (name, ""255"", quote + "255" + quote) .
+
+decoded char : quote + text(code(name SUB invalid char pos)) + quote.
+
+ENDPROC decode invalid chars ;
+
+PROC insert (THESAURUS VAR thesaurus, TEXT CONST name) :
+
+ INT VAR index ;
+ insert (thesaurus, name, index) ;
+ IF index = nil AND NOT is error
+ THEN errorstop ("THESAURUS-Ueberlauf")
+ FI .
+
+ENDPROC insert ;
+
+PROC delete (THESAURUS VAR thesaurus, TEXT CONST name, INT VAR index) :
+
+ access (thesaurus, name) ;
+ index := cache index ;
+ delete (thesaurus, index) .
+
+ENDPROC delete ;
+
+PROC delete (THESAURUS VAR thesaurus, INT CONST index) :
+
+ access (thesaurus, index) ;
+ IF entry found
+ THEN delete entry
+ FI .
+
+delete entry :
+ IF is last entry of thesaurus
+ THEN cut off as much as possible
+ ELSE set to nil entry
+ FI .
+
+set to nil entry :
+ change (list, cache pos, cache pos + LENGTH entry - 1, nil entry) .
+
+cut off as much as possible :
+ WHILE predecessor is also nil entry REP
+ set cache to this entry
+ PER ;
+ list := subtext (list, 1, cache pos - 1) ;
+ erase cache .
+
+predecessor is also nil entry :
+ subtext (list, cache pos - 4, cache pos - 3) = nil entry .
+
+set cache to this entry :
+ cache pos DECR 4 .
+
+erase cache :
+ cache pos := 0 ;
+ cache index := 0 .
+
+is last entry of thesaurus :
+ pos (list, end entry char, cache pos) = LENGTH list - 2 .
+
+list : CONCR (thesaurus) .
+
+entry found : cache index > nil .
+
+ENDPROC delete ;
+
+
+BOOL OP CONTAINS (THESAURUS CONST thesaurus, TEXT CONST name ) :
+
+ IF name = niltext OR LENGTH name > max name length
+ THEN FALSE
+ ELSE access (thesaurus, name) ; entry found
+ FI .
+
+entry found : cache index > nil .
+
+ENDOP CONTAINS ;
+
+PROC rename (THESAURUS VAR thesaurus, TEXT CONST old, new) :
+
+ rename (thesaurus, link (thesaurus, old), new)
+
+ENDPROC rename ;
+
+PROC rename (THESAURUS VAR thesaurus, INT CONST index, TEXT CONST new) :
+
+ insert name := new ;
+ decode invalid chars (insert name, 1) ;
+ IF overflow
+ THEN errorstop ("THESAURUS-Ueberlauf")
+ ELIF insert name = "" OR LENGTH insert name > max name length
+ THEN errorstop ("Name unzulaessig")
+ ELSE change to new name
+ FI .
+
+overflow :
+ LENGTH CONCR (thesaurus) + LENGTH insert name + 4 > max text length .
+
+change to new name :
+ access (thesaurus, index) ;
+ IF cache index <> 0 AND entry <> ""
+ THEN change (list, cache pos + 1, cache pos + LENGTH entry - 2, insert name)
+ FI .
+
+list : CONCR (thesaurus) .
+
+ENDPROC rename ;
+
+INT PROC link (THESAURUS CONST thesaurus, TEXT CONST name) :
+
+ access (thesaurus, name) ;
+ cache index .
+
+ENDPROC link ;
+
+TEXT PROC name (THESAURUS CONST thesaurus, INT CONST index) :
+
+ access (thesaurus, index) ;
+ subtext (entry, 2, LENGTH entry - 1) .
+
+ENDPROC name ;
+
+PROC get (THESAURUS CONST thesaurus, TEXT VAR name, INT VAR index) :
+
+ identify index ;
+ REP
+ to next entry
+ UNTIL end of list COR valid entry found PER .
+
+identify index :
+ IF index = 0
+ THEN cache index := 0 ;
+ cache pos := 1
+ ELSE access (thesaurus, index)
+ FI .
+
+to next entry :
+ cache pos := pos (list, begin entry char, cache pos + 1) ;
+ IF cache pos > 0
+ THEN correct cache pos ;
+ get entry
+ ELSE get nil entry
+ FI .
+
+correct cache pos :
+ IF (list SUB cache pos + 2) = begin entry char
+ THEN cache pos INCR 2
+ ELIF (list SUB cache pos + 1) = begin entry char
+ THEN cache pos INCR 1
+ FI .
+
+get entry :
+ cache index INCR 1 ;
+ index := cache index ;
+ name := subtext (list, cache pos + 1, end entry pos - 1) .
+
+get nil entry :
+ cache index := 0 ;
+ cache pos := 0 ;
+ index := 0 ;
+ name := "" .
+
+end entry pos : pos (list, end entry char, cache pos) .
+
+end of list : index = 0 .
+
+valid entry found : name <> "" .
+
+list : CONCR (thesaurus) .
+
+ENDPROC get ;
+
+INT PROC highest entry (THESAURUS CONST thesaurus) : (*840813*)
+
+ decode (list, LENGTH list - 1) - 1 .
+
+list : CONCR (thesaurus) .
+
+ENDPROC highest entry ;
+
+ENDPACKET thesaurus handling ;
+
diff --git a/prolog/topographie b/prolog/topographie
new file mode 100644
index 0000000..c0924cf
--- /dev/null
+++ b/prolog/topographie
@@ -0,0 +1,59 @@
+member(X,[X|_]).
+member(X,[_|Y]):-
+ member(X,Y).
+
+append([],L,L).
+append([X|A],B,[X|C]):-
+ append(A,B,C).
+
+efface(A,[A|L],L):-
+ !.
+efface(A,[B|L],[B|M]):-
+ efface(A,L,M).
+efface(_,[],[]).
+
+
+nol(N):-
+ read(N).
+
+input(_,_,N,N,L,L).
+input(X,Y,R,N,L,O):-
+ read(X),
+ read(Y),
+ append([[X,Y]],L,M),
+ C IS R+1,
+ input(_,_,C,N,M,O).
+
+enter(L):-
+ nol(N),
+ input(X,Y,0,N,[],L).
+
+
+searchnext(X,Y,[H|T]):-
+ H=[X,Y];
+ H=[Y,X];
+ searchnext(X,Y,T).
+
+onemove(_,_,[],L):-
+ write(L).
+onemove(X,Y,L,H):-
+ searchnext(X,Y,L),
+ efface([X,Y],L,N),
+ L<>N,
+ write(N),elan(line),
+ append(H,[Y],F),
+ onemove(Y,Z,N,F).
+onemove(X,Y,L,H):-
+ searchnext(X,Y,L),
+ efface([Y,X],L,N),
+ L<>N,
+ write(N),elan(line),
+ append(H,[Y],F),
+ onemove(Y,Z,N,F).
+
+
+
+go:-
+ enter(L),!,
+ onemove(X,Y,L,[X]).
+
diff --git a/prozess/ls-MENUKARTE:Prozess b/prozess/ls-MENUKARTE:Prozess
new file mode 100644
index 0000000..9a2e009
--- /dev/null
+++ b/prozess/ls-MENUKARTE:Prozess
Binary files differ
diff --git a/prozess/ls-Prozess 1 für AKTRONIC-Adapter b/prozess/ls-Prozess 1 für AKTRONIC-Adapter
new file mode 100644
index 0000000..c42cfa5
--- /dev/null
+++ b/prozess/ls-Prozess 1 für AKTRONIC-Adapter
@@ -0,0 +1,57 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Prozess 1 **
+ ** **
+ ** Anpassung für AKTRONIC-Adapter **
+ ** **
+ ** Version 1.02 **
+ ** **
+ ** (Stand : 26.01.90) **
+ ** **
+ ** **
+ ** Autoren: Bruno Pollok, Bielefeld **
+ ** Wolfgang Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls prozess 1 DEFINES
+ run pdv,{} run pdv again,{} initialisiere interface,{} schalte alles aus,{} ausgeben,{} eingabe,{} warte,{} abbruch gewuenscht,{} tue nichts,{} trage kanaldaten ein,{} beende kanaldaten eintragen,{} hole spannungsbereich,{} letzte ausgabe,{} pruefe kanal,{} pruefe abbruch,{} teste interface,{} oeffne interface,{} schliesse interface,{} nicht belegt,{} digital aus,{} analog aus,{}
+ digital ein,{} analog ein,{} kanalbreite,{} ganzzahl obergrenze,{} adapterart,{} (* ------------------------- *){} kanalkoppler,{} interface kanal,{} oeffne interface direkt,{} schliesse interface direkt,{} initialisiere interface direkt,{} direkt ausgeben,{} direkt eingabe:{}(******** A N P A S S U N G A N A K T R O N I C - A D A P T E R ********){}LET interface test code = ""240"",{} interface open code = ""176"",{}
+ interface close code = ""176"",{} adresse 0 code = ""176"",{} interface write code = 64 ,{} interface read code = 192 ;{}TEXT CONST adapterart :: "AKTRONIC-Adapter";{}TEXT PROC interface anpassung (INT CONST kanalnummer, steuerungscode):{} IF es ist ein ausgabekanal{} THEN code (interface write code + device + faktor * steuerungscode){} ELIF es ist ein eingabekanal{} THEN lesecode in abhaengigkeit von der taktzahl{} ELSE ""{} FI.{} es ist ein ausgabekanal:{}
+ kanal [kanalnummer].betriebsart < 0.{} es ist ein eingabekanal:{} kanal [kanalnummer].betriebsart > 0.{} device:{} IF steckplatznummer < 3{} THEN 16{} ELSE 32{} FI.{} faktor:{} IF steckplatznummer MOD 2 = 0{} THEN 4{} ELSE 1{} FI.{} steckplatznummer:{} IF kanalnummer < 10{} THEN 1{} ELSE kanalnummer DIV 10{} FI.{} lesecode in abhaengigkeit von der taktzahl:{} SELECT kanal [kanalnummer].taktzahl OF{} CASE 1: code fuer digital oder analog eingang{}
+ CASE 2: code fuer kombi e1{} CASE 3: code fuer kombi e2{} OTHERWISE "" END SELECT.{} code fuer digital oder analog eingang:{} IF kanal [kanalnummer].betriebsart = analog ein{} THEN kanal [kanalnummer].taktzahl := 2; (* ad wandler muss hier *){} lesecode + lesecode (* 2x gelesen werden! *){} ELSE lesecode{} FI.{} lesecode : code (interface read code + device + faktor * steuerungscode).{} code fuer kombi e1:{} kanal [kanalnummer].taktzahl INCR 1; (* bei Analogport1 der Kombikarte *){}
+ adresse 0 code + (3 * lesecode). (* sind hier 3 Takte noetig ! *){} code fuer kombi e2:{} kanal [kanalnummer].taktzahl DECR 1; (* hier nur 2 Takte noetig ! *){} adresse 0 code + lesecode + lesecode.{}END PROC interface anpassung;{}(************ H A R D W A R E U N A B H Ä N G I G E R T E I L ************){}LET max kanalanzahl = 49,{} initcode = 50,{} endcode = 51,{} alles aus code = 52,{}
+ endezeichen = "q",{} abbruchzeichen = "h",{} esc = ""27"";{}INT CONST analog aus :: -2, (* Betriebsarten *){} digital aus :: -1,{} nicht belegt :: 0,{} digital ein :: 1,{} analog ein :: 2,{} kanalbreite :: 8,{} ganzzahl obergrenze :: 2 ** kanalbreite,{} configuration error code :: -1,{}
+ kanal besetzt code :: -3,{} interface error code :: -4,{} not init code :: -5;{}INT VAR interfacechannel :: 2,{} dummy;{}TEXT VAR meldung :: "";{}BOOL VAR kanaldaten sind eingetragen :: FALSE,{} endezeichen gegeben :: FALSE,{} programm mit pdv gestartet :: FALSE,{} fehler zu melden :: FALSE;{}TASK VAR interface task :: niltask;{}DATASPACE VAR ds :: nilspace;{}
+TYPE KANAL = STRUCT (INT betriebsart, taktzahl, TEXT steuercode),{} SPANNUNG = STRUCT (REAL minimalwert, maximalwert);{}ROW max kanalanzahl INT VAR vorherige ausgabe;{}ROW max kanalanzahl KANAL VAR kanal;{}ROW max kanalanzahl SPANNUNG VAR spannung;{}ROW 5 TEXT CONST fehlermeldung :: ROW 5 TEXT :{} ("Interface ist noch nicht konfiguriert!",{} "Interface-Task ist besetzt!",{} "Interface-Kanal ist belegt!",{} "Interface meldet sich nicht!",{} "Interface kann nicht geöffnet werden!");{}
+PROC run pdv:{} run pdv (last param){}END PROC run pdv;{}PROC run pdv (TEXT CONST programmname):{} enable stop;{} last param (programmname);{} programm mit pdv gestartet := TRUE;{} teste interface;{} disable stop;{} run (programmname);{} IF is error{} THEN fehlerbehandlung{} ELSE melde programmende{} FI;{} schliesse interface;{} programm mit pdv gestartet := FALSE;{} enable stop;{} IF fehler zu melden{} THEN errorstop (meldung){} FI{}END PROC run pdv;{}PROC run pdv again:{}
+ enable stop;{} programm mit pdv gestartet := TRUE;{} teste interface;{} disable stop;{} run again;{} IF is error{} THEN fehlerbehandlung{} ELSE melde programmende{} FI;{} schliesse interface;{} programm mit pdv gestartet := FALSE;{} enable stop;{} IF fehler zu melden{} THEN errorstop (meldung){} FI{}END PROC run pdv again;{}PROC melde programmende:{} page;{} menufootnote ("Programmende! Zum Weitermachen bitte irgendeine Taste tippen.");{} pause;{} schalte alles aus{}END PROC melde programmende;{}
+PROC initialisiere interface:{} enable stop;{} pruefe abbruch;{} IF programm mit pdv gestartet{} THEN schalte alles aus{} ELSE errorstop ("PDV-Programme müssen mit 'run pdv' gestartet werden!"){} FI{}END PROC initialisiere interface;{}PROC schalte alles aus:{} INT VAR k;{} FOR k FROM 1 UPTO max kanalanzahl REP{} vorherige ausgabe [k] := 0{} PER;{} forget (ds); ds := nilspace;{} call (interface task, alles aus code, ds, dummy){}END PROC schalte alles aus;{}PROC ausgeben (INT CONST kanalnummer, wert):{}
+ merke wert;{} gib wert aus.{} merke wert:{} vorherige ausgabe [kanalnummer] := wert.{} gib wert aus:{} call (interface task, 256 * kanalnummer + wert, ds, dummy).{}END PROC ausgeben;{}INT PROC eingabe (INT CONST kanalnummer):{} INT VAR eingabewert;{} call (interface task, kanalnummer, ds, eingabewert);{} eingabewert{}END PROC eingabe;{}PROC warte (REAL CONST sekunden):{} TEXT VAR eingabe;{} pruefe abbruch;{} eingabe := incharety (int (sekunden * 10.0 + 0.5));{} IF eingabe = esc{}
+ THEN untersuche naechstes zeichen{} FI.{} untersuche naechstes zeichen:{} eingabe := incharety (30);{} IF eingabe = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF eingabe = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){} FI.{}END PROC warte;{}PROC warte (INT CONST sekunden):{} TEXT VAR eingabe;{} pruefe abbruch;{} eingabe := incharety (sekunden * 10);{} IF eingabe = esc{} THEN untersuche naechstes zeichen{}
+ FI.{} untersuche naechstes zeichen:{} eingabe := incharety (30);{} IF eingabe = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF eingabe = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){} FI.{}END PROC warte;{}BOOL PROC abbruch gewuenscht:{} pruefe abbruch;{} BOOL VAR entscheidung :: endezeichen gegeben;{} endezeichen gegeben := FALSE;{} entscheidung{}END PROC abbruch gewuenscht;{}PROC tue nichts:{}
+ pruefe abbruch{}END PROC tue nichts;{}PROC trage kanaldaten ein (INT CONST kanalnummer,{} ROW 2 REAL CONST spannungsbereich,{} ROW 3 INT CONST kanalparameter):{} spannung [kanalnummer].minimalwert := spannungsbereich [1];{} spannung [kanalnummer].maximalwert := spannungsbereich [2];{} kanal [kanalnummer].betriebsart := kanalparameter [1];{} kanal [kanalnummer].taktzahl := kanalparameter [2];{} kanal [kanalnummer].steuercode := interface anpassung{}
+ (kanalnummer, kanalparameter [3]){}END PROC trage kanaldaten ein;{}PROC beende kanaldaten eintragen:{} loesche interface task;{} begin (PROC kanal koppler, interface task);{} kanaldaten sind eingetragen := TRUE.{} loesche interface task:{} disable stop;{} end (interface task);{} IF is error{} THEN clear error{} FI;{} enable stop.{}END PROC beende kanaldaten eintragen;{}PROC hole spannungsbereich (INT CONST kanalnummer, REAL VAR u min, u max):{}
+ u min := spannung [kanalnummer].minimalwert;{} u max := spannung [kanalnummer].maximalwert{}END PROC hole spannungsbereich;{}INT PROC letzte ausgabe (INT CONST kanalnummer):{} vorherige ausgabe [kanalnummer]{}END PROC letzte ausgabe;{}PROC pruefe kanal (INT CONST kanalnummer, gewuenschte betriebsart):{} pruefe abbruch;{} pruefe kanalnummer;{} pruefe betriebsart.{} pruefe kanalnummer:{} IF kanalnummer < 1 OR kanalnummer > max kanalanzahl{} THEN errorstop ("Kanalnummer " + text (kanalnummer) +{}
+ " ist unzulaessig !"){} FI.{} pruefe betriebsart:{} IF gewuenschte betriebsart <> kanal [kanalnummer].betriebsart{} THEN errorstop ("An Kanal " + text (kanalnummer) +{} " keine " + wunsch + " moeglich!"){} FI.{} wunsch:{} IF gewuenschte betriebsart = analog aus{} THEN "Analog-Ausgabe"{} ELIF gewuenschte betriebsart = digital aus{} THEN "Digital-Ausgabe"{} ELIF gewuenschte betriebsart = digital ein{} THEN "Digital-Eingabe"{}
+ ELIF gewuenschte betriebsart = analog ein{} THEN "Analog-Eingabe"{} ELSE "Ein- oder Ausgabe"{} FI.{}END PROC pruefe kanal;{}PROC pruefe abbruch:{} IF incharety = esc{} THEN pruefe weiter{} FI.{} pruefe weiter:{} TEXT CONST zeichen :: incharety (30);{} IF zeichen = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF zeichen = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){}
+ FI.{}END PROC pruefe abbruch;{}PROC oeffne interface (INT VAR status):{} enable stop;{} forget (ds); ds := nilspace;{} IF kanaldaten sind eingetragen{} THEN pingpong (interfacetask, initcode, ds, status){} ELSE status := configuration error code{} FI;{} IF status > 0 THEN status DECR maxint FI;{} forget (ds); ds := nilspace{}END PROC oeffne interface;{}PROC schliesse interface:{} enable stop;{} forget (ds); ds := nilspace;{} pingpong (interface task, end code, ds, dummy);{} forget (ds); ds := nilspace{}
+END PROC schliesse interface;{}PROC teste interface:{} INT VAR test;{} oeffne interface (test);{} IF test < 0{} THEN errorstop (fehlermeldung [min (5, abs (test))]){} ELSE fehler zu melden := FALSE;{} endezeichen gegeben := FALSE{} FI{}END PROC teste interface;{}PROC fehlerbehandlung:{} meldung := errormessage;{} IF meldung <> ""{} THEN meldung CAT fehlerzeile;{} fehler zu melden := TRUE{} FI;{} clear error;{} initialisiere interface.{} fehlerzeile:{}
+ IF errorline = 0{} THEN ""{} ELSE " (bei Zeile " + text (errorline) + ")"{} FI.{}END PROC fehlerbehandlung;{}(******************** EIN-/AUSGABE AM INTERFACE-KANAL ********************){}PROC kanalkoppler:{} IF name (myself) <> "-"{} THEN errorstop ("Unzulässiges Kommando!"){} ELSE warte auf anrufe{} FI.{} warte auf anrufe:{} TASK VAR absender;{} TEXT VAR dummy;{} INT VAR codenummer, antwort;{} disable stop;{} REP forget (ds);{} wait (ds, codenummer, absender);{}
+ IF codenummer = initcode{} THEN kopple an interface kanal;{} IF interface ist betriebsbereit{} THEN bearbeite weitere auftraege{} ELSE gib negative rueckmeldung{} FI;{} gib kanal frei{} ELSE antwort := not init code;{} gib negative rueckmeldung{} FI{} PER.{} kopple an interface kanal:{} continue (interface channel);{} IF is error{} THEN clear error;{} antwort := kanal besetzt code{}
+ ELSE oeffne interface direkt (antwort){} FI.{} interface ist betriebsbereit: antwort = 0.{} gib negative rueckmeldung: send (absender, antwort, ds).{} gib kanal frei:{} break (quiet);{} send (absender, 0, ds, antwort);{} collect heap garbage.{} bearbeite weitere auftraege:{} REP call (absender, antwort, ds, codenummer);{} IF codenummer > 255{} THEN sende wert an interface{} ELIF codenummer < 50{} THEN hole wert von interface{} ELIF codenummer = alles aus code{}
+ THEN initialisiere interface direkt{} FI{} UNTIL codenummer = endcode PER;{} IF is error THEN clear error FI;{} schliesse interface direkt.{} sende wert an interface:{} out (kanal [codenummer DIV 256].steuercode);{} out (code (codenummer)).{} hole wert von interface:{} out (kanal [codenummer].steuercode);{} SELECT kanal [codenummer].taktzahl OF{} CASE 1 : antwort := erstes zeichen{} CASE 2 : antwort := zweites zeichen{} CASE 3 : antwort := drittes zeichen{}
+ OTHERWISE antwort := -1{} END SELECT.{} erstes zeichen:{} code (incharety (1)).{} zweites zeichen:{} dummy := incharety (1);{} code (incharety (1)).{} drittes zeichen:{} dummy := incharety (1);{} dummy := incharety (1);{} code (incharety (1)).{}END PROC kanalkoppler;{}PROC interface kanal (INT CONST kanalnummer):{} enable stop;{} IF kanalnummer < 1 OR kanalnummer > 24{} THEN errorstop ("Unzulaessige Kanalnummer"){} ELSE interface channel := kanalnummer{}
+ FI{}END PROC interface kanal;{}INT PROC interface kanal:{} interface channel{}END PROC interface kanal;{}PROC oeffne interface direkt (INT VAR status):{} leere puffer;{} out (interface test code);{} IF antwort <> ""{} THEN status := 0;{} out (interface open code){} ELSE status := interface error code{} FI.{} leere puffer:{} REP UNTIL incharety = "" PER.{} antwort: incharety (1).{}END PROC oeffne interface direkt;{}PROC schliesse interface direkt:{} out (interface close code){}
+END PROC schliesse interface direkt;{}PROC initialisiere interface direkt:{} schalte alles aus.{} schalte alles aus:{} INT VAR kanalnummer, kanalbetriebsart;{} FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{} kanalbetriebsart := kanal [kanalnummer].betriebsart;{} IF kanalbetriebsart = digital aus{} THEN direkt ausgeben (kanalnummer, 0){} ELIF kanalbetriebsart = analog aus{} THEN direkt ausgeben (kanalnummer, gewandelte nullspannung){} FI{}
+ PER.{} gewandelte nullspannung:{} int(- real (ganzzahl obergrenze) * u min / (u max - u min) + 0.5).{} u max : spannung [kanalnummer].maximalwert.{} u min : spannung [kanalnummer].minimalwert.{}END PROC initialisiere interface direkt;{}PROC direkt ausgeben (INT CONST kanalnummer, wert):{} out (kanal [kanalnummer].steuercode);{} out (code (wert)){}END PROC direkt ausgeben;{}INT PROC direkt eingabe (INT CONST kanalnummer):{} gib lesecode aus;{} erhaltene antwort.{} gib lesecode aus:{}
+ out (kanal [kanalnummer].steuercode).{} erhaltene antwort:{} TEXT VAR dummy;{} SELECT kanal [kanalnummer].taktzahl OF{} CASE 1 : erstes zeichen{} CASE 2 : zweites zeichen{} CASE 3 : drittes zeichen{} OTHERWISE -1{} END SELECT.{} erstes zeichen:{} code (incharety (1)).{} zweites zeichen:{} dummy := incharety (1);{} code (incharety (1)).{} drittes zeichen:{} dummy := incharety (1);{} dummy := incharety (1);{} code (incharety (1)).{}
+END PROC direkt eingabe;{}PROC initialisiere die kanaele:{} INT VAR kanalnummer;{} FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{} trage kanaldaten ein (kanalnummer, keine spannung, leere karte);{} vorherige ausgabe [kanalnummer] := 0{} PER.{} keine spannung:{} ROW 2 REAL : (0.0, 0.0).{} leere karte:{} ROW 3 INT : (nicht belegt, 0, 0).{}END PROC initialisiere die kanaele;{}initialisiere die kanaele;{}END PACKET ls prozess 1{}
+
diff --git a/prozess/ls-Prozess 1 für MUFI als Endgerät b/prozess/ls-Prozess 1 für MUFI als Endgerät
new file mode 100644
index 0000000..4d2a5f4
--- /dev/null
+++ b/prozess/ls-Prozess 1 für MUFI als Endgerät
@@ -0,0 +1,57 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Prozess 1 **
+ ** **
+ ** Anpassung für MUFI als Endgerät **
+ ** **
+ ** Version 1.02 **
+ ** **
+ ** (Stand : 26.01.90) **
+ ** **
+ ** **
+ ** Autoren: Bruno Pollok, Bielefeld **
+ ** Wolfgang Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls prozess 1 DEFINES
+ run pdv,{} run pdv again,{} initialisiere interface,{} schalte alles aus,{} ausgeben,{} eingabe,{} warte,{} abbruch gewuenscht,{} tue nichts,{} trage kanaldaten ein,{} beende kanaldaten eintragen,{} hole spannungsbereich,{} letzte ausgabe,{} pruefe kanal,{} pruefe abbruch,{} teste interface,{} oeffne interface,{} schliesse interface,{} nicht belegt,{} digital aus,{} analog aus,{}
+ digital ein,{} analog ein,{} kanalbreite,{} ganzzahl obergrenze,{} adapterart,{} (* ------------------------- *){} kanalkoppler,{} interface kanal,{} oeffne interface direkt,{} schliesse interface direkt,{} initialisiere interface direkt,{} direkt ausgeben,{} direkt eingabe:{}(******************** A N P A S S U N G A N M U F I ********************){}LET interface test code = ""27""27"10",{} interface okay code = ""27""27"00",{}
+ interface open code = ""27""27"1A18",{} interface close code = ""25""27""27"13",{} adresse 0 code = ""61"",{} leertakt code = ""62"",{} interface write code = 80 ,{} interface read code = 64 ,{} erwartete zeichen = 4 ;{}TEXT CONST adapterart :: "MUFI als Endgerät";{}TEXT PROC interface anpassung (INT CONST kanalnummer, steuerungscode):{} IF es ist ein ausgabekanal{} THEN code (interface write code + device + 4 * steuerungscode){} ELIF es ist ein eingabekanal{}
+ THEN lesecode in abhaengigkeit von der taktzahl{} ELSE ""{} FI.{} es ist ein ausgabekanal:{} kanal [kanalnummer].betriebsart < 0.{} es ist ein eingabekanal:{} kanal [kanalnummer].betriebsart > 0.{} device:{} IF kanalnummer < 10{} THEN 0{} ELSE kanalnummer DIV 10 - 1{} FI.{} lesecode in abhaengigkeit von der taktzahl:{} SELECT kanal [kanalnummer].taktzahl OF{} CASE 1: lesecode{} CASE 2: adresse 0 code + lesecode + lesecode{} CASE 3: adresse 0 code + lesecode + zwei weitere takte{}
+ OTHERWISE "" END SELECT.{} lesecode : code (interface read code + device + 4 * steuerungscode).{} zwei weitere takte:{} IF leertakt code = ""{} THEN lesecode + lesecode{} ELSE kanal [kanalnummer].taktzahl DECR 1;{} leertakt code + lesecode{} FI.{}END PROC interface anpassung;{}(************ H A R D W A R E U N A B H Ä N G I G E R T E I L ************){}LET max kanalanzahl = 49,{} initcode = 50,{} endcode = 51,{}
+ alles aus code = 52,{} endezeichen = "q",{} abbruchzeichen = "h",{} esc = ""27"";{}INT CONST analog aus :: -2, (* Betriebsarten *){} digital aus :: -1,{} nicht belegt :: 0,{} digital ein :: 1,{} analog ein :: 2,{} kanalbreite :: 8,{} ganzzahl obergrenze :: 2 ** kanalbreite,{}
+ configuration error code :: -1,{} kanal besetzt code :: -3,{} interface error code :: -4,{} not init code :: -5;{}INT VAR interfacechannel :: 2,{} dummy;{}TEXT VAR meldung :: "";{}BOOL VAR kanaldaten sind eingetragen :: FALSE,{} endezeichen gegeben :: FALSE,{} programm mit pdv gestartet :: FALSE,{} fehler zu melden :: FALSE;{}TASK VAR interface task :: niltask;{}
+DATASPACE VAR ds :: nilspace;{}TYPE KANAL = STRUCT (INT betriebsart, taktzahl, TEXT steuercode),{} SPANNUNG = STRUCT (REAL minimalwert, maximalwert);{}ROW max kanalanzahl INT VAR vorherige ausgabe;{}ROW max kanalanzahl KANAL VAR kanal;{}ROW max kanalanzahl SPANNUNG VAR spannung;{}ROW 5 TEXT CONST fehlermeldung :: ROW 5 TEXT :{} ("Interface ist noch nicht konfiguriert!",{} "Interface-Task ist besetzt!",{} "Interface-Kanal ist belegt!",{} "Interface meldet sich nicht!",{} "Interface kann nicht geöffnet werden!");{}
+PROC run pdv:{} run pdv (last param){}END PROC run pdv;{}PROC run pdv (TEXT CONST programmname):{} enable stop;{} last param (programmname);{} programm mit pdv gestartet := TRUE;{} teste interface;{} disable stop;{} run (programmname);{} IF is error{} THEN fehlerbehandlung{} ELSE melde programmende{} FI;{} schliesse interface;{} programm mit pdv gestartet := FALSE;{} enable stop;{} IF fehler zu melden{} THEN errorstop (meldung){} FI{}END PROC run pdv;{}PROC run pdv again:{}
+ enable stop;{} programm mit pdv gestartet := TRUE;{} teste interface;{} disable stop;{} run again;{} IF is error{} THEN fehlerbehandlung{} ELSE melde programmende{} FI;{} schliesse interface;{} programm mit pdv gestartet := FALSE;{} enable stop;{} IF fehler zu melden{} THEN errorstop (meldung){} FI{}END PROC run pdv again;{}PROC melde programmende:{} page;{} menufootnote ("Programmende! Zum Weitermachen bitte irgendeine Taste tippen.");{} pause;{} schalte alles aus{}END PROC melde programmende;{}
+PROC initialisiere interface:{} enable stop;{} pruefe abbruch;{} IF programm mit pdv gestartet{} THEN schalte alles aus{} ELSE errorstop ("PDV-Programme müssen mit 'run pdv' gestartet werden!"){} FI{}END PROC initialisiere interface;{}PROC schalte alles aus:{} INT VAR k;{} FOR k FROM 1 UPTO max kanalanzahl REP{} vorherige ausgabe [k] := 0{} PER;{} forget (ds); ds := nilspace;{} call (interface task, alles aus code, ds, dummy){}END PROC schalte alles aus;{}PROC ausgeben (INT CONST kanalnummer, wert):{}
+ merke wert;{} gib wert aus.{} merke wert:{} vorherige ausgabe [kanalnummer] := wert.{} gib wert aus:{} call (interface task, 256 * kanalnummer + wert, ds, dummy).{}END PROC ausgeben;{}INT PROC eingabe (INT CONST kanalnummer):{} INT VAR eingabewert;{} call (interface task, kanalnummer, ds, eingabewert);{} eingabewert{}END PROC eingabe;{}PROC warte (REAL CONST sekunden):{} TEXT VAR eingabe;{} pruefe abbruch;{} eingabe := incharety (int (sekunden * 10.0 + 0.5));{} IF eingabe = esc{}
+ THEN untersuche naechstes zeichen{} FI.{} untersuche naechstes zeichen:{} eingabe := incharety (30);{} IF eingabe = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF eingabe = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){} FI.{}END PROC warte;{}PROC warte (INT CONST sekunden):{} TEXT VAR eingabe;{} pruefe abbruch;{} eingabe := incharety (sekunden * 10);{} IF eingabe = esc{} THEN untersuche naechstes zeichen{}
+ FI.{} untersuche naechstes zeichen:{} eingabe := incharety (30);{} IF eingabe = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF eingabe = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){} FI.{}END PROC warte;{}BOOL PROC abbruch gewuenscht:{} pruefe abbruch;{} BOOL VAR entscheidung :: endezeichen gegeben;{} endezeichen gegeben := FALSE;{} entscheidung{}END PROC abbruch gewuenscht;{}PROC tue nichts:{}
+ pruefe abbruch{}END PROC tue nichts;{}PROC trage kanaldaten ein (INT CONST kanalnummer,{} ROW 2 REAL CONST spannungsbereich,{} ROW 3 INT CONST kanalparameter):{} spannung [kanalnummer].minimalwert := spannungsbereich [1];{} spannung [kanalnummer].maximalwert := spannungsbereich [2];{} kanal [kanalnummer].betriebsart := kanalparameter [1];{} kanal [kanalnummer].taktzahl := kanalparameter [2];{} kanal [kanalnummer].steuercode := interface anpassung{}
+ (kanalnummer, kanalparameter [3]){}END PROC trage kanaldaten ein;{}PROC beende kanaldaten eintragen:{} loesche interface task;{} begin (PROC kanal koppler, interface task);{} kanaldaten sind eingetragen := TRUE.{} loesche interface task:{} disable stop;{} end (interface task);{} IF is error{} THEN clear error{} FI;{} enable stop.{}END PROC beende kanaldaten eintragen;{}PROC hole spannungsbereich (INT CONST kanalnummer, REAL VAR u min, u max):{}
+ u min := spannung [kanalnummer].minimalwert;{} u max := spannung [kanalnummer].maximalwert{}END PROC hole spannungsbereich;{}INT PROC letzte ausgabe (INT CONST kanalnummer):{} vorherige ausgabe [kanalnummer]{}END PROC letzte ausgabe;{}PROC pruefe kanal (INT CONST kanalnummer, gewuenschte betriebsart):{} pruefe abbruch;{} pruefe kanalnummer;{} pruefe betriebsart.{} pruefe kanalnummer:{} IF kanalnummer < 1 OR kanalnummer > max kanalanzahl{} THEN errorstop ("Kanalnummer " + text (kanalnummer) +{}
+ " ist unzulaessig !"){} FI.{} pruefe betriebsart:{} IF gewuenschte betriebsart <> kanal [kanalnummer].betriebsart{} THEN errorstop ("An Kanal " + text (kanalnummer) +{} " keine " + wunsch + " moeglich!"){} FI.{} wunsch:{} IF gewuenschte betriebsart = analog aus{} THEN "Analog-Ausgabe"{} ELIF gewuenschte betriebsart = digital aus{} THEN "Digital-Ausgabe"{} ELIF gewuenschte betriebsart = digital ein{} THEN "Digital-Eingabe"{}
+ ELIF gewuenschte betriebsart = analog ein{} THEN "Analog-Eingabe"{} ELSE "Ein- oder Ausgabe"{} FI.{}END PROC pruefe kanal;{}PROC pruefe abbruch:{} IF incharety = esc{} THEN pruefe weiter{} FI.{} pruefe weiter:{} TEXT CONST zeichen :: incharety (30);{} IF zeichen = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF zeichen = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){}
+ FI.{}END PROC pruefe abbruch;{}PROC oeffne interface (INT VAR status):{} enable stop;{} forget (ds); ds := nilspace;{} IF kanaldaten sind eingetragen{} THEN pingpong (interfacetask, initcode, ds, status){} ELSE status := configuration error code{} FI;{} IF status > 0 THEN status DECR maxint FI;{} forget (ds); ds := nilspace{}END PROC oeffne interface;{}PROC schliesse interface:{} enable stop;{} forget (ds); ds := nilspace;{} pingpong (interface task, end code, ds, dummy);{} forget (ds); ds := nilspace{}
+END PROC schliesse interface;{}PROC teste interface:{} INT VAR test;{} oeffne interface (test);{} IF test < 0{} THEN errorstop (fehlermeldung [min (5, abs (test))]){} ELSE fehler zu melden := FALSE;{} endezeichen gegeben := FALSE{} FI{}END PROC teste interface;{}PROC fehlerbehandlung:{} meldung := errormessage;{} IF meldung <> ""{} THEN meldung CAT fehlerzeile;{} fehler zu melden := TRUE{} FI;{} clear error;{} initialisiere interface.{} fehlerzeile:{}
+ IF errorline = 0{} THEN ""{} ELSE " (bei Zeile " + text (errorline) + ")"{} FI.{}END PROC fehlerbehandlung;{}(******************** EIN-/AUSGABE AM INTERFACE-KANAL ********************){}PROC kanalkoppler:{} IF name (myself) <> "-"{} THEN errorstop ("Unzulässiges Kommando!"){} ELSE warte auf anrufe{} FI.{} warte auf anrufe:{} TASK VAR absender;{} TEXT VAR dummy;{} INT VAR codenummer, antwort;{} disable stop;{} REP forget (ds);{} wait (ds, codenummer, absender);{}
+ IF codenummer = initcode{} THEN kopple an interface kanal;{} IF interface ist betriebsbereit{} THEN bearbeite weitere auftraege{} ELSE gib negative rueckmeldung{} FI;{} gib kanal frei{} ELSE antwort := not init code;{} gib negative rueckmeldung{} FI{} PER.{} kopple an interface kanal:{} continue (interface channel);{} IF is error{} THEN clear error;{} antwort := kanal besetzt code{}
+ ELSE oeffne interface direkt (antwort){} FI.{} interface ist betriebsbereit: antwort = 0.{} gib negative rueckmeldung: send (absender, antwort, ds).{} gib kanal frei:{} break (quiet);{} send (absender, 0, ds, antwort);{} collect heap garbage.{} bearbeite weitere auftraege:{} REP call (absender, antwort, ds, codenummer);{} IF codenummer > 255{} THEN sende wert an interface{} ELIF codenummer < 50{} THEN hole wert von interface{} ELIF codenummer = alles aus code{}
+ THEN initialisiere interface direkt{} FI{} UNTIL codenummer = endcode PER;{} IF is error THEN clear error FI;{} schliesse interface direkt.{} sende wert an interface:{} out (kanal [codenummer DIV 256].steuercode);{} out (code (codenummer)).{} hole wert von interface:{} out (kanal [codenummer].steuercode);{} SELECT kanal [codenummer].taktzahl OF{} CASE 1 : antwort := erstes zeichen{} CASE 2 : antwort := zweites zeichen{} CASE 3 : antwort := drittes zeichen{}
+ OTHERWISE antwort := -1{} END SELECT.{} erstes zeichen:{} code (incharety (1)).{} zweites zeichen:{} dummy := incharety (1);{} code (incharety (1)).{} drittes zeichen:{} dummy := incharety (1);{} dummy := incharety (1);{} code (incharety (1)).{}END PROC kanalkoppler;{}PROC interface kanal (INT CONST kanalnummer):{} enable stop;{} IF kanalnummer < 1 OR kanalnummer > 24{} THEN errorstop ("Unzulaessige Kanalnummer"){} ELSE interface channel := kanalnummer{}
+ FI{}END PROC interface kanal;{}INT PROC interface kanal:{} interface channel{}END PROC interface kanal;{}PROC oeffne interface direkt (INT VAR status):{} leere puffer;{} out (interface test code);{} fange antwort;{} IF antwort = interface okay code{} THEN status := 0;{} out (interface open code){} ELSE status := interface error code{} FI.{} leere puffer:{} REP UNTIL incharety = "" PER.{} fange antwort:{} INT VAR zaehler;{} TEXT VAR antwort :: "";{} FOR zaehler FROM 1 UPTO erwartete zeichen REP{}
+ antwort CAT incharety (1){} PER.{}END PROC oeffne interface direkt;{}PROC schliesse interface direkt:{} out (interface close code){}END PROC schliesse interface direkt;{}PROC initialisiere interface direkt:{} schalte alles aus.{} schalte alles aus:{} INT VAR kanalnummer, kanalbetriebsart;{} FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{} kanalbetriebsart := kanal [kanalnummer].betriebsart;{} IF kanalbetriebsart = digital aus{} THEN direkt ausgeben (kanalnummer, 0){}
+ ELIF kanalbetriebsart = analog aus{} THEN direkt ausgeben (kanalnummer, gewandelte nullspannung){} FI{} PER.{} gewandelte nullspannung:{} int(- real (ganzzahl obergrenze) * u min / (u max - u min) + 0.5).{} u max : spannung [kanalnummer].maximalwert.{} u min : spannung [kanalnummer].minimalwert.{}END PROC initialisiere interface direkt;{}PROC direkt ausgeben (INT CONST kanalnummer, wert):{} out (kanal [kanalnummer].steuercode);{} out (code (wert)){}END PROC direkt ausgeben;{}
+INT PROC direkt eingabe (INT CONST kanalnummer):{} gib lesecode aus;{} erhaltene antwort.{} gib lesecode aus:{} out (kanal [kanalnummer].steuercode).{} erhaltene antwort:{} TEXT VAR dummy;{} SELECT kanal [kanalnummer].taktzahl OF{} CASE 1 : erstes zeichen{} CASE 2 : zweites zeichen{} CASE 3 : drittes zeichen{} OTHERWISE -1{} END SELECT.{} erstes zeichen:{} code (incharety (1)).{} zweites zeichen:{} dummy := incharety (1);{} code (incharety (1)).{}
+ drittes zeichen:{} dummy := incharety (1);{} dummy := incharety (1);{} code (incharety (1)).{}END PROC direkt eingabe;{}PROC initialisiere die kanaele:{} INT VAR kanalnummer;{} FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{} trage kanaldaten ein (kanalnummer, keine spannung, leere karte);{} vorherige ausgabe [kanalnummer] := 0{} PER.{} keine spannung:{} ROW 2 REAL : (0.0, 0.0).{} leere karte:{} ROW 3 INT : (nicht belegt, 0, 0).{}END PROC initialisiere die kanaele;{}
+initialisiere die kanaele;{}END PACKET ls prozess 1{}
+
diff --git a/prozess/ls-Prozess 1 für MUFI im Terminalkanal b/prozess/ls-Prozess 1 für MUFI im Terminalkanal
new file mode 100644
index 0000000..d1edbc1
--- /dev/null
+++ b/prozess/ls-Prozess 1 für MUFI im Terminalkanal
@@ -0,0 +1,55 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Prozess 1 **
+ ** **
+ ** Anpassung für MUFI im Terminalkanal **
+ ** **
+ ** Version 1.02 **
+ ** **
+ ** (Stand : 26.01.90) **
+ ** **
+ ** **
+ ** Autoren: Bruno Pollok, Bielefeld **
+ ** Wolfgang Weber, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET altes incharety DEFINES old incharety:
+TEXT PROC old incharety:{} incharety{}END PROC old incharety;{}TEXT PROC old incharety (INT CONST timelimit):{} incharety (timelimit){}END PROC old incharety;{}END PACKET altes incharety;{}PACKET ls prozess 1 DEFINES{} run pdv,{} run pdv again,{} initialisiere interface,{} ausgeben,{} eingabe,{} warte,{} abbruch gewuenscht,{} tue nichts,{} trage kanaldaten ein,{} beende kanaldaten eintragen,{} hole spannungsbereich,{} letzte ausgabe,{}
+ pruefe kanal,{} pruefe abbruch,{} teste interface,{} schalte alles aus,{} oeffne interface,{} schliesse interface,{} nicht belegt,{} digital aus,{} analog aus,{} digital ein,{} analog ein,{} kanalbreite,{} ganzzahl obergrenze,{} adapterart,{} incharety,{} inchar,{} pause:{}(******************** A N P A S S U N G A N M U F I ********************){}LET mufikennung = ""31""31"",{} erwartete zeichen = 4 ;{}
+TEXT CONST adapterart :: "MUFI im Terminalkanal",{} interface test code :: ""27""27"10",{} interface okay code :: ""27""27"00",{} interface open code :: ""27""27"1C" + hex (mufikennung),{} interface close code :: mufikennung + "1C" + hex (""27""27""),{} adresse 0 code :: mufikennung + "3D",{} leertakt code :: mufikennung + "3E",{} interface write code :: mufikennung + "5" ,{} interface read code :: mufikennung + "4" ;{}
+TEXT VAR puffer :: "";{}ROW 256 TEXT CONST hexcode :: ROW 256 TEXT : ({}"00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",{}"10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",{}"20","21","22","23","24","25","26","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",{}"40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",{}"50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",{}
+"60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",{}"70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",{}"80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",{}"90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",{}"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",{}"B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",{}"C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",{}
+"D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",{}"E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",{}"F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF");{}TEXT PROC interface anpassung (INT CONST kanalnummer, steuerungscode):{} LET hexzeichen = "0123456789ABCDEF";{} IF es ist ein ausgabekanal{} THEN interface write code{} + (hexzeichen SUB (device + 4 * steuerungscode)){} ELIF es ist ein eingabekanal{}
+ THEN lesecode in abhaengigkeit von der taktzahl{} ELSE ""{} FI.{} es ist ein ausgabekanal:{} kanal [kanalnummer].betriebsart < 0.{} es ist ein eingabekanal:{} kanal [kanalnummer].betriebsart > 0.{} device:{} IF kanalnummer < 10{} THEN 1{} ELSE kanalnummer DIV 10{} FI.{} lesecode in abhaengigkeit von der taktzahl:{} SELECT kanal [kanalnummer].taktzahl OF{} CASE 1: lesecode{} CASE 2: adresse 0 code + lesecode + lesecode{} CASE 3: adresse 0 code + lesecode + zwei weitere takte{}
+ OTHERWISE "" END SELECT.{} lesecode:{} interface read code + (hexzeichen SUB (device + 4 * steuerungscode)).{} zwei weitere takte:{} IF leertakt code = ""{} THEN lesecode + lesecode{} ELSE kanal [kanalnummer].taktzahl DECR 1;{} leertakt code + lesecode{} FI.{}END PROC interface anpassung;{}PROC ausgeben (INT CONST kanalnummer, wert):{} merke wert;{} gib wert aus.{} merke wert:{} vorherige ausgabe [kanalnummer] := wert.{} gib wert aus:{} out (kanal [kanalnummer].steuercode);{}
+ out (hexcode [wert + 1]).{}END PROC ausgeben;{}INT PROC eingabe (INT CONST kanalnummer):{} gib lesecode aus;{} erhaltene antwort.{} gib lesecode aus:{} out (kanal [kanalnummer].steuercode).{} erhaltene antwort:{} TEXT VAR dummy;{} SELECT kanal [kanalnummer].taktzahl OF{} CASE 1 : erste sendung{} CASE 2 : zweite sendung{} CASE 3 : dritte sendung{} OTHERWISE -1{} END SELECT.{} erste sendung:{} fange mufikennung;{} dezimalwert (old incharety (1), old incharety (1)).{}
+ zweite sendung:{} fange mufikennung;{} dummy := old incharety (1);{} dummy := old incharety (1);{} erste sendung.{} dritte sendung:{} fange mufikennung;{} dummy := old incharety (1);{} dummy := old incharety (1);{} zweite sendung.{} fange mufikennung:{} puffer CAT old incharety;{} REP puffer CAT old incharety{} UNTIL pos (puffer, mufikennung) > 0 PER;{} puffer := subtext (puffer, 1, length (puffer) - 2).{}END PROC eingabe;{}(************ H A R D W A R E U N A B H Ä N G I G E R T E I L ************){}
+LET max kanalanzahl = 49,{} endezeichen = "q",{} abbruchzeichen = "h",{} esc = ""27"";{}INT CONST analog aus :: -2, (* Betriebsarten *){} digital aus :: -1,{} nicht belegt :: 0,{} digital ein :: 1,{} analog ein :: 2,{} kanalbreite :: 8,{} ganzzahl obergrenze :: 2 ** kanalbreite,{}
+ configuration error code :: -1,{} interface error code :: -4;{}TEXT VAR meldung :: "";{}BOOL VAR kanaldaten sind eingetragen :: FALSE,{} endezeichen gegeben :: FALSE,{} programm mit pdv gestartet :: FALSE,{} fehler zu melden :: FALSE;{}TYPE KANAL = STRUCT (INT betriebsart, taktzahl, TEXT steuercode),{} SPANNUNG = STRUCT (REAL minimalwert, maximalwert);{}ROW max kanalanzahl INT VAR vorherige ausgabe;{}
+ROW max kanalanzahl KANAL VAR kanal;{}ROW max kanalanzahl SPANNUNG VAR spannung;{}PROC run pdv:{} run pdv (last param){}END PROC run pdv;{}PROC run pdv (TEXT CONST programmname):{} enable stop;{} last param (programmname);{} programm mit pdv gestartet := TRUE;{} teste interface;{} disable stop;{} run (programmname);{} IF is error{} THEN fehlerbehandlung{} ELSE melde programmende{} FI;{} schliesse interface;{} programm mit pdv gestartet := FALSE;{} enable stop;{} IF fehler zu melden{}
+ THEN errorstop (meldung){} FI{}END PROC run pdv;{}PROC run pdv again:{} enable stop;{} programm mit pdv gestartet := TRUE;{} teste interface;{} disable stop;{} run again;{} IF is error{} THEN fehlerbehandlung{} ELSE melde programmende{} FI;{} schliesse interface;{} programm mit pdv gestartet := FALSE;{} enable stop;{} IF fehler zu melden{} THEN errorstop (meldung){} FI{}END PROC run pdv again;{}PROC melde programmende:{} page;{} menufootnote ("Programmende! Zum Weitermachen bitte irgendeine Taste tippen.");{}
+ pause;{} schalte alles aus{}END PROC melde programmende;{}PROC initialisiere interface:{} enable stop;{} pruefe abbruch;{} IF programm mit pdv gestartet{} THEN schalte alles aus{} ELSE errorstop ("PDV-Programme müssen mit 'run pdv' gestartet werden!"){} FI{}END PROC initialisiere interface;{}PROC schalte alles aus:{} INT VAR kanalnummer, kanalbetriebsart;{} FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{} kanalbetriebsart := kanal [kanalnummer].betriebsart;{} IF kanalbetriebsart = digital aus{}
+ THEN ausgeben (kanalnummer, 0){} ELIF kanalbetriebsart = analog aus{} THEN ausgeben (kanalnummer, gewandelte nullspannung){} FI{} PER.{} gewandelte nullspannung:{} int(- real (ganzzahl obergrenze) * u min / (u max - u min) + 0.5).{} u max : spannung [kanalnummer].maximalwert.{} u min : spannung [kanalnummer].minimalwert.{}END PROC schalte alles aus;{}PROC warte (REAL CONST sekunden):{} TEXT VAR eingabe;{} pruefe abbruch;{} eingabe := incharety (int (sekunden * 10.0 + 0.5));{}
+ IF eingabe = esc{} THEN untersuche naechstes zeichen{} FI.{} untersuche naechstes zeichen:{} eingabe := incharety (30);{} IF eingabe = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF eingabe = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){} FI.{}END PROC warte;{}PROC warte (INT CONST sekunden):{} TEXT VAR eingabe;{} pruefe abbruch;{} eingabe := incharety (sekunden * 10);{} IF eingabe = esc{}
+ THEN untersuche naechstes zeichen{} FI.{} untersuche naechstes zeichen:{} eingabe := incharety (30);{} IF eingabe = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF eingabe = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){} FI.{}END PROC warte;{}TEXT PROC incharety:{} IF puffer = ""{} THEN old incharety{} ELSE erstes zeichen von puffer{} FI.{} erstes zeichen von puffer:{} TEXT CONST zeichen :: puffer SUB 1;{}
+ puffer := subtext (puffer, 2);{} zeichen.{}END PROC incharety;{}TEXT PROC incharety (INT CONST timelimit):{} IF puffer = ""{} THEN old incharety (timelimit){} ELSE erstes zeichen von puffer{} FI.{} erstes zeichen von puffer:{} TEXT CONST zeichen :: puffer SUB 1;{} puffer := subtext (puffer, 2);{} zeichen.{}END PROC incharety;{}PROC inchar (TEXT VAR character):{} REP character := incharety{} UNTIL character <> "" PER{}END PROC inchar;{}PROC pause:{} TEXT VAR dummy;{} inchar (dummy){}
+END PROC pause;{}PROC pause (INT CONST timelimit):{} TEXT VAR dummy := incharety (timelimit){}END PROC pause;{}BOOL PROC abbruch gewuenscht:{} pruefe abbruch;{} BOOL VAR entscheidung :: endezeichen gegeben;{} endezeichen gegeben := FALSE;{} entscheidung{}END PROC abbruch gewuenscht;{}PROC tue nichts:{} pruefe abbruch{}END PROC tue nichts;{}PROC trage kanaldaten ein (INT CONST kanalnummer,{} ROW 2 REAL CONST spannungsbereich,{} ROW 3 INT CONST kanalparameter):{}
+ spannung [kanalnummer].minimalwert := spannungsbereich [1];{} spannung [kanalnummer].maximalwert := spannungsbereich [2];{} kanal [kanalnummer].betriebsart := kanalparameter [1];{} kanal [kanalnummer].taktzahl := kanalparameter [2];{} kanal [kanalnummer].steuercode := interface anpassung{} (kanalnummer, kanalparameter [3]){}END PROC trage kanaldaten ein;{}PROC beende kanaldaten eintragen:{} kanaldaten sind eingetragen := TRUE{}END PROC beende kanaldaten eintragen;{}
+PROC hole spannungsbereich (INT CONST kanalnummer, REAL VAR u min, u max):{} u min := spannung [kanalnummer].minimalwert;{} u max := spannung [kanalnummer].maximalwert{}END PROC hole spannungsbereich;{}INT PROC letzte ausgabe (INT CONST kanalnummer):{} vorherige ausgabe [kanalnummer]{}END PROC letzte ausgabe;{}PROC pruefe kanal (INT CONST kanalnummer, gewuenschte betriebsart):{} pruefe abbruch;{} pruefe kanalnummer;{} pruefe betriebsart.{} pruefe kanalnummer:{} IF kanalnummer < 1 OR kanalnummer > max kanalanzahl{}
+ THEN errorstop ("Kanalnummer " + text (kanalnummer) +{} " ist unzulaessig !"){} FI.{} pruefe betriebsart:{} IF gewuenschte betriebsart <> kanal [kanalnummer].betriebsart{} THEN errorstop ("An Kanal " + text (kanalnummer) +{} " keine " + wunsch + " moeglich!"){} FI.{} wunsch:{} IF gewuenschte betriebsart = analog aus{} THEN "Analog-Ausgabe"{} ELIF gewuenschte betriebsart = digital aus{} THEN "Digital-Ausgabe"{}
+ ELIF gewuenschte betriebsart = digital ein{} THEN "Digital-Eingabe"{} ELIF gewuenschte betriebsart = analog ein{} THEN "Analog-Eingabe"{} ELSE "Ein- oder Ausgabe"{} FI.{}END PROC pruefe kanal;{}PROC pruefe abbruch:{} TEXT VAR zeichen :: incharety;{} IF zeichen = esc{} THEN pruefe weiter{} FI.{} pruefe weiter:{} zeichen := incharety (30);{} IF zeichen = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF zeichen = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{}
+ + abbruchzeichen + ">!"){} FI.{}END PROC pruefe abbruch;{}PROC oeffne interface (INT VAR status):{} enable stop;{} IF kanaldaten sind eingetragen{} THEN teste interface funktion{} ELSE status := configuration error code{} FI.{} teste interface funktion:{} leere puffer;{} out (interface test code);{} fange antwort;{} IF antwort = interface okay code{} THEN status := 0;{} out (interface open code){} ELSE status := interface error code{}
+ FI.{} leere puffer:{} puffer := "";{} REP UNTIL old incharety = "" PER.{} fange antwort:{} INT VAR zaehler;{} TEXT VAR antwort :: "";{} FOR zaehler FROM 1 UPTO erwartete zeichen REP{} antwort CAT old incharety (1){} PER.{}END PROC oeffne interface;{}PROC schliesse interface:{} enable stop;{} out (interface close code){}END PROC schliesse interface;{}(********************* H I L F S P R O Z E D U R E N *********************){}PROC teste interface:{} INT VAR test;{}
+ warte etwas;{} oeffne interface (test);{} IF test < 0{} THEN errorstop (fehlermeldung){} ELSE endezeichen gegeben := FALSE;{} fehler zu melden := FALSE{} FI.{} warte etwas:{} pause (1); pause (1); pause (1); pause (1); pause (1).{} fehlermeldung:{} IF test = configuration error code{} THEN "Interface ist noch nicht konfiguriert!"{} ELIF test = interface error code{} THEN "Interface meldet sich nicht!"{} ELSE "Interface kann nicht geöffnet werden!"{}
+ FI.{}END PROC teste interface;{}PROC fehlerbehandlung:{} meldung := errormessage;{} IF meldung <> ""{} THEN meldung CAT fehlerzeile;{} fehler zu melden := TRUE{} FI;{} clear error;{} initialisiere interface.{} fehlerzeile:{} IF errorline = 0{} THEN ""{} ELSE " (bei Zeile " + text (errorline) + ")"{} FI.{}END PROC fehlerbehandlung;{}INT PROC dezimalwert (TEXT CONST zeichen 1, zeichen 2):{} 16 * pos (hexzeichen, zeichen 1) + pos (hexzeichen, zeichen 2).{} hexzeichen: "123456789ABCDEF".{}
+END PROC dezimalwert;{}TEXT PROC hex (TEXT CONST zwei zeichen):{} hex (code (zwei zeichen SUB 1)) + hex (code (zwei zeichen SUB 2)){}END PROC hex;{}TEXT PROC hex (INT CONST wert):{} (hexzeichen SUB (wert DIV 16 + 1)) + (hexzeichen SUB (wert MOD 16 + 1)).{} hexzeichen: "0123456789ABCDEF".{}END PROC hex;{}PROC initialisiere die kanaele:{} INT VAR kanalnummer;{} FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{} trage kanaldaten ein (kanalnummer, keine spannung, leere karte);{} vorherige ausgabe [kanalnummer] := 0{}
+ PER.{} keine spannung:{} ROW 2 REAL : (0.0, 0.0).{} leere karte:{} ROW 3 INT : (nicht belegt, 0, 0).{}END PROC initialisiere die kanaele;{}initialisiere die kanaele{}END PACKET ls prozess 1{}
+
diff --git a/prozess/ls-Prozess 2 b/prozess/ls-Prozess 2
new file mode 100644
index 0000000..11cb4e7
--- /dev/null
+++ b/prozess/ls-Prozess 2
@@ -0,0 +1,39 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Prozess 2 **
+ ** **
+ ** Version 1.02 **
+ ** **
+ ** (Stand : 06.06.89) **
+ ** **
+ ** **
+ ** **
+ ** Autoren: Bruno Pollok, Bielefeld **
+ ** Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls prozess 2 DEFINES
+ wert an analogausgang ausgeben,{} spannungswert ausgeben,{} bitsymbol ausgeben,{} bitmuster ausgeben,{} dezimalwert ausgeben,{} bitmuster gleich,{} bit ist gesetzt,{} wert von analogeingang,{} spannungswert,{} bitsymbol,{} bitmuster,{} dezimalwert:{}LET eins = "I",{} null = "O",{} invers = "T",{} egal = "X";{}REAL CONST maximalwert :: real (ganzzahl obergrenze - 1);{}(********************* A U S G A B E - B E F E H L E *********************){}
+PROC wert an analogausgang ausgeben (INT CONST kanal, wert):{} pruefe kanal (kanal, analog aus);{} ausgeben (kanal, wert MOD ganzzahlobergrenze){}END PROC wert an analogausgang ausgeben;{}PROC spannungswert ausgeben (INT CONST kanal, REAL CONST wert):{} pruefe kanal (kanal, analog aus);{} pruefe spannungswert;{} ausgeben (kanal, gewandelte spannung).{} pruefe spannungswert:{} REAL VAR u min, u max;{} hole spannungsbereich (kanal, u min, u max);{} IF wert < u min OR wert > u max{} THEN errorstop ("Der Spannungswert " + text (wert) +{}
+ " ist nicht zulaessig!"){} FI.{} gewandelte spannung:{} int (((wert - u min) * maximalwert) / (u max - u min) + 0.5).{}END PROC spannungswert ausgeben;{}PROC bitsymbol ausgeben (INT CONST kanal, bitnummer, TEXT CONST zeichen):{} pruefe kanal (kanal, digital aus);{} pruefe bitnummer (bitnummer);{} ausgeben (kanal, relativer dezimalwert (zeichen, bitnummer, kanal)){}END PROC bitsymbol ausgeben;{}PROC bitmuster ausgeben (INT CONST kanal, TEXT CONST zeichenkette):{}
+ pruefe kanal (kanal, digital aus);{} ausgeben (kanal, relativer dezimalwert (zeichenkette, kanal)){}END PROC bitmuster ausgeben;{}PROC dezimalwert ausgeben (INT CONST kanal, wert):{} pruefe kanal (kanal, digital aus);{} ausgeben (kanal, wert MOD ganzzahl obergrenze){}END PROC dezimalwert ausgeben;{}(********************* E I N G A B E - B E F E H L E *********************){}BOOL PROC bitmuster gleich (INT CONST kanal, TEXT CONST zeichenkette):{} INT CONST eingabewert :: dezimalwert (kanal);{}
+ pruefe zeichenkette;{} eingabe passt zur zeichenkette.{} pruefe zeichenkette:{} IF length (zeichenkette) <> kanalbreite{} THEN errorstop ("Das Bitmuster '" + zeichenkette +{} "' hat eine unzulaessige Laenge!"){} FI.{} eingabe passt zur zeichenkette:{} INT VAR stelle;{} BOOL VAR abweichung gefunden :: FALSE;{} FOR stelle FROM 1 UPTO kanalbreite REP{} teste bit an dieser stelle{} UNTIL abweichung gefunden PER;{} NOT abweichung gefunden.{} teste bit an dieser stelle:{}
+ TEXT CONST einzelbit :: zeichenkette SUB stelle;{} IF einzelbit = eins{} THEN teste eingabebit auf eins{} ELIF einzelbit = null{} THEN teste eingabebit auf null{} ELIF einzelbit = egal{} THEN eingabebit ist beliebig{} ELSE errorstop ("'" + einzelbit + "' ist unzulaessiges " +{} "Bitsymbol in '" + zeichenkette + "'!"){} FI.{} teste eingabebit auf eins:{} IF NOT bit (eingabewert, kanalbreite - stelle){} THEN abweichung gefunden := TRUE{} FI.{}
+ teste eingabebit auf null:{} IF bit (eingabewert, kanalbreite - stelle){} THEN abweichung gefunden := TRUE{} FI.{} eingabebit ist beliebig:{} .{}END PROC bitmuster gleich;{}BOOL PROC bit ist gesetzt (INT CONST kanal, bitnummer):{} pruefe kanal (kanal, digital ein);{} pruefe bitnummer (bitnummer);{} IF bit (eingabe (kanal), bitnummer){} THEN TRUE{} ELSE FALSE{} FI{}END PROC bit ist gesetzt;{}INT PROC wert von analogeingang (INT CONST kanal):{} pruefe kanal (kanal, analog ein);{}
+ eingabe (kanal){}END PROC wert von analogeingang;{}REAL PROC spannungswert (INT CONST kanal):{} INT CONST dezimalwert :: wert von analogeingang (kanal);{} REAL VAR u min, u max;{} hole spannungsbereich (kanal, u min, u max);{} round (real (dezimalwert) * (u max - u min) / maximalwert + u min, 3){}END PROC spannungswert;{}TEXT PROC bitsymbol (INT CONST kanal, bitnummer):{} pruefe kanal (kanal, digital ein);{} pruefe bitnummer (bitnummer);{} IF bit (eingabe (kanal), bitnummer){} THEN eins{}
+ ELSE null{} FI{}END PROC bitsymbol;{}TEXT PROC bitmuster (INT CONST kanal):{} TEXT VAR zeichenkette :: "";{} INT CONST wert :: dezimalwert (kanal);{} wandle wert;{} zeichenkette.{} wandle wert:{} INT VAR zeiger;{} FOR zeiger FROM kanalbreite - 1 DOWNTO 0 REP{} IF bit (wert, zeiger){} THEN zeichenkette CAT eins{} ELSE zeichenkette CAT null{} FI{} PER.{}END PROC bitmuster;{}INT PROC dezimalwert (INT CONST kanal):{} pruefe kanal (kanal, digital ein);{}
+ eingabe (kanal){}END PROC dezimalwert;{}(******************** H I L F S - P R O Z E D U R E N ********************){}INT PROC relativer dezimalwert (TEXT CONST zeichenkette, INT CONST kanal):{} INT VAR wert := letzte ausgabe (kanal);{} pruefe zeichenkette auf korrekte laenge;{} veraendere alten wert;{} wert.{} pruefe zeichenkette auf korrekte laenge:{} IF length (zeichenkette) <> kanalbreite{} THEN errorstop ("Bitmuster '" + zeichenkette + "' hat "{} + "unzulaessige Laenge!"){}
+ FI.{} veraendere alten wert:{} INT VAR zeiger;{} FOR zeiger FROM 1 UPTO kanalbreite REP{} veraendere dieses bit{} PER.{} veraendere dieses bit:{} TEXT CONST einzelbit :: zeichenkette SUB zeiger;{} IF einzelbit = eins THEN setze bit{} ELIF einzelbit = null THEN loesche bit{} ELIF einzelbit = invers THEN invertiere bit{} ELIF einzelbit = egal THEN lasse bit{} ELSE errorstop ("'" + einzelbit + "' ist unzulaessiges " +{} "Bitsymbol in '" + zeichenkette + "'!"){}
+ FI.{} setze bit:{} set bit (wert, kanalbreite - zeiger).{} loesche bit:{} reset bit (wert, kanalbreite - zeiger).{} invertiere bit:{} IF bit (wert, kanalbreite - zeiger){} THEN loesche bit{} ELSE setze bit{} FI.{} lasse bit:{} .{} END PROC relativer dezimalwert;{}INT PROC relativer dezimalwert (TEXT CONST bitzeichen,{} INT CONST bitnummer, kanal):{} INT VAR wert :: letzte ausgabe (kanal);{} IF bitzeichen = eins THEN setze bit{}
+ ELIF bitzeichen = null THEN loesche bit{} ELIF bitzeichen = invers THEN invertiere bit{} ELIF bitzeichen = egal THEN lasse bit{} ELSE errorstop ("'" + bitzeichen + "' ist ein unzulaessiges " +{} "Bitsymbol!"){} FI;{} wert.{} setze bit:{} set bit (wert, bitnummer).{} loesche bit:{} reset bit (wert, bitnummer).{} invertiere bit:{} IF bit (wert, bitnummer){} THEN loesche bit{} ELSE setze bit{} FI.{} lasse bit:{}
+ .{}END PROC relativer dezimalwert;{}PROC pruefe bitnummer (INT CONST bitnummer):{} IF bitnummer < 0 OR bitnummer > kanalbreite - 1{} THEN errorstop ("Bitnummer " + text (bitnummer) +{} " ist nicht zulaessig!"){} FI{}END PROC pruefe bitnummer{}END PACKET ls prozess 2{}
+
diff --git a/prozess/ls-Prozess 3 b/prozess/ls-Prozess 3
new file mode 100644
index 0000000..28ef825
--- /dev/null
+++ b/prozess/ls-Prozess 3
@@ -0,0 +1,26 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Prozess 3 **
+ ** **
+ ** Version 1.02 **
+ ** **
+ ** (Stand : 06.06.89) **
+ ** **
+ ** **
+ ** **
+ ** Autoren: Bruno Pollok, Bielefeld **
+ ** Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls prozess 3 DEFINES
+ temperatur:{}LET thermometerkonstante = 50.0,{} minimaltemperatur = 10.0;{}REAL PROC temperatur (REAL CONST spannungswert):{} spannungswert * thermometerkonstante - minimaltemperatur{}END PROC temperatur{}END PACKET ls prozess 3{}
+
diff --git a/prozess/ls-Prozess 4 b/prozess/ls-Prozess 4
new file mode 100644
index 0000000..158b548
--- /dev/null
+++ b/prozess/ls-Prozess 4
@@ -0,0 +1,61 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Prozess 4 **
+ ** **
+ ** Version 1.02 **
+ ** **
+ ** (Stand : 26.01.90) **
+ ** **
+ ** **
+ ** **
+ ** Autoren: Bruno Pollok, Bielefeld **
+ ** Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls prozess 4 DEFINES
+ pdv befehlsuebersicht anzeigen,{} pdv ausgabebefehle anzeigen,{} pdv eingabebefehle anzeigen,{} pdv testbefehle anzeigen,{} pdv weitere befehle anzeigen,{} pdv bitmuster erlaeutern,{} pdv symbole erlaeutern,{} pdv digital analog werte,{} pdv programm neu erstellen,{} pdv programm ansehen,{} pdv programm starten,{} pdv programm wiederholen,{} pdv dateien verzeichnis,{}
+ pdv datei kopieren,{} pdv datei umbenennen,{} pdv dateien loeschen,{} pdv dateien drucken,{} init pdv,{} pdv:{}LET menukarte = "ls-MENUKARTE:Prozess",{} niltext = "",{} maxlaenge = 45,{} maxnamenslaenge = 35;{}WINDOW VAR w :: window (1, 3, 79, 19);{}TEXT VAR programmname :: "";{}BOOL VAR noch kein programm gelaufen :: TRUE;{}PROC pdv:{} init pdv;{} install menu (menukarte, FALSE);{}
+ handle menu ("PDV"){}END PROC pdv;{}PROC init pdv:{} programmname := "";{} noch kein programm gelaufen := TRUE;{} cursor off;{}END PROC init pdv;{}PROC pdv befehlsuebersicht anzeigen:{} menuinfo (anwendungstext (20)){}END PROC pdv befehlsuebersicht anzeigen;{}PROC pdv ausgabebefehle anzeigen:{} INT VAR i;{} REP{} i := menualternative (anwendungstext (1), anwendungstext (3),{} anwendungstext (4), 5, TRUE);{} SELECT i OF{} CASE 1, 101: menuinfo (anwendungstext (21)){}
+ CASE 2, 102: menuinfo (anwendungstext (22)){} CASE 3, 103: menuinfo (anwendungstext (23)){} CASE 4, 104: menuinfo (anwendungstext (24)){} CASE 5, 105: menuinfo (anwendungstext (25)){} END SELECT{} UNTIL i = 6 OR i = 106 PER;{}END PROC pdv ausgabebefehle anzeigen;{}PROC pdv eingabebefehle anzeigen:{} INT VAR i;{} REP{} i := menualternative (anwendungstext (2), anwendungstext (3),{} anwendungstext (4), 5, TRUE);{} SELECT i OF{} CASE 1, 101: menuinfo (anwendungstext (31)){}
+ CASE 2, 102: menuinfo (anwendungstext (32)){} CASE 3, 103: menuinfo (anwendungstext (33)){} CASE 4, 104: menuinfo (anwendungstext (34)){} CASE 5, 105: menuinfo (anwendungstext (35)){} END SELECT{} UNTIL i = 6 OR i = 106 PER;{}END PROC pdv eingabebefehle anzeigen;{}PROC pdv testbefehle anzeigen:{} INT VAR i;{} REP{} i := menualternative (anwendungstext (5), anwendungstext (7),{} anwendungstext (8), 5, TRUE);{} SELECT i OF{} CASE 1, 101: menuinfo (anwendungstext (41)){}
+ CASE 2, 102: menuinfo (anwendungstext (42)){} END SELECT{} UNTIL i = 3 OR i = 103 PER;{}END PROC pdv testbefehle anzeigen;{}PROC pdv weitere befehle anzeigen:{} INT VAR i;{} REP{} i := menualternative (anwendungstext (6), anwendungstext (7),{} anwendungstext (8), 5, TRUE);{} SELECT i OF{} CASE 1, 101: menuinfo (anwendungstext (43)){} CASE 2, 102: menuinfo (anwendungstext (44)){} END SELECT{} UNTIL i = 3 OR i = 103 PER;{}END PROC pdv weitere befehle anzeigen;{}
+PROC pdv bitmuster erlaeutern:{} menuinfo (anwendungstext (46)){}END PROC pdv bitmuster erlaeutern;{}PROC pdv symbole erlaeutern:{} menuinfo (anwendungstext (47)){}END PROC pdv symbole erlaeutern;{}PROC pdv digital analog werte:{} menuinfo (anwendungstext (48)){}END PROC pdv digital analog werte;{}PROC pdvdateien verzeichnis:{} disable stop;{} forget ("Verzeichnis der Dateien", quiet);{} THESAURUS VAR programme :: ALL myself;{} FILE VAR f ::{} sequential file (output, "Verzeichnis der Dateien");{}
+ f FILLBY programme;{} modify (f);{} to line (f, 1); insert record (f);{} menufootnote ("Verlassen: <ESC> <q>");{} cursor on;{} show (w, f);{} cursor off;{} forget ("Verzeichnis der Dateien", quiet);{} IF is error{} THEN regenerate menuscreen;{} out (""7"");{} menuinfo (" " + invers ("FEHLER: " + errormessage));{} clear error{} ELSE menu bildschirm{} FI;{} enable stop{}END PROC pdvdateien verzeichnis;{}PROC pdvprogramm neu erstellen:{} hole programmname;{}
+ kontrolliere den programmnamen;{} command dialogue (FALSE);{} cursor on;{} disable stop;{} stdinfoedit (programmname, 3);{} cursor off;{} command dialogue (TRUE);{} IF is error{} THEN regenerate menuscreen;{} out (""7"");{} menuinfo (" " + invers (errormessage));{} clear error{} ELSE menu bildschirm{} FI;{} enable stop.{} hole programmname:{} programmname := "";{} programmname := menuanswer (ausgabe, programmname, 5).{} ausgabe:{} center (maxlaenge, invers ("Programm neu erstellen")) + ""13""13""{}
+ + " Bitte den Namen für das Programm "13""13"".{} kontrolliere den programmnamen:{} IF programmname = niltext{} THEN LEAVE pdvprogramm neu erstellen{} ELIF length (programmname) > maxnamenslaenge{} THEN meckere zu langen namen an;{} programmname := niltext;{} LEAVE pdvprogramm neu erstellen{} ELIF exists (programmname){} THEN meckere existierendes programm an;{} LEAVE pdvprogramm neu erstellen{} FI.{}END PROC pdvprogramm neu erstellen;{}
+PROC pdvprogramm ansehen:{} IF programmname <> niltext CAND exists (programmname){} THEN frage nach diesem programm{} ELSE lasse programm auswaehlen{} FI;{} cursor on;{} disable stop;{} stdinfoedit (programmname, 3);{} cursor off;{} IF is error{} THEN regenerate menuscreen;{} out (""7"");{} menuinfo (" " + invers ("FEHLER: " + errormessage));{} clear error{} ELSE menu bildschirm{} FI;{} enable stop.{} frage nach diesem programm:{} IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " + name{}
+ + " Soll mit diesem Programm gearbeitet werden", 5){} THEN lasse programm auswaehlen{} FI.{} ueberschrift:{} center (maxlaenge, invers ("Programm ansehen/ändern")) + ""13""13"".{} name:{} ""13""13" " + invers (programmname) + ""13""13"".{} lasse programm auswaehlen:{} THESAURUS VAR verfuegbare :: ALL myself;{} IF NOT not empty (verfuegbare){} THEN noch kein programm;{} LEAVE pdvprogramm ansehen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{}
+ programmname := menuone (verfuegbare, "Programm ansehen/ändern",{} "Bitte das gewünschte Programm ankreuzen!",{} FALSE);{} IF programmname = niltext{} THEN menu bildschirm;{} LEAVE pdvprogramm ansehen{} FI.{}END PROC pdvprogramm ansehen;{}PROC pdvdateien drucken:{} lasse programme auswaehlen;{} drucke programme;{} menu bildschirm.{} lasse programme auswaehlen:{} THESAURUS VAR verfuegbare :: ALL myself;{} IF NOT not empty (verfuegbare){}
+ THEN noch kein programm;{} LEAVE pdvdateien drucken{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} verfuegbare := menusome (verfuegbare, "Dateien drucken",{} "Bitte die Dateien ankreuzen, die gedruckt werden sollen!",{} FALSE).{} drucke programme:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers ("Dateien drucken")));{} menuwindowline (2);{} command dialogue (FALSE);{}
+ fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (" Alle ausgewählten Dateien wurden gedruckt!");{} menuwindowstop.{} fuehre einzelne operationen aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{} IF name (verfuegbare, k) <> ""{} THEN disable stop;{} menuwindowout ( " """ + name (verfuegbare, k) +{} """ wird gedruckt!");{} menuwindowline;{}
+ print (name (verfuegbare, k));{} fehlerbehandlung{} FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN menuwindowline (2);{} menuwindowout (" Es wurde keine Datei ausgewählt!");{} menuwindowstop;{} menu bildschirm;{} LEAVE pdvdateien drucken{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){}
+ FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen; out (""7"");{} menuinfo (" " + invers (errormessage));{} clear error; enable stop;{} LEAVE pdvdateien drucken{} ELSE enable stop{} FI.{}END PROC pdvdateien drucken;{}PROC pdvdatei kopieren:{} ermittle alten programmnamen;{} erfrage neuen programmnamen;{} kopiere ggf das programm.{} ermittle alten programmnamen:{} IF NOT not empty (ALL myself){} THEN noch kein programm;{}
+ LEAVE pdvdatei kopieren{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} TEXT VAR alter name := menuone (ALL myself, "Datei kopieren",{} "Bitte die Datei ankreuzen, das kopiert werden soll!",FALSE);{} menu bildschirm;{} IF alter name = niltext{} THEN LEAVE pdvdatei kopieren{} FI.{} erfrage neuen programmnamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + " Name der 'alten' Datei: " + bisheriger name{}
+ + " Bitte den Namen für die Kopie: ".{} ueberschrift:{} center (maxlaenge, invers ("Datei kopieren")) + ""13""13"".{} bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{} kopiere ggf das programm:{} IF neuer name = niltext{} THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{} LEAVE pdvdatei kopieren{} ELIF exists (neuer name){} THEN mache vorwurf;{} LEAVE pdvdatei kopieren{} ELSE copy (alter name, neuer name){}
+ FI.{} mache vorwurf:{} menuinfo (" " + invers ("Eine Datei mit diesem Namen gibt es bereits!")).{}END PROC pdvdatei kopieren;{}PROC pdvdatei umbenennen:{} ermittle alten programmnamen;{} erfrage neuen programmnamen;{} benenne ggf das programm um.{} ermittle alten programmnamen:{} IF NOT not empty (ALL myself){} THEN noch kein programm;{} LEAVE pdvdatei umbenennen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} TEXT VAR alter name := menuone ( ALL myself, "Datei umbenennen",{}
+ "Bitte die Datei ankreuzen, die umbenannt werden soll!", FALSE);{} menu bildschirm;{} IF alter name = niltext{} THEN LEAVE pdvdatei umbenennen{} FI.{} erfrage neuen programmnamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + " Bisheriger Dateiname: " + bisheriger name{} + " Zukünftiger Dateiname: ".{} ueberschrift:{} center (maxlaenge, invers ("Datei umbenennen")) + ""13""13"".{} bisheriger name:{}
+ ""13""13" " + invers (alter name) + ""13""13"".{} benenne ggf das programm um:{} IF neuer name = niltext{} THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{} LEAVE pdvdatei umbenennen{} ELIF exists (neuer name){} THEN mache vorwurf;{} LEAVE pdvdatei umbenennen{} ELSE rename (alter name, neuer name);{} programmname := neuer name{} FI.{} mache vorwurf:{} menuinfo (" " + invers ("Eine Datei mit diesem Namen gibt es bereits!")).{}
+END PROC pdvdatei umbenennen;{}PROC pdvdateien loeschen:{} lasse programme auswaehlen;{} loesche programme;{} menu bildschirm.{} lasse programme auswaehlen:{} THESAURUS VAR verfuegbare :: ALL myself;{} IF NOT not empty (verfuegbare){} THEN noch kein programm;{} LEAVE pdvdateien loeschen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} verfuegbare := menusome (verfuegbare, "Dateien löschen",{} "Bitte alle Dateien ankreuzen, die gelöscht werden sollen!", FALSE).{}
+ loesche programme:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers ("Dateien löschen")));{} menuwindowline (2);{} command dialogue (FALSE);{} fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (" Alle ausgewählten Dateien wurden gelöscht!");{} menuwindowstop.{} fuehre einzelne operationen aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}
+ IF name (verfuegbare, k) <> ""{} THEN disable stop;{} IF menuwindowyes (" """ + name (verfuegbare, k) + """ löschen"){} THEN forget (name (verfuegbare, k), quiet){} FI;{} fehlerbehandlung{} FI{} PER;{} programmname := "".{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN menuwindowline (2);{} menuwindowout (" Es wurde keine Datei ausgewählt!");{} menuwindowstop;{}
+ menu bildschirm;{} LEAVE pdvdateien loeschen{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen; out (""7"");{} menuinfo (" " + invers (errormessage));{} clear error; enable stop;{} LEAVE pdvdateien loeschen{} ELSE enable stop{} FI.{}END PROC pdvdateien loeschen;{}
+PROC pdvprogramm starten:{} programmname ermitteln;{} bildschirm vorbereiten;{} cursor on;{} disable stop;{} warnings off;{} check on;{} run pdv (programmname);{} noch kein programm gelaufen := FALSE;{} cursor off;{} IF is error{} THEN fehler ggf melden;{} clear error{} ELSE regenerate menuscreen{} FI;{} enable stop.{} bildschirm vorbereiten:{} cursor (17, 2); out (waagerecht);{} cursor (38, 2); out (waagerecht);{} cursor ( 1, 3); out (""4"");{} menufootnote ("Programmabbruch: <ESC><h>");{}
+ cursor (1, 5);{} out ("Das Programm wird übersetzt. Zeilen-Nr.: ").{} fehler ggf melden:{} IF errormessage <> ""{} THEN fehler melden{} FI.{} fehler melden:{} IF pos (errormessage, "'halt' vom Terminal") > 0{} THEN regenerate menuscreen;{} out (""7""); menuinfo (" "15"'halt' vom Terminal "14""){} ELIF pos (errormessage, "Programm-Abbruch durch <ESC><h>") > 0{} THEN regenerate menuscreen;{} out (""7""); menuinfo (" "15"Programm-Abbruch durch <ESC><h> "14""){}
+ ELIF pos (errormessage, "(bei Zeile") > 0 AND exists (programmname){} THEN programm mit fehler im notebook zeigen;{} regenerate menuscreen{} ELSE regenerate menuscreen;{} out (""7""); menuinfo (" " + invers ("FEHLER: "{} + subtext (errormessage, 1, 61))){} FI.{} programm mit fehler im notebook zeigen:{} noteline;{} note ("FEHLER: " + errormessage);{} INT VAR n; FOR n FROM 1 UPTO 9 REP noteline PER;{} note (""15"Verlassen: <ESC><q> "14"");{}
+ FILE VAR p :: sequential file (modify, programmname);{} to line (p, max (1, fehlerzeile));{} col (1);{} clear error;{} out (""7"");{} cursor on;{} noteedit (p);{} cursor off.{} fehlerzeile:{} int (subtext (errormessage, zahlposition)).{} zahlposition: pos (errormessage, "(bei Zeile") + 10.{} programmname ermitteln:{} IF programmname <> niltext CAND exists (programmname){} THEN frage nach diesem programm{} ELSE lasse programm auswaehlen{} FI.{} frage nach diesem programm:{}
+ IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " +{} name + " Soll mit diesem Programm gearbeitet werden", 5){} THEN lasse programm auswaehlen{} FI.{} ueberschrift:{} center (maxlaenge, invers ("Programm starten")) + ""13""13"".{} name:{} ""13""13" " + invers (programmname) + ""13""13"".{} lasse programm auswaehlen:{} THESAURUS VAR verfuegbare :: ALL myself;{} IF NOT not empty (verfuegbare){} THEN noch kein programm;{} LEAVE pdvprogramm starten{}
+ ELSE biete auswahl an{} FI.{} biete auswahl an:{} programmname := menuone (verfuegbare, "Programm starten",{} "Bitte das gewünschte Programm ankreuzen!", FALSE);{} IF programmname = niltext{} THEN menubildschirm;{} LEAVE pdv programm starten{} FI.{}END PROC pdvprogramm starten;{}PROC pdv programm wiederholen:{} bildschirm vorbereiten;{} cursor on;{} disable stop;{} IF noch kein programm gelaufen{} THEN errorstop ("Eine Wiederholung ist nicht moeglich!"){}
+ ELSE run pdv again{} FI;{} cursor off;{} regenerate menuscreen;{} IF is error{} THEN zeige fehler;{} clear error{} FI;{} enable stop.{} bildschirm vorbereiten:{} cursor (17, 2); out (waagerecht);{} cursor (38, 2); out (waagerecht);{} cursor ( 1, 3); out (""4"");{} menufootnote ("Programmabbruch: <ESC><h>");{} cursor (1,3).{} zeige fehler:{} out (""7"");{} IF errormessage = "'run again' nicht moeglich"{} THEN menuinfo (" "15"Eine Wiederholung ist nicht moeglich! "14""){}
+ ELIF pos (errormessage, "'halt' vom Terminal") > 0{} THEN menuinfo (" "15"'halt' vom Terminal "14""){} ELIF pos (errormessage, "Programm-Abbruch durch <ESC><h>") > 0{} THEN menuinfo (" "15"Programm-Abbruch durch <ESC><h> "14""){} ELSE menuinfo (" " + invers ("FEHLER: "{} + subtext (errormessage, 1, 61))){} FI.{}END PROC pdv programm wiederholen;{}PROC meckere zu langen namen an:{} menuinfo (" " + invers ("Hier dürfen Namen höchstens "{} + text (max namenslaenge){}
+ + " Zeichen lang sein!")){}END PROC meckere zu langen namen an;{}PROC meckere existierendes programm an:{} menuinfo (" " + invers ("Ein Programm mit diesem Namen gibt es bereits!")){}END PROC meckere existierendes programm an;{}PROC noch kein programm:{} menuinfo (" " + invers ("Es existiert noch kein Programm!")){}END PROC noch kein programm;{}PROC menu bildschirm:{} cursor (1, 2);{} out (5 * waagerecht);{} cursor (1, 3);{} out (""4"");{} cursor (1,23);{} out (79 * waagerecht);{}
+ refresh submenu{}END PROC menu bildschirm{}END PACKET ls prozess 4{}
+
diff --git a/prozess/ls-Prozess 5 b/prozess/ls-Prozess 5
new file mode 100644
index 0000000..66bdf94
--- /dev/null
+++ b/prozess/ls-Prozess 5
@@ -0,0 +1,84 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Prozess 5 **
+ ** **
+ ** Version 1.02 **
+ ** **
+ ** (Stand : 26.01.90) **
+ ** **
+ ** **
+ ** **
+ ** Autoren: Bruno Pollok, Bielefeld **
+ ** Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls prozess 5 DEFINES
+ pdv konfiguration zugelassen,{} pdv konfiguration evtl aktivieren,{} pdv konfiguration zeigen,{} pdv kanal konfigurieren,{} pdv interfaceausgabe testen,{} pdv interfaceeingabe testen:{}LET max steckplaetze = 4,{} max portanzahl = 4,{} anzahl kartensorten = 5,{} betriebsart = 1,{} keine karte = 1,{} ea karte = 2,{} kombi = 3,{} da karte = 4,{} ad karte = 5,{}
+ compact = 6,{} einzel = 7,{} mehrfach = 8;{}LET testfenster x = 11,{} testfenster y = 5,{} testfenster xsize = 59,{} testfenster ysize = 15;{}WINDOW VAR testfenster :: window (testfenster x, testfenster y,{} testfenster xsize, testfenster ysize);{}INT VAR steckplatzart :: 0;{}BOOL VAR mit konfigurationsmoeglichkeit :: TRUE;{}TASK VAR konfigurationsmanager :: niltask;{}
+ROW max steckplaetze INT VAR kartenart :: ROW max steckplaetze INT :{} (keine karte, keine karte,{} keine karte, keine karte);{}LET SPANNUNG = ROW 2 REAL,{} PORT = ROW 3 INT,{} KARTE = ROW max portanzahl PORT;{}ROW anzahl kartensorten KARTE CONST karte :: ROW anzahl kartensorten KARTE :{}(* ---------------------------------------------------------------------- *){}( KARTE : ({}(* ---------------------------------------------------------------------- *){}
+(* *) PORT : (nicht belegt, 0, 0), (* Port 1 *){}(* leere *) PORT : (nicht belegt, 0, 0), (* Port 2 *){}(* Karte *) PORT : (nicht belegt, 0, 0), (* Port 3 *){}(* *) PORT : (nicht belegt, 0, 0)), (* Port 4 *){}(*----------------------------------------------------------------------- *){} KARTE : ({}(* ---------------------------------------------------------------------- *){}(* *) PORT : (digital ein, 1, 3), (* Port 1 *){}
+(* E/A *) PORT : (digital aus, 1, 1), (* Port 2 *){}(* Karte *) PORT : (digital ein, 1, 3), (* Port 3 *){}(* *) PORT : (digital aus, 1, 1)), (* Port 4 *){}(*----------------------------------------------------------------------- *){} KARTE : ({}(* ---------------------------------------------------------------------- *){}(* *) PORT : (analog ein, 2, 2), (* Port 1 *){}(* Kombi *) PORT : (analog ein, 3, 2), (* Port 2 *){}
+(* Karte *) PORT : (digital ein, 1, 3), (* Port 3 *){}(* *) PORT : (digital aus, 1, 1 )), (* Port 4 *){}(*----------------------------------------------------------------------- *){} KARTE : ({}(* ---------------------------------------------------------------------- *){}(* *) PORT : (analog aus, 1, 1), (* Port 1 *){}(* D/A *) PORT : (analog aus, 1, 3), (* Port 2 *){}(* Wandler *) PORT : (nicht belegt, 0, 0), (* Port 3 *){}
+(* *) PORT : (nicht belegt, 0, 0)), (* Port 4 *){}(*----------------------------------------------------------------------- *){} KARTE : ({}(* ---------------------------------------------------------------------- *){}(* *) PORT : (analog ein, 1, 1), (* Port 1 *){}(* A/D *) PORT : (analog ein, 1, 3), (* Port 2 *){}(* Wandler *) PORT : (nicht belegt, 0, 0), (* Port 3 *){}(* *) PORT : (nicht belegt, 0, 0)) (* Port 4 *){}
+(*----------------------------------------------------------------------- *){} );{}PROC pdv konfiguration zugelassen (BOOL CONST wahrheitswert):{} teste berechtigung;{} mit konfigurationsmoeglichkeit := wahrheitswert;{} IF mit konfigurationsmoeglichkeit{} THEN konfigurationsmanager := niltask{} ELSE konfigurationsmanager := myself{} FI.{} teste berechtigung:{} enable stop;{} IF NOT (konfigurationsmanager = niltask OR{}
+ konfigurationsmanager = myself){} THEN errorstop ("Befehl ist nur in Task '" +{} name (konfigurationsmanager) + "' zugelassen!"){} FI.{}END PROC pdv konfiguration zugelassen;{}PROC pdv konfiguration evtl aktivieren:{} IF mit konfigurationsmoeglichkeit{} THEN activate (3){} ELSE deactivate (3){} FI{}END PROC pdv konfiguration evtl aktivieren;{}PROC pdv kanal konfigurieren:{} TEXT CONST info :: " "15"Auswahl der Steckplatzart "14" "13""13""{}
+ + " c Compactbox "13""{} + " e Einzelsteckplatz "13""{} + " m Mehrfachsteckplatz ",{} liste :: "Compact"13"Einzel"13"Mehrfach",{} tasten :: "cemCEM";{} INT VAR auswahl := menualternative (info, liste, tasten, 5, FALSE);{} SELECT auswahl OF{} CASE 1, 101, 104 : trage compactbox ein;{} zeige kanalbelegung (0){} CASE 2, 102, 105 : trage einzelplatzbelegung ein;{}
+ zeige kanalbelegung (0){} CASE 3, 103, 106 : bearbeite die steckplaetze einzeln{} END SELECT;{} beende kanaldaten eintragen.{} trage compactbox ein:{} steckplatzart := compact;{} trage steckplatzbelegung ein (1, kombi);{} trage steckplatzbelegung ein (2, keine karte);{} trage steckplatzbelegung ein (3, keine karte);{} trage steckplatzbelegung ein (4, keine karte).{} trage einzelplatzbelegung ein:{} steckplatzart := einzel;{} trage steckplatzbelegung ein (1, ermittelte kartenart (0));{}
+ trage steckplatzbelegung ein (2, keine karte);{} trage steckplatzbelegung ein (3, keine karte);{} trage steckplatzbelegung ein (4, keine karte).{} bearbeite die steckplaetze einzeln:{} INT VAR platz;{} steckplatzart := mehrfach;{} FOR platz FROM 1 UPTO max steckplaetze REP{} trage steckplatzbelegung ein (platz, ermittelte kartenart (platz));{} zeige kanalbelegung (platz * 10){} PER.{}END PROC pdv kanal konfigurieren;{}PROC pdv konfiguration zeigen:{} SELECT steckplatzart OF{}
+ CASE compact : zeige kanalbelegung (0){} CASE einzel : zeige kanalbelegung (0){} CASE mehrfach : zeige belegung einzelner steckplaetze{} OTHERWISE noch nicht konfiguriert{} END SELECT.{} noch nicht konfiguriert:{} menuinfo (" "15"Warnung: "14" "13""13""13""{} + " Das Interface wurde noch nicht konfiguriert! "13""13""{} + " In diesem Zustand sind weder Eingaben noch "13""{} + " Ausgaben über das Interface möglich. "13"").{}
+ zeige belegung einzelner steckplaetze:{} TEXT CONST info ::{} " "15"Eingestellt: Mehrfachsteckplatz "14" "13""13""{} + " 1 Info Steckplatz 1 "13""{} + " 2 Info Steckplatz 2 "13""{} + " 3 Info Steckplatz 3 "13""{} + " 4 Info Steckplatz 4 "13""13""{} + " z Zurück ins Hauptmenü ",{} liste :: "1"13"2"13"3"13"4"13"z",{}
+ tasten :: "1234zZ";{} INT VAR auswahl;{} REP auswahl := menualternative (info, liste, tasten, 5, FALSE);{} SELECT auswahl OF{} CASE 1, 101 : zeige kanalbelegung (10){} CASE 2, 102 : zeige kanalbelegung (20){} CASE 3, 103 : zeige kanalbelegung (30){} CASE 4, 104 : zeige kanalbelegung (40){} END SELECT{} UNTIL (auswahl = 5) OR (auswahl > 104) PER{}END PROC pdv konfiguration zeigen;{}PROC pdv interfaceausgabe testen:{} gestalte testfenster ("Ausgabetest");{}
+ disable stop;{} teste interface;{} IF NOT is error{} THEN teste interface ausgabe{} FI;{} IF is error{} THEN fehlerbehandlung{} ELSE schliesse interface;{} enable stop;{} beseitige testfenster;{} refresh submenu{} FI.{} fehlerbehandlung:{} TEXT VAR meldung :: errormessage;{} clear error;{} schalte alles aus;{} schliesse interface;{} enable stop;{} cursor off;{} regenerate menuscreen;{} menuinfo (" " + invers (meldung)).{}END PROC pdv interfaceausgabe testen;{}
+PROC pdv interfaceeingabe testen:{} gestalte testfenster ("Eingabetest");{} disable stop;{} teste interface;{} IF NOT is error{} THEN teste interface eingabe{} FI;{} IF is error{} THEN fehlerbehandlung{} ELSE schliesse interface;{} enable stop;{} beseitige testfenster;{} refresh submenu{} FI.{} fehlerbehandlung:{} TEXT VAR meldung :: errormessage;{} clear error;{} schalte alles aus;{} schliesse interface;{} enable stop;{} cursor off;{}
+ regenerate menuscreen;{} menuinfo (" " + invers (meldung)).{}END PROC pdv interfaceeingabe testen;{}PROC beseitige testfenster:{} INT VAR z;{} FOR z FROM testfenster y + testfenster ysize DOWNTO testfenster y - 1 REP{} cursor (testfenster x - 1, z);{} out (""5""){} PER{}END PROC beseitige testfenster;{}PROC gestalte testfenster (TEXT CONST funktionsart):{} show (testfenster);{} cursor (testfenster x - 1, testfenster y + testfenster ysize - 2);{} out (balken links + (testfenster xsize * waagerecht) + balken rechts);{}
+ cursor (testfenster, 1, 2);{} out (testfenster, center (testfenster, invers (funktionsart))){}END PROC gestalte testfenster;{}PROC testfensterfussnote (TEXT CONST meldung):{} cursor (testfenster, 2, testfenster ysize);{} out (testfenster, meldung){}END PROC testfensterfussnote;{}PROC teste interfaceausgabe:{} INT VAR kanalnummer, steckplatz, port;{} TEXT VAR nummer :: "";{} enable stop;{} REP hole kanalnummer;{} teste ausgabe an kanal{} PER.{} hole kanalnummer:{} SELECT steckplatzart OF{}
+ CASE compact : kanalnummer := 4; steckplatz := 1; port := 4{} CASE einzel : kanalnummer muss evtl erfragt werden{} CASE mehrfach : kanalnummer muss erfragt werden{} OTHERWISE errorstop ("Interface ist noch nicht konfiguriert!"){} END SELECT;{} cursor (testfenster, 2, 5);{} out (testfenster, "Ausgabe an Kanal " + text (kanalnummer) + klammer +{} kanalbeschreibung (steckplatz, port));{} IF steckplatzart = mehrfach{} THEN cursor (testfenster, 25, 6);{}
+ out (testfenster, "in Steckplatz " + text (steckplatz)){} FI;{} out (testfenster, ")").{} klammer:{} IF kanalnummer < 10{} THEN " (= "{} ELSE " (= "{} FI.{} kanalnummer muss evtl erfragt werden:{} SELECT kartenart [1] OF{} CASE kombi : kanalnummer := 4; steckplatz := 1; port := 4{} CASE eakarte : kanalnummer := 2; steckplatz := 1; port := 2{} CASE dakarte : frage nach kanalnummer auf da karte;{} steckplatz := 1; port := kanalnummer{}
+ OTHERWISE errorstop ("Keine Ausgabe an " + kartenname + " möglich!"){} END SELECT.{} kartenname:{} IF kartenart [1] = ad karte{} THEN "A/D-Karte"{} ELSE "leeren Steckplatz"{} FI.{} frage nach kanalnummer auf da karte:{} menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{} testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{} cursor (testfenster, 2, 5);{} out (testfenster, "Ausgabe - Kanal (1 oder 2): ");{} cursor on;{} REP inchar (nummer){} UNTIL (pos ("12", nummer) > 0) OR esc q gedrueckt PER;{}
+ cursor off;{} IF nummer = ""27""{} THEN LEAVE teste interface ausgabe{} ELSE kanalnummer := int (nummer){} FI.{} esc q gedrueckt:{} (nummer = ""27"") AND (incharety (20) = "q").{} kanalnummer muss erfragt werden:{} TEXT VAR exit char;{} menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{} testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{} cursor (testfenster, 2, 5);{} out (testfenster, "Ausgabe - Kanal:");{} cursor on;{} REP cursor (testfenster, 19, 5);{}
+ editget (testfenster, nummer, 4, 4, "", "q", exit char){} UNTIL (exit char = ""27"q") OR ausgabekanal eingegeben PER;{} cursor off;{} IF exit char = ""27"q"{} THEN LEAVE teste interface ausgabe{} FI.{} ausgabekanal eingegeben:{} kanalnummer := abs (int (nummer));{} steckplatz := kanalnummer DIV 10;{} port := kanalnummer MOD 10;{} IF steckplatz = 0 THEN steckplatz := 1 FI;{} cursor (testfenster, 2, 7);{} IF (kanalnummer < 1) OR (kanalnummer > 49){}
+ THEN out (testfenster, "Unzulässige Kanalnummer! "); FALSE{} ELIF (port = 0) OR (port > max portanzahl) OR kein ausgabeport{} THEN out (testfenster, "Dies ist kein Ausgabe-Kanal! "); FALSE{} ELSE out (testfenster, " "); TRUE{} FI.{} kein ausgabeport:{} (port betriebsart <> digital aus) AND (port betriebsart <> analog aus).{} port betriebsart: karte [sorte][port][betriebsart].{} sorte : kartenart [steckplatz].{}
+ teste ausgabe an kanal:{} TEXT VAR wert;{} cursor (testfenster, 1, 8);{} out (testfenster, testfenster xsize * "-");{} cursor (testfenster, 2, 11);{} out (testfenster, "Ausgabewert: ");{} testfenster fussnote ("Bitte einen Wert zwischen 0 und 255 eingeben!");{} menufootnote ("'Werte ausgeben' beenden: <ESC><q>");{} cursor on;{} REP cursor (testfenster, 15, 11);{} wert := "0";{} editget (testfenster, wert, 4, 4, "", "qh", exit char);{} IF exit char = return{}
+ THEN ausgeben (kanalnummer, int (wert) MOD ganzzahlobergrenze){} ELIF exit char = ""27"h"{} THEN errorstop ("Programm-Abbruch durch <ESC><h>!"){} FI{} UNTIL exitchar = ""27"q" PER;{} cursor off;{} IF (steckplatzart = mehrfach) OR (kartenart [1] = da karte){} THEN cursor (testfenster, 1, 5);{} out (testfenster, (2 * testfenster xsize) * " ");{} cursor (testfenster, 2, 11);{} out (testfenster, " ");{}
+ testfenster fussnote ((testfenster xsize - 2) * " "){} ELSE LEAVE teste interfaceausgabe{} FI.{} return: ""13"".{}END PROC teste interfaceausgabe;{}PROC teste interfaceeingabe:{} INT VAR kanalnummer, steckplatz, port;{} TEXT VAR nummer :: "";{} enable stop;{} REP hole kanalnummer;{} teste eingabe vom kanal{} PER.{} hole kanalnummer:{} IF steckplatzart = 0{} THEN errorstop ("Interface ist noch nicht konfiguriert!"){} ELSE kanalnummer erfragen{}
+ FI;{} cursor (testfenster, 2, 5);{} out (testfenster, "Eingabe von Kanal " + text (kanalnummer) + klammer +{} kanalbeschreibung (steckplatz, port));{} IF steckplatzart = mehrfach{} THEN cursor (testfenster, 26, 6);{} out (testfenster, "in Steckplatz " + text (steckplatz)){} FI;{} out (testfenster, ")").{} klammer:{} IF kanalnummer < 10{} THEN " (= "{} ELSE " (= "{} FI.{} kanalnummer erfragen:{} SELECT steckplatzart OF{}
+ CASE compact : drei kanaele anbieten;{} steckplatz := 1; port := kanalnummer{} CASE einzel : zwei oder drei kanaele anbieten;{} steckplatz := 1; port := kanalnummer{} CASE mehrfach : alle kanaele moeglich{} END SELECT.{} drei kanaele anbieten:{} menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{} testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{} cursor (testfenster, 2, 5);{} out (testfenster, "Eingabe - Kanal (1, 2 oder 3): ");{}
+ cursor on;{} REP inchar (nummer){} UNTIL (pos ("123", nummer) > 0) OR esc q gedrueckt PER;{} cursor off;{} IF nummer = ""27""{} THEN LEAVE teste interface eingabe{} ELSE kanalnummer := int (nummer){} FI.{} esc q gedrueckt:{} (nummer = ""27"") AND (incharety (20) = "q").{} zwei oder drei kanaele anbieten:{} SELECT kartenart [1] OF{} CASE kombi : drei kanaele anbieten{} CASE ad karte : zwei kanaele anbieten{} CASE ea karte : kanalnummer := 1{}
+ OTHERWISE errorstop ("Eingabe bei " + kartenname + " nicht möglich!"){} END SELECT.{} kartenname:{} IF kartenart [1] = da karte{} THEN "D/A-Karte"{} ELSE "leerem Steckplatz"{} FI.{} zwei kanaele anbieten:{} menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{} testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{} cursor (testfenster, 2, 5);{} out (testfenster, "Eingabe - Kanal (1 oder 2): ");{} cursor on;{} REP inchar (nummer){} UNTIL (pos ("12", nummer) > 0) OR esc q gedrueckt PER;{}
+ cursor off;{} IF nummer = ""27""{} THEN LEAVE teste interface eingabe{} ELSE kanalnummer := int (nummer){} FI.{} alle kanaele moeglich:{} TEXT VAR exit char;{} menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{} testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{} cursor (testfenster, 2, 5);{} out (testfenster, "Eingabe - Kanal:");{} cursor on;{} REP cursor (testfenster, 19, 5);{} editget (testfenster, nummer, 4, 4, "", "q", exit char){} UNTIL (exit char = ""27"q") OR eingabekanal eingegeben PER;{}
+ cursor off;{} IF exit char = ""27"q"{} THEN LEAVE teste interface eingabe{} FI.{} eingabekanal eingegeben:{} kanalnummer := abs (int (nummer));{} steckplatz := kanalnummer DIV 10;{} port := kanalnummer MOD 10;{} IF steckplatz = 0 THEN steckplatz := 1 FI;{} cursor (testfenster, 2, 7);{} IF (kanalnummer < 1) OR (kanalnummer > 49){} THEN out (testfenster, "Unzulässige Kanalnummer! "); FALSE{} ELIF (port = 0) OR (port > max portanzahl) OR kein eingabeport{}
+ THEN out (testfenster, "Dies ist kein Eingabe-Kanal! "); FALSE{} ELSE out (testfenster, " "); TRUE{} FI.{} kein eingabeport:{} (port betriebsart <> digital ein) AND (port betriebsart <> analog ein).{} port betriebsart: karte [sorte][port][betriebsart].{} sorte : kartenart [steckplatz].{} teste eingabe vom kanal:{} cursor (testfenster, 1, 8);{} out (testfenster, testfenster xsize * "-");{} cursor (testfenster, 2, 11);{}
+ out (testfenster, "Eingelesener Wert: ");{} testfenster fussnote (" ");{} menufootnote ("'Werte einlesen' beenden: <ESC><q>");{} REP cursor (testfenster, 21, 11);{} out (text (eingabe (kanalnummer), 3));{} warte (0.1){} UNTIL abbruch gewuenscht PER;{} IF (steckplatzart = einzel) AND (kartenart [1] = ea karte){} THEN LEAVE teste interfaceeingabe{} ELSE cursor (testfenster, 1, 5);{} out (testfenster, (2 * testfenster xsize) * " ");{}
+ cursor (testfenster, 2, 11);{} out (testfenster, " "){} FI.{}END PROC teste interfaceeingabe;{}TEXT PROC kanalbeschreibung (INT CONST steckplatz, port):{} IF steckplatzart = compact{} THEN port auf compactbox{} ELSE port auf steckkarte{} FI.{} port auf compactbox:{} portbeschreibung + " der Compact-Box".{} port auf steckkarte:{} SELECT kartenart [steckplatz] OF{} CASE kombi : portbeschreibung + " der Kombi-Karte"{} CASE ea karte : portbeschreibung + " der E/A-Karte"{}
+ CASE da karte : portbeschreibung + " der D/A-Karte"{} CASE ad karte : portbeschreibung + " der A/D-Karte"{} OTHERWISE ""{} END SELECT.{} portbeschreibung:{} SELECT 2 + karte [kartenart [steckplatz]][port][betriebsart] OF{} CASE 1 : "Digitalausgang"{} CASE 3 : "Digitaleingang"{} CASE 0 : "Analogausgang " + text (port){} CASE 4 : "Analogeingang " + text (port){} OTHERWISE ""{} END SELECT.{}END PROC kanalbeschreibung;{}PROC trage steckplatzbelegung ein (INT CONST steckplatz, art):{}
+ INT VAR port;{} kartenart [steckplatz] := art;{} klaere spannungsbereiche;{} FOR port FROM 1 UPTO max portanzahl REP{} trage kanaldaten ein (kanalnummer, spannungsbereich, portdaten);{} IF steckplatz = 1{} THEN trage kanaldaten ein (port, spannungsbereich, portdaten){} FI{} PER.{} kanalnummer: port + 10 * steckplatz.{} portdaten : karte [kartenart [steckplatz]][port].{} spannungsbereich:{} IF port = 1{} THEN bereich von e1{} ELIF port = 2{} THEN bereich von e2{}
+ ELSE SPANNUNG : (0.0, 0.0){} FI.{} klaere spannungsbereiche:{} SPANNUNG VAR bereich von e1, bereich von e2;{} SELECT kartenart [steckplatz] OF{} CASE kombi : spannungsbereich 0 bis 5 volt{} CASE da karte : setze spannungsbereiche{} CASE ad karte : erfrage adkarte schalterstellungen{} OTHERWISE alles auf 0 setzen{} END SELECT.{} spannungsbereich 0 bis 5 volt:{} bereich von e1 := SPANNUNG : (0.0, 5.0);{} bereich von e2 := SPANNUNG : (0.0, 5.0).{} setze spannungsbereiche:{}
+ bereich von e1 := SPANNUNG : (-5.0, 5.0);{} bereich von e2 := SPANNUNG : ( 0.0, 5.0).{} alles auf 0 setzen:{} bereich von e1 := SPANNUNG : (0.0, 0.0);{} bereich von e2 := SPANNUNG : (0.0, 0.0).{}erfrage adkarte schalterstellungen:{} REP{} hole schalterstellung{} UNTIL schalterstellung sinnvoll PER;{} bestimme spannungsbereiche (schalterzustand, bereich von e1, bereich von e2).{} hole schalterstellung:{} TEXT VAR schalterzustand := menuanswer (infotext, "00000000", 5).{} infotext:{}
+ ueberschrift{} + " Bitte die aktuelle Schalterstellung eintragen: "13""13""{} + " Es bedeutet : 1 - Schalterstellung 'on' "13""{} + " 0 - Schalterstellung 'off' "13""13""{} + " Nummer : 12345678 "13""{} + " |||||||| ".{} ueberschrift:{} IF steckplatzart = mehrfach{} THEN " "15"Angabe der Schalterstellungen auf der A/D-Karte "14""13""{} + " "15" in Steckplatz "{} + text (steckplatz) + ": "14""13""13""{}
+ ELSE " "15"Angabe der Schalterstellungen auf der A/D-Karte: "14""13""13""{} FI.{} schalterstellung sinnvoll:{} (length (schalterzustand) = 8) AND nur nullen und einsen.{} nur nullen und einsen:{} BOOL VAR ok := TRUE; INT VAR m;{} FOR m FROM 1 UPTO 8 REP{} IF NOT ((schalterzustand SUB m) = "1" OR (schalterzustand SUB m ) = "0"){} THEN ok := FALSE{} FI{} PER;{} ok.{}END PROC trage steckplatzbelegung ein;{}INT PROC ermittelte kartenart (INT CONST steckplatz):{} TEXT CONST info e :: " "15"Angabe der Interfacekarte: "14" "13""13""{}
+ + " k Kombikarte "13""{} + " e E / A - Karte "13""{} + " d D / A - Wandler - Karte "13""{} + " a A / D - Wandler - Karte "13""{} + " 0 Keine Steckkarte ",{} info m :: " "15"Angabe der Interfacekarte für Steckplatz "{} + text (steckplatz) + ": "14" "13""13""{} + " k Kombikarte "13""{}
+ + " e E / A - Karte "13""{} + " d D / A - Wandler - Karte "13""{} + " a A / D - Wandler - Karte "13""{} + " 0 Keine Steckkarte ",{} liste :: "Kombi"13"E/A"13"D/A"13"A/D"13"Keine",{} tasten :: "keda0KEDA";{} INT VAR auswahl := menualternative (infotext, liste, tasten, 5, FALSE);{} SELECT auswahl OF{} CASE 1, 101, 106 : kombi{}
+ CASE 2, 102, 107 : eakarte{} CASE 3, 103, 108 : dakarte{} CASE 4, 104, 109 : adkarte{} OTHERWISE keine karte{} END SELECT.{} infotext:{} IF steckplatz = 0{} THEN info e{} ELSE info m{} FI.{}END PROC ermittelte kartenart;{}PROC zeige kanalbelegung (INT CONST steckplatz):{} ROW 4 TEXT VAR kanalnummer;{} kanalnummer [1] := text (steckplatz + 1, 2);{} kanalnummer [2] := text (steckplatz + 2, 2);{} kanalnummer [3] := text (steckplatz + 3, 2);{}
+ kanalnummer [4] := text (steckplatz + 4, 2);{} IF steckplatzart = compact{} THEN zeige compactboxbelegung{} ELSE zeige steckplatz mit karte{} FI.{} zeige steckplatz mit karte:{} SELECT kartenart [steckplatznummer] OF{} CASE kombi : zeige steckplatz mit kombi{} CASE eakarte: zeige steckplatz mit eakarte{} CASE dakarte: zeige steckplatz mit dakarte{} CASE adkarte: zeige steckplatz mit adkarte{} OTHERWISE zeige steckplatz ohne karte{} END SELECT.{}
+ steckplatznummer:{} IF steckplatz = 0{} THEN 1{} ELSE steckplatz DIV 10{} FI.{} zeige compactboxbelegung:{} menuinfo ({} " "15"Eingestellt: Compactbox "14" "13""13""{} + " Belegung der Kanäle: "13""13""13""{} + kanalnummeranzeige kombikarte).{} zeige steckplatz mit kombi:{} menuinfo (ueberschrift + " mit Kombikarte: "14" "13""13""{} + " Belegung der Kanäle: "13""13""13""{} + kanalnummeranzeige kombikarte).{}
+ zeige steckplatz mit eakarte:{} menuinfo (ueberschrift + " mit E / A - Karte: "14" "13""13""{} + " Belegung der Kanäle: "13""13""13""{} + kanalnummeranzeige eakarte).{} zeige steckplatz mit dakarte:{} menuinfo (ueberschrift + " mit D / A - Karte: "14" "13""13""{} + " Belegung der Kanäle: "13""13""{} + kanalnummeranzeige dakarte).{} zeige steckplatz mit adkarte:{} hole spannungsbereiche;{} menuinfo (" " + ueberschrift + " mit A / D - Karte: "14""13""13""{}
+ + " Zwei analoge Eingänge stehen zur Verfügung: "13""13""{} + kanalnummeranzeige adkarte).{} hole spannungsbereiche:{} SPANNUNG VAR e1 bereich, e2 bereich;{} hole spannungsbereich (steckplatz + 1, e1 bereich [1], e1 bereich [2]);{} hole spannungsbereich (steckplatz + 2, e2 bereich [1], e2 bereich [2]).{} zeige steckplatz ohne karte:{} IF steckplatz = 0{} THEN menuinfo ({} " "15"Einzelsteckplatz ohne Steckkarte: "14" "13""13""13""{} + " Es sind weder Ein- noch Ausgaben möglich! "13""){}
+ ELSE menuinfo ({} " "15"Steckplatz "{} + text (steckplatz DIV 10) + " ohne Steckkarte: "14""13""13""13""{} + " Es sind hier weder Ein- noch Ausgaben möglich! "13""){} FI.{} ueberschrift:{} IF steckplatz = 0{} THEN " "15"Einzelsteckplatz"{} ELSE " "15"Steckplatz " + text (steckplatz DIV 10){} FI.{} kanalnummeranzeige kombikarte:{} " "15"Kanal " + kanalnummer [1]{} + ": "14" Analogeingang 1 (E1) "13""13""{}
+ + " "15"Kanal " + kanalnummer [2]{} + ": "14" Analogeingang 2 (E2) "13""13""{} + " "15"Kanal " + kanalnummer [3]{} + ": "14" Digitaleingang "13""13""{} + " "15"Kanal " + kanalnummer [4]{} + ": "14" Digitalausgang "13"".{} kanalnummeranzeige eakarte:{} " "15"Kanal " + kanalnummer [1]{} + ": "14" Digitaleingang "13""13""{} + " "15"Kanal " + kanalnummer [2]{} + ": "14" Digitalausgang "13""13""{}
+ + " ( "15"Kanal " + kanalnummer [3]{} + ": "14" Digitaleingang (= Kanal " + kanalnummer [1] + ") )"13""13""{} + " ( "15"Kanal " + kanalnummer [4]{} + ": "14" Digitalausgang (= Kanal " + kanalnummer [2] + ") )"13"".{} kanalnummeranzeige adkarte:{} " "15"Kanal " + kanalnummer [1]{} + ": "14" (E1) Spannungsbereich " + bereich1 + ""13""13""{} + " "15"Kanal " + kanalnummer [2]{} + ": "14" (E2) Spannungsbereich " + bereich2 + ""13"".{}
+ bereich1:{} IF e1 bereich [1] = 0.0{} THEN " 0.000 V - +" + text (e1 bereich [2], 6, 3) + " V "{} ELSE text (e1 bereich [1], 7, 3) + " V - +" + text (e1 bereich [2], 6, 3) + " V "{} FI.{} bereich2:{} IF e2 bereich [1] = 0.0{} THEN " 0.000 V - +" + text (e2 bereich [2], 6, 3) + " V"{} ELSE text (e2 bereich [1], 7, 3) + " V - +" + text (e2 bereich [2], 6, 3) + " V"{} FI.{} kanalnummeranzeige dakarte:{} " Die Karte stellt einen Analogausgang zur Verfügung, "13""{}
+ + " der auf zwei Arten angesprochen werden kann: "13""13""13""{} + " "15"Kanal " + kanalnummer [1]{} + ": "14" Spannungsbereich -5 V - +5 V "13""13""{} + " "15"Kanal " + kanalnummer [2]{} + ": "14" Spannungsbereich 0 V - +5 V "13"".{}END PROC zeige kanalbelegung;{}PROC bestimme spannungsbereiche (TEXT CONST schalterstellung,{} SPANNUNG VAR bereich von e1,{} SPANNUNG VAR bereich von e2):{}
+ bestimme bereich von e1;{} bestimme bereich von e2.{} bestimme bereich von e1:{} IF schalter 3 geschlossen{} THEN umax1 := 0.25{} ELIF schalter 2 geschlossen{} THEN umax1 := 2.5{} ELIF schalter 1 geschlossen{} THEN umax1 := 25.0{} ELSE umax1 := 0.0{} FI;{} IF schalter 8 geschlossen{} THEN symmetrische spannungsmessung ueber e1{} ELSE asymmetrische spannungsmessung ueber e1{} FI.{} schalter 1 geschlossen: (schalterstellung SUB 1) = on.{}
+ schalter 2 geschlossen: (schalterstellung SUB 2) = on.{} schalter 3 geschlossen: (schalterstellung SUB 3) = on.{} schalter 8 geschlossen: (schalterstellung SUB 8) = on.{} umin1: bereich von e1 [1].{} umax1: bereich von e1 [2].{} symmetrische spannungsmessung ueber e1:{} umax1 := umax1 / 2.0;{} umin1 := - umax1.{} asymmetrische spannungsmessung ueber e1:{} umin1 := 0.0.{} bestimme bereich von e2:{} IF schalter 6 geschlossen{} THEN umax2 := 0.25{} ELIF schalter 5 geschlossen{}
+ THEN umax2 := 2.5{} ELIF schalter 4 geschlossen{} THEN umax2 := 25.0{} ELSE umax2 := 0.0{} FI;{} IF schalter 7 geschlossen{} THEN symmetrische spannungsmessung ueber e2{} ELSE asymmetrische spannungsmessung ueber e2{} FI.{} schalter 4 geschlossen: (schalterstellung SUB 4) = on.{} schalter 5 geschlossen: (schalterstellung SUB 5) = on.{} schalter 6 geschlossen: (schalterstellung SUB 6) = on.{} schalter 7 geschlossen: (schalterstellung SUB 7) = on.{}
+ umin2: bereich von e2 [1].{} umax2: bereich von e2 [2].{} symmetrische spannungsmessung ueber e2:{} umax2 := umax2 / 2.0;{} umin2 := - umax2.{} asymmetrische spannungsmessung ueber e2:{} umin2 := 0.0.{} on: "1".{}END PROC bestimme spannungsbereiche{}END PACKET ls prozess 5{}
+
diff --git a/prozess/ls-Prozess-gen b/prozess/ls-Prozess-gen
new file mode 100644
index 0000000..b93e4b9
--- /dev/null
+++ b/prozess/ls-Prozess-gen
@@ -0,0 +1,146 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Prozess/gen **
+ ** **
+ ** Version 1.02 **
+ ** **
+ ** (Stand : 26.01.90) **
+ ** **
+ ** **
+ ** **
+ ** Autoren: Bruno Pollok, Bielefeld **
+ ** Wolfgang Weber, Bielefeld **
+ ** **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ **********************************************************
+ **********************************************************
+
+ *)
+WINDOW VAR fenster := window (1, 1, 79, 24);
+TEXT CONST titel :: ""15"ls-Prozess : Automatische Generierung "14"",
+ ueberschrift :: "Auswahl der Interface-Anpassung",
+ hinweis :: "Bitte gewünschte Anpassung ankreuzen!";
+TEXT VAR anpassung;
+BOOL VAR alles okay;
+frage nach diskette;
+IF alles okay
+ THEN installation
+FI;
+PROC installation:
+ THESAURUS VAR thes :: infix namen (ALL archive, "ls-Prozess 1");
+ anpassung := boxone (fenster, thes, ueberschrift, hinweis, FALSE);
+ cursor (1, 3);
+ out (""4"");
+ IF anpassung <> ""
+ THEN installiere ls prozess
+ ELSE warnung
+ FI.
+ warnung:
+ out (""7"");
+ line (2);
+ out (" FEHLER: Es muß unbedingt eine Anpassung ausgewaehlt werden!");
+ cursor (5, 7);
+ IF no ("Generierung abbrechen")
+ THEN installation
+ FI.
+END PROC installation;
+PROC installiere ls prozess:
+ forget ("ls-Prozess/gen", quiet);
+ frage evtl nach interfacekanal;
+ check off;
+ warnings off;
+ installiere (anpassung);
+ installiere ("ls-Prozess 2");
+ installiere ("ls-Prozess 3");
+ installiere ("ls-Prozess 4");
+ installiere ("ls-Prozess 5");
+
+ installiere ("ls-MENUKARTE:Prozess");
+ check on;
+ release (archive);
+ setze ggf interface kanal;
+ global manager.
+ frage evtl nach interfacekanal:
+ IF adapter fuer separate schnittstelle
+ THEN erfrage kanalnummer
+ FI.
+ erfrage kanalnummer:
+ INT VAR kanalnummer;
+ line (2);
+ REP put (" Gib Interfacekanal:");
+ get (kanalnummer);
+ IF kanalnummer < 1 OR kanalnummer > 24
+ THEN out (""7" Unzulaessige Kanalnummer!");
+ line (2)
+
+ FI
+ UNTIL kanalnummer > 0 AND kanalnummer < 25 PER;
+ cursor (1, 3);
+ out (""4"").
+ setze ggf interfacekanal:
+ IF adapter fuer separate schnittstelle
+ THEN do ("interface kanal (" + text (kanalnummer) + ")")
+ FI.
+ adapter fuer separate schnittstelle:
+ (anpassung = "ls-Prozess 1 für AKTRONIC-Adapter") OR
+ (anpassung = "ls-Prozess 1 für MUFI als Endgerät").
+END PROC installiere ls prozess;
+PROC installiere (TEXT CONST datei):
+ INT VAR zeile, spalte;
+
+ hole datei vom archiv;
+ IF datei = "ls-MENUKARTE:Prozess"
+ THEN schicke zu menukarten task
+ ELSE insertiere
+ FI.
+ hole datei vom archiv:
+ line (2);
+ out ("'" + datei + "' ");
+ get cursor (spalte, zeile);
+ IF NOT exists (datei)
+ THEN out ("wird von der Archivdiskette geholt.");
+ fetch (datei, archive)
+ FI.
+ insertiere:
+ cursor (spalte, zeile);
+ out (""5"");
+ out ("wird insertiert.");
+ insert (datei);
+ cursor (spalte, zeile);
+
+ out (""4"");
+ forget (datei, quiet).
+ schicke zu menukarten task:
+ cursor (spalte, zeile);
+ out (""5"");
+ command dialogue (FALSE);
+ save (datei, /"ls-MENUKARTEN");
+ command dialogue (TRUE);
+ forget (datei, quiet).
+END PROC installiere;
+PROC frage nach diskette:
+ page;
+ out (center (fenster, titel));
+ line (4);
+ putline (" Ist das Archiv angemeldet,");
+ putline (" die Diskette mit 'ls-Prozess' eingelegt");
+ IF yes (" und das Laufwerk geschlossen")
+
+ THEN alles okay := TRUE
+ ELSE alles okay := FALSE;
+ warnung
+ FI.
+ warnung:
+ line (3);
+ out (" FEHLER : Diskettenzugriff nicht gesichert!"7"");
+ line (2);
+ out (" Bitte Fehler beseitigen und Programm neu starten!");
+ line (5)
+END PROC frage nach diskette;
+
+
diff --git a/system/crypt b/system/crypt
new file mode 100644
index 0000000..b04728a
--- /dev/null
+++ b/system/crypt
@@ -0,0 +1,138 @@
+(* ------------------- VERSION 2 vom 21.04.86 ------------------- *)
+PACKET cryptograf DEFINES (* Autor: J.Liedtke *)
+
+ crypt ,
+ decrypt :
+
+TEXT VAR char , in buffer, out buffer ;
+INT VAR in pos , key index ;
+DATASPACE VAR scratch space ;
+FILE VAR in, out;
+
+PROC crypt (TEXT CONST file, key) :
+
+ open (file) ;
+ initialize crypt (key) ;
+ WHILE NOT eof REP
+ read char ;
+ crypt char ;
+ write char
+ PER ;
+ close (file) .
+
+crypt char :
+ char := code (( character + random char + key char ) MOD 250) ;
+ IF key index = LENGTH key
+ THEN key index := 1
+ ELSE key index INCR 1
+ FI .
+
+character : code (char) .
+
+random char : random (0,250).
+
+key char : code (key SUB key index) .
+
+ENDPROC crypt ;
+
+PROC decrypt (TEXT CONST file, key) :
+
+ open (file) ;
+ initialize crypt (key) ;
+ WHILE NOT eof REP
+ read char ;
+ decrypt char ;
+ write char
+ PER ;
+ close (file) .
+
+decrypt char :
+ char := code (( character - random char - key char ) MOD 250) ;
+ IF key index = LENGTH key
+ THEN key index := 1
+ ELSE key index INCR 1
+ FI .
+
+character : code (char) .
+
+random char : random (0,250) .
+
+key char : code (key SUB key index) .
+
+ENDPROC decrypt ;
+
+PROC initialize crypt (TEXT CONST key) :
+
+ INT VAR random key := 0 ;
+ FOR key index FROM 1 UPTO LENGTH key REP
+ random key := (random key + code (key SUB key index)) MOD 32000
+ PER ;
+ initialize random (random key) ;
+ key index := 1
+
+ENDPROC initialize crypt ;
+
+PROC open (TEXT CONST source file) :
+
+ in := sequential file (input, source file) ;
+ getline (in, in buffer) ;
+ in pos := 1 ;
+ forget (scratch space) ;
+ scratch space := nilspace ;
+ out := sequential file (output, scratch space) ;
+ out buffer := "" .
+
+ENDPROC open ;
+
+PROC close (TEXT CONST source file) :
+
+ IF out buffer <> ""
+ THEN putline (out, out buffer)
+ FI ;
+ forget (source file, quiet) ;
+ copy (scratch space, source file) ;
+ forget (scratch space) .
+
+ENDPROC close ;
+
+BOOL PROC eof :
+
+ IF in pos > LENGTH in buffer
+ THEN eof (in)
+ ELSE FALSE
+ FI
+
+ENDPROC eof ;
+
+PROC read char :
+
+ IF in pos > 250
+ THEN getline (in, in buffer) ;
+ in pos := 1 ;
+ read char
+ ELIF in pos > LENGTH in buffer
+ THEN in pos := 1 ;
+ getline (in, in buffer) ;
+ char := ""13""
+ ELSE char := in buffer SUB in pos ;
+ in pos INCR 1
+ FI .
+
+ENDPROC read char ;
+
+PROC write char :
+
+ IF char = ""13""
+ THEN putline (out, out buffer) ;
+ out buffer := ""
+ ELSE out buffer CAT char
+ FI ;
+ IF LENGTH out buffer = 250
+ THEN putline (out, out buffer) ;
+ out buffer := ""
+ FI .
+
+ENDPROC write char ;
+
+ENDPACKET cryptograf ;
+
diff --git a/system/eumel printer.5 b/system/eumel printer.5
new file mode 100644
index 0000000..e61a073
--- /dev/null
+++ b/system/eumel printer.5
@@ -0,0 +1,3473 @@
+PACKET eumel printer (* Autor : Rudolf Ruland *)
+ (* Version : 5 *)
+ (* Stand : 25.04.88 *)
+ DEFINES print,
+ with elan listings,
+ is elan source,
+ bottom label for elan listings,
+ x pos,
+ y pos,
+ y offset index,
+ line type,
+ material,
+ pages printed,
+
+(* >>> ***************************************************************** <<< *)
+(* >>> Aus Kompatibilitätsgründen zur Textverarbeitung der Version 1.8.0 <<< *)
+(* >>> siehe bei 'Berechnung des Zeilenvorschubs' <<< *)
+
+ old linefeed :
+
+BOOL VAR old linefeed calculation := TRUE;
+
+PROC old linefeed (BOOL CONST value) : old linefeed calculation := value END PROC old linefeed;
+
+BOOL PROC old linefeed : old linefeed calculation END PROC old linefeed;
+
+(* >>> ***************************************************************** <<< *)
+
+INT CONST int length := length of one int;
+
+. length of one int :
+ INT VAR int counter := 0, int value := max int;
+ REP int counter INCR 1;
+ int value := int value DIV 256;
+ UNTIL int value = 0 PER;
+ int counter
+.;
+
+(* >>> ***************************************************************** <<< *)
+
+LET std x wanted = 2.54,
+ std y wanted = 2.35,
+ std limit = 16.0,
+ std pagelength = 25.0,
+ std linefeed faktor = 1.0,
+ std material = "";
+
+LET blank = " ",
+ blank code 1 = 33,
+ geschuetztes blank = ""223"",
+ keine blankanalyse = 0,
+ einfach blank = 1,
+ doppel blank = 2,
+
+ anweisungszeichen = "#",
+ anweisungszeichen code 1 = 36,
+ geschuetztes anweisungszeichen = ""222"",
+ druckerkommando zeichen = "/",
+ quote = """",
+ kommentar zeichen = "-",
+
+ punkt = ".",
+
+ leer = 0,
+
+ kommando token = 0,
+ text token = 1,
+
+ underline linetype = 1,
+(* fraction linetype = 2,
+ root linetype = 3,
+*)
+ underline bit = 0,
+ bold bit = 1,
+ italics bit = 2,
+ modifikations liste = "ubir",
+ anzahl modifikationen = 4,
+
+ document = 1,
+ page = 2,
+
+ write text = 1,
+ write cmd = 2,
+ carriage return = 3,
+ move = 4,
+ draw = 5,
+ on = 6,
+ off = 7,
+ type = 8,
+
+ text code = 1,
+(* error code = 2, *)
+ token code = 3,
+
+ tag type = 1,
+ bold type = 2,
+ number type = 3,
+ text type = 4,
+ delimiter type = 6,
+ eof type = 7;
+
+
+INT CONST null ausgang := minint,
+ erweiterungs ausgang := maxint,
+ blank ausgang := maxint - 1,
+ anweisungs ausgang := maxint - 2,
+ d code ausgang := maxint - 3,
+ max breite := maxint - 4,
+
+ linien token := -1;
+
+ROW anzahl modifikationen INT CONST modifikations werte :=
+ ROW anzahl modifikationen INT : (1, 2, 4, 8);
+
+TEXT CONST anweisungsliste :=
+ "type:1.1on:2.1off:3.1center:4.0right:5.0u:6.0d:7.0e:8.0b:9.0" +
+ "fillchar:10.1mark:11.2markend:12.0" +
+ "ub:13.0ue:14.0fb:15.0fe:16.0" +
+ "block:20.0columns:21.2columnsend:22.0free:23.1limit:24.1linefeed:25.1" +
+ "material:26.1page:27.01pagelength:29.1start:30.2" +
+ "table:31.0tableend:32.0clearpos:33.01" +
+ "lpos:35.1rpos:36.1cpos:37.1dpos:38.2bpos:39.2" +
+ "textbegin:40.02textend:42.0" +
+ "indentation:43.1ytab:44.1";
+
+LET a type = 1, a block = 20,
+ a on = 2, a columns = 21,
+ a off = 3, a columnsend = 22,
+ a center = 4, a free = 23,
+ a right = 5, a limit = 24,
+ a up = 6, a linefeed = 25,
+ a down = 7, a material = 26,
+ a end up or down = 8, a page0 = 27,
+ a bsp = 9, a page1 = 28,
+ a fill char = 10, a pagelength = 29,
+ a mark = 11, a start = 30,
+ a markend = 12, a table = 31,
+ a ub = 13, a tableend = 32,
+ a ue = 14, a clearpos0 = 33,
+ a fb = 15, a clearpos1 = 34,
+ a fe = 16, a lpos = 35,
+ a rpos = 36,
+ a cpos = 37,
+ a dpos = 38,
+ a bpos = 39,
+ a textbegin0 = 40,
+ a textbegin2 = 41,
+ a textend = 42,
+ a indentation = 43,
+ a y tab = 44;
+
+INT VAR a xpos, a breite, a font, a modifikationen,
+ a modifikationen fuer x move, a ypos, aktuelle ypos,
+ letzter font, letzte modifikationen,
+ d ypos, d xpos, d font, d modifikationen,
+
+ zeilenpos, alte zeilenpos, zeilen laenge, anzahl zeichen, ausgang,
+ anzahl einrueck blanks, blankbreite, fuehrende anweisungen,
+ einrueckbreite, aktuelle einrueckbreite, alte einrueckbreite,
+ aktuelle zeilentiefe der letzten zeile,
+ blankmodus, alter blankmodus,
+ token zeiger, erstes token der zeile,
+
+ erstes tab token, tab anfang, anzahl blanks,
+ d code 1, d pitch, fuell zeichen breite, erstes fuell token,
+ letztes fuell token,
+
+ x size, y size, x wanted, y wanted, x start, y start,
+ pagelength, limit, indentation,
+ left margin, top margin, seitenlaenge,
+ papierlaenge, papierbreite,
+ luecke, anzahl spalten, aktuelle spalte,
+
+ verschiebung, linien verschiebung,
+ rest, neue modifikationen, modifikations modus, pass,
+
+ int param, anweisungs index, anzahl params,
+
+ gedruckte seiten;
+
+BOOL VAR zeile ist absatzzeile, letzte zeile war absatzzeile,
+ zeile muss geblockt werden, rechts, a block token, offsets,
+ tabellen modus, block modus, center modus, right modus,
+ seite ist offen, vor erster seite;
+
+REAL VAR linefeed faktor, real param;
+
+TEXT VAR zeile, anweisung, par1, par2, material wert, replacements,
+ fuell zeichen, d string, font offsets;
+
+ROW 256 INT VAR zeichenbreiten, replacement tabelle, zeichen zaehler;
+
+INITFLAG VAR in dieser task := FALSE;
+
+. zeile ist zu ende : zeilenpos > zeilen laenge
+
+. zeilen breite : a xpos - left margin
+
+. naechstes zeichen ist blank : pos (zeile, blank, zeilenpos + 1, zeilenpos + 1) <> 0
+
+. naechstes nicht blankes zeichen : pos (zeile, ""33"", ""255"", zeilenpos)
+
+. in letzter spalte : aktuelle spalte >= anzahl spalten
+
+. anfangs blankmodus :
+ INT VAR dummy;
+ IF center modus OR right modus
+ THEN dummy
+ ELIF index zaehler = 0
+ THEN blankmodus
+ ELSE alter blankmodus
+ FI
+
+. initialisiere tab variablen :
+ erstes tab token := token index f + 1;
+ tab anfang := zeilen breite;
+ anzahl blanks := 0;
+ a block token := FALSE;
+.;
+
+(******************************************************************)
+
+LET zeilen nr laenge = 4,
+ teil einrueckung = 5,
+
+ headline pre = "Zeile **** E L A N EUMEL 1.8.2 **** ",
+ headline post = " **** ";
+
+INT VAR zeilen nr, rest auf seite,
+ max zeichen zeile, max zeichen fuss, layout laenge, layout laenge name,
+ symbol type, naechster symbol type, select counter;
+
+BOOL VAR vor erstem packet, innerhalb einer liste;
+
+TEXT VAR bottom label, dateiname, layout blanks, refinement layout zeile;
+
+
+. symbol : fuell zeichen
+. naechstes symbol : d string
+. elan text : d token. text
+.;
+
+(******************************************************************)
+(*** Berechnung des Zeilenvorschubs ***)
+
+INT VAR fonthoehe, fonttiefe, fontdurchschuss,
+ groesste fonthoehe, groesste fonttiefe,
+ groesste analysatorhoehe, groesste analysatortiefe,
+ letzte zeilenhoehe, letzte zeilentiefe,
+ aktuelle zeilenhoehe, aktuelle zeilentiefe;
+REAL VAR real fontgroesse;
+
+. fontgroesse : fonthoehe + fonttiefe
+. groesste fontgroesse : groesste fonthoehe + groesste fonttiefe
+. letzte zeilengroesse : letzte zeilenhoehe + letzte zeilentiefe
+. aktuelle zeilengroesse : aktuelle zeilenhoehe + aktuelle zeilentiefe
+
+.
+ initialisiere zeilenvorschub :
+ aktuelle zeilenhoehe := letzte zeilenhoehe;
+ aktuelle zeilentiefe := letzte zeilentiefe;
+ groesste fonthoehe := fonthoehe;
+ groesste fonttiefe := fonttiefe;
+ groesste analysatorhoehe := 0;
+ groesste analysatortiefe := 0;
+
+.
+ ueberpruefe groesste fontgroesse :
+ IF old linefeed calculation
+ THEN
+(* >>> Maximumsbestimmung über Fontgröße ******************************* <<< *)
+ IF fontgroesse >= groesste fontgroesse
+ THEN groesste fonthoehe := fonthoehe;
+ groesste fonttiefe := fonttiefe;
+ FI;
+ ELSE
+(* >>> Maximumsbestimmung über Fonthöhe und Fonttiefe ****************** <<< *)
+ groesste fonthoehe := max (fonthoehe, groesste fonthoehe);
+ groesste fonttiefe := max (fonttiefe, groesste fonttiefe);
+ FI;
+
+.
+ berechne fontgroesse :
+ fonthoehe INCR (fontdurchschuss DIV 2 + fontdurchschuss MOD 2);
+ fonttiefe INCR fontdurchschuss DIV 2;
+ real fontgroesse := real (fontgroesse);
+
+.
+ berechne letzte zeilengroesse :
+ REAL CONST zeilengroesse := real fontgroesse * linefeed faktor;
+ letzte zeilenhoehe := int (real (fonthoehe) * zeilengroesse / real fontgroesse + 0.5);
+ letzte zeilentiefe := int (zeilengroesse + 0.5) - letzte zeilenhoehe;
+.;
+
+PROC berechne aktuelle zeilengroesse :
+
+ IF linefeed faktor >= 1.0
+ THEN aktuelle zeilenhoehe := max (groesste fonthoehe, letzte zeilenhoehe);
+ aktuelle zeilentiefe := max (groesste fonttiefe, letzte zeilentiefe);
+ ELSE
+ IF old linefeed calculation
+ THEN
+(* >>> Maximumsbestimmung über Fontgröße ******************************* <<< *)
+ IF letzte zeilengroesse >= aktuelle zeilengroesse
+ THEN aktuelle zeilenhoehe := letzte zeilenhoehe;
+ aktuelle zeilentiefe := letzte zeilentiefe;
+ FI;
+ ELSE
+(* >>> Maximumsbestimmung über Fonthöhe und Fonttiefe ****************** <<< *)
+ aktuelle zeilenhoehe := max (letzte zeilenhoehe, aktuelle zeilenhoehe);
+ aktuelle zeilentiefe := max (letzte zeilentiefe, aktuelle zeilentiefe);
+ FI;
+ FI;
+ aktuelle zeilenhoehe := max (groesste analysatorhoehe, aktuelle zeilenhoehe);
+ aktuelle zeilentiefe := max (groesste analysatortiefe, aktuelle zeilentiefe);
+
+END PROC berechne aktuelle zeilengroesse;
+
+(******************************************************************)
+(*** tokenspeicher ***)
+
+LET max number token = 3000,
+ max number ypos = 1000,
+
+ TOKEN = STRUCT (TEXT text,
+ INT xpos, breite, font, modifikationen,
+ modifikationen fuer x move,
+ offset index, naechster token index,
+ BOOL block token ),
+
+ YPOS = STRUCT (INT ypos, vorheriger ypos index, naechster ypos index,
+ erster token index, letzter token index ),
+
+ TOKENLISTE = STRUCT (ROW max number token TOKEN token liste,
+ ROW max number ypos YPOS ypos liste );
+
+DATASPACE VAR ds;
+
+BOUND TOKENLISTE VAR tokenspeicher;
+
+TOKEN VAR d token, offset token;
+
+INT VAR erster ypos index a, letzter ypos index a,
+ erster ypos index d, letzter ypos index d,
+ ypos index, ypos index f, ypos index a, ypos index d,
+ token index, token index f;
+
+. t : tokenspeicher. token liste (token index)
+. tf : tokenspeicher. token liste (token index f)
+
+. y : tokenspeicher. ypos liste (ypos index)
+. yf : tokenspeicher. ypos liste (ypos index f)
+. ya : tokenspeicher. ypos liste (ypos index a)
+. yd : tokenspeicher. ypos liste (ypos index d)
+
+. loesche druckspeicher :
+ erster ypos index d := 0;
+ ypos index f := 0;
+ token index f := 0;
+
+. druckspeicher ist nicht leer :
+ erster ypos index d <> 0
+
+. loesche analysespeicher :
+ erster ypos index a := 0;
+
+. analysespeicher ist nicht leer :
+ erster ypos index a <> 0
+.;
+
+(******************************************************************)
+(*** anweisungsspeicher ***)
+
+INT VAR anweisungszaehler;
+TEXT VAR anweisungs indizes, params1 zeiger, params2 zeiger;
+THESAURUS VAR params1, params2;
+
+PROC loesche anweisungsspeicher :
+
+ anweisungs zaehler := 0;
+ anweisungs indizes := "";
+ params1 zeiger := "";
+ params2 zeiger := "";
+ params1 := empty thesaurus;
+ params2 := empty thesaurus;
+
+END PROC loesche anweisungsspeicher;
+
+(******************************************************************)
+(*** indexspeicher ***)
+
+INT VAR index zaehler, hoechster index zaehler;
+TEXT VAR letzte index breite, xpos vor index, zeilenpos nach index, grosse fonts,
+ index verschiebung;
+
+PROC loesche indexspeicher :
+
+ index zaehler := 0;
+ hoechster index zaehler := 0;
+ letzte index breite := "";
+ xpos vor index := "";
+ zeilenpos nach index := "";
+ index verschiebung := "";
+ grosse fonts := "";
+
+END PROC loesche indexspeicher;
+
+
+PROC loesche hoehere index level :
+
+ IF hoechster index zaehler > index zaehler
+ THEN letzte index breite := subtext (letzte index breite, 1, int length * index zaehler);
+ xpos vor index := subtext (xpos vor index, 1, int length * index zaehler);
+ zeilenpos nach index := subtext (zeilenpos nach index, 1, int length * index zaehler);
+ index verschiebung := subtext (index verschiebung, int length * index zaehler);
+ grosse fonts := subtext (grosse fonts, 1, int length * index zaehler);
+ hoechster index zaehler := index zaehler;
+ FI;
+
+END PROC loesche hoehere index level;
+
+(******************************************************************)
+(*** tabellenspeicher ***)
+
+LET max tabs = 30,
+ TABELLENEINTRAG = STRUCT (INT tab typ, tab position, tab param);
+
+TEXT VAR tab liste, fill char;
+THESAURUS VAR d strings;
+ROW max tabs TABELLENEINTRAG VAR tabspeicher;
+
+INT VAR tab index;
+
+. tab typ : tab speicher (tab liste ISUB tab index). tab typ
+. tab position : tab speicher (tab liste ISUB tab index). tab position
+. tab param : tab speicher (tab liste ISUB tab index). tab param
+. anzahl tabs : LENGTH tab liste DIV int length
+.;
+
+PROC loesche tabellenspeicher :
+
+ fill char := " ";
+ tabliste := "";
+ d strings := empty thesaurus;
+ FOR tab index FROM 1 UPTO max tabs
+ REP tab speicher (tab index). tab typ := leer PER;
+
+END PROC loesche tabellenspeicher;
+
+(******************************************************************)
+(*** markierungsspeicher ***)
+
+INT VAR mark index l, mark index r, alter mark index l, alter mark index r;
+
+ROW 4 TOKEN VAR mark token;
+
+. markierung links : mark index l > 0
+. markierung rechts : mark index r > 0
+.;
+
+PROC loesche markierung :
+
+ mark index l := 0;
+ mark index r := 0;
+
+END PROC loesche markierung;
+
+
+PROC loesche alte markierung :
+
+ alter mark index l := 0;
+ alter mark index r := 0;
+
+END PROC loesche alte markierung;
+
+
+PROC initialisiere markierung :
+
+ FOR mark index l FROM 1 UPTO 4
+ REP mark token (mark index l). modifikationen fuer x move := 0;
+ mark token (mark index l). offset index := text token;
+ mark token (mark index l). block token := FALSE;
+ mark token (mark index l). naechster token index := 0;
+ PER;
+
+END PROC initialisiere markierung;
+
+(******************************************************************)
+(*** durchschuss ***)
+
+INT VAR durchschuss 1, durchschuss 2, anzahl durchschuss 1,
+ anzahl durchschuss, zeilen zaehler;
+
+BOOL VAR wechsel := TRUE;
+
+INT PROC durchschuss :
+
+ zeilen zaehler INCR 1;
+ IF zeilen zaehler <= anzahl durchschuss 1
+ THEN durchschuss 1
+ ELIF zeilen zaehler <= anzahl durchschuss
+ THEN durchschuss 2
+ ELSE 0
+ FI
+
+END PROC durchschuss;
+
+
+PROC neuer durchschuss (INT CONST anzahl, rest l) :
+
+ zeilen zaehler := 0;
+ anzahl durchschuss := anzahl;
+ IF anzahl > 0
+ THEN IF wechsel
+ THEN durchschuss 1 := rest l DIV anzahl durchschuss;
+ durchschuss 2 := durchschuss 1 + sign (rest l);
+ anzahl durchschuss 1 := anzahl durchschuss -
+ abs (rest l) MOD anzahl durchschuss;
+ wechsel := FALSE;
+ ELSE durchschuss 2 := rest l DIV anzahl durchschuss;
+ durchschuss 1 := durchschuss 2 + sign (rest l);
+ anzahl durchschuss 1 := abs (rest l) MOD anzahl durchschuss;
+ wechsel := TRUE;
+ FI;
+ ELSE loesche durchschuss
+ FI;
+
+END PROC neuer durchschuss;
+
+
+PROC loesche durchschuss :
+
+ durchschuss 1 := 0;
+ durchschuss 2 := 0;
+ anzahl durchschuss 1 := 0;
+ anzahl durchschuss := 0;
+ zeilen zaehler := 0;
+
+END PROC loesche durchschuss;
+
+(****************************************************************)
+
+PROC initialisierung :
+
+ INT VAR index;
+ forget (ds);
+ ds := nilspace; tokenspeicher := ds;
+ loesche druckspeicher;
+ loesche anweisungsspeicher;
+ loesche indexspeicher;
+ initialisiere markierung;
+ right modus := FALSE;
+ center modus := FALSE;
+ seite ist offen := FALSE;
+ pass := 0;
+ a breite := 0;
+ a modifikationen fuer x move := 0;
+ aktuelle zeilentiefe der letzten zeile := 0;
+ d code 1 := leer;
+ erstes fuell token := leer;
+ IF two bytes
+ THEN FOR index FROM 1 UPTO 129 REP zeichen zaehler (index) := 1 PER;
+ FOR index FROM 130 UPTO 160 REP zeichen zaehler (index) := - maxint PER;
+ FOR index FROM 161 UPTO 224 REP zeichen zaehler (index) := 1 PER;
+ FOR index FROM 225 UPTO 240 REP zeichen zaehler (index) := - maxint PER;
+ FOR index FROM 241 UPTO 256 REP zeichen zaehler (index) := 1 PER;
+ ELSE FOR index FROM 1 UPTO 256 REP zeichen zaehler (index) := 1 PER;
+ FI;
+
+END PROC initialisierung;
+
+(****************************************************************)
+(*** print - Kommando ***)
+
+BOOL VAR elan listings erlaubt;
+FILE VAR eingabe;
+THESAURUS VAR elan bolds := empty thesaurus;
+
+insert (elan bolds, "PACKET"); insert (elan bolds, "PROC");
+insert (elan bolds, "PROCEDURE"); insert (elan bolds, "OP");
+insert (elan bolds, "OPERATOR"); insert (elan bolds, "LET");
+insert (elan bolds, "ROW"); insert (elan bolds, "STRUCT");
+insert (elan bolds, "TYPE"); insert (elan bolds, "BOUND");
+insert (elan bolds, "IF"); insert (elan bolds, "REP");
+insert (elan bolds, "REPEAT"); insert (elan bolds, "FOR");
+insert (elan bolds, "WHILE"); insert (elan bolds, "SELECT");
+
+with elan listings (TRUE);
+
+PROC with elan listings (BOOL CONST flag) :
+ elan listings erlaubt := flag;
+END PROC with elan listings;
+
+BOOL PROC with elan listings : elan listings erlaubt END PROC with elan listings;
+
+
+PROC print (FILE VAR file,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+ eingabe := file;
+ input (eingabe);
+ print (PROC (TEXT VAR) lese zeile, BOOL PROC is eof,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute,
+ PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) std analysator,
+ elan listings erlaubt CAND is elan source (eingabe),
+ headline (eingabe) );
+
+END PROC print;
+
+
+PROC print (FILE VAR file,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute,
+ PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator ) :
+
+ eingabe := file;
+ input (eingabe);
+ print (PROC (TEXT VAR) lese zeile, BOOL PROC is eof,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute,
+ PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator,
+ elan listings erlaubt CAND is elan source (eingabe),
+ headline (eingabe) );
+
+END PROC print;
+
+PROC lese zeile (TEXT VAR zeile l) : getline (eingabe, zeile l) END PROC lese zeile;
+
+BOOL PROC is eof : eof (eingabe) END PROC is eof;
+
+
+BOOL PROC is elan source (FILE VAR eingabe l) :
+
+hole erstes symbol;
+elan programm tag COR elan programm bold COR kommentar COR elanlist anweisung
+
+. elan programm tag :
+ symbol type = tag type CAND pos (zeile, ";") > 0
+
+. elan programm bold :
+ symbol type = bold type CAND is elan bold
+
+ . is elan bold :
+ (elan bolds CONTAINS symbol) COR deklaration COR proc oder op (naechstes symbol)
+
+ . deklaration :
+ next symbol (naechstes symbol);
+ naechstes symbol = "VAR" OR naechstes symbol = "CONST"
+
+. kommentar :
+ pos (zeile, "(*") > 0 OR pos (zeile, "{") > 0
+
+. elanlist anweisung :
+ symbol = "#" AND elanlist folgt
+
+ . elanlist folgt :
+ next symbol (naechstes symbol);
+ naechstes symbol = "elanlist"
+
+.
+ hole erstes symbol :
+ hole erstes nicht blankes symbol;
+ scan (zeile);
+ next symbol (symbol, symbol type);
+
+ . hole erstes nicht blankes symbol :
+ IF eof (eingabe l) THEN LEAVE is elan source WITH FALSE FI;
+ REP getline (eingabe l, zeile);
+ UNTIL pos (zeile, ""33"",""254"", 1) > 0 OR eof (eingabe l) PER;
+ reset (eingabe l);
+
+END PROC is elan source;
+
+(****************************************************************)
+
+bottom label for elan listings ("");
+
+PROC bottom label for elan listings (TEXT CONST label) :
+ bottom label := label;
+END PROC bottom label for elan listings;
+
+TEXT PROC bottom label for elan listings : bottom label END PROC bottom label for elan listings;
+
+
+PROC print (PROC (TEXT VAR) next line, BOOL PROC eof,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute,
+ PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator,
+ BOOL CONST elan listing, TEXT CONST file name) :
+
+disable stop;
+gedruckte seiten := 0;
+drucke datei (PROC (TEXT VAR) next line, BOOL PROC eof,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute,
+ PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator,
+ elan listing, file name );
+IF is error THEN behandle fehlermeldung FI;
+
+. behandle fehlermeldung :
+ TEXT CONST fehler meldung := error message;
+ INT CONST fehler zeile := error line,
+ fehler code := error code;
+ clear error;
+ IF NOT vor erster seite
+ THEN IF seite ist offen
+ THEN schliesse seite ab (PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute )
+ FI;
+ clear error;
+ close (document, 0);
+ clear error;
+ FI;
+ initialisierung;
+ errorstop (fehler code, fehler meldung (* + " -> " + text (fehler zeile) *) );
+
+END PROC print;
+
+d xpos := 0;
+d ypos := 0;
+d token. offset index := 1;
+material wert := "";
+gedruckte seiten := 0;
+
+INT PROC x pos : d xpos END PROC x pos;
+INT PROC y pos : d ypos END PROC y pos;
+INT PROC y offset index : d token. offset index END PROC y offset index;
+INT PROC linetype : - d token. offset index END PROC linetype;
+TEXT PROC material : material wert END PROC material;
+INT PROC pages printed : gedruckte seiten END PROC pages printed;
+
+(****************************************************************)
+
+PROC drucke datei (PROC (TEXT VAR) next line, BOOL PROC eof,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute,
+ PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator,
+ BOOL CONST elan listing, TEXT CONST file name ) :
+
+
+enable stop;
+IF elan listing
+ THEN dateiname := file name;
+ drucke elan listing;
+ ELSE drucke text datei;
+FI;
+
+.
+ drucke text datei :
+ initialisiere druck;
+ WHILE NOT eof
+ REP next line (zeile);
+ analysiere zeile (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ drucke token soweit wie moeglich;
+ werte anweisungsspeicher aus;
+ PER;
+ schliesse druck ab;
+
+.
+ initialisiere druck :
+ IF NOT initialized (in dieser task)
+ THEN ds := nilspace;
+ initialisierung
+ FI;
+ vor erster seite := TRUE;
+ tabellen modus := FALSE;
+ block modus := FALSE;
+ zeile ist absatzzeile := TRUE;
+ x wanted := x step conversion (std x wanted);
+ y wanted := y step conversion (std y wanted);
+ limit := x step conversion (std limit);
+ pagelength := y step conversion (std pagelength);
+ linefeed faktor := std linefeed faktor;
+ material wert := std material;
+ indentation := 0;
+ modifikations modus := maxint;
+ seitenlaenge := maxint;
+ papierlaenge := maxint;
+ left margin := 0;
+ top margin := 0;
+ a ypos := top margin;
+ a font := -1;
+ a modifikationen := 0;
+ aktuelle spalte := 1;
+ anzahl spalten := 1;
+ stelle neuen font ein (1);
+ loesche tabellenspeicher;
+ loesche markierung;
+ loesche alte markierung;
+ loesche durchschuss;
+
+.
+ schliesse druck ab :
+ IF NOT vor erster seite
+ THEN IF seite ist offen
+ THEN schliesse seite ab (PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute )
+ FI;
+ close (document, 0);
+ FI;
+
+.
+ drucke token soweit wie moeglich :
+ IF analysespeicher ist nicht leer
+ THEN letztes token bei gleicher ypos;
+ IF NOT seite ist offen
+ THEN eroeffne seite (x wanted, y wanted,
+ PROC (INT CONST, INT VAR, INT VAR) open);
+ FI;
+ IF seitenlaenge ueberschritten OR papierlaenge ueberschritten
+ THEN neue seite oder spalte;
+ analysiere zeile nochmal;
+ ELSE sortiere neue token ein;
+ IF in letzter spalte
+ THEN drucke tokenspeicher (a ypos,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+ FI;
+ FI;
+
+ . seitenlaenge ueberschritten :
+ a ypos + aktuelle zeilentiefe > seitenlaenge
+
+ . papierlaenge ueberschritten :
+ a ypos + aktuelle zeilentiefe > papierlaenge
+
+ . neue seite oder spalte :
+ IF in letzter spalte
+ THEN INT CONST aktuelles y wanted := y wanted bei seitenwechel ohne page;
+ schliesse seite ab (PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ eroeffne seite (x wanted, aktuelles y wanted,
+ PROC (INT CONST, INT VAR, INT VAR) open);
+ ELSE neue spalte;
+ FI;
+
+ . y wanted bei seitenwechel ohne page :
+ IF seitenlaenge ueberschritten
+ THEN y wanted
+ ELSE 0
+ FI
+
+ . analysiere zeile nochmal :
+ setze auf alte werte zurueck;
+ loesche anweisungsspeicher;
+ analysiere zeile (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ letztes token bei gleicher ypos;
+ sortiere neue token ein;
+
+ . setze auf alte werte zurueck :
+ zeile ist absatzzeile := letzte zeile war absatzzeile;
+ a modifikationen := letzte modifikationen;
+ stelle neuen font ein (letzter font);
+
+.
+ werte anweisungsspeicher aus :
+ INT VAR index;
+ FOR index FROM 1 UPTO anweisungszaehler
+ REP
+ SELECT anweisungs indizes ISUB index OF
+ CASE a block : block anweisung
+ CASE a columns : columns anweisung
+ CASE a columnsend : columnsend anweisung
+ CASE a free : free anweisung
+ CASE a limit : limit anweisung
+ CASE a linefeed : linefeed anweisung
+ CASE a material : material anweisung
+ CASE a page0, a page1 : page anweisung
+ CASE a pagelength : pagelength anweisung
+ CASE a start : start anweisung
+ CASE a table : table anweisung
+ CASE a tableend : tableend anweisung
+ CASE a clearpos0 : clearpos0 anweisung
+ CASE a clearpos1 : clearpos1 anweisung
+ CASE a lpos, a rpos, a cpos, a dpos
+ : lpos rpos cpos dpos anweisung
+ CASE a bpos : bpos anweisung
+ CASE a fillchar : fillchar anweisung
+ CASE a textbegin0 : textbegin0 anweisung
+ CASE a textbegin2 : textbegin2 anweisung
+ CASE a textend : textend anweisung
+ CASE a indentation : indentation anweisung
+ CASE a y tab : y tab anweisung
+ END SELECT
+ PER;
+ loesche anweisungsspeicher;
+
+ . block anweisung :
+ blockmodus := TRUE;
+
+ . columns anweisung :
+ IF anzahl spalten = 1 AND int conversion ok (param1)
+ AND real conversion ok (param2)
+ THEN anzahl spalten := max (1, int param);
+ luecke := x step conversion (real param);
+ FI;
+
+ . columnsend anweisung :
+ anzahl spalten := 1;
+ aktuelle spalte := 1;
+ left margin := x wanted - x start + indentation;
+
+ . free anweisung :
+ IF real conversion ok (param1) THEN a ypos INCR y step conversion (real param) FI;
+
+ . limit anweisung :
+ IF real conversion ok (param1) THEN limit := x step conversion (real param) FI;
+
+ . linefeed anweisung :
+ IF real conversion ok (param1)
+ THEN linefeed faktor := real param;
+ berechne letzte zeilengroesse;
+ FI;
+
+ . material anweisung :
+ material wert := param1;
+
+ . page anweisung :
+ IF seite ist offen
+ THEN IF NOT in letzter spalte
+ THEN neue spalte
+ ELSE schliesse seite ab (PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ papier laenge := maxint;
+ FI;
+ ELSE a ypos := top margin;
+ papier laenge := maxint;
+ FI;
+
+ . pagelength anweisung :
+ IF real conversion ok (param1)
+ THEN pagelength := y step conversion (real param);
+ FI;
+
+ . start anweisung :
+ IF real conversion ok (param1) THEN x wanted := x step conversion (real param) FI;
+ IF real conversion ok (param2) THEN y wanted := y step conversion (real param) FI;
+
+ . table anweisung :
+ tabellenmodus := TRUE;
+
+ . tableend anweisung :
+ tabellenmodus := FALSE;
+
+ . clearpos0 anweisung :
+ loesche tabellenspeicher;
+
+ . clearpos1 anweisung :
+ IF real conversion ok (param1)
+ THEN int param := x step conversion (real param);
+ FOR tab index FROM 1 UPTO anzahl tabs
+ REP IF tab position = int param
+ THEN tab typ := leer;
+ delete int (tab liste, tab index);
+ LEAVE clearpos1 anweisung;
+ FI;
+ PER;
+ FI;
+
+ . lpos rpos cpos dpos anweisung :
+ IF real conversion ok (param1)
+ THEN neuer tab eintrag (anweisungs indizes ISUB index, param2) FI;
+
+ . bpos anweisung :
+ IF real conversion ok (param2) CAND real conversion ok (param1)
+ CAND real (param2) > real param
+ THEN neuer tab eintrag (a bpos, param2) FI;
+
+ . fillchar anweisung :
+ fill char := param1;
+
+ . textbegin0 anweisung :
+ aktuelle einrueckbreite := alte einrueckbreite;
+ mark index l := alter mark index l;
+ mark index r := alter mark index r;
+ loesche alte markierung;
+
+ . textbegin2 anweisung :
+ aktuelle einrueckbreite := alte einrueckbreite;
+ mark index l := alter mark index l;
+ mark index r := alter mark index r;
+ loesche alte markierung;
+ neuer durchschuss (int (param1), y step conversion (real (param 2)));
+
+ . textend anweisung :
+ alte einrueckbreite := aktuelle einrueckbreite;
+ alter mark index l := mark index l;
+ alter mark index r := mark index r;
+ loesche markierung;
+ loesche durchschuss;
+
+ . indentation anweisung :
+(**) IF real conversion ok (param1)
+ THEN int param := x step conversion (real param);
+ left margin INCR (int param - indentation);
+ indentation := int param;
+ FI;
+(**)
+ . y tab anweisung :
+(**) IF real conversion ok (param1)
+ THEN int param := y step conversion (real param);
+ IF int param <= seitenlaenge THEN a ypos := int param FI;
+ FI;
+(**)
+ . param1 :
+ IF (params1 zeiger ISUB index) <> 0
+ THEN name (params1, params1 zeiger ISUB index)
+ ELSE ""
+ FI
+
+ . param2 :
+ IF (params2 zeiger ISUB index) <> 0
+ THEN name (params2, params2 zeiger ISUB index)
+ ELSE ""
+ FI
+
+
+.
+ drucke elan listing :
+ initialisiere elan listing;
+ WHILE NOT eof
+ REP next line (zeile);
+ zeilen nr INCR 1;
+ drucke elan zeile;
+ PER;
+ schliesse elan listing ab;
+
+.
+ initialisiere elan listing :
+ open document cmd;
+ hole elan list font;
+ initialisiere variablen;
+ elan fuss und kopf (1,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+ . open document cmd :
+ material wert := "";
+ d token. offset index := 1;
+ erster ypos index d := 0;
+ vor erster seite := FALSE;
+ seite ist offen := TRUE;
+ open (document, x size, y size);
+ vor erster seite := FALSE;
+
+ . hole elan list font :
+ d font := max (1, font ("elanlist"));
+ get replacements (d font, replacements, replacement tabelle);
+ einrueckbreite := indentation pitch (d font) ;
+ font hoehe := font lead (d font) + font height (d font) + font depth (d font);
+
+ . initialisiere variablen :
+ innerhalb einer liste := FALSE;
+ vor erstem packet := TRUE;
+ zeilen nr := 0;
+ select counter := 0;
+ y wanted := y size DIV 23;
+ pagelength := y size - y wanted - y wanted;
+ x wanted := (min (x size DIV 10, x step conversion (2.54))
+ DIV einrueckbreite) * einrueckbreite;
+ max zeichen zeile := (x size - x wanted - (x wanted DIV 3)) DIV einrueckbreite;
+ max zeichen fuss := fusszeilenbreite;
+ layout laenge := min (38, max zeichen zeile DIV 3);
+ layout laenge name := layout laenge - zeilen nr laenge - 8;
+ layout blanks := (layout laenge - zeilen nr laenge - 1) * " ";
+ refinement layout zeile := (layout laenge - 1) * " " ;
+ refinement layout zeile CAT "|" ;
+ IF pagelength DIV fonthoehe - 6 < 35 OR max zeichen zeile < 65
+ THEN errorstop ("Schreibfeld fuer 'elan listing' zu klein") FI;
+
+ . fusszeilenbreite :
+ INT CONST dina 4 breite := x step conversion (21.0);
+ IF x size <= dina 4 breite
+ THEN (x size - 2 * x wanted) DIV einrueckbreite
+ ELIF 120 * einrueckbreite <= dina 4 breite - 2 * x wanted
+ THEN (dina 4 breite - 2 * x wanted) DIV einrueckbreite
+ ELSE min (120, (x size - 2 * x wanted) DIV einrueckbreite)
+ FI
+
+.
+ schliesse elan listing ab :
+ elan fuss und kopf (-1,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ close (document, 0);
+
+.
+ drucke elan zeile :
+ IF pos (zeile, "#page#") = 1
+ THEN IF nicht am seiten anfang THEN seiten wechsel FI;
+ ELIF pos (zeile, "#elanlist#") <> 1
+ THEN bestimme elan layout;
+ bestimme elan zeile;
+ gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ seitenwechsel wenn noetig;
+ FI;
+
+ . nicht am seitenanfang :
+ rest auf seite < pagelength - 3 * font hoehe
+
+ . seiten wechsel :
+ elan fuss und kopf (0,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+.
+ bestimme elan layout :
+ IF innerhalb einer liste
+ THEN leeres layout;
+ pruefe ende der liste
+ ELIF pos (zeile, "P") <> 0 COR pos (zeile, ":") <> 0
+ THEN analysiere elan zeile
+ ELIF innerhalb einer select kette
+ THEN leeres layout;
+ pruefe ende der select kette
+ ELIF pos (zeile, "SELECT") <> 0
+ THEN analysiere select kette
+ ELSE leeres layout
+ FI;
+ elan text CAT "|";
+
+ . leeres layout :
+ elan text := text (zeilen nr, zeilen nr laenge);
+ elan text CAT layout blanks;
+
+ . analysiere elan zeile :
+ scan (zeile);
+ next symbol (symbol, symbol type);
+ next symbol (naechstes symbol, naechster symbol type);
+ IF packet anfang
+ THEN packet layout
+ ELIF type anfang
+ THEN type layout
+ ELIF proc op anfang
+ THEN proc op layout
+ ELSE IF innerhalb einer select kette
+ THEN pruefe ende der select kette;
+ leeres layout
+ ELIF refinement anfang
+ THEN refinement layout
+ ELSE leeres layout
+ FI;
+ FI;
+
+
+ . packet anfang :
+ symbol = "PACKET"
+
+ . type anfang :
+ symbol = "TYPE"
+
+ . proc op anfang :
+ IF proc oder op (symbol)
+ THEN naechster symbol type <> delimiter type
+ ELIF (symbol <> "END") AND proc oder op (naechstes symbol)
+ THEN symbol := naechstes symbol;
+ next symbol (naechstes symbol, naechster symbol type);
+ naechster symbol type <> delimiter type
+ ELSE FALSE
+ FI
+
+ . refinement anfang :
+ symbol type = tag type AND naechstes symbol = ":"
+
+ . packet layout :
+ IF nicht am seiten anfang AND
+ (NOT vor erstem packet OR gedruckte seiten > 1)
+ THEN seiten wechsel
+ FI;
+ layout (" ", naechstes symbol, "*") ;
+ vor erstem packet := FALSE;
+ select counter := 0;
+ innerhalb einer liste := TRUE;
+ pruefe ende der liste;
+
+ . type layout :
+ layout (" ", naechstes symbol, ".");
+ select counter := 0;
+
+ . proc op layout :
+ IF keine vier zeilen mehr
+ THEN seiten wechsel
+ ELIF nicht am seitenanfang
+ THEN cr plus lf (2, PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI ;
+ layout (" ", naechstes symbol, ".");
+ select counter := 0;
+ innerhalb einer liste := TRUE;
+ pruefe ende der liste;
+
+ . keine vier zeilen mehr :
+ rest auf seite <= 8 * font hoehe
+
+ . refinement layout :
+ IF keine drei zeilen mehr
+ THEN seiten wechsel
+ ELIF nicht am seitenanfang
+ THEN elan text := refinement layout zeile;
+ gib elan text aus
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI ;
+ layout (" ", symbol, " ");
+
+ . keine drei zeilen mehr :
+ rest auf seite <= 7 * font hoehe
+
+ . pruefe ende der liste :
+ IF pos (zeile, ":") <> 0
+ THEN scan (zeile);
+ WHILE innerhalb einer liste
+ REP next symbol (symbol);
+ IF symbol = ":" THEN innerhalb einer liste := FALSE FI;
+ UNTIL symbol = "" PER;
+ FI;
+
+ . innerhalb einer select kette :
+ select counter > 0
+
+ . analysiere select kette :
+ scan (zeile);
+ naechstes symbol := "";
+ REP symbol := naechstes symbol;
+ next symbol (naechstes symbol);
+ IF naechstes symbol = "SELECT" CAND symbol <> "END"
+ THEN select counter := 1;
+ untersuche select kette;
+ FI;
+ UNTIL naechstes symbol = "" PER;
+ leeres layout;
+
+ . pruefe ende der select kette :
+ IF pos (zeile, "SELECT") <> 0
+ THEN scan (zeile);
+ naechstes symbol := "";
+ untersuche select kette;
+ FI;
+
+ . untersuche select kette :
+ REP symbol := naechstes symbol;
+ next symbol (naechstes symbol);
+ IF naechstes symbol = "SELECT"
+ THEN select counter INCR select step
+ ELIF naechstes symbol = "ENDSELECT"
+ THEN select counter DECR 1
+ FI;
+ UNTIL naechstes symbol = "" PER;
+
+ . select step :
+ IF symbol = "END" THEN -1 ELSE 1 FI
+
+.
+ bestimme elan zeile :
+ IF zeile ist nicht zu lang
+ THEN elan text CAT zeile;
+ ELSE drucke zeile in teilen
+ FI;
+
+ . zeile ist nicht zu lang :
+ zeilen laenge := LENGTH zeile;
+ zeilen laenge <= rest auf zeile
+
+ . rest auf zeile :
+ max zeichen zeile - LENGTH elan text
+
+ . drucke zeile in teilen :
+ zeilen pos := 1;
+ bestimme einrueckung;
+ WHILE zeile noch nicht ganz gedruckt REP teil layout PER;
+
+ . bestimme einrueckung :
+ anzahl einrueck blanks := naechstes nicht blankes zeichen - 1;
+ IF anzahl einrueck blanks > rest auf zeile - 20
+ THEN anzahl einrueck blanks := 0 FI;
+
+ . zeile noch nicht ganz gedruckt :
+ bestimme zeilenteil;
+ NOT zeile ist zu ende
+
+ . bestimme zeilenteil :
+ bestimme laenge;
+ zeilen teil := subtext (zeile, zeilen pos, zeilen pos + laenge - 1);
+ elan text CAT zeilen teil;
+ zeilen pos INCR laenge;
+
+ . zeilen teil : par1
+
+ . bestimme laenge :
+ INT VAR laenge := zeilen laenge - zeilen pos + 1;
+ IF laenge > rest auf zeile
+ THEN laenge := rest auf zeile;
+ WHILE (zeile SUB (zeilen pos + laenge - 1)) <> " "
+ REP laenge DECR 1 UNTIL laenge = 0 PER;
+ IF laenge = 0 THEN laenge := rest auf zeile FI;
+ FI;
+
+ . teil layout :
+ gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ elan text := (zeilen nr laenge - 1) * " ";
+ elan text CAT "+";
+ elan text CAT layout blanks;
+ elan text CAT "|";
+ elan text cat blanks (anzahl einrueck blanks + teil einrueckung);
+
+.
+ seiten wechsel wenn noetig :
+ IF keine zeilen mehr AND NOT eof THEN seiten wechsel FI;
+
+ . keine zeilen mehr :
+ rest auf seite <= 4 * font hoehe
+
+END PROC drucke datei;
+
+
+BOOL PROC real conversion ok (TEXT CONST param) :
+ real param := real (param);
+ last conversion ok AND real param >= 0.0
+END PROC real conversion ok;
+
+
+BOOL PROC int conversion ok (TEXT CONST param) :
+ int param := int (param);
+ last conversion ok AND int param >= 0
+END PROC int conversion ok;
+
+
+PROC neuer tab eintrag (INT CONST typ, TEXT CONST param) :
+
+ suche neuen eintrag;
+ sortiere neue tab position ein;
+ tab typ := typ;
+ tab position := neue tab position;
+ tab param := eventueller parameter;
+
+ . suche neuen eintrag :
+ INT VAR index := 0;
+ REP index INCR 1;
+ IF tab speicher (index). tab typ = leer
+ THEN LEAVE suche neuen eintrag FI;
+ UNTIL index = max tabs PER;
+ LEAVE neuer tab eintrag;
+
+ . sortiere neue tab position ein :
+ INT VAR neue tab position := x step conversion (real param);
+ FOR tab index FROM 1 UPTO anzahl tabs
+ REP IF tab position = neue tab position
+ THEN LEAVE neuer tab eintrag
+ ELIF tab position > neue tab position
+ THEN insert int (tab liste, tab index, index);
+ LEAVE sortiere neue tab position ein;
+ FI;
+ PER;
+ tab liste CAT index;
+ tab index := anzahl tabs;
+
+ . eventueller parameter :
+ INT VAR link;
+ SELECT typ OF
+ CASE a dpos : insert (d strings, param, link); link
+ CASE a bpos : x step conversion (real(param))
+ OTHERWISE : 0
+ END SELECT
+
+END PROC neuer tab eintrag;
+
+
+PROC neue spalte :
+ a ypos := top margin;
+ aktuelle zeilentiefe der letzten zeile := 0;
+ left margin INCR (limit + luecke);
+ aktuelle spalte INCR 1;
+END PROC neue spalte ;
+
+
+BOOL PROC proc oder op (TEXT CONST symbol) :
+
+ symbol = "PROC" OR symbol = "PROCEDURE"
+ OR symbol = "OP" OR symbol = "OPERATOR"
+
+ENDPROC proc oder op ;
+
+
+PROC layout (TEXT CONST pre, TEXT VAR name, TEXT CONST post) :
+
+name := subtext (name, 1, layout laenge name) ;
+elan text := text (zeilen nr, zeilen nr laenge);
+elan text CAT pre;
+elan text CAT name;
+elan text CAT " ";
+generiere strukturiertes layout;
+
+. generiere strukturiertes layout :
+ INT VAR index;
+ FOR index FROM 1 UPTO layout laenge - LENGTH elan text - 1
+ REP elan text CAT post PER;
+
+END PROC layout ;
+
+
+PROC elan text cat blanks (INT CONST anzahl) :
+
+ par2 := anzahl * " ";
+ elan text CAT par2;
+
+END PROC elan text cat blanks;
+
+
+(***********************************************************************)
+
+PROC analysiere zeile (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator) :
+
+loesche analysespeicher;
+behandle fuehrende blanks;
+pruefe ob markierung links;
+
+IF tabellen modus
+ THEN analysiere tabellenzeile
+ELIF letzte zeile war absatzzeile
+ THEN analysiere zeile nach absatzzeile
+ ELSE analysiere zeile nach blockzeile
+FI;
+
+pruefe center und right modus;
+pruefe ob tabulation vorliegt;
+werte indexspeicher aus;
+IF zeile ist keine anweisungszeile
+ THEN berechne zeilenvorschub;
+ pruefe ob markierung rechts;
+ ELSE behandle anweisungszeile;
+FI;
+
+.
+ analysiere zeile nach absatzzeile :
+ test auf aufzaehlung;
+ IF zeile muss geblockt werden
+ THEN analysiere blockzeile nach absatzzeile
+ ELSE analysiere absatzzeile nach absatzzeile
+ FI;
+.
+ analysiere zeile nach blockzeile :
+ IF zeile muss geblockt werden
+ THEN analysiere blockzeile nach blockzeile
+ ELSE analysiere absatzzeile nach blockzeile
+ FI;
+
+
+.
+ behandle fuehrende blanks :
+ zeilenpos := 1;
+ zeilenpos := naechstes nicht blankes zeichen;
+ letzte zeile war absatzzeile := zeile ist absatzzeile;
+ IF letzte zeile war absatzzeile THEN neue einrueckung FI;
+ IF zeilenpos = 0
+ THEN behandle leerzeile;
+ LEAVE analysiere zeile;
+ ELSE initialisiere analyse;
+ FI;
+
+ . behandle leerzeile :
+ a ypos INCR (letzte zeilenhoehe +
+ aktuelle zeilentiefe der letzten zeile + durchschuss);
+ aktuelle zeilentiefe der letzten zeile := letzte zeilentiefe;
+ zeile ist absatzzeile := LENGTH zeile > 0;
+ pruefe ob markierung links;
+ pruefe ob markierung rechts;
+
+ . neue einrueckung :
+ aktuelle einrueckbreite := einrueckbreite;
+
+ . initialisiere analyse :
+ zeile ist absatzzeile := (zeile SUB LENGTH zeile) = blank;
+ zeile muss geblockt werden := block modus AND NOT zeile ist absatzzeile;
+ erstes token der zeile := token index f + 1;
+ zeilen laenge := laenge der zeile;
+ anzahl einrueck blanks := zeilen pos - 1;
+ anzahl zeichen := anzahl einrueck blanks;
+ a xpos := left margin + anzahl zeichen * aktuelle einrueckbreite;
+ a modifikationen fuer x move := 0;
+ letzter font := a font;
+ letzte modifikationen := a modifikationen;
+ fuehrende anweisungen := 0;
+ initialisiere zeilenvorschub;
+ IF zeile muss geblockt werden THEN initialisiere tab variablen FI;
+ IF hoechster index zaehler > 0 THEN loesche index speicher FI;
+
+ . laenge der zeile :
+ IF zeile ist absatzzeile
+ THEN LENGTH zeile - 1
+ ELSE LENGTH zeile
+ FI
+
+.
+ pruefe ob markierung links :
+ INT VAR linkes markierungs token;
+ IF markierung links
+ THEN mark token (mark index l). xpos :=
+ left margin - mark token (mark index l). breite;
+ linkes markierungs token := token index f + 1;
+ lege markierungs token an (mark index l);
+ erstes token der zeile := token index f + 1;
+ initialisiere tab variablen;
+ ELSE linkes markierungs token := 0;
+ FI;
+
+.
+ analysiere tabellenzeile :
+ anfangs blankmodus := doppel blank;
+ alte zeilenpos := zeilen pos;
+ a xpos := left margin;
+ FOR tab index FROM 1 UPTO anzahl tabs
+ REP lege fuell token an wenn noetig;
+ initialisiere tab variablen;
+ SELECT tab typ OF
+ CASE a lpos : linksbuendige spalte
+ CASE a rpos : rechtsbuendige spalte
+ CASE a cpos : zentrierte spalte
+ CASE a dpos : dezimale spalte
+ CASE a bpos : geblockte spalte
+ END SELECT;
+ berechne fuell token wenn noetig;
+ tabulation;
+ PER;
+ analysiere rest der zeile;
+
+ . lege fuell token an wenn noetig :
+ IF fill char <> blank
+ THEN fuellzeichen := fill char;
+ fuellzeichen breite := string breite (fuellzeichen);
+ token zeiger := zeilen pos;
+ erstes fuell token := token index f + 1;
+ lege token an (zeile, token zeiger, zeilen pos - 1, text token);
+ letztes fuell token := token index f;
+ a modifikationen fuer x move := a modifikationen
+ FI;
+
+ . berechne fuell token wenn noetig :
+ IF erstes fuell token <> leer
+ THEN IF letztes fuell token <> token index f
+ THEN berechne fuell token;
+ ELSE loesche letzte token;
+ FI;
+ erstes fuell token := leer
+ FI;
+
+ . berechne fuell token :
+ INT VAR anzahl fuellzeichen, fuell breite;
+ token index := erstes fuell token;
+ anzahl fuellzeichen := (tab anfang - t. xpos + left margin)
+ DIV fuellzeichen breite;
+ rest := (tab anfang - t. xpos + left margin)
+ MOD fuellzeichen breite;
+ IF anzahl fuell zeichen > 0
+ THEN fuell text := anzahl fuellzeichen * fuellzeichen;
+ fuell breite := anzahl fuellzeichen * fuellzeichen breite;
+ FOR token index FROM erstes fuell token UPTO letztes fuell token
+ REP t. text := fuell text;
+ t. breite := fuell breite;
+ IF erstes fuell token <> erstes token der zeile
+ THEN t. xpos INCR rest DIV 2;
+ t. modifikationen fuer x move := t. modifikationen;
+ FI;
+ PER;
+ FI;
+
+ . fuell text : par1
+
+ . loesche letzte token :
+ FOR token index FROM letztes fuell token DOWNTO erstes fuell token
+ REP loesche letztes token PER;
+
+ . tabulation :
+ alte zeilenpos := zeilenpos;
+ zeilenpos := naechstes nicht blankes zeichen;
+ IF zeilenpos = 0
+ THEN zeilenpos := zeilenlaenge + 1;
+ LEAVE analysiere tabellenzeile;
+ FI;
+ anzahl zeichen INCR zeilenpos - alte zeilenpos;
+
+ . linksbuendige spalte :
+ a xpos := left margin + tab position;
+ tab anfang := tab position;
+ bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+
+ . rechtsbuendige spalte :
+ bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ schreibe zeile rechtsbuendig (tab position);
+
+ . zentrierte spalte :
+ bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ zentriere zeile (tab position);
+
+ . dezimale spalte :
+ d string := name (d strings, tab param);
+ d code 1 := code (d string SUB 1) + 1;
+ d pitch := zeichenbreiten (d code 1);
+ zeichenbreiten (d code 1) := d code ausgang;
+ bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ zeichenbreiten (d code 1) := d pitch;
+ d code 1 := leer;
+ schreibe zeile rechtsbuendig (tab position);
+ IF zeichen ist dezimal zeichen
+ THEN IF tab position <> zeilen breite
+ THEN a xpos := left margin + tab position;
+ tab anfang := tab position;
+ FI;
+ bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ FI;
+
+ . zeichen ist dezimal zeichen :
+ pos (zeile, d string, zeilen pos) = zeilen pos
+
+ . geblockte spalte :
+ blankmodus := einfach blank;
+ a xpos := left margin + tab position;
+ tab anfang := tab position;
+ REP bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ IF zeile ist zu ende OR naechstes zeichen ist blank
+ THEN blocke spalte wenn noetig;
+ LEAVE geblockte spalte;
+ ELSE dehnbares blank gefunden;
+ FI;
+ PER;
+
+ . blocke spalte wenn noetig :
+ IF letztes zeichen ist kein geschuetztes blank
+ THEN blocke zeile (tab param) FI;
+ blank modus := doppel blank;
+
+ . letztes zeichen ist kein geschuetztes blank :
+ pos (zeile, geschuetztes blank, zeilen pos - 1, zeilen pos - 1) = 0
+ AND NOT within kanji (zeile, zeilen pos - 2)
+
+ . analysiere rest der zeile :
+ blankmodus := keine blankanalyse;
+ zeilen pos := alte zeilenpos;
+ bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+
+.
+ test auf aufzaehlung :
+ anfangs blankmodus := einfach blank;
+ bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ IF zeile ist zu ende
+ THEN LEAVE analysiere zeile nach absatzzeile
+ ELSE aufzaehlung moeglich
+ FI;
+
+ . aufzaehlung moeglich :
+ bestimme letztes zeichen;
+ IF (anzahl zeichen bei aufzaehlung < 2 AND letztes zeichen = "-")
+ OR (anzahl zeichen bei aufzaehlung < 20 AND letztes zeichen = ":")
+ OR (anzahl zeichen bei aufzaehlung < 7
+ AND pos (".)", letztes zeichen) <> 0)
+ OR naechstes zeichen ist blank
+ THEN tabulator position gefunden;
+ ELIF zeile muss geblockt werden
+ THEN dehnbares blank gefunden;
+ FI;
+
+ . bestimme letztes zeichen :
+ token index := token index f;
+ WHILE token index >= erstes token der zeile
+ REP IF token ist text token
+ THEN letztes zeichen := t. text SUB LENGTH t. text;
+ LEAVE bestimme letztes zeichen;
+ FI;
+ token index DECR 1;
+ PER;
+ letztes zeichen := "";
+
+ . letztes zeichen : par1
+
+ . anzahl zeichen bei aufzaehlung :
+ anzahl zeichen - anzahl einrueck blanks
+
+ . token ist text token :
+ t. offset index >= text token
+.
+ analysiere blockzeile nach absatzzeile :
+ REP bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ IF zeile ist zu ende
+ THEN blocke zeile (limit);
+ LEAVE analysiere blockzeile nach absatzzeile
+ ELSE analysiere blank in blockzeile nach absatzzeile
+ FI;
+ PER;
+
+ . analysiere blank in blockzeile nach absatzzeile :
+ IF naechstes zeichen ist blank
+ THEN tabulator position gefunden;
+ ELSE dehnbares blank gefunden;
+ FI;
+
+.
+ analysiere absatzzeile nach absatzzeile :
+ blankmodus := doppel blank;
+ REP bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ IF zeile ist zu ende
+ THEN LEAVE analysiere absatzzeile nach absatzzeile
+ ELSE tabulator position gefunden
+ FI;
+ PER;
+
+.
+ analysiere blockzeile nach blockzeile :
+ anfangs blankmodus := einfach blank;
+ REP bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ IF zeile ist zu ende
+ THEN blocke zeile (limit);
+ LEAVE analysiere blockzeile nach blockzeile
+ ELSE dehnbares blank gefunden
+ FI;
+ PER;
+
+.
+ analysiere absatzzeile nach blockzeile :
+ anfangs blankmodus := keine blankanalyse;
+ bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+
+
+.
+ dehnbares blank gefunden :
+ anzahl zeichen INCR 1;
+ zeilenpos INCR 1;
+ a xpos INCR blankbreite;
+ a modifikationen fuer x move := a modifikationen;
+ IF NOT a block token
+ THEN anzahl blanks INCR 1;
+ a block token := TRUE;
+ FI;
+.
+ tabulator position gefunden :
+ alte zeilenpos := zeilenpos;
+ zeilenpos := naechstes nicht blankes zeichen;
+ IF zeilenpos = 0
+ THEN zeilenpos := zeilen laenge + 1;
+ ELSE IF erstes token der zeile > token index f
+ THEN token zeiger := zeilen pos;
+ lege token an (zeile, token zeiger, zeilen pos - 1, text token);
+ FI;
+ anzahl zeichen INCR (zeilenpos - alte zeilenpos);
+ a xpos := left margin + anzahl zeichen * aktuelle einrueckbreite;
+ a modifikationen fuer x move := a modifikationen;
+ IF zeile muss geblockt werden THEN initialisiere tab variablen FI;
+ FI;
+
+.
+ pruefe center und right modus :
+ IF center modus THEN zentriere zeile (limit DIV 2) FI;
+ IF right modus THEN schreibe zeile rechtsbuendig (limit) FI;
+.
+ pruefe ob tabulation vorliegt:
+ IF analyse speicher ist nicht leer CAND a xpos > tf. xpos + tf. breite
+ THEN a modifikationen fuer x move := a modifikationen;
+ token zeiger := zeilen pos;
+ lege token an (zeile, token zeiger, zeilen pos - 1, text token);
+ FI;
+.
+ werte indexspeicher aus :
+ INT VAR index;
+ IF index zaehler > 0
+ THEN FOR index FROM index zaehler DOWNTO 1
+ REP a ypos DECR (index verschiebung ISUB index);
+ IF (letzte index breite ISUB index) <> 0
+ THEN a xpos := (xpos vor index ISUB index) +
+ min (a xpos - (xpos vor index ISUB index),
+ letzte index breite ISUB index);
+ FI;
+ PER;
+ stelle neuen font ein (grosse fonts ISUB 1);
+ FI;
+.
+ zeile ist keine anweisungszeile :
+ fuehrende anweisungen <> zeilen laenge
+.
+ berechne zeilenvorschub :
+ verschiebung := aktuelle zeilenhoehe +
+ aktuelle zeilentiefe der letzten zeile + durchschuss;
+ aktuelle zeilentiefe der letzten zeile := aktuelle zeilentiefe;
+ a ypos INCR verschiebung;
+ verschiebe token ypos (verschiebung);
+
+.
+ pruefe ob markierung rechts :
+ IF markierung rechts
+ THEN mark token (mark index r). xpos := left margin + limit;
+ lege markierungs token an (mark index r);
+ FI;
+.
+ behandle anweisungszeile :
+ IF linkes markierungs token > 0
+ THEN IF erstes token der zeile = token index f + 1
+ THEN loesche analysespeicher;
+ ELSE FOR token index FROM linkes markierungs token
+ UPTO erstes token der zeile - 1
+ REP t. text := "";
+ t. xpos := 0;
+ t. breite := 0;
+ PER;
+ FI;
+ FI;
+
+END PROC analysiere zeile;
+
+
+PROC blocke zeile (INT CONST rechter rand) :
+
+rest := rechter rand - zeilen breite;
+IF rest > 0 AND anzahl blanks > 0
+ THEN INT CONST schmaler schritt := rest DIV anzahl blanks,
+ breiter schritt := schmaler schritt + 1,
+ anzahl breite schritte := rest MOD anzahl blanks;
+ IF rechts
+ THEN blocke token xpos (breiter schritt, schmaler schritt,
+ anzahl breite schritte);
+ rechts := FALSE;
+ ELSE blocke token xpos (schmaler schritt, breiter schritt,
+ anzahl blanks - anzahl breite schritte);
+ rechts := TRUE;
+ FI;
+ a xpos INCR ( breiter schritt * anzahl breite schritte +
+ schmaler schritt * (anzahl blanks - anzahl breite schritte) );
+FI;
+
+END PROC blocke zeile;
+
+
+PROC zentriere zeile (INT CONST zentrier pos) :
+
+IF erstes tab token <= token index f
+ THEN verschiebung := zentrier pos - tab anfang -
+ (zeilen breite - tab anfang) DIV 2;
+ verschiebe token xpos (verschiebung);
+ a xpos INCR verschiebung;
+ tab anfang INCR verschiebung;
+FI;
+center modus := FALSE;
+
+END PROC zentriere zeile;
+
+
+PROC schreibe zeile rechtsbuendig (INT CONST rechte pos) :
+
+IF erstes tab token <= token index f
+ THEN verschiebung := rechte pos - zeilen breite;
+ verschiebe token xpos (verschiebung);
+ a xpos INCR verschiebung;
+ tab anfang INCR verschiebung;
+FI;
+right modus := FALSE;
+
+
+END PROC schreibe zeile rechtsbuendig;
+
+
+PROC bestimme token bis terminator oder zeilenende
+ (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator):
+
+token zeiger := zeilen pos;
+REP stranalyze (zeichenbreiten, a breite, max breite,
+ zeile, zeilen pos, zeilen laenge,
+ ausgang);
+ zeilen pos INCR 1;
+ IF ausgang = blank ausgang
+ THEN analysiere blank
+ ELIF ausgang = anweisungs ausgang
+ THEN anweisung gefunden
+ ELIF ausgang = d code ausgang
+ THEN analysiere d string
+ ELIF ausgang = erweiterungs ausgang
+ THEN erweiterung gefunden
+ ELSE terminator oder zeilenende gefunden
+ FI;
+PER;
+
+. analysiere blank :
+ IF blankmodus = einfach blank OR
+ (blankmodus = doppel blank AND naechstes zeichen ist blank)
+ THEN terminator oder zeilenende gefunden
+ ELSE a breite INCR blankbreite;
+ zeilenpos INCR 1;
+ FI;
+
+. analysiere d string :
+ IF pos (zeile, d string, zeilen pos) = zeilen pos
+ THEN terminator oder zeilenende gefunden
+ ELSE IF d pitch = maxint
+ THEN erweiterung gefunden
+ ELIF d pitch < 0
+ THEN a breite INCR (d pitch XOR - maxint - 1);
+ zeilen pos INCR 2;
+ ELSE a breite INCR d pitch;
+ zeilenpos INCR 1;
+ FI;
+ FI;
+
+. erweiterung gefunden :
+ a breite INCR extended char pitch (a font, zeile SUB zeilen pos,
+ zeile SUB zeilen pos + 1);
+ zeilen pos INCR 2;
+
+. anweisung gefunden :
+ gegebenfalls neues token gefunden;
+ analysiere anweisung (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ IF zeile ist zu ende
+ THEN LEAVE bestimme token bis terminator oder zeilenende FI;
+ token zeiger := zeilenpos;
+
+. terminator oder zeilenende gefunden :
+ IF ausgang = null ausgang THEN zeilen laenge DECR 1 FI;
+ gegebenfalls neues token gefunden;
+ LEAVE bestimme token bis terminator oder zeilenende;
+
+ . gegebenfalls neues token gefunden :
+ IF token zeiger < zeilenpos
+ THEN lege token an (zeile, token zeiger, zeilen pos - 1, text token) FI;
+
+END PROC bestimme token bis terminator oder zeilen ende;
+
+
+PROC analysiere anweisung (PROC (INT CONST, TEXT VAR,
+ INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator) :
+
+ bestimme anweisung;
+ IF anweisung ist kommando
+ THEN lege token an (anweisung, 1, maxint, kommando token);
+ ELIF anweisung ist kein kommentar
+ THEN werte anweisung aus;
+ FI;
+
+ . anweisungsende : zeilen pos - 2
+
+ . erstes zeichen : par1
+
+. bestimme anweisung :
+ INT CONST anweisungsanfang := zeilenpos + 1;
+ zeilen pos := pos (zeile, anweisungszeichen, anweisungsanfang, zeilenlaenge);
+ IF zeilenpos = 0
+ THEN zeilenpos := anweisungsanfang - 1;
+ replace (zeile, zeilenpos, geschuetztes anweisungszeichen);
+ LEAVE analysiere anweisung;
+ FI;
+ IF fuehrende anweisungen = anweisungsanfang - 2 THEN fuehrende anweisungen := zeilen pos FI;
+ zeilen pos INCR 1;
+ anweisung := subtext (zeile, anweisungsanfang, anweisungsende);
+ erstes zeichen := anweisung SUB 1;
+
+. anweisung ist kommando :
+ IF erstes zeichen = quote
+ THEN scan (anweisung);
+ next symbol (anweisung, symbol type);
+ next symbol (par2, naechster symbol type);
+ IF symbol type <> text type OR naechster symbol type <> eof type
+ THEN LEAVE analysiere anweisung FI;
+ TRUE
+ ELIF erstes zeichen = druckerkommando zeichen
+ THEN delete char (anweisung, 1);
+ TRUE
+ ELSE FALSE
+ FI
+
+. anweisung ist kein kommentar :
+ erstes zeichen <> kommentar zeichen
+
+.
+ werte anweisung aus :
+ analyze command (anweisungs liste, anweisung, number type,
+ anweisungs index, anzahl params, par1, par2);
+ SELECT anweisungs index OF
+ CASE a type : type anweisung
+ CASE a on : on anweisung
+ CASE a off : off anweisung
+ CASE a ub, a fb : ub fb anweisung
+ CASE a ue, a fe : ue fe anweisung
+ CASE a center : center anweisung
+ CASE a right : right anweisung
+ CASE a up, a down : index anweisung
+ CASE a end up or down : end index anweisung
+ CASE a bsp : bsp anweisung
+ CASE a fillchar : fillchar anweisung
+ CASE a mark : mark anweisung
+ CASE a markend : markend anweisung
+ OTHERWISE : IF anweisungs index > 0
+ THEN speichere anweisung
+ ELSE rufe analysator
+ FI;
+ END SELECT;
+
+ . type anweisung :
+ change all (par1, " ", "");
+ stelle neuen font ein (font (par1));
+ a modifikationen := 0;
+ ueberpruefe groesste fontgroesse;
+ IF nicht innerhalb eines indexes
+ THEN berechne aktuelle zeilengroesse FI;
+
+ . nicht innerhalb eines indexes :
+ index zaehler = 0
+
+ . on anweisung :
+ par1 := par1 SUB 1;
+ IF pos (modifikations liste, par1) > 0
+ THEN set bit (a modifikationen, pos (modifikations liste, par1) - 1 );
+ FI;
+
+ . off anweisung :
+ par1 := par1 SUB 1;
+ IF pos (modifikations liste, par1) > 0
+ THEN reset bit (a modifikationen, pos (modifikations liste, par1) - 1 );
+ FI;
+
+ . ub fb anweisung :
+ IF anweisungs index = a ub
+ THEN par1 := "u"
+ ELSE par1 := "b"
+ FI;
+ on anweisung;
+
+ . ue fe anweisung :
+ IF anweisungs index = a ue
+ THEN par1 := "u"
+ ELSE par1 := "b"
+ FI;
+ off anweisung;
+
+ . center anweisung :
+ IF NOT zeile muss geblockt werden AND NOT tabellen modus
+ AND NOT right modus
+ THEN center modus := TRUE;
+ blankmodus := keine blankanalyse;
+ initialisiere tab variablen;
+ FI;
+
+ . right anweisung :
+ IF NOT zeile muss geblockt werden AND NOT tabellen modus
+ THEN IF center modus THEN zentriere zeile (limit DIV 2) FI;
+ right modus := TRUE;
+ blankmodus := keine blankanalyse;
+ initialisiere tab variablen;
+ FI;
+
+ . index anweisung :
+ INT CONST grosser font := a font,
+ grosse fonthoehe := fonthoehe, grosse fonttiefe := fonttiefe;
+ INT VAR kleiner font;
+ IF next smaller font exists (grosser font, kleiner font)
+ THEN stelle neuen font ein (kleiner font) FI;
+ IF font hoehe < grosse fonthoehe
+ THEN verschiebung := verschiebung fuer kleinen font
+ ELSE verschiebung := verschiebung fuer grossen font
+ FI;
+ a ypos INCR verschiebung;
+ merke index werte;
+
+ . verschiebung fuer kleinen font :
+ IF anweisungs index = a down
+ THEN 15 PROZENT (grosse fonthoehe + grosse fonttiefe)
+ ELSE - ( 4 PROZENT (grosse fonthoehe + grosse fonttiefe) )
+ - (grosse fonthoehe + grosse fonttiefe - fonthoehe - fonttiefe)
+ FI
+
+ . verschiebung fuer grossen font :
+ IF anweisungs index = a down
+ THEN 25 PROZENT (fonthoehe + fonttiefe)
+ ELSE - (50 PROZENT (fonthoehe + fonttiefe) )
+ FI
+
+ . merke index werte :
+ index zaehler INCR 1;
+ IF hoechster index zaehler < index zaehler
+ THEN neues index level
+ ELSE altes index level
+ FI;
+ IF index zaehler = 1
+ THEN alter blankmodus := blankmodus;
+ blankmodus := keine blankanalyse;
+ FI;
+
+ . neues index level :
+ hoechster index zaehler := index zaehler;
+ letzte index breite CAT 0;
+ xpos vor index CAT a xpos;
+ zeilenpos nach index CAT -1;
+ index verschiebung CAT verschiebung;
+ grosse fonts CAT grosser font;
+
+ . altes index level :
+ IF (zeilenpos nach index ISUB index zaehler) = anweisungsanfang - 1
+ AND sign (index verschiebung ISUB index zaehler) <> sign (verschiebung)
+ THEN doppelindex gefunden;
+ ELSE replace (xpos vor index, index zaehler, a xpos);
+ FI;
+ replace (index verschiebung, index zaehler, verschiebung);
+ replace (grosse fonts, index zaehler, grosser font);
+
+ . doppelindex gefunden :
+ replace (letzte index breite, index zaehler,
+ a xpos - (xpos vor index ISUB index zaehler));
+ a xpos := xpos vor index ISUB index zaehler;
+
+ . end index anweisung :
+ IF index zaehler > 0
+ THEN schalte auf alte index werte zurueck;
+ FI;
+
+ . schalte auf alte index werte zurueck :
+ IF index zaehler = 1 THEN blankmodus := alter blankmodus FI;
+ a ypos DECR (index verschiebung ISUB index zaehler);
+ stelle neuen font ein (grosse fonts ISUB index zaehler);
+ IF (letzte index breite ISUB index zaehler) <> 0
+ THEN berechne doppelindex
+ ELSE replace (zeilenpos nach index, index zaehler, zeilenpos);
+ FI;
+ index zaehler DECR 1;
+
+ . berechne doppelindex :
+ a xpos := (xpos vor index ISUB index zaehler) +
+ max (a xpos - (xpos vor index ISUB index zaehler),
+ letzte index breite ISUB index zaehler);
+ replace (zeilenpos nach index, index zaehler, -1);
+ replace (letzte index breite, index zaehler, 0);
+
+ . bsp anweisung :
+ INT VAR breite davor, breite dahinter;
+ IF anweisungs anfang - 2 >= 1 AND anweisungs ende + 2 <= zeilen laenge
+ THEN IF is kanji esc (zeile SUB anweisungs anfang - 3)
+ THEN zeichen davor := subtext (zeile, anweisungs anfang - 3,
+ anweisungs anfang - 2);
+ ELSE zeichen davor := zeile SUB anweisungs anfang - 2;
+ FI;
+ IF is kanji esc (zeile SUB anweisungs ende + 2)
+ THEN zeichen dahinter := subtext (zeile, anweisungs ende + 2,
+ anweisungs ende + 3 );
+ ELSE zeichen dahinter := zeile SUB anweisungs ende + 2;
+ FI;
+ IF pos (" #", zeichen davor) = 0 AND pos (" #", zeichen dahinter) = 0
+ THEN breite davor := char pitch (a font, zeichen davor);
+ breite dahinter := char pitch (a font, zeichen dahinter);
+ IF breite davor < breite dahinter THEN vertausche zeichen FI;
+ lege token fuer zeichen dahinter an;
+ a xpos INCR (breite davor - breite dahinter) DIV 2;
+ FI;
+ FI;
+
+ . zeichen davor : par1
+ . zeichen dahinter : par2
+
+ . vertausche zeichen :
+ change (zeile, anweisungs anfang - 2 - LENGTH zeichen davor + 1,
+ anweisungs anfang - 2, zeichen dahinter);
+ change (zeile, anweisungs ende + 2,
+ anweisungs ende + 2 + LENGTH zeichen dahinter - 1, zeichen davor);
+ change (tf. text, LENGTH tf. text - LENGTH zeichen davor + 1,
+ LENGTH tf. text, zeichen dahinter);
+ tf. breite INCR (breite dahinter - breite davor);
+ a xpos INCR (breite dahinter - breite davor);
+ int param := breite davor;
+ breite davor := breite dahinter;
+ breite dahinter := int param;
+
+ . lege token fuer zeichen dahinter an :
+ token zeiger := zeilen pos;
+ a breite := breite dahinter;
+ zeilen pos INCR LENGTH zeichen dahinter;
+ a xpos DECR (breite davor + breite dahinter) DIV 2;
+ lege token an (zeile, token zeiger, zeilen pos - 1, text token);
+ anzahl zeichen DECR 1;
+
+ . fillchar anweisung :
+ IF par1 = "" THEN par1 := " " FI;
+ fill char := par1;
+ speichere anweisung;
+
+ . mark anweisung :
+ IF par1 <> ""
+ THEN mark index l := (alter mark index l MOD 2) + 1;
+ neue markierung (par1, mark index l);
+ ELSE mark index l := 0;
+ FI;
+ IF par2 <> ""
+ THEN mark index r := (alter mark index r MOD 2) + 3;
+ neue markierung (par2, mark index r);
+ ELSE mark index r := 0;
+ FI;
+
+ . markend anweisung :
+ loesche markierung;
+
+ . speichere anweisung :
+ anweisungs zaehler INCR 1;
+ anweisungs indizes CAT anweisungs index;
+ IF par1 <> ""
+ THEN insert (params1, par1);
+ params1 zeiger CAT highest entry (params1);
+ ELSE params1 zeiger CAT 0;
+ FI;
+ IF par2 <> ""
+ THEN insert (params2, par2);
+ params2 zeiger CAT highest entry (params2);
+ ELSE params2 zeiger CAT 0;
+ FI;
+
+ . rufe analysator :
+ INT CONST alte xpos := a xpos, alte y pos := a ypos;
+ INT VAR analysatorbreite, analysatorhoehe, analysatortiefe,
+ analysator font := a font,
+ analysator modifikationen := a modifikationen;
+ zeilen pos := anweisungsanfang - 1;
+disable stop;
+ analysator (text code, zeile, zeilen pos,
+ analysator font, analysator modifikationen,
+ analysatorbreite, analysatorhoehe, analysatortiefe, dummy);
+IF is error
+ THEN par1 := error message;
+ par1 CAT " a1-> ";
+ par1 CAT text (errorline);
+ clear error;
+ errorstop (par1);
+FI;
+enable stop;
+ hole token der analyse;
+ a xpos := alte xpos + analysatorbreite;
+ a ypos := alte ypos;
+ a modifikationen := analysator modifikationen;
+ groesste analysatorhoehe := max (analysatorhoehe, groesste analysator hoehe);
+ groesste analysatortiefe := max (analysatortiefe, groesste analysator tiefe);
+ IF analysator font <> a font
+ THEN stelle neuen font ein (analysator font);
+ ueberpruefe groesste fontgroesse;
+ IF nicht innerhalb eines indexes
+ THEN berechne aktuelle zeilengroesse FI;
+ ELSE aktuelle zeilenhoehe := max (groesste analysatorhoehe,
+ aktuelle zeilenhoehe);
+ aktuelle zeilentiefe := max (groesste analysatortiefe,
+ aktuelle zeilentiefe);
+ FI;
+
+ . hole token der analyse :
+ INT VAR token nr := 0, token font, token xpos, token ypos, token typ;
+ BOOL VAR font changed := FALSE;
+ token text := "";
+ REP
+disable stop;
+ analysator (token code, token text, token nr,
+ token font, a modifikationen, a breite,
+ token xpos, token ypos, token typ);
+IF is error
+ THEN par1 := error message;
+ par1 CAT " a2-> ";
+ par1 CAT text (errorline);
+ clear error;
+ errorstop (par1);
+FI;
+enable stop;
+ IF token nr = 0
+ THEN IF font changed THEN a font := -1 FI;
+ LEAVE hole token der analyse
+ FI;
+ IF token font <> a font
+ THEN a font := token font;
+ font offsets := y offsets (a font);
+ offsets := LENGTH font offsets > 2;
+ font changed := TRUE;
+ FI;
+ a xpos := alte xpos + token xpos;
+ a ypos := alte ypos + token ypos;
+ lege token an (token text, 1, max int, token typ)
+ PER;
+
+ . token text : par1
+
+END PROC analysiere anweisung;
+
+
+PROC stelle neuen font ein (INT CONST font nr ) :
+
+ IF font nr <> a font THEN neuer font FI;
+
+ . neuer font :
+ a font := max (1, font nr);
+ get font (a font, einrueckbreite, fontdurchschuss, fonthoehe, fonttiefe,
+ zeichenbreiten);
+ blankbreite := zeichenbreiten (blank code 1);
+ zeichenbreiten (blank code 1) := blank ausgang;
+ zeichenbreiten (anweisungs zeichen code 1) := anweisungs ausgang;
+ font offsets := y offsets (a font);
+ offsets := LENGTH font offsets > int length;
+ berechne fontgroesse;
+ berechne letzte zeilengroesse;
+ IF d code 1 <> leer
+ THEN d pitch := zeichenbreiten (d code 1);
+ zeichenbreiten (d code 1) := d code ausgang;
+ FI;
+
+END PROC stelle neuen font ein;
+
+
+INT OP PROZENT (INT CONST prozent, wert) :
+
+ (wert * prozent + 99) DIV 100
+
+END OP PROZENT;
+
+
+PROC neue markierung (TEXT CONST text, INT CONST mark index) :
+
+ mark token (mark index). text := text;
+ mark token (mark index). breite := string breite (text);
+ mark token (mark index). font := a font;
+ mark token (mark index). modifikationen := a modifikationen;
+
+END PROC neue markierung;
+
+
+INT PROC string breite (TEXT CONST string) :
+
+ INT VAR summe := 0, pos := 1;
+ REP stranalyze (zeichenbreiten, summe, max breite, string, pos, maxint, ausgang);
+ IF ausgang = erweiterungs ausgang
+ THEN summe INCR extended char pitch (a font,
+ string SUB pos+1, string SUB pos+2);
+ pos INCR 3;
+ ELIF ausgang = blank ausgang
+ THEN summe INCR blankbreite;
+ pos INCR 2;
+ ELIF ausgang = anweisungs ausgang
+ THEN summe INCR char pitch (a font, anweisungszeichen);
+ pos INCR 2;
+ ELSE LEAVE string breite WITH summe
+ FI;
+ PER;
+ 0
+
+END PROC string breite;
+
+(*******************************************************************)
+
+PROC lege token an (TEXT CONST token text,
+ INT CONST token anfang, token ende, token typ) :
+
+ INT VAR anfang := token anfang;
+ aktuelle ypos := a ypos + (font offsets ISUB 1);
+ neuer token index;
+ uebertrage token (tf, token text, token anfang, token ende, token typ);
+ IF token typ >= text token
+ THEN IF offsets THEN lege offsets an (font offsets) FI;
+ stranalyze (zeichen zaehler, anzahl zeichen, max int,
+ token text, anfang, token ende, ausgang);
+ a xpos INCR a breite;
+ FI;
+ a breite := 0;
+ a modifikationen fuer x move := 0;
+ a block token := FALSE;
+
+END PROC lege token an;
+
+
+PROC uebertrage token (TOKEN VAR tf, TEXT CONST token text,
+ INT CONST token anfang, token ende, token typ) :
+
+ tf. text := subtext (token text, token anfang, token ende);
+ tf. xpos := a xpos;
+ tf. breite := a breite;
+ tf. font := a font;
+ tf. modifikationen := a modifikationen;
+ tf. modifikationen fuer x move := a modifikationen fuer x move;
+ tf. offset index := token typ;
+ tf. block token := a block token;
+
+END PROC uebertrage token;
+
+
+PROC lege markierungs token an (INT CONST mark index) :
+
+ aktuelle ypos := a ypos + (mark font offsets ISUB 1);
+ neuer token index;
+ tf := mark token (mark index);
+ IF mark offsets THEN lege offsets an (mark font offsets) FI;
+
+ . mark font offsets : y offsets (mark token (mark index). font)
+
+ . mark offsets : LENGTH mark font offsets > int length
+
+END PROC lege markierungs token an;
+
+
+PROC lege offsets an (TEXT CONST offsets l) :
+
+ INT CONST anzahl offsets := LENGTH offsets l DIV int length;
+ INT VAR index;
+ offset token := tf;
+ offset token. block token := FALSE;
+ reset bit (offset token. modifikationen, underline bit);
+ reset bit (offset token. modifikationen fuer x move, underline bit);
+ FOR index FROM 2 UPTO anzahl offsets
+ REP aktuelle ypos := a ypos + (offsets l ISUB index);
+ neuer token index;
+ tf := offset token;
+ tf. offset index := index;
+ PER;
+
+END PROC lege offsets an;
+
+
+PROC neuer token index :
+
+IF erster ypos index a = 0
+ THEN erste ypos
+ELIF ya. ypos = aktuelle ypos
+ THEN neues token bei gleicher ypos
+ ELSE fuege neue ypos ein
+FI;
+
+ . erste ypos :
+ ypos index f INCR 1;
+ erster ypos index a := ypos index f;
+ letzter ypos index a := ypos index f;
+ yf. vorheriger ypos index := 0;
+ yf. naechster ypos index := 0;
+ erstes token bei neuer ypos;
+
+ . fuege neue ypos ein :
+ letztes token bei gleicher ypos;
+ IF ya. ypos > aktuelle ypos
+ THEN richtige ypos ist oberhalb
+ ELSE richtige ypos ist unterhalb
+ FI;
+
+ . richtige ypos ist oberhalb :
+ REP ypos index a := ya. vorheriger ypos index;
+ IF ypos index a = 0
+ THEN fuege ypos vor erstem ypos index ein;
+ LEAVE richtige ypos ist oberhalb;
+ ELIF ya. ypos = aktuelle ypos
+ THEN neues token bei neuer ypos;
+ LEAVE richtige ypos ist oberhalb;
+ ELIF ya. ypos < aktuelle ypos
+ THEN fuege ypos nach ypos index ein;
+ LEAVE richtige ypos ist oberhalb;
+ FI;
+ PER;
+
+ . richtige ypos ist unterhalb :
+ REP ypos index a := ya. naechster ypos index;
+ IF ypos index a = 0
+ THEN fuege ypos nach letztem ypos index ein;
+ LEAVE richtige ypos ist unterhalb;
+ ELIF ya. ypos = aktuelle ypos
+ THEN neues token bei neuer ypos;
+ LEAVE richtige ypos ist unterhalb;
+ ELIF ya. ypos > aktuelle ypos
+ THEN fuege ypos vor ypos index ein;
+ LEAVE richtige ypos ist unterhalb;
+ FI;
+ PER;
+
+ . fuege ypos vor erstem ypos index ein :
+ ypos index f INCR 1;
+ yf. vorheriger ypos index := 0;
+ yf. naechster ypos index := erster ypos index a;
+ erster ypos index a := ypos index f;
+ ypos index a := yf. naechster ypos index;
+ ya. vorheriger ypos index := ypos index f;
+ erstes token bei neuer ypos;
+
+ . fuege ypos nach ypos index ein :
+ ypos index f INCR 1;
+ yf. vorheriger ypos index := ypos index a;
+ yf. naechster ypos index := ya. naechster ypos index;
+ ya. naechster ypos index := ypos index f;
+ ypos index a := yf. naechster ypos index;
+ ya. vorheriger ypos index := ypos index f;
+ erstes token bei neuer ypos;
+
+ . fuege ypos vor ypos index ein :
+ ypos index f INCR 1;
+ yf. naechster ypos index := ypos index a;
+ yf. vorheriger ypos index := ya. vorheriger ypos index;
+ ya. vorheriger ypos index := ypos index f;
+ ypos index a := yf. vorheriger ypos index;
+ ya. naechster ypos index := ypos index f;
+ erstes token bei neuer ypos;
+
+ . fuege ypos nach letztem ypos index ein :
+ ypos index f INCR 1;
+ yf. naechster ypos index := 0;
+ yf. vorheriger ypos index := letzter ypos index a;
+ letzter ypos index a := ypos index f;
+ ypos index a := yf. vorheriger ypos index;
+ ya. naechster ypos index := ypos index f;
+ erstes token bei neuer ypos;
+
+END PROC neuer token index;
+
+
+PROC erstes token bei neuer ypos :
+ token index f INCR 1;
+ ypos index a := ypos index f;
+ ya. erster token index := token index f;
+ ya. ypos := aktuelle ypos;
+END PROC erstes token bei neuer ypos;
+
+
+PROC neues token bei neuer ypos :
+ token index f INCR 1;
+ ya. ypos := aktuelle ypos;
+ token index := ya. letzter token index;
+ t. naechster token index := token index f;
+END PROC neues token bei neuer ypos;
+
+
+PROC neues token bei gleicher ypos :
+ tf. naechster token index := token index f + 1;
+ token index f INCR 1;
+END PROC neues token bei gleicher ypos;
+
+
+PROC letztes token bei gleicher ypos :
+ tf. naechster token index := 0;
+ ya. letzter token index := token index f;
+END PROC letztes token bei gleicher ypos;
+
+
+PROC loesche letztes token :
+
+ IF token index f = ya. erster token index
+ THEN loesche ypos
+ ELSE token index f DECR 1;
+ FI;
+
+ . loesche ypos :
+ kette vorgaenger um;
+ kette nachfolger um;
+ bestimme letzten ypos index;
+
+ . kette vorgaenger um :
+ ypos index := ya. vorheriger ypos index;
+ IF ypos index = 0
+ THEN erster ypos index a := ya. naechster ypos index;
+ ELSE y. naechster ypos index := ya. naechster ypos index;
+ FI;
+
+ . kette nachfolger um :
+ ypos index := ya. naechster ypos index;
+ IF ypos index = 0
+ THEN letzter ypos index a := ya. vorheriger ypos index;
+ ELSE y. vorheriger ypos index := ya. vorheriger ypos index;
+ FI;
+
+ . bestimme letzten ypos index :
+ IF ypos index a = ypos index f THEN ypos index f DECR 1 FI;
+ token index f DECR 1;
+ ypos index a := letzter ypos index a;
+ WHILE ypos index a <> 0
+ CAND ya. letzter token index <> token index f
+ REP ypos index a := ya. vorheriger ypos index PER;
+
+END PROC loesche letztes token;
+
+
+PROC blocke token xpos (INT CONST dehnung 1, dehnung 2,
+ anzahl dehnungen fuer dehnung 1 ) :
+
+ INT VAR dehnung := 0, anzahl dehnungen := 0;
+ token index := erstes tab token;
+ WHILE token index <= token index f
+ REP erhoehe token xpos bei block token;
+ t. xpos INCR dehnung;
+ token index INCR 1;
+ PER;
+
+ . erhoehe token xpos bei block token :
+ IF t. block token
+ THEN IF anzahl dehnungen < anzahl dehnungen fuer dehnung 1
+ THEN anzahl dehnungen INCR 1;
+ dehnung INCR dehnung 1;
+ ELSE dehnung INCR dehnung 2;
+ FI;
+ FI;
+
+END PROC blocke token xpos;
+
+
+PROC verschiebe token xpos (INT CONST verschiebung l) :
+
+ token index := erstes tab token;
+ WHILE token index <= token index f
+ REP t. xpos INCR verschiebung l;
+ token index INCR 1;
+ PER;
+
+END PROC verschiebe token xpos;
+
+
+PROC verschiebe token ypos (INT CONST verschiebung l) :
+
+ ypos index := erster ypos index a;
+ WHILE ypos index <> 0
+ REP y. ypos INCR verschiebung l;
+ ypos index := y. naechster ypos index;
+ PER;
+
+END PROC verschiebe token ypos;
+
+
+PROC sortiere neue token ein :
+
+INT VAR index;
+IF analysespeicher ist nicht leer
+ THEN IF druckspeicher ist nicht leer
+ THEN sortiere neue token in sortierte liste ein
+ ELSE sortierte liste ist leer
+ FI;
+FI;
+
+. sortierte liste ist leer :
+ IF erster ypos index a <> 0
+ THEN erster ypos index d := erster ypos index a;
+ letzter ypos index d := letzter ypos index a;
+ ypos index d := letzter ypos index a;
+ FI;
+
+. sortiere neue token in sortierte liste ein :
+ gehe zum ersten neuen token;
+ bestimme erste einsortierposition;
+ WHILE es gibt noch neue token
+ REP IF ypos index d = 0
+ THEN haenge neue token ans ende der sortierten liste
+ ELIF ya. ypos > yd. ypos
+ THEN naechste ypos der sortierten liste
+ ELIF ya. ypos = yd. ypos
+ THEN neues token auf gleicher ypos
+ ELSE neue token vor ypos
+ FI;
+ PER;
+
+ . gehe zum ersten neuen token :
+ ypos index a := erster ypos index a;
+
+ . bestimme erste einsortierposition :
+ WHILE ypos index d <> 0 CAND ya. ypos < yd. ypos
+ REP ypos index d := yd. vorheriger ypos index PER;
+ IF ypos index d = 0 THEN erste neue token vor listen anfang FI;
+
+ . erste neue token vor listen anfang :
+ ypos index d := erster ypos index d;
+ erster ypos index d := erster ypos index a;
+ REP ypos index a := ya. naechster ypos index;
+ IF ypos index a = 0
+ THEN verkette letztes ya mit yd;
+ LEAVE sortiere neue token in sortierte liste ein
+ ELIF ya. ypos = yd. ypos
+ THEN verkette ya mit yd;
+ LEAVE erste neue token vor listen anfang
+ ELIF ya. ypos > yd. ypos
+ THEN verkette vorheriges ya mit yd;
+ ypos index d := yd. naechster ypos index;
+ LEAVE erste neue token vor listen anfang
+ FI;
+ PER;
+
+ . es gibt noch neue token :
+ ypos index a <> 0
+
+ . haenge neue token ans ende der sortierten liste :
+ ypos index d := letzter ypos index d;
+ yd. naechster ypos index := ypos index a;
+ ya. vorheriger ypos index := ypos index d;
+ letzter ypos index d := letzter ypos index a;
+ ypos index d := letzter ypos index a;
+ ypos index a := 0;
+
+ . naechste ypos der sortierten liste :
+ ypos index d := yd. naechster ypos index;
+
+ . neues token auf gleicher ypos :
+ token index := yd. letzter token index;
+ t . naechster token index := ya. erster token index;
+ yd. letzter token index := ya. letzter token index;
+ ypos index a := ya. naechster ypos index;
+ ypos index d := yd. naechster ypos index;
+ IF ypos index d = 0 THEN ypos index d := letzter ypos index d FI;
+
+ . neue token vor ypos :
+ verkette ya mit vorherigem yd;
+ REP ypos index a := ya. naechster ypos index;
+ IF ypos index a = 0
+ THEN verkette letztes ya mit yd;
+ LEAVE sortiere neue token in sortierte liste ein
+ ELIF ya. ypos = yd. ypos
+ THEN verkette ya mit yd;
+ LEAVE neue token vor ypos
+ ELIF ya. ypos > yd. ypos
+ THEN verkette vorheriges ya mit yd;
+ ypos index d := yd. naechster ypos index;
+ LEAVE neue token vor ypos
+ FI;
+ PER;
+
+
+. verkette ya mit vorherigem yd :
+ index := ypos index d;
+ ypos index d := yd. vorheriger ypos index;
+ yd. naechster ypos index := ypos index a;
+ ya. vorheriger ypos index := ypos index d;
+ ypos index d := index;
+
+. verkette letztes ya mit yd :
+ ypos index a := letzter ypos index a;
+ yd. vorheriger ypos index := ypos index a;
+ ya. naechster ypos index := ypos index d;
+ ypos index a := 0;
+
+. verkette vorheriges ya mit yd :
+ index := ypos index a;
+ ypos index a := ya. vorheriger ypos index;
+ yd. vorheriger ypos index := ypos index a;
+ ya. naechster ypos index := ypos index d;
+ ypos index a := index;
+
+. verkette ya mit yd :
+ verkette vorheriges ya mit yd;
+ neues token auf gleicher ypos;
+
+END PROC sortiere neue token ein;
+
+(***************************************************************)
+
+PROC drucke tokenspeicher
+ (INT CONST max ypos,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+IF druckspeicher ist nicht leer
+ THEN gehe zur ersten ypos;
+ WHILE yd. ypos <= max ypos
+ REP drucke token bei ypos;
+ gehe zur naechsten ypos;
+ PER;
+ loesche gedruckte token;
+FI;
+
+. gehe zur ersten ypos :
+ ypos index d := erster ypos index d;
+
+. drucke token bei ypos :
+ IF yd. ypos >= - y start
+ THEN druck durchgang;
+ IF bold pass THEN fett durchgang FI;
+ IF underline pass THEN unterstreich durchgang FI;
+ FI;
+
+ . bold pass : bit (pass, bold bit)
+
+ . underline pass : bit (pass, underline bit)
+
+. gehe zur naechsten ypos :
+ IF ypos index d = letzter ypos index d
+ THEN loesche druckspeicher;
+ LEAVE drucke tokenspeicher;
+ FI;
+ ypos index d := yd. naechster ypos index;
+
+. loesche gedruckte token :
+ erster ypos index d := ypos index d;
+ yd. vorheriger ypos index := 0;
+
+.
+ druck durchgang :
+ verschiebung := yd. ypos - d ypos;
+ y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ gehe zum ersten token dieser ypos;
+ REP drucke token UNTIL kein token mehr vorhanden PER;
+
+ . drucke token :
+ IF NOT token passt in zeile
+ THEN IF token ist text token
+ THEN berechne token teil
+ ELSE LEAVE drucke token
+ FI;
+ FI;
+ font wechsel wenn noetig;
+ x move mit modifikations ueberpruefung;
+ IF token ist text token
+ THEN gib text token aus
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ ELIF token ist linien token
+ THEN gib linien token aus
+ ELSE gib kommando token aus
+ FI;
+
+ . gib linien token aus :
+ linien verschiebung := d token. breite;
+ ziehe horizontale linie (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+ . gib kommando token aus :
+ execute (write cmd, d token. text, 1, LENGTH d token. text)
+
+ . berechne token teil :
+ INT CONST fuenf punkte := 5 * char pitch (d token. font, punkt);
+ INT VAR token pos, token breite, anzahl punkte, zeichen laenge, zeichen breite;
+ IF d token. xpos < - x start
+ AND d token. xpos + d token. breite > - x start
+ THEN berechne token teil von links
+ ELIF d token. xpos < papierbreite
+ AND d token. xpos + d token. breite > papierbreite
+ THEN berechne token teil nach rechts
+ ELSE LEAVE drucke token
+ FI;
+
+ . berechne token teil von links :
+ rest := min (x size, d token. xpos + d token. breite + x start);
+ d token. xpos := - x start;
+ IF rest <= fuenf punkte
+ THEN anzahl punkte := rest DIV char pitch (d token. font, punkt);
+ d token. text := anzahl punkte * punkt;
+ d token. breite := anzahl punkte * char pitch (d token. font, punkt);
+ ELSE token pos := LENGTH d token. text + 1;
+ token breite := fuenf punkte;
+ berechne token teil breite von hinten;
+ change (d token. text, 1, token pos - 1, 5 * punkt);
+ d token. breite := token breite;
+ FI;
+
+ . berechne token teil breite von hinten :
+ WHILE naechstes zeichen passt noch davor
+ REP token breite INCR zeichen breite;
+ token pos DECR zeichen laenge;
+ PER;
+
+ . naechstes zeichen passt noch davor :
+ IF within kanji (d token. text, token pos - 1)
+ THEN zeichen laenge := 2
+ ELSE zeichen laenge := 1
+ FI;
+ zeichen breite := char pitch (d token. font,
+ subtext (d token. text, token pos - zeichen laenge, token pos - 1));
+ token breite + zeichen breite < rest
+
+ . berechne token teil nach rechts :
+ rest := papier breite - d token. xpos;
+ IF rest <= fuenf punkte
+ THEN anzahl punkte := rest DIV char pitch (d token. font, punkt);
+ d token. text := anzahl punkte * punkt;
+ d token. breite := anzahl punkte * char pitch (d token. font, punkt);
+ ELSE token pos := 0;
+ token breite := fuenf punkte;
+ berechne token teil breite von vorne;
+ change (d token. text, token pos + 1, LENGTH d token. text, 5 * punkt);
+ d token. breite := token breite;
+ FI;
+
+ . berechne token teil breite von vorne :
+ WHILE naechstes zeichen passt noch dahinter
+ REP token breite INCR zeichen breite;
+ token pos INCR zeichen laenge;
+ PER;
+
+ . naechstes zeichen passt noch dahinter :
+ IF is kanji esc (d token. text SUB token pos + 1)
+ THEN zeichen laenge := 2
+ ELSE zeichen laenge := 1
+ FI;
+ zeichen breite := char pitch (d token. font,
+ subtext (d token. text, token pos + 1, token pos + zeichen laenge));
+ token breite + zeichen breite < rest
+
+.
+ fett durchgang :
+ reset bit (pass, bold bit);
+ gib cr aus;
+ gehe zum ersten token dieser ypos;
+ REP gib token nochmal aus UNTIL kein token mehr vorhanden PER;
+ schalte modifikationen aus wenn noetig;
+
+ . gib token nochmal aus :
+ INT CONST min verschiebung := bold offset (d token. font);
+ d token. xpos INCR min verschiebung;
+ IF bit (d token. modifikationen, bold bit) AND
+ token passt in zeile AND token ist text token
+ THEN verschiebung := d token. xpos - d xpos;
+ font wechsel wenn noetig;
+ schalte italics ein wenn noetig;
+ x move wenn noetig;
+ gib text token aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+ d token. xpos DECR min verschiebung;
+
+ . schalte italics ein wenn noetig :
+ IF bit (d token. modifikationen, italics bit)
+ THEN neue modifikationen := modifikations werte (italics bit + 1);
+ schalte modifikationen ein wenn noetig;
+ ELSE schalte modifikationen aus wenn noetig;
+ FI;
+
+.
+ unterstreich durchgang :
+ INT VAR l xpos := 0;
+ reset bit (pass, underline bit);
+ gib cr aus;
+ schalte modifikationen aus wenn noetig;
+ gehe zum ersten token dieser ypos;
+ REP unterstreiche token UNTIL kein token mehr vorhanden PER;
+
+ . unterstreiche token :
+ IF token muss unterstrichen werden AND
+ token passt in zeile AND token ist text token
+ THEN font wechsel wenn noetig;
+ berechne x move laenge;
+ x move wenn noetig;
+ berechne unterstreich laenge;
+ ziehe horizontale linie (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+ l xpos := d token. xpos + d token. breite;
+
+ . token muss unterstrichen werden :
+ bit (d token. modifikationen, underline bit) OR
+ bit (d token. modifikationen fuer x move, underline bit)
+
+ . berechne x move laenge :
+ IF bit (d token. modifikationen fuer x move, underline bit)
+ THEN verschiebung := l xpos - d xpos
+ ELSE verschiebung := d token. xpos - d xpos
+ FI;
+
+ . berechne unterstreich laenge :
+ IF bit (d token. modifikationen, underline bit)
+ THEN linien verschiebung := d token. xpos +
+ d token. breite - d xpos
+ ELSE linien verschiebung := d token. xpos - d xpos
+ FI;
+ d token. offset index := - underline line type;
+
+
+. gehe zum ersten token dieser ypos :
+ token index := yd. erster token index;
+ d token := t;
+
+. kein token mehr vorhanden :
+ token index := d token. naechster token index;
+ IF token index = 0
+ THEN TRUE
+ ELSE d token := t;
+ FALSE
+ FI
+
+. token ist text token :
+ d token. offset index >= text token
+
+. token ist linien token :
+ d token. offset index <= linien token
+
+. token passt in zeile :
+ d token. xpos >= - x start AND
+ d token. xpos + d token. breite <= papier breite
+
+. font wechsel wenn noetig :
+ IF d token. font <> d font
+ THEN font wechsel (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) FI;
+
+. schalte modifikationen ein wenn noetig :
+ IF d modifikationen <> neue modifikationen
+ THEN schalte modifikationen ein (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) FI;
+
+. schalte modifikationen aus wenn noetig :
+ IF d modifikationen <> 0
+ THEN schalte modifikationen aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) FI;
+
+. x move wenn noetig :
+ IF verschiebung <> 0
+ THEN x move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) FI;
+
+.
+ x move mit modifikations ueberpruefung :
+ verschiebung := d token. xpos - d xpos;
+ IF verschiebung <> 0
+ THEN neue modifikationen := d token. modifikationen fuer x move;
+ schalte modifikationen ein wenn noetig;
+ x move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+ neue modifikationen := d token. modifikationen;
+ schalte modifikationen ein wenn noetig;
+
+. gib cr aus :
+ IF d xpos <> 0
+ THEN execute (carriage return, "", d xpos, 0);
+ d xpos := 0;
+ FI;
+
+END PROC drucke tokenspeicher;
+
+
+PROC ziehe horizontale linie (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+ IF linien verschiebung > 0
+ THEN disable stop;
+ d xpos INCR linien verschiebung;
+ execute (draw, "", linien verschiebung, 0);
+ IF is error
+ THEN ziehe horizontale linie nach cr;
+ FI;
+ enable stop;
+ FI;
+
+ . ziehe horizontale linie nach cr :
+ clear error;
+ d xpos DECR linien verschiebung;
+ verschiebung := d xpos;
+ gib cr aus;
+ x move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ d xpos INCR linien verschiebung;
+ execute (draw, "", linien verschiebung, 0);
+ IF is error
+ THEN clear error;
+ d xpos DECR linien verschiebung;
+ FI;
+
+ . gib cr aus :
+ IF d xpos <> 0
+ THEN execute (carriage return, "", d xpos, 0);
+ d xpos := 0;
+ FI;
+
+END PROC ziehe horizontale linie;
+
+
+PROC y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+ IF verschiebung <> 0
+ THEN gib cr aus;
+ disable stop;
+ d ypos INCR verschiebung;
+ execute (move, "", 0, verschiebung);
+ IF is error
+ THEN clear error;
+ d ypos DECR verschiebung;
+ verschiebung := 0;
+ FI;
+ enable stop;
+ FI;
+
+ . gib cr aus :
+ IF d xpos <> 0
+ THEN execute (carriage return, "", d xpos, 0);
+ d xpos := 0;
+ FI;
+
+END PROC y move;
+
+
+PROC x move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+ disable stop;
+ d xpos INCR verschiebung;
+ execute (move, "", verschiebung, 0);
+ IF is error
+ THEN fuehre x move nach cr aus
+ FI;
+
+ . fuehre x move nach cr aus :
+ clear error;
+ schalte modifikationen aus wenn noetig;
+ gib cr bei x move aus;
+ IF d xpos <> 0
+ THEN execute (move, "", d xpos, 0);
+ IF is error
+ THEN clear error;
+ d xpos := 0;
+ FI
+ FI;
+ schalte modifikationen ein wenn noetig;
+
+ . gib cr bei x move aus :
+ execute (carriage return, "", d xpos - verschiebung, 0);
+
+ . schalte modifikationen aus wenn noetig :
+ neue modifikationen := d modifikationen;
+ IF d modifikationen <> 0
+ THEN schalte modifikationen aus
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+
+ . schalte modifikationen ein wenn noetig :
+ IF d modifikationen <> neue modifikationen
+ THEN schalte modifikationen ein
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+
+END PROC x move;
+
+
+PROC schalte modifikationen ein
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+ disable stop;
+ INT VAR index;
+ IF d modifikationen <> 0
+ THEN schalte modifikationen aus
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+ d modifikationen := neue modifikationen;
+ FOR index FROM 1 UPTO anzahl modifikationen
+ REP IF bit (d modifikationen, modifikations bit)
+ THEN modifikation muss eingeschaltet werden
+ FI;
+ PER;
+
+ . modifikations bit : index - 1
+
+ . modifikation muss eingeschaltet werden :
+ IF bit (modifikations modus, modifikations bit)
+ THEN execute (on, "", modifikations werte (index), 0);
+ IF is error
+ THEN clear error;
+ reset bit (modifikations modus, modifikations bit);
+ set bit (pass, modifikations bit);
+ FI;
+ ELSE set bit (pass, modifikations bit);
+ FI;
+
+END PROC schalte modifikationen ein;
+
+
+PROC schalte modifikationen aus
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+ disable stop;
+ INT VAR index;
+ FOR index FROM 1 UPTO anzahl modifikationen
+ REP IF bit (d modifikationen, modifikations bit)
+ THEN modifikation muss ausgeschaltet werden
+ FI;
+ PER;
+ d modifikationen := 0;
+
+ . modifikations bit : index - 1
+
+ . modifikation muss ausgeschaltet werden :
+ IF bit (modifikations modus, modifikations bit)
+ THEN execute (off, "", modifikations werte (index), 0);
+ IF is error THEN clear error FI;
+ FI;
+
+END PROC schalte modifikationen aus;
+
+
+PROC font wechsel
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+ disable stop;
+ d font := d token. font;
+ get replacements (d font, replacements, replacement tabelle);
+ execute (type, "", d font, 0);
+ IF is error THEN font wechsel nach cr FI;
+ enable stop;
+
+ . font wechsel nach cr :
+ clear error;
+ verschiebung := d xpos;
+ gib cr aus;
+ execute (type, "", d font, 0);
+ IF NOT is error
+ THEN schalte modifikationen aus
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ x move
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+
+ . gib cr aus :
+ IF d xpos <> 0
+ THEN execute (carriage return, "", d xpos, 0);
+ d xpos := 0;
+ FI;
+
+END PROC font wechsel;
+
+
+PROC gib text token aus
+ (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+ INT CONST token laenge := LENGTH d token. text;
+ INT VAR token pos := 1, alte token pos, summe := 0;
+ IF token laenge > 0
+ THEN REP alte token pos := token pos;
+ stranalyze (replacement tabelle, summe, 0,
+ d token. text, token pos, token laenge,
+ ausgang);
+ IF ausgang = 0
+ THEN gib token rest aus;
+ ELSE gib token teil aus;
+ gib ersatzdarstellung aus;
+ FI;
+ PER;
+ FI;
+
+ . gib token rest aus :
+ IF token laenge >= alte token pos
+ THEN execute (write text, d token. text, alte token pos, token laenge) FI;
+ d xpos INCR d token. breite;
+ LEAVE gib text token aus;
+
+ . gib token teil aus :
+ IF token pos >= alte token pos
+ THEN execute (write text, d token. text, alte token pos, token pos) FI;
+
+ . gib ersatzdarstellung aus :
+ IF ausgang = maxint
+ THEN ersatzdarstellung := extended replacement (d token. font,
+ d token. text SUB token pos + 1, d token. text SUB token pos + 2);
+ execute (write text, ersatzdarstellung, 1, LENGTH ersatzdarstellung);
+ tokenpos INCR 3;
+ ELSE IF ausgang < 0
+ THEN ausgang := ausgang XOR minint;
+ token pos INCR 1;
+ FI;
+ execute (write text, replacements, ausgang + 1, ausgang + code (replacements SUB ausgang));
+ token pos INCR 2;
+ FI;
+
+ . ersatzdarstellung : par1
+
+END PROC gib text token aus;
+
+
+PROC schliesse seite ab (PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+enable stop;
+gebe restliche token aus;
+gib cr aus;
+seiten ende kommando;
+
+. gebe restliche token aus :
+ IF erster ypos index d <> 0
+ THEN drucke tokenspeicher (maxint,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ FI;
+ rest := papier laenge - d ypos;
+ aktuelle zeilentiefe der letzten zeile := 0;
+
+. gib cr aus :
+ IF d xpos <> 0
+ THEN execute (carriage return, "", d xpos, 0);
+ d xpos := 0;
+ FI;
+
+. seiten ende kommando :
+ seite ist offen := FALSE;
+ a ypos := top margin;
+ aktuelle spalte := 1;
+ close (page, rest);
+
+END PROC schliesse seite ab;
+
+
+PROC eroeffne seite (INT CONST x wanted l, y wanted l,
+ PROC (INT CONST, INT VAR, INT VAR) open ) :
+
+IF vor erster seite THEN eroeffne druck FI;
+seiten anfang kommando;
+initialisiere neue seite;
+
+. eroeffne druck :
+ open (document, x size, y size);
+ vor erster seite := FALSE;
+ d font := -1;
+ d modifikationen := 0;
+
+. seiten anfang kommando :
+ x start := x wanted l;
+ y start := y wanted l;
+ open (page, x start, y start);
+ gedruckte seiten INCR 1;
+ seite ist offen := TRUE;
+
+. initialisiere neue seite :
+ INT CONST dif left margin := x wanted l - x start - left margin + indentation,
+ dif top margin := y wanted l - y start - top margin;
+ IF dif left margin <> 0
+ THEN erstes tab token := 1;
+ verschiebe token xpos (dif left margin);
+ a xpos INCR dif left margin;
+ left margin INCR dif left margin;
+ FI;
+ IF dif top margin <> 0
+ THEN verschiebe token ypos (dif top margin);
+ a ypos INCR dif top margin;
+ top margin INCR dif top margin;
+ FI;
+ d xpos := 0;
+ d ypos := 0;
+ IF seitenlaenge <= papierlaenge
+ THEN seitenlaenge := top margin + pagelength;
+ ELSE seitenlaenge DECR papierlaenge;
+ FI;
+ papierlaenge := y size - y start;
+ papierbreite := x size - x start;
+
+END PROC eroeffne seite;
+
+(****************************************************************)
+
+PROC elan fuss und kopf (INT CONST fuss oder kopf,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+IF fuss oder kopf <= 0 THEN elan fuss FI;
+IF fuss oder kopf >= 0 THEN elan kopf FI;
+
+.
+ elan fuss :
+ y move zur fusszeile;
+ drucke elan fuss;
+ close page cmd;
+
+. y move zur fusszeile :
+ execute (carriage return, "", d xpos, 0);
+ d xpos := 0;
+ verschiebung := rest auf seite - font hoehe;
+ y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+. drucke elan fuss :
+ IF bottom label = ""
+ THEN seiten nr := ""
+ ELSE seiten nr := bottom label;
+ seiten nr CAT "/";
+ FI;
+ seiten nr CAT text (gedruckte seiten);
+ elan text := seiten nr;
+ elan text CAT " ";
+ elan text cat blanks ((max zeichen fuss - LENGTH dateiname) DIV 2 - LENGTH elan text);
+ elan text CAT dateiname;
+ elan text cat blanks (max zeichen fuss - LENGTH seiten nr - LENGTH elan text - 3);
+ elan text CAT " ";
+ elan text CAT seiten nr;
+ IF LENGTH elan text > max zeichen zeile
+ THEN elan text := subtext (elan text, 1, max zeichen zeile) FI;
+ gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+ . seiten nr : par1
+
+. close page cmd :
+ execute (carriage return, "", d xpos, 0);
+ d xpos := 0;
+ close (page, papierlaenge - d ypos);
+ seite ist offen := FALSE;
+
+.
+ elan kopf :
+ open page cmd ;
+ y move zur kopfzeile;
+ drucke elan kopf;
+
+. open page cmd :
+ x start := x wanted;
+ y start := y wanted;
+ open (page, x start, y start);
+ IF fuss oder kopf = 1 THEN execute (type, "", d font, 0) FI;
+ gedruckte seiten INCR 1;
+ seite ist offen := TRUE;
+ top margin := y wanted - y start;
+ left margin := x wanted - x start;
+ rest auf seite := pagelength;
+ papierlaenge := y size - y start;
+ d ypos := 0;
+ d xpos := 0;
+
+. y move zur kopf zeile :
+ verschiebung := top margin;
+ y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ IF verschiebung = 0 THEN rest auf seite INCR top margin FI;
+
+. drucke elan kopf :
+ elan text := headline pre;
+ elan text CAT date;
+ elan text CAT headline post;
+ elan text CAT datei name;
+ IF LENGTH elan text > max zeichen zeile
+ THEN elan text := subtext (elan text, 1, max zeichen zeile) FI;
+ gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ cr plus lf (2, PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+ENDPROC elan fuss und kopf;
+
+
+PROC gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+cr plus lf (1, PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+linker rand wenn noetig;
+d token. breite := LENGTH elan text * einrueckbreite;
+gib text token aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+. linker rand wenn noetig :
+ IF left margin > 0
+ THEN disable stop;
+ d xpos := left margin;
+ execute (move, "", left margin, 0);
+ IF is error
+ THEN clear error;
+ d xpos := 0;
+ FI;
+ enable stop;
+ FI;
+
+END PROC gib elan text aus;
+
+
+PROC cr plus lf (INT CONST anzahl,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+
+gib cr aus;
+gib lf aus;
+rest auf seite DECR verschiebung;
+
+. gib cr aus :
+ execute (carriage return, "", d xpos, 0);
+ d xpos := 0;
+
+. gib lf aus :
+ verschiebung := anzahl * font hoehe;
+ y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+END PROC cr plus lf ;
+
+
+END PACKET eumel printer;
+
diff --git a/system/eumelmeter b/system/eumelmeter
new file mode 100644
index 0000000..ba92476
--- /dev/null
+++ b/system/eumelmeter
@@ -0,0 +1,131 @@
+ (* Author: J.Liedtke*)
+PACKET eumelmeter DEFINES (* Stand: 11.10.83 *)
+
+ init log ,
+ log :
+
+
+LET snapshot interval = 590.0 ;
+
+REAL VAR next snapshot time ,
+ time , timex ,
+ paging wait , paging wait x ,
+ paging busy , paging busy x ,
+ fore cpu , fore cpu x ,
+ back cpu , back cpu x ,
+ system cpu , system cpu x ,
+ delta t ;
+INT VAR storage max, used ;
+TEXT VAR record ;
+
+PROC init log :
+
+ time := clock (1) ;
+ paging wait := clock (2) ;
+ paging busy := clock (3) ;
+ fore cpu := clock (4) ;
+ back cpu := clock (5) ;
+ system cpu := clock (6) ;
+ next snapshot time := time + snapshot interval
+
+ENDPROC init log ;
+
+PROC log (INT CONST active terminals, active background) :
+
+ new snapshot time if was clock reset ;
+ IF clock (1) >= next snapshot time
+ THEN save values ;
+ get new values ;
+ create stat record ;
+ put log (record) ;
+ define next snapshot time
+ FI .
+
+new snapshot time if was clock reset :
+ IF clock (1) < next snapshot time - snapshot interval
+ THEN next snapshot time := clock (1)
+ FI .
+
+save values :
+ time x := time ;
+ paging wait x := paging wait ;
+ paging busy x := paging busy ;
+ fore cpu x := fore cpu ;
+ back cpu x := back cpu ;
+ system cpu x := system cpu .
+
+get new values :
+ time := clock (1) ;
+ paging wait := clock (2) ;
+ paging busy := clock (3) ;
+ fore cpu := clock (4) ;
+ back cpu := clock (5) ;
+ system cpu := clock (6) ;
+ storage (storage max, used) .
+
+create stat record :
+ record := text (used, 5) ;
+ record CAT text (active terminals,3) ;
+ record CAT text (active background,3) ;
+ delta t := (time - time x) ;
+ percent (paging wait, paging wait x) ;
+ percent (paging busy, paging busy x) ;
+ percent (fore cpu, fore cpu x) ;
+ percent (back cpu, back cpu x) ;
+ percent (system cpu, system cpu x) ;
+ percent (last, 0.0) ;
+ percent (nutz, 0.0) .
+
+last : paging wait + paging busy + fore cpu + back cpu + system cpu
+ - paging waitx - paging busyx - fore cpux - back cpux - system cpux .
+
+nutz : time - paging wait - system cpu
+ - timex + paging waitx + system cpux .
+
+define next snapshot time :
+ next snapshot time := time + snapshot interval .
+
+ENDPROC log ;
+
+PROC percent (REAL CONST neu, alt ) :
+
+ record CAT text ( (neu-alt) / delta t * 100.0, 6,1) + "%"
+
+ENDPROC percent ;
+
+ENDPACKET eumelmeter ;
+
+INT VAR active terminals , active background ;
+
+task password ("-") ;
+break ;
+command dialogue (FALSE) ;
+forget ("eumelmeter") ;
+init log ;
+REP
+ pause (6000) ;
+ count active processes (active terminals, active background) ;
+ log (active terminals, active background)
+PER ;
+
+PROC count active processes (INT VAR active terminals, active background) :
+
+ active terminals := 0 ;
+ active background := 0 ;
+ TASK VAR process := myself ;
+ REP
+ next active (process) ;
+ IF user process
+ THEN IF process at terminal
+ THEN active terminals INCR 1
+ ELSE active background INCR 1
+ FI
+ FI
+ UNTIL process = myself PER .
+
+user process : NOT (process < supervisor) .
+
+process at terminal : channel (process) >= 0 .
+
+ENDPROC count active processes ;
+
diff --git a/system/font convertor 9 b/system/font convertor 9
new file mode 100644
index 0000000..a5d0ea7
--- /dev/null
+++ b/system/font convertor 9
@@ -0,0 +1,1095 @@
+PACKET font convertor (* Autor : Rudolf Ruland *)
+ (* Stand : 29.03.88 *)
+ DEFINES create font table ,
+ add fonts,
+ create font file :
+
+(* >>> ***************************************************************** <<< *)
+
+INT CONST int length := length of one int,
+ highest bit := int length * 8 - 1;
+
+. length of one int :
+ INT VAR int counter := 0, int value := max int;
+ REP int counter INCR 1;
+ int value := int value DIV 256;
+ UNTIL int value = 0 PER;
+ int counter
+.;
+
+(* >>> ***************************************************************** <<< *)
+
+LET t tag = 1,
+ t bold = 2,
+ t number = 3,
+ t text = 4,
+ t operator = 5,
+ t delimiter = 6,
+ t end of file = 7,
+
+ nil modus = 0,
+ font table modus = 1,
+ font modus = 2,
+ extension modus = 3,
+
+ x unit = 1,
+ y unit = 2,
+ on string = 3,
+ off string = 4,
+ indentation pitch = 5,
+ font lead = 6,
+ font height = 7,
+ font depth = 8,
+ larger font = 9,
+ smaller font = 10,
+ font string = 11,
+ y off sets = 12,
+ bold off set = 13;
+
+THESAURUS VAR names, english identification := empty thesaurus,
+ german identification := empty thesaurus;
+
+insert (english identification, "xunit");
+insert (english identification, "yunit");
+insert (english identification, "onstring");
+insert (english identification, "offstring");
+insert (english identification, "indentationpitch");
+insert (english identification, "fontlead");
+insert (english identification, "fontheight");
+insert (english identification, "fontdepth");
+insert (english identification, "nextlargerfont");
+insert (english identification, "nextsmallerfont");
+insert (english identification, "fontstring");
+insert (english identification, "yoffsets");
+insert (english identification, "boldoffset");
+
+insert (german identification, "xeinheit");
+insert (german identification, "yeinheit");
+insert (german identification, "onsequenz");
+insert (german identification, "offsequenz");
+insert (german identification, "einrueckbreite");
+insert (german identification, "durchschuss");
+insert (german identification, "fonthoehe");
+insert (german identification, "fonttiefe");
+insert (german identification, "groessererfont");
+insert (german identification, "kleinererfont");
+insert (german identification, "fontsequenz");
+insert (german identification, "yverschiebungen");
+insert (german identification, "boldverschiebung");
+
+INT VAR modus, last modus, symbol type, int symbol, pitch,
+ identification nr, link nr, extension code 1,
+ char code 1, char code, char pos, vorzeichen,
+ replacements length, index;
+TEXT VAR symbol, font table name, replacement, char, buffer, z;
+BOOL VAR english;
+FILE VAR file, font file;
+
+(*****************************************************************)
+
+LET max fonts = 50,
+ max extensions = 120,
+ font table type = 3009,
+
+ FONTTABLE = STRUCT (
+
+ THESAURUS font names,
+
+ TEXT replacements, font name links,
+ extension chars, extension indexes,
+
+ ROW 4 TEXT on strings, off strings,
+
+ REAL x unit, y unit,
+
+ ROW 256 INT replacements table,
+
+ INT last font, last extension,
+
+ ROW max fonts STRUCT (
+ TEXT font string, font name indexes, replacements,
+ extension chars, extension indexes, y offsets,
+ ROW 256 INT pitch table, replacements table,
+ INT indentation pitch, font lead, font height, font depth,
+ next larger font, next smaller font, bold offset ) fonts ,
+
+ ROW max extensions STRUCT (
+ TEXT replacements,
+ ROW 256 INT pitch table, replacements table,
+ INT std pitch ) extensions ,
+
+ );
+
+BOUND FONTTABLE VAR font table;
+
+DATASPACE VAR ds;
+
+INT VAR font nr, extension nr;
+
+. font : font table. fonts (font nr)
+. extension : font table. extensions (extension nr)
+. line nr : line no (file) - 1
+.;
+
+(*****************************************************************)
+
+
+PROC create font table :
+
+ create font table (last param)
+
+END PROC create font table;
+
+
+PROC create font table (TEXT CONST font file name) :
+
+file := sequential file (input, font file name);
+disable stop;
+ds := nilspace;
+modus := nil modus;
+load;
+IF is error THEN error (errormessage) FI;
+forget (ds);
+
+END PROC create font table;
+
+
+PROC add fonts (TEXT CONST font tab name, font file name) :
+
+file := sequential file (input, font file name);
+font table name := font tab name;
+change all (font table name, " ", "");
+IF NOT exists (font table name) COR type (old (font table name)) <> font table type
+ THEN errorstop ("Fonttabelle """ + font table name + """ gibt es nicht")
+FI;
+disable stop;
+ds := old (font table name);
+fonttable := ds;
+modus := font modus;
+font nr := fonttable. last font;
+extension nr := fonttable. last extension;
+load;
+IF is error THEN error (errormessage) FI;
+forget (ds);
+
+END PROC add fonts;
+
+
+PROC load :
+
+enable stop;
+initialize loading;
+REP get kennung;
+ get identification;
+ get char specifications;
+UNTIL symbol type >= t end of file PER;
+font table found;
+
+. initialize loading :
+ scan (file);
+ get next symbol;
+
+. font table found :
+ IF font nr = 0
+ THEN errorstop ("Fonts zur Fonttabelle """
+ + font table name + """ fehlen");
+ ELSE font table. last font := font nr;
+ font table. last extension := extension nr;
+ forget (font table name, quiet);
+ copy (ds, font table name);
+ type (old (font table name), font table type);
+ forget (ds); ds := nilspace;
+ FI;
+
+. get next symbol :
+ next symbol (file, symbol, symbol type);
+
+. get semicolon :
+ get next symbol;
+ IF symbol <> ";" OR symbol type <> t delimiter
+ THEN errorstop ("';' erwartet") FI;
+
+.
+ get kennung :
+ cout (line nr);
+ IF symbol type <> t bold
+ THEN errorstop ("Kennung erwartet") FI;
+ IF symbol = "FONTTABLE" OR symbol = "FONTTABELLE"
+ THEN initialize font table;
+ get font table name;
+ ELIF symbol = "FONT"
+ THEN initialize font;
+ get font names;
+ ELIF symbol = "EXTENSION" OR symbol = "ERWEITERUNG"
+ THEN get extension char;
+ initialize extension;
+ ELIF modus = nil modus
+ THEN errorstop ("Kennung 'FONTTABLE' oder 'FONTTABELLE' zu Beginn der Datei erwartet")
+ ELSE errorstop ("unzulaessige Kennung")
+ FI;
+
+ . initialize font table :
+ IF modus <> nil modus THEN font table found FI;
+ modus := font table modus;
+ font nr := 0;
+ extension nr := 0;
+ font table := ds;
+ font table. font names := empty thesaurus;
+ font table. replacements := "";
+ font table. font name links := "";
+ font table. extension chars := "";
+ font table. extension indexes := "";
+ font table. x unit := 10.0/2.54;
+ font table. y unit := 6.0/2.54;
+ font table. replacements table := 0;
+ FOR index FROM 1 UPTO 4
+ REP font table. on strings (index) := "";
+ font table. off strings (index) := "";
+ PER;
+
+ . get font table name :
+ get name list;
+ symbol type := t text;
+ symbol := name (names, 1);
+ IF exists (symbol)
+ THEN forget (symbol);
+ IF exists (symbol)
+ THEN errorstop ("Fonttabelle existiert schon") FI;
+ FI;
+ font table name := symbol;
+
+ . initialize font :
+ IF font nr = max fonts
+ THEN errorstop ("zu viele Fonts") FI;
+ font nr INCR 1;
+ modus := font modus;
+ replacements length := LENGTH font table. replacements;
+ font. font string := "";
+ font. font name indexes := "";
+ font. replacements := "";
+ font. extension chars := "";
+ font. extension indexes := "";
+ font. y offsets := int length * ""0"";
+ font. indentation pitch := int (font table. x unit * 2.54 / 10.0);
+ font. font lead := 0;
+ font. font height := int (font table. y unit * 2.54 / 6.0);
+ font. font depth := 0;
+ font. next larger font := 0;
+ font. next smaller font := 0;
+ font. bold offset := 0;
+ font. pitch table := font. indentation pitch;
+ font. replacements table := font table. replacements table;
+ FOR index FROM 1 UPTO LENGTH font table. extension chars
+ REP font. replacements table
+ ( code (font table. extension chars SUB index) + 1 ) := maxint;
+ PER;
+
+ . get font names :
+ get name list;
+ index := 0;
+ symbol type := t text;
+ WHILE next font name
+ REP link nr := link (font table. font names, symbol);
+ IF link nr = 0
+ THEN insert (font table. font names, symbol, link nr);
+ font table. font name links CAT font nr;
+ ELIF (font table. font name links ISUB link nr) = 0
+ THEN replace (font table. font name links, link nr, font nr);
+ ELSE errorstop ("Font existiert in Fonttabelle """
+ + font table name + """ schon")
+ FI;
+ font. font name indexes CAT link nr;
+ PER;
+
+ . next font name :
+ get (names, symbol, index);
+ symbol <> ""
+
+ . get extension char :
+ IF NOT two bytes
+ THEN errorstop ("Erweiterungen nur im zwei-Byte-Modus erlaubt") FI;
+ get name list;
+ symbol type := t text;
+ symbol := name (names, 1);
+ IF LENGTH symbol <> 1
+ THEN errorstop ("nur ein Zeichen bei Erweiterung erlaubt") FI;
+ extension code 1 := code (symbol) + 1;
+ IF NOT is kanji esc (symbol)
+ THEN errorstop ("Kanji-ESC-Zeichen erwartet") FI;
+
+ . initialize extension :
+ IF extension nr = max extensions
+ THEN errorstop ("zu viele Erweiterungen") FI;
+ extension nr INCR 1;
+ IF modus <> extension modus THEN last modus := modus FI;
+ modus := extension modus;
+ IF last modus = font table modus
+ THEN initalize font table extension
+ ELSE initalize font extension
+ FI;
+
+ . initalize font table extension :
+ IF pos (font table. extension chars, symbol) <> 0
+ THEN errorstop ("Erweiterung wurde schon definiert") FI;
+ extension. replacements := "";
+ extension. std pitch := 0;
+ extension. pitch table := 0;
+ extension. replacements table := 0;
+ font table. extension chars CAT symbol;
+ font table. extension indexes CAT extension nr;
+ font table. replacements table (extension code 1) := max int;
+ replacements length := 0;
+
+ . initalize font extension :
+ IF pos (font. extension chars, symbol) <> 0
+ THEN errorstop ("Erweiterung wurde schon definiert") FI;
+ extension. replacements := "";
+ extension. std pitch := font. pitch table (extension code 1) XOR (-maxint-1);
+ extension. pitch table := extension. std pitch;
+ font. extension chars CAT symbol;
+ font. extension indexes CAT extension nr;
+ char pos := pos (font table. extension chars, symbol);
+ IF char pos <> 0
+ THEN index := font table. extension indexes ISUB char pos;
+ extension. replacements table :=
+ font table. extensions (index). replacements table;
+ replacements length :=
+ LENGTH font table. extensions (index). replacements;
+ font. replacements table (extension code 1) := max int;
+ ELSE extension. replacements table := 0;
+ replacements length := 0;
+ FI;
+
+.
+ get identification :
+ WHILE identification found
+ REP cout (line nr);
+ determine identification link nr;
+ select identification;
+ PER;
+
+ . identification found :
+ get next symbol;
+ symbol type = t tag
+
+ . determine identification link nr :
+ identification nr := link (english identification, symbol);
+ english := TRUE;
+ IF identification nr = 0
+ THEN identification nr := link (german identification, symbol);
+ english := FALSE;
+ IF identification nr = 0
+ THEN errorstop ("unzulaesige Identifikation") FI;
+ FI;
+
+ . select identification :
+ get next symbol;
+ IF symbol <> "=" OR symbol type <> t operator
+ THEN errorstop ("'=' nach Identifikation fehlt") FI;
+ get next symbol;
+ SELECT identification nr OF
+ CASE x unit : x unit found
+ CASE y unit : y unit found
+ CASE on string : on string found
+ CASE off string : off string found
+ CASE indentation pitch : indentation pitch found
+ CASE font lead : font lead found
+ CASE font height : font height found
+ CASE font depth : font depth found
+ CASE larger font : larger font found
+ CASE smaller font : smaller font found
+ CASE font string : font string found
+ CASE y offsets : y offsets found
+ CASE bold offset : bold offset found
+ END SELECT;
+
+ . x unit found :
+ check modus (font table modus);
+ font table. x unit := real (symbol);
+ IF NOT last conversion ok
+ THEN IF english
+ THEN errorstop ("REAL-Denoter nach 'x unit' erwartet")
+ ELSE errorstop ("REAL-Denoter nach 'x einheit' erwartet")
+ FI;
+ FI;
+ get semicolon;
+
+ . y unit found :
+ check modus (font table modus);
+ font table. y unit := real (symbol);
+ IF NOT last conversion ok
+ THEN IF english
+ THEN errorstop ("REAL-Denoter nach 'y unit' erwartet")
+ ELSE errorstop ("REAL-Denoter nach 'y einheit' erwartet")
+ FI;
+ FI;
+ get semicolon;
+
+ . on string found :
+ check modus (font table modus);
+ FOR index FROM 1 UPTO 4
+ REP IF symbol type <> t text
+ THEN IF english
+ THEN errorstop ("TEXT-Denoter nach 'on string' erwartet")
+ ELSE errorstop ("TEXT-Denoter nach 'on sequenz' erwartet")
+ FI;
+ FI;
+ font table. on strings (index) := symbol;
+ get next symbol;
+ IF (symbol <> "," AND symbol <> ";") OR symbol type <> t delimiter
+ THEN errorstop ("',' oder ';' in Liste erwartet") FI;
+ IF symbol = ";" THEN LEAVE on string found FI;
+ IF index = 4 THEN errorstop ("';' erwartet") FI;
+ get next symbol;
+ PER;
+
+ . off string found :
+ check modus (font table modus);
+ FOR index FROM 1 UPTO 4
+ REP IF symbol type <> t text
+ THEN IF english
+ THEN errorstop ("TEXT-Denoter nach 'off string' erwartet")
+ ELSE errorstop ("TEXT-Denoter nach 'off sequenz' erwartet")
+ FI;
+ FI;
+ font table. off strings (index) := symbol;
+ get next symbol;
+ IF (symbol <> "," AND symbol <> ";") OR symbol type <> t delimiter
+ THEN errorstop ("',' oder ';' in Liste erwartet") FI;
+ IF symbol = ";" THEN LEAVE off string found FI;
+ IF index = 4 THEN errorstop ("';' erwartet") FI;
+ get next symbol;
+ PER;
+
+ . indentation pitch found :
+ check modus (font modus);
+ font. indentation pitch := int (symbol);
+ IF NOT last conversion ok
+ THEN IF english
+ THEN errorstop ("INT-Denoter nach 'indentation pitch' erwartet")
+ ELSE errorstop ("INT-Denoter nach 'einrueckbreite' erwartet")
+ FI;
+ FI;
+ font. pitch table := font. indentation pitch;
+ get semicolon;
+
+ . font lead found :
+ check modus (font modus);
+ font. font lead := int (symbol);
+ IF NOT last conversion ok
+ THEN IF english
+ THEN errorstop ("INT-Denoter nach 'font lead' erwartet")
+ ELSE errorstop ("INT-Denoter nach 'durchschuss' erwartet")
+ FI;
+ FI;
+ get semicolon;
+
+ . font height found :
+ check modus (font modus);
+ font. font height := int (symbol);
+ IF NOT last conversion ok
+ THEN IF english
+ THEN errorstop ("INT-Denoter nach 'font height' erwartet")
+ ELSE errorstop ("INT-Denoter nach 'fonthoehe' erwartet")
+ FI;
+ FI;
+ get semicolon;
+
+ . font depth found :
+ check modus (font modus);
+ font. font depth := int (symbol);
+ IF NOT last conversion ok
+ THEN IF english
+ THEN errorstop ("INT-Denoter nach 'font depth' erwartet")
+ ELSE errorstop ("INT-Denoter nach 'fonttiefe' erwartet")
+ FI;
+ FI;
+ get semicolon;
+
+ . larger font found :
+ check modus (font modus);
+ IF symbol type <> t text
+ THEN IF english
+ THEN errorstop ("TEXT-Denoter nach 'next larger font' erwartet")
+ ELSE errorstop ("TEXT-Denoter nach 'groesserer font' erwartet")
+ FI;
+ FI;
+ determine link nr;
+ font. next larger font := link nr;
+ get semicolon;
+
+ . smaller font found :
+ check modus (font modus);
+ IF symbol type <> t text
+ THEN IF english
+ THEN errorstop ("TEXT-Denoter nach 'next smaller font' erwartet")
+ ELSE errorstop ("TEXT-Denoter nach 'kleinerer font' erwartet")
+ FI;
+ FI;
+ determine link nr;
+ font. next smaller font := link nr;
+ get semicolon;
+
+ . determine link nr :
+ change all (symbol, " ", "");
+ IF symbol = ""
+ THEN link nr := 0
+ ELSE link nr := link (font table. font names, symbol);
+ IF link nr = 0
+ THEN insert (font table. font names, symbol, link nr);
+ font table. font name links CAT 0;
+ FI;
+ FI;
+
+ . font string found :
+ check modus (font modus);
+ IF symbol type <> t text
+ THEN IF english
+ THEN errorstop ("TEXT-Denoter nach 'font string' erwartet")
+ ELSE errorstop ("TEXT-Denoter nach 'fontsequenz' erwartet")
+ FI;
+ FI;
+ font. font string := symbol;
+ get semicolon;
+
+ . y offsets found :
+ check modus (font modus);
+ font. y offsets := "";
+ REP IF symbol = "-" AND symbol type = t operator
+ THEN vorzeichen := -1;
+ get next symbol;
+ ELSE vorzeichen := 1;
+ FI;
+ int symbol := vorzeichen * int (symbol);
+ IF NOT last conversion ok
+ THEN IF english
+ THEN errorstop ("INT-Denoter nach 'y offsets' erwartet")
+ ELSE errorstop ("INT-Denoter nach 'y verschiebungen' erwartet")
+ FI;
+ FI;
+ font. y offsets CAT int symbol;
+ get next symbol;
+ IF (symbol <> "," AND symbol <> ";") OR symbol type <> t delimiter
+ THEN errorstop ("',' oder ';' in Liste erwartet") FI;
+ IF symbol = ";" THEN LEAVE y offsets found FI;
+ get next symbol;
+ PER;
+
+ . bold offset found :
+ check modus (font modus);
+ IF symbol = "-" AND symbol type = t operator
+ THEN vorzeichen := -1;
+ get next symbol;
+ ELSE vorzeichen := 1;
+ FI;
+ font. bold offset := vorzeichen * int (symbol);
+ IF NOT last conversion ok
+ THEN IF english
+ THEN errorstop ("INT-Denoter nach 'bold offset' erwartet")
+ ELSE errorstop ("INT-Denoter nach 'bold verschiebungen' erwartet")
+ FI;
+ FI;
+ get semicolon;
+
+.
+ get char specifications :
+ WHILE char found
+ REP cout (line nr);
+ char specification;
+ get next symbol;
+ PER;
+
+ . char found :
+ symbol type = t text
+
+ . char specification :
+ IF LENGTH symbol <> 1
+ THEN errorstop ("nur ein Zeichen bei Zeichenangabe erlaubt") FI;
+ char := symbol;
+ char code 1 := code (char) + 1;
+ look for specification;
+ look for specification;
+ get semicolon;
+
+ . look for specification :
+ get next symbol;
+ IF symbol = ";" AND symbol type = t delimiter
+ THEN LEAVE char specification
+ ELIF symbol = "," AND symbol type = t delimiter
+ THEN get specification
+ ELSE errorstop ("',' oder ';' bei Zeichenspezifikation erwartet")
+ FI;
+
+ . get specification :
+ get next symbol;
+ IF symbol type = t number
+ THEN pitch specification;
+ ELIF symbol type = t text
+ THEN replacement specification
+ ELSE errorstop ("unzulaessiger Wert bei Zeichenspezifikation")
+ FI;
+
+ . pitch specification :
+ int symbol := int (symbol);
+ IF NOT last conversion ok
+ THEN errorstop ("INT-Denoter bei Breitenangabe erwartet") FI;
+ IF modus = font modus
+ THEN font. pitch table (char code 1) := int symbol;
+ IF is kanji esc (char)
+ THEN set bit (font. pitch table (char code 1), highest bit) FI;
+ ELIF modus = extension modus
+ THEN IF last modus = font modus AND
+ font. pitch table (extension code 1) <> max int
+ THEN font. pitch table (extension code 1) := max int FI;
+ extension. pitch table (char code 1) := int symbol;
+ FI;
+
+ . replacement specification :
+ IF LENGTH symbol > 255
+ THEN errorstop ("Ersatzdarstellungen duerfen nur 255 Zeichen haben") FI;
+ IF modus = font table modus
+ THEN font table. replacements table (char code 1) :=
+ (LENGTH font table. replacements + 1);
+ font table. replacements CAT code (LENGTH symbol);
+ font table. replacements CAT symbol;
+ IF is kanji esc (char)
+ THEN set bit (font table. replacements table (char code 1), highest bit) FI;
+ ELIF modus = font modus
+ THEN font. replacements table (char code 1) :=
+ (replacements length + LENGTH font. replacements + 1);
+ font. replacements CAT code (LENGTH symbol);
+ font. replacements CAT symbol;
+ IF is kanji esc (char)
+ THEN set bit (font. replacements table (char code 1), highest bit) FI;
+ ELIF modus = extension modus
+ THEN IF last modus = font modus AND
+ font. replacements table (extension code 1) <> max int
+ THEN font. replacements table (extension code 1) := max int FI;
+ extension. replacements table (char code 1) :=
+ (replacements length + LENGTH extension. replacements + 1);
+ extension. replacements CAT code (LENGTH symbol);
+ extension. replacements CAT symbol;
+ FI;
+
+END PROC load;
+
+
+PROC get name list :
+
+ names := empty thesaurus;
+ get next symbol;
+ IF symbol <> ":" OR symbol type <> t delimiter
+ THEN errorstop ("':' nach Kennung erwartet") FI;
+ REP get next symbol;
+ change all (symbol, " ", "");
+ IF symbol type <> t text
+ THEN errorstop ("TEXT-Denoter in Namesliste erwartet") FI;
+ IF symbol = ""
+ THEN errorstop ("'niltext' als Name nicht erlaubt") FI;
+ insert (names, symbol);
+ get next symbol;
+ IF (symbol <> "," AND symbol <> ";") OR symbol type <> t delimiter
+ THEN errorstop ("',' oder ';' in Liste erwartet") FI;
+ UNTIL symbol = ";" PER;
+
+ . get next symbol :
+ next symbol (file, symbol, symbol type);
+
+END PROC get name list;
+
+
+OP := (ROW 256 INT VAR l, INT CONST r) :
+
+INT VAR i;
+IF modus = extension modus OR NOT two bytes
+ THEN FOR i FROM 1 UPTO 256 REP l (i) := r PER;
+ ELSE FOR i FROM 1 UPTO 129 REP l (i) := r PER;
+ FOR i FROM 130 UPTO 160 REP l (i) := r - maxint - 1 PER;
+ FOR i FROM 161 UPTO 224 REP l (i) := r PER;
+ FOR i FROM 225 UPTO 240 REP l (i) := r - maxint - 1 PER;
+ FOR i FROM 241 UPTO 256 REP l (i) := r PER;
+FI;
+
+END OP :=;
+
+
+PROC check modus (INT CONST mod) :
+
+ IF mod <> modus THEN errorstop ("unzulaessige Identifikation") FI;
+
+END PROC check modus;
+
+
+PROC error (TEXT CONST message) :
+
+(*INT CONST l := error line;*)
+ clear error;
+ errorstop ("Zeile " + text (line nr) + " bei " + letztes symbol +
+ " : " + message (* + errorline if neccessary *) );
+
+ . letztes symbol :
+ IF symbol type = t text
+ THEN decode (symbol);
+ """" + symbol + """"
+ ELIF symbol type >= t end of file
+ THEN "EOF"
+ ELSE symbol
+ FI
+(*
+ . errorline if neccessary :
+ IF l = 0
+ THEN ""
+ ELSE " -> " + text (l)
+ FI
+*)
+END PROC error;
+
+
+(*******************************************************************)
+
+
+PROC create font file (TEXT CONST font tab name, font file name) :
+
+enable stop;
+connect font table;
+put font table in font file;
+
+.
+ connect font table :
+ buffer := font tab name;
+ change all (buffer, " ", "");
+ IF NOT exists (buffer) COR type (old (buffer)) <> font table type
+ THEN errorstop ("Fonttabelle """ + buffer + """ gibt es nicht")
+ FI;
+ font table := old (buffer);
+
+.
+ put font table in font file :
+ INT VAR font file nr := 0;
+ enable stop;
+ font file := sequential file (output, font file name);
+ max line length (font file, 16000);
+ check file overflow;
+ z := " ";
+ put font table;
+ FOR font nr FROM 1 UPTO font table. last font REP put font PER;
+
+ . check file overflow :
+ WHILE lines (font file) > 3600
+ REP font file nr INCR 1;
+ font file := sequential file (output, font file name + "." + text (font file nr));
+ max line length (font file, 16000);
+ PER;
+
+. put font table :
+ put z;
+ z CAT "FONTTABLE : """; z CAT buffer; z CAT """;"; put z;
+ z CAT " x unit = "; z CAT text (font table. x unit); z CAT ";"; put z;
+ z CAT " y unit = "; z CAT text (font table. y unit); z CAT ";"; put z;
+ z CAT " on string = """; z cat on strings; z CAT """;"; put z;
+ z CAT " off string = """; z cat off strings; z CAT """;"; put z;
+ put font table replacements;
+ put font table extensions;
+ put z;
+
+ . z cat on strings :
+ FOR index FROM 1 UPTO 4
+ REP buffer := font table. on strings (index);
+ decode (buffer);
+ z CAT buffer;
+ IF index <> 4 THEN z CAT """, """ FI;
+ PER;
+
+ . z cat off strings :
+ FOR index FROM 1 UPTO 4
+ REP buffer := font table. off strings (index);
+ decode (buffer);
+ z CAT buffer;
+ IF index <> 4 THEN z CAT """, """ FI;
+ PER;
+
+ . put font table replacements :
+ put z;
+ FOR char code FROM 0 UPTO 255
+ REP char code 1 := char code + 1;
+ link nr := font table. replacements table (char code 1);
+ reset bit (link nr, highest bit);
+ IF link nr > 0 AND link nr <> maxint
+ THEN z CAT " ";
+ put char code;
+ put font table replacement;
+ put z;
+ FI;
+ PER;
+
+ . put font table replacement :
+ replacement := subtext (font table. replacements, link nr + 1,
+ link nr + code (font table. replacements SUB link nr) );
+ put replacement;
+
+ . put font table extensions :
+ IF font table. extension chars <> ""
+ THEN FOR index FROM 1 UPTO LENGTH font table. extension chars
+ REP put font table extension PER;
+ FI;
+
+ . put font table extension :
+ check file overflow;
+ put z;
+ z CAT " EXTENSION : """"";
+ z CAT text 3 (code (font table. extension chars SUB index));
+ z CAT """"";";
+ put z; put z;
+ replacements length := 0;
+ extension nr := font table. extension indexes ISUB index;
+ FOR char code FROM 0 UPTO 255
+ REP char code 1 := char code + 1;
+ link nr := extension. replacements table (char code 1);
+ IF link nr > 0
+ THEN z CAT " ";
+ put char code;
+ put extension replacement;
+ put z;
+ FI;
+ PER;
+
+. put font :
+ check file overflow;
+ put z;
+ z CAT " FONT : "; z cat font names; z CAT ";"; put z;
+ z CAT " indentation pitch = ";
+ z CAT text(font. indentation pitch);
+ z CAT ";"; put z;
+ IF font. font lead <> 0
+ THEN z CAT " font lead = ";
+ z CAT text(font. font lead);
+ z CAT ";"; put z;
+ FI;
+ z CAT " font height = ";
+ z CAT text(font. font height);
+ z CAT ";"; put z;
+ IF font. font depth <> 0
+ THEN z CAT " font depth = ";
+ z CAT text(font. font depth);
+ z CAT ";"; put z;
+ FI;
+ IF next larger <> ""
+ THEN z CAT " next larger font = """;
+ z CAT next larger;
+ z CAT """;"; put z;
+ FI;
+ IF next smaller <> ""
+ THEN z CAT " next smaller font = """;
+ z CAT next smaller;
+ z CAT """;"; put z;
+ FI;
+ IF font. font string <> ""
+ THEN z CAT " font string = """;
+ z CAT font string;
+ z CAT """;"; put z;
+ FI;
+ IF (font. y offsets ISUB 1) <> 0 OR LENGTH font. y offsets > int length
+ THEN z CAT " y offsets = ";
+ z cat y offsets;
+ z CAT ";"; put z;
+ FI;
+ IF font. bold offset <> 0
+ THEN z CAT " bold offset = ";
+ z CAT text(font. bold offset);
+ z CAT ";"; put z;
+ FI;
+ put font pitches and replacements;
+ put font extensions;
+
+ . next larger : name (font table. font names, font. next larger font)
+ . next smaller : name (font table. font names, font. next smaller font)
+ . font string : buffer := font. font string; decode (buffer); buffer
+
+ . z cat font names :
+ z CAT """";
+ z CAT name (font table. font names, font. font name indexes ISUB 1);
+ z CAT """";
+ FOR index FROM 2 UPTO LENGTH font. font name indexes DIV int length
+ REP z CAT ", """;
+ z CAT name (font table. font names, font. font name indexes ISUB index);
+ z CAT """";
+ PER;
+
+ . z cat y offsets :
+ z CAT text (font. y offsets ISUB 1);
+ FOR index FROM 2 UPTO LENGTH font. y offsets DIV int length
+ REP z CAT ", ";
+ z CAT text (font. y offsets ISUB index);
+ PER;
+
+ . put font pitches and replacements :
+ BOOL VAR ausgabe := FALSE;
+ replacements length := LENGTH font table. replacements;
+ put z;
+ z CAT " ";
+ FOR char code FROM 0 UPTO 255
+ REP char code 1 := char code + 1;
+ pitch := font. pitch table (char code 1);
+ reset bit (pitch, highest bit);
+ link nr := font. replacements table (char code 1);
+ reset bit (link nr, highest bit);
+ IF (pitch <> font. indentation pitch) OR
+ (link nr > replacements length AND link nr <> maxint)
+ THEN put font char pitch and replacement;
+ IF ausgabe
+ THEN put z;
+ ausgabe := FALSE;
+ ELSE ausgabe := TRUE;
+ FI;
+ z CAT " ";
+ FI;
+ PER;
+ IF ausgabe THEN put z ELSE z := " " FI;
+
+ . put font char pitch and replacement :
+ put char code;
+ put font char pitch;
+ IF link nr > replacements length AND link nr <> maxint
+ THEN put font replacement;
+ IF NOT ausgabe THEN z CAT (6 - LENGTH replacement) * " " FI;
+ ELIF ausgabe
+ THEN z CAT ";"
+ ELSE z CAT "; ";
+ FI;
+
+ . put font char pitch :
+ IF pitch = max int
+ THEN char pos := pos (font. extension chars, code (char code));
+ IF char pos <> 0
+ THEN pitch := font table. extensions
+ (font. extension indexes ISUB char pos). std pitch
+ FI;
+ FI;
+ put char pitch;
+
+ . put font replacement :
+ link nr DECR replacements length;
+ replacement := subtext (font. replacements, link nr + 1,
+ link nr + code (font. replacements SUB link nr) );
+ put replacement;
+
+ . put font extensions :
+ IF font. extension chars <> ""
+ THEN FOR index FROM 1 UPTO LENGTH font. extension chars
+ REP put font extension PER;
+ FI;
+
+ . put font extension :
+ check file overflow;
+ put z;
+ z CAT " EXTENSION : """"";
+ z CAT text 3 (code (font. extension chars SUB index));
+ z CAT """"";";
+ put z; put z; z CAT " ";
+ detemine replacements length;
+ extension nr := font. extension indexes ISUB index;
+ ausgabe := FALSE;
+ FOR char code FROM 0 UPTO 255
+ REP char code 1 := char code + 1;
+ pitch := extension. pitch table (char code 1);
+ link nr := extension. replacements table (char code 1);
+ IF pitch <> extension. std pitch OR link nr > replacements length
+ THEN put extension char pitch and replacement;
+ IF ausgabe
+ THEN put z;
+ ausgabe := FALSE;
+ ELSE ausgabe := TRUE;
+ FI;
+ z CAT " ";
+ FI;
+ PER;
+ IF ausgabe THEN put z ELSE z := " " FI;
+
+ . detemine replacements length :
+ char pos := pos (font table. extension chars,
+ font. extension chars SUB index);
+ IF char pos <> 0
+ THEN replacements length := LENGTH font table. extensions
+ (font table. extension indexes ISUB char pos). replacements;
+ ELSE replacements length := 0;
+ FI;
+
+ . put extension char pitch and replacement :
+ put char code;
+ put char pitch;
+ IF link nr > replacements length
+ THEN put extension replacement;
+ IF NOT ausgabe THEN z CAT (6 - LENGTH replacement) * " " FI;
+ ELIF ausgabe
+ THEN z CAT ";"
+ ELSE z CAT "; ";
+ FI;
+
+. put extension replacement :
+ link nr DECR replacements length;
+ replacement := subtext (extension. replacements, link nr + 1,
+ link nr + code (extension. replacements SUB link nr) );
+ put replacement;
+
+. put char code :
+ IF (char code >= 32 AND char code <= 122) OR
+ (char code >= 214 AND char code <= 223) OR
+ char code = 124 OR char code = 126 OR char code = 251
+ THEN z CAT "(* ";
+ z CAT code (char code);
+ z CAT " *) """"";
+ ELSE z CAT " """"";
+ FI;
+ z CAT text 3 (char code);
+ z CAT """""";
+
+. put char pitch :
+ z CAT ",";
+ z CAT text (pitch, 5);
+
+. put replacement :
+ decode (replacement);
+ z CAT ", """;
+ z CAT replacement;
+ z CAT """;"
+
+END PROC create font file;
+
+
+PROC put z :
+
+ putline (font file, z);
+ cout (lines (font file));
+ z := " ";
+
+END PROC put z;
+
+
+PROC decode (TEXT VAR string) :
+
+ INT VAR p;
+ change all (string, """", """""");
+ p := pos (string, ""0"", ""31"", 1);
+ WHILE p <> 0
+ REP change (string, p, p, """" + text (code(string SUB p)) + """");
+ p := pos (string, ""0"", ""31"", p);
+ PER;
+ p := pos (string, ""127"", ""255"", 1);
+ WHILE p <> 0
+ REP change (string, p, p, """" + text (code(string SUB p)) + """");
+ p := pos (string, ""127"", ""255"", p);
+ PER;
+
+END PROC decode;
+
+
+TEXT PROC text 3 (INT CONST value) :
+
+ buffer := text (value, 3);
+ change all (buffer, " ", "0");
+ buffer
+
+END PROC text 3;
+
+END PACKET font convertor;
+
diff --git a/system/free channel b/system/free channel
new file mode 100644
index 0000000..3814f9d
--- /dev/null
+++ b/system/free channel
@@ -0,0 +1,430 @@
+PACKET free channel DEFINES (* Autor: J.Liedtke *)
+ (* Stand: 10.06.86 *)
+ FCHANNEL ,
+ := ,
+ free channel ,
+ open ,
+ close ,
+ out ,
+ in ,
+ dialogue ,
+ save ,
+ fetch :
+
+
+
+LET ack = 0 ,
+ nak = 1 ,
+ error nak = 2 ,
+ empty message code = 256 ,
+ long message code = 257 ,
+ file send code = 1024 ,
+ file receive code = 2048 ,
+ open code = 1000 ,
+ close code = 1001 ,
+
+ file type = 1003 ;
+
+INT CONST task not existing := - 1 ;
+
+
+TYPE FCHANNEL = STRUCT (TASK server, TEXT input buffer, server name) ;
+
+INT VAR message code , response code ;
+TASK VAR partner ;
+DATASPACE VAR ds ;
+
+BOUND TEXT VAR msg ;
+TEXT VAR response, char, esc char , record ;
+
+FILE VAR file ;
+
+
+OP := (FCHANNEL VAR dest, FCHANNEL CONST source) :
+
+ dest.server := source.server ;
+ dest.input buffer := "" ;
+ dest.server name := source.server name ;
+ open (dest)
+
+ENDOP := ;
+
+FCHANNEL PROC free channel (TEXT CONST channel name) :
+
+ FCHANNEL:(niltask,"", channel name)
+
+ENDPROC free channel ;
+
+PROC open (FCHANNEL VAR channel) :
+
+ INT VAR receipt ;
+
+ initialize message dataspace ;
+ send open code ;
+ IF receipt <> ack
+ THEN errorstop ("channel not free")
+ FI .
+
+initialize message dataspace :
+ forget (ds) ;
+ ds := nilspace .
+
+send open code :
+ ping pong (channel.server, open code, ds, receipt) ;
+ IF receipt = task not existing
+ THEN channel.server := task (channel.server name) ;
+ ping pong (channel.server, open code, ds, receipt)
+ FI .
+
+ENDPROC open ;
+
+PROC close (FCHANNEL VAR channel) :
+
+ forget (ds) ;
+ ds := nilspace ;
+ call (channel.server, close code, ds, response code)
+
+ENDPROC close ;
+
+PROC close (TEXT CONST channel server) :
+
+ forget (ds) ;
+ ds := nilspace ;
+ call (task (channel server), close code, ds, response code)
+
+ENDPROC close ;
+
+
+PROC out (FCHANNEL VAR channel, TEXT CONST message) :
+
+ send message ;
+ get response .
+
+send message :
+ IF message = ""
+ THEN call (channel.server, empty message code, ds, response code)
+ ELSE msg := ds ;
+ CONCR (msg) := message ;
+ call (channel.server, long message code, ds, response code)
+ FI .
+
+get response :
+ IF response code < 0
+ THEN errorstop ("channel not ready")
+ ELIF response code < 256
+ THEN channel.input buffer CAT code (response code)
+ ELIF response code = long message code
+ THEN msg := ds ;
+ channel.input buffer CAT CONCR (msg)
+ FI .
+
+ENDPROC out ;
+
+PROC in (FCHANNEL VAR channel, TEXT VAR response) :
+
+ out (channel, "") ;
+ response := channel.input buffer ;
+ channel.input buffer := ""
+
+ENDPROC in ;
+
+PROC save (FCHANNEL VAR channel, TEXT CONST file name, control chars) :
+
+ prepare ds ;
+ call (channel.server, file send code, ds, response code) ;
+ IF response code = error nak
+ THEN BOUND TEXT VAR error msg := ds ;
+ errorstop (error msg)
+ FI .
+
+prepare ds :
+ forget (ds) ;
+ ds := old (file name, file type) ;
+ FILE VAR f := sequential file (modify, ds) ;
+ headline (f, control chars) .
+
+ENDPROC save ;
+
+PROC fetch (FCHANNEL VAR channel, TEXT CONST file name, control chars) :
+
+ IF NOT exists (file name) COR yes ("""" + file name + """ loeschen")
+ THEN fetch first part ;
+ WHILE more to fetch REP
+ fetch next part
+ PER
+ FI .
+
+fetch first part :
+ INT VAR part := 0 ;
+ receive file (channel, file name, control chars) .
+
+fetch next part :
+ part INCR 1 ;
+ receive file (channel, file name + "." + text (part), control chars) .
+
+more to fetch : response code = file receive code .
+
+ENDPROC fetch ;
+
+PROC receive file (FCHANNEL VAR channel,TEXT CONST file name, control chars):
+
+ prepare ds ;
+ call (channel.server, file receive code, ds, response code);
+ IF response code = error nak
+ THEN BOUND TEXT VAR error msg := ds ;
+ errorstop (error msg)
+ ELSE forget (file name, quiet) ;
+ copy (ds, file name) ;
+ forget (ds) ;
+ ds := nilspace ;
+ FI .
+
+prepare ds :
+ forget (ds) ;
+ ds := nilspace ;
+ BOUND TEXT VAR ctl := ds ;
+ ctl := control chars .
+
+ENDPROC receive file ;
+
+
+PROC dialogue (FCHANNEL CONST channel, TEXT CONST esc) :
+
+ forget (ds) ;
+ ds := nilspace ;
+ partner := channel.server ;
+ esc char := esc ;
+ enable stop ;
+
+ response code := empty message code ;
+ REP
+ get and send message charety ;
+ out response option
+ PER .
+
+get and send message charety :
+ IF response code = empty message code
+ THEN char := incharety (10)
+ ELSE char := incharety
+ FI ;
+ IF char = ""
+ THEN call (partner, empty message code, ds, response code)
+ ELIF char = esc char
+ THEN LEAVE dialogue
+ ELSE call (partner, code (char), ds, response code)
+ FI .
+
+out response option :
+ IF response code < 256
+ THEN out (code (response code))
+ ELIF response code = long message code
+ THEN msg := ds ;
+ out (CONCR (msg))
+ FI .
+
+ENDPROC dialogue ;
+
+PROC free channel (INT CONST nr) :
+
+ INT CONST my channel := nr ;
+ break ;
+ disable stop ;
+ REP
+ wait (ds, message code, partner) ;
+ IF message code = open code
+ THEN connect to my channel ;
+ use channel ;
+ break (quiet)
+ ELIF message code >= 0
+ THEN send (partner, nak, ds)
+ FI
+ PER .
+
+use channel :
+ ping pong (partner, ack, ds, message code) ;
+ WHILE message code <> close code AND message code >= 0 REP
+ IF message code <= long message code THEN dialogue
+ ELIF message code = file receive code THEN receive file
+ ELIF message code = file send code THEN send file
+ ELIF message code = open code THEN ignore open
+ ELSE errorstop ("falsche Sendung")
+ FI
+ UNTIL is error PER ;
+ IF is error
+ THEN send error message
+ ELSE send handshake ack
+ FI .
+
+dialogue :
+ IF message code < 256
+ THEN out (code (message code))
+ ELIF message code = long message code
+ THEN msg := ds ;
+ out (CONCR (msg))
+ FI ;
+ response := incharety (1) ;
+ IF response = ""
+ THEN ping pong (partner, empty message code, ds, message code)
+ ELSE short or long response
+ FI .
+
+short or long response :
+ char := incharety ;
+ IF char = ""
+ THEN short response
+ ELSE long response
+ FI .
+
+short response :
+ ping pong (partner, code (response), ds, message code) .
+
+long response :
+ msg := ds ;
+ response CAT char ;
+ msg := response ;
+ REP
+ cat input (msg, char) ;
+ msg CAT char
+ UNTIL char = "" OR LENGTH msg > 500 PER ;
+ ping pong (partner, long message code, ds, message code) .
+
+connect to my channel :
+ continue (my channel) ;
+ WHILE is error REP
+ clear error ;
+ pause (100) ;
+ continue (my channel)
+ PER .
+
+send handshake ack :
+ send (partner, ack, ds) .
+
+send error message :
+ forget (ds) ;
+ ds := nilspace ;
+ BOUND TEXT VAR error msg := ds ;
+ error msg := error message ;
+ clear error ;
+ send (partner, error nak, ds) .
+
+ignore open :
+ ping pong (partner, ack, ds, message code) .
+
+ENDPROC free channel ;
+
+PROC send file :
+
+ enable stop ;
+ file := sequential file (input,ds) ;
+ get control chars ;
+ skip chars ;
+ REP
+ getline (file, record) ;
+ out (record) ;
+ end of line
+ UNTIL eof (file) PER ;
+ end of transmission ;
+ send ack reply .
+
+get control chars :
+ TEXT CONST
+ control chars := headline (file) ,
+ end of file char := control chars SUB 1 ,
+ end of line char := control chars SUB 2 ,
+ handshake char := control chars SUB 3 .
+
+end of line :
+ out (end of line char) ;
+ IF handshake char <> ""
+ THEN wait for handshake
+ FI .
+
+wait for handshake :
+ REP
+ char := incharety (300) ;
+ IF char = ""
+ THEN errorstop ("timeout")
+ FI
+ UNTIL char = handshake char PER .
+
+end of transmission :
+ skip chars ;
+ out (end of file char) .
+
+skip chars :
+ WHILE incharety (3) <> "" REP PER .
+
+send ack reply :
+ forget (ds) ;
+ ds := nilspace ;
+ ping pong (partner, ack, ds, message code) .
+
+ENDPROC send file ;
+
+PROC receive file :
+
+ enable stop ;
+ get control chars ;
+ open file ;
+ INT VAR line no := 0 ;
+ REP
+ receive line ;
+ IF eof received
+ THEN ping pong (partner, ack, ds, message code) ;
+ LEAVE receive file
+ FI ;
+ putline (file, record) ;
+ line no INCR 1
+ UNTIL near file overflow PER ;
+ ping pong (partner, file receive code, ds, message code) .
+
+get control chars :
+ BOUND TEXT VAR control chars := ds ;
+ TEXT CONST
+ end of file char := control chars SUB 1 ,
+ end of line char := control chars SUB 2 ,
+ handshake char := control chars SUB 3 ,
+ handshake prompt := control chars SUB 4 .
+
+open file :
+ forget (ds) ;
+ ds := nilspace ;
+ file := sequential file (output, ds) .
+
+receive line :
+ record := "" ;
+ REP
+ cat input (record, char) ;
+ IF char = ""
+ THEN wait for char
+ FI ;
+ IF char = handshake prompt THEN out (handshake char)
+ ELIF char = ""9"" THEN expand tabs
+ ELIF char = ""12"" THEN page
+ FI
+ UNTIL char = end of line char OR char = end of file char PER .
+
+wait for char :
+ char := incharety (300) ;
+ IF char = ""
+ THEN errorstop ("timeout")
+ ELIF char >= ""32""
+ THEN record CAT char
+ FI .
+
+expand tabs:
+ record CAT (8-(LENGTH record MOD 8)) * " " .
+
+page:
+ record := "#page# " .
+
+eof received :
+ char = end of file char OR (record SUB LENGTH record ) = end of file char .
+
+near file overflow :
+ line no > 3999 OR (line no > 3800 AND record = "#page# ") .
+
+ENDPROC receive file ;
+
+ENDPACKET free channel ;
+
diff --git a/system/port server b/system/port server
new file mode 100644
index 0000000..46c647f
--- /dev/null
+++ b/system/port server
@@ -0,0 +1,164 @@
+PACKET port server: (* Autor : R. Ruland *)
+ (* Stand : 21.03.86 *)
+
+INT VAR port station;
+TEXT VAR port := "PRINTER";
+
+put ("gib Name des Zielspools : "); editget (port); line;
+put ("gib Stationsnummer des Zielspools : "); get (port station);
+
+server channel (15);
+spool duty ("Verwalter fuer Task """ + port +
+ """ auf Station " + text (port station));
+
+LET max counter = 10 ,
+ time slice = 300 ,
+
+ ack = 0 ,
+ fetch code = 11 ,
+ param fetch code = 21 ,
+ file save code = 22 ,
+ file type = 1003 ,
+
+ begin char = ""0"",
+ end char = ""1"";
+
+
+INT VAR reply, old heap size;
+TEXT VAR file name, write pass, read pass, sendername, buffer;
+FILE VAR file;
+
+DATASPACE VAR ds, file ds, send ds;
+
+BOUND STRUCT (TEXT file name, write pass, read pass, sendername, INT station) VAR msg;
+BOUND TEXT VAR error msg ;
+
+spool manager (PROC save file);
+
+PROC save file :
+
+ disable stop ;
+ command dialogue (FALSE);
+ ds := nilspace; file ds := nilspace; send ds := nil space;
+ old heap size := heap size;
+
+ REP
+ execute save file;
+
+ IF is error THEN save error (error message) FI;
+
+ IF heap size > old heap size + 4
+ THEN collect heap garbage ;
+ old heap size := heap size
+ FI;
+
+ PER
+
+ENDPROC save file;
+
+
+PROC execute save file :
+
+enable stop;
+forget (file ds) ; file ds := nilspace;
+call (father, fetch code, file ds, reply);
+IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE save file ds
+FI;
+
+. save file ds :
+ IF type (file ds) = file type
+ THEN get file params;
+ insert file params;
+ call station (port station, port, file save code, file ds);
+ ELSE errorstop ("Datenraum hat falschen Typ")
+ FI;
+
+. get file params :
+ forget (ds); ds := nilspace;
+ call (father, param fetch code, ds, reply);
+ IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE msg := ds;
+ file name := msg. file name;
+ write pass := msg. write pass;
+ read pass := msg. read pass;
+ sendername := msg. sender name;
+ FI;
+
+. insert file params :
+ buffer := "";
+ in headline (filename);
+ in headline (write pass);
+ in headline (read pass);
+ in headline (sendername);
+ file := sequential file (input, file ds) ;
+ headline (file, buffer);
+
+END PROC execute save file;
+
+
+PROC call station (INT CONST order task station, TEXT CONST order task name,
+ INT CONST order code, DATASPACE VAR order ds) :
+
+ INT VAR counter := 0;
+ TASK VAR order task;
+ disable stop;
+ REP order task := order task station // order task name;
+ IF is error CAND pos (error message, "antwortet nicht") > 0
+ THEN clear error;
+ counter := min (max counter, counter + 1);
+ pause (counter * time slice);
+ ELSE enable stop;
+ forget (send ds); send ds := order ds;
+ call (order task, order code, send ds, reply);
+ disable stop;
+ IF reply = ack
+ THEN forget (order ds); order ds := send ds;
+ forget (send ds);
+ LEAVE call station
+ ELSE error msg := send ds;
+ errorstop (error msg);
+ FI;
+ FI;
+ PER;
+
+END PROC call station;
+
+
+TASK OP // (INT CONST station, TEXT CONST name) :
+
+ enable stop;
+ station / name
+
+END OP //;
+
+
+PROC in headline (TEXT CONST information) :
+ IF pos (information, begin char) <> 0
+ OR pos (information, end char) <> 0
+ THEN errorstop ("Name darf nicht Code 0 oder Code 1 enthalten") FI;
+ buffer CAT begin char;
+ buffer CAT information;
+ buffer CAT end char;
+END PROC in headline;
+
+
+PROC save error (TEXT CONST message) :
+ clear error;
+ file name CAT ".";
+ file name CAT sender name;
+ file name CAT ".ERROR";
+ file := sequential file (output, file name);
+ putline (file, " ");
+ putline (file, "Uebertragung nicht korrekt beendet ");
+ putline (file, " ");
+ put (file, "ERROR :"); put (file, message);
+ save (file name, public);
+ clear error;
+ forget(file name, quiet);
+END PROC save error;
+
+ENDPACKET port server;
+
diff --git a/system/printer server b/system/printer server
new file mode 100644
index 0000000..b1a30bc
--- /dev/null
+++ b/system/printer server
@@ -0,0 +1,99 @@
+PACKET multi user printer : (* Autor : Rudolf Ruland *)
+ (* Stand : 24.03.86 *)
+
+INT VAR c;
+put ("gib Druckerkanal : "); get (c);
+
+ server channel (c);
+ station only (FALSE) ;
+ spool duty ("Ausgabe mit dem Drucker");
+ spool control task (myself);
+
+LET ack = 0 ,
+
+ fetch code = 11 ,
+ param fetch code = 21 ,
+ file type = 1003 ;
+
+INT VAR reply, old heap size, sender station;
+TEXT VAR file name, userid, password, sendername;
+FILE VAR file ;
+
+DATASPACE VAR ds, file ds;
+
+BOUND STRUCT (TEXT file name, userid, password, sendername, INT station) VAR msg;
+BOUND TEXT VAR error msg ;
+
+spool manager (PROC printer);
+
+PROC printer :
+
+ disable stop ;
+ command dialogue (FALSE);
+ ds := nilspace; file ds := nilspace;
+ continue (server channel) ;
+ check error ("Kanal belegt");
+
+ old heap size := heap size ;
+ REP
+ execute print ;
+
+ IF is error
+ THEN put error;
+ clear error;
+ FI ;
+
+ IF heap size > old heap size + 4
+ THEN collect heap garbage ;
+ old heap size := heap size
+ FI
+ PER
+
+ENDPROC printer ;
+
+
+PROC execute print :
+
+ enable stop ;
+ forget (file ds) ; file ds := nilspace ;
+ call (father, fetch code, file ds, reply) ;
+ IF reply = ack CAND type (file ds) = file type
+ THEN get file params;
+ print file
+ FI ;
+
+. get file params :
+ forget (ds); ds := nilspace;
+ call (father, param fetch code, ds, reply);
+ IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE msg := ds;
+ file name := msg. file name;
+ userid := msg. userid;
+ password := msg. password;
+ sendername := msg. sender name;
+ sender station := msg. station;
+ FI;
+
+. print file :
+ file := sequential file (input, file ds);
+ print (file,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+ENDPROC execute print ;
+
+
+PROC check error (TEXT CONST message) :
+ IF is error
+ THEN clear error;
+ rename myself (message);
+ IF is error THEN clear error; end (myself) FI;
+ pause (18000);
+ end (myself);
+ FI;
+END PROC check error;
+
+ENDPACKET multi user printer ;
+
diff --git a/system/purge b/system/purge
new file mode 100644
index 0000000..55230ff
--- /dev/null
+++ b/system/purge
@@ -0,0 +1,85 @@
+PACKET purge DEFINES purge :
+
+
+TEXT VAR task name, record, file name, dummy ;
+
+FILE VAR permit ;
+
+
+PROC purge :
+
+ IF exists ("permitted tasks")
+ THEN access catalogue ;
+ permit := sequential file (input, "permitted tasks") ;
+ say (""10""13"TASKS :"10""10""13"") ;
+ IF myself < supervisor
+ THEN purge son tasks (brother (supervisor))
+ ELSE purge son tasks (myself)
+ FI
+ FI ;
+ IF exists ("permitted files")
+ THEN permit := sequential file (input, "permitted files") ;
+ say (""10""13"DATEIEN :"10""10""13"") ;
+ purge files
+ FI
+
+ENDPROC purge ;
+
+PROC purge son tasks (TASK CONST father task) :
+
+ TASK VAR actual task := son (father task) ;
+ WHILE NOT is niltask (actual task) REP
+ purge son tasks (actual task) ;
+ IF NOT actual task permitted
+ THEN erase actual task
+ FI ;
+ actual task := brother (actual task)
+ END REP .
+
+erase actual task :
+ say ("""") ; say (task name) ; say ("""") ;
+ IF yes (" loeschen")
+ THEN end (actual task)
+ FI .
+
+actual task permitted :
+ task name := name (actual task) ;
+ reset (permit) ;
+ WHILE NOT eof (permit) REP
+ getline (permit, record) ;
+ IF task name = record
+ THEN LEAVE actual task permitted WITH TRUE
+ FI
+ END REP ;
+ FALSE .
+
+ENDPROC purge son tasks ;
+
+PROC purge files :
+
+ begin list ;
+ get list entry (file name, dummy) ;
+ WHILE file name <> "" REP
+ IF NOT file permitted
+ THEN forget (file name)
+ FI ;
+ get list entry (file name, dummy)
+ END REP .
+
+file permitted :
+ IF file name = "permitted tasks" OR file name = "permitted files"
+ THEN LEAVE file permitted WITH TRUE
+ FI ;
+ reset (permit) ;
+ WHILE NOT eof (permit) REP
+ getline (permit, record) ;
+ IF file name = record
+ THEN LEAVE file permitted WITH TRUE
+ FI
+ END REP ;
+ FALSE .
+
+ENDPROC purge files ;
+
+ENDPACKET purge ;
+
diff --git a/system/referencer b/system/referencer
new file mode 100644
index 0000000..2ee65e4
--- /dev/null
+++ b/system/referencer
@@ -0,0 +1,1077 @@
+(* ------------------- VERSION 10 vom 01.08.86 -------------------- *)
+PACKET referencer errors DEFINES report referencer error:
+
+(* Programm zur Fehlerbehandlung des referencers.
+ Autor: Rainer Hahn *)
+
+TEXT VAR fehlerdummy,
+ message;
+
+PROC report referencer error (INT CONST error nr,
+ INT CONST line nr,
+ TEXT CONST addition):
+
+ einfache fehlermeldung aufbauen;
+ diese auf terminal ausgeben;
+ fehlermeldung in fehlerdatei ausgeben.
+
+einfache fehlermeldung aufbauen:
+ message := "WARNUNG in Zeile ";
+ message CAT text (line nr);
+ message CAT " : ";
+ message CAT simple message.
+
+diese auf terminal ausgeben:
+ line ;
+ putline (message).
+
+fehlermeldung in fehlerdatei ausgeben:
+ note (message);
+ note line ;
+ fehlerdummy := " >>> ";
+ fehlerdummy CAT zusatz;
+ note (fehlerdummy);
+ note line.
+
+simple message:
+ SELECT error nr OF
+ CASE 1: "Text Denoter ueber mehr als eine Zeile"
+ CASE 2: "Nicht beendeter Text Denoter bei Programmende"
+ CASE 3: "Kommentar ueber mehr als eine Zeile"
+ CASE 4: "Nicht beendeter Kommentar bei Programmende"
+ CASE 5: "Ueberdeckung"
+ CASE 6, 9: "Refinement mehrmals eingesetzt"
+ CASE 7, 10: "Refinement wird nicht aufgerufen"
+ CASE 8: "Objekt wird nicht angesprochen"
+ OTHERWISE ""
+ ENDSELECT.
+
+zusatz:
+ SELECT error nr OF
+ CASE 1, 2, 3, 4: "Ueber " + addition + " Zeilen"
+ CASE 5: addition
+ CASE 6, 7, 8: addition
+ CASE 9, 10: addition + " in mindestens einer Prozedur"
+ OTHERWISE "interner Fehler: HRZ Bielefeld benachrichtigen!"
+ END SELECT.
+END PROC report referencer error
+END PACKET referencer errors;
+(************************************************************************)
+
+PACKET name table handling
+ DEFINES NAMETABLE,
+ empty name table,
+ put name,
+ get name,
+ dump table:
+
+(* Programm zur Speicherung von Namen.
+ Autor: Rainer Hahn *)
+
+LET hash table length = 1024,
+ hash table length minus one = 1023,
+ start of name table = 255,
+ name table length = 2000;
+
+TYPE NAMETABLE = STRUCT (INT number of entries,
+ ROW hash table length INT hash table,
+ ROW name table length INT next,
+ ROW name table length TEXT name table);
+
+TEXT VAR dummy, f;
+
+PROC put name (NAMETABLE VAR n, TEXT CONST name, INT VAR pointer):
+ INT VAR errechneter index;
+ hash (name, errechneter index);
+ IF noch kein eintrag
+ THEN gaenzlich neuer eintrag
+ ELSE name in vorhandener kette
+ FI.
+
+noch kein eintrag:
+ n . hash table [errechneter index] = 0.
+
+gaenzlich neuer eintrag:
+ n . hash table [errechneter index] := n . number of entries;
+ neuer eintrag (n, name, pointer).
+
+name in vorhandener kette:
+ INT VAR dieser eintrag :: n. hash table [errechneter index];
+ REP
+ IF name ist vorhanden
+ THEN pointer := dieser eintrag;
+ LEAVE put name
+ ELIF kette zu ende
+ THEN neuer eintrag an vorhandene kette anketten;
+ neuer eintrag (n, name, pointer);
+ LEAVE put name
+ ELSE naechster eintrag in der kette
+ FI
+ END REP.
+
+name ist vorhanden:
+ n . name table [dieser eintrag] = name.
+
+kette zu ende:
+ n . next [dieser eintrag] = 0.
+
+neuer eintrag an vorhandene kette anketten:
+ n . next [dieser eintrag] := n . number of entries.
+
+naechster eintrag in der kette:
+ dieser eintrag := n . next [dieser eintrag].
+END PROC put name;
+
+PROC neuer eintrag (NAMETABLE VAR n, TEXT CONST name, INT VAR pointer):
+ n . name table [n . number of entries] := name;
+ n . next [n . number of entries] := 0;
+ pointer := n . number of entries;
+ n . number of entries INCR 1;
+ IF n . number of entries > name table length
+ THEN errorstop ("volle Namenstabelle")
+ FI
+END PROC neuer eintrag;
+
+PROC hash (TEXT CONST name, INT VAR index) :
+ INT VAR i;
+ index := code (name SUB 1);
+ FOR i FROM 2 UPTO length (name) REP
+ addmult cyclic
+ ENDREP.
+
+addmult cyclic :
+ index INCR index ;
+ IF index > hash table length minus one
+ THEN wrap around
+ FI;
+ index := (index + code (name SUB i)) MOD hash table length.
+
+wrap around :
+ index DECR hash table length minus one
+ENDPROC hash ;
+
+PROC get name (NAMETABLE CONST n, INT CONST index, TEXT VAR t):
+ IF index < n . number of entries AND index >= start of name table
+ THEN t := n . name table [index]
+ ELSE errorstop ("Interner Fehler 1")
+ FI
+END PROC get name;
+
+PROC empty name table (NAMETABLE VAR n):
+INT VAR i;
+ n . number of entries := start of name table;
+ FOR i FROM 1 UPTO hash table length REP
+ n . hash table [i] := 0
+ END REP
+END PROC empty name table;
+
+PROC dump table (NAMETABLE CONST n):
+ line ;
+ put ("Bitte Name der Datei, in die die Namenstabelle gehen soll:");
+ getline (f);
+ line ;
+ file assoziieren;
+ dump namens ketten;
+ zusammenfassung.
+
+file assoziieren:
+ FILE VAR file :: sequential file (output, f).
+
+dump namens ketten:
+ INT VAR i,
+ anz hash eintraege :: 0,
+ kette 3 eintraege :: 0;
+ FOR i FROM 1 UPTO hash table length REP
+ IF n . hash table [i] <> 0
+ THEN anz hash eintraege INCR 1;
+ INT VAR naechster eintrag :: n . hash table [i];
+ dump hash eintrag;
+ ketten eintraege
+ FI
+ END REP.
+
+dump hash eintrag:
+ dummy := text (i);
+ WHILE length (dummy) < 4 REP dummy CAT " " END REP;
+ dummy CAT ": ".
+
+ketten eintraege:
+ INT VAR anz eintraege pro kette :: 0;
+ WHILE naechster eintrag > 0 REP
+ anz eintraege pro kette INCR 1;
+ dummy CAT " ";
+ dummy CAT text (naechster eintrag);
+ dummy CAT " -> ";
+ dummy CAT n . name table [naechster eintrag];
+ naechster eintrag := n . next [naechster eintrag];
+ END REP;
+ IF anz eintraege pro kette > 2
+ THEN kette 3 eintraege INCR 1
+ FI;
+ putline (file, dummy).
+
+zusammenfassung:
+ statistik ueberschrift;
+ anzahl hash eintraege;
+ anzahl namens eintraege;
+ verkettungsfaktor;
+ anzahl laengerer ketten.
+
+statistik ueberschrift:
+ line (file, 2);
+ dummy := " ---------- ";
+ dummy CAT "S T A T I S T I K:";
+ dummy CAT " ---------- ";
+ putline (file, dummy);
+ line (file, 2).
+
+anzahl hash eintraege:
+ dummy := "Anzahl Hash-Eintraege (max. ";
+ dummy CAT text (hash table length);
+ dummy CAT "): ";
+ dummy CAT text (anz hash eintraege);
+ putline (file, dummy).
+
+anzahl namens eintraege:
+ dummy := "Anzahl Namen (max. ";
+ dummy CAT text (name table length - start of name table + 1);
+ dummy CAT "): ";
+ dummy CAT text (n . number of entries - start of name table);
+ putline (file, dummy).
+
+verkettungsfaktor:
+ dummy := "Verkettungsfaktor (Anzahl Namen / Anzahl Ketten): ";
+ dummy CAT text (real (n . number of entries - start of name table) /
+ real (anz hash eintraege));
+ putline (file, dummy).
+
+anzahl laengerer ketten:
+ dummy := "Anzahl Ketten > 2 Eintraege: ";
+ dummy CAT text (kette 3 eintraege);
+ putline (file, dummy).
+END PROC dump table;
+END PACKET name table handling;
+(***************************************************************************)
+
+PACKET scanner DEFINES init scanning,
+ init name table with,
+ dump name table,
+ get name,
+ end scanning,
+ line number,
+ symbol:
+
+(* Programm zum scannen von ELAN-Programmen.
+ Autor: Rainer Hahn *)
+
+FILE VAR eingabe;
+
+DATASPACE VAR ds alt := nilspace,
+ ds neu := nilspace;
+
+BOUND NAMETABLE VAR tabelle;
+
+TEXT VAR zeile,
+ zeichen,
+ dummy;
+
+LET end of program = ""30"",
+ eop = 1,
+ identifier = 2,
+ keyword = 3,
+ delimiter = 4,
+ punkt = 46,
+ doppelpunkt = 58,
+ init symbol = 30,
+ assign symbol = 31;
+
+INT VAR zeilen nr,
+ zeichen pos;
+
+PROC init name table with (TEXT CONST worte):
+INT VAR index;
+ forget (ds alt);
+ ds alt := nilspace;
+ tabelle := dsalt;
+ empty name table (CONCR (tabelle));
+ INT VAR anf :: 1,
+ ende :: pos (worte, ",", 1);
+ WHILE ende > 0 REP
+ dummy := subtext (worte, anf, ende - 1);
+ put name (CONCR (tabelle), dummy, index);
+ anf := ende + 1;
+ ende := pos (worte, ",", ende + 1)
+ END REP;
+ dummy := subtext (worte, anf);
+ put name (CONCR (tabelle), dummy, index)
+END PROC init name table with;
+
+PROC init scanning (TEXT CONST f):
+ IF exists (f)
+ THEN namenstabelle holen;
+ erste zeile lesen
+ ELSE errorstop ("Datei existiert nicht")
+ FI.
+
+namenstabelle holen:
+ forget (ds neu);
+ ds neu := ds alt;
+ tabelle := ds neu.
+
+erste zeile lesen:
+ eingabe := sequential file (input, f);
+ IF eof (eingabe)
+ THEN errorstop ("Datei ist leer")
+ ELSE zeile := "";
+ zeilen nr := 0;
+ zeile lesen;
+ naechstes non blank zeichen
+ FI
+END PROC init scanning;
+
+PROC dump name table:
+ dump table (CONCR (tabelle))
+END PROC dump name table;
+
+PROC end scanning (TEXT CONST f):
+ IF anything noted
+ THEN eingabe := sequential file (modify, f);
+ note edit (eingabe)
+ FI
+END PROC end scanning;
+
+PROC get name (INT CONST index, TEXT VAR t):
+ get name (CONCR (tabelle), index, t)
+END PROC get name;
+
+PROC zeile lesen:
+ getline (eingabe, zeile);
+ zeilen nr INCR 1;
+ cout (zeilen nr);
+ zeichen pos := 0
+END PROC zeile lesen;
+
+PROC naechstes non blank zeichen:
+ REP
+ zeichen pos := pos (zeile, ""33"", ""254"", zeichen pos + 1);
+ IF zeichen pos <> 0
+ THEN zeichen := (zeile SUB zeichen pos);
+ LEAVE naechstes non blank zeichen
+ ELIF eof (eingabe)
+ THEN zeichen := end of program;
+ LEAVE naechstes non blank zeichen
+ ELSE zeile lesen
+ FI
+ END REP.
+END PROC naechstes non blank zeichen;
+
+PROC naechstes zeichen:
+ IF zeichen pos > length (zeile)
+ THEN IF eof (eingabe)
+ THEN zeichen := end of program;
+ LEAVE naechstes zeichen
+ ELSE zeile lesen
+ FI
+ FI;
+ zeichenpos INCR 1;
+ zeichen := zeile SUB zeichenpos
+END PROC naechstes zeichen;
+
+INT PROC line number:
+ IF zeichenpos = pos (zeile, ""33"", ""254"", 1)
+ THEN zeilen nr - 1
+ ELSE zeilen nr
+ FI
+END PROC line number;
+
+PROC symbol (INT VAR symb, type):
+ REP
+ suche naechstes checker symbol
+ END REP.
+
+suche naechstes checker symbol:
+ SELECT code (zeichen) OF
+ CASE 30: (* end of programn *)
+ symb := eop;
+ type := eop;
+ LEAVE symbol
+ CASE 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122:
+ (* small letters *)
+ identifier aufsammeln;
+ put name (CONCR (tabelle), dummy, symb);
+ type := identifier;
+ LEAVE symbol
+ CASE 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: (* large letters *)
+ schluesselwort aufsammeln;
+ put name (CONCR (tabelle), dummy, symb);
+ type := keyword;
+ LEAVE symbol
+ CASE 34: (* " *)
+ skip text denoter
+ CASE 40: (* ( *)
+ IF (zeile SUB zeichen pos + 1) = "*"
+ THEN skip comment
+ ELSE symb := code (zeichen);
+ type := delimiter;
+ naechstes non blank zeichen;
+ LEAVE symbol;
+ FI
+ CASE 58: (* : *)
+ IF (zeile SUB zeichenpos + 1) = "="
+ THEN symb := assign symbol;
+ zeichenpos INCR 1
+ ELIF (zeile SUB zeichenpos + 1) = ":"
+ THEN symb := init symbol;
+ zeichenpos INCR 1
+ ELSE symb := doppelpunkt
+ FI;
+ type := delimiter;
+ naechstes non blank zeichen;
+ LEAVE symbol
+ CASE 48, 49, 50, 51, 52, 53, 54, 55, 56, 57: (* 0 - 9 *)
+ int denoter skippen;
+ IF zeichen = "."
+ THEN naechstes non blank zeichen;
+ IF digit
+ THEN real denoter skippen
+ ELSE symb := punkt;
+ type := delimiter;
+ LEAVE symbol
+ FI
+ FI
+ CASE 41, 44, 46, 59, 61: (* ) , . ; = *)
+ symb := code (zeichen);
+ type := delimiter;
+ naechstes non blank zeichen;
+ LEAVE symbol
+ OTHERWISE naechstes non blank zeichen
+ END SELECT.
+END PROC symbol;
+
+PROC real denoter skippen:
+ int denoter skippen;
+ IF zeichen = "e"
+ THEN naechstes non blank zeichen;
+ int denoter skippen
+ FI
+END PROC real denoter skippen;
+
+PROC int denoter skippen:
+ naechstes non blank zeichen;
+ WHILE zeichen >= "0" AND zeichen <= "9" REP
+ naechstes non blank zeichen
+ ENDREP;
+ zeichenpos DECR 1;
+ naechstes non blank zeichen
+END PROC int denoter skippen;
+
+PROC identifier aufsammeln:
+ dummy := zeichen;
+ REP
+ naechstes non blank zeichen;
+ IF small letter or digit
+ THEN dummy CAT zeichen
+ ELSE LEAVE identifier aufsammeln
+ FI
+ END REP
+END PROC identifier aufsammeln;
+
+PROC schluesselwort aufsammeln:
+ dummy := "";
+ sammle schluesselwort;
+ IF dummy = "END"
+ THEN noch einmal
+ FI.
+
+sammle schluesselwort:
+ WHILE large letter REP
+ dummy CAT zeichen;
+ naechstes zeichen
+ END REP;
+ IF zeichen = " "
+ THEN naechstes non blank zeichen
+ FI.
+
+noch einmal:
+ sammle schluesselwort
+END PROC schluesselwort aufsammeln;
+
+PROC skip text denoter:
+ INT VAR anz zeilen :: 0;
+ zeichen pos := pos (zeile, """", zeichenpos + 1);
+ WHILE zeichen pos = 0 REP
+ naechste zeile einlesen;
+ zeichen pos := pos (zeile, """");
+ END REP;
+ ende text denoter.
+
+ende text denoter:
+ IF anz zeilen > 1
+ THEN report referencer error (1, zeilen nr, text (anz zeilen))
+ FI;
+ naechstes non blank zeichen.
+
+naechste zeile einlesen:
+ IF eof (eingabe)
+ THEN report referencer error (2, zeilen nr, text (anz zeilen));
+ zeichen := end of program;
+ LEAVE skip text denoter
+ ELSE zeile lesen;
+ anz zeilen INCR 1
+ FI.
+END PROC skip text denoter;
+
+PROC skip comment:
+ INT VAR anz zeilen :: 0;
+ zeichen pos := pos (zeile, "*)", zeichenpos + 2);
+ WHILE zeichen pos = 0 REP
+ naechste zeile einlesen;
+ zeichen pos := pos (zeile, "*)");
+ END REP;
+ ende comment.
+
+ende comment:
+ IF anz zeilen > 1
+ THEN report referencer error (3, zeilen nr, text (anz zeilen))
+ FI;
+ zeichen pos INCR 2;
+ naechstes non blank zeichen.
+
+naechste zeile einlesen:
+ IF eof (eingabe)
+ THEN report referencer error (4, zeilen nr, text (anz zeilen));
+ zeichen := end of program;
+ LEAVE skip comment
+ ELSE zeile lesen;
+ anz zeilen INCR 1
+ FI.
+END PROC skip comment;
+
+BOOL PROC small letter or digit:
+ (zeichen >= "0" AND zeichen <= "9") OR (zeichen >= "a" AND zeichen <= "z")
+END PROC small letter or digit;
+
+BOOL PROC small letter:
+ zeichen >= "a" AND zeichen <= "z"
+END PROC small letter;
+
+BOOL PROC large letter:
+ zeichen >= "A" AND zeichen <= "Z"
+END PROC large letter;
+
+BOOL PROC digit:
+ zeichen >= "0" AND zeichen <= "9"
+END PROC digit;
+END PACKET scanner;
+(*************************************************************************)
+PACKET referencer2 DEFINES referencer:
+
+(* Programm fuer den 'referencer'
+ Autor: Rainer Hahn *)
+
+INT VAR symb,
+ typ,
+ max index;
+
+TEXT VAR dummy,
+ dummy2,
+ name;
+
+DATASPACE VAR ds;
+
+BOUND ROW max TEXT VAR liste;
+
+FILE VAR f;
+
+BOOL VAR initialisiert :: FALSE,
+ symbol bereits geholt,
+ globale deklarationen;
+
+LET max = 1751,
+ global text = "<--G",
+ local text = "<--L",
+ refinement text = "<--R",
+ procedure text = "<--P",
+ eop = 1,
+ identifier = 2,
+ keyword = 3,
+ init symbol = 30,
+ assign symbol = 31,
+ klammer auf = 40,
+ klammer zu = 41,
+ komma = 44,
+ punkt = 46,
+ doppelpunkt = 58,
+ semikolon = 59,
+ proc symbol = 255,
+ end proc symbol = 256,
+ packet symbol = 257,
+ end packet symbol = 258,
+ type symbol = 259,
+ var symbol = 260,
+ const symbol = 261,
+ let symbol = 262,
+ leave symbol = 263,
+ op symbol = 264,
+ endop symbol = 265,
+ endif symbol = 266,
+ fi symbol = 266;
+
+PROC referencer:
+ referencer (last param)
+END PROC referencer;
+
+PROC referencer (TEXT CONST check file):
+ referencer (check file, check file + ".r")
+END PROC referencer;
+
+PROC referencer (TEXT CONST check file, dump file):
+ IF exists (check file)
+ THEN dump file ggf loeschen
+ ELSE errorstop ("Eingabe-Datei nicht vorhanden")
+ FI;
+ disable stop;
+ start referencing (check file, dump file);
+ forget (ds);
+ enable stop.
+
+dump file ggf loeschen:
+ IF exists (dump file)
+ THEN forget (dump file, quiet)
+ FI.
+END PROC referencer;
+
+PROC start referencing (TEXT CONST check file, dump file):
+ enable stop;
+ ueberschrift;
+ initialisierung;
+ verkuerzte syntax analyse;
+ line ;
+ in dump file kopieren (dump file);
+ line ;
+ end scanning (check file).
+
+ueberschrift:
+ page;
+ put ("REFERENCER:");
+ put (check file);
+ put ("->");
+ putline (dump file).
+
+initialisierung:
+ IF NOT initialisiert
+ THEN init name table with
+("PROC,ENDPROC,PACKET,ENDPACKET,TYPE,VAR,CONST,LET,LEAVE,OP,ENDOP,ENDIF,FI");
+ initialisiert := TRUE
+ FI;
+ ds := nilspace;
+ liste := ds;
+ max index := end op symbol;
+ dummy := checkfile.
+
+verkuerzte syntax analyse:
+ globale deklarationen := TRUE;
+ line ;
+ init scanning (dummy);
+ symbol bereits geholt := FALSE;
+ REP
+ IF symbol bereits geholt
+ THEN symbol bereits geholt := FALSE
+ ELSE symbol (symb, typ)
+ FI;
+ IF typ = keyword
+ THEN nach schluesselwort verarbeiten
+ ELIF symb = punkt
+ THEN ggf refinement aufnehmen
+ ELIF typ = identifier
+ THEN identifier aufnehmen und ggf aktuelle parameter liste
+ FI
+ UNTIL typ = eop ENDREP.
+
+identifier aufnehmen und ggf aktuelle parameter liste:
+ in die liste (symb, "");
+ symbol (symb, typ);
+ IF symb = klammer auf
+ THEN aktuelle parameter aufnehmen
+ ELSE symbol bereits geholt := TRUE
+ FI.
+
+nach schluesselwort verarbeiten:
+ SELECT symb OF
+ CASE let symbol:
+ let deklarationen aufsammeln
+ CASE packet symbol:
+ namen des interface aufsammeln
+ CASE end packet symbol:
+ skip naechstes symbol
+ CASE var symbol, const symbol:
+ datenobjekt deklaration aufnehmen
+ CASE proc symbol:
+ globale deklarationen := FALSE;
+ prozedur name und ggf parameter aufsammeln
+ CASE end proc symbol:
+ globale deklarationen := TRUE;
+ skip naechstes symbol
+ CASE op symbol:
+ globale deklarationen := FALSE;
+ operatornamen skippen und ggf parameter aufsammeln
+ CASE end op symbol:
+ globale deklarationen := TRUE;
+ skip until (semikolon)
+ CASE type symbol:
+ namen der typ definition aufsammeln
+ CASE leave symbol:
+ skip naechstes symbol
+ OTHERWISE:
+ ENDSELECT.
+
+skip naechstes symbol:
+ symbol (symb, typ).
+END PROC start referencing;
+
+PROC aktuelle parameter aufnehmen:
+ REP
+ symbol (symb, typ);
+ IF typ = identifier
+ THEN in die liste (symb, "")
+ FI
+ UNTIL symb = klammer zu END REP.
+END PROC aktuelle parameter aufnehmen;
+
+PROC ggf refinement aufnehmen:
+ symbol (symb, typ);
+ symbol bereits geholt := TRUE;
+ WHILE typ = identifier REP
+ doppelpunkt oder selektor
+ END REP.
+
+doppelpunkt oder selektor:
+ INT CONST letzter id :: symb;
+ symbol (symb, typ);
+ IF symb = doppelpunkt
+ THEN in die liste (letzter id, refinement text);
+ LEAVE ggf refinement aufnehmen
+ ELSE in die liste (letzter id, "");
+ IF symb = punkt
+ THEN symbol (symb, typ)
+ ELSE LEAVE ggf refinement aufnehmen
+ FI
+ FI
+END PROC ggf refinement aufnehmen;
+
+PROC namen des interface aufsammeln:
+ packet name ueberspringen;
+ namen der schnittstelle aufsammeln.
+
+packet name ueberspringen:
+ symbol (symb, typ).
+
+namen der schnittstelle aufsammeln:
+ REP
+ symbol (symb, typ);
+ IF typ = identifier
+ THEN in die liste (symb, "")
+ FI
+ UNTIL symb = doppelpunkt END REP.
+END PROC namen des interface aufsammeln;
+
+PROC let deklarationen aufsammeln:
+ REP
+ symbol (symb, typ);
+ IF typ = identifier
+ THEN let name aufnehmen
+ ELIF typ = keyword
+ THEN bis zum komma oder semikolon
+ FI;
+ UNTIL symb = semikolon END REP.
+
+let name aufnehmen:
+ IF globale deklarationen
+ THEN in die liste (symb, global text)
+ ELSE in die liste (symb, "")
+ FI;
+ REP
+ symbol (symb, typ);
+ IF typ = identifier
+ THEN in die liste (symb, "")
+ FI
+ UNTIL symb = komma OR symb = semikolon END REP.
+END PROC let deklarationen aufsammeln;
+
+PROC namen der typ definition aufsammeln:
+ REP
+ symbol (symb, typ);
+ bis zum komma oder semikolon
+ UNTIL symb = semikolon END REP
+END PROC namen der typ definition aufsammeln;
+
+PROC bis zum komma oder semikolon:
+ INT VAR anz klammern :: 0;
+ REP
+ symbol (symb, typ); (* fields aufnehmen weggelassen *)
+ IF symb = klammer auf
+ THEN anz klammern INCR 1
+ ELIF symb = klammer zu
+ THEN anz klammern DECR 1
+ FI
+ UNTIL (symb = komma AND anz klammern = 0) OR symb = semikolon ENDREP.
+END PROC bis zum komma oder semikolon;
+
+PROC datenobjekt deklaration aufnehmen:
+ symbol (symb, typ);
+ REP
+ IF globale deklarationen
+ THEN in die liste (symb, global text)
+ ELSE in die liste (symb, local text)
+ FI;
+ skip ggf initialisierung;
+ IF symb = komma
+ THEN symbol (symb, typ)
+ FI
+ UNTIL symb = semikolon OR symb = punkt END REP.
+
+skip ggf initialisierung:
+ symbol (symb, typ);
+ IF symb = init symbol OR symb = assign symbol
+ THEN initialisierung skippen
+ FI.
+
+initialisierung skippen:
+ INT VAR anz klammern :: 0;
+ REP
+ INT CONST vorheriges symbol :: symb,
+ vorheriger typ :: typ;
+ symbol (symb, typ);
+ IF symb = klammer auf
+ THEN anz klammern INCR 1;
+ IF vorheriger typ = identifier
+ THEN in die liste (vorheriges symbol, "")
+ FI
+ ELIF symb = klammer zu
+ THEN anz klammern DECR 1;
+ IF vorheriger typ = identifier
+ THEN in die liste (vorheriges symbol, "")
+ FI
+ ELIF vorheriger typ = identifier AND symb = doppelpunkt
+ THEN in die liste (vorheriges symbol, refinement text);
+ LEAVE datenobjekt deklaration aufnehmen
+ ELIF vorheriger typ = identifier
+ THEN in die liste (vorheriges symbol, "")
+ FI
+ UNTIL (symb = komma AND anz klammern = 0)
+ OR symb = semikolon OR symb = end proc symbol OR
+ symb = end op symbol OR symb = endif symbol OR symb = fi symbol
+ END REP.
+END PROC datenobjekt deklaration aufnehmen;
+
+PROC prozedur name und ggf parameter aufsammeln:
+ prozedurname aufsammeln;
+ symbol (symb, typ);
+ IF symb <> doppelpunkt
+ THEN formale parameter aufsammeln
+ FI.
+
+prozedurname aufsammeln:
+ symbol (symb, typ);
+ in die liste (symb, procedure text).
+END PROC prozedurname und ggf parameter aufsammeln;
+
+PROC operatornamen skippen und ggf parameter aufsammeln:
+ symbol (symb, typ);
+ IF symb <> doppelpunkt
+ THEN formale parameter aufsammeln
+ FI
+END PROC operatornamen skippen und ggf parameter aufsammeln;
+
+PROC formale parameter aufsammeln:
+ REP
+ symbol (symb, typ);
+ IF typ = identifier
+ THEN in die liste (symb, local text);
+ FI
+ UNTIL symb = doppelpunkt END REP
+END PROC formale parameter aufsammeln;
+
+PROC skip until (INT CONST zeichencode):
+ skip until (zeichencode, 0)
+END PROC skip until;
+
+PROC skip until (INT CONST z1, z2):
+ REP
+ symbol (symb, typ)
+ UNTIL symb = z1 OR symb = z2 END REP
+END PROC skip until;
+
+PROC in die liste (INT CONST index, TEXT CONST zusatz):
+ IF index > max index
+ THEN listenelemente initialisieren;
+ FI;
+ IF aktueller eintrag = ""
+ THEN namens eintrag
+ FI;
+ aktueller eintrag CAT " ";
+ aktueller eintrag CAT text (line number);
+ aktueller eintrag CAT zusatz.
+
+aktueller eintrag:
+ liste [index].
+
+listenelemente initialisieren:
+ INT VAR i;
+ FOR i FROM max index + 1 UPTO index REP
+ liste [i] := ""
+ END REP;
+ max index := index.
+
+namens eintrag:
+ get name (index, aktueller eintrag);
+ WHILE length (aktueller eintrag) < 15 REP
+ aktueller eintrag CAT " "
+ END REP;
+ aktueller eintrag CAT ":".
+END PROC in die liste;
+
+TEXT VAR zeile;
+
+PROC in dump file kopieren (TEXT CONST dump file):
+ putline ("Ausgabedatei erstellen");
+ f := sequential file (output, dump file);
+ INT VAR i;
+ kopieren und ggf fehlermeldung;
+ modify (f);
+ ggf sortieren;
+ zeile ggf aufspalten;
+ modify (f);
+ to line (f, 1).
+
+kopieren und ggf fehlermeldung:
+ FOR i FROM fi symbol UPTO max index REP
+ cout (i);
+ zeile := liste [i];
+ IF zeile <> ""
+ THEN ausgabe der referenz und ggf fehlermeldung
+ FI
+ ENDREP.
+
+ausgabe der referenz und ggf fehlermeldung:
+ putline (f, zeile);
+ ggf referencer fehlermeldung.
+
+ggf sortieren:
+ IF yes (dump file + " sortieren")
+ THEN sort (dump file);
+ FI.
+
+zeile ggf aufspalten:
+ i := 0;
+ to line (f, 1);
+ WHILE NOT eof (f) REP
+ i INCR 1;
+ cout (i);
+ read record (f, zeile);
+ ggf aufspalten
+ END REP.
+
+ggf aufspalten:
+INT VAR anf :: 1, ende :: pos (zeile, " ", 72);
+ IF ende > 0
+ THEN dummy := subtext (zeile, 1, ende - 1);
+ write record (f, dummy);
+ spalte bis restzeile auf;
+ dummy CAT subtext (zeile, anf);
+ write record (f, dummy);
+ FI;
+ down (f).
+
+spalte bis restzeile auf:
+ REP
+ dummy := " ";
+ anf := ende + 1;
+ ende := pos (zeile, " ", ende + 55);
+ down (f);
+ insert record (f);
+ IF ende <= 0
+ THEN LEAVE spalte bis restzeile auf
+ FI;
+ dummy CAT subtext (zeile, anf, ende - 1);
+ write record (f, dummy);
+ END REP.
+END PROC in dump file kopieren;
+
+PROC ggf referencer fehlermeldung:
+ name := subtext (zeile, 1, min( pos(zeile, " "), pos(zeile, ":")) - 1);
+ dummy := subtext (zeile, pos (zeile, ": ") + 2);
+ ueberdeckungs ueberpruefung;
+ not used ueberpruefung;
+ IF pos (dummy, "R") > 0
+ THEN refinement mehr als zweimal verwendet
+ FI.
+
+ueberdeckungs ueberpruefung:
+ IF pos (dummy, global text) > 0 AND pos (dummy, local text) > 0
+ THEN dummy2 := "und Zeile ";
+ dummy2 CAT text (nr (pos (dummy, local text)));
+ dummy2 CAT ": ";
+ dummy2 CAT name;
+ report referencer error
+ (5, nr (pos (dummy, global text)), dummy2)
+ FI.
+
+not used ueberpruefung:
+ IF pos (dummy, " ") = 0 AND
+ (pos (dummy, global text) > 0 OR pos (dummy, local text) > 0 OR
+ pos (dummy, refinement text) > 0)
+ THEN not used fehlermeldung
+ FI.
+
+not used fehlermeldung:
+ report referencer error
+ (8, nr (length (dummy) - length (local text) + 1), name).
+
+refinement mehr als zweimal verwendet:
+ INT VAR refinement deklarationen :: 0,
+ refinement aufrufe :: 0,
+ anf :: 1;
+ WHILE pos (dummy,"R", anf) > 0 REP
+ refinement deklarationen INCR 1;
+ anf := pos (dummy, "R", anf) + 1
+ END REP;
+ anf := 1;
+ WHILE pos (dummy, " ", anf) > 0 REP
+ refinement aufrufe INCR 1;
+ anf := pos (dummy, " ", anf) + 1
+ END REP;
+ IF refinement deklarationen = 1
+ THEN IF refinement aufrufe > 1
+ THEN report referencer error
+ (6, nr (pos (dummy, refinement text)), name)
+ ELIF refinement aufrufe = 0
+ THEN report referencer error
+ (7, nr (pos (dummy, refinement text)), name)
+ FI
+ ELIF refinement deklarationen > 1
+ THEN IF 2 * refinement deklarationen - 1 > refinement aufrufe
+ THEN report referencer error (9, 0, name)
+ ELIF 2 * refinement deklarationen - 1 < refinement aufrufe
+ THEN report referencer error (10, 0, name)
+ FI
+ FI.
+END PROC ggf referencer fehlermeldung;
+
+INT PROC nr (INT CONST ende):
+ INT VAR von :: ende - 1;
+ WHILE von > 0 AND ((dummy SUB von) >= "0" AND (dummy SUB von) <= "9") REP
+ von DECR 1
+ END REP;
+ int (subtext (dummy, von + 1, ende - 1))
+END PROC nr;
+END PACKET referencer2;
+
+(*
+REP
+ referencer ("ref fehler");
+ edit ("ref fehler.r");
+UNTIL no ("nochmal") END REP*)
+
diff --git a/system/reporter b/system/reporter
new file mode 100644
index 0000000..4febc32
--- /dev/null
+++ b/system/reporter
@@ -0,0 +1,531 @@
+(* ------------------- VERSION 12 vom 06.08.86 -------------------- *)
+PACKET reporter routines DEFINES generate counts,
+ count on,
+ count off,
+ generate reports,
+ eliminate reports,
+ assert,
+ report on,
+ report off,
+ report:
+
+(* Programm zur Ablaufverfolgung von ELAN Programmen. Das Programm
+ verfolgt Prozedur- und Refinementaufrufe ('trace') und erstellt
+ eine Haeufigkeitszaehlung ('count') und beachtet 'assertions'.
+ Autor: Rainer Hahn *)
+
+FILE VAR input file;
+
+INT VAR zeilen nr,
+ type;
+
+TEXT VAR zeile,
+ dummy,
+ dummy1,
+ symbol;
+
+LET quadro fis = "####",
+ triple fis = "###",
+ double fis = "##",
+ tag = 1,
+ bold = 2;
+
+DATASPACE VAR ds := nilspace;
+BOUND ROW max STRUCT (INT anzahl, BOOL proc) VAR zaehlwerk;
+
+LET max = 3000;
+
+(******************* gen report-Routinen ******************************)
+
+PROC generate reports:
+ generate reports (last param)
+END PROC generate reports;
+
+PROC generate reports (TEXT CONST name):
+ disable stop;
+ gen trace statements (name);
+ IF is error AND error message = "ende"
+ THEN clear error;
+ last param (name)
+ FI;
+ to line (input file, 1);
+ enable stop.
+END PROC generate reports;
+
+PROC gen trace statements (TEXT CONST name):
+ enable stop;
+ IF exists (name)
+ THEN input file := sequential file (modify, name)
+ ELSE errorstop ("input file does not exist")
+ FI;
+ input file modifizieren
+END PROC gen trace statements;
+
+(*************************** Test file modifizieren *****************)
+
+PROC input file modifizieren:
+ zeilen nr := 1;
+ to line (input file, 1);
+ col (input file, 1);
+ REP
+ lese zeile;
+ IF triple fis symbol
+ THEN wandele in quadro fis
+ FI;
+ IF proc oder op symbol
+ THEN verarbeite operator oder prozedurkopf
+ ELIF refinement symbol
+ THEN verarbeite ggf refinements
+ FI;
+ vorwaerts
+ END REP.
+
+triple fis symbol:
+ pos (zeile, triple fis) > 0 AND
+ (pos (zeile, triple fis) <> pos (zeile, quadro fis)).
+
+wandele in quadro fis:
+ change all (zeile, triple fis, quadro fis);
+ write record (input file, zeile).
+
+proc oder op symbol:
+ pos (zeile, "PROC") > 0 OR pos (zeile, "OP") > 0.
+
+verarbeite operator oder prozedurkopf:
+ scan (zeile);
+ symbol lesen;
+ IF symbol = "PROC" OR symbol = "OP"
+ THEN
+ ELIF symbol = "END"
+ THEN LEAVE verarbeite operator oder prozedurkopf
+ ELIF type = bold
+ THEN next symbol (symbol, type);
+ IF NOT (symbol = "PROC" OR symbol = "OP")
+ THEN LEAVE verarbeite operator oder prozedurkopf
+ FI
+ ELSE LEAVE verarbeite operator oder prozedurkopf
+ FI;
+ scanne kopf;
+ insertiere trace anweisung.
+
+scanne kopf:
+ dummy := double fis;
+ dummy CAT "report(""";
+ dummy CAT text (line no (input file) + 1);
+ dummy CAT ": ";
+ dummy CAT symbol; (* PROC oder OP *)
+ dummy CAT " ";
+ symbol lesen;
+ dummy CAT symbol;
+ fuege bis namens ende an;
+ dummy CAT " ";
+ ueberlese ggf parameterliste.
+
+fuege bis namens ende an:
+ REP
+ symbol lesen;
+ IF symbol = "(" OR symbol = ":"
+ THEN LEAVE fuege bis namensende an
+ FI;
+ dummy CAT symbol
+ END REP.
+
+ueberlese ggf parameterliste:
+ WHILE symbol <> ":" REP
+ symbol lesen
+ END REP.
+
+insertiere trace anweisung:
+ WHILE pos (zeile, ":") = 0 REP
+ vorwaerts;
+ lese zeile
+ END REP;
+ schreibe zeile mit report statement.
+
+refinement symbol:
+ INT CONST point pos := pos (zeile, ".") ;
+ point pos > 0 AND point pos >= length (zeile) - 1.
+
+verarbeite ggf refinements:
+ ueberlies leere zeilen ;
+ IF ist wirklich refinement
+ THEN insertiere report fuer refinement
+ FI .
+
+ueberlies leere zeilen :
+ REP
+ vorwaerts;
+ lese zeile
+ UNTIL pos (zeile, ""33"", ""254"", 1) > 0 PER .
+
+ist wirklich refinement :
+ scan (zeile) ;
+ next symbol (symbol, type) ;
+ next symbol (symbol) ;
+ symbol = ":" AND type = tag .
+
+insertiere report fuer refinement:
+ dummy := double fis;
+ dummy CAT "report("" ";
+ dummy CAT text (line no (input file) + 1);
+ dummy CAT ": ";
+ dummy1 := subtext (zeile, 1, pos (zeile, ":") - 1);
+ dummy CAT dummy1;
+ schreibe zeile mit report statement
+END PROC input file modifizieren;
+
+PROC schreibe zeile mit report statement:
+ dummy CAT """);";
+ dummy CAT double fis;
+ IF doppelpunkt steht am ende der zeile
+ THEN vorwaerts;
+ insert record (input file);
+ write record (input file, dummy)
+ ELSE insert char (dummy, ":", 1);
+ change (zeile, ":", dummy);
+ write record (input file, zeile)
+ FI.
+
+doppelpunkt steht am ende der zeile:
+ (zeile SUB length (zeile)) = ":" OR (zeile SUB length (zeile) - 1) = ":".
+END PROC schreibe zeile mit report statement;
+
+PROC symbol lesen:
+ next symbol (symbol, type);
+ IF ende der zeile gescannt
+ THEN vorwaerts;
+ lese zeile;
+ continue scan (zeile);
+ next symbol (symbol, type)
+ FI.
+
+ende der zeile gescannt:
+ type >= 7.
+END PROC symbol lesen;
+
+PROC vorwaerts:
+ IF eof (input file)
+ THEN errorstop ("ende")
+ FI;
+ down (input file);
+ IF eof (input file)
+ THEN errorstop ("ende")
+ FI
+END PROC vorwaerts;
+
+PROC lese zeile:
+ read record (input file, zeile);
+ cout (zeilen nr);
+ zeilen nr INCR 1
+END PROC lese zeile;
+
+(************************ eliminate reports-Routinen ******************)
+
+PROC eliminate reports:
+ eliminate reports (last param)
+END PROC eliminate reports;
+
+PROC eliminate reports (TEXT CONST name):
+ disable stop;
+ eliminate statements (name);
+ IF is error AND error message = "ende"
+ THEN clear error;
+ last param (name)
+ FI;
+ to line (input file, 1);
+ enable stop.
+END PROC eliminate reports;
+
+PROC eliminate statements (TEXT CONST name):
+ enable stop;
+ IF exists (name)
+ THEN input file := sequential file (modify, name)
+ ELSE errorstop ("input file does not exist")
+ FI;
+ statements entfernen.
+
+statements entfernen:
+ to line (input file, 1);
+ col (input file, 1);
+ zeilen nr := 1;
+ WHILE NOT eof (input file) REP
+ lese zeile;
+ IF pos (zeile, double fis) > 0
+ THEN eliminiere zeichenketten in dieser zeile
+ ELSE vorwaerts
+ FI
+ END REP.
+
+eliminiere zeichenketten in dieser zeile:
+ INT VAR anfang := pos (zeile, double fis);
+ WHILE es ist noch etwas zu eliminieren REP
+ IF es ist ein quadro fis
+ THEN wandele es in ein triple fis
+ ELIF es ist ein triple fis
+ THEN lass diese sequenz stehen
+ ELSE entferne zeichenkette
+ FI
+ END REP;
+ IF zeile ist jetzt leer
+ THEN delete record (input file)
+ ELSE write record (input file, zeile);
+ vorwaerts
+ FI.
+
+es ist noch etwas zu eliminieren:
+ anfang > 0.
+
+es ist ein quadro fis:
+ pos (zeile, quadro fis, anfang) = anfang.
+
+wandele es in ein triple fis:
+ delete char (zeile, anfang);
+ anfang := pos (zeile, double fis, anfang + 3).
+
+es ist ein triple fis:
+ pos (zeile, triple fis, anfang) = anfang.
+
+lass diese sequenz stehen:
+ anfang := pos (zeile, triple fis, anfang + 1) + 3.
+
+entferne zeichenkette:
+ INT VAR end := pos (zeile, double fis, anfang+2) ;
+ IF end > 0
+ THEN change (zeile, anfang, end + 1, "");
+ anfang := pos (zeile, double fis, anfang)
+ ELSE anfang := pos (zeile, double fis, anfang+2)
+ FI .
+
+zeile ist jetzt leer:
+ pos (zeile, ""33"", ""254"", 1) = 0.
+END PROC eliminate statements;
+
+(********************** Trace-Routinen *******************************)
+
+FILE VAR trace file;
+
+BOOL VAR zaehlwerk initialisiert :: FALSE,
+ trace on,
+ haeufigkeit on;
+
+PROC report (TEXT CONST message):
+ IF exists ("TRACE")
+ THEN
+ ELSE trace on := TRUE;
+ haeufigkeit on := FALSE;
+ FI;
+ BOOL CONST ist prozedur ::
+ pos (message, "PROC") > 0 OR pos (message, "OP") > 0;
+ trace file := sequential file (modify, "TRACE");
+ IF lines (trace file) <= 0
+ THEN insert record (trace file);
+ write record (trace file, "")
+ ELSE to line (trace file, lines (trace file));
+ read record (trace file, dummy);
+ IF dummy <> ""
+ THEN down (trace file);
+ insert record (trace file);
+ write record (trace file, "")
+ FI
+ FI;
+ IF trace on
+ THEN write record (trace file, message);
+ down (trace file);
+ insert record (trace file);
+ write record (trace file, "")
+ FI;
+ IF haeufigkeit on
+ THEN haeufigkeits zaehlung
+ FI.
+
+haeufigkeits zaehlung:
+ hole zeilen nr;
+ zaehle mit.
+
+hole zeilen nr:
+ INT CONST von pos :: pos (message, ""33"", ""254"", 1);
+ zeilen nr :=
+ int (subtext (message, von pos, pos (message, ":", von pos + 1) - 1)).
+
+zaehle mit:
+ IF last conversion ok AND zeilen nr > 0 AND zeilen nr <= max
+ THEN zaehlwerk [zeilen nr] . anzahl INCR 1;
+ zaehlwerk [zeilen nr] . proc := ist prozedur
+ FI
+END PROC report;
+
+PROC report (TEXT CONST message, INT CONST value):
+ report (message, text (value))
+END PROC report;
+
+PROC report (TEXT CONST message, REAL CONST value):
+ report (message, text (value))
+END PROC report;
+
+PROC report (TEXT CONST message, TEXT CONST value):
+ dummy1 := message;
+ dummy1 CAT ": ";
+ dummy1 CAT value;
+ report (dummy1)
+END PROC report;
+
+PROC report (TEXT CONST message, BOOL CONST value):
+ dummy1 := message;
+ dummy1 CAT ": ";
+ IF value
+ THEN dummy1 CAT "TRUE"
+ ELSE dummy1 CAT "FALSE"
+ FI;
+ report (dummy1)
+END PROC report;
+
+PROC report on:
+ trace on := TRUE;
+ dummy1 := "REPORT ---> ON";
+ report (dummy1)
+END PROC report on;
+
+PROC report off:
+ dummy1 := "REPORT ---> OFF";
+ report (dummy1);
+ trace on := FALSE;
+END PROC report off;
+
+PROC assert (BOOL CONST value):
+ assert ("", value)
+END PROC assert;
+
+PROC assert (TEXT CONST message, BOOL CONST value):
+ dummy1 := "ASSERTION:";
+ dummy1 CAT message;
+ dummy1 CAT " ---> ";
+ IF value
+ THEN dummy1 CAT "TRUE"
+ ELSE line;
+ put ("ASSERTION:");
+ put (message);
+ put ("---> FALSE");
+ line;
+ IF yes ("weiter")
+ THEN dummy1 CAT "FALSE"
+ ELSE errorstop ("assertion failed")
+ FI
+ FI;
+ report (dummy1)
+END PROC assert;
+
+(************************** haeufigkeits-zaehlung ****************)
+
+PROC count on:
+ report ("COUNT ---> ON");
+ haeufigkeit on := TRUE;
+ initialisiere haeufigkeit.
+
+initialisiere haeufigkeit:
+ INT VAR i;
+ forget (ds);
+ ds := nilspace;
+ zaehlwerk initialisiert := TRUE;
+ zaehlwerk := ds;
+ FOR i FROM 1 UPTO max REP
+ zaehlwerk [i] . anzahl := 0
+ END REP
+END PROC count on;
+
+PROC count off:
+ report ("COUNT ---> OFF");
+ haeufigkeit on := FALSE
+END PROC count off;
+
+PROC generate counts:
+ generate counts (last param)
+END PROC generate counts;
+
+PROC generate counts (TEXT CONST name):
+ disable stop;
+ insert counts (name);
+ last param (name);
+ to line (input file, 1);
+ enable stop.
+END PROC generate counts;
+
+PROC insert counts (TEXT CONST name):
+ enable stop;
+ IF exists (name)
+ THEN input file := sequential file (modify, name);
+ col (input file, 1)
+ ELSE errorstop ("input file does not exist")
+ FI;
+ IF NOT zaehlwerk initialisiert
+ THEN errorstop ("count nicht eingeschaltet")
+ FI;
+ counts insertieren;
+ dataspace loeschen;
+ statistik ausgeben.
+
+counts insertieren:
+ REAL VAR gesamt aufrufe :: 0.0,
+ proc aufrufe :: 0.0,
+ andere aufrufe :: 0.0;
+ zeilen nr := 1;
+ WHILE zeilen nr <= lines (input file) REP
+ cout (zeilen nr);
+ IF zaehlwerk [zeilen nr] . anzahl > 0
+ THEN anzahl aufrufe in die eingabe zeile einfuegen;
+ aufrufe mitzaehlen
+ FI;
+ zeilen nr INCR 1
+ END REP.
+
+anzahl aufrufe in die eingabe zeile einfuegen:
+ to line (input file, zeilen nr);
+ read record (input file, zeile);
+ dummy := double fis;
+ dummy CAT text (zaehlwerk [zeilen nr] . anzahl);
+ dummy CAT double fis;
+ change (zeile, 1, 0, dummy);
+ write record (input file, zeile).
+
+aufrufe mitzaehlen:
+ gesamt aufrufe INCR real (zaehlwerk [zeilen nr] . anzahl);
+ IF zaehlwerk [zeilen nr] . proc
+ THEN proc aufrufe INCR real (zaehlwerk [zeilen nr] . anzahl)
+ ELSE andere aufrufe INCR real (zaehlwerk [zeilen nr] . anzahl)
+ FI.
+
+dataspace loeschen:
+ zaehlwerk initialisiert := FALSE;
+ forget (ds).
+
+statistik ausgeben:
+ line (2);
+ put ("Anzahl der Gesamtaufrufe:");
+ ggf int put (gesamt aufrufe);
+ line;
+ put ("davon:");
+ line;
+ ggf int put (proc aufrufe); put ("Prozeduren oder Operatoren");
+ line;
+ ggf int put (andere aufrufe); put ("Refinements und andere");
+ line.
+END PROC insert counts;
+
+PROC ggf int put (REAL CONST wert):
+ IF wert >= real (maxint)
+ THEN put (wert)
+ ELSE put (int (wert))
+ FI
+END PROC ggf int put;
+END PACKET reporter routines;
+(*
+REP
+ IF exists ("rep fehler")
+ THEN copy ("rep fehler", "zzz")
+ ELSE errorstop ("rep fehler exisitiert nicht")
+ FI;
+ generate reports ("zzz");
+ edit("zzz");
+ forget ("zzz")
+UNTIL no ("nochmal") END REP;
+edit("reporter")*)
+
diff --git a/system/scheduler b/system/scheduler
new file mode 100644
index 0000000..cba48e0
--- /dev/null
+++ b/system/scheduler
@@ -0,0 +1,420 @@
+
+PACKET std schedule strategy DEFINES (* Autor: J.Liedtke *)
+ (* Stand: 15.10.82 *)
+ strategic decision :
+
+
+PROC strategic decision
+ (INT CONST foreground workers, background workers,
+ REAL CONST fore cpu load, back cpu load, paging load,
+ INT VAR lowest activation prio, max background tasks) :
+
+ IF no background permitted
+ THEN lowest activation prio := 0 ;
+ max background tasks := 0
+ ELSE lowest activation prio := 10 ;
+ select max background tasks
+ FI .
+
+no background permitted :
+ foreground workers > 0 AND fore cpu load > 0.03 .
+
+select max background tasks :
+ IF fore cpu load > 0.01
+ THEN max background tasks := 1
+ ELIF paging load < 0.07
+ THEN max background tasks := 3
+ ELIF paging load < 0.15
+ THEN max background tasks := 2
+ ELSE max background tasks := 1
+ FI .
+
+ENDPROC strategic decision ;
+
+ENDPACKET std schedule strategy ;
+
+
+ (* Autor: J.Liedtke*)
+PACKET eumelmeter DEFINES (* Stand: 11.10.83 *)
+
+ init log ,
+ log :
+
+
+LET snapshot interval = 590.0 ;
+
+REAL VAR next snapshot time ,
+ time , timex ,
+ paging wait , paging wait x ,
+ paging busy , paging busy x ,
+ fore cpu , fore cpu x ,
+ back cpu , back cpu x ,
+ system cpu , system cpu x ,
+ delta t ;
+INT VAR storage max, used ;
+TEXT VAR record ;
+
+PROC init log :
+
+ time := clock (1) ;
+ paging wait := clock (2) ;
+ paging busy := clock (3) ;
+ fore cpu := clock (4) ;
+ back cpu := clock (5) ;
+ system cpu := clock (6) ;
+ next snapshot time := time + snapshot interval
+
+ENDPROC init log ;
+
+PROC log (INT CONST active terminals, active background) :
+
+ new snapshot time if was clock reset ;
+ IF clock (1) >= next snapshot time
+ THEN save values ;
+ get new values ;
+ create stat record ;
+ put log (record) ;
+ define next snapshot time
+ FI .
+
+new snapshot time if was clock reset :
+ IF clock (1) < next snapshot time - snapshot interval
+ THEN next snapshot time := clock (1)
+ FI .
+
+save values :
+ time x := time ;
+ paging wait x := paging wait ;
+ paging busy x := paging busy ;
+ fore cpu x := fore cpu ;
+ back cpu x := back cpu ;
+ system cpu x := system cpu .
+
+get new values :
+ time := clock (1) ;
+ paging wait := clock (2) ;
+ paging busy := clock (3) ;
+ fore cpu := clock (4) ;
+ back cpu := clock (5) ;
+ system cpu := clock (6) ;
+ storage (storage max, used) .
+
+create stat record :
+ record := text (used, 5) ;
+ record CAT text (active terminals,3) ;
+ record CAT text (active background,3) ;
+ delta t := (time - time x) ;
+ percent (paging wait, paging wait x) ;
+ percent (paging busy, paging busy x) ;
+ percent (fore cpu, fore cpu x) ;
+ percent (back cpu, back cpu x) ;
+ percent (system cpu, system cpu x) ;
+ percent (last, 0.0) ;
+ percent (nutz, 0.0) .
+
+last : paging wait + paging busy + fore cpu + back cpu + system cpu
+ - paging waitx - paging busyx - fore cpux - back cpux - system cpux .
+
+nutz : time - paging wait - system cpu
+ - timex + paging waitx + system cpux .
+
+define next snapshot time :
+ next snapshot time := time + snapshot interval .
+
+ENDPROC log ;
+
+PROC percent (REAL CONST neu, alt ) :
+
+ record CAT text ( (neu-alt) / delta t * 100.0, 6,1) + "%"
+
+ENDPROC percent ;
+
+ENDPACKET eumelmeter ;
+
+
+
+PACKET background que manager DEFINES (* Autor: J.Liedtke *)
+ (* Stand: 15.10.82 *)
+ into background que ,
+ delete from background que ,
+ get first from background que ,
+ get next from background que :
+
+LET que size = 100 ,
+ ENTRY = STRUCT (TASK task, INT class) ;
+
+INT VAR end of que := 0 ,
+ actual entry pos ;
+
+ROW que size ENTRY VAR que ;
+
+
+PROC into background que (TASK CONST task) :
+
+ INT VAR class := prio (task) ;
+ IF end of que = que size
+ THEN delete all not existing tasks
+ FI ;
+ check whether already in que ;
+ IF already in que
+ THEN IF in same class
+ THEN LEAVE into background que
+ ELSE delete from background que (task) ;
+ into background que (task)
+ FI
+ ELSE insert new entry
+ FI .
+
+check whether already in que :
+ INT VAR entry pos := 1 ;
+ WHILE entry pos <= end of que REP
+ IF que (entry pos).task = task
+ THEN LEAVE check whether already in que
+ FI ;
+ entry pos INCR 1
+ PER .
+
+already in que : entry pos <= end of que .
+
+in same class : que (entry pos).class = class .
+
+insert new entry :
+ end of que INCR 1 ;
+ que (end of que) := ENTRY:( task, class ) .
+
+delete all not existing tasks :
+ INT VAR j ;
+ FOR j FROM 1 UPTO end of que REP
+ TASK VAR examined := que (j).task ;
+ IF NOT exists (examined)
+ THEN delete from background que (examined)
+ FI
+ PER .
+
+ENDPROC into background que ;
+
+PROC delete from background que (TASK CONST task) :
+
+ search for entry ;
+ IF entry found
+ THEN delete entry ;
+ update actual entry pos
+ FI .
+
+search for entry :
+ INT VAR entry pos := 1 ;
+ WHILE entry pos <= end of que REP
+ IF que (entry pos).task = task
+ THEN LEAVE search for entry
+ FI ;
+ entry pos INCR 1
+ PER .
+
+entry found : entry pos <= end of que .
+
+delete entry :
+ INT VAR i ;
+ FOR i FROM entry pos UPTO end of que - 1 REP
+ que (i) := que (i+1)
+ PER ;
+ end of que DECR 1 .
+
+update actual entry pos :
+ IF actual entry or following one deleted
+ THEN actual entry pos DECR 1
+ FI .
+
+actual entry or following one deleted :
+ entry pos >= actual entry pos .
+
+ENDPROC delete from background que ;
+
+PROC get first from background que (TASK VAR task, INT CONST lowest class) :
+
+ actual entry pos := 0 ;
+ get next from background que (task, lowest class)
+
+ENDPROC get first from background que ;
+
+PROC get next from background que (TASK VAR task, INT CONST lowest class) :
+
+ search next entry of permitted class ;
+ IF actual entry pos <= end of que
+ THEN task := que (actual entry pos).task
+ ELSE task := niltask
+ FI .
+
+search next entry of permitted class :
+ REP
+ actual entry pos INCR 1
+ UNTIL actual entry pos > end of que
+ COR que (actual entry pos).class <= lowest class PER.
+
+ENDPROC get next from background que ;
+
+ENDPACKET background que manager ;
+
+
+
+PACKET scheduler DEFINES (* Autor: J.Liedtke *)
+ (* Stand: 09.12.82 *)
+ scheduler :
+
+
+LET std background prio = 7 ,
+ highest background prio = 5 ,
+ long slice = 6000 ,
+ short slice = 600 ,
+ blocked busy = 4 ;
+
+INT VAR slice ,
+ foreground workers ,
+ background workers ;
+
+BOOL VAR is logging ;
+
+REAL VAR fore cpu load , back cpu load , paging load ;
+
+
+access catalogue ;
+TASK CONST ur task := brother (supervisor) ;
+
+TASK VAR actual task ;
+
+
+PROC scheduler :
+ IF yes ("mit eumelmeter")
+ THEN is logging := TRUE
+ ELSE is logging := FALSE
+ FI ;
+ task password ("-") ;
+ break ;
+ set autonom ;
+ command dialogue (FALSE) ;
+ forget ("scheduler", quiet) ;
+ disable stop;
+ REP scheduler operation;
+ clear error
+ PER;
+
+END PROC scheduler;
+
+PROC scheduler operation:
+ enable stop;
+ IF is logging
+ THEN init log
+ FI;
+ slice := short slice ;
+ init system load moniting ;
+ REP
+ pause (slice) ;
+ monit system load ;
+ look at all active user tasks and block background workers ;
+ activate next background workers if possible ;
+ IF is logging
+ THEN log (foreground workers, background workers)
+ FI
+ PER .
+
+init system load moniting :
+ REAL VAR
+ time x := clock (1) ,
+ fore cpu x := clock (4) ,
+ back cpu x := clock (5) ,
+ paging x := clock (2) + clock (3) .
+
+monit system load :
+ REAL VAR interval := clock (1) - time x ;
+ fore cpu load := (clock (4) - fore cpu x) / interval ;
+ back cpu load := (clock (5) - back cpu x) / interval ;
+ paging load := (clock (2) + clock (3) - paging x) / interval ;
+ time x := clock (1) ;
+ fore cpu x := clock (4) ;
+ back cpu x := clock (5) ;
+ paging x := clock (2) + clock (3) .
+
+ENDPROC scheduler operation;
+
+PROC look at all active user tasks and block background workers :
+
+ foreground workers := 0 ;
+ background workers := 0 ;
+ actual task := myself ;
+ next active (actual task) ;
+ WHILE NOT (actual task = myself) REP
+ IF actual task < ur task
+ THEN look at this task
+ FI ;
+ next active (actual task)
+ END REP .
+
+look at this task :
+ IF channel (actual task) >= 0
+ THEN foreground workers INCR 1
+ ELSE background workers INCR 1 ;
+ block actual task if simple worker
+ FI .
+
+block actual task if simple worker :
+ IF son (actual task) = niltask
+ THEN pause (5) ;
+ block (actual task) ;
+ IF status (actual task) = blocked busy
+ THEN set background prio ;
+ into background que (actual task)
+ ELIF prio (actual task) < highest background prio
+ THEN unblock (actual task)
+ FI
+ FI .
+
+set background prio :
+ IF prio (actual task) < highest background prio
+ THEN prio (actual task, std background prio)
+ FI .
+
+ENDPROC look at all active user tasks and block background workers ;
+
+PROC activate next background workers if possible :
+
+ INT VAR lowest activation prio ,
+ max background workers ,
+ active background workers := 0 ;
+
+ strategic decision (foreground workers, background workers,
+ fore cpu load, back cpu load, paging load,
+ lowest activation prio, max background workers) ;
+
+ IF background permitted
+ THEN try to activate background workers
+ FI ;
+ IF active background workers > 0
+ THEN slice := short slice
+ ELSE slice := long slice
+ FI .
+
+background permitted : max background workers > 0 .
+
+try to activate background workers :
+ get first from background que (actual task, lowest activation prio) ;
+ IF NOT is niltask (actual task)
+ THEN delete from background que (actual task)
+ FI ;
+
+ WHILE active background workers < max background workers REP
+ IF is niltask (actual task)
+ THEN LEAVE try to activate background workers
+ ELIF status (actual task) <> blocked busy
+ THEN delete from background que (actual task)
+ ELSE
+ unblock (actual task) ;
+ active background workers INCR 1
+ FI ;
+ get next from background que (actual task, lowest activation prio)
+ PER .
+
+ENDPROC activate next background workers if possible ;
+
+ENDPACKET scheduler ;
+
+scheduler;
+
diff --git a/system/spool cmd b/system/spool cmd
new file mode 100644
index 0000000..9b43d36
--- /dev/null
+++ b/system/spool cmd
@@ -0,0 +1,178 @@
+PACKET spool cmd (* Autor : R. Ruland *)
+ (* Stand : 13.08.87 *)
+ DEFINES
+ spool control password,
+
+ kill spool,
+ first spool,
+ start spool,
+ stop spool,
+ halt spool,
+ wait for halt :
+
+LET error nak = 2 ,
+
+ entry line code = 23 ,
+ killer code = 24 ,
+ first code = 25 ,
+ start code = 26 ,
+ stop code = 27 ,
+ halt code = 28 ,
+ wait for halt code = 29 ;
+
+DATASPACE VAR ds;
+
+BOUND STRUCT (TEXT entry line, INT index, TEXT actual entries, password) VAR control msg;
+BOUND TEXT VAR error msg;
+INT VAR reply;
+
+INITFLAG VAR in this task := FALSE;
+BOOL VAR dialogue;
+TEXT VAR control password, password;
+
+control password := "";
+
+PROC spool control password (TEXT CONST new password):
+
+ IF on line THEN say (""3""13""5"") FI;
+ disable stop;
+ do ("enter spool control password (""" + new password + """)");
+ clear error;
+ no do again;
+ cover tracks;
+ cover tracks (control password);
+ control password := new password;
+
+END PROC spool control password;
+
+
+PROC call spool (INT CONST op code, TEXT CONST name, TASK CONST spool) :
+
+ dialogue := command dialogue;
+ password := write password;
+ password CAT "/";
+ password CAT read password;
+ disable stop;
+ command dialogue (FALSE);
+ enter password (control password);
+ command dialogue (dialogue);
+ call (op code, name, spool);
+ command dialogue (FALSE);
+ enter password (password);
+ command dialogue (dialogue);
+
+END PROC call spool;
+
+
+PROC start spool (TASK CONST spool) :
+
+ enable stop;
+ call spool (halt code, "", spool);
+ call spool (start code, "", spool);
+
+END PROC start spool;
+
+
+PROC start spool (TASK CONST spool, INT CONST new channel) :
+
+ enable stop;
+ call spool (halt code, "", spool);
+ call spool (start code, text (new channel), spool);
+
+END PROC start spool;
+
+
+PROC stop spool (TASK CONST spool) :
+
+ call spool (stop code, "", spool);
+
+END PROC stop spool;
+
+PROC stop spool (TASK CONST spool, TEXT CONST deactive msg) :
+
+ call spool (stop code, deactive msg, spool);
+
+END PROC stop spool;
+
+
+PROC halt spool (TASK CONST spool) :
+
+ call spool (halt code, "", spool);
+
+END PROC halt spool;
+
+PROC halt spool (TASK CONST spool, TEXT CONST deactive msg) :
+
+ call spool (halt code, deactive msg, spool);
+
+END PROC halt spool;
+
+
+PROC wait for halt (TASK CONST spool) :
+
+ call spool (wait for halt code, "", spool);
+
+END PROC wait for halt;
+
+PROC wait for halt (TASK CONST spool, TEXT CONST deactive msg) :
+
+ call spool (wait for halt code, deactive msg, spool);
+
+END PROC wait for halt;
+
+
+PROC control spool (TASK CONST spool, INT CONST control code,
+ TEXT CONST question, BOOL CONST leave) :
+
+ enable stop;
+ initialize control msg;
+ WHILE valid spool entry
+ REP IF control question THEN control spool entry FI PER;
+
+ . initialize control msg :
+ IF NOT initialized (in this task) THEN ds := nilspace FI;
+ forget (ds); ds := nilspace; control msg := ds;
+ control msg. entry line := "";
+ control msg. password := control password;
+ control msg. index := 0;
+ say (""13""10"");
+
+ . valid spool entry :
+ call (spool, entry line code, ds, reply);
+ IF reply = error nak
+ THEN error msg := ds;
+ errorstop (error msg);
+ FI;
+ control msg. index <> 0
+
+ . control question :
+ say (control msg. entry line);
+ yes (question)
+
+ . control spool entry :
+ call (spool, control code, ds, reply);
+ IF reply = error nak
+ THEN error msg := ds;
+ errorstop (error msg);
+ FI;
+ IF leave THEN LEAVE control spool FI;
+
+END PROC control spool;
+
+
+PROC kill spool (TASK CONST spool) :
+
+ control spool (spool, killer code, " loeschen", FALSE)
+
+END PROC kill spool;
+
+
+PROC first spool (TASK CONST spool) :
+
+ control spool (spool, first code, " als erstes", TRUE)
+
+END PROC first spool;
+
+
+END PACKET spool cmd;
+
diff --git a/system/spool manager b/system/spool manager
new file mode 100644
index 0000000..6b4fe55
--- /dev/null
+++ b/system/spool manager
@@ -0,0 +1,1058 @@
+PACKET spool manager DEFINES (* Autor : R. Ruland *)
+ (* Stand : 23.02.88 *)
+
+ spool manager ,
+
+ server channel ,
+ spool duty,
+ station only,
+ auto stop,
+ enter spool control password,
+ spool control password,
+
+ start spool,
+ stop spool,
+ halt spool,
+ kill spool,
+ first spool,
+ spool entry line,
+ number spool entries,
+ spool status,
+ server task,
+ clear spool,
+ list spool,
+ :
+
+LET que size = 200 ,
+
+ ack = 0 ,
+ nak = 1 ,
+ error nak = 2 ,
+ second phase ack = 5 ,
+ false code = 6 ,
+
+ fetch code = 11 ,
+ save code = 12 ,
+ exists code = 13 ,
+ erase code = 14 ,
+ list code = 15 ,
+ all code = 17 ,
+ param fetch code = 21 ,
+ file save code = 22 ,
+ entry line code = 23 ,
+ killer code = 24 ,
+ first code = 25 ,
+ start code = 26 ,
+ stop code = 27 ,
+ halt code = 28 ,
+ wait for halt code = 29 ,
+ help code = 49 ,
+ continue code = 100 ,
+
+ control codes = ""23""24""25""26""27""28""29"" ,
+
+ file type = 1003 ,
+ help file name = "help";
+
+LET begin char = ""0"",
+ end char = ""1"";
+
+LET PARAMS = STRUCT (TEXT name, userid, password, sendername, INT station);
+
+BOUND ROW que size STRUCT (PARAMS ds params, TEXT entry line) VAR que;
+
+ ROW que size DATASPACE VAR que space;
+
+PARAMS VAR save params;
+
+DATASPACE VAR que ds, global ds;
+
+FILE VAR file;
+
+INT VAR last order, reply, old heap size, que index, fetch index,
+ station by start, begin pos, end pos, order task station, sp channel;
+
+TEXT VAR que entries, free entries, order task name, buffer, deactive message,
+ error message buffer, sp duty, start time, control password;
+
+BOOL VAR server is waiting, stop cmd pending, start cmd pending,
+ auto stop pending, stat only;
+
+TASK VAR last order task, server, calling parent, task in control;
+
+INITFLAG VAR in this task := FALSE, init que space := FALSE;
+
+BOUND STRUCT (TEXT name, userid, password) VAR msg;
+BOUND STRUCT (TEXT entry line, INT index, TEXT actual entries, password) VAR control msg;
+BOUND PARAMS VAR fetch msg;
+BOUND THESAURUS VAR all msg;
+BOUND TEXT VAR error msg;
+
+
+. que is empty : que entries = ""
+. que is full : free entries = ""
+. number entries : LENGTH que entries
+
+. first index : code (que entries SUB 1)
+. list index : code (que entries SUB que index)
+. last index : code (que entries SUB number entries)
+
+. fetch entry : que (fetch index)
+. list entry : que (list index)
+. last entry : que (last index)
+
+. was define station : station by start <> station (myself)
+. is valid fetch entry : fetch index > 0
+.;
+
+INT VAR command index , params ;
+TEXT VAR param 1, param 2 ;
+LET spool command list = "start:1.01stop:3.0halt:4.0first:5.0killer:6.0";
+
+sp channel := 0;
+sp duty := "";
+deactive message := "";
+stat only := FALSE;
+auto stop pending := FALSE;
+task in control := supervisor;
+control password := "-";
+
+
+PROC server channel (INT CONST channel nr) :
+ IF channel nr <= 0 OR channel nr >= 33
+ THEN errorstop ("falsche Kanalangabe") FI;
+ sp channel := channel nr;
+END PROC server channel;
+
+INT PROC server channel : sp channel END PROC server channel;
+
+
+PROC station only (BOOL CONST flag) :
+ stat only := flag
+END PROC station only;
+
+BOOL PROC station only : stat only END PROC station only;
+
+
+PROC auto stop (BOOL CONST flag) :
+ auto stop pending := flag
+END PROC auto stop;
+
+BOOL PROC auto stop : auto stop pending END PROC auto stop;
+
+
+PROC spool duty (TEXT CONST duty) :
+ sp duty := duty;
+END PROC spool duty;
+
+TEXT PROC spool duty : sp duty END PROC spool duty;
+
+
+PROC enter spool control password (TEXT CONST new password):
+ disable stop;
+ cover tracks;
+ cover tracks (control password);
+ control password := new password;
+END PROC enter spool control password;
+
+PROC spool control password (TEXT CONST new password):
+ IF on line THEN say (""3""13""5"") FI;
+ enter spool control password (new password);
+END PROC spool control password;
+
+
+PROC spool manager (PROC server start) :
+ spool manager (PROC (DATASPACE VAR, INT CONST,
+ INT CONST, TASK CONST) spool manager,
+ PROC server start, TRUE)
+END PROC spool manager;
+
+
+PROC spool manager (PROC server start, BOOL CONST initial start) :
+ spool manager (PROC (DATASPACE VAR, INT CONST,
+ INT CONST, TASK CONST) spool manager,
+ PROC server start, initial start)
+END PROC spool manager;
+
+
+PROC spool manager (PROC (DATASPACE VAR, INT CONST,
+ INT CONST, TASK CONST) spool,
+ PROC server start,
+ BOOL CONST initial start) :
+
+ set autonom;
+ break;
+ disable stop;
+ command dialogue (FALSE);
+ initialize spool manager;
+ REP start spool if necessary;
+ wait for next order;
+ IF order not allowed THEN reject order
+ ELIF is first phase THEN first phase
+ ELIF is second phase THEN second phase
+ ELSE send nak
+ FI;
+ send error if necessary;
+ collect heap garbage if necessary;
+ PER
+
+ . initialize spool manager :
+ initialize if necessary;
+ stop server;
+ erase fetch entry;
+ start cmd pending := initial start;
+ stop cmd pending := FALSE;
+ last order task := niltask;
+
+ . initialize if necessary :
+ IF NOT initialized (in this task)
+ THEN clear spool;
+ global ds := nilspace;
+ que ds := nilspace;
+ que := que ds;
+ server := niltask;
+ calling parent := niltask;
+ server is waiting := FALSE;
+ station by start := station (myself);
+ old heap size := 0;
+ error message buffer := "";
+ FI;
+
+ . start spool if necessary :
+ IF start cmd pending AND NOT stop cmd pending
+ THEN start server (PROC server start) FI;
+
+ . wait for next order :
+ INT VAR order, phase;
+ TASK VAR order task;
+ forget (global ds);
+ wait (global ds, order, order task);
+
+ . order not allowed :
+ station only CAND station (ordertask) <> station (myself) CAND
+ ( order > 255 COR pos (control codes, code (order)) = 0 )
+
+ . reject order :
+ errorstop ("kein Zugriffsrecht auf Task " + text (station(myself))
+ + "/""" + name(myself) + """")
+
+ . is first phase :
+ order <> second phase ack
+
+ . first phase :
+ phase := 1;
+ last order := order;
+ last order task := order task;
+ spool (global ds, order, phase, order task);
+
+ . is second phase :
+ order task = last order task
+
+ . second phase :
+ phase INCR 1 ;
+ order := last order;
+ spool (global ds, order, phase, order task);
+
+ . send nak :
+ forget (global ds);
+ global ds := nilspace;
+ send (order task, nak, global ds);
+
+ . send error if necessary :
+ IF is error
+ THEN forget (global ds);
+ global ds := nilspace;
+ error msg := global ds;
+ CONCR (error msg) := error message;
+ clear error;
+ send (order task, error nak, global ds);
+ FI;
+
+ . collect heap garbage if necessary :
+ IF heap size > old heap size + 2
+ THEN collect heap garbage;
+ old heap size := heap size;
+ FI;
+
+END PROC spool manager;
+
+
+PROC spool manager (DATASPACE VAR order ds,
+ INT CONST order, phase,
+ TASK CONST order task ):
+
+ enable stop;
+ SELECT order OF
+ CASE fetch code, help code : out of que or help
+ CASE param fetch code : send fetch params
+ CASE save code : new que entry
+ CASE file save code : new file que entry
+ CASE exists code : exists que entry
+ CASE erase code : erase que entry
+ CASE list code : send spool list
+ CASE all code : send owners ds names
+
+ CASE entry line code : send next entry line
+ CASE killer code : kill entry
+ CASE first code : make to first
+ CASE start code : start server task
+ CASE stop code : stop server task
+ CASE halt code, wait for halt code
+ : halt server task
+
+ OTHERWISE :
+
+ IF order >= continue code AND order task = supervisor
+ THEN spool monitor
+ ELSE wrong operation
+ FI;
+
+ END SELECT;
+
+. wrong operation :
+ IF order > error nak
+ THEN errorstop ("falscher Auftrag fuer Task " + text (station(myself))
+ + "/""" + name(myself) + """")
+ FI;
+
+.
+ out of que or help :
+ IF order task = server
+ THEN out of que
+ ELSE send help file
+ FI;
+
+ . out of que :
+ erase fetch entry;
+ IF stop cmd pending
+ THEN stop server
+ ELIF que is empty
+ THEN IF auto stop pending
+ THEN stop server
+ ELSE server is waiting := TRUE
+ FI;
+ ELSE send first entry;
+ FI;
+
+ . send help file :
+ check server (TRUE);
+ IF order = fetch code
+ THEN msg := order ds;
+ IF msg. name <> help file name
+ THEN errorstop ("keine Servertask") FI;
+ FI;
+ forget (order ds);
+ order ds := old (help file name);
+ send (order task, ack, order ds);
+
+.
+ send fetch params :
+ IF order task = server
+ THEN send params
+ ELSE errorstop ("keine Servertask")
+ FI;
+
+ . send params :
+ forget(order ds); order ds := nilspace;
+ fetch msg := order ds;
+ fetch msg := fetch entry. ds params;
+ send (order task, ack, order ds);
+
+.
+ new que entry :
+ IF phase = 1
+ THEN prepare into que
+ ELSE into que (order ds, order task)
+ FI;
+
+.
+ prepare into que :
+ msg := order ds ;
+ save params. name := msg.name;
+ save params. userid := msg.userid;
+ save params. password := msg.password;
+ save params. sendername := name (order task);
+ save params. station := station (order task);
+ forget (order ds); order ds := nilspace;
+ send (order task, second phase ack, order ds);
+
+.
+ new file que entry :
+ IF type (order ds) <> file type
+ THEN errorstop ("Datenraum hat falschen Typ");
+ ELSE get file params;
+ into que (order ds, order task);
+ FI;
+
+ . get file params :
+ file := sequential file (input, order ds);
+ end pos := 0;
+ next headline information (save params. name);
+ next headline information (save params. userid);
+ next headline information (save params. password);
+ next headline information (save params. sendername);
+ next headline information (buffer);
+ save params. station := int (buffer);
+ IF NOT last conversion ok
+ THEN save params. station := station (order task) FI;
+ IF save params. sendername = ""
+ THEN save params. sendername := name (order task) FI;
+ IF save params. name = ""
+ THEN IF headline (file) <> ""
+ THEN save params. name := headline (file);
+ ELSE errorstop ("Name unzulaessig")
+ FI;
+ ELSE headline (file, save params. name);
+ FI;
+
+.
+ exists que entry :
+ msg := order ds ;
+ order task name := name (order task);
+ order task station := station (order task);
+ FOR que index FROM 1 UPTO number entries
+ REP IF is entry from order task (msg. name)
+ THEN send ack;
+ LEAVE exists que entry
+ FI;
+ PER ;
+ forget (order ds); order ds := nilspace;
+ send (order task, false code, order ds)
+
+.
+ erase que entry :
+ msg := order ds ;
+ order task name := name (order task);
+ order task station := station (order task);
+ IF phase = 1
+ THEN ask for erase
+ ELSE erase entry from order task
+ FI;
+
+ . ask for erase :
+ FOR que index FROM 1 UPTO number entries
+ REP IF is entry from order task (msg. name)
+ THEN manager question ("""" + msg.name + """ loeschen", order task);
+ LEAVE erase que entry
+ FI;
+ PER ;
+ manager message ("""" + msg.name + """ existiert nicht", order task);
+
+ . erase entry from order task :
+ IF is valid que index (que index) CAND is entry from order task (msg. name)
+ THEN delete que entry;
+ LEAVE erase que entry
+ ELSE FOR que index FROM 1 UPTO number entries
+ REP IF is entry from order task (msg. name)
+ THEN delete que entry;
+ LEAVE erase que entry
+ FI;
+ PER;
+ manager message ("""" + msg.name + """ existiert nicht", order task);
+ FI;
+
+ . delete que entry :
+ kill spool (que index);
+ send ack;
+
+.
+ send owners ds names:
+ order task name := name (order task);
+ order task station := station (order task);
+ forget (order ds); order ds := nilspace; all msg := order ds;
+ all msg := empty thesaurus;
+ FOR que index FROM 1 UPTO number entries
+ REP IF is entry from order task ("")
+ THEN insert (all msg, list entry. ds params. name)
+ FI;
+ PER;
+ send (order task, ack, order ds)
+
+.
+ send spool list :
+ forget (global ds); global ds := nilspace;
+ file := sequential file (output, global ds);
+ list spool (file);
+ send (order task, ack, global ds);
+
+.
+ send next entry line :
+ control msg := order ds; check control password (control msg. password);
+ IF control msg. index = 0 THEN control msg. actual entries := que entries FI;
+ get next entry line;
+ send (order task, ack, order ds);
+
+ . get next entry line :
+ REP control msg. index INCR 1;
+ IF control msg. index > LENGTH control msg. actual entries
+ THEN control msg. index := 0;
+ control msg. entry line := "";
+ LEAVE get next entry line;
+ FI;
+ que index := control que index;
+ UNTIL is valid que index (que index) PER;
+ control msg. entry line := list entry. entry line;
+
+ . control que index :
+ pos (que entries, control msg. actual entries SUB control msg. index)
+
+.
+ kill entry :
+ control msg := order ds; check control password (control msg. password);
+ kill spool (control que index);
+ send (order task, ack, order ds);
+
+.
+ make to first :
+ control msg := order ds; check control password (control msg. password);
+ first spool (control que index);
+ send (order task, ack, order ds);
+
+.
+ start server task :
+ msg := order ds; check control password (msg. password);
+ IF exists (server) AND NOT stop cmd pending
+ THEN errorstop ("Spool muß zuerst gestoppt werden") FI;
+ new server channel is necessary;
+ start cmd pending := TRUE;
+ IF server channel <= 0 OR server channel >= 33
+ THEN manager message ("WARNUNG : Serverkanal nicht eingestellt", order task);
+ ELSE send ack
+ FI;
+
+ . new server channel is necessary :
+ INT CONST new channel := int (msg. name);
+ IF last conversion ok THEN server channel (new channel) FI;
+
+.
+ stop server task :
+ msg := order ds; check control password (msg. password);
+ IF phase = 1
+ THEN start cmd pending := FALSE;
+ deactive message := msg. name;
+ stop server;
+ check fetch entry;
+ ELSE reinsert fetch entry;
+ send ack;
+ FI;
+
+.
+ halt server task :
+ msg := order ds; check control password (msg. password);
+ IF phase = 1
+ THEN stop cmd pending := TRUE;
+ start cmd pending := FALSE;
+ deactive message := msg. name;
+ IF NOT exists (server) OR server is waiting
+ THEN stop server;
+ check fetch entry;
+ ELIF order = wait for halt code
+ THEN calling parent := order task;
+ ELSE send ack;
+ FI;
+ ELSE reinsert fetch entry;
+ send ack;
+ FI;
+
+ . check fetch entry :
+ IF is valid fetch entry
+ THEN manager question (""13""10"" +
+ fetch entry. entry line + " neu eintragen", order task);
+ fetch index := -fetch index;
+ ELSE send ack;
+ FI;
+
+.
+ send ack :
+ forget (order ds); order ds := nilspace;
+ send (order task, ack, order ds)
+
+.
+ spool monitor :
+ continue (order - continue code);
+ disable stop;
+ put error message if there is one;
+ WHILE online
+ REP command dialogue (TRUE);
+ sysout ("");
+ sysin ("");
+ get command ("gib Spool-Kommando:");
+ analyze command (spool command list, 3, command index, params, param1, param2);
+ reset editor;
+ SELECT command index OF
+ CASE 1 : start spool
+ CASE 2 : start spool (int (param1))
+ CASE 3 : stop spool
+ CASE 4 : halt spool
+ CASE 5 : first spool
+ CASE 6 : kill spool
+ OTHERWISE : do command
+ END SELECT;
+ PER;
+ save error message if there is one;
+ command dialogue (FALSE);
+ break (quiet);
+ set autonom;
+
+ . put error message if there is one :
+ IF error message buffer <> ""
+ THEN errorstop (error message buffer); FI;
+
+ . save error message if there is one :
+ IF is error
+ THEN error message buffer := error message;
+ clear error;
+ ELSE error message buffer := "";
+ FI;
+
+ . reset editor :
+ WHILE aktueller editor > 0 REP quit PER;
+ clear error;
+
+END PROC spool manager;
+
+
+PROC send first entry :
+
+ forget (global ds);
+ global ds := que space (first index);
+ send (server, ack, global ds, reply) ;
+ IF reply = ack
+ THEN fetch index := first index;
+ que entries := subtext (que entries, 2);
+ server is waiting := FALSE;
+ start time := time of day;
+ start time CAT " am ";
+ start time CAT date;
+ FI;
+
+END PROC send first entry;
+
+
+PROC into que (DATASPACE VAR order ds, TASK CONST order task) :
+
+ IF que is full
+ THEN errorstop ("Spool ist voll")
+ ELSE make new entry;
+ send ack;
+ awake server if necessary
+ FI;
+
+ . make new entry :
+ que entries CAT (free entries SUB 1);
+ free entries := subtext (free entries, 2);
+ que space (last index) := order ds;
+ last entry. ds params := save params;
+ build entry line;
+
+ . build entry line :
+ IF LENGTH last entry. ds params. sender name > 16
+ THEN buffer := subtext (last entry. ds params. sender name, 1, 13);
+ buffer CAT "...""";
+ ELSE buffer := last entry. ds params. sender name;
+ buffer CAT """";
+ buffer := text (buffer, 17);
+ FI;
+ last entry. entry line := entry station text;
+ last entry. entry line CAT "/""";
+ last entry. entry line CAT buffer;
+ last entry. entry line CAT " : """ ;
+ last entry. entry line CAT last entry. ds params. name;
+ last entry. entry line CAT """ (" ;
+ last entry. entry line CAT text (storage (order ds));
+ last entry. entry line CAT " K)";
+
+ . entry station text :
+ IF last entry. ds params. station = 0
+ THEN " "
+ ELSE text (last entry. ds params. station, 3)
+ FI
+
+ . send ack :
+ forget (order ds); order ds := nilspace;
+ send (order task, ack, order ds)
+
+ . awake server if necessary :
+ IF server is waiting THEN send first entry FI;
+
+END PROC into que;
+
+
+(*********************************************************************)
+(* Hilfsprozeduren zum Spoolmanager *)
+(*********************************************************************)
+
+
+PROC reinsert fetch entry :
+
+ IF fetch index <> 0
+ THEN insert char (que entries, code (abs (fetch index)), 1);
+ fetch index := 0;
+ FI;
+
+END PROC reinsert fetch entry;
+
+
+PROC erase fetch entry :
+
+ IF fetch index <> 0
+ THEN free entries CAT code (abs (fetch index));
+ forget (que space (abs (fetch index)));
+ fetch index := 0;
+ FI;
+
+END PROC erase fetch entry;
+
+
+PROC start server (PROC server start):
+
+ stop server;
+ begin (PROC server start, server);
+ station by start := station (myself);
+ start cmd pending := FALSE;
+ deactive message := "";
+
+END PROC start server;
+
+
+PROC stop server :
+
+ IF exists (server) THEN end (server) ELSE check server (FALSE) FI;
+ server := niltask;
+ server is waiting := FALSE;
+ stop cmd pending := FALSE;
+ send calling parent reply if necessary;
+
+ . send calling parent reply if necessary :
+ IF exists (calling parent)
+ THEN forget (global ds); global ds := nilspace;
+ send (calling parent, ack, global ds);
+ calling parent := niltask;
+ FI;
+
+END PROC stop server;
+
+
+PROC check server (BOOL CONST with stop) :
+
+ IF was define station CAND NOT is niltask (server)
+ THEN stop old server if necessary FI;
+
+ . stop old server if necessary :
+ access catalogue;
+ TASK VAR old server := son (myself);
+ WHILE NOT is niltask (old server)
+ REP IF index (old server) = index (server) THEN old server found FI;
+ old server := brother (old server);
+ PER;
+
+ . old server found :
+ IF name (old server) = "-" THEN end (old server) FI;
+ IF with stop THEN stop server FI;
+ LEAVE stop old server if necessary;
+
+END PROC check server;
+
+
+BOOL PROC is valid que index (INT CONST index) :
+
+ 1 <= index AND index <= number entries
+
+END PROC is valid que index;
+
+
+BOOL PROC is entry from order task (TEXT CONST file name) :
+
+ correct order task CAND correct filename
+
+ . correct order task :
+ order task name = list entry. ds params. sendername
+ AND order task station = list entry. ds params. station
+
+ . correct file name :
+ file name = "" OR file name = list entry. ds params. name
+
+END PROC is entry from order task;
+
+
+PROC check control password (TEXT CONST password) :
+
+ IF control password = "-"
+ THEN errorstop ("Kontrolle des Spools nicht erlaubt")
+ ELIF control password <> "" CAND control password <> password
+ THEN errorstop ("Passwort falsch")
+ FI;
+
+END PROC check control password;
+
+
+PROC next headline information (TEXT VAR t):
+
+ begin pos := pos (headline (file), begin char, end pos + 1);
+ IF begin pos = 0
+ THEN begin pos := LENGTH headline (file) + 1;
+ t := "";
+ ELSE end pos := pos (headline (file), end char, begin pos + 1);
+ IF end pos = 0
+ THEN end pos := LENGTH headline (file) + 1;
+ t := "";
+ ELSE t := subtext (headline (file), begin pos+1, end pos-1)
+ FI
+ FI
+
+END PROC next headline information;
+
+(*********************************************************************)
+(* Prozeduren zur Verwaltung der Warteschlange *)
+(*********************************************************************)
+
+PROC start spool :
+
+ enable stop;
+ IF server channel <= 0 OR server channel >= 33
+ THEN display (""13""10"WARNUNG : Serverkanal nicht eingestellt"13""10"")
+ FI;
+ halt spool;
+ start cmd pending := TRUE;
+
+END PROC start spool;
+
+PROC start spool (INT CONST new channel) :
+
+ enable stop;
+ server channel (new channel);
+ start spool;
+
+END PROC start spool;
+
+PROC stop spool (TEXT CONST deactive msg) :
+
+ disable stop;
+ deactive message := deactive msg;
+ start cmd pending := FALSE;
+ stop server;
+ IF is valid fetch entry CAND on line CAND
+ yes (""13""10"" + fetch entry. entry line + " neu eintragen")
+ THEN reinsert fetch entry
+ ELSE erase fetch entry;
+ FI;
+
+END PROC stop spool;
+
+PROC stop spool : stop spool ("") END PROC stop spool;
+
+PROC halt spool (TEXT CONST deactive msg) :
+
+ enable stop;
+ deactive message := deactive msg;
+ stop cmd pending := TRUE;
+ start cmd pending := FALSE;
+ IF NOT exists (server) OR server is waiting THEN stop spool FI;
+
+END PROC halt spool;
+
+PROC halt spool : halt spool ("") END PROC halt spool;
+
+
+PROC kill spool :
+
+ enable stop;
+ say (""13""10"");
+ que index := 1;
+ WHILE que index <= number entries
+ REP IF yes (list entry. entry line + " loeschen")
+ THEN kill spool (que index)
+ ELSE que index INCR 1
+ FI;
+ PER;
+
+END PROC kill spool;
+
+PROC kill spool (INT CONST index) :
+
+ IF is valid que index (index)
+ THEN forget (que space (code (que entries SUB index)));
+ free entries CAT (que entries SUB index);
+ delete char (que entries, index);
+ FI;
+
+END PROC kill spool;
+
+
+PROC first spool :
+
+ enable stop;
+ say (""13""10"");
+ FOR que index FROM 1 UPTO number entries
+ REP IF yes (list entry. entry line + " als erstes")
+ THEN first spool (que index);
+ LEAVE first spool
+ FI;
+ PER;
+
+END PROC first spool;
+
+PROC first spool (INT CONST index) :
+
+ IF is valid que index (index)
+ THEN insert char (que entries, que entries SUB index, 1);
+ delete char (que entries, index + 1);
+ FI;
+
+END PROC first spool;
+
+
+TEXT PROC spool entry line (INT CONST index) :
+
+ IF index = 0 CAND is valid fetch entry
+ THEN fetch entry. entry line
+ ELIF is valid que index (index)
+ THEN entry. entry line
+ ELSE ""
+ FI
+
+ . entry : que (code (que entries SUB index))
+
+END PROC spool entry line;
+
+
+INT PROC number spool entries : number entries END PROC number spool entries;
+
+INT PROC spool status :
+
+ IF exists (server)
+ THEN IF stop cmd pending
+ THEN IF start cmd pending
+ THEN 3 (* aktiviert (neu start) *)
+ ELSE 2 (* aktiviert (warten auf halt) *)
+ FI
+ ELSE IF server is waiting
+ THEN 0 (* kein Auftrag in Bearbeitung *)
+ ELSE 1 (* aktiviert *)
+ FI
+ FI
+ ELIF start cmd pending
+ THEN 0 (* wird aktiviert *)
+ ELIF is valid fetch entry
+ THEN IF was define station
+ THEN -3 (* deaktiviert (define station) *)
+ ELSE -2 (* deaktiviert (server gelöcht) *)
+ FI
+ ELSE -1 (* deaktiviert *)
+ FI
+
+END PROC spool status;
+
+TASK PROC server task : server END PROC server task;
+
+
+PROC clear spool :
+
+ disable stop;
+ IF NOT initialized (init que space)
+ THEN FOR que index FROM 1 UPTO que size
+ REP que space (que index) := nilspace PER;
+ FI;
+ que entries := "";
+ free entries := "";
+ fetch index := 0;
+ stop server;
+ FOR que index FROM 1 UPTO que size
+ REP forget (que space (que index));
+ free entries CAT code (que index);
+ PER;
+
+END PROC clear spool;
+
+
+PROC list spool :
+
+ disable stop;
+ DATASPACE VAR list ds := nilspace;
+ FILE VAR list file := sequential file (output, list ds);
+ list spool (list file);
+ show (list file);
+ forget (list ds);
+
+END PROC list spool;
+
+
+PROC list spool (FILE VAR f) :
+
+ enable stop;
+ output (f);
+ max line length (f, 1000);
+ headline (f, station text + name (myself) + """");
+ put spool duty;
+ put current job;
+ put spool que;
+
+ . station text :
+ IF station(myself) = 0
+ THEN "/"""
+ ELSE text (station(myself)) + "/"""
+ FI
+
+ . put spool duty :
+ IF spool duty <> ""
+ THEN write (f, "Aufgabe: ");
+ write (f, spool duty );
+ line (f, 2);
+ FI;
+
+ . put current job :
+ IF is valid fetch entry
+ THEN write (f, "In Bearbeitung seit ");
+ write (f, start time);
+ write (f, ":");
+ line (f, 2);
+ putline (f, fetch entry. entry line);
+ IF NOT exists (server)
+ THEN IF was define station
+ THEN putline (f, "Spool ist deaktiviert, da Stationsnummer geaendert wurde")
+ ELSE putline (f, "Spool ist deaktiviert, da der Server gelöscht wurde")
+ FI;
+ ELIF stop cmd pending
+ THEN IF start cmd pending
+ THEN putline (f, "Spool wird nach diesem Auftrag neu aktiviert");
+ ELSE putline (f, "Spool wird nach diesem Auftrag deaktiviert");
+ FI;
+ FI;
+ line (f);
+ ELSE write (f, "kein Auftrag in Bearbeitung");
+ IF NOT exists (server)
+ THEN write (f, ", da Spool deaktiviert");
+ IF start cmd pending
+ THEN line (f);
+ write (f, "Spool wird nach Verlassen der Task aktiviert");
+ FI;
+ IF deactive message <> ""
+ THEN line (f);
+ write (f, deactive message);
+ FI;
+ ELIF que is empty
+ THEN write (f, ", da Warteschlange leer");
+ LEAVE list spool;
+ FI;
+ line (f, 2);
+ FI;
+
+ . put spool que :
+ IF que is empty
+ THEN putline (f, "Warteschlange ist leer");
+ ELSE write (f, "Warteschlange (");
+ write (f, text (number entries));
+ IF number entries = 1
+ THEN write (f, " Auftrag):");
+ ELSE write (f, " Auftraege):");
+ FI;
+ line (f, 2);
+ FOR que index FROM 1 UPTO number entries
+ REP putline (f, list entry. entry line) PER;
+ FI;
+
+END PROC list spool;
+
+
+ENDPACKET spool manager;
+
diff --git a/system/std analysator b/system/std analysator
new file mode 100644
index 0000000..7e14722
--- /dev/null
+++ b/system/std analysator
@@ -0,0 +1,68 @@
+PACKET std analysator (* Autor : Rudolf Ruland *)
+ (* Stand : 06.11.86 *)
+ DEFINES std analysator :
+
+
+LET text code = 1,
+ error code = 2,
+ token code = 3;
+
+INT VAR instruction begin;
+TEXT VAR unknown instruction := "";
+
+PROC std analysator (INT CONST op code, TEXT VAR string,
+ INT VAR par1, par2, par3, par4, par5, par6, par7) :
+
+ SELECT op code OF
+
+ CASE text code : analyse text
+ CASE error code : report errors
+ CASE token code : report tokens
+
+ END SELECT ;
+
+ . record : string
+ . record pos : par1
+ . width : par4
+ . height : par5
+ . depth : par6
+
+ . analyse text :
+ instruction begin := record pos + 1;
+ record pos := pos (record, "#", instruction begin) + 1;
+ width := 0;
+ height := 0;
+ depth := 0;
+ unknown instruction := subtext (record, instruction begin, instruction end);
+
+ . instruction end : record pos - 2
+
+
+. error msg : string
+. error nr : par1
+.
+ report errors :
+ IF error nr = 0
+ THEN error msg := "unbekannte Anweisung (ignoriert): ";
+ error msg CAT unknown instruction;
+ error nr := 1;
+ ELSE error msg := "";
+ error nr := 0;
+ FI;
+
+
+. token text : string
+. token nr : par1
+. token font nr : par2
+. token modifications : par3
+. token width : par4
+. token x pos : par5
+. token y pos : par6
+. token type : par7
+.
+ report tokens :
+
+END PROC std analysator;
+
+END PACKET std analysator;
+
diff --git a/tecal/TeCal b/tecal/TeCal
new file mode 100644
index 0000000..0bcb18e
--- /dev/null
+++ b/tecal/TeCal
@@ -0,0 +1,856 @@
+(**********************************************************************)
+(* *)
+(* TeCal - Text Calculator *)
+(* *)
+(* Autor : Andreas Schmeink 06.09.1984 *)
+(* Korrektur: Hilmar v.d. Bussche 17.09.1984 *)
+(* 20.09.1984 *)
+(* Adaption : Uwe Behrend, Andreas Schmeink 03.08.1987 *)
+(**********************************************************************)
+
+PACKET pick DEFINES pick up number, left range, right range,
+ replace number, last pick up ok :
+
+(********************************************************************)
+(* *)
+(* Zahlen erkennen und schreiben für TeCal 12.09.84 *)
+(* *)
+(********************************************************************)
+
+LET ziffern = "0123456789", pseudoblankcode = 223;
+
+ROW 10 REAL VAR ziffer plus eins
+ := ROW 10 REAL : (0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0);
+REAL VAR number;
+BOOL VAR ziffer gefunden;
+INT VAR anfang, ende, zeichencode, vorkommastellen, p, dezimalzeichen;
+TEXT VAR worktext;
+
+BOOL PROC last pick up ok:
+ ziffer gefunden
+END PROC last pick up ok;
+
+REAL PROC code to digit (INT CONST code) :
+ ziffer plus eins (code-47)
+END PROC code to digit;
+
+INT PROC left range :
+ anfang
+END PROC left range;
+
+INT PROC right range :
+ ende
+END PROC right range;
+
+REAL PROC pick up number (TEXT CONST source, INT CONST where) :
+
+ suche ende der zahl;
+ lies zahl ein;
+ number.
+
+suche ende der zahl :
+ fange bei gegebener position an;
+ IF vorzeichen THEN
+ nach rechts ruecken
+ FI;
+ WHILE erlaubtes zeichen REP
+ nach rechts ruecken
+ PER;
+ ende merken.
+
+fange bei gegebener position an:
+ ziffer gefunden := FALSE;
+ p := where;
+ betrachte aktuelles zeichen.
+
+nach rechts ruecken:
+ p INCR 1;
+ betrachte aktuelles zeichen.
+
+nach links ruecken:
+ p DECR 1;
+ betrachte aktuelles zeichen.
+
+ende merken :
+ ende := p - 1.
+
+lies zahl ein :
+ fange hinter der zahl an;
+ sammle ziffern auf;
+ pruefe vorzeichen;
+ werte exponent aus.
+
+sammle ziffern auf :
+ REP
+ nach links ruecken;
+ IF ziffer THEN
+ ziffer behandeln
+ ELIF punkt OR komma THEN
+ IF wirkt als dezimalzeichen THEN
+ dezimalzeichen behandeln
+ ELSE ignorieren
+ FI
+ ELIF pseudoblank vor ziffer THEN
+ ignorieren
+ ELSE
+ LEAVE sammle ziffern auf
+ FI;
+ PER.
+
+pruefe vorzeichen :
+ IF minus THEN
+ anfang := p;
+ number := number * -1.0
+ ELIF plus THEN
+ anfang := p
+ ELSE
+ anfang := p+1
+ FI.
+
+werte exponent aus :
+ set exp (vorkommastellen+decimal exponent(number), number).
+
+fange hinter der zahl an :
+ vorkommastellen := 0;
+ dezimalzeichen := 0;
+ number := 0.0;
+ p := ende + 1.
+
+betrachte aktuelles zeichen:
+ zeichencode := code (source SUB p).
+
+ziffer behandeln :
+ ziffer gefunden := TRUE;
+ number := (number + code to digit (zeichencode))/10.0;
+ vorkommastellen INCR 1.
+
+dezimalzeichen behandeln :
+ dezimalzeichen := zeichencode;
+ vorkommastellen := 0.
+
+wirkt als dezimalzeichen :
+ dezimalzeichen = 0 OR dezimalzeichen = zeichencode.
+
+erlaubtes zeichen :
+ ziffer OR punkt OR komma OR pseudoblank vor ziffer.
+
+pseudoblank vor ziffer :
+ zeichencode = pseudoblankcode AND pos (ziffern, source SUB (p+1) ) > 0.
+
+vorzeichen : plus OR minus.
+
+ziffer : zeichencode >= 48 AND zeichencode <= 57.
+
+plus : zeichencode = 43.
+
+minus : zeichencode = 45.
+
+punkt : zeichencode = 46.
+
+komma : zeichencode = 44.
+
+ignorieren :.
+
+END PROC pick up number;
+
+PROC replace number (TEXT VAR source, REAL CONST value, INT CONST where,
+ nachkommastellen) :
+
+ alte grenzen feststellen;
+ wenn noetig auf format der neuen zahl erweitern;
+ zahl in text umwandeln;
+ zahl ersetzen.
+
+alte grenzen feststellen :
+ REAL VAR dummy;
+ dummy := pick up number (source, where).
+
+wenn noetig auf format der neuen zahl erweitern :
+ INT VAR schreibanfang := min (anfang, neuer anfang),
+ schreibende := max (ende, neues ende).
+
+neuer anfang : where - vorkommazeichen + 1.
+
+vorkommazeichen : max (2,(decimal exponent (value) + 2)).
+
+neues ende : where + nachkommastellen + 1.
+
+zahl in text umwandeln :
+ worktext := text (value,stellen,nachkommastellen);
+ IF decimal exponent (value) < 0 THEN
+ change (worktext," .","0."); change (worktext," -.","-0.");
+ FI;
+ IF nachkommastellen = 0 THEN
+ replace (worktext, LENGTH worktext, " ")
+ FI;
+ WHILE LENGTH worktext < schreibende-schreibanfang+1 REP
+ worktext CAT " "
+ PER.
+
+zahl ersetzen :
+ WHILE LENGTH source < schreibende REP
+ source CAT " "
+ PER;
+ replace (source, schreibanfang, worktext) .
+
+stellen : where-schreibanfang+2+nachkommastellen.
+
+END PROC replace number;
+
+END PACKET pick;
+
+PACKET rechner DEFINES clear, push, result, do,
+ superklammer auf, superklammer zu,
+ empty, operand expected, dump:
+
+(********************************************************************)
+(* *)
+(* Rechenwerk fuer TeCal 13.09.84 *)
+(* *)
+(********************************************************************)
+
+LET plus = 1, minus = 2, mal = 3, durch = 4, hoch = 5,
+ monad minus = 6, klammer auf = 7, klammer zu = 8, gleich = 9;
+
+LET klammerpriostufe = 10, superklammerpriostufe = 500;
+
+LET tiefe = 30;
+
+REAL VAR dummy;
+BOOL VAR war operand;
+
+INT VAR operandentop, operatorentop, klammerprio, superklammerprio;
+
+ROW tiefe INT VAR operatorenstack;
+ROW tiefe REAL VAR operandenstack;
+
+PROC superklammer auf :
+ IF war operand THEN
+ pop (dummy)
+ FI;
+ superklammerprio INCR superklammerpriostufe;
+ klammerprio INCR superklammerpriostufe
+END PROC superklammer auf;
+
+PROC superklammer zu :
+ IF superklammerprio > 0 THEN
+ push (gleich);
+ superklammerprio DECR superklammerpriostufe;
+ klammerprio DECR superklammerpriostufe
+ FI;
+END PROC superklammer zu;
+
+INT PROC prio (INT CONST op):
+ klammer prio + elementar prio.
+
+elementar prio :
+ SELECT op OF
+ CASE plus,minus : 2
+ CASE mal,durch : 3
+ CASE hoch : 4
+ CASE monadminus : 6
+ CASE klammerzu : 0
+ CASE gleich : -klammerprio+superklammerprio
+ OTHERWISE errorstop ("prio("+text(op)+")"); 0
+ END SELECT
+END PROC prio;
+
+PROC clear :
+ operandentop := 0;
+ operatorentop := 0;
+ war operand := FALSE;
+ klammerprio := 0;
+ superklammerprio := 0;
+END PROC clear;
+
+PROC push (INT CONST op) :
+ enable stop;
+ IF war operand THEN
+ dyadischer operator oder gleich oder klammer zu
+ ELIF op = minus COR op = monad minus THEN
+ push monadisches minus
+ ELIF op = plus THEN
+ (* ignoriere monad plus *)
+ ELIF op = klammer auf THEN
+ IF stack zu voll THEN
+ errorstop ("Zuviele offene Klammern")
+ FI;
+ klammerprio INCR klammerpriostufe
+ ELSE
+ errorstop ("Zahl erwartet, letzten Operator ignoriert")
+ FI.
+
+dyadischer operator oder gleich oder klammer zu :
+ IF op = monad minus COR op = klammer auf THEN
+ (* errorstop ("Operator (+,-,*,/) vor Klammer auf fehlt")*)
+ ignore last operand;
+ push (op);
+ LEAVE push
+ ELSE
+ WHILE prio (op) <= stack top prio REPEAT
+ auswerten
+ PER;
+ push operator
+ FI.
+
+stack top prio :
+ IF operatorentop = 0 THEN -1
+ ELSE operator DIV 10
+ FI.
+
+stack zu voll :
+ operandentop >= tiefe - 4.
+
+auswerten :
+ REAL VAR op2;
+ SELECT operator MOD 10 OF
+ CASE monad minus : operand := - operand
+ CASE plus : pop (op2); operand INCR op2
+ CASE minus: pop (op2); operand DECR op2
+ CASE mal : pop (op2); operand := operand * op2
+ CASE durch: pop (op2); operand := operand / op2
+ CASE hoch : pop (op2); operand := operand ** op2
+ OTHERWISE
+(**) errorstop ("Im Opstack ("+text(operatorentop)+") gefunden : "+text(operator))
+ END SELECT;
+ war operand := TRUE;
+ operatorentop DECR 1.
+
+push operator :
+ IF op = klammerzu THEN
+ IF klammerprio > superklammerprio THEN
+ klammerprio DECR klammerpriostufe (* ELSE ignoriere ")" zuviel *)
+ FI
+ ELIF op = gleich THEN
+ klammerprio := superklammerprio;
+ ELSE
+ operatorentop INCR 1;
+ operator := prio (op) * 10 + op;
+ war operand := FALSE
+ FI.
+
+push monadisches minus :
+ operatorentop INCR 1;
+ operator := prio (monad minus) * 10 + monad minus.
+
+ignore last operand :
+ pop (dummy).
+
+END PROC push;
+
+PROC push (REAL CONST op) :
+ IF war operand THEN
+ operand := op; (* Operand wird ueberschrieben *)
+ ELSE
+ operandentop INCR 1;
+ operand := op;
+ war operand := TRUE
+ FI
+END PROC push;
+
+PROC pop (REAL VAR r) :
+ IF operandentop = 0 THEN
+ errorstop ("Operand fehlt")
+ ELSE r := operand;
+ operandentop DECR 1
+ FI;
+ war operand := FALSE
+END PROC pop;
+
+REAL PROC result :
+ IF operanden top > 0 THEN operand ELSE 0.0 FI
+END PROC result;
+
+BOOL PROC empty :
+ operandentop < 1
+END PROC empty;
+
+BOOL PROC operand expected :
+ NOT war operand
+END PROC operand expected;
+
+PROC do (REAL PROC (REAL CONST) f):
+ IF NOT war operand THEN
+ push (f(result))
+ ELSE
+ operand := f(operand)
+ FI
+END PROC do;
+
+PROC dump :
+ INT VAR x,y;
+ get cursor (x,y);
+ cursor (1,1);
+ INT VAR i;
+ put(operatorentop);put ("OPERATOREN");
+ FOR i FROM 1 UPTO operatorentop REP
+ put (text (operatorenstack(i),8));
+ PER;out (""5""); line;
+ put (operandentop);put ("OPERANDEN ");
+ FOR i FROM 1 UPTO operandentop REP
+ put (text (operandenstack(i),8,2));
+ PER;out (""5""); line;
+ put ("Klammern:");put(klammerprio);
+ put ("Superklammern:");put(superklammerprio);
+ IF war operand THEN put ("war operand") ELSE put ("war operator") FI;line;
+ cursor (x,y);
+END PROC dump;
+
+.
+operand : operandenstack (operandentop).
+operator: operatorenstack(operatorentop).
+
+END PACKET rechner;
+
+PACKET tecalfunctions DEFINES merke, prozentsatz, kommastellen,
+ prozent, evaluate, tecal :
+
+(********************************************************************)
+(* *)
+(* TeCal - Funktionen 15.09.84 *)
+(* *)
+(********************************************************************)
+
+LET operatorenliste = "+-*/^ ()=", gib ausdruck = ""15" gib wert : ";
+
+REAL VAR speicher := 0.0, percent := 14.0, displayed value := -1.0;
+INT VAR nachkommastellen := 2;
+
+INT VAR zeiger,dachpos; (* fuer evaluate *)
+TEXT VAR char; (* fuer evaluate *)
+
+TEXT VAR status line, anzeigetext;
+INT VAR anzeigestart, anzeigelaenge, memorystart, prozentstart;
+init status line;
+
+PROC evaluate (TEXT CONST formel):
+ evaluate (formel,1)
+END PROC evaluate;
+
+PROC evaluate (TEXT CONST formel, INT CONST ab wo):
+ enable stop;
+ zum formelanfang;
+ REP
+ zum naechsten relevanten zeichen;
+ IF formelende THEN LEAVE evaluate
+ FI;
+ symbol verarbeiten
+ UNTIL gleich zeichen verarbeitet PER.
+
+zum formelanfang :
+ dachpos := pos (formel,"^");
+ zeiger:= ab wo - 1.
+
+zum naechsten relevanten zeichen :
+ REP
+ zum naechsten wahrscheinlich relevanten zeichen
+ UNTIL formelende COR wirklich relevant PER.
+
+zum naechsten wahrscheinlich relevanten zeichen:
+ zeiger := pos (formel,"%","=",zeiger+1);
+ IF dachpos <> 0 CAND zeiger > dachpos THEN
+ zeiger := dachpos;
+ dachpos := pos (formel,"^",dachpos+1)
+ FI.
+
+formelende :
+ zeiger = 0.
+
+wirklich relevant :
+ char := formel SUB zeiger;
+ pos ("',.:;<", char) = 0.
+
+symbol verarbeiten :
+ IF ziffer THEN
+ push (abs(pick up number(formel,zeiger)));
+ zeiger := right range
+ ELSE
+ INT VAR op := pos (operatorenliste,char);
+ IF op > 0 THEN
+ push (op)
+ ELIF char = "%" THEN
+ do (REAL PROC (REAL CONST) prozent)
+ ELSE errorstop ("TeCal FEHLER : symbol verarbeiten")
+ FI
+ FI.
+
+gleichzeichen verarbeitet : char = "=".
+
+ziffer : pos ("0123456789",char) > 0.
+
+END PROC evaluate;
+
+PROC merke (REAL CONST wert) :
+ speicher := wert;
+ set anzeigetext (speicher);
+ replace (statusline,memorystart,anzeigetext);
+ show status line
+END PROC merke;
+
+PROC merke (INT CONST wert) :
+ merke (real (wert));
+END PROC merke;
+
+PROC prozentsatz (REAL CONST wert) :
+ percent := wert;
+ replace (statusline,prozentstart,text(percent,6,2));
+ show status line;
+END PROC prozentsatz;
+
+PROC prozentsatz (INT CONST wert) :
+ prozentsatz (real (wert));
+END PROC prozentsatz;
+
+PROC kommastellen (INT CONST anz stellen) :
+ nachkommastellen := max ( 0, min (anz stellen, 16)) ;
+ set anzeigetext (0.0);
+ replace (statusline,anzeigestart,anzeigetext);
+ merke (speicher);
+END PROC kommastellen;
+
+REAL PROC prozent (REAL CONST wovon) :
+ percent * wovon / 100.0
+END PROC prozent;
+
+REAL PROC runden (REAL CONST was) :
+ round (was,nachkommastellen)
+END PROC runden;
+
+PROC init status line :
+ statusline :=
+"$Anzeige: & __________._________ $ %%%.%%% Memory: ----------.--------- &"
+; change all (statusline,"$",""15"");
+ change all (statusline,"&",""14"");
+ anzeigestart := pos (statusline,"_");
+ anzeigelaenge:= pos (statusline," ",anzeigestart)-anzeigestart;
+ memorystart := pos (statusline,"-");
+ prozentstart := pos (statusline,"%");
+ set anzeigetext (0.0);
+ replace (statusline,anzeigestart,anzeigetext);
+ set anzeigetext (speicher);
+ replace (statusline,memorystart,anzeigetext);
+ replace (statusline,prozentstart,text(percent,6,2))
+END PROC init status line;
+
+PROC show status line :
+ cursor (1,y screen size); out (statusline);
+ displayed value := 0.0;
+ display value
+END PROC show status line;
+
+PROC display value :
+ IF displayed value <> result THEN
+ cursor (anzeigestart,y screen size);
+ set anzeigetext (result);
+ out (anzeigetext)
+ FI.
+
+END PROC display value;
+
+PROC get expression (TEXT VAR exp) :
+ cursor (1,yscreen size);
+ out (gib ausdruck);
+ (x screen size - 4 - LENGTH gib ausdruck) TIMESOUT " ";
+ out (""14""15""8" ");
+ cursor (LENGTH gib ausdruck, y screen size);
+ editget (exp);
+END PROC get expression;
+
+PROC set anzeigetext (REAL CONST r) :
+ IF decimal exponent (r) + nachkommastellen + 3 <= anzeigelaenge THEN
+ anzeigetext := text (r,anzeigelaenge,nachkommastellen);
+ IF decimal exponent (r) < 0 THEN
+ change (anzeigetext," .","0."); change (anzeigetext," -.","-0.");
+ FI;
+ IF nachkommastellen = 0 THEN
+ replace (anzeigetext, LENGTH anzeigetext, " ")
+ FI;
+ ELSE
+ anzeigetext := text (r,anzeigelaenge)
+ FI
+END PROC set anzeigetext;
+
+(*************** TeCal - Editor - Schnittstelle *****************)
+
+
+LET tecal tasten = "tq%()*+-/=CEFHKLMNRSVW^T"9"?",
+ funktionenliste = "LSCEFHKMNRVWtq%"9"T?" ,
+ zahlzeichen = "1234567890.,-+" ,
+ std tasten = "tqevw19dpgn"9"" ;
+
+LET kommando prozent = 15,
+ kommando clear = 3,
+ kommando einlesen = 4,
+ kommando formel = 5,
+ kommando recall = 7,
+ kommando lesen = 1,
+ kommando store = 8,
+ kommando naechste = 9,
+ kommando q = 14,
+ kommando runden = 10,
+ kommando schreiben= 2,
+ kommando umschalt = 13,
+ kommando ver sum = 11,
+ kommando fenster = 12,
+ kommando type = 17,
+ kommando help = 18;
+
+LET x screen size = 79,
+ y screen size = 24;
+
+FILE VAR tecal file;
+
+TEXT VAR record, input buffer;
+INT VAR record pos;
+
+PROC dateizeile lesen :
+ set busy indicator;
+ read record (tecal file, record);
+ record pos := col (tecal file)
+END PROC dateizeile lesen;
+
+PROC zahl aufsammeln :
+ dateizeile lesen;
+ REAL VAR zahl := pick up number (record, record pos);
+ IF last pick up ok THEN
+ push (zahl)
+ ELSE
+ errorstop ("Keine Zahl gefunden")
+ FI
+END PROC zahl aufsammeln;
+
+REAL PROC spaltensumme :
+
+ anfangsposition merken;
+ nach oben laufen und addieren;
+ zum anfang zurueck;
+ summe.
+
+nach oben laufen und addieren :
+ WHILE NOT oben angekommen REP
+ hochgehen und satz lesen;
+ record auswerten
+ PER.
+
+anfangsposition merken :
+ INT VAR alte zeile := line no (tecal file);
+ dateizeile lesen;
+ REAL VAR summe := pick up number (record,record pos);
+ BOOL VAR weiterlaufen := TRUE
+ IF NOT last pick up ok THEN
+ summe := 0.0
+ FI.
+
+zum anfang zurueck :
+ to line (tecalfile, alte zeile).
+
+hochgehen und satz lesen :
+ up (tecal file);
+ read record (tecal file, record).
+
+oben angekommen : line no (tecalfile) = 1 COR NOT weiterlaufen.
+
+record auswerten :
+ IF blankzeile THEN
+ weiterlaufen := TRUE
+ ELIF kein zahlzeichen THEN
+ weiterlaufen := FALSE
+ ELSE
+ summe INCR pick up number (record,record pos);
+ weiterlaufen := last pick up ok
+ FI.
+
+blankzeile : LENGTH record < record pos COR (record SUB record pos) = " ".
+
+kein zahlzeichen : pos (zahlzeichen,record SUB recordpos) = 0.
+
+END PROC spaltensumme;
+
+PROC tecal (TEXT CONST filename) :
+ type (""27"t");
+ edit (filename).
+
+END PROC tecal;
+
+PROC tecal :
+ IF groesster editor > 0
+ THEN tecal auf editfile
+ ELSE tecal (lastparam)
+ FI.
+
+tecal auf editfile :
+ FILE VAR f := editfile;
+ quit;
+ tecal (f) .
+
+END PROC tecal;
+
+PROC tecal (FILE VAR ed file) :
+ enable stop ;
+ open editor (groesster editor + 1, ed file, TRUE,
+ 1, 1, x screen size, y screen size - 1);
+ show status line;
+ edit (groesster editor, tecal tasten + std tasten,
+ PROC (TEXT CONST) tecal interpreter) .
+
+END PROC tecal;
+
+PROC tecal interpreter (TEXT CONST symbol) :
+
+ tecal file := editfile ;
+ nichts neu ;
+ INT VAR kommando := pos (operatorenliste,symbol);
+ IF kommando > 0 THEN
+ normale rechenoperation
+ ELSE kommando := pos (funktionenliste,symbol);
+ sonderfunktion
+ FI.
+
+normale rechenoperation :
+ IF operand expected CAND keine klammer auf THEN
+ zahl aufsammeln
+ FI;
+ push (kommando);
+ display value.
+
+keine klammer auf : symbol <> "(".
+
+sonderfunktion :
+ SELECT kommando OF
+ CASE kommando prozent : do prozent
+ CASE kommando clear : do clear
+ CASE kommando einlesen : do get
+ CASE kommando formel : do formelrechnung
+ CASE kommando ver sum : do spaltensumme
+ CASE kommando recall : do speicher lesen
+ CASE kommando lesen : do zahl aufsammeln
+ CASE kommando store : do speicher schreiben
+ CASE kommando naechste : do zur naechsten zahl
+ CASE kommando q : quit
+ CASE kommando runden : do runden
+ CASE kommando schreiben: do schreiben
+ CASE kommando umschalt : do tecal abschalten
+ CASE kommando type : do type displayed value
+(* CASE kommando hor sum : calculate ver sum*)
+ CASE kommando fenster : do fenster als zweiten operanden
+(* CASE kommando tab : calculate tab sum *)
+ CASE kommando help : do ("tecal auskunft")
+ OTHERWISE : std kommando interpreter (symbol)
+ END SELECT.
+
+do prozent :
+ IF operand expected THEN
+ zahl aufsammeln
+ FI;
+ do (REAL PROC (REAL CONST) prozent);
+ display value.
+
+do clear :
+ clear;
+ ueberschrift neu;
+ show status line.
+
+do get :
+ input buffer := "";
+ get expression (input buffer);
+ IF input buffer > " " THEN
+ disable stop;
+ superklammer auf;
+ evaluate (input buffer);
+ superklammer zu;
+ show status line;
+ enable stop;
+ ELSE
+ show status line
+ FI.
+
+do zahl aufsammeln :
+ zahl aufsammeln;
+ display value.
+
+do speicher schreiben :
+ merke (result);
+ show status line.
+
+do type displayed value :
+ set anzeigetext (result);
+ push(compress(anzeigetext)).
+
+do speicher lesen :
+ push (speicher);
+ display value.
+
+do spaltensumme :
+ push (spaltensumme);
+ display value.
+
+do formelrechnung :
+ dateizeile lesen;
+ disable stop;
+ superklammer auf;
+ evaluate (record);
+ superklammer zu;
+ enable stop;
+ display value;
+ IF enthaelt gleichzeichen CAND NOT empty THEN
+ ergebnis dahinter schreiben
+ ELSE
+ col (LENGTH record + 1)
+ FI.
+
+enthaelt gleichzeichen :
+ INT VAR gleichpos := pos (record,"=");
+ gleichpos > 0.
+
+ergebnis dahinter schreiben :
+ record pos := gleichpos + 2 + decimal exponent (result);
+ gleich pos := pos (record, ".", recordpos + 1) -1;
+ IF gleichpos > 0 THEN
+ record pos := gleichpos
+ FI;
+ ergebnis eintragen und dateizeile zurueckschreiben.
+
+ergebnis eintragen und dateizeile zurueckschreiben :
+ replace number (record, result, record pos, nachkommastellen);
+ write record (tecal file, record);
+ zeile neu;
+ col (record pos).
+
+do zur naechsten zahl :
+ dateizeile lesen;
+ record pos := pos (record,"0","9",record pos);
+ IF record pos = 0 THEN
+ record pos := LENGTH record + 1
+ FI;
+ col (record pos).
+
+do schreiben :
+ IF NOT empty THEN
+ dateizeile lesen;
+ ergebnis eintragen und dateizeile zurueckschreiben
+ FI.
+
+do runden :
+ IF NOT empty AND NOT operand expected THEN
+ do (REAL PROC (REAL CONST) runden)
+ FI.
+
+do fenster als zweiten operanden :
+ IF empty THEN
+ push (0.0)
+ ELSE
+ push (result)
+ FI.
+
+do tecal abschalten :
+ quit;
+ edit (tecalfile).
+
+END PROC tecal interpreter;
+
+clear;
+kommando auf taste legen ("t","tecal");
+(*kommando auf taste legen ("?","tecalauskunft");*)
+
+END PACKET tecal functions;
+
diff --git a/tecal/TeCal Auskunft b/tecal/TeCal Auskunft
new file mode 100644
index 0000000..9468265
--- /dev/null
+++ b/tecal/TeCal Auskunft
Binary files differ
diff --git a/tecal/TeCal.gen b/tecal/TeCal.gen
new file mode 100644
index 0000000..c670db7
--- /dev/null
+++ b/tecal/TeCal.gen
@@ -0,0 +1,55 @@
+LET tecal = "TeCal",
+ auskunft = "TeCal Auskunft";
+
+IF NOT exists ("TeCal") THEN fetch ("TeCal",archive) FI;
+IF NOT exists ("TeCal Auskunft") THEN fetch ("TeCal Auskunft",archive) FI;
+
+checkoff;
+insert tecal;
+insert auskunft;
+shorten auskunft file;
+forget ("Tecal.gen", quiet).
+
+insert tecal :
+ display (""13""10""15" TeCal-Rechner wird installiert "14""13""10"");
+ insert (tecal);
+ forget (tecal, quiet).
+
+insert auskunft:
+ display (""13""15" TeCal-Auskunftfile wird installiert "14""13""10"");
+ insert (auskunft).
+
+shorten auskunft file :
+ display (""13""10""15" TeCal-Auskunftfile wird komprimiert "14""13""10"");
+ disable stop;
+ DATASPACE VAR dspace := nil space;
+ FILE VAR file := sequential file ( input, auskunft),
+ shorted:= sequential file (output, dspace);
+ TEXT VAR buffer;
+ INT VAR i;
+
+ WHILE NOT eof (file)
+ REPEAT get line (file, buffer)
+ UNTIL (pos ("(*", buffer) > 0) OR is error PER;
+ i:= 1;
+ IF eof (file) COR text not transfered
+ THEN errorstop ("TeCal-Auskunftsfile ist bereits komprimiert!"13""10"" +
+ "'ESC <?>' funktioniert wahrscheinlich nicht."13""10"" +
+ "Bitte ORIGINAL Auskunftsfile von Diskette verwenden")
+ ELSE forget (auskunft, quiet);
+ copy (dspace, auskunft)
+ FI;
+ forget (dspace) .
+
+ text not transfered :
+ WHILE NOT eof (file)
+ REPEAT cout (i);
+ get line (file, buffer);
+ IF pos (buffer, "*)") > 0
+ THEN LEAVE text not transfered WITH FALSE
+ ELSE put line (shorted, buffer)
+ FI;
+ i INCR 1
+ UNTIL is error PER;
+ TRUE .
+
diff --git a/warenhaus/ls-MENUKARTE:Warenhaus b/warenhaus/ls-MENUKARTE:Warenhaus
new file mode 100644
index 0000000..414470a
--- /dev/null
+++ b/warenhaus/ls-MENUKARTE:Warenhaus
Binary files differ
diff --git a/warenhaus/ls-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter b/warenhaus/ls-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter
new file mode 100644
index 0000000..36de5ef
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter
@@ -0,0 +1,36 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus 0 **
+ ** **
+ ** Anpassung für Kartenleser an AKTRONIC-Adapter **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls warenhaus 0 DEFINES
+ interface anpassung,{} oeffne interface,{} schliesse interface,{} wert von interface,{} pressed key,{}(* --------------------------- *){} kanalkoppler,{} interfacechannel,{} init interfacechannel:{}TEXT CONST interface anpassung :: "mit Kartenleser an AKTRONIC-Adapter";{}LET max channel = 24,{} initcode = 26,{} endcode = 27,{} read code = 28;{}INT CONST nicht initialisiert code :: -3,{} interface error code :: -4,{}
+ kanal besetzt code :: -5;{}INT VAR interfacekanal :: 0;{}TEXT VAR puffer :: "";{}TASK VAR hardwaremanager :: niltask,{} interface task :: niltask,{} absender;{}DATASPACE VAR ds :: nilspace;{}INT PROC interfacechannel:{} interfacekanal{}END PROC interfacechannel;{}PROC oeffne interface (INT VAR status):{} puffer := "";{} forget (ds); ds := nilspace;{} pingpong (interfacetask, init code, ds, status);{} IF status > 0 THEN status DECR maxint FI;{}
+ forget (ds); ds := nilspace{}END PROC oeffne interface;{}INT PROC wert von interface:{} INT VAR wert;{} puffer CAT incharety (1);{} call (interface task, read code, ds, wert);{} wert.{}END PROC wert von interface;{}PROC schliesse interface:{} forget (ds); ds := nilspace;{} send (interface task, end code, ds);{} forget (ds); ds := nilspace{}END PROC schliesse interface;{}TEXT PROC pressed key:{} IF puffer = ""{} THEN incharety{} ELSE erstes pufferzeichen{} FI.{} erstes pufferzeichen:{}
+ TEXT VAR zeichen :: puffer SUB 1;{} puffer := subtext (puffer, 2);{} zeichen.{}END PROC pressed key;{}TEXT PROC pressed key (INT CONST warten):{} IF puffer = ""{} THEN incharety (warten){} ELSE erstes pufferzeichen{} FI.{} erstes pufferzeichen:{} TEXT VAR zeichen :: puffer SUB 1;{} puffer := subtext (puffer, 2);{} zeichen.{}END PROC pressed key;{}(*************************************************************************){}PROC kanalkoppler:{} enable stop;{} IF name (myself) <> "-"{}
+ THEN errorstop ("Unzulässiges Kommando!"){} ELSE warte auf anrufe{} FI.{} warte auf anrufe:{} INT VAR codenummer, antwort;{} disable stop;{} REP wait (ds, codenummer, absender);{} reagiere auf anruf;{} loesche ggf fehlerzustand{} PER.{} reagiere auf anruf:{} IF codenummer = initcode{} THEN kopple an interface;{} IF interface ist betriebsbereit{} THEN bearbeite weitere auftraege{} ELSE gib negative rueckmeldung{}
+ FI;{} gib kanal frei{} ELSE send (absender, nicht initialisiert code, ds){} FI.{} loesche ggf fehlerzustand:{} IF is error{} THEN clear error{} FI.{} kopple an interface:{} IF task (interfacekanal) <> niltask AND task (interfacekanal) <> myself{} THEN antwort := kanal besetzt code;{} ELSE continue (interfacekanal);{} teste interface{} FI.{} teste interface:{} leere puffer;{} out (""240"");{} IF incharety (1) <> ""{} THEN antwort := 0;{}
+ out (""176""){} ELSE antwort := interface error code{} FI.{} leere puffer:{} REP UNTIL incharety = "" PER.{} interface ist betriebsbereit: antwort = 0.{} gib negative rueckmeldung: send (absender, antwort, ds).{} gib kanal frei: break (quiet).{} ende: out (""176"").{} bearbeite weitere auftraege:{} REP pingpong (absender, antwort, ds, codenummer);{} IF codenummer = read code{} THEN hole wert von interface{}
+ ELIF codenummer < 0{} THEN send (absender, codenummer, ds);{} codenummer := endcode{} ELSE antwort := 0{} FI{} UNTIL codenummer = endcode PER;{} ende.{} hole wert von interface:{} out (""211"");{} antwort := code (incharety (1)).{}END PROC kanalkoppler;{}PROC init interfacechannel:{} teste auf zulaessigkeit;{} loesche interfacetask;{} erfrage interface kanal;{} generiere ggf neue interfacetask.{} teste auf zulaessigkeit:{}
+ enable stop;{} IF hardwaremanager <> niltask AND hardwaremanager <> myself{} THEN errorstop ("Dieses Kommando kann nur von der Task '" +{} name (hardwaremanager) + "' aus gegeben werden!"){} ELSE hardwaremanager := myself{} FI.{} loesche interfacetask:{} disable stop;{} end (interfacetask);{} IF is error THEN clear error FI;{} enable stop.{} generiere ggf neue interfacetask:{} IF interface kanal = 0{} THEN interface task := niltask;{} hardwaremanager := niltask{}
+ ELSE begin (PROC kanalkoppler, interface task);{} hardwaremanager := myself{} FI.{} erfrage interfacekanal:{} INT VAR kanalnummer;{} put ("Gib Interface - Kanal:");{} get (kanalnummer);{} set interfacechannel (kanalnummer).{}END PROC init interfacechannel;{}PROC set interface channel (INT CONST channel number):{} IF channel number < 0 OR channel number > max channel{} THEN errorstop ("Unzulässige Kanalnummer"){} ELSE interfacekanal := channel number{} FI{}END PROC set interface channel;{}
+BOOL OP <> (TASK CONST t1, t2):{} NOT (t1 = t2){}END OP <>;{}init interfacechannel{}END PACKET ls warenhaus 0{}
+
diff --git a/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endgerät b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endgerät
new file mode 100644
index 0000000..f108f7b
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endgerät
@@ -0,0 +1,36 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus 0 **
+ ** **
+ ** Anpassung für Kartenleser an MUFI als Endgerät **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls warenhaus 0 DEFINES
+ interface anpassung,{} oeffne interface,{} schliesse interface,{} wert von interface,{} pressed key,{}(* --------------------------- *){} kanalkoppler,{} interfacechannel,{} init interfacechannel:{}TEXT CONST interface anpassung :: "mit Kartenleser an MUFI als Endgerät";{}LET mufikennung = ""27""27"",{} max channel = 24,{} initcode = 26,{} endcode = 27,{} read code = 28;{}INT CONST nicht initialisiert code :: -3,{} interface error code :: -4,{}
+ kanal besetzt code :: -5;{}INT VAR interfacekanal :: 2;{}TEXT VAR puffer :: "";{}TASK VAR hardwaremanager :: niltask,{} interface task :: niltask,{} absender;{}DATASPACE VAR ds :: nilspace;{}INT PROC interfacechannel:{} interfacekanal{}END PROC interfacechannel;{}PROC oeffne interface (INT VAR status):{} puffer := "";{} forget (ds); ds := nilspace;{} pingpong (interfacetask, init code, ds, status);{} IF status > 0 THEN status DECR maxint FI;{}
+ forget (ds); ds := nilspace{}END PROC oeffne interface;{}INT PROC wert von interface:{} INT VAR wert;{} puffer CAT incharety (1);{} call (interface task, read code, ds, wert);{} wert.{}END PROC wert von interface;{}PROC schliesse interface:{} forget (ds); ds := nilspace;{} send (interface task, end code, ds);{} forget (ds); ds := nilspace{}END PROC schliesse interface;{}TEXT PROC pressed key:{} IF puffer = ""{} THEN incharety{} ELSE erstes pufferzeichen{} FI.{} erstes pufferzeichen:{}
+ TEXT VAR zeichen :: puffer SUB 1;{} puffer := subtext (puffer, 2);{} zeichen.{}END PROC pressed key;{}TEXT PROC pressed key (INT CONST warten):{} IF puffer = ""{} THEN incharety (warten){} ELSE erstes pufferzeichen{} FI.{} erstes pufferzeichen:{} TEXT VAR zeichen :: puffer SUB 1;{} puffer := subtext (puffer, 2);{} zeichen.{}END PROC pressed key;{}(*************************************************************************){}PROC kanalkoppler:{} enable stop;{} IF name (myself) <> "-"{}
+ THEN errorstop ("Unzulässiges Kommando!"){} ELSE warte auf anrufe{} FI.{} warte auf anrufe:{} INT VAR codenummer, antwort;{} disable stop;{} REP wait (ds, codenummer, absender);{} reagiere auf anruf;{} loesche ggf fehlerzustand{} PER.{} reagiere auf anruf:{} IF codenummer = initcode{} THEN kopple an interface;{} IF interface ist betriebsbereit{} THEN bearbeite weitere auftraege{} ELSE gib negative rueckmeldung{}
+ FI;{} gib kanal frei{} ELSE send (absender, nicht initialisiert code, ds){} FI.{} loesche ggf fehlerzustand:{} IF is error{} THEN clear error{} FI.{} kopple an interface:{} IF task (interfacekanal) <> niltask AND task (interfacekanal) <> myself{} THEN antwort := kanal besetzt code;{} ELSE continue (interfacekanal);{} teste interface{} FI.{} teste interface:{} leere puffer;{} out (mufikennung + "10");{} fange status;{} IF status = mufikennung + "00"{}
+ THEN antwort := 0;{} out (mufikennung + "1A18"22""){} ELSE antwort := interface error code{} FI.{} leere puffer:{} REP UNTIL incharety = "" PER.{} fange status:{} INT VAR zaehler;{} TEXT VAR status :: "";{} FOR zaehler FROM 1 UPTO 4 REP{} status CAT incharety (1){} PER.{} interface ist betriebsbereit: antwort = 0.{} gib negative rueckmeldung: send (absender, antwort, ds).{} gib kanal frei: break (quiet).{} ende: out (""25"").{}
+ bearbeite weitere auftraege:{} REP pingpong (absender, antwort, ds, codenummer);{} IF codenummer = read code{} THEN hole wert von interface{} ELIF codenummer < 0{} THEN send (absender, codenummer, ds);{} codenummer := endcode{} ELSE antwort := 0{} FI{} UNTIL codenummer = endcode PER;{} ende.{} hole wert von interface:{} out (""76"");{} antwort := code (incharety (1)).{}END PROC kanalkoppler;{}PROC init interfacechannel:{}
+ teste auf zulaessigkeit;{} loesche interfacetask;{} erfrage interface kanal;{} generiere ggf neue interfacetask.{} teste auf zulaessigkeit:{} enable stop;{} IF hardwaremanager <> niltask AND hardwaremanager <> myself{} THEN errorstop ("Dieses Kommando kann nur von der Task '" +{} name (hardwaremanager) + "' aus gegeben werden!"){} FI.{} loesche interfacetask:{} disable stop;{} end (interfacetask);{} IF is error THEN clear error FI;{} enable stop.{} generiere ggf neue interfacetask:{}
+ IF interface kanal = 0{} THEN interface task := niltask;{} hardwaremanager := niltask{} ELSE begin (PROC kanalkoppler, interface task);{} hardwaremanager := myself{} FI.{} erfrage interfacekanal:{} INT VAR kanalnummer;{} put ("Gib Interface - Kanal:");{} get (kanalnummer);{} set interfacechannel (kanalnummer).{}END PROC init interfacechannel;{}PROC set interface channel (INT CONST channel number):{} IF channel number < 0 OR channel number > max channel{} THEN errorstop ("Unzulässige Kanalnummer!"){}
+ ELSE interface kanal := channel number{} FI{}END PROC set interface channel;{}BOOL OP <> (TASK CONST t1, t2):{} NOT (t1 = t2){}END OP <>;{}init interfacechannel{}END PACKET ls warenhaus 0{}
+
diff --git a/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal
new file mode 100644
index 0000000..30c69da
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal
@@ -0,0 +1,30 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus 0 **
+ ** **
+ ** Anpassung für Kartenleser an MUFI im Terminalkanal **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls warenhaus 0 DEFINES
+ interface anpassung,{} oeffne interface,{} schliesse interface,{} wert von interface,{} pressed key:{}TEXT CONST interface anpassung :: "mit Kartenleser an MUFI im Terminalkanal";{}LET mufikennung = ""31""31"";{}INT CONST interface error code :: -4;{}TEXT CONST readcode :: mufikennung + "4C";{}TEXT VAR puffer :: "";{}PROC oeffne interface (INT VAR status):{} cursor (2,24);{} warte etwas;{} leere eingangspuffer;{} out (""27""27"10");{} fange antwort;{} IF antwort = ""27""27"00"{}
+ THEN status := 0;{} out (""27""27"1C" + hex (mufikennung)){} ELSE status := interface error code{} FI.{} warte etwas:{} pause (1); pause (1); pause (1); pause (1); pause (1).{} leere eingangspuffer:{} puffer := "";{} REP UNTIL incharety = "" PER.{} fange antwort:{} TEXT VAR antwort :: incharety (1);{} INT VAR i;{} FOR i FROM 1 UPTO 3 REP{} antwort CAT incharety (1){} PER.{}END PROC oeffne interface;{}INT PROC wert von interface:{} puffer CAT incharety (1);{}
+ out (readcode);{} fange mufikennung;{} dezimalwert (incharety (1), incharety (1)).{} fange mufikennung:{} REP puffer CAT incharety{} UNTIL pos (puffer, mufikennung) > 0 PER;{} change (puffer, mufikennung, "").{}END PROC wert von interface;{}PROC schliesse interface:{} cursor (2,24);{} out (mufikennung + "1C" + hex (""27""27"")){}END PROC schliesse interface;{}TEXT PROC pressed key:{} IF puffer = ""{} THEN incharety{} ELSE erstes pufferzeichen{} FI.{} erstes pufferzeichen:{}
+ TEXT VAR zeichen :: puffer SUB 1;{} puffer := subtext (puffer, 2);{} zeichen.{}END PROC pressed key;{}TEXT PROC pressed key (INT CONST warten):{} IF puffer = ""{} THEN incharety (warten){} ELSE erstes pufferzeichen{} FI.{} erstes pufferzeichen:{} TEXT VAR zeichen :: puffer SUB 1;{} puffer := subtext (puffer, 2);{} zeichen.{}END PROC pressed key;{}INT PROC dezimalwert (TEXT CONST zeichen 1, zeichen 2):{} 16 * pos (hexzeichen, zeichen 1) + pos (hexzeichen, zeichen 2).{}
+ hexzeichen: "123456789ABCDEF".{}END PROC dezimalwert;{}TEXT PROC hex (TEXT CONST zwei zeichen):{} hex (code (zwei zeichen SUB 1)) + hex (code (zwei zeichen SUB 2)){}END PROC hex;{}TEXT PROC hex (INT CONST wert):{} (hexzeichen SUB (wert DIV 16 + 1)) + (hexzeichen SUB (wert MOD 16 + 1)).{} hexzeichen: "0123456789ABCDEF".{}END PROC hex{}END PACKET ls warenhaus 0{}
+
diff --git a/warenhaus/ls-Warenhaus 0: ohne Kartenleser b/warenhaus/ls-Warenhaus 0: ohne Kartenleser
new file mode 100644
index 0000000..4912d64
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 0: ohne Kartenleser
@@ -0,0 +1,27 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus 0 **
+ ** **
+ ** Anpassung für den Betrieb ohne Kartenleser **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls warenhaus 0 DEFINES
+ interface anpassung,{} oeffne interface,{} schliesse interface,{} wert von interface,{} pressed key:{}TEXT CONST interface anpassung :: "ohne Kartenleser";{}PROC oeffne interface (INT VAR test):{} test := -6{}END PROC oeffne interface;{}PROC schliesse interface:{}END PROC schliesse interface;{}INT PROC wert von interface:{} INT VAR wert :: 0;{} wert{}END PROC wert von interface;{}TEXT PROC pressed key:{} incharety{}END PROC pressed key;{}TEXT PROC pressed key (INT CONST warten):{}
+ incharety (warten){}END PROC pressed key;{}END PACKET ls warenhaus 0{}
+
diff --git a/warenhaus/ls-Warenhaus 1 b/warenhaus/ls-Warenhaus 1
new file mode 100644
index 0000000..81fd8ee
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 1
@@ -0,0 +1,37 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus 1 **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET monitor alt DEFINES original monitor:
+ PROC original monitor:{} monitor{} END PROC originalmonitor{}END PACKET monitor alt;{}PACKET ls warenhaus 1 DEFINES{} zentrale,{} monitor,{} warenhaus direktstart,{} warenhaus hauptstelle,{} hauptstellenname:{}LET max kundenzahl = 31,{} min kundennummer = 129,{} kundendatei holen code = 100,{} kundendatei ergaenzen code = 200;{}TYPE KUNDENDATEN = STRUCT (TEXT nachname, vorname, geschlecht),{} KUNDENDATEI = ROW max kundenzahl KUNDENDATEN;{}{}
+BOUND KUNDENDATEN VAR kundendaten;{}BOUND KUNDENDATEI VAR bound kundendatei;{}KUNDENDATEI VAR kundendatei;{}DATASPACE VAR ds;{}TASK VAR absender,{} zentraltask :: niltask,{} hauptstelle :: niltask,{} direktstartmanager :: niltask;{}BOOL VAR mit direktstart :: FALSE,{} mit loeschen :: FALSE;{}INT VAR codenummer;{}PROC zentrale:{} enable stop;{} IF pos (name (myself), ".Zentrale") = 0{} THEN errorstop ("Unzulaessiger Befehl!"){}{}
+ FI;{} disable stop;{} REP wait (ds, codenummer, absender);{} bearbeite auftrag;{} send (absender, codenummer, ds);{} IF is error THEN clear error FI{} PER.{} bearbeite auftrag:{} IF codenummer = kundendatei holen code{} THEN hole kundendatei{} ELIF codenummer = kundendatei ergaenzen code{} THEN ergaenze kundendatei{} ELIF codenummer >= min kundennummer{} THEN lies kundendaten{} ELSE speichere kundendaten{} FI.{}END PROC zentrale;{}{}
+PROC hole kundendatei:{} bound kundendatei := ds;{} bound kundendatei := kundendatei{}END PROC hole kundendatei;{}PROC ergaenze kundendatei:{} INT VAR kundennummer;{} bound kundendatei := ds;{} FOR kundennummer FROM 1 UPTO max kundenzahl REP{} IF kundendatei [kundennummer].nachname = ""{} THEN kundendatei [kundennummer] := bound kundendatei [kundennummer]{} FI{} PER;{} init ds{}END PROC ergaenze kundendatei;{}PROC lies kundendaten:{} kundendaten := ds;{} kundendaten := kundendatei [platznummer].{}{}
+ platznummer: codenummer - min kundennummer + 1.{}END PROC lies kundendaten;{}PROC speichere kundendaten:{} kundendaten := ds;{} kundendatei [codenummer] := kundendaten;{} init ds{}END PROC speichere kundendaten;{}PROC warenhaus hauptstelle (BOOL CONST task soll hauptstelle sein):{} enable stop;{} IF task soll hauptstelle sein{} THEN mache task zur hauptstelle{} ELSE mache hauptstellenstatus rueckgaengig{} FI.{} mache task zur hauptstelle:{} sei eine hauptstelle;{} line (2);{}{}
+ IF NOT mit direktstart CAND yes ("Mit Direktstart"){} THEN warenhaus direktstart (TRUE){} ELSE global manager{} FI{}END PROC warenhaus hauptstelle;{}PROC sei eine hauptstelle:{} IF NOT (hauptstelle = niltask OR hauptstelle = myself){} THEN errorstop ("Hauptstelle ist bereits die Task '" +{} name (hauptstelle) + "'!"){} FI;{} disable stop;{} end (zentraltask);{} IF is error THEN clear error FI;{} enable stop;{} hauptstelle := niltask;{} begin (name (myself) + ".Zentrale", PROC zentrale, zentraltask);{}{}
+ hauptstelle := myself{}END PROC sei eine hauptstelle;{}PROC mache hauptstellenstatus rueckgaengig:{} IF NOT (hauptstelle = niltask OR hauptstelle = myself){} THEN errorstop ("Dieses Kommando darf nur in der Task '" +{} name (hauptstelle) + " gegeben werden!"){} FI;{} disable stop;{} end (zentraltask);{} IF is error THEN clear error FI;{} enable stop;{} hauptstelle := niltask;{} warenhaus direktstart (FALSE){}END PROC mache hauptstellenstatus rueckgaengig;{}PROC warenhaus direktstart (BOOL CONST wahl):{}{}
+ pruefe zulaessigkeit;{} mit direktstart := wahl;{} IF mit direktstart{} THEN direktstartmanager := myself;{} mit loeschen := yes ("Mit automatischem Löschen"){} ELSE direktstartmanager := niltask{} FI;{} global manager.{} pruefe zulaessigkeit:{} enable stop;{} IF NOT (direktstartmanager = niltask OR direktstartmanager = myself){} THEN errorstop ("Der Direktstart kann nur aus der Task '" +{} name (direktstartmanager) + "'geaendert werden!"){}{}
+ FI.{}END PROC warenhaus direktstart;{}TEXT PROC hauptstellenname:{} name (hauptstelle){}END PROC hauptstellenname;{}PROC monitor:{} IF mit direktstart{} THEN warenhaus monitor{} ELSE original monitor{} FI{}END PROC monitor;{}PROC warenhausmonitor:{} disable stop;{} INT VAR previous heapsize := heap size;{} REP command dialogue (TRUE);{} sysin (""); sysout ("");{} cry if not enough storage;{} reset dialog; erase menunotice;{} do ("warenhaus");{} IF is error{}{}
+ THEN clear error{} ELSE sitzungsende{} FI{} PER.{} sitzungsende:{} collect heap garbage if necessary;{} page;{} IF mit loeschen{} THEN break; end (myself){} ELSE end; break{} FI.{} collect heap garbage if necessary:{} IF heap size > previous heapsize + 10{} THEN collect heap garbage;{} previous heapsize := heap size{} FI.{} cry if not enough storage:{} INT VAR size, used;{} storage (size, used);{} IF used > size{} THEN out (""7"Speicher Engpass! Dateien loeschen!"13""10""){}{}
+ FI.{}END PROC warenhausmonitor;{}OP := (KUNDENDATEN VAR ziel, KUNDENDATEN CONST quelle):{} CONCR (ziel) := CONCR (quelle){}END OP :=;{}OP := (KUNDENDATEI VAR ziel, KUNDENDATEI CONST quelle):{} CONCR (ziel) := CONCR (quelle){}END OP :=;{}PROC init ds:{} forget (ds); ds := nilspace{}END PROC init ds;{}PROC initialisiere kundendatei:{} KUNDENDATEN CONST leer :: KUNDENDATEN : ("", "", "");{} INT VAR nr;{} FOR nr FROM 1 UPTO max kundenzahl REP{} kundendatei [nr] := leer{} PER{}END PROC initialisiere kundendatei;{}{}
+initialisiere kundendatei{}END PACKET ls warenhaus 1{}{}
+
diff --git a/warenhaus/ls-Warenhaus 2 b/warenhaus/ls-Warenhaus 2
new file mode 100644
index 0000000..7048aff
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 2
@@ -0,0 +1,112 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus 2 **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls warenhaus 2 DEFINES
+ max artikelzahl,{} max kundenzahl,{} min kundennummer,{} max kundennummer,{} min artikelnummer,{} max artikelnummer,{} filialverwaltung,{} initialisiere verwaltung,{} hole artikeldaten,{} speichere artikeldaten,{} registriere verkauf,{} hole kundendaten,{} speichere kundendaten,{} sichere filialdaten,{} lade filialdaten,{} hole bestelliste,{} hole auskunft ein:{}LET max filialen = 10,{} max artikel = 15,{}
+ max kunden = 31,{} min kundennr = 129,{} max kundennr = 159,{} min artikelnr = 1,{} max artikelnr = 15;{}LET zentrale kundendatei holen code = 100,{} zentrale kundendatei ergaenzen code = 200,{} filialdaten holen code = 201,{} filialdaten ergaenzen code = 202;{}INT CONST max artikelzahl :: max artikel,{} max kundenzahl :: max kunden,{} min kundennummer :: min kundennr,{} max kundennummer :: max kundennr,{}
+ min artikelnummer :: min artikelnr,{} max artikelnummer :: max artikelnr;{}TYPE ARTIKELDATEN = STRUCT (TEXT artikelname, REAL preis,{} INT mindestbestand, bestand),{} KUNDENDATEN = STRUCT (TEXT nachname, vorname, geschlecht),{} WARENDATEI = ROW max artikel ARTIKELDATEN,{} KUNDENDATEI = ROW max kunden KUNDENDATEN,{} EINKAUFSDATEI = ROW max kunden ROW max artikel INT,{} VERKAUFSDATEI = ROW max artikel INT,{} FILIALDATEN = STRUCT (WARENDATEI waren, KUNDENDATEI kunden,{}
+ EINKAUFSDATEI einkaeufe,{} VERKAUFSDATEI hitliste);{}KUNDENDATEI VAR kunde;{}WARENDATEI VAR artikel;{}EINKAUFSDATEI VAR einkaufsdatei;{}VERKAUFSDATEI VAR verkaufszahl;{}DATASPACE VAR ds;{}INT VAR codenummer, reply code;{}TASK VAR zentrale, verwaltung, absender;{}TEXT VAR hauptstelle :: "",{} filialnummer :: "0",{} filialverwaltungsname :: "";{}PROC filialverwaltung:{} enable stop;{}
+ IF pos (name (myself), ".Filialverwaltung") = 0{} THEN errorstop ("Unzulaessiger Befehl!"){} FI;{} disable stop;{} REP wait (ds, codenummer, absender);{} bearbeite auftrag;{} send (absender, 0, ds);{} IF is error THEN clear error FI{} PER.{} bearbeite auftrag:{} IF codenummer <= max artikel{} THEN artikeldaten speichern{} ELIF codenummer <= max kundennr{} THEN kauf registrieren{} ELIF codenummer <= max kundennr + max kunden{} THEN kundendaten speichern{}
+ ELIF codenummer = filialdaten holen code{} THEN filialdaten holen{} ELIF codenummer = filialdaten ergaenzen code{} THEN filialdaten ergaenzen; init ds{} ELIF codenummer = 256{} THEN sperre task{} FI.{} sperre task:{} call (absender, 256, ds, codenummer).{}END PROC filialverwaltung;{}PROC artikeldaten speichern:{} BOUND ARTIKELDATEN VAR artikeldaten :: ds;{} artikel [codenummer] := artikeldaten;{} init ds{}END PROC artikeldaten speichern;{}PROC kauf registrieren:{}
+ artikelnummer aus ds lesen;{} artikel [artikelnummer].bestand DECR 1;{} verkaufszahl [artikelnummer] INCR 1;{} IF kundennummer > 0{} THEN einkaufsdatei [kundennummer][artikelnummer] INCR 1{} FI.{} artikelnummer aus ds lesen:{} BOUND INT VAR nummer :: ds;{} INT CONST artikelnummer :: nummer,{} kundennummer :: codenummer - min kundennr + 1;{} init ds{}END PROC kauf registrieren;{}PROC kundendaten speichern:{} BOUND KUNDENDATEN VAR kundendaten :: ds;{} kunde [codenummer - min kundennr - max kunden + 1] := kundendaten{}
+END PROC kundendaten speichern;{}PROC filialdaten holen:{} init ds;{} BOUND FILIALDATEN VAR filialdaten :: ds;{} CONCR (filialdaten.waren) := CONCR (artikel);{} CONCR (filialdaten.kunden) := CONCR (kunde);{} CONCR (filialdaten.einkaeufe) := CONCR (einkaufsdatei);{} CONCR (filialdaten.hitliste) := CONCR (verkaufszahl){}END PROC filialdaten holen;{}PROC filialdaten ergaenzen:{} BOUND FILIALDATEN VAR neue daten :: ds;{} INT VAR kundennummer, artikelnummer;{} ergaenze artikeldatei und verkaufszahlen;{}
+ ergaenze kundendatei;{} ergaenze einkaufsdatei.{} ergaenze artikeldatei und verkaufszahlen:{} FOR artikelnummer FROM 1 UPTO max artikel REP{} verkaufszahl [artikelnummer] INCR neue daten.hitliste [artikelnummer];{} IF artikel [artikelnummer].artikelname = ""{} THEN artikel [artikelnummer] := neue daten.waren [artikelnummer]{} FI{} PER.{} ergaenze kundendatei:{} FOR kundennummer FROM 1 UPTO max kunden REP{} IF kunde [kundennummer].nachname = ""{} THEN kunde [kundennummer] := neue daten.kunden [kundennummer]{}
+ FI{} PER.{} ergaenze einkaufsdatei:{} FOR kundennummer FROM 1 UPTO max kunden REP{} FOR artikelnummer FROM 1 UPTO max artikel REP{} einkaufsdatei [kundennummer][artikelnummer]{} INCR neue daten.einkaeufe [kundennummer][artikelnummer]{} PER{} PER.{}END PROC filialdaten ergaenzen;{}OP := (ARTIKELDATEN VAR ziel, ARTIKELDATEN CONST quelle):{} CONCR (ziel) := CONCR (quelle){}END OP :=;{}OP := (KUNDENDATEN VAR ziel, KUNDENDATEN CONST quelle):{} CONCR (ziel) := CONCR (quelle){}
+END OP :=;{}PROC init ds:{} forget (ds); ds := nilspace{}END PROC init ds;{}(************************************************************************){}PROC initialisiere verwaltung:{} hauptstelle := hauptstellenname;{} zentrale := task (hauptstelle + ".Zentrale");{} filialnummer := text (channel (myself));{} filialverwaltungsname := hauptstellenname + ".Filialverwaltung ";{} begin (filialverwaltungsname + filialnummer,{} PROC filialverwaltung, verwaltung){}END PROC initialisiere verwaltung;{}
+PROC hole artikeldaten (INT CONST artikelnummer,{} TEXT VAR name, REAL VAR preis,{} INT VAR mindestbestand, bestand):{} enable stop;{} pruefe artikelnummer;{} hole daten.{} pruefe artikelnummer:{} INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{} IF artikelindex < 1 OR artikelindex > max artikel{} THEN errorstop ("Unzulässige Artikelnummer!"){} FI.{} hole daten:{} name := artikel [artikelindex].artikelname;{}
+ preis := artikel [artikelindex].preis;{} mindestbestand := artikel [artikelindex].mindestbestand;{} bestand := artikel [artikelindex].bestand.{}END PROC hole artikeldaten;{}PROC speichere artikeldaten (INT CONST artikelnummer,{} TEXT CONST name, REAL CONST preis,{} INT CONST mindestbestand, bestand):{} enable stop;{} pruefe artikelnummer;{} speichere daten;{} schicke kopie an verwaltung.{} pruefe artikelnummer:{}
+ INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{} IF artikelindex < 1 OR artikelindex > max artikel{} THEN errorstop ("Unzulässige Artikelnummer!"){} FI.{} speichere daten:{} artikel [artikelindex].artikelname := name;{} artikel [artikelindex].preis := preis;{} artikel [artikelindex].mindestbestand:= mindestbestand;{} artikel [artikelindex].bestand := bestand.{} schicke kopie an verwaltung:{} init ds;{} BOUND ARTIKELDATEN VAR artikeldaten :: ds;{}
+ artikeldaten := artikel [artikelindex];{} call (verwaltung, artikelindex, ds, reply code).{}END PROC speichere artikeldaten;{}PROC registriere verkauf (INT CONST kundennummer, artikelnummer):{} enable stop;{} pruefe daten;{} speichere daten;{} schicke kopie zur verwaltung.{} pruefe daten:{} INT VAR kundenindex :: kundennummer - min kundennr + 1,{} artikelindex :: artikelnummer - min artikelnr + 1;{} IF kundenindex < 0 OR kundenindex > max kunden{} THEN errorstop ("Unzulässige Kundennummer!"){}
+ ELIF artikelindex < 1 OR artikelindex > max artikel{} THEN errorstop ("Unzulässige Artikelnummer!"){} FI.{} speichere daten:{} IF artikel [artikelindex].bestand > 0{} THEN artikel [artikelindex].bestand DECR 1;{} verkaufszahl [artikelindex] INCR 1;{} IF kundenindex > 0{} THEN trage evtl in einkaufsdatei ein{} FI FI.{} trage evtl in einkaufsdatei ein:{} IF kunde [kundenindex].nachname = ""{} THEN kundenindex := 0{} ELSE einkaufsdatei [kundenindex][artikelindex] INCR 1{}
+ FI.{} schicke kopie zur verwaltung:{} init ds;{} BOUND INT VAR nummer :: ds;{} nummer := artikelindex;{} call (verwaltung, kundenindex + min kundennr - 1, ds, reply code).{}END PROC registriere verkauf;{}PROC hole kundendaten (INT CONST kundennummer,{} TEXT VAR nachname, vorname, geschlecht):{} enable stop;{} pruefe kundennummer;{} rufe zentrale an;{} uebergib die zentraldaten;{} IF aenderungen vorhanden{} THEN aktualisiere filialdaten{} FI;{} forget (ds).{}
+ pruefe kundennummer:{} INT CONST index :: kundennummer - min kundennr + 1;{} IF index < 1 OR index > max kunden{} THEN errorstop ("Unzulässige Kundennummer!"){} FI.{} rufe zentrale an:{} init ds;{} call (zentrale, kundennummer, ds, reply code).{} aenderungen vorhanden:{} (kunde [index].nachname <> nachname ) OR{} (kunde [index].vorname <> vorname ) OR{} (kunde [index].geschlecht <> geschlecht).{} aktualisiere filialdaten:{} kunde [index] := daten von zentrale;{}
+ call (verwaltung, kundennummer + max kunden, ds, reply code).{} uebergib die zentraldaten:{} BOUND KUNDENDATEN VAR daten von zentrale :: ds;{} nachname := daten von zentrale.nachname;{} vorname := daten von zentrale.vorname;{} geschlecht := daten von zentrale.geschlecht.{}END PROC hole kundendaten;{}PROC speichere kundendaten(INT CONST kundennummer,{} TEXT CONST nachname, vorname, geschlecht):{} enable stop;{} pruefe kundennummer;{} IF kundendaten geaendert{}
+ THEN speichere daten;{} schicke kopie an verwaltung und zentrale{} FI.{} pruefe kundennummer:{} IF kundennummer < min kundennr OR kundennummer > max kundennr{} THEN errorstop ("Unzulässige Kundennummer!"){} FI.{} kundendaten geaendert:{} INT CONST index :: kundennummer - min kundennr + 1;{} nachname <> kunde [index].nachname OR{} vorname <> kunde [index].vorname OR{} geschlecht <> kunde [index].geschlecht.{} speichere daten:{} kunde [index].nachname := nachname;{}
+ kunde [index].vorname := vorname;{} kunde [index].geschlecht := geschlecht.{} schicke kopie an verwaltung und zentrale:{} init ds;{} BOUND KUNDENDATEN VAR kundendaten :: ds;{} kundendaten := kunde [index];{} call (verwaltung, kundennummer + max kunden, ds, reply code);{} call (zentrale, kundennummer - min kundennr + 1, ds, reply code);{} forget (ds).{}END PROC speichere kundendaten;{}PROC sichere filialdaten (TEXT CONST name):{} enable stop;{} filialdaten holen;{}
+ type (ds, 1951);{} forget (name, quiet);{} copy (ds, name);{} forget (ds){}END PROC sichere filialdaten;{}PROC lade filialdaten (TEXT CONST name):{} enable stop;{} forget (ds);{} ds := old (name);{} IF type (ds) = 1951{} THEN filialdaten ergaenzen;{} kopie an verwaltung schicken;{} kopie der kundendatei an zentrale schicken{} ELSE errorstop ("'" + name + "' enthält keine Filialdaten!"){} FI.{} kopie an verwaltung schicken:{} call (verwaltung, filialdaten ergaenzen code, ds, reply code).{}
+ kopie der kundendatei an zentrale schicken:{} BOUND KUNDENDATEI VAR kundendatei :: ds;{} CONCR (CONCR (kundendatei)) := CONCR (kunde);{} call (zentrale, zentrale kundendatei ergaenzen code, ds, reply code).{}END PROC lade filialdaten;{}PROC hole bestelliste (FILE VAR f):{} bereite datei vor;{} schreibe daten in datei.{} bereite datei vor:{} forget("Nachbestellung",quiet);{} f := sequential file (output, "Nachbestellung");{} line (f);{} write (f, " Nachbestellungen für " +{}
+ invers ("Filiale " + filialnummer)+":");{} line;{} write (f, " ==================================================");{} line (f, 2);{} write (f, " | Art.Nr. | Artikelname | Anzahl |");{} line (f);{} write (f, " +----------+-------------------------+-----------+");{} line (f).{} schreibe daten in datei:{} INT VAR artikelnummer;{} FOR artikelnummer FROM 1 UPTO max artikel REP{} IF artikel[artikelnummer].bestand{}
+ < artikel[artikelnummer].mindestbestand{} THEN bestelle artikel nach{} FI{} PER;{} write (f, " +----------+-------------------------+-----------+");{} line (f).{} bestelle artikel nach:{} write (f, " | " + wirkliche artikelnummer + " | "{} + text (artikel [artikelnummer].artikelname, 23) + " | "{} + text (nachzubestellende anzahl, 6) + " |");{} line (f);{} artikel [artikelnummer].bestand{} := 2 * artikel [artikelnummer].mindestbestand.{}
+ wirkliche artikelnummer:{} text (artikelnummer + min artikelnr - 1, 5).{} nachzubestellende anzahl:{} 2 * artikel [artikelnummer].mindestbestand{} - artikel [artikelnummer].bestand.{}END PROC hole bestelliste;{}PROC hole auskunft ein (INT CONST codenummer, artikel oder kundennummer,{} FILE VAR f):{} enable stop;{} hauptstelle := hauptstellenname;{} SELECT codenummer OF CASE 66 : hitliste von zentrale (f){} CASE 67 : hitliste von filiale (f){}
+ CASE 68 : hitlisten aller filialen (f){} (* --------------------------------------------- *){} CASE 73 : artikelkaeuferliste von zentrale{} (artikel oder kundennummer, f){} CASE 74 : artikelkaeuferliste von filiale{} (artikel oder kundennummer, f){} CASE 75 : artikelkaeuferlisten aller filialen{} (artikel oder kundennummer, f){}
+ (* --------------------------------------------- *){} CASE 77 : kundenliste von zentrale (f){} CASE 78 : kundenliste von filiale (f){} CASE 79 : kundenlisten aller filialen (f){} (* --------------------------------------------- *){} CASE 84 : kundeneinkaufsliste von zentrale{} (artikel oder kundennummer, f){} CASE 85 : kundeneinkaufsliste von filiale{}
+ (artikel oder kundennummer, f){} CASE 86 : kundeneinkaufslisten aller filialen{} (artikel oder kundennummer, f){} (* --------------------------------------------- *){} CASE 89 : lageruebersicht von zentrale (f){} CASE 90 : lageruebersicht von filiale (f){} CASE 91 : lageruebersichten aller filialen (f){} (* --------------------------------------------- *){}
+ OTHERWISE errorstop ("Unzulässige Code - Nummer bei Auskunft!"){} END SELECT{}END PROC hole auskunft ein;{}PROC hitliste von zentrale (FILE VAR f):{} INT VAR filialnr;{} beginne mit eigener filiale;{} FOR filialnr FROM 1 UPTO max filialen REP{} TEXT CONST aktuelle verwaltung ::{} hauptstelle + ".Filialverwaltung " + text (filialnr);{} IF filialnr <> int (filialnummer) CAND{} exists task (aktuelle verwaltung){} THEN hole daten dieser filiale;{} schreibe daten in zentralliste{}
+ FI{} PER;{} werte zentralliste aus.{} beginne mit eigener filiale:{} WARENDATEI VAR zentrale warendatei;{} CONCR (zentrale warendatei) := CONCR (artikel);{} VERKAUFSDATEI VAR zentrale verkaufsdatei;{} CONCR (zentrale verkaufsdatei) := CONCR (verkaufszahl).{} hole daten dieser filiale:{} init ds;{} call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{} BOUND FILIALDATEN VAR aktuelle daten :: ds.{} schreibe daten in zentralliste:{} INT VAR i;{}
+ FOR i FROM 1 UPTO max artikel REP{} IF zentrale warendatei [i].artikelname = ""{} THEN zentrale warendatei [i] := aktuelle daten.waren [i]{} FI;{} zentrale verkaufsdatei [i] INCR aktuelle daten.hitliste [i]{} PER.{} werte zentralliste aus:{} forget (ds);{} forget ("Auskunft: Zentrale", quiet);{} f := sequential file (output, "Auskunft: Zentrale");{} line (f);{} write (f, " Zentrale Warenliste, geordnet nach Verkaufszahlen:");{} sortiere (zentrale warendatei, zentrale verkaufsdatei);{}
+ fuelle (f, zentrale warendatei, zentrale verkaufsdatei).{}END PROC hitliste von zentrale;{}PROC hitliste von filiale (FILE VAR f):{} bereite auskunftsdatei vor;{} kopiere artikeldatei und verkaufsdatei;{} sortiere (hilfsdatei artikel, hilfsdatei verkaufszahlen);{} fuelle (f,hilfsdatei artikel, hilfsdatei verkaufszahlen).{} kopiere artikeldatei und verkaufsdatei:{} WARENDATEI VAR hilfsdatei artikel;{} CONCR (hilfsdatei artikel) := CONCR (artikel);{} VERKAUFSDATEI VAR hilfsdatei verkaufszahlen;{}
+ CONCR (hilfsdatei verkaufszahlen) := CONCR (verkaufszahl).{} bereite auskunftsdatei vor:{} forget ("Auskunft: Filiale " + filialnummer, quiet);{} f := sequential file (output, "Auskunft: Filiale " + filialnummer);{} line (f);{} write (f, " Warenliste, geordnet nach Verkaufszahlen:").{}END PROC hitliste von filiale;{}PROC hitlisten aller filialen (FILE VAR f):{} WARENDATEI VAR aktuelle warendatei;{} VERKAUFSDATEI VAR aktuelle verkaufsdatei;{} INT VAR filialnr;{}
+ bereite auskunftsdatei vor;{} FOR filialnr FROM 1 UPTO max filialen REP{} TEXT CONST aktuelle verwaltung ::{} hauptstelle + ".Filialverwaltung " + text (filialnr);{} IF filialnr = int (filialnummer){} THEN nimm eigene daten{} ELIF exists task (aktuelle verwaltung){} THEN hole daten dieser filiale;{} arbeite mit diesen daten{} FI{} PER;{} forget (ds).{} bereite auskunftsdatei vor:{} forget ("Auskunft: Alle Filialen", quiet);{} f := sequential file (output, "Auskunft: Alle Filialen");{}
+ line (f).{} nimm eigene daten:{} CONCR (aktuelle warendatei) := CONCR (artikel);{} CONCR (aktuelle verkaufsdatei) := CONCR (verkaufszahl);{} sortiere und fuelle.{} sortiere und fuelle:{} write (f, " Warenliste von " + invers ("Filiale " + text (filialnr)){} + ", geordnet nach Verkaufszahlen:");{} sortiere (aktuelle warendatei, aktuelle verkaufsdatei);{} fuelle (f,aktuelle warendatei, aktuelle verkaufsdatei).{} hole daten dieser filiale:{} init ds;{} call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{}
+ BOUND FILIALDATEN VAR aktuelle daten :: ds.{} arbeite mit diesen daten:{} CONCR (aktuelle warendatei) := CONCR (aktuelle daten.waren);{} CONCR (aktuelle verkaufsdatei) := CONCR (aktuelle daten.hitliste);{} sortiere und fuelle.{}END PROC hitlisten aller filialen;{}PROC sortiere (WARENDATEI VAR warendatei, VERKAUFSDATEI VAR stueckzahl):{} INT VAR i,j;{} FOR i FROM 1 UPTO max artikel - 1 REP{} FOR j FROM i + 1 UPTO max artikel REP{} IF stueckzahl [i] < stueckzahl [j]{} THEN vertausche{}
+ FI{} PER PER.{} vertausche:{} INT CONST hilfsint :: stueckzahl [i];{} ARTIKELDATEN CONST hilfsartikel :: warendatei [i];{} stueckzahl [i] := stueckzahl [j];{} warendatei [i] := warendatei [j];{} stueckzahl [j] := hilfsint;{} warendatei [j] := hilfsartikel.{}END PROC sortiere;{}PROC fuelle (FILE VAR f, WARENDATEI VAR warendat, VERKAUFSDATEI VAR anzahl):{} INT VAR nummer, platz :: 0;{} bereite datei vor;{} schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f," ============================================================");{}
+ line (f,2);{} write(f," | Platz | Verk.Anzahl | Artikelname | Preis |");{} line (f);{} write(f," +-------+-------------+------------------------+-----------+");{} line (f).{}schreibe daten in datei:{} FOR nummer FROM 1 UPTO max artikel REP{} IF warendat [nummer].artikelname <> ""{} THEN schreibe in datei; line (f){} FI{} PER;{} write(f," +-------+-------------+------------------------+-----------+");{} line (f,3).{}schreibe in datei:{} platz INCR 1;{} write (f, " |" + text (platz, 5) + " |"{}
+ + text (anzahl [nummer], 9) + " | "{} + text (warendat [nummer].artikelname, 22) + " | "{} + text (warendat [nummer].preis,8,2) + " |").{}END PROC fuelle;{}PROC artikelkaeuferliste von zentrale (INT CONST artikelnummer, FILE VAR f):{} INT VAR filialnr;{} pruefe artikelnummer;{} beginne mit eigener filiale;{} FOR filialnr FROM 1 UPTO max filialen REP{} TEXT CONST aktuelle verwaltung ::{} hauptstelle + ".Filialverwaltung " + text (filialnr);{}
+ IF filialnr <> int (filialnummer) CAND{} exists task (aktuelle verwaltung){} THEN hole daten dieser filiale;{} schreibe daten in zentralliste{} FI{} PER;{} werte zentralliste aus.{} pruefe artikelnummer:{} INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{} IF artikelindex < 1 OR artikelindex > max artikel{} THEN errorstop ("Unzulässige Artikelnummer!"){} FI.{} beginne mit eigener filiale:{} TEXT VAR aktueller artikelname :: artikel [artikelindex].artikelname;{}
+ KUNDENDATEI VAR hilfsdatei;{} CONCR (hilfsdatei) := CONCR (kunde);{} ROW max kunden INT VAR kaeufe;{} INT VAR i;{} FOR i FROM 1 UPTO max kunden REP{} kaeufe [i] := einkaufsdatei [i][artikelindex]{} PER.{} hole daten dieser filiale:{} init ds;{} call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code).{} schreibe daten in zentralliste:{} BOUND FILIALDATEN VAR aktuelle daten :: ds;{} IF aktueller artikelname = ""{} THEN aktueller artikelname{}
+ := aktuelle daten.waren [artikelindex].artikelname{} FI;{} FOR i FROM 1 UPTO max kunden REP{} kaeufe [i] INCR aktuelle daten.einkaeufe [i][artikelindex];{} IF hilfsdatei [i].nachname = ""{} THEN hilfsdatei [i] := aktuelle daten.kunden [i]{} FI{} PER.{} werte zentralliste aus:{} forget (ds);{} forget ("Auskunft: Zentrale", quiet);{} f := sequential file (output, "Auskunft: Zentrale");{} line (f);{} IF aktueller artikelname = ""{} THEN write (f, " Der Artikel Nr. " + text (artikelindex){}
+ + " wird in keiner Filiale geführt.");{} line (f);{} write(f,{} " ============================================================");{} line (f,3);{} ELSE write (f, " Gesamtkäuferliste des Artikels "{} + invers (aktueller artikelname) + ":");{} fuelle (f, hilfsdatei, kaeufe){} FI.{}END PROC artikelkaeuferliste von zentrale;{}PROC artikelkaeuferliste von filiale (INT CONST artikelnummer, FILE VAR f):{}
+ pruefe artikelnummer;{} kopiere einkaufszahlen in hilfsliste;{} erstelle filialliste.{} pruefe artikelnummer:{} INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{} IF artikelindex < 1 OR artikelindex > max artikel{} THEN errorstop ("Unzulässige Artikelnummer!"){} FI.{} kopiere einkaufszahlen in hilfsliste:{} ROW max kunden INT VAR kaeufe;{} INT VAR i;{} FOR i FROM 1 UPTO max kunden REP{} kaeufe [i] := einkaufsdatei [i][artikelindex]{} PER.{} erstelle filialliste:{}
+ forget ("Auskunft: Filiale " + filialnummer, quiet);{} f := sequential file (output, "Auskunft: Filiale " + filialnummer);{} line (f);{} IF artikel [artikelindex].artikelname = ""{} THEN write (f, " Der Artikel Nr. " + text (artikelindex){} + " wird in dieser Filiale nicht geführt.");{} line (f);{} write(f,{} " ============================================================");{} line (f,3);{} ELSE write (f, " Käufer des Artikels "{}
+ + invers (artikel [artikelindex].artikelname){} + ":");{} fuelle (f, kunde, kaeufe){} FI.{}END PROC artikelkaeuferliste von filiale;{}PROC artikelkaeuferlisten aller filialen(INT CONST artikelnummer,FILE VAR f):{} INT VAR i, filialnr;{} ROW max kunden INT VAR kaeufe;{} pruefe artikelnummer;{} bereite datei vor;{} FOR filialnr FROM 1 UPTO max filialen REP{} TEXT CONST aktuelle verwaltung ::{} hauptstelle + ".Filialverwaltung " + text (filialnr);{}
+ IF filialnr = int (filialnummer){} THEN kopiere eigene einkaufszahlen in hilfsliste;{} schreibe eigene daten in auskunftsdatei{} ELIF exists task (aktuelle verwaltung){} THEN hole daten dieser filiale;{} schreibe daten in auskunftsdatei{} FI{} PER;{} forget (ds).{} pruefe artikelnummer:{} INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{} IF artikelindex < 1 OR artikelindex > max artikel{} THEN errorstop ("Unzulässige Artikelnummer!"){}
+ FI.{} bereite datei vor:{} forget ("Auskunft: Alle Filialen", quiet);{} f := sequential file (output, "Auskunft: Alle Filialen");{} line (f).{} kopiere eigene einkaufszahlen in hilfsliste:{} FOR i FROM 1 UPTO max kunden REP{} kaeufe [i] := einkaufsdatei [i][artikelindex]{} PER.{} schreibe eigene daten in auskunftsdatei:{} IF artikel [artikelindex].artikelname = ""{} THEN write (f, " Der Artikel Nr. " + text (artikelindex){} + " wird in "{}
+ + invers ("Filiale " + filialnummer){} + " nicht geführt.");{} line (f);{} write(f,{} " ============================================================");{} line (f,3){} ELSE write (f, " Käufer des Artikels '"{} + artikel [artikelindex].artikelname{} + "' in " + invers ("Filiale " + filialnummer) + ":");{} fuelle(f, kunde, kaeufe){} FI.{} hole daten dieser filiale:{}
+ init ds;{} call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{} BOUND FILIALDATEN VAR aktuelle daten :: ds;{} TEXT CONST aktueller artikelname{} := aktuelle daten.waren [artikelindex].artikelname{} FOR i FROM 1 UPTO max kunden REP{} kaeufe [i] := aktuelle daten.einkaeufe [i][artikelindex];{} PER.{} schreibe daten in auskunftsdatei:{} IF aktueller artikelname = ""{} THEN write (f, " Der Artikel Nr. " + text (artikelindex){}
+ + " wird in "{} + invers ("Filiale " + text (filialnr)){} + " nicht geführt.");{} line (f);{} write(f,{} " ============================================================");{} line (f,3){} ELSE write (f, " Käufer des Artikels '"{} + aktueller artikelname{} + "' in " + invers ("Filiale " + text(filialnr)) + ":");{} fuelle(f, aktuelle daten.kunden, kaeufe){}
+ FI.{}END PROC artikelkaeuferlisten aller filialen;{}PROC fuelle (FILE VAR f, KUNDENDATEI CONST kundenliste,{} ROW max kunden INT CONST einkaufszahlen):{} INT VAR kundennummer;{} bereite datei vor;{} schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f," ============================================================");{} line (f, 2);{} write(f," | Anzahl | Nachname, Vorname | Geschlecht |");{} line (f);{} write(f," +--------+------------------------------------+------------+");{}
+ line (f).{}schreibe daten in datei:{} FOR kundennummer FROM 1 UPTO max kunden REP{} IF einkaufszahlen [kundennummer] > 0{} THEN schreibe in datei; line (f);{} FI{} PER;{} write(f," +--------+------------------------------------+------------+");{} line (f, 3).{}schreibe in datei:{} write(f," |" + text(einkaufszahlen [kundennummer], 5) + " | "{} + text(kundenliste [kundennummer].nachname + ",", 17) + " "{} + text(kundenliste [kundennummer].vorname, 16) + " | ");{}
+ IF kundenliste [kundennummer].geschlecht = "m"{} THEN write (f, " männlich |"){} ELIF kundenliste [kundennummer].geschlecht = "w"{} THEN write (f, " weiblich |"){} ELSE write (f, " |"){} FI.{}END PROC fuelle;{}PROC kundenliste von zentrale (FILE VAR f):{} hole kundenliste von zentrale;{} bereite datei vor;{} schreibe daten in datei.{} hole kundenliste von zentrale:{} init ds;{} call (zentrale, zentrale kundendatei holen code, ds, reply code);{} BOUND KUNDENDATEI VAR zentrale kundenliste :: ds.{}
+ bereite datei vor:{} forget ("Auskunft: Zentrale", quiet);{} f := sequential file (output, "Auskunft: Zentrale");{} line (f);{} write (f, " Zentrale Kundenliste:").{} schreibe daten in datei:{} fuelle (f, zentrale kundenliste);{} forget (ds).{}END PROC kundenliste von zentrale;{}PROC kundenliste von filiale (FILE VAR f):{} bereite datei vor;{} schreibe daten in datei.{} bereite datei vor:{} forget ("Auskunft: Filiale " + filialnummer, quiet);{} f := sequential file (output, "Auskunft: Filiale " + filialnummer);{}
+ line (f);{} write (f," Kundenliste:").{} schreibe daten in datei:{} fuelle (f, kunde).{}END PROC kundenliste von filiale;{}PROC kundenlisten aller filialen (FILE VAR f):{} INT VAR filialnr;{} bereite datei vor;{} FOR filialnr FROM 1 UPTO max filialen REP{} TEXT CONST aktuelle verwaltung ::{} hauptstelle + ".Filialverwaltung " + text (filialnr);{} IF filialnr = int (filialnummer){} THEN schreibe eigene daten in auskunftsdatei{} ELIF exists task (aktuelle verwaltung){}
+ THEN hole daten dieser filiale;{} schreibe daten dieser filiale in auskunftsdatei{} FI{} PER.{} bereite datei vor:{} forget ("Auskunft: Alle Filialen", quiet);{} f := sequential file (output, "Auskunft: Alle Filialen");{} line (f).{} schreibe eigene daten in auskunftsdatei:{} schreibe ueberschrift;{} fuelle (f, kunde).{} hole daten dieser filiale:{} init ds;{} call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{} BOUND FILIALDATEN VAR aktuelle filialdaten :: ds.{}
+ schreibe daten dieser filiale in auskunftsdatei:{} schreibe ueberschrift;{} fuelle (f, aktuelle filialdaten.kunden).{} schreibe ueberschrift:{} write (f, " Kundenliste für " +{} invers ("Filiale " + text (filialnr)) + ":").{}END PROC kundenlisten aller filialen;{}PROC fuelle (FILE VAR f, KUNDENDATEI VAR kundendatei):{} INT VAR kundennummer;{} bereite datei vor;{} schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f," ============================================================");{}
+ line (f,2);{} write(f," | Kun.Nr.| Nachname, Vorname | Geschlecht |");{} line (f);{} write(f," +--------+------------------------------------+------------+");{} line (f).{}schreibe daten in datei:{} FOR kundennummer FROM 1 UPTO max kunden REP{} IF kundendatei [kundennummer].nachname <> ""{} THEN schreibe in datei; line (f){} FI{} PER;{} write(f," +--------+------------------------------------+------------+");{} line (f, 3).{}schreibe in datei:{} write (f, " |" + text (kundennummer + min kundennummer - 1, 6) + " | "{}
+ + text (kundendatei [kundennummer].nachname + ",", 17) + " "{} + text (kundendatei [kundennummer].vorname, 16) + " | ");{} IF kundendatei [kundennummer].geschlecht = "m"{} THEN write (f, " männlich |"){} ELIF kundendatei [kundennummer].geschlecht = "w"{} THEN write (f, " weiblich |"){} ELSE write (f, " |"){} FI.{}END PROC fuelle;{}PROC kundeneinkaufsliste von zentrale (INT CONST kundennummer, FILE VAR f):{} INT VAR filialnr;{}
+ pruefe kundennummer;{} beginne mit eigener filiale;{} FOR filialnr FROM 1 UPTO max filialen REP{} TEXT CONST aktuelle verwaltung ::{} hauptstelle + ".Filialverwaltung " + text (filialnr);{} IF filialnr <> int (filialnummer) CAND{} exists task (aktuelle verwaltung){} THEN hole daten dieser filiale;{} schreibe daten in zentralliste{} FI{} PER;{} werte zentralliste aus.{} pruefe kundennummer:{} INT CONST kundenindex :: kundennummer - min kundennr + 1;{}
+ IF kundenindex < 1 OR kundenindex > max kunden{} THEN errorstop ("Unzulässige Kundennummer!"){} FI.{} beginne mit eigener filiale:{} KUNDENDATEN VAR aktueller kunde :: kunde [kundenindex];{} WARENDATEI VAR hilfsdatei;{} CONCR (hilfsdatei) := CONCR (artikel);{} ROW max artikel INT VAR kaeufe;{} INT VAR i;{} FOR i FROM 1 UPTO max artikel REP{} kaeufe [i] := einkaufsdatei [kundenindex][i]{} PER.{} hole daten dieser filiale:{} init ds;{} call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code).{}
+ schreibe daten in zentralliste:{} BOUND FILIALDATEN VAR aktuelle daten :: ds;{} IF aktueller kunde.nachname = ""{} THEN aktueller kunde := aktuelle daten.kunden [kundenindex]{} FI;{} FOR i FROM 1 UPTO max artikel REP{} kaeufe [i] INCR aktuelle daten.einkaeufe [kundenindex][i];{} IF hilfsdatei [i].artikelname = ""{} THEN hilfsdatei [i] := aktuelle daten.waren [i]{} FI{} PER.{} werte zentralliste aus:{} forget (ds);{} forget ("Auskunft: Zentrale", quiet);{}
+ f := sequential file (output, "Auskunft: Zentrale");{} line (f);{} IF aktueller kunde.nachname = ""{} THEN write (f, " Ein Kunde mit Nr. " + text (kundenindex){} + " ist in keiner Filiale bekannt.");{} line (f);{} write(f,{} " ============================================================");{} line (f,3);{} ELSE write (f, " Gesamteinkaufsliste " + anrede{} + invers (aktueller kundenname) + ":");{}
+ fuelle (f, hilfsdatei, kaeufe){} FI.{} anrede:{} IF aktueller kunde.geschlecht = "m"{} THEN "des Kunden "{} ELIF aktueller kunde.geschlecht = "w"{} THEN "der Kundin "{} ELSE "von "{} FI.{} aktueller kundenname:{} (aktueller kunde.vorname SUB 1) + ". " + aktueller kunde.nachname.{}END PROC kundeneinkaufsliste von zentrale;{}PROC kundeneinkaufsliste von filiale (INT CONST kundennummer, FILE VAR f):{} pruefe kundennummer;{} erstelle filialliste.{}
+ pruefe kundennummer:{} INT CONST kundenindex :: kundennummer - min kundennr + 1;{} IF kundenindex < 1 OR kundenindex > max kunden{} THEN errorstop ("Unzulässige Kundennummer!"){} FI.{} erstelle filialliste:{} forget ("Auskunft: Filiale " + filialnummer, quiet);{} f := sequential file (output, "Auskunft: Filiale " + filialnummer);{} line (f);{} IF kunde [kundenindex].nachname = ""{} THEN schicke leere liste zurueck{} ELSE schreibe dateikopf;{} fuelle (f, artikel, einkaufsdatei [kundenindex]){}
+ FI.{} schicke leere liste zurueck:{} write (f," Ein Kunde mit Nr. " + text (kundennummer) + " ist in "{} + "dieser Filiale nicht bekannt.");{} line (f);{} write (f,{} " ============================================================");{} line (f,3).{} schreibe dateikopf:{} write (f, " Einkaufsliste " + anrede +{} invers ((kunde [kundenindex].vorname SUB 1) + ". " +{} kunde [kundenindex].nachname) + ":").{} anrede:{} IF kunde [kundenindex].geschlecht = "m"{}
+ THEN "des Kunden "{} ELIF kunde [kundenindex].geschlecht = "w"{} THEN "der Kundin "{} ELSE "von "{} FI.{}END PROC kundeneinkaufsliste von filiale;{}PROC kundeneinkaufslisten aller filialen (INT CONST kundennummer,FILE VAR f):{} INT VAR filialnr;{} pruefe kundennummer;{} bereite datei vor;{} FOR filialnr FROM 1 UPTO max filialen REP{} TEXT CONST aktuelle verwaltung ::{} hauptstelle + ".Filialverwaltung " + text (filialnr);{} IF filialnr = int (filialnummer){}
+ THEN schreibe eigene daten in auskunftsdatei{} ELIF exists task (aktuelle verwaltung){} THEN hole daten dieser filiale;{} schreibe daten in auskunftsdatei{} FI{} PER;{} forget (ds).{} pruefe kundennummer:{} INT CONST kundenindex :: kundennummer - min kundennr + 1;{} IF kundenindex < 1 OR kundenindex > max kunden{} THEN errorstop ("Unzulässige Kundennummer!"){} FI.{} bereite datei vor:{} forget ("Auskunft: Alle Filialen", quiet);{} f := sequential file (output, "Auskunft: Alle Filialen");{}
+ line (f).{} schreibe eigene daten in auskunftsdatei:{} IF kunde [kundenindex].nachname = ""{} THEN write (f," Ein Kunde mit Nr. " + text (kundennummer){} + " ist in " + invers ("Filiale " + filialnummer){} + " nicht bekannt.");{} line (f);{} write(f,{} " ============================================================");{} line (f,3){} ELSE write (f, " Einkaufsliste " + anrede hier +{} (kunde [kundenindex].vorname SUB 1) + ". " +{}
+ kunde [kundenindex].nachname +{} " in " + invers ("Filiale " + filialnummer) + ":");{} fuelle (f, artikel, einkaufsdatei [kundenindex]){} FI.{} anrede hier:{} IF kunde [kundenindex].geschlecht = "m"{} THEN "des Kunden "{} ELIF kunde [kundenindex].geschlecht = "w"{} THEN "der Kundin "{} ELSE "von "{} FI.{} hole daten dieser filiale:{} init ds;{} call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{}
+ BOUND FILIALDATEN VAR aktuelle daten :: ds;{} KUNDENDATEN CONST aktueller kunde := aktuelle daten.kunden [kundenindex].{} schreibe daten in auskunftsdatei:{} IF aktueller kunde.nachname = ""{} THEN write (f," Ein Kunde mit Nr. " + text (kundennummer){} + " ist in " + invers ("Filiale " + text (filialnr)){} + " nicht bekannt.");{} line (f);{} write(f,{} " ============================================================");{}
+ line (f,3){} ELSE write (f, " Einkaufsliste " + anrede +{} (aktueller kunde.vorname SUB 1) + ". " +{} aktueller kunde.nachname +{} " in " + invers ("Filiale " + text (filialnr)) + ":");{} fuelle (f, aktuelle daten.waren,{} aktuelle daten.einkaeufe [kundenindex]){} FI.{} anrede:{} IF aktueller kunde.geschlecht = "m"{} THEN "des Kunden "{} ELIF aktueller kunde.geschlecht = "w"{}
+ THEN "der Kundin "{} ELSE "von "{} FI.{}END PROC kundeneinkaufslisten aller filialen;{}PROC fuelle (FILE VAR f, WARENDATEI CONST warendatei,{} ROW max artikel INT CONST einkaufszahlen):{} INT VAR artikelnummer;{} REAL VAR gesamtpreis, summe :: 0.0;{} bereite datei vor;{} schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f," ============================================================");{} line (f,2);{} write(f," | Art.Nr.| Artikelname | Anzahl | Preis | Gesamt |");{}
+ line (f);{} write(f," +--------+-------------------+--------+---------+----------+");{} line (f).{}schreibe daten in datei:{} FOR artikelnummer FROM 1 UPTO max artikel REP{} IF einkaufszahlen [artikelnummer] > 0{} THEN schreibe in datei; line (f){} FI{} PER;{} write(f," +--------+-------------------+--------+---------+----------+");{} line (f);{} write(f," Summe: " +{} text (summe,8,2));{}
+ line (f, 3).{}schreibe in datei:{} gesamtpreis := real (einkaufszahlen [artikelnummer]) *{} warendatei [artikelnummer].preis;{} summe INCR gesamtpreis;{} write (f," |" + text(artikelnummer,5) + " | "{} + text(warendatei [artikelnummer].artikelname,17) + " | "{} + text(einkaufszahlen [artikelnummer],4) + " |"{} + text(warendatei [artikelnummer].preis,7,2) + " |"{} + text(gesamtpreis,8,2) + " |").{}
+END PROC fuelle;{}PROC lageruebersicht von zentrale (FILE VAR f):{} INT VAR filialnr;{} beginne mit eigener filiale;{} FOR filialnr FROM 1 UPTO max filialen REP{} TEXT CONST aktuelle verwaltung ::{} hauptstelle + ".Filialverwaltung " + text (filialnr);{} IF filialnr <> int (filialnummer) CAND{} exists task (aktuelle verwaltung){} THEN hole daten dieser filiale;{} schreibe daten in zentralliste{} FI{} PER;{} werte zentralliste aus.{} beginne mit eigener filiale:{}
+ WARENDATEI VAR hilfsdatei;{} CONCR (hilfsdatei) := CONCR (artikel).{} hole daten dieser filiale:{} init ds;{} call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code).{} schreibe daten in zentralliste:{} BOUND FILIALDATEN VAR aktuelle daten :: ds;{} INT VAR i;{} FOR i FROM 1 UPTO max artikel REP{} IF hilfsdatei [i].artikelname = ""{} THEN hilfsdatei [i] := aktuelle daten.waren [i]{} ELSE hilfsdatei [i].mindestbestand INCR aktuell.mindestbestand;{}
+ hilfsdatei [i].bestand INCR aktuell.bestand{} FI{} PER.{} aktuell: aktuelle daten.waren [i].{} werte zentralliste aus:{} forget (ds);{} forget ("Auskunft: Zentrale", quiet);{} f := sequential file (output, "Auskunft: Zentrale");{} line (f);{} write (f, " Zentrale Lagerübersicht:");{} fuelle (f, hilfsdatei).{}END PROC lageruebersicht von zentrale;{}PROC lageruebersicht von filiale (FILE VAR f):{} forget ("Auskunft: Filiale " + filialnummer, quiet);{}
+ f := sequential file (output, "Auskunft: Filiale " + filialnummer);{} schreibe dateikopf;{} fuelle (f, artikel).{} schreibe dateikopf:{} line (f);{} write (f, " Lagerübersicht:").{}END PROC lageruebersicht von filiale;{}PROC lageruebersichten aller filialen (FILE VAR f):{} INT VAR filialnr;{} bereite datei vor;{} FOR filialnr FROM 1 UPTO max filialen REP{} TEXT CONST aktuelle verwaltung ::{} hauptstelle + ".Filialverwaltung " + text (filialnr);{} IF filialnr = int (filialnummer){}
+ THEN schreibe eigene daten in auskunftsdatei{} ELIF exists task (aktuelle verwaltung){} THEN hole daten dieser filiale;{} schreibe daten in auskunftsdatei{} FI{} PER;{} forget (ds).{} bereite datei vor:{} forget ("Auskunft: Alle Filialen", quiet);{} f := sequential file (output, "Auskunft: Alle Filialen").{} schreibe eigene daten in auskunftsdatei:{} line (f);{} write (f, " Lagerübersicht für " +{} invers ("Filiale " + filialnummer) + ":");{}
+ fuelle (f, artikel).{} hole daten dieser filiale:{} init ds;{} call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{} BOUND FILIALDATEN VAR aktuelle daten :: ds.{} schreibe daten in auskunftsdatei:{} line (f);{} write (f, " Lagerübersicht für " +{} invers ("Filiale " + text (filialnr)) + ":");{} fuelle (f, aktuelle daten.waren).{}END PROC lageruebersichten aller filialen;{}PROC fuelle (FILE VAR f, WARENDATEI CONST warendatei):{} INT VAR artikelnummer;{}
+ bereite datei vor;{} schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f," ============================================================");{} line (f,2);{} write(f," | Art.Nr.| Artikelname | Preis | Min.Best.| Bestand |");{} line (f);{} write(f," +--------+-------------------+--------+----------+---------+");{} line (f).{}schreibe daten in datei:{} FOR artikelnummer FROM 1 UPTO max artikel REP{} IF warendatei[artikelnummer].artikelname <> ""{} THEN schreibe in datei; line (f){}
+ FI{} PER;{} write(f," +--------+-------------------+--------+----------+---------+");{} line (f, 3).{}schreibe in datei:{} write (f, " |" + text(artikelnummer,5) + " | "{} + text(warendatei[artikelnummer].artikelname,17) + " |"{} + text(warendatei[artikelnummer].preis,7,2) + " | "{} + text(warendatei[artikelnummer].mindestbestand,6)+" | "{} + text(warendatei[artikelnummer].bestand,6) + " |").{}END PROC fuelle;{}
+PROC initialisiere dateien:{} INT VAR kundennummer, artikelnummer;{} FOR kundennummer FROM 1 UPTO max kunden REP{} kunde [kundennummer].nachname := "";{} kunde [kundennummer].vorname := "";{} kunde [kundennummer].geschlecht := ""{} PER;{} FOR artikelnummer FROM 1 UPTO max artikel REP{} verkaufszahl [artikelnummer] := 0;{} artikel [artikelnummer].mindestbestand := 0;{} artikel [artikelnummer].bestand := 0;{} artikel [artikelnummer].artikelname := "";{}
+ artikel [artikelnummer].preis := 0.0;{} FOR kundennummer FROM 1 UPTO max kunden REP{} einkaufsdatei[kundennummer][artikelnummer] := 0{} PER;{} PER{}END PROC initialisiere dateien;{}initialisiere dateien{}END PACKET ls warenhaus 2{}
+
diff --git a/warenhaus/ls-Warenhaus 3 b/warenhaus/ls-Warenhaus 3
new file mode 100644
index 0000000..3473e0f
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 3
@@ -0,0 +1,82 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus 3 **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls warenhaus 3 DEFINES
+ artikelnummer lesen,{} artikeldaten eingeben,{} kundennummer lesen,{} kundendaten eingeben,{} neues blatt,{} rechnungskopf,{} artikel kaufen,{} abrechnung,{} nachbestellen,{} auskunft,{} stoptaste gedrueckt,{} stoptaste gedrückt,{} dezimalwert lesen,{} bitmuster lesen,{} bildschirm neu,{}(* ------------------------------ *){} tastatureingabe,{} eingabesicherheit,{} eingabe mit codekartenleser,{}
+ cursor w3 1 1:{}LET esc = ""27"",{} stopzeichen = "q",{} abbruchzeichen = "h";{}WINDOW VAR w1 :: window (43, 3, 36, 16),{} w2 :: window (43, 20, 36, 3),{} w3k :: window ( 2, 4, 40, 3),{} w3 :: window ( 2, 7, 40, 16),{} w4 :: window ( 8, 4, 66, 18);{}BOOL VAR ende gewuenscht := FALSE,{} artikelnummer ist eingelesen := FALSE,{} kundennummer ist eingelesen := FALSE,{} codekartenleser aktiviert := FALSE,{}
+ auf neuem blatt := TRUE;{}INT VAR artikelnummer :: 0,{} mindestbestand :: 0,{} bestand :: 0,{} kundennummer :: 0,{} sicherheit :: 5;{}TEXT VAR artikelname :: "",{} nachname :: "",{} vorname :: "",{} geschlecht :: "",{} ueberschrift :: " RECHNUNG",{} hilfstext, exit char;{}REAL VAR preis :: 0.0,{} summe :: 0.0;{}PROC eingabesicherheit (INT CONST wert):{}
+ sicherheit := abs (wert){}END PROC eingabesicherheit;{}PROC cursor w3 1 1:{} cursor (w1, 1, 1);{} cursor (w2, 1, 1);{} cursor (w3, 1, 1);{} cursor (w3k, 1, 1);{} forget ("WARENHAUS:Rechnung", quiet);{} setze variable in anfangszustand{}END PROC cursor w3 1 1;{}PROC setze variable in anfangszustand:{} ende gewuenscht := FALSE;{} artikelnummer ist eingelesen := FALSE;{} kundennummer ist eingelesen := FALSE;{} artikelnummer := 0;{} mindestbestand := 0;{} bestand := 0;{}
+ kundennummer := 0;{} artikelname := "";{} nachname := "";{} vorname := "";{} geschlecht := "";{} ueberschrift := " RECHNUNG";{} preis := 0.0;{} summe := 0.0{}END PROC setze variable in anfangszustand;{}PROC bildschirm neu:{} cursor off;{} pruefe abbruch;{} cursor (w1, 1, 1);{} cursor (w2, 1, 1);{} cursor (w3, 1, 1);{} cursor (w3k,1, 1);{} auf neuem blatt := TRUE;{} page;{} out ("WARENHAUS: Info Eingabeart Kommandos "15"Programme "14" " +{}
+ "Filialdaten Archiv"); line;{} out (ecke oben links + (40 * waagerecht) + balken oben{} + (36 * waagerecht) + ecke oben rechts);{} INT VAR zeile;{} FOR zeile FROM 3 UPTO 22 REP{} cursor ( 1, zeile); out (senkrecht);{} cursor (42, zeile); out (senkrecht);{} cursor (79, zeile); out (senkrecht){} PER;{} cursor (1, 23);{} out (ecke unten links + (40 * waagerecht) + balken unten{} + (36 * waagerecht) + ecke unten rechts);{}
+ cursor (42, 19);{} out (balken links + (36 * waagerecht) + balken rechts);{} cursor (2, 24);{} out ("Programmabbruch: <ESC><" + abbruchzeichen + ">");{} cursor on{}END PROC bildschirm neu;{}PROC pruefe abbruch:{} IF pressed key = esc{} THEN pruefe weiter{} FI.{} pruefe weiter:{} TEXT VAR naechstes zeichen :: pressed key (20);{} IF naechstes zeichen = stopzeichen{} THEN ende gewuenscht := TRUE{} ELIF naechstes zeichen = abbruch zeichen{}
+ THEN setze variable in anfangszustand;{} cursor off;{} errorstop (1951, "Programm - Abbruch durch <ESC><"{} + abbruchzeichen + ">"){} FI{}END PROC pruefe abbruch;{}PROC regeneriere w2:{} cursor (42, 19);{} out (ecke oben links + (36 * waagerecht));{} INT VAR zeile;{} FOR zeile FROM 20 UPTO 22 REP{} cursor (42, zeile); out (senkrecht);{} PER;{} cursor (42, 23); out (balken unten);{} page (w2){}
+END PROC regeneriere w2;{}PROC fenster putzen:{} page (w1);{} page (w2){}END PROC fenster putzen;{}PROC lies nummer ein (INT VAR nummer):{} line (w2, 2);{} out (w2, " Stoptaste: <ESC><" + stopzeichen + ">");{} hilfstext := text (nummer);{} REP cursor (w1, 19, 2);{} editget (w1, hilfstext, 4, 4, "", stopzeichen + abbruchzeichen,{} exit char);{} pruefe exit char;{} change all (hilfstext, " ", ""){} UNTIL hilfstext >= "0" AND hilfstext <= "9999" PER;{}
+ nummer := int (hilfstext).{} pruefe exit char:{} IF exit char = esc + stopzeichen{} THEN ende gewuenscht := TRUE;{} cursor off; fenster putzen; cursor on;{} nummer := 0;{} LEAVE lies nummer ein{} ELIF exit char = esc + abbruchzeichen{} THEN setze variable in anfangszustand;{} errorstop (1951, "Progamm - Abbruch durch <ESC><"{} + abbruchzeichen + ">"){} ELSE ende gewuenscht := FALSE{} FI.{}
+END PROC lies nummer ein;{}PROC lies artikelnummer ein:{} page (w2);{} cursor (w1, 2, 2);{} out (w1, "Artikelnummer : ");{} IF codekartenleser aktiviert{} THEN artikelnummer := gesicherter wert von interface{} (min artikelnummer , max artikelnummer, "Warenkarte"){} ELSE artikelnummer von tastatur lesen{} FI;{} IF ende gewuenscht{} THEN artikelnummer ist eingelesen := FALSE{} ELSE artikelnummer ist eingelesen := TRUE{}
+ FI.{} artikelnummer von tastatur lesen:{} cursor on;{} REP out (w2, " Artikelnummer eingeben");{} lies nummer ein (artikelnummer);{} UNTIL ende gewuenscht COR artikelnummer zulaessig PER.{} artikelnummer zulaessig:{} IF (artikelnummer < min artikelnummer OR{} artikelnummer > max artikelnummer){} THEN page (w2); out (""7"");{} out (w2, " Unzulässige Artikelnummer!");{} line (w2, 2);{} out (w2, " Bitte irgendeine Taste tippen!");{}
+ pause; page (w2);{} FALSE{} ELSE TRUE{} FI.{}END PROC lies artikelnummer ein;{}PROC artikelnummer lesen:{} pruefe abbruch;{} lies artikelnummer ein;{} IF artikelnummer ist eingelesen{} THEN hole artikeldaten (artikelnummer, artikelname, preis,{} mindestbestand, bestand){} FI{}END PROC artikelnummer lesen;{}PROC kundennummer lesen:{} pruefe abbruch;{} lies kundennummer ein;{} IF kundennummer ist eingelesen{} THEN hole kundendaten (kundennummer, nachname, vorname, geschlecht){}
+ FI{}END PROC kundennummer lesen;{}PROC lies kundennummer ein:{} page (w2);{} cursor (w1, 2, 2);{} out (w1, "Kundennummer : ");{} IF codekartenleser aktiviert{} THEN kundennummer := gesicherter wert von interface{} (min kundennummer , max kundennummer, "Kundenkarte"){} ELSE kundennummer von tastatur lesen{} FI;{} IF ende gewuenscht{} THEN kundennummer ist eingelesen := FALSE{} ELSE kundennummer ist eingelesen := TRUE{} FI.{} kundennummer von tastatur lesen:{}
+ cursor on;{} REP out (w2, " Kundennummer eingeben");{} lies nummer ein (kundennummer){} UNTIL ende gewuenscht COR kundennummer zulaessig PER.{} kundennummer zulaessig:{} IF (kundennummer < min kundennummer OR{} kundennummer > max kundennummer){} THEN page (w2); out (""7"");{} out (w2, " Unzulässige Kundennummer!");{} line (w2, 2);{} out (w2, " Bitte irgendeine Taste tippen!");{} pause; page (w2);{} FALSE{}
+ ELSE TRUE{} FI.{}END PROC lies kundennummer ein;{}PROC zeige artikeldaten:{} cursor (w1, 2, 6);{} out (w1, "Artikelname : " + text (artikelname, 16));{} cursor (w1, 2, 8);{} out (w1, "Preis : " + text preis + " ");{} cursor (w1, 2, 10);{} out (w1, "Mindestbestand : " + text (mindestbestand) + " ");{} cursor (w1, 2, 12);{} out (w1, "Bestand : " + text (bestand) + " ").{} text preis:{} TEXT VAR hilfe :: text (preis, min (8, pos(text(preis),".")+2), 2);{}
+ change (hilfe, " ", "0");{} hilfe.{}END PROC zeige artikeldaten;{}PROC zeige kundendaten:{} cursor (w1, 2, 6);{} out (w1, "Nachname : " + text (nachname, 16));{} cursor (w1, 2, 8);{} out (w1, "Vorname : " + text (vorname , 16));{} cursor (w1, 2, 10);{} out (w1, "Geschlecht : " + geschlecht + " ");{}END PROC zeige kundendaten;{}PROC artikeldaten speichern:{} pruefe abbruch;{} page (w2); line (w2);{} out (w2, " Artikeldaten werden gespeichert") ;{}
+ speichere artikeldaten (artikelnummer, artikelname, preis,{} mindestbestand, bestand);{} pause (10);{} IF codekartenleser aktiviert{} THEN lasse karte entfernen (FALSE){} FI{}END PROC artikeldaten speichern;{}PROC kundendaten speichern:{} pruefe abbruch;{} page (w2); line (w2);{} out (w2, " Kundendaten werden gespeichert") ;{} speichere kundendaten (kundennummer, nachname,vorname, geschlecht);{} pause (10);{} IF codekartenleser aktiviert{} THEN lasse karte entfernen (FALSE){}
+ FI{}END PROC kundendaten speichern;{}BOOL PROC stoptaste gedrueckt:{} pruefe abbruch;{} ende gewuenscht{}END PROC stoptaste gedrueckt;{}BOOL PROC stoptaste gedrückt:{} stoptaste gedrueckt{}END PROC stoptaste gedrückt;{}PROC neues blatt:{} pruefe abbruch;{} page (w3k);{} page (w3);{} auf neuem blatt := TRUE;{} forget ("WARENHAUS:Rechnung", quiet){}END PROC neues blatt;{}PROC nachbestellen:{} pruefe abbruch;{} FILE VAR f;{} warten in w2;{} hole bestelliste (f);{} pruefe abbruch;{} cursor (2,24);{}
+ out ("Weiter mit <ESC><q>; Cursor bewegen: <Pfeile>");{} cursor on;{} show (w4, f);{} cursor off;{} cursor (1, 24); out (""5"");{} WINDOW VAR w :: window(45,18,25,3);{} outframe (w);{} IF yes (w, "Bestelliste drucken", FALSE){} THEN drucke (headline (f)){} FI;{} cursor on;{} forget (headline (f), quiet){}END PROC nachbestellen;{}PROC warten in w2:{} cursor off;{} page (w2);{} line (w2);{} out (w2, " Bitte warten!");{} cursor on{}END PROC warten in w2;{}PROC codenummer von tastatur lesen (INT VAR codenummer):{}
+ codenummer := 0;{} out (w2, " Codenummer eingeben");{} cursor on;{} lies nummer ein (codenummer){}END PROC codenummer von tastatur lesen;{}PROC auskunft:{} pruefe abbruch;{} FILE VAR f;{} INT VAR codenummer :: 0;{} cursor (w1, 2, 2);{} out (w1, "Codenummer : ");{} page (w2);{} IF codekartenleser aktiviert{} THEN codenummer := gesicherter wert von interface (0,254, "Codekarte");{} lasse karte entfernen (FALSE){} ELSE codenummer von tastatur lesen (codenummer){}
+ FI;{} IF ende gewuenscht THEN LEAVE auskunft FI;{} SELECT codenummer OF CASE 66, 67, 68 : hitliste{} CASE 73, 74, 75 : kaeuferliste{} CASE 77, 78, 79 : kundenliste{} CASE 84, 85, 86 : einkaufsliste{} CASE 89, 90, 91 : lageruebersicht{} OTHERWISE teste auf artikel oder kundennummer{} END SELECT;{} IF codekartenleser aktiviert CAND wert von interface <> 255{} THEN karte entfernen{} FI.{} karte entfernen:{}
+ SELECT codenummer OF{} CASE 66, 67, 68, 73, 74, 75, 77, 78, 79, 84, 85, 86, 89, 90,{} 91: lasse karte entfernen (TRUE){} OTHERWISE lasse karte entfernen (FALSE){} END SELECT.{} teste auf artikel oder kundennummer:{} IF codenummer >= min artikelnummer AND codenummer <= max artikelnummer{} THEN gib auskunft ueber artikeldaten{} ELIF codenummer >= min kundennummer AND codenummer <= max kundennummer{} THEN gib auskunft ueber kundendaten{} ELSE unzulaessige codenummer{}
+ FI.{} unzulaessige codenummer:{} out (10 * ""7"");{} page (w2);{} out (w2, " Unzulässige Codenummer !!!");{} line (w2, 2);{} out (w2, " Bitte irgendeine Taste tippen!");{} pause;{} page (w2).{} gib auskunft ueber artikeldaten:{} hole artikeldaten (codenummer, artikelname, preis,{} mindestbestand, bestand);{} zeige artikeldaten;{} artikelnummer ist eingelesen := FALSE;{} stop w2;{} page (w1).{} gib auskunft ueber kundendaten:{} hole kundendaten (codenummer, nachname, vorname, geschlecht);{}
+ zeige kundendaten;{} kundennummer ist eingelesen := FALSE;{} stop w2;{} page (w1).{} hitliste:{} warten in w2;{} hole auskunft ein (codenummer, 0, f);{} zeige f.{} kundenliste:{} warten in w2;{} hole auskunft ein (codenummer, 0, f);{} zeige f.{} zeige f:{} pruefe abbruch;{} cursor (2, 24);{} out ("Weiter mit <ESC><q>; Cursor bewegen: <Pfeile>");{} show (w4, f);{} cursor (1, 24); out (""5"");{} evtl drucken.{} lageruebersicht:{} warten in w2;{}
+ hole auskunft ein (codenummer, 0, f);{} zeige f.{} kaeuferliste:{} lies artikelnummer ein;{} IF artikelnummer ist eingelesen{} THEN artikelnummer ist eingelesen := FALSE;{} warten in w2;{} hole auskunft ein (codenummer, artikelnummer, f);{} zeige f{} FI.{} einkaufsliste:{} lies kundennummer ein;{} IF kundennummer ist eingelesen{} THEN kundennummer ist eingelesen := FALSE;{} warten in w2;{} hole auskunft ein (codenummer, kundennummer, f);{}
+ zeige f{} FI.{} evtl drucken:{} WINDOW VAR w :: window(46,18,22,3);{} cursor off;{} outframe (w);{} IF yes (w, "Auskunft drucken", FALSE){} THEN drucke (headline (f)){} FI;{} cursor on;{} forget (headline (f), quiet).{}END PROC auskunft;{}PROC rechnungskopf:{} pruefe abbruch;{} IF kundennummer ist eingelesen AND nachname <> ""{} THEN ueberschrift := " RECHNUNG für " + anrede + (vorname SUB 1) +{} ". " + text (nachname, 10){} ELSE ueberschrift := " RECHNUNG"{}
+ FI;{} summe := 0.0;{} schreibe ueberschrift auf bildschirm;{} schreibe in rechnungsdatei;{} IF codekartenleser aktiviert{} THEN lasse karte entfernen (FALSE){} FI.{} schreibe in rechnungsdatei:{} sysout ("WARENHAUS:Rechnung");{} line;{} put (ueberschrift);{} line;{} put (" ==================================");{} line (2);{} sysout ("").{} anrede:{} IF geschlecht = "m"{} THEN "Herrn "{} ELIF geschlecht = "w"{} THEN "Frau "{} ELSE ""{}
+ FI.{}END PROC rechnungskopf;{}PROC schreibe ueberschrift auf bildschirm:{} INT VAR spalte, zeile;{} get cursor (w3, spalte, zeile);{} IF zeile = 1{} THEN auf neuem blatt := TRUE;{} schreibe in w3k{} ELSE auf neuem blatt := FALSE;{} schreibe in w3{} FI.{} schreibe in w3:{} IF remaining lines (w3) < 7{} THEN page (w3);{} page (w3k);{} auf neuem blatt := TRUE;{} schreibe in w3k{} ELSE line (w3);{} out (w3, ueberschrift);{}
+ line (w3);{} out (w3, " ==================================");{} line (w3, 2){} FI.{} schreibe in w3k:{} out (w3k, ueberschrift);{} line (w3k);{} out (w3k, " ==================================").{}END PROC schreibe ueberschrift auf bildschirm;{}PROC artikel kaufen:{} pruefe abbruch;{} IF artikelnummer ist eingelesen{} THEN kauf registrieren{} ELSE setze variable in anfangszustand;{} errorstop ("Es ist keine Artikelnummer eingelesen worden!"){}
+ FI;{} IF codekartenleser aktiviert{} THEN lasse karte entfernen (FALSE){} FI.{} kauf registrieren:{} artikelnummer ist eingelesen := FALSE;{} IF bestand > 0{} THEN artikel auf rechnung setzen;{} registrieren{} ELSE page (w2); out (""7"");{} IF artikelname = ""{} THEN out (w2, " Artikel hier nicht erhältlich!"){} ELSE out (w2, " Der Artikel ist ausverkauft!"){} FI;{} line (w2, 2);{} out (w2, " Weiter durch Tippen einer Taste");{}
+ pause{} FI.{} registrieren:{} IF kundennummer ist eingelesen{} THEN registriere verkauf (kundennummer, artikelnummer){} ELSE registriere verkauf (min kundennummer - 1, artikelnummer){} FI.{} artikel auf rechnung setzen:{} summe INCR preis;{} IF remaining lines (w3) < 3{} THEN beginne wieder oben{} FI;{} out (w3, " " + text (artikelname, 15) + text (preis, 12, 2));{} line (w3);{} sysout ("WARENHAUS:Rechnung");{} put (" " + text (artikelname, 15) + text preis);{}
+ line;{} sysout ("").{} beginne wieder oben:{} IF auf neuem blatt{} THEN page (w3){} ELSE schreibe ueberschrift auf bildschirm{} FI.{} text preis:{} TEXT VAR hilfe :: text (preis, 12, 2);{} INT VAR vor punkt :: pos (hilfe, ".") - 1;{} IF (hilfe SUB vor punkt) = " "{} THEN change (hilfe, vor punkt, vor punkt, "0"){} FI;{} hilfe.{}END PROC artikel kaufen;{}PROC abrechnung:{} pruefe abbruch;{} schreibe summe auf bildschirm;{}
+ schreibe summe in rechnungsdatei;{} setze variable zurueck;{} frage ob drucken;{} IF codekartenleser aktiviert{} THEN lasse karte entfernen (FALSE){} FI.{} schreibe summe auf bildschirm:{} IF remaining lines (w3) < 2{} THEN beginne wieder oben{} FI;{} put (w3, " -------------");{} line (w3);{} put (w3, " Summe " + text (summe, 12, 2));{} line (w3).{} beginne wieder oben:{} IF auf neuem blatt{} THEN page (w3){} ELSE schreibe ueberschrift auf bildschirm{}
+ FI.{} schreibe summe in rechnungsdatei:{} sysout ("WARENHAUS:Rechnung");{} put (" -------------");{} line;{} put (" Summe " + text (summe, 12, 2));{} line;{} sysout ("").{} setze variable zurueck:{} BOOL VAR alter wert :: ende gewuenscht;{} setze variable in anfangszustand;{} ende gewuenscht := alter wert.{} frage ob drucken:{} IF yes (w2, "Rechnung drucken", FALSE){} THEN cursor (3, 22);{} disable stop;{} print ("WARENHAUS:Rechnung");{}
+ IF is error THEN clear error FI;{} enable stop{} FI.{}END PROC abrechnung;{}PROC artikeldaten eingeben:{} pruefe abbruch;{} IF artikelnummer ist eingelesen{} THEN lies artikeldaten ein;{} artikeldaten speichern{} ELSE setze variable in anfangszustand;{} errorstop ("Es ist keine Artikelnummer eingelesen worden!"){} FI.{} lies artikeldaten ein:{} zeige artikeldaten;{} IF artikelname <> ""{} THEN vielleicht schon fertig{} ELSE page (w2){}
+ FI;{} REP line (w2);{} put (w2, " Artikeldaten eingeben");{} eingabe{} UNTIL yes (w2, "Alles richtig", TRUE){} PER;{} artikelnummer ist eingelesen := FALSE.{} vielleicht schon fertig:{} IF yes (w2, "Alles richtig", TRUE){} THEN artikelnummer ist eingelesen := FALSE;{} IF codekartenleser aktiviert{} THEN lasse karte entfernen (FALSE){} FI;{} LEAVE artikeldaten eingeben{} FI.{} eingabe:{} name holen;{}
+ preis holen;{} mindestbestand holen;{} bestand holen.{} name holen:{} REP cursor (w1, 19, 6);{} editget (w1, artikelname, 80, 80, "", abbruchzeichen + stopzeichen,{} exit char);{} teste auf abbruch{} UNTIL artikelname <> "" PER.{} preis holen:{} hilfstext := text (preis, pos(text(preis),".") + 2, 2);{} change (hilfstext, " ", "0");{} REP cursor (w1, 19, 8);{} editget (w1, hilfstext, 8, 8, "", abbruch zeichen + stopzeichen,{}
+ exit char);{} change (hilfstext, ",", ".");{} preis := round (real (hilfstext), 2);{} teste auf abbruch{} UNTIL preis >= 0.0 PER.{} mindestbestand holen:{} hilfstext := text (mindestbestand);{} REP cursor (w1, 19, 10);{} editget (w1, hilfstext, 4, 4, "", abbruch zeichen + stopzeichen,{} exit char);{} mindestbestand := int (hilfstext);{} teste auf abbruch{} UNTIL mindestbestand >= 0 PER.{}
+ bestand holen:{} hilfstext := text (bestand);{} REP cursor (w1, 19, 12);{} editget (w1, hilfstext, 4, 4, "", abbruch zeichen + stopzeichen,{} exit char);{} bestand := int (hilfstext);{} teste auf abbruch{} UNTIL bestand >= 0 PER.{} teste auf abbruch:{} IF exit char = esc + stopzeichen{} THEN ende gewuenscht := TRUE{} ELIF exit char = esc + abbruchzeichen{} THEN setze variable in anfangszustand;{} errorstop (1951, "Programm - Abbruch durch <ESC><"{}
+ + abbruchzeichen + ">"){} FI.{}END PROC artikeldaten eingeben;{}PROC kundendaten eingeben:{} IF kundennummer ist eingelesen{} THEN lies kundendaten ein;{} kundendaten speichern{} ELSE setze variable in anfangszustand;{} errorstop ("Es ist keine Kundennummer eingelesen worden!"){} FI.{} lies kundendaten ein:{} zeige kundendaten;{} IF nachname <> ""{} THEN vielleicht schon fertig{} ELSE page (w2){} FI;{} REP line (w2);{}
+ put (w2, " Kundendaten eingeben");{} eingabe{} UNTIL yes (w2, "Alles richtig", TRUE) PER;{} kundennummer ist eingelesen := FALSE.{} vielleicht schon fertig:{} IF yes (w2, "Alles richtig", TRUE){} THEN kundennummer ist eingelesen := FALSE;{} IF codekartenleser aktiviert{} THEN lasse karte entfernen (FALSE){} FI;{} LEAVE kundendaten eingeben{} FI.{} eingabe:{} nachname holen;{} vorname holen;{} geschlecht holen.{}
+ nachname holen:{} REP cursor (w1, 19, 6);{} editget (w1, nachname, 80, 80, "", abbruch zeichen + stopzeichen,{} exit char);{} teste auf abbruch{} UNTIL nachname <> "" PER.{} vorname holen:{} REP cursor (w1, 19, 8);{} editget (w1, vorname, 80, 80, "", abbruch zeichen + stopzeichen,{} exit char);{} teste auf abbruch{} UNTIL vorname <> "" PER.{} geschlecht holen:{} REP cursor (w1, 19, 10);{}
+ editget (w1, geschlecht, 9, 9, "", abbruchzeichen + stopzeichen,{} exit char);{} geschlecht := geschlecht SUB 1;{} teste auf abbruch{} UNTIL geschlecht = "m" OR geschlecht = "w" PER.{} teste auf abbruch:{} IF exit char = esc + stopzeichen{} THEN ende gewuenscht := TRUE{} ELIF exit char = esc + abbruchzeichen{} THEN setze variable in anfangszustand;{} errorstop (1951, "Programm - Abbruch durch <ESC><"{}
+ + abbruchzeichen + ">"){} FI.{}END PROC kundendaten eingeben;{}PROC drucke (TEXT CONST name):{} TEXT VAR zeile;{} FILE VAR f :: sequential file (modify, name);{} to line (f, 1);{} insert record (f);{} write record (f, "#center#" + name);{} down (f);{} insert record (f);{} down (f);{} WHILE NOT eof (f) REP{} read record (f, zeile);{} IF pos (zeile, ""15"") > 0{} THEN change (zeile, ""15"", "#on(""r"")#");{} change (zeile, ""14"", "#off(""r"")#");{}
+ write record (f, zeile){} FI;{} down (f){} PER;{} cursor (3, 22);{} print (name){}END PROC drucke;{}PROC stop w2:{} cursor off;{} page (w2);{} out (w2," Zum Weitermachen bitte");line(w2);{} out (w2," irgendeine Taste tippen!");{} pause;{} page (w2);{} cursor on{}END PROC stop w2;{}BOOL PROC yes (WINDOW VAR w, TEXT CONST frage, BOOL CONST default):{} BOOL VAR antwort :: default;{} TEXT VAR taste;{} INT CONST ja pos :: (areaxsize (w) - 9) DIV 2;{} cursor off;{} cursor (42,24); out ("Ändern: <Pfeile> Bestätigen: <RETURN>");{}
+ page (w);{} out (w, center (w, frage + " ?"));{} cursor (w, ja pos, 3);{} IF default{} THEN out (w, ""15"Ja "14" Nein ");{} cursor (w, ja pos, 3){} ELSE out (w, " Ja "15"Nein "14"");{} cursor (w, ja pos + 5, 3){} FI;{} tastendruck auswerten;{} page (w);{} cursor (42,24); out (""5"");{} cursor on;{} antwort.{} tastendruck auswerten:{} REP inchar (taste);{} SELECT code (taste) OF CASE 2, 8 : position aendern{} CASE 13 : LEAVE tastendruck auswerten{}
+ CASE 74, 106 : antwort := TRUE; (*Jj*){} LEAVE tastendruck auswerten{} CASE 78, 110 : antwort := FALSE; (*Nn*){} LEAVE tastendruck auswerten{} OTHERWISE out (""7"") END SELECT{} PER.{} position aendern:{} IF antwort THEN antwort := FALSE;{} cursor (w, ja pos, 3);{} out (w, " Ja "15"Nein "14"");{}
+ cursor (w, ja pos + 5, 3){} ELSE antwort := TRUE;{} cursor (w, ja pos, 3);{} out (w, ""15"Ja "14" Nein ");{} cursor (w, ja pos, 3){} FI.{}END PROC yes;{}PROC tastatureingabe (BOOL CONST erwuenscht, INT VAR rueckmeldung):{} IF erwuenscht{} THEN rueckmeldung := 0;{} codekartenleser aktiviert := FALSE;{} schliesse interface{} ELSE oeffne interface (rueckmeldung);{} IF rueckmeldung >= 0{}
+ THEN codekartenleser aktiviert := TRUE{} ELSE codekartenleser aktiviert := FALSE{} FI{} FI{}END PROC tastatureingabe;{}BOOL PROC eingabe mit codekartenleser:{} codekartenleser aktiviert{}END PROC eingabe mit codekartenleser;{}PROC dezimalwert lesen:{} pruefe abbruch;{} IF codekartenleser aktiviert{} THEN interfacewerte zeigen{} ELSE setze variable in anfangszustand;{} errorstop ("Eingabeart ist auf Tastatur eingestellt!"){} FI.{} interfacewerte zeigen:{}
+ cursor off;{} fenster putzen;{} line (w1, 4); line (w2);{} out (w1, " Dezimalwert :");{} out (w2, " Lesen beenden mit <ESC><q>");{} ende gewuenscht := FALSE;{} REP pruefe abbruch;{} cursor (w1, 17, 5);{} out (w1, text (wert von interface, 3)){} UNTIL ende gewuenscht PER;{} page (w2); cursor (w1, 1, 5); out (" ");{} cursor on.{}END PROC dezimalwert lesen;{}PROC bitmuster lesen:{} pruefe abbruch;{} IF codekartenleser aktiviert{}
+ THEN interfacewerte zeigen{} ELSE setze variable in anfangszustand;{} errorstop ("Eingabeart ist auf Tastatur eingestellt!"){} FI.{} interfacewerte zeigen:{} cursor off;{} fenster putzen;{} line (w1, 4); line (w2);{} out (w1, " Bitmuster :");{} out (w2, " Lesen beenden mit <ESC><q>");{} ende gewuenscht := FALSE;{} REP pruefe abbruch;{} cursor (w1, 16, 5);{} out (w1, bitmuster (wert von interface)){} UNTIL ende gewuenscht PER;{} page (w2); cursor (w1, 1, 5); out (" ");{}
+ cursor on.{}END PROC bitmuster lesen;{}TEXT PROC bitmuster (INT CONST wert):{} INT VAR bitnr;{} TEXT VAR muster :: "";{} FOR bitnr FROM 7 DOWNTO 0 REP{} IF bit (wert, bitnr){} THEN muster CAT "I"{} ELSE muster CAT "O"{} FI{} PER;{} muster{}END PROC bitmuster;{}PROC lasse karte entfernen (BOOL CONST mit rahmen):{} IF wert von interface <> 255{} THEN cursor off;{} IF mit rahmen THEN regeneriere w2 ELSE page (w2) FI;{} line (w2);{} out (w2, " Bitte Karte entfernen");{}
+ REP pruefe abbruch{} UNTIL (wert von interface = 255) OR ende gewuenscht PER;{} cursor on{} FI{}END PROC lasse karte entfernen;{}INT PROC gesicherter wert von interface (INT CONST von, bis,{} TEXT CONST kartenart):{} INT VAR wert, zaehler;{} ende gewuenscht := FALSE;{} cursor off;{} REP out (w2, " Bitte " + kartenart + " einschieben");{} line (w2, 2);{} out (w2, " Stoptaste: <ESC><" + stopzeichen + ">");{} cursor (79, 24);{}
+ gesicherten wert einlesen;{} cursor (w1, 19, 2);{} out (w1, text (wert, 3));{} IF wert < von OR wert > bis{} THEN warnung{} FI{} UNTIL wert >= von AND wert <= bis PER;{} cursor on;{} wert.{} gesicherten wert einlesen:{} REP zaehler := 0;{} warte auf karte;{} wert := wert von interface;{} lies wert{} UNTIL wert gesichert AND wert <> 255 PER.{} warte auf karte:{} REP beachte esc q{} UNTIL wert von interface <> 255 PER.{} beachte esc q:{}
+ pruefe abbruch;{} IF ende gewuenscht{} THEN cursor on;{} LEAVE gesicherter wert von interface WITH 0{} FI.{} lies wert:{} REP beachte esc q;{} IF wert = wert von interface{} THEN zaehler INCR 1{} ELSE LEAVE lies wert{} FI{} UNTIL wert gesichert PER.{} wert gesichert: zaehler = sicherheit.{} warnung:{} page (w2); out (""7"");{} out (w2, " Dies ist keine " + kartenart + "!");{} line (w2, 2);{} out (w2, " Bitte Karte entfernen");{}
+ REP beachte esc q{} UNTIL wert von interface = 255 PER;{} page (w2).{}END PROC gesicherter wert von interface{}END PACKET ls warenhaus 3{}
+
diff --git a/warenhaus/ls-Warenhaus 4 b/warenhaus/ls-Warenhaus 4
new file mode 100644
index 0000000..a19a6d6
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 4
@@ -0,0 +1,48 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus 4 **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls warenhaus 4 DEFINES
+ uebersetze:{}TYPE VOKABEL = STRUCT (TEXT grin, elan),{} REFINEMENT = STRUCT (TEXT name, INT aufruf);{}LET befehlsanzahl = 10,{} max refinements = 20,{} max offene strukturen = 10,{} schleife = 1,{} abfrage = 2;{}ROW befehlsanzahl VOKABEL CONST befehl :: ROW befehlsanzahl VOKABEL :{} (VOKABEL : ("Artikelnummerlesen", "artikelnummer lesen"),{} VOKABEL : ("Artikeldateneingeben", "artikeldaten eingeben"),{} VOKABEL : ("Kundennummerlesen", "kundennummer lesen"),{}{}
+ VOKABEL : ("Kundendateneingeben", "kundendaten eingeben"),{} VOKABEL : ("Rechnungskopf", "rechnungskopf"),{} VOKABEL : ("Artikelkaufen", "artikel kaufen"),{} VOKABEL : ("Abrechnung", "abrechnung"),{} VOKABEL : ("Auskunft", "auskunft"),{} VOKABEL : ("neuesBlatt", "neues blatt"),{} VOKABEL : ("Bildschirmneu", "bildschirm neu"));{}ROW max refinements REFINEMENT VAR refinement;{}ROW max offene strukturen INT VAR offene struktur;{}{}
+INT VAR zeilennummer, erster fehler;{}OP := (VOKABEL VAR links, VOKABEL CONST rechts):{} CONCR (links) := CONCR (rechts){}END OP :=;{}PROC uebersetze (TEXT CONST dateiname):{}forget ("elanprogramm", quiet);{}FILE VAR quelle :: sequential file (input, dateiname),{} ziel :: sequential file (output, "elanprogramm");{}suche programmanfang;{}WHILE NOT (eof (quelle) OR anything noted) REP{} bearbeite zeile{}PER;{}IF NOT anything noted{} THEN abschlusspruefung{}FI;{}IF anything noted{} THEN quelle := sequential file (modify, dateiname);{}{}
+ to line (quelle, erster fehler);{} col (1);{} noteedit (quelle);{} errorstop (""){}FI.{}abschlusspruefung:{} IF anzahl refinements > 0{} THEN pruefe refinementliste{} ELSE pruefe programmende{} FI.{}pruefe programmende:{} IF programmende fehlt{} THEN zeilennummer INCR 1;{} fehler (16){} FI.{}pruefe refinementliste:{} zeilennummer INCR 1;{} pruefe auf offene schleife oder abfrage;{} put (ziel, "END PROC refinement " + text (letztes refinement));{}{}
+ FOR index FROM 1 UPTO anzahl refinements REP{} IF refinement [index].aufruf > 0{} THEN zeilennummer := refinement [index].aufruf;{} fehler (25){} ELIF refinement [index].aufruf < 0{} THEN zeilennummer := - refinement [index].aufruf;{} fehler (26){} FI{} PER.{}suche programmanfang:{} TEXT VAR restzeile, zeile :: "";{} BOOL VAR programmende fehlt := FALSE,{} refinement muss folgen := FALSE;{} INT VAR anzahl refinements := 0,{} letztes refinement := 0,{}{}
+ letzte geoeffnete := 0,{} index;{} zeilennummer := 0;{} erster fehler := 0;{} WHILE NOT eof (quelle) AND zeile = "" REP{} getline (quelle, zeile);{} zeile := compress (zeile);{} zeilennummer INCR 1;{} cout (zeilennummer);{} IF zeile = "" THEN line (ziel) FI;{} PER;{} put (ziel, "bildschirm neu;");{} IF zeile = "" THEN LEAVE uebersetze{} ELIF pos (zeile, "PROGRAMM") = 1{} THEN programmende fehlt := TRUE{} ELSE fehler (1){} FI.{}bearbeite zeile:{}{}
+ zeilennummer INCR 1;{} cout (zeilennummer);{} getline (quelle, zeile);{} zeile := compress (zeile);{} change all (zeile, " ", "");{} IF zeile = ""{} THEN line (ziel){} ELSE analysiere und uebersetze{} FI.{}analysiere und uebersetze:{} IF refinement muss folgen{} THEN erstes refinement{} ELSE pruefe zunaechst auf schluesselworte;{} durchsuche befehlsliste{} FI.{}erstes refinement:{} IF pos (zeile, ":") = 0{} THEN fehler (19){} ELIF pos (zeile, ":") < length (zeile){}{}
+ THEN fehler (20){} ELIF (pos (zeile, "PROGRAMM") = 1) OR{} (pos (zeile, "ENDE") = 1) OR{} (pos (zeile, "WIEDERHOLE") = 1) OR{} (pos (zeile, "BIS") = 1) OR{} (pos (zeile, "WENN") = 1){} THEN fehler (21){} ELIF (zeile = "Stoptastegedrückt:") OR{} (zeile = "nichtStoptastegedrückt:") OR{} (zeile = "Stoptastegedrueckt:") OR{} (zeile = "nichtStoptastegedrueckt:"){} THEN fehler (22){} ELSE refinement muss folgen := FALSE;{}{}
+ line (ziel);{} trage befehlsdefinition ein{} FI.{}trage befehlsdefinition ein:{} change (zeile, ":", "");{} FOR index FROM 1 UPTO anzahl refinements REP{} IF refinement [index].name = zeile{} THEN pruefe aufruf; LEAVE trage befehlsdefinition ein{} FI{} PER;{} anzahl refinements INCR 1;{} IF anzahl refinements > max refinements{} THEN fehler (24){} ELSE refinement [anzahl refinements].name := zeile;{} refinement [anzahl refinements].aufruf := - zeilennummer;{}{}
+ letztes refinement := anzahl refinements;{} line (ziel);{} put (ziel, "PROC refinement " + text (anzahl refinements) + ":"){} FI.{}pruefe aufruf:{} IF refinement [index].aufruf > 0{} THEN refinement [index].aufruf := 0;{} line (ziel);{} put (ziel, "PROC refinement " + text (index) + ":");{} letztes refinement := index{} ELSE fehler (23){} FI.{}pruefe zunaechst auf schluesselworte:{} IF pos (zeile, "WIEDERHOLE") = 1{} THEN oeffne schleife; LEAVE analysiere und uebersetze{}{}
+ ELIF pos (zeile, "WENN") = 1{} THEN oeffne if; LEAVE analysiere und uebersetze{} ELIF pos (zeile, "BIS") = 1{} THEN schliesse mit until; LEAVE analysiere und uebersetze{} ELIF pos (zeile, "ENDE") = 1{} THEN schliesse; LEAVE analysiere und uebersetze{} ELIF pos (zeile, "PROGRAMM") = 1{} THEN fehler (18); LEAVE analysiere und uebersetze{} FI.{}oeffne schleife:{} IF letzte geoeffnete = max offene strukturen{} THEN fehler (2){} ELSE letzte geoeffnete INCR 1;{} offene struktur [letzte geoeffnete] := schleife;{}{}
+ analysiere schleifenart{} FI.{}analysiere schleifenart:{} IF zeile = "WIEDERHOLE"{} THEN line (ziel); put (ziel, "REPEAT"){} ELSE es muss eine zaehlschleife sein{} FI.{}es muss eine zaehlschleife sein:{} restzeile := subtext (zeile, 11);{} INT VAR malpos := pos (restzeile, "MAL");{} IF malpos > 0{} THEN zaehlschleife{} ELSE fehler (3){} FI.{}zaehlschleife:{} IF length (restzeile) > malpos + 2{} THEN fehler (4){} ELSE bestimme anzahl der wiederholungen{} FI.{}{}
+bestimme anzahl der wiederholungen:{} INT VAR wdh := int (subtext (restzeile, 1, malpos - 1));{} IF last conversion ok{} THEN line (ziel);{} put (ziel, "INT VAR index" + text (zeilennummer) +{} "; FOR index" + text (zeilennummer) +{} " FROM 1 UPTO " + text (wdh) + " REPEAT"){} ELSE fehler (5){} FI.{}oeffne if:{} IF letzte geoeffnete = max offene strukturen{} THEN fehler (6){} ELSE letzte geoeffnete INCR 1;{} offene struktur [letzte geoeffnete] := abfrage;{}{}
+ uebersetze abfrage{} FI.{}uebersetze abfrage:{} restzeile := subtext (zeile, 5);{} IF (restzeile = "Stoptastegedrückt") OR{} (restzeile = "Stoptastegedrueckt"){} THEN line (ziel); put (ziel, "IF stoptaste gedrueckt THEN"){} ELIF (restzeile = "nichtStoptastegedrückt") OR{} (restzeile = "nichtStoptastegedrueckt"){} THEN line (ziel); put (ziel, "IF NOT stoptaste gedrueckt THEN"){} ELIF restzeile = ""{} THEN fehler (7){} ELSE fehler (8){} FI.{}schliesse mit until:{}{}
+ teste ob als letztes schleife offen;{} letzte geoeffnete DECR 1;{} restzeile := subtext (zeile, 4);{} IF (restzeile = "Stoptastegedrückt") OR{} (restzeile = "Stoptastegedrueckt"){} THEN line (ziel);{} put (ziel, "UNTIL stoptaste gedrueckt END REPEAT;");{} ELIF (restzeile = "nichtStoptastegedrückt") OR{} (restzeile = "nichtStoptastegedrueckt"){} THEN line (ziel);{} put (ziel, "UNTIL NOT stoptaste gedrueckt END REPEAT;");{} ELIF restzeile = ""{}{}
+ THEN fehler (9){} ELSE fehler (8){} FI.{}schliesse:{} restzeile := subtext (zeile, 5);{} IF restzeile = "WIEDERHOLE"{} THEN schliesse schleife{} ELIF restzeile = "WENN"{} THEN schliesse if{} ELIF restzeile = "PROGRAMM"{} THEN programmende{} ELSE fehler (10){} FI.{}schliesse schleife:{} teste ob als letztes schleife offen;{} letzte geoeffnete DECR 1;{} line (ziel); put (ziel, "END REPEAT;").{}teste ob als letztes schleife offen:{} IF letzte geoeffnete = 0{} THEN fehler (11);{}{}
+ LEAVE bearbeite zeile{} ELIF offene struktur [letzte geoeffnete] = abfrage{} THEN fehler (12){} FI.{}schliesse if:{} teste ob als letztes abfrage offen;{} line (ziel); put (ziel, "END IF;");{} letzte geoeffnete DECR 1.{}teste ob als letztes abfrage offen:{} IF letzte geoeffnete = 0{} THEN fehler (13);{} LEAVE bearbeite zeile{} ELIF offene struktur [letzte geoeffnete] = schleife{} THEN fehler (14){} FI.{}programmende:{} IF programmende fehlt{} THEN programmende fehlt := FALSE;{}{}
+ refinement muss folgen := TRUE{} ELSE fehler (17);{} LEAVE programmende{} FI;{} pruefe auf offene schleife oder abfrage.{}pruefe auf offene schleife oder abfrage:{} IF letzte geoeffnete = 0{} THEN alles okay{} ELIF offene struktur [letzte geoeffnete] = schleife{} THEN fehler (14){} ELSE fehler (12){} FI.{} alles okay: .{}durchsuche befehlsliste:{} IF pos (zeile, ":") > 0{} THEN auf refinementdefinition pruefen{} ELSE befehl suchen{} FI.{}befehl suchen:{}{}
+ BOOL VAR gefunden := FALSE;{} INT VAR i;{} verhindere bedingung;{} FOR i FROM 1 UPTO befehlsanzahl REP{} IF befehl [i].grin = zeile{} THEN gefunden := TRUE;{} line (ziel);{} put (ziel, befehl [i].elan + ";"){} FI{} UNTIL gefunden PER;{} IF NOT gefunden{} THEN trage in refinementliste ein{} FI.{}auf refinementdefinition pruefen:{} IF pos (zeile, ":") < length (zeile){} THEN fehler (20){} ELIF programmende fehlt{} THEN fehler (16){} ELIF (zeile = "Stoptastegedrückt:") OR{}{}
+ (zeile = "nichtStoptastegedrückt:") OR{} (zeile = "Stoptastegedrueckt:") OR{} (zeile = "nichtStoptastegedrueckt:"){} THEN fehler (22){} ELSE pruefe auf offene schleife oder abfrage;{} put (ziel, "END PROC refinement " + text (letztes refinement){} + ";");{} trage befehlsdefinition ein{} FI.{}trage in refinementliste ein:{} FOR index FROM 1 UPTO anzahl refinements REP{} IF refinement [index].name = zeile{}{}
+ THEN trage evtl aufruf ein;{} LEAVE trage in refinementliste ein{} FI{} PER;{} anzahl refinements INCR 1;{} IF anzahl refinements > max refinements{} THEN fehler (24){} ELSE refinement [anzahl refinements].name := zeile;{} refinement [anzahl refinements].aufruf := zeilennummer;{} line (ziel);{} put (ziel, "refinement " + text (anzahl refinements) + ";"){} FI.{}trage evtl aufruf ein:{} line (ziel);{} put (ziel, "refinement " + text (index) + ";");{}{}
+ IF refinement [index].aufruf < 0{} THEN refinement [index].aufruf := 0{} FI.{}verhindere bedingung:{} IF (zeile = "Stoptastegedrückt") OR (zeile = "nichtStoptastegedrückt") OR{} (zeile = "Stoptastegedrueckt") OR (zeile = "nichtStoptastegedrueckt"){} THEN fehler (15);{} LEAVE bearbeite zeile{} FI.{}END PROC uebersetze;{}PROC fehler (INT CONST fehlernr):{} noteline;{} note ("FEHLER in Zeile " + text (zeilennummer) + ": ");{} noteline;{} note (" " + anwendungstext (fehlernr + 20));{}{}
+ noteline;{} IF erster fehler = 0{} THEN erster fehler := zeilennummer{} FI{}END PROC fehler{}END PACKET ls warenhaus 4{}{}
+
diff --git a/warenhaus/ls-Warenhaus 5 b/warenhaus/ls-Warenhaus 5
new file mode 100644
index 0000000..6b05bad
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 5
@@ -0,0 +1,103 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus 5 **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+PACKET ls warenhaus 5 DEFINES
+ warenhaus,{} grin,{} direktbefehl 1,{} direktbefehl 2,{} direktbefehl 3,{} direktbefehl 4,{} direktbefehl 5,{} direktbefehl 6,{} direktbefehl 7,{} warenhausbefehle zeigen,{} eingabe grundeinstellung,{} tastatur einstellen,{} kartenleser einstellen,{} evtl d und b sperren,{} loesche zwischenraum,{} eingabeart anzeigen,{} filialdaten zusammenstellen,{} filialdaten eintragen,{} filialdaten verzeichnis,{}
+ filialdaten umbenennen,{} filialdaten loeschen,{} warenhausprogramme verzeichnis,{} warenhausprogramm neu erstellen,{} warenhausprogramm ansehen,{} warenhausprogramm kopieren,{} warenhausprogramm umbenennen,{} warenhausprogramme loeschen,{} warenhausprogramme drucken,{} warenhausprogramm starten,{} warenhausprogramm wiederholen:{}LET menukarte = "ls-MENUKARTE:Warenhaus",{} praefix = "Filialdaten:",{} filialdatentyp = 1951,{}
+ niltext = "",{} maxlaenge = 45,{} maxnamenslaenge = 35;{}TEXT VAR filialdatenname :: "",{} programmname :: "";{}INT VAR fehlerzeile :: 0;{}BOOL VAR grin version :: FALSE,{} noch kein programm gelaufen :: TRUE,{} bildschirm neu eingesetzt :: FALSE;{}WINDOW VAR w :: window (1, 3, 79, 19);{}INITFLAG VAR in this task :: FALSE;{}PROC warenhausbefehle zeigen:{} TEXT VAR info, liste, tasten;{} INT VAR grinoffset;{}
+ IF grin version{} THEN grinbefehle{} ELSE elanbefehle{} FI;{} REP{} INT VAR auswahl := menualternative (info, liste, tasten, 5, FALSE);{} SELECT auswahl OF{} CASE 1, 101, 105 : menuinfo (anwendungstext (1 + grinoffset)){} CASE 2, 102, 106 : menuinfo (anwendungstext (2 + grinoffset)){} CASE 3, 103, 107 : menuinfo (anwendungstext (3 + grinoffset)){} END SELECT{} UNTIL auswahl = 4 OR auswahl = 104 OR auswahl = 108 PER.{} grinbefehle:{} grinoffset := 13;{} info := " "15"Info zu den Programmierbefehlen "14""13""13""{}
+ + " d Datei - Bearbeitung "13""{} + " e Einkaufen und Auskunft "13""{} + " k Kontroll - Strukturen "13""13""{} + " z Zurück zum Hauptmenü ";{} liste := "Datei"13"Kaufen/Auskunft"13"Kontroll"13"Zurück";{} tasten := "dekzDEKZ".{} elanbefehle:{} grinoffset := 0;{} info := " "15"Info zu den Programmierbefehlen "14""13""13""{} + " d Datei - Bearbeitung "13""{}
+ + " e Einkaufen und Auskunft "13""{} + " s Sonstige Befehle "13""13""{} + " z Zurück zum Hauptmenü ";{} liste := "Datei"13"Kaufen/Auskunft"13"Sonstige"13"Zurück";{} tasten := "deszDESZ".{}END PROC warenhausbefehle zeigen;{}PROC eingabe grundeinstellung:{} INT VAR dummy;{} IF eingabe mit codekartenleser{} THEN tastatureingabe (TRUE, dummy){} FI{}END PROC eingabe grundeinstellung;{}PROC tastatur einstellen:{}
+ eingabe grundeinstellung;{} menuinfo (anwendungstext (6), 4){}END PROC tastatur einstellen;{}PROC kartenleser einstellen:{} INT VAR ergebnis;{} IF eingabe mit codekartenleser{} THEN tastatureingabe (TRUE, ergebnis){} FI;{} pause (10);{} tastatureingabe (FALSE, ergebnis);{} IF ergebnis < 0{} THEN menuinfo (anwendungstext (7 - ergebnis), 5){} ELSE menuinfo (anwendungstext (7), 4){} FI{}END PROC kartenleser einstellen;{}PROC loesche zwischenraum:{} INT VAR zeile;{} cursor (1, 2); out (79 * waagerecht + " ");{}
+ FOR zeile FROM 3 UPTO 22 REP{} cursor (1, zeile); out (""5"");{} PER;{} cursor (1, 23); out (79 * waagerecht + " ");{} cursor (1, 24); out (""5"");{}END PROC loesche zwischenraum;{}PROC ergaenze bildschirm:{} cursor ( 1, 2); out (ecke oben links);{} cursor (42, 2); out (balken oben);{} cursor (80, 2); out (ecke oben rechts);{} INT VAR zeile;{} FOR zeile FROM 3 UPTO 22 REP{} cursor ( 1, zeile); out (senkrecht);{} cursor (42, zeile); out (senkrecht);{} cursor (80, zeile); out (senkrecht){}
+ PER;{} cursor ( 1, 23); out (ecke unten links);{} cursor (42, 23); out (balken unten);{} cursor (80, 23); out (ecke unten rechts);{} cursor (42, 19);{} out (balken links + (37 * waagerecht) + balken rechts);{} cursor w3 1 1{}END PROC ergaenze bildschirm;{}PROC zweite zeile:{} cursor (1, 2); out (79 * waagerecht + " "){}END PROC zweite zeile;{}PROC evtl d und b sperren:{} IF eingabe mit codekartenleser{} THEN activate ( 9);{} activate (10){} ELSE deactivate ( 9);{} deactivate (10){}
+ FI{}END PROC evtl d und b sperren;{}PROC direktbefehl 1:{} disable stop;{} warendatei bearbeiten;{} cursor off;{} IF is error{} THEN regenerate menuscreen;{} menuinfo (" " + invers (errormessage));{} clear error{} ELSE zweite zeile;{} menu bildschirm{} FI;{} enable stop{}END PROC direktbefehl 1;{}PROC warendatei bearbeiten:{} enable stop;{} loesche zwischenraum;{} ergaenze bildschirm;{} cursor (2, 24); out (invers ("Warendatei bearbeiten"));{} REP artikelnummer lesen;{}
+ IF NOT stoptaste gedrueckt{} THEN artikeldaten eingeben{} FI{} UNTIL stoptaste gedrueckt PER{}END PROC warendatei bearbeiten;{}PROC direktbefehl 2:{} disable stop;{} kundendatei bearbeiten;{} cursor off;{} IF is error{} THEN regenerate menuscreen;{} menuinfo (" " + invers (errormessage));{} clear error{} ELSE zweite zeile;{} menu bildschirm{} FI;{} enable stop{}END PROC direktbefehl 2;{}PROC kundendatei bearbeiten:{} enable stop;{} loesche zwischenraum;{}
+ ergaenze bildschirm;{} cursor (2, 24); out (invers ("Kundendatei bearbeiten"));{} REP kundennummer lesen;{} IF NOT stoptaste gedrueckt{} THEN kundendaten eingeben{} FI{} UNTIL stoptaste gedrueckt PER{}END PROC kundendatei bearbeiten;{}PROC direktbefehl 3:{} disable stop;{} einkaufen gehen;{} cursor off;{} IF is error{} THEN regenerate menuscreen;{} menuinfo (" " + invers (errormessage));{} clear error{} ELSE zweite zeile;{} menu bildschirm{}
+ FI;{} enable stop{}END PROC direktbefehl 3;{}PROC einkaufen gehen:{} enable stop;{} loesche zwischenraum;{} ergaenze bildschirm;{} cursor (2, 24); out (invers ("Einkaufen"));{} forget ("WARENHAUS:Rechnung", quiet);{} kundennummer lesen;{} rechnungskopf;{} REP einkaufen{} UNTIL stoptaste gedrueckt PER;{} abrechnung;{} forget ("WARENHAUS:Rechnung", quiet).{} einkaufen:{} artikelnummer lesen;{} IF NOT stoptaste gedrueckt{} THEN artikel kaufen{} FI.{}END PROC einkaufen gehen;{}
+PROC direktbefehl 4:{} disable stop;{} auskunft einholen;{} cursor off;{} IF is error{} THEN regenerate menuscreen;{} menuinfo (" " + invers (errormessage));{} clear error{} ELSE zweite zeile;{} menu bildschirm{} FI;{} enable stop{}END PROC direktbefehl 4;{}PROC auskunft einholen:{} enable stop;{} loesche zwischenraum;{} ergaenze bildschirm;{} cursor (2, 24); out (invers ("Auskunft"));{} auskunft{}END PROC auskunft einholen;{}PROC direktbefehl 5:{} disable stop;{}
+ ware nachbestellen;{} cursor off;{} IF is error{} THEN regenerate menuscreen;{} menuinfo (" " + invers (errormessage));{} clear error{} ELSE zweite zeile;{} menu bildschirm{} FI;{} enable stop{}END PROC direktbefehl 5;{}PROC ware nachbestellen:{} enable stop;{} loesche zwischenraum;{} ergaenze bildschirm;{} cursor (2, 24); out (invers ("Nachbestellen"));{} nachbestellen{}END PROC ware nachbestellen;{}PROC direktbefehl 6:{} disable stop;{} dezimalwerte von interface lesen;{}
+ cursor off;{} IF is error{} THEN regenerate menuscreen;{} menuinfo (" " + invers (errormessage));{} clear error{} ELSE zweite zeile;{} menu bildschirm{} FI;{} enable stop{}END PROC direktbefehl 6;{}PROC dezimalwerte von interface lesen:{} enable stop;{} loesche zwischenraum;{} ergaenze bildschirm;{} cursor (2, 24); out (invers ("Dezimalwert lesen"));{} dezimalwert lesen{}END PROC dezimalwerte von interface lesen;{}PROC direktbefehl 7:{} disable stop;{}
+ bitmuster von interface lesen;{} cursor off;{} IF is error{} THEN regenerate menuscreen;{} menuinfo (" " + invers (errormessage));{} clear error{} ELSE zweite zeile;{} menu bildschirm{} FI;{} enable stop{}END PROC direktbefehl 7;{}PROC bitmuster von interface lesen:{} enable stop;{} loesche zwischenraum;{} ergaenze bildschirm;{} cursor (2, 24); out (invers ("Bitmuster lesen"));{} bitmuster lesen{}END PROC bitmuster von interface lesen;{}PROC eingabeart anzeigen:{}
+ IF eingabe mit codekartenleser{} THEN menuinfo (anwendungstext (7), 4){} ELSE menuinfo (anwendungstext (6), 4){} FI{}END PROC eingabeart anzeigen;{}PROC warenhaus:{} BOOL VAR am ende loeschen :: TRUE;{} pruefe zulaessigkeit;{} installiere menukarte mit anfangsbild;{} initialisiere warenhaus;{} handle menu ("WARENHAUS");{} IF am ende loeschen{} THEN sperre verwaltungstask;{} end (task (verwaltung)){} FI.{} installiere menukarte mit anfangsbild:{} install menu (menukarte, TRUE);{}
+ cursor off;{} cursor (17, 20);{} out (" W A R E N H A U S ");{} cursor (21, 22);{} out (invers("Filiale " + text (channel (myself))));{} cursor (79, 24);{} pause (10).{} sperre verwaltungstask:{} DATASPACE VAR ds;{} INT VAR dummy;{} forget (ds); ds := nilspace;{} call (task (verwaltung), 256, ds, dummy).{} pruefe zulaessigkeit:{} IF hauptstellenname = ""{} THEN line;{} putline ("Keine uebergeordnete Task ist 'warenhaus hauptstelle'!");{} end; LEAVE warenhaus{}
+ ELIF name (myself) = hauptstellenname{} THEN errorstop ("Dieser Befehl darf nur von Söhnen dieser "{} + "Task aus gegeben werden!");{} LEAVE warenhaus{} FI.{} initialisiere warenhaus:{} TEXT CONST verwaltung :: hauptstellenname + ".Filialverwaltung "{} + text (channel (myself));{} IF NOT exists task (verwaltung){} THEN initialisiere verwaltung{} ELSE biete evtl loeschen an{} FI;{} IF NOT initialized (in this task){}
+ THEN filialdatenname := "";{} programmname := ""{} FI;{} noch kein programm gelaufen := TRUE.{} biete evtl loeschen an:{} access catalogue;{} IF NOT (father (task (verwaltung)) = myself){} THEN fehlermeldung;{} line;{} end;{} am ende loeschen := FALSE{} FI.{} fehlermeldung:{} cursor (1, 22);{} putline ("Filiale " + text (channel (myself)) +{} " ist bereits besetzt durch TASK '"{} + name (father (task (verwaltung))) + "'!");{}
+ putline ("Es ist so kein geregelter Warenhaus-Betrieb moeglich!").{}END PROC warenhaus;{}PROC grin (BOOL CONST entscheidung):{} enable stop;{} IF hauptstellenname = "" OR hauptstellenname = name (myself){} THEN grin version := entscheidung{} ELSE errorstop ("Dieser Befehl darf nur von der Task '" +{} hauptstellenname + "' aus gegeben werden!"){} FI;{} bildschirm neu eingesetzt := FALSE{}END PROC grin;{}PROC filialdaten verzeichnis:{} disable stop;{} THESAURUS VAR filialdaten ::{}
+ ohne praefix (infix namen (ALL myself, praefix, filialdatentyp), praefix);{} forget ("Verzeichnis der Filialdaten-Dateien", quiet);{} FILE VAR f ::{} sequential file (output, "Verzeichnis der Filialdaten-Dateien");{} f FILLBY filialdaten;{} modify (f);{} to line (f, 1); insert record (f);{} menufootnote ("Verlassen: <ESC> <q>");{} cursor on;{} show (w, f);{} cursor off;{} forget ("Verzeichnis der Filialdaten-Dateien", quiet);{} IF is error{} THEN regenerate menuscreen;{} out (""7"");{}
+ menuinfo (" " + invers ("FEHLER: " + errormessage));{} clear error{} ELSE menu bildschirm{} FI;{} enable stop{}END PROC filialdaten verzeichnis;{}PROC warenhausprogramme verzeichnis:{} disable stop;{} forget ("Verzeichnis der Programme", quiet);{} THESAURUS VAR programme ::{} ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{} IF exists ("WARENHAUS:Rechnung"){} THEN programme := programme - "WARENHAUS:Rechnung"{} FI;{} FILE VAR f ::{} sequential file (output, "Verzeichnis der Programme");{}
+ f FILLBY programme;{} modify (f);{} to line (f, 1); insert record (f);{} menufootnote ("Verlassen: <ESC> <q>");{} cursor on;{} show (w, f);{} cursor off;{} forget ("Verzeichnis der Programme", quiet);{} IF is error{} THEN regenerate menuscreen;{} out (""7"");{} menuinfo (" " + invers ("FEHLER: " + errormessage));{} clear error{} ELSE menu bildschirm{} FI;{} enable stop{}END PROC warenhausprogramme verzeichnis;{}PROC filialdaten zusammenstellen:{} hole filialdatenname;{}
+ kontrolliere den filialdatennamen;{} disable stop;{} sichere filialdaten (praefix + filialdatenname);{} IF is error{} THEN out (""7"");{} menuinfo (" " + invers ("FEHLER: " + errormessage));{} clear error{} ELSE bestaetige{} FI;{} enable stop.{} hole filialdatenname:{} filialdatenname := menuanswer (ausgabe, filialdatenname, 5).{} ausgabe:{} center (maxlaenge, invers ("Filialdaten zusammenstellen")) + ""13""13""{} + " Bitte den Namen für die Filialdaten "13""13"".{}
+ kontrolliere den filialdatennamen:{} IF filialdatenname = niltext{} THEN enable stop; LEAVE filialdaten zusammenstellen{} ELIF length (filialdatenname) > maxnamenslaenge{} THEN meckere zu langen namen an;{} filialdatenname := niltext;{} enable stop; LEAVE filialdaten zusammenstellen{} ELIF exists (praefix + filialdatenname){} THEN meckere existierenden filialdatennamen an;{} enable stop; LEAVE filialdaten zusammenstellen{}
+ FI.{} bestaetige:{} menuinfo (" "15"Bestätigung "14" "13""13"" +{} " Die Filialdaten wurden von der "13"" +{} " Verwaltung unter dem gewünschten "13"" +{} " Namen zusammengestellt. "13"" , 3).{}END PROC filialdaten zusammenstellen;{}PROC warenhausprogramm neu erstellen:{} hole programmname;{} kontrolliere den programmnamen;{} command dialogue (FALSE);{} cursor on;{} disable stop;{} stdinfoedit (programmname, 3);{}
+ cursor off;{} command dialogue (TRUE);{} IF is error{} THEN regenerate menuscreen;{} out (""7"");{} menuinfo (" " + invers (errormessage));{} clear error{} ELSE menu bildschirm{} FI;{} enable stop.{} hole programmname:{} programmname := "";{} programmname := menuanswer (ausgabe, programmname, 5).{} ausgabe:{} center (maxlaenge, invers ("Programm neu erstellen")) + ""13""13""{} + " Bitte den Namen für das Programm "13""13"".{} kontrolliere den programmnamen:{}
+ IF programmname = niltext{} THEN LEAVE warenhausprogramm neu erstellen{} ELIF length (programmname) > maxnamenslaenge{} THEN meckere zu langen namen an;{} programmname := niltext;{} LEAVE warenhausprogramm neu erstellen{} ELIF exists (programmname){} THEN meckere existierendes programm an;{} LEAVE warenhausprogramm neu erstellen{} FI.{}END PROC warenhausprogramm neu erstellen;{}PROC warenhausprogramm ansehen:{} IF programmname <> niltext CAND exists (programmname){}
+ THEN frage nach diesem programm{} ELSE lasse programm auswaehlen{} FI;{} cursor on;{} disable stop;{} stdinfoedit (programmname, 3);{} cursor off;{} IF is error{} THEN regenerate menuscreen;{} out (""7"");{} menuinfo (" " + invers ("FEHLER: " + errormessage));{} clear error{} ELSE menu bildschirm{} FI;{} enable stop.{} frage nach diesem programm:{} IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " + name{} + " Soll mit diesem Programm gearbeitet werden", 5){}
+ THEN lasse programm auswaehlen{} FI.{} ueberschrift:{} center (maxlaenge, invers ("Programm ansehen/ändern")) + ""13""13"".{} name:{} ""13""13" " + invers (programmname) + ""13""13"".{} lasse programm auswaehlen:{} THESAURUS VAR verfuegbare ::{} ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{} IF exists ("WARENHAUS:Rechnung"){} THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{} FI;{} IF NOT not empty (verfuegbare){} THEN noch kein programm;{}
+ LEAVE warenhausprogramm ansehen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} programmname := menuone (verfuegbare, "Programm ansehen/ändern",{} "Bitte das gewünschte Programm ankreuzen!",{} FALSE);{} IF programmname = niltext{} THEN menu bildschirm;{} LEAVE warenhausprogramm ansehen{} FI.{}END PROC warenhausprogramm ansehen;{}PROC filialdaten eintragen:{} lasse filialdaten auswaehlen;{}
+ trage filialdaten ein;{} menu bildschirm.{} lasse filialdaten auswaehlen:{} THESAURUS VAR verfuegbare ::{} ohne praefix (infix namen (ALL myself,praefix,filialdatentyp),praefix);{} IF NOT not empty (verfuegbare){} THEN noch keine filialdaten;{} LEAVE filialdaten eintragen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} verfuegbare := menusome (verfuegbare, bezeichnung,{} "Bitte die Filialdaten ankreuzen, die eingetragen werden sollen!", FALSE).{} trage filialdaten ein:{}
+ show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers (bezeichnung)));{} menuwindowline (2);{} command dialogue (FALSE);{} fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (schlussbemerkung);{} menuwindowstop.{} bezeichnung:{} "Filialdaten eintragen/ergänzen".{} schlussbemerkung:{} " Alle ausgewählten Filialdaten wurden eingetragen!".{} fuehre einzelne operationen aus:{}
+ INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{} IF name (verfuegbare, k) <> ""{} THEN disable stop;{} menuwindowout ( " Filialdaten """ + name (verfuegbare, k){} + """ werden eingetragen!");{} menuwindowline;{} lade filialdaten (praefix + name (verfuegbare, k));{} fehlerbehandlung{} FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){}
+ THEN menuwindowline (2);{} menuwindowout (" Es wurde keine Filialdaten-Datei ausgewählt!");{} menuwindowstop;{} menu bildschirm;{} LEAVE filialdaten eintragen{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen; out (""7"");{} menuinfo (" " + invers (errormessage));{}
+ clear error; enable stop;{} LEAVE filialdaten eintragen{} ELSE enable stop{} FI.{}END PROC filialdaten eintragen;{}PROC warenhausprogramme drucken:{} lasse programme auswaehlen;{} drucke programme;{} menu bildschirm.{} lasse programme auswaehlen:{} THESAURUS VAR verfuegbare ::{} ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{} IF exists ("WARENHAUS:Rechnung"){} THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{} FI;{} IF NOT not empty (verfuegbare){}
+ THEN noch kein programm;{} LEAVE warenhausprogramme drucken{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} verfuegbare := menusome (verfuegbare, "Programme drucken",{} "Bitte die Programme ankreuzen, die gedruckt werden sollen!",{} FALSE).{} drucke programme:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers ("Programme drucken")));{} menuwindowline (2);{} command dialogue (FALSE);{}
+ fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (" Alle ausgewählten Programme wurden gedruckt!");{} menuwindowstop.{} fuehre einzelne operationen aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{} IF name (verfuegbare, k) <> ""{} THEN disable stop;{} menuwindowout ( " """ + name (verfuegbare, k) +{} """ wird gedruckt!");{} menuwindowline;{}
+ print (name (verfuegbare, k));{} fehlerbehandlung{} FI{} PER.{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN menuwindowline (2);{} menuwindowout (" Es wurde kein Programm ausgewählt!");{} menuwindowstop;{} menu bildschirm;{} LEAVE warenhausprogramme drucken{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{}
+ ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen; out (""7"");{} menuinfo (" " + invers (errormessage));{} clear error; enable stop;{} LEAVE warenhausprogramme drucken{} ELSE enable stop{} FI.{}END PROC warenhausprogramme drucken;{}PROC warenhausprogramm kopieren:{} ermittle alten programmnamen;{} erfrage neuen programmnamen;{} kopiere ggf das programm.{} ermittle alten programmnamen:{} IF NOT not empty (bestand){}
+ THEN noch kein programm;{} LEAVE warenhausprogramm kopieren{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} TEXT VAR alter name := menuone ( bestand, "Programm kopieren",{} "Bitte das Programm ankreuzen, das kopiert werden soll!",FALSE);{} menu bildschirm;{} IF alter name = niltext{} THEN LEAVE warenhausprogramm kopieren{} FI.{} bestand:{} ALL myself - infix namen (ALL myself, praefix, filialdatentyp){} - "WARENHAUS:Rechnung".{}
+ erfrage neuen programmnamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + " Name des 'alten' Programms: " + bisheriger name{} + " Bitte den Namen für die Kopie: ".{} ueberschrift:{} center (maxlaenge, invers ("Programm kopieren")) + ""13""13"".{} bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{} kopiere ggf das programm:{} IF neuer name = niltext{} THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{}
+ LEAVE warenhausprogramm kopieren{} ELIF exists (neuer name){} THEN mache vorwurf;{} LEAVE warenhausprogramm kopieren{} ELSE copy (alter name, neuer name){} FI.{} mache vorwurf:{} menuinfo (" " + invers ("Ein Programm mit diesem Namen gibt es bereits!")).{}END PROC warenhausprogramm kopieren;{}PROC filialdaten umbenennen:{} ermittle alten filialdatennamen;{} erfrage neuen filialdatennamen;{} benenne ggf die filialdaten um.{} ermittle alten filialdatennamen:{}
+ IF NOT not empty (bestand){} THEN noch keine filialdaten;{} LEAVE filialdaten umbenennen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} TEXT VAR alter name := menuone ( bestand, text1, text2, FALSE);{} menu bildschirm;{} IF alter name = niltext{} THEN LEAVE filialdaten umbenennen{} FI.{} bestand:{} ohne praefix (infix namen (ALL myself, praefix, filialdatentyp), praefix).{} text1: "Filialdaten umbenennen".{} text2:{} "Bitte die Filialdaten-Datei ankreuzen, die umbenannt werden soll!" .{}
+ erfrage neuen filialdatennamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + hinweis auf alt + bisheriger name + aufforderung.{} ueberschrift:{} center (maxlaenge, invers ("Filialdaten umbenennen")) + ""13""13"".{} hinweis auf alt:{} " Bisheriger Filialdaten-Name: ".{} bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{} aufforderung:{} " Zukünftiger Filialdaten-Name: ".{} benenne ggf die filialdaten um:{} IF neuer name = niltext{}
+ THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{} LEAVE filialdaten umbenennen{} ELIF exists (praefix + neuer name){} THEN menuinfo (" " + invers("Filialdaten mit diesem Namen gibt es bereits!"));{} LEAVE filialdaten umbenennen{} ELSE rename (praefix + alter name, praefix + neuer name);{} filialdatenname := neuer name{} FI.{}END PROC filialdaten umbenennen;{}PROC warenhausprogramm umbenennen:{} ermittle alten programmnamen;{}
+ erfrage neuen programmnamen;{} benenne ggf das programm um.{} ermittle alten programmnamen:{} IF NOT not empty (bestand){} THEN noch kein programm;{} LEAVE warenhausprogramm umbenennen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} TEXT VAR alter name := menuone ( bestand, "Programm umbenennen",{} "Bitte das Programm ankreuzen, das umbenannt werden soll!", FALSE);{} menu bildschirm;{} IF alter name = niltext{} THEN LEAVE warenhausprogramm umbenennen{}
+ FI.{} bestand:{} ALL myself - infix namen (ALL myself, praefix, filialdatentyp){} - "WARENHAUS:Rechnung".{} erfrage neuen programmnamen:{} TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{} ausgabe:{} ueberschrift + " Bisheriger Programmname: " + bisheriger name{} + " Zukünftiger Programmname: ".{} ueberschrift:{} center (maxlaenge, invers ("Programm umbenennen")) + ""13""13"".{} bisheriger name:{} ""13""13" " + invers (alter name) + ""13""13"".{}
+ benenne ggf das programm um:{} IF neuer name = niltext{} THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{} LEAVE warenhausprogramm umbenennen{} ELIF exists (neuer name){} THEN mache vorwurf;{} LEAVE warenhausprogramm umbenennen{} ELSE rename (alter name, neuer name);{} programmname := neuer name{} FI.{} mache vorwurf:{} menuinfo (" " + invers ("Ein Programm mit diesem Namen gibt es bereits!")).{}END PROC warenhausprogramm umbenennen;{}
+PROC filialdaten loeschen:{} lasse filialdaten auswaehlen;{} loesche filialdaten;{} menu bildschirm.{} lasse filialdaten auswaehlen:{} THESAURUS VAR verfuegbare ::{} ohne praefix (infix namen (ALL myself, praefix, filialdatentyp), praefix);{} IF NOT not empty (verfuegbare){} THEN noch keine filialdaten;{} LEAVE filialdaten loeschen{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} verfuegbare := menusome (verfuegbare, "Filialdaten-Dateien löschen",{} "Bitte alle Dateien ankreuzen, die gelöscht werden sollen!", FALSE).{}
+ loesche filialdaten:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers ("Filialdaten-Dateien löschen")));{} menuwindowline (2);{} command dialogue (FALSE);{} fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{} menuwindowout (" Alle ausgewählten Dateien wurden gelöscht!");{} menuwindowstop.{} fuehre einzelne operationen aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}
+ IF name (verfuegbare, k) <> ""{} THEN disable stop;{} IF menuwindowyes (" """ + name (verfuegbare, k){} + """ löschen"){} THEN forget (praefix + name (verfuegbare, k), quiet){} FI;{} fehlerbehandlung{} FI{} PER;{} filialdatenname := "".{} steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN menuwindowline (2);{} menuwindowout (" Es wurde keine Filialdaten-Datei ausgewählt!");{}
+ menuwindowstop;{} menu bildschirm;{} LEAVE filialdaten loeschen{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} menuinfo (" " + invers (errormessage));{} clear error; enable stop;{} LEAVE filialdaten loeschen{} ELSE enable stop{} FI.{}
+END PROC filialdaten loeschen;{}PROC warenhausprogramme loeschen:{} lasse programme auswaehlen;{} loesche programme;{} menu bildschirm.{} lasse programme auswaehlen:{} THESAURUS VAR verfuegbare ::{} ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{} IF exists ("WARENHAUS:Rechnung"){} THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{} FI;{} IF NOT not empty (verfuegbare){} THEN noch kein programm;{} LEAVE warenhausprogramme loeschen{}
+ ELSE biete auswahl an{} FI.{} biete auswahl an:{} verfuegbare := menusome (verfuegbare, "Programm löschen",{} "Bitte alle Programme ankreuzen, die gelöscht werden sollen!", FALSE).{} loesche programme:{} show menuwindow;{} steige ggf bei leerem thesaurus aus;{} menuwindowout (menuwindowcenter (invers ("Programme löschen")));{} menuwindowline (2);{} command dialogue (FALSE);{} fuehre einzelne operationen aus;{} command dialogue (TRUE);{} schlage ggf neue seite auf;{}
+ menuwindowout (" Alle ausgewählten Programme wurden gelöscht!");{} menuwindowstop.{} fuehre einzelne operationen aus:{} INT VAR k;{} FOR k FROM 1 UPTO highest entry (verfuegbare) REP{} IF name (verfuegbare, k) <> ""{} THEN disable stop;{} IF menuwindowyes (" """ + name (verfuegbare, k) + """ löschen"){} THEN forget (name (verfuegbare, k), quiet){} FI;{} fehlerbehandlung{} FI{} PER;{} programmname := "".{}
+ steige ggf bei leerem thesaurus aus:{} IF NOT not empty (verfuegbare){} THEN menuwindowline (2);{} menuwindowout (" Es wurde kein Programm ausgewählt!");{} menuwindowstop;{} menu bildschirm;{} LEAVE warenhausprogramme loeschen{} FI.{} schlage ggf neue seite auf:{} IF remaining menuwindowlines < 7{} THEN menuwindowpage; menuwindowline{} ELSE menuwindowline (2){} FI.{} fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen; out (""7"");{}
+ menuinfo (" " + invers (errormessage));{} clear error; enable stop;{} LEAVE warenhausprogramme loeschen{} ELSE enable stop{} FI.{}END PROC warenhausprogramme loeschen;{}PROC warenhausprogramm starten:{} IF grin version{} THEN warenhausprogramm uebersetzen und starten{} ELSE warenhausprogramm direkt starten{} FI{}END PROC warenhausprogramm starten;{}PROC warenhausprogramm direkt starten:{} programmname ermitteln;{} bildschirm neu eingesetzt := FALSE;{}
+ untersuche programmdatei auf bildschirm neu;{} cursor w3 1 1;{} cursor (1, 24); out(""5"Das Programm wird übersetzt. Zeilen-Nr.: ");{} cursor on;{} check on;{} warnings off;{} disable stop;{} run (programmname);{} noch kein programm gelaufen := FALSE;{} IF bildschirm neu eingesetzt{} THEN entferne befehl aus programmdatei{} FI;{} cursor off;{} fehlerbehandlung;{} cursor (2,23); out ((40 * waagerecht) + balken unten + (36 * waagerecht));{} cursor (2,24);{} out ("Das Programm ist beendet. " +{}
+ "Zum Weitermachen bitte irgendeine Taste tippen!");{} pause;{} regenerate menuscreen.{} fehlerbehandlung:{} IF is error{} THEN fehler ggf melden{} ELSE enable stop{} FI.{} fehler ggf melden:{} IF errormessage = ""{} THEN regenerate menuscreen{} ELSE fehler melden{} FI;{} clear error; enable stop;{} LEAVE warenhausprogramm direkt starten.{} fehler melden:{} out (""7"");{} IF errorcode = 1 OR errorcode = 1951{} THEN regenerate menuscreen;{}
+ menuinfo (" " + invers (errormessage)){} ELSE programm mit fehler zeigen;{} regenerate menuscreen{} FI.{} programmname ermitteln:{} IF programmname <> niltext CAND exists (programmname){} THEN frage nach diesem programm{} ELSE lasse programm auswaehlen{} FI.{} frage nach diesem programm:{} IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " +{} name + " Soll mit diesem Programm gearbeitet werden", 5){} THEN lasse programm auswaehlen{}
+ FI.{} ueberschrift:{} center (maxlaenge, invers ("Programm starten")) + ""13""13"".{} name:{} ""13""13" " + invers (programmname) + ""13""13"".{} lasse programm auswaehlen:{} THESAURUS VAR verfuegbare ::{} ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{} IF exists ("WARENHAUS:Rechnung"){} THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{} FI;{} IF NOT not empty (verfuegbare){} THEN noch kein programm;{} LEAVE warenhausprogramm direkt starten{}
+ ELSE biete auswahl an{} FI.{} biete auswahl an:{} programmname := menuone (verfuegbare, "Programm starten",{} "Bitte das gewünschte Programm ankreuzen!", FALSE);{} menubildschirm;{} menufootnote ("");{} IF programmname = niltext{} THEN LEAVE warenhaus programm direkt starten{} FI.{} untersuche programmdatei auf bildschirm neu:{} FILE VAR a :: sequential file (modify, programmname);{} TEXT VAR zeile;{} to line (a, 1);{} REP{} read record (a, zeile);{}
+ IF NOT eof (a) THEN down (a) FI{} UNTIL zeile <> "" OR eof (a) PER;{} change all (zeile, " ", "");{} IF pos (zeile, "bildschirmneu") = 0{} THEN setze befehl in datei ein{} FI.{} setze befehl in datei ein:{} to line (a, 1);{} zeile := "bildschirm neu; (* ergänzt *)";{} insert record (a);{} write record (a, zeile);{} bildschirm neu eingesetzt := TRUE.{} entferne befehl aus programmdatei:{} FILE VAR b :: sequential file (modify, programmname);{} to line (b, 1);{}
+ REP{} read record (b, zeile);{} IF NOT eof (b) THEN down (b) FI{} UNTIL zeile <> "" OR eof (b) PER;{} change all (zeile, " ", "");{} IF pos (zeile, "bildschirmneu;(*ergänzt*)") > 0{} THEN up (b); delete record (b){} FI.{}END PROC warenhausprogramm direkt starten;{}PROC warenhausprogramm uebersetzen und starten:{} programmname ermitteln;{} cursor w3 1 1;{} cursor (1, 24); out(""5"Das Programm wird übersetzt. Zeilen-Nr.: ");{} cursor on;{} disable stop;{} uebersetze (programmname);{}
+ IF NOT is error{} THEN check on;{} warnings off;{} run ("elanprogramm");{} noch kein programm gelaufen := FALSE{} FI;{} forget ("elanprogramm", quiet);{} cursor off;{} fehlerbehandlung;{} cursor (2,23); out ((40 * waagerecht) + balken unten + (36 * waagerecht));{} cursor (2,24);{} out ("Das Programm ist beendet. " +{} "Zum Weitermachen bitte irgendeine Taste tippen!");{} pause;{} regenerate menuscreen.{} fehlerbehandlung:{} IF is error{} THEN fehler ggf melden{}
+ ELSE enable stop{} FI.{} fehler ggf melden:{} IF errormessage = ""{} THEN regenerate menuscreen{} ELSE fehler melden{} FI;{} clear error; enable stop;{} LEAVE warenhausprogramm uebersetzen und starten.{} fehler melden:{} out (""7"");{} IF errorcode = 1 OR errorcode = 1951{} THEN regenerate menuscreen;{} menuinfo (" " + invers (errormessage)){} ELSE programm mit fehler zeigen ;{} regenerate menuscreen{} FI.{} programmname ermitteln:{}
+ IF programmname <> niltext CAND exists (programmname){} THEN frage nach diesem programm{} ELSE lasse programm auswaehlen{} FI.{} frage nach diesem programm:{} IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " +{} name + " Soll mit diesem Programm gearbeitet werden", 5){} THEN lasse programm auswaehlen{} FI.{} ueberschrift:{} center (maxlaenge, invers ("Programm starten")) + ""13""13"".{} name:{} ""13""13" " + invers (programmname) + ""13""13"".{}
+ lasse programm auswaehlen:{} THESAURUS VAR verfuegbare ::{} ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{} IF exists ("WARENHAUS:Rechnung"){} THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{} FI;{} IF NOT not empty (verfuegbare){} THEN noch kein programm;{} LEAVE warenhausprogramm uebersetzen und starten{} ELSE biete auswahl an{} FI.{} biete auswahl an:{} programmname := menuone (verfuegbare, "Programm starten",{}
+ "Bitte das gewünschte Programm ankreuzen!", FALSE);{} menubildschirm;{} menufootnote ("");{} IF programmname = niltext{} THEN LEAVE warenhaus programm uebersetzen und starten{} FI.{}END PROC warenhausprogramm uebersetzen und starten;{}PROC programm mit fehler zeigen:{} IF exists (programmname){} THEN noteline;{} note (fehlermeldung mit zeilennummer);{} INT VAR i; FOR i FROM 1 UPTO 9 REP noteline PER;{} note (invers ("Verlassen: <ESC><q>"));{}
+ FILE VAR f :: sequential file (modify, programmname);{} to line (f, max (1, fehlerzeile));{} col (1);{} clear error;{} cursor on;{} noteedit (f);{} cursor off{} ELSE menuinfo (invers (fehlermeldung mit zeilennummer)){} FI{}END PROC programm mit fehler zeigen;{}PROC warenhausprogramm wiederholen:{} cursor on;{} disable stop;{} IF noch kein programm gelaufen{} THEN errorstop ("'run again' nicht moeglich"){} ELSE runagain{} FI;{}
+ cursor off;{} fehlerbehandlung;{} cursor (2,23); out ((40 * waagerecht) + balken unten + (36 * waagerecht));{} cursor (2,24);{} out ("Das Programm ist beendet. " +{} "Zum Weitermachen bitte irgendeine Taste tippen!");{} pause;{} regenerate menuscreen.{}fehlerbehandlung:{} IF is error{} THEN regenerate menuscreen;{} fehler melden;{} clear error; enable stop;{} LEAVE warenhausprogramm wiederholen{} ELSE enable stop{} FI.{} fehler melden:{}
+ out (""7"");{} IF errorcode = 1 OR errorcode = 1951{} THEN menuinfo (" " + invers (errormessage)){} ELIF errormessage = "'run again' nicht moeglich"{} THEN menuinfo (" " + invers ("Wiederholung nicht möglich!")){} ELSE menuinfo (" " + invers (fehlermeldung mit zeilennummer)){} FI{}END PROC warenhausprogramm wiederholen;{}TEXT PROC fehlermeldung mit zeilennummer:{} TEXT VAR meldung :: "FEHLER: " + errormessage;{} fuege ggf fehlerzeile an;{} IF length (meldung) < 70{}
+ THEN meldung{} ELSE subtext (meldung, 1, 69){} FI.{} fuege ggf fehlerzeile an:{} fehlerzeile := errorline;{} IF errorline < 1{} THEN LEAVE fuege ggf fehlerzeile an{} ELIF bildschirm neu eingesetzt{} THEN meldung CAT " (bei Zeile " + text (errorline - 1) + ")"{} ELSE meldung CAT " (bei Zeile " + text (errorline) + ")"{} FI.{}END PROC fehlermeldung mit zeilennummer;{}PROC meckere zu langen namen an:{} menuinfo (" " + invers ("Hier dürfen Namen höchstens "{}
+ + text (max namenslaenge){} + " Zeichen lang sein!")){}END PROC meckere zu langen namen an;{}PROC meckere existierenden filialdatennamen an:{} menuinfo (" " + invers ("Filialdaten mit diesem Namen gibt es bereits!")){}END PROC meckere existierenden filialdatennamen an;{}PROC meckere existierendes programm an:{} menuinfo (" " + invers ("Ein Programm mit diesem Namen gibt es bereits!")){}END PROC meckere existierendes programm an;{}PROC noch keine filialdaten:{} menuinfo (" " + invers ("Es existiert noch keine Filialdaten-Datei!")){}
+END PROC noch keine filialdaten;{}PROC noch kein programm:{} menuinfo (" " + invers ("Es existiert noch kein Programm!")){}END PROC noch kein programm;{}PROC menu bildschirm:{} cursor (1, 2);{} out (5 * waagerecht);{} cursor (1, 3);{} out (""4"");{} cursor (1, 23);{} out (79 * waagerecht);{} refresh submenu{}END PROC menu bildschirm{}END PACKET ls warenhaus 5{}
+
diff --git a/warenhaus/ls-Warenhaus-gen b/warenhaus/ls-Warenhaus-gen
new file mode 100644
index 0000000..f4bd77f
--- /dev/null
+++ b/warenhaus/ls-Warenhaus-gen
@@ -0,0 +1,29 @@
+(*
+
+ **********************************************************
+ **********************************************************
+ ** **
+ ** ls-Warenhaus/gen **
+ ** **
+ ** Version 1.01 **
+ ** **
+ ** **
+ ** (Stand: 30.08.89) **
+ ** **
+ ** **
+ ** **
+ ** Autor: Bruno Pollok, Bielefeld **
+ ** **
+ ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld **
+ ** Copyright (C) 1990 ERGOS GmbH, Siegburg **
+ ** **
+ **********************************************************
+ **********************************************************
+
+ *)
+LET kartenleserkennung = "ls-Warenhaus 0: mit Kartenleser";
+baue bildschirm auf;{}schicke menukarte ab;{}erfrage anpassung;{}check off;{}warnings off;{}insertiere (anpassung);{}loesche alle anpassungen;{}insertiere ("ls-Warenhaus 1");{}insertiere ("ls-Warenhaus 2");{}insertiere ("ls-Warenhaus 3");{}insertiere ("ls-Warenhaus 4");{}insertiere ("ls-Warenhaus 5");{}check on;{}frage nach grin;{}frage nach hauptstelle.{}baue bildschirm auf:{} page;{} cursor (18, 1);{} out (invers ("ls-Warenhaus : Automatische Generierung"));{} line (3).{}erfrage anpassung:{}
+ WINDOW VAR w :: window (1, 1, 79, 24);{} TEXT VAR anpassung :: boxone (w, alle kartenleser,{} "Auswahl einer Interface - Anpassung für den Codekartenleser",{} "Wenn kein Kartenleser benutzt wird, <ESC><q> tippen!", FALSE);{} IF anpassung = ""{} THEN anpassung := "ls-Warenhaus 0: ohne Kartenleser"{} FI;{} baue bildschirm auf.{}alle kartenleser:{} infix namen (ALL myself, kartenleserkennung).{}loesche alle anpassungen:{} command dialogue (FALSE);{} forget (infixnamen (ALL myself, "ls-Warenhaus 0"));{}
+ forget ("--------------------------------------------------------",quiet);{} command dialogue (TRUE).{}schicke menukarte ab:{} command dialogue (FALSE);{} save ("ls-MENUKARTE:Warenhaus", /"ls-MENUKARTEN");{} command dialogue (TRUE);{} forget ("ls-MENUKARTE:Warenhaus", quiet);{} forget ("ls-Warenhaus/gen", quiet).{}frage nach grin:{} line;{} IF yes ("Version für GRIN"){} THEN do ("grin (TRUE)"){} ELSE do ("grin (FALSE)"){} FI.{}frage nach hauptstelle:{} line (2);{} IF yes ("Soll diese Task Warenhaus - Hauptstelle sein"){}
+ THEN do ("warenhaus hauptstelle (TRUE)"){} ELSE global manager{} FI.{};{}PROC insertiere (TEXT CONST dateiname):{} INT VAR s, z;{} out ("'" + dateiname + "'");{} get cursor (s, z);{} out (" wird insertiert. ");{} insert (dateiname);{} forget (dateiname, quiet);{} cursor (s, z);{} out (""4"") ;{} line{}END PROC insertiere{}
+