Use the QVM build toolchain from ioq3
This commit is contained in:
@@ -63,9 +63,9 @@ char *ex_argv[MAX_EX_ARGC];
|
||||
void ExpandWildcards( int *argc, char ***argv )
|
||||
{
|
||||
struct _finddata_t fileinfo;
|
||||
int handle;
|
||||
intptr_t handle;
|
||||
int i;
|
||||
char filename[1024];
|
||||
char filename[2048];
|
||||
char filebase[1024];
|
||||
char *path;
|
||||
|
||||
@@ -88,7 +88,7 @@ void ExpandWildcards( int *argc, char ***argv )
|
||||
|
||||
do
|
||||
{
|
||||
sprintf (filename, "%s%s", filebase, fileinfo.name);
|
||||
snprintf (filename, sizeof(filename), "%s%s", filebase, fileinfo.name);
|
||||
ex_argv[ex_argc++] = copystring (filename);
|
||||
} while (_findnext( handle, &fileinfo ) != -1);
|
||||
|
||||
@@ -126,7 +126,7 @@ void Error( const char *error, ... )
|
||||
vsprintf (text, error,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
sprintf (text2, "%s\nGetLastError() = %i", text, err);
|
||||
snprintf (text2, sizeof(text2), "%s\nGetLastError() = %i", text, err);
|
||||
MessageBox(NULL, text2, "Error", 0 /* MB_OK */ );
|
||||
|
||||
exit (1);
|
||||
@@ -185,7 +185,7 @@ void _printf( const char *format, ... ) {
|
||||
vsprintf (text, format, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
printf(text);
|
||||
printf("%s", text);
|
||||
|
||||
#ifdef WIN32
|
||||
if (!lookedForServer) {
|
||||
@@ -318,7 +318,7 @@ char *ExpandPath (const char *path)
|
||||
strcpy( full, path );
|
||||
return full;
|
||||
}
|
||||
sprintf (full, "%s%s", qdir, path);
|
||||
snprintf (full, sizeof(full), "%s%s", qdir, path);
|
||||
return full;
|
||||
}
|
||||
|
||||
@@ -331,20 +331,20 @@ char *ExpandGamePath (const char *path)
|
||||
strcpy( full, path );
|
||||
return full;
|
||||
}
|
||||
sprintf (full, "%s%s", gamedir, path);
|
||||
snprintf (full, sizeof(full), "%s%s", gamedir, path);
|
||||
return full;
|
||||
}
|
||||
|
||||
char *ExpandPathAndArchive (const char *path)
|
||||
{
|
||||
char *expanded;
|
||||
char archivename[1024];
|
||||
char archivename[2048];
|
||||
|
||||
expanded = ExpandPath (path);
|
||||
|
||||
if (archive)
|
||||
{
|
||||
sprintf (archivename, "%s/%s", archivedir, path);
|
||||
snprintf (archivename, sizeof(archivename), "%s/%s", archivedir, path);
|
||||
QCopyFile (expanded, archivename);
|
||||
}
|
||||
return expanded;
|
||||
@@ -396,10 +396,12 @@ void Q_getwd (char *out)
|
||||
int i = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
_getcwd (out, 256);
|
||||
if (_getcwd (out, 256) == NULL)
|
||||
strcpy(out, "."); /* shrug */
|
||||
strcat (out, "\\");
|
||||
#else
|
||||
getcwd (out, 256);
|
||||
if (getcwd (out, 256) == NULL)
|
||||
strcpy(out, "."); /* shrug */
|
||||
strcat (out, "/");
|
||||
#endif
|
||||
|
||||
@@ -732,7 +734,7 @@ int LoadFile( const char *filename, void **bufferptr )
|
||||
==============
|
||||
LoadFileBlock
|
||||
-
|
||||
rounds up memory allocation to 4K boundry
|
||||
rounds up memory allocation to 4K boundary
|
||||
-
|
||||
==============
|
||||
*/
|
||||
@@ -808,7 +810,7 @@ void DefaultExtension (char *path, const char *extension)
|
||||
{
|
||||
char *src;
|
||||
//
|
||||
// if path doesnt have a .EXT, append extension
|
||||
// if path doesn't have a .EXT, append extension
|
||||
// (extension should include the .)
|
||||
//
|
||||
src = path + strlen(path) - 1;
|
||||
|
@@ -59,7 +59,7 @@ typedef unsigned char byte;
|
||||
#define MAX_OS_PATH 1024
|
||||
#define MEM_BLOCKSIZE 4096
|
||||
|
||||
// the dec offsetof macro doesnt work very well...
|
||||
// the dec offsetof macro doesn't work very well...
|
||||
#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier)
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@ char *strupr (char *in);
|
||||
char *strlower (char *in);
|
||||
int Q_strncasecmp( const char *s1, const char *s2, int n );
|
||||
int Q_stricmp( const char *s1, const char *s2 );
|
||||
#define Q_strequal(s1,s2) (Q_stricmp(s1,s2)==0)
|
||||
void Q_getwd( char *out );
|
||||
|
||||
int Q_filelength (FILE *f);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
|
||||
don't do any paramter conversion (double to float, etc)
|
||||
don't do any parameter conversion (double to float, etc)
|
||||
|
||||
|
||||
|
||||
|
@@ -250,7 +250,6 @@ static void hashtable_init (hashtable_t *H, int buckets)
|
||||
{
|
||||
H->buckets = buckets;
|
||||
H->table = calloc(H->buckets, sizeof(*(H->table)));
|
||||
return;
|
||||
}
|
||||
|
||||
static hashtable_t *hashtable_new (int buckets)
|
||||
@@ -285,7 +284,6 @@ static void hashtable_add (hashtable_t *H, int hashvalue, void *datum)
|
||||
}
|
||||
hc->data = datum;
|
||||
hc->next = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static hashchain_t *hashtable_get (hashtable_t *H, int hashvalue)
|
||||
@@ -386,8 +384,12 @@ static void sort_symbols ()
|
||||
symbol_t *s;
|
||||
symbol_t **symlist;
|
||||
|
||||
if(!symbols)
|
||||
return;
|
||||
|
||||
//crumb("sort_symbols: Constructing symlist array\n");
|
||||
for (elems = 0, s = symbols; s; s = s->next, elems++) /* nop */ ;
|
||||
|
||||
symlist = malloc(elems * sizeof(symbol_t*));
|
||||
for (i = 0, s = symbols; s; s = s->next, i++)
|
||||
{
|
||||
@@ -475,7 +477,7 @@ static unsigned int HashString (const char *key)
|
||||
acc = (acc << 2) | (acc >> 30);
|
||||
acc &= 0xffffffffU;
|
||||
}
|
||||
return abs(acc);
|
||||
return acc;
|
||||
}
|
||||
|
||||
|
||||
@@ -489,10 +491,10 @@ static void CodeError( char *fmt, ... ) {
|
||||
|
||||
errorCount++;
|
||||
|
||||
report( "%s:%i ", currentFileName, currentFileLine );
|
||||
fprintf( stderr, "%s:%i ", currentFileName, currentFileLine );
|
||||
|
||||
va_start( argptr,fmt );
|
||||
vprintf( fmt,argptr );
|
||||
vfprintf( stderr, fmt, argptr );
|
||||
va_end( argptr );
|
||||
}
|
||||
|
||||
@@ -544,7 +546,7 @@ static void DefineSymbol( char *sym, int value ) {
|
||||
|
||||
// add the file prefix to local symbols to guarantee unique
|
||||
if ( sym[0] == '$' ) {
|
||||
sprintf( expanded, "%s_%i", sym, currentFileIndex );
|
||||
snprintf( expanded, sizeof(expanded), "%s_%i", sym, currentFileIndex );
|
||||
sym = expanded;
|
||||
}
|
||||
|
||||
@@ -600,7 +602,7 @@ static int LookupSymbol( char *sym ) {
|
||||
|
||||
// add the file prefix to local symbols to guarantee unique
|
||||
if ( sym[0] == '$' ) {
|
||||
sprintf( expanded, "%s_%i", sym, currentFileIndex );
|
||||
snprintf( expanded, sizeof(expanded), "%s_%i", sym, currentFileIndex );
|
||||
sym = expanded;
|
||||
}
|
||||
|
||||
@@ -786,7 +788,7 @@ HackToSegment
|
||||
|
||||
BIG HACK: I want to put all 32 bit values in the data
|
||||
segment so they can be byte swapped, and all char data in the lit
|
||||
segment, but switch jump tables are emited in the lit segment and
|
||||
segment, but switch jump tables are emitted in the lit segment and
|
||||
initialized strng variables are put in the data segment.
|
||||
|
||||
I can change segments here, but I also need to fixup the
|
||||
@@ -946,12 +948,11 @@ STAT("PROC");
|
||||
|
||||
ASM(ENDPROC)
|
||||
{
|
||||
int v, v2;
|
||||
if ( !strcmp( token, "endproc" ) ) {
|
||||
STAT("ENDPROC");
|
||||
Parse(); // skip the function name
|
||||
v = ParseValue(); // locals
|
||||
v2 = ParseValue(); // arg marshalling
|
||||
ParseValue(); // locals
|
||||
ParseValue(); // arg marshalling
|
||||
|
||||
// all functions must leave something on the opstack
|
||||
instructionCount++;
|
||||
@@ -1128,7 +1129,7 @@ STAT("BYTE");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// code labels are emited as instruction counts, not byte offsets,
|
||||
// code labels are emitted as instruction counts, not byte offsets,
|
||||
// because the physical size of the code will change with
|
||||
// different run time compilers and we want to minimize the
|
||||
// size of the required translation table
|
||||
@@ -1520,12 +1521,13 @@ static void ShowHelp( char *argv0 ) {
|
||||
Error("Usage: %s [OPTION]... [FILES]...\n\
|
||||
Assemble LCC bytecode assembly to Q3VM bytecode.\n\
|
||||
\n\
|
||||
-o OUTPUT Write assembled output to file OUTPUT.qvm\n\
|
||||
-f LISTFILE Read options and list of files to assemble from LISTFILE.q3asm\n\
|
||||
-b BUCKETS Set symbol hash table to BUCKETS buckets\n\
|
||||
-v Verbose compilation report\n\
|
||||
-vq3 Produce a qvm file compatible with Q3 1.32b\n\
|
||||
-h --help -? Show this help\n\
|
||||
-o OUTPUT Write assembled output to file OUTPUT.qvm\n\
|
||||
-f LISTFILE Read options and list of files to assemble from LISTFILE.q3asm\n\
|
||||
-b BUCKETS Set symbol hash table to BUCKETS buckets\n\
|
||||
-m Generate a mapfile for each OUTPUT.qvm\n\
|
||||
-v Verbose compilation report\n\
|
||||
-vq3 Produce a qvm file compatible with Q3 1.32b\n\
|
||||
-h --help -? Show this help\n\
|
||||
", argv0);
|
||||
}
|
||||
|
||||
@@ -1562,7 +1564,7 @@ int main( int argc, char **argv ) {
|
||||
|
||||
if ( !strcmp( argv[i], "-o" ) ) {
|
||||
if ( i == argc - 1 ) {
|
||||
Error( "-o must preceed a filename" );
|
||||
Error( "-o must precede a filename" );
|
||||
}
|
||||
/* Timbo of Tremulous pointed out -o not working; stock ID q3asm folded in the change. Yay. */
|
||||
strcpy( outputFilename, argv[ i+1 ] );
|
||||
@@ -1572,7 +1574,7 @@ int main( int argc, char **argv ) {
|
||||
|
||||
if ( !strcmp( argv[i], "-f" ) ) {
|
||||
if ( i == argc - 1 ) {
|
||||
Error( "-f must preceed a filename" );
|
||||
Error( "-f must precede a filename" );
|
||||
}
|
||||
ParseOptionFile( argv[ i+1 ] );
|
||||
i++;
|
||||
@@ -1618,7 +1620,7 @@ Motivation: not wanting to scrollback for pages to find asm error.
|
||||
}
|
||||
// In some case it Segfault without this check
|
||||
if ( numAsmFiles == 0 ) {
|
||||
Error( "No file to assemble\n" );
|
||||
Error( "No file to assemble" );
|
||||
}
|
||||
|
||||
InitTables();
|
||||
|
@@ -9,7 +9,7 @@ char rcsid[] = "cpp.c - faked rcsid";
|
||||
|
||||
#define OUTS 16384
|
||||
char outbuf[OUTS];
|
||||
char *outp = outbuf;
|
||||
char *outbufp = outbuf;
|
||||
Source *cursource;
|
||||
int nerrs;
|
||||
struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
|
||||
@@ -19,6 +19,15 @@ int ifdepth;
|
||||
int ifsatisfied[NIF];
|
||||
int skipping;
|
||||
|
||||
time_t reproducible_time()
|
||||
{
|
||||
char *source_date_epoch;
|
||||
time_t t;
|
||||
if ((source_date_epoch = getenv("SOURCE_DATE_EPOCH")) == NULL ||
|
||||
(t = (time_t)strtol(source_date_epoch, NULL, 10)) <= 0)
|
||||
return time(NULL);
|
||||
return t;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@@ -28,7 +37,7 @@ main(int argc, char **argv)
|
||||
char ebuf[BUFSIZ];
|
||||
|
||||
setbuf(stderr, ebuf);
|
||||
t = time(NULL);
|
||||
t = reproducible_time();
|
||||
curtime = ctime(&t);
|
||||
maketokenrow(3, &tr);
|
||||
expandlex();
|
||||
@@ -51,7 +60,7 @@ process(Tokenrow *trp)
|
||||
for (;;) {
|
||||
if (trp->tp >= trp->lp) {
|
||||
trp->tp = trp->lp = trp->bp;
|
||||
outp = outbuf;
|
||||
outbufp = outbuf;
|
||||
anymacros |= gettokens(trp, 1);
|
||||
trp->tp = trp->bp;
|
||||
}
|
||||
@@ -250,7 +259,6 @@ control(Tokenrow *trp)
|
||||
break;
|
||||
}
|
||||
setempty(trp);
|
||||
return;
|
||||
}
|
||||
|
||||
void *
|
||||
|
@@ -143,7 +143,7 @@ void setobjname(char *);
|
||||
|
||||
char *basepath( char *fname );
|
||||
|
||||
extern char *outp;
|
||||
extern char *outbufp;
|
||||
extern Token nltoken;
|
||||
extern Source *cursource;
|
||||
extern char *curtime;
|
||||
|
@@ -108,7 +108,6 @@ doinclude(Tokenrow *trp)
|
||||
return;
|
||||
syntax:
|
||||
error(ERROR, "Syntax error in #include");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -121,7 +120,7 @@ genline(void)
|
||||
static Tokenrow tr = { &ta, &ta, &ta+1, 1 };
|
||||
uchar *p;
|
||||
|
||||
ta.t = p = (uchar*)outp;
|
||||
ta.t = p = (uchar*)outbufp;
|
||||
strcpy((char*)p, "#line ");
|
||||
p += sizeof("#line ")-1;
|
||||
p = (uchar*)outnum((char*)p, cursource->line);
|
||||
@@ -134,8 +133,8 @@ genline(void)
|
||||
strcpy((char*)p, cursource->filename);
|
||||
p += strlen((char*)p);
|
||||
*p++ = '"'; *p++ = '\n';
|
||||
ta.len = (char*)p-outp;
|
||||
outp = (char*)p;
|
||||
ta.len = (char*)p-outbufp;
|
||||
outbufp = (char*)p;
|
||||
tr.tp = tr.bp;
|
||||
puttokens(&tr);
|
||||
}
|
||||
|
@@ -511,6 +511,25 @@ foldline(Source *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This doesn't have proper tracking across read() to only remove \r from \r\n sequence.
|
||||
// The lexer doesn't correctly handle standalone \r anyway though.
|
||||
int
|
||||
crlf_to_lf(unsigned char *buf, int n) {
|
||||
int i, count;
|
||||
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (buf[i] == '\r') {
|
||||
continue;
|
||||
}
|
||||
|
||||
buf[count++] = buf[i];
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
fillbuf(Source *s)
|
||||
{
|
||||
@@ -521,6 +540,7 @@ fillbuf(Source *s)
|
||||
error(FATAL, "Input buffer overflow");
|
||||
if (s->fd<0 || (n=read(s->fd, (char *)s->inl, INS/8)) <= 0)
|
||||
n = 0;
|
||||
n = crlf_to_lf(s->inl, n);
|
||||
if ((*s->inp&0xff) == EOB) /* sentinel character appears in input */
|
||||
*s->inp = EOFC;
|
||||
s->inl += n;
|
||||
|
@@ -218,7 +218,6 @@ expand(Tokenrow *trp, Nlist *np)
|
||||
insertrow(trp, ntokc, &ntr);
|
||||
trp->tp -= rowlen(&ntr);
|
||||
dofree(ntr.bp);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -471,10 +470,10 @@ builtin(Tokenrow *trp, int biname)
|
||||
/* most are strings */
|
||||
tp->type = STRING;
|
||||
if (tp->wslen) {
|
||||
*outp++ = ' ';
|
||||
*outbufp++ = ' ';
|
||||
tp->wslen = 1;
|
||||
}
|
||||
op = outp;
|
||||
op = outbufp;
|
||||
*op++ = '"';
|
||||
switch (biname) {
|
||||
|
||||
@@ -509,7 +508,7 @@ builtin(Tokenrow *trp, int biname)
|
||||
}
|
||||
if (tp->type==STRING)
|
||||
*op++ = '"';
|
||||
tp->t = (uchar*)outp;
|
||||
tp->len = op - outp;
|
||||
outp = op;
|
||||
tp->t = (uchar*)outbufp;
|
||||
tp->len = op - outbufp;
|
||||
outbufp = op;
|
||||
}
|
||||
|
@@ -267,7 +267,7 @@ peektokens(Tokenrow *trp, char *str)
|
||||
if (str)
|
||||
fprintf(stderr, "%s ", str);
|
||||
if (tp<trp->bp || tp>trp->lp)
|
||||
fprintf(stderr, "(tp offset %d) ", tp-trp->bp);
|
||||
fprintf(stderr, "(tp offset %ld) ", (long int) (tp - trp->bp));
|
||||
for (tp=trp->bp; tp<trp->lp && tp<trp->bp+32; tp++) {
|
||||
if (tp->type!=NL) {
|
||||
int c = tp->t[tp->len];
|
||||
@@ -315,7 +315,7 @@ puttokens(Tokenrow *trp)
|
||||
if (wbp >= &wbuf[OBS]) {
|
||||
write(1, wbuf, OBS);
|
||||
if (wbp > &wbuf[OBS])
|
||||
memcpy(wbuf, wbuf+OBS, wbp - &wbuf[OBS]);
|
||||
memmove(wbuf, wbuf+OBS, wbp - &wbuf[OBS]);
|
||||
wbp -= OBS;
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include "cpp.h"
|
||||
|
||||
extern int lcc_getopt(int, char *const *, const char *);
|
||||
@@ -64,11 +65,22 @@ setup(int argc, char **argv)
|
||||
fp = (char*)newstring((uchar*)argv[optind], strlen(argv[optind]), 0);
|
||||
if ((fd = open(fp, 0)) <= 0)
|
||||
error(FATAL, "Can't open input file %s", fp);
|
||||
#ifdef WIN32
|
||||
_setmode(fd, _O_BINARY);
|
||||
#endif
|
||||
}
|
||||
if (optind+1<argc) {
|
||||
int fdo = creat(argv[optind+1], 0666);
|
||||
int fdo;
|
||||
#ifdef WIN32
|
||||
fdo = creat(argv[optind+1], _S_IREAD | _S_IWRITE);
|
||||
#else
|
||||
fdo = creat(argv[optind+1], 0666);
|
||||
#endif
|
||||
if (fdo<0)
|
||||
error(FATAL, "Can't open output file %s", argv[optind+1]);
|
||||
#ifdef WIN32
|
||||
_setmode(fdo, _O_BINARY);
|
||||
#endif
|
||||
dup2(fdo, 1);
|
||||
}
|
||||
if(Mflag)
|
||||
@@ -99,7 +111,8 @@ char *basepath( char *fname )
|
||||
/* memmove is defined here because some vendors don't provide it at
|
||||
all and others do a terrible job (like calling malloc) */
|
||||
// -- ouch, that hurts -- ln
|
||||
#ifndef MACOS_X /* always use the system memmove() on Mac OS X. --ryan. */
|
||||
/* always use the system memmove() on Mac OS X. --ryan. */
|
||||
#if !defined(__APPLE__) && !defined(_MSC_VER)
|
||||
#ifdef memmove
|
||||
#undef memmove
|
||||
#endif
|
||||
@@ -109,7 +122,7 @@ memmove(void *dp, const void *sp, size_t n)
|
||||
unsigned char *cdp, *csp;
|
||||
|
||||
if (n<=0)
|
||||
return 0;
|
||||
return dp;
|
||||
cdp = dp;
|
||||
csp = (unsigned char *)sp;
|
||||
if (cdp < csp) {
|
||||
@@ -123,6 +136,6 @@ memmove(void *dp, const void *sp, size_t n)
|
||||
*--cdp = *--csp;
|
||||
} while (--n);
|
||||
}
|
||||
return 0;
|
||||
return dp;
|
||||
}
|
||||
#endif
|
||||
|
@@ -41,7 +41,7 @@ and insisted that pointers fit in unsigned integers (see Sec. 5.1 of <cite>A Ret
|
||||
C Compiler</cite>). These assumptions simplified the compiler, and were suitable for
|
||||
32-bit architectures. But on 64-bit architectures, such as the DEC ALPHA, it's natural to
|
||||
have four sizes of integers and perhaps three sizes of floats, and on 16-bit
|
||||
architectures, 32-bit pointers don't fit in unsigned integers. Also, the 3.x constaints
|
||||
architectures, 32-bit pointers don't fit in unsigned integers. Also, the 3.x constraints
|
||||
limited the use of lcc's back ends for other languages, such as Java.</p>
|
||||
|
||||
<p>Version 4.x removes all of these restrictions: It supports any number of sizes for
|
||||
@@ -99,7 +99,7 @@ the symbol's <code>type</code> field.</p>
|
||||
|
||||
<h2><a NAME="operators">5.5 Dag Operators</a></h2>
|
||||
|
||||
<p>The <code>op</code> field a of <code>node</code> structure holds a dag operator, which
|
||||
<p>The <code>op</code> field of a <code>node</code> structure holds a dag operator, which
|
||||
consists of a generic operator, a type suffix, and a size indicator. The type suffixes
|
||||
are:</p>
|
||||
|
||||
@@ -516,14 +516,14 @@ e.g.,</p>
|
||||
<p>The type suffix for a conversion operator denotes the type of the result and the size
|
||||
indicator gives the size of the result. For example, <code>CVUI4</code> converts an
|
||||
unsigned (<code>U</code>) to a 4-byte signed integer (<code>I4</code>). The <code>syms[0]</code>
|
||||
field points to a symbol-table entry for a integer constant that gives the size of the
|
||||
field points to a symbol-table entry for an integer constant that gives the size of the
|
||||
source operand. For example, if <code>syms[0]</code> in a <code>CVUI4</code> points to a
|
||||
symbol-table entry for 2, the conversion widens a 2-byte unsigned integer to a 4-byte
|
||||
signed integer. Conversions that widen unsigned integers zero-extend; those that widen
|
||||
signed integers sign-extend.</p>
|
||||
|
||||
<p>The front end composes conversions between types <em>T</em><sub>1</sub> and <em>T</em><sub>2</sub>
|
||||
by widening <em>T</em><sub>1</sub> to it's "supertype", if necessary, converting
|
||||
by widening <em>T</em><sub>1</sub> to its "supertype", if necessary, converting
|
||||
that result to <em>T</em><sub>2</sub>'s supertype, then narrowing the result to <em>T</em><sub>2</sub>,
|
||||
if necessary. The following table lists the supertypes; omitted entries are their own
|
||||
supertypes.</p>
|
||||
|
@@ -722,7 +722,7 @@ C:\dist\lcc\4.1>copy %BUILDDIR%\bprint.exe \bin
|
||||
<h2><a NAME="bugs">Reporting Bugs</a></h2>
|
||||
|
||||
<p>lcc is a large, complex program. We find and repair errors routinely. If you think that
|
||||
you've found a error, follow the steps below, which are adapted from the instructions in
|
||||
you've found an error, follow the steps below, which are adapted from the instructions in
|
||||
Chapter 1 of <cite>A Retargetable C Compiler: Design and Implementation</cite>.
|
||||
|
||||
<ol>
|
||||
@@ -751,7 +751,7 @@ Chapter 1 of <cite>A Retargetable C Compiler: Design and Implementation</cite>.
|
||||
HREF="ftp://ftp.cs.princeton.edu/pub/lcc"><code>pub/lcc</code></a>. A <a
|
||||
HREF="ftp://ftp.cs.princeton.edu/pub/lcc/README"><code>README</code></a> file there gives
|
||||
acquistion details, and the <a HREF="../LOG"><code>LOG</code></a> file reports what errors
|
||||
were fixed and when they were fixed. If you report a error that's been fixed, you might
|
||||
were fixed and when they were fixed. If you report an error that's been fixed, you might
|
||||
get a canned reply.</li>
|
||||
<li>Send your program by electronic mail to <code>lcc-bugs@cs.princeton.edu</code>. Please
|
||||
send only valid C programs; put all remarks in C comments so that we can process reports
|
||||
|
@@ -34,9 +34,14 @@ void UpdatePaths( const char *lccBinary )
|
||||
{
|
||||
char basepath[ 1024 ];
|
||||
char *p;
|
||||
size_t basepathsz = sizeof( basepath ) - 1;
|
||||
|
||||
strncpy( basepath, lccBinary, 1024 );
|
||||
p = strrchr( basepath, PATH_SEP );
|
||||
strncpy( basepath, lccBinary, basepathsz );
|
||||
basepath[basepathsz] = 0;
|
||||
p = strrchr( basepath, '/' );
|
||||
|
||||
if( !p )
|
||||
p = strrchr( basepath, '\\' );
|
||||
|
||||
if( p )
|
||||
{
|
||||
@@ -52,6 +57,10 @@ int option(char *arg) {
|
||||
cpp[0] = concat(&arg[8], "/q3cpp" BINEXT);
|
||||
include[0] = concat("-I", concat(&arg[8], "/include"));
|
||||
com[0] = concat(&arg[8], "/q3rcc" BINEXT);
|
||||
} else if (strncmp(arg, "-lcppdir=", 9) == 0) {
|
||||
cpp[0] = concat(&arg[9], "/q3cpp" BINEXT);
|
||||
} else if (strncmp(arg, "-lrccdir=", 9) == 0) {
|
||||
com[0] = concat(&arg[9], "/q3rcc" BINEXT);
|
||||
} else if (strcmp(arg, "-p") == 0 || strcmp(arg, "-pg") == 0) {
|
||||
fprintf( stderr, "no profiling supported, %s ignored.\n", arg);
|
||||
} else if (strcmp(arg, "-b") == 0)
|
||||
|
@@ -11,7 +11,12 @@ static char rcsid[] = "Id: dummy rcsid";
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#ifdef WIN32
|
||||
#include <process.h> /* getpid() */
|
||||
#include <io.h> /* access() */
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef TEMPDIR
|
||||
#define TEMPDIR "/tmp"
|
||||
@@ -217,14 +222,74 @@ char *basename(char *name) {
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
|
||||
static char *escapeDoubleQuotes(const char *string) {
|
||||
int stringLength = strlen(string);
|
||||
int bufferSize = stringLength + 1;
|
||||
int i, j;
|
||||
char *newString;
|
||||
|
||||
if (string == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < stringLength; i++) {
|
||||
if (string[i] == '"')
|
||||
bufferSize++;
|
||||
}
|
||||
|
||||
newString = (char*)malloc(bufferSize);
|
||||
|
||||
if (newString == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0, j = 0; i < stringLength; i++) {
|
||||
if (string[i] == '"')
|
||||
newString[j++] = '\\';
|
||||
|
||||
newString[j++] = string[i];
|
||||
}
|
||||
|
||||
newString[j] = '\0';
|
||||
|
||||
return newString;
|
||||
}
|
||||
|
||||
static int spawn(const char *cmdname, char **argv) {
|
||||
int argc = 0;
|
||||
char **newArgv = argv;
|
||||
int i;
|
||||
intptr_t exitStatus;
|
||||
|
||||
// _spawnvp removes double quotes from arguments, so we
|
||||
// have to escape them manually
|
||||
while (*newArgv++ != NULL)
|
||||
argc++;
|
||||
|
||||
newArgv = (char **)malloc(sizeof(char*) * (argc + 1));
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
newArgv[i] = escapeDoubleQuotes(argv[i]);
|
||||
|
||||
newArgv[argc] = NULL;
|
||||
|
||||
exitStatus = _spawnvp(_P_WAIT, cmdname, (const char *const *)newArgv);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
free(newArgv[i]);
|
||||
|
||||
free(newArgv);
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define _P_WAIT 0
|
||||
#ifndef __sun
|
||||
extern int fork(void);
|
||||
#endif
|
||||
extern int wait(int *);
|
||||
|
||||
static int _spawnvp(int mode, const char *cmdname, char *argv[]) {
|
||||
static int spawn(const char *cmdname, char **argv) {
|
||||
int pid, n, status;
|
||||
|
||||
switch (pid = fork()) {
|
||||
@@ -292,11 +357,7 @@ static int callsys(char **av) {
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
if (verbose < 2)
|
||||
#ifndef WIN32
|
||||
status = _spawnvp(_P_WAIT, executable, argv);
|
||||
#else
|
||||
status = _spawnvp(_P_WAIT, executable, (const char* const*)argv);
|
||||
#endif
|
||||
status = spawn(executable, argv);
|
||||
if (status == -1) {
|
||||
fprintf(stderr, "%s: ", progname);
|
||||
perror(argv[0]);
|
||||
@@ -376,7 +437,7 @@ static char *exists(char *name) {
|
||||
b = b->link;
|
||||
if (b->str[0]) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "%s/%s", b->str, name);
|
||||
snprintf(buf, sizeof(buf), "%s/%s", b->str, name);
|
||||
if (access(buf, 4) == 0)
|
||||
return strsave(buf);
|
||||
} else if (access(name, 4) == 0)
|
||||
@@ -575,7 +636,7 @@ static void opt(char *arg) {
|
||||
clist = append(&arg[3], clist);
|
||||
return;
|
||||
}
|
||||
break; /* and fall thru */
|
||||
break; /* and fall through */
|
||||
case 'a':
|
||||
alist = append(&arg[3], alist);
|
||||
return;
|
||||
@@ -757,10 +818,9 @@ char *strsave(const char *str) {
|
||||
char *stringf(const char *fmt, ...) {
|
||||
char buf[1024];
|
||||
va_list ap;
|
||||
int n;
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = vsprintf(buf, fmt, ap);
|
||||
vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
return strsave(buf);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -70,12 +70,32 @@ static char buf[BUFSIZ], *bp = buf;
|
||||
static int ppercent = 0;
|
||||
static int code = 0;
|
||||
|
||||
static void crlf_to_lf(char *buf, int bufmax) {
|
||||
int i, count;
|
||||
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < bufmax; i++) {
|
||||
if (buf[i] == '\r' && buf[i+1] == '\n') {
|
||||
// skip '\r'
|
||||
continue;
|
||||
}
|
||||
|
||||
buf[count++] = buf[i];
|
||||
|
||||
if (buf[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int get(void) {
|
||||
if (*bp == 0) {
|
||||
bp = buf;
|
||||
*bp = 0;
|
||||
if (fgets(buf, sizeof buf, infp) == NULL)
|
||||
return EOF;
|
||||
crlf_to_lf(buf, sizeof buf);
|
||||
yylineno++;
|
||||
while (buf[0] == '%' && buf[1] == '{' && buf[2] == '\n') {
|
||||
for (;;) {
|
||||
@@ -83,6 +103,7 @@ static int get(void) {
|
||||
yywarn("unterminated %{...%}\n");
|
||||
return EOF;
|
||||
}
|
||||
crlf_to_lf(buf, sizeof buf);
|
||||
yylineno++;
|
||||
if (strcmp(buf, "%}\n") == 0)
|
||||
break;
|
||||
@@ -90,6 +111,7 @@ static int get(void) {
|
||||
}
|
||||
if (fgets(buf, sizeof buf, infp) == NULL)
|
||||
return EOF;
|
||||
crlf_to_lf(buf, sizeof buf);
|
||||
yylineno++;
|
||||
}
|
||||
}
|
||||
@@ -199,4 +221,5 @@ void yywarn(char *fmt, ...) {
|
||||
fprintf(stderr, "line %d: ", yylineno);
|
||||
fprintf(stderr, "warning: ");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
@@ -56,14 +56,14 @@ int main(int argc, char *argv[]) {
|
||||
} else if (infp == NULL) {
|
||||
if (strcmp(argv[i], "-") == 0)
|
||||
infp = stdin;
|
||||
else if ((infp = fopen(argv[i], "r")) == NULL) {
|
||||
else if ((infp = fopen(argv[i], "rb")) == NULL) {
|
||||
yyerror("%s: can't read `%s'\n", argv[0], argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
} else if (outfp == NULL) {
|
||||
if (strcmp(argv[i], "-") == 0)
|
||||
outfp = stdout;
|
||||
if ((outfp = fopen(argv[i], "w")) == NULL) {
|
||||
if ((outfp = fopen(argv[i], "wb")) == NULL) {
|
||||
yyerror("%s: can't write `%s'\n", argv[0], argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
|
@@ -261,8 +261,7 @@ static void LoadSourceFile( const char *filename ) {
|
||||
length = filelength( f );
|
||||
sourceFile = malloc( length + 1 );
|
||||
if ( sourceFile ) {
|
||||
size_t size;
|
||||
size = fread( sourceFile, length, 1, f );
|
||||
fread( sourceFile, length, 1, f );
|
||||
sourceFile[length] = 0;
|
||||
}
|
||||
|
||||
|
@@ -577,6 +577,7 @@ extern Tree cnsttree(Type, ...);
|
||||
extern Tree consttree(unsigned int, Type);
|
||||
extern Tree eqtree(int, Tree, Tree);
|
||||
extern int iscallb(Tree);
|
||||
extern int isnullptr(Tree);
|
||||
extern Tree shtree(int, Tree, Tree);
|
||||
extern void typeerror(int, Tree, Tree);
|
||||
|
||||
@@ -644,7 +645,7 @@ extern int process(char *);
|
||||
extern int findfunc(char *, char *);
|
||||
extern int findcount(char *, int, int);
|
||||
|
||||
extern Tree constexpr(int);
|
||||
extern Tree constantexpr(int);
|
||||
extern int intexpr(int, int);
|
||||
extern Tree simplify(int, Type, Tree, Tree);
|
||||
extern int ispow2(unsigned long u);
|
||||
|
@@ -519,7 +519,8 @@ void emitcode(void) {
|
||||
(*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break;
|
||||
case Gen: case Jump:
|
||||
case Label: if (cp->u.forest)
|
||||
(*IR->emit)(cp->u.forest); break;
|
||||
(*IR->emit)(cp->u.forest);
|
||||
break;
|
||||
case Local: if (glevel && IR->stabsym) {
|
||||
(*IR->stabsym)(cp->u.var);
|
||||
swtoseg(CODE);
|
||||
|
@@ -5,7 +5,6 @@ static Tree addtree(int, Tree, Tree);
|
||||
static Tree andtree(int, Tree, Tree);
|
||||
static Tree cmptree(int, Tree, Tree);
|
||||
static int compatible(Type, Type);
|
||||
static int isnullptr(Tree e);
|
||||
static Tree multree(int, Tree, Tree);
|
||||
static Tree subtree(int, Tree, Tree);
|
||||
#define isvoidptr(ty) \
|
||||
@@ -220,7 +219,7 @@ static int compatible(Type ty1, Type ty2) {
|
||||
&& isptr(ty2) && !isfunc(ty2->type)
|
||||
&& eqtype(unqual(ty1->type), unqual(ty2->type), 0);
|
||||
}
|
||||
static int isnullptr(Tree e) {
|
||||
int isnullptr(Tree e) {
|
||||
Type ty = unqual(e->type);
|
||||
|
||||
return generic(e->op) == CNST
|
||||
@@ -402,7 +401,7 @@ Tree addrof(Tree p) {
|
||||
Symbol t1 = q->u.sym;
|
||||
q->u.sym = 0;
|
||||
q = idtree(t1);
|
||||
/* fall thru */
|
||||
/* fall through */
|
||||
}
|
||||
case INDIR:
|
||||
if (p == q)
|
||||
|
@@ -80,7 +80,7 @@ int fatal(const char *name, const char *fmt, int n) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* printtoken - print current token preceeded by a space */
|
||||
/* printtoken - print current token preceded by a space */
|
||||
static void printtoken(void) {
|
||||
switch (t) {
|
||||
case ID: fprint(stderr, " `%s'", token); break;
|
||||
|
@@ -159,7 +159,8 @@ static Tree unary(void) {
|
||||
if (isarith(p->type))
|
||||
p = cast(p, promote(p->type));
|
||||
else
|
||||
typeerror(ADD, p, NULL); break;
|
||||
typeerror(ADD, p, NULL);
|
||||
break;
|
||||
case '-': t = gettok(); p = unary(); p = pointer(p);
|
||||
if (isarith(p->type)) {
|
||||
Type ty = promote(p->type);
|
||||
@@ -170,18 +171,21 @@ static Tree unary(void) {
|
||||
} else
|
||||
p = simplify(NEG, ty, p, NULL);
|
||||
} else
|
||||
typeerror(SUB, p, NULL); break;
|
||||
typeerror(SUB, p, NULL);
|
||||
break;
|
||||
case '~': t = gettok(); p = unary(); p = pointer(p);
|
||||
if (isint(p->type)) {
|
||||
Type ty = promote(p->type);
|
||||
p = simplify(BCOM, ty, cast(p, ty), NULL);
|
||||
} else
|
||||
typeerror(BCOM, p, NULL); break;
|
||||
typeerror(BCOM, p, NULL);
|
||||
break;
|
||||
case '!': t = gettok(); p = unary(); p = pointer(p);
|
||||
if (isscalar(p->type))
|
||||
p = simplify(NOT, inttype, cond(p), NULL);
|
||||
else
|
||||
typeerror(NOT, p, NULL); break;
|
||||
typeerror(NOT, p, NULL);
|
||||
break;
|
||||
case INCR: t = gettok(); p = unary(); p = incr(INCR, pointer(p), consttree(1, inttype)); break;
|
||||
case DECR: t = gettok(); p = unary(); p = incr(DECR, pointer(p), consttree(1, inttype)); break;
|
||||
case TYPECODE: case SIZEOF: { int op = t;
|
||||
@@ -318,7 +322,8 @@ static Tree postfix(Tree p) {
|
||||
p->type);
|
||||
t = gettok();
|
||||
} else
|
||||
error("field name expected\n"); break;
|
||||
error("field name expected\n");
|
||||
break;
|
||||
case DEREF: t = gettok();
|
||||
p = pointer(p);
|
||||
if (t == ID) {
|
||||
@@ -331,7 +336,8 @@ static Tree postfix(Tree p) {
|
||||
|
||||
t = gettok();
|
||||
} else
|
||||
error("field name expected\n"); break;
|
||||
error("field name expected\n");
|
||||
break;
|
||||
default:
|
||||
return p;
|
||||
}
|
||||
@@ -621,7 +627,7 @@ Tree cast(Tree p, Type type) {
|
||||
p = simplify(CVP, dst, p, NULL);
|
||||
else {
|
||||
if ((isfunc(src->type) && !isfunc(dst->type))
|
||||
|| (!isfunc(src->type) && isfunc(dst->type)))
|
||||
|| (!isnullptr(p) && !isfunc(src->type) && isfunc(dst->type)))
|
||||
warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, type);
|
||||
|
||||
if (src->size != dst->size)
|
||||
|
@@ -292,7 +292,7 @@ static void dumptree(Node p) {
|
||||
dumptree(p->kids[0]);
|
||||
break;
|
||||
}
|
||||
/* else fall thru */
|
||||
/* else fall through */
|
||||
case EQ: case NE: case GT: case GE: case LE: case LT:
|
||||
case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH:
|
||||
case ADD: case SUB: case DIV: case MUL: case MOD:
|
||||
|
@@ -40,7 +40,7 @@ static int genconst(Tree e, int def) {
|
||||
if (isarith(e->type))
|
||||
error("cast from `%t' to `%t' is illegal in constant expressions\n",
|
||||
e->kids[0]->type, e->type);
|
||||
/* fall thru */
|
||||
/* fall through */
|
||||
case CVI: case CVU: case CVF:
|
||||
e = e->kids[0];
|
||||
continue;
|
||||
@@ -192,7 +192,7 @@ static int initstruct(int len, Type ty, int lev) {
|
||||
return n;
|
||||
}
|
||||
|
||||
/* initializer - constexpr | { constexpr ( , constexpr )* [ , ] } */
|
||||
/* initializer - constantexpr | { constantexpr ( , constantexpr )* [ , ] } */
|
||||
Type initializer(Type ty, int lev) {
|
||||
int n = 0;
|
||||
Tree e;
|
||||
|
@@ -33,7 +33,7 @@ int length(List list) {
|
||||
return n;
|
||||
}
|
||||
|
||||
/* ltov - convert list to an NULL-terminated vector allocated in arena */
|
||||
/* ltov - convert list to a NULL-terminated vector allocated in arena */
|
||||
void *ltov(List *list, unsigned arena) {
|
||||
int i = 0;
|
||||
void **array = newarray(length(*list) + 1, sizeof array[0], arena);
|
||||
|
@@ -80,7 +80,7 @@ void vfprint(FILE *f, char *bp, const char *fmt, va_list ap) {
|
||||
static char format[] = "%f";
|
||||
char buf[128];
|
||||
format[1] = *fmt;
|
||||
sprintf(buf, format, va_arg(ap, double));
|
||||
snprintf(buf, sizeof(buf), format, va_arg(ap, double));
|
||||
bp = outs(buf, f, bp);
|
||||
}
|
||||
; break;
|
||||
|
@@ -182,7 +182,7 @@ static int subi(long x, long y, long min, long max, int needconst) {
|
||||
static int subd(double x, double y, double min, double max, int needconst) {
|
||||
return addd(x, -y, min, max, needconst);
|
||||
}
|
||||
Tree constexpr(int tok) {
|
||||
Tree constantexpr(int tok) {
|
||||
Tree p;
|
||||
|
||||
needconst++;
|
||||
@@ -192,7 +192,7 @@ Tree constexpr(int tok) {
|
||||
}
|
||||
|
||||
int intexpr(int tok, int n) {
|
||||
Tree p = constexpr(tok);
|
||||
Tree p = constantexpr(tok);
|
||||
|
||||
needconst++;
|
||||
if (p->op == CNST+I || p->op == CNST+U)
|
||||
|
@@ -119,7 +119,7 @@ void statement(int loop, Swtch swp, int lev) {
|
||||
static char stop[] = { IF, ID, 0 };
|
||||
Tree p;
|
||||
t = gettok();
|
||||
p = constexpr(0);
|
||||
p = constantexpr(0);
|
||||
if (generic(p->op) == CNST && isint(p->type)) {
|
||||
if (swp) {
|
||||
needconst++;
|
||||
@@ -184,8 +184,9 @@ void statement(int loop, Swtch swp, int lev) {
|
||||
branch(p->u.l.label);
|
||||
t = gettok();
|
||||
} else
|
||||
error("missing label in goto\n"); expect(';');
|
||||
break;
|
||||
error("missing label in goto\n");
|
||||
expect(';');
|
||||
break;
|
||||
|
||||
case ID: if (getchr() == ':') {
|
||||
stmtlabel();
|
||||
|
@@ -86,7 +86,7 @@ static Tree root1(Tree p) {
|
||||
warning("reference to `%t' elided\n", p->type);
|
||||
if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
|
||||
warning("reference to `volatile %t' elided\n", p->type);
|
||||
/* fall thru */
|
||||
/* fall through */
|
||||
case CVI: case CVF: case CVU: case CVP:
|
||||
case NEG: case BCOM: case FIELD:
|
||||
if (warn++ == 0)
|
||||
|
Reference in New Issue
Block a user