Refactor some util/platform usage and extend file system file interface to accept its own flags and EOF

This commit is contained in:
Dale Weiler 2013-10-11 06:12:56 -04:00
parent e9bde1e4e4
commit 87d9371a5c
18 changed files with 183 additions and 147 deletions

23
ansi.c
View file

@ -20,6 +20,7 @@
* 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 <unistd.h>
@ -31,15 +32,8 @@ int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list a
return vsnprintf(buffer, bytes, format, arg);
}
int platform_sscanf(const char *str, const char *format, ...) {
int rt;
va_list va;
va_start(va, format);
rt = vsscanf(str, format, va);
va_end (va);
return rt;
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) {
@ -62,17 +56,6 @@ const char *platform_getenv(char *var) {
return getenv(var);
}
int platform_snprintf(char *src, size_t bytes, const char *format, ...) {
int rt;
va_list va;
va_start(va, format);
rt = vsnprintf(src, bytes, format, va);
va_end(va);
return rt;
}
int platform_vasprintf(char **dat, const char *fmt, va_list args) {
int ret;
int len;

21
ast.c
View file

@ -27,7 +27,6 @@
#include "gmqcc.h"
#include "ast.h"
#include "parser.h"
#include "platform.h"
#define ast_instantiate(T, ctx, destroyfn) \
T* self = (T*)mem_a(sizeof(T)); \
@ -260,7 +259,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi
if (!e) {
if (pos + 6 >= bufsize)
goto full;
platform_strncpy(buf + pos, "(null)", 6);
util_strncpy(buf + pos, "(null)", 6);
return pos + 6;
}
@ -269,7 +268,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi
switch (e->vtype) {
case TYPE_VARIANT:
platform_strncpy(buf + pos, "(variant)", 9);
util_strncpy(buf + pos, "(variant)", 9);
return pos + 9;
case TYPE_FIELD:
@ -315,7 +314,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi
if (pos + 1 >= bufsize)
goto full;
buf[pos++] = '[';
pos += platform_snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->count);
pos += util_snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->count);
if (pos + 1 >= bufsize)
goto full;
buf[pos++] = ']';
@ -326,7 +325,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi
typelen = strlen(typestr);
if (pos + typelen >= bufsize)
goto full;
platform_strncpy(buf + pos, typestr, typelen);
util_strncpy(buf + pos, typestr, typelen);
return pos + typelen;
}
@ -1464,12 +1463,12 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
platform_strncpy(name, self->name, namelen);
util_strncpy(name, self->name, namelen);
array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->expression.count);
array->ir_values[0] = v;
for (ai = 1; ai < array->expression.count; ++ai) {
platform_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
array->ir_values[ai] = ir_builder_create_field(ir, name, vtype);
if (!array->ir_values[ai]) {
mem_d(name);
@ -1533,12 +1532,12 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
platform_strncpy(name, self->name, namelen);
util_strncpy(name, self->name, namelen);
self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
self->ir_values[0] = v;
for (ai = 1; ai < self->expression.count; ++ai) {
platform_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
self->ir_values[ai] = ir_builder_create_global(ir, name, vtype);
if (!self->ir_values[ai]) {
mem_d(name);
@ -1678,11 +1677,11 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
platform_strncpy(name, self->name, namelen);
util_strncpy(name, self->name, namelen);
self->ir_values[0] = v;
for (ai = 1; ai < self->expression.count; ++ai) {
platform_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
self->ir_values[ai] = ir_function_create_local(func, name, vtype, param);
if (!self->ir_values[ai]) {
compile_error(ast_ctx(self), "internal_error: ir_builder_create_global failed on `%s`", name);

View file

@ -20,6 +20,7 @@
* 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"

12
exec.c
View file

@ -25,9 +25,9 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "gmqcc.h"
#include "platform.h"
static void loaderror(const char *fmt, ...)
{
@ -36,7 +36,7 @@ static void loaderror(const char *fmt, ...)
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
printf(": %s\n", platform_strerror(err));
printf(": %s\n", util_strerror(err));
}
static void qcvmerror(qc_program_t *prog, const char *fmt, ...)
@ -660,7 +660,7 @@ static int qc_ftos(qc_program_t *prog) {
qcany_t str;
CheckArgs(1);
num = GetArg(0);
platform_snprintf(buffer, sizeof(buffer), "%g", num->_float);
util_snprintf(buffer, sizeof(buffer), "%g", num->_float);
str.string = prog_tempstring(prog, buffer);
Return(str);
return 0;
@ -682,7 +682,7 @@ static int qc_vtos(qc_program_t *prog) {
qcany_t str;
CheckArgs(1);
num = GetArg(0);
platform_snprintf(buffer, sizeof(buffer), "'%g %g %g'", num->vector[0], num->vector[1], num->vector[2]);
util_snprintf(buffer, sizeof(buffer), "'%g %g %g'", num->vector[0], num->vector[1], num->vector[2]);
str.string = prog_tempstring(prog, buffer);
Return(str);
return 0;
@ -694,7 +694,7 @@ static int qc_etos(qc_program_t *prog) {
qcany_t str;
CheckArgs(1);
num = GetArg(0);
platform_snprintf(buffer, sizeof(buffer), "%i", num->_int);
util_snprintf(buffer, sizeof(buffer), "%i", num->_int);
str.string = prog_tempstring(prog, buffer);
Return(str);
return 0;
@ -876,7 +876,7 @@ static void prog_main_setparams(qc_program_t *prog) {
arg->vector[2] = 0;
switch (main_params[i].vtype) {
case TYPE_VECTOR:
(void)platform_sscanf(main_params[i].value, " %f %f %f ",
(void)util_sscanf(main_params[i].value, " %f %f %f ",
&arg->vector[0],
&arg->vector[1],
&arg->vector[2]);

3
fold.c
View file

@ -25,7 +25,6 @@
#include "ast.h"
#include "parser.h"
#include "platform.h"
#define FOLD_STRING_UNTRANSLATE_HTSIZE 1024
#define FOLD_STRING_DOTRANSLATE_HTSIZE 1024
@ -339,7 +338,7 @@ ast_expression *fold_constgen_string(fold_t *fold, const char *str, bool transla
if (translate) {
char name[32];
platform_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(fold->parser->translated++));
util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(fold->parser->translated++));
out = ast_value_new(parser_ctx(fold->parser), name, TYPE_STRING);
out->expression.flags |= AST_FLAG_INCLUDE_DEF; /* def needs to be included for translatables */
} else

9
fs.c
View file

@ -20,6 +20,7 @@
* 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"
@ -59,7 +60,8 @@ int fs_file_error(fs_file_t *fp) {
}
int fs_file_getc(fs_file_t *fp) {
return platform_fgetc((FILE*)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) {
@ -67,6 +69,11 @@ int fs_file_puts(fs_file_t *fp, const char *str) {
}
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);
}

22
ftepp.c
View file

@ -23,11 +23,11 @@
*/
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include "gmqcc.h"
#include "lexer.h"
#include "platform.h"
#define HT_MACROS 1024
@ -93,7 +93,7 @@ static char *ftepp_predef_date(lex_file *context) {
(void)context;
time (&rtime);
itime = platform_localtime(&rtime);
itime = util_localtime(&rtime);
strftime(value, 82, "\"%b %d %Y\"", itime);
return value;
@ -108,7 +108,7 @@ static char *ftepp_predef_time(lex_file *context) {
(void)context;
time (&rtime);
itime = platform_localtime(&rtime);
itime = util_localtime(&rtime);
strftime(value, 82, "\"%X\"", itime);
return value;
@ -124,7 +124,7 @@ static char *ftepp_predef_line(lex_file *context) {
static char *ftepp_predef_file(lex_file *context) {
size_t length = strlen(context->name) + 3; /* two quotes and a terminator */
char *value = (char*)mem_a(length);
platform_snprintf(value, length, "\"%s\"", context->name);
util_snprintf(value, length, "\"%s\"", context->name);
return value;
}
@ -172,7 +172,7 @@ static char *ftepp_predef_timestamp(lex_file *context) {
if (stat(context->name, &finfo))
return util_strdup("\"<failed to determine timestamp>\"");
find = platform_ctime(&finfo.st_mtime);
find = util_ctime(&finfo.st_mtime);
value = (char*)mem_a(strlen(find) + 1);
memcpy(&value[1], find, (size = strlen(find)) - 1);
@ -865,7 +865,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
if (resetline && !ftepp->in_macro) {
char lineno[128];
platform_snprintf(lineno, 128, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline));
util_snprintf(lineno, 128, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline));
ftepp_out(ftepp, lineno, false);
}
@ -1465,7 +1465,7 @@ static bool ftepp_include(ftepp_t *ftepp)
ftepp_out(ftepp, "\n#pragma file(", false);
ftepp_out(ftepp, ctx.file, false);
platform_snprintf(lineno, sizeof(lineno), ")\n#pragma line(%lu)\n", (unsigned long)(ctx.line+1));
util_snprintf(lineno, sizeof(lineno), ")\n#pragma line(%lu)\n", (unsigned long)(ctx.line+1));
ftepp_out(ftepp, lineno, false);
/* skip the line */
@ -1844,12 +1844,12 @@ ftepp_t *ftepp_create()
minor[2] = '"';
} else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_GMQCC) {
ftepp_add_define(ftepp, NULL, "__STD_GMQCC__");
platform_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
platform_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
util_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
util_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
} else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCCX) {
ftepp_add_define(ftepp, NULL, "__STD_QCCX__");
platform_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
platform_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
util_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
util_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
} else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC) {
ftepp_add_define(ftepp, NULL, "__STD_QCC__");
/* 1.0 */

18
gmqcc.h
View file

@ -25,6 +25,7 @@
#define GMQCC_HDR
#include <stdarg.h>
#include <stddef.h>
#include <time.h> /* TODO remove?*/
/*
* Disable some over protective warnings in visual studio because fixing them is a waste
@ -301,8 +302,15 @@ uint16_t util_crc16(uint16_t crc, const char *data, size_t len);
void util_seed(uint32_t);
uint32_t util_rand(void);
int util_vasprintf(char **ret, const char *fmt, va_list);
int util_asprintf (char **ret, const char *fmt, ...);
int util_sscanf (const char *str, const char *format, ...);
char *util_strncpy (char *dest, const char *src, size_t n);
char *util_strncat (char *dest, const char *src, size_t n);
char *util_strcat (char *dest, const char *src);
const char *util_strerror(int err);
const struct tm *util_localtime(const time_t *timer);
const char *util_ctime (const time_t *timer);
/*
* A flexible vector implementation: all vector pointers contain some
@ -386,8 +394,15 @@ void util_htrm (hash_table_t *ht, const char *key, void (*cb)(void*));
void *util_htget (hash_table_t *ht, const char *key);
void *util_htgeth(hash_table_t *ht, const char *key, size_t hash);
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;
@ -412,6 +427,7 @@ fs_dir_t *fs_dir_open (const char *);
int fs_dir_close (fs_dir_t *);
fs_dirent_t *fs_dir_read (fs_dir_t *);
/* correct.c */
typedef struct correct_trie_s {
void *value;

View file

@ -21,9 +21,7 @@
* SOFTWARE.
*/
#include <string.h>
#include "parser.h"
#include "platform.h"
/*
* Provides all the "intrinsics" / "builtins" for GMQCC. These can do
@ -41,8 +39,8 @@ static GMQCC_INLINE ast_function *intrin_value(intrin_t *intrin, ast_value **val
char buffer[1024];
char stype [1024];
platform_snprintf(buffer, sizeof(buffer), "__builtin_%s", name);
platform_snprintf(stype, sizeof(stype), "<%s>", type_name[vtype]);
util_snprintf(buffer, sizeof(buffer), "__builtin_%s", name);
util_snprintf(stype, sizeof(stype), "<%s>", type_name[vtype]);
*value = ast_value_new(intrin_ctx(intrin), buffer, TYPE_FUNCTION);
(*value)->intrinsic = true;

9
ir.c
View file

@ -26,7 +26,6 @@
#include "gmqcc.h"
#include "ir.h"
#include "platform.h"
/***********************************************************************
* Type sizes used at multiple points in the IR codegen
@ -3321,7 +3320,7 @@ static ir_value* ir_gen_extparam_proto(ir_builder *ir)
ir_value *global;
char name[128];
platform_snprintf(name, sizeof(name), "EXTPARM#%i", (int)(vec_size(ir->extparam_protos)));
util_snprintf(name, sizeof(name), "EXTPARM#%i", (int)(vec_size(ir->extparam_protos)));
global = ir_value_var(name, store_global, TYPE_VECTOR);
vec_push(ir->extparam_protos, global);
@ -4036,7 +4035,7 @@ void ir_function_dump(ir_function *f, char *ind,
return;
}
oprintf("%sfunction %s\n", ind, f->name);
platform_strncat(ind, "\t", IND_BUFSZ-1);
util_strncat(ind, "\t", IND_BUFSZ-1);
if (vec_size(f->locals))
{
oprintf("%s%i locals:\n", ind, (int)vec_size(f->locals));
@ -4132,7 +4131,7 @@ void ir_block_dump(ir_block* b, char *ind,
{
size_t i;
oprintf("%s:%s\n", ind, b->label);
platform_strncat(ind, "\t", IND_BUFSZ-1);
util_strncat(ind, "\t", IND_BUFSZ-1);
if (b->instr && b->instr[0])
oprintf("%s (%i) [entry]\n", ind, (int)(b->instr[0]->eid-1));
@ -4166,7 +4165,7 @@ void ir_instr_dump(ir_instr *in, char *ind,
return;
}
platform_strncat(ind, "\t", IND_BUFSZ-1);
util_strncat(ind, "\t", IND_BUFSZ-1);
if (in->_ops[0] && (in->_ops[1] || in->_ops[2])) {
ir_value_dump(in->_ops[0], oprintf);

41
lexer.c
View file

@ -25,7 +25,6 @@
#include "gmqcc.h"
#include "lexer.h"
#include "platform.h"
/*
* List of Keywords
@ -275,11 +274,11 @@ static int lex_fgetc(lex_file *lex)
}
if (lex->open_string) {
if (lex->open_string_pos >= lex->open_string_length)
return EOF;
return FS_FILE_EOF;
lex->column++;
return lex->open_string[lex->open_string_pos++];
}
return EOF;
return FS_FILE_EOF;
}
/* Get or put-back data
@ -495,7 +494,7 @@ static bool lex_try_pragma(lex_file *lex)
goto unroll;
lex->line = line;
while (ch != '\n' && ch != EOF)
while (ch != '\n' && ch != FS_FILE_EOF)
ch = lex_getch(lex);
vec_free(command);
vec_free(param);
@ -575,7 +574,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite)
do
{
ch = lex_getch(lex);
while (ch != EOF && util_isspace(ch)) {
while (ch != FS_FILE_EOF && util_isspace(ch)) {
if (ch == '\n') {
if (lex_try_pragma(lex))
continue;
@ -615,7 +614,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite)
lex_tokench(lex, ' ');
}
while (ch != EOF && ch != '\n') {
while (ch != FS_FILE_EOF && ch != '\n') {
if (lex->flags.preprocessing)
lex_tokench(lex, ' '); /* ch); */
ch = lex_getch(lex);
@ -640,7 +639,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite)
lex_tokench(lex, ' ');
}
while (ch != EOF)
while (ch != FS_FILE_EOF)
{
ch = lex_getch(lex);
if (ch == '*') {
@ -673,7 +672,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite)
ch = '/';
break;
}
} while (ch != EOF && util_isspace(ch));
} while (ch != FS_FILE_EOF && util_isspace(ch));
if (haswhite) {
lex_endtoken(lex);
@ -689,7 +688,7 @@ static bool GMQCC_WARN lex_finish_ident(lex_file *lex)
int ch;
ch = lex_getch(lex);
while (ch != EOF && isident(ch))
while (ch != FS_FILE_EOF && isident(ch))
{
lex_tokench(lex, ch);
ch = lex_getch(lex);
@ -709,7 +708,7 @@ static int lex_parse_frame(lex_file *lex)
lex_token_new(lex);
ch = lex_getch(lex);
while (ch != EOF && ch != '\n' && util_isspace(ch))
while (ch != FS_FILE_EOF && ch != '\n' && util_isspace(ch))
ch = lex_getch(lex);
if (ch == '\n')
@ -770,7 +769,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 != EOF)
while (ch != FS_FILE_EOF)
{
ch = lex_getch(lex);
if (ch == quote)
@ -779,18 +778,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 == EOF) {
if (ch == FS_FILE_EOF) {
lexerror(lex, "unexpected end of file");
lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
lex_ungetch(lex, FS_FILE_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 == EOF) {
if (ch == FS_FILE_EOF) {
lexerror(lex, "unexpected end of file");
lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
lex_ungetch(lex, FS_FILE_EOF); /* next token to be TOKEN_EOF */
return (lex->tok.ttype = TOKEN_ERROR);
}
@ -913,7 +912,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, EOF); /* next token to be TOKEN_EOF */
lex_ungetch(lex, FS_FILE_EOF); /* next token to be TOKEN_EOF */
return (lex->tok.ttype = TOKEN_ERROR);
}
@ -1034,7 +1033,7 @@ int lex_do(lex_file *lex)
if (lex->eof)
return (lex->tok.ttype = TOKEN_FATAL);
if (ch == EOF) {
if (ch == FS_FILE_EOF) {
lex->eof = true;
return (lex->tok.ttype = TOKEN_EOF);
}
@ -1071,7 +1070,7 @@ int lex_do(lex_file *lex)
if (!strcmp(v, "framevalue"))
{
ch = lex_getch(lex);
while (ch != EOF && util_isspace(ch) && ch != '\n')
while (ch != FS_FILE_EOF && util_isspace(ch) && ch != '\n')
ch = lex_getch(lex);
if (!util_isdigit(ch)) {
@ -1151,7 +1150,7 @@ int lex_do(lex_file *lex)
vec_free(lex->frames);
/* skip line (fteqcc does it too) */
ch = lex_getch(lex);
while (ch != EOF && ch != '\n')
while (ch != FS_FILE_EOF && ch != '\n')
ch = lex_getch(lex);
return lex_do(lex);
}
@ -1165,7 +1164,7 @@ int lex_do(lex_file *lex)
{
/* skip line */
ch = lex_getch(lex);
while (ch != EOF && ch != '\n')
while (ch != FS_FILE_EOF && ch != '\n')
ch = lex_getch(lex);
return lex_do(lex);
}
@ -1477,7 +1476,7 @@ int lex_do(lex_file *lex)
lex->tok.ttype = TOKEN_CHARCONST;
/* It's a vector if we can successfully scan 3 floats */
if (platform_sscanf(lex->tok.value, " %f %f %f ",
if (util_sscanf(lex->tok.value, " %f %f %f ",
&lex->tok.constval.v.x, &lex->tok.constval.v.y, &lex->tok.constval.v.z) == 3)
{

21
msvc.c
View file

@ -20,6 +20,7 @@
* 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>
@ -54,18 +55,15 @@ int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list a
vsnprintf_s(buffer, bytes, bytes, format, arg);
}
int platform_sscanf(const char *str, const char *format, ...) {
va_list va;
va_start(va, format);
vsscanf_s(str, format, va);
va_end(va);
int platform_vsscanf(const char *str, const char *format, va_list va) {
return vsscanf_s(str, format, va);
}
const struct tm *platform_localtime(const time_t *timer) {
struct tm *t;
t = (struct tm*)platform_mem_allocate(sizeof(struct tm));
localtime_s(&t, timer);
return &t;
return t;
}
const char *platform_ctime(const time_t *timer) {
@ -89,17 +87,6 @@ const char *platform_getenv(char *var) {
return buffer;
}
int platform_snprintf(char *src, size_t bytes, const char *format, ...) {
int rt;
va_list va;
va_start(va, format);
rt = vsprintf_s(src, bytes, format, va);
va_end (va);
return rt;
}
/*
* TODO: this isn't exactly 'accurate' for MSVC but it seems to work,
* at least to some extent.

7
opts.c
View file

@ -25,7 +25,6 @@
#include <stdlib.h>
#include "gmqcc.h"
#include "platform.h"
const unsigned int opts_opt_oflag[COUNT_OPTIMIZATIONS+1] = {
# define GMQCC_TYPE_OPTIMIZATIONS
@ -231,7 +230,7 @@ static size_t opts_ini_parse (
char *read_name;
char *read_value;
while (fs_file_getline(&line, &linesize, filehandle) != EOF) {
while (fs_file_getline(&line, &linesize, filehandle) != FS_FILE_EOF) {
parse_beg = line;
/* handle BOM */
@ -252,7 +251,7 @@ static size_t opts_ini_parse (
/* section found */
if (*(parse_end = opts_ini_next(parse_beg + 1, ']')) == ']') {
* parse_end = '\0'; /* terminate bro */
platform_strncpy(section_data, parse_beg + 1, sizeof(section_data));
util_strncpy(section_data, parse_beg + 1, sizeof(section_data));
section_data[sizeof(section_data) - 1] = '\0';
*oldname_data = '\0';
} else if (!error) {
@ -273,7 +272,7 @@ static size_t opts_ini_parse (
opts_ini_rstrip(read_value);
/* valid name value pair, lets call down to handler */
platform_strncpy(oldname_data, read_name, sizeof(oldname_data));
util_strncpy(oldname_data, read_name, sizeof(oldname_data));
oldname_data[sizeof(oldname_data) - 1] ='\0';
if ((*errorhandle = loadhandle(section_data, read_name, read_value)) && !error)

25
pak.c
View file

@ -24,7 +24,6 @@
#include <stdlib.h>
#include "gmqcc.h"
#include "platform.h"
/*
* The PAK format uses a FOURCC concept for storing the magic ident within
@ -99,14 +98,14 @@ static void pak_tree_build(const char *entry) {
memset(pathsplit, 0, 56);
platform_strncpy(directory, entry, 56);
util_strncpy(directory, entry, 56);
for (itr = 0; (token = pak_tree_sep(&directory, "/")) != NULL; itr++) {
elements[itr] = token;
}
for (jtr = 0; jtr < itr - 1; jtr++) {
platform_strcat(pathsplit, elements[jtr]);
platform_strcat(pathsplit, "/");
util_strcat(pathsplit, elements[jtr]);
util_strcat(pathsplit, "/");
if (fs_dir_make(pathsplit)) {
mem_d(pathsplit);
@ -163,7 +162,7 @@ static pak_file_t *pak_open_read(const char *file) {
* Time to read in the directory handles and prepare the directories
* vector. We're going to be reading some the file inwards soon.
*/
fs_file_seek(pak->handle, pak->header.diroff, SEEK_SET);
fs_file_seek(pak->handle, pak->header.diroff, FS_FILE_SEEK_SET);
/*
* Read in all directories from the PAK file. These are considered
@ -296,7 +295,7 @@ static bool pak_extract_one(pak_file_t *pak, const char *file, const char *outdi
mem_d(local);
/* read */
if (fs_file_seek (pak->handle, dir->pos, SEEK_SET) != 0)
if (fs_file_seek (pak->handle, dir->pos, FS_FILE_SEEK_SET) != 0)
goto err;
fs_file_read (dat, 1, dir->len, pak->handle);
@ -352,9 +351,9 @@ static bool pak_insert_one(pak_file_t *pak, const char *file) {
* the directory entry, and the actual contents of the file
* to the PAK file itself.
*/
if (fs_file_seek(fp, 0, SEEK_END) != 0 || ((len = fs_file_tell(fp)) < 0))
if (fs_file_seek(fp, 0, FS_FILE_SEEK_END) != 0 || ((len = fs_file_tell(fp)) < 0))
goto err;
if (fs_file_seek(fp, 0, SEEK_SET) != 0)
if (fs_file_seek(fp, 0, FS_FILE_SEEK_SET) != 0)
goto err;
dir.len = len;
@ -367,7 +366,7 @@ static bool pak_insert_one(pak_file_t *pak, const char *file) {
if (strlen(file) >= 56)
goto err;
platform_strncpy(dir.name, file, strlen(file));
util_strncpy(dir.name, file, strlen(file));
/*
* Allocate some memory for loading in the data that will be
@ -439,18 +438,17 @@ static bool pak_close(pak_file_t *pak) {
pak->header.diroff = tell;
/* patch header */
if (fs_file_seek (pak->handle, 0, SEEK_SET) != 0)
if (fs_file_seek (pak->handle, 0, FS_FILE_SEEK_SET) != 0)
goto err;
fs_file_write(&(pak->header), sizeof(pak_header_t), 1, pak->handle);
/* write directories */
if (fs_file_seek (pak->handle, pak->header.diroff, SEEK_SET) != 0)
if (fs_file_seek (pak->handle, pak->header.diroff, FS_FILE_SEEK_SET) != 0)
goto err;
for (itr = 0; itr < vec_size(pak->directories); itr++) {
for (itr = 0; itr < vec_size(pak->directories); itr++)
fs_file_write(&(pak->directories[itr]), sizeof(pak_directory_t), 1, pak->handle);
}
}
vec_free (pak->directories);
@ -497,6 +495,7 @@ static bool parsecmd(const char *optname, int *argc_, char ***argv_, char **out,
return true;
}
#include <stdio.h>
int main(int argc, char **argv) {
bool extract = true;
char *redirout = (char*)stdout;

View file

@ -25,7 +25,6 @@
#include <math.h>
#include "parser.h"
#include "platform.h"
#define PARSER_HT_LOCALS 2
#define PARSER_HT_SIZE 512
@ -4025,13 +4024,13 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
varargs->expression.flags |= AST_FLAG_IS_VARARG;
varargs->expression.next = (ast_expression*)ast_value_new(ast_ctx(var), NULL, TYPE_VECTOR);
varargs->expression.count = 0;
platform_snprintf(name, sizeof(name), "%s##va##SET", var->name);
util_snprintf(name, sizeof(name), "%s##va##SET", var->name);
if (!parser_create_array_setter_proto(parser, varargs, name)) {
ast_delete(varargs);
ast_block_delete(block);
goto enderrfn;
}
platform_snprintf(name, sizeof(name), "%s##va##GET", var->name);
util_snprintf(name, sizeof(name), "%s##va##GET", var->name);
if (!parser_create_array_getter_proto(parser, varargs, varargs->expression.next, name)) {
ast_delete(varargs);
ast_block_delete(block);
@ -4928,10 +4927,10 @@ static bool parser_check_qualifiers(parser_t *parser, const ast_value *var, cons
static bool create_array_accessors(parser_t *parser, ast_value *var)
{
char name[1024];
platform_snprintf(name, sizeof(name), "%s##SET", var->name);
util_snprintf(name, sizeof(name), "%s##SET", var->name);
if (!parser_create_array_setter(parser, var, name))
return false;
platform_snprintf(name, sizeof(name), "%s##GET", var->name);
util_snprintf(name, sizeof(name), "%s##GET", var->name);
if (!parser_create_array_getter(parser, var, var->expression.next, name))
return false;
return true;
@ -5459,14 +5458,14 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
goto cleanup;
}
platform_snprintf(name, sizeof(name), "%s##SETF", var->name);
util_snprintf(name, sizeof(name), "%s##SETF", var->name);
if (!parser_create_array_field_setter(parser, array, name))
goto cleanup;
telem = ast_type_copy(ast_ctx(var), array->expression.next);
tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD);
tfield->expression.next = telem;
platform_snprintf(name, sizeof(name), "%s##GETFP", var->name);
util_snprintf(name, sizeof(name), "%s##GETFP", var->name);
if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) {
ast_delete(tfield);
goto cleanup;
@ -5907,7 +5906,7 @@ parser_t *parser_create()
}
}
if (!parser->assign_op) {
printf("internal error: initializing parser: failed to find assign operator\n");
con_err("internal error: initializing parser: failed to find assign operator\n");
mem_d(parser);
return NULL;
}

View file

@ -23,6 +23,12 @@
#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>
@ -70,13 +76,12 @@
#endif /*!_WIN32*/
int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg);
int platform_sscanf(const char *str, const char *format, ...);
int platform_vsscanf(const char *str, const char *format, va_list arg);
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, ...);
int platform_vasprintf(char **dat, const char *fmt, va_list args);
char *platform_strcat(char *dest, const char *src);
char *platform_strncpy(char *dest, const char *src, size_t num);

43
test.c
View file

@ -20,6 +20,7 @@
* 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>
@ -161,8 +162,8 @@ static int task_pclose(fs_file_t **handles) {
char *cmd = NULL;
popen_t *open = (popen_t*)mem_a(sizeof(popen_t));
platform_tmpnam(open->name_err);
platform_tmpnam(open->name_out);
util_tmpnam(open->name_err);
util_tmpnam(open->name_out);
(void)mode; /* excluded */
@ -369,7 +370,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) != EOF) {
while (fs_file_getline(&back, &size, fp) != FS_FILE_EOF) {
/* skip whitespace */
data = back;
if (*data && (*data == ' ' || *data == '\t'))
@ -503,7 +504,7 @@ static task_template_t *task_template_compile(const char *file, const char *dir,
fs_file_t *tempfile = NULL;
task_template_t *tmpl = NULL;
platform_snprintf(fullfile, sizeof(fullfile), "%s/%s", dir, file);
util_snprintf(fullfile, sizeof(fullfile), "%s/%s", dir, file);
tempfile = fs_file_open(fullfile, "r");
tmpl = (task_template_t*)mem_a(sizeof(task_template_t));
@ -713,7 +714,7 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
dir = fs_dir_open(directories[i]);
while ((files = fs_dir_read(dir))) {
platform_snprintf(buffer, sizeof(buffer), "%s/%s", directories[i], files->d_name);
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");
abort();
@ -760,7 +761,7 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
if (strcmp(tmpl->proceduretype, "-pp")) {
if (qcflags) {
if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) {
platform_snprintf(buf, sizeof(buf), "%s %s/%s %s %s -o %s",
util_snprintf(buf, sizeof(buf), "%s %s/%s %s %s -o %s",
task_bins[TASK_COMPILE],
directories[i],
tmpl->sourcefile,
@ -769,7 +770,7 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
tmpl->tempfilename
);
} else {
platform_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s %s -o %s",
util_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s %s -o %s",
task_bins[TASK_COMPILE],
curdir,
defs,
@ -782,7 +783,7 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
}
} else {
if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) {
platform_snprintf(buf, sizeof(buf), "%s %s/%s %s -o %s",
util_snprintf(buf, sizeof(buf), "%s %s/%s %s -o %s",
task_bins[TASK_COMPILE],
directories[i],
tmpl->sourcefile,
@ -790,7 +791,7 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
tmpl->tempfilename
);
} else {
platform_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s -o %s",
util_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s -o %s",
task_bins[TASK_COMPILE],
curdir,
defs,
@ -804,14 +805,14 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
} else {
/* Preprocessing (qcflags mean shit all here we don't allow them) */
if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) {
platform_snprintf(buf, sizeof(buf), "%s -E %s/%s -o %s",
util_snprintf(buf, sizeof(buf), "%s -E %s/%s -o %s",
task_bins[TASK_COMPILE],
directories[i],
tmpl->sourcefile,
tmpl->tempfilename
);
} else {
platform_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s -o %s",
util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s -o %s",
task_bins[TASK_COMPILE],
curdir,
defs,
@ -837,14 +838,14 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
* Open up some file desciptors for logging the stdout/stderr
* to our own.
*/
platform_snprintf(buf, sizeof(buf), "%s.stdout", tmpl->tempfilename);
util_snprintf(buf, sizeof(buf), "%s.stdout", tmpl->tempfilename);
task.stdoutlogfile = util_strdup(buf);
if (!(task.stdoutlog = fs_file_open(buf, "w"))) {
con_err("error opening %s for stdout\n", buf);
continue;
}
platform_snprintf(buf, sizeof(buf), "%s.stderr", tmpl->tempfilename);
util_snprintf(buf, sizeof(buf), "%s.stderr", tmpl->tempfilename);
task.stderrlogfile = util_strdup(buf);
if (!(task.stderrlog = fs_file_open(buf, "w"))) {
con_err("error opening %s for stderr\n", buf);
@ -879,7 +880,7 @@ static void task_precleanup(const char *curdir) {
strstr(files->d_name, ".stdout") ||
strstr(files->d_name, ".stderr"))
{
platform_snprintf(buffer, sizeof(buffer), "%s/%s", curdir, files->d_name);
util_snprintf(buffer, sizeof(buffer), "%s/%s", curdir, files->d_name);
if (remove(buffer))
con_err("error removing temporary file: %s\n", buffer);
}
@ -948,12 +949,12 @@ static bool task_trymatch(size_t i, char ***line) {
* actually specified.
*/
if (!strcmp(tmpl->executeflags, "$null")) {
platform_snprintf(buffer, sizeof(buffer), "%s %s",
util_snprintf(buffer, sizeof(buffer), "%s %s",
task_bins[TASK_EXECUTE],
tmpl->tempfilename
);
} else {
platform_snprintf(buffer, sizeof(buffer), "%s %s %s",
util_snprintf(buffer, sizeof(buffer), "%s %s %s",
task_bins[TASK_EXECUTE],
tmpl->executeflags,
tmpl->tempfilename
@ -993,7 +994,7 @@ static bool task_trymatch(size_t i, char ***line) {
size_t size = 0;
size_t compare = 0;
while (fs_file_getline(&data, &size, execute) != EOF) {
while (fs_file_getline(&data, &size, execute) != FS_FILE_EOF) {
if (!strcmp(data, "No main function found\n")) {
con_err("test failure: `%s` (No main function found) [%s]\n",
tmpl->description,
@ -1098,11 +1099,11 @@ static size_t task_schedualize(size_t *pad) {
size_t j = 0;
size_t failed = 0;
platform_snprintf(space[0], sizeof(space[0]), "%d", (int)vec_size(task_tasks));
util_snprintf(space[0], sizeof(space[0]), "%d", (int)vec_size(task_tasks));
for (; i < vec_size(task_tasks); i++) {
memset(space[1], 0, sizeof(space[1]));
platform_snprintf(space[1], sizeof(space[1]), "%d", (int)(i + 1));
util_snprintf(space[1], sizeof(space[1]), "%d", (int)(i + 1));
con_out("test #%u %*s", i + 1, strlen(space[0]) - strlen(space[1]), "");
@ -1126,7 +1127,7 @@ 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]) != EOF) {
while (fs_file_getline(&data, &size, task_tasks[i].runhandles[1]) != FS_FILE_EOF) {
fs_file_puts(task_tasks[i].stdoutlog, data);
if (strstr(data, "failed to open file")) {
@ -1134,7 +1135,7 @@ static size_t task_schedualize(size_t *pad) {
execute = false;
}
}
while (fs_file_getline(&data, &size, task_tasks[i].runhandles[2]) != EOF) {
while (fs_file_getline(&data, &size, task_tasks[i].runhandles[2]) != FS_FILE_EOF) {
/*
* If a string contains an error we just dissalow execution
* of it in the vm.

45
util.c
View file

@ -21,8 +21,10 @@
* 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 <stdarg.h>
#include "gmqcc.h"
#include "platform.h"
@ -225,9 +227,21 @@ size_t util_optimizationtostr(const char *in, char *out, size_t outsz) {
return util_strtransform(in, out, outsz, "_ ", 'a'-'A');
}
int util_snprintf(char *str, size_t size, const char *fmt, ...) {
va_list arg;
int ret;
va_start(arg, fmt);
ret = platform_vsnprintf(str, size, fmt, arg);
va_end(arg);
return ret;
}
int util_asprintf(char **ret, const char *fmt, ...) {
va_list args;
int read;
va_start(args, fmt);
read = platform_vasprintf(ret, fmt, args);
va_end (args);
@ -235,6 +249,37 @@ int util_asprintf(char **ret, const char *fmt, ...) {
return read;
}
int util_sscanf(const char *str, const char *format, ...) {
va_list args;
int read;
va_start(args, format);
read = platform_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);
}
char *util_strncat(char *dest, const char *src, size_t n) {
return platform_strncat(dest, src, n);
}
char *util_strcat(char *dest, const char *src) {
return platform_strcat(dest, src);
}
const char *util_strerror(int err) {
return platform_strerror(err);
}
const struct tm *util_localtime(const time_t *timer) {
return platform_localtime(timer);
}
const char *util_ctime(const time_t *timer) {
return platform_ctime(timer);
}
void util_seed(uint32_t value) {
srand((int)value);
}