#include "gmqcc.h"
-/*
-(prog_section_statement, code)
-(prog_section_def, defs)
-(prog_section_def, fields)
-(prog_section_function, functions)
-(char, strings)
-(qcint, globals)
-(qcint, entitydata)
-(bool, entitypool)
-(qcint, localstack)
-(qc_exec_stack, stack)
-(size_t, profile)
-(prog_builtin, builtins)
-(const char*, function_stack)
-*/
-
static void loaderror(const char *fmt, ...)
{
int err = errno;
qc_program* prog_load(const char *filename)
{
- qc_program *prog;
- prog_header header;
- FILE *file;
+ qc_program *prog;
+ prog_header header;
+ FILE *file = file_open(filename, "rb");
- file = util_fopen(filename, "rb");
if (!file)
return NULL;
- if (fread(&header, sizeof(header), 1, file) != 1) {
+ if (file_read(&header, sizeof(header), 1, file) != 1) {
loaderror("failed to read header from '%s'", filename);
- fclose(file);
+ file_close(file);
return NULL;
}
if (header.version != 6) {
loaderror("header says this is a version %i progs, we need version 6\n", header.version);
- fclose(file);
+ file_close(file);
return NULL;
}
prog = (qc_program*)mem_a(sizeof(qc_program));
if (!prog) {
- fclose(file);
+ file_close(file);
printf("failed to allocate program data\n");
return NULL;
}
}
#define read_data(hdrvar, progvar, reserved) \
- if (fseek(file, header.hdrvar.offset, SEEK_SET) != 0) { \
+ if (file_seek(file, header.hdrvar.offset, SEEK_SET) != 0) { \
loaderror("seek failed"); \
goto error; \
} \
- if (fread(vec_add(prog->progvar, header.hdrvar.length + reserved), \
- sizeof(*prog->progvar), \
- header.hdrvar.length, file) \
- != header.hdrvar.length) \
- { \
+ if (file_read ( \
+ vec_add(prog->progvar, header.hdrvar.length + reserved), \
+ sizeof(*prog->progvar), \
+ header.hdrvar.length, \
+ file \
+ )!= header.hdrvar.length \
+ ) { \
loaderror("read failed"); \
goto error; \
}
read_data1(strings);
read_data2(globals, 2); /* reserve more in case a RETURN using with the global at "the end" exists */
- fclose(file);
+ file_close(file);
/* profile counters */
memset(vec_add(prog->profile, vec_size(prog->code)), 0, sizeof(prog->profile[0]) * vec_size(prog->code));
char* prog_getstring(qc_program *prog, qcint str)
{
+ /* cast for return required for C++ */
if (str < 0 || str >= (qcint)vec_size(prog->strings))
- return "<<<invalid string>>>";
+ return (char*)"<<<invalid string>>>";
return prog->strings + str;
}
#define QCVM_PROFILE 0
#define QCVM_TRACE 0
# include __FILE__
- break;
}
case (VMXF_TRACE):
{
#define QCVM_PROFILE 0
#define QCVM_TRACE 1
# include __FILE__
- break;
}
case (VMXF_PROFILE):
{
#define QCVM_PROFILE 1
#define QCVM_TRACE 0
# include __FILE__
- break;
}
case (VMXF_TRACE|VMXF_PROFILE):
{
#define QCVM_PROFILE 1
#define QCVM_TRACE 1
# include __FILE__
- break;
}
};
const char *laststr = NULL;
for (i = 0; i < (size_t)prog->argc; ++i) {
qcany *str = (qcany*)(prog->globals + OFS_PARM0 + 3*i);
- printf("%s", (laststr = prog_getstring(prog, str->string)));
+ laststr = prog_getstring(prog, str->string);
+ printf("%s", laststr);
}
if (laststr && (prog->xflags & VMXF_TRACE)) {
size_t len = strlen(laststr);
static const char *arg0 = NULL;
-void usage()
+static void version() {
+ printf("GMQCC-QCVM %d.%d.%d Built %s %s\n",
+ GMQCC_VERSION_MAJOR,
+ GMQCC_VERSION_MINOR,
+ GMQCC_VERSION_PATCH,
+ __DATE__,
+ __TIME__
+ );
+}
+
+static void usage()
{
printf("usage: %s [options] [parameters] file\n", arg0);
printf("options:\n");
arg->vector[2] = 0;
switch (main_params[i].vtype) {
case TYPE_VECTOR:
-#ifdef WIN32
+#ifdef _MSC_VER
(void)sscanf_s(main_params[i].value, " %f %f %f ",
&arg->vector[0],
&arg->vector[1],
bool opts_disasm = false;
bool opts_info = false;
bool noexec = false;
+ const char *progsfile = NULL;
arg0 = argv[0];
exit(1);
}
- while (argc > 2) {
+ while (argc > 1) {
if (!strcmp(argv[1], "-h") ||
!strcmp(argv[1], "-help") ||
!strcmp(argv[1], "--help"))
usage();
exit(0);
}
+ else if (!strcmp(argv[1], "-v") ||
+ !strcmp(argv[1], "-version") ||
+ !strcmp(argv[1], "--version"))
+ {
+ version();
+ exit(0);
+ }
else if (!strcmp(argv[1], "-trace")) {
--argc;
++argv;
--argc;
++argv;
}
+ else if (!strcmp(argv[1], "--")) {
+ --argc;
+ ++argv;
+ break;
+ }
+ else if (argv[1][0] != '-') {
+ if (progsfile) {
+ printf("only 1 program file may be specified\n");
+ usage();
+ exit(1);
+ }
+ progsfile = argv[1];
+ --argc;
+ ++argv;
+ }
else
{
usage();
}
}
+ if (argc > 2) {
+ usage();
+ exit(1);
+ }
+ if (argc > 1) {
+ if (progsfile) {
+ printf("only 1 program file may be specified\n");
+ usage();
+ exit(1);
+ }
+ progsfile = argv[1];
+ --argc;
+ ++argv;
+ }
+
+ if (!progsfile) {
+ usage();
+ exit(1);
+ }
- prog = prog_load(argv[1]);
+ prog = prog_load(progsfile);
if (!prog) {
- printf("failed to load program '%s'\n", argv[1]);
+ printf("failed to load program '%s'\n", progsfile);
exit(1);
}
printf("Program's system-checksum = 0x%04x\n", (unsigned int)prog->crc16);
printf("Entity field space: %u\n", (unsigned int)prog->entityfields);
printf("Globals: %u\n", (unsigned int)vec_size(prog->globals));
+ printf("Counts:\n"
+ " code: %lu\n"
+ " defs: %lu\n"
+ " fields: %lu\n"
+ " functions: %lu\n"
+ " strings: %lu\n",
+ (unsigned long)vec_size(prog->code),
+ (unsigned long)vec_size(prog->defs),
+ (unsigned long)vec_size(prog->fields),
+ (unsigned long)vec_size(prog->functions),
+ (unsigned long)vec_size(prog->strings));
}
if (opts_info) {