BOOL TSteering::LoadMacro( LPSTR makname, LPSTR fn )
{
// Function tested
// Last changes 950811
FILE* hFile;
int idx = nMacroNumber;
char* token;
char buf[MaxString+1];
int cnt;
LPSTR cmd, p1, p2, p3;
hFile = fopen( fn, "r" );
if (!hFile)
{
wsprintf( buf, "Cannot open file %s !", fn );
MessageBox( GetFocus(), buf, "Message", MBINFO );
return FALSE;
}
// search for macro in file
while (GetFileLine( hFile, buf, MaxString ))
{
if (!strstr( buf, "[Common]" ))
// neue Zeile holen, bis "[Common]" auftaucht
continue;
while (GetFileLine( hFile, buf, MaxString ))
{
if (buf[0] == '#')
// Kommentare werden überlesen
continue;
token = strtok( buf, " =\r\n\t" );
// strcmp() liefert 0 bei Übereinstimmung
if (!strcmp( token, "Name" ))
{
token = strtok( NULL, " =\r\n\t" );
if (strcmp( makname, token ))
// gefundenes Makro ist nicht das gesuchte
break;
ParsingMacroId( aMacroList[idx], token );
strcpy( aMacroList[idx].FileName, fn );
}
if (!strcmp( token, "Length" ))
{
token = strtok( NULL, " =\r\n\t" );
aMacroList[idx].Length = atoi( token );
}
if (!strcmp( token, "[Commands]" ))
{
aMacroList[idx].CmdList = new TCmdTag[aMacroList[idx].Length];
cnt = 0;
while (GetFileLine( hFile, buf, MaxString ))
{
if (buf[0] == '#')
// Kommentare werden überlesen
continue;
if ((strstr( buf, "[End]" )) || (cnt > aMacroList[idx].Length))
// [End] erreicht oder angegebene Länge überschritten
// zweiter Fall kann nicht eintreten, da er weiter unten
// bereits abgefangen wird
break;
// Befehl mit allen Parametern einlesen
cmd = strtok( buf, " \r\n\t" );
p1 = strtok( NULL, " \r\n\t" );
p2 = strtok( NULL, " \r\n\t" );
p3 = strtok( NULL, "\r\n\t" );
ParsingCmd( aMacroList[idx].CmdList[cnt], cmd, p1, p2, p3 );
// aktuelle Befehlsanzahl erhöhen
cnt++;
if (cnt == aMacroList[idx].Length)
// maximale Länge erreicht
break;
}
// Befehlslistenlänge auf den tatsächlichen Wert setzen
aMacroList[idx].Length = cnt;
// the last command has to be Stop
// (und zwar zwangsweise...)
aMacroList[idx].CmdList[cnt-1].Id = Stop;
aMacroList[nMacroNumber].bIsReady = TRUE;
// Makroanzahl erhöhen
nMacroNumber++;
// Falls das Makro schon existiert, wird das alte ersetzt
idx = nMacroNumber - 1;
while (idx)
{
idx--;
if (!strcmp( aMacroList[nMacroNumber - 1].Name, aMacroList[idx].Name ))
{
// alte Befehlsfolge löschen
delete aMacroList[idx].CmdList;
idx++;
// Rest der Makroliste eins nach vorn schieben
while (idx < nMacroNumber)
{
aMacroList[idx-1] = aMacroList[idx];
idx++;
}
nMacroNumber--;
// Speichergrösse anpassen
memset( &(aMacroList[nMacroNumber]), 0, sizeof(TMacroTag) );
// unsinniger Seitenausstieg 1
fclose( hFile );
return TRUE;
}
}
// unsinniger Seitenausstieg 2
fclose( hFile );
return TRUE;
}
}
}
// Datei schliessen und Funktion verlassen
fclose( hFile );
return TRUE;
}
Die Funktion strtok( str1, str2 ) liefert den durch eins der in str2 angegebenen Trennzeichen begrenzten Teilstring von str1. Nachfolgende Aufrufe von strtok( NULL, str2 ) liefern die weiteren Teilstrings.
Beispiel:
// strtokBsp.cpp
// Demonstration der Funktion strtok( char*, char* )
#include <string>
#include <iostream>
int main()
{
char text[] = "Hallo Du! ";
cout << strtok( text, " " ) << endl;
cout << strtok( NULL, " " ) << endl;
return 0;
}
Obiges Programm liefert folgerichtig diese Ausschriften:
beat schuetzl 31 ( ~/projekt98/texte ) > ./strtokBsp Hallo Du! beat schuetzl 32 ( ~/projekt98/texte ) >Zurück nach oben.
Die Funktion LoadMacro() ist prinzipiell leicht verständlich, jedoch haarsträubend implementiert. Die Verschachtelung von drei while-Schleifen ist nicht nur unschön, sondern auch unübersichtlich und unnötig. Hier sind mit Leichtigkeit Änderungen vornehmbar, die sich auf die Wartbarkeit positiv auswirken wuerden.