Some more platform / compiler specific code refactoring.

This commit is contained in:
Dale Weiler 2013-10-11 03:02:38 -04:00
parent 151606e255
commit 12a864abf5
16 changed files with 176 additions and 235 deletions

View file

@ -148,22 +148,22 @@ install-doc:
# DO NOT DELETE # DO NOT DELETE
pak.o: gmqcc.h opts.def pak.o: gmqcc.h opts.def platform.h
ansi.o: gmqcc.h opts.def ansi.o: platform.h
util.o: gmqcc.h opts.def util.o: gmqcc.h opts.def
stat.o: gmqcc.h opts.def stat.o: gmqcc.h opts.def
fs.o: gmqcc.h opts.def fs.o: gmqcc.h opts.def platform.h
conout.o: gmqcc.h opts.def conout.o: gmqcc.h opts.def
opts.o: gmqcc.h opts.def opts.o: gmqcc.h opts.def platform.h
test.o: gmqcc.h opts.def test.o: gmqcc.h opts.def platform.h
main.o: gmqcc.h opts.def lexer.h main.o: gmqcc.h opts.def lexer.h
lexer.o: gmqcc.h opts.def lexer.h lexer.o: gmqcc.h opts.def lexer.h platform.h
parser.o: parser.h gmqcc.h opts.def lexer.h ast.h ir.h parser.o: parser.h gmqcc.h opts.def lexer.h ast.h ir.h platform.h
code.o: gmqcc.h opts.def code.o: gmqcc.h opts.def
ast.o: gmqcc.h opts.def ast.h ir.h parser.h lexer.h ast.o: gmqcc.h opts.def ast.h ir.h parser.h lexer.h platform.h
ir.o: gmqcc.h opts.def ir.h ir.o: gmqcc.h opts.def ir.h platform.h
ftepp.o: gmqcc.h opts.def lexer.h ftepp.o: gmqcc.h opts.def lexer.h platform.h
utf8.o: gmqcc.h opts.def utf8.o: gmqcc.h opts.def
correct.o: gmqcc.h opts.def correct.o: gmqcc.h opts.def
fold.o: ast.h ir.h gmqcc.h opts.def parser.h lexer.h fold.o: ast.h ir.h gmqcc.h opts.def parser.h lexer.h platform.h
intrin.o: parser.h gmqcc.h opts.def lexer.h ast.h ir.h intrin.o: parser.h gmqcc.h opts.def lexer.h ast.h ir.h platform.h

58
ansi.c
View file

@ -23,7 +23,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "gmqcc.h" #include "platform.h"
int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg) { int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg) {
return vsnprintf(buffer, bytes, format, arg); return vsnprintf(buffer, bytes, format, arg);
@ -82,3 +82,59 @@ char *platform_strncpy(char *dest, const char *src, size_t num) {
const char *platform_strerror(int err) { const char *platform_strerror(int err) {
return strerror(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_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) {
return mkdir(path, mode);
}
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);
}

1
ast.c
View file

@ -27,6 +27,7 @@
#include "gmqcc.h" #include "gmqcc.h"
#include "ast.h" #include "ast.h"
#include "parser.h" #include "parser.h"
#include "platform.h"
#define ast_instantiate(T, ctx, destroyfn) \ #define ast_instantiate(T, ctx, destroyfn) \
T* self = (T*)mem_a(sizeof(T)); \ T* self = (T*)mem_a(sizeof(T)); \

5
exec.c
View file

@ -23,12 +23,11 @@
*/ */
#ifndef QCVM_LOOP #ifndef QCVM_LOOP
#include <errno.h> #include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "gmqcc.h" #include "gmqcc.h"
#include "platform.h"
static void loaderror(const char *fmt, ...) static void loaderror(const char *fmt, ...)
{ {

1
fold.c
View file

@ -25,6 +25,7 @@
#include "ast.h" #include "ast.h"
#include "parser.h" #include "parser.h"
#include "platform.h"
#define FOLD_STRING_UNTRANSLATE_HTSIZE 1024 #define FOLD_STRING_UNTRANSLATE_HTSIZE 1024
#define FOLD_STRING_DOTRANSLATE_HTSIZE 1024 #define FOLD_STRING_DOTRANSLATE_HTSIZE 1024

209
fs.c
View file

@ -21,119 +21,28 @@
* SOFTWARE. * SOFTWARE.
*/ */
#include "gmqcc.h" #include "gmqcc.h"
#include "platform.h"
/*
* This is essentially a "wrapper" interface around standard C's IO
* library. There is two reason we implement this, 1) visual studio
* hearts for "secure" varations, as part of it's "Security Enhancements
* in the CRT" (http://msdn.microsoft.com/en-us/library/8ef0s5kh.aspx).
* 2) But one of the greater reasons is for the possibility of large file
* support in the future. I don't expect to reach the 2GB limit any
* time soon (mainly because that would be insane). But when it comes
* to adding support for some other larger IO tasks (in the test-suite,
* or even the QCVM we'll need it). There is also a third possibility of
* building .dat files directly from zip files (which would be very cool
* at least I think so).
*/
#ifdef _MSC_VER
#include <crtdbg.h> /* _CrtSetReportMode, _CRT_ASSERT */
/* {{{ */
/*
* Visual Studio has security CRT features which I actually want to support
* if we ever port to Windows 8, and want GMQCC to be API safe.
*
* We handle them here, for all file-operations.
*/
static void file_exception (
const wchar_t *expression,
const wchar_t *function,
const wchar_t *file,
unsigned int line,
uintptr_t reserved
) {
wprintf(L"Invalid parameter dectected %s:%d %s [%s]\n", file, line, function, expression);
wprintf(L"Aborting ...\n");
exit(EXIT_FAILURE);
}
static void file_init() {
static bool init = false;
if (init)
return;
_set_invalid_parameter_handler(&file_exception);
/*
* Turnoff the message box for CRT asserations otherwise
* we don't get the error reported to the console as we should
* otherwise get.
*/
_CrtSetReportMode(_CRT_ASSERT, 0);
init = !init;
}
FILE *fs_file_open(const char *filename, const char *mode) { FILE *fs_file_open(const char *filename, const char *mode) {
FILE *handle = NULL; return platform_fopen(filename, mode);
file_init();
return (fopen_s(&handle, filename, mode) != 0) ? NULL : handle;
} }
size_t fs_file_read(void *buffer, size_t size, size_t count, FILE *fp) { size_t fs_file_read(void *buffer, size_t size, size_t count, FILE *fp) {
file_init(); return platform_fread(buffer, size, count, fp);
return fread_s(buffer, size*count, size, count, fp);
} }
int fs_file_printf(FILE *fp, const char *format, ...) { int fs_file_printf(FILE *fp, const char *format, ...) {
int rt; int rt;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
rt = platform_vfprintf(fp, format, va);
file_init();
rt = vfprintf_s(fp, format, va);
va_end (va); va_end (va);
return rt; return rt;
} }
/* }}} */
#else
/* {{{ */
/*
* All other compilers/platforms that don't restrict insane policies on
* IO for no aparent reason.
*/
FILE *fs_file_open(const char *filename, const char *mode) {
return fopen(filename, mode);
}
size_t fs_file_read(void *buffer, size_t size, size_t count, FILE *fp) {
return fread(buffer, size, count, fp);
}
int fs_file_printf(FILE *fp, const char *format, ...) {
int rt;
va_list va;
va_start(va, format);
rt = vfprintf(fp, format, va);
va_end (va);
return rt;
}
/* }}} */
#endif
/*
* These are implemented as just generic wrappers to keep consistency in
* the API. Not as macros though
*/
void fs_file_close(FILE *fp) { void fs_file_close(FILE *fp) {
/* Invokes file_exception on windows if fp is null */ platform_fclose (fp);
fclose (fp);
} }
size_t fs_file_write ( size_t fs_file_write (
@ -142,33 +51,27 @@ size_t fs_file_write (
size_t count, size_t count,
FILE *fp FILE *fp
) { ) {
/* Invokes file_exception on windows if fp is null */ return platform_fwrite(buffer, size, count, fp);
return fwrite(buffer, size, count, fp);
} }
int fs_file_error(FILE *fp) { int fs_file_error(FILE *fp) {
/* Invokes file_exception on windows if fp is null */ return platform_ferror(fp);
return ferror(fp);
} }
int fs_file_getc(FILE *fp) { int fs_file_getc(FILE *fp) {
/* Invokes file_exception on windows if fp is null */ return platform_fgetc(fp);
return fgetc(fp);
} }
int fs_file_puts(FILE *fp, const char *str) { int fs_file_puts(FILE *fp, const char *str) {
/* Invokes file_exception on windows if fp is null */ return platform_fputs(str, fp);
return fputs(str, fp);
} }
int fs_file_seek(FILE *fp, long int off, int whence) { int fs_file_seek(FILE *fp, long int off, int whence) {
/* Invokes file_exception on windows if fp is null */ return platform_fseek(fp, off, whence);
return fseek(fp, off, whence);
} }
long int fs_file_tell(FILE *fp) { long int fs_file_tell(FILE *fp) {
/* Invokes file_exception on windows if fp is null */ return platform_ftell(fp);
return ftell(fp);
} }
/* /*
@ -219,94 +122,18 @@ int fs_file_getline(char **lineptr, size_t *n, FILE *stream) {
return (ret = pos - *lineptr); return (ret = pos - *lineptr);
} }
/* int fs_dir_make(const char *path) {
* Now we implement some directory functionality. Windows lacks dirent.h return platform_mkdir(path, 0700);
* this is such a pisss off, we implement it here. }
*/
#if defined(_WIN32) && !defined(__MINGW32__)
DIR *fs_dir_open(const char *name) {
DIR *dir = (DIR*)mem_a(sizeof(DIR) + strlen(name));
if (!dir)
return NULL;
platform_strncpy(dir->dd_name, name, strlen(name)); DIR *fs_dir_open(const char *name) {
return dir; return platform_opendir(name);
} }
int fs_dir_close(DIR *dir) { int fs_dir_close(DIR *dir) {
FindClose((HANDLE)dir->dd_handle); return platform_closedir(dir);
mem_d ((void*)dir);
return 0;
} }
struct dirent *fs_dir_read(DIR *dir) { struct dirent *fs_dir_read(DIR *dir) {
WIN32_FIND_DATA info; return platform_readdir(dir);
struct dirent *data;
int rets;
if (!dir->dd_handle) {
char *dirname;
if (*dir->dd_name) {
size_t n = strlen(dir->dd_name);
if ((dirname = (char*)mem_a(n + 5) /* 4 + 1 */)) {
platform_strncpy(dirname, dir->dd_name, n);
platform_strncpy(dirname + n, "\\*.*", 4); /* 4 + 1 */
} }
} else {
if (!(dirname = util_strdup("\\*.*")))
return NULL;
}
dir->dd_handle = (long)FindFirstFile(dirname, &info);
mem_d(dirname);
rets = !(!dir->dd_handle);
} else if (dir->dd_handle != -11) {
rets = FindNextFile ((HANDLE)dir->dd_handle, &info);
} else {
rets = 0;
}
if (!rets)
return NULL;
if ((data = (struct dirent*)mem_a(sizeof(struct dirent)))) {
platform_strncpy(data->d_name, info.cFileName, FILENAME_MAX - 1);
data->d_name[FILENAME_MAX - 1] = '\0'; /* terminate */
data->d_namlen = strlen(data->d_name);
}
return data;
}
int fs_dir_change(const char *path) {
return !SetCurrentDirectory(path);
}
int fs_dir_make(const char *path) {
return !CreateDirectory(path, NULL);
}
#else
# if !defined(__MINGW32__)
# include <sys/stat.h> /* mkdir */
int fs_dir_make(const char *path) {
return mkdir(path, 0700);
}
# else
int fs_dir_make(const char *path) {
return mkdir(path);
}
# endif /*! !defined(__MINGW32__) */
DIR *fs_dir_open(const char *name) {
return opendir(name);
}
int fs_dir_close(DIR *dir) {
return closedir(dir);
}
struct dirent *fs_dir_read(DIR *dir) {
return readdir(dir);
}
#endif /*! defined(_WIN32) && !defined(__MINGW32__) */

View file

@ -21,13 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
#include <time.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h>
#include "gmqcc.h" #include "gmqcc.h"
#include "lexer.h" #include "lexer.h"
#include "platform.h"
#define HT_MACROS 1024 #define HT_MACROS 1024
typedef struct { typedef struct {

14
gmqcc.h
View file

@ -24,7 +24,6 @@
#ifndef GMQCC_HDR #ifndef GMQCC_HDR
#define GMQCC_HDR #define GMQCC_HDR
#include <stdarg.h> #include <stdarg.h>
#include <time.h> /* TODO: remove this? */
#include <stdio.h> /* TODO: remove this */ #include <stdio.h> /* TODO: remove this */
/* /*
@ -460,19 +459,6 @@ DIR *fs_dir_open (const char *);
int fs_dir_close (DIR *); int fs_dir_close (DIR *);
struct dirent *fs_dir_read (DIR *); struct dirent *fs_dir_read (DIR *);
int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg);
int platform_sscanf(const char *str, const char *format, ...);
const struct tm *platform_localtime(const time_t *timer);
const char *platform_ctime(const time_t *timer);
char *platform_strncat(char *dest, const char *src, size_t num);
const char *platform_tmpnam(char *str);
const char *platform_getenv(char *var);
int platform_snprintf(char *src, size_t bytes, const char *format, ...);
char *platform_strcat(char *dest, const char *src);
char *platform_strncpy(char *dest, const char *src, size_t num);
const char *platform_strerror(int err);
/*===================================================================*/ /*===================================================================*/
/*=========================== correct.c =============================*/ /*=========================== correct.c =============================*/
/*===================================================================*/ /*===================================================================*/

View file

@ -21,7 +21,9 @@
* SOFTWARE. * SOFTWARE.
*/ */
#include <string.h> #include <string.h>
#include "parser.h" #include "parser.h"
#include "platform.h"
/* /*
* Provides all the "intrinsics" / "builtins" for GMQCC. These can do * Provides all the "intrinsics" / "builtins" for GMQCC. These can do

1
ir.c
View file

@ -26,6 +26,7 @@
#include "gmqcc.h" #include "gmqcc.h"
#include "ir.h" #include "ir.h"
#include "platform.h"
/*********************************************************************** /***********************************************************************
* Type sizes used at multiple points in the IR codegen * Type sizes used at multiple points in the IR codegen

View file

@ -25,6 +25,8 @@
#include "gmqcc.h" #include "gmqcc.h"
#include "lexer.h" #include "lexer.h"
#include "platform.h"
/* /*
* List of Keywords * List of Keywords
*/ */

1
opts.c
View file

@ -25,6 +25,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "gmqcc.h" #include "gmqcc.h"
#include "platform.h"
const unsigned int opts_opt_oflag[COUNT_OPTIMIZATIONS+1] = { const unsigned int opts_opt_oflag[COUNT_OPTIMIZATIONS+1] = {
# define GMQCC_TYPE_OPTIMIZATIONS # define GMQCC_TYPE_OPTIMIZATIONS

1
pak.c
View file

@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "gmqcc.h" #include "gmqcc.h"
#include "platform.h"
/* /*
* The PAK format uses a FOURCC concept for storing the magic ident within * The PAK format uses a FOURCC concept for storing the magic ident within

View file

@ -23,7 +23,9 @@
*/ */
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include "parser.h" #include "parser.h"
#include "platform.h"
#define PARSER_HT_LOCALS 2 #define PARSER_HT_LOCALS 2
#define PARSER_HT_SIZE 512 #define PARSER_HT_SIZE 512

64
platform.h Normal file
View file

@ -0,0 +1,64 @@
/*
* Copyright (C) 2012, 2013
* Dale Weiler
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef GMQCC_PLATFORM_HDR
#define GMQCC_PLATFORM_HDR
#include <stddef.h>
#include <stdarg.h>
#include <time.h>
#include <stdio.h>
#ifndef _MSC_VER
# include <sys/types.h>
# include <sys/stat.h>
# include <dirent.h>
#endif
int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg);
int platform_sscanf(const char *str, const char *format, ...);
const struct tm *platform_localtime(const time_t *timer);
const char *platform_ctime(const time_t *timer);
char *platform_strncat(char *dest, const char *src, size_t num);
const char *platform_tmpnam(char *str);
const char *platform_getenv(char *var);
int platform_snprintf(char *src, size_t bytes, const char *format, ...);
char *platform_strcat(char *dest, const char *src);
char *platform_strncpy(char *dest, const char *src, size_t num);
const char *platform_strerror(int err);
FILE *platform_fopen(const char *filename, const char *mode);
size_t platform_fread(void *ptr, size_t size, size_t count, FILE *stream);
size_t platform_fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
int platform_vfprintf(FILE *stream, const char *format, va_list arg);
int platform_fclose(FILE *stream);
int platform_ferror(FILE *stream);
int platform_fgetc(FILE *stream);
int platform_fputs(const char *str, FILE *stream);
int platform_fseek(FILE *stream, long offset, int origin);
long platform_ftell(FILE *stream);
int platform_mkdir(const char *path, int mode);
DIR *platform_opendir(const char *path);
int platform_closedir(DIR *dir);
struct dirent *platform_readdir(DIR *dir);
#endif

3
test.c
View file

@ -22,10 +22,9 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "gmqcc.h" #include "gmqcc.h"
#include "platform.h"
static const char *task_bins[] = { static const char *task_bins[] = {
"./gmqcc", "./gmqcc",