Add support for arrays of structs (up to 4 dimensions) to extractfuncs.

This commit is contained in:
Knightmare66 2021-10-28 20:28:49 -04:00
parent 1816e40c8f
commit b573e7da75
7 changed files with 309 additions and 126 deletions

View file

@ -48,13 +48,20 @@ typedef enum {false, true} qboolean;
//#define PATHSEPERATOR_STR "\\"
#define MAX_VAR_ARRAY_DIMENSIONS 4 // Knightmare added
typedef struct replacefunc_s
{
char *name;
char *newname;
char *filename;
char dec[MAX_TOKEN]; //function declaration
struct replacefunc_s *next;
char *name;
char *newname;
char *filename;
char dec[MAX_TOKEN]; // function declaration
// Knightmare added
int isArray;
int nArrayDims;
size_t arrayDimSizes[MAX_VAR_ARRAY_DIMENSIONS];
// end Knightmare
struct replacefunc_s *next;
} replacefunc_t;
typedef struct tokenList_s

View file

@ -68,8 +68,8 @@ void WriteWhiteSpace (FILE *fp, script_t *script)
fputc( c, fp );
}
c = PS_NextWhiteSpaceChar( script );
} //end while
} //end of the function WriteWhiteSpace
} // end while
} // end of the function WriteWhiteSpace
/*
=================
@ -85,8 +85,8 @@ void WriteString (FILE *fp, script_t *script)
{
fputc( *ptr, fp );
ptr++;
} //end while
} //end of the function WriteString
} // end while
} // end of the function WriteString
/*
=================
@ -129,12 +129,12 @@ void ScrewUpFile (char *oldfile, char *newfile)
else
{
WriteString( fp, script );
} //end else
} //end while
} // end else
} // end while
WriteWhiteSpace( fp, script );
FreeMemory( script );
fclose( fp );
} //end of the function ScrewUpFile
} // end of the function ScrewUpFile
#endif
/*
@ -160,12 +160,15 @@ DumpReplaceFunctions
*/
void DumpReplaceFunctions (char *typeName)
{
replacefunc_t *rf;
char path[_MAX_PATH];
FILE *f;
int len, newlen;
unsigned char *buf, *newbuf;
int updated;
replacefunc_t *rf;
char path[_MAX_PATH];
FILE *f;
int len, newlen;
unsigned char *buf, *newbuf;
int updated;
// Knightmare added
size_t i, j, k, l;
char varNameBuf[256];
updated = 0;
@ -180,10 +183,43 @@ void DumpReplaceFunctions (char *typeName)
for ( rf = replacefuncs; rf; rf = rf->next )
{
if (typeName)
Log_Print( "{\"%s\", &%s},\n", rf->name, rf->name );
{
// TODO: output all elements of an array
if (rf->isArray)
{
for (i = 0; i < rf->arrayDimSizes[0]; i++)
{
for (j = 0; j < rf->arrayDimSizes[1]; j++)
{
for (k = 0; k < rf->arrayDimSizes[2]; k++)
{
for (l = 0; l < rf->arrayDimSizes[3]; l++) {
Com_sprintf (varNameBuf, sizeof(varNameBuf), "%s[%d][%d][%d][%d]", rf->name, i, j, k, l);
Log_Print( "{\"%s\", &%s},\n", varNameBuf, varNameBuf );
}
if (rf->nArrayDims == 3) {
Com_sprintf (varNameBuf, sizeof(varNameBuf), "%s[%d][%d][%d]", rf->name, i, j, k);
Log_Print( "{\"%s\", &%s},\n", varNameBuf, varNameBuf );
}
}
if (rf->nArrayDims == 2) {
Com_sprintf (varNameBuf, sizeof(varNameBuf), "%s[%d][%d]", rf->name, i, j);
Log_Print( "{\"%s\", &%s},\n", varNameBuf, varNameBuf );
}
}
if (rf->nArrayDims == 1) {
Com_sprintf (varNameBuf, sizeof(varNameBuf), "%s[%d]", rf->name, i);
Log_Print( "{\"%s\", &%s},\n", varNameBuf, varNameBuf );
}
}
}
else {
Log_Print( "{\"%s\", &%s},\n", rf->name, rf->name );
}
}
else
Log_Print( "{\"%s\", (byte *)%s},\n", rf->name, rf->name );
} //end for
} // end for
Log_Print( "{0, 0}\n" );
Log_Close();
@ -230,6 +266,10 @@ void DumpReplaceFunctions (char *typeName)
remove( "debug\\g_save.sbr" );
remove( "release\\g_save.obj" );
remove( "release\\g_save.sbr" );
remove( "x64\\debug\\g_save.obj" );
remove( "x64\\debug\\g_save.sbr" );
remove( "x64\\release\\g_save.obj" );
remove( "x64\\release\\g_save.sbr" );
#endif
updated = 1;
@ -305,6 +345,10 @@ void DumpReplaceFunctions (char *typeName)
remove( "debug\\g_save.sbr" );
remove( "release\\g_save.obj" );
remove( "release\\g_save.sbr" );
remove( "x64\\debug\\g_save.obj" );
remove( "x64\\debug\\g_save.sbr" );
remove( "x64\\release\\g_save.obj" );
remove( "x64\\release\\g_save.sbr" );
#endif
updated = 1;
@ -324,8 +368,14 @@ void DumpReplaceFunctions (char *typeName)
free( newbuf );
#ifdef _WIN32
if ( updated ) {
printf( "Updated the function table, recompile required.\n" );
if ( updated )
{
if (typeName) {
printf( "Updated the %s table, recompile required.\n", typeName );
}
else {
printf( "Updated the function table, recompile required.\n" );
}
}
#endif
} // end of the function DumpReplaceFunctions
@ -345,9 +395,9 @@ replacefunc_t *FindFunctionName (char *funcname)
{
return f;
}
} //end for
} // end for
return NULL;
} //end of the function FindFunctionName
} // end of the function FindFunctionName
/*
=================
@ -369,7 +419,7 @@ int MayScrewUp (char *funcname)
return false;
}
return true;
} //end of the function MayScrewUp
} // end of the function MayScrewUp
/*
=================
@ -388,8 +438,7 @@ void ConcatDec (tokenList_t *list, char *str, size_t strSize, int inc)
return;
}
}*/
if (list->next)
{
if (list->next) {
ConcatDec (list->next, str, strSize, inc);
}
// strncat (str, list->token.string);
@ -408,8 +457,7 @@ void AddFunctionName (char *funcname, char *filename, tokenList_t *head)
replacefunc_t *f;
tokenList_t *list;
if ( FindFunctionName(funcname) )
{
if ( FindFunctionName(funcname) ) {
return;
}
@ -450,8 +498,81 @@ void AddFunctionName (char *funcname, char *filename, tokenList_t *head)
list = head;
f->dec[0] = '\0';
ConcatDec (list, f->dec, sizeof(f->dec), 0);
} // end of the function AddFunctionName
} //end of the function AddFunctionName
/*
=================
ConcatVarDec
Knightmare- this builds out var declaration
=================
*/
void ConcatVarDec (tokenList_t *list, char *str, size_t strSize, int nDims, size_t DimSizes[])
{
int i;
char buf[32];
if (list->next) {
ConcatVarDec (list->next, str, strSize, nDims, DimSizes);
}
Q_strncatz (str, strSize, list->token.string);
for (i = 0; i < nDims; i++) {
Com_sprintf (buf, sizeof(buf), "[%d]", DimSizes[i]);
Q_strncatz (str, strSize, buf );
}
Q_strncatz (str, strSize, " " );
}
/*
=================
AddVarName
Knightmare- this adds structs / vars of a given type
=================
*/
void AddVarName (char *funcname, int nDims, size_t DimSizes[], char *filename, tokenList_t *head)
{
int i;
replacefunc_t *f;
tokenList_t *list;
if ( FindFunctionName(funcname) ) {
return;
}
f = (replacefunc_t *) GetMemory(sizeof(replacefunc_t) + (int)strlen(funcname) + 1 + 6 + (int)strlen(filename) + 1);
f->name = (char *)f + sizeof(replacefunc_t);
Q_strncpyz (f->name, strlen(funcname) + 1, funcname);
f->newname = (char *)f + sizeof(replacefunc_t) + strlen(funcname) + 1;
Com_sprintf (f->newname, 6, "F%d", numfuncs++);
f->filename = (char *)f + sizeof(replacefunc_t) + strlen(funcname) + 1 + strlen(f->newname) + 1;
Q_strncpyz (f->filename, strlen(filename) + 1, filename);
if (nDims > 0)
{
f->isArray = 1;
f->nArrayDims = min(nDims, MAX_VAR_ARRAY_DIMENSIONS);
for (i = 0; i < MAX_VAR_ARRAY_DIMENSIONS; i++) {
f->arrayDimSizes[i] = DimSizes[i];
}
/* printf ("AddVarName: var %s has array size(s) of: ", funcname);
for (i = 0; i < f->nArrayDims; i++) {
printf ("[%d]", f->arrayDimSizes[i]);
}
printf ("\n"); */
}
else {
f->isArray = 0;
f->nArrayDims = 0;
memset (f->arrayDimSizes, 0, sizeof(f->arrayDimSizes));
}
f->next = replacefuncs;
replacefuncs = f;
// construct the declaration
list = head;
f->dec[0] = '\0';
ConcatVarDec (list, f->dec, sizeof(f->dec), f->nArrayDims, f->arrayDimSizes);
}
/*
=================
@ -512,36 +633,40 @@ void StripTokenList (tokenList_t *head)
}
}
// now kill everything after lastTrav
// KillTokenList( lastTrav );
// KillTokenList (lastTrav);
lastTrav->next = NULL;
}
/*
=================
GetTypeNamesFromFile
GetVarNamesFromFile
Knightmare- this gets structs / vars of a given type
=================
*/
void GetTypeNamesFromFile (char *filename, char *typeName)
void GetVarNamesFromFile (char *filename, char *typeName)
{
source_t *source;
token_t token, lasttoken;
int indent = 0;//, brace;
token_t token, lastToken, varToken;
int indent = 0;
int isStatic = 0;
int isExtern = 0;
int isArray = 0;
int sqBracketLevel = 0;
int nArrayDims = 0;
size_t arrayDimSizes[MAX_VAR_ARRAY_DIMENSIONS] = {0};
tokenList_t *listHead;
listHead = NULL;
source = LoadSourceFile( filename );
source = LoadSourceFile (filename);
if ( !source ) {
Error( "error opening %s", filename );
Error ("error opening %s", filename);
return;
}
while ( 1 )
{
if ( !PC_ReadToken( source, &token ) ) {
if ( !PC_ReadToken(source, &token) ) {
break;
}
if ( token.type == TT_PUNCTUATION )
@ -551,6 +676,9 @@ void GetTypeNamesFromFile (char *filename, char *typeName)
case ';':
isStatic = 0;
isExtern = 0;
isArray = 0;
nArrayDims = 0;
memset(arrayDimSizes, 0, sizeof(arrayDimSizes));
break;
case '{':
indent++;
@ -570,24 +698,68 @@ void GetTypeNamesFromFile (char *filename, char *typeName)
if ( token.string[0] == 'e' && !strcmp( token.string, "extern" ) ) {
isExtern = 1;
}
if ( !isStatic && !isExtern && indent == 0 && !strcmp(token.string, typeName) )
if ( !isStatic && !isExtern && (indent == 0) && !strcmp(token.string, typeName) ) // type name matches
{
if ( PC_ReadToken( source, &token ) )
if ( PC_ReadToken(source, &token) ) // next token should be var name
{
if ( token.type == TT_NAME )
{
memcpy( &varToken, &token, sizeof(token_t) ); // save var name
// look for array sizes after var name
while ( PC_ReadToken(source, &token) )
{
if ( token.string[0] == ';' ) { // end of declaration
break;
}
// look for array dimensions ( e.g. var[x]... )
if ( token.type == TT_PUNCTUATION )
{
switch ( token.string[0] )
{
case '[':
isArray = 1;
sqBracketLevel++;
break;
case ']':
sqBracketLevel--;
if ( sqBracketLevel < 0 )
sqBracketLevel = 0;
break;
}
}
// set array sizes
if ( isArray && (token.type == TT_NUMBER) && (sqBracketLevel == 1) )
{
if (nArrayDims < MAX_VAR_ARRAY_DIMENSIONS) {
arrayDimSizes[nArrayDims] = token.intvalue;
nArrayDims++;
}
else {
printf ("Too many array dimensions for var %s in file %s!\n", varToken.string, filename);
}
}
}
if (listHead)
listHead->next = NULL;
listHead = NULL;
AddTokenToList( &listHead, &token );
AddFunctionName( token.string, filename, listHead );
AddTokenToList (&listHead, &varToken);
AddVarName (varToken.string, nArrayDims, arrayDimSizes, filename, listHead);
// AddTokenToList (&listHead, &token);
// AddVarName (token.string, nArrayDims, arrayDimSizes, filename, listHead);
// reset array sizes
isArray = 0;
nArrayDims = 0;
memset(arrayDimSizes, 0, sizeof(arrayDimSizes));
}
}
}
}
memcpy( &lasttoken, &token, sizeof( token_t ) );
memcpy( &lastToken, &token, sizeof(token_t) );
}
FreeSource( source );
FreeSource (source);
}
/*
@ -609,9 +781,9 @@ void GetFunctionNamesFromFile (char *filename)
}
listHead = NULL;
source = LoadSourceFile( filename );
source = LoadSourceFile (filename);
if ( !source ) {
Error( "error opening %s", filename );
Error ("error opening %s", filename);
return;
}
@ -623,10 +795,10 @@ void GetFunctionNamesFromFile (char *filename)
// } //end if
while ( 1 )
{
if ( !PC_ReadToken( source, &token ) ) {
if ( !PC_ReadToken(source, &token) ) {
break;
}
AddTokenToList( &listHead, &token );
AddTokenToList (&listHead, &token);
if ( token.type == TT_PUNCTUATION )
{
switch ( token.string[0] )
@ -645,12 +817,12 @@ void GetFunctionNamesFromFile (char *filename)
case '(':
if ( indent <= 0 && lasttoken.type == TT_NAME )
{
StripTokenList( listHead );
StripTokenList (listHead);
brace = 1;
while ( PC_ReadToken( source, &token ) )
while ( PC_ReadToken(source, &token) )
{
AddTokenToList( &listHead, &token );
AddTokenToList (&listHead, &token);
if ( token.string[0] == '(' ) {
brace++;
}
@ -659,33 +831,33 @@ void GetFunctionNamesFromFile (char *filename)
brace--;
if ( brace <= 0 )
{
if ( !PC_ReadToken( source, &token ) ) {
if ( !PC_ReadToken(source, &token) ) {
break;
}
if ( token.string[0] == '{' ) {
indent++;
if ( !isStatic && MayScrewUp( lasttoken.string ) ) {
AddFunctionName( lasttoken.string, filename, listHead );
if ( !isStatic && MayScrewUp(lasttoken.string) ) {
AddFunctionName (lasttoken.string, filename, listHead);
}
} //end if
} // end if
break;
} //end if
} //end if
} //end while
} //end if
} // end if
} // end if
} // end while
} // end if
break;
} //end switch
} //end if
} // end switch
} // end if
if ( token.type == TT_NAME )
{
if ( token.string[0] == 's' && !strcmp( token.string, "static" ) ) {
isStatic = 1;
}
}
memcpy( &lasttoken, &token, sizeof( token_t ) );
} //end while
FreeSource( source );
} //end of the function GetFunctionNamesFromFile
memcpy( &lasttoken, &token, sizeof(token_t) );
} // end while
FreeSource (source);
} // end of the function GetFunctionNamesFromFile
/*
=================
@ -752,7 +924,7 @@ void main (int argc, char *argv[])
}
}
if (argc < 1 || (firstParmSet && firstParm < 1))
if ( (argc < 1) || (firstParmSet && firstParm < 1) )
Usage ();
// end Knightmare
@ -763,11 +935,11 @@ void main (int argc, char *argv[])
if ( !(filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
if (typeExtract)
GetTypeNamesFromFile (filedata.cFileName, typeName);
GetVarNamesFromFile (filedata.cFileName, typeName);
else
GetFunctionNamesFromFile (filedata.cFileName);
}
//find the next file
// find the next file
done = !FindNextFile (handle, &filedata);
}
if (typeExtract)
@ -845,7 +1017,7 @@ int main (int argc, char *argv[])
{
// printf( "%d: %s\n", i, argv[i] );
if (typeExtract)
GetTypeNamesFromFile (argv[i], typeName);
GetVarNamesFromFile (argv[i], typeName);
else
GetFunctionNamesFromFile (argv[i]);
}

View file

@ -1960,8 +1960,7 @@ int PC_EvaluateTokens( source_t *source, token_t *tokens, signed long int *intva
v->intvalue = 1;
v->floatvalue = 1;
} //end if
else
{
else {
v->intvalue = 0;
v->floatvalue = 0;
} //end else
@ -1970,7 +1969,10 @@ int PC_EvaluateTokens( source_t *source, token_t *tokens, signed long int *intva
v->prev = lastvalue;
if ( lastvalue ) {
lastvalue->next = v;
} else { firstvalue = v;}
}
else {
firstvalue = v;
}
lastvalue = v;
if ( brace ) {
t = t->next;
@ -1998,8 +2000,7 @@ int PC_EvaluateTokens( source_t *source, token_t *tokens, signed long int *intva
v->intvalue = -(signed int) t->intvalue;
v->floatvalue = -t->floatvalue;
} //end if
else
{
else {
v->intvalue = t->intvalue;
v->floatvalue = t->floatvalue;
} //end else
@ -2008,7 +2009,10 @@ int PC_EvaluateTokens( source_t *source, token_t *tokens, signed long int *intva
v->prev = lastvalue;
if ( lastvalue ) {
lastvalue->next = v;
} else { firstvalue = v;}
}
else {
firstvalue = v;
}
lastvalue = v;
//last token was a value
lastwasvalue = 1;
@ -2041,7 +2045,7 @@ int PC_EvaluateTokens( source_t *source, token_t *tokens, signed long int *intva
t->subtype == P_RSHIFT || t->subtype == P_LSHIFT ||
t->subtype == P_BIN_AND || t->subtype == P_BIN_OR ||
t->subtype == P_BIN_XOR ) {
SourceError( source, "illigal operator %s on floating point operands\n", t->string );
SourceError( source, "illegal operator %s on floating point operands\n", t->string );
error = 1;
break;
} //end if
@ -2972,7 +2976,7 @@ int PC_ReadToken( source_t *source, token_t *token )
*/
#ifdef QUAKEC
if ( !BuiltinFunction( source ) )
#endif //QUAKC
#endif // QUAKC
{
//read the precompiler directive
if ( !PC_ReadDirective( source ) ) {
@ -2981,12 +2985,12 @@ int PC_ReadToken( source_t *source, token_t *token )
return qfalse;
}
continue;
} //end if
} //end if
} // end if
} // end if
if ( token->type == TT_PUNCTUATION && *token->string == '$' ) {
#ifdef QUAKEC
if ( !QuakeCMacro( source ) )
#endif //QUAKEC
#endif // QUAKEC
{
//read the precompiler directive
if ( !PC_ReadDollarDirective( source ) ) {
@ -2995,9 +2999,9 @@ int PC_ReadToken( source_t *source, token_t *token )
return qfalse;
}
continue;
} //end if
} // end if
} //end if
//if skipping source because of conditional compilation
// if skipping source because of conditional compilation
if ( source->skip ) {
continue;
}
@ -3009,7 +3013,7 @@ int PC_ReadToken( source_t *source, token_t *token )
define = PC_FindHashedDefine( source->definehash, token->string );
#else
define = PC_FindDefine( source->defines, token->string );
#endif //DEFINEHASHING
#endif // DEFINEHASHING
//if it is a define macro
if ( define ) {
@ -3028,14 +3032,14 @@ int PC_ReadToken( source_t *source, token_t *token )
return qfalse;
}
continue;
} //end if
} //end if
//copy token for unreading
} // end if
} // end if
// copy token for unreading
memcpy( &source->token, token, sizeof( token_t ) );
//found a token
// found a token
return qtrue;
} //end while
} //end of the function PC_ReadToken
} // end while
} // end of the function PC_ReadToken
//============================================================================
//
// Parameter: -

View file

@ -89,14 +89,14 @@ __inline int Q_vsnprintf (char *Dest, size_t Count, const char *Format, va_list
#define SCFL_NOSTRINGESCAPECHARS 0x0008
#define SCFL_PRIMITIVE 0x0010
#define SCFL_NOBINARYNUMBERS 0x0020
#define SCFL_NONUMBERVALUES 0x0040
#define SCFL_NONUMBERVALUES 0x0040
//token types
#define TT_STRING 1 // string
#define TT_LITERAL 2 // literal
#define TT_NUMBER 3 // number
#define TT_NAME 4 // name
#define TT_PUNCTUATION 5 // punctuation
#define TT_STRING 1 // string
#define TT_LITERAL 2 // literal
#define TT_NUMBER 3 // number
#define TT_NAME 4 // name
#define TT_PUNCTUATION 5 // punctuation
//string sub type
//---------------
@ -107,27 +107,27 @@ __inline int Q_vsnprintf (char *Dest, size_t Count, const char *Format, va_list
//number sub type
//---------------
#define TT_DECIMAL 0x0008 // decimal number
#define TT_HEX 0x0100 // hexadecimal number
#define TT_OCTAL 0x0200 // octal number
#define TT_HEX 0x0100 // hexadecimal number
#define TT_OCTAL 0x0200 // octal number
#ifdef BINARYNUMBERS
#define TT_BINARY 0x0400 // binary number
#define TT_BINARY 0x0400 // binary number
#endif //BINARYNUMBERS
#define TT_FLOAT 0x0800 // floating point number
#define TT_FLOAT 0x0800 // floating point number
#define TT_INTEGER 0x1000 // integer number
#define TT_LONG 0x2000 // long number
#define TT_UNSIGNED 0x4000 // unsigned number
//punctuation sub type
//--------------------
#define P_RSHIFT_ASSIGN 1
#define P_LSHIFT_ASSIGN 2
#define P_PARMS 3
#define P_PRECOMPMERGE 4
#define P_RSHIFT_ASSIGN 1
#define P_LSHIFT_ASSIGN 2
#define P_PARMS 3
#define P_PRECOMPMERGE 4
#define P_LOGIC_AND 5
#define P_LOGIC_OR 6
#define P_LOGIC_GEQ 7
#define P_LOGIC_LEQ 8
#define P_LOGIC_EQ 9
#define P_LOGIC_AND 5
#define P_LOGIC_OR 6
#define P_LOGIC_GEQ 7
#define P_LOGIC_LEQ 8
#define P_LOGIC_EQ 9
#define P_LOGIC_UNEQ 10
#define P_MUL_ASSIGN 11
@ -138,9 +138,9 @@ __inline int Q_vsnprintf (char *Dest, size_t Count, const char *Format, va_list
#define P_INC 16
#define P_DEC 17
#define P_BIN_AND_ASSIGN 18
#define P_BIN_OR_ASSIGN 19
#define P_BIN_XOR_ASSIGN 20
#define P_BIN_AND_ASSIGN 18
#define P_BIN_OR_ASSIGN 19
#define P_BIN_XOR_ASSIGN 20
#define P_RSHIFT 21
#define P_LSHIFT 22
@ -159,23 +159,23 @@ __inline int Q_vsnprintf (char *Dest, size_t Count, const char *Format, va_list
#define P_BIN_XOR 34
#define P_BIN_NOT 35
#define P_LOGIC_NOT 36
#define P_LOGIC_GREATER 37
#define P_LOGIC_LESS 38
#define P_LOGIC_NOT 36
#define P_LOGIC_GREATER 37
#define P_LOGIC_LESS 38
#define P_REF 39
#define P_COMMA 40
#define P_SEMICOLON 41
#define P_COLON 42
#define P_QUESTIONMARK 43
#define P_REF 39
#define P_COMMA 40
#define P_SEMICOLON 41
#define P_COLON 42
#define P_QUESTIONMARK 43
#define P_PARENTHESESOPEN 44
#define P_PARENTHESESCLOSE 45
#define P_BRACEOPEN 46
#define P_BRACECLOSE 47
#define P_SQBRACKETOPEN 48
#define P_SQBRACKETCLOSE 49
#define P_BACKSLASH 50
#define P_PARENTHESESOPEN 44
#define P_PARENTHESESCLOSE 45
#define P_BRACEOPEN 46
#define P_BRACECLOSE 47
#define P_SQBRACKETOPEN 48
#define P_SQBRACKETCLOSE 49
#define P_BACKSLASH 50
#define P_PRECOMP 51
#define P_DOLLAR 52

Binary file not shown.

Binary file not shown.