8d6f6463d2
X-SVN-Rev: 5009
221 lines
5.8 KiB
C++
221 lines
5.8 KiB
C++
/**
|
|
* File: mac_utils.cpp
|
|
*
|
|
* Routines
|
|
* --------
|
|
*
|
|
* get_path_string
|
|
* FSpGetFileSize
|
|
* p2c_strdup
|
|
* exit
|
|
*
|
|
* Description
|
|
* -----------
|
|
*
|
|
* Contains functions needed for Macintosh versions of command-line compilers
|
|
*
|
|
* Authors
|
|
* -------
|
|
*
|
|
* Sean K. Todd (stodd@broadjump.com)
|
|
* Marty Saxton (msaxton@broadjump.com)
|
|
*/
|
|
|
|
#include "mac_utils.h"
|
|
|
|
// icu headers
|
|
#include "cmemory.h"
|
|
#include "utypes.h"
|
|
|
|
// msl headers
|
|
#include <string>
|
|
|
|
|
|
extern "C" pascal OSErr FSpGetFullPath( const FSSpec *spec, short *fullPathLength, Handle *fullPath);
|
|
|
|
CWFileSpec gOutputFile;
|
|
CWFileSpec gSourceFile;
|
|
char* gDestPath = NULL;
|
|
char* gSourceFileName = NULL;
|
|
|
|
/**
|
|
* get_path_string
|
|
*
|
|
* Creates a string with the full path (with or without the file name) from
|
|
* a FSSpec. Command-line tools expect full paths but Macs deal with files
|
|
* via filespecs. The limitation to using full paths is that it is possible
|
|
* to have two mounted volumes with the same name on a Mac. Filespecs can
|
|
* distinguish between the two (by using volume reference numbers) but full
|
|
* paths cannot.
|
|
*
|
|
*/
|
|
|
|
void get_path_string( char** oPath,
|
|
char oPathBuffer[],
|
|
CWFileSpec* iFileSpec,
|
|
bool doTruncate
|
|
)
|
|
{
|
|
Handle theHandle = 0;
|
|
short len = 0;
|
|
|
|
OSErr theErr = FSpGetFullPath( iFileSpec, &len, &theHandle );
|
|
|
|
if ( theHandle && !theErr) {
|
|
|
|
::HLock( theHandle);
|
|
|
|
uprv_memcpy( oPathBuffer, ( static_cast< char*>( *theHandle)), len);
|
|
oPathBuffer[ len ] = 0;
|
|
*oPath = oPathBuffer;
|
|
|
|
::DisposeHandle( theHandle);
|
|
theHandle = 0;
|
|
|
|
if ( doTruncate) {
|
|
// truncate file name from full path string
|
|
std::string str = *oPath;
|
|
str = str.substr( 0, str.find_last_of( ":" ) + 1);
|
|
std::strcpy( *oPath, str.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* FSpGetFileSize
|
|
*
|
|
* This function code was derived from code in MoreFilesExtras.h which is part
|
|
* of 'MoreFiles' (Apple Sample Code).
|
|
*
|
|
*/
|
|
|
|
pascal OSErr FSpGetFileSize( const FSSpec* spec, long* dataSize, long* rsrcSize)
|
|
{
|
|
HParamBlockRec pb;
|
|
|
|
pb.fileParam.ioNamePtr = const_cast< StringPtr>( spec->name);
|
|
pb.fileParam.ioVRefNum = spec->vRefNum;
|
|
pb.fileParam.ioFVersNum = 0;
|
|
pb.fileParam.ioDirID = spec->parID;
|
|
pb.fileParam.ioFDirIndex = 0;
|
|
|
|
OSErr error = PBHGetFInfoSync( &pb);
|
|
|
|
if ( noErr == error ) {
|
|
*dataSize = pb.fileParam.ioFlLgLen;
|
|
*rsrcSize = pb.fileParam.ioFlRLgLen;
|
|
}
|
|
|
|
return ( error );
|
|
}
|
|
|
|
/**
|
|
* p2c_strdup
|
|
*
|
|
* Creates a duplicate c string from a pascal string.
|
|
*
|
|
* NOTE: The user is responsible for calling delete[]
|
|
* when he/she is finished using the string in
|
|
* order to prevent a memory leak.
|
|
*
|
|
*/
|
|
|
|
char* p2c_strdup( StringPtr pstr)
|
|
{
|
|
size_t len = pstr[0];
|
|
char* cstr = new char[1 + len];
|
|
|
|
if ( cstr != NULL) {
|
|
::BlockMoveData( pstr + 1, cstr, len);
|
|
cstr[len] = '\0';
|
|
}
|
|
return cstr;
|
|
}
|
|
|
|
/**
|
|
* exit
|
|
*
|
|
* simply throw us out of here!
|
|
*/
|
|
|
|
jmp_buf exit_jump;
|
|
int exit_status = 0;
|
|
|
|
void std::exit( int status)
|
|
{
|
|
exit_status = status;
|
|
longjmp( exit_jump, -1);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*
|
|
StringPtr c2p_strcpy( StringPtr pstr, const char* cstr)
|
|
{
|
|
size_t len = ::strlen(cstr);
|
|
if (len > 255) len = 255;
|
|
BlockMoveData(cstr, pstr + 1, len);
|
|
pstr[0] = len;
|
|
return pstr;
|
|
}
|
|
*/
|
|
/*****************************************************************************/
|
|
/*
|
|
CWResult LocateFile(CWPluginContext context, const char* filename, FSSpec& file)
|
|
{
|
|
// prefill the CWFileInfo struct
|
|
CWFileInfo fileinfo;
|
|
BlockZero(&fileinfo, sizeof(fileinfo));
|
|
// memset(&fileinfo, 0, sizeof(fileinfo));
|
|
fileinfo.fullsearch = true;
|
|
fileinfo.suppressload = true;
|
|
fileinfo.dependencyType = cwNormalDependency;
|
|
fileinfo.isdependentoffile = kCurrentCompiledFile;
|
|
|
|
// locate the file name using the project's access paths
|
|
CWResult err = CWFindAndLoadFile(context, filename, &fileinfo);
|
|
if (err == cwNoErr) {
|
|
file = fileinfo.filespec;
|
|
} else if (err == cwErrFileNotFound) {
|
|
char errmsg[200];
|
|
sprintf(errmsg, "Can't locate file \"%s\".", filename);
|
|
CWResult callbackResult = CWReportMessage(context, 0, errmsg, 0, messagetypeError, 0);
|
|
}
|
|
|
|
return (err);
|
|
}
|
|
*/
|
|
/**
|
|
* Substitute for standard fopen, treats certain filenames specially,
|
|
* and also considers the mode argument. If a file is being opened
|
|
* for reading, the file is assumed to be locateable using CodeWarrior's
|
|
* standard access paths. If it's for writing, the file is opened in
|
|
* the current project's output directory.
|
|
*/
|
|
/*
|
|
extern "C" FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
|
|
|
|
|
|
FILE* std::fopen(const char* filename, const char *mode)
|
|
{
|
|
FSSpec filespec;
|
|
CWResult err = noErr;
|
|
do {
|
|
if (filename == gSourcePath || strcmp(filename, gSourcePath) == 0) {
|
|
// opening the main source file.
|
|
filespec = gSourceFile;
|
|
} else if (mode[0] == 'w') {
|
|
// if an output file, open it in the current compilation's output directory.
|
|
c2p_strcpy(filespec.name, filename);
|
|
filespec.vRefNum = gOutputFile.vRefNum;
|
|
filespec.parID = gOutputFile.parID;
|
|
c2p_strcpy(gOutputFile.name, filename);
|
|
} else {
|
|
// an input file, use CodeWarrior's search paths to find the named source file.
|
|
// err = LocateFile(gPluginContext, filename, filespec);
|
|
}
|
|
} while (0);
|
|
// if all went well, we have a file to open.
|
|
return (err == noErr ? FSp_fopen(&filespec, mode) : NULL);
|
|
}
|
|
*/ |