summaryrefslogtreecommitdiff
path: root/src/tools/asm/q3asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/asm/q3asm.c')
-rw-r--r--src/tools/asm/q3asm.c129
1 files changed, 74 insertions, 55 deletions
diff --git a/src/tools/asm/q3asm.c b/src/tools/asm/q3asm.c
index 4f4c9a3..44a4219 100644
--- a/src/tools/asm/q3asm.c
+++ b/src/tools/asm/q3asm.c
@@ -1,7 +1,7 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
+Copyright (C) 2000-2013 Darklegion Development
This file is part of Tremulous.
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
+#include "../../qcommon/q_platform.h"
#include "cmdlib.h"
#include "mathlib.h"
#include "../../qcommon/qfiles.h"
@@ -131,7 +132,7 @@ typedef enum {
DATASEG, // initialized 32 bit data, will be byte swapped
LITSEG, // strings
BSSSEG, // 0 filled
- JTRGSEG, // psuedo-segment that contains only jump table targets
+ JTRGSEG, // pseudo-segment that contains only jump table targets
NUM_SEGMENTS
} segmentName_t;
@@ -226,16 +227,14 @@ int opcodesHash[ NUM_SOURCE_OPS ];
-int
-vreport (const char* fmt, va_list vp)
+static int vreport (const char* fmt, va_list vp)
{
if (options.verbose != qtrue)
return 0;
return vprintf(fmt, vp);
}
-int
-report (const char *fmt, ...)
+static int report (const char *fmt, ...)
{
va_list va;
int retval;
@@ -248,16 +247,13 @@ report (const char *fmt, ...)
/* The chain-and-bucket hash table. -PH */
-void
-hashtable_init (hashtable_t *H, int buckets)
+static void hashtable_init (hashtable_t *H, int buckets)
{
H->buckets = buckets;
H->table = calloc(H->buckets, sizeof(*(H->table)));
- return;
}
-hashtable_t *
-hashtable_new (int buckets)
+static hashtable_t *hashtable_new (int buckets)
{
hashtable_t *H;
@@ -268,8 +264,7 @@ hashtable_new (int buckets)
/* No destroy/destructor. No need. */
-void
-hashtable_add (hashtable_t *H, int hashvalue, void *datum)
+static void hashtable_add (hashtable_t *H, int hashvalue, void *datum)
{
hashchain_t *hc, **hb;
@@ -290,18 +285,15 @@ hashtable_add (hashtable_t *H, int hashvalue, void *datum)
}
hc->data = datum;
hc->next = 0;
- return;
}
-hashchain_t *
-hashtable_get (hashtable_t *H, int hashvalue)
+static hashchain_t *hashtable_get (hashtable_t *H, int hashvalue)
{
hashvalue = (abs(hashvalue) % H->buckets);
return (H->table[hashvalue]);
}
-void
-hashtable_stats (hashtable_t *H)
+static void hashtable_stats (hashtable_t *H)
{
int len, empties, longest, nodes;
int i;
@@ -341,8 +333,7 @@ hashtable_stats (hashtable_t *H)
/* Kludge. */
/* Check if symbol already exists. */
/* Returns 0 if symbol does NOT already exist, non-zero otherwise. */
-int
-hashtable_symbol_exists (hashtable_t *H, int hash, char *sym)
+static int hashtable_symbol_exists (hashtable_t *H, int hash, char *sym)
{
hashchain_t *hc;
symbol_t *s;
@@ -372,8 +363,7 @@ hashtable_symbol_exists (hashtable_t *H, int hash, char *sym)
/* Comparator function for quicksorting. */
-int
-symlist_cmp (const void *e1, const void *e2)
+static int symlist_cmp (const void *e1, const void *e2)
{
const symbol_t *a, *b;
@@ -389,15 +379,18 @@ symlist_cmp (const void *e1, const void *e2)
However, qsort(3) already exists, and I'm really lazy.
-PH
*/
-void
-sort_symbols ()
+static void sort_symbols ()
{
int i, elems;
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++)
{
@@ -439,7 +432,7 @@ sort_symbols ()
This function is one big evil hack to work around this problem.
*/
-int atoiNoCap (const char *s)
+static int atoiNoCap (const char *s)
{
INT64 l;
union {
@@ -465,7 +458,7 @@ HashString
=============
*/
/* Default hash function of Kazlib 1.19, slightly modified. */
-unsigned int HashString (const char *key)
+static unsigned int HashString (const char *key)
{
static unsigned long randbox[] = {
0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U,
@@ -494,15 +487,15 @@ unsigned int HashString (const char *key)
CodeError
============
*/
-void CodeError( char *fmt, ... ) {
+static void CodeError( char *fmt, ... ) {
va_list argptr;
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 );
}
@@ -511,7 +504,7 @@ void CodeError( char *fmt, ... ) {
EmitByte
============
*/
-void EmitByte( segment_t *seg, int v ) {
+static void EmitByte( segment_t *seg, int v ) {
if ( seg->imageUsed >= MAX_IMAGE ) {
Error( "MAX_IMAGE" );
}
@@ -524,7 +517,7 @@ void EmitByte( segment_t *seg, int v ) {
EmitInt
============
*/
-void EmitInt( segment_t *seg, int v ) {
+static void EmitInt( segment_t *seg, int v ) {
if ( seg->imageUsed >= MAX_IMAGE - 4) {
Error( "MAX_IMAGE" );
}
@@ -542,7 +535,7 @@ DefineSymbol
Symbols can only be defined on pass 0
============
*/
-void DefineSymbol( char *sym, int value ) {
+static void DefineSymbol( char *sym, int value ) {
/* Hand optimization by PhaethonH */
symbol_t *s;
char expanded[MAX_LINE_LENGTH];
@@ -598,7 +591,7 @@ LookupSymbol
Symbols can only be evaluated on pass 1
============
*/
-int LookupSymbol( char *sym ) {
+static int LookupSymbol( char *sym ) {
symbol_t *s;
char expanded[MAX_LINE_LENGTH];
int hash;
@@ -646,7 +639,7 @@ If a full line isn't parsed, returns NULL
Otherwise returns the updated parse pointer
===============
*/
-char *ExtractLine( char *data ) {
+static char *ExtractLine( char *data ) {
/* Goal:
Given a string `data', extract one text line into buffer `lineBuffer' that
is no longer than MAX_LINE_LENGTH characters long. Return value is
@@ -688,7 +681,7 @@ Parse
Parse a token out of linebuffer
==============
*/
-qboolean Parse( void ) {
+static qboolean Parse( void ) {
/* Hand-optimized by PhaethonH */
const char *p, *q;
@@ -724,7 +717,7 @@ qboolean Parse( void ) {
ParseValue
==============
*/
-int ParseValue( void ) {
+static int ParseValue( void ) {
Parse();
return atoiNoCap( token );
}
@@ -735,7 +728,7 @@ int ParseValue( void ) {
ParseExpression
==============
*/
-int ParseExpression(void) {
+static int ParseExpression(void) {
/* Hand optimization, PhaethonH */
int i, j;
char sym[MAX_LINE_LENGTH];
@@ -806,7 +799,7 @@ Note that the lit segment is read-write in the VM, so strings
aren't read only as in some architectures.
==============
*/
-void HackToSegment( segmentName_t seg ) {
+static void HackToSegment( segmentName_t seg ) {
if ( currentSegment == &segment[seg] ) {
return;
}
@@ -956,12 +949,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++;
@@ -1165,7 +1157,7 @@ AssembleLine
==============
*/
-void AssembleLine( void ) {
+static void AssembleLine( void ) {
hashchain_t *hc;
sourceOps_t *op;
int i;
@@ -1320,7 +1312,7 @@ void InitTables( void ) {
WriteMapFile
==============
*/
-void WriteMapFile( void ) {
+static void WriteMapFile( void ) {
FILE *f;
symbol_t *s;
char imageName[MAX_OS_PATH];
@@ -1352,7 +1344,7 @@ void WriteMapFile( void ) {
WriteVmFile
===============
*/
-void WriteVmFile( void ) {
+static void WriteVmFile( void ) {
char imageName[MAX_OS_PATH];
vmHeader_t header;
FILE *f;
@@ -1401,6 +1393,17 @@ void WriteVmFile( void ) {
report( "Writing to %s\n", imageName );
+#ifdef Q3_BIG_ENDIAN
+ {
+ int i;
+
+ // byte swap the header
+ for ( i = 0 ; i < sizeof( vmHeader_t ) / 4 ; i++ ) {
+ ((int *)&header)[i] = LittleLong( ((int *)&header)[i] );
+ }
+ }
+#endif
+
CreatePath( imageName );
f = SafeOpenWrite( imageName );
SafeWrite( f, &header, headerSize );
@@ -1420,7 +1423,7 @@ void WriteVmFile( void ) {
Assemble
===============
*/
-void Assemble( void ) {
+static void Assemble( void ) {
int i;
char filename[MAX_OS_PATH];
char *ptr;
@@ -1487,7 +1490,7 @@ ParseOptionFile
=============
*/
-void ParseOptionFile( const char *filename ) {
+static void ParseOptionFile( const char *filename ) {
char expanded[MAX_OS_PATH];
char *text, *text_p;
@@ -1515,6 +1518,20 @@ void ParseOptionFile( const char *filename ) {
}
}
+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\
+ -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);
+}
+
/*
==============
main
@@ -1527,15 +1544,7 @@ int main( int argc, char **argv ) {
// _chdir( "/quake3/jccode/cgame/lccout" ); // hack for vc profiler
if ( argc < 2 ) {
- 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\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\
-", argv[0]);
+ ShowHelp( argv[0] );
}
start = I_FloatTime ();
@@ -1548,6 +1557,12 @@ Assemble LCC bytecode assembly to Q3VM bytecode.\n\
if ( argv[i][0] != '-' ) {
break;
}
+ if( !strcmp( argv[ i ], "-h" ) ||
+ !strcmp( argv[ i ], "--help" ) ||
+ !strcmp( argv[ i ], "-?") ) {
+ ShowHelp( argv[0] );
+ }
+
if ( !strcmp( argv[i], "-o" ) ) {
if ( i == argc - 1 ) {
Error( "-o must preceed a filename" );
@@ -1604,6 +1619,10 @@ Motivation: not wanting to scrollback for pages to find asm error.
asmFileNames[ numAsmFiles ] = copystring( argv[ i ] );
numAsmFiles++;
}
+ // In some case it Segfault without this check
+ if ( numAsmFiles == 0 ) {
+ Error( "No file to assemble" );
+ }
InitTables();
Assemble();