/* Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // cmdlib.c // TTimo 09/30/2000 // from an initial copy of common/cmdlib.c // stripped out the Sys_Printf Sys_Printf stuff // SPoG 05/27/2001 // merging alpha branch into trunk // replaced qprintf with Sys_Printf #include "cmdlib.h" #include "inout.h" #include "qstringops.h" #include "qpathops.h" #include "stream/stringstream.h" #include "stream/textstream.h" #include #include #include #include #ifdef WIN32 #include #include #endif #if defined ( __linux__ ) || defined ( __APPLE__ ) #include #endif void_ptr safe_malloc( size_t size ){ void *p = malloc( size ); if ( !p ) { Error( "safe_malloc failed on allocation of %zu bytes", size ); } return p; } void_ptr safe_calloc( size_t size ){ void *p = calloc( 1, size ); if ( !p ) { Error( "safe_calloc failed on allocation of %zu bytes", size ); } return p; } char *ExpandArg( const char *path ){ static char full[1024]; if ( path_is_absolute( path ) ) { strcpy( full, path ); } else{ Q_getwd( full ); strcat( full, path ); } return full; } /* ================ I_FloatTime ================ */ double I_FloatTime( void ){ time_t t; time( &t ); return t; #if 0 // more precise, less portable struct timeval tp; struct timezone tzp; static int secbase; gettimeofday( &tp, &tzp ); if ( !secbase ) { secbase = tp.tv_sec; return tp.tv_usec / 1000000.0; } return ( tp.tv_sec - secbase ) + tp.tv_usec / 1000000.0; #endif } void Q_getwd( char *out ){ #ifdef WIN32 _getcwd( out, 256 ); #else // Gef: Changed from getwd() to getcwd() to avoid potential buffer overflow if ( !getcwd( out, 256 ) ) { strClear( out ); } #endif path_add_slash( out ); FixDOSName( out ); } void Q_mkdir( const char *path ){ char parentbuf[256]; const char *p = NULL; int retry = 2; while ( retry-- ) { #ifdef WIN32 if ( _mkdir( path ) != -1 ) { return; } #else if ( mkdir( path, 0777 ) != -1 ) { return; } #endif if ( errno == ENOENT ) { p = path_get_last_separator( path ); } if ( !strEmptyOrNull( p ) ) { strcpyQ( parentbuf, path, p - path + 1 ); if ( ( p - path ) < (ptrdiff_t) sizeof( parentbuf ) ) { Sys_Printf( "mkdir: %s: creating parent %s first\n", path, parentbuf ); Q_mkdir( parentbuf ); continue; } } break; } if ( errno != EEXIST ) { Error( "mkdir %s: %s", path, strerror( errno ) ); } } /* ============================================================================= MISC FUNCTIONS ============================================================================= */ /* ================ Q_filelength ================ */ int Q_filelength( FILE *f ){ int pos; int end; pos = ftell( f ); fseek( f, 0, SEEK_END ); end = ftell( f ); fseek( f, pos, SEEK_SET ); return end; } FILE *SafeOpenWrite( const char *filename, const char *mode ){ FILE *f = fopen( filename, mode ); if ( !f ) { Error( "Error opening %s: %s", filename, strerror( errno ) ); } return f; } FILE *SafeOpenRead( const char *filename, const char *mode ){ FILE *f = fopen( filename, mode ); if ( !f ) { Error( "Error opening %s: %s", filename, strerror( errno ) ); } return f; } void SafeRead( FILE *f, void *buffer, int count ){ if ( fread( buffer, 1, count, f ) != (size_t)count ) { Error( "File read failure" ); } } void SafeWrite( FILE *f, const void *buffer, int count ){ if ( buffer != NULL && fwrite( buffer, 1, count, f ) != (size_t)count ) { Error( "File write failure" ); } } /* ============== FileExists ============== */ bool FileExists( const char *filename ){ FILE *f; f = fopen( filename, "r" ); if ( !f ) { return false; } fclose( f ); return true; } /* ============== LoadFile ============== */ int LoadFile( const char *filename, void **bufferptr ){ FILE *f; int length; void *buffer; f = SafeOpenRead( filename ); length = Q_filelength( f ); buffer = safe_malloc( length + 1 ); ( (char *)buffer )[length] = 0; SafeRead( f, buffer, length ); fclose( f ); *bufferptr = buffer; return length; } /* ============== TryLoadFile Allows failure ============== */ int TryLoadFile( const char *filename, void **bufferptr ){ FILE *f; int length; void *buffer; *bufferptr = NULL; f = fopen( filename, "rb" ); if ( !f ) { return -1; } length = Q_filelength( f ); buffer = safe_malloc( length + 1 ); ( (char *)buffer )[length] = 0; SafeRead( f, buffer, length ); fclose( f ); *bufferptr = buffer; return length; } /* ============== SaveFile ============== */ void SaveFile( const char *filename, const void *buffer, int count ){ FILE *f; f = SafeOpenWrite( filename ); SafeWrite( f, buffer, count ); fclose( f ); } /* ============================================================================ BYTE ORDER FUNCTIONS ============================================================================ */ #ifdef _SGI_SOURCE #define __BIG_ENDIAN__ #endif #ifdef __BIG_ENDIAN__ short LittleShort( short l ){ byte b1,b2; b1 = l & 255; b2 = ( l >> 8 ) & 255; return ( b1 << 8 ) + b2; } short BigShort( short l ){ return l; } int LittleLong( int l ){ byte b1,b2,b3,b4; b1 = l & 255; b2 = ( l >> 8 ) & 255; b3 = ( l >> 16 ) & 255; b4 = ( l >> 24 ) & 255; return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; } int BigLong( int l ){ return l; } float LittleFloat( float l ){ union {byte b[4]; float f; } in, out; in.f = l; out.b[0] = in.b[3]; out.b[1] = in.b[2]; out.b[2] = in.b[1]; out.b[3] = in.b[0]; return out.f; } float BigFloat( float l ){ return l; } #else short BigShort( short l ){ byte b1,b2; b1 = l & 255; b2 = ( l >> 8 ) & 255; return ( b1 << 8 ) + b2; } short LittleShort( short l ){ return l; } int BigLong( int l ){ byte b1,b2,b3,b4; b1 = l & 255; b2 = ( l >> 8 ) & 255; b3 = ( l >> 16 ) & 255; b4 = ( l >> 24 ) & 255; return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; } int LittleLong( int l ){ return l; } float BigFloat( float l ){ union {byte b[4]; float f; } in, out; in.f = l; out.b[0] = in.b[3]; out.b[1] = in.b[2]; out.b[2] = in.b[1]; out.b[3] = in.b[0]; return out.f; } float LittleFloat( float l ){ return l; } #endif //======================================================= void Sys_Sleep( int n ){ #ifdef WIN32 Sleep( n ); #endif #if defined ( __linux__ ) || defined ( __APPLE__ ) usleep( n * 1000 ); #endif }