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).
This commit is contained in:
@@ -31,47 +31,63 @@
|
|||||||
|
|
||||||
extern int yydebug;
|
extern int yydebug;
|
||||||
|
|
||||||
|
/* Read from fd until EOF and return a string of everything read.
|
||||||
|
*/
|
||||||
static char *
|
static char *
|
||||||
load_text_file(void *ctx, const char *file_name)
|
load_text_fd (void *ctx, int fd)
|
||||||
{
|
{
|
||||||
|
#define CHUNK 4096
|
||||||
char *text = NULL;
|
char *text = NULL;
|
||||||
struct stat st;
|
ssize_t text_size = 0;
|
||||||
ssize_t total_read = 0;
|
ssize_t total_read = 0;
|
||||||
|
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 (bytes == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_read += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
text[total_read] = '\0';
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
load_text_file(void *ctx, const char *filename)
|
||||||
|
{
|
||||||
|
char *text;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (file_name == NULL || strcmp(file_name, "-") == 0) {
|
if (filename == NULL || strcmp (filename, "-") == 0)
|
||||||
fd = STDIN_FILENO;
|
return load_text_fd (ctx, STDIN_FILENO);
|
||||||
} else {
|
|
||||||
fd = open (file_name, O_RDONLY);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
fd = open (filename, O_RDONLY);
|
||||||
fprintf (stderr, "Failed to open file %s: %s\n",
|
if (fd < 0) {
|
||||||
file_name, strerror (errno));
|
fprintf (stderr, "Failed to open file %s: %s\n",
|
||||||
return NULL;
|
filename, strerror (errno));
|
||||||
}
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(fd, & st) == 0) {
|
text = load_text_fd (ctx, fd);
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@@ -91,7 +107,7 @@ main (int argc, char *argv[])
|
|||||||
filename = argv[1];
|
filename = argv[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
shader = load_text_file(ctx, filename);
|
shader = load_text_file (ctx, filename);
|
||||||
if (shader == NULL)
|
if (shader == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user