From 724cc003460ec67eda269911da85c9f9e40aa6cf Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Fri, 30 Sep 2016 16:57:23 +0200 Subject: Add extracted sources from floppy disk images Some files have no textual representation (yet) and were added as raw dataspaces. --- at/AT Generator | 135 + at/AT Utilities | 1057 ++++++ at/AT install | 93 + basic/BASIC.Administration | 1886 +++++++++++ basic/BASIC.Compiler | 2305 +++++++++++++ basic/BASIC.Runtime | 1571 +++++++++ basic/eumel coder 1.8.1 | 3086 +++++++++++++++++ basic/eumel0 codes | Bin 0 -> 512 bytes basic/gen.BASIC | 80 + datatype/complex | 115 + datatype/longint | 423 +++ datatype/matrix | 482 +++ datatype/vector | 213 ++ dialog/ls-DIALOG 1 | 60 + dialog/ls-DIALOG 2 | 77 + dialog/ls-DIALOG 3 | 48 + dialog/ls-DIALOG 4 | 71 + dialog/ls-DIALOG 5 | 118 + dialog/ls-DIALOG 6 | 102 + dialog/ls-DIALOG 7 | 54 + dialog/ls-DIALOG MENUKARTEN MANAGER | 28 + dialog/ls-DIALOG MM-gen | 27 + dialog/ls-DIALOG decompress | 150 + dialog/ls-DIALOG-gen | 34 + dialog/ls-MENUKARTE:Archiv | Bin 0 -> 40960 bytes doc/basic/basic handbuch.1 | 1075 ++++++ doc/basic/basic handbuch.2 | 2441 ++++++++++++++ doc/basic/basic handbuch.3 | 698 ++++ doc/basic/basic handbuch.index | 232 ++ doc/dialog/gs-dialog handbuch.impressum | 89 + doc/dialog/gs-dialog-1 | 107 + doc/dialog/gs-dialog-2 | 215 ++ doc/dialog/gs-dialog-3 | 683 ++++ doc/dialog/gs-dialog-4 | 672 ++++ doc/dialog/gs-dialog-5 | 176 + doc/dialog/gs-dialog-Inhaltsverzeichnis | 45 + doc/dynamo/dynamo handbuch | 1826 ++++++++++ doc/dynamo/dynamo handbuch.index | 69 + doc/dynamo/dynamo handbuch.inhalt | 131 + doc/eudas/abb.1-1 | 94 + doc/eudas/abb.4-1 | 43 + doc/eudas/abb.4-2 | 46 + doc/eudas/abb.6-1 | 75 + doc/eudas/abb.6-2 | 77 + doc/eudas/abb.7-1 | 46 + doc/eudas/abb.9-1 | 41 + doc/eudas/abb.9-2 | 96 + doc/eudas/abb.9-3 | 113 + doc/eudas/abb.9-4 | 98 + doc/eudas/abb.9-5 | 51 + doc/eudas/bildergenerator | 25 + doc/eudas/eudas.hdb.1 | 267 ++ doc/eudas/eudas.hdb.10 | 510 +++ doc/eudas/eudas.hdb.11 | 674 ++++ doc/eudas/eudas.hdb.12 | 446 +++ doc/eudas/eudas.hdb.13 | 757 +++++ doc/eudas/eudas.hdb.14 | 724 ++++ doc/eudas/eudas.hdb.15 | 286 ++ doc/eudas/eudas.hdb.16 | 350 ++ doc/eudas/eudas.hdb.2 | 178 + doc/eudas/eudas.hdb.3 | 515 +++ doc/eudas/eudas.hdb.5 | 386 +++ doc/eudas/eudas.hdb.6 | 394 +++ doc/eudas/eudas.hdb.7 | 687 ++++ doc/eudas/eudas.hdb.8 | 211 ++ doc/eudas/eudas.hdb.9 | 556 ++++ doc/eudas/eudas.hdb.inhalt | 133 + doc/eudas/eudas.hdb.macros | 80 + doc/eudas/eudas.hdb.titel | 99 + doc/eudas/eudas.hdb.vorwort | 89 + doc/eudas/eudas.ref.1 | 326 ++ doc/eudas/eudas.ref.10 | 406 +++ doc/eudas/eudas.ref.11 | 347 ++ doc/eudas/eudas.ref.2 | 830 +++++ doc/eudas/eudas.ref.3 | 270 ++ doc/eudas/eudas.ref.4 | 441 +++ doc/eudas/eudas.ref.5 | 432 +++ doc/eudas/eudas.ref.6 | 399 +++ doc/eudas/eudas.ref.7 | 447 +++ doc/eudas/eudas.ref.8 | 454 +++ doc/eudas/eudas.ref.9 | 194 ++ doc/eudas/eudas.ref.fehler | 139 + doc/eudas/eudas.ref.inhalt | 120 + doc/eudas/eudas.ref.macros | 73 + doc/eudas/eudas.ref.proz | 205 ++ doc/eudas/eudas.ref.reg | 436 +++ doc/eudas/eudas.ref.titel | 91 + doc/eudas/eudas.ref.vorwort | 81 + doc/eudas/ref.abb.1-1 | 42 + doc/eudas/register | 490 +++ doc/eudas/uedas.hdb.4 | 686 ++++ doc/graphic/Altes Handbuch - Teil 10 - Graphik | 831 +++++ doc/graphic/GRAPHIK.book | 897 +++++ doc/graphic/graphik beschreibung | 661 ++++ ...Doku: gs-Herbert und Robbi - Inhaltsverzeichnis | 45 + .../A5 - Doku: gs-Herbert und Robbi - Kapitel 1 | 93 + .../A5 - Doku: gs-Herbert und Robbi - Kapitel 2 | 389 +++ .../A5 - Doku: gs-Herbert und Robbi - Kapitel 3 | 199 ++ .../A5 - Doku: gs-Herbert und Robbi - Kapitel 4 | 1312 ++++++++ .../A5 - Doku: gs-Herbert und Robbi - Kapitel 5 | 167 + .../A5 - Doku: gs-Herbert und Robbi - Kapitel 6 | 73 + .../gs-Herbert und Robbi handbuch.impressum | 87 + doc/lisp/lisp handbuch | 2260 +++++++++++++ doc/menugenerator/menu-generator handbuch.1 | 100 + doc/menugenerator/menu-generator handbuch.2 | 87 + doc/menugenerator/menu-generator handbuch.3 | 155 + doc/menugenerator/menu-generator handbuch.4 | 424 +++ doc/menugenerator/menu-generator handbuch.5 | 975 ++++++ doc/menugenerator/menu-generator handbuch.6 | 235 ++ doc/menugenerator/menu-generator handbuch.7 | 367 +++ doc/menugenerator/menu-generator handbuch.8 | 1676 ++++++++++ .../menu-generator handbuch.impressum | 88 + doc/menugenerator/menu-generator handbuch.index | 258 ++ doc/menugenerator/menu-generator handbuch.inhalt | 72 + .../A5 - Doku: gs-MP BAP - Inhaltsverzeichnis | 50 + doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1 | 119 + doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2 | 302 ++ doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3 | 237 ++ doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4 | 638 ++++ doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5 | 699 ++++ doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6 | 53 + doc/mp-bap/gs-MP BAP handbuch.impressum | 104 + doc/programming/programmierhandbuch.1 | 650 ++++ doc/programming/programmierhandbuch.2a | 1845 +++++++++++ doc/programming/programmierhandbuch.2b | 1395 ++++++++ doc/programming/programmierhandbuch.3 | 728 ++++ doc/programming/programmierhandbuch.4 | 1692 ++++++++++ doc/programming/programmierhandbuch.5 | 1329 ++++++++ doc/programming/programmierhandbuch.5b | 1481 +++++++++ doc/programming/programmierhandbuch.6 | 1441 ++++++++ doc/programming/programmierhandbuch.index | 449 +++ doc/programming/programmierhandbuch.inhalt | 249 ++ doc/programming/programmierhandbuch.titel | 52 + doc/prolog/prolog handbuch | 581 ++++ doc/prozess/Anhang Prozess | 92 + doc/prozess/Inhalt Prozess | 84 + doc/prozess/gs-Prozess handbuch.impressum | 104 + doc/prozess/gs-Prozess-2 | 255 ++ doc/prozess/gs-Prozess-3 | 346 ++ doc/prozess/gs-Prozess-4 | 173 + doc/prozess/gs-prozess-1 | 99 + doc/prozess/gs-prozess-5 | 819 +++++ doc/prozess/gs-prozess-6 | 641 ++++ doc/prozess/gs-prozess-7 | 1121 +++++++ doc/prozess/gs-prozess-8 | 377 +++ doc/prozess/gs-prozess-9 | 477 +++ doc/system/systemhandbuch.1 | 1685 ++++++++++ doc/system/systemhandbuch.2 | 1351 ++++++++ doc/system/systemhandbuch.3 | 1366 ++++++++ doc/system/systemhandbuch.4 | 1185 +++++++ doc/user/benutzerhandbuch.1 | 580 ++++ doc/user/benutzerhandbuch.2 | 443 +++ doc/user/benutzerhandbuch.3 | 2019 ++++++++++++ doc/user/benutzerhandbuch.4 | 2242 +++++++++++++ doc/user/benutzerhandbuch.5a | 1446 ++++++++ doc/user/benutzerhandbuch.5b | 1632 +++++++++ doc/user/benutzerhandbuch.5c | 711 ++++ doc/user/benutzerhandbuch.5d | 211 ++ doc/user/benutzerhandbuch.5e | 223 ++ doc/user/benutzerhandbuch.6 | 474 +++ doc/user/benutzerhandbuch.anhang | 484 +++ doc/warenhaus/Anhang Warenhaus | 65 + doc/warenhaus/Inhalt Warenhaus | 50 + doc/warenhaus/gs-Warenhaus handbuch.impressum | 89 + doc/warenhaus/gs-Warenhaus-1 | 124 + doc/warenhaus/gs-Warenhaus-2 | 72 + doc/warenhaus/gs-Warenhaus-3 | 309 ++ doc/warenhaus/gs-Warenhaus-4 | 378 +++ doc/warenhaus/gs-Warenhaus-5 | 1468 +++++++++ doc/warenhaus/gs-Warenhaus-6 | 589 ++++ doc/warenhaus/gs-Warenhaus-7 | 235 ++ dos/block i-o | 180 + dos/dir.dos | 693 ++++ dos/disk descriptor.dos | 339 ++ dos/dos hd inserter | 41 + dos/dos inserter | 59 + dos/dos-dat-handbuch | 650 ++++ dos/dump | 49 + dos/eu disk descriptor | 107 + dos/fat.dos | 369 +++ dos/fetch | 371 +++ dos/fetch save interface | 70 + dos/get put interface.dos | 368 +++ dos/insert.dos | 14 + dos/konvert | 75 + dos/manager-M.dos | 211 ++ dos/manager-S.dos | 268 ++ dos/name conversion.dos | 77 + dos/open | 66 + dos/save | 233 ++ dos/shard interface | 20 + dynamo/dyn.33 | 2073 ++++++++++++ dynamo/dyn.abnahme | 19 + dynamo/dyn.bev | 50 + dynamo/dyn.cob | 19 + dynamo/dyn.delaytest | 8 + dynamo/dyn.errors | 68 + dynamo/dyn.forest | 47 + dynamo/dyn.forst7 | 76 + dynamo/dyn.gekoppeltependel | 19 + dynamo/dyn.grashasenfuchs | 42 + dynamo/dyn.help | 24 + dynamo/dyn.inserter | 54 + dynamo/dyn.mac | 44 + dynamo/dyn.mehreredelays | 9 + dynamo/dyn.natchez | 14 + dynamo/dyn.oszillator | 26 + dynamo/dyn.plot | 235 ++ dynamo/dyn.plot+ | 729 ++++ dynamo/dyn.print | 43 + dynamo/dyn.proc | 160 + dynamo/dyn.quadrat | 13 + dynamo/dyn.rts | 376 +++ dynamo/dyn.ruestungswettlauf | 32 + dynamo/dyn.simon | 28 + dynamo/dyn.std | 9 + dynamo/dyn.steifedgl | 15 + dynamo/dyn.tool | 217 ++ dynamo/dyn.vec | 209 ++ dynamo/dyn.wachstum | 19 + "dynamo/dyn.wasser\303\266ko" | 64 + dynamo/dyn.welt-forrester | 124 + dynamo/dyn.wohnen | 105 + dynamo/dyn.workfluc | 44 + dynamo/dyn.wurzel | 14 + dynamo/out.world | 43 + eudas/Adressen | Bin 0 -> 3584 bytes eudas/dummy.text | 14 + eudas/eudas.1 | 52 + eudas/eudas.2 | 62 + eudas/eudas.3 | 58 + eudas/eudas.4 | 150 + eudas/eudas.generator | 86 + eudas/eudas.init | 1463 +++++++++ eudas/pos.173 | 19 + graphic/Beispiel.Kreuz | 41 + graphic/Beispiel.Sinus | 45 + graphic/GRAPHIK.Picfile | 738 +++++ graphic/GRAPHIK.Plot | 285 ++ graphic/GRAPHIK.Plotter | 247 ++ graphic/GRAPHIK.Server | 97 + graphic/GRAPHIK.Transform | 366 +++ graphic/GRAPHIK.vektor plot | 506 +++ graphic/HP7475.plot | 254 ++ graphic/PC.plot | 758 +++++ graphic/ZEICHENSATZ | Bin 0 -> 11776 bytes graphic/gen Graphik | 16 + graphic/gen Plotter | 16 + graphic/graphik editor | 324 ++ hamster/ls-Herbert und Robbi 1 | 84 + hamster/ls-Herbert und Robbi 2 | 31 + hamster/ls-Herbert und Robbi 3 | 84 + hamster/ls-Herbert und Robbi-gen | 33 + hamster/ls-MENUKARTE:Herbert und Robbi | Bin 0 -> 94720 bytes lisp/lisp.1 | 1306 ++++++++ lisp/lisp.2 | 584 ++++ lisp/lisp.3 | 767 +++++ lisp/lisp.4 | 143 + lisp/lisp.bootstrap | 118 + menugenerator/Generatordatei: Archivmenu | 323 ++ menugenerator/fonttab.ls-Menu-Generator | Bin 0 -> 2560 bytes menugenerator/ls-MENUBASISTEXTE | Bin 0 -> 17408 bytes menugenerator/ls-Menu-Generator 1 | 47 + menugenerator/ls-Menu-Generator 2 | 72 + menugenerator/ls-Menu-Generator-gen | 30 + mp-bap/ls-MENUKARTE:MP-BAP | Bin 0 -> 79872 bytes mp-bap/ls-MP BAP 1 | 119 + mp-bap/ls-MP BAP 2 | 126 + mp-bap/ls-MP BAP-gen | 30 + net/basic net | 1148 +++++++ net/net files-M | 5 + net/net hardware interface | 389 +++ net/net inserter | 145 + net/net manager | 797 +++++ net/net report | 41 + net/netz | 20 + net/netzhandbuch | 2045 ++++++++++++ net/netzhandbuch.anhang | 58 + net/netzhandbuch.index | 259 ++ net/port server | 164 + net/printer server | 99 + net/spool cmd | 112 + net/spool manager | 915 ++++++ printer/dotmatrix24/beschreibungen24 | 62 + printer/dotmatrix24/fonttab.brother | Bin 0 -> 38400 bytes printer/dotmatrix24/fonttab.epson.lq1500 | Bin 0 -> 35840 bytes printer/dotmatrix24/fonttab.epson.lq850 | Bin 0 -> 38400 bytes printer/dotmatrix24/fonttab.nec.p5 | Bin 0 -> 39936 bytes printer/dotmatrix24/fonttab.nec.p5.new | Bin 0 -> 39936 bytes printer/dotmatrix24/fonttab.nec.p6+ | Bin 0 -> 48128 bytes printer/dotmatrix24/fonttab.oki | Bin 0 -> 38400 bytes printer/dotmatrix24/fonttab.toshiba.p321 | Bin 0 -> 15872 bytes printer/dotmatrix24/inserter | 793 +++++ printer/dotmatrix24/module24 | 1554 +++++++++ printer/dotmatrix24/printer.24.nadel | 776 +++++ printer/dotmatrix24/readme | 320 ++ printer/dotmatrix9/beschreibungen9 | 97 + printer/dotmatrix9/fonttab.1 | Bin 0 -> 11264 bytes printer/dotmatrix9/fonttab.10 | Bin 0 -> 15872 bytes printer/dotmatrix9/fonttab.20 | Bin 0 -> 36864 bytes printer/dotmatrix9/fonttab.20.lc | Bin 0 -> 36864 bytes printer/dotmatrix9/fonttab.20.lx | Bin 0 -> 24576 bytes printer/dotmatrix9/fonttab.7 | Bin 0 -> 46080 bytes printer/dotmatrix9/fonttab.7.cxp | Bin 0 -> 46080 bytes printer/dotmatrix9/fonttab.7.fuj | Bin 0 -> 56832 bytes printer/dotmatrix9/fonttab.7.mt | Bin 0 -> 46080 bytes printer/dotmatrix9/module9 | 1099 +++++++ printer/dotmatrix9/printer.neun.nadel | 1129 +++++++ printer/dotmatrix9/readme | 324 ++ printer/laser/fonttab.apple.laserwriter | Bin 0 -> 100864 bytes printer/laser/fonttab.canon.lbp-8 | Bin 0 -> 58368 bytes printer/laser/fonttab.epson.sq | Bin 0 -> 29696 bytes printer/laser/fonttab.hp.laserjet | Bin 0 -> 24064 bytes printer/laser/fonttab.kyocera.f-1010 | Bin 0 -> 71168 bytes printer/laser/fonttab.nec.lc-08 | Bin 0 -> 38400 bytes printer/laser/genfont.kyocera.f-1010.dynamic1 | 30 + printer/laser/genfont.kyocera.f-1010.dynamic2 | 30 + printer/laser/laser.inserter | 275 ++ printer/laser/printer.apple.laserwriter | 770 +++++ printer/laser/printer.canon.lbp-8 | 327 ++ printer/laser/printer.epson.sq | 585 ++++ printer/laser/printer.hp.laserjet | 417 +++ printer/laser/printer.kyocera.f-1010 | 373 +++ printer/laser/printer.nec.lc-08 | 626 ++++ printer/laser/readme | 155 + prolog/calc | 32 + prolog/family | 29 + prolog/permute | 15 + prolog/prieks | 58 + prolog/prolog | 2488 ++++++++++++++ prolog/prolog installation | 117 + prolog/puzzle | 24 + prolog/quicksort | 14 + prolog/standard | 35 + prolog/sum | 13 + prolog/thesaurus | 360 ++ prolog/topographie | 59 + prozess/ls-MENUKARTE:Prozess | Bin 0 -> 62464 bytes "prozess/ls-Prozess 1 f\303\274r AKTRONIC-Adapter" | 57 + ...-Prozess 1 f\303\274r MUFI als Endger\303\244t" | 57 + .../ls-Prozess 1 f\303\274r MUFI im Terminalkanal" | 55 + prozess/ls-Prozess 2 | 39 + prozess/ls-Prozess 3 | 26 + prozess/ls-Prozess 4 | 61 + prozess/ls-Prozess 5 | 84 + prozess/ls-Prozess-gen | 146 + system/crypt | 138 + system/eumel printer.5 | 3473 ++++++++++++++++++++ system/eumelmeter | 131 + system/font convertor 9 | 1095 ++++++ system/free channel | 430 +++ system/port server | 164 + system/printer server | 99 + system/purge | 85 + system/referencer | 1077 ++++++ system/reporter | 531 +++ system/scheduler | 420 +++ system/spool cmd | 178 + system/spool manager | 1058 ++++++ system/std analysator | 68 + tecal/TeCal | 856 +++++ tecal/TeCal Auskunft | Bin 0 -> 45056 bytes tecal/TeCal.gen | 55 + warenhaus/ls-MENUKARTE:Warenhaus | Bin 0 -> 60928 bytes ...arenhaus 0: mit Kartenleser an AKTRONIC-Adapter | 36 + ...0: mit Kartenleser an MUFI als Endger\303\244t" | 36 + ...aus 0: mit Kartenleser an MUFI im Terminalkanal | 30 + warenhaus/ls-Warenhaus 0: ohne Kartenleser | 27 + warenhaus/ls-Warenhaus 1 | 37 + warenhaus/ls-Warenhaus 2 | 112 + warenhaus/ls-Warenhaus 3 | 82 + warenhaus/ls-Warenhaus 4 | 48 + warenhaus/ls-Warenhaus 5 | 103 + warenhaus/ls-Warenhaus-gen | 29 + 374 files changed, 134225 insertions(+) create mode 100644 at/AT Generator create mode 100644 at/AT Utilities create mode 100644 at/AT install create mode 100644 basic/BASIC.Administration create mode 100644 basic/BASIC.Compiler create mode 100644 basic/BASIC.Runtime create mode 100644 basic/eumel coder 1.8.1 create mode 100644 basic/eumel0 codes create mode 100644 basic/gen.BASIC create mode 100644 datatype/complex create mode 100644 datatype/longint create mode 100644 datatype/matrix create mode 100644 datatype/vector create mode 100644 dialog/ls-DIALOG 1 create mode 100644 dialog/ls-DIALOG 2 create mode 100644 dialog/ls-DIALOG 3 create mode 100644 dialog/ls-DIALOG 4 create mode 100644 dialog/ls-DIALOG 5 create mode 100644 dialog/ls-DIALOG 6 create mode 100644 dialog/ls-DIALOG 7 create mode 100644 dialog/ls-DIALOG MENUKARTEN MANAGER create mode 100644 dialog/ls-DIALOG MM-gen create mode 100644 dialog/ls-DIALOG decompress create mode 100644 dialog/ls-DIALOG-gen create mode 100644 dialog/ls-MENUKARTE:Archiv create mode 100644 doc/basic/basic handbuch.1 create mode 100644 doc/basic/basic handbuch.2 create mode 100644 doc/basic/basic handbuch.3 create mode 100644 doc/basic/basic handbuch.index create mode 100644 doc/dialog/gs-dialog handbuch.impressum create mode 100644 doc/dialog/gs-dialog-1 create mode 100644 doc/dialog/gs-dialog-2 create mode 100644 doc/dialog/gs-dialog-3 create mode 100644 doc/dialog/gs-dialog-4 create mode 100644 doc/dialog/gs-dialog-5 create mode 100644 doc/dialog/gs-dialog-Inhaltsverzeichnis create mode 100644 doc/dynamo/dynamo handbuch create mode 100644 doc/dynamo/dynamo handbuch.index create mode 100644 doc/dynamo/dynamo handbuch.inhalt create mode 100644 doc/eudas/abb.1-1 create mode 100644 doc/eudas/abb.4-1 create mode 100644 doc/eudas/abb.4-2 create mode 100644 doc/eudas/abb.6-1 create mode 100644 doc/eudas/abb.6-2 create mode 100644 doc/eudas/abb.7-1 create mode 100644 doc/eudas/abb.9-1 create mode 100644 doc/eudas/abb.9-2 create mode 100644 doc/eudas/abb.9-3 create mode 100644 doc/eudas/abb.9-4 create mode 100644 doc/eudas/abb.9-5 create mode 100644 doc/eudas/bildergenerator create mode 100644 doc/eudas/eudas.hdb.1 create mode 100644 doc/eudas/eudas.hdb.10 create mode 100644 doc/eudas/eudas.hdb.11 create mode 100644 doc/eudas/eudas.hdb.12 create mode 100644 doc/eudas/eudas.hdb.13 create mode 100644 doc/eudas/eudas.hdb.14 create mode 100644 doc/eudas/eudas.hdb.15 create mode 100644 doc/eudas/eudas.hdb.16 create mode 100644 doc/eudas/eudas.hdb.2 create mode 100644 doc/eudas/eudas.hdb.3 create mode 100644 doc/eudas/eudas.hdb.5 create mode 100644 doc/eudas/eudas.hdb.6 create mode 100644 doc/eudas/eudas.hdb.7 create mode 100644 doc/eudas/eudas.hdb.8 create mode 100644 doc/eudas/eudas.hdb.9 create mode 100644 doc/eudas/eudas.hdb.inhalt create mode 100644 doc/eudas/eudas.hdb.macros create mode 100644 doc/eudas/eudas.hdb.titel create mode 100644 doc/eudas/eudas.hdb.vorwort create mode 100644 doc/eudas/eudas.ref.1 create mode 100644 doc/eudas/eudas.ref.10 create mode 100644 doc/eudas/eudas.ref.11 create mode 100644 doc/eudas/eudas.ref.2 create mode 100644 doc/eudas/eudas.ref.3 create mode 100644 doc/eudas/eudas.ref.4 create mode 100644 doc/eudas/eudas.ref.5 create mode 100644 doc/eudas/eudas.ref.6 create mode 100644 doc/eudas/eudas.ref.7 create mode 100644 doc/eudas/eudas.ref.8 create mode 100644 doc/eudas/eudas.ref.9 create mode 100644 doc/eudas/eudas.ref.fehler create mode 100644 doc/eudas/eudas.ref.inhalt create mode 100644 doc/eudas/eudas.ref.macros create mode 100644 doc/eudas/eudas.ref.proz create mode 100644 doc/eudas/eudas.ref.reg create mode 100644 doc/eudas/eudas.ref.titel create mode 100644 doc/eudas/eudas.ref.vorwort create mode 100644 doc/eudas/ref.abb.1-1 create mode 100644 doc/eudas/register create mode 100644 doc/eudas/uedas.hdb.4 create mode 100644 doc/graphic/Altes Handbuch - Teil 10 - Graphik create mode 100644 doc/graphic/GRAPHIK.book create mode 100644 doc/graphic/graphik beschreibung create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Inhaltsverzeichnis create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 1 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 2 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 3 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 4 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 5 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 6 create mode 100644 doc/hamster/gs-Herbert und Robbi handbuch.impressum create mode 100644 doc/lisp/lisp handbuch create mode 100644 doc/menugenerator/menu-generator handbuch.1 create mode 100644 doc/menugenerator/menu-generator handbuch.2 create mode 100644 doc/menugenerator/menu-generator handbuch.3 create mode 100644 doc/menugenerator/menu-generator handbuch.4 create mode 100644 doc/menugenerator/menu-generator handbuch.5 create mode 100644 doc/menugenerator/menu-generator handbuch.6 create mode 100644 doc/menugenerator/menu-generator handbuch.7 create mode 100644 doc/menugenerator/menu-generator handbuch.8 create mode 100644 doc/menugenerator/menu-generator handbuch.impressum create mode 100644 doc/menugenerator/menu-generator handbuch.index create mode 100644 doc/menugenerator/menu-generator handbuch.inhalt create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Inhaltsverzeichnis create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6 create mode 100644 doc/mp-bap/gs-MP BAP handbuch.impressum create mode 100644 doc/programming/programmierhandbuch.1 create mode 100644 doc/programming/programmierhandbuch.2a create mode 100644 doc/programming/programmierhandbuch.2b create mode 100644 doc/programming/programmierhandbuch.3 create mode 100644 doc/programming/programmierhandbuch.4 create mode 100644 doc/programming/programmierhandbuch.5 create mode 100644 doc/programming/programmierhandbuch.5b create mode 100644 doc/programming/programmierhandbuch.6 create mode 100644 doc/programming/programmierhandbuch.index create mode 100644 doc/programming/programmierhandbuch.inhalt create mode 100644 doc/programming/programmierhandbuch.titel create mode 100644 doc/prolog/prolog handbuch create mode 100644 doc/prozess/Anhang Prozess create mode 100644 doc/prozess/Inhalt Prozess create mode 100644 doc/prozess/gs-Prozess handbuch.impressum create mode 100644 doc/prozess/gs-Prozess-2 create mode 100644 doc/prozess/gs-Prozess-3 create mode 100644 doc/prozess/gs-Prozess-4 create mode 100644 doc/prozess/gs-prozess-1 create mode 100644 doc/prozess/gs-prozess-5 create mode 100644 doc/prozess/gs-prozess-6 create mode 100644 doc/prozess/gs-prozess-7 create mode 100644 doc/prozess/gs-prozess-8 create mode 100644 doc/prozess/gs-prozess-9 create mode 100644 doc/system/systemhandbuch.1 create mode 100644 doc/system/systemhandbuch.2 create mode 100644 doc/system/systemhandbuch.3 create mode 100644 doc/system/systemhandbuch.4 create mode 100644 doc/user/benutzerhandbuch.1 create mode 100644 doc/user/benutzerhandbuch.2 create mode 100644 doc/user/benutzerhandbuch.3 create mode 100644 doc/user/benutzerhandbuch.4 create mode 100644 doc/user/benutzerhandbuch.5a create mode 100644 doc/user/benutzerhandbuch.5b create mode 100644 doc/user/benutzerhandbuch.5c create mode 100644 doc/user/benutzerhandbuch.5d create mode 100644 doc/user/benutzerhandbuch.5e create mode 100644 doc/user/benutzerhandbuch.6 create mode 100644 doc/user/benutzerhandbuch.anhang create mode 100644 doc/warenhaus/Anhang Warenhaus create mode 100644 doc/warenhaus/Inhalt Warenhaus create mode 100644 doc/warenhaus/gs-Warenhaus handbuch.impressum create mode 100644 doc/warenhaus/gs-Warenhaus-1 create mode 100644 doc/warenhaus/gs-Warenhaus-2 create mode 100644 doc/warenhaus/gs-Warenhaus-3 create mode 100644 doc/warenhaus/gs-Warenhaus-4 create mode 100644 doc/warenhaus/gs-Warenhaus-5 create mode 100644 doc/warenhaus/gs-Warenhaus-6 create mode 100644 doc/warenhaus/gs-Warenhaus-7 create mode 100644 dos/block i-o create mode 100644 dos/dir.dos create mode 100644 dos/disk descriptor.dos create mode 100644 dos/dos hd inserter create mode 100644 dos/dos inserter create mode 100644 dos/dos-dat-handbuch create mode 100644 dos/dump create mode 100644 dos/eu disk descriptor create mode 100644 dos/fat.dos create mode 100644 dos/fetch create mode 100644 dos/fetch save interface create mode 100644 dos/get put interface.dos create mode 100644 dos/insert.dos create mode 100644 dos/konvert create mode 100644 dos/manager-M.dos create mode 100644 dos/manager-S.dos create mode 100644 dos/name conversion.dos create mode 100644 dos/open create mode 100644 dos/save create mode 100644 dos/shard interface create mode 100644 dynamo/dyn.33 create mode 100644 dynamo/dyn.abnahme create mode 100644 dynamo/dyn.bev create mode 100644 dynamo/dyn.cob create mode 100644 dynamo/dyn.delaytest create mode 100644 dynamo/dyn.errors create mode 100644 dynamo/dyn.forest create mode 100644 dynamo/dyn.forst7 create mode 100644 dynamo/dyn.gekoppeltependel create mode 100644 dynamo/dyn.grashasenfuchs create mode 100644 dynamo/dyn.help create mode 100644 dynamo/dyn.inserter create mode 100644 dynamo/dyn.mac create mode 100644 dynamo/dyn.mehreredelays create mode 100644 dynamo/dyn.natchez create mode 100644 dynamo/dyn.oszillator create mode 100644 dynamo/dyn.plot create mode 100644 dynamo/dyn.plot+ create mode 100644 dynamo/dyn.print create mode 100644 dynamo/dyn.proc create mode 100644 dynamo/dyn.quadrat create mode 100644 dynamo/dyn.rts create mode 100644 dynamo/dyn.ruestungswettlauf create mode 100644 dynamo/dyn.simon create mode 100644 dynamo/dyn.std create mode 100644 dynamo/dyn.steifedgl create mode 100644 dynamo/dyn.tool create mode 100644 dynamo/dyn.vec create mode 100644 dynamo/dyn.wachstum create mode 100644 "dynamo/dyn.wasser\303\266ko" create mode 100644 dynamo/dyn.welt-forrester create mode 100644 dynamo/dyn.wohnen create mode 100644 dynamo/dyn.workfluc create mode 100644 dynamo/dyn.wurzel create mode 100644 dynamo/out.world create mode 100644 eudas/Adressen create mode 100644 eudas/dummy.text create mode 100644 eudas/eudas.1 create mode 100644 eudas/eudas.2 create mode 100644 eudas/eudas.3 create mode 100644 eudas/eudas.4 create mode 100644 eudas/eudas.generator create mode 100644 eudas/eudas.init create mode 100644 eudas/pos.173 create mode 100644 graphic/Beispiel.Kreuz create mode 100644 graphic/Beispiel.Sinus create mode 100644 graphic/GRAPHIK.Picfile create mode 100644 graphic/GRAPHIK.Plot create mode 100644 graphic/GRAPHIK.Plotter create mode 100644 graphic/GRAPHIK.Server create mode 100644 graphic/GRAPHIK.Transform create mode 100644 graphic/GRAPHIK.vektor plot create mode 100644 graphic/HP7475.plot create mode 100644 graphic/PC.plot create mode 100644 graphic/ZEICHENSATZ create mode 100644 graphic/gen Graphik create mode 100644 graphic/gen Plotter create mode 100644 graphic/graphik editor create mode 100644 hamster/ls-Herbert und Robbi 1 create mode 100644 hamster/ls-Herbert und Robbi 2 create mode 100644 hamster/ls-Herbert und Robbi 3 create mode 100644 hamster/ls-Herbert und Robbi-gen create mode 100644 hamster/ls-MENUKARTE:Herbert und Robbi create mode 100644 lisp/lisp.1 create mode 100644 lisp/lisp.2 create mode 100644 lisp/lisp.3 create mode 100644 lisp/lisp.4 create mode 100644 lisp/lisp.bootstrap create mode 100644 menugenerator/Generatordatei: Archivmenu create mode 100644 menugenerator/fonttab.ls-Menu-Generator create mode 100644 menugenerator/ls-MENUBASISTEXTE create mode 100644 menugenerator/ls-Menu-Generator 1 create mode 100644 menugenerator/ls-Menu-Generator 2 create mode 100644 menugenerator/ls-Menu-Generator-gen create mode 100644 mp-bap/ls-MENUKARTE:MP-BAP create mode 100644 mp-bap/ls-MP BAP 1 create mode 100644 mp-bap/ls-MP BAP 2 create mode 100644 mp-bap/ls-MP BAP-gen create mode 100644 net/basic net create mode 100644 net/net files-M create mode 100644 net/net hardware interface create mode 100644 net/net inserter create mode 100644 net/net manager create mode 100644 net/net report create mode 100644 net/netz create mode 100644 net/netzhandbuch create mode 100644 net/netzhandbuch.anhang create mode 100644 net/netzhandbuch.index create mode 100644 net/port server create mode 100644 net/printer server create mode 100644 net/spool cmd create mode 100644 net/spool manager create mode 100644 printer/dotmatrix24/beschreibungen24 create mode 100644 printer/dotmatrix24/fonttab.brother create mode 100644 printer/dotmatrix24/fonttab.epson.lq1500 create mode 100644 printer/dotmatrix24/fonttab.epson.lq850 create mode 100644 printer/dotmatrix24/fonttab.nec.p5 create mode 100644 printer/dotmatrix24/fonttab.nec.p5.new create mode 100644 printer/dotmatrix24/fonttab.nec.p6+ create mode 100644 printer/dotmatrix24/fonttab.oki create mode 100644 printer/dotmatrix24/fonttab.toshiba.p321 create mode 100644 printer/dotmatrix24/inserter create mode 100644 printer/dotmatrix24/module24 create mode 100644 printer/dotmatrix24/printer.24.nadel create mode 100644 printer/dotmatrix24/readme create mode 100644 printer/dotmatrix9/beschreibungen9 create mode 100644 printer/dotmatrix9/fonttab.1 create mode 100644 printer/dotmatrix9/fonttab.10 create mode 100644 printer/dotmatrix9/fonttab.20 create mode 100644 printer/dotmatrix9/fonttab.20.lc create mode 100644 printer/dotmatrix9/fonttab.20.lx create mode 100644 printer/dotmatrix9/fonttab.7 create mode 100644 printer/dotmatrix9/fonttab.7.cxp create mode 100644 printer/dotmatrix9/fonttab.7.fuj create mode 100644 printer/dotmatrix9/fonttab.7.mt create mode 100644 printer/dotmatrix9/module9 create mode 100644 printer/dotmatrix9/printer.neun.nadel create mode 100644 printer/dotmatrix9/readme create mode 100644 printer/laser/fonttab.apple.laserwriter create mode 100644 printer/laser/fonttab.canon.lbp-8 create mode 100644 printer/laser/fonttab.epson.sq create mode 100644 printer/laser/fonttab.hp.laserjet create mode 100644 printer/laser/fonttab.kyocera.f-1010 create mode 100644 printer/laser/fonttab.nec.lc-08 create mode 100644 printer/laser/genfont.kyocera.f-1010.dynamic1 create mode 100644 printer/laser/genfont.kyocera.f-1010.dynamic2 create mode 100644 printer/laser/laser.inserter create mode 100644 printer/laser/printer.apple.laserwriter create mode 100644 printer/laser/printer.canon.lbp-8 create mode 100644 printer/laser/printer.epson.sq create mode 100644 printer/laser/printer.hp.laserjet create mode 100644 printer/laser/printer.kyocera.f-1010 create mode 100644 printer/laser/printer.nec.lc-08 create mode 100644 printer/laser/readme create mode 100644 prolog/calc create mode 100644 prolog/family create mode 100644 prolog/permute create mode 100644 prolog/prieks create mode 100644 prolog/prolog create mode 100644 prolog/prolog installation create mode 100644 prolog/puzzle create mode 100644 prolog/quicksort create mode 100644 prolog/standard create mode 100644 prolog/sum create mode 100644 prolog/thesaurus create mode 100644 prolog/topographie create mode 100644 prozess/ls-MENUKARTE:Prozess create mode 100644 "prozess/ls-Prozess 1 f\303\274r AKTRONIC-Adapter" create mode 100644 "prozess/ls-Prozess 1 f\303\274r MUFI als Endger\303\244t" create mode 100644 "prozess/ls-Prozess 1 f\303\274r MUFI im Terminalkanal" create mode 100644 prozess/ls-Prozess 2 create mode 100644 prozess/ls-Prozess 3 create mode 100644 prozess/ls-Prozess 4 create mode 100644 prozess/ls-Prozess 5 create mode 100644 prozess/ls-Prozess-gen create mode 100644 system/crypt create mode 100644 system/eumel printer.5 create mode 100644 system/eumelmeter create mode 100644 system/font convertor 9 create mode 100644 system/free channel create mode 100644 system/port server create mode 100644 system/printer server create mode 100644 system/purge create mode 100644 system/referencer create mode 100644 system/reporter create mode 100644 system/scheduler create mode 100644 system/spool cmd create mode 100644 system/spool manager create mode 100644 system/std analysator create mode 100644 tecal/TeCal create mode 100644 tecal/TeCal Auskunft create mode 100644 tecal/TeCal.gen create mode 100644 warenhaus/ls-MENUKARTE:Warenhaus create mode 100644 warenhaus/ls-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter create mode 100644 "warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endger\303\244t" create mode 100644 warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal create mode 100644 warenhaus/ls-Warenhaus 0: ohne Kartenleser create mode 100644 warenhaus/ls-Warenhaus 1 create mode 100644 warenhaus/ls-Warenhaus 2 create mode 100644 warenhaus/ls-Warenhaus 3 create mode 100644 warenhaus/ls-Warenhaus 4 create mode 100644 warenhaus/ls-Warenhaus 5 create mode 100644 warenhaus/ls-Warenhaus-gen 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 "); + 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 [()] *) + 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 *) + 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 [(parameter list)] = *) + 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 *) + 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 *) + 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 *) + 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 *) + next symbol; + get const (label, int type); + gosub (this label) . + +goto statement : +(*GOTO *) + 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 *) + 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] = *) + 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">;] *) + 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 = *) + 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$ (, from [,len]) = *) + 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 AS *) + 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 [] *) + 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 *) + 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 *) + next statement; + symb := SYMBOL : ("", eol, eos, LOC 0, void type); + LEAVE get basic line . + +restore statement: +(*RESTORE [] *) + 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 = *) + 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 , *) + 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 [] *) + 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 = 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 [][,...] *) + 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 THEN | *) +(* [ELSE |] *) +(* IF GOTO *) +(* [ELSE |] *) + 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 GOSUB *) +(*3. ON GOTO *) + 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 [] *) +(*PRINT USING ; *) +(*PRINT #, *) +(*PRINT #, USING ; *) + 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 *) + 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 ab + 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 ab + 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 ab + 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 Binary files /dev/null and b/basic/eumel0 codes 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: Abbrechen: ",{} " 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: Bestätigen: Abbruch: ",{}" Ändern: Bestätigen: Ja: Nein: ",{}" Ändern: Bestätigen: ",{}" Fertig: Zeigen: Abbruch: ",{} +" Fertig: Abbruch: ",{}"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:/ Wahl: Ausführen: Verlassen:",{}" 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 Binary files /dev/null and b/dialog/ls-MENUKARTE:Archiv 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. ) 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: + + +[][...]EOF + +Dabei bedeutet #ib(3)#EOF (end of file)#ie(3)# das Ende der Programmdatei. + +Eine #ib(3)#Programmzeile#ie(3)# hat folgende Syntax: + + +[][][:][...][:]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[([,][...])]= +#right# + +: Zeichenfolge, die der Syntax für Variablennamen ent­ + sprechen muß. + FN bilden zusammen den Namen der neuen + Funktion. +<#ib(3)#Parameter#ie(3)#>: Zeichenfolge, die der Syntax für Variablennamen ent­ + sprechen muß. +: 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 [ ( [, ] [...] ) ] + +<#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 () + +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 () + +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 () + +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 #right#[ ( [, ] [...] ) ] + +Erklärung : : Folge aus Zeichen, die für Prozeduren im + EUMEL-System zugelassen sind (also Buchstaben und - ab der + zweiten Stelle - Zahlen), aber keine Leerzeichen. + + : | + + : Ausdruck (genau des von der Prozedur + benötigten Typs) + : Variable (genau des von der Prozedur benö­ + tigten Typs) + + Die Prozedur mit dem angegebenen 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 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 () + +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$ () + +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 () + +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 () + +Erklärung : : 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 () + CVI () + +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 [] [, []] [...] + +Erklärung : : | + : von Anführungszeichen umschlossene Zeichen­ + folge, die alle Zeichen außer Anführungs­ + zeichen enthalten darf + : 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 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 [ - ] + #right#[, [ - ] ] [...] + DEFINT [ - ] + #right#[, [ - ] ] [...] + DEFSNG [ - ] + #right#[, [ - ] ] [...] + DEFSTR [ - ] + #right#[, [ - ] ] [...] + + +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 [ ( [, ] #right# [...] ) ] = + +Erklärung : : Zeichenfolge, die der Syntax für Variablennamen + entsprechen muß + FN bilden zusammen den Namen der + neuen Funktion + : Zeichenfolge, die der Syntax für Variablennamen + entsprechen muß + : 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 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 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 [, ] [...] + +Erklärung : : ( + #right#[, ] [...] ) + : 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 + +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 () + +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 () + +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 = #ib(3)#TO#ie(3)# + #right#[ #ib(3)#STEP#ie(3)# ] + + + +Erklärung : : INT- oder REAL-Variable + : numerischer Ausdruck + : numerischer Ausdruck + : numerischer Ausdruck + : 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 , + sowie gegebenenfalls 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 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 () + FRE () + +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 + +Erklärung : : 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 + +Erklärung : : 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$ () + +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 + #right#[,] #ib(3)#THEN#ie(3)# | + #right#[ [,] #ib(3)#ELSE#ie(3)# |] + IF [,] GOTO + #right#[ [,] ELSE |] + +Erklärung : : numerischer Ausdruck + : Eine oder mehrere BASIC-Anweisungen, wobei + mehrere wie gewohnt durch ':' zu trennen sind + : 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 [;] [ ,|; ][ #ib(3)#EOF#ie(3)# + ] + #right# [, ] [...] + +Erklärung : : TEXT-Konstante + : INT-Konstante + : 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 , 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 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 ! ()" 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$ () + +Erklärung : : INT-Ausdruck + + Die Funktion liefert eine Folge von 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 ( [,] , + #right#) + +Erklärung : : 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 () + +Erklärung : Die Funktion liefert die größte ganze Zahl, für die gilt: + n kleiner gleich . + 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 + +Erklärung : : TEXT-Ausdruck + Die Datei wird (ohne Nachfrage) gelöscht. + + +Beispiel : 2110 KILL "Scratchdatei" + + + + +Funktion : LEFT$ + +Zweck : Erzeugung eines Teiltextes aus einem anderen Text + +Syntax : LEFT$ (, ) + +Erklärung : : INT-Ausdruck + + Die Funktion liefert die ersten 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 () + +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] = + +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 = oder + Die numerische Konstante wird automatisch in einen TEXT umge­ + wandelt (vgl. STR$-Funktion) + + #on("iZuweisung an INT-Variablen:#off("i + LET = + 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 = + 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 [;] [;] + #right# + +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 () + +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 () + +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)# ;] + #right#[ #ib(3)#TAB#ie(3)# () | , | ; | ] [...] + +Erklärung : : TEXT-Ausdruck für USING (vgl. PRINT) + : INT-Ausdruck (vgl. PRINT) + : 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 = + +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$ (, + #right#[, ] ) = + +Erklärung : : INT-Ausdruck + : INT-Ausdruck + + Das Ergebnis des TEXT-Ausdrucks wird, bei + beginnend, in der TEXT-Variablen eingesetzt. Es werden höch­ + stens LEN Textzeichen ersetzt. Ist keine + 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$ (, + #right# [, ]) + +Erklärung : : INT-Ausdruck + : INT-Ausdruck + + Die Funktion liefert höchstens Textzeichen des + TEXT-Ausdrucks von Position an. + Wird nicht angegeben, so werden alle Zeichen + ab Startposition geliefert. + Werden rechts von keine Zeichen mehr gefunden + oder ist 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$ () + MKI$ () + +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 AS + +Erklärung : : TEXT-Ausdruck + : TEXT-Ausdruck + + NAME benennt die Datei in um. + + +Beispiel : 10 NAME "Käufer" AS "Kunden" + + + + +Anweisung : NEXT + +Zweck : Markierung des Endes einer FOR-Schleife + +Syntax : NEXT [] [, ] [...] + +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$ () + +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 GOTO | GOSUB + #right# [, ] [...] + +Erklärung : : INT-Ausdruck + : 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 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 () + +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)# ;] + #right#[ #ib(3)#TAB#ie(3)# () | , | ; | ] [...] + +Erklärung : : TEXT-Ausdruck für USING (s. u.) + : INT-Ausdruck (s. u.) + : 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 (), 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 [] + +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 [, ] [...] + +Erklärung : : 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 + +Erklärung : : 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 [] + +Erklärung : : INT-Konstante + + Der READ-DATA-Zeiger (vgl. DATA-Anweisung) wird auf die Zeile + gesetzt. + Wird keine Zeilennummer angegeben, so wird für + 1 eingesetzt. + + Existiert die Programmzeile 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 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$ (, ) +Erklärung : : INT-Ausdruck + + Die Funktion liefert die letzten Textzeichen des + TEXT-Ausdrucks. + Ist 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 [] + +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 = + +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 () + +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 () + +Erklärung : : 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$ () + +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 () + +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$ () + +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$ (, |) + +Erklärung : : INT-Ausdruck + : INT-Ausdruck (Wert im Bereich 0 bis 255) + + Die Funktion liefert mal das Zeichen, + - das den ASCII-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 , + +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 () + +Erklärung : : 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 + #right#[ ( [, ] [...] ) ] + +Erklärung : : Folge aus Zeichen, die für Prozeduren im + EUMEL-System zugelassen sind (also Buchstaben und - ab der + zweiten Stelle - Zahlen), jedoch keine Leerzeichen. + + : | + + : Ausdruck (genau des von der Prozedur + benötigten Typs) + : Variable (genau des von der Prozedur benö­ + tigten Typs) + + Die Prozedur mit dem angegebenen 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 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 () + +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 + + +Erklärung : : numerischer Ausdruck + : 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 + +Erklärung : : 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 [] [, ] [...] + +Erklärung : : 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: #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) + + 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")# + (Supervisor - Taste) +#off("b")# + + --> gib supervisor kommando: + +#on("b")# + begin ("gs-MENUKARTEN") +#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") + + fetch("gs-DIALOG MM/gen",archive) + + run +#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")# + (Supervisor - Taste) +#off("b")# + + --> gib supervisor kommando: + +#on("b")# + begin ("MENU") +#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") + + fetch("gs-DIALOG/gen",archive) + + run +#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 +#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 - Mit diesem Befehl stel­ + len Sie für #on("b")#gs-DIALOG#off("b")# + den 'IBM - Graphikzei­ + chensatz' ein. + +ft20 graphic char - Mit diesem Befehl stel­ + len Sie für #on("b")#gs-DIALOG#off("b")# + den 'Beehive FT20 - + Graphikzeichensatz' + ein. + +std  graphic char - 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")# + (Supervisor - Taste) +#off("b")# + --> gib supervisor kommando: +#on("b")# + begin ("TEST","MENU") +#off("b")# + + --> gib kommando: +#on("b")# + archiv +#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:/ Wahl: Ausführen: Verlassen: +#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 oder . 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:/ Wahl: Ausführen: Verlassen: +#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 oder 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 und +. 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 , 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 oder +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 -Taste +oder Sie tippen direkt die entsprechende Buchstabentaste +(z.B. ). 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 -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 . + 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 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 -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 (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: Abbrechen: | +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 und können +Sie nun mit dem Pfeil vor den Namen fahren, den Sie an­ +kreuzen möchten. Tippen Sie dann die Taste oder +, 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 (kleines 'o') oder . +Dadurch wird das Kreuz entfernt und gegebenenfalls eine +Umnumerierung der schon angekreuzten Dateinamen vor­ +genommen. Verlassen Sie jetzt die Auswahl mit der Tasten­ +folge , 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 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 (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 (für 'ja') bzw. (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 - +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 können Sie Buchstaben löschen, mit + einfügen. Die Eingabe wird durch Tippen der +-Taste abgeschlossen. + Ist der von Ihnen gewünschte Name schon in Ihrer Task +vorhanden und steht in der Fußzeile der Hinweis 'Zeigen: +', 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 -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 +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 auf. Damit erhalten Sie + weitere Informationen. + + 3. Funktioniert eine Tastenkombination nicht (geben + Sie dem Rechner eine kurze Zeit zum Reagieren), + versuchen Sie die Tastenkombination (Ver­ + lassen) oder (Abbruch). Falls sich darauf­ + hin etwas ändert, verfahren Sie wie unter 1). + + 4. Erfolgt noch immer keine Reaktion, tippen Sie die + -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 -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 , so wird die Bedienung des + Menus auf dem Bildschirm kurz erläutert. + Mit der Tastenfolge wird das + Menu (nach einer Sicherheitsabfrage) + verlassen. + +Dateiauswahl: Hier können Sie die gewünschten Namen + mit ankreuzen und das Kreuz mit + wieder entfernen. Die Auswahl - sofern + mehrere Dateien ausgewählt werden kön­ + nen - wird durch die Tastenfolge + verlassen. Alle Möglichkeiten + der Bedienung werden angezeigt, wenn die + Fragezeichentaste getippt wird. Die Aus­ + wahl wird abgebrochen (ohne Kreuze!), + wenn die Tastenfolge 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 + ': 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 möglich. + +Frage: Beantworten Sie die an Sie gerichtete + Frage mit oder . Sie können auch + auf dem Bildschirm die Markierung auf + die gewünschte Antwort setzten und an­ + schließend die -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 -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 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 + bzw. 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 + abschließen. Sie können sich aber auch durch + die Tastenfolge (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 ('ja') - zur Verhinderung die Taste + ('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 + abschließen. Sie können sich aber auch durch + die Tastenfolge (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 + abschließen. Sie können sich aber auch durch + die Tastenfolge (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 + 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 + abschließen. Sie können sich aber auch durch + die Tastenfolge (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 + 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 abschließen. Sie können sich + aber auch durch die Tastenfolge (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 abschließen. Sie können sich + aber auch durch die Tastenfolge (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 + 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 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 + 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 + verlassen werden. Falls nicht alle Dateinamen + auf den Bildschirm passen, können Sie das Fenster mit + und 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 -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 -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 -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 -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 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 -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 . + +Wenn 'gib kommando:' erscheint, geben Sie den Befehl + + reset dialog + + 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 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 + + Zweck: Ausführen des übersetzten Programms und retten des Konstantendaten­ + raums in des Datenraum mit dem Namen ".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 =Wert [/=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 bei >> << : . + +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 : !, + !. + ::= "+"; "-". + +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 : ; + ; + ; + ; + '(', , ')'; + , . + ::= '+'; '-'. + +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 + steht für einen beliebigen Bezeichner gemäß der DYNAMO-Syntax + 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 ', 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 .K=#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() + +Erklärung: Liefert den Absolutbetrag + + + IF >= 0 THEN + + ELSE + - + 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() + +Erklärung: Berechnet den Arcustangens von ; 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() + +Erklärung: Berechnet den Arcustangens von ; 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 = + +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(,,,) + +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 >= THEN + + ELSE + + 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() + +Erklärung: Es wird der Cosinus des Wertes , 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() + +Erklärung: Es wird der Cosinus des Wertes , 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() + +Erklärung: Liefert e#u##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(,,,) + +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 >= THEN + + ELSE + + 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(,,) + +Erklärung: Wenn der Parameter den Wert 0 hat, so wird + geliefert, andernfalls + + + IF = 0 THEN + + ELSE + + 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() + +Erklärung: Liefert die Vorkommastellen von + +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 =, + +Erklärung: bezeichnet eine Schleifenvariable, die von bis + 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() + +Erklärung: Liefert die Nachkommastellen von + +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 .K=.J+ + + +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() + +Erklärung: Berechnet den natürlichen Logarithmus von + +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() + +Erklärung: Berechnet den Logarithmus von 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() + +Erklärung: Berechnet den Logarithmus von 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 ([,[...]]) + +Erklärung: Durch die Verwendung der MACRO-Anweisung können Sie einer oder + mehreren DYNAMO-Gleichungen einen Namen geben (). + 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(,) + +Erklärung: Liefert die größere Zahl aus und + + + IF > THEN + + ELSE + + 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(,) + +Erklärung: Liefert die kleinere Zahl aus und + +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 = + +Erklärung: Initialisert eine Variable mit dem Bezeichner auf den Wert + , 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() + +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 + 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(,) + +Erklärung: Liefert einen Wert zwischen - * 2.4 und + + * 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 + +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 [=][(, + )][/...][,...] + +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(,) + +Erklärung: Liefert #u##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 [/...][,...] + +Erklärung: Durch diese Anweisung werden die Werte () 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.KL= + +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(,) + +Erklärung: Wenn TIME kleiner , dann liefert RAMP 0, andernfalls wird + * (TIME - ) geliefert. + + + IF TIME < THEN + 0 + ELSE + * (TIME - ) + 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 .K= + +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(,,,,) + +Erklärung: Liefert das Skalarprokukt der Tabellen und , + wobei und den Ausschnitt aus der ersten Tabelle + angeben und 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() + +Erklärung: Berechnet den Sinus von , 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() + +Erklärung: Berechnet den Sinus von , 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= +Format: SPEC { LENGTH= }[/...] + PLTPER= + PRTPER= + +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() + +Erklärung: Berechnet die Quadratwurzel aus + +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(,) + +Erklärung: Ist TIME kleiner , so wird 0 geliefert, ansonsten + + + IF TIME < THEN + 0.0 + ELSE + + 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() + +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(,,) + +Erklärung: Summierung der Einträge in der Tabelle von Element bis + Element + +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(,,) + +Erklärung: Wenn der Parameter den Wert 0 hat, so wird + geliefert, andernfalls (gleichbedeutend mit FIFZE). + + + IF = 0 THEN + + ELSE + + 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 =[/[....]] + +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(,,,) + +Erklärung: IF < THEN + () + ELIF <= AND <= THEN + TABLE (, , , ) + ELSE + () + 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(,,,,) + +Erklärung: Verknüpft die Werte aus mit , wobei den + ersten und den letzten Tabelleneintrag angibt. 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() + +Erklärung: Berechnet den Tangens von , 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() + +Erklärung: Berechnet den Tangens von , 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 + +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 '%' 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 %! + + ... + % 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 &! + %% ELSE + Sehr geehrter Herr &! + %% 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: + + + + + +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")# + + + 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")# + + + 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")# + "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")# + #on("i")#Vorname#off("i")# + #on("i")#PLZ#off("i")# + #on("i")#Ort#off("i")# + #on("i")#Strasse#off("i")# + #on("i")#m/w#off("i")##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 . 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 , 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")# + #on("i")#Herbert#off("i")# + #on("i")#5000#off("i")# + #on("i")#Köln#off("i")# + #on("i")#Krämergasse 12#off("i")# + #on("i")#m#off("i")##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")# + #on("i")#Helga#off("i")# + #on("i")#5300#off("i")# + #on("i")#Bonn 1#off("i")# + #on("i")#Willicher Weg 109#off("i")# + #on("i")#w#off("i")##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")# + #on("i")#Albert#off("i")# + #on("i")#5210#off("i")# + #on("i")#Troisdorf#off("i")# + #on("i")#Lindenstr. 3#off("i")# + #on("i")#m#off("i")##on("i")#w#off("i")# + + #on("i")#Ulmen#off("i")# + #on("i")#Peter#off("i")# + #on("i")#5#off("i")# + #on("i")#Köln 60#off("i")# + #on("i")#Mozartstraße 17#off("i")# + #on("i")#m#off("i")##on("i")#w#off("i")# + + #on("i")#Regmann#off("i")# + #on("i")#Karin#off("i")# + #on("i")#5000#off("i")# + #on("i")#Köln 90#off("i")# + #on("i")#Grengelweg 44#off("i")# + #on("i")#w#off("i")##on("i")#w#off("i")# + + #on("i")#Arken#off("i")# + #on("i")#Hubert#off("i")# + #on("i")#5200#off("i")# + #on("i")#Siegburg#off("i")# + #on("i")#Talweg 12#off("i")# + #on("i")#m#off("i")##on("i")#w#off("i")# + + #on("i")#Simmern#off("i")# + #on("i")#Anna-Maria#off("i")# + #on("i")#5#off("i")# + #on("i")#Köln 3#off("i")# + #on("i")#Platanenweg 67#off("i")# + #on("i")#w#off("i")##on("i")#w#off("i")# + + #on("i")#Kaufmann-Drescher#off("i")# + #on("i")#Angelika#off("i")# + #on("i")#53#off("i")# + #on("i")#Bonn#off("i")# + #on("i")#Hauptstr. 123#off("i")# + #on("i")#w#off("i")##on("i")#w#off("i")# + + #on("i")#Fuhrmann#off("i")# + #on("i")#Harald#off("i")# + #on("i")#5000#off("i")# + #on("i")#Köln 1#off("i")# + #on("i")#Glockengasse 44#off("i")# + #on("i")#m#off("i")##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")# + #on("i")#Friedrich#off("i")# + #on("i")#5000#off("i")# + #on("i")#Köln-Ehrenfeld#off("i")# + #on("i")#Kabelgasse#off("i")# + #on("i")#m#off("i")##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 +in das erste Menü zurück. Dort tippen Sie wieder so lange , +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 nach oben bis zur Funktion 'Öffnen' und tippen Sie die +Leertaste. Danach ergibt sich folgender Dialog: + + + Name der Datei: #on("i")#Mitglieder#off("i")# + Wollen Sie etwas aendern (eine Arbeitskopie einrichten) + ? (j/n) #on("i")#n#off("i")# + + +Danach gehen Sie durch Tippen von 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")# + + +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")##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 , bis die Schreibmarke neben der Bezeichnung +'m/w' steht. Dort tippen Sie + + + #on("i")#w#off("i")##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 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")# + + +Dann wird der Bildschirm gelöscht und Sie können folgendes einge­ +ben: + + + #on("i")#% VORSPANN#off ("i")# + #on("i")#Liste der weiblichen Mitglieder#off ("i")# + #on("i")#-------------------------------#off ("i")# + #on("i")#% WIEDERHOLUNG#off ("i")# + #on("i")#&Vorname %Name#off ("i")##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")# + + + 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")# + + + 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")# + + + Es erscheint die gleiche Ausgabe wie unter 1 beschrieben auf + dem Bildschirm. Wenn Sie die Ausgabe genug gesehen haben, + kehren Sie durch + + + #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 + + #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 + &, %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 %, %, %PLZ %, %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 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 + [&] &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. + + + 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")# + + +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")# + +#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: + + halt, beende die Landschafts-/Arbeitsfeld­ + gestaltung +<\#> setze ein Hindernis und gehe ein Feld + weiter + leere das Feld und gehe ein Feld weiter + lege hier ein Korn/Werkstück ab + nimm ein Korn/Werkstück auf (falls hier + welche liegen) + zeige, wie viele Körner/Werkstücke hier + liegen + 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 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) + + 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")# + (Supervisor - Taste) + +#off("b")# + --> gib supervisor kommando: +#on("b")# + begin ("HAMSTER","MENU") +#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") + + fetch("gs-Herbert und Robbi/gen",archive) + + run +#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 bzw. . + 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")# + (Supervisor - Taste) + +#off("b")# + --> gib supervisor kommando: +#on("b")# + begin ("hamster1","HAMSTER") +#off("b")# + + --> gib kommando: + + +Mit dem Kommando + +#center##on("b")#hamster bzw. roboter #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")# + (Supervisor - Taste) + +#off("b")# + --> gib supervisor kommando: +#on("b")# + continue ("HAMSTER") +#off("b")# + + --> gib kommando: +#on("b")# + direktstart ("hamster", TRUE) +#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:/ Wahl: Ausführen: Verlassen: +#off("b")# + +#on("u")#oder#off("u")# + +#on("b")# +ROBOTER: Info Arbeitsfeld Programm Lauf Archiv ++----------------------------+-------------------------------------------- +| a Arbeitsfeldgestaltung | +| b Befehlsvorrat | +| s Steuerung des Laufs | ++----------------------------+ + + + + + + + + + + + + +-------------------------------------------------------------------------- +Info:/ Wahl: Ausführen: Verlassen: +#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 können Sie sich Informa­ + tionen zur Bedienung des Menusystems in das Menu + einblenden lassen + +- Mit den Pfeiltasten und 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 und 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 -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 (für 'ja') bzw. (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 oder können Sie + den Namen ankreuzen. Ist die Auswahl mehrerer Datein­ + amen möglich, so können Sie den Vorgang wiederholen. + Mit den Tasten oder 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 + 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 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 - + 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 können Sie Buch­ + staben löschen, mit einfügen. Die Eingabe wird + durch Tippen der -Taste abgeschlossen. Ist + der von Ihnen gewünschte Name schon in Ihrer Task + vorhanden und steht in der Fußzeile der Hinweis 'Zei­ + gen: ', 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 -Taste zur Aus­ + führung bringen. (Manchmal ist das auch durch Tippen + der den Alternativen vorangestellten Buchstaben oder + Ziffern möglich). + +- Durch die Tastenfolge 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 bzw. . + +#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: + + : 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:/ Wahl: Ausführen: Verlassen: +#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 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 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 und + 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 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 ('ja') - zur + Verhinderung ('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 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 + 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 + 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:/ Wahl: Ausführen: Verlassen: +#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 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 . + 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 + 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 und 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 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 ('ja') - zur Verhinderung + ('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 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 + 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 + 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:/ Wahl: Ausführen: Verlassen: +#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 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")#: + + or inks um imm ib

rotokoll 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 ( - vor, - links um, - + nimm, - 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. , 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

(- 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:/ Wahl: Ausführen: Verlassen: +#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 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 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 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 verlassen werden. Falls + nicht alle Dateinamen auf den Bildschirm passen, + können Sie das Fenster mit und + 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 -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 -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 -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 + -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 , 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: + break lisp . + +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 + + wobei der Name einer Eigenschaft (i.a. APVAL oder FUNCTION) + und ein beliebiger S-Ausdruck sein müssen. Die drei Elemente müs­ + sen jeweils durch mindestens ein Leerzeichen getrennt sein. + + Wenn das Atom nicht existiert, wird es erzeugt; danach wird + unter in der Eigenschaftsliste eingetragen. + + Wenn NIL ist, muß 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") + + fetch("ls-Menu-Generator/gen",archive) + + run + + 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") ). 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 +() 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 () 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:   Abbruch: '. +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 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 verlassen, so wird niltext +geliefert. + +Wird in obiger Prozedur die Eingabe mit 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 , so wird ein +Thesaurus mit allen angekreuzten Namen geliefert; bei Verlassen mit +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 zu bestätigen. +Möchte er die Auswahl zum Ankreuzen angeboten bekommen, so braucht er nur die +Tastenfolge (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 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 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 ) 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 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 -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 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 +, 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 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 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 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 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 abgeschlossen oder durch + 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 abgeschlossen, wird der eingegebene Text + geliefert. Statt der Eingabe kann der Benutzer sich durch die Tastenfolge + auch die in 'thesaurus' übergebenen Namen zur Auswahl + anbieten lassen. Wird ein Name angekreuzt, wird dieser geliefert; wird die + Auswahl durch 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 abgeschlossen, wird der eingegebene Text in + einem Thesaurus geliefert. Statt der Eingabe kann der Benutzer sich + durch die Tastenfolge auch die in 'thesaurus' übergebenen + Namen zur Auswahl anbieten lassen. Werden Namen angekreuzt, werden + diese in einem Thesaurus geliefert; wird die Auswahl durch + 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 + 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 + 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 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 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 + 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 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 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 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 verlassen werden. Der/ die angekreuzte(n) + Name(n) wird/werden in einem Thesaurus geliefert. Wird die Auswahl + durch die Tastenfolge 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 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 ). 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 + ) 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: +   Verlassen: " angezeigt. Nach Tippen von + 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 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 + () 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 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 , , und +benutzen; damit kann er den Lichtfleck innerhalb +des Zeichen-Blocks bewegen. Zur Ausbesserung dient +die -Taste. Mit der -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) + + 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")# + (Supervisor - Taste) +#off("b")# + + --> gib supervisor kommando: +#on("b")# + begin ("MP BAP","MENU") +#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") + + fetch("gs-MP BAP/gen",archive) + + run +#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 . + 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")# + (Supervisor - Taste) +#off("b")# + + --> gib supervisor kommando: +#on("b")# + begin ("mp bap","MP BAP") +#off("b")# + + --> gib kommando: + +Mit dem Kommando + +#center##on("b")#mp bzw. bap #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 #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") #off("b")# + #on("b")#begin ("Anwender2", "mp bap") #off("b")# + #on("b")#begin ("Anwender3", "mp bap") #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")# + (Supervisor - Taste) + +#off("b")# + --> gib supervisor kommando: +#on("b")# + continue ("mp bap") +#off("b")# + + --> gib kommando: +#on("b")# + direktstart ("mp", TRUE) +#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 #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:/ Wahl: Ausführen: Verlassen: +#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 +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:/ Wahl: Ausführen: Verlassen: +#off("b")# + +Nach Tippen der Taste (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 : || | + | +| Nach links : || | + | +| Nach oben : ||0.5| + | +| Nach unten : || | + | +| Ausbesserung : || | + | +| Nächstes : || | + | +| || | + | +| 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 (, +, und ) innerhalb des Werk­ +stücks bewegt werden. Steht der Cursor auf einem +Fehlerzeichen, so verschwindet es, wenn die - +Taste getippt wird. Nach Tippen der -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 . 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 tippen), ändert sich der +Fensterinhalt: + +#on("b")# ++-------------------------++---------------------------------------------+ +| Informationen || Anzahl Arbeitsphasen festlegen: | +| || | +| Kleinster Wert: 2 ||Mit den Pfeilen und den Wert| +| Größter Wert: 20 ||einstellen. Eingabe mit abschließen.| +| || | +| Eingestellter Wert: 3 ||Bitte die Anzahl der Arbeitsphasen: 3 | ++-------------------------++---------------------------------------------+ + + Bestimmt ist Ihnen schon klar, was zu tun ist: +Mit der Pfeiltaste stellen Sie den +kleinstmöglichen Wert (2) ein - anschließend tippen +Sie die -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 -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 : | | Anzahl der Arbeitsphasen: 3 | +| Nach links : | | Dauer einer Arbeitsphase: 10 min | +| Nach oben : | | Dauer einer Pause : 2 min | +| Nach unten : | | Simulationsgesamtdauer : 34 min | +| Ausbesserung : | | | +| Nächstes : | | 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 ) und die Auswahl durch +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 : Anzahl der Arbeitsphasen: 3 +Nach links : Dauer einer Arbeitsphase: 10 min +Nach oben : Dauer einer Pause : 2 min +Nach unten : Simulationsgesamtdauer : 34 min +Ausbesserung : +Nächstes : 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 -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 können Sie sich + Informationen zur Bedienung des Menusystems in + das Menu einblenden lassen. + +- Mit den Pfeiltasten und 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 und 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 -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 (für 'ja') bzw. + (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 oder kön­ + nen Sie den Namen ankreuzen. Ist die Auswahl + mehrerer Dateinamen möglich, so können Sie den + Vorgang wiederholen. Mit den Tasten oder + 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 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 + 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 -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 können Sie + Buchstaben löschen, mit einfügen. Die + Eingabe wird durch Tippen der -Taste + abgeschlossen. Ist der von Ihnen gewünschte Name + schon in Ihrer Task vorhanden und steht in der + Fußzeile der Hinweis 'Zeigen: ', 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 -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 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 bzw. . + +#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:/ Wahl: Ausführen: Verlassen: +#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 ) 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 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 + und 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 + 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 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:/ Wahl: Ausführen: Verlassen: +#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 ) 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 zu erhöhen, mit der + Pfeiltaste zu erniedrigen - aller­ + dings nur innerhalb der angezeigten Grenzen. + Wenn Sie die gewünschte Einstellung vorgenom­ + men und die Eingabe durch 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 + markieren Sie den Bereich, der vor dem Fehler­ + zeichen liegt; mit der Pfeiltaste + 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 + -Taste. + Anschließend bestimmen Sie den Bereich hin­ + ter dem Fehlerzeichen auf vergleichbare Weise + und schließen auch hier die Einstellung mit + der -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 + und ) das neue Fehlerzeichen + einzustellen. Die Einstellung wird durch + 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 - + 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 + zu erhöhen, mit der Pfeiltaste zu + erniedrigen - allerdings nur innerhalb der + angezeigten Grenzen. + Wenn Sie die gewünschte Einstellung vorge­ + nommen und die Eingabe durch 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 und 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 -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:/ Wahl: Ausführen: Verlassen: +#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:/ Wahl: Ausführen: Verlassen: +#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:/ Wahl: Ausführen: Verlassen: +#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: + + + + +- 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)# + + + <^> <>> <<> Positionierungstasten +#table# + + Umschalttaste + + Eingabe-/ Absatztaste + + Kommandotaste + + Supervisortaste + + Verstärkertaste + + Löschtaste + + Einfügetaste + + Tabulatortaste + + Markiertaste + + Stoptaste + + 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. + + 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 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 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 antwortet. + +Haben Sie das Programm eingegeben, so können Sie die Bearbeitung dieser Pro­ +grammdatei durch Drücken der Tasten (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 (nacheinander!) wieder verlassen. + + +____________________________________________________________________________ + + gib kommando : + run ("mein erstes Programm") + +____________________________________________________________________________ + + +Nach Eingabe von 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 , so wird die Ausführung des Programms beendet. + + +____________________________________________________________________________ + + gib kommando : + +____________________________________________________________________________ + + +Um die Arbeit in der Task zu beenden, geben Sie auch an dieser Stelle +(nacheinander!) ein. + +Nach Verlassen der Task ist wiederum die EUMEL-Tapete auf dem Bildschirm. Jede +weitere Aktion wird wiederum von hier aus durch begonnen. Insbesondere vor +dem #ib#Ausschalten des Geräts#ie# muß nach eine Task des priviliegierten System­ +zweigs (oft: '#ib#shutup#ie#') mit 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. + + ; + + +____________________________________________________________________________ + ........................... 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. + + ; + . + + + 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: + + ; + ; + + + 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: + + ; + ; + . + + + 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# oder + + +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 + + + +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)# + <^> <>> <<> Positionierungstasten +#table# +#free(0.5)# + Eingabe-/ Absatztaste +#free(0.5)# + Kommandotaste +#free(0.5)# + Verstärkertaste +#free(0.5)# + Tabulatortaste +#free(0.5)# + Markiertaste +#free(0.5)# + Löschtaste +#free(0.5)# + Einfügetaste +#free(0.5)# + Supervisortaste +#free(0.5)# + Stoptaste +#free(0.5)# + 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 + + + +#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)# +<>> <<> + + <^> + +Positionierungstasten + +#ib#Positionierung des Cursors#ie# um eine Spalten-/Zeilenposition in die jeweilige Richtung. +#free(0.5)# + + +#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. + + + +"#ib#Verstärkertaste#ie#"; wird als Vorschalttaste bedient. + +In Kombination mit anderen Funktionstasten wird deren Wirkung verstärkt. + + + + +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# + + +#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# + + +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# + + +#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# + + +#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: + + Markierten Abschnitt in 'Scratch'-Datei kopieren. + +

Markierten Abschnitt herauskopieren. + + 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# + + +#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)# + + +#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 + + + +#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: + + + + +____________________________________________________________________________ + ............... 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 + +   + +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 + +   + +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 + +   + +in einem Fenster, so verschwindet dieses und alle darin eingeschachtelten Fenster, +und man befindet sich im übergeordneten Fenster. + +Durch + +  

oder    + +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 + +   + +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 + + + +ab der aktuellen Cursorposition ein Fenster eröffnet wird. Das Notizbuch nimmt +insbesondere Fehlermeldungen und Meldungen bei der Übersetzung von Programmen +auf. + + + +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: + + + +Dadurch wird der Lernmodus ausgeschaltet und nichts gelernt, die Gefahr ist gebannt.#off("b")# + +#page# + + +#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 + + + +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 von Bedeutung, da hier­ +durch der Fehler 'halt vom Terminal' erzeugt wird. Dadurch können unerwünscht +laufende Programme abgebrochen werden. +#off("b")# +#page# + + +#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)# + + +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 in einer Task gedrückt werden, um durch 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 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 abgebrochen werden, + die Vater-Task angekoppelt und mit 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 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 + 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 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#: + +wobei folgende Werte annehmen kann: + +#on("bold")# 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 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 +aufgerufen werden. Aus der editierten Datei werden Werte mit gelesen, +durch <+> (bzw. -,*,/) verknüpft und mit an die aktuelle Cursor­ +position geschrieben werden. + +Der von TeCal errechnete Wert wird durch 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 <(> <)>. + +Durch die Hilfsfunktion lassen sich die TeCal Funktionen auflisten. + +Der Prozentoperator <%> erlaubt einfache Rechnungen der Form: 'zahl' <+> + <%> <=> . + +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 +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 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") ') und geben Sie dann das Kommando 'configurate +'. 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' (). + +Wollen Sie sich nur die aktuelle Konfiguration ansehen, so beantworten Sie alle dann +gestellten Fragen zum Kanal mit 'ja' (), 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") ') und geben Sie dann das Kommando 'configurate +'. Für alle vorhandenen Kanäle werden Sie nun nacheinander gefragt, +ob Sie eine Konfiguration vornehmen wollen. Beim vorgesehenen Kanal antworten Sie +mit 'ja' (). + +Wollen Sie sich nur die aktuelle Konfiguration ansehen, so beantworten Sie alle dann +gestellten Fragen zum Kanal mit 'ja' (), 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) #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")# + (Supervisor - Taste) + + --> gib supervisor kommando: + + begin ("PDV","MENU") + + --> 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") + + fetch("gs-Prozess/gen",archive) + + run + +#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:  Abbrechen:  | + +--------------------------------------------------------+ +#center#Abb.6:  Auswahl der Interface-Anpassung + + +Bringen Sie den Pfeil mit den Pfeiltasten vor die gewünschte Anpassung und drücken +Sie die -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")# + (Supervisor - Taste) +#off("b")# + --> gib supervisor kommando: +#on("b")# + begin ("pdvtest","PDV") +#off("b")# + --> gib kommando: +#on("b")# + pdv +#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:/ Wahl: Ausführen: Verlassen:| ++---------------------------------------------------------------------+ + + + Abb.9:  Eingangsbildschirm #on("b")#gs-Prozess#off("b")# +#page# + ++-----------------------------------------------------------------------+ +| PDV:  Info Interface Programm Archiv | ++-------+-------------------+-------------------------------------------+ +| | i  Informationen | | +| | ---------------- | | +| | k  Konfigurieren | | +| | ---------------- | | +| | a  Ausgabetest | | +| | e  Eingabetest | | +| +-------------------+ | +| | +| | +| | ++---------------------------------------------------------------------- + +| Info:/ Wahl: Ausführen: Verlassen: | ++-----------------------------------------------------------------------+ + + #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 . 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 +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 -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 und +aktivieren Sie anschließend den Menupunkt 'Eingabetest' indem Sie z.B. die Taste + 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 . + + +#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) ' 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) ' kann die + Belegung der Kanäle eingesehen werden. Ggf. erst ein Terminal an den + Kanal anschließen (Kanal umkonfigurieren!) und dort 'break + ' 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 -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 . 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 +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 + 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 , 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 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 + ("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:/ Wahl: Ausführen: Verlassen:| ++---------------------------------------------------------------------+ + +#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 können Sie sich Informationen zur Bedienung + des Menusystems in das Menu einblenden lassen. + +- Mit den Pfeiltasten und 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 und 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 -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 (für 'ja') bzw. (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 oder können Sie den Namen + ankreuzen. Ist die Auswahl mehrerer Dateinamen möglich, so können Sie den + Vorgang wiederholen. Mit den Tasten oder 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 + 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 + 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 -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 + können Sie Buchstaben löschen, mit einfügen. Die +#page# + Eingabe wird durch Tippen der -Taste abgeschlossen. Ist der von + Ihnen gewünschte Name schon in Ihrer Task vorhanden und steht in der Fußzeile + der Hinweis 'Zeigen: ', 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 + -Taste zur Ausführung bringen. (Manchmal ist das auch durch + Tippen der den Alternativen vorangestellten Buchstaben oder Ziffern möglich). + +- Durch die Tastenfolge 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 bzw. . + + +#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:/ Wahl: Ausführen: Verlassen: | ++-----------------------------------------------------------------------+ + +#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 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) ') und diese dann abmelden + ('break' oder 'end'). Die Nummer des Interfacekanals kann + mit dem Kommando 'put (interfacekanal) ' + 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) ') und diese dann abmelden + ('break' oder 'end'). Die Nummer des Interfacekanals kann + mit dem Kommando 'put (interfacekanal) ' + 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:/ Wahl: Ausführen: Verlassen: | ++-------------------------------------------------------------------------+ + +#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 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 . 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 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 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 + und 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 + 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 ('ja') - zur Verhinderung ('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 + 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 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 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:/ Wahl: Ausführen: Verlassen: | ++-----------------------------------------------------------------------+ + +#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 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 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 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 verlassen werden. Falls nicht alle Dateinamen auf + den Bildschirm passen, können Sie das Fenster mit und + 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 -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 -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 -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 -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 + 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". +#page# + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge eingegeben wurde. +#page# +#on("b")# +PROC warte (INT CONST sekunden) +#off("b")# + + - untersucht, ob inzwischen die Tastenfolge eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge eingegeben wurde. + - wirkt sonst wie 'pause (sekunden * 10)'. + + +#on("b")# +PROC warte (REAL CONST sekunden) +#off("b")# + + - untersucht, ob inzwischen die Tastenfolge eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 eingegeben wurde. + Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung + "Programm-Abbruch durch !". + - registriert, ob inzwischen die Tastenfolge 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 ' 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) + ', 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) '. +#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) ' 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) ' 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) '. 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))' ' 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)) ', +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 +-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 (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 . 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 -Taste (F1). Damit landen Sie im Supervisor-Menü, dem +Systemverteiler. Mit 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 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 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 , , + , , , 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 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")#> = ; ] + + 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: [ [, ] + [, ] ; ] + + + 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: + + + + + + + + + +- 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 Taste dem Monitor zur Bearbeitung überge­ +ben: + +____________________________________________________________________________ + +gib kommando : +edit ("Geschäftsbrief") + +____________________________________________________________________________ + + + + +#on("b")##on("i")#Die Eingabe von 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 oder (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)# + Umschalttaste +#free(0.5)# + Eingabe-/ Absatztaste +#free(0.5)# + Verstärkertaste +#free(0.5)# + Löschtaste +#free(0.5)# + Einfügetaste +#free(0.5)# + Tabulatortaste +#free(0.5)# + Markiertaste +#free(0.5)# + Kommandotaste +#free(0.5)# + Supervisortaste +#free(0.5)# + Stoptaste +#free(0.5)# + 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: + + 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 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 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 (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 +(nacheinander!) ein. + +Nach Verlassen der Task ist wiederum die EUMEL-Tapete auf dem Bildschirm. Jede +weitere Aktion wird wiederum von hier aus durch begonnen. Insbesondere zum +#ib#Ausschalten des Geräts#ie# muß nach 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 + + + + +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 und Kennzeichen oder auch durch vollständiges Eintip­ +pen eingegeben werden können und mit ausgelöst werden. + +Die Eingabe eines falschen Zeichens nach 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: + + + +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 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: + + + +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 weiter. + +____________________________________________________________________________ + + gib supervisor kommando: + break + +____________________________________________________________________________ + + +Nach dieser Eingabe ist das Terminal abgekoppelt. Jede neue Aktivität ist wiederum +mit 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 ein. + +Sobald der Supervisor-Bildschirm erscheint, drücken Sie die Tasten + +#center# (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: + + + + +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. 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# + +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# + + bzw. 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 . + +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 . + + +#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 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: + + bzw. 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 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 + + oder + +

+ + 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 + + + +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)# + Umschalttaste +#free(0.5)# + Eingabe-/ Absatztaste +#free(0.5)# + Verstärkertaste +#free(0.5)# + Löschtaste +#free(0.5)# + Einfügetaste +#free(0.5)# + Tabulatortaste +#free(0.5)# + Markiertaste +#free(0.5)# + Kommandotaste +#free(0.5)# + Supervisortaste +#free(0.5)# + Stoptaste +#free(0.5)# + Weitertaste +#tableend##clear pos# + + +#page# +Die Wirkung der Funktionstasten +#free(0.5)# + + +#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)# + + +#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: + + Anhalten der Bildschirmausgabe + + Wirkung der SV-Taste (bei jedem Rechner) + + Bildschirmausgabe fortführen +#l pos (0.0)##l pos(4.0)# + + +#free(1.5)# + + +#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)# + + +"#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")# + + + + +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)# + + +#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 - 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# + + + + +#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 - 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. + +____________________________________________________________________________ + + + + + +#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)# + + +#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)# + + +#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)# + + +#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 + + + +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)# + + +#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)# + + +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)# + + +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")#) + + + + + +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)# + <>> + +#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)# + <<> + +#ib#Sprung an den Bildschirmrand links#ie# (ggf. seitlich blätternd). +#free(1.0)# + <^> + +#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)# + + +#ib#Sprung auf die letzte Zeile des Bildschirms#ie#. + +Das Blättern erfolgt analog HOP OBEN. +#free(1.0)# + + +Positioniert das Fenster so, daß die aktuelle Zeile zur ersten des Fensters wird. +#free(1.0)# + + +#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 und 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. + + + + +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 und 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)# + + +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. + + + + +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)# + + +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). + + + +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 + + + +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> + +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. + + <'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. + + <'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)# + + +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. + + + + +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")# + + + +#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 + + + +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 + + + +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 + + + +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 + +

oder + +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 + + + +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#. + + + +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 + + + + + +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: + + + + +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")# + + + +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: + + + +____________________________________________________________________________ + +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")# + + + +____________________________________________________________________________ + +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")# + + + +____________________________________________________________________________ + +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#): + + + +____________________________________________________________________________ + +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 + + <'taste'> auf eine Taste gelegt werden. + +#on("u")#Beispiel:#off("u")# + + + (* die Kommandozeile erscheint *) + +____________________________________________________________________________ + +gib kommando: save (SOME myself) + +____________________________________________________________________________ + + + (* 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 + + <'taste'> + + +#on("u")#Beispiel:#off("u")# + + (* in den Kommandodialog gehen *) + + + (* 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" 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 + 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 ( 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' 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##ie(1,"-Abbruch")##ib##ie(1,"Abbruch mit ESC")#-Taste oder die #ib# #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 . +#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 ( 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 +-Taste betätigt werden. 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")# + + Trennen. + + +<<> Trennzeichen um ein Zeichen nach links verschieben. + + +<>> Trennstelle um ein Zeichen nach rechts verschieben. + + + <<> Trennstelle vor das Wort setzen (das Wort wird an + dieser Position nicht getrennt). + + + <>> Trennstelle an das Ende der Markierung setzen. + + + 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. + + + 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 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 . 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" ( , und ). + + +Ä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 , 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")# + + Seitenende an diese Stelle plazieren. + + + <^> Seitenende eine Zeile nach oben verschieben. + + + Seitenende eine Zeile nach unten verschieben (wenn + vorher nach oben verschoben bzw. wenn \#pageblock\#- + Anweisung gegeben ist). + + + <^> Seitenende um einen Bildschirm nach oben verschieben. + + + Seitenende um einen Bildschirm nach unten verschieben. + + + 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")# + + + Leerzeilen einfügen. Anstatt der Markierung können + durch (u.U. mehrmaliges) Leerzeilen eingefügt + werden. beendet den Vorgang (wie + Zeileneinfügen im Editor). + + 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")# + + + Seitenende bestätigen. + + \#page\#-Anweisung ignorieren. Die Prozedur 'pageform' + bearbeitet in diesem Fall die Datei weiter, als ob keine + \#page\#-Anweisung angetroffen wurde. + + 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 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 für den Fenstereditor die Tasten 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 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 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 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 +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 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 # #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 , + 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 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) #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")# + (Supervisor - Taste) + +#off("b")# + --> gib supervisor kommando: +#on("b")# + begin ("WARENHAUS","MENU") +#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") + + fetch (ALL archive, archive) + + release (archive) + + run ("gs-Warenhaus/gen") +#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, 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:  Abbrechen:  | +| | ++----------------------------------------------------------------------- +Soll kein Kartenleser benutzt werden, tippen Sie einfach . Sonst fahren +Sie den Pfeil mit den Cursor-Tasten in die gewünschte Zeile und drücken +. 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 , so werden später in der Programmierumgebung die +'Soester' Befehle und Syntax-Regeln benutzt, ein 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 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 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 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 . +Haben Sie die Frage mit 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 legen Sie fest, daß in den Sohntasks nach Verlassen des +Menus die jeweilige Task automatisch gelöscht wird. Tippen Sie ein , 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 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")# + (Supervisor - Taste) + +#off("b")# + --> gib supervisor kommando: +#on("b")# + begin ("Test","WARENHAUS") +#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 #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")# + (Supervisor - Taste) + +#off("b")# + --> gib supervisor kommando: +#on("b")# + begin ("Hauptstelle A","WARENHAUS") +#off("b")# + + --> gib kommando: + + +Mit dem Kommando + +#center##on("b")#warenhaus hauptstelle (TRUE) #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 +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") ') und geben Sie dann das Kommando 'configurate +'. 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' (). Wollen Sie sich nur die aktuelle Konfiguration ansehen, so +beantworten Sie alle weiterhin gestellten Fragen zu diesem Kanal mit 'ja' (), +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:/ Wahl: Ausführen: Verlassen: | + +------------------------------------------------------------------------+ + +#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 können Sie sich Informationen zur Bedienung + des Menusystems in das Menu einblenden lassen + +- Mit den Pfeiltasten und 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 und 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 -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 (für 'ja') bzw. (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 oder können Sie den Namen + ankreuzen. Ist die Auswahl mehrerer Dateinamen möglich, so können Sie den + Vorgang wiederholen. Mit den Tasten oder 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 + 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 + 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 -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 + können Sie Buchstaben löschen, mit einfügen. Die + Eingabe wird durch Tippen der -Taste abgeschlossen. Ist der von + Ihnen gewünschte Name schon in Ihrer Task vorhanden und steht in der Fußzeile + der Hinweis 'Zeigen: ', 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 + -Taste zur Ausführung bringen. (Manchmal ist das auch durch + Tippen der den Alternativen vorangestellten Buchstaben oder Ziffern möglich). +#page# +- Durch die Tastenfolge 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 bzw. . + + +#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:/ Wahl: Ausführen: Verlassen: | ++-------------------------------------------------------------------------+ +#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:/ Wahl: Ausführen: Verlassen:| ++-------------------------------------------------------------------------+ +#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:/ Wahl: Ausführen: Verlassen: | ++------------------------------------------------------------------------+ +#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 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 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 + 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:   | +|----------------------------------+-------------------------------------| +| Einkaufen | ++------------------------------------------------------------------------+ +#off("b")# | + + Dieser Vorgang wird solange wiederholt, bis die Eingabe einer Artikelnummer + durch Tippen der Tastenfolge 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:    Bestätigen:  | + + -----------------------------------------------------------------------+ + +#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 + 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 gedrückt + wird. +#on("b")# ++-------------------------------------------------------------------------+ +| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv | +|-----------------------------------+-------------------------------------| +| | | +| | | +| | Bitmuster :    0I00III0 | +| | | +| | | +| | | +| | | +| | | +| | | +| | | +| | | +| | | +| | Lesen beenden mit | +| +-------------------------------------| +| | +| 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:/ Wahl: Ausführen: Verlassen: | ++-------------------------------------------------------------------------+ +#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 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 . 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 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 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 + und 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 + 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 ('ja') - zur Verhinderung ('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 + 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 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 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:/ Wahl: Ausführen: Verlassen:| ++-------------------------------------------------------------------------+ + +#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 verlassen + werden - hierauf wird auch in der letzten Bildschirmzeile hingewiesen. Falls + nicht alle Namen auf den Bildschirm passen, können Sie das Fenster mit + und 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 + 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 ('ja') - zur Ver­ + hinderung ('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 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:/ Wahl: Ausführen: Verlassen: | ++--------------------------------------------------------------------------+ +#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 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 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 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 verlassen werden. Falls nicht alle Dateinamen auf + den Bildschirm passen, können Sie das Fenster mit und + 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 -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 -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 -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 -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' , + 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 . Nach dieser + Zeile dürfen nur noch leere Zeilen folgen, es sei denn zwischen und 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 . 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")# 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 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")# + + + . + . + #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")# #on("b")#MAL#off("b")# (ELAN: INT VAR i; + FOR i FROM 1 UPTO n REPEAT + . + . . + . . + #on("b")#ENDE WIEDERHOLE#off("b")# END REPEAT) + + +Die Anweisungen innerhalb der Schleife werden  - mal ausgeführt. + + +b) Schleife mit Ausgangsbedingung: + + + #on("b")#WIEDERHOLE#off("b")# (ELAN: REPEAT + . + . + . . + . . + #on("b")#BIS#off("b")# 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 () beendet werden kann. + + +c) Zählschleife mit Ausgangsbedingung: + + + #on("b")#WIEDERHOLE#off("b")# #on("b")#MAL#off("b")# (ELAN: INT VAR i; + FOR i FROM 1 UPTO n REPEAT + . + . . + . . + #on("b")#BIS#off("b")# UNTIL bedingung END REPEAT) + + +Die Anweisungen innerhalb der Schleife werden -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 + . + . + . . + . . + #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 () +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")# (ELAN: IF bedingung + THEN anweisung 1; + 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 getippt worden ist; + sonst ist sie nicht erfüllt (Wahrheitswert 'falsch'). (Das Tippen von + 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 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 abzu­ + schließen. Akzeptiert werden nur Werte von 1 bis 15, ansonsten erfolgt eine + Warnung, und die Eingabe wird wiederholt. + - Durch Tippen der Tastenfolge 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 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 oder der Tastenfolge + abzuschließen. Durch 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 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 abzu­ + schließen. Akzeptiert werden nur Werte von 129 bis 159, ansonsten erfolgt eine + Warnung, und die Eingabe wird wiederholt. + - Durch Tippen der Tastenfolge 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 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 oder der Tastenfolge + abzuschließen. Durch 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 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 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 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 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 + 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 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 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, "

"); +(*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 q) : + + run ...................... Ausführen des übersetzten Programms + + c =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 + + .................... 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 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\303\266ko" "b/dynamo/dyn.wasser\303\266ko" new file mode 100644 index 0000000..fe05881 --- /dev/null +++ "b/dynamo/dyn.wasser\303\266ko" @@ -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 Binary files /dev/null and b/eudas/Adressen 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)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=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.s00THENz1.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:o0e7REPi3(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.satznrg8THEN LEAVEt7END IF.b8:IF NOT(o6LEXEQUALp6)THEN LEAVEt7END IF.d8:IFo6<>p6THEN LEAVEt7END IF.x7:IFe8THENf8>g8ELSEf8p6ELSEo6p6ELSEo60THENtext:="-"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;WHILEc00THENc0INCR1;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=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.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;WHILEr21THENk1:=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)=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=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;v3INCR1UNTILl20THENi4;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=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;IFq11t11THENu12;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)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.e0f.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))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:IFu41THENv4:=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;WHILEx31THENwahlDECR1ELSEwahl:=length(w2.e2)END IF.j7:w4:=3;LEAVEr5.k7:IFwahl0.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;WHILEx3i10THENa11DECR1; +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+o100THENw11;x11END IF.w11:change(p10,2*v11-1,2*v11,s0).m7:IFt60THENx3:=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=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*a131THENa13DECR1END 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=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;WHILEl0y1THENm0:=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)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""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:IFd11THENd1DECR1;ELSEp2(1);e1:=1END IF.f2:IF NOTdateiendeTHEN IFd11THENd1:=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)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 Binary files /dev/null and b/graphic/ZEICHENSATZ 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",{} 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: )");{} 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 Binary files /dev/null and b/hamster/ls-MENUKARTE:Herbert und Robbi 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 l + All nodes are represented as +--------+--------+ in all comments + l l 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 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 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 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 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 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 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 Binary files /dev/null and b/menugenerator/fonttab.ls-Menu-Generator differ diff --git a/menugenerator/ls-MENUBASISTEXTE b/menugenerator/ls-MENUBASISTEXTE new file mode 100644 index 0000000..48ef277 Binary files /dev/null and b/menugenerator/ls-MENUBASISTEXTE 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 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 Binary files /dev/null and b/mp-bap/ls-MENUKARTE:MP-BAP 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 ,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#, , , <#ib#quelle#ie#>, <(n-4) byte> + + ist #ib#Längenangabe#ie# ( 8 <= n <= 160) + , 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 + 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, , <#ib#quelle#ie#>, , + + 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 = , so ist + das #ib#Telegramm#ie# angekommen. Andernfalls muß die Station + den #ib#Nachbarn#ie# zum Erreichen des als + neues einsetzen und das Telegramm an diesen + Nachbarn weiterleiten. + + <#ib#endquelle#ie#> Eigentliche #ib#Absenderstation#ie#. 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 + + 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 = (( DIV anzahl pakete pro seite) + 2) + + #ib#Nutzinformation#ie#. Diese gehört zur #ib#Adresse#ie# a des Daten­ + raums. + + a = + N ( DIV anzahl pakete pro seite + 1) * 512 + + ( 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 ). + + - #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. + + 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 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. + + : [<#ib#Stromnummer#ie#> : ] + + +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#. + + (,) + + 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 (sqnr/) + + + #ib#Stromnummer#ie# + + #ib#Sequenznummer#ie# des gerade bearbeiteten #ib#Telegramm#ie#s + + 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 Binary files /dev/null and b/printer/dotmatrix24/fonttab.brother differ diff --git a/printer/dotmatrix24/fonttab.epson.lq1500 b/printer/dotmatrix24/fonttab.epson.lq1500 new file mode 100644 index 0000000..1b4c6a6 Binary files /dev/null and b/printer/dotmatrix24/fonttab.epson.lq1500 differ diff --git a/printer/dotmatrix24/fonttab.epson.lq850 b/printer/dotmatrix24/fonttab.epson.lq850 new file mode 100644 index 0000000..7a6d2f0 Binary files /dev/null and b/printer/dotmatrix24/fonttab.epson.lq850 differ diff --git a/printer/dotmatrix24/fonttab.nec.p5 b/printer/dotmatrix24/fonttab.nec.p5 new file mode 100644 index 0000000..9910da6 Binary files /dev/null and b/printer/dotmatrix24/fonttab.nec.p5 differ diff --git a/printer/dotmatrix24/fonttab.nec.p5.new b/printer/dotmatrix24/fonttab.nec.p5.new new file mode 100644 index 0000000..9804bd5 Binary files /dev/null and b/printer/dotmatrix24/fonttab.nec.p5.new differ diff --git a/printer/dotmatrix24/fonttab.nec.p6+ b/printer/dotmatrix24/fonttab.nec.p6+ new file mode 100644 index 0000000..b209e81 Binary files /dev/null and b/printer/dotmatrix24/fonttab.nec.p6+ differ diff --git a/printer/dotmatrix24/fonttab.oki b/printer/dotmatrix24/fonttab.oki new file mode 100644 index 0000000..2251e18 Binary files /dev/null and b/printer/dotmatrix24/fonttab.oki differ diff --git a/printer/dotmatrix24/fonttab.toshiba.p321 b/printer/dotmatrix24/fonttab.toshiba.p321 new file mode 100644 index 0000000..452afca Binary files /dev/null and b/printer/dotmatrix24/fonttab.toshiba.p321 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 Binary files /dev/null and b/printer/dotmatrix9/fonttab.1 differ diff --git a/printer/dotmatrix9/fonttab.10 b/printer/dotmatrix9/fonttab.10 new file mode 100644 index 0000000..6a13c49 Binary files /dev/null and b/printer/dotmatrix9/fonttab.10 differ diff --git a/printer/dotmatrix9/fonttab.20 b/printer/dotmatrix9/fonttab.20 new file mode 100644 index 0000000..7cf0aaf Binary files /dev/null and b/printer/dotmatrix9/fonttab.20 differ diff --git a/printer/dotmatrix9/fonttab.20.lc b/printer/dotmatrix9/fonttab.20.lc new file mode 100644 index 0000000..ddf4535 Binary files /dev/null and b/printer/dotmatrix9/fonttab.20.lc differ diff --git a/printer/dotmatrix9/fonttab.20.lx b/printer/dotmatrix9/fonttab.20.lx new file mode 100644 index 0000000..1ce0940 Binary files /dev/null and b/printer/dotmatrix9/fonttab.20.lx differ diff --git a/printer/dotmatrix9/fonttab.7 b/printer/dotmatrix9/fonttab.7 new file mode 100644 index 0000000..676b9a0 Binary files /dev/null and b/printer/dotmatrix9/fonttab.7 differ diff --git a/printer/dotmatrix9/fonttab.7.cxp b/printer/dotmatrix9/fonttab.7.cxp new file mode 100644 index 0000000..0a996f3 Binary files /dev/null and b/printer/dotmatrix9/fonttab.7.cxp differ diff --git a/printer/dotmatrix9/fonttab.7.fuj b/printer/dotmatrix9/fonttab.7.fuj new file mode 100644 index 0000000..1ed83be Binary files /dev/null and b/printer/dotmatrix9/fonttab.7.fuj differ diff --git a/printer/dotmatrix9/fonttab.7.mt b/printer/dotmatrix9/fonttab.7.mt new file mode 100644 index 0000000..c816646 Binary files /dev/null and b/printer/dotmatrix9/fonttab.7.mt 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 Binary files /dev/null and b/printer/laser/fonttab.apple.laserwriter differ diff --git a/printer/laser/fonttab.canon.lbp-8 b/printer/laser/fonttab.canon.lbp-8 new file mode 100644 index 0000000..45314ac Binary files /dev/null and b/printer/laser/fonttab.canon.lbp-8 differ diff --git a/printer/laser/fonttab.epson.sq b/printer/laser/fonttab.epson.sq new file mode 100644 index 0000000..a3f7af3 Binary files /dev/null and b/printer/laser/fonttab.epson.sq differ diff --git a/printer/laser/fonttab.hp.laserjet b/printer/laser/fonttab.hp.laserjet new file mode 100644 index 0000000..4082e46 Binary files /dev/null and b/printer/laser/fonttab.hp.laserjet differ diff --git a/printer/laser/fonttab.kyocera.f-1010 b/printer/laser/fonttab.kyocera.f-1010 new file mode 100644 index 0000000..9c3fbda Binary files /dev/null and b/printer/laser/fonttab.kyocera.f-1010 differ diff --git a/printer/laser/fonttab.nec.lc-08 b/printer/laser/fonttab.nec.lc-08 new file mode 100644 index 0000000..f032953 Binary files /dev/null and b/printer/laser/fonttab.nec.lc-08 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 and , + 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 to in the environment } + 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 is bound and + assigns 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 Binary files /dev/null and b/prozess/ls-MENUKARTE:Prozess differ diff --git "a/prozess/ls-Prozess 1 f\303\274r AKTRONIC-Adapter" "b/prozess/ls-Prozess 1 f\303\274r AKTRONIC-Adapter" new file mode 100644 index 0000000..c42cfa5 --- /dev/null +++ "b/prozess/ls-Prozess 1 f\303\274r 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 <"{} + 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 <"{} + 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 <"{} + 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\303\274r MUFI als Endger\303\244t" "b/prozess/ls-Prozess 1 f\303\274r MUFI als Endger\303\244t" new file mode 100644 index 0000000..4d2a5f4 --- /dev/null +++ "b/prozess/ls-Prozess 1 f\303\274r MUFI als Endger\303\244t" @@ -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 <"{} + 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 <"{} + 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 <"{} + 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\303\274r MUFI im Terminalkanal" "b/prozess/ls-Prozess 1 f\303\274r MUFI im Terminalkanal" new file mode 100644 index 0000000..d1edbc1 --- /dev/null +++ "b/prozess/ls-Prozess 1 f\303\274r 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 <"{} + 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 <"{} + 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 <"{} + + 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: ");{} 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: ");{} + 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 ") > 0{} THEN regenerate menuscreen;{} out (""7""); menuinfo (" "15"Programm-Abbruch durch "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: "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: ");{} 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 ") > 0{} THEN menuinfo (" "15"Programm-Abbruch durch "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ü: ");{} 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ü: ");{} 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: ");{} 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 !"){} 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ü: ");{} 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ü: ");{} 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ü: ");{} 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: ");{} 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 Binary files /dev/null and b/tecal/TeCal Auskunft 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 Binary files /dev/null and b/warenhaus/ls-MENUKARTE:Warenhaus 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\303\244t" "b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endger\303\244t" new file mode 100644 index 0000000..f108f7b --- /dev/null +++ "b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endger\303\244t" @@ -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: <" + 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 <"{} + 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: <" + 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 <"{} + 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 ; Cursor bewegen: ");{} 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 ; Cursor bewegen: ");{} 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 <"{} + + 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 <"{} + + 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: Bestätigen: ");{} + 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 ");{} 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 ");{} 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: <" + 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: ");{} 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: ");{} 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: "));{} + 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, 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{} + -- cgit v1.2.3