blob: 101bde62a46cbdcb1f14d6f39dd7fd1a1617054a [file] [log] [blame]
/**
* 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);
}
*/