Gerade bei Studenten erfreuen sich die Computer der ATARI ST-Serie allergrösster Beliebtheit. Um Programmieraufgaben zu lösen, greifen die Studenten meist auf die im Studium erlernte Pascal-Sprache zurück. Für den ATARI ST gibt es ja dankenswerterweise eine tolle PASCAL-Implementation der Firma CCD, allseits als ST PASCAL+ bekannt. Mit ihr kann (wenn der Programmierer das nötige Know-How besitzt) auf relativ einfache Art ein voll GEM-unterstütztes Programm erstellt werden.
Leider hört das saubere Programmieren meist bei der Pfadhandhabung auf. Wie oft habe ich schon erlebt, daß ein Programm auf Festplatte nicht installierbar war. weil absolute Pfade im Programm vorgegeben waren. Oft muß man sich auch aus oberster Directory-Ebene in den Ordner des geladenen Programms durchklicken, um an die dort abgelegten Dateien zu kommen. manchmal sogar jedesmal nach Aufruf der Fileselectorbox. Um nun jedem Programmierer das Erstellen von sauberen GEM-Programmen zu erleichtern, habe ich einige Routinen entworfen, die schon oft ihren Einsatz in Simulations- und Rechenprogrammen gefunden haben. Sie sind verwendbar für jede Art von Programm, sei es ein Zeichenprogramm oder eine Dateiverwaltung.
Im einzelnen werden folgende Aufgaben vereinfacht:
Jeder Pascal-Anwender sollte jetzt schnellstens das Listing eintippen und der Dinge harren. die da passieren (zum Testen der neuen Funktionen wurde ein kurzes Demo-Programm hinzugefügt). Nach Starten des Programms wird zuerst der aktuelle Pfad bei Programmstart ermittelt und auf dem Bildschirm ausgegeben. Hiernach erscheint eine Dialogbox. in der der werte Leser eine Datei (unter einem beliebigen Pfad) auswählen sollte, um das Können des Programms auf die Probe zu stellen. Hat nun der User (aus Versehen natürlich) nicht dummerweise auf den Abbruch-Button geklickt, erscheint jetzt der komplette Pfad mit der ausgewählten Datei auf dem Bildschirm. Weiterhin wird der Dateiname mit Pfad ohne Suffix sow ie nur der Dateiname ohne Suffix und der Suffix selbst ausgegeben.
Jeder Programmierer, der etwas Mitleid mit uns armen Festplattenbesitzern hat. sollte nun immer diese Routinen zur Dateiauswahl in seine Programme einbinden (der Klick-Finger meiner rechten Hand wird es danken).
In der Funktion exist_file wird nachgeschaut, ob der angegebene Pfad mit angehängtem Dateinamen existiert. Ist er vorhanden, wird ein TRUE zurückgeliefert. ansonsten ein FALSE. Zum Nachschauen wird die Funktion fsfirst des GEMDOS benutzt. Sie sucht auf dem Datenträger nach dem ersten Auftauchen einer Datei, welche die angegebenen Bedingungen (bei uns der vollständige Dateipfad mit zugehörigem Dateinamen) erfüllt. Wird anstatt des kompletten Pfades mit Dateinamen nur ein Pattern (z.B.: A:*.*) vorgegeben. wird die erste Datei, die das Muster erfüllt, gesucht. Deshalb findet diese Routine auch hauptsächlich zum Einlesen des Directories Verwendung.
Als zweites soll die Prozedur get_akt_path genannt werden. die den aktuellen Pfad ermittelt. Dies geschieht mit der GEMDOS-Routine getdir. Leider beinhaltet dieser Pfad nicht die Kennzeichnung des aktuellen Laufwerks. Oft verzichten die Programmierer auf das Einfügen des Laufwerksnamens, was man in der Fileselectorbox erkennen kann. Dort beginnt das Pfadmuster (mit INDEX bezeichnet) direkt mit einem Backslash (z.B.: \DEMO*.*). Dies ist nicht anwenderfreundlich, da der Benutzer insbesondere bei Festplattenbenutzung so nicht weiß, auf welcher Partition er jetzt Unheil anrichtet (sprich Dateioperationen ausführt). Deshalb muß der Laufwerksnamen noch mit der Routine dgetdrv ermittelt und dem Pfad vorangestellt werden.
Die dritte wichtige Routine ist die set_path-Funktion. Sie ruft die Routine get_new_path_and_filename auf und dient nur zur Kommunikation mit dem Benutzer. Es wird die Fileselectorbox auf dem Bildschirm dargestellt und vom Betriebssystem verwaltet. Nach Anklicken von OK werden die Einstellungen der Box übernommen und zum aufrufenden Programm zurückgekehrt. Bei Anklicken von Abbruch erfolgt die Rückkehr ohne Übernahme der aktuellen Einstellungen. Anklicken von OK liefert TRUE. Anklicken von Abbruch FALSE zurück.
Als letztes soll die Routine cut_suffix besprochen werden. Sie dient zum Entfernen des Suffixes eines Dateipfades. Dies ist besonders nützlich, wenn ein fester Suffix vom Programm vorgegeben werden soll (z.B. bei DEGAS je nach Auflösung z.B. .PI3) und dieser vom Anwender nicht geändert werden darf, da die betreffende Datei sonst vom Programm nicht mehr wiedergefunden werden kann. Ein weiterer Einsatzzweck ist gegeben. wenn nach Eingabe eines Dateinamens mehrere Dateien mit verschiedenem Suffix abgelegt werden müssen (z.B. die verschiedenen Dateien, die beim Anlegen einer Datenbank mit ADIMENS geschrieben werden müssen). Übergeben werden muß der Pfad (mit Dateinamen). und zurückgeliefert werden der Pfad mit Dateinamen. aber ohne Suffix, nur der Dateinamen (also ohne Pfad und ohne Suffix) und extra der Suffix. Da auch der übergebene Pfad mit Dateinamen von der Routine verändert wird (Suffix wird entfernt), sollte der Aufruf nur mit einer Kopie der verwendeten Pfad-Variablen geschehen.
{=================================================
Routinen für das Dateihandling mit ST Pascal+
auf ATARI ST von Matthias Baldauf
(c) MAXON Computer GmbH 1990
vom 15.10.1989
=================================================}
program DATEIHANDLING;
{--- Konstantendefinition ---}
const
{$I o:TRIXCONS.PAS}
{$I o:GEMCONST.PAS}
{--- Typ-Vereinbarungen ---}
type
{$I o:TRIXTYPE.PAS}
{$I o:GEMTYPE.PAS}
DatNameType = string[150];
{--- Variablendeklarationen ---}
var
dummy:boolean;
dateipfad,dateiname,suffix,name:DatNameType;
a:char;
{--- Prozedurteil ---}
{$I o:TRIXSUBS.PAS}
{$1 o:GEMSUBS.PAS}
{------------------------------------------------
Nachschauen, ob Datei mit Pfad vorhanden ist
-----------------------------------------------}
function exist_file(dateiname:DatNameType): boolean;
var handle:integer;
cstr:Cstring;
function fsfirst(var dateiname:Cstring;attr:integer):integer;
gemdos($4e);
begin
PtoCstr(dateiname,cstr);
handle := fsfirst(cstr,0);
if handle < 0 then
exist_file := false
else
exist_file := true;
end;
{------------------------------------------------
Pfad beim Starten des Programms ermitteln
------------------------------------------------}
procedure get_akt_path(var path:DatNameType);
var path_char:Cstring;
dummy:integer;
function getdir(var path:Cstring;
drv:integer):integer;
gemdos($47);
function dgetdrv:integer;
gemdos($19);
begin
dummy := getdir(path_char,0);
if dummy = 0 then
begin
CtoPstr(path_char,path);
path := concat(chr(dgetdrv+65),':',path);
end
else { Fehler ! }
;
end;
{------------------------------------------------
Neuen Pfad/Dateinamen vom Benutzer holen
-----------------------------------------------}
function get_new_path_and_filename(var pfad, dateiname:DatNameType):boolean;
var path,name:DatNameType;
ergebnis:boolean;
begin
path := copy(pfad,1,length(pfad));
name := copy(dateiname,1,length(dateiname));
ergebnis := Get_in_file(path,name);
if ergebnis then
begin
pfad : = copy(path,1,length(path));
dateiname := copy(name,1,length(name));
end;
get_new_path_and_filename := ergebnis;
end;
{------------------------------------------------
Neuen Pfad holen (Dialog)
-------------------------
Hier können eigene Anpassungen vorgenommen
werden (z.B.: Maus-Zeiger wieder
sichtbar machen, Hintergrund restaurieren etc.)
-----------------------------------------------}
function set_path(var path,dateiname:DatNameType):boolean;
var dummy_bool:boolean;
begin
dummy_bool := get_new_path_and_filename(path,dateiname);
set_path := dummy_bool;
end;
{------------------------------------------------
Routinen zum entfernen der Suffix eines Namens
-----------------------------------------------}
procedure revers_str(var name:DatNameType);
var i,len:integer;
puffer:DatNameType;
begin
len := length(name);
puffer := '';
for i := len downto 1 do
puffer := concat(puffer,name[i]);
name := puffer;
end;
procedure cut_suffix(var dateiname,name,suffix:DatNameType);
var i:integer;
begin
revers_str(dateiname);
if pos('\',dateiname) <> 0 then
begin
name := copy(dateiname,1,pos('\', dateiname)-1);
delete(dateiname,1,length(name));
revers_str(dateiname);
if pos('.',name) <> 0 then
begin
suffix := copy(name,1,pos('.',name)-1);
revers_str(suffix);
end
else
suffix := '';
revers_str(name);
if pos('.',name) <> 0 then
name := copy(name,1,pos('.',name)-1);
dateiname := concat(dateiname,name);
end
else
begin
revers_str(dateiname);
if pos('.',dateiname) <> 0 then
name := copy(name,1,pos('.',name)-1);
if pos('.',dateiname) <> 0 then
begin
suffix := copy(dateiname,1,pos('.', dateiname)-1);
revers_str(suffix);
end
else
suffix := '';
end;
end;
{ ------------------------ Suffix Routinen Ende --}
{==================================================
Hauptprogramm (DEMO)
==================================================}
begin
if Init_Gem >= 0 then
begin
Clear_Home;
get_akt_path(dateipfad); {aktuellen Pfad ermitteln}
writeln('Pfad bei Programmstart: ',dateipfad);
writeln;
writeln('Bitte irgendeine Datei auswählen:');
dateiname := concat(dateipfad,'\DEMO'); { Dateinamen 'basteln' }
dateipfad := concat(dateipfad,'\*.*''); { das 'Auswahlpattern' hinzufügen }
dummy := set_path(dateipfad,dateiname); { File-Selector-Box aufrufen }
if dummy then
begin
Clear_Home;
writeln('Ausgewählte Datei: ',dateiname);
dummy := exist_file(dateiname);
if dummy then
writeln('+++ Datei existiert +++')
else
writeln('--- Datei nicht vorhanden —--');
cut_suffix(dateiname,name,suffix);
writeln('Dateiname und Pfad ohne Suffix: ', dateiname);
writeln('Dateiname ohne Pfad und ohne Suffix: ',name);
writeln('Suffix: ',suffix);
writeln;
writeln('--- Taste ---');
read(a);
end
else
begin
Clear_Home;
writeln('Sie haben auf ABBRUCH geklickt !!!');
writeln;
writeln('--- Taste ---');
read(a);
end;
Exit_Gam;
end;
end.
{------------------------------- PROGRAMMENDE ---}