b45ce608c0
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5940 fc73d0e0-1445-4013-8a0c-d673dee63da5
272 lines
4.2 KiB
C
272 lines
4.2 KiB
C
//compile routines
|
|
|
|
#include "qcc.h"
|
|
#undef progfuncs
|
|
|
|
char errorfile[128];
|
|
int errorline;
|
|
|
|
progfuncs_t *qccprogfuncs;
|
|
|
|
#include <setjmp.h>
|
|
|
|
extern int qcc_compileactive;
|
|
jmp_buf qcccompileerror;
|
|
char qcc_gamedir[128];
|
|
void QCC_PR_ResetErrorScope(void);
|
|
|
|
|
|
|
|
#if defined(MINIMAL) || defined(OMIT_QCC)
|
|
|
|
#else
|
|
|
|
static struct qcchunk_s
|
|
{
|
|
struct qcchunk_s *older;
|
|
char *data;
|
|
char *end;
|
|
} *qcc_hunk;
|
|
static void qccHunkExtend(size_t minsize)
|
|
{
|
|
struct qcchunk_s *n;
|
|
size_t sz;
|
|
minsize += sizeof(struct qcchunk_s)+64;
|
|
sz = max(minsize, 256*1024*1024);
|
|
|
|
for (;;)
|
|
{
|
|
if (sz < minsize)
|
|
QCC_Error(ERR_INTERNAL, "Compile hunk was filled");
|
|
n = malloc(sz);
|
|
if (n)
|
|
break;
|
|
sz /= 2;
|
|
}
|
|
|
|
n->data = (char*)(n+1);
|
|
n->end = ((char*)n)+sz;
|
|
n->older = qcc_hunk;
|
|
qcc_hunk = n;
|
|
}
|
|
void *qccHunkAlloc(size_t mem)
|
|
{
|
|
char *ret;
|
|
mem = (mem + 7)&~7;
|
|
|
|
if (qcc_hunk->data+mem > qcc_hunk->end)
|
|
qccHunkExtend(mem);
|
|
ret = qcc_hunk->data;
|
|
qcc_hunk->data += mem;
|
|
|
|
memset(ret, 0, mem);
|
|
return ret;
|
|
}
|
|
void qccClearHunk(void)
|
|
{
|
|
struct qcchunk_s *t;
|
|
while (qcc_hunk)
|
|
{
|
|
t = qcc_hunk;
|
|
qcc_hunk = t->older;
|
|
free(t);
|
|
}
|
|
}
|
|
int qccpersisthunk;
|
|
void PostCompile(void)
|
|
{
|
|
if (!qccpersisthunk)
|
|
qccClearHunk();
|
|
QCC_PR_CloseProcessor();
|
|
QCC_Cleanup();
|
|
|
|
if (asmfile)
|
|
{
|
|
fclose(asmfile);
|
|
asmfile = NULL;
|
|
}
|
|
}
|
|
pbool PreCompile(void)
|
|
{
|
|
QCC_PR_ResetErrorScope();
|
|
|
|
qccClearHunk();
|
|
strcpy(qcc_gamedir, "");
|
|
|
|
qccHunkExtend(0);
|
|
return true;
|
|
}
|
|
|
|
pbool QCC_main (int argc, const char **argv);
|
|
void QCC_FinishCompile(void);
|
|
|
|
int comp_nump;const char **comp_parms;
|
|
//void Editor(char *fname, int line, int numparms, char **compileparms);
|
|
pbool CompileParams(progfuncs_t *progfuncs, void(*cb)(void), int nump, const char **parms)
|
|
{
|
|
comp_nump = nump;
|
|
comp_parms = parms;
|
|
*errorfile = '\0';
|
|
qccprogfuncs = progfuncs;
|
|
if (setjmp(qcccompileerror))
|
|
{
|
|
PostCompile();
|
|
if (*errorfile)
|
|
{
|
|
externs->Printf("Error in %s on line %i\n", errorfile, errorline);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (!QCC_main(nump, parms))
|
|
return false;
|
|
|
|
while(qcc_compileactive)
|
|
{
|
|
if (cb)
|
|
cb();
|
|
|
|
QCC_ContinueCompile();
|
|
}
|
|
|
|
PostCompile();
|
|
|
|
return !pr_error_count;
|
|
}
|
|
int PDECL Comp_Begin(pubprogfuncs_t *progfuncs, int nump, const char **parms)
|
|
{
|
|
comp_nump = nump;
|
|
comp_parms = parms;
|
|
qccprogfuncs = (progfuncs_t*)progfuncs;
|
|
*errorfile = '\0';
|
|
if (setjmp(qcccompileerror))
|
|
{
|
|
PostCompile();
|
|
return false;
|
|
}
|
|
|
|
if (!QCC_main(nump, parms))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
int PDECL Comp_Continue(pubprogfuncs_t *progfuncs)
|
|
{
|
|
qccprogfuncs = (progfuncs_t *)progfuncs;
|
|
if (setjmp(qcccompileerror))
|
|
{
|
|
PostCompile();
|
|
return false;
|
|
}
|
|
|
|
if (qcc_compileactive)
|
|
QCC_ContinueCompile();
|
|
else
|
|
{
|
|
PostCompile();
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
#endif
|
|
pbool CompileFile(progfuncs_t *progfuncs, const char *filename)
|
|
{
|
|
#if defined(MINIMAL) || defined(OMIT_QCC)
|
|
return false;
|
|
#else
|
|
char srcfile[32];
|
|
char newname[32];
|
|
static const char *p[5];
|
|
int parms;
|
|
char *s, *s2;
|
|
|
|
p[0] = NULL;
|
|
parms = 1;
|
|
|
|
strcpy(newname, filename);
|
|
s = newname;
|
|
if (strchr(s+1, '/'))
|
|
{
|
|
while(1)
|
|
{
|
|
s2 = strchr(s+1, '/');
|
|
if (!s2)
|
|
{
|
|
*s = '\0';
|
|
break;
|
|
}
|
|
s = s2;
|
|
}
|
|
p[parms] = "-src";
|
|
p[parms+1] = newname;
|
|
parms+=2;
|
|
|
|
strcpy(srcfile, s+1);
|
|
srcfile[strlen(srcfile)-4] = '\0';
|
|
strcat(srcfile, ".src");
|
|
|
|
if (externs->FileSize(qcva("%s/%s", newname, srcfile))>0)
|
|
{
|
|
p[parms] = "-srcfile";
|
|
p[parms+1] = srcfile;
|
|
parms+=2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
p[parms] = "-srcfile";
|
|
p[parms+1] = newname;
|
|
newname[strlen(newname)-4] = '\0';
|
|
strcat(newname, ".src");
|
|
parms+=2;
|
|
}
|
|
// p[2][strlen(p[2])-4] = '\0';
|
|
// strcat(p[2], "/");
|
|
|
|
while (!CompileParams(progfuncs, NULL, parms, p))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
int QC_strncasecmp(const char *s1, const char *s2, int n)
|
|
{
|
|
int c1, c2;
|
|
|
|
while (1)
|
|
{
|
|
c1 = *s1++;
|
|
c2 = *s2++;
|
|
|
|
if (!n--)
|
|
return 0; // strings are equal until end point
|
|
|
|
if (c1 != c2)
|
|
{
|
|
if (c1 >= 'a' && c1 <= 'z')
|
|
c1 -= ('a' - 'A');
|
|
if (c2 >= 'a' && c2 <= 'z')
|
|
c2 -= ('a' - 'A');
|
|
if (c1 != c2)
|
|
return -1; // strings not equal
|
|
}
|
|
if (!c1)
|
|
return 0; // strings are equal
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void editbadfile(const char *fname, int line)
|
|
{
|
|
if (!*errorfile)
|
|
{
|
|
strcpy(errorfile, fname);
|
|
errorline = line;
|
|
}
|
|
}
|
|
|