First Checked In.

This commit is contained in:
beard%netscape.com 1999-05-06 14:39:20 +00:00
parent 3218ac0e70
commit db2e9da53f
30 changed files with 4590 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,103 @@
#include "mac_console.h"
#ifndef __CONSOLE__
#include <console.h>
#endif
extern CWPluginContext gPluginContext;
UInt32 mac_console_count = 0;
CWMemHandle mac_console_handle = NULL;
/*
* The following four functions provide the UI for the console package.
* Users wishing to replace SIOUX with their own console package need
* only provide the four functions below in a library.
*/
/*
* extern short InstallConsole(short fd);
*
* Installs the Console package, this function will be called right
* before any read or write to one of the standard streams.
*
* short fd: The stream which we are reading/writing to/from.
* returns short: 0 no error occurred, anything else error.
*/
short InstallConsole(short fd)
{
#pragma unused (fd)
mac_console_count = 0;
CWAllocMemHandle(gPluginContext, 8192, false, &mac_console_handle);
return 0;
}
/*
* extern void RemoveConsole(void);
*
* Removes the console package. It is called after all other streams
* are closed and exit functions (installed by either atexit or _atexit)
* have been called. Since there is no way to recover from an error,
* this function doesn't need to return any.
*/
void RemoveConsole(void)
{
if (mac_console_handle != NULL) {
CWFreeMemHandle(gPluginContext, mac_console_handle);
mac_console_handle = NULL;
}
}
/*
* extern long WriteCharsToConsole(char *buffer, long n);
*
* Writes a stream of output to the Console window. This function is
* called by write.
*
* char *buffer: Pointer to the buffer to be written.
* long n: The length of the buffer to be written.
* returns short: Actual number of characters written to the stream,
* -1 if an error occurred.
*/
long WriteCharsToConsole(char *buffer, long n)
{
long size = 0;
char* ptr = NULL;
if (CWGetMemHandleSize(gPluginContext, mac_console_handle, &size) == noErr) {
if (mac_console_count + n >= size) {
size += 8192;
if (CWResizeMemHandle(gPluginContext, mac_console_handle, size) != noErr)
return -1;
}
}
if (CWLockMemHandle(gPluginContext, mac_console_handle, false, &ptr) == noErr) {
BlockMoveData(buffer, ptr + mac_console_count, n);
mac_console_count += n;
CWUnlockMemHandle(gPluginContext, mac_console_handle);
}
return 0;
}
/*
* extern long ReadCharsFromConsole(char *buffer, long n);
*
* Reads from the Console into a buffer. This function is called by
* read.
*
* char *buffer: Pointer to the buffer which will recieve the input.
* long n: The maximum amount of characters to be read (size of
* buffer).
* returns short: Actual number of characters read from the stream,
* -1 if an error occurred.
*/
long ReadCharsFromConsole(char *buffer, long n)
{
return 0;
}

View File

@ -0,0 +1,30 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
mac_console.h
*/
#pragma once
#include <Files.h>
#include <Memory.h>
#include "CWPlugins.h"
extern UInt32 mac_console_count;
extern CWMemHandle mac_console_handle;

View File

@ -0,0 +1,110 @@
/*
mac_memory.cpp
*/
#include <new.h>
#include <stdlib.h>
#include <Files.h>
#include <Memory.h>
#include "DropInCompilerLinker.h"
#include "CompilerMapping.h"
#include "CWPluginErrors.h"
extern CWPluginContext gPluginContext;
/**
* Note: memory allocated by these operators will automatically be freed after the
* current call into xpidl_compiler completes. This should be fine in most cases,
* as we are also having the compiler be reloaded for every request to reinitialize
* global data. Just be careful out there!
*/
const bool kTemporaryAllocation = false;
void* operator new(size_t size)
{
void* ptr = NULL;
if (CWAllocateMemory(gPluginContext, size, kTemporaryAllocation, &ptr) == cwNoErr)
return ptr;
return NULL;
}
void operator delete(void* ptr)
{
if (ptr != NULL)
CWFreeMemory(gPluginContext, ptr, kTemporaryAllocation);
}
void* operator new[] (size_t size)
{
void* ptr = NULL;
if (CWAllocateMemory(gPluginContext, size, kTemporaryAllocation, &ptr) == cwNoErr)
return ptr;
return NULL;
}
void operator delete[](void* ptr)
{
if (ptr != NULL)
CWFreeMemory(gPluginContext, ptr, kTemporaryAllocation);
}
namespace std {
#define TRACK_ALLOCATION
#define kTrackedCookie 'TRKD'
void* malloc(size_t size)
{
#if defined(TRACK_ALLOCATION)
OSType* ptr = (OSType*) new char[sizeof(OSType) + size];
if (ptr != NULL)
*ptr++ = kTrackedCookie;
return ptr;
#else
return new char[size];
#endif
}
void free(void *ptr)
{
#if defined(TRACK_ALLOCATION)
OSType* type = (OSType*)ptr;
if (*--type == kTrackedCookie)
delete[] (char*) type;
else
DebugStr("\pillegal block passed to free.");
#else
delete[] (char*) ptr;
#endif
}
void* calloc(size_t nmemb, size_t size)
{
size *= nmemb;
void* ptr = malloc(size);
if (ptr != NULL) {
BlockZero(ptr, size);
}
return ptr;
}
void* realloc(void * ptr, size_t size)
{
void* newptr = NULL;
if (size > 0)
newptr = malloc(size);
if (ptr != NULL && newptr != NULL)
BlockMoveData(ptr, newptr, size);
if (ptr != NULL)
free(ptr);
return newptr;
}
}

View File

@ -0,0 +1,19 @@
/*
mac_stdlib.cpp
replacement functions for the Metrowerks plugin.
by Patrick C. Beard.
*/
#include <stdio.h>
#include <stdlib.h>
// simply throw us out of here!
void std::exit(int status)
{
throw status;
}

View File

@ -0,0 +1,38 @@
/*
mac_strings.cpp
*/
#include "mac_strings.h"
#include <string.h>
#include <Memory.h>
#include <new>
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;
}
char* p2c_strcpy(char* cstr, const StringPtr pstr)
{
size_t len = pstr[0];
BlockMoveData(pstr + 1, cstr, len);
cstr[len] = '\0';
return cstr;
}
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;
}

View File

@ -0,0 +1,11 @@
/*
mac_strings.h
*/
#pragma once
#include <MacTypes.h>
StringPtr c2p_strcpy(StringPtr pstr, const char* cstr);
char* p2c_strcpy(char* cstr, const StringPtr pstr);
char* p2c_strdup(StringPtr pstr);

View File

@ -0,0 +1,355 @@
/*
mac_xpidl.cpp
Metrowerks Codewarrior IDL plugin.
by Patrick C. Beard.
*/
/* standard headers */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <new.h>
/* system headers */
#include <Files.h>
#include <Errors.h>
#include <Strings.h>
#include "FullPath.h"
#include "MoreFilesExtras.h"
/* compiler headers */
#include "DropInCompilerLinker.h"
#include "CompilerMapping.h"
#include "CWPluginErrors.h"
/* local headers. */
#include "mac_xpidl.h"
#include "mac_console.h"
#include "mac_strings.h"
#include "mac_xpidl_panel.h"
/* prototypes of local functions */
static CWResult Compile(CWPluginContext context);
static CWResult Disassemble(CWPluginContext context);
static CWResult LocateFile(CWPluginContext context, const char* filename, FSSpec& file);
/* global variables */
CWPluginContext gPluginContext;
/* local variables */
static CWFileSpec gSourceFile;
static char* gSourcePath = NULL;
extern "C" {
pascal short xpidl_compiler(CWPluginContext context);
int xpidl_main(int argc, char* argv[]);
int xptdump_main(int argc, char* argv[]);
FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
}
pascal short xpidl_compiler(CWPluginContext context)
{
long request;
if (CWGetPluginRequest(context, &request) != cwNoErr)
return cwErrRequestFailed;
gPluginContext = context;
short result = cwNoErr;
/* dispatch on compiler request */
switch (request) {
case reqInitCompiler:
/* compiler has just been loaded into memory */
break;
case reqTermCompiler:
/* compiler is about to be unloaded from memory */
break;
case reqCompile:
/* compile a source file */
result = Compile(context);
break;
case reqCompDisassemble:
/* disassemble a source file */
result = Disassemble(context);
break;
default:
result = cwErrRequestFailed;
break;
}
/* is this necessary? */
CWDonePluginRequest(context, result);
/* return result code */
return (result);
}
static char* full_path_to(const FSSpec& file)
{
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 CWResult GetSettings(CWPluginContext context, XPIDLSettings& settings)
{
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 noErr;
}
static CWResult Compile(CWPluginContext context)
{
CWResult err = CWGetMainFileSpec(context, &gSourceFile);
if (!CWSUCCESS(err))
return (err);
// the compiler only understands full path names.
gSourcePath = p2c_strdup(gSourceFile.name);
if (gSourcePath == NULL)
return cwErrOutOfMemory;
// build an argument list and call the compiler.
XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeHeader, false, false };
GetSettings(context, settings);
int argc = 3;
char* modes[] = { "header", "stub", "typelib", "doc" };
char* argv[] = { "xpidl", "-m", modes[settings.mode - 1], NULL, NULL, NULL, NULL, };
if (settings.warnings) argv[argc++] = "-w";
if (settings.verbose) argv[argc++] = "-v";
argv[argc++] = gSourcePath;
try {
xpidl_main(argc, argv);
} catch (int status) {
// evidently the good old exit function got called.
err = cwErrRequestFailed;
}
delete[] gSourcePath;
gSourcePath = NULL;
return (err);
}
static CWResult Disassemble(CWPluginContext context)
{
CWFileSpec sourceFile;
CWResult err = CWGetMainFileSpec(context, &sourceFile);
if (!CWSUCCESS(err))
return (err);
char* sourceName = p2c_strdup(sourceFile.name);
char* dot = strrchr(sourceName, '.');
if (dot != NULL)
strcpy(dot + 1, "xpt");
err = CWGetOutputFileDirectory(gPluginContext, &gSourceFile);
if (!CWSUCCESS(err))
return (err);
c2p_strcpy(gSourceFile.name, sourceName);
gSourcePath = full_path_to(gSourceFile);
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++] = gSourcePath;
try {
xptdump_main(argc, argv);
} catch (int status) {
// evidently the good old exit function got called.
err = cwErrRequestFailed;
}
delete[] gSourcePath;
gSourcePath = NULL;
if (err == noErr) {
CWNewTextDocumentInfo info = {
NULL,
mac_console_handle,
false
};
CWResizeMemHandle(context, mac_console_handle, mac_console_count);
err = CWCreateNewTextDocument(context, &info);
}
return (err);
}
static CWResult LocateFile(CWPluginContext context, const char* filename, FSSpec& file)
{
/* prefill the CWFileInfo struct */
CWFileInfo 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);
}
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 (strncmp(mode, "w", 1) == 0) {
// if an output file, try opening it in the current's project's
CWFileSpec outputDir;
CWResult err = CWGetOutputFileDirectory(gPluginContext, &outputDir);
if (err == noErr) {
c2p_strcpy(filespec.name, filename);
filespec.vRefNum = outputDir.vRefNum;
Boolean isDirectory;
err = FSpGetDirectoryID(&outputDir, &filespec.parID, &isDirectory);
}
} 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);
}
void mac_warning(const char* warning_message)
{
CWReportMessage(gPluginContext, 0, warning_message, 0, messagetypeError, 0);
}
void mac_error(const char* error_message)
{
CWReportMessage(gPluginContext, 0, error_message, 0, messagetypeError, 0);
}
// plugin compiler exports.
#if CW_USE_PRAGMA_EXPORT
#pragma export on
#endif
CWPLUGIN_ENTRY(CWPlugin_GetDropInFlags)(const DropInFlags** flags, long* flagsSize)
{
static const DropInFlags sFlags = {
kCurrentDropInFlagsVersion,
CWDROPINCOMPILERTYPE,
DROPINCOMPILERLINKERAPIVERSION,
(kGeneratescode | kCandisassemble | kCompMultiTargAware | kCompAlwaysReload),
Lang_MISC,
DROPINCOMPILERLINKERAPIVERSION
};
*flags = &sFlags;
*flagsSize = sizeof(sFlags);
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDropInName)(const char** dropinName)
{
static const char* sDropInName = "xpidl";
*dropinName = sDropInName;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDisplayName)(const char** displayName)
{
static const char* sDisplayName = "xpidl";
*displayName = sDisplayName;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetPanelList)(const CWPanelList** panelList)
{
static const char* sPanelName = kXPIDLPanelName;
static CWPanelList sPanelList = { kCurrentCWPanelListVersion, 1, &sPanelName };
*panelList = &sPanelList;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetTargetList)(const CWTargetList** targetList)
{
static CWDataType sCPU = '****';
static CWDataType sOS = '****';
static CWTargetList sTargetList = { kCurrentCWTargetListVersion, 1, &sCPU, 1, &sOS };
*targetList = &sTargetList;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDefaultMappingList)(const CWExtMapList** defaultMappingList)
{
static CWExtensionMapping sExtension = { 'TEXT', ".idl", 0 };
static CWExtMapList sExtensionMapList = { kCurrentCWExtMapListVersion, 1, &sExtension };
*defaultMappingList = &sExtensionMapList;
return cwNoErr;
}
#if CW_USE_PRAGMA_EXPORT
#pragma export off
#endif

View File

@ -0,0 +1,26 @@
/*
mac_xpidl.h
prototypes for the Mac CodeWarrior plugin version of xpidl.
by Patrick C. Beard.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _STDIO_H
#include <stdio.h>
#endif
FILE* mac_fopen(const char* filename, const char *mode);
void mac_warning(const char* warning_message);
void mac_error(const char* error_message);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
/*
mac_xpidl_panel.h
*/
#ifndef __MAC_XPIDL_PANEL__
#define __MAC_XPIDL_PANEL__
#ifndef __TYPES__
#include <Types.h>
#endif
#pragma options align=mac68k
/* this is the name of the panel, as shown in the Finder */
#define kXPIDLPanelName "xpidl Settings"
/*
* AppleScript dictionary info. As a rule of thumb, dropin panels should use the
* same terminology and numeric code in their 'aete' that the IDE uses if there
* is already a similar item in the IDE's 'aete'. That is the case here, so we
* merely duplicate applicable 68K Project and 68K Linker user terms below.
*/
enum {
/* Symbolic Name Code AETE Terminology */
class_XPIDL = 'XIDL',
prefsPR_ProjectType = 'PR01', /* Project Type */
prefsPR_FileName = 'PR02', /* File Name */
prefsLN_GenerateSymFile = 'LN02', /* Generate SYM File */
/* enumeration for project type */
enumeration_ProjectType = 'PRPT',
enum_Project_Application = 'PRPA', /* application */
enum_Project_Library = 'PRPL', /* library */
enum_Project_SharedLibrary = 'PRPS', /* shared library */
enum_Project_CodeResource = 'PRPC', /* code resource */
enum_Project_MPWTool = 'PRPM' /* MPW tool */
};
enum {
kXPIDLModeHeader = 1,
kXPIDLModeStub,
kXPIDLModeTypelib,
kXPIDLModeDoc
};
/* This is the structure that is manipulated by the panel. The sample
* compiler & linker both "know" about this structure.
*/
enum {
kXPIDLSettingsVersion = 0x0100
};
struct XPIDLSettings {
short version; /* version # of settings data */
short mode; /* one of kXPIDLModeHeader, ... */
Boolean warnings; /* generate warnings. */
Boolean verbose; /* verbose mode */
Str32 output; /* name of the output file */
};
typedef struct XPIDLSettings XPIDLSettings, **XPIDLSettingsHandle;
#pragma options align=reset
#endif /* __MAC_XPIDL_PANEL__ */

View File

@ -0,0 +1,481 @@
/*
* Sample Linker.c - public interface to Sample Linker
*
* Copyright © 1993 metrowerks inc. All rights reserved.
*
*/
/* standard headers */
#include <stdio.h>
#include <string.h>
/* system headers */
#include <Files.h>
#include <Strings.h>
/* compiler headers */
#include "DropInCompilerLinker.h"
#include "CompilerMapping.h"
#include "CWPluginErrors.h"
/* project headers */
#include "mac_xpidl_panel.h"
#include "mac_console.h"
#include "mac_strings.h"
#include "FullPath.h"
#include "MoreFilesExtras.h"
/* use standard CodeWarrior debugger */
#define kDebuggerCreator 'MWDB'
/* prototypes of local functions */
static CWResult Link(CWPluginContext context);
static CWResult Disassemble(CWPluginContext context);
static CWResult GetTargetInfo(CWPluginContext context);
extern "C" {
pascal short xpt_linker(CWPluginContext context);
int xptlink_main(int argc, char* argv[]);
int xptdump_main(int argc, char* argv[]);
}
/* global variables */
CWPluginContext gPluginContext;
/* local variables */
static CWFileSpec gSourceFile;
static char* gSourcePath = NULL;
/*
* main - main entry-point for Drop-In Sample linker
*
*/
pascal short xpt_linker(CWPluginContext context)
{
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;
}
struct SamplePref {};
static char* full_path_to(const FSSpec& file)
{
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;
}
/**
* Provides the full path name to a given directory.
*/
static char* full_path_to(short vRefNum, long dirID)
{
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;
}
static CWResult GetSettings(CWPluginContext context, XPIDLSettings& settings)
{
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 noErr;
}
static CWResult Link(CWPluginContext context)
{
long index;
CWResult err;
long filecount;
/* load the relevant prefs */
XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeTypelib, false, false };
err = GetSettings(context, settings);
if (err != cwNoErr)
return (err);
/*
* Once all initialization has been done, the principal interaction
* between the linker and the IDE occurs in a loop where the linker
* processes all files in the project.
*/
err = CWGetProjectFileCount(context, &filecount);
if (err != cwNoErr)
return (err);
// assemble the argument list.
char** argv = new char*[2 + filecount + 1];
int argc = 0;
argv[argc++] = "xpt_link";
// get the full path to the output directory.
FSSpec outputDir;
err = CWGetOutputFileDirectory(context, &outputDir);
if (!CWSUCCESS(err))
return (err);
char* outputPrefix = full_path_to(outputDir.vRefNum, outputDir.parID);
if (outputPrefix == NULL)
return cwErrOutOfMemory;
size_t outputPrefixLen = strlen(outputPrefix);
// full path to output file.
char* outputFilePath = new char[outputPrefixLen + settings.output[0] + 1];
if (outputFilePath == NULL)
return cwErrOutOfMemory;
strcpy(outputFilePath, outputPrefix);
p2c_strcpy(outputFilePath + outputPrefixLen, settings.output);
argv[argc++] = outputFilePath;
for (index = 0; (err == cwNoErr) && (index < filecount); index++) {
CWProjectFileInfo fileInfo;
/* first, get info about the file */
err = CWGetFileInfo(context, index, false, &fileInfo);
if (err != cwNoErr)
continue;
// create file spec for the resulting .xpt file.
// idea: compiler could just store an alias to the darn file in each object code entry.
FSSpec& xptFile = fileInfo.filespec;
xptFile.vRefNum = outputDir.vRefNum;
xptFile.parID = outputDir.parID;
// change the extension from .idl to .xpt.
size_t len = xptFile.name[0] - 2;
xptFile.name[len++] = 'x';
xptFile.name[len++] = 'p';
xptFile.name[len++] = 't';
// construct a full path to the .xpt file.
char* xptFilePath = new char[outputPrefixLen + xptFile.name[0] + 1];
if (xptFilePath == NULL)
return cwErrOutOfMemory;
strcpy(xptFilePath, outputPrefix);
p2c_strcpy(xptFilePath + outputPrefixLen, xptFile.name);
argv[argc++] = xptFilePath;
#if 0
/* determine if we need to process this file */
if (!fileInfo.hasobjectcode && !fileInfo.hasresources && !fileInfo.isresourcefile)
continue;
if (fileInfo.isresourcefile) {
/* handle resource files here */
} else {
/*
* Other kinds of files store stuff in the project, either in the form
* of object code or of a resource fork image. We handle those here.
*/
/* load the object data */
CWMemHandle objectData;
err = CWLoadObjectData(context, index, &objectData);
if (err != cwNoErr)
continue;
if (fileInfo.hasobjectcode) {
/* link the object code */
}
if (fileInfo.hasresources) {
/* copy resources */
}
/* release the object code when done */
err = CWFreeObjectData(context, index, objectData);
}
#endif
}
try {
xptlink_main(argc, argv);
} catch (int status) {
// evidently the good old exit function got called.
err = cwErrRequestFailed;
}
return (err);
}
static CWResult Disassemble(CWPluginContext context)
{
CWResult err = noErr;
CWFileSpec sourceFile;
err = CWGetMainFileSpec(context, &sourceFile);
if (!CWSUCCESS(err))
return (err);
char* sourceName = p2c_strdup(sourceFile.name);
char* dot = strrchr(sourceName, '.');
if (dot != NULL)
strcpy(dot + 1, "xpt");
err = CWGetOutputFileDirectory(gPluginContext, &gSourceFile);
if (!CWSUCCESS(err))
return (err);
c2p_strcpy(gSourceFile.name, sourceName);
gSourcePath = full_path_to(gSourceFile);
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++] = gSourcePath;
try {
xptdump_main(argc, argv);
} catch (int status) {
// evidently the good old exit function got called.
err = cwErrRequestFailed;
}
delete[] gSourcePath;
gSourcePath = NULL;
if (err == noErr) {
CWNewTextDocumentInfo info = {
NULL,
mac_console_handle,
false
};
CWResizeMemHandle(context, mac_console_handle, mac_console_count);
err = CWCreateNewTextDocument(context, &info);
}
return (err);
}
static CWResult GetTargetInfo(CWPluginContext context)
{
CWTargetInfo targ;
CWMemHandle prefsHand;
SamplePref prefsData;
SamplePref *prefsPtr;
CWResult err;
memset(&targ, 0, sizeof(targ));
err = CWGetOutputFileDirectory(context, &targ.outfile);
targ.outputType = linkOutputFile;
targ.symfile = targ.outfile; /* location of SYM file */
targ.linkType = exelinkageFlat;
targ.targetCPU = 'SAMP';
targ.targetOS = 'SAMP';
/* load the relevant prefs */
err = CWGetNamedPreferences(context, kXPIDLPanelName, &prefsHand);
if (err != cwNoErr)
return (err);
err = CWLockMemHandle(context, prefsHand, false, (void**)&prefsPtr);
if (err != cwNoErr)
return (err);
prefsData = *prefsPtr;
err = CWUnlockMemHandle(context, prefsHand);
if (err != cwNoErr)
return (err);
#if CWPLUGIN_HOST == CWPLUGIN_HOST_MACOS
targ.outfileCreator = 'MWIE';
targ.outfileType = 'TEXT';
targ.debuggerCreator = kDebuggerCreator; /* so IDE can locate our debugger */
/* we put output file in same folder as project, but with name stored in prefs */
// targ.outfile.name[0] = strlen(prefsData.outfile);
// BlockMoveData(prefsData.outfile, targ.outfile.name + 1, targ.outfile.name[0]);
/* we put SYM file in same folder as project, but with name stored in prefs */
BlockMoveData(targ.outfile.name, targ.symfile.name, StrLength(targ.outfile.name)+1);
{
char* cstr;
cstr = p2cstr(targ.symfile.name);
strcat(cstr, ".SYM");
c2pstr(cstr);
}
#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;
}
#if 0
#if CW_USE_PRAGMA_EXPORT
#pragma export on
#endif
CWPLUGIN_ENTRY(CWPlugin_GetDropInFlags)(const DropInFlags** flags, long* flagsSize)
{
static const DropInFlags sFlags = {
kCurrentDropInFlagsVersion,
CWDROPINLINKERTYPE,
DROPINCOMPILERLINKERAPIVERSION_7,
(linkMultiTargAware | linkAlwaysReload),
0,
DROPINCOMPILERLINKERAPIVERSION
};
*flags = &sFlags;
*flagsSize = sizeof(sFlags);
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDropInName)(const char** dropinName)
{
static const char* sDropInName = "xpt Linker";
*dropinName = sDropInName;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDisplayName)(const char** displayName)
{
static const char* sDisplayName = "xpt Linker";
*displayName = sDisplayName;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetPanelList)(const CWPanelList** panelList)
{
// +++Turn this on when the sample panel has been converted!
static const char* sPanelName = kXPIDLPanelName;
static CWPanelList sPanelList = { kCurrentCWPanelListVersion, 1, &sPanelName };
*panelList = &sPanelList;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetTargetList)(const CWTargetList** targetList)
{
static CWDataType sCPU = '****';
static CWDataType sOS = '****';
static CWTargetList sTargetList = { kCurrentCWTargetListVersion, 1, &sCPU, 1, &sOS };
*targetList = &sTargetList;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDefaultMappingList)(const CWExtMapList** defaultMappingList)
{
static CWExtensionMapping sExtension = { 'MMCH', ".xpt", 0 };
static CWExtMapList sExtensionMapList = { kCurrentCWExtMapListVersion, 1, &sExtension };
*defaultMappingList = &sExtensionMapList;
return cwNoErr;
}
CWPLUGIN_ENTRY (CWPlugin_GetFamilyList)(const CWFamilyList** familyList)
{
static CWFamily sFamily = { 'XIDL', "xpidl Settings" };
static CWFamilyList sFamilyList = { kCurrentCWFamilyListVersion, 0, &sFamily };
*familyList = &sFamilyList;
return cwNoErr;
}
#if CW_USE_PRAGMA_EXPORT
#pragma export off
#endif
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,103 @@
#include "mac_console.h"
#ifndef __CONSOLE__
#include <console.h>
#endif
extern CWPluginContext gPluginContext;
UInt32 mac_console_count = 0;
CWMemHandle mac_console_handle = NULL;
/*
* The following four functions provide the UI for the console package.
* Users wishing to replace SIOUX with their own console package need
* only provide the four functions below in a library.
*/
/*
* extern short InstallConsole(short fd);
*
* Installs the Console package, this function will be called right
* before any read or write to one of the standard streams.
*
* short fd: The stream which we are reading/writing to/from.
* returns short: 0 no error occurred, anything else error.
*/
short InstallConsole(short fd)
{
#pragma unused (fd)
mac_console_count = 0;
CWAllocMemHandle(gPluginContext, 8192, false, &mac_console_handle);
return 0;
}
/*
* extern void RemoveConsole(void);
*
* Removes the console package. It is called after all other streams
* are closed and exit functions (installed by either atexit or _atexit)
* have been called. Since there is no way to recover from an error,
* this function doesn't need to return any.
*/
void RemoveConsole(void)
{
if (mac_console_handle != NULL) {
CWFreeMemHandle(gPluginContext, mac_console_handle);
mac_console_handle = NULL;
}
}
/*
* extern long WriteCharsToConsole(char *buffer, long n);
*
* Writes a stream of output to the Console window. This function is
* called by write.
*
* char *buffer: Pointer to the buffer to be written.
* long n: The length of the buffer to be written.
* returns short: Actual number of characters written to the stream,
* -1 if an error occurred.
*/
long WriteCharsToConsole(char *buffer, long n)
{
long size = 0;
char* ptr = NULL;
if (CWGetMemHandleSize(gPluginContext, mac_console_handle, &size) == noErr) {
if (mac_console_count + n >= size) {
size += 8192;
if (CWResizeMemHandle(gPluginContext, mac_console_handle, size) != noErr)
return -1;
}
}
if (CWLockMemHandle(gPluginContext, mac_console_handle, false, &ptr) == noErr) {
BlockMoveData(buffer, ptr + mac_console_count, n);
mac_console_count += n;
CWUnlockMemHandle(gPluginContext, mac_console_handle);
}
return 0;
}
/*
* extern long ReadCharsFromConsole(char *buffer, long n);
*
* Reads from the Console into a buffer. This function is called by
* read.
*
* char *buffer: Pointer to the buffer which will recieve the input.
* long n: The maximum amount of characters to be read (size of
* buffer).
* returns short: Actual number of characters read from the stream,
* -1 if an error occurred.
*/
long ReadCharsFromConsole(char *buffer, long n)
{
return 0;
}

View File

@ -0,0 +1,30 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
mac_console.h
*/
#pragma once
#include <Files.h>
#include <Memory.h>
#include "CWPlugins.h"
extern UInt32 mac_console_count;
extern CWMemHandle mac_console_handle;

View File

@ -0,0 +1,110 @@
/*
mac_memory.cpp
*/
#include <new.h>
#include <stdlib.h>
#include <Files.h>
#include <Memory.h>
#include "DropInCompilerLinker.h"
#include "CompilerMapping.h"
#include "CWPluginErrors.h"
extern CWPluginContext gPluginContext;
/**
* Note: memory allocated by these operators will automatically be freed after the
* current call into xpidl_compiler completes. This should be fine in most cases,
* as we are also having the compiler be reloaded for every request to reinitialize
* global data. Just be careful out there!
*/
const bool kTemporaryAllocation = false;
void* operator new(size_t size)
{
void* ptr = NULL;
if (CWAllocateMemory(gPluginContext, size, kTemporaryAllocation, &ptr) == cwNoErr)
return ptr;
return NULL;
}
void operator delete(void* ptr)
{
if (ptr != NULL)
CWFreeMemory(gPluginContext, ptr, kTemporaryAllocation);
}
void* operator new[] (size_t size)
{
void* ptr = NULL;
if (CWAllocateMemory(gPluginContext, size, kTemporaryAllocation, &ptr) == cwNoErr)
return ptr;
return NULL;
}
void operator delete[](void* ptr)
{
if (ptr != NULL)
CWFreeMemory(gPluginContext, ptr, kTemporaryAllocation);
}
namespace std {
#define TRACK_ALLOCATION
#define kTrackedCookie 'TRKD'
void* malloc(size_t size)
{
#if defined(TRACK_ALLOCATION)
OSType* ptr = (OSType*) new char[sizeof(OSType) + size];
if (ptr != NULL)
*ptr++ = kTrackedCookie;
return ptr;
#else
return new char[size];
#endif
}
void free(void *ptr)
{
#if defined(TRACK_ALLOCATION)
OSType* type = (OSType*)ptr;
if (*--type == kTrackedCookie)
delete[] (char*) type;
else
DebugStr("\pillegal block passed to free.");
#else
delete[] (char*) ptr;
#endif
}
void* calloc(size_t nmemb, size_t size)
{
size *= nmemb;
void* ptr = malloc(size);
if (ptr != NULL) {
BlockZero(ptr, size);
}
return ptr;
}
void* realloc(void * ptr, size_t size)
{
void* newptr = NULL;
if (size > 0)
newptr = malloc(size);
if (ptr != NULL && newptr != NULL)
BlockMoveData(ptr, newptr, size);
if (ptr != NULL)
free(ptr);
return newptr;
}
}

View File

@ -0,0 +1,19 @@
/*
mac_stdlib.cpp
replacement functions for the Metrowerks plugin.
by Patrick C. Beard.
*/
#include <stdio.h>
#include <stdlib.h>
// simply throw us out of here!
void std::exit(int status)
{
throw status;
}

View File

@ -0,0 +1,38 @@
/*
mac_strings.cpp
*/
#include "mac_strings.h"
#include <string.h>
#include <Memory.h>
#include <new>
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;
}
char* p2c_strcpy(char* cstr, const StringPtr pstr)
{
size_t len = pstr[0];
BlockMoveData(pstr + 1, cstr, len);
cstr[len] = '\0';
return cstr;
}
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;
}

View File

@ -0,0 +1,11 @@
/*
mac_strings.h
*/
#pragma once
#include <MacTypes.h>
StringPtr c2p_strcpy(StringPtr pstr, const char* cstr);
char* p2c_strcpy(char* cstr, const StringPtr pstr);
char* p2c_strdup(StringPtr pstr);

View File

@ -0,0 +1,355 @@
/*
mac_xpidl.cpp
Metrowerks Codewarrior IDL plugin.
by Patrick C. Beard.
*/
/* standard headers */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <new.h>
/* system headers */
#include <Files.h>
#include <Errors.h>
#include <Strings.h>
#include "FullPath.h"
#include "MoreFilesExtras.h"
/* compiler headers */
#include "DropInCompilerLinker.h"
#include "CompilerMapping.h"
#include "CWPluginErrors.h"
/* local headers. */
#include "mac_xpidl.h"
#include "mac_console.h"
#include "mac_strings.h"
#include "mac_xpidl_panel.h"
/* prototypes of local functions */
static CWResult Compile(CWPluginContext context);
static CWResult Disassemble(CWPluginContext context);
static CWResult LocateFile(CWPluginContext context, const char* filename, FSSpec& file);
/* global variables */
CWPluginContext gPluginContext;
/* local variables */
static CWFileSpec gSourceFile;
static char* gSourcePath = NULL;
extern "C" {
pascal short xpidl_compiler(CWPluginContext context);
int xpidl_main(int argc, char* argv[]);
int xptdump_main(int argc, char* argv[]);
FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
}
pascal short xpidl_compiler(CWPluginContext context)
{
long request;
if (CWGetPluginRequest(context, &request) != cwNoErr)
return cwErrRequestFailed;
gPluginContext = context;
short result = cwNoErr;
/* dispatch on compiler request */
switch (request) {
case reqInitCompiler:
/* compiler has just been loaded into memory */
break;
case reqTermCompiler:
/* compiler is about to be unloaded from memory */
break;
case reqCompile:
/* compile a source file */
result = Compile(context);
break;
case reqCompDisassemble:
/* disassemble a source file */
result = Disassemble(context);
break;
default:
result = cwErrRequestFailed;
break;
}
/* is this necessary? */
CWDonePluginRequest(context, result);
/* return result code */
return (result);
}
static char* full_path_to(const FSSpec& file)
{
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 CWResult GetSettings(CWPluginContext context, XPIDLSettings& settings)
{
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 noErr;
}
static CWResult Compile(CWPluginContext context)
{
CWResult err = CWGetMainFileSpec(context, &gSourceFile);
if (!CWSUCCESS(err))
return (err);
// the compiler only understands full path names.
gSourcePath = p2c_strdup(gSourceFile.name);
if (gSourcePath == NULL)
return cwErrOutOfMemory;
// build an argument list and call the compiler.
XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeHeader, false, false };
GetSettings(context, settings);
int argc = 3;
char* modes[] = { "header", "stub", "typelib", "doc" };
char* argv[] = { "xpidl", "-m", modes[settings.mode - 1], NULL, NULL, NULL, NULL, };
if (settings.warnings) argv[argc++] = "-w";
if (settings.verbose) argv[argc++] = "-v";
argv[argc++] = gSourcePath;
try {
xpidl_main(argc, argv);
} catch (int status) {
// evidently the good old exit function got called.
err = cwErrRequestFailed;
}
delete[] gSourcePath;
gSourcePath = NULL;
return (err);
}
static CWResult Disassemble(CWPluginContext context)
{
CWFileSpec sourceFile;
CWResult err = CWGetMainFileSpec(context, &sourceFile);
if (!CWSUCCESS(err))
return (err);
char* sourceName = p2c_strdup(sourceFile.name);
char* dot = strrchr(sourceName, '.');
if (dot != NULL)
strcpy(dot + 1, "xpt");
err = CWGetOutputFileDirectory(gPluginContext, &gSourceFile);
if (!CWSUCCESS(err))
return (err);
c2p_strcpy(gSourceFile.name, sourceName);
gSourcePath = full_path_to(gSourceFile);
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++] = gSourcePath;
try {
xptdump_main(argc, argv);
} catch (int status) {
// evidently the good old exit function got called.
err = cwErrRequestFailed;
}
delete[] gSourcePath;
gSourcePath = NULL;
if (err == noErr) {
CWNewTextDocumentInfo info = {
NULL,
mac_console_handle,
false
};
CWResizeMemHandle(context, mac_console_handle, mac_console_count);
err = CWCreateNewTextDocument(context, &info);
}
return (err);
}
static CWResult LocateFile(CWPluginContext context, const char* filename, FSSpec& file)
{
/* prefill the CWFileInfo struct */
CWFileInfo 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);
}
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 (strncmp(mode, "w", 1) == 0) {
// if an output file, try opening it in the current's project's
CWFileSpec outputDir;
CWResult err = CWGetOutputFileDirectory(gPluginContext, &outputDir);
if (err == noErr) {
c2p_strcpy(filespec.name, filename);
filespec.vRefNum = outputDir.vRefNum;
Boolean isDirectory;
err = FSpGetDirectoryID(&outputDir, &filespec.parID, &isDirectory);
}
} 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);
}
void mac_warning(const char* warning_message)
{
CWReportMessage(gPluginContext, 0, warning_message, 0, messagetypeError, 0);
}
void mac_error(const char* error_message)
{
CWReportMessage(gPluginContext, 0, error_message, 0, messagetypeError, 0);
}
// plugin compiler exports.
#if CW_USE_PRAGMA_EXPORT
#pragma export on
#endif
CWPLUGIN_ENTRY(CWPlugin_GetDropInFlags)(const DropInFlags** flags, long* flagsSize)
{
static const DropInFlags sFlags = {
kCurrentDropInFlagsVersion,
CWDROPINCOMPILERTYPE,
DROPINCOMPILERLINKERAPIVERSION,
(kGeneratescode | kCandisassemble | kCompMultiTargAware | kCompAlwaysReload),
Lang_MISC,
DROPINCOMPILERLINKERAPIVERSION
};
*flags = &sFlags;
*flagsSize = sizeof(sFlags);
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDropInName)(const char** dropinName)
{
static const char* sDropInName = "xpidl";
*dropinName = sDropInName;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDisplayName)(const char** displayName)
{
static const char* sDisplayName = "xpidl";
*displayName = sDisplayName;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetPanelList)(const CWPanelList** panelList)
{
static const char* sPanelName = kXPIDLPanelName;
static CWPanelList sPanelList = { kCurrentCWPanelListVersion, 1, &sPanelName };
*panelList = &sPanelList;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetTargetList)(const CWTargetList** targetList)
{
static CWDataType sCPU = '****';
static CWDataType sOS = '****';
static CWTargetList sTargetList = { kCurrentCWTargetListVersion, 1, &sCPU, 1, &sOS };
*targetList = &sTargetList;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDefaultMappingList)(const CWExtMapList** defaultMappingList)
{
static CWExtensionMapping sExtension = { 'TEXT', ".idl", 0 };
static CWExtMapList sExtensionMapList = { kCurrentCWExtMapListVersion, 1, &sExtension };
*defaultMappingList = &sExtensionMapList;
return cwNoErr;
}
#if CW_USE_PRAGMA_EXPORT
#pragma export off
#endif

View File

@ -0,0 +1,26 @@
/*
mac_xpidl.h
prototypes for the Mac CodeWarrior plugin version of xpidl.
by Patrick C. Beard.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _STDIO_H
#include <stdio.h>
#endif
FILE* mac_fopen(const char* filename, const char *mode);
void mac_warning(const char* warning_message);
void mac_error(const char* error_message);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
/*
mac_xpidl_panel.h
*/
#ifndef __MAC_XPIDL_PANEL__
#define __MAC_XPIDL_PANEL__
#ifndef __TYPES__
#include <Types.h>
#endif
#pragma options align=mac68k
/* this is the name of the panel, as shown in the Finder */
#define kXPIDLPanelName "xpidl Settings"
/*
* AppleScript dictionary info. As a rule of thumb, dropin panels should use the
* same terminology and numeric code in their 'aete' that the IDE uses if there
* is already a similar item in the IDE's 'aete'. That is the case here, so we
* merely duplicate applicable 68K Project and 68K Linker user terms below.
*/
enum {
/* Symbolic Name Code AETE Terminology */
class_XPIDL = 'XIDL',
prefsPR_ProjectType = 'PR01', /* Project Type */
prefsPR_FileName = 'PR02', /* File Name */
prefsLN_GenerateSymFile = 'LN02', /* Generate SYM File */
/* enumeration for project type */
enumeration_ProjectType = 'PRPT',
enum_Project_Application = 'PRPA', /* application */
enum_Project_Library = 'PRPL', /* library */
enum_Project_SharedLibrary = 'PRPS', /* shared library */
enum_Project_CodeResource = 'PRPC', /* code resource */
enum_Project_MPWTool = 'PRPM' /* MPW tool */
};
enum {
kXPIDLModeHeader = 1,
kXPIDLModeStub,
kXPIDLModeTypelib,
kXPIDLModeDoc
};
/* This is the structure that is manipulated by the panel. The sample
* compiler & linker both "know" about this structure.
*/
enum {
kXPIDLSettingsVersion = 0x0100
};
struct XPIDLSettings {
short version; /* version # of settings data */
short mode; /* one of kXPIDLModeHeader, ... */
Boolean warnings; /* generate warnings. */
Boolean verbose; /* verbose mode */
Str32 output; /* name of the output file */
};
typedef struct XPIDLSettings XPIDLSettings, **XPIDLSettingsHandle;
#pragma options align=reset
#endif /* __MAC_XPIDL_PANEL__ */

View File

@ -0,0 +1,481 @@
/*
* Sample Linker.c - public interface to Sample Linker
*
* Copyright © 1993 metrowerks inc. All rights reserved.
*
*/
/* standard headers */
#include <stdio.h>
#include <string.h>
/* system headers */
#include <Files.h>
#include <Strings.h>
/* compiler headers */
#include "DropInCompilerLinker.h"
#include "CompilerMapping.h"
#include "CWPluginErrors.h"
/* project headers */
#include "mac_xpidl_panel.h"
#include "mac_console.h"
#include "mac_strings.h"
#include "FullPath.h"
#include "MoreFilesExtras.h"
/* use standard CodeWarrior debugger */
#define kDebuggerCreator 'MWDB'
/* prototypes of local functions */
static CWResult Link(CWPluginContext context);
static CWResult Disassemble(CWPluginContext context);
static CWResult GetTargetInfo(CWPluginContext context);
extern "C" {
pascal short xpt_linker(CWPluginContext context);
int xptlink_main(int argc, char* argv[]);
int xptdump_main(int argc, char* argv[]);
}
/* global variables */
CWPluginContext gPluginContext;
/* local variables */
static CWFileSpec gSourceFile;
static char* gSourcePath = NULL;
/*
* main - main entry-point for Drop-In Sample linker
*
*/
pascal short xpt_linker(CWPluginContext context)
{
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;
}
struct SamplePref {};
static char* full_path_to(const FSSpec& file)
{
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;
}
/**
* Provides the full path name to a given directory.
*/
static char* full_path_to(short vRefNum, long dirID)
{
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;
}
static CWResult GetSettings(CWPluginContext context, XPIDLSettings& settings)
{
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 noErr;
}
static CWResult Link(CWPluginContext context)
{
long index;
CWResult err;
long filecount;
/* load the relevant prefs */
XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeTypelib, false, false };
err = GetSettings(context, settings);
if (err != cwNoErr)
return (err);
/*
* Once all initialization has been done, the principal interaction
* between the linker and the IDE occurs in a loop where the linker
* processes all files in the project.
*/
err = CWGetProjectFileCount(context, &filecount);
if (err != cwNoErr)
return (err);
// assemble the argument list.
char** argv = new char*[2 + filecount + 1];
int argc = 0;
argv[argc++] = "xpt_link";
// get the full path to the output directory.
FSSpec outputDir;
err = CWGetOutputFileDirectory(context, &outputDir);
if (!CWSUCCESS(err))
return (err);
char* outputPrefix = full_path_to(outputDir.vRefNum, outputDir.parID);
if (outputPrefix == NULL)
return cwErrOutOfMemory;
size_t outputPrefixLen = strlen(outputPrefix);
// full path to output file.
char* outputFilePath = new char[outputPrefixLen + settings.output[0] + 1];
if (outputFilePath == NULL)
return cwErrOutOfMemory;
strcpy(outputFilePath, outputPrefix);
p2c_strcpy(outputFilePath + outputPrefixLen, settings.output);
argv[argc++] = outputFilePath;
for (index = 0; (err == cwNoErr) && (index < filecount); index++) {
CWProjectFileInfo fileInfo;
/* first, get info about the file */
err = CWGetFileInfo(context, index, false, &fileInfo);
if (err != cwNoErr)
continue;
// create file spec for the resulting .xpt file.
// idea: compiler could just store an alias to the darn file in each object code entry.
FSSpec& xptFile = fileInfo.filespec;
xptFile.vRefNum = outputDir.vRefNum;
xptFile.parID = outputDir.parID;
// change the extension from .idl to .xpt.
size_t len = xptFile.name[0] - 2;
xptFile.name[len++] = 'x';
xptFile.name[len++] = 'p';
xptFile.name[len++] = 't';
// construct a full path to the .xpt file.
char* xptFilePath = new char[outputPrefixLen + xptFile.name[0] + 1];
if (xptFilePath == NULL)
return cwErrOutOfMemory;
strcpy(xptFilePath, outputPrefix);
p2c_strcpy(xptFilePath + outputPrefixLen, xptFile.name);
argv[argc++] = xptFilePath;
#if 0
/* determine if we need to process this file */
if (!fileInfo.hasobjectcode && !fileInfo.hasresources && !fileInfo.isresourcefile)
continue;
if (fileInfo.isresourcefile) {
/* handle resource files here */
} else {
/*
* Other kinds of files store stuff in the project, either in the form
* of object code or of a resource fork image. We handle those here.
*/
/* load the object data */
CWMemHandle objectData;
err = CWLoadObjectData(context, index, &objectData);
if (err != cwNoErr)
continue;
if (fileInfo.hasobjectcode) {
/* link the object code */
}
if (fileInfo.hasresources) {
/* copy resources */
}
/* release the object code when done */
err = CWFreeObjectData(context, index, objectData);
}
#endif
}
try {
xptlink_main(argc, argv);
} catch (int status) {
// evidently the good old exit function got called.
err = cwErrRequestFailed;
}
return (err);
}
static CWResult Disassemble(CWPluginContext context)
{
CWResult err = noErr;
CWFileSpec sourceFile;
err = CWGetMainFileSpec(context, &sourceFile);
if (!CWSUCCESS(err))
return (err);
char* sourceName = p2c_strdup(sourceFile.name);
char* dot = strrchr(sourceName, '.');
if (dot != NULL)
strcpy(dot + 1, "xpt");
err = CWGetOutputFileDirectory(gPluginContext, &gSourceFile);
if (!CWSUCCESS(err))
return (err);
c2p_strcpy(gSourceFile.name, sourceName);
gSourcePath = full_path_to(gSourceFile);
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++] = gSourcePath;
try {
xptdump_main(argc, argv);
} catch (int status) {
// evidently the good old exit function got called.
err = cwErrRequestFailed;
}
delete[] gSourcePath;
gSourcePath = NULL;
if (err == noErr) {
CWNewTextDocumentInfo info = {
NULL,
mac_console_handle,
false
};
CWResizeMemHandle(context, mac_console_handle, mac_console_count);
err = CWCreateNewTextDocument(context, &info);
}
return (err);
}
static CWResult GetTargetInfo(CWPluginContext context)
{
CWTargetInfo targ;
CWMemHandle prefsHand;
SamplePref prefsData;
SamplePref *prefsPtr;
CWResult err;
memset(&targ, 0, sizeof(targ));
err = CWGetOutputFileDirectory(context, &targ.outfile);
targ.outputType = linkOutputFile;
targ.symfile = targ.outfile; /* location of SYM file */
targ.linkType = exelinkageFlat;
targ.targetCPU = 'SAMP';
targ.targetOS = 'SAMP';
/* load the relevant prefs */
err = CWGetNamedPreferences(context, kXPIDLPanelName, &prefsHand);
if (err != cwNoErr)
return (err);
err = CWLockMemHandle(context, prefsHand, false, (void**)&prefsPtr);
if (err != cwNoErr)
return (err);
prefsData = *prefsPtr;
err = CWUnlockMemHandle(context, prefsHand);
if (err != cwNoErr)
return (err);
#if CWPLUGIN_HOST == CWPLUGIN_HOST_MACOS
targ.outfileCreator = 'MWIE';
targ.outfileType = 'TEXT';
targ.debuggerCreator = kDebuggerCreator; /* so IDE can locate our debugger */
/* we put output file in same folder as project, but with name stored in prefs */
// targ.outfile.name[0] = strlen(prefsData.outfile);
// BlockMoveData(prefsData.outfile, targ.outfile.name + 1, targ.outfile.name[0]);
/* we put SYM file in same folder as project, but with name stored in prefs */
BlockMoveData(targ.outfile.name, targ.symfile.name, StrLength(targ.outfile.name)+1);
{
char* cstr;
cstr = p2cstr(targ.symfile.name);
strcat(cstr, ".SYM");
c2pstr(cstr);
}
#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;
}
#if 0
#if CW_USE_PRAGMA_EXPORT
#pragma export on
#endif
CWPLUGIN_ENTRY(CWPlugin_GetDropInFlags)(const DropInFlags** flags, long* flagsSize)
{
static const DropInFlags sFlags = {
kCurrentDropInFlagsVersion,
CWDROPINLINKERTYPE,
DROPINCOMPILERLINKERAPIVERSION_7,
(linkMultiTargAware | linkAlwaysReload),
0,
DROPINCOMPILERLINKERAPIVERSION
};
*flags = &sFlags;
*flagsSize = sizeof(sFlags);
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDropInName)(const char** dropinName)
{
static const char* sDropInName = "xpt Linker";
*dropinName = sDropInName;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDisplayName)(const char** displayName)
{
static const char* sDisplayName = "xpt Linker";
*displayName = sDisplayName;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetPanelList)(const CWPanelList** panelList)
{
// +++Turn this on when the sample panel has been converted!
static const char* sPanelName = kXPIDLPanelName;
static CWPanelList sPanelList = { kCurrentCWPanelListVersion, 1, &sPanelName };
*panelList = &sPanelList;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetTargetList)(const CWTargetList** targetList)
{
static CWDataType sCPU = '****';
static CWDataType sOS = '****';
static CWTargetList sTargetList = { kCurrentCWTargetListVersion, 1, &sCPU, 1, &sOS };
*targetList = &sTargetList;
return cwNoErr;
}
CWPLUGIN_ENTRY(CWPlugin_GetDefaultMappingList)(const CWExtMapList** defaultMappingList)
{
static CWExtensionMapping sExtension = { 'MMCH', ".xpt", 0 };
static CWExtMapList sExtensionMapList = { kCurrentCWExtMapListVersion, 1, &sExtension };
*defaultMappingList = &sExtensionMapList;
return cwNoErr;
}
CWPLUGIN_ENTRY (CWPlugin_GetFamilyList)(const CWFamilyList** familyList)
{
static CWFamily sFamily = { 'XIDL', "xpidl Settings" };
static CWFamilyList sFamilyList = { kCurrentCWFamilyListVersion, 0, &sFamily };
*familyList = &sFamilyList;
return cwNoErr;
}
#if CW_USE_PRAGMA_EXPORT
#pragma export off
#endif
#endif

Binary file not shown.