summaryrefslogtreecommitdiffstats
path: root/tools/globalcode/utility/util.c
diff options
context:
space:
mode:
authorSvxy <aidan61605@gmail.com>2023-05-31 23:31:32 +0200
committerSvxy <aidan61605@gmail.com>2023-05-31 23:31:32 +0200
commiteb4b3404aa00220d659e532151dab13d642c17a3 (patch)
tree7e1107c4995489a26c4007e41b53ea8d00ab2134 /tools/globalcode/utility/util.c
downloadThe-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.gz
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.bz2
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.lz
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.xz
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.zst
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.zip
Diffstat (limited to 'tools/globalcode/utility/util.c')
-rw-r--r--tools/globalcode/utility/util.c724
1 files changed, 724 insertions, 0 deletions
diff --git a/tools/globalcode/utility/util.c b/tools/globalcode/utility/util.c
new file mode 100644
index 0000000..79764df
--- /dev/null
+++ b/tools/globalcode/utility/util.c
@@ -0,0 +1,724 @@
+/*-----------------------------------------------------------------------------
+** Copyright (C) 2001 Radical Entertainment Ltd. All rights reserved.
+**
+** winutil.h
+**
+** Description: A set of utilities which are specific to the windows development
+** environment.
+**
+** Modification History:
+** + Created Aug 03, 2001 -- bkusy
+**---------------------------------------------------------------------------*/
+
+/*----------------------------------------
+** System Includes
+**--------------------------------------*/
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+
+/*----------------------------------------
+** Project Includes
+**--------------------------------------*/
+#include "util.h"
+
+/*----------------------------------------
+** Constants
+**--------------------------------------*/
+#define BUFFER_SIZE 512
+
+/*----------------------------------------
+** Globals
+**--------------------------------------*/
+char* util_optarg;
+int util_optind;
+int util_opterr = 1;
+int util_optopt;
+
+
+/*-----------------------------------------------------------------------------
+** u t i l _ b a s e n a m e
+**
+** Synopsis: Determine the basename in a file path. ( eg/ would return
+** "newfile.c" from the path "/usr/home/newfile.c".
+**
+** Parameters: buffer - buffer to receive basename.
+** size - size of buffer.
+** path - path to determine basename from.
+**
+** Returns: non-zero if successful, 0 if buffer is too small.
+**
+** Constraints: path must use '/' and not '\' as directory separators.
+**
+**---------------------------------------------------------------------------*/
+int util_basename( char* buffer, int size, const char* path )
+{
+ char* d;
+ char* n;
+ char* e;
+ int length;
+ int result = 0;
+
+ assert( buffer );
+
+ util_decomposeFilePath( path, &d, &n, &e );
+
+ length = strlen( n ) + strlen( e ) + 1;
+
+ if ( length < size )
+ {
+ strcpy( buffer, n );
+ strcat( buffer, "." );
+ strcat( buffer, e );
+
+ result = 1;
+ }
+
+ return result;
+}
+/*-----------------------------------------------------------------------------
+** u t i l _ c h a n g e F i l e E x t e n s i o n
+**
+** Synopsis: Changes the file extension in the given buffer to the given
+** given extension.
+**
+** Parameters: buffer - the file path to be modified.
+** ext - the new file extension.
+**
+** Returns: NOTHING
+**
+** Constraints: If the original file path does not have an extension, as
+** identified by the presence of a "." character, no change will
+** take place.
+** If the new extension is longer than the old extension, no
+** change will take place.
+**
+**---------------------------------------------------------------------------*/
+void util_changeFileExtension( char* buffer, const char* ext )
+{
+ char* oldExt = 0;
+
+ assert( buffer );
+ assert( ext );
+
+ oldExt = (char*)(util_rindex( buffer, '.' ));
+
+ if ( oldExt )
+ {
+ oldExt++;
+
+ if ( strlen( oldExt ) <= strlen( ext ) )
+ {
+ strcpy( oldExt, ext );
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ d e c o m p o s e F i l e P a t h
+**
+** Synopsis: Decompose a file path into its directory, filename and extension.
+**
+** Parameters: path - the path to decompose.
+** dir - a pointer which will be set to the start of the directory.
+** name - a pointer which will be set to the start of the name.
+** ext - a pointer which will be set to the start of the extension.
+**
+** Returns: NOTHING
+**
+** Constraints: path must use '/' and not '\' as directory separators. The pointers
+** returned in dir, name, and ext are only valid until the next call
+** to util_DecomposePath().
+**
+**---------------------------------------------------------------------------*/
+void util_decomposeFilePath( const char* path, char** dir, char** name, char** ext )
+{
+ static char buffer[ BUFFER_SIZE + 1 ];
+ strncpy( buffer, path, BUFFER_SIZE );
+
+ *ext = strrchr( buffer, '.' );
+ if ( *ext )
+ {
+ /*
+ * Remove the extension by replacing '.' with a NULL character.
+ */
+ **ext = '\0';
+
+ /*
+ * The extension will be in the next position.
+ */
+ (*ext)++;
+ }
+
+ *name = strrchr( buffer, '/' );
+ if ( *name )
+ {
+ /*
+ * Remove the name by replacing the last '/' with a NULL character.
+ */
+ **name = '\0';
+
+ /*
+ * The name will be in the next position.
+ */
+ (*name)++;
+
+ /*
+ * Set dir to the start of the string and we are done.
+ */
+ *dir = buffer;
+ }
+ else
+ {
+ /*
+ * Name must extend to the beginning of the path. Set the name pointer
+ * accordingly and set dir to null.
+ */
+ *name = buffer;
+ *dir = 0;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ d i r n a m e
+**
+** Synopsis: Determine the directory in a file path.
+**
+** Parameters: buffer - buffer to recieve directory.
+** size - size of buffer.
+** path - the path to retrieve the directory from.
+**
+** Returns: non-zero if successful, zero if buffer is too small to receive
+** the directory.
+**
+** Constraints: path must use '/' and not '\' as directory separators.
+**
+**---------------------------------------------------------------------------*/
+int util_dirname( char* buffer, int size, const char* path )
+{
+ char* d;
+ char* n;
+ char* e;
+ int length;
+ int result = 0;
+
+ util_decomposeFilePath( path, &d, &n, &e );
+
+ length = strlen( d );
+ if ( length < size )
+ {
+ strcpy( buffer, d );
+ result = 1;
+ }
+
+ return result;
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ f i l e E x i s t s
+**
+** Synopsis: Determines if the give file exists.
+**
+** Parameters: filename - the name of the file to check for existence.
+**
+** Returns: 0 if file does not exist, non-zero otherwise.
+**
+** Constraints:
+**
+**---------------------------------------------------------------------------*/
+int util_fileExists( const char* filename )
+{
+ FILE *fp;
+
+ assert( filename );
+
+ fp = fopen( filename, "r" );
+
+ if ( fp )
+ {
+ fclose( fp );
+ return 1;
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ g e t o p t _ i n i t
+**
+** Synopsis: Initializes the getopt parser.
+**
+** Parameters: NONE
+**
+** Returns: NOTHING
+**
+** Constraints: NONE
+**
+** Author: Angus Mackay
+**
+**---------------------------------------------------------------------------*/
+void util_getopt_init()
+{
+ util_optind = 1;
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ g e t o p t
+**
+** Synopsis: Used to parse command line arguments based on a specified
+** syntax. The argument for the current option is stored in
+** the global variable "util_optarg".
+**
+** Parameters: argc - the number of arguments in the array.
+** argv - the argumnet array.
+** opts - option specifier string. Options can be of two forms:
+** boolean flags ( its either there or it isn't ) and
+** flag value pairs in which a flag is always followed
+** by some value. Options which require an argument
+** must be followed by a ":" in the option specifier
+** string. So for a command which can have two boolean
+** flags, "h" and "i", and two argument flags, "t" and
+** "u", the following option specifier string would be
+** used: "hit:u:".
+**
+** Returns: the option character found, or -1 if no more option
+** characters.
+**
+** Constraints: NONE
+**
+** Author: Angus Mackay
+**
+**---------------------------------------------------------------------------*/
+int util_getopt( int argc, char* const* argv, const char* opts )
+{
+ static int init_done = 0;
+ static int suboptionpos = 1;
+
+ if(!init_done) { util_getopt_init(); init_done = 1; }
+
+ util_optarg = NULL;
+
+ if(util_optind == argc)
+ {
+ /* we are done */
+ return(-1);
+ }
+
+ if(argv[util_optind][0] == '-')
+ {
+ char *argp;
+
+ /* test for end of arg marker */
+ if(argv[util_optind][1] == '-' && argv[util_optind][2] == '\0')
+ {
+ suboptionpos = 1;
+ util_optind++;
+ return(-1);
+ }
+
+ for(argp=&(argv[util_optind][suboptionpos]); *argp != '\0'; argp++)
+ {
+ char *optp;
+ int numcolon = 0;
+ char *p;
+
+ if((optp=strchr(opts, *argp)) == NULL)
+ {
+ if(util_opterr != 0)
+ {
+ fprintf(stderr, "%s: illegal option -- %c\n", argv[0], *argp);
+ }
+ util_optopt = *argp;
+ suboptionpos++;
+ if(argv[util_optind][suboptionpos] == '\0')
+ {
+ suboptionpos = 1;
+ util_optind++;
+ }
+ return('?');
+ }
+
+ /* zero, one or two colons? */
+ for(p=(optp+1); *p == ':'; p++) { numcolon++; }
+ switch(numcolon)
+ {
+ /* no argument */
+ case 0:
+ suboptionpos++;
+ if(argv[util_optind][suboptionpos] == '\0')
+ {
+ suboptionpos = 1;
+ util_optind++;
+ }
+ return(*optp);
+ break;
+
+ /* manditory argument */
+ case 1:
+ /* the argument is seperated by a space */
+ if(argp[1] == '\0')
+ {
+ /* ther are more args */
+ if(util_optind+1 == argc)
+ {
+ suboptionpos++;
+ if(argv[util_optind][suboptionpos] == '\0')
+ {
+ suboptionpos = 1;
+ util_optind++;
+ }
+ if(util_opterr != 0)
+ {
+ fprintf(stderr, "%s: option requires an argument -- %c\n",
+ argv[0], *argp);
+ }
+ util_optopt = *argp;
+ return('?');
+ }
+
+ util_optind++;
+ suboptionpos = 1;
+ util_optarg = argv[util_optind];
+ util_optind++;
+ return(*optp);
+ }
+
+ /* the argument is attached */
+ util_optarg = argp+1;
+ suboptionpos = 1;
+ util_optind++;
+ return(*optp);
+ break;
+
+ /* optional argument */
+ case 2:
+ /* the argument is seperated by a space */
+ if(argp[1] == '\0')
+ {
+ util_optind++;
+ suboptionpos = 1;
+ util_optarg = NULL;
+ return(*optp);
+ }
+
+ /* the argument is attached */
+ suboptionpos = 1;
+ util_optarg = argp+1;
+ util_optind++;
+ return(*optp);
+ break;
+
+ /* a case of too many colons */
+ default:
+ suboptionpos++;
+ if(argv[util_optind][suboptionpos] == '\0')
+ {
+ suboptionpos = 1;
+ util_optind++;
+ }
+ util_optopt = '?';
+ return('?');
+ break;
+ }
+ }
+ suboptionpos = 1;
+ }
+ else
+ {
+ /* we are done */
+ return(-1);
+ }
+
+ /* we shouldn't get here */
+ return(-1);
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ i n d e x
+**
+** Synopsis: returns a pointer to the first occurrence of the character
+** "c" in the string "s".
+**
+** Parameters: s - the string to search.
+** c - the character to search for.
+**
+** Returns: a pointer to the matched character, or NULL if the character
+** is not found.
+**
+** Constraints: NONE
+**
+**---------------------------------------------------------------------------*/
+const char* util_index( const char* s, int c )
+{
+ const char* result = 0;
+ const char* sp = 0;
+
+ assert( s );
+
+ sp = s;
+
+ while ( *sp != '\0' )
+ {
+ if ( *sp == c )
+ {
+ result = sp;
+ break;
+ }
+
+ sp++;
+ }
+
+ return result;
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ p o s i x F i l e P a t h
+**
+** Synopsis: Ensures the given path uses POSIX style slashes.
+**
+** Parameters: path - the path to "posixfy".
+**
+** Returns: NOTHING
+**
+** Constraints: NONE
+**
+**---------------------------------------------------------------------------*/
+void util_posixFilePath( char* path )
+{
+ char* pp = path;
+ while ( *pp )
+ {
+ if ( '\\' == *pp ) *pp = '/';
+ pp++;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ r e p l a c e C h a r a c t e r s
+**
+** Synopsis: Replace characters in a string.
+**
+** Parameters: find - the character to find.
+** replace - the charcter to replace the found character with.
+** string - the string within which to do the find/replace.
+**
+** Returns: NOTHING
+**
+** Constraints: NONE
+**
+**---------------------------------------------------------------------------*/
+void util_replaceCharacters( char find, char replace, char* string )
+{
+ char* p = 0;
+
+ if ( string )
+ {
+ while ( p = strchr( string, find ) )
+ {
+ *p = replace;
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ r e v e r s e S p a n
+**
+** Synopsis: Finds the suffix which is composed completely of characters in
+** in the spanSet in the specified string.
+**
+** Example: end = util_ReverseSpan( "name123", "312" );
+** *
+** * end now points to "123".
+** *
+** end = util_ReverseSpan( "name123", "21" );
+** *
+** * end would point to NULL because the character "3" is not
+** * in the spanSet.
+**
+** Parameters: string - the string to be searched.
+** spanSet - a string of characters that can be in the suffix.
+**
+** Returns: a pointer to the suffix string, or NULL if there is no
+** suffix.
+**
+** Constraints: NONE
+**
+**---------------------------------------------------------------------------*/
+const char* util_reverseSpan( const char* string, const char* spanSet )
+{
+ const char* sp = 0;
+ const char* next_sp = 0;
+ int isEndSpan = 0;
+
+ /*
+ * Set a pointer to the end of the string to be searched.
+ */
+ sp = string + strlen( string );
+
+ /*
+ * If the string passed in is empty, we are done.
+ */
+ if ( sp == string ) return sp;
+
+ while( sp > string && !isEndSpan )
+ {
+ next_sp = sp - 1;
+
+ if ( strchr( spanSet, *next_sp ) )
+ {
+ sp--;
+ }
+ else
+ {
+ isEndSpan = 1;
+ }
+ }
+
+ return sp;
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ r i n d e x
+**
+** Synopsis: returns a pointer to the last occurrence of the character
+** "c" in the string "s".
+**
+** Parameters: s - the string to search.
+** c - the character to search for.
+**
+** Returns: a pointer to the matched character, or NULL if the character
+** is not found.
+**
+** Constraints: NONE
+**
+**---------------------------------------------------------------------------*/
+const char* util_rindex( const char* s, int c )
+{
+ const char* result = 0;
+ const char* sp = 0;
+ int length;
+
+ assert( s );
+
+ length = strlen(s);
+ sp = s + length;
+
+ if ( length > 0 )
+ {
+ while ( sp != s )
+ {
+ sp--;
+
+ if ( *sp == c )
+ {
+ result = sp;
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+/*-----------------------------------------------------------------------------
+** u t i l _ s u b s t i t u t e
+**
+** Synopsis: Substitue strings matchin "find" with "replace" in "string".
+** If this cannot be done without exceeding the size of "string"
+** An error will be returned and "string" will be as it was
+** when util_substitute was originally called.
+**
+** Parameters: find - the substring to find.
+** replace - the substring to insert in place of found strings.
+** string - the string to operate on.
+** stringSize - the maximum size the string can grow to.
+** firstOnly - flag. If non-zero only the first occurence of
+** "find" will be replaced. If zero, all occurences
+** will be replaced.
+**
+** Returns: 0 on error, the new size of the string on success.
+**
+** Constraints: NONE
+**
+**---------------------------------------------------------------------------*/
+int util_substitute( const char* find,
+ const char* replace,
+ char* string,
+ int stringSize,
+ int firstOnly
+ )
+{
+ char buffer[ BUFFER_SIZE + 1 ];
+ char* sp;
+ char* bp;
+ char* p;
+ int findLength = strlen( find );
+ int replaceLength = strlen( replace );
+ int count = 0;
+ int total = 0;
+ int tooBig = 0;
+ int status = 0;
+
+ assert( stringSize <= BUFFER_SIZE );
+
+ bp = buffer;
+ sp = string;
+ while( !tooBig && (p = strstr( sp, find )) )
+ {
+ /*
+ * Determine the number of characters since last find.
+ * Add to total characters.
+ * If total characters exceeds "stringSize" then break and return
+ * error. Otherwise copy characters since last find to buffer.
+ */
+ count = p - sp;
+ total += count;
+ if ( total >= stringSize )
+ {
+ tooBig = 1;
+ continue;
+ }
+ strncpy( bp, sp, count );
+ bp += count;
+ *bp = '\0';
+
+ /*
+ * If adding the replace string causes buffer to exceed "stringSize"
+ * break and return error. Otherwise copy the replace string into
+ * buffer.
+ */
+ total += replaceLength;
+ if ( total >= stringSize )
+ {
+ tooBig = 1;
+ continue;
+ }
+ strcpy( bp, replace );
+ bp += replaceLength;
+
+ /*
+ * Update the position of sp so that it points to next character
+ * after the last found "find" string.
+ */
+ sp += count + findLength;
+ }
+
+ if ( !tooBig )
+ {
+ /*
+ * Attempt to copy the remaining portion of string into buffer.
+ * If successful, copy buffer into string and return success.
+ * Otherwise return error.
+ */
+ total += strlen( sp );
+ if ( total < stringSize )
+ {
+ strcpy( bp, sp );
+ strcpy( string, buffer );
+ status = strlen( string );
+ }
+ }
+
+ return status;
+}
+