diff options
Diffstat (limited to 'rushs/tinyprintf/tinylibstream')
| -rw-r--r-- | rushs/tinyprintf/tinylibstream/Makefile | 13 | ||||
| -rw-r--r-- | rushs/tinyprintf/tinylibstream/include/libstream.h | 167 | ||||
| -rw-r--r-- | rushs/tinyprintf/tinylibstream/src/tinylibstream.c | 221 | ||||
| -rw-r--r-- | rushs/tinyprintf/tinylibstream/stdin_buffering_test.c | 70 | ||||
| -rw-r--r-- | rushs/tinyprintf/tinylibstream/stdout_buffering_test.c | 13 |
5 files changed, 0 insertions, 484 deletions
diff --git a/rushs/tinyprintf/tinylibstream/Makefile b/rushs/tinyprintf/tinylibstream/Makefile deleted file mode 100644 index b060495..0000000 --- a/rushs/tinyprintf/tinylibstream/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -CC = gcc -CFLAGS = -std=c99 -pedantic -Werror -Wall -Wextra -Wvla - -.PHONY: library clean - -library: src/tinylibstream.o - ar csr libstream.a src/tinylibstream.o - -clean: - rm libstream.a src/tinylibstream.o - -check: - $(CC) $(CFLAGS) -lcriterion src/tinylibstream.c tests/tests.c diff --git a/rushs/tinyprintf/tinylibstream/include/libstream.h b/rushs/tinyprintf/tinylibstream/include/libstream.h deleted file mode 100644 index 459432d..0000000 --- a/rushs/tinyprintf/tinylibstream/include/libstream.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef LIBSTREAM_H -#define LIBSTREAM_H - -#include <fcntl.h> -#include <stdbool.h> -#include <stddef.h> -#include <unistd.h> - -/* -** /!\ DO NOT MODIFY THIS FILE, AS IT WILL BE OVERRIDDEN DURING CORRECTION. /!\ -** -** You can add your own functions declarations to OTHER HEADER FILES. -*/ - -/* the value returned when end of file is reached */ -#define LBS_EOF (-1) - -/* the size of the buffer */ -#define LBS_BUFFER_SIZE 32 - -/* -** Describes the current operation: -** - if reading, the buffer contains read-buffered data -** - if writing, the buffer contains write-buffered data -*/ -enum stream_io_operation -{ - STREAM_READING = 0, - STREAM_WRITING, -}; - -/* -** Controls when to flush the buffer: -** - when unbuffered, flush every time a character is written -** - when buffered, flush when the buffer is full -** - when line buffered, flush when the buffer is full or when a \n -** character is written -*/ -enum stream_buffering -{ - STREAM_UNBUFFERED = 0, - STREAM_LINE_BUFFERED, - STREAM_BUFFERED, -}; - -struct stream -{ - /* the flags passed to open */ - int flags; - - /* - ** Initially, this variable is 0. - ** When a function such as fgetc fails, it is set to 1 to indicate - ** something went wrong. This is useful to make the difference between - ** reaching the end of file and read errors while using fgetc and - ** some others. - ** It is often referred to as the error indicator. - */ - int error; - - /* the file descriptor, as returned by open(2) */ - int fd; - - /* - ** the kind of data stored by the buffer. - ** The default value shouldn't matter. - */ - enum stream_io_operation io_operation; - - /* - ** defines when to flush **output**. - ** This field does not control input buffering (which is always fully - ** buffered). - ** - ** The default value is LINE_BUFFERED if isatty(fd), BUFFERED otherwise. - */ - enum stream_buffering buffering_mode; - - /* the amount of used bytes in the buffer */ - size_t buffered_size; - - /* - ** /!\ This field only makes sense when io_operation is STREAM_READING /!\ - ** the amount of data already read from the buffer by the user. - */ - size_t already_read; - - /* - ** buffer - ** --------------> - ** +==============+====================+---------------------+ - ** | already_read | remaining_buffered | unused_buffer_space | - ** +==============+====================+---------------------+ - ** \_______________________________/ - ** buffered_size - ** - ** /!\ The buffer can contain either read-buffered or write-buffered data, - ** depending on the value of io_operation /!\ - */ - char buffer[LBS_BUFFER_SIZE]; -}; - -/* -** These functions are defined in a header for optimization reasons: -** each .c file that includes this header will get its own copy of the -** function's code, thus easily make optimizations. -** -** ``static`` means each compilation unit (.c file) will have its own copy -** of the function without them clashing. -** -** ``inline`` means the content of the function should be "copy pasted" -** where it's called. It also tells the compiler not to complain when the -** function isn't used. -** -** They're just like a macro, except the type of arguments is checked. -*/ - -static inline size_t stream_remaining_buffered(struct stream *stream) -{ - return stream->buffered_size - stream->already_read; -} - -static inline size_t stream_unused_buffer_space(struct stream *stream) -{ - return sizeof(stream->buffer) - stream->buffered_size; -} - -static inline bool stream_readable(struct stream *stream) -{ - int access_mode = stream->flags & O_ACCMODE; - if (access_mode == O_RDWR) - return true; - return access_mode == O_RDONLY; -} - -static inline bool stream_writable(struct stream *stream) -{ - int access_mode = stream->flags & O_ACCMODE; - if (access_mode == O_RDWR) - return true; - return access_mode == O_WRONLY; -} - -static inline int lbs_ferror(struct stream *stream) -{ - return stream->error; -} - -static inline void lbs_clearerr(struct stream *stream) -{ - stream->error = 0; -} - -static inline void lbs_setbufmode(struct stream *stream, - enum stream_buffering mode) -{ - stream->buffering_mode = mode; -} - -struct stream *lbs_fopen(const char *path, const char *mode); -struct stream *lbs_fdopen(int fd, const char *mode); -int lbs_fflush(struct stream *stream); -int lbs_fclose(struct stream *stream); -int lbs_fputc(int c, struct stream *stream); -int lbs_fgetc(struct stream *stream); - -#endif /* !LIBSTREAM_H */ diff --git a/rushs/tinyprintf/tinylibstream/src/tinylibstream.c b/rushs/tinyprintf/tinylibstream/src/tinylibstream.c deleted file mode 100644 index dca1c01..0000000 --- a/rushs/tinyprintf/tinylibstream/src/tinylibstream.c +++ /dev/null @@ -1,221 +0,0 @@ -#include <stdlib.h> -#include <string.h> - -#include "../include/libstream.h" - -int get_flags(const char *mode) -{ - int flags; - if (strcmp(mode, "r") == 0) - { - flags = O_RDONLY; - } - else if (strcmp(mode, "r+") == 0) - { - flags = O_RDWR; - } - else if (strcmp(mode, "w") == 0) - { - flags = O_WRONLY | O_TRUNC | O_CREAT; - } - else - { - flags = O_RDWR | O_TRUNC | O_CREAT; - } - - return flags; -} - -struct stream *lbs_fopen(const char *path, const char *mode) -{ - int fd = open(path, get_flags(mode)); - - return lbs_fdopen(fd, mode); -} - -struct stream *lbs_fdopen(int fd, const char *mode) -{ - if (fd == -1) - { - return NULL; - } - - struct stream *s = malloc(sizeof(struct stream)); - if (s == NULL) - { - return NULL; - } - - s->flags = get_flags(mode); - s->error = 0; - s->fd = fd; - if (isatty(fd)) - { - s->buffering_mode = STREAM_LINE_BUFFERED; - } - else - { - s->buffering_mode = STREAM_BUFFERED; - } - s->buffered_size = 0; - s->already_read = 0; - - return s; -} - -int lbs_fflush(struct stream *stream) -{ - if (stream == NULL || stream->buffered_size == 0) - { - return 0; - } - - if (stream->io_operation == STREAM_READING) - { - if (!stream_readable(stream)) - { - stream->error = 1; - return LBS_EOF; - } - if (stream_remaining_buffered(stream) != 0 - && lseek(stream->fd, -stream_remaining_buffered(stream), SEEK_CUR) - == -1) - { - stream->error = 1; - return LBS_EOF; - } - stream->buffered_size = 0; - stream->already_read = 0; - } - else - { - if (!stream_writable(stream)) - { - stream->error = 1; - return LBS_EOF; - } - ssize_t w; - if ((w = write(stream->fd, stream->buffer, stream->buffered_size)) - == -1) - { - stream->error = 1; - return LBS_EOF; - } - stream->buffered_size = 0; - stream->already_read = 0; - } - return 0; -} - -int lbs_fclose(struct stream *stream) -{ - if (stream == NULL) - { - return 1; - } - - lbs_fflush(stream); - if (close(stream->fd) == -1) - { - return 1; - } - - free(stream); - - return 0; -} - -int lbs_fputc(int c, struct stream *stream) -{ - if (!stream_writable(stream)) - { - stream->error = 1; - return -1; - } - - if (stream->io_operation == STREAM_READING) - { - if (lbs_fflush(stream) != 0) - { - return -1; - } - stream->buffered_size = 0; - stream->already_read = 0; - } - stream->io_operation = STREAM_WRITING; - - if (stream_unused_buffer_space(stream) == 0 - || stream->buffering_mode == STREAM_UNBUFFERED) - { - if (lbs_fflush(stream) != 0) - { - return -1; - } - } - - stream->buffer[stream->buffered_size] = c; - stream->buffered_size++; - if (stream_unused_buffer_space(stream) == 0 - || stream->buffering_mode == STREAM_UNBUFFERED - || (stream->buffering_mode == STREAM_LINE_BUFFERED && c == '\n')) - { - if (lbs_fflush(stream) != 0) - { - return -1; - } - } - - return c; -} - -int refill_buffer(struct stream *stream) -{ - stream->already_read = 0; - ssize_t r; - if ((r = read(stream->fd, stream->buffer, LBS_BUFFER_SIZE)) == -1) - { - stream->error = 1; - return -1; - } - if (r == 0) - { - return -1; - } - stream->buffered_size = r; - return r; -} - -int lbs_fgetc(struct stream *stream) -{ - if (!stream_readable(stream)) - { - stream->error = 1; - return -1; - } - if (stream->io_operation == STREAM_WRITING) - { - if (lbs_fflush(stream) != 0) - { - stream->error = 1; - return -1; - } - stream->already_read = 0; - } - stream->io_operation = STREAM_READING; - - if (stream_remaining_buffered(stream) == 0) - { - int r; - if ((r = refill_buffer(stream)) == -1) - { - stream->error = 1; - return -1; - } - } - - int res = stream->buffer[stream->already_read++]; - - unsigned char c = res; - - return c; -} diff --git a/rushs/tinyprintf/tinylibstream/stdin_buffering_test.c b/rushs/tinyprintf/tinylibstream/stdin_buffering_test.c deleted file mode 100644 index 6d3361b..0000000 --- a/rushs/tinyprintf/tinylibstream/stdin_buffering_test.c +++ /dev/null @@ -1,70 +0,0 @@ -#define _GNU_SOURCE -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -struct slow_cookie -{ - int fd; -}; - -static ssize_t slow_read(void *vcookie, char *buf, size_t count) -{ - struct slow_cookie *cookie = vcookie; - usleep(500000); // sleep for half of a second - - ssize_t res; - - while ((res = read(cookie->fd, buf, count)) < 0) - if (errno != EINTR && errno != EAGAIN) - break; - - return res; -} - -static int slow_close(void *vcookie) -{ - struct slow_cookie *cookie = vcookie; - return close(cookie->fd); -} - -cookie_io_functions_t slow_stdio = { - .read = slow_read, - .close = slow_close, -}; - -int main(void) -{ - /* setup a custom stdin stream with a slow read function */ - struct slow_cookie cookie = { - .fd = STDIN_FILENO, - }; - - FILE *input_stream = fopencookie(&cookie, "r", slow_stdio); - - /* change the buffer size to the one given by stdbuf. - ** it doesn't work out of the box as stdbuf only does - ** this for the already existing stdin stream. - */ - char *buffer = NULL; - char *buffer_size = getenv("_STDBUF_I"); - if (buffer_size) - { - size_t size = atoi(buffer_size); - buffer = malloc(size); - setvbuf(input_stream, buffer, _IOFBF, size); - } - - /* forward all characters from stdin to stdout */ - int c; - while ((c = fgetc(input_stream)) != EOF) - { - fputc(c, stdout); - fflush(stdout); - } - - fclose(input_stream); - free(buffer); - return 0; -} diff --git a/rushs/tinyprintf/tinylibstream/stdout_buffering_test.c b/rushs/tinyprintf/tinylibstream/stdout_buffering_test.c deleted file mode 100644 index 45c0a83..0000000 --- a/rushs/tinyprintf/tinylibstream/stdout_buffering_test.c +++ /dev/null @@ -1,13 +0,0 @@ -#define _XOPEN_SOURCE 500 -#include <stdio.h> -#include <unistd.h> - -int main(void) -{ - const char test_string[] = "Robin\nloves\nBatman\n"; - for (size_t i = 0; test_string[i]; i++) - { - usleep(100000); // wait a tenth of a second - putchar(test_string[i]); - } -} |
