/*
* Copyright (C) 2012, 2013
* Wolfgang Bumiller
- * Dale Weiler
+ * 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
} else {
*out = ir_block_create_load_from_ent(func->curblock, ast_ctx(self), ast_function_label(func, "efv"),
ent, field, self->expression.vtype);
- /* Done AFTER error checking:
+ /* Done AFTER error checking:
codegen_output_type(self, *out);
*/
}
ast_expression *left;
ast_expression *right;
ast_binary_ref refs;
-
+
};
ast_binary* ast_binary_new(lex_ctx ctx,
int op,
/*
* Defaultizer because stdio.h shouldn't be used anywhere except here
* and inside file.c To prevent mis-match of wrapper-interfaces.
- */
+ */
FILE *con_default_out() {
return (console.handle_out = stdout);
}
* Copyright (C) 2012, 2013
* Dale Weiler
* Wolfgang Bumiller
- *
+ *
* 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
* Bayesian interpretation. You can read more about it from here:
* http://www.celiagreen.com/charlesmccreery/statistics/bayestutorial.pdf
* (which is probably the only good online documentation for bayes theroy
- * no lie. Everything else just sucks ..)
- *
+ * no lie. Everything else just sucks ..)
+ *
* Bayes' Thereom suggests something like the following:
* AC P(I|C) P(C) / P(I)
- *
+ *
* However since P(I) is the same for every possibility of I, we can
* completley ignore it giving just:
* AC P(I|C) P(C)
* 3: AC, the control mechanisim, an enumerator if you will, one that
* enumerates all feasible values of C, to determine the one that
* gives the greatest probability score.
- *
+ *
* In reality the requirement for a more complex expression involving
* two seperate models is considerably a waste. But one must recognize
* that P(C|I) is already conflating two factors. It's just much simpler
* distance no greater than one. Knowing this we can optimize for most
* cases of mistakes without taking a performance hit. Which is what we
* base longer edit distances off of. Opposed to the original method of
- * I had concieved of checking everything.
- *
+ * I had concieved of checking everything.
+ *
* A little information on additional algorithms used:
*
* Initially when I implemented this corrector, it was very slow.
* char-to-index map into the branches. We've complelty made the trie
* accesses entierly constant in lookup time. No really, a lookup is
* literally trie[str[0]] [str[1]] [2] .... .value.
- *
- *
+ *
+ *
* Future Work (If we really need it)
*
* Currently we can only distinguish one source of error in the
* Currently the error model has been fairly trivial, the smaller the
* edit distance the smaller the error. This usually causes some un-
* expected problems. e.g reciet->recite yields recipt. For QuakeC
- * this could become a problem when lots of identifiers are involved.
+ * this could become a problem when lots of identifiers are involved.
*/
* not in the mood to figure out that logic. This is a reminder to
* do it, or for someone else to :-) correct_edit however would also
* need to take a size_t ** to carry it along (would all the argument
- * overhead be worth it?)
+ * overhead be worth it?)
*/
static GMQCC_INLINE size_t correct_deletion(const char *ident, char **array) {
size_t itr = 0;
/*
* We can save tons of calls to memcmp if we simply ignore comparisions
* that we know cannot contain the same length.
- */
+ */
if (sizes[itr] == len && !memcmp(array[itr], ident, len))
return 1;
}
* 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).
+ * at least I think so).
*/
#ifdef _MSC_VER
/* {{{ */
* 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.
+ * We handle them here, for all file-operations.
*/
static void file_exception (
/*
* These are implemented as just generic wrappers to keep consistency in
- * the API. Not as macros though
+ * the API. Not as macros though
*/
void fs_file_close(FILE *fp) {
/* Invokes file_exception on windows if fp is null */
/*
* Now we implement some directory functionality. Windows lacks dirent.h
* 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));
strncpy(dir->dd_name, name, strlen(name));
return dir;
}
-
+
int fs_dir_close(DIR *dir) {
FindClose((HANDLE)dir->dd_handle);
mem_d ((void*)dir);
if (!rets)
return NULL;
-
+
if ((data = (struct dirent*)mem_a(sizeof(struct dirent)))) {
strncpy(data->d_name, info.cFileName, FILENAME_MAX - 1);
data->d_name[FILENAME_MAX - 1] = '\0'; /* terminate */
/*
* Copyright (C) 2012, 2013
* Wolfgang Bumiller
- * Dale Weiler
+ * 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
/*
* Implement the predef subsystem now. We can do this safely with the
* help of lexer contexts.
- */
+ */
static uint32_t ftepp_predef_countval = 0;
static uint32_t ftepp_predef_randval = 0;
typedef __int64 int64_t;
#endif /*! _MSC_VER */
-/*
+/*
*windows makes these prefixed because they're C99
* TODO: utility versions that are type-safe and not
* just plain textual subsitution.
* On windows systems where we're not compiling with MING32 we need a
* little extra help on dependinces for implementing our own dirent.h
* in fs.c.
- */
+ */
#if defined(_WIN32) && !defined(__MINGW32__)
# define _WIN32_LEAN_AND_MEAN
# include <windows.h>
void *util_htget (hash_table_t *ht, const char *key);
void *util_htgeth(hash_table_t *ht, const char *key, size_t hash);
-
+
/*===================================================================*/
/*============================ file.c ===============================*/
/*===================================================================*/
int fs_file_printf (FILE *, const char *, ...);
int fs_file_puts (FILE *, const char *);
int fs_file_seek (FILE *, long int, int);
-long int fs_file_tell (FILE *);
+long int fs_file_tell (FILE *);
size_t fs_file_read (void *, size_t, size_t, FILE *);
size_t fs_file_write (const void *, size_t, size_t, FILE *);
* local *= x;
* }
* return local;
- * }
+ * }
*/
static ast_value *value = NULL;
* float mod(float x, float y) {
* return x - y * floor(x / y);
* }
- */
+ */
static ast_value *value = NULL;
if (!value) {
* local = x;
*
* return (x != local);
- * }
- */
+ * }
+ */
static ast_value *value = NULL;
if (!value) {
ast_value *local = ast_value_new (parser_ctx(parser), "local", TYPE_FLOAT);
ast_block *body = ast_block_new (parser_ctx(parser));
ast_function *func = NULL;
-
+
INTRIN_VAL(value, "isnan", func, "<float>", TYPE_FLOAT);
vec_push(body->locals, local);
/*
* jesus fucking christ, Blub design something less fucking
* impossible to use, like a ast_is_builtin(ast_expression *), also
- * use a hashtable :P
- */
+ * use a hashtable :P
+ */
if ((find = (void*)parser_find_global(parser, name)) && ((ast_value*)find)->expression.vtype == TYPE_FUNCTION)
for (i = 0; i < vec_size(parser->functions); ++i)
if (((ast_value*)find)->name && !strcmp(parser->functions[i]->name, ((ast_value*)find)->name) && parser->functions[i]->builtin < 0)
if ((find = util_htget(intrin_intrinsics(), name))) {
/* intrinsic is in table. This will "generate the function" so
* to speak (if it's not already generated).
- */
+ */
return ((intrin_t*)find)->intrin(parser);
}
}
if (vec_size(f->blocks))
{
- oprintf("%slife passes: %i\n", ind, (int)f->run_id);
+ oprintf("%slife passes: %i\n", ind, (int)f->run_id);
for (i = 0; i < vec_size(f->blocks); ++i) {
ir_block_dump(f->blocks[i], ind, oprintf);
}
/*
case '+':
case '-':
- */
+ */
case '*':
case '/':
case '<':
/*
* Copyright (C) 2012, 2013
* Wolfgang Bumiller
- * Dale Weiler
+ * 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
/*
* undef all of these because they may still be defined like in my
* case they where.
- */
+ */
#undef GMQCC_TYPE_FLAGS
#undef GMQCC_TYPE_OPTIMIZATIONS
#undef GMQCC_TYPE_WARNS
size_t line;
FILE *ini;
-
+
if (!file) {
/* try ini */
if (!(ini = fs_file_open((file = "gmqcc.ini"), "r")))
}
fs_file_close(ini);
-}
+}
/*
* Copyright (C) 2013
- * Dale Weiler
+ * 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 PAK format uses a FOURCC concept for storing the magic ident within
* the header as a uint32_t.
- */
+ */
#define PAK_FOURCC ((uint32_t)(('P' | ('A' << 8) | ('C' << 16) | ('K' << 24))))
typedef struct {
* best to store the directories at the end of the file opposed
* to the front, since it allows easy insertion without having
* to load the entire file into memory again.
- */
+ */
uint32_t diroff;
uint32_t dirlen;
} pak_header_t;
* describes a file (with directories/nested ones too in it's
* file name). Hence it can be a file, file with directory, or
* file with directories.
- */
+ */
typedef struct {
char name[56];
uint32_t pos;
* Used to get the next token from a string, where the
* strings themselfs are seperated by chracters from
* `sep`. This is essentially strsep.
- */
+ */
static char *pak_tree_sep(char **str, const char *sep) {
char *beg = *str;
char *end;
/*
* 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);
/*
* Read in all directories from the PAK file. These are considered
* to be the "file entries".
- */
+ */
for (itr = 0; itr < pak->header.dirlen / 64; itr++) {
pak_directory_t dir;
fs_file_read (&dir, sizeof(pak_directory_t), 1, pak->handle);
/*
* Generate the required directory structure / tree for
* writing this PAK file too.
- */
+ */
pak_tree_build(file);
if (!(pak->handle = fs_file_open(file, "wb"))) {
/*
* The directory tree that was created, needs to be
* removed entierly if we failed to open a file.
- */
+ */
/* TODO backup directory clean */
mem_d(pak);
if (!pak || !file)
return false;
-
+
for (itr = 0; itr < vec_size(pak->directories); itr++) {
if (!strcmp(pak->directories[itr].name, file)) {
/*
* Store back a pointer to the directory that matches
* the request if requested (NULL is not allowed).
- */
+ */
if (dir) {
*dir = &(pak->directories[itr]);
}
/*
* Extraction abilities. These work as you expect them to.
- */
+ */
bool pak_extract_one(pak_file_t *pak, const char *file, const char *outdir) {
pak_directory_t *dir = NULL;
unsigned char *dat = NULL;
/*
* Generate the directory structure / tree that will be required
* to store the extracted file.
- */
+ */
pak_tree_build(file);
/* TODO portable path seperators */
/*
* Now create the file, if this operation fails. Then abort
* It shouldn't fail though.
- */
+ */
if (!(out = fs_file_open(local, "wb"))) {
mem_d(dat);
return false;
/*
* We don't allow insertion on files that already exist within the
* pak file. Weird shit can happen if we allow that ;). We also
- * don't allow insertion if the pak isn't opened in write mode.
- */
+ * don't allow insertion if the pak isn't opened in write mode.
+ */
if (!pak || !file || !pak->insert || pak_exists(pak, file, NULL))
return false;
/*
* We're limited to 56 bytes for a file name string, that INCLUDES
* the directory and '/' seperators.
- */
+ */
if (strlen(file) >= 56) {
fs_file_close(fp);
return false;
/*
* Allocate some memory for loading in the data that will be
* redirected into the PAK file.
- */
+ */
if (!(dat = (unsigned char *)mem_a(dir.len))) {
fs_file_close(fp);
return false;
/*
* Like pak_insert_one, except this collects files in all directories
* from a root directory, and inserts them all.
- */
+ */
bool pak_insert_all(pak_file_t *pak, const char *dir) {
DIR *dp;
struct dirent *dirp;
/*
* In insert mode we need to patch the header, and write
* our directory entries at the end of the file.
- */
+ */
if (pak->insert) {
pak->header.dirlen = vec_size(pak->directories) * 64;
pak->header.diroff = ftell(pak->handle);
- /* patch header */
+ /* patch header */
fs_file_seek (pak->handle, 0, SEEK_SET);
fs_file_write(&(pak->header), sizeof(pak_header_t), 1, pak->handle);
* Copyright (C) 2012, 2013
* Wolfgang Bumiller
* 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
} else {
var = intrin_func(parser, parser_tokval(parser));
}
-
+
if (!var) {
char *correct = NULL;
size_t i;
/*
* store the vstring back to var for alias and
* deprecation messages.
- */
+ */
if (var->expression.flags & AST_FLAG_DEPRECATED ||
var->expression.flags & AST_FLAG_ALIAS)
var->desc = vstring;
ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name);
if (!parser_check_qualifiers(parser, var, proto)) {
retval = false;
- if (proto->desc)
+ if (proto->desc)
mem_d(proto->desc);
proto = NULL;
goto cleanup;
/*
* add alias to aliases table and to corrector
* so corrections can apply for aliases as well.
- */
+ */
util_htset(parser->aliases, var->name, find);
/*
* add to corrector so corrections can work
* even for aliases too.
- */
+ */
correct_add (
vec_last(parser->correct_variables),
&vec_last(parser->correct_variables_score),
/*
* add to corrector so corrections can work
* even for aliases too.
- */
+ */
correct_add (
vec_last(parser->correct_variables),
&vec_last(parser->correct_variables_score),
* This will perform compilation and execution
* -fail
* This will perform compilation, but requires
- * the compilation to fail in order to succeed.
+ * the compilation to fail in order to succeed.
*
* This must be provided, this tag is NOT optional.
*
/*
* Create some padding for the description to align the
* printing of the rules file.
- */
+ */
if ((desclen = strlen(tmpl->description)) > pad[0])
pad[0] = desclen;
}
/*
* Create some padding for the printing to align the
* printing of the rules file to the console.
- */
+ */
if ((filepadd = strlen(fullfile)) > pad[1])
pad[1] = filepadd;
/*
* Only remove the log files if the test actually compiled otherwise
* forget about it (or if it didn't compile, and the procedure type
- * was set to -fail (meaning it shouldn't compile) .. stil remove)
+ * was set to -fail (meaning it shouldn't compile) .. stil remove)
*/
if (task_tasks[i].compiled || !strcmp(task_tasks[i].tmpl->proceduretype, "-fail")) {
if (remove(task_tasks[i].stdoutlogfile))
* This executes the QCVM task for a specificly compiled progs.dat
* using the template passed into it for call-flags and user defined
* messages IF the procedure type is -execute, otherwise it matches
- * the preprocessor output.
+ * the preprocessor output.
*/
bool task_trymatch(task_template_t *tmpl, char ***line) {
bool success = true;
/*
* Copy to output vector for diagnostics if execution match
* fails.
- */
+ */
vec_push(*line, data);
/* reset */
for (; i < vec_size(task_tasks); i++) {
memset(space[1], 0, sizeof(space[1]));
snprintf(space[1], sizeof(space[1]), "%d", (int)(i + 1));
-
+
con_out("test #%u %*s", i + 1, strlen(space[0]) - strlen(space[1]), "");
util_debug("TEST", "executing task: %d: %s\n", i, task_tasks[i].tmpl->description);
task_tasks[i].tmpl->rulesfile,
(pad[1] + pad[2] - strlen(task_tasks[i].tmpl->rulesfile)) + (strlen(task_type(task_tasks[i].tmpl)) - pad[2]),
task_type(task_tasks[i].tmpl)
-
+
);
continue;
}
/*
* If we made it here that concludes the task is to be executed
* in the virtual machine (or the preprocessor output needs to
- * be matched).
+ * be matched).
*/
if (!task_trymatch(task_tasks[i].tmpl, &match)) {
size_t d = 0;
* Print the non-expected out (since we are simply not expecting it)
* This will help track down bugs in template files that fail to match
* something.
- */
+ */
if (vec_size(match) > vec_size(task_tasks[i].tmpl->comparematch)) {
for (d = 0; d < vec_size(match) - vec_size(task_tasks[i].tmpl->comparematch); d++) {
con_out(" Expected: Nothing | Got: \"%s\"\n",
);
}
}
-
+
for (j = 0; j < vec_size(match); j++)
mem_d(match[j]);
task_tasks[i].tmpl->rulesfile,
(pad[1] + pad[2] - strlen(task_tasks[i].tmpl->rulesfile)) + (strlen(task_type(task_tasks[i].tmpl))- pad[2]),
task_type(task_tasks[i].tmpl)
-
+
);
}
mem_d(data);
/*
* If the default definition file isn't set to anything. We will
* use the default_defs here, which is "defs.qc"
- */
+ */
if (!defs) {
defs = default_defs;
}
-
+
task_precleanup(curdir);
if (!task_propagate(curdir, pad, defs)) {
/*
* only required if big endian .. otherwise no need to swap
* data.
- */
+ */
#if PLATFORM_BYTE_ORDER == GMQCC_BYTE_ORDER_BIG
static GMQCC_INLINE void util_swap16(uint16_t *d, size_t l) {
while (l--) {
/* Non - Reflected */
uint16_t util_crc16(uint16_t current, const char *k, size_t len) {
register uint16_t h = current;
- for (; len; --len, ++k)
+ for (; len; --len, ++k)
h = util_crc16_table[(h>>8)^((unsigned char)*k)]^(h<<8);
return h;
}
#if 0
uint16_t util_crc16(const char *k, int len, const short clamp) {
register uint16_t h= (uint16_t)0xFFFFFFFF;
- for (; len; --len, ++k)
+ for (; len; --len, ++k)
h = util_crc16_table[(h^((unsigned char)*k))&0xFF]^(h>>8);
- return (~h)%clamp;
+ return (~h)%clamp;
}
#endif
* Portable implementation of vasprintf/asprintf. Assumes vsnprintf
* exists, otherwise compiler error.
*
- * TODO: fix for MSVC ....
+ * TODO: fix for MSVC ....
*/
int util_vasprintf(char **dat, const char *fmt, va_list args) {
int ret;
* formatted string if it overflows. However there is a MSVC
* intrinsic (which is documented wrong) called _vcsprintf which
* will return the required amount to allocate.
- */
+ */
#ifdef _MSC_VER
char *str;
if ((len = _vscprintf(fmt, args)) < 0) {
* a branch that is executed every iteration from [0, MT_SIZE).
*
* Please see: http://www.quadibloc.com/crypto/co4814.htm for more
- * information on how this clever trick works.
+ * information on how this clever trick works.
*/
static const uint32_t matrix[2] = {
0x00000000,