Was ist M2POSIX ? ================= Diese Modulsammlung soll einige der POSIX-Systemaufrufe (die bisher nur fr ``C'' definiert sind) auch unter Modula-2 verfgbar machen. Insbesondere unter GEMDOS werden ja manche Dinge v”llig unterschiedlich zu *IX-Systemen, und damit auch POSIX, gehandhabt. Ich denke da nur an das Suchen von Dateien: Unter GEMDOS werden dazu die Betriebssystemaufrufe "Fsfirst()" und "Fsnext()" benutzt, unter POSIX wird ein Verzeichnis mit "opendir()" ge”ffnet, jeweils der Name der n„chsten im Verzeichnis enthaltenen Datei mit "readdir()" ermittelt, mit "fnmatch()" wird berprft, ob der Name mit der oder den gesuchten bereinstimmt (dabei k”nnen die ``Wildcards'' *, ? und [...] benutzt werden) und schliežlich werden mit "stat()" alle weiteren Informationen ber die Datei eingeholt (unter GEMDOS stehen die vorhandenen Informationen in der DTA). Ein Beispiel fr die Ermittlung von Dateien nach diesem Muster ist in LISTDIR.MPP enthalten, das ein sehr vereinfachtes ``ls'' darstellt. Als Grundlage dieser Modulsammlung diente die ``C''-Bibliothek MiNTLib von Eric R. Smith, dem Autor von MiNT. Diese Bibliothek macht die speziellen Eigenschaften von MiNT, dem GEMDOS-Multitasking-Ersatz bzw. der MultiTOS-Grundlage, auch innerhalb der (*IX)-Standardbibliothek fr ``C''-Compiler, speziell dem GNU-C-Compiler, zug„nglich. Abgesehen vom reinen šbertragen ``C'' --> Modula sind einige Funktionen gleichgeblieben, aber bei den meisten habe ich erweitert, verkrzt, ver„ndert, Fehler beseitigt, Fehler hinzugefgt oder sonst irgendwas. Ich habe auch versucht die Funktionen etwas mehr den POSIX-Funktionen anzugleichen. Bei der Modulaufteilung und der Namensgebung war ich manchmal etwas ratlos, aber zumindest die Funktionsnamen sind, bis auf einen ("Exit()" statt "_exit()"), gleichgeblieben. Zeitweise war fr die Moduleinteilung auch ein einzelnes Modul im Gespr„ch, z.B. 'SYS' oder 'POSIX', aber das w„re wohl ein ziemliches Monster an Umfang geworden; auch die Struktur der POSIX-C-Header zu bernehmen schien mir nicht so geeignet, da hier die Verteilung der Funktionen schlecht geregelt w„re (in 'UNISTD' st„nde dann fast alles und in den anderen Modulen, wie 'STAT', 'DIRENT' u.„. jeweils nur ein paar wenige Funktionen). Die Funktionen machen, soweit m”glich, von MiNT Gebrauch, falls dieses geladen ist. Ich empfehle, mindestens die Version 0.95 einzusetzen! Es gibt zwar einige Abfragen auf die Version im Quelltext, aber im Laufe der MiNT-Entwicklung haben sich ”fters Datenstrukturen und Funktionen ge„ndert, und die Bercksichtigung aller Unterschiede, falls berhaupt sinnvoll, w„re sicher ziemlich aufwendig. Mit der Version 0.95 scheinen die vorhandenen Dinge aber ziemlich stabil zu sein. Es ist aber auch m”glich, den Quellcode so zu bersetzen, daž die MiNT-spezifischen Teile ausgelassen werden, was die Objektdateien etwas kleiner werden l„žt; empfehlen wrde ich das allerdings nicht. Die Entscheidung ber die Verwendung von MiNT-Funktionen wird in der Header-Datei PORTAB.M2H getroffen, in der das Makro MINT entsprechend eingestellt werden kann. Moment -- Makro? Ganz recht, diese Module bestehen nicht aus reinem Modula-Quellcode, sondern enthalten noch Kommandos eines ``C''-Pr„prozessors, der die šbersetzbarkeit der Module unter verschiedenen Compilern erleichtern soll. N„here Informationen zum Pr„prozessor geben die folgenden Abschnitte. Fr wen ist M2POSIX geeignet ? ============================== Diese Modulsammlung ist nichts fr Anf„nger! Wer sich mit den Modulen befassen will, sollte schon mit einem Kommandointerpreter umgehen k”nnen, und wissen wie ein Pr„prozessor zu benutzen ist. Weiterhin sollte man bereit sein, sich auf ein bižchen Experimentieren einzulassen. Wer Žnderungen vornehmen will, muž vor allem aufmerksam die Implementationsmodule und die Header-Dateien durchsehen. Also nochmal: DIESE MODULE SIND NUR ETWAS FšR LEUTE, DIE BEREIT SIND, SICH MEHR ODER WENIGER INTENSIV DAMIT AUSEINANDERZUSETZEN!!! An zus„tzlichen Programmen, neben einem M2-Compiler, werden ben”tigt: o Ein Kommandointerpreter, vorzugsweise GULŽM.PRG. o Ein ``C''-Pr„prozessor, vorzugsweise GCC-CPP.TTP bzw. CPP.TTP (GNU-C-Pr„prozessor). Diese Programme findet man bestimmt auf jedem FTP-Server. Der Pr„prozessor drfte meistens zusammen mit dem GNU-C-Compiler in einem gemeinsamen Archiv zu finden sein. Aužerdem gibt es beide Programme auch noch auf (teuren) PD-Disketten. Ich selbst besitze nur den PD-Compiler LPR-Modula, mit dem ich die Module auch entwickelt habe; die šbersetzbarkeit/Lauff„higkeit mit den kommerziellen Systemen von Megamax, H„nisch und TDI konnte ich nur ber den Umweg von Demoversionen bzw. anderen Leuten testen (Dank an Ulrich Kaiser), deshalb mag die Funktionsf„higkeit mit diesen Systemen nicht 100-prozentig sein. Die Demoversion des SPC-Compilers l„žt leider kein vernnftiges Testen zu; da mir der SPC-Compiler aber zu 99% kompatibel zum LPR-Compiler erscheint, drfte es mit SPC keine (gr”žeren) Schwierigkeiten geben. Bedingungen, unter denen M2POSIX verwendet werden darf ====================================================== Die Verwendung von M2POSIX unterliegt keiner Einschr„nkung, aužer daž bei der Weitergabe alle Dateien unver„ndert enthalten sein mssen. Natrlich drfen fr die Weitergabe auch keine Gebhren zus„tzlich zu Diskettenkosten, Kopierkosten o.„. verlangt werden! Ich bernehme keinerlei Verantwortung fr die Korrektheit und Verwendbarkeit der Funktionen. Wer M2POSIX benutzt, ist selber fr alle evtl. Folgen verantwortlich. Warum ein Pr„prozessor ? ======================== Leider verstehen nicht alle Modula-Compiler einen gemeinsamen ``Dialekt''. Sicher -- die Sprache ist in einer Sprachbeschreibung definiert worden, aber zum einen gibt es mehrere Versionen dieser Beschreibung (PIM1..PIM4), zum anderen ist lediglich die Syntax formal definiert (BNF), die Semantik aber in Form natrlichsprachlicher Texte, sodaž einige Dinge nicht eindeutig festgelegt sind (werden k”nnen). Aužerdem haben die Compiler-Hersteller auch eigene Restriktionen und/oder Erweiterungen hinzugefgt. Diese Situation wird sich erst „ndern, wenn sich die Hersteller an die ISO-Norm fr Modula-2 halten, hier wird n„mlich auch die Semantik bis ins kleinste formal definiert. Die Unterschiede bestehen vor allem in folgenden Bereichen: o standardm„žige Gr”žen von INTEGER und CARDINAL (16 oder 32 Bit) o Typtransfer: das Žndern des Typs eines Ausdrucks, ohne daž dafr Code generiert wird; d.h. das betreffende Bitmuster wird nur anders interpretiert, bzw. die Typprfung des Compilers umdirigiert. o Typkonvertierung: das Žndern des Typs eines Ausdrucks, wobei evtl. Code generiert wird, z.B. bei der Wandlung zwischen SHORT- und LONG-Typen. o Adressarithmetik o Setzen und Lesen von Prozessorregistern. o Kennzeichnung von LONG-Konstanten Um diese Unterschiede m”glichst aus dem Weg zu r„umen, werden die Module mit Pr„prozessormakros versehen, die z.T. von der Syntax her wie ISO-M2-Code aussehen (z.B. CAST, VAL, ADDADR, SUBADR, DIFADR, INT usw.). In der Datei PORTAB.M2H, die die Definitionen enth„lt, werden die Makros dann auf die compilerspezifischen Konstruktionen abgebildet. Eine weitere Datei mit Makros ist OSCALLS.M2H; sie enth„lt die Definitionen fr die Aufrufe der Betriebssystemfunktionen. Durch das Konzept der Makros k”nnen die Module also einheitlich fr unterschiedliche Compiler programmiert werden; die Unterschiede werden dann erst beim Bearbeiten mit dem Pr„prozessor bercksichtigt, das am besten als erster Pass des šbersetzungsvorganges betrachtet wird. (Bei ``C''-Compilern ist dieses Vorgehen ja bereits integriert, es hindert einen aber niemand daran, dies auch fr andere Sprachen, wie Modula-2, zu benutzen.) Um Module mit und ohne Makros leicht auseinanderhalten zu k”nnen, verwende ich folgende Extensionen fr M2-Dateien mit Pr„prozessorkommandos: .DPP fr Definitionsmodule, .IPP fr Implementationsmodule und .MPP fr Programmodule Diese Kennzeichnung ist natrlich nur ein Vorschlag. Die Benutzung eines ``C''-Pr„prozessors hat natrlich(?) auch Nachteile: o Die Modula-Kommentarklammern sind keine ``C''-Kommentarklammern -- deshalb werden Zeichenketten, die mit definierten Makros bereinstimmen, auch innerhalb von Modula-Kommentaren durch den Pr„prozessor ersetzt. Als Behelf kann man die entsprechenden Schlsselworte innerhalb der Modula-Kommentare in doppelte Anfhrungszeichen (") setzen, da der Pr„prozessor, zumindest der GNU-C-Pr„prozessor, keine Makros in C-Strings ersetzt. o Der Backslash '\' hat fr den Pr„prozessor eine Spezialbedeutung; je nach dem (oder den) nachfolgenden Zeichen wird fr die Kombination der Zeichen nachher durch den Compiler ein Spezial (meistens Control)-Zeichen eingesetzt. Obwohl nicht der Pr„prozessor fr die Ersetzung verantwortlich ist, meldet er jedoch einen Fehler (-> "unterminated string constant"), wenn hinter dem Backslash in einer Zeichen- oder Stringkonstante kein Zeichen mehr folgt. (Das gilt zumindest fr den GNU-C-Pr„prozessor.) Pr„prozessieren der Module ========================== Im folgenden wird davon ausgegangen, daž ``Gul„m'' als CLI zusammen mit den vorgefertigten Batch-Dateien benutzt, und als Pr„prozessor der GNU-C-Pr„prozessor verwendet wird. Wer einen anderen CLI (z.B. Mupfel) benutzt, oder gar einen anderen Pr„prozessor, muž entsprechende Žnderungen vornehmen. Der Aufbau der Batch-Dateien ist als Kommentar in den Dateien selbst enthalten, es sollte also keine gr”žeren Schwierigkeiten geben, diese an andere Gegebenheiten anzupassen. Beim Pr„prozessieren wird am besten folgende Reihenfolge eingehalten: 1) Erstellen einer Datei X.G, die die Batch-Datei X_M2.G mit den n”tigen Parametern aufruft, d.h. Name des Compilers, Zielverzeichnis, Endungen von Definitions- und Implementationsmodulen. Meine Datei fr LPR-Modula sieht so aus: Name: XLPR.G Inhalt: x_m2 LPRM2 m: def mod Die pr„prozessierten Module landen bei mir auf der RAM-Disk M:\. Eine „hnliche Datei muž auch fr das Pr„prozessieren der Testmodule erstellt werden, wobei hier nur die Endung fr Programmodule ben”tigt wird: Name: TLPR.G Inhalt: t_m2 LPRM2 m: mod 2) Eintragen des vollst„ndigen Pfades der Datei PORTAB.M2H in die Batch-Datei M2PPX.G. Die Datei kann in einem beliebigen Verzeichnis stehen, da nur an dieser einen Stelle auf sie zugegriffen wird. Sinnvoll ist es jedoch, sie in dem Verzeichnis unterzubringen, wo auch die anderen Header-Dateien stehen, falls solche existieren (z.B. vom ``C''-Compiler). 3) Die Batch-Dateien (bei mir M2PPX.G, X_M2.G, XLPR.G, T_M2.G und TLPR.G), der Pr„prozessor CPP.TTP bzw. GCC-CPP.TTP und das kleine Programm X2D1.TOS werden in ein Verzeichnis kopiert, wo Gul„m sie als ausfhrbare Dateien finden kann; das Verzeichnis muž also in der Environmentvariablen PATH erw„hnt sein. Bei mir steht deshalb in GULAM.G folgende Definition (die Punkte sollen weitere Pfade andeuten): set path '.,f:\usr\bin,f:\bin,...' , wobei die Batch-Dateien und X2D1.TOS im ersten Verzeichnis stehen und der Pr„prozessor im zweiten. Bemerkung: Nach einem 'set path' wird bei Gul„m automatisch die Environmentvariable PATH gesetzt. 4) Alle Dateien mit den Endungen .DPP, .IPP und .MPP und die Datei OSCALLS.M2H in ein Verzeichnis kopieren. OSCALLS.M2H kann alternativ ebenfalls in das Verzeichnis kopiert werden, wo die anderen Header-Dateien stehen, dann muž jedoch der Pr„prozessor wissen, wo er zu suchen hat; in meinem GULAM.G steht deswegen folgende Zeile: setenv GNUINC f:\usr\include\m2,f:\usr\include Im ersten Verzeichnis stehen dabei alle Modula-2-Header, im zweiten die ``C''-Header. 5) Gul„m starten und in das Verzeichnis mit den M2-Dateien wechseln. 6) Einfach die in Punkt 1) erstellten Batch-Dateien aufrufen, z.B. mit: XLPR und wenn kein Fehler aufgetreten ist: TLPR Dann sollten im Zielverzeichnis die Module in reinem M2-Quellcode stehen. Die Module k”nnen dann mit dem Modula-Compiler bersetzt werden. Da die Module teilweise voneinander abh„ngig sind, muž beim šbersetzen natrlich eine bestimmte Reihenfolge eingehalten werden, hierfr kann aber einfach die gleiche Reihenfolge benutzt werden, wie sie in der Batch-Datei X_M2.G fr das Pr„prozessieren verwendet wurde. Anpassung an andere Compiler ============================ Gleich vorneweg: Folgende Compiler werden nicht bercksichtigt: o ana-systems m2 (ANAM2): ein Shareware-Compiler, der sich an PIM2 orientiert; der Hauptnachteil ist aber, daž er keine arithmetischen 16-Bit-Typen kennt. o Modular Systems (MSM2): orientiert sich auch irgendwo zwischen PIM2 und PIM3, hat aber viel zu viele Eigenheiten. o FTL-Modula: hat einige Compilerfehler, die einem das Leben schwer, wenn nicht gar unm”glich machen, zumindest in der Version 1.18. Ich behaupte nicht, daž diese Compiler schlecht w„ren, es ist mir aber zu viel Arbeit, auf die Eigenheiten dieser Systeme Rcksicht zu nehmen. Momentan werden nur die Compiler LPR (PD-Compiler der TU-Mnchen), Megamax, H„nisch und TDI (kommerzielle Compiler) untersttzt; da der SPC-Compiler (nur der Compiler, nicht etwa das ganze System) aber fast identisch zu LPR ist, drfte auch dieser geeignet sein (Žhnliches drfte auch fr andere Compiler gelten, die vom Original-ETH-Compiler abstammen). Wer die Module an sein System anpassen will, muž auf jeden Fall die Header-Datei PORTAB.M2H anpassen, wahrscheinlich auch OSCALLS.M2H, da dort die Betriebssystemaufrufe definiert werden. Aužerdem muž im Modul 'cmdline' die systemspezifische Prozedur zur Ermittlung der 'Basepage' verwendet werden, vielleicht ist die 'Basepage' auch als Variable in irgendeinem Systemmodul deklariert. Im Modul 'lib' sind einige Assemblerprozeduren; die Routinen selber sind allgemein gehalten, sodaž hier keine Anpassung n”tig sein drfte, evtl. mssen aber andere Register gerettet werden, dazu steht aber ein Kommentar im Quelltext. Es kann auch sein, daž im Quellcode spezielle Abfragen auf das System n”tig werden, z.B in der Form: ... #if M2 ... #else ... #endif ... Es sollte jedoch versucht werden, s„mtliche Compiler-Abh„ngigkeiten in die Header-Dateien zu verlegen -- soweit m”glich. Am besten ist es, mal die Testmodule (mit der Endung .MPP) zu bersetzen, und sowohl unter GEMDOS als auch unter MiNT laufen zu lassen -- vorausgesetzt natrlich, daž der Compiler dazu berredet werden kann, die Module zu bersetzen. Falls der Compiler fr INTEGER und CARDINAL per Option 16 oder 32 Bit benutzen kann, sollten auch beide Einstellungen ausprobiert werden. šbersetzt man FORKEXEC.MPP und SPAWN.MPP mit dem H„nisch-Compiler, so muž der Speicherhunger der Programme begrenzt werden, da sonst kein weiterer Prozež gestartet werden kann. Anscheinend belegt ein HM2-Programm den gesamten verfgbaren Speicher (fragt sich nur: warum(?) Vielleicht hab' ich auch was falsch gemacht...). In der TC-Shell kann das z.B. mit folgender Anweisung erledigt werden: limit datasize 500 Dieser Befehl begrenzt den Speicherbereich fr das Programm auf 500kB -- man kann natrlich auch andere (kleinere) Werte nehmen. Die ``Test''-Module sind allerdings keine vollst„ndigen Tests, vielmehr werden einfach nur einige der Funktionen mit unterschiedlichen Parametern aufgerufen, und geprft, ob das Erwartete passiert. Z.T. ist auch die šberprfung durch den Benutzer erforderlich, oder es werden einfach nur Systemeinstellungen abgefragt. Fr weitere Informationen ber die Anwendung der Testmodule muž der Quellcode durchgesehen werden. Da bei solchen Anpassungen einiges schief gehen kann, sollte vielleicht eine RAM-Disk benutzt werden, auf der dann Dateien ohne Auswirkungen zerst”rt werden k”nnen... Auf jeden Fall bernehme ich keine Verantwortung fr zerschossene Festplatten oder „hnliches... Eine Anpassung an MSDOS- oder gar *IX-Systeme ben”tigt sicherlich einiges an Arbeit, ich will aber niemanden davon abhalten... Generell: Ich wrde mich freuen, wenn mir jemand, der eine Anpassung vorgenommen hat, eine Kopie zukommen l„žt. Das gilt natrlich auch fr Anregungen, Fehlermeldungen u. „. Meine Adresse lautet: Holger Kleinschmidt Promenadenstr. 11 B W-1000 Berlin 45 Literatur ========= Zlotnick, F., The POSIX.1 Standard: A Programmer's Guide, The Benjamin/Cummings Publishing Company, 1991