summaryrefslogtreecommitdiff
path: root/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil7
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil7')
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil72469
1 files changed, 2469 insertions, 0 deletions
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil7 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil7
new file mode 100644
index 0000000..1aadc5f
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil7
@@ -0,0 +1,2469 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 7: Dateien, Datei-Verwaltung und Datenräume
+
+1. Übersicht
+
+Dateien dienen zur Aufnahme von Informationen, die auch über die Bearbei-
+tungszeit eines Programms erhalten bleiben (können). Dateien werden als
+Objekte in einer Task gehalten. Sie bleiben solange erhalten, bis sie expli-
+zit gelöscht ('forget'-Kommando) oder die Task beendet wird ('end'-Kommando).
+
+Dateien kann man an andere Tasks schicken ('save'-Kommando) oder von anderen
+Tasks holen ('fetch'-Kommando). Mit diesen (hier vorgestellten) Kommandos
+ist der Transport von Dateien jedoch nur in direkter Linie des Task-Baums
+möglich, also an einen "Vater" oder einen "Sohn". Damit ist automatisch eine
+Datei-Hierarchie im EUMEL-System realisiert.
+
+Alle Datei-Arten des EUMEL-Systems basieren auf Datenräumen. Ein Datenraum
+ist ein Speicherplatz, der 1 MByte Daten speichern kann und vom EUMEL-System
+verwaltet wird. Datenräume können gelöscht, kopiert usw. werden. Mit Hilfe
+Mit Hilfe von Datenräumen werden alle Datei-Arten des EUMEL-Systems reali-
+siert, indem einem Datenraum eine Struktur (Datentyp) aufgeprägt wird. Da-
+durch wird es Benutzern des EUMEL-Systems ermöglicht, auf einfache Weise
+neben den bereits vorhandenen Datei-Arten (FILEs für die Speicherung von
+Texten, PICFILEs für die Speicherung von Bildinformationen, u.a.m.)
+spezielle Dateien zu konstruieren.
+
+Die wichtigste Datei-Art, mit der ein Benutzer in Berührung kommt, ist die
+sequentielle Datei, genannt FILE. Ein FILE kann nur TEXTe aufnehmen und hat
+z.Zt. ein Fassungsvermögen von 4000 Zeilen (Sätze). Insgesamt darf ein FILE
+1 MByte aufnehmen. Eine Datei-Zeile (Satz) kann bis zu 32 000 Zeichen auf-
+nehmen.
+
+FILEs können in einer von drei Betriebsrichtungen bearbeitet werden:
+- "input": nur Lesen.
+- "output": nur Schreiben.
+- "modify": Lesen/Schreiben und zusätzlich beliebiges Positionieren, Ein-
+ fügen und Löschen von Sätzen.
+
+'input'-Dateien sind also Eingabedateien, 'output'- sind Ausgabedateien und
+'modify'-Dateien kann man verändern. Insbesondere die 'modify'-Dateien eig-
+nen sich, um andere Datei-Arten leicht zu realisieren (z.B. indexsequentiel-
+le Dateien).
+
+Eine Datei kann auf einen bestimmten Zeilenbereich eingeschränkt werden. Ein
+solches Segment kann selbst wie eine Datei von einem Programm behandelt
+werden.
+
+
+
+2. Datei-Kommandos
+
+Dateien werden in der Regel in einer Benutzer-Task gehalten. Die Kommandos
+für die Behandlung von Dateien in einer Benutzer-Task werden hier vorge-
+stellt. Dann wird erklärt, wie Dateien zu einer übergeordneten Task ge-
+schickt oder geholt werden können.
+
+
+
+Datei-Kommandos für Benutzer-Tasks
+
+Im Monitor-Dialog kann man Dateien kopieren, löschen und einen anderen Namen
+geben.
+
+Mit dem Kommando
+
+ edit ("dateiname")
+
+wird eine Text-Datei im Monitor-Dialog (implizit) eingerichtet, wenn es sich
+um einen noch nicht vorhandenen 'dateiname' handelt (vergl. auch die Editor-
+Beschreibung).
+
+Welche Dateien in der Benutzer-Task vorhanden sind, kann mit dem Kommando
+
+ list
+
+erfragt werden. 'list' zeigt auf dem Bildschirm die Dateinamen der Benutzer-
+Task. Vor jedem Namen steht ein Datum, welches anzeigt, an welchem Tag die
+Datei zuletzt von einem Programm bearbeitet wurde. Ein 'a' hinter dem Datum
+kennzeichnet Dateien, die nach einer Archivierung nicht bearbeitet wurden.
+
+Ein Duplizieren einer Datei kann mit
+
+ copy ("alte datei", "neue datei")
+
+erreicht werden, wobei eine Kopie von 'alter datei' angelegt wird, die den
+Namen 'neue datei' erhält. Man beachte, daß es sich um eine logische (und
+vorerst um keine physikalische) Kopie handelt. Erst bei Schreibzugriffen
+werden Seiten " entshared" ("copy-on-write"). Ein Umbenennen einer Datei
+kann mit
+
+ rename ("alter datei name", "neuer datei name")
+
+erfolgen. Mit
+
+ forget ("dateiname")
+
+kann eine Datei gelöscht werden.
+
+Wurde in einer Datei editiert, kann durch Löschen oder Einfügen von Zeilen
+der interne Verwaltungsaufwand hoch werden, so daß Positionierungen nicht
+mehr effizient vor sich gehen. Mit dem Kommando
+
+ reorganize ("dateiname")
+
+wird die Datei so organisiert, als wenn sie neu erstellt wäre (gilt nur für
+Text-Dateien). Sie braucht dann in der Regel auch etwas weniger Speicher-
+platz.
+
+
+Merke: Das Kommando 'rename' gibt einer Datei einen anderen Namen, 'copy'
+dupliziert eine Datei. Mit 'list' kann man sich anzeigen lassen, welche
+Dateien in der Task vorhanden sind.
+
+
+
+Datei-Kommandos für Vater-Tasks
+
+Man kann Dateien von einer Vater-Task holen oder an eine Vater-Task schicken,
+um sie dort längerfristig zu speichern. Auch wenn die Benutzer-Task gelöscht
+wird, bleiben alle Dateien, die bei einer Vater-Task gespeichert (also
+"gerettet") sind, erhalten. Andere Sohn-Tasks können sich Dateien bei einer
+Vater-Task abholen.
+
+Auf Dateien einer Benutzer-Task können andere Nutzer aus anderen Tasks in
+der Regel nicht zugreifen. Manchmal ist es jedoch notwendig, daß mehrere
+Nutzer Dateien gemeinsam benutzen oder eine Datei eine Task "überleben" soll.
+In solchen Fällen muß man Dateien bei einem Vater aufbewahren.
+
+Mit der Prozedur
+
+ global manager
+
+kann die Benutzer-Task zu einem Datei-Manager gemacht werden. Erst nach
+Aufruf dieser Prozedur können Söhne dieser Task eingerichtet werden.
+
+Von einer Benutzer-Task kann eine Datei mit
+
+ save ("Buch 1")
+
+der direkten Vater-Task übergeben werden, wobei 'buch 1' in der Benutzer-
+Task erhalten bleibt. 'save' wirkt also wie ein Transport einer Kopie der
+angegebenen Datei in die Vater-Task. Achtung: ist eine Datei 'Buch 1' in der
+Vater-Task bereits vorhanden, wird diese ohne Warnung überschrieben.
+
+Analog zu der 'forget'-Prozedur für Dateien einer Benutzer-Task können
+Dateien einer unmittelbaren Vater-Task mit
+
+ erase ("datei name")
+
+gelöscht werden. Soll eine Datei von einer Vater-Task in eine Benutzer-Task
+geholt werden, so benutzt man die Prozedur
+
+ fetch ("datei")
+
+Nach Aufruf dieser Prozedur wird eine Kopie der angegebenen Datei in der
+Benutzer-Task angelegt. Ist bereits eine Datei 'datei' in der Benutzer-Task
+vorhanden, so erfolgt eine Fehlermeldung.
+
+Mit 'save', 'fetch' und 'erase' ist es möglich, daß zwei oder mehr Benutzer
+eine Datei alternierend bearbeiten. In diesem Fall müssen sich die Benutzer
+als Söhne einer gemeinsamen Vater-Task einrichten und die Datei mit 'fetch'
+jeweils in die Benutzer-Task holen. Um zu verhindern, daß ein anderer Be-
+nutzer zur gleichen Zeit mit der Datei arbeitet, wird sie jeweils mit 'erase'
+bei der Vater-Task gelöscht. Nach Beendigung der Arbeiten muß die Datei dann
+wieder mit 'save' in die Vater-Task transportiert werden. Dann steht sie
+wieder anderen Benutzern zur Verarbeitung zur Verfügung. Beispiel:
+
+ fetch ("datei"); erase ("datei"); (* Datei vom Vater holen und dort
+ loeschen *)
+ edit ("datei"); (* Datei bearbeiten *)
+ save ("datei"); (* Datei zur Vater-Task bringen *)
+ forget ("datei") (* Datei in Benutzer-Task
+ loeschen *)
+
+Mit den Prozeduren
+
+ save all
+ fetch all
+
+kann man alle Dateien einer Benutzer-Task in die direkte Vater-Task schicken
+oder von dort holen.
+
+Merke:
+ * * * * * * * * * *
+ * *
+ * <-+ * Vater-Task
+ * | | *
+ * * * | * * | * * *
+ | |
+ fetch save
+ | |
+ * * * | * * | * * *
+ * | | *
+ * ->edit| * Benutzer-Task
+ * *
+ * * * * * * * * * *
+
+
+
+Ansprechen von anderen Tasks
+
+Sollen Dateien in andere als die direkte Vater-Task transportiert oder von
+anderen Tasks geholt werden, muß man den internen Task-Bezeichner angeben.
+
+Es gibt einige Prozeduren, mit denen man den internen Task-Bezeichner einer
+Task bekommt. Solch eine Prozedur ist
+
+ father
+
+Prozeduren, mit denen man Dateien transportieren kann, liegen auch in einer
+Version vor, bei denen man den internen Task-Bezeichner angeben kann.
+Beispiel:
+
+ save ("datei", father) (* wie: save ("datei") *)
+ erase ("datei", father) (* wie: erase ("datei") *)
+ fetch ("datei", father) (* wie: fetch ("datei") *)
+
+Weitere Prozeduren, die einen internen Task-Bezeichner liefern, sind:
+
+ myself
+ printer
+ public
+ archive
+
+Anmerkung: Zur Prozedur 'archive' siehe auch das nächste Kapitel; zu 'print'
+siehe auch SPOOLER. Dadurch kann man Dateien auch zu anderen als der
+Vater-Task transportieren, holen oder löschen. Beispiele:
+
+ erase ("datei", public) (* Loescht 'datei' in Task 'PUBLIC' *)
+ fetch ("datei", public) (* Holt 'datei' aus der Task "PUBLIC" *)
+ save ("datei", public) (* Kopiert 'datei' in die Task 'PUBLIC' *)
+ save ("datei", printer) (* Uebergibt 'datei' dem Spooler und
+ druckt die Datei *)
+ list (father) (* Listet Dateien der Vater-Task *)
+
+Bei komplizierten "Verwandschafts-Verhältnisse" von Tasks ist es einfacher,
+eine Task mit Hilfe des Task-Namens anzusprechen. Das erfolgt mit Hilfe der
+Prozedur 'task'. Beispiel:
+
+ save ("datei", task ("hugo"))
+
+'task' liefert den internen Task-Bezeichner von 'hugo'. Die Umkehr-Prozedur
+zu 'task' ist 'name':
+
+ put (name (myself))
+
+schreibt den Namen der Task, in der man sich gerade befindet, auf den Bild-
+schirm.
+
+Durch die Prozedur 'father', die einen internen Task-Bezeichner als
+Parameter erwartet, kann man an die Vater-Task einer Task gelangen.
+Beispiel:
+
+ save ("datei", father (father))
+
+Hier wird die Datei 'datei' an die Vater-Task der Vater-Task geschickt (also
+zur "Großvater-Task").
+
+Mit dem Operator /
+
+kann man aus einem Tasknamen den internen Tasknamen erhalten. '/' kann über-
+all dort eingesetzt werden, wo ein interner Taskname verlangt wird. Beispiel:
+
+ task status (/"meine task")
+
+
+Merke: Mit den internen Task-Bezeichner kann man mit anderen Tasks als der
+Vater-Task kommunizieren.
+
+
+
+Kommandos für mehrere Dateien
+
+Durch die vom EUMEL-System bereitgestellten Task-Variablen und Datei-Ver-
+zeichnisse (Thesaurus, Plural: Thesauren) ist es möglich, mehrere Dateien
+mit einem Kommando zu behandeln.
+
+Sollen alle Dateien einer Task zu einer anderen transportiert werden (mit
+'save') oder alle Dateien geholt werden, kann man 'save all' und 'fetch all'
+auch mit einem internen Task-Bezeichner versehen. Beispiele:
+
+ save all (public)
+ fetch all (public)
+
+Damit werden alle Dateien der Benutzer-Task zu der Task 'PUBLIC' geschickt
+oder von dort geholt.
+
+Die internen Tasknamen wie z.B. 'myself', 'father', 'public' usw. werden
+auch bei dem Einsatz eines Thesaurus benutzt. Was ist ein "Thesaurus"?
+
+Das EUMEL-System hält sich die Dateinamen einer Task des Taskbaums in einer
+internen Liste. Die Namens-Liste wird Thesaurus (laut Duden: ein
+"systematisch geordnetes Verzeichnis") genannt.
+
+Der Operator ALL liefert den Thesaurus einer Task. Beispiel:
+
+ ALL father
+ ALL myself
+
+liefert jeweils den Thesaurus der Vater- oder der eigenen Task. Solche
+Thesauren kann man als Parameter der meisten der oben erwähnten Kommandos
+verwenden:
+
+ save (ALL myself) (* kopiert alle Dateien in die Vater-Task;
+ arbeitet wie 'save all' *)
+ forget (ALL myself) (* loescht alle Dateien der Benutzer-Task *)
+ fetch (ALL father) (* holt alle Dateien der Vater-Task;
+ arbeitet wie 'fetch all' *)
+
+Der Operator SOME dagegen bietet einen Thesaurus vorher zum Editieren an,
+um Dateinamen zu streichen (HOP RUBOUT). Beispiele:
+
+ fetch (SOME father) (* holt die nicht gestrichenen Dateien *)
+ save (SOME myself) (* kopiert die nicht gestrichenen Dateien *)
+ forget (SOME myself) (* loescht die nicht gestrichenen Dateien *)
+
+Es ist auch möglich, aus den Thesauren mehrerer Tasks einen neuen Thesaurus
+zu bilden:
+
+ - (* Differenzmenge *)
+ / (* Schnittmenge *)
+ + (* Vereinigungsmenge *)
+
+Beispiel:
+
+ fetch (ALL father - ALL myself)
+
+holt alle Dateien der Vater-Task, die nicht bereits in der Benutzer-Task
+sind.
+
+
+Merke: Mit den Operatoren 'ALL' und 'SOME' kann man mehrere Dateien mit
+einem Kommando behandeln.
+
+
+
+Datei-Schutz durch Paßworte und Verschlüsselung
+
+Dateien können vor unbefugtem Zugriff mit Hilfe von Paßworten und/oder der
+Verschlüsselung der Informationen geschützt werden.
+
+
+
+Paßworte
+
+Paßworte für Dateien dienen zur Verhinderung von unbefugtem Zugriff auf
+Dateien, die bei einer Vater-Task gespeichert werden. (Die Dateien der
+Benutzer-Task können durch ein Task-Paßwort geschützt werden). Dabei sollte
+man bedenken, daß Paßworte bekannt werden können.
+
+Der Paßwort-Schutz ist im EUMEL-System etwas sicherer als in anderen
+Betriebssystemen, weil Paßworte nur selten angegeben werden müssen und
+daher nicht so leicht bekannt werden können (z.B. durch "über die Schulter
+schauen"). Die Kommandozeile wird zudem bei der Angabe eines Paßworts nach
+dem Betätigen der RETURN-Taste gelöscht.
+
+Paßworte werden nur im Verkehr mit Vater-Tasks eingesetzt. Lokale Benutzer-
+Dateien brauchen nicht gesondert gesichert zu werden, da man ein Paßwort
+auf die Benutzer-Task legen kann oder die zu sichernden Dateien aus dem
+System nehmen kann. Ein Paßwort kann mit der Prozedur
+
+ enter password ("schreibpasswort / lesepasswort")
+
+angegeben oder ein bereits eingestelltes Paßwort kann mit dieser Prozedur
+überschrieben werden. Voreingestellt ist kein Paßwort. Nachdem ein Benutzer
+die 'enter password'-Prozedur angegeben hat, wird jeder Datei-Verkehr mit
+einer Vater-Task mit Hilfe dieses Paßworts überprüft. Unzulässige Zugriffe
+durch Benutzer anderer Tasks auf Dateien einer Vater-Task werden abgewiesen.
+
+Ein Paßwort hat eine eigene Syntax. Es besteht aus zwei Teilen, die leer
+sein können und die durch ein "/"-Zeichen voneinander getrennt sind. Der
+erste Teil ist das Schreib-Paßwort, der zweite das Lese-Paßwort. Wird kein
+Lese-Paßwort angegeben, gilt das Schreib-Paßwort auch für das Lesen. Ist
+also kein "/"-Zeichen im Paßwort-String vorhanden, so wird das Schreib-
+Paßwort sozusagen gedoppelt. Beispiele:
+
+ enter password ("") (* kein Paßwort *)
+ enter password ("hugo") (* 'hugo' gilt fuer das Schreiben und
+ Lesen *)
+ enter password ("egon/meier") (* 'egon' fuers Schreiben, 'meier' fuers
+ Lesen *)
+
+Zusätzlich kann das "-"-Zeichen in dem Teil des Paßworts angegeben werden,
+für den ein Zugriff nicht erlaubt sein soll. Beispiel:
+
+ enter password ("-/nurlesen") (* Schreibzugriff nicht erlaubt,
+ Lese-Passwort ist 'nurlesen' *)
+
+Das Lese-Paßwort gilt für die Prozedur
+
+ fetch
+
+während das Schreib-Paßwort für die Prozeduren
+
+ save
+ erase
+
+gilt. Sofern die betreffende Datei durch ein Paßwort geschützt ist, ist
+folgendes zu beachten:
+
+a) fetch:
+ Will ein Benutzer mit der Prozedur 'fetch' eine Datei in seine Benutzer-
+ Task holen, so wird sein aktuell eingestelltes Paßwort (nur Lese-Teil)
+ und das Paßwort der Datei überprüft. Stimmen diese nicht überein, so wird
+ der 'fetch'-Zugriff auf eine Datei der Vater-Task abgewiesen.
+
+b) save:
+ Bei einem Transport in eine Vater-Task mit Hilfe der Prozedur 'save' sind
+ zwei Fälle zu unterscheiden:
+
+ - Datei ist in der Vater-Task noch nicht vorhanden: Diese Datei wird
+ in der Vater-Task mit dem aktuellen Paßwort des Benutzers einge-
+ tragen.
+
+ - Datei ist in der Vater-Task bereits vorhanden und soll durch die
+ neue Datei ersetzt werden: Es wird überprüft, ob das aktuelle
+ Schreib-Paßwort des Benutzers mit dem der gleichnamigen Datei in der
+ Vater-Task übereinstimmt. Ist dies nicht der Fall, wird die Datei
+ nicht in der Vater-Task eingetragen.
+
+c) erase:
+ Soll eine Datei der Vater-Task gelöscht werden, wird überprüft, ob das
+ aktuelle Schreib-Paßwort mit dem der zu löschenden Datei in der Vater-
+ Task übereinstimmt. Ist dies nicht der Fall, wird die Lösch-Operation
+ abgewiesen.
+
+
+Merke: Dateien können bei der Sicherung in einer Vater-Task vor unbefugtem
+Zugriff durch Paßworte geschützt werden.
+
+
+
+Dateien verschlüsseln
+
+Zusätzlich zu einem Paßwort kann man eine Datei vor unbefugtem Zugriff
+schützen, indem sie verschlüsselt wird.
+
+Mit den Prozeduren
+
+ crypt
+ decrypt
+
+kann eine Datei ver- oder entschlüsselt werden (Datenschutz für einzelne
+Dateien). Dabei ist es möglich, eine Datei mehrfach zu verschlüsseln (man
+muß die Verschlüsselung dann allerdings auch mehrfach rückgängig machen).
+Beispiel:
+
+ crypt ("datei", "schluessel")
+
+verschlüsselt 'datei' mit 'schluessel'. Die Entschlüsselung erfolgt, indem
+man die Prozedur 'decrypt' auf 'datei' anwendet und den gleichen Schlüssel
+zur Entschlüsselung benutzt. Beispiel:
+
+ decrypt ("datei", "schluessel")
+
+Den Text des Schlüssels (hier: 'schluessel') sollte man sich also unbedingt
+merken, sonst kann die Datei nicht mehr entschluesselt werden.
+
+Merke: Dateien werden durch 'crypt' und 'decrypt' ver- und entschlüsselt.
+
+
+
+3. Das Archiv
+
+Dateien werden im EUMEL-System auf Systemträgern gespeichert. Mit dem Archiv
+können Dateien vom System auf externe Speichermedien (normalerweise
+Disketten) gebracht und von diesen ins System geholt werden.
+
+Das EUMEL-Archiv hat folgende Aufgaben:
+
+a) Das Archiv wird als Sicherheitsbereich benutzt, indem man von wichtigen
+ Dateien Kopien anlegt und diese außerhalb des EUMEL-Systems speichert.
+
+b) Man kann das Archiv-System aber auch benutzen, um Dateien, die nur selten
+ oder in größeren Zeitabständen benötigt werden, zu kopieren ("archi-
+ vieren") und im EUMEL-System zu löschen. Falls diese Dateien wieder
+ gebraucht werden, können sie wieder in das EUMEL-System geholt werden.
+ Damit wird erreicht, daß im EUMEL-System nur die wirklich notwendigen
+ Dateien stehen.
+
+c) Sollen Dateien von einer EUMEL-Installation auf eine andere übertragen
+ werden, so kann man ebenfalls Archive verwenden.
+
+d) Bei Versionswechsel des EUMEL-Systems sind Archive die einzige Möglich-
+ keit, Dateien in die neue Systemversion einzuspielen. Dabei wird garan-
+ tiert, daß zumindest Archive der letzten Version gelesen werden können.
+
+Merke: Durch das Archiv können Dateien außerhalb des Systems gesichert
+werden.
+
+
+
+Das Archiv reservieren
+
+Soll archiviert werden, muß man das dem Archiv-System mitteilen, damit nicht
+ein anderer Benutzer zur gleichen Zeit auf das Archiv zugreift. Dieser
+Vorgang wird "reservieren" genannt.
+
+Archiv-Disketten haben aus Sicherheitsgründen einen Namen. Dieser Name muß
+bei der Anmeldung einer Archivierung angegeben werden. Die Anmeldung einer
+Archivierung und gleichzeitige Reservierung erfolgt mit
+
+ archive ("name")
+
+Der Archiv-Name wird bei folgenden Archiv-Operationen zur Überprüfung mit
+dem eingelegten Archiv verwandt.
+
+Wichtig: Eine Diskette sollte erst nach dem 'archive'-Kommando in das
+Laufwerk geschoben werden, d.h. erst dann, wenn das Archiv-System reserviert
+ist. Sonst kann es geschehen, daß ein anderer Benutzer auf dieser Diskette
+archiviert.
+
+Archivierungen erfolgen durch die schon beschriebenen Transportkommandos
+'save' und 'fetch'. Dabei wird als Zieltask 'archive' angegeben. Beispiel:
+
+ save ("mein buch", archive)
+ fetch ("kapitel 1", archive)
+ save all (archive)
+ fetch all (archive)
+
+Das Archiv bleibt für den Nutzer solange reserviert, wie er Archivierungs-
+operationen vollzieht. Dann sollte er das Archiv wieder für andere Benutzer
+mit der Prozedur
+
+ release (archive)
+
+freigeben.
+
+Leitet ein Nutzer innerhalb von fünf Minuten nach der letzten Archiv-
+Operation keine neue ein und meldet sich ein anderer Nutzer mit 'archive'
+bei dem Archiv-System an, so wird dem ersten Nutzer die Archiv-Berechtigung
+entzogen, um Blockaden zu verhindern. Wenn der erste Nutzer eine erneute
+Archiv-Operation versucht, erhält er eine Fehlermeldung. Dadurch kann ein
+Nutzer das Archiv längere Zeit (ohne 'release') benutzen, ohne den Betrieb
+zu stören, da andere Nutzer bei Bedarf jederzeit eingeschoben werden.
+
+Wichtig: Muß die Archiv-Floppy gewechselt werden (weil etwa von einer
+Diskette eine Datei gelesen wurde und diese auf eine andere geschrieben
+werden soll), muß erneut das 'archive'-Kommando gegeben werden. Dies ist
+notwendig, um das Verzeichnis aller auf der Diskette befindlichen Dateien
+der neuen Diskette zu lesen.
+
+Merke: Mit 'archive' wird die Archiv-Verwaltung für einen Nutzer reserviert, mit 'release' wieder freigegeben. Mit 'archive' wird
+gleichzeitig ein Archiv-Name eingestellt, der bei Archiv-Operationen mit dem
+auf der Diskette gespeicherten Archiv-Namen verglichen wird.
+
+
+
+Archiv löschen und einen Namen geben
+
+Bevor ein Archiv-Diskette benutzt werden kann, muß sie den mit 'archive'
+eingestellten Namen bekommen.
+
+Bei der Erstbenutzung eines Archivs muß dieses mit einem Namen versehen
+werden. Als Archiv-Name wird der mit 'archive' eingestellte Name verwandt.
+Dies erfolgt mit der Prozedur
+
+ clear (archive)
+
+Gleichzeitig werden alle Dateien, die sich eventuell vorher auf dem Archiv-
+Träger befanden, gelöscht. Somit wird 'clear' auch für das Löschen von
+Archiven verwendet.
+
+
+Merke: Mit 'clear' wird die Archiv-Diskette gelöscht und gleichzeitig der
+mit 'archive' eingestellte Name gegeben.
+
+
+
+Einfache Archiv-Operationen
+
+In diesem Abschnitt werden einfache Archiv-Operationen beschrieben.
+
+Mit den Prozeduren
+
+ save ("datei", archive)
+ fetch ("datei", archive)
+ erase ("datei", archive)
+
+kann jeweils eine Datei auf die Archiv-Diskette ('save') und von dem Archiv
+in das EUMEL-System kopiert ('fetch') oder auf dem Archiv gelöscht ('erase')
+werden. Dabei bedeutet 'datei' die zu kopierende Datei und 'archive' der
+interne Task-Name für die Archiv-Verwaltung. Bei den ersten zwei Kommandos
+ist zu beachten, daß die Datei, die auf das Archiv geschrieben (bei 'save')
+oder die in die Benutzer-Task geholt werden soll (bei 'fetch'), immer
+kopiert wird. Dateien bleiben also im "Ursprung" immer erhalten.
+
+Ist eine Datei gleichen Namens bereits auf der Archiv-Diskette (bei 'save')
+oder in der Benutzer-Task (bei 'fetch') vorhanden, wird von der Archiv-Ver-
+waltung angefragt, ob diese Datei überschrieben werden darf. Es kann somit
+nicht zu einem unbeabsichtigten Löschen von Dateien kommen.
+
+Mit dem Kommando
+
+ list (archive)
+
+erhält man (wie bei dem "normalen" 'list'-Kommando) ein Namens-Verzeichnis
+aller Dateien, die sich auf der eingelegten Archiv-Diskette befinden.
+
+
+Merke: Nachdem ein Archiv mit 'archive' reserviert wurde, kann mit 'save'
+eine Datei auf das Archiv geschrieben und mit 'fetch' eine Datei von dem
+Archiv in die Benutzer-Task kopiert werden.
+
+
+
+Archiv-Operationen für mehrere Dateien
+
+Hier wird beschrieben, wie man mehrere Dateien auf einmal auf ein Archiv
+schreibt oder von einem Archiv liest.
+
+Mit den Kommandos
+
+ save all (archive)
+ fetch all (archive)
+
+werden alle Dateien der Benutzer-Task auf das Archiv geschrieben bzw. von
+dort geholt.
+
+Zusätzlich ist es möglich, die Operatoren 'ALL' und 'SOME' auf ein Archiv
+anzuwenden. Wie bereits geschildert, liefern diese Operatoren einen
+Thesaurus der angegebenen Task: 'ALL' liefert alle Dateinamen, während man
+bei 'SOME' eine Auswahl treffen kann. Damit ist es möglich, alle oder einige
+Dateien der Benutzer-Task auf eine Archiv-Diskette zu kopieren oder von der
+Archiv-Diskette in die Benutzer-Task zu holen:
+
+ fetch (SOME archive, archive) (* zeigt die Namen der Dateien der
+ Archiv-Diskette. Die nicht ge-
+ strichenen Dateien werden in die
+ Benutzer-Task geholt *)
+ save (SOME myself, archive) (* zeigt die Namen der Dateien der
+ Benutzer-Task. Die nicht ge-
+ strichenen Dateien werden auf die
+ Archiv-Diskette kopiert *)
+ save (ALL archive, archive) (* sichert alle Dateien der Benutzer-
+ Task, die sich schon auf dem Archiv
+ befinden (alte Version). Das
+ Kommando ist für Sicherungs-
+ Disketten gedacht, bei dem man immer
+ die gleichen Dateien auf dem Archiv
+ haben will *)
+
+Durch die Thesaurus-Operatoren '-' (Differenzmenge), '/' (Schnittmenge) und
+'+' (Vereinigungsmenge) kann man kompliziertere Wirkungen erzielen.
+Beispiele:
+
+ save (ALL myself - ALL archive, archive) (* Schreibt alle Dateien der
+ Benutzer-Task auf das Archiv,
+ die nicht bereits auf dem
+ Archiv stehen *)
+ save (ALL myself - ALL father - ALL archive, archive)
+ (* Schreibt alle Dateien der
+ Benutzer-Task auf das Archiv,
+ mit Ausnahme der Dateien, die
+ längerfristig in der Vater-
+ Task gespeichert sind und die
+ nicht bereits auf dem Archiv
+ stehen *)
+ fetch (ALL archive - ALL myself) (* Holt alle Dateien vom Archiv,
+ die sich nicht bereits in der
+ Benutzer-Task befinden *)
+
+Werden mehrere Dateien mittels eines Thesaurus bearbeitet, kann man nach
+einer Unterbrechung der Bearbeitung (d.h. Fehlermeldung) die Operation wieder
+aufsetzen. Dazu liefert das Kommando
+
+ remainder
+
+den "Rest"-Thesaurus. Er enthält alle nicht bearbeiteten Dateinamen.
+Beispiel:
+
+ save (SOME myself, archive) (* Unterbrechung, z.B. durch einen vom
+ Programm erzeugten 'errorstop' oder SV
+ und 'halt' *)
+ save (remainder, archive) (* bearbeitet die restlichen Dateien *)
+
+
+Merke: Mit 'save all' bzw. 'fetch all' kann man alle Dateien einer Benutzer-
+Task archivieren bzw. alle Dateien eines Archivs in die Benutzer-Task holen.
+Mit den Operatoren SOME und ALL sind weitere Operationen möglich.
+
+
+
+Fehlermeldungen des Archivs
+
+Bei Archiv-Operationen kann es zu Fehlersituationen kommen.
+
+Versucht man eine Datei vom Archiv zu lesen, kann es vorkommen, daß das
+Archiv-System
+
+ Lese-Fehler (Archiv)
+
+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
+Disketten-Geräte). In einem solchen Fall vermerkt das Archiv-System intern,
+daß die Datei nicht korrekt gelesen werden kann. Das sieht man z.B. beim
+'list (archive)'. Dort ist der betreffende Datei-Name mit dem Zusatz 'mit
+Lese-Fehler' gekennzeichnet. Um diese Datei trotzdem zu lesen, muß man sie
+im Datei-Namen mit dem Zusatz 'mit Lese-Fehler' versehen. Beispiel:
+
+ 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
+
+ check ("dateiname", archive) (* oder *)
+ check (ALL archive, archive) (* fuer alle Archiv-Dateien *)
+
+Durch dieses Kommando werden eventuelle Lese-Fehler gemeldet.
+
+Weitere Fehlermeldungen des Archivs:
+
+* Lesen unmöglich (Archiv) Archiv-Floppy nicht eingelegt oder die Tür
+ des Laufwerks ist nicht geschlossen.
+
+* Schreiben unmöglich (Archiv) Floppy ist schreibgeschützt.
+
+* Archiv nicht angemeldet Archiv wurde nicht angemeldet
+ ('archive ("name")' geben).
+
+* Lese-Fehler (Archiv) Siehe obige Beschreibung.
+
+* Schreibfehler (Archiv) Die Floppy kann nicht (mehr) beschrieben
+ werden. Andere Floppy verwenden.
+
+* Speicherengpass Im System ist nicht mehr genügend Platz, um
+ eine Datei vom Archiv zu laden.
+ Ggf. Dateien löschen.
+
+* RERUN beim Archiv-Zugriff Das System wurde bei einer Archiv-Operation
+ durch Ausschalten bzw. Reset unterbrochen.
+
+* ... gibt es nicht Die Datei ... gibt es nicht auf dem Archiv.
+
+* Archiv heißt ... Die eingelegte Floppy hat einen anderen als
+ den eingestellten Archiv-Namen.
+
+* Archiv wird von Task ... benutzt Das Archiv wurde von einem anderen
+ Benutzer reserviert.
+
+* ... kann nicht geschrieben werden (Archive voll) Das Archiv ist voll.
+ Neue Archiv-Floppy
+ benutzen.
+
+* Archiv inkonsistent Die eingelegte Floppy hat nicht die Struk-
+ tur einer Archiv-Floppy ('clear (archive)'
+ vergessen).
+
+* save/erase wegen Lese-Fehler verboten Bei Archiven mit Lese-Fehler sind
+ Schreiboperationen verboten, weil
+ ein Erfolg nicht garantiert
+ werden kann.
+
+
+
+4. FILEs in Programmen
+
+Die bisher geschilderten Kommandos gelten für alle Datei-Arten. In diesem
+Kapitel wird der Standard Datei-Typ FILE beschrieben. Eine Datei von Daten-
+typ FILE ist eine sequentielle Datei, die das Lesen und Schreiben von Daten
+in strikter Aufeinanderfolge von Sätzen erlaubt (Betriebsrichtungen 'input'
+und 'output'). Die Betriebsrichtung 'modify' erlaubt das gleichzeitige Lesen
+und Schreiben sowie beliebiges Positionieren.
+
+
+
+Deklaration, Assoziierung und Betriebsrichtungen
+
+Für ELAN-Programme gibt es standardmäßig den Datentyp FILE. FILEs müssen
+deklariert werden. Die Kopplung einer FILE VAR im Programm mit einer Datei
+erfolgt durch eine Assoziierungsprozedur. Bei der Assoziierung muß man an-
+geben, wie die Datei bearbeitet werden soll.
+
+Dateien müssen in einem ELAN-Programm - wie alle anderen Objekte auch -
+deklariert werden. Beispiel:
+
+ FILE VAR f :: ...
+
+Mit der Deklaration wird dem ELAN-Compiler der Name der Datei-Variablen
+bekannt gemacht. Dabei ist zu beachten, daß im EUMEL-System alle FILEs mit
+VAR deklariert werden müssen, denn jede Lese/Schreib-Operation verändert
+einen FILE. FILE CONST Objekte sind also nicht erlaubt. Ähnlich wie bei
+anderen Datenobjekten werden FILEs initialisiert. In der Regel erfolgt dies
+mit einer Assoziierungsprozedur. Beispiele:
+
+ FILE VAR meine datei :: sequential file (output, "daten")
+ ...
+ (* oder: *)
+ TEXT VAR datei name;
+ put ("Dateiname bitte:"); get (datei name);
+ FILE VAR f :: sequential file (input, datei name);
+
+Die Assoziierungsprozedur 'sequential file' hat die Aufgabe, eine in einem
+Programm deklarierte FILE VAR mit einer bereits vorhandenen oder noch einzu-
+richtenden Datei (abhängig von der Betriebsrichtung, siehe unten) des
+EUMEL-Systems zu koppeln. Den Dateinamen gibt man als zweiten Parameter
+an. Dadurch können ELAN-Programme geschrieben werden, die Dateien
+bearbeiten, deren Namen man beim Erstellen des Programms noch nicht kennt.
+
+Der erste Parameter gibt die sog. Betriebsrichtung an. Sie bestimmt, in
+welcher Weise die assoziierte Datei bearbeitet wird. Es gibt folgende drei
+Betriebsarten:
+
+a) input:
+ Die Datei kann vom Programm nur gelesen werden. Durch 'input' wird bei
+ der Assoziierung automatisch auf den ersten Satz der Datei positioniert.
+ Ist die zu lesende Datei nicht vorhanden, wird ein Fehler gemeldet.
+
+b) 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 vorhanden, wird sie automatisch einge-
+ richtet.
+
+c) 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. Hier ist nicht definiert, auf welchen Satz der Datei
+ man nach erfolgter Assoziierung steht. Die Datei wird automatisch einge-
+ richtet, wenn sie vor der Assoziierung nicht vorhanden war.
+
+Anmerkung:
+In jeder Betriebsrichtung sind nur bestimmte Operationen zugelassen. Z.B.
+sind bei 'input' keine Schreib-Prozeduren erlaubt. Vergl. dazu die nächsten
+Abschnitte.
+
+Neben der Betriebsrichtung 'input', 'output' oder 'modify' muß bei
+'sequential file' als zweiter Parameter der Name der zu bearbeitenden Datei
+angegeben werden. Beispiel:
+
+ TEXT VAR datei name, zeile;
+ put ("Bitte Name der zu bearbeitenden Datei eingeben:");
+ get (datei name);
+ FILE VAR f :: sequential file (input, dateiname);
+ ...
+ getline (f, zeile);
+ ...
+
+Hier wird der Name der zu bearbeitenden Datei zuerst eingelesen. Diese Datei
+wird mit 'f' in der Betriebsrichtung 'input' assoziiert, d.h. würde man z.B.
+die Prozedur
+
+ putline (f, irgendein text)
+
+an einer Stelle im Programm verwenden, wird ein Fehler gemeldet. Die Be-
+triebsrichtung hilft also, Fehler bei der Programmierung zu vermeiden.
+
+Mit den Prozeduren
+
+ modify (f)
+ input (f)
+ output (f)
+
+kann die Betriebsrichtung von Dateien geändert werden.
+
+Dateien brauchen im EUMEL-System vor Programmende nicht geschlossen zu
+werden, da sie vom System immer konsistent gehalten werden.
+
+Merke: Die Betriebsrichtung gibt an, wie man eine Datei bearbeiten will.
+'input' steht für Lesen, 'output' für Schreiben und 'modify' für Verändern.
+Jede Datei muß vor einer Benutzung mit 'sequential file' assoziiert werden.
+Die Assoziierungsprozedur stellt die Kopplung zwischen dem Programm und dem
+EUMEL-Betriebssystem her.
+
+
+
+Operationen der Betriebsrichtung 'output'
+
+In der Betriebsrichtung 'output' sind nur Schreib-Operationen gestattet.
+'output' ist also für das Bearbeiten von Ausgabedateien vorgesehen.
+
+Mit den Prozeduren
+
+ put
+
+können INT-, REAL- und TEXT-Werte in eine Datei geschrieben werden. Die
+Prozedur
+
+ line
+
+sorgt dafür, daß eine neue Zeile in der Datei begonnen wird. Beispiel:
+
+ FILE VAR f :: sequential file (output, "daten");
+ put (f, "Daten:");
+ line (f);
+ schreibe daten.
+
+ schreibe daten:
+ INT VAR intwert;
+ REAL VAR textwert;
+ put ("bitte Daten eingeben (INT, REAL):");
+ REP
+ get (intwert);
+ put (f, intwert);
+ get (realwert);
+ put (f, realwert);
+ line (f);
+ UNTIL yes ("fertig") END REP.
+
+Durch die Assoziierungsprozedur mit der Betriebsrichtung 'output' wird
+hinter den letzten Satz der Datei positioniert, bei einer leeren Datei also
+auf den ersten Satz. In dem ersten Satz in unserem Beispiel wird also
+'Daten:' geschrieben. Durch die Prozedur 'line' geht man auf den nächsten
+Satz. Dann werden jeweils ein INT- und ein REAL-Wert in eine Datei-Zeile
+geschrieben, bis die Frage 'fertig' mit 'j' beantwortet wird.
+
+Die 'put'-Prozeduren schreiben die Werte jeweils in die aktuelle Datei-Zeile.
+Zwischen den Werten wird von den 'put'-Prozeduren jeweils ein Leerzeichen
+eingefügt. Im Gegensatz zu den 'put'-Prozeduren schreibt die Prozedur 'write'
+einen TEXT ohne ein anschließendes Leerzeichen in die aktuelle Datei-Zeile.
+Beispiel:
+
+ ...
+ write (f, "meine Daten:");
+ write (f, " ");
+ write (f, text (17 + 4));
+ (* das Gleiche wie: put (f, "meine Daten:"); put (f, 17 + 4) *)
+
+Auf eine neue Datei-Zeile kann auf zwei verschiedene Arten positioniert
+werden:
+
+a) Prozedur 'line':
+ Diese darf auch mit einem Parameter angegeben werden, der die Anzahl
+ Zeilen angibt. Beispiel:
+
+ line (f); (* positioniert auf die naechste Zeile *)
+ line (f, 1) (* das Gleiche *)
+ line (f, 4) (* Vier Zeilen weiter; dazwischen sind 3 Leerzeilen *)
+
+b) Überschreiten der Zeilengrenze:
+ Eine Datei-Zeile kann (voreingestellt) 77 Zeichen aufnehmen. Wird bei
+ einer Schreib-Operation diese Grenze überschritten, wird der auszugebende
+ Wert auf die nächste Zeile plaziert. Mit der Prozedur 'max line length'
+ kann die eingestellte Datei-Zeilenlänge gelesen oder verändert werden.
+ Beispiel:
+
+ FILE VAR f :: sequential file (output, "meine daten");
+ put (max line length (f)); (* ergibt 77 *)
+ max line length (f, 132);
+ put (max line length (f)) (* ergibt 132 *)
+
+ Ist die Länge des auszugebenden Textes größer als die verbleibende
+ Zeilenbreite, wird der Text auf der nächsten Zeile ausgegeben.
+
+Die 'putline'-Prozedur bietet die Möglichkeit, eine ganze Datei-Zeile auf
+einmal auszugeben. Eine Positionierung auf die nächste Datei-Zeile ('line')
+braucht dabei nicht vorgenommen werden. Beispiel:
+
+ TEXT VAR zeile :: "";
+ ...
+ zeile := ...;
+ putline (f, zeile);
+ ...
+
+Merke: In der Betriebsrichtung 'output' kann in eine Datei geschrieben
+werden. Dazu stehen die Prozeduren 'put', 'write' und 'putline' zur Verfü-
+gung. Die Prozedur 'line' positioniert auf die nächste Zeile der Ausgabe-
+datei. Mit 'max line length' kann die Länge einer Datei-Zeile verändert oder
+erfragt werden.
+
+
+
+Operationen der Betriebsrichtung 'input'
+
+In der Betriebsrichtung 'input' sind nur Lese-Operationen gestattet. 'input'
+ist also für das Bearbeiten von Eingabedateien vorgesehen.
+
+Analog der Betriebsrichtung 'output' sind bei 'input' 'get'-Prozeduren vor-
+handen, die INT-, REAL- oder TEXT-Werte aus einer Datei lesen. Beispiel:
+
+ FILE VAR f :: sequential file (input, "Betriebszeiten");
+ REAL VAR zeiten;
+ zeiten einlesen und berechnen.
+
+ zeiten einlesen und berechnen:
+ REP
+ get (f, zeiten);
+ IF zeiten = 0.0
+ THEN LEAVE zeiten einlesen und berechnen
+ FI; (* siehe auch 'eof'-Prozedur *)
+ berechne
+ END REP.
+
+ berechne:
+ ...
+
+Die 'get'-Prozeduren positionieren automatisch auf die nächste Zeile, sofern
+keine Werte mehr in der aktuellen Zeile vorhanden sind. Mit der Prozedur
+'line' kann explizit auf die nächste Zeile positioniert werden. Damit können
+die restlichen Daten einer Zeile überschlagen werden. Für die 'get'-Proze-
+duren gilt, daß jeder zu lesende Wert entweder beim nächsten Leerzeichen
+oder beim Zeilenende aufhört. Beispiel:
+
+ FILE VAR f :: sequential file (input, "text");
+ TEXT VAR wort;
+ lese worte.
+
+ lese worte:
+ REP
+ get (f, wort); (* Lesen eines Worts ohne Leerzeichen *)
+ put (wort); (* Schreiben eines Worts mit Leerzeichen *)
+ IF wort = "Ende"
+ THEN LEAVE lese worte
+ FI
+ END REP.
+
+
+Trennzeichen ("separator") zwischen den Worten sind also Leerzeichen, welche
+nicht eingelesen werden. Manchmal sollen jedoch Daten eingelesen werden, die
+durch andere Zeichen als dem Leerzeichen voneinander getrennt sind. Eine
+Möglichkeit, solche Daten zu behandeln, bietet die 'getline'-Prozedur. Sie
+liest (analog 'putline') eine ganze Zeile und positioniert auf die nächste
+Zeile. Dann kann man mit Hilfe von TEXT-Prozeduren solche Zeilen 'per Hand'
+auseinandernehmen. Als Beispiel zeigen wir ein Programm, welches den zweiten
+Wert einer Zeile lesen soll. Die Werte werden durch Kommata voneinander
+getrennt:
+
+ FILE VAR eingabe datei :: sequential file (input, "daten");
+ TEXT VAR zeile, wert;
+ lese jeweils zweiten wert;
+ verarbeite wert.
+
+ lese jeweils zweiten wert:
+ REP
+ getline (f, zeile);
+ IF zeile = "Ende"
+ THEN LEAVE lese jeweils zweiten wert
+ FI;
+ extrahiere zweiten wert
+ END REP.
+
+ extrahiere zweiten wert:
+ wert := subtext (zeile, anfang, ende).
+
+ anfang:
+ pos (zeile, ",") + 1.
+
+ ende:
+ pos (zeile, ",", anfang) + 1.
+
+ verarbeite wert:
+ ...
+
+Diese (etwas umständliche) Methode ist immer dann angebracht, wenn Zeilen
+unterschiedlich untersucht werden müssen. Eine einfachere Möglichkeit, die
+in vielen Fällen angewandt werden kann, bietet eine andere Form der 'get'-
+Prozedur, bei der man das oder die Trennzeichen angeben kann. Beispiel:
+
+ ...
+ extrahiere zweiten wert:
+ get (f, wert, ","); (* ersten Wert der Zeile ueberlesen *)
+ get (f, wert, ","). (* hier der richtige zweite Wert *)
+
+Hier wird also das Trennzeichen mit angegeben (dritter Parameter). Eine
+andere Methode müssen wir anwenden, wenn Daten nicht durch ein Trennzeichen
+unterschieden werden, sondern nur durch ihre Länge definiert sind. Beispiel:
+
+ ...
+ lese fuenfstellige werte:
+ REP
+ get (f, wort, 5);
+ verarbeite wert
+ ...
+ END REP.
+
+Bei dieser 'get'-Prozedur wird die Länge des einzulesenden Textes als
+dritter Parameter angegeben. Man beachte, daß die letzten zwei 'get'-Proze-
+duren nur TEXTe einlesen. Entsprechende Typwandlungen hat der Programmierer
+vorzunehmen.
+
+Merke: Die Betriebsrichtung 'input' erlaubt nur Lesen aus einer Eingabedatei.
+Für diesen Zweck gibt es die Prozeduren 'get', 'getline' und 'line'.
+
+
+
+Operationen der Betriebsrichtung 'modify'
+
+Die Betriebsrichtung 'modify' erlaubt das Lesen und Schreiben von Informa-
+tionen auf Dateien. Zusätzlich ist beliebiges Positionieren auf Dateien
+erlaubt. 'modify' ist also für Dateien gedacht, die man gleichzeitig als
+Ausgabe- und Eingabedateien behandeln will.
+
+Die Betriebsrichtung 'modify' erlaubt ein Ändern einer Datei ("updating"),
+wobei die sequentielle Natur der Datei erhalten bleibt.
+
+Eine Datei der Betriebsrichtung 'modify' muß ebenso mit 'sequential file'
+assoziiert werden, wie bei den zwei anderen Betriebsrichtungen. Während bei
+'input' auf den ersten bzw. bei 'output' auf den letzten Satz der Datei
+positioniert wird, ist bei 'modify' nicht definiert, auf welchem Satz der
+Datei nach erfolgter Assoziierung positioniert wird. Man muß also die erste
+Positionierung explizit vornehmen. Für die Zwecke der Positionierung gibt es
+die Prozeduren
+
+ to line (* auf eine bestimmte Zeile *)
+ col (* auf eine Spalte innerhalb der Zeile *)
+ down (* eine Zeile vorwaerts *)
+ up (* eine Zeile zurueck *)
+
+Neben diesen Positionierungsprozeduren gibt es die Informationsprozeduren:
+
+ lines (* Anzahl Zeilen in der Datei *)
+ line no (* aktuelle Zeilennummer *)
+ eof (* Dateiende? *)
+
+Beispiele:
+
+ down (f); (* wie: to line (f, line no (f) + 1) *)
+ (* Nicht über eof *)
+ up (f); (* wie: to line (f, line no (f) - 1) *)
+ (* Nicht über Zeile 1 *)
+
+Mit der Prozedur
+
+ read record
+
+kann der Satz, auf den aktuell positioniert wurde, gelesen werden. Mit
+
+ write record
+
+kann sein Inhalt geschrieben werden (also auch "überschreiben"). Mit den
+Prozeduren
+
+ insert record
+ delete record
+
+kann eine Zeile vor der aktuellen eingefügt (Position ist dann die einge-
+fügte Zeile) oder der aktuelle Satz gelöscht werden (Position ist dann der
+nächste Satz). Beispiele:
+
+ FILE VAR f :: sequential file (modify, "meine daten")
+ TEXT VAR zeile, neue zeile;
+ to line (f, 1);
+ read record (f, zeile); (* erste Zeile lesen *)
+ ...
+ insert record (f); (* neue erste Zeile *)
+ write record (f, neue zeile);
+ down (f); (* auf die 2. Zeile, die vorher die 1. war *)
+ delete record (f); (* diese loeschen, so dass die
+ Zeilenzahl wieder stimmt *)
+
+Das nächste Beispiel zeigt, wie hinter den letzten Satz einer Datei eine
+Zeile eingefügt werden kann (hier wird ausgenutzt, daß man in der Betriebs-
+richtung 'modify' hinter den letzten Satz der Datei positioniert werden
+kann):
+
+ FILE VAR f :: sequential file (modify, "test");
+ to line (f, lines (f)); (* auf die letzte Zeile *)
+ down (f);
+ insert record (f);
+ write record (f, "neue letzte Zeile");
+ ...
+
+Mit 'down' bzw. 'up' kann man auch um einige Zeilen auf einmal vorwärts oder
+rückwärts positionieren. Beispiele:
+
+ down (f, 17) (* 17 Zeilen vorwaerts *)
+ up (f, 13) (* 13 zeilen rueckwaerts *)
+
+Merke: In der Betriebsrichtung 'modify' können Dateien gelesen und/oder ge-
+schrieben werden ('read record' oder 'write record'). Positionierungen kön-
+nen mit 'down', 'up' oder 'to line' vorgenommen werden.
+
+
+
+Manipulationen von FILEs
+
+FILEs können im EUMEL-System auch als Einheiten behandelt werden. Dazu
+stehen die bereits erläuterten Prozeduren zur Verfügung, die wir hier der
+Vollständigkeit halber nochmals aufführen.
+
+Mit der Prozedur
+
+ exists
+
+kann erfragt werden, ob eine Datei bereits existiert. Beispiel:
+
+ TEXT VAR name;
+ REP
+ erfrage name;
+ UNTIL exists (name) END REP;
+ ...
+
+ erfrage name:
+ put ("Dateiname bitte:");
+ get (name);
+ line.
+
+Weitere Prozeduren:
+
+ forget (* Datei löschen *)
+ rename (* umbenennen *)
+ copy (* kopieren *)
+
+Für Programmierer ist eine Version der 'forget'-Prozedur interessant, die
+eine Datei ohne Kontroll-Anfrage löscht. Beispiel:
+
+ forget ("meine scratch datei", quiet)
+
+Merke: Mit 'exists' kann erfragt werden, ob ein FILE bereits existiert.
+
+
+
+Texte Suchen
+
+Mit den Prozeduren 'down' und 'up' kann man (ebenso wie im Editor) auch nach
+Texten suchen.
+
+Die Prozeduren 'down' bzw. 'up' suchen einen Text in der Datei. Beispiele:
+
+ down (f, "dieser text")
+ up (f, "noch'n text")
+
+Diese Prozeduren suchen direkt auf der Dateistruktur. Wird der gesuchte Text
+gefunden, steht man direkt auf dem gesuchten Text. Wird der Text nicht
+gefunden, steht man auf dem ersten (bei 'up') oder hinter dem letzten (bei
+'down') Zeichen der Datei. Die Position innerhalb der Zeile nach einer Suche
+kann mit
+
+ col (f)
+
+abgefragt werden. Um die Suche auf einen Bereich zu beschränken, kann man
+'down' bzw. 'up' mit einem weiterem Parameter versehen, der die max. Anzahl
+von Zeilen angibt. Beispiel:
+
+ FILE VAR f :: ...
+ ...
+ INT VAR akt zeilennr :: line no (f);
+ down (f, "pattern", 100);
+ (* sucht in den naechsten 100 Zeilen nach 'pattern' *)
+ IF line no (f) <> akt zeilen nr + 100
+ THEN gefunden
+ ELSE nicht gefunden
+ FI;
+ ...
+
+Achtung: 'down' bzw. 'up' beginnen die Suche immer mit dem nächsten Zeichen
+in Suchrichtung, so daß man mehrmals hintereinander suchen kann, ohne in
+eine Endlosschleife zu geraten (Erinnerung: wird ein Text gefunden, ist die
+Position innerhalb der Zeile das erste Zeichen des gesuchten Begriffs).
+
+Mit den Prozeduren (gleiche Parameterversorgung wie 'down' und 'up')
+
+ downety
+ uppety
+
+beginnt man mit der Suche immer auf der aktuellen Position. Darum sollte man
+diese Prozeduren mit Vorsicht verwenden. Mit der Prozedur
+
+ pattern found
+
+kann man anfragen, ob die letzte Suchoperation erfolgreich war oder nicht.
+Beispiel:
+
+ FILE VAR f :: ...
+ ...
+ INT VAR akt zeilennr :: line no (f);
+ down (f, "pattern", 100);
+ (* sucht in den naechsten 100 Zeilen nach 'pattern' *)
+ IF pattern found THEN gefunden
+ ELSE nicht gefunden
+ FI;
+ ...
+
+Mit der Prozedur
+
+ at
+
+kann man anfragen, ob man auf einem gewünschten Wort steht. Beispiel:
+
+ IF at (f, "pattern")
+ THEN ..
+ FI
+
+Die Prozedur
+
+ word
+
+liefert das aktuelle Wort der aktuellen Position einer Zeile. Beispiele:
+
+ TEXT VAR dieses wort :: word (f);
+ (* Zeichenkette von der aktuellen Position bis zum nächsten Blank oder
+ Zeilenende *)
+ dieses wort := word (f, "<");
+ (* Zeichenkette (Wort) von der aktuellen Position bis zum Zeichen '<'
+ oder Zeilenende *)
+ dieses wort := word (f, 13);
+ (* Zeichenkette (Wort) mit der Laenge 13 *)
+
+Merke: Die Prozeduren 'down' und 'up' suchen einen Text innerhalb einer
+Datei. Mit 'at' kann man anfragen, ob man auf dem gesuchten Begriff steht.
+'word' liefert das aktuelle Wort.
+
+
+
+FILE-Ausschnitte
+
+Hier wird erklärt, wie man mehrere Zeilen aus einer Datei auf einmal löschen
+und/oder verschieben und wie man nur einen Ausschnitt einer Datei zugänglich
+machen kann.
+
+Den einfachsten Zugang zu Datei-Abschnitten erhält ein Programmierer durch
+einige Anwendungsprozeduren, die u.a. auch im Editor verwandt werden. Dort
+gibt es die Möglichkeit, einen markierten Bereich "vorsichtig" zu löschen
+und u.U. an anderer Stelle wieder einzufügen (ESC RUBOUT und ESC RUBIN).
+Solche Prozeduren stehen auch einem Programmierer zur Verfügung. Beispiel:
+
+ FILE VAR f :: ....
+ ....
+ remove (f, 100); (* entfernt 100 Zeilen von der aktuellen
+ Position rueckwaerts (!) aus der Datei 'f' *)
+ to line (27); (* zum Beispiel *)
+ re insert (f) (* fuegt die "vorsichtig" geloeschten Zeilen vor
+ (!) die Zeile 27 ein *)
+
+Die Prozedur
+
+ remove
+
+löscht also eine angebbare Anzahl von Zeilen in der Datei (rückwärts von der
+aktuellen Zeilennummer ab) und schreibt diesen Datei-Abschnitt in einen
+internen Puffer. Man beachte, daß sich dabei natürlich die Zeilennummer der
+Datei ändert. Die entfernten Zeilen können aus dem internen Puffer an einer
+anderen Stelle durch
+
+ reinsert
+
+genau einmal wieder eingefügt werden. Sollen jedoch die mit 'remove' ent-
+fernten Zeilen wirklich gelöscht und nicht mehr an anderer Stelle eingesetzt
+werden, dann kann man die Prozedur
+
+ clear removed
+
+verwenden. Beispiel:
+
+ ...
+ remove (f, 50); (* loescht vorsichtig *)
+ clear removed (f); (* und endgueltig *)
+ ...
+
+Durch solche Löschungen oder Einfügungen entstehen Datei-Segmente.
+Innerhalb eines Segments kann direkt positioniert werden. Werden jedoch
+Löschungen oder Einfügungen vorgenommen (Sätze werden ein- oder ausgekettet),
+muß erst zu einem entsprechenden Segment positioniert und dann innerhalb des
+Segments auf den entsprechenden Satz positioniert werden. Das kann - je nach
+Anzahl der Segmente - zeitaufwendig sein. Deshalb existiert die Prozedur
+
+ segments
+
+mit der man feststellen kann, wieviel Datei-Segmente in der Datei existieren.
+(Sind es "zu viele", kann man die Datei "reorganisieren").
+
+Diese und die folgenden Prozeduren nutzen eine vom EUMEL-System bereitge-
+stellte Möglichkeit, Ausschnitte aus Dateien wie eigenständige Dateien zu
+behandeln. Beispiel:
+
+ FILE VAR f :: ...
+ ...
+ FRANGE VAR alter bereich;
+ set range (f, 200, 1, alter bereich);
+ (* Datei mit 200 Zeilen von der Spalte 1 der aktuellen Zeile *)
+ edit (f); (* Zeilen 1-200 editieren *)
+ set range (f, alter bereich); (* Datei zuruecksetzen *)
+ ...
+
+Von dem Beispiel-Programm wird die Datei 'f' bearbeitet. Die FRANGE-Variable
+dient hier dazu, sich den ursprünglichen Bereich der Datei 'f' (der auch
+schon eingeschränkt sein kann), zu merken. Mit der Prozedur 'set range' wird
+die Datei 'f' auf 200 Zeilen eingeschränkt (von der aktuellen Zeile 200
+Zeilen rückwärts). Mit der Prozedur 'edit' kann nun der Benutzer unseres
+Programms die (eingeschränkte) Datei beliebig editieren. Ihm steht am Anfang
+Zeilen 1 bis 200 zur Verfügung; die "ausgeblendeten" Datei-Teile kann er
+nicht verändern. Mit dem zweiten Aufruf von 'set range' wird der einge-
+schränkte (und u.U. veränderte) Datei-Bereich aufgehoben, so daß hier wieder
+alle ursprünglichen Datei-Zeilen zur Verfügung stehen.
+
+Solche Beschränkungen können natürlich mehrmals geschachtelt vorgenommen
+werden. Um nach Ablauf solcher Programmteile sicher wieder die ursprüngliche
+Datei (mit allen ihren Zeilen) zur Verfügung zu haben, gibt es die Prozedur
+
+ reset range (f)
+
+Sie setzt die Datei 'f' auf den größtmöglichen Bereich zurück.
+
+Merke: Mit 'remove' und 'reinsert' können Zeilen gelöscht und/oder ver-
+schoben werden. Mit dem Datentyp FRANGE und den Prozeduren 'set range'
+können Dateien eingeschränkt werden.
+
+
+
+5. Datenräume
+
+Die bis jetzt behandelten Dateien können nur TEXTe aufnehmen (bei einigen
+Schreib-/Lese-Operationen werden Daten in Texte umgewandelt, z.B. bei 'get'
+und 'put'). Damit ist gewährleistet, daß alle Programme im EUMEL-System
+(Editor, Drucker, Compiler, Benutzer-Programme usw.) auf gleiche Art und
+Weise auf Dateien zugreifen können, unabhängig davon, welche Daten wirklich
+gespeichert sind. Der folgende Abschnitt zeigt, wie man mit Dateien umgeht,
+die nicht vom Standardtyp FILE sind.
+
+
+
+Konzept des Datenraums
+
+Standarddateien (FILEs) 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. Hierfür stehen Standard-
+prozeduren 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. Daher wurden in EUMEL� die
+Datenräume eingef�hrt, 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
+der Datei gespeicherten Objektes nicht kennen.
+
+Einen Datenraum kann man sich als eine Sammlung von Daten vorstellen (u.U.
+leer), die ausschließlich von einem Programm her behandelt wird. Man kann
+einem Datenraum durch ein Programm einen Datentyp "aufprägen". Meist handelt
+es sich um Reihungen, weil die Benutzung von Datenräumen erst bei größeren
+Datenmengen lohnt. Nach einem solchen "Aufpräge"-Vorgang kann der Datenraum
+wie ein "normaler" Datentyp behandelt werden, mit dem Unterschied, daß die
+Daten in einem Datenraum (d.h. Datei) gespeichert werden. Somit können nach-
+folgende Programme auf die im Datenraum gespeicherten Daten zugreifen, so-
+fern sie den gleichen Datentyp auf den Datenraum aufprägen.
+
+Merke: Ein Datenraum ist eine Sammlung von Daten. Er kann ausschließlich
+durch ein Programm (und z.B. nicht durch den Editor) behandelt werden.
+Programme können Datenräumen Datentypen aufprägen und sie dann mit den ver-
+fügbaren Operationen dieses Datentyps manipulieren.
+
+
+Ein Beispiel
+
+Diesen etwas komplizierten Vorgang wollen wir an Hand eines Beispiels
+Schritt für Schritt erklären.
+
+Angenommen, Programmierer Meier hat ein Gehaltsprogramm zu erstellen. Er
+überlegt sich, das Programm in (mindestens) zwei Moduln (PACKETs) zu er-
+stellen:
+
+a) Berechnung der Gehaltssumme aus den Arbeitszeiten (also Bruttogehalt) und
+ dann
+b) Endgültige Berechnung der Gehälter durch Abzug von Steuern usw.
+
+Das Programm aus a) erstellt also eine Gehaltsliste für alle Beschäftigten
+des Betriebs. Die Gehaltsliste soll ebenfalls von Modul b) genutzt werden.
+
+Meier entschließt sich, die Gehaltsliste in einem Datenraum zu speichern.
+Das hat neben der effizienteren Bearbeitung noch den Vorteil, daß man die
+Gehaltsliste - ohne Programmierkenntnisse zu besitzen - nicht mit dem Editor
+bearbeiten kann (Datenschutz).
+
+Dem ELAN-Compiler muß Meier also mitteilen, daß die Reihung für die
+Gehaltsliste (oder irgendein anderer Datentyp) nicht im Speicherbereich des
+Programms, sondern in einem Datenraum gespeichert werden soll. Dies erfolgt
+mit dem Schlüsselwort BOUND, welches dem Datentyp bei der Deklaration
+vorangestellt wird. Beispiel:
+
+ BOUND ROW 1000 REAL VAR gehaltsliste
+
+Dieses BOUND-Objekt muß Meier noch mit einer Datei verbinden, man spricht
+von "ankoppeln". Die Ankopplung erfolgt durch den Operator ':='. Dies kann
+man gleich bei der Initialisierung vornehmen. Beispiel:
+
+ BOUND ROW 1000 REAL VAR gehaltsliste := new ("hugo")
+
+Die Prozedur 'new' kreiert dabei einen leeren Datenraum (hier mit dem Namen
+'hugo'), der mit Hilfe der Zuweisung (hier: Initialisierung) an die Variable
+'gehaltsliste' gekoppelt wird.
+
+Nun kann Meier mit der 'gehaltsliste' arbeiten wie mit allen anderen Feldern
+auch, mit dem Unterschied, daß die Daten, die er in 'gehaltsliste' speichert,
+eigentlich im Datenraum 'hugo' gespeichert sind. Beispiele:
+
+ gehaltsliste [5] := 10 000.0; (* Traumgehalt *)
+ gehaltsliste [index] INCR 200.0; (* usw. *)
+
+Meier kann auch Prozeduren schreiben, die auf der Gehaltsliste arbeiten.
+Beispiel:
+
+ PROC sort (ROW 1000 REAL VAR liste):
+ ...
+ END PROC sort;
+ ...
+ sort (gehaltsliste);
+ ...
+
+Man beachte, daß der formale Parameter der Prozedur 'sort' nicht mit BOUND
+spezifiziert werden darf (BOUND wird nur bei der Deklaration des Objekts
+angegeben). Das ist übrigens ein weiterer wichtiger Vorteil von BOUND-Objek-
+ten: man kann alle Prozeduren des EUMEL-Systems auch für BOUND-Objekte
+verwenden, nur die Datentypen müssen natürlich übereinstimmen.
+
+Nach der Bearbeitung des Moduls a) ist Meier nun sicher, daß seine Brutto-
+daten in dem Datenraum 'hugo' stehen. Meier braucht (genauso wie bei FILEs)
+den Datenraum nicht zu schließen. Im zweiten Modul muß Meier nun erneut ein
+BOUND-Objekt deklarieren.
+Deshalb deklariert Meier nun
+
+ BOUND ROW 1000 REAL VAR nettoliste :: old ("hugo");
+
+Hier muß Meier nun die Prozedur 'old' verwenden, weil der Datenraum bereits
+aus dem ersten Modul existiert. Nun kann Meier weiter programmieren, bis er
+letztendlich den Datenraum löscht:
+
+ forget ("hugo")
+
+Merke: Ein Datenobjekt eines beliebigen Datentyps kann mit einem vorange-
+stellten BOUND deklariert werden und an einen Datenraum gekoppelt werden.
+Der Datentyp ist dann auf den Datenraum aufgeprägt und man kann mit ihm
+arbeiten wie mit allen anderen Objekten dieses Datentyps.
+
+
+
+Datenräume als Datentyp
+
+Datenräume können auch als eigener Datentyp (DATASPACE) in einem Programm
+behandelt werden. Somit können Datenräume (als Ganzes) ohne Kenntnis eines
+eventuell (vorher oder später) aufgeprägten Typs verwandt werden.
+
+Als Operationen auf DATASPACE-Objekten sind nur Transporte, Löschen und
+Initialisieren zugelassen.
+
+ DATASPACE VAR ds :: old ("daten");
+
+Der Zuweisungsoperator bewirkt eine Kopie des Datenraums vom rechten auf
+den linken Operanden. Des weiteren gibt es eine DATASPACE Konstante 'nil-
+space', die eine leere Datenraum repräsentiert. Mit diesem Wert initialisiert
+der Datei-Manager Dateien, die neu kreiert werden.
+
+Eine neuer Datenraum kann durch
+
+ new ("name")
+
+eingerichtet werden. 'new' liefert gleichzeitig einen Datenraum und wird
+deshalb für Initialisierungen verwandt. Beispiel:
+
+ DATASPACE VAR datenraum :: new ("name1"); (* Kopie ! *)
+
+Ein bereits vorhandener Datenraum in der Benutzer-Task kann mit
+
+ old ("datei")
+
+erneut benutzt werden. 'old' liefert (wie 'new') einen DATASPACE, so daß
+'old' ebenfalls zur Initialisierung benutzt werden kann. Die Prozedur
+
+ nilspace
+
+liefert einen leeren Datenraum.
+
+Für Datenräume gelten zusätzlich einige der Prozeduren wie für FILEs, u.a.:
+
+ forget
+ fetch
+ save
+ rename
+
+Ausgenommen davon sind Prozeduren, die einen TEXT-File voraussetzen, wie
+z.B. 'crypt' und 'decrypt', 'put', 'putline' usw.
+
+Abschließend soll hier noch auf häufig gemachte Fehler hingewiesen werden:
+
+Wenn man an ein DATASPACE-Objekt zuweist (z.B.: DATASPACE VAR ds :=
+new ("mein datenraum")) so erhält man, wie oben 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
+(d.h. im Beispiel, daß die Datenraum 'hugo' nicht verändert wird, hier also
+leer bleibt). Für Änderungen in den vom Datei-Manager verwalteten Dateien
+ist also stets direkt anzukoppeln, wie es im Beispiel gezeigt wurde.
+
+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'.
+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) (* Datei löschen, damit der Platz wieder verwendet wird *)
+
+Ein automatisches Löschen von DATASPACE-Objekten erfolgt auch nicht bei
+Programmende (sonst könnten sie ihre Funktion als Datei nicht erfüllen).
+Erst beim Löschen einer Task werden alle ihr gehörenden DATASPACE-Objekte
+freigegeben. Verboten ist weiterhin folgendes:
+
+ BOUND X ...;
+
+wobei 'X' mit BOUND deklariert wurde oder ein DATASPACE ist.
+
+Merke: Datenräume können durch 'new' erschaffen werden. Mit 'old' kann ein
+bereits vorhandener Datenraum angesprochen werden. Im Übrigen gelten auch
+einige der für FILEs vorhandenen Operationen.
+
+
+
+Datei-Typen definieren
+
+Durch die Datenräume und die Datentyp-Definition von ELAN ist es für
+Programmierer 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 zeigen wir an dem Beispiel DIRFILE (welcher zwar im
+ELAN-Standard definiert, aber nicht im EUMEL-System realisiert ist), wie ein
+neuer Datei-Datentyp definiert wird:
+
+ 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 vor-
+handenen Datenraum oder richtet einen neuen ein. Um eine Initialisierung mit
+der 'dirfile'-Prozedur vornehmen zu können, braucht man auch einen Zu-
+weisungsoperator, 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
+benutzen. 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;
+ ...
+
+Merke: Neue Datei-Typen für spezielle Anwendungen kann man leicht selbst
+programmieren.
+
+
+
+6. Beschreibung der Prozeduren
+
+In diesem Abschnitt werden alle Operationen, die für Dateien zur Verfügung
+stehen, aufgeführt. Dabei werden die Operationen für FILEs und Datenräume
+mit (F) gekennzeichnet.
+
++
+ THESAURUS OP + (THESAURUS CONST left, right)
+ Zweck: Vereinigungsmenge von 'left' und 'right'.
+
+ THESAURUS OP + (THESAURUS VAR left, TEXT CONST name)
+ Zweck: Nimmt den TEXT 'name' in den Thesaurus 'left' auf. Beispiel:
+
+ save (SOME father + "hugo", archive)
+
+-
+ THESAURUS OP - (THESAURUS CONST left, right)
+ Zweck: Differenzmenge von 'left' und 'right'.
+
+ THESAURUS OP - (THESAURUS VAR left, TEXT CONST name)
+ Zweck: Liefert einen Thesaurus aus left, aber ohne den Eintrag 'name'.
+ Beispiel:
+
+ save (ALL myself - "hugo", archive)
+
+/
+ THESAURUS OP / (THESAURUS CONST left, right)
+ Zweck: Schnittmenge von 'left' und 'right'.
+
+ TASK OP / (TEXT CONST task name)
+ Zweck: Liefert aus einem Tasknamen den internen Tasknamen. '/' kann über-
+ all dort eingesetzt werden, wo ein interner Taskname verlangt wird.
+
+ALL
+ THESAURUS OP ALL (TASK CONST task)
+ Zweck: Liefert einen Thesaurus, der alle Dateinamen der angegebenen Task
+ enthält (auch der Benutzer-Task: 'myself').
+
+ THESAURUS OP ALL (TEXT CONST file name)
+ Zweck: Liefert einen Thesaurus, der die in 'file name' vorhandenen Datei-
+ namen (jede Zeile ein Name) enthält.
+
+at (F)
+ BOOL PROC at (FILE VAR f, TEXT CONST word)
+ Zweck: Abfrage, ob man auf 'word' in der Datei 'f' positioniert ist.
+ Beispiel:
+
+ ...
+ down (f, "muster")
+ IF at (f, "muster")
+ THEN gefunden
+ ELSE nicht gefunden
+ FI;
+ ...
+
+archive
+ PROC archive (TEXT CONST archive name)
+ Zweck: Anmeldung von Archiv-Operationen. 'archive name' wird zur Über-
+ prü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.
+
+ TASK PROC archive
+ Zweck: Liefert den internen Task-Bezeichner für die Verwendung in
+ Datei-Kommandos. Beispiel:
+
+ save ("datei", archive)
+
+brother
+ TASK PROC brother (TASK CONST task)
+ Zweck: Liefert den internen Task-Bezeichner der angegebenen "Bruder"-
+ Task.
+
+check
+ PROC check (TEXT CONST dateiname, TASK CONST task)
+ Zweck: Überprüft, ob die Datei 'dateiname' auf dem Archiv lesbar ist.
+ Beispiel:
+
+ check ("meine datei", archive)
+
+ PROC check (THESAURUS CONST t, TASK CONST task)
+ Zweck: Überprüft, ob die in dem Thesaurus 't' enthaltenen Dateien auf dem
+ Archiv lesbar sind. Beispiel:
+
+ check (ALL archive, archive)
+
+clear
+ PROC clear (TASK CONST task)
+ Zweck: Löscht alle Dateien der Task 'task'. Ist z.Z. nur für die Task
+ 'ARCHIVE' implementiert.
+
+clear removed (F)
+ PROC clear removed (FILE VAR f)
+ Zweck: Löscht die mit 'remove' "vorsichtig" gelöschten Zeilen aus der
+ Datei 'f' endgültig.
+
+close (F)
+ PROC close (FILE VAR file)
+ Zweck: Schließen der Datei 'file'. Im EUMEL-System ist der Aufruf von
+ 'close' nicht notwendig. 'close' wurde nur aufgenommen, um die
+ Kompatibilität zu Standard zu wahren.
+
+col (F)
+ PROC col (FILE VAR f, INT CONST position)
+ Zweck: Positionierung auf die Spalte 'position' innerhalb der aktuellen
+ Zeile.
+
+ INT PROC col (FILE CONST f)
+ Zweck: Liefert die aktuelle Position innerhalb der aktuellen Zeile.
+
+copy (F)
+ PROC copy (TEXT CONST source, destination)
+ Zweck: Kopiert die Datei 'source' in eine neue Datei mit dem Namen
+ 'destination' in der Benutzer-Task.
+ Fehlerfälle:
+ * destination file already exists
+ Eine Datei mit dem Namen 'destination' existiert bereits.
+ * source file does not exist
+ Die Ursprungsdatei mit dem Namen 'source' ist nicht vorhanden.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien der Benutzer-Task ist über-
+ schritten.
+
+ PROC copy (DATASPACE CONST ds, TEXT CONST destination)
+ Zweck: Eintragen eines unbenannten DATASPACE in die Datei-Verwaltung.
+ Fehlerfälle:
+ * destination file already exists
+ Eine Datei mit dem Namen 'destination' existiert bereits.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien der Benutzer-Task ist über-
+ schritten.
+
+create
+ PROC create (TEXT CONST name)
+ Zweck: Erschafft einen neuen Datenraum in der Benutzer-Task.
+ Fehlerfälle:
+ * file already exists
+ Eine Datei mit dem Namen 'name' existiert bereits in der Benutzer-
+ Task.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien der Benutzer-Task ist über-
+ schritten.
+
+crypt (F)
+ PROC crypt (TEXT CONST name, parole)
+ Zweck: Verschlüsseln des Inhaltes der Datei 'name' mit Hilfe des Textes
+ 'parole' für Zwecke des Datenschutzes. Die Verschlüsselung ist
+ umso besser (bzw. umso schwieriger zu "knacken"), je länger der
+ Text 'parole' ist. Die Datei kann mit der Prozedur 'decrypt'
+ wieder entschlüsselt werden.
+
+ Eine Datei kann mehrfach verschlüsselt werden. Dabei gilt bei
+ einer Entschlüsselung das Klammerungsprinzip. Es muß also genau so
+ oft entschlüsselt werden, wie anfangs verschlüsselt wurde. Dabei
+ ist auf die richtige Angabe der 'parole'n zu achten. Beispiel:
+
+ crypt ("hugo", "verschluesselung1");
+ crypt ("hugo", "verschluesselung2");
+ ...
+ decrypt ("hugo", "verschluesselung2");
+ decrypt ("hugo", "verschluesselung1")
+
+ Achtung: 'crypt' und 'decrypt' sind nicht standardmäßig insertiert.
+
+decrypt (F)
+ PROC decrypt (TEXT CONST name, parole)
+ Zweck: Entschlüsselt die Datei 'name' mit Hilfe der angegebenen 'parole'.
+ Dabei ist darauf zu achten, daß die gleiche 'parole' anzugeben
+ ist, die verwendet wurde, um die Datei zu verschlüsseln (sonst
+ wirkt 'decrypt' wie ein erneuter Aufruf von 'crypt').Beim mehr-
+ fachen Ver- und Entschlüsseln ist das Klammerungsprinzip zu be-
+ achten (dazu vergl. 'crypt').
+
+delete record (F)
+ PROC delete record (FILE VAR file)
+ Zweck: Der aktuelle Satz der Datei 'file' wird gelöscht. Der folgende
+ Satz wird der aktuelle Satz. Die Datei 'file' muß mit der Verar-
+ beitungsart 'modify' assoziiert worden sein.
+
+do
+ PROC do (PROC (TEXT CONST) operate, THESAURUS CONST thesaurus)
+ Zweck: Ruft 'operate' mit allen im 'thesaurus' enthaltenen Dateinamen
+ nacheinander auf. Man beachte, daß bei Prozedur-Parametern der
+ Name der Prozedur hinter dessen Parametern geschrieben wird.
+ Beispiel:
+
+ do (PROC (TEXT CONST) reorganize, ALL myself)
+
+ PROC do (PROC (TEXT CONST, TASK CONST) operate,
+ THESAURUS CONST thesaurus, TASK CONST task)
+ Zweck: S.o.. Dabei ist zu beachten, daß 'task' als zweiter Parameter in
+ der Prozedur 'operate' eingesetzt wird. Beispiel:
+
+ do (PROC (TEXT CONST, TASK CONST) save,
+ SOME myself, father)
+ (* enspricht: *)
+ save (SOME myself, father)
+
+down (F)
+ PROC down (FILE VAR f)
+ Zweck: Positionieren um eine Zeile vorwärts in der Datei 'f'.
+
+ PROC down (FILE VAR f, INT CONST number)
+ Zweck: Positionieren um 'number' Zeilen vorwärts in der Datei 'f'.
+
+ PROC down (FILE VAR f, TEXT CONST pattern)
+ Zweck: Suche nach 'pattern' in der Datei 'f'. Wird 'pattern' gefunden,
+ ist die Position das erste Zeichen von 'pattern'. 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.
+
+ PROC down (FILE VAR f, TEXT CONST pattern, INT CONST number)
+ Zweck: Wie obiges 'down', aber maximal nur 'number'-Zeilen weit.
+
+downety (F)
+ PROC downety (FILE VAR f, TEXT CONST pattern)
+ Zweck: Suche nach 'pattern' in der Datei 'f'. Wird 'pattern' gefunden,
+ ist die Position das erste Zeichen von 'pattern'. Andernfalls
+ steht man auf dem letzten Zeichen der Datei. Achtung: 'downety'
+ sucht (im Gegensatz zu 'down') vom aktuellen Zeichen.
+
+ PROC downety (FILE VAR f, TEXT CONST pattern, INT CONST number)
+ Zweck: Wie obiges 'downety', aber maximal nur 'number'-Zeilen weit.
+
+enter password
+ PROC enter password (TEXT CONST password)
+ Zweck: Einstellen eines Paßwortes in der Benutzer-Task für den Datei-
+ Verkehr mit einer Vater-Task. Der Parameter 'password' kann dabei
+ aus zwei Teilen bestehen, die durch ein "/"-Zeichen getrennt
+ werden müssen. Der erste Teil bedeutet das schreib-Passwort,
+ während der TEXT nach dem "/"-Zeichen das Lese-Paßwort beinhaltet.
+ Enthält der Parameter 'password' kein "/"-Zeichen, gilt der ange-
+ gebene TEXT sowohl für das Schreib- wie auch für das Lese-Paßwort.
+ Im Schreib- bzw. Lese-Teil des Paßworts kann man das "-"-Zeichen
+ angeben, um eine Datei vor überschreibendem oder lesendem Zugriff
+ zu schützen.
+
+ Die Paßwort-Überprüfung findet statt bei
+
+ - fetch (Überprüfung der Lese-Berechtigung)
+ - save (Überprüfung der Schreib-Berechtigung)
+ - erase (Überprüfung der Schreib-Berechtigung)
+
+eof (F)
+ BOOL PROC eof (FILE CONST file)
+ Zweck: Informationsprozedur auf das Ende eines FILEs. Liefert den Wert
+ TRUE, sofern hinter den letzten Satz eines FILEs positioniert
+ wurde.
+
+erase
+ PROC erase (TEXT CONST name)
+ Zweck: Löscht eine Datei mit dem Namen 'name' in der unmittelbaren
+ Vater-Task.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Eine Datei mit dem Namen 'name' existiert in der unmittelbaren
+ Vater-Task nicht.
+ * wrong password
+ Es wurde mit der Prozedur 'enter password' nicht das richtige
+ Paßwort angegeben.
+
+ PROC erase (TEXT CONST name, TASK CONST task)
+ Zweck: Löscht eine Datei mit dem Namen 'name' in der Task 'task'. Bei-
+ spiel:
+
+ erase ("meine datei", father)
+
+ PROC erase (THESAURUS CONST thesaurus)
+ Zweck: Löscht die im 'thesaurus' angegebenen Dateien in der Vater-Task.
+ Beispiel (löscht alle Dateien in der Vater-Task, die in der Benut-
+ zer-Task vorhanden sind):
+
+ erase (ALL myself)
+
+ PROC erase (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: S.o..
+
+exists (F)
+ BOOL PROC exists (TEXT CONST name)
+ Zweck: Informationsprozedur zur Abfrage der Existenz einer Datei in der
+ Benutzer-Task. Beispiel:
+
+ IF exists ("dateiname")
+ THEN FILE VAR f :: sequential file ...;
+ ELSE errorstop ("Datei existiert nicht")
+ FI
+
+father
+ TASK PROC father
+ Zweck: Liefert den internen Task-Bezeichner der Vater-Task der Benutzer-
+ Task. Beispiel:
+
+ save ("datei", father)
+
+ TASK PROC father (TASK CONST task)
+ Zweck: Liefert den internen Task-Bezeichner von 'task'. Beispiel:
+
+ save ("datei", father (father)) (* Kopiert 'datei' zum "Opa" *)
+
+fetch
+ PROC fetch (TEXT CONST name)
+ Zweck: Einbringen einer Datei in die Benutzer-Task von dem "direkten"
+ Vater im Taskbaum.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Die Datei existiert bei dem Vater nicht.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien der Benutzer-Task ist über-
+ schritten.
+ * wrong password
+ Es wurde mit der Prozedur 'enter password' nicht das richtige
+ Paßwort angegeben.
+
+ PROC fetch (TEXT CONST name, TASK CONST task)
+ Zweck: Kopieren einer Datei in die Benutzer-Task von 'task'. Beispiel:
+
+ fetch ("datei", public)
+
+ PROC fetch (THESAURUS CONST thesaurus)
+ Zweck: Holt alle im 'thesaurus' enthaltenen Dateien von der Vater-Task.
+
+ PROC fetch (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: Holt alle im 'thesaurus' enthaltenen Dateien von der 'manager'-
+ Task.
+
+forget (F)
+ PROC forget (TEXT CONST name)
+ Zweck: Löschen einer Datei mit dem Namen 'name' in der Benutzer-Task.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Die Datei mit dem Namen 'name' existiert nicht in der Benutzer-
+ Task.
+
+ PROC forget (DATASPACE VAR ds)
+ Zweck: Löschen des Datenraums 'ds'.
+
+ PROC forget (THESAURUS CONST thesaurus)
+ Zweck: Löscht die im 'thesaurus' enthaltenen Dateinamen in der Benutzer-
+ Task. Beispiel:
+
+ forget (SOME myself)
+
+ PROC forget (TEXT CONST file name, QUIET CONST q)
+ Zweck: Löschen der Datei 'file name' ohne Anfrage. Als zweiter Parameter
+ muß 'quiet' übergeben werden. Beispiel:
+
+ forget ("hugo", quiet)
+
+get (F)
+ PROC get (FILE VAR f, INT VAR number)
+ Zweck: Lesen eines INT-Wertes 'number' von der Datei 'f'.
+
+ PROC get (FILE VAR f, REAL VAR number)
+ Zweck: Lesen eines REAL-Wertes 'number' von der Datei 'f'.
+
+ PROC get (FILE VAR f, TEXT VAR text)
+ Zweck: Lesen eines TEXT-Wertes 'text' von der Datei 'f'.
+
+ PROC get (FILE VAR f, TEXT VAR text, TEXT CONST delimiter)
+ Zweck: Lesen eines TEXT-Wertes 'text' von der Datei 'f', bis das Zeichen
+ 'delimiter' angetroffen wird. Ein eventueller Zeilenwechsel in der
+ Datei wird dabei nicht übergangen.
+
+ PROC get (FILE VAR f, TEXT VAR text, INT CONST maxlength)
+ Zweck: Lesen eines TEXT-Wertes 'text' von der Datei 'f' mit 'maxlength'
+ Zeichen. Ein eventueller Zeilenwechsel in der Datei wird dabei
+ nicht übergangen.
+
+getline (F)
+ PROC get line (FILE VAR file, TEXT VAR record)
+ Zweck: Lesen einer Zeile 'record' von einer sequentiellen Datei 'file'.
+ Die Datei muß mit 'input' assoziiert sein (vergl. 'sequential
+ file').
+ Fehlerfälle:
+ * file not open
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+ * input after end of file
+ Es wurde versucht, über die letzte Zeile einer Datei zu lesen.
+ * input access to output file
+ Es wurde versucht, von einem mit 'output' assoziierten FILE zu
+ lesen.
+
+global manager
+ PROC global manager
+ Zweck: Durch den Aufruf der Prozedur wird die Benutzer-Task zu einem
+ Datei-Manager. Danach können Söhne dieser Task eingerichtet
+ werden.
+
+input (F)
+ PROC input (FILE VAR f)
+ Zweck: Ändern der Verarbeitungsart von 'modify' oder 'output' in 'input'.
+ Dabei wird auf den ersten Satz der Datei positioniert.
+
+ TRANSPUTDIRECTION CONST input
+ Zweck: Assoziierung in Zusammenhang mit der Prozedur 'sequential file'
+ einer sequentiellen Datei mit der 'TRANSPUTDIRECTION' 'input' (nur
+ lesen).
+
+insert record (F)
+ PROC insert record (FILE VAR file)
+ Zweck: 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). Die Datei 'file' muß mit der Verarbeitungsart
+ 'modify' assoziiert worden sein.
+
+line no (F)
+ INT PROC line no (FILE CONST file)
+ Zweck: Liefert die aktuelle Zeilennummer.
+
+line (F)
+ PROC line (FILE VAR file)
+ Zweck: Positionierung auf die nähhste Zeile der Datei 'file'. Die Datei
+ 'file' darf mit 'output' oder 'input' assoziiert sein. Wird ver-
+ sucht, über das Ende eines mit 'input' assoziierten FILEs zu
+ positionieren, wird keine Aktion vorgenommen.
+
+ PROC line (FILE VAR file, INT CONST lines)
+ Zweck: Positionierung auf 'lines' nächste Zeilen der Datei 'file'. Die
+ Datei 'file' darf mit 'output' oder 'input' assoziiert sein. Wird
+ versucht, über das Ende eines mit 'input' assoziierten FILEs zu
+ positionieren, wird keine Aktion vorgenommen. Ist 'lines' <= 0,
+ wird keine Aktion durchgeführt.
+
+lines (F)
+ PROC lines (FILE VAR f)
+ Zweck: Liefert die Anzahl der Zeilen der Datei 'f'.
+
+list
+ PROC list
+ Zweck: Listet alle Dateien der Benutzer-Task mit Namen und Datum des
+ letzten Zugriffs auf dem Terminal auf.
+
+ PROC list (FILE VAR f)
+ Zweck: Schreibt alle Dateien der Benutzer-Task mit Namen und Datum der
+ letzten Änderung in die Datei 'f'.
+
+ PROC list (TASK CONST task)
+ Zweck: Listet alle Dateien der angegebenen 'task' mit Namen und Datum der
+ letzten Änderung auf dem Terminal auf. Beispiel:
+
+ list (father)
+
+max line length (F)
+ INT PROC max line length (FILE CONST file)
+ Zweck: Informationsprozedur über die Anzahl von Zeichen in einer Zeile
+ der Datei 'file'. Standardmäßig sind die Anzahl der Zeichen einer
+ Zeile wie beim Editor 77 Zeichen.
+
+ PROC max line length (FILE VAR file, INT CONST number)
+ Zweck: Setzen der Anzahl von Zeichen einer Zeile in dem FILE 'file'.
+
+modify (F)
+ TRANSPUTDIRECTION CONST modify
+ Zweck: Diese Betriebsrichtung erlaubt das Vorwärts- und Rückwärts-Posi-
+ tionieren und das beliebige Einfügen und Löschen von Sätzen.
+ 'modify' wird für die Assoziierungsprozedur 'sequential file'
+ benötigt.
+
+ PROC modify (FILE VAR f)
+ Zweck: Ändern der Betriebsrichtung von 'input' oder 'output' in die Be-
+ triebsrichtung 'modify'.
+
+myself
+ TASK PROC myself
+ Zweck: Liefert den internen Task-Bezeichner der Benutzer-Task. Beispiel:
+
+ save (ALL myself, father)
+
+name
+ TEXT PROC name (TASK CONST task)
+ Zweck: Liefert den TEXT-Namen von 'task'. Beispiel:
+
+ put (name (myself))
+
+new (F)
+ DATASPACE PROC new (TEXT CONST name)
+ Zweck: Richtet eine neue Datei in der Benutzer-Task ein.
+ Fehlerfälle:
+ * file already exists
+ Die Datei mit dem Namen 'name' existiert bereits in der Benutzer-
+ Task.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien in der Benutzer-Task ist über-
+ schritten.
+
+nilspace (F)
+ DATASPACE CONST nilspace
+ Zweck: Liefert einen leeren Datenraum.
+
+old (F)
+ DATASPACE PROC old (TEXT CONST name)
+ Zweck: Eine bereits vorhandene Datei der Benutzer-Task wird erneut zur
+ Bearbeitung angemeldet.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Die Datei mit dem Namen 'name' ist nicht in der Benutzer-Task
+ vorhanden.
+
+output (F)
+ PROC output (FILE VAR file)
+ Zweck: Ändern der Verarbeitungsart von 'input' oder 'modify' in 'output'.
+ Dabei wird hinter den letzten Satz der Datei positioniert.
+
+ TRANSPUTDIRECTION CONST output
+ Zweck: In Verbindung mit der Prozedur 'sequential file' kann eine Datei
+ assoziiert werden mit der Betriebsrichtung 'output' (nur
+ schreiben).
+
+pattern found
+ BOOL PROC pattern found
+ Zweck: Liefert TRUE, sofern die letzte Suchoperation (siehe 'down' und
+ 'up') erfolgreich war, sonst FALSE.
+
+printer
+ TASK PROC printer
+ Zweck: Liefert den internen TASK-Bezeichner der SPOOLer-Task für den
+ Drucker. Beispiel:
+
+ save ("datei", printer)
+
+public
+ TASK PROC public
+ Zweck: Liefert den internen Task-Bezeichner von "PUBLIC". Beispiel:
+
+ fetch ("datei", public)
+
+put (F)
+ PROC put (FILE VAR f, INT CONST number)
+ Zweck: Ausgabe eines INT-Wertes 'number' in die Datei 'f'. Dabei wird ein
+ Leerzeichen an die Ausgabe angefügt.
+
+ PROC put (FILE VAR f, REAL CONST number)
+ Zweck: Ausgabe eines REAL-Wertes 'number' in die Datei 'f'. Dabei wird
+ ein Leerzeichen an die Ausgabe angefügt.
+
+ PROC put (FILE VAR f, TEXT CONST text)
+ Zweck: Ausgabe eines TEXT-Wertes 'text' in die Datei 'f'. Dabei wird ein
+ Leerzeichen an die Ausgabe angefügt.
+
+putline (F)
+ PROC putline (FILE VAR file, TEXT CONST record)
+ Zweck: Ausgabe eines TEXTes 'record' in die Datei 'file'. 'file' muß mit
+ 'output' assoziiert sein.
+ Fehlerfälle:
+ * file not open
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+ * output access to input file
+ Es wurde versucht, auf einen mit 'input' assoziierten FILE zu
+ schreiben.
+
+read record (F)
+ PROC read record (FILE CONST file, TEXT VAR record)
+ Zweck: Liest den aktuellen Satz der Datei 'file' in den TEXT 'record'.
+ Die Position wird dabei nicht verändert. Die Datei 'file' muß mit
+ der Verarbeitungsart 'modify' assoziiert worden sein.
+
+reinsert (F)
+ PROC reinsert (FILE VAR f)
+ Zweck: Einfügen von "vorsichtig gelöschten" Zeilen (vergl. 'remove') an
+ der aktuellen Position.
+
+release
+ PROC release (TASK CONST task)
+ Zweck: Aufgabe der Reservierung des Archivs. Ein implizites 'release'
+ wird automatisch fünf Minuten nach der letzten Archiv-Operation
+ gegeben, sofern ein 'archive' eines anderen Nutzers vorliegt.
+ Beispiel:
+
+ release (archive)
+
+rename (F)
+ PROC rename (TEXT CONST oldname, newname)
+ Zweck: Umbenennen einer Datei von 'oldname' in 'newname'.
+
+remainder
+ THESAURUS PROC remainder
+ Zweck: Liefert nach der Unterbrechung einer Thesaurus-Operation den
+ "Rest"-Thesaurus.
+
+reorganize (F)
+ PROC reorganize (TEXT CONST filename)
+ Zweck: Reorganisiert eine Datei. Die durch eventuelles Einfügen und
+ Löschen entstandene Lücken werden eliminiert und die Anordung der
+ Sätze der Datei wird linearisiert.
+
+reset (F)
+ PROC reset (FILE VAR file)
+ Zweck: Positionieren in einem FILE auf den Anfang (bei mit 'input' asso-
+ ziierten FILEs) oder auf das Ende (bei mit 'output' assoziierten
+ FILEs).
+
+reset range (F)
+ PROC reset range (FILE VAR file)
+ Zweck: Setzt alle Einschränkungen auf 'file' zurück. Siehe auch 'set
+ range'.
+
+remove (F)
+ PROC remove (FILE VAR f, INT CONST anzahl)
+ Zweck: Löscht eine 'anzahl' von Zeilen "vorsichtig" aus der Datei 'f',
+ die mit 'reinsert' an anderer Stelle wieder eingesetzt werden
+ können.
+
+save
+ PROC save (TEXT CONST datei)
+ Zweck: Datei 'datei' wird an die unmittelbare Vater-Task übertragen.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Eine Datei mit dem Namen 'datei' existiert nicht in der Benutzer-
+ Task.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien in 'task' ist überschritten.
+ * wrong password
+ Es wurde mit der Prozedur 'enter password' nicht das richtige
+ Paßwort angegeben.
+
+ PROC save (TEXT CONST name, TASK CONST task)
+ Zweck: Datei mit dem Namen 'name' in Task 'task' kopieren. Beispiel:
+
+ save ("meine datei", father)
+
+ Fehlerfälle:
+ * ... gibt es nicht
+ Eine Datei mit dem Namen 'name' existiert nicht in der Benutzer-
+ Task.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien in der angegebenen task ist
+ überschritten.
+ * wrong password
+ Es wurde mit der Prozedur 'enter password' nicht das richtige
+ Paßwort angegeben.
+
+ PROC save (THESAURUS CONST thesaurus)
+ Zweck: Kopiert die Dateien, die in 'thesaurus' enthalten sind, in die
+ Vater-Task. Beispiel:
+
+ save (SOME myself)
+
+ PROC save (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: Kopiert die Dateien, die in 'thesaurus' enthalten sind, in Task
+ 'manager'.
+
+segments (F)
+ INT PROC segments (FILE CONST f)
+ Zweck: Liefert die Anzahl der Datei-Segmente von 'f'. Nach 'reorganize'
+ besteht 'f' aus einem Segment. Einfügungen oder Löschungen
+ erhöhen die Segmentanzahl.
+
+sequential file (F)
+ FILE PROC sequential file (TRANSPUTDIRECTION CONST mode, DATASPACE VAR ds)
+ Zweck: Assoziierung einer sequentiellen Datei mit dem Dataspace 'ds' und
+ der Betriebsrichtung 'TRANSPUTDIRECTION' (vergl. 'modify', 'input'
+ bzw. 'output'). Diese Prozedur dient zur Assoziierung eines tempo-
+ rä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.
+
+ FILE PROC sequential file (TRANSPUTDIRECTION CONST mode, TEXT CONST name)
+ Zweck: Assoziierung einer sequentiellen Datei mit dem Namen 'name' und
+ der Betriebsrichtung 'TRANSPUTDIRECTION' (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 dagegen der FILE noch nicht und ist
+ die TRANSPUTDIRECTION 'output', wird ein neuer FILE eingerichtet.
+ Fehlerfall:
+ * input file not existing
+ Es wurde versucht, einen nicht vorhandenen FILE mit 'input' zu
+ assoziieren.
+
+set range (F)
+ PROC set range (FILE VAR f, INT CONST anz, INT CONST column, FRANGE VAR b)
+ Zweck: Schränkt die Datei 'f' auf 'anz' Zeilen beginnend bei der Position
+ 'column' der aktuellen Zeile. Der "alte" Datei-Bereich wird in 'b'
+ gespeichert.
+
+ PROC set range (FILE VAR f, FRANGE VAR b)
+ Zweck: Setzt die Datei 'f' auf die in 'b' gespeicherten Bereich zurück.
+
+son
+ TASK PROC son (TASK CONST task)
+ Zweck: Liefert den internen Task-Bezeichner der Sohn-Task. Beispiel:
+
+ put (name (son (myself)))
+
+SOME
+ THESAURUS OP SOME (THESAURUS CONST thesaurus)
+ Zweck: Bietet den angegebenen 'thesaurus' zum Editieren an. Dabei können
+ nicht erwünschte Namen gestrichen werden.
+
+ THESAURUS OP SOME (TASK CONST task)
+ Zweck: Bietet einen THESAURUS von 'task' zum Editieren an.
+
+ THESAURUS OP SOME (TEXT CONST file name)
+ Zweck: Bietet einen 'thesaurus', der aus 'file name' gebildet wird, zum
+ editieren an.
+
+to line (F)
+ PROC to line (FILE VAR f, INT CONST number)
+ Zweck: Positionierung auf die Zeile 'number'. Nur erlaubt in der
+ Betriebsrichtung 'modify'.
+
+task
+ TASK PROC task (TEXT CONST task name)
+ Zweck: Liefert den internen Task-Bezeichner von 'task name'. Beispiel:
+
+ save ("datei", task ("PUBLIC"))
+
+ (* das gleiche wie: *)
+
+ save ("datei", public)
+
+type (F)
+ INT PROC type (DATASPACE CONST ds)
+ Zweck: Liefert den frei wählbaren (INT-) Schlüssel des Datenraums 'ds'.
+ Wurde der Datenraum noch nie angekoppelt, so liefert die Prozedur
+ 'type' einen Wert < 0, erfolgte eine Ankopplung und hat ein
+ Programmierer für den Datenraum 'ds' noch keinen anderen Schlüssel
+ festgelegt, so liefert 'type' den Wert '0'.
+
+ PROC type (DATASPACE CONST ds, INT CONST type)
+ Zweck: Setzt den frei wählbaren Schlüssel 'type' für den Datenraum 'ds'
+ (vergl. obige Prozedur 'type').
+
+up (F)
+ PROC up (FILE VAR f)
+ Zweck: Positionieren um eine Zeile rückwärts in der Datei 'f'.
+
+ PROC up (FILE VAR f, INT CONST number)
+ Zweck: Positionieren um 'number' Zeilen rückwärts in der Datei 'f'.
+
+ PROC up (FILE VAR f, TEXT CONST pattern)
+ Zweck: Suche nach 'pattern' rückwärts in der Datei 'f'. Wird 'pattern'
+ gefunden, ist die Position das erste Zeichen von 'pattern'.
+ Andernfalls steht man auf dem ersten Zeichen der Datei. Achtung:
+ 'down' sucht vom nächsten Zeichen links ab, so daß wiederholtes
+ Suchen keine Endlosschleife ergibt.
+
+ PROC up (FILE VAR f, TEXT CONST pattern, INT CONST number)
+ Zweck: Wie obiges 'up', aber maximal nur 'number'-Zeilen weit.
+
+uppety (F)
+ PROC uppety (FILE VAR f, TEXT CONST pattern)
+ Zweck: Suche nach 'pattern' rückwärts in der Datei 'f'. Wird 'pattern'
+ gefunden, ist die Position das erste Zeichen von 'pattern'.
+ Andernfalls steht man auf dem ersten Zeichen der Datei. Achtung:
+ 'uppety' sucht (im Gegensatz zu 'up') vom aktuellen Zeichen.
+
+ PROC uppety (FILE VAR f, TEXT CONST pattern, INT CONST number)
+ Zweck: Wie obiges 'uppety', aber maximal nur 'number'-Zeilen weit.
+
+word (F)
+ TEXT PROC word (FILE CONST f)
+ Zweck: Liefert das aktuelle Wort (bis zum nächsten Leerzeichen oder
+ Zeilenende).
+
+ TEXT PROC word (FILE CONST f, TEXT CONST sep)
+ Zweck: Liefert einen Text von der aktuellen Position bis zum nächsten
+ 'sep-Zeichen oder Zeilenende.
+
+ TEXT CONST word (FILE CONST f, INT CONST len)
+ Zweck: Liefert einen Text von der aktuellen Position mit der Länge 'len'
+ bzw. bis zum Zeilenende.
+
+write (F)
+ PROC write (FILE VAR f, TEXT CONST text)
+ Zweck: Schreibt 'text' in die Datei 'f' (analog 'put (f, text)'), aber
+ ohne Trennblank.
+
+write record (F)
+ PROC write record (FILE VAR file, TEXT CONST record)
+ Zweck: 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. Die Datei 'file' muß mit der Verar-
+ beitungsart 'modify' assoziiert worden sein.
+
+