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
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#define GMQCC_PLATFORM_HEADER
#include <string.h>
#include <stdlib.h>
#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;
*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);
-}
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;
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;
}
#include <stdio.h>
#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;
/*
* 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);
}
/**********************************************************************
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) {
}
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) {
* 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;
}
/*
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,
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;
}
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;
}
}
#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, \
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));
vec_free(prog->entitypool);
mem_d(prog);
- fs_file_close(file);
+ fclose(file);
return NULL;
}
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] = ' ';
}
}
* 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;
pos = *lineptr;
for (;;) {
- int c = fs_file_getc(stream);
+ int c = getc(stream);
if (chr < 2) {
*n += (*n > 16) ? *n : 64;
pos = *n - chr + *lineptr;
}
- if (fs_file_error(stream))
+ if (ferror(stream))
return -1;
if (c == EOF) {
if (pos == *lineptr)
*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);
-}
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;
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);
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
+#include <stdio.h>
#include <time.h>
#define GMQCC_VERSION_MAJOR 0
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);
/*
/* 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 */
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, ...);
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 *, ...);
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) {
lex = (lex_file*)mem_a(sizeof(*lex));
if (!lex) {
- fs_file_close(in);
+ fclose(in);
lexerror(NULL, "out of memory\n");
return NULL;
}
vec_free(lex->modelname);
if (lex->file)
- fs_file_close(lex->file);
+ fclose(lex->file);
vec_free(lex->tok.value);
{
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
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);
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;
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);
lex_tokench(lex, ' ');
}
- while (ch != FS_FILE_EOF)
+ while (ch != EOF)
{
ch = lex_getch(lex);
if (ch == '*') {
ch = '/';
break;
}
- } while (ch != FS_FILE_EOF && util_isspace(ch));
+ } while (ch != EOF && util_isspace(ch));
if (haswhite) {
lex_endtoken(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);
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')
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)
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);
}
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);
}
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);
}
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)) {
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);
}
{
/* 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);
}
} 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;
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;
}
/* 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;
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;
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;
}
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;
}
}
- fs_file_close(src);
+ fclose(src);
mem_d(line);
}
}
out = ftepp_get(ftepp);
if (out)
- fs_file_printf(outfile, "%s", out);
+ fprintf(outfile, "%s", out);
ftepp_flush(ftepp);
}
else {
}
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
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 */
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);
/* Change the file name */
mem_d(*parse_file);
*parse_file = util_strdup(value);
- fs_file_close(file);
+ fclose(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);
}
mem_d(parse_file);
- fs_file_close(ini);
+ fclose(ini);
}
#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 <stdarg.h>
#include <time.h>
#include <stdio.h>
-#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 <windows.h>
-# include <io.h>
-# include <fcntl.h>
-
- 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 <dirent.h>
-# endif /*!__MINGW32__*/
-
-# ifndef S_ISDIR
-# define S_ISDIR(X) ((X)&_S_IFDIR)
-# endif
-#else
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <unistd.h>
-# include <dirent.h>
-#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 <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
-/*
- * 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
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#define GMQCC_PLATFORM_HEADER /* TODO: eliminate! */
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <unistd.h>
#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 <sys/types.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#include <unistd.h>
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];
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);
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;
return status;
}
-#else
- #include <sys/stat.h>
- 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
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;
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'))
/* 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);
}
success:
- fs_file_close(tempfile);
+ fclose(tempfile);
return tmpl;
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;
*/
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;
*/
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;
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;
}
claim = NULL;
}
}
- fs_dir_close(dir);
+ closedir(dir);
/*
* Now do all the work, by touching all the directories inside
* 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");
* 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
*/
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);
* 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") ||
}
}
- fs_dir_close(dir);
+ closedir(dir);
}
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
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;
);
}
- execute = (fs_file_t*)popen(buffer, "r");
+ execute = popen(buffer, "r");
if (!execute)
return false;
} else if (!strcmp(tmpl->proceduretype, "-pp")) {
* 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 {
/*
* 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;
}
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;
if (process)
retval = pclose((FILE*)execute);
else
- fs_file_close(execute);
+ fclose(execute);
return success && retval == EXIT_SUCCESS;
}
* 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.
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")) {
}
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;
--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;
return -1;
}
}
- con_change(redirout, redirerr);
succeed = test_perform("tests", defs);
return (succeed) ? EXIT_SUCCESS : EXIT_FAILURE;
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#define GMQCC_PLATFORM_HEADER
#include <stdlib.h>
+#include <string.h>
#include "gmqcc.h"
#include "platform.h"
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 <unistd.h>
+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