Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
mac_xpt_linker.cpp File Reference
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include <Files.h>
#include <Strings.h>
#include <Aliases.h>
#include <Resources.h>
#include "DropInCompilerLinker.h"
#include "CompilerMapping.h"
#include "CWPluginErrors.h"
#include "mac_xpidl_panel.h"
#include "mac_console.h"
#include "mac_strings.h"
#include "FullPath.h"
#include "MoreFilesExtras.h"

Go to the source code of this file.

Defines

#define kDebuggerCreator   'MWDB'

Functions

static CWResult Link (CWPluginContext context)
static CWResult Disassemble (CWPluginContext context)
static CWResult GetTargetInfo (CWPluginContext context)
pascal short xpt_linker (CWPluginContext context)
int xptlink_main (int argc, char *argv[])
int xptdump_main (int argc, char *argv[])
FILEFSp_fopen (ConstFSSpecPtr spec, const char *open_mode)
size_t mac_get_file_length (const char *filename)
 Returns the length of a file, assuming it is always located in the project's object code directory.
static char * full_path_to (const FSSpec &file)
static char * full_path_to (short vRefNum, long dirID)
 Provides the full path name to a given directory.
static CWResult GetSettings (CWPluginContext context, XPIDLSettings &settings)
static CWResult LinkHeaders (CWPluginContext context, XPIDLSettings &settings)
static CWResult LinkTypeLib (CWPluginContext context, XPIDLSettings &settings)

Variables

jmp_buf exit_jump
int exit_status
CWPluginContext gPluginContext
static CWFileSpec gOutputDirectory
static CWFileSpec gObjectCodeDirectory

Define Documentation

#define kDebuggerCreator   'MWDB'

Definition at line 69 of file mac_xpt_linker.cpp.


Function Documentation

static CWResult Disassemble ( CWPluginContext  context) [static]

Definition at line 353 of file mac_xpt_linker.cpp.

{
       CWResult err = noErr;

       // cache the project's output directory.
       err = CWGetOutputFileDirectory(gPluginContext, &gOutputDirectory);
       if (!CWSUCCESS(err))
              return err;

       long fileNum;
       err = CWGetMainFileNumber(context, &fileNum);
       if (!CWSUCCESS(err))
              return err;

       // get the output file's location from the stored object data.
       err = CWGetStoredObjectFileSpec(context, fileNum, &gObjectCodeDirectory);
       if (!CWSUCCESS(err))
              return err;
       
       char* outputName = p2c_strdup(gObjectCodeDirectory.name);
       if (outputName == NULL)
              return cwErrOutOfMemory;

       XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeTypelib, false, false };
       GetSettings(context, settings);

       // build an argument list and call xpt_dump.
       int argc = 1;
       char* argv[] = { "xpt_dump", NULL, NULL, NULL };
       if (settings.verbose) argv[argc++] = "-v";
       argv[argc++] = outputName;
       
       // trap calls to exit, which longjmp back to here.
       if (setjmp(exit_jump) == 0) {
              if (xptdump_main(argc, argv) != 0)
                     err = cwErrRequestFailed;
       } else {
              // evidently the good old exit function got called.
              if (exit_status != 0)
                     err = cwErrRequestFailed;
       }

       delete[] outputName;

       if (err == noErr) {
              // display the disassembly in its own fresh text window.
              CWNewTextDocumentInfo info = {
                     NULL,
                     mac_console_handle,
                     false
              };
              CWResizeMemHandle(context, mac_console_handle, mac_console_count);
              err = CWCreateNewTextDocument(context, &info);
       }

       return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

FILE* FSp_fopen ( ConstFSSpecPtr  spec,
const char *  open_mode 
)
static char* full_path_to ( const FSSpec file) [static]

Definition at line 145 of file mac_xpt_linker.cpp.

{
       short len = 0;
       Handle fullPath = NULL;
       if (FSpGetFullPath(&file, &len, &fullPath) == noErr && fullPath != NULL) {
              char* path = new char[1 + len];
              if (path != NULL) {
                     BlockMoveData(*fullPath, path, len);
                     path[len] = '\0';
              }
              DisposeHandle(fullPath);
              return path;
       }
       return NULL;
}
static char* full_path_to ( short  vRefNum,
long  dirID 
) [static]

Provides the full path name to a given directory.

Definition at line 164 of file mac_xpt_linker.cpp.

{
       long parID;
       if (GetParentID(vRefNum, dirID, NULL, &parID) == noErr) {
              FSSpec dirSpec = { vRefNum, parID };
              if (GetDirName(vRefNum, dirID, dirSpec.name) == noErr) {
                     return full_path_to(dirSpec);
              }
       }
       return NULL;
}

Here is the call graph for this function:

static CWResult GetSettings ( CWPluginContext  context,
XPIDLSettings settings 
) [static]

Definition at line 202 of file mac_xpt_linker.cpp.

{
       CWMemHandle   settingsHand;
       CWResult err = CWGetNamedPreferences(context, kXPIDLPanelName, &settingsHand);
       if (!CWSUCCESS(err))
              return err;
       
       XPIDLSettings* settingsPtr = NULL;
       err = CWLockMemHandle(context, settingsHand, false, (void**)&settingsPtr);
       if (!CWSUCCESS(err))
              return err;
       
       settings = *settingsPtr;
       
       err = CWUnlockMemHandle(context, settingsHand);
       if (!CWSUCCESS(err))
              return err;

       return cwNoErr;
}

Here is the caller graph for this function:

static CWResult GetTargetInfo ( CWPluginContext  context) [static]

Definition at line 411 of file mac_xpt_linker.cpp.

{
       CWTargetInfo targ;
       memset(&targ, 0, sizeof(targ));
       
       CWResult err = CWGetOutputFileDirectory(context, &targ.outfile);
       targ.outputType = linkOutputFile;
       targ.symfile = targ.outfile;       /* location of SYM file */
       targ.linkType = exelinkageFlat;
       targ.targetCPU = '****';
       targ.targetOS = '****';
       
       // load the relevant settings.
       XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeTypelib, false, false };
       err = GetSettings(context, settings);
       if (err != cwNoErr)
              return err;
       
#if CWPLUGIN_HOST == CWPLUGIN_HOST_MACOS
       // tell the IDE about the output file.
       targ.outfileCreator         = 'MMCH';
       targ.outfileType            = 'CWIE';
       targ.debuggerCreator = kDebuggerCreator;  /* so IDE can locate our debugger  */

       BlockMoveData(settings.output, targ.outfile.name, 1 + settings.output[0]);
       targ.symfile.name[0] = 0;
#endif

#if CWPLUGIN_HOST == CWPLUGIN_HOST_WIN32
       targ.debugHelperIsRegKey = true;
       *(long*)targ.debugHelperName = kDebuggerCreator;
       targ.debugHelperName[4] = 0;
       strcat(targ.outfile.path, "\\");
       strcat(targ.outfile.path, prefsData.outfile);
       strcpy(targ.symfile.path, targ.outfile.path);
       strcat(targ.symfile.path, ".SYM");
#endif

       targ.runfile                = targ.outfile;
       targ.linkAgainstFile = targ.outfile;

       /* we can only run applications */
       // targ.canRun = (prefsData.projtype == kProjTypeApplication);
       
       /* we can only debug if we have a SYM file */
       // targ.canDebug = prefsData.linksym;     
       
       err = CWSetTargetInfo(context, &targ);
       
       return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CWResult Link ( CWPluginContext  context) [static]

Definition at line 335 of file mac_xpt_linker.cpp.

{
       // load the relevant prefs.
       XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeTypelib, false, false };
       CWResult err = GetSettings(context, settings);
       if (err != cwNoErr)
              return err;

       switch (settings.mode) {
       case kXPIDLModeHeader:
              return LinkHeaders(context, settings);
       case kXPIDLModeTypelib:
              return LinkTypeLib(context, settings);
       default:
              return cwNoErr;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CWResult LinkHeaders ( CWPluginContext  context,
XPIDLSettings settings 
) [static]

Definition at line 223 of file mac_xpt_linker.cpp.

{
       // find out how many files there are to link.
       long fileCount = 0;
       CWResult err = CWGetProjectFileCount(context, &fileCount);
       if (err != cwNoErr || fileCount == 0)
              return err;

       // get the output directory.
       FSSpec outputDir;
       err = CWGetOutputFileDirectory(context, &outputDir);
       if (!CWSUCCESS(err))
              return err;
       
       // enumerate all of the output header files, and make aliases to them in
       // the output directory.
       for (long index = 0; (err == cwNoErr) && (index < fileCount); index++) {
              // get the name of each output file.
              CWFileSpec outputFile;
              err = CWGetStoredObjectFileSpec(context, index, &outputFile);
              if (err == cwNoErr) {
                     FInfo info;
                     err = FSpGetFInfo(&outputFile, &info);
                     
                     FSSpec aliasFile = { outputDir.vRefNum, outputDir.parID };
                     BlockMoveData(outputFile.name, aliasFile.name, 1 + outputFile.name[0]);
                     
                     AliasHandle alias = NULL;
                     if (NewAliasMinimal(&outputFile, &alias) == noErr) {
                            // recreate the alias file from scratch.
                            FSpDelete(&aliasFile);
                            FSpCreateResFile(&aliasFile, info.fdCreator, info.fdType, smRoman);
                            short refNum = FSpOpenResFile(&aliasFile, fsRdWrPerm);
                            if (refNum != -1) {
                                   UseResFile(refNum);
                                   AddResource(Handle(alias), rAliasType, 0, aliasFile.name);
                                   ReleaseResource(Handle(alias));
                                   UpdateResFile(refNum);
                                   CloseResFile(refNum);
                            }
                            // finally, mark the newly created file as an alias file.
                            FSpGetFInfo(&aliasFile, &info);
                            info.fdFlags |= kIsAlias;
                            FSpSetFInfo(&aliasFile, &info);
                     }
              }
       }
       
       // create the target file in the output directory.
       BlockMoveData(settings.output, outputDir.name, 1 + settings.output[0]);
       FILE* outputFile = FSp_fopen(&outputDir, "w");
       if (outputFile != NULL) fclose(outputFile);

       return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CWResult LinkTypeLib ( CWPluginContext  context,
XPIDLSettings settings 
) [static]

Definition at line 279 of file mac_xpt_linker.cpp.

{
       // find out how many files there are to link.
       long fileCount = 0;
       CWResult err = CWGetProjectFileCount(context, &fileCount);
       if (err != cwNoErr || fileCount == 0)
              return err;

       // assemble the argument list.
       // { "xpt_link", outputFile, inputFile1, ..., inputFileN, NULL }
       char** argv = new char*[2 + fileCount + 1];
       int argc = 0;
       argv[argc++] = "xpt_link";

       // get the output directory.
       err = CWGetOutputFileDirectory(context, &gOutputDirectory);
       if (!CWSUCCESS(err))
              return err;
       
       // get the object code directory.
       err = CWGetStoredObjectFileSpec(context, 0, &gObjectCodeDirectory);
       if (!CWSUCCESS(err))
              return err;

       // push the output file name.
       if ((argv[argc++] = p2c_strdup(settings.output)) == NULL)
              return cwErrOutOfMemory;

       for (long index = 0; (err == cwNoErr) && (index < fileCount); index++) {
              // get the name of each output file.
              CWFileSpec outputFile;
              err = CWGetStoredObjectFileSpec(context, index, &outputFile);
              if (err == cwNoErr) {
                     if ((argv[argc++] = p2c_strdup(outputFile.name)) == NULL) {
                            err = cwErrOutOfMemory;
                            break;
                     }
              }
       }
       
       if (err != cwNoErr)
              return err;
       
       // trap calls to exit, which longjmp back to here.
       if (setjmp(exit_jump) == 0) {
              if (xptlink_main(argc, argv) != 0)
                     err = cwErrRequestFailed;
       } else {
              // evidently the good old exit function got called.
              if (exit_status != 0)
                     err = cwErrRequestFailed;
       }
       
       return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t mac_get_file_length ( const char *  filename)

Returns the length of a file, assuming it is always located in the project's object code directory.

Returns the length of a file, assuming it is always located in the project's output directory.

Definition at line 321 of file mac_xpidl.cpp.

{
       long dataSize= 0, rsrcSize = 0;
       FSSpec filespec;
       if (CWGetOutputFileDirectory(gPluginContext, &filespec) != noErr)
              return 0;
       c2p_strcpy(filespec.name, filename);
       if (FSpGetFileSize(&filespec, &dataSize, &rsrcSize) != noErr)
              return 0;
       return dataSize;
}

Here is the call graph for this function:

pascal short xpt_linker ( CWPluginContext  context)

Definition at line 100 of file mac_xpt_linker.cpp.

{
       long request;
       if (CWGetPluginRequest(context, &request) != cwNoErr)
              return cwErrRequestFailed;
       
       gPluginContext = context;
       short result = cwNoErr;
              
       /* dispatch on linker request */
       switch (request) {
       case reqInitLinker:
              /* linker has just been loaded into memory */
              break;
              
       case reqTermLinker:
              /* linker is about to be unloaded from memory */
              break;
              
       case reqLink:
              /* build the final executable */
              result = Link(context);
              break;
              
       case reqDisassemble:
              /* disassemble object code for a given project file */
              result = Disassemble(context);
              break;
       
       case reqTargetInfo:
              /* return info describing target characteristics */
              result = GetTargetInfo(context);
              break;
              
       default:
              result = cwErrRequestFailed;
              break;
       }
       
       result = CWDonePluginRequest(context, result);
       
       /* return result code */
       return result;
}

Here is the call graph for this function:

int xptdump_main ( int  argc,
char *  argv[] 
)
int xptlink_main ( int  argc,
char *  argv[] 
)

Here is the caller graph for this function:


Variable Documentation

jmp_buf exit_jump

Definition at line 51 of file mac_stdlib.cpp.

Definition at line 52 of file mac_stdlib.cpp.

CWFileSpec gObjectCodeDirectory [static]

Definition at line 94 of file mac_xpt_linker.cpp.

CWFileSpec gOutputDirectory [static]

Definition at line 93 of file mac_xpt_linker.cpp.

CWPluginContext gPluginContext

Definition at line 90 of file mac_xpt_linker.cpp.