diff options
author | Carl Worth <[email protected]> | 2010-08-23 10:43:27 -0700 |
---|---|---|
committer | Carl Worth <[email protected]> | 2010-08-23 10:48:10 -0700 |
commit | 61f73fec532b24ef5ec4b5baef81f5e6b9f20918 (patch) | |
tree | 4afb5c938b17bfb2f02d34ac48ebfde122de8640 /src/glsl/glcpp | |
parent | 21560c40e8aa98624a225752b98babc7ae2938d5 (diff) |
glcpp: Make standalone preprocessor work with a tty as stdin
Previously glcpp would silently abort if it couldn't fstat the file being
read, (so it would work with stdin redirected from a file, but would not
work with stdin as a tty). The stat was so that glcpp could allocate
a buffer for the file content in a single call.
We now use talloc_realloc instead, (even if the fstat is
possible). This is theoretically less efficient, but quite irrelevant,
(particularly because the standalone preprocessor is used only for
testing).
Diffstat (limited to 'src/glsl/glcpp')
-rw-r--r-- | src/glsl/glcpp/glcpp.c | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/src/glsl/glcpp/glcpp.c b/src/glsl/glcpp/glcpp.c index 011058a36ac..56714936bbc 100644 --- a/src/glsl/glcpp/glcpp.c +++ b/src/glsl/glcpp/glcpp.c @@ -31,48 +31,64 @@ extern int yydebug; +/* Read from fd until EOF and return a string of everything read. + */ static char * -load_text_file(void *ctx, const char *file_name) +load_text_fd (void *ctx, int fd) { +#define CHUNK 4096 char *text = NULL; - struct stat st; + ssize_t text_size = 0; ssize_t total_read = 0; - int fd; + ssize_t bytes; + + while (1) { + if (total_read + CHUNK + 1 > text_size) { + text_size = text_size ? text_size * 2 : CHUNK + 1; + text = talloc_realloc_size (ctx, text, text_size); + if (text == NULL) { + fprintf (stderr, "Out of memory\n"); + return NULL; + } + } + bytes = read (fd, text + total_read, CHUNK); + if (bytes < 0) { + fprintf (stderr, "Error while reading: %s\n", + strerror (errno)); + talloc_free (text); + return NULL; + } - if (file_name == NULL || strcmp(file_name, "-") == 0) { - fd = STDIN_FILENO; - } else { - fd = open (file_name, O_RDONLY); + if (bytes == 0) { + break; + } - if (fd < 0) { - fprintf (stderr, "Failed to open file %s: %s\n", - file_name, strerror (errno)); - return NULL; - } + total_read += bytes; } - if (fstat(fd, & st) == 0) { - text = (char *) talloc_size(ctx, st.st_size + 1); - if (text != NULL) { - do { - ssize_t bytes = read(fd, text + total_read, - st.st_size - total_read); - if (bytes < 0) { - text = NULL; - break; - } - - if (bytes == 0) { - break; - } - - total_read += bytes; - } while (total_read < st.st_size); - - text[total_read] = '\0'; - } + text[total_read] = '\0'; + + return text; +} + +static char * +load_text_file(void *ctx, const char *filename) +{ + char *text; + int fd; + + if (filename == NULL || strcmp (filename, "-") == 0) + return load_text_fd (ctx, STDIN_FILENO); + + fd = open (filename, O_RDONLY); + if (fd < 0) { + fprintf (stderr, "Failed to open file %s: %s\n", + filename, strerror (errno)); + return NULL; } + text = load_text_fd (ctx, fd); + close(fd); return text; @@ -91,7 +107,7 @@ main (int argc, char *argv[]) filename = argv[1]; } - shader = load_text_file(ctx, filename); + shader = load_text_file (ctx, filename); if (shader == NULL) return 1; |