Diesen Monat vermeldet das ATARIUM seine 75. Ausgabe. Wieviele es in Zukunft noch werden, hängt in erster Linie von ATARI, aber auch von den Kunden ab. Viele Software-Hersteller beklagen stark zurückgehende Neuverkäufe, und wenn es so weitergeht, muß man wohl auch in Zukunft mit etlichen Abgängen rechnen.
Also der völlig ernstgemeinte Hinweis: wer selbst nie etwas kauft, braucht sich auch nicht zu wundern, wenn es irgendwann nichts Neues mehr gibt, und auch plötzlich keiner mehr da ist, der sich um die ‘alten’ Programme kümmert.
Signale von ATARI fehlen leider. Im Computerbereich gibt es keinerlei Fortentwicklung, und so hat es nur ganz Verträumte überrascht, daß ATARI die CeBIT abgesagt hat. Was sollte schon gezeigt werden, und wie hätte man sich in einer Halle zusammen mit Apple präsentieren können, ohne sich zu blamieren? Stattdessen werden zur Zeit alle Anstrengungen in den Jaguar gesetzt, und das ist auch vernünftig. Die Europapremiere war für Mitte März angesetzt: Sie werden vielleicht jetzt schon wissen, ob es geklappt hat. Im ersten Versandhauskatalog wurde er ja zumindest schon jetzt gesichtet.
Währenddessen engagiert sich der ‘harte’ Kern der ATARI-Branche weiter, und wenn alles klappt, trifft man sich wie letztes Jahr im Mai zur ‘FEZ-A-BIT’ in Berlin.
Kommen wir zurück zum konkreten Programmieralltag. Im letzten Heft hatte ich ja Routinen zur Speicherverwaltung vorgestellt und es kam, wie es kommen mußte: eine der Funktionen machte ganz und gar nicht, was sie tun sollte. Die korrigierte Fassung ist in Listing 1 zu sehen. Entschuldigung!
Als ATARI vor über vier Jahren das ARGV-Verfahren definierte (vgl. [1], [2] und [3]), hatten leider alle daran Beteiligten ein kleines Problem übersehen: die einzelnen Parameter werden nach dem Eintrag ‘ARGV=’ hintereinanderweg in das Environment eingetragen. Da die einzelnen Einträge voneinander durch Nullbytes getrennt sind, konnten nunmehr auch Variablen mit Leerzeichen übergeben werden, und das Längenlimit der Kommandozeile war auch überwunden. Das Ende der Liste wird logischerweise durch zwei aufeinanderfolgende Nullbytes markiert. Problematisch wird es, wenn man tatsächlich mal in die Verlegenheit kommt, leere Parameter übergeben zu müssen: wenn man sie so wie dokumentiert einträgt, wird ein vorzeitiges Ende der Parameterliste erkannt (zwei Leerbytes hintereinander).
Doch kann ein solcher Fall überhaupt auftreten? Gewiß. In Kommandoshells können normalerweise Shell-Variablen benutzt werden und damit natürlich auch beim Aufruf von Programmen auftreten. Vertippt man sich beispielsweise bei dem Variablennamen, wird eine Unix-ähnliche Shell eine leere Zeichenkette anstelle der Variable einsetzen. Auch wenn das gestartete Programm mit dem leeren Parameter nicht viel Sinnvolles anfangen kann, sollte es doch zumindest alle weiteren Parameter an der richtigen Position erhalten.
Natürlich gibt es auch Fälle, in denen man wirklich einen leeren Parameter übergeben will. Ein gutes Beispiel wäre eine Programmoption, mit der man eine Zeichenkette für einen Seitenkopf definieren kann. In solchen Fällen ist es offensichtlich wichtig, auch leere Parameter übermitteln zu können.
Dieses Problem wurde im Herbst ’92 im Internet mit Eric Smith diskutiert, der daraus hervorgegangene Vorschlag zu einer kompatiblen Erweiterung allerdings nie offiziell ‘abgesegnet’.
Da die MiNT-Library das Verfahren nun aber unterstützt, kann man es sicherlich als Quasistandard betrachten.
Das Hauptproblem bei der Suche nach einer Lösung war, daß es nur noch eine einzige Stelle gibt, an der Erweiterungen möglich sind: der ‘Wert’ der Environmentvariable ARGV. Imbisherigen Standard wird diese Frage absichtlich ausgeklammert, weil Programme, die mit der Mark-Williams-C-Library übersetzt sind dort spezielle Informationen erwarten (ARGV ist aus der MW C-Konvention hervorgegangen, insofern ist auch die fehlende Berücksichtigung leerer Argumente Mark Williams anzulasten).
Daraus folgte die wichtige Festlegung: wenn keiner der Parameter leer ist, sollte man genau wie zuvor Vorgehen. Damit ist die volle Kompatibilität für solche Fälle, die vom bisherigen Standard korrekt behandelt wurden, gesichert. Nur dann, wenn leere Parameter auftreten, sollten die Erweiterungen benutzt werden. In einem solchen Fall werden sich alte, inkompatible Programme möglicherweise falsch verhalten - aber das hätten sie ohne die Erweiterung ohnehin getan (siehe oben).
Leere Parameter werden in der Kommandozeile in einfache Anführungsstriche gesetzt. Im Environment tauchen sie als genau ein Leerzeichen auf. Zusätzlich ist ein Wert für die Environmentvariable ARGV definiert: wenn sie mit ‘NULL:’ beginnt, dann enthält der Rest der Zeile die (dezimalen) Positionen der leeren Parameter (durch Kommata getrennt). Ein Beispiel:
ARGV=NULL:3,5,9
bedeutet, daß argv [3], argv[5] und argv[9] leer sind. Der Startupcode sollte sich also darum kümmern, die entsprechenden Parameter zu löschen.
Genau dies tut der Pure-C-Startupcode aus Listing 2. Er beruht auf dem Code aus [2] und der Anpassung, die Michael Hohmuth für die MiNT-Library vorgenommen hat (siehe Startupcode der MiNT-Library). Er stellt lediglich ein Frontend für main() dar, der normale Startupcode PCSTART.O (nicht PCX START.O) muß also dennoch mitgelinkt werden. Aus der Funktion main() im Hauptprogramm wird daher argvmain().
Es sei noch der Hinweis erlaubt, daß man selbst mit dem lange etablierten ARGV-Verfahren im Vergleich zu MS-DOS sehr gut dasteht. Dort gibt es nämlich keine entsprechende Konvention. Folge ist, daß Linker beispielsweise unnötig kompliziert über spezielle Kommandodateien bedient werden müssen.
Und nun will ich noch auf ein Programm-Update hinweisen, auf das viele seit Jahren gewartet haben: seit dem 31. Dezember 1993 ist die erste Version vom Desktop Gemini 2 (Versionsnummer noch 1.99) freigegeben.
Gegenüber der letzten Fassung (1.21) hat sich vieles getan: MiNT (Beispiel: lange Dateinamen, symbolische Links, Pipes, Hintergrundausführung), MultiTOS (Beispiel: Drag & Drop), MagiX! (Beispiel: Parallelausführung) und SpeedoGDOS (Beispiel: nichtproportionale Schriften in Verzeichnisfenstern) werden unterstützt. Andere Highlights sind farbige Icons und stark erweiterte Selektionsmöglichkeiten per Tastatur (siehe Screenshot).
Die Mupfel (die eingebaute Kommandoshell) ist völlig neu geschrieben worden und bietet jetzt eine Scriptsprache wie von Unix-Shells (sh, bash, ksh) gewohnt. Damit sind endlich Kommandosubstution (Backquotes), Pipes, Schleifen und ähnliches möglich. Passend zu Stefan Eissings Mupfel gibt es von mir eine Sammlung von externen Kommandos, die die Möglichkeiten vervollständigen. Zum Redaktionsschluß waren Gemini (GMNI2.TOS) und die Utility-Sammlung (MUPFTL01.TOS) in praktisch jeder Maus-Mailbox zu bekommen. Wenn Sie dieses Heft in der Hand halten, werden allerdings wohl schon neuere Versionen verfügbar sein.
Kommen wir zum Schluß: Die nachfolgende Tabelle enthält eine Stichwortliste über die ersten 74 Nummern des ATARIUMs. Ich hoffe, daß es beim Wiederauffinden zurückliegender Themen eine Hilfe ist. Natürlich stammen alle Artikel vor 9/93 noch aus dem ST-Magazin.
Quellennachweis:
[1] Jankowski/Rabidi/Reschke: „ATARI Profibuch ST-STE-TT“, 12. Auflage, Sybex Düsseldorf 1992, ISBN 3-88745-888-5
[2] Ken Badertscher, „Gemdos Extended Argument (ARGV) Specification ",
aus: INFO-ATAR116
Digest 595/89, (2. November 1989)
[3] Julian F. Reschke: „Wiedersehen mit ARGV, Basepage und OS-Header“, ST-Magazin 4/1992, Seite 52.
void
memory_release (void **a)
{
int *p = * ((int **)a);
if (*(p - 1) == TRUE)
Mfree (p - 1);
else
free (p - 1);
}
Listing 1: Ausschnitt aus memory.c
/*
mainargv.c
(c)1993 by MAXON-Computer
Julian F. Reschke, 21. Januar 1994
Startup fuer Atari-ARGV
Anwendung: im Hauptprogramm
’main' durch 'argvmain' ersetzen
*/
#include <ctype.h>
#include <ext.h>
#include <tos.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MIN_ARGV_COUNT 4
extern int argvmain (int, char **, char **);
char **environ;
static DTA _mydta;
static char *
get_argv (void)
{
char *c = _BasPag->p_env;
while (*c)
{
if (!strncmp (c, "ARGV=", 5))
return c + 5;
else
c += strlen (c) + 1;
}
return NULL;
}
int
main (int argc, char *argv(]. char *envp[])
{
char **myargv;
extern BASPAG *_BasPag;
char *min_argv[MIN_ARGV_COUNT];
char *env;
char *startpar;
char *argv_value;
int count;
int i;
/* Damit der erste FsfirstO nicht die Kommandozeile überschreibt */
Fsetdta (&_mydta);
/* Flag fuer Verwendung von ARGV */
if (_BasPag->p_cmdlin[0] != 127)
return argvmain (argc, argv, envp);
/* Zeiger auf Env-Var merken */
argv_value = env = get_argv ();
if (!env) return argvmain (argc, argv, envp);
/* alle weiteren envp's löschen */
i = 0;
while (strncmp (envp[i], "ARGV=", 5)) i++;
envp[i] = NULL;
/* zu argv[0] gehen */
while (*env++);
/* auf extended ARGV testen */
if (strncmp (argv_value, "NULL:", 5))
argv_value = NULL;
else
argv_value += 5;
/* Parameterstart */
startpar = env;
/* Parameter zählen */
count = 0;
while (*env) {
count++;
while (*env++);
}
/* Speicher fuer neuen Argument-Vektor */
if (count < MIN_ARGV_COUNT)
myargv = min_argv;
else
myargv = malloc ((count+1)*sizeof (char *));
env = startpar;
count = 0;
while (*env) {
myargv[count++] = env;
while (*env++);
}
myargv[count] = NULL;
/* Leere Argumente vernichten */
if (argv_value)
{
while (*argv_value) {
unsigned int idx = 0;
char *s = argv_value;
for (; *s && *s != ',' ;) {
if (! isdigit (*s))
goto bail_out;
idx *= 10;
idx += *s++ - '0';
}
if (*s == ',') s += 1;
argv_value = s;
if (idx < count)
myargv[idx][0] = '\0‘;
else
goto bail_out;
}
}
bail_ out;
/* und ...argvmain() starten */
count = argvmain (count, myargv, envp);
if (myargv != min_argv)
mfree (myargv);
return count;
}
40-Ordner-Fehler.................................. siehe FOLDR100.PRG
ABC-GEM......................................................... 8/88
Accessories, Einschränkungen.............................. 3/91, 7/91
Accessory-Startup................................... 7/88, 1/89, 1/90
AC_CL0SE.................................................. 3/91, 7/91
act_pd.......................................................... 3/91
AES-Environment.................................... siehe Environment
AHDI............................ 10/89, 12/89, 1/91, 2/92, 4/92, 1/94
Alternate RAM........................................ siehe Mxalloc()
AMCGDOS...................................... 4/89, 7/89, 2/90, 11/90
appl_find()..................................................... 9/88
appl_write().................................................... 9/88
ARGV-Verfahren................................ 1/90, 4/90, 8/90, 4/92
ASSIGN.SYS-Datei, Format der.................................... 2/90
ASV (Atari-unix).................................. 12/90, 5/91, 11/91
Atari-Mailbox.................................................. 11/91
AT-Bus-Platten..................................... siehe IDE-Platten
Auflösungswechsel......................................... 3/91, 7/91
Basepage............................................ 4/92, 3/93, 6/93
Bcostat()....................................................... 6/91
BigScreen................................. 10-11/88, 5/91, 7/91, 6/92
BIOS-Aufrufe aus Interrupts..................................... 5/89
Bitstream-Schriften.................... 11/92, siehe auch Speedo-GDOS
Blockkonzept.................................................... 2/91
CD-ROM........................................... 10/90, 1/93, 7-8/93
Clipboard........................................... siehe Klemmbrett
Cookie Jar.......................................... 3/90, 1/91, 9/91
Critical Error Handler......................................... 10/92
Dateinamen, erlaubte Zeichen.................................... 4/91
Dateisysteme (FAT).............................................. 1/94
Dateisysteme (MiNT)..................................... 6-8/92, 5/93
Debugging....................................................... 2/94
Diablo-Emulator......................................... 10/90, 10/93
Digital Research................................................ 5/92
Dlock()......................................................... 6/93
DMAread(), DMAwrite()........................................... 2/92
DOS-Partitionierung............................................. 1/94
Dpathconf()................................ siehe Dateisysteme (MiNT)
Drag&Drop............................................. 6/93, 10-12/93
Drag&Drop, Beispielcode........................................ 12/93
Drag&Drop, Spezifikation....................................... 10/93
Dsetdrv()....................................................... 8/91
Ein- und Ausgabeumlenkung...................... siehe I/O-Redirection
Entwicklerkonferenz............................... 11/89, 2/91, 12/91
Environment............................................... 3/88, 6/90
exec_os......................................................... 6/90
Fast-RAM............................................. siehe Mxalloc()
_FDC-Cookie..................................................... 1/92
Fensterdialoge, nichtmodale..................................... 9/92
Fensterfarben................................................... 1/91
Fido-Netz....................................................... 8/89
File-Locking....................................... siehe _FLK-Cookie
_FLK-Cookie............................................... 1/92, 3/92
FlexOS................................................... siehe X/GEM
Floprate()..................................................... 11/89
FOLDR100.PRG.............................................. 7/90, 6/91
FontGDOS....................................................... 11/92
_FPU-Cookie..................................................... 1/91
fsel_input().................................................... 3/91
fsel_exinput()........................................... 12/88, 3/91
FSMGDOS................................. 10-11/90, 5/91, 11/91, 11/92
GDOS.................................... 6/88, 8/88, 7/89, 2/90, 2/93
GDOS-Treiber.................................................... 2/93
GEMDOS-Listing.................................................. 4/88
GEMDOS-Pool......................... siehe FOLDR100.PRG, POOLFIX3.PRG
Gemini-AV-Protokoll....................................... 11/91,2/92
GEM-Programmierrichtlinien...................................... 2/91
getcookie()..................................................... 9/91
Guläm........................................................... 2/89
HaBoo........................................................... 6/92
HalfScreen...................................................... 5/90
HD-Support......................................... siehe _FDC-Cookie
HDX....................................................... siehe AHDI
Human Engineering............................................... 7/89
HuSHI........................................................... 6/92
Hyperscreen........................................... siehe Overscan
IDE-Platten..................................................... 2/92
l/O-Redirection........................................... 8/90,10/91
‘Inside Mac’.................................................... 9/92
isatty()........................................................ 8/90
KAOS....................................................... 4/91,6/91
Keksdose............................................ siehe Cookie Jar
Klemmbrett..................... 2/88, 3/89, 5/89, 9-11/89, 2/91,12/91
Länderkennung im ROM-Header.................................... 12/89
Laufwerke, Anzahl............................................... 8/91
Line-A-Variablen, negative..................................... 10/88
Line-A-Rasterfunktionen......................................... 2/90
Links............................................. siehe Dateisysteme
Longframe....................................................... 3/90
MACCEL2......................................................... 3/90
Maddalt()....................................................... 1/91
Mag!x........................................................... 5/92
Master.......................................................... 3/89
MausNet....................................... 4/89, 8/89, 4/90, 2/92
_MCH-Cookie......................................... 3/90, 7/90, 9/91
Mega STE........................................................ 1/91
Memory Protection......................................... 5/92, 4/93
Metadateien..................................................... 2/93
MetaDOS.............................. 10/90, 8/91, 5/92, 7-8/93, 1/94
Message-Pipe.............................................. 9/88, 6/89
MGR...................................................... 12/90, 3/92
Micro-RTX...................................................... 12/90
MiNT............................................. 12/90, 1/91, 3-8/92
MiNT 0.95...................................................... 10/92
MiNT 0.96...................................................... 12/92
MiNT, Debugging........................................ siehe Tracing
MiNT, Dämon-Programmierung...................................... 3/93
MiNT-Libraries.................................. 8-10/92, 12/92, 4/93
MiNT-Versionen, neue....................................... (laufend)
Multi-GEM................................................ 12/90, 5/91
Multi-GEM 2..................................................... 5/92
Multisession............................................ siehe CD-ROM
Multitasking................................................... 12/90
MultiTOS................................................ 5-6/92, 4/93
Mxalloc()...................................................... 11/90
_NET-Cookie..................................................... 1/92
Netzwerkstandard (alter)....................................... 11/89
Netzwerkstandard (neuer)................................. 5/91,1-2/92
Notification Management......................................... 9/92
OS-Header....................................................... 4/92
Overscan................................................. 8/89, 10/89
Partitionierung................................................. 1/94
Patchprogramme............................................ 7/90, 6/91
PC-GEM.................................................... 8/88, 4/89
p_cookies........................................... siehe Cookie Jar
Pexec()......................................................... 3/93
Photo-CD................................................ siehe CD-ROM
Pipes........................................................... 8/90
PMMU-Cookie..................................................... 1/92
POOLFIX3.PRG.......................................... 4/90,7/90,6/91
POSIX 1003.1 ............................................ 3/92,7-8/92
Programmflags...................................... 11/90, 3/91, 4/93
Prozeßdateisystem............................................... 6/93
Ptermres()...................................................... 3/93
PTSINFIX.PRG............................................... 3/91,6/91
PUNJNFO-Struktur................................... 12/89, 2/92, 6/92
Rainbow-TOS........................................... siehe TOS 1.04
Rasterfunktionen.................................. 10/88, 10/89, 2/90
Resource-Dateien, Versionscheck................................. 2/94
Rootsektor...................................................... 1/94
rsrc_load()......................................... 3/88, 5/90, 3/91
SAA-Richtlinien................................................. 2/91
S.A.L.A.D .......................... siehe Line-A-Variablen, negative
scrp_....()......................................... siehe Klemmbrett
SCSI-Tool....................................................... 6/92
SERPTCH1.PRG.................................................... 6/91
SERPTCH2.PRG.................................................... 9/91
Shared Memory.................................................. 10/92
Shared Text.................................................... 12/92
shel_envrn().............................................. 3/88, 6/90
shel_find()............................................... 3/88, 5/90
shel_read()..................................................... 5/90
shel_get()/sheLput()............................................ 5/89
shell_p............................................... siehe system()
Smith. Eric............................................... siehe MiNT
Sound-Unterstützung durch TOS.................................. 10/91
SpeedoGDOS......................................... 11/92, 2/93, 2/94
Speicher, virtueller...................................... 1/92, 6/92
Standard-Menüs.................................................. 2/91
stderr.................................................... 8/90, 9/90
STEFIX.PRG...................................................... 7/90
Symbolische Links................................. siehe Dateisysteme
SysMON.......................................................... 2/94
system()........................................................ 2/89
Tastaturbelegung.................................................2/91
Templemon................................................. 4/89, 2/94
TOS 1.02........................................................ 7/90
TOS 1.04............................. 5/89, 11/89, 4-5/90, 7/90, 6/91
TOS 1.06.......................................... 3-4/90, 7/90, 6/91
TOS 1.62........................................................ 6/91
TOS 2.05....................................................... 11/91
TOS 2.06........................................................ 2/92
TOS 3.01..................................... 11/90, 1/91, 3/91, 6/91
TOS 3.05................................................... 3/91,6/91
TOS 3.06........................................................ 1/92
TOS14FIX.PRG.................................................... 7/90
TOS14FX2.PRG.................................................... 9/91
TOSWIN......................................................... 12/92
Tracing........................................................ 12/92
Turbo-DOS...................................................... 6-7/88
Verzeichnisfunktionen.......................................... 7-8/92
VDIFIX.PRG........................................... 3/90, 7/90, 6/91
virtueller Speicher........................ siehe Speicher, virtueller
Volume-Name...................................................... 1/89
v_opnvwk()................................... siehe Workstation-Fehler
vq_gdos()........................................................ 2/90
VRAM........................................ siehe virtueller Speicher
VSCR-Cookie...................................................... 7/91
Workplace-Shell................................................. 11/93
Workstation-Fehler......................................... 1/90, 3/90
Xact............................................................ 11/92
xArg-Verfahren............................................. 7/88, 1/90
XBRA-Verfahren......................... 10/88, 4/89, 11/89, 3/90, 2/91
XBRA-Liste.... 12/88, 4/89, 8/89, 12/89, 4-5/90, 4-5/91, 8-11/91, 6/92
XCONTROL.......................................... 1/91, 3/91, 9-10/91
X/GEM............................................................ 5/92
XHDI-Spezifikation................................... 6/92, 4/93, 7/93
Zoo.............................................................. 6/89