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 )
|
void ExpandWildcards( int *argc, char ***argv )
|
||||||
{
|
{
|
||||||
struct _finddata_t fileinfo;
|
struct _finddata_t fileinfo;
|
||||||
int handle;
|
intptr_t handle;
|
||||||
int i;
|
int i;
|
||||||
char filename[1024];
|
char filename[2048];
|
||||||
char filebase[1024];
|
char filebase[1024];
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ void ExpandWildcards( int *argc, char ***argv )
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
sprintf (filename, "%s%s", filebase, fileinfo.name);
|
snprintf (filename, sizeof(filename), "%s%s", filebase, fileinfo.name);
|
||||||
ex_argv[ex_argc++] = copystring (filename);
|
ex_argv[ex_argc++] = copystring (filename);
|
||||||
} while (_findnext( handle, &fileinfo ) != -1);
|
} while (_findnext( handle, &fileinfo ) != -1);
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ void Error( const char *error, ... )
|
|||||||
vsprintf (text, error,argptr);
|
vsprintf (text, error,argptr);
|
||||||
va_end (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 */ );
|
MessageBox(NULL, text2, "Error", 0 /* MB_OK */ );
|
||||||
|
|
||||||
exit (1);
|
exit (1);
|
||||||
@@ -185,7 +185,7 @@ void _printf( const char *format, ... ) {
|
|||||||
vsprintf (text, format, argptr);
|
vsprintf (text, format, argptr);
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
|
|
||||||
printf(text);
|
printf("%s", text);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (!lookedForServer) {
|
if (!lookedForServer) {
|
||||||
@@ -318,7 +318,7 @@ char *ExpandPath (const char *path)
|
|||||||
strcpy( full, path );
|
strcpy( full, path );
|
||||||
return full;
|
return full;
|
||||||
}
|
}
|
||||||
sprintf (full, "%s%s", qdir, path);
|
snprintf (full, sizeof(full), "%s%s", qdir, path);
|
||||||
return full;
|
return full;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,20 +331,20 @@ char *ExpandGamePath (const char *path)
|
|||||||
strcpy( full, path );
|
strcpy( full, path );
|
||||||
return full;
|
return full;
|
||||||
}
|
}
|
||||||
sprintf (full, "%s%s", gamedir, path);
|
snprintf (full, sizeof(full), "%s%s", gamedir, path);
|
||||||
return full;
|
return full;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ExpandPathAndArchive (const char *path)
|
char *ExpandPathAndArchive (const char *path)
|
||||||
{
|
{
|
||||||
char *expanded;
|
char *expanded;
|
||||||
char archivename[1024];
|
char archivename[2048];
|
||||||
|
|
||||||
expanded = ExpandPath (path);
|
expanded = ExpandPath (path);
|
||||||
|
|
||||||
if (archive)
|
if (archive)
|
||||||
{
|
{
|
||||||
sprintf (archivename, "%s/%s", archivedir, path);
|
snprintf (archivename, sizeof(archivename), "%s/%s", archivedir, path);
|
||||||
QCopyFile (expanded, archivename);
|
QCopyFile (expanded, archivename);
|
||||||
}
|
}
|
||||||
return expanded;
|
return expanded;
|
||||||
@@ -396,10 +396,12 @@ void Q_getwd (char *out)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
_getcwd (out, 256);
|
if (_getcwd (out, 256) == NULL)
|
||||||
|
strcpy(out, "."); /* shrug */
|
||||||
strcat (out, "\\");
|
strcat (out, "\\");
|
||||||
#else
|
#else
|
||||||
getcwd (out, 256);
|
if (getcwd (out, 256) == NULL)
|
||||||
|
strcpy(out, "."); /* shrug */
|
||||||
strcat (out, "/");
|
strcat (out, "/");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -732,7 +734,7 @@ int LoadFile( const char *filename, void **bufferptr )
|
|||||||
==============
|
==============
|
||||||
LoadFileBlock
|
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;
|
char *src;
|
||||||
//
|
//
|
||||||
// if path doesnt have a .EXT, append extension
|
// if path doesn't have a .EXT, append extension
|
||||||
// (extension should include the .)
|
// (extension should include the .)
|
||||||
//
|
//
|
||||||
src = path + strlen(path) - 1;
|
src = path + strlen(path) - 1;
|
||||||
|
@@ -59,7 +59,7 @@ typedef unsigned char byte;
|
|||||||
#define MAX_OS_PATH 1024
|
#define MAX_OS_PATH 1024
|
||||||
#define MEM_BLOCKSIZE 4096
|
#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)
|
#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier)
|
||||||
|
|
||||||
|
|
||||||
@@ -71,7 +71,6 @@ char *strupr (char *in);
|
|||||||
char *strlower (char *in);
|
char *strlower (char *in);
|
||||||
int Q_strncasecmp( const char *s1, const char *s2, int n );
|
int Q_strncasecmp( const char *s1, const char *s2, int n );
|
||||||
int Q_stricmp( const char *s1, const char *s2 );
|
int Q_stricmp( const char *s1, const char *s2 );
|
||||||
#define Q_strequal(s1,s2) (Q_stricmp(s1,s2)==0)
|
|
||||||
void Q_getwd( char *out );
|
void Q_getwd( char *out );
|
||||||
|
|
||||||
int Q_filelength (FILE *f);
|
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->buckets = buckets;
|
||||||
H->table = calloc(H->buckets, sizeof(*(H->table)));
|
H->table = calloc(H->buckets, sizeof(*(H->table)));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static hashtable_t *hashtable_new (int buckets)
|
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->data = datum;
|
||||||
hc->next = 0;
|
hc->next = 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static hashchain_t *hashtable_get (hashtable_t *H, int hashvalue)
|
static hashchain_t *hashtable_get (hashtable_t *H, int hashvalue)
|
||||||
@@ -386,8 +384,12 @@ static void sort_symbols ()
|
|||||||
symbol_t *s;
|
symbol_t *s;
|
||||||
symbol_t **symlist;
|
symbol_t **symlist;
|
||||||
|
|
||||||
|
if(!symbols)
|
||||||
|
return;
|
||||||
|
|
||||||
//crumb("sort_symbols: Constructing symlist array\n");
|
//crumb("sort_symbols: Constructing symlist array\n");
|
||||||
for (elems = 0, s = symbols; s; s = s->next, elems++) /* nop */ ;
|
for (elems = 0, s = symbols; s; s = s->next, elems++) /* nop */ ;
|
||||||
|
|
||||||
symlist = malloc(elems * sizeof(symbol_t*));
|
symlist = malloc(elems * sizeof(symbol_t*));
|
||||||
for (i = 0, s = symbols; s; s = s->next, i++)
|
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 = (acc << 2) | (acc >> 30);
|
||||||
acc &= 0xffffffffU;
|
acc &= 0xffffffffU;
|
||||||
}
|
}
|
||||||
return abs(acc);
|
return acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -489,10 +491,10 @@ static void CodeError( char *fmt, ... ) {
|
|||||||
|
|
||||||
errorCount++;
|
errorCount++;
|
||||||
|
|
||||||
report( "%s:%i ", currentFileName, currentFileLine );
|
fprintf( stderr, "%s:%i ", currentFileName, currentFileLine );
|
||||||
|
|
||||||
va_start( argptr,fmt );
|
va_start( argptr,fmt );
|
||||||
vprintf( fmt,argptr );
|
vfprintf( stderr, fmt, argptr );
|
||||||
va_end( 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
|
// add the file prefix to local symbols to guarantee unique
|
||||||
if ( sym[0] == '$' ) {
|
if ( sym[0] == '$' ) {
|
||||||
sprintf( expanded, "%s_%i", sym, currentFileIndex );
|
snprintf( expanded, sizeof(expanded), "%s_%i", sym, currentFileIndex );
|
||||||
sym = expanded;
|
sym = expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -600,7 +602,7 @@ static int LookupSymbol( char *sym ) {
|
|||||||
|
|
||||||
// add the file prefix to local symbols to guarantee unique
|
// add the file prefix to local symbols to guarantee unique
|
||||||
if ( sym[0] == '$' ) {
|
if ( sym[0] == '$' ) {
|
||||||
sprintf( expanded, "%s_%i", sym, currentFileIndex );
|
snprintf( expanded, sizeof(expanded), "%s_%i", sym, currentFileIndex );
|
||||||
sym = expanded;
|
sym = expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -786,7 +788,7 @@ HackToSegment
|
|||||||
|
|
||||||
BIG HACK: I want to put all 32 bit values in the data
|
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 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.
|
initialized strng variables are put in the data segment.
|
||||||
|
|
||||||
I can change segments here, but I also need to fixup the
|
I can change segments here, but I also need to fixup the
|
||||||
@@ -946,12 +948,11 @@ STAT("PROC");
|
|||||||
|
|
||||||
ASM(ENDPROC)
|
ASM(ENDPROC)
|
||||||
{
|
{
|
||||||
int v, v2;
|
|
||||||
if ( !strcmp( token, "endproc" ) ) {
|
if ( !strcmp( token, "endproc" ) ) {
|
||||||
STAT("ENDPROC");
|
STAT("ENDPROC");
|
||||||
Parse(); // skip the function name
|
Parse(); // skip the function name
|
||||||
v = ParseValue(); // locals
|
ParseValue(); // locals
|
||||||
v2 = ParseValue(); // arg marshalling
|
ParseValue(); // arg marshalling
|
||||||
|
|
||||||
// all functions must leave something on the opstack
|
// all functions must leave something on the opstack
|
||||||
instructionCount++;
|
instructionCount++;
|
||||||
@@ -1128,7 +1129,7 @@ STAT("BYTE");
|
|||||||
return 0;
|
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
|
// because the physical size of the code will change with
|
||||||
// different run time compilers and we want to minimize the
|
// different run time compilers and we want to minimize the
|
||||||
// size of the required translation table
|
// size of the required translation table
|
||||||
@@ -1520,12 +1521,13 @@ static void ShowHelp( char *argv0 ) {
|
|||||||
Error("Usage: %s [OPTION]... [FILES]...\n\
|
Error("Usage: %s [OPTION]... [FILES]...\n\
|
||||||
Assemble LCC bytecode assembly to Q3VM bytecode.\n\
|
Assemble LCC bytecode assembly to Q3VM bytecode.\n\
|
||||||
\n\
|
\n\
|
||||||
-o OUTPUT Write assembled output to file OUTPUT.qvm\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\
|
-f LISTFILE Read options and list of files to assemble from LISTFILE.q3asm\n\
|
||||||
-b BUCKETS Set symbol hash table to BUCKETS buckets\n\
|
-b BUCKETS Set symbol hash table to BUCKETS buckets\n\
|
||||||
-v Verbose compilation report\n\
|
-m Generate a mapfile for each OUTPUT.qvm\n\
|
||||||
-vq3 Produce a qvm file compatible with Q3 1.32b\n\
|
-v Verbose compilation report\n\
|
||||||
-h --help -? Show this help\n\
|
-vq3 Produce a qvm file compatible with Q3 1.32b\n\
|
||||||
|
-h --help -? Show this help\n\
|
||||||
", argv0);
|
", argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1562,7 +1564,7 @@ int main( int argc, char **argv ) {
|
|||||||
|
|
||||||
if ( !strcmp( argv[i], "-o" ) ) {
|
if ( !strcmp( argv[i], "-o" ) ) {
|
||||||
if ( i == argc - 1 ) {
|
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. */
|
/* Timbo of Tremulous pointed out -o not working; stock ID q3asm folded in the change. Yay. */
|
||||||
strcpy( outputFilename, argv[ i+1 ] );
|
strcpy( outputFilename, argv[ i+1 ] );
|
||||||
@@ -1572,7 +1574,7 @@ int main( int argc, char **argv ) {
|
|||||||
|
|
||||||
if ( !strcmp( argv[i], "-f" ) ) {
|
if ( !strcmp( argv[i], "-f" ) ) {
|
||||||
if ( i == argc - 1 ) {
|
if ( i == argc - 1 ) {
|
||||||
Error( "-f must preceed a filename" );
|
Error( "-f must precede a filename" );
|
||||||
}
|
}
|
||||||
ParseOptionFile( argv[ i+1 ] );
|
ParseOptionFile( argv[ i+1 ] );
|
||||||
i++;
|
i++;
|
||||||
@@ -1618,7 +1620,7 @@ Motivation: not wanting to scrollback for pages to find asm error.
|
|||||||
}
|
}
|
||||||
// In some case it Segfault without this check
|
// In some case it Segfault without this check
|
||||||
if ( numAsmFiles == 0 ) {
|
if ( numAsmFiles == 0 ) {
|
||||||
Error( "No file to assemble\n" );
|
Error( "No file to assemble" );
|
||||||
}
|
}
|
||||||
|
|
||||||
InitTables();
|
InitTables();
|
||||||
|
@@ -9,7 +9,7 @@ char rcsid[] = "cpp.c - faked rcsid";
|
|||||||
|
|
||||||
#define OUTS 16384
|
#define OUTS 16384
|
||||||
char outbuf[OUTS];
|
char outbuf[OUTS];
|
||||||
char *outp = outbuf;
|
char *outbufp = outbuf;
|
||||||
Source *cursource;
|
Source *cursource;
|
||||||
int nerrs;
|
int nerrs;
|
||||||
struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
|
struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
|
||||||
@@ -19,6 +19,15 @@ int ifdepth;
|
|||||||
int ifsatisfied[NIF];
|
int ifsatisfied[NIF];
|
||||||
int skipping;
|
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
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
@@ -28,7 +37,7 @@ main(int argc, char **argv)
|
|||||||
char ebuf[BUFSIZ];
|
char ebuf[BUFSIZ];
|
||||||
|
|
||||||
setbuf(stderr, ebuf);
|
setbuf(stderr, ebuf);
|
||||||
t = time(NULL);
|
t = reproducible_time();
|
||||||
curtime = ctime(&t);
|
curtime = ctime(&t);
|
||||||
maketokenrow(3, &tr);
|
maketokenrow(3, &tr);
|
||||||
expandlex();
|
expandlex();
|
||||||
@@ -51,7 +60,7 @@ process(Tokenrow *trp)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
if (trp->tp >= trp->lp) {
|
if (trp->tp >= trp->lp) {
|
||||||
trp->tp = trp->lp = trp->bp;
|
trp->tp = trp->lp = trp->bp;
|
||||||
outp = outbuf;
|
outbufp = outbuf;
|
||||||
anymacros |= gettokens(trp, 1);
|
anymacros |= gettokens(trp, 1);
|
||||||
trp->tp = trp->bp;
|
trp->tp = trp->bp;
|
||||||
}
|
}
|
||||||
@@ -250,7 +259,6 @@ control(Tokenrow *trp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setempty(trp);
|
setempty(trp);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@@ -143,7 +143,7 @@ void setobjname(char *);
|
|||||||
|
|
||||||
char *basepath( char *fname );
|
char *basepath( char *fname );
|
||||||
|
|
||||||
extern char *outp;
|
extern char *outbufp;
|
||||||
extern Token nltoken;
|
extern Token nltoken;
|
||||||
extern Source *cursource;
|
extern Source *cursource;
|
||||||
extern char *curtime;
|
extern char *curtime;
|
||||||
|
@@ -108,7 +108,6 @@ doinclude(Tokenrow *trp)
|
|||||||
return;
|
return;
|
||||||
syntax:
|
syntax:
|
||||||
error(ERROR, "Syntax error in #include");
|
error(ERROR, "Syntax error in #include");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -121,7 +120,7 @@ genline(void)
|
|||||||
static Tokenrow tr = { &ta, &ta, &ta+1, 1 };
|
static Tokenrow tr = { &ta, &ta, &ta+1, 1 };
|
||||||
uchar *p;
|
uchar *p;
|
||||||
|
|
||||||
ta.t = p = (uchar*)outp;
|
ta.t = p = (uchar*)outbufp;
|
||||||
strcpy((char*)p, "#line ");
|
strcpy((char*)p, "#line ");
|
||||||
p += sizeof("#line ")-1;
|
p += sizeof("#line ")-1;
|
||||||
p = (uchar*)outnum((char*)p, cursource->line);
|
p = (uchar*)outnum((char*)p, cursource->line);
|
||||||
@@ -134,8 +133,8 @@ genline(void)
|
|||||||
strcpy((char*)p, cursource->filename);
|
strcpy((char*)p, cursource->filename);
|
||||||
p += strlen((char*)p);
|
p += strlen((char*)p);
|
||||||
*p++ = '"'; *p++ = '\n';
|
*p++ = '"'; *p++ = '\n';
|
||||||
ta.len = (char*)p-outp;
|
ta.len = (char*)p-outbufp;
|
||||||
outp = (char*)p;
|
outbufp = (char*)p;
|
||||||
tr.tp = tr.bp;
|
tr.tp = tr.bp;
|
||||||
puttokens(&tr);
|
puttokens(&tr);
|
||||||
}
|
}
|
||||||
|
@@ -511,6 +511,25 @@ foldline(Source *s)
|
|||||||
return 0;
|
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
|
int
|
||||||
fillbuf(Source *s)
|
fillbuf(Source *s)
|
||||||
{
|
{
|
||||||
@@ -521,6 +540,7 @@ fillbuf(Source *s)
|
|||||||
error(FATAL, "Input buffer overflow");
|
error(FATAL, "Input buffer overflow");
|
||||||
if (s->fd<0 || (n=read(s->fd, (char *)s->inl, INS/8)) <= 0)
|
if (s->fd<0 || (n=read(s->fd, (char *)s->inl, INS/8)) <= 0)
|
||||||
n = 0;
|
n = 0;
|
||||||
|
n = crlf_to_lf(s->inl, n);
|
||||||
if ((*s->inp&0xff) == EOB) /* sentinel character appears in input */
|
if ((*s->inp&0xff) == EOB) /* sentinel character appears in input */
|
||||||
*s->inp = EOFC;
|
*s->inp = EOFC;
|
||||||
s->inl += n;
|
s->inl += n;
|
||||||
|
@@ -218,7 +218,6 @@ expand(Tokenrow *trp, Nlist *np)
|
|||||||
insertrow(trp, ntokc, &ntr);
|
insertrow(trp, ntokc, &ntr);
|
||||||
trp->tp -= rowlen(&ntr);
|
trp->tp -= rowlen(&ntr);
|
||||||
dofree(ntr.bp);
|
dofree(ntr.bp);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -471,10 +470,10 @@ builtin(Tokenrow *trp, int biname)
|
|||||||
/* most are strings */
|
/* most are strings */
|
||||||
tp->type = STRING;
|
tp->type = STRING;
|
||||||
if (tp->wslen) {
|
if (tp->wslen) {
|
||||||
*outp++ = ' ';
|
*outbufp++ = ' ';
|
||||||
tp->wslen = 1;
|
tp->wslen = 1;
|
||||||
}
|
}
|
||||||
op = outp;
|
op = outbufp;
|
||||||
*op++ = '"';
|
*op++ = '"';
|
||||||
switch (biname) {
|
switch (biname) {
|
||||||
|
|
||||||
@@ -509,7 +508,7 @@ builtin(Tokenrow *trp, int biname)
|
|||||||
}
|
}
|
||||||
if (tp->type==STRING)
|
if (tp->type==STRING)
|
||||||
*op++ = '"';
|
*op++ = '"';
|
||||||
tp->t = (uchar*)outp;
|
tp->t = (uchar*)outbufp;
|
||||||
tp->len = op - outp;
|
tp->len = op - outbufp;
|
||||||
outp = op;
|
outbufp = op;
|
||||||
}
|
}
|
||||||
|
@@ -267,7 +267,7 @@ peektokens(Tokenrow *trp, char *str)
|
|||||||
if (str)
|
if (str)
|
||||||
fprintf(stderr, "%s ", str);
|
fprintf(stderr, "%s ", str);
|
||||||
if (tp<trp->bp || tp>trp->lp)
|
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++) {
|
for (tp=trp->bp; tp<trp->lp && tp<trp->bp+32; tp++) {
|
||||||
if (tp->type!=NL) {
|
if (tp->type!=NL) {
|
||||||
int c = tp->t[tp->len];
|
int c = tp->t[tp->len];
|
||||||
@@ -315,7 +315,7 @@ puttokens(Tokenrow *trp)
|
|||||||
if (wbp >= &wbuf[OBS]) {
|
if (wbp >= &wbuf[OBS]) {
|
||||||
write(1, wbuf, OBS);
|
write(1, wbuf, OBS);
|
||||||
if (wbp > &wbuf[OBS])
|
if (wbp > &wbuf[OBS])
|
||||||
memcpy(wbuf, wbuf+OBS, wbp - &wbuf[OBS]);
|
memmove(wbuf, wbuf+OBS, wbp - &wbuf[OBS]);
|
||||||
wbp -= OBS;
|
wbp -= OBS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include "cpp.h"
|
#include "cpp.h"
|
||||||
|
|
||||||
extern int lcc_getopt(int, char *const *, const char *);
|
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);
|
fp = (char*)newstring((uchar*)argv[optind], strlen(argv[optind]), 0);
|
||||||
if ((fd = open(fp, 0)) <= 0)
|
if ((fd = open(fp, 0)) <= 0)
|
||||||
error(FATAL, "Can't open input file %s", fp);
|
error(FATAL, "Can't open input file %s", fp);
|
||||||
|
#ifdef WIN32
|
||||||
|
_setmode(fd, _O_BINARY);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (optind+1<argc) {
|
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)
|
if (fdo<0)
|
||||||
error(FATAL, "Can't open output file %s", argv[optind+1]);
|
error(FATAL, "Can't open output file %s", argv[optind+1]);
|
||||||
|
#ifdef WIN32
|
||||||
|
_setmode(fdo, _O_BINARY);
|
||||||
|
#endif
|
||||||
dup2(fdo, 1);
|
dup2(fdo, 1);
|
||||||
}
|
}
|
||||||
if(Mflag)
|
if(Mflag)
|
||||||
@@ -99,7 +111,8 @@ char *basepath( char *fname )
|
|||||||
/* memmove is defined here because some vendors don't provide it at
|
/* memmove is defined here because some vendors don't provide it at
|
||||||
all and others do a terrible job (like calling malloc) */
|
all and others do a terrible job (like calling malloc) */
|
||||||
// -- ouch, that hurts -- ln
|
// -- 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
|
#ifdef memmove
|
||||||
#undef memmove
|
#undef memmove
|
||||||
#endif
|
#endif
|
||||||
@@ -109,7 +122,7 @@ memmove(void *dp, const void *sp, size_t n)
|
|||||||
unsigned char *cdp, *csp;
|
unsigned char *cdp, *csp;
|
||||||
|
|
||||||
if (n<=0)
|
if (n<=0)
|
||||||
return 0;
|
return dp;
|
||||||
cdp = dp;
|
cdp = dp;
|
||||||
csp = (unsigned char *)sp;
|
csp = (unsigned char *)sp;
|
||||||
if (cdp < csp) {
|
if (cdp < csp) {
|
||||||
@@ -123,6 +136,6 @@ memmove(void *dp, const void *sp, size_t n)
|
|||||||
*--cdp = *--csp;
|
*--cdp = *--csp;
|
||||||
} while (--n);
|
} while (--n);
|
||||||
}
|
}
|
||||||
return 0;
|
return dp;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
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
|
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
|
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>
|
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
|
<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>
|
<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
|
consists of a generic operator, a type suffix, and a size indicator. The type suffixes
|
||||||
are:</p>
|
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
|
<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
|
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>
|
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
|
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
|
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 integer. Conversions that widen unsigned integers zero-extend; those that widen
|
||||||
signed integers sign-extend.</p>
|
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>
|
<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>,
|
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
|
if necessary. The following table lists the supertypes; omitted entries are their own
|
||||||
supertypes.</p>
|
supertypes.</p>
|
||||||
|
@@ -722,7 +722,7 @@ C:\dist\lcc\4.1>copy %BUILDDIR%\bprint.exe \bin
|
|||||||
<h2><a NAME="bugs">Reporting Bugs</a></h2>
|
<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
|
<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>.
|
Chapter 1 of <cite>A Retargetable C Compiler: Design and Implementation</cite>.
|
||||||
|
|
||||||
<ol>
|
<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"><code>pub/lcc</code></a>. A <a
|
||||||
HREF="ftp://ftp.cs.princeton.edu/pub/lcc/README"><code>README</code></a> file there gives
|
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
|
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>
|
get a canned reply.</li>
|
||||||
<li>Send your program by electronic mail to <code>lcc-bugs@cs.princeton.edu</code>. Please
|
<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
|
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 basepath[ 1024 ];
|
||||||
char *p;
|
char *p;
|
||||||
|
size_t basepathsz = sizeof( basepath ) - 1;
|
||||||
|
|
||||||
strncpy( basepath, lccBinary, 1024 );
|
strncpy( basepath, lccBinary, basepathsz );
|
||||||
p = strrchr( basepath, PATH_SEP );
|
basepath[basepathsz] = 0;
|
||||||
|
p = strrchr( basepath, '/' );
|
||||||
|
|
||||||
|
if( !p )
|
||||||
|
p = strrchr( basepath, '\\' );
|
||||||
|
|
||||||
if( p )
|
if( p )
|
||||||
{
|
{
|
||||||
@@ -52,6 +57,10 @@ int option(char *arg) {
|
|||||||
cpp[0] = concat(&arg[8], "/q3cpp" BINEXT);
|
cpp[0] = concat(&arg[8], "/q3cpp" BINEXT);
|
||||||
include[0] = concat("-I", concat(&arg[8], "/include"));
|
include[0] = concat("-I", concat(&arg[8], "/include"));
|
||||||
com[0] = concat(&arg[8], "/q3rcc" BINEXT);
|
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) {
|
} else if (strcmp(arg, "-p") == 0 || strcmp(arg, "-pg") == 0) {
|
||||||
fprintf( stderr, "no profiling supported, %s ignored.\n", arg);
|
fprintf( stderr, "no profiling supported, %s ignored.\n", arg);
|
||||||
} else if (strcmp(arg, "-b") == 0)
|
} else if (strcmp(arg, "-b") == 0)
|
||||||
|
@@ -11,7 +11,12 @@ static char rcsid[] = "Id: dummy rcsid";
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <process.h> /* getpid() */
|
||||||
|
#include <io.h> /* access() */
|
||||||
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef TEMPDIR
|
#ifndef TEMPDIR
|
||||||
#define TEMPDIR "/tmp"
|
#define TEMPDIR "/tmp"
|
||||||
@@ -217,14 +222,74 @@ char *basename(char *name) {
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <process.h>
|
#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
|
#else
|
||||||
|
|
||||||
#define _P_WAIT 0
|
#define _P_WAIT 0
|
||||||
#ifndef __sun
|
#ifndef __sun
|
||||||
extern int fork(void);
|
extern int fork(void);
|
||||||
#endif
|
#endif
|
||||||
extern int wait(int *);
|
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;
|
int pid, n, status;
|
||||||
|
|
||||||
switch (pid = fork()) {
|
switch (pid = fork()) {
|
||||||
@@ -292,11 +357,7 @@ static int callsys(char **av) {
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
if (verbose < 2)
|
if (verbose < 2)
|
||||||
#ifndef WIN32
|
status = spawn(executable, argv);
|
||||||
status = _spawnvp(_P_WAIT, executable, argv);
|
|
||||||
#else
|
|
||||||
status = _spawnvp(_P_WAIT, executable, (const char* const*)argv);
|
|
||||||
#endif
|
|
||||||
if (status == -1) {
|
if (status == -1) {
|
||||||
fprintf(stderr, "%s: ", progname);
|
fprintf(stderr, "%s: ", progname);
|
||||||
perror(argv[0]);
|
perror(argv[0]);
|
||||||
@@ -376,7 +437,7 @@ static char *exists(char *name) {
|
|||||||
b = b->link;
|
b = b->link;
|
||||||
if (b->str[0]) {
|
if (b->str[0]) {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
sprintf(buf, "%s/%s", b->str, name);
|
snprintf(buf, sizeof(buf), "%s/%s", b->str, name);
|
||||||
if (access(buf, 4) == 0)
|
if (access(buf, 4) == 0)
|
||||||
return strsave(buf);
|
return strsave(buf);
|
||||||
} else if (access(name, 4) == 0)
|
} else if (access(name, 4) == 0)
|
||||||
@@ -575,7 +636,7 @@ static void opt(char *arg) {
|
|||||||
clist = append(&arg[3], clist);
|
clist = append(&arg[3], clist);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break; /* and fall thru */
|
break; /* and fall through */
|
||||||
case 'a':
|
case 'a':
|
||||||
alist = append(&arg[3], alist);
|
alist = append(&arg[3], alist);
|
||||||
return;
|
return;
|
||||||
@@ -757,10 +818,9 @@ char *strsave(const char *str) {
|
|||||||
char *stringf(const char *fmt, ...) {
|
char *stringf(const char *fmt, ...) {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int n;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
n = vsprintf(buf, fmt, ap);
|
vsprintf(buf, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return strsave(buf);
|
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 ppercent = 0;
|
||||||
static int code = 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) {
|
static int get(void) {
|
||||||
if (*bp == 0) {
|
if (*bp == 0) {
|
||||||
bp = buf;
|
bp = buf;
|
||||||
*bp = 0;
|
*bp = 0;
|
||||||
if (fgets(buf, sizeof buf, infp) == NULL)
|
if (fgets(buf, sizeof buf, infp) == NULL)
|
||||||
return EOF;
|
return EOF;
|
||||||
|
crlf_to_lf(buf, sizeof buf);
|
||||||
yylineno++;
|
yylineno++;
|
||||||
while (buf[0] == '%' && buf[1] == '{' && buf[2] == '\n') {
|
while (buf[0] == '%' && buf[1] == '{' && buf[2] == '\n') {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -83,6 +103,7 @@ static int get(void) {
|
|||||||
yywarn("unterminated %{...%}\n");
|
yywarn("unterminated %{...%}\n");
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
crlf_to_lf(buf, sizeof buf);
|
||||||
yylineno++;
|
yylineno++;
|
||||||
if (strcmp(buf, "%}\n") == 0)
|
if (strcmp(buf, "%}\n") == 0)
|
||||||
break;
|
break;
|
||||||
@@ -90,6 +111,7 @@ static int get(void) {
|
|||||||
}
|
}
|
||||||
if (fgets(buf, sizeof buf, infp) == NULL)
|
if (fgets(buf, sizeof buf, infp) == NULL)
|
||||||
return EOF;
|
return EOF;
|
||||||
|
crlf_to_lf(buf, sizeof buf);
|
||||||
yylineno++;
|
yylineno++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,4 +221,5 @@ void yywarn(char *fmt, ...) {
|
|||||||
fprintf(stderr, "line %d: ", yylineno);
|
fprintf(stderr, "line %d: ", yylineno);
|
||||||
fprintf(stderr, "warning: ");
|
fprintf(stderr, "warning: ");
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
@@ -56,14 +56,14 @@ int main(int argc, char *argv[]) {
|
|||||||
} else if (infp == NULL) {
|
} else if (infp == NULL) {
|
||||||
if (strcmp(argv[i], "-") == 0)
|
if (strcmp(argv[i], "-") == 0)
|
||||||
infp = stdin;
|
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]);
|
yyerror("%s: can't read `%s'\n", argv[0], argv[i]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} else if (outfp == NULL) {
|
} else if (outfp == NULL) {
|
||||||
if (strcmp(argv[i], "-") == 0)
|
if (strcmp(argv[i], "-") == 0)
|
||||||
outfp = stdout;
|
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]);
|
yyerror("%s: can't write `%s'\n", argv[0], argv[i]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@@ -261,8 +261,7 @@ static void LoadSourceFile( const char *filename ) {
|
|||||||
length = filelength( f );
|
length = filelength( f );
|
||||||
sourceFile = malloc( length + 1 );
|
sourceFile = malloc( length + 1 );
|
||||||
if ( sourceFile ) {
|
if ( sourceFile ) {
|
||||||
size_t size;
|
fread( sourceFile, length, 1, f );
|
||||||
size = fread( sourceFile, length, 1, f );
|
|
||||||
sourceFile[length] = 0;
|
sourceFile[length] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -577,6 +577,7 @@ extern Tree cnsttree(Type, ...);
|
|||||||
extern Tree consttree(unsigned int, Type);
|
extern Tree consttree(unsigned int, Type);
|
||||||
extern Tree eqtree(int, Tree, Tree);
|
extern Tree eqtree(int, Tree, Tree);
|
||||||
extern int iscallb(Tree);
|
extern int iscallb(Tree);
|
||||||
|
extern int isnullptr(Tree);
|
||||||
extern Tree shtree(int, Tree, Tree);
|
extern Tree shtree(int, Tree, Tree);
|
||||||
extern void typeerror(int, Tree, Tree);
|
extern void typeerror(int, Tree, Tree);
|
||||||
|
|
||||||
@@ -644,7 +645,7 @@ extern int process(char *);
|
|||||||
extern int findfunc(char *, char *);
|
extern int findfunc(char *, char *);
|
||||||
extern int findcount(char *, int, int);
|
extern int findcount(char *, int, int);
|
||||||
|
|
||||||
extern Tree constexpr(int);
|
extern Tree constantexpr(int);
|
||||||
extern int intexpr(int, int);
|
extern int intexpr(int, int);
|
||||||
extern Tree simplify(int, Type, Tree, Tree);
|
extern Tree simplify(int, Type, Tree, Tree);
|
||||||
extern int ispow2(unsigned long u);
|
extern int ispow2(unsigned long u);
|
||||||
|
@@ -519,7 +519,8 @@ void emitcode(void) {
|
|||||||
(*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break;
|
(*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break;
|
||||||
case Gen: case Jump:
|
case Gen: case Jump:
|
||||||
case Label: if (cp->u.forest)
|
case Label: if (cp->u.forest)
|
||||||
(*IR->emit)(cp->u.forest); break;
|
(*IR->emit)(cp->u.forest);
|
||||||
|
break;
|
||||||
case Local: if (glevel && IR->stabsym) {
|
case Local: if (glevel && IR->stabsym) {
|
||||||
(*IR->stabsym)(cp->u.var);
|
(*IR->stabsym)(cp->u.var);
|
||||||
swtoseg(CODE);
|
swtoseg(CODE);
|
||||||
|
@@ -5,7 +5,6 @@ static Tree addtree(int, Tree, Tree);
|
|||||||
static Tree andtree(int, Tree, Tree);
|
static Tree andtree(int, Tree, Tree);
|
||||||
static Tree cmptree(int, Tree, Tree);
|
static Tree cmptree(int, Tree, Tree);
|
||||||
static int compatible(Type, Type);
|
static int compatible(Type, Type);
|
||||||
static int isnullptr(Tree e);
|
|
||||||
static Tree multree(int, Tree, Tree);
|
static Tree multree(int, Tree, Tree);
|
||||||
static Tree subtree(int, Tree, Tree);
|
static Tree subtree(int, Tree, Tree);
|
||||||
#define isvoidptr(ty) \
|
#define isvoidptr(ty) \
|
||||||
@@ -220,7 +219,7 @@ static int compatible(Type ty1, Type ty2) {
|
|||||||
&& isptr(ty2) && !isfunc(ty2->type)
|
&& isptr(ty2) && !isfunc(ty2->type)
|
||||||
&& eqtype(unqual(ty1->type), unqual(ty2->type), 0);
|
&& eqtype(unqual(ty1->type), unqual(ty2->type), 0);
|
||||||
}
|
}
|
||||||
static int isnullptr(Tree e) {
|
int isnullptr(Tree e) {
|
||||||
Type ty = unqual(e->type);
|
Type ty = unqual(e->type);
|
||||||
|
|
||||||
return generic(e->op) == CNST
|
return generic(e->op) == CNST
|
||||||
@@ -402,7 +401,7 @@ Tree addrof(Tree p) {
|
|||||||
Symbol t1 = q->u.sym;
|
Symbol t1 = q->u.sym;
|
||||||
q->u.sym = 0;
|
q->u.sym = 0;
|
||||||
q = idtree(t1);
|
q = idtree(t1);
|
||||||
/* fall thru */
|
/* fall through */
|
||||||
}
|
}
|
||||||
case INDIR:
|
case INDIR:
|
||||||
if (p == q)
|
if (p == q)
|
||||||
|
@@ -80,7 +80,7 @@ int fatal(const char *name, const char *fmt, int n) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* printtoken - print current token preceeded by a space */
|
/* printtoken - print current token preceded by a space */
|
||||||
static void printtoken(void) {
|
static void printtoken(void) {
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case ID: fprint(stderr, " `%s'", token); break;
|
case ID: fprint(stderr, " `%s'", token); break;
|
||||||
|
@@ -159,7 +159,8 @@ static Tree unary(void) {
|
|||||||
if (isarith(p->type))
|
if (isarith(p->type))
|
||||||
p = cast(p, promote(p->type));
|
p = cast(p, promote(p->type));
|
||||||
else
|
else
|
||||||
typeerror(ADD, p, NULL); break;
|
typeerror(ADD, p, NULL);
|
||||||
|
break;
|
||||||
case '-': t = gettok(); p = unary(); p = pointer(p);
|
case '-': t = gettok(); p = unary(); p = pointer(p);
|
||||||
if (isarith(p->type)) {
|
if (isarith(p->type)) {
|
||||||
Type ty = promote(p->type);
|
Type ty = promote(p->type);
|
||||||
@@ -170,18 +171,21 @@ static Tree unary(void) {
|
|||||||
} else
|
} else
|
||||||
p = simplify(NEG, ty, p, NULL);
|
p = simplify(NEG, ty, p, NULL);
|
||||||
} else
|
} else
|
||||||
typeerror(SUB, p, NULL); break;
|
typeerror(SUB, p, NULL);
|
||||||
|
break;
|
||||||
case '~': t = gettok(); p = unary(); p = pointer(p);
|
case '~': t = gettok(); p = unary(); p = pointer(p);
|
||||||
if (isint(p->type)) {
|
if (isint(p->type)) {
|
||||||
Type ty = promote(p->type);
|
Type ty = promote(p->type);
|
||||||
p = simplify(BCOM, ty, cast(p, ty), NULL);
|
p = simplify(BCOM, ty, cast(p, ty), NULL);
|
||||||
} else
|
} else
|
||||||
typeerror(BCOM, p, NULL); break;
|
typeerror(BCOM, p, NULL);
|
||||||
|
break;
|
||||||
case '!': t = gettok(); p = unary(); p = pointer(p);
|
case '!': t = gettok(); p = unary(); p = pointer(p);
|
||||||
if (isscalar(p->type))
|
if (isscalar(p->type))
|
||||||
p = simplify(NOT, inttype, cond(p), NULL);
|
p = simplify(NOT, inttype, cond(p), NULL);
|
||||||
else
|
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 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 DECR: t = gettok(); p = unary(); p = incr(DECR, pointer(p), consttree(1, inttype)); break;
|
||||||
case TYPECODE: case SIZEOF: { int op = t;
|
case TYPECODE: case SIZEOF: { int op = t;
|
||||||
@@ -318,7 +322,8 @@ static Tree postfix(Tree p) {
|
|||||||
p->type);
|
p->type);
|
||||||
t = gettok();
|
t = gettok();
|
||||||
} else
|
} else
|
||||||
error("field name expected\n"); break;
|
error("field name expected\n");
|
||||||
|
break;
|
||||||
case DEREF: t = gettok();
|
case DEREF: t = gettok();
|
||||||
p = pointer(p);
|
p = pointer(p);
|
||||||
if (t == ID) {
|
if (t == ID) {
|
||||||
@@ -331,7 +336,8 @@ static Tree postfix(Tree p) {
|
|||||||
|
|
||||||
t = gettok();
|
t = gettok();
|
||||||
} else
|
} else
|
||||||
error("field name expected\n"); break;
|
error("field name expected\n");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -621,7 +627,7 @@ Tree cast(Tree p, Type type) {
|
|||||||
p = simplify(CVP, dst, p, NULL);
|
p = simplify(CVP, dst, p, NULL);
|
||||||
else {
|
else {
|
||||||
if ((isfunc(src->type) && !isfunc(dst->type))
|
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);
|
warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, type);
|
||||||
|
|
||||||
if (src->size != dst->size)
|
if (src->size != dst->size)
|
||||||
|
@@ -292,7 +292,7 @@ static void dumptree(Node p) {
|
|||||||
dumptree(p->kids[0]);
|
dumptree(p->kids[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* else fall thru */
|
/* else fall through */
|
||||||
case EQ: case NE: case GT: case GE: case LE: case LT:
|
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 ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH:
|
||||||
case ADD: case SUB: case DIV: case MUL: case MOD:
|
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))
|
if (isarith(e->type))
|
||||||
error("cast from `%t' to `%t' is illegal in constant expressions\n",
|
error("cast from `%t' to `%t' is illegal in constant expressions\n",
|
||||||
e->kids[0]->type, e->type);
|
e->kids[0]->type, e->type);
|
||||||
/* fall thru */
|
/* fall through */
|
||||||
case CVI: case CVU: case CVF:
|
case CVI: case CVU: case CVF:
|
||||||
e = e->kids[0];
|
e = e->kids[0];
|
||||||
continue;
|
continue;
|
||||||
@@ -192,7 +192,7 @@ static int initstruct(int len, Type ty, int lev) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initializer - constexpr | { constexpr ( , constexpr )* [ , ] } */
|
/* initializer - constantexpr | { constantexpr ( , constantexpr )* [ , ] } */
|
||||||
Type initializer(Type ty, int lev) {
|
Type initializer(Type ty, int lev) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
Tree e;
|
Tree e;
|
||||||
|
@@ -33,7 +33,7 @@ int length(List list) {
|
|||||||
return n;
|
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) {
|
void *ltov(List *list, unsigned arena) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
void **array = newarray(length(*list) + 1, sizeof array[0], arena);
|
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";
|
static char format[] = "%f";
|
||||||
char buf[128];
|
char buf[128];
|
||||||
format[1] = *fmt;
|
format[1] = *fmt;
|
||||||
sprintf(buf, format, va_arg(ap, double));
|
snprintf(buf, sizeof(buf), format, va_arg(ap, double));
|
||||||
bp = outs(buf, f, bp);
|
bp = outs(buf, f, bp);
|
||||||
}
|
}
|
||||||
; break;
|
; 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) {
|
static int subd(double x, double y, double min, double max, int needconst) {
|
||||||
return addd(x, -y, min, max, needconst);
|
return addd(x, -y, min, max, needconst);
|
||||||
}
|
}
|
||||||
Tree constexpr(int tok) {
|
Tree constantexpr(int tok) {
|
||||||
Tree p;
|
Tree p;
|
||||||
|
|
||||||
needconst++;
|
needconst++;
|
||||||
@@ -192,7 +192,7 @@ Tree constexpr(int tok) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int intexpr(int tok, int n) {
|
int intexpr(int tok, int n) {
|
||||||
Tree p = constexpr(tok);
|
Tree p = constantexpr(tok);
|
||||||
|
|
||||||
needconst++;
|
needconst++;
|
||||||
if (p->op == CNST+I || p->op == CNST+U)
|
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 };
|
static char stop[] = { IF, ID, 0 };
|
||||||
Tree p;
|
Tree p;
|
||||||
t = gettok();
|
t = gettok();
|
||||||
p = constexpr(0);
|
p = constantexpr(0);
|
||||||
if (generic(p->op) == CNST && isint(p->type)) {
|
if (generic(p->op) == CNST && isint(p->type)) {
|
||||||
if (swp) {
|
if (swp) {
|
||||||
needconst++;
|
needconst++;
|
||||||
@@ -184,8 +184,9 @@ void statement(int loop, Swtch swp, int lev) {
|
|||||||
branch(p->u.l.label);
|
branch(p->u.l.label);
|
||||||
t = gettok();
|
t = gettok();
|
||||||
} else
|
} else
|
||||||
error("missing label in goto\n"); expect(';');
|
error("missing label in goto\n");
|
||||||
break;
|
expect(';');
|
||||||
|
break;
|
||||||
|
|
||||||
case ID: if (getchr() == ':') {
|
case ID: if (getchr() == ':') {
|
||||||
stmtlabel();
|
stmtlabel();
|
||||||
|
@@ -86,7 +86,7 @@ static Tree root1(Tree p) {
|
|||||||
warning("reference to `%t' elided\n", p->type);
|
warning("reference to `%t' elided\n", p->type);
|
||||||
if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
|
if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
|
||||||
warning("reference to `volatile %t' elided\n", p->type);
|
warning("reference to `volatile %t' elided\n", p->type);
|
||||||
/* fall thru */
|
/* fall through */
|
||||||
case CVI: case CVF: case CVU: case CVP:
|
case CVI: case CVF: case CVU: case CVP:
|
||||||
case NEG: case BCOM: case FIELD:
|
case NEG: case BCOM: case FIELD:
|
||||||
if (warn++ == 0)
|
if (warn++ == 0)
|
||||||
|
Reference in New Issue
Block a user