Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented simple (read-only) (ungetc-able) string-stream
Refactored the stream interface and implemented a simple stringstream. Now have working filestream and stringstream. Next up is make eval read "(repl)" from stringstream.
- Loading branch information
Showing
11 changed files
with
178 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,3 +23,4 @@ TAGS | |
/src/vm/cpp_vm.d | ||
/src/vm/test/test_context.d | ||
/tlisp | ||
/test/test_stringstream |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "filestream.h" | ||
|
||
int filestream_getc(STREAM *stream); | ||
int filestream_ungetc(int ch, STREAM *stream); | ||
int filestream_flush(STREAM *stream); | ||
int filestream_close(STREAM *stream); | ||
|
||
int make_filestream(STREAM *stream, FILE *f) { | ||
stream->payload = f; | ||
stream->fgetc_fun = filestream_getc; | ||
stream->ungetc_fun = filestream_ungetc; | ||
stream->flush_fun = filestream_flush; | ||
stream->close_fun = filestream_close; | ||
return 1; | ||
} | ||
|
||
int filestream_getc(STREAM *stream) { | ||
return fgetc((FILE *)stream->payload); | ||
} | ||
|
||
int filestream_ungetc(int ch, STREAM *stream) { | ||
return ungetc(ch, (FILE *)stream->payload); | ||
} | ||
|
||
int filestream_flush(STREAM *stream) { | ||
return fflush((FILE *)stream->payload); | ||
} | ||
|
||
int filestream_close(STREAM *stream) { | ||
FILE *f = (FILE *)stream->payload; | ||
stream->payload = NULL; | ||
return fclose(f); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef _FILESTREAM_H | ||
#define _FILESTREAM_H 1 | ||
|
||
#include <stdio.h> | ||
#include "t_stream.h" | ||
|
||
int make_filestream(STREAM *stream, FILE *f); | ||
|
||
#endif /* _FILESTREAM_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include "stringstream.h" | ||
|
||
#include <string.h> | ||
#include <stdio.h> | ||
|
||
#include "memory.h" | ||
|
||
int stringstream_getc(STREAM *stream); | ||
int stringstream_ungetc(int ch, STREAM *stream); | ||
int stringstream_flush(STREAM *stream); | ||
int stringstream_close(STREAM *stream); | ||
|
||
typedef struct string_info { | ||
char *str; | ||
size_t len; | ||
size_t index; | ||
} string_info; | ||
|
||
int make_stringstream(STREAM *stream, const char *str, size_t size) { | ||
char *target; | ||
string_info *s = new_malloc(string_info); | ||
|
||
/* This will at most trigger a read overflow + pagefault. Sweet */ | ||
if(strlen(str) >= size) { /* str + '\0' must fit in size */ | ||
memset(stream, 0, sizeof(STREAM)/sizeof(char)); | ||
return 0; | ||
} else if (size < 1) { | ||
memset(stream, 0, sizeof(STREAM)/sizeof(char)); | ||
return 0; | ||
} | ||
|
||
target = malloc_or_bail(size); | ||
strcpy(target, str); // we got here, len(target) >= len(str + 1) | ||
s->len = size-1; | ||
s->index = 0; | ||
s->str = target; | ||
|
||
stream->payload = s; | ||
|
||
stream->fgetc_fun = stringstream_getc; | ||
stream->ungetc_fun = stringstream_ungetc; | ||
stream->flush_fun = stringstream_flush; | ||
stream->close_fun = stringstream_close; | ||
return 1; | ||
} | ||
|
||
int stringstream_getc(STREAM *stream) { | ||
string_info *s = (string_info *)stream->payload; | ||
if (s->index >= s->len) | ||
return EOF; | ||
return (int)((unsigned char)*(s->str + s->index++)); | ||
} | ||
|
||
int stringstream_ungetc(int ch, STREAM *stream) { | ||
string_info *s = (string_info *)stream->payload; | ||
if (s->index <= 0) | ||
return EOF; | ||
|
||
*(s->str + --(s->index)) = (char)ch; | ||
return ch; | ||
} | ||
|
||
int stringstream_flush(STREAM *stream) { | ||
return 1; | ||
} | ||
|
||
int stringstream_close(STREAM *stream) { | ||
free_malloced(((string_info *)stream->payload)->str); | ||
free_malloced(stream->payload); | ||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef _STRINGSTREAM_H | ||
#define _STRINGSTREAM_H 1 | ||
|
||
#include <stdlib.h> | ||
|
||
#include "t_stream.h" | ||
|
||
int make_stringstream(STREAM *stream, const char *str, size_t size); | ||
|
||
#endif /* _STRINGSTREAM_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
#include <ctype.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
|
||
#include "errors.h" | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#include "../src/ast-walker/stringstream.c" | ||
#include "../src/ast-walker/memory.h" | ||
#include "../src/ast-walker/memory.c" | ||
#include "../src/ast-walker/t_stream.h" | ||
#include "../src/ast-walker/t_stream.c" | ||
|
||
#include <string.h> | ||
|
||
int main(void) { | ||
STREAM s; | ||
const char *tmp = "hej pa dig"; | ||
int ch, i; | ||
|
||
make_stringstream(&s, tmp, strlen(tmp)+1); | ||
|
||
while((ch = stream_getc(&s)) != EOF) | ||
putchar(ch); | ||
|
||
printf("END\n"); | ||
stream_close(&s); | ||
|
||
printf("%s\n", tmp); | ||
|
||
make_stringstream(&s, tmp, strlen(tmp)+1); | ||
for (i = 0; i < 4; i++) | ||
ch = stream_getc(&s); | ||
|
||
stream_ungetc('.', &s); | ||
stream_ungetc('J', &s); | ||
stream_ungetc('O', &s); | ||
stream_ungetc('H', &s); | ||
|
||
ch = stream_ungetc('2', &s); | ||
if (ch != EOF) { | ||
printf("Should get EOF\n"); | ||
} else { | ||
printf("All ok, got EOF\n"); | ||
} | ||
|
||
printf("UNCHANGED: %s\n", tmp); | ||
|
||
while((ch = stream_getc(&s)) != EOF) | ||
putchar(ch); | ||
printf("END\n"); | ||
|
||
stream_close(&s); | ||
} |