From 2c421c3b716a51f1353f15cb33ed5abb973acbb2 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Tue, 13 Jan 2015 21:18:47 -0500 Subject: [PATCH] Major cleanup of platform/fs stuff --- Makefile | 2 +- ansi.c | 110 ----------- code.c | 42 ++--- conout.c | 84 +++------ exec.c | 20 +- fs.c | 89 +-------- ftepp.c | 6 +- gmqcc.h | 39 +--- lexer.c | 46 ++--- lexer.h | 2 +- main.c | 22 +-- opts.c | 18 +- platform.h | 523 +---------------------------------------------------- test.c | 205 +++++++-------------- util.c | 50 ++--- 15 files changed, 205 insertions(+), 1053 deletions(-) diff --git a/Makefile b/Makefile index a032e87..9b02469 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC ?= clang -CFLAGS = -MD -Wall -Wextra -pedantic-errors +CFLAGS = -MD -std=gnu99 -Wall -Wextra -pedantic-errors -g3 LDFLAGS = -lm CSRCS = ansi.c ast.c code.c conout.c fold.c fs.c ftepp.c hash.c intrin.c ir.c lexer.c main.c opts.c parser.c stat.c utf8.c util.c diff --git a/ansi.c b/ansi.c index 1317e15..02db1b9 100644 --- a/ansi.c +++ b/ansi.c @@ -20,37 +20,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#define GMQCC_PLATFORM_HEADER #include #include #include "platform.h" #include "gmqcc.h" -int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg) { - return vsnprintf(buffer, bytes, format, arg); -} - -int platform_vsscanf(const char *str, const char *format, va_list arg) { - return vsscanf(str, format, arg); -} - -const struct tm *platform_localtime(const time_t *timer) { - return localtime(timer); -} - -const char *platform_ctime(const time_t *timer) { - return ctime(timer); -} - -char *platform_strncat(char *dest, const char *src, size_t num) { - return strncat(dest, src, num); -} - -const char *platform_getenv(const char *var) { - return getenv(var); -} - int platform_vasprintf(char **dat, const char *fmt, va_list args) { int ret; int len; @@ -80,88 +55,3 @@ int platform_vasprintf(char **dat, const char *fmt, va_list args) { *dat = tmp; return len; } - -char *platform_strcat(char *dest, const char *src) { - return strcat(dest, src); -} - -char *platform_strncpy(char *dest, const char *src, size_t num) { - return strncpy(dest, src, num); -} - -const char *platform_strerror(int err) { - return strerror(err); -} - -FILE *platform_fopen(const char *filename, const char *mode) { - return fopen(filename, mode); -} - -size_t platform_fread(void *ptr, size_t size, size_t count, FILE *stream) { - return fread(ptr, size, count, stream); -} - -size_t platform_fwrite(const void *ptr, size_t size, size_t count, FILE *stream) { - return fwrite(ptr, size, count, stream); -} - -int platform_fflush(FILE *stream) { - return fflush(stream); -} - -int platform_vfprintf(FILE *stream, const char *format, va_list arg) { - return vfprintf(stream, format, arg); -} - -int platform_fclose(FILE *stream) { - return fclose(stream); -} - -int platform_ferror(FILE *stream) { - return ferror(stream); -} - -int platform_fgetc(FILE *stream) { - return fgetc(stream); -} - -int platform_fputs(const char *str, FILE *stream) { - return fputs(str, stream); -} - -int platform_fseek(FILE *stream, long offset, int origin) { - return fseek(stream, offset, origin); -} - -long platform_ftell(FILE *stream) { - return ftell(stream); -} - -int platform_mkdir(const char *path, int mode) { - /* - * For some reason mingw32 just doesn't have a correct mkdir impl - * so we handle that here. - */ -# ifdef _WIN32 - (void)mode; - return mkdir(path); -# else - return mkdir(path, mode); -# endif /*!_WIN32*/ -} - -DIR *platform_opendir(const char *path) { - return opendir(path); -} - -int platform_closedir(DIR *dir) { - return closedir(dir); -} - -struct dirent *platform_readdir(DIR *dir) { - return readdir(dir); -} - -int platform_isatty(int fd) { - return isatty(fd); -} diff --git a/code.c b/code.c index 6f040ce..811b085 100644 --- a/code.c +++ b/code.c @@ -393,14 +393,14 @@ static bool code_write_memory(code_t *code, uint8_t **datmem, size_t *sizedat, u bool code_write(code_t *code, const char *filename, const char *lnofile) { prog_header_t code_header; - fs_file_t *fp = NULL; + FILE *fp = NULL; code_create_header(code, &code_header, filename, lnofile); if (lnofile) { uint32_t version = 1; - fp = fs_file_open(lnofile, "wb"); + fp = fopen(lnofile, "wb"); if (!fp) return false; @@ -408,39 +408,39 @@ bool code_write(code_t *code, const char *filename, const char *lnofile) { util_endianswap(code->linenums, vec_size(code->linenums), sizeof(code->linenums[0])); util_endianswap(code->columnnums, vec_size(code->columnnums), sizeof(code->columnnums[0])); - if (fs_file_write("LNOF", 4, 1, fp) != 1 || - fs_file_write(&version, sizeof(version), 1, fp) != 1 || - fs_file_write(&code_header.defs.length, sizeof(code_header.defs.length), 1, fp) != 1 || - fs_file_write(&code_header.globals.length, sizeof(code_header.globals.length), 1, fp) != 1 || - fs_file_write(&code_header.fields.length, sizeof(code_header.fields.length), 1, fp) != 1 || - fs_file_write(&code_header.statements.length, sizeof(code_header.statements.length), 1, fp) != 1 || - fs_file_write(code->linenums, sizeof(code->linenums[0]), vec_size(code->linenums), fp) != vec_size(code->linenums) || - fs_file_write(code->columnnums, sizeof(code->columnnums[0]), vec_size(code->columnnums), fp) != vec_size(code->columnnums)) + if (fwrite("LNOF", 4, 1, fp) != 1 || + fwrite(&version, sizeof(version), 1, fp) != 1 || + fwrite(&code_header.defs.length, sizeof(code_header.defs.length), 1, fp) != 1 || + fwrite(&code_header.globals.length, sizeof(code_header.globals.length), 1, fp) != 1 || + fwrite(&code_header.fields.length, sizeof(code_header.fields.length), 1, fp) != 1 || + fwrite(&code_header.statements.length, sizeof(code_header.statements.length), 1, fp) != 1 || + fwrite(code->linenums, sizeof(code->linenums[0]), vec_size(code->linenums), fp) != vec_size(code->linenums) || + fwrite(code->columnnums, sizeof(code->columnnums[0]), vec_size(code->columnnums), fp) != vec_size(code->columnnums)) { con_err("failed to write lno file\n"); } - fs_file_close(fp); + fclose(fp); fp = NULL; } - fp = fs_file_open(filename, "wb"); + fp = fopen(filename, "wb"); if (!fp) return false; - if (1 != fs_file_write(&code_header, sizeof(prog_header_t) , 1 , fp) || - vec_size(code->statements) != fs_file_write(code->statements, sizeof(prog_section_statement_t), vec_size(code->statements), fp) || - vec_size(code->defs) != fs_file_write(code->defs, sizeof(prog_section_def_t) , vec_size(code->defs) , fp) || - vec_size(code->fields) != fs_file_write(code->fields, sizeof(prog_section_field_t) , vec_size(code->fields) , fp) || - vec_size(code->functions) != fs_file_write(code->functions, sizeof(prog_section_function_t) , vec_size(code->functions) , fp) || - vec_size(code->globals) != fs_file_write(code->globals, sizeof(int32_t) , vec_size(code->globals) , fp) || - vec_size(code->chars) != fs_file_write(code->chars, 1 , vec_size(code->chars) , fp)) + if (1 != fwrite(&code_header, sizeof(prog_header_t) , 1 , fp) || + vec_size(code->statements) != fwrite(code->statements, sizeof(prog_section_statement_t), vec_size(code->statements), fp) || + vec_size(code->defs) != fwrite(code->defs, sizeof(prog_section_def_t) , vec_size(code->defs) , fp) || + vec_size(code->fields) != fwrite(code->fields, sizeof(prog_section_field_t) , vec_size(code->fields) , fp) || + vec_size(code->functions) != fwrite(code->functions, sizeof(prog_section_function_t) , vec_size(code->functions) , fp) || + vec_size(code->globals) != fwrite(code->globals, sizeof(int32_t) , vec_size(code->globals) , fp) || + vec_size(code->chars) != fwrite(code->chars, 1 , vec_size(code->chars) , fp)) { - fs_file_close(fp); + fclose(fp); return false; } - fs_file_close(fp); + fclose(fp); code_stats(filename, lnofile, code, &code_header); return true; } diff --git a/conout.c b/conout.c index c4c285b..0ee110b 100644 --- a/conout.c +++ b/conout.c @@ -23,21 +23,17 @@ #include #include "gmqcc.h" -#define GMQCC_IS_STDOUT(X) ((fs_file_t*)((void*)X) == (fs_file_t*)stdout) -#define GMQCC_IS_STDERR(X) ((fs_file_t*)((void*)X) == (fs_file_t*)stderr) +#define GMQCC_IS_STDOUT(X) ((X) == stdout) +#define GMQCC_IS_STDERR(X) ((X) == stderr) #define GMQCC_IS_DEFINE(X) (GMQCC_IS_STDERR(X) || GMQCC_IS_STDOUT(X)) typedef struct { - fs_file_t *handle_err; - fs_file_t *handle_out; - int color_err; - int color_out; + FILE *handle_err; + FILE *handle_out; + int color_err; + int color_out; } con_t; -/* - * We use standard files as default. These can be changed at any time - * with con_change(F, F) - */ static con_t console; /* @@ -58,8 +54,8 @@ static void con_enablecolor(void) { * arguments. This colorizes for windows as well via translate * step. */ -static int con_write(fs_file_t *handle, const char *fmt, va_list va) { - return vfprintf((FILE*)handle, fmt, va); +static int con_write(FILE *handle, const char *fmt, va_list va) { + return vfprintf(handle, fmt, va); } /********************************************************************** @@ -68,9 +64,9 @@ static int con_write(fs_file_t *handle, const char *fmt, va_list va) { void con_close() { if (!GMQCC_IS_DEFINE(console.handle_err)) - fs_file_close(console.handle_err); + fclose(console.handle_err); if (!GMQCC_IS_DEFINE(console.handle_out)) - fs_file_close(console.handle_out); + fclose(console.handle_out); } void con_color(int state) { @@ -83,54 +79,26 @@ void con_color(int state) { } void con_init() { - console.handle_err = (fs_file_t*)stderr; - console.handle_out = (fs_file_t*)stdout; + console.handle_err = stderr; + console.handle_out = stdout; con_enablecolor(); } void con_reset() { con_close(); - con_init (); -} - -/* - * This is clever, say you want to change the console to use two - * files for out/err. You pass in two strings, it will properly - * close the existing handles (if they're not std* handles) and - * open them. Now say you want TO use stdout and stderr, this - * allows you to do that so long as you cast them to (char*). - * Say you need stdout for out, but want a file for error, you can - * do this too, just cast the stdout for (char*) and stick to a - * string for the error file. - */ -int con_change(const char *out, const char *err) { - con_close(); - - if (!out) out = (const char *)((!console.handle_out) ? (fs_file_t*)stdout : console.handle_out); - if (!err) err = (const char *)((!console.handle_err) ? (fs_file_t*)stderr : console.handle_err); - - if (GMQCC_IS_DEFINE(out)) { - console.handle_out = (fs_file_t*)(GMQCC_IS_STDOUT(out) ? stdout : stderr); - con_enablecolor(); - } else if (!(console.handle_out = fs_file_open(out, "w"))) return 0; - - if (GMQCC_IS_DEFINE(err)) { - console.handle_err = (fs_file_t*)(GMQCC_IS_STDOUT(err) ? stdout : stderr); - con_enablecolor(); - } else if (!(console.handle_err = fs_file_open(err, "w"))) return 0; - - return 1; + con_init(); } /* * Defaultizer because stdio.h shouldn't be used anywhere except here * and inside file.c To prevent mis-match of wrapper-interfaces. */ -fs_file_t *con_default_out() { - return (fs_file_t*)(console.handle_out = (fs_file_t*)stdout); +FILE *con_default_out() { + return console.handle_out = stdout; } -fs_file_t *con_default_err() { - return (fs_file_t*)(console.handle_err = (fs_file_t*)stderr); + +FILE *con_default_err() { + return console.handle_err = stderr; } int con_verr(const char *fmt, va_list va) { @@ -145,20 +113,20 @@ int con_vout(const char *fmt, va_list va) { * to be used. */ int con_err(const char *fmt, ...) { - va_list va; - int ln = 0; + va_list va; + int ln = 0; va_start(va, fmt); con_verr(fmt, va); - va_end (va); - return ln; + va_end(va); + return ln; } int con_out(const char *fmt, ...) { - va_list va; - int ln = 0; + va_list va; + int ln = 0; va_start(va, fmt); con_vout(fmt, va); - va_end (va); - return ln; + va_end (va); + return ln; } /* diff --git a/exec.c b/exec.c index 455a6c5..47b9edf 100644 --- a/exec.c +++ b/exec.c @@ -56,7 +56,7 @@ qc_program_t* prog_load(const char *filename, bool skipversion) prog_header_t header; qc_program_t *prog; size_t i; - fs_file_t *file = fs_file_open(filename, "rb"); + FILE *file = fopen(filename, "rb"); /* we need all those in order to support INSTR_STATE: */ bool has_self = false, @@ -68,9 +68,9 @@ qc_program_t* prog_load(const char *filename, bool skipversion) if (!file) return NULL; - if (fs_file_read(&header, sizeof(header), 1, file) != 1) { + if (fread(&header, sizeof(header), 1, file) != 1) { loaderror("failed to read header from '%s'", filename); - fs_file_close(file); + fclose(file); return NULL; } @@ -78,13 +78,13 @@ qc_program_t* prog_load(const char *filename, bool skipversion) if (!skipversion && header.version != 6) { loaderror("header says this is a version %i progs, we need version 6\n", header.version); - fs_file_close(file); + fclose(file); return NULL; } prog = (qc_program_t*)mem_a(sizeof(qc_program_t)); if (!prog) { - fs_file_close(file); + fclose(file); fprintf(stderr, "failed to allocate program data\n"); return NULL; } @@ -100,11 +100,11 @@ qc_program_t* prog_load(const char *filename, bool skipversion) } #define read_data(hdrvar, progvar, reserved) \ - if (fs_file_seek(file, header.hdrvar.offset, SEEK_SET) != 0) { \ + if (fseek(file, header.hdrvar.offset, SEEK_SET) != 0) { \ loaderror("seek failed"); \ goto error; \ } \ - if (fs_file_read ( \ + if (fread( \ vec_add(prog->progvar, header.hdrvar.length + reserved), \ sizeof(*prog->progvar), \ header.hdrvar.length, \ @@ -130,7 +130,7 @@ qc_program_t* prog_load(const char *filename, bool skipversion) util_swap_functions (prog->functions); util_swap_globals (prog->globals); - fs_file_close(file); + fclose(file); /* profile counters */ memset(vec_add(prog->profile, vec_size(prog->code)), 0, sizeof(prog->profile[0]) * vec_size(prog->code)); @@ -190,7 +190,7 @@ error: vec_free(prog->entitypool); mem_d(prog); - fs_file_close(file); + fclose(file); return NULL; } @@ -397,7 +397,7 @@ static void trace_print_global(qc_program_t *prog, unsigned int glob, int vtype) done: if (len < (int)sizeof(spaces)-1) { spaces[sizeof(spaces)-1-len] = 0; - fs_file_puts((fs_file_t*)stdout, spaces); + fputs(spaces, stdout); spaces[sizeof(spaces)-1-len] = ' '; } } diff --git a/fs.c b/fs.c index 1e06ecc..4c7a178 100644 --- a/fs.c +++ b/fs.c @@ -20,76 +20,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#define GMQCC_PLATFORM_HEADER #include "gmqcc.h" -#include "platform.h" -fs_file_t *fs_file_open(const char *filename, const char *mode) { - return (fs_file_t*)platform_fopen(filename, mode); -} - -size_t fs_file_read(void *buffer, size_t size, size_t count, fs_file_t *fp) { - return platform_fread(buffer, size, count, (FILE*)fp); -} - -int fs_file_printf(fs_file_t *fp, const char *format, ...) { - int rt; - va_list va; - va_start(va, format); - rt = platform_vfprintf((FILE*)fp, format, va); - va_end (va); - - return rt; -} - -void fs_file_close(fs_file_t *fp) { - platform_fclose((FILE*)fp); -} - -size_t fs_file_write ( - const void *buffer, - size_t size, - size_t count, - fs_file_t *fp -) { - return platform_fwrite(buffer, size, count, (FILE*)fp); -} - -int fs_file_error(fs_file_t *fp) { - return platform_ferror((FILE*)fp); -} - -int fs_file_getc(fs_file_t *fp) { - int get = platform_fgetc((FILE*)fp); - return (get == EOF) ? FS_FILE_EOF : get; -} - -int fs_file_puts(fs_file_t *fp, const char *str) { - return platform_fputs(str, (FILE*)fp); -} - -int fs_file_seek(fs_file_t *fp, long int off, int whence) { - switch(whence) { - case FS_FILE_SEEK_CUR: whence = SEEK_CUR; break; - case FS_FILE_SEEK_SET: whence = SEEK_SET; break; - case FS_FILE_SEEK_END: whence = SEEK_END; break; - } - return platform_fseek((FILE*)fp, off, whence); -} - -long int fs_file_tell(fs_file_t *fp) { - return platform_ftell((FILE*)fp); -} - -int fs_file_flush(fs_file_t *fp) { - return platform_fflush((FILE*)fp); -} - -/* - * Implements libc getline for systems that don't have it, which is - * assmed all. This works the same as getline(). - */ -int fs_file_getline(char **lineptr, size_t *n, fs_file_t *stream) { +int fs_file_getline(char **lineptr, size_t *n, FILE *stream) { int chr; int ret; char *pos; @@ -105,7 +38,7 @@ int fs_file_getline(char **lineptr, size_t *n, fs_file_t *stream) { pos = *lineptr; for (;;) { - int c = fs_file_getc(stream); + int c = getc(stream); if (chr < 2) { *n += (*n > 16) ? *n : 64; @@ -115,7 +48,7 @@ int fs_file_getline(char **lineptr, size_t *n, fs_file_t *stream) { pos = *n - chr + *lineptr; } - if (fs_file_error(stream)) + if (ferror(stream)) return -1; if (c == EOF) { if (pos == *lineptr) @@ -132,19 +65,3 @@ int fs_file_getline(char **lineptr, size_t *n, fs_file_t *stream) { *pos = '\0'; return (ret = pos - *lineptr); } - -int fs_dir_make(const char *path) { - return platform_mkdir(path, 0700); -} - -fs_dir_t *fs_dir_open(const char *name) { - return (fs_dir_t*)platform_opendir(name); -} - -int fs_dir_close(fs_dir_t *dir) { - return platform_closedir((DIR*)dir); -} - -fs_dirent_t *fs_dir_read(fs_dir_t *dir) { - return (fs_dirent_t*)platform_readdir((DIR*)dir); -} diff --git a/ftepp.c b/ftepp.c index d2c01df..a94eb11 100644 --- a/ftepp.c +++ b/ftepp.c @@ -1323,7 +1323,7 @@ static void unescape(const char *str, char *out) { static char *ftepp_include_find_path(const char *file, const char *pathfile) { - fs_file_t *fp; + FILE *fp; char *filename = NULL; const char *last_slash; size_t len; @@ -1343,9 +1343,9 @@ static char *ftepp_include_find_path(const char *file, const char *pathfile) memcpy(vec_add(filename, len+1), file, len); vec_last(filename) = 0; - fp = fs_file_open(filename, "rb"); + fp = fopen(filename, "rb"); if (fp) { - fs_file_close(fp); + fclose(fp); return filename; } vec_free(filename); diff --git a/gmqcc.h b/gmqcc.h index e609257..235059d 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #define GMQCC_VERSION_MAJOR 0 @@ -233,9 +234,7 @@ const char *util_strerror(int err); const struct tm *util_localtime(const time_t *timer); const char *util_ctime (const time_t *timer); -typedef struct fs_file_s fs_file_t; - -bool util_isatty(fs_file_t *); +bool util_isatty(FILE *); size_t hash(const char *key); /* @@ -326,34 +325,7 @@ int util_snprintf(char *str, size_t, const char *fmt, ...); /* fs.c */ -#define FS_FILE_SEEK_SET 0 -#define FS_FILE_SEEK_CUR 1 -#define FS_FILE_SEEK_END 2 -#define FS_FILE_EOF -1 - -typedef struct fs_dir_s fs_dir_t; -/*typedef struct fs_file_s fs_file_t;*/ -typedef struct dirent fs_dirent_t; - -void fs_file_close (fs_file_t *); -int fs_file_error (fs_file_t *); -int fs_file_getc (fs_file_t *); -int fs_file_printf (fs_file_t *, const char *, ...); -int fs_file_puts (fs_file_t *, const char *); -int fs_file_seek (fs_file_t *, long int, int); -long fs_file_tell (fs_file_t *); -int fs_file_flush (fs_file_t *); - -size_t fs_file_read (void *, size_t, size_t, fs_file_t *); -size_t fs_file_write (const void *, size_t, size_t, fs_file_t *); - -fs_file_t *fs_file_open (const char *, const char *); -int fs_file_getline(char **, size_t *, fs_file_t *); - -int fs_dir_make (const char *); -fs_dir_t *fs_dir_open (const char *); -int fs_dir_close (fs_dir_t *); -fs_dirent_t *fs_dir_read (fs_dir_t *); +int fs_file_getline(char **, size_t *, FILE *); /* code.c */ @@ -676,8 +648,8 @@ enum { LVL_ERROR }; -fs_file_t *con_default_out(void); -fs_file_t *con_default_err(void); +FILE *con_default_out(void); +FILE *con_default_err(void); void con_vprintmsg (int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, va_list ap); void con_printmsg (int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, ...); @@ -688,7 +660,6 @@ void con_close (void); void con_init (void); void con_reset (void); void con_color (int); -int con_change(const char *, const char *); int con_verr (const char *, va_list); int con_vout (const char *, va_list); int con_err (const char *, ...); diff --git a/lexer.c b/lexer.c index a495d27..e5684c0 100644 --- a/lexer.c +++ b/lexer.c @@ -99,7 +99,7 @@ static int lex_getch(lex_file *lex); lex_file* lex_open(const char *file) { lex_file *lex; - fs_file_t *in = fs_file_open(file, "rb"); + FILE *in = fopen(file, "rb"); uint32_t read; if (!in) { @@ -109,7 +109,7 @@ lex_file* lex_open(const char *file) lex = (lex_file*)mem_a(sizeof(*lex)); if (!lex) { - fs_file_close(in); + fclose(in); lexerror(NULL, "out of memory\n"); return NULL; } @@ -187,7 +187,7 @@ void lex_close(lex_file *lex) vec_free(lex->modelname); if (lex->file) - fs_file_close(lex->file); + fclose(lex->file); vec_free(lex->tok.value); @@ -201,15 +201,15 @@ static int lex_fgetc(lex_file *lex) { if (lex->file) { lex->column++; - return fs_file_getc(lex->file); + return fgetc(lex->file); } if (lex->open_string) { if (lex->open_string_pos >= lex->open_string_length) - return FS_FILE_EOF; + return EOF; lex->column++; return lex->open_string[lex->open_string_pos++]; } - return FS_FILE_EOF; + return EOF; } /* Get or put-back data @@ -424,7 +424,7 @@ static bool lex_try_pragma(lex_file *lex) goto unroll; lex->line = line; - while (ch != '\n' && ch != FS_FILE_EOF) + while (ch != '\n' && ch != EOF) ch = lex_getch(lex); vec_free(command); vec_free(param); @@ -504,7 +504,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) do { ch = lex_getch(lex); - while (ch != FS_FILE_EOF && util_isspace(ch)) { + while (ch != EOF && util_isspace(ch)) { if (ch == '\n') { if (lex_try_pragma(lex)) continue; @@ -540,7 +540,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) lex_tokench(lex, ' '); } - while (ch != FS_FILE_EOF && ch != '\n') { + while (ch != EOF && ch != '\n') { if (lex->flags.preprocessing) lex_tokench(lex, ' '); /* ch); */ ch = lex_getch(lex); @@ -561,7 +561,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) lex_tokench(lex, ' '); } - while (ch != FS_FILE_EOF) + while (ch != EOF) { ch = lex_getch(lex); if (ch == '*') { @@ -590,7 +590,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) ch = '/'; break; } - } while (ch != FS_FILE_EOF && util_isspace(ch)); + } while (ch != EOF && util_isspace(ch)); if (haswhite) { lex_endtoken(lex); @@ -606,7 +606,7 @@ static bool GMQCC_WARN lex_finish_ident(lex_file *lex) int ch; ch = lex_getch(lex); - while (ch != FS_FILE_EOF && isident(ch)) + while (ch != EOF && isident(ch)) { lex_tokench(lex, ch); ch = lex_getch(lex); @@ -626,7 +626,7 @@ static int lex_parse_frame(lex_file *lex) lex_token_new(lex); ch = lex_getch(lex); - while (ch != FS_FILE_EOF && ch != '\n' && util_isspace(ch)) + while (ch != EOF && ch != '\n' && util_isspace(ch)) ch = lex_getch(lex); if (ch == '\n') @@ -688,7 +688,7 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) char u8buf[8]; /* way more than enough */ int u8len, uc; - while (ch != FS_FILE_EOF) + while (ch != EOF) { ch = lex_getch(lex); if (ch == quote) @@ -697,18 +697,18 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) if (lex->flags.preprocessing && ch == '\\') { lex_tokench(lex, ch); ch = lex_getch(lex); - if (ch == FS_FILE_EOF) { + if (ch == EOF) { lexerror(lex, "unexpected end of file"); - lex_ungetch(lex, FS_FILE_EOF); /* next token to be TOKEN_EOF */ + lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */ return (lex->tok.ttype = TOKEN_ERROR); } lex_tokench(lex, ch); } else if (ch == '\\') { ch = lex_getch(lex); - if (ch == FS_FILE_EOF) { + if (ch == EOF) { lexerror(lex, "unexpected end of file"); - lex_ungetch(lex, FS_FILE_EOF); /* next token to be TOKEN_EOF */ + lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */ return (lex->tok.ttype = TOKEN_ERROR); } @@ -846,7 +846,7 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) lex_tokench(lex, ch); } lexerror(lex, "unexpected end of file within string constant"); - lex_ungetch(lex, FS_FILE_EOF); /* next token to be TOKEN_EOF */ + lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */ return (lex->tok.ttype = TOKEN_ERROR); } @@ -963,7 +963,7 @@ int lex_do(lex_file *lex) if (lex->eof) return (lex->tok.ttype = TOKEN_FATAL); - if (ch == FS_FILE_EOF) { + if (ch == EOF) { lex->eof = true; return (lex->tok.ttype = TOKEN_EOF); } @@ -1000,7 +1000,7 @@ int lex_do(lex_file *lex) if (!strcmp(v, "framevalue")) { ch = lex_getch(lex); - while (ch != FS_FILE_EOF && util_isspace(ch) && ch != '\n') + while (ch != EOF && util_isspace(ch) && ch != '\n') ch = lex_getch(lex); if (!util_isdigit(ch)) { @@ -1080,7 +1080,7 @@ int lex_do(lex_file *lex) vec_free(lex->frames); /* skip line (fteqcc does it too) */ ch = lex_getch(lex); - while (ch != FS_FILE_EOF && ch != '\n') + while (ch != EOF && ch != '\n') ch = lex_getch(lex); return lex_do(lex); } @@ -1094,7 +1094,7 @@ int lex_do(lex_file *lex) { /* skip line */ ch = lex_getch(lex); - while (ch != FS_FILE_EOF && ch != '\n') + while (ch != EOF && ch != '\n') ch = lex_getch(lex); return lex_do(lex); } diff --git a/lexer.h b/lexer.h index 07fa5d7..2d5ec0d 100644 --- a/lexer.h +++ b/lexer.h @@ -107,7 +107,7 @@ typedef struct { } frame_macro; typedef struct lex_file_s { - fs_file_t *file; + FILE *file; const char *open_string; size_t open_string_length; size_t open_string_pos; diff --git a/main.c b/main.c index 41828c7..9f64baf 100644 --- a/main.c +++ b/main.c @@ -223,14 +223,6 @@ static bool options_parse(int argc, char **argv) { opts_set(opts.flags, EMULATE_STATE, true); continue; } - if (options_long_gcc("redirout", &argc, &argv, &redirout)) { - con_change(redirout, redirerr); - continue; - } - if (options_long_gcc("redirerr", &argc, &argv, &redirerr)) { - con_change(redirout, redirerr); - continue; - } if (options_long_gcc("config", &argc, &argv, &argarg)) { config = argarg; continue; @@ -532,7 +524,7 @@ static bool options_parse(int argc, char **argv) { } /* returns the line number, or -1 on error */ -static bool progs_nextline(char **out, size_t *alen, fs_file_t *src) { +static bool progs_nextline(char **out, size_t *alen, FILE *src) { int len; char *line; char *start; @@ -562,7 +554,7 @@ int main(int argc, char **argv) { int retval = 0; bool operators_free = false; bool progs_src = false; - fs_file_t *outfile = NULL; + FILE *outfile = NULL; struct parser_s *parser = NULL; struct ftepp_s *ftepp = NULL; @@ -626,7 +618,7 @@ int main(int argc, char **argv) { if (OPTS_OPTION_BOOL(OPTION_PP_ONLY)) { if (opts_output_wasset) { - outfile = fs_file_open(OPTS_OPTION_STR(OPTION_OUTPUT), "wb"); + outfile = fopen(OPTS_OPTION_STR(OPTION_OUTPUT), "wb"); if (!outfile) { con_err("failed to open `%s` for writing\n", OPTS_OPTION_STR(OPTION_OUTPUT)); retval = 1; @@ -667,14 +659,14 @@ int main(int argc, char **argv) { } if (!vec_size(items)) { - fs_file_t *src; + FILE *src; char *line = NULL; size_t linelen = 0; bool hasline = false; progs_src = true; - src = fs_file_open(OPTS_OPTION_STR(OPTION_PROGSRC), "rb"); + src = fopen(OPTS_OPTION_STR(OPTION_PROGSRC), "rb"); if (!src) { con_err("failed to open `%s` for reading\n", OPTS_OPTION_STR(OPTION_PROGSRC)); retval = 1; @@ -697,7 +689,7 @@ int main(int argc, char **argv) { } } - fs_file_close(src); + fclose(src); mem_d(line); } @@ -729,7 +721,7 @@ int main(int argc, char **argv) { } out = ftepp_get(ftepp); if (out) - fs_file_printf(outfile, "%s", out); + fprintf(outfile, "%s", out); ftepp_flush(ftepp); } else { diff --git a/opts.c b/opts.c index 3f5c25b..116792f 100644 --- a/opts.c +++ b/opts.c @@ -216,7 +216,7 @@ static char *opts_ini_next(const char *s, char c) { } static size_t opts_ini_parse ( - fs_file_t *filehandle, + FILE *filehandle, char *(*loadhandle)(const char *, const char *, const char *, char **), char **errorhandle, char **parse_file @@ -234,7 +234,7 @@ static size_t opts_ini_parse ( char *read_name; char *read_value; - while (fs_file_getline(&line, &linesize, filehandle) != FS_FILE_EOF) { + while (fs_file_getline(&line, &linesize, filehandle) != EOF) { parse_beg = line; /* handle BOM */ @@ -330,7 +330,7 @@ static char *opts_ini_load(const char *section, const char *name, const char *va if (!strcmp(section, "includes")) { static const char *include_error_beg = "failed to open file `"; static const char *include_error_end = "' for inclusion"; - fs_file_t *file = fs_file_open(value, "r"); + FILE *file = fopen(value, "r"); found = true; if (!file) { vec_append(error, strlen(include_error_beg), include_error_beg); @@ -342,7 +342,7 @@ static char *opts_ini_load(const char *section, const char *name, const char *va /* Change the file name */ mem_d(*parse_file); *parse_file = util_strdup(value); - fs_file_close(file); + fclose(file); } } @@ -423,15 +423,15 @@ void opts_ini_init(const char *file) { char *error = NULL; char *parse_file = NULL; size_t line; - fs_file_t *ini; + FILE *ini; if (!file) { /* try ini */ - if (!(ini = fs_file_open((file = "gmqcc.ini"), "r"))) + if (!(ini = fopen((file = "gmqcc.ini"), "r"))) /* try cfg */ - if (!(ini = fs_file_open((file = "gmqcc.cfg"), "r"))) + if (!(ini = fopen((file = "gmqcc.cfg"), "r"))) return; - } else if (!(ini = fs_file_open(file, "r"))) + } else if (!(ini = fopen(file, "r"))) return; con_out("found ini file `%s`\n", file); @@ -444,5 +444,5 @@ void opts_ini_init(const char *file) { } mem_d(parse_file); - fs_file_close(ini); + fclose(ini); } diff --git a/platform.h b/platform.h index 57ba352..f4bd9ef 100644 --- a/platform.h +++ b/platform.h @@ -24,531 +24,14 @@ #ifndef GMQCC_PLATFORM_HDR #define GMQCC_PLATFORM_HDR -#ifndef GMQCC_PLATFORM_HEADER -# error "This header shouldn't be included!" -#endif - -#undef GMQCC_PLATFORM_HEADER #include #include #include -#ifdef _WIN32 -# ifndef STDERR_FILENO -# define STDERR_FILENO 2 -# endif -# ifndef STDOUT_FILENO -# define STDOUT_FILENO 1 -# endif -# ifndef __MINGW32__ -# define _WIN32_LEAN_AND_MEAN -# include -# include -# include - - struct dirent { - long d_ino; - unsigned short d_reclen; - unsigned short d_namlen; - char d_name[FILENAME_MAX]; - }; - - typedef struct { - struct _finddata_t dd_dta; - struct dirent dd_dir; - long dd_handle; - int dd_stat; - char dd_name[1]; - } DIR; -# else -# include -# endif /*!__MINGW32__*/ - -# ifndef S_ISDIR -# define S_ISDIR(X) ((X)&_S_IFDIR) -# endif -#else -# include -# include -# include -# include -#endif /*!_WIN32*/ - -/* - * Function: platform_vsnprintf - * Write formatted output using a pointer to a lis of arguments. - * - * Parameters: - * buffer - Storage location for output. - * bytes - Maximum number of characters to write. - * format - Format specification. - * arg - Variable argument list. - * - * Returns: - * The number of characters written if the number of characters to write - * is less than or equal to `bytes`; if the number of characters to write - * is greater than `bytes`, this function returns -1 indicating that the - * output has been truncated. The return value does not include the - * terminating null, if one is written. - * - * Remarks: - * Function takes pointer to an argument list, then formats the data, - * and writes up to `bytes` characters to the memory pointed to by - * `buffer`. If there is room at the end (that is, if the number of - * character to write is less than `bytes`), the buffer will be null-terminated. - */ -int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg); - -/* - * Function: platform_vsscanf - * Reads formatted data from a string. - * - * Parameters: - * buffer - Stored data to read. - * format - Format specification. - * arg - Variable argument list. - * - * Returns: - * The number of fields that are successfully converted and assigned; - * the return value does not include fields that were read but not - * assigned. A return vlaue of 0 indicated that no fields were assigned. - * The return value if EOF for error or if the end of the string is - * reached before the first conversion. - * - * Remarks: - * Reads data from `buffer` into the locations that are given by each - * argument in the `arg` argument list. Every argument in the list must - * be a pointer to a variable that has a type that corresponds to a - * type specifier in `format`. The `format` argument controls th - * interpretation of the input fields and has the same form and function - * as the `format` argument for the *scanf* function. If copying takes - * place between strings that overlap, the behaviour is undefined. - */ -int platform_vsscanf(const char *buffer, const char *format, va_list arg); - -/* - * Function: platform_localtime - * Convert a time value and correct for the local time zone. - * - * Parameters - * timer - Pointer to stored time. - * - * Returns: - * A pointer to a structure result, or NULL if the date passed to - * the function is before midnight, January 1, 1970. - */ -const struct tm *platform_localtime(const time_t *timer); - -/* - * Function: platform_ctime - * Convert a time value to a string and adjust for local time zone - * settings. - * - * Parameters: - * timer - Pointer to stored time. - * - * Returns: - * Pointer to the character string result. NULL will be returned if time - * represents a date before midnight, January 1, 1970, UTC. - * - * Remarks: - * Converts a time value stored as a `time_t` value into a chracter string. - * The `timer` value is usually obtained from a call to *time*, which returns - * the number of seconds since midnight, January 1, 1970 UTC. The return - * value of the string contains exactly 26 characters. A 24-hour clock is used. - * All fields have constant width. The newline chracter and the null character - * occupy the last two positions of the string. The converted character string - * is also adjusted according to the local time zone settings. - */ -const char *platform_ctime(const time_t *timer); - -/* - * Function: platform_strncat - * Append characters of a string. - * - * Parameters: - * dest - Null terminated destination string - * src - Source string - * num - Number of characters to append - * - * Returns: - * Pointer to the destination string. No return value is used to indicate - * an error. - * - * Remarks: - * Function appends, at mode, the first `num` characters of `src` to - * `dest`. The initial character of `src` overwrites the terminating - * null chracter of `dest`. If a null character appears in `src` before - * `num` chracters are appended, `platform_strncat` appends all chracters - * from `src`, up to the null chracter. If `num` is greater than the - * length of `src`, the length of `src` is used in place of `num`. - */ -char *platform_strncat(char *dest, const char *src, size_t num); - -/* - * Function: platform_getenv - * Get a value from the current enviroment. - * - * Parameters: - * var - Enviroment variable name - * - * Returns: - * A pointer to the enviroment table entry containing `var. It's not - * safe to modify the value of the enviroment variable using the returned - * pointer. The return value is *NULL* if `var` is not found in the - * enviroment table. - */ -const char *platform_getenv(const char *var); +#include +#include +#include -/* - * Function: platform_vasprintf - * Print to allocated string - * - * Parameters: - * dat - Pointer to pointer to store allocated data. - * fmt - Format specification. - * args - Variable argument list. - * - * Returns: - * Number of character written, -1 is used to indicate an error. - * - * Remarks: - * Allocate a string large enough to hold the output including - * the terminating null character than write formatted output - * to it using format specification. - */ int platform_vasprintf(char **dat, const char *fmt, va_list args); -/* - * Function: platform_vfprintf - * Write formatted output using a pointer to a list of arguments. - * - * Parameters: - * stream - Pointer to stream. - * format - Format specification. - * atrg - Variable argument list. - * - * Returns: - * Number of characters written, not including the terminating null - * character, or a negitive value if an output error occurs. -1 is - * also used to indicate an error. - * - * Remarks: - * Takes a pointer to an argument list, then formats and writes the - * given data to `stream`. - */ -int platform_vfprintf(FILE *stream, const char *format, va_list arg); - -/* - * Function: platform_strcat - * Append characters of a string. - * - * Parameters: - * dest - Null terminated destination string - * src - Source string - * - * Returns: - * Pointer to the destination string. No return value is used to indicate - * an error. - * - * Remarks: - * Appens `src` to `dest` and terminates with resulting null character. - * The initial character of `src` overwrites the terminating null - * character of `dest`. The behaviour of platform_strcat is undefined - * if the source and destination string overlap. - */ -char *platform_strcat(char *dest, const char *src); - -/* - * Function: platform_strncpy - * Copys characters of one string to another. - * - * Parameters: - * dest - Destination string. - * src - Source string. - * num - Number of characters to be copied. - * - * Returns: - * `dest`. No return value is reserved to indicate an error. - * - * Remarks: - * Copies the initial characters of `src` to `dest` and returns `dest`. - * If `num` is less than or equal to the length of `src1 a null character - * is not appended automatically to the copied string. If `num` is greater - * than the length of `src`, the destination string is padded with null - * characters up to length `num`. The behaviour of this function is undefined - * if the source and destination strings overlap. - */ -char *platform_strncpy(char *dest, const char *src, size_t num); - -/* - * Function: platform_strerror - * Get a system error message - * - * Parameters: - * err - Error number. - * - * Returns: - * A pointer to the error message - */ -const char *platform_strerror(int err); - -/* - * Function: platform_fopen - * Opens a file - * - * Parameters: - * filename - File name. - * mode - Kind of access that's enabled. - * - * Returns: - * A pointer to the open file. A null pointer value indicates an error. - */ -FILE *platform_fopen(const char *filename, const char *mode); - -/* - * Function: platform_fread - * Reads data from a stream - * - * Parameters: - * ptr - Storage location for data. - * size - Item size in bytes. - * count - Maximum number of items to be read. - * stream - Pointer to stream - * - * Returns: - * The number of full items actually read, which may be less than `count` - * if an error occurs or if the end of the file is encountered before - * reaching `count`. If `size` or `count` is 0, `platform_fread` - * returns 0 and the buffer contents are unchanged. - */ -size_t platform_fread(void *ptr, size_t size, size_t count, FILE *stream); - -/* - * Function: platform_fwrite - * Writes data to a stream - * - * Parameters: - * ptr - Pointer to data to be written. - * size - Item size in bytes. - * count - Maximum number of items to be read. - * stream - Pointer to stream - * - * Returns: - * The number of full items actually written, which may be less than - * `count` if an error occurs. Also, if an error occurs, the - * file-position indicator cannot be determined. - * - * Remarks: - * Writes up to `count` items, of `size` length each, from `ptr` to the - * output stream. The file pointer associated with stream (if there is one) - * is incremented by the number of bytes actually written. - */ -size_t platform_fwrite(const void *ptr, size_t size, size_t count, FILE *stream); - -/* - * Function: platform_fflush - * Flushes a stream - * - * Parameters: - * stream - Pointer to stream - * - * Returns: - * 0 value if the buffer was succesffuly flushed. The value 0 is also - * returned in cases in which the specified stream has no buffer or is - * open for reading only. A return value of *EOF* indicates an error. - * - * Remarks: - * Flushes a stream. If the file associated with stream is open for output, - * platform_fflush writes to that file the contents of the buffer - * associated with the stream. If the stream is open for input, - * platform_fflush clears the contents of the buffer. platform_fflush - * negates the effect of any prior call to ungetc against stream. Also, - * platform_fflush(NULL) flushes all streams opened for output. - * The stream remains open after the call. platform_fflush has no effect - * on an unbuffered stream. - */ -int platform_fflush(FILE *stream); - -/* - * Function: platform_fclose - * Closes a stream. - * - * Parameters: - * stream - Pointer to stream. - * - * Returns: - * 0 value. *EOF* is used to indicate an error. - * - * Remarks: - * Closes a stream. - */ -int platform_fclose(FILE *stream); - -/* - * Function: platform_ferror - * Tests for an error on a stream. - * - * Parameters: - * stream - Pointer to stream. - * - * Returns: - * If not error has occured on `stream`, 0 value is returned, otherwise - * it returns a nonzero value. - * - * Remarks: - * Tests for a reading or writing error on the file associated with `stream`. - * If an error has occured, the error indicator for the stream remains set - * until the stream is closed or rewound. - */ -int platform_ferror(FILE *stream); - -/* - * Function: platform_fgetc - * Read a character from a stream. - * - * Parameters: - * stream - Pointer to a stream. - * - * Returns: - * The chracter read as an int or EOF to indicate an error or end-of-file. - * - * Remarks: - * Reads a single chracter from the current position of the file associated - * with `stream`. Than increments that position. If the steam is at the end - * of the file, the end-of-file indicator for the stream is set. - */ -int platform_fgetc(FILE *stream); - -/* - * Function: platform_fputs - * Write a string to a stream - * - * Parameters: - * str - Output string. - * stream - Pointer to stream. - * - * Returns: - * Non-negative value if successful. EOF is used to indicate an error. - * - * Remarks: - * Copies `str` to the output stream at the current position. - */ -int platform_fputs(const char *str, FILE *stream); - -/* - * Function: platform_fseek - * Moves the file pointer to a specified location. - * - * Parameters: - * stream - Pointer to stream. - * offset - Number of bytes from origin to offset. - * origin - Initital position. - * - * Returns: - * 0 value, nonzero values are used to indicate an error. - * - * Remarks: - * Moves the file pointer (if any) associated with stream to a new - * location that is offset bytes from origin. - * The next operation on the stream takes place at the new location. - * On a stream open for update, the next operation can be either a - * read or a write. - */ -int platform_fseek(FILE *stream, long offset, int origin); - -/* - * Function: platform_ftell - * Gets the current position of a file pointer - * - * Parameters: - * stream - Pointer to stream - * - * Returns: - * Current file position. May not reflect physical byte offset, e.g - * systems where read-mode does carriage return-linefeed translation. - * -1 value is used to indivate an error. - */ -long platform_ftell(FILE *stream); - -/* - * Function: platform_mkdir - * Make a directory - * - * Parameters: - * path - Path to create - * mode - The mode of the directory (implementation defined) - * - * Returns: - * 0 value. -1 value is used to indicate an error. On error no - * directory shall be created. - * - * Remarks: - * Shall create a new empty directory with with the name path specified - * by argument `path. - */ -int platform_mkdir(const char *path, int mode); - -/* - * Function: platform_opendir - * Open a directory - * - * Parameters: - * path - Path to the directory to open - * - * Returns: - * Pointer to an object of type *DIR*. A null pointer value indicates - * an error. - * - * Remarks: - * Shall open a directory stream corresponding to the directory named by - * the `path` argument. The directory stream is positioned at the first entry. - */ -DIR *platform_opendir(const char *path); - -/* - * Function: platform_closedir - * Close a directory stream - * - * Parameters: - * dir - Pointer to directory stream - * - * Returns: - * 0 value. A -1 value indicated an error. - * - * Remarks: - * Shall close the directory stream referred to by the argument - * `dir`. Upon return, the value of `dir` may no longer point to - * an accessible object of the type *DIR*. - */ -int platform_closedir(DIR *dir); - -/* - * Function: platform_readdir - * Read directory - * - * Parameters: - * dir - Pointer to directory stream - * - * Returns: - * Pointer to an object of type `struct dirent`. A null pointer value - * indicates an error. - * - * Remarks: - * When the end of the directory is encountered, a null pointer is - * returned. - */ -struct dirent *platform_readdir(DIR *dir); - -/* - * Function: platform_isatty - * Determines whether a file descriptor is associated with a character - * device. - * - * Returns: - * A nonzero value if the descriptor is associated with a character - * device. Otherwise `platform_isatty` returns 0. - */ -int platform_isatty(int fd); - #endif diff --git a/test.c b/test.c index a096910..f15d1fb 100644 --- a/test.c +++ b/test.c @@ -20,48 +20,33 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#define GMQCC_PLATFORM_HEADER /* TODO: eliminate! */ #include #include +#include + +#include +#include +#include + +#include +#include #include "gmqcc.h" -#include "platform.h" static const char *task_bins[] = { "./gmqcc", "./qcvm" }; -/* - * TODO: Windows version - * this implements a unique bi-directional popen-like function that - * allows reading data from both stdout and stderr. And writing to - * stdin :) - * - * Example of use: - * FILE *handles[3] = task_popen("ls", "-l", "r"); - * if (!handles) { perror("failed to open stdin/stdout/stderr to ls"); - * // handles[0] = stdin - * // handles[1] = stdout - * // handles[2] = stderr - * - * task_pclose(handles); // to close - */ -#ifndef _WIN32 -#include -#include -#include -#include typedef struct { - fs_file_t *handles[3]; - int pipes [3]; - + FILE *handles[3]; + int pipes[3]; int stderr_fd; int stdout_fd; int pid; } popen_t; -static fs_file_t **task_popen(const char *command, const char *mode) { +static FILE **task_popen(const char *command, const char *mode) { int inhandle [2]; int outhandle [2]; int errhandle [2]; @@ -95,17 +80,15 @@ static fs_file_t **task_popen(const char *command, const char *mode) { if ((data->pid = fork()) > 0) { /* parent */ - close(inhandle [0]); + close(inhandle [0]); close(outhandle [1]); close(errhandle [1]); - - data->pipes [0] = inhandle [1]; - data->pipes [1] = outhandle[0]; - data->pipes [2] = errhandle[0]; - - data->handles[0] = (fs_file_t*)fdopen(inhandle [1], "w"); - data->handles[1] = (fs_file_t*)fdopen(outhandle[0], mode); - data->handles[2] = (fs_file_t*)fdopen(errhandle[0], mode); + data->pipes[0] = inhandle [1]; + data->pipes[1] = outhandle[0]; + data->pipes[2] = errhandle[0]; + data->handles[0] = fdopen(inhandle [1], "w"); + data->handles[1] = fdopen(outhandle[0], mode); + data->handles[2] = fdopen(errhandle[0], mode); /* sigh */ vec_free(argv); @@ -137,7 +120,7 @@ task_popen_error_0: return NULL; } -static int task_pclose(fs_file_t **handles) { +static int task_pclose(FILE **handles) { popen_t *data = (popen_t*)handles; int status = 0; @@ -151,51 +134,6 @@ static int task_pclose(fs_file_t **handles) { return status; } -#else - #include - typedef struct { - fs_file_t *handles[3]; - char name_err[L_tmpnam]; - char name_out[L_tmpnam]; - } popen_t; - - static fs_file_t **task_popen(const char *command, const char *mode) { - char *cmd = NULL; - popen_t *open = (popen_t*)mem_a(sizeof(popen_t)); - - tmpnam(open->name_err); - tmpnam(open->name_out); - - (void)mode; /* excluded */ - - util_asprintf(&cmd, "%s -redirout=%s -redirerr=%s", command, open->name_out, open->name_err); - - system(cmd); /* HACK */ - open->handles[0] = NULL; - open->handles[1] = fs_file_open(open->name_out, "r"); - open->handles[2] = fs_file_open(open->name_err, "r"); - - mem_d(cmd); - - return open->handles; - } - - static int task_pclose(fs_file_t **files) { - popen_t *open = ((popen_t*)files); - - fs_file_close(files[1]); - fs_file_close(files[2]); - - remove(open->name_err); - remove(open->name_out); - - mem_d(open); - - return EXIT_SUCCESS; - } -# define popen _popen -# define pclose _pclose -#endif /*! _WIN32 */ #define TASK_COMPILE 0 #define TASK_EXECUTE 1 @@ -361,7 +299,7 @@ static bool task_template_generate(task_template_t *tmpl, char tag, const char * return true; } -static bool task_template_parse(const char *file, task_template_t *tmpl, fs_file_t *fp, size_t *pad) { +static bool task_template_parse(const char *file, task_template_t *tmpl, FILE *fp, size_t *pad) { char *data = NULL; char *back = NULL; size_t size = 0; @@ -371,7 +309,7 @@ static bool task_template_parse(const char *file, task_template_t *tmpl, fs_file return false; /* top down parsing */ - while (fs_file_getline(&back, &size, fp) != FS_FILE_EOF) { + while (fs_file_getline(&back, &size, fp) != EOF) { /* skip whitespace */ data = back; if (*data && (*data == ' ' || *data == '\t')) @@ -502,12 +440,12 @@ static task_template_t *task_template_compile(const char *file, const char *dir, /* a page should be enough */ char fullfile[4096]; size_t filepadd = 0; - fs_file_t *tempfile = NULL; + FILE *tempfile = NULL; task_template_t *tmpl = NULL; util_snprintf(fullfile, sizeof(fullfile), "%s/%s", dir, file); - tempfile = fs_file_open(fullfile, "r"); + tempfile = fopen(fullfile, "r"); tmpl = (task_template_t*)mem_a(sizeof(task_template_t)); task_template_nullify(tmpl); @@ -604,7 +542,7 @@ static task_template_t *task_template_compile(const char *file, const char *dir, } success: - fs_file_close(tempfile); + fclose(tempfile); return tmpl; failure: @@ -613,7 +551,7 @@ failure: * so the check to see if it's not null here is required. */ if (tempfile) - fs_file_close(tempfile); + fclose(tempfile); mem_d (tmpl); return NULL; @@ -657,12 +595,12 @@ static void task_template_destroy(task_template_t *tmpl) { */ typedef struct { task_template_t *tmpl; - fs_file_t **runhandles; - fs_file_t *stderrlog; - fs_file_t *stdoutlog; - char *stdoutlogfile; - char *stderrlogfile; - bool compiled; + FILE **runhandles; + FILE *stderrlog; + FILE *stdoutlog; + char *stdoutlogfile; + char *stderrlogfile; + bool compiled; } task_t; static task_t *task_tasks = NULL; @@ -673,8 +611,8 @@ static task_t *task_tasks = NULL; */ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) { bool success = true; - fs_dir_t *dir; - fs_dirent_t *files; + DIR *dir; + struct dirent *files; struct stat directory; char buffer[4096]; size_t found = 0; @@ -683,16 +621,16 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) { size_t i; vec_push(directories, claim); - dir = fs_dir_open(claim); + dir = opendir(claim); /* * Generate a list of subdirectories since we'll be checking them too * for tmpl files. */ - while ((files = fs_dir_read(dir))) { + while ((files = readdir(dir))) { util_asprintf(&claim, "%s/%s", curdir, files->d_name); if (stat(claim, &directory) == -1) { - fs_dir_close(dir); + closedir(dir); mem_d(claim); return false; } @@ -704,7 +642,7 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) { claim = NULL; } } - fs_dir_close(dir); + closedir(dir); /* * Now do all the work, by touching all the directories inside @@ -712,9 +650,9 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) { * use to run the tests. */ for (i = 0; i < vec_size(directories); i++) { - dir = fs_dir_open(directories[i]); + dir = opendir(directories[i]); - while ((files = fs_dir_read(dir))) { + while ((files = readdir(dir))) { util_snprintf(buffer, sizeof(buffer), "%s/%s", directories[i], files->d_name); if (stat(buffer, &directory) == -1) { con_err("internal error: stat failed, aborting\n"); @@ -752,7 +690,7 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) { * to test compile flags for all tests. This needs to be * BEFORE other flags (so that the .tmpl can override them) */ - qcflags = platform_getenv("QCFLAGS"); + qcflags = getenv("QCFLAGS"); /* * Generate the command required to open a pipe to a process @@ -843,23 +781,21 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) { */ util_snprintf(buf, sizeof(buf), "%s.stdout", tmpl->tempfilename); task.stdoutlogfile = util_strdup(buf); - if (!(task.stdoutlog = fs_file_open(buf, "w"))) { + if (!(task.stdoutlog = fopen(buf, "w"))) { con_err("error opening %s for stdout\n", buf); continue; } util_snprintf(buf, sizeof(buf), "%s.stderr", tmpl->tempfilename); task.stderrlogfile = util_strdup(buf); - if (!(task.stderrlog = fs_file_open(buf, "w"))) { + if (!(task.stderrlog = fopen(buf, "w"))) { con_err("error opening %s for stderr\n", buf); continue; } - vec_push(task_tasks, task); } } - - fs_dir_close(dir); + closedir(dir); mem_d(directories[i]); /* free claimed memory */ } vec_free(directories); @@ -872,13 +808,13 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) { * left behind from a previous invoke of the test-suite. */ static void task_precleanup(const char *curdir) { - fs_dir_t *dir; - fs_dirent_t *files; + DIR *dir; + struct dirent *files; char buffer[4096]; - dir = fs_dir_open(curdir); + dir = opendir(curdir); - while ((files = fs_dir_read(dir))) { + while ((files = readdir(dir))) { if (strstr(files->d_name, "TMP") || strstr(files->d_name, ".stdout") || strstr(files->d_name, ".stderr") || @@ -890,7 +826,7 @@ static void task_precleanup(const char *curdir) { } } - fs_dir_close(dir); + closedir(dir); } static void task_destroy(void) { @@ -905,8 +841,8 @@ static void task_destroy(void) { * Close any open handles to files or processes here. It's mighty * annoying to have to do all this cleanup work. */ - if (task_tasks[i].stdoutlog) fs_file_close (task_tasks[i].stdoutlog); - if (task_tasks[i].stderrlog) fs_file_close (task_tasks[i].stderrlog); + if (task_tasks[i].stdoutlog) fclose(task_tasks[i].stdoutlog); + if (task_tasks[i].stderrlog) fclose(task_tasks[i].stderrlog); /* * Only remove the log files if the test actually compiled otherwise @@ -941,7 +877,7 @@ static bool task_trymatch(size_t i, char ***line) { bool success = true; bool process = true; int retval = EXIT_SUCCESS; - fs_file_t *execute; + FILE *execute; char buffer[4096]; task_template_t *tmpl = task_tasks[i].tmpl; @@ -965,7 +901,7 @@ static bool task_trymatch(size_t i, char ***line) { ); } - execute = (fs_file_t*)popen(buffer, "r"); + execute = popen(buffer, "r"); if (!execute) return false; } else if (!strcmp(tmpl->proceduretype, "-pp")) { @@ -973,9 +909,8 @@ static bool task_trymatch(size_t i, char ***line) { * we're preprocessing, which means we need to read int * the produced file and do some really weird shit. */ - if (!(execute = fs_file_open(tmpl->tempfilename, "r"))) + if (!(execute = fopen(tmpl->tempfilename, "r"))) return false; - process = false; } else { /* @@ -983,9 +918,8 @@ static bool task_trymatch(size_t i, char ***line) { * in runhandles[2] (stderr) since that is where the compiler * puts it's errors. */ - if (!(execute = fs_file_open(task_tasks[i].stderrlogfile, "r"))) + if (!(execute = fopen(task_tasks[i].stderrlogfile, "r"))) return false; - process = false; } @@ -998,14 +932,14 @@ static bool task_trymatch(size_t i, char ***line) { size_t size = 0; size_t compare = 0; - while (fs_file_getline(&data, &size, execute) != FS_FILE_EOF) { + while (fs_file_getline(&data, &size, execute) != EOF) { if (!strcmp(data, "No main function found\n")) { con_err("test failure: `%s` (No main function found) [%s]\n", tmpl->description, tmpl->rulesfile ); if (!process) - fs_file_close(execute); + fclose(execute); else pclose((FILE*)execute); return false; @@ -1069,7 +1003,7 @@ static bool task_trymatch(size_t i, char ***line) { if (process) retval = pclose((FILE*)execute); else - fs_file_close(execute); + fclose(execute); return success && retval == EXIT_SUCCESS; } @@ -1132,15 +1066,15 @@ static size_t task_schedualize(size_t *pad) { * Read data from stdout first and pipe that stuff into a log file * then we do the same for stderr. */ - while (fs_file_getline(&data, &size, task_tasks[i].runhandles[1]) != FS_FILE_EOF) { - fs_file_puts(task_tasks[i].stdoutlog, data); + while (fs_file_getline(&data, &size, task_tasks[i].runhandles[1]) != EOF) { + fputs(data, task_tasks[i].stdoutlog); if (strstr(data, "failed to open file")) { task_tasks[i].compiled = false; execute = false; } } - while (fs_file_getline(&data, &size, task_tasks[i].runhandles[2]) != FS_FILE_EOF) { + while (fs_file_getline(&data, &size, task_tasks[i].runhandles[2]) != EOF) { /* * If a string contains an error we just dissalow execution * of it in the vm. @@ -1154,8 +1088,8 @@ static size_t task_schedualize(size_t *pad) { task_tasks[i].compiled = false; } - fs_file_puts (task_tasks[i].stderrlog, data); - fs_file_flush(task_tasks[i].stderrlog); /* fast flush for read */ + fputs(data, task_tasks[i].stderrlog); + fflush(task_tasks[i].stderrlog); /* fast flush for read */ } if (!task_tasks[i].compiled && strcmp(task_tasks[i].tmpl->proceduretype, "-fail")) { @@ -1363,10 +1297,8 @@ static bool parsecmd(const char *optname, int *argc_, char ***argv_, char **out, } int main(int argc, char **argv) { - bool succeed = false; - char *redirout = (char*)stdout; - char *redirerr = (char*)stderr; - char *defs = NULL; + bool succeed = false; + char *defs = NULL; con_init(); OPTS_OPTION_U16(OPTION_MEMDUMPCOLS) = 16; @@ -1380,14 +1312,8 @@ int main(int argc, char **argv) { --argc; if (argv[0][0] == '-') { - if (parsecmd("redirout", &argc, &argv, &redirout, 1, false)) - continue; - if (parsecmd("redirerr", &argc, &argv, &redirerr, 1, false)) + if (parsecmd("defs", &argc, &argv, &defs, 1, false)) continue; - if (parsecmd("defs", &argc, &argv, &defs, 1, false)) - continue; - - con_change(redirout, redirerr); if (!strcmp(argv[0]+1, "debug")) { OPTS_OPTION_BOOL(OPTION_DEBUG) = true; @@ -1406,7 +1332,6 @@ int main(int argc, char **argv) { return -1; } } - con_change(redirout, redirerr); succeed = test_perform("tests", defs); return (succeed) ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/util.c b/util.c index c2ab21a..0e468c0 100644 --- a/util.c +++ b/util.c @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#define GMQCC_PLATFORM_HEADER #include +#include #include "gmqcc.h" #include "platform.h" @@ -586,62 +586,68 @@ size_t util_optimizationtostr(const char *in, char *out, size_t outsz) { int util_snprintf(char *str, size_t size, const char *fmt, ...) { va_list arg; - int ret; - + int ret; va_start(arg, fmt); - ret = platform_vsnprintf(str, size, fmt, arg); + ret = vsnprintf(str, size, fmt, arg); va_end(arg); - return ret; } int util_asprintf(char **ret, const char *fmt, ...) { va_list args; - int read; - + int read; va_start(args, fmt); read = platform_vasprintf(ret, fmt, args); - va_end (args); - + va_end(args); return read; } int util_sscanf(const char *str, const char *format, ...) { va_list args; - int read; - + int read; va_start(args, format); - read = platform_vsscanf(str, format, args); + read = vsscanf(str, format, args); va_end(args); - return read; } char *util_strncpy(char *dest, const char *src, size_t n) { - return platform_strncpy(dest, src, n); + return strncpy(dest, src, n); } + char *util_strncat(char *dest, const char *src, size_t n) { - return platform_strncat(dest, src, n); + return strncat(dest, src, n); } + char *util_strcat(char *dest, const char *src) { - return platform_strcat(dest, src); + return strcat(dest, src); } + const char *util_strerror(int err) { - return platform_strerror(err); + return strerror(err); } const struct tm *util_localtime(const time_t *timer) { - return platform_localtime(timer); + return localtime(timer); } + const char *util_ctime(const time_t *timer) { - return platform_ctime(timer); + return ctime(timer); } -bool util_isatty(fs_file_t *file) { - if (file == (fs_file_t*)stdout) return !!platform_isatty(STDOUT_FILENO); - if (file == (fs_file_t*)stderr) return !!platform_isatty(STDERR_FILENO); +#ifndef _WIN32 +#include +bool util_isatty(FILE *file) { + if (file == stdout) return !!isatty(STDOUT_FILENO); + if (file == stderr) return !!isatty(STDERR_FILENO); + return false; +} +#else +bool util_isatty(FILE *file) { return false; } +#endif + /* * A small noncryptographic PRNG based on: * http://burtleburtle.net/bob/rand/smallprng.html -- 2.39.2