428 lines
7.3 KiB
C++
428 lines
7.3 KiB
C++
/*
|
|
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 <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <time.h>
|
|
|
|
#ifdef WIN32
|
|
#include <direct.h>
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#if defined ( __linux__ ) || defined ( __APPLE__ )
|
|
#include <unistd.h>
|
|
#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
|
|
}
|