Dies ist das erste Mal, dass ich splint (aus den Ubuntu-Repositories) benutze, und ich wurde sofort von einem WTF getroffen. Die Fehlermeldung:
nightcracker@nightcracker-pc:~/c/brainfuck$ splint brainfuck.c
Splint 3.1.2 --- 03 Mai 2009
brainfuck.c:17:6: Parsefehler. (Für Hilfe bei Parsefehlern siehe splint -help
parseerrors.)
*** Kann nicht fortgesetzt werden.
Offenbar sieht es jetzt etwas falsches in Zeile 16, Spalte 6. Lassen Sie uns das überprüfen (Veröffentlichung des vollständigen Codes):
#include
#include
#include
enum {
CELL_CHUNK_SIZE = 1024,
};
typedef unsigned char cell;
int main(int argc, char *argv[]) {
if (argc < 1) {
fprintf(stderr, "FEHLER: Nicht genügend Argumente\n");
return 1;
}
FILE *srcfile; // Quelldatei << DIESE LINIE SCHEINT FALSCH ZU SEIN
long srclen; // Größe der Quelldatei
char *bf; // Brainfuck-Code in Speicher
char *ip; // Befehlszeiger
cell *cells; // Brainfuck-Zellen
cell *newcells; // zum Erstellen eines neuen Zellchunks verwendet
cell *cp; // Zellenzeiger
unsigned long numcells = CELL_CHUNK_SIZE; // Anzahl der aktuellen Zellen
unsigned nest; // aktuelle Verschachtelung
int buf; // Ein-/Ausgabe-Puffer
srcfile = fopen(argv[1], "rb");
if (srcfile == NULL) {
fprintf(stderr, "FEHLER: Konnte die Quelldatei nicht öffnen\n");
return 2;
}
// Quelldateilänge abrufen
fseek(srcfile, 0, SEEK_END);
srclen = ftell(srcfile);
fseek(srcfile, 0, SEEK_SET);
// Speicher für Quelldatei zuweisen
bf = malloc(srclen);
if (bf == NULL) {
fprintf(stderr, "FEHLER: Konnte keinen Speicher für die Quelldatei zuweisen\n");
return 3;
}
// Quelldatei im Speicher lesen
if (srclen != fread(bf, sizeof(char), srclen, srcfile)) {
fprintf(stderr, "FEHLER: Fehler beim Lesen der Quelldatei\n");
free(bf);
return 4;
}
fclose(srcfile);
cells = malloc(CELL_CHUNK_SIZE * sizeof(cell));
memset(cells, 0, CELL_CHUNK_SIZE);
if (cells == NULL) {
fprintf(stderr, "FEHLER: Speicherzuweisung fehlgeschlagen\n");
free(bf);
free(cells);
return 5;
}
cp = cells; // Zellenzeiger auf am weitesten links stehende Zelle initialisiert
ip = bf; // Befehlszeiger auf das erste Zeichen initialisiert
nest = 0;
while (ip >= bf && ip <= (bf + srclen)) {
switch (*ip) {
case '+':
(*cp)++;
break;
case '-':
(*cp)--;
break;
case '>':
cp++;
if ((cp - cells) == numcells) {
newcells = realloc(cells, (numcells + CELL_CHUNK_SIZE) * sizeof(cell)); // Speicher für neuen Chunk zuweisen
if (newcells == NULL) {
fprintf(stderr, "FEHLER: Speicherzuweisung fehlgeschlagen\n");
free(bf);
free(cells);
return 5;
}
cp = newcells + (cp - cells); // Zellenzeiger auf Zelle im neuen Chunk zeigen lassen
cells = newcells; // Zellen auf neue Speicherstelle zeigen lassen (falls verändert)
memset(cp, 0, CELL_CHUNK_SIZE); // neuen Chunk initialisieren
numcells += CELL_CHUNK_SIZE;
}
break;
case '<':
cp--;
break;
case '.':
putchar(*cp);
break;
case ',':
if ((buf = getchar()) != EOF) {
*cp = (unsigned char) buf;
} else *cp = 0;
break;
case '[':
if (!(*cp)) {
ip++; // über die öffnende Klammer hinaus bewegen
while (nest > 0 || *ip != ']') { // zu passendem ] springen
if (*ip == '[') nest++; // Verschachtelung betreten
if (*ip == ']') nest--; // Verschachtelung verlassen (oder Hauptschleife, bei der Verschachtelung > 0 fehlschlägt)
ip++; // nach rechts bewegen
}
}
break;
case ']':
if (*cp) {
ip--; // vor schließende Klammer bewegen
while (nest > 0 || *ip != '[') { // zu passendem [ zurückspulen
if (*ip == '[') nest--; // Verschachtelung verlassen (oder Hauptschleife, bei der Verschachtelung > 0 fehlschlägt)
if (*ip == ']') nest++; // Verschachtelung betreten
ip--; // nach links bewegen
}
ip--; // vor der öffnenden Klammer bewegen
}
break;
}
ip++; // zu nächster Anweisung bewegen
}
free(cells);
free(bf);
return 0;
}
Beachten Sie, dass dieses Programm ohne Fehler kompiliert (gcc -Wall -std=c99 brainfuck.c
) und sich zur Laufzeit normal verhält.
Hinweis: Wenn Sie sich durch den Namen Brainfuck beleidigt fühlen, leben Sie damit. Es ist eine Programmiersprache, die vom Autor so benannt wurde, und ich respektiere und verwende diesen Namen.