~ubuntu-branches/ubuntu/gutsy/virtualbox-ose/gutsy

« back to all changes in this revision

Viewing changes to src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-09-08 16:44:58 UTC
  • Revision ID: james.westby@ubuntu.com-20070908164458-wao29470vqtr8ksy
Tags: upstream-1.5.0-dfsg2
ImportĀ upstreamĀ versionĀ 1.5.0-dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Netscape Public License
 
5
 * Version 1.1 (the "License"); you may not use this file except in
 
6
 * compliance with the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/NPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is mozilla.org code.
 
15
 *
 
16
 * The Initial Developer of the Original Code is 
 
17
 * Netscape Communications Corporation.
 
18
 * Portions created by the Initial Developer are Copyright (C) 1998
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *
 
23
 * Alternatively, the contents of this file may be used under the terms of
 
24
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 
25
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
26
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
27
 * of those above. If you wish to allow use of your version of this file only
 
28
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
29
 * use your version of this file under the terms of the NPL, indicate your
 
30
 * decision by deleting the provisions above and replace them with the notice
 
31
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
32
 * the provisions above, a recipient may use your version of this file under
 
33
 * the terms of any one of the NPL, the GPL or the LGPL.
 
34
 *
 
35
 * ***** END LICENSE BLOCK ***** */
 
36
 
 
37
/*
 
38
        mac_xpidl.cpp
 
39
        
 
40
        Metrowerks Codewarrior IDL plugin.
 
41
        
 
42
        by Patrick C. Beard.
 
43
 */
 
44
 
 
45
/* standard headers */
 
46
#include <ctype.h>
 
47
#include <stdio.h>
 
48
#include <string.h>
 
49
#include <stdlib.h>
 
50
#include <new.h>
 
51
#include <setjmp.h>
 
52
 
 
53
/* system headers */
 
54
#include <Files.h>
 
55
#include <Errors.h>
 
56
#include <Strings.h>
 
57
 
 
58
#include "FullPath.h"
 
59
#include "MoreFilesExtras.h"
 
60
 
 
61
/* compiler headers */
 
62
#include "DropInCompilerLinker.h"
 
63
#include "CompilerMapping.h"
 
64
#include "CWPluginErrors.h"
 
65
 
 
66
/* local headers. */
 
67
#include "mac_xpidl.h"
 
68
#include "mac_console.h"
 
69
#include "mac_strings.h"
 
70
#include "mac_xpidl_panel.h"
 
71
 
 
72
/* prototypes of local functions */
 
73
static CWResult Compile(CWPluginContext context);
 
74
static CWResult Disassemble(CWPluginContext context);
 
75
static CWResult LocateFile(CWPluginContext context, const char* filename, FSSpec& file);
 
76
 
 
77
/* external variables */
 
78
extern jmp_buf exit_jump;
 
79
extern int exit_status;
 
80
 
 
81
/* global variables */
 
82
CWPluginContext gPluginContext;
 
83
 
 
84
/* local variables */
 
85
static CWFileSpec gSourceFile;
 
86
static char* gSourcePath = NULL;
 
87
static CWFileSpec gOutputFile;
 
88
 
 
89
extern "C" {
 
90
pascal short xpidl_compiler(CWPluginContext context);
 
91
int xpidl_main(int argc, char* argv[]);
 
92
int xptdump_main(int argc, char* argv[]);
 
93
 
 
94
FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
 
95
}
 
96
 
 
97
pascal short xpidl_compiler(CWPluginContext context)
 
98
{
 
99
        long request;
 
100
        if (CWGetPluginRequest(context, &request) != cwNoErr)
 
101
                return cwErrRequestFailed;
 
102
        
 
103
        gPluginContext = context;
 
104
        short result = cwNoErr;
 
105
        
 
106
        /* dispatch on compiler request */
 
107
        switch (request) {
 
108
        case reqInitCompiler:
 
109
                /* compiler has just been loaded into memory */
 
110
                break;
 
111
                
 
112
        case reqTermCompiler:
 
113
                /* compiler is about to be unloaded from memory */
 
114
                break;
 
115
                
 
116
        case reqCompile:
 
117
                /* compile a source file */
 
118
                result = Compile(context);
 
119
                break;
 
120
        
 
121
        case reqCompDisassemble:
 
122
                /* disassemble a source file */
 
123
                result = Disassemble(context);
 
124
                break;
 
125
        
 
126
        default:
 
127
                result = cwErrRequestFailed;
 
128
                break;
 
129
        }
 
130
        
 
131
        /* is this necessary? */
 
132
        CWDonePluginRequest(context, result);
 
133
        
 
134
        /* return result code */
 
135
        return (result);
 
136
}
 
137
 
 
138
static char* full_path_to(const FSSpec& file)
 
139
{
 
140
        short len = 0;
 
141
        Handle fullPath = NULL;
 
142
        if (FSpGetFullPath(&file, &len, &fullPath) == noErr && fullPath != NULL) {
 
143
                char* path = new char[1 + len];
 
144
                if (path != NULL) {
 
145
                        BlockMoveData(*fullPath, path, len);
 
146
                        path[len] = '\0';
 
147
                }
 
148
                DisposeHandle(fullPath);
 
149
                return path;
 
150
        }
 
151
        return NULL;
 
152
}
 
153
 
 
154
static CWResult GetSettings(CWPluginContext context, XPIDLSettings& settings)
 
155
{
 
156
        CWMemHandle     settingsHand;
 
157
        CWResult err = CWGetNamedPreferences(context, kXPIDLPanelName, &settingsHand);
 
158
        if (!CWSUCCESS(err))
 
159
                return (err);
 
160
        
 
161
        XPIDLSettings* settingsPtr = NULL;
 
162
        err = CWLockMemHandle(context, settingsHand, false, (void**)&settingsPtr);
 
163
        if (!CWSUCCESS(err))
 
164
                return (err);
 
165
        
 
166
        settings = *settingsPtr;
 
167
        
 
168
        err = CWUnlockMemHandle(context, settingsHand);
 
169
        if (!CWSUCCESS(err))
 
170
                return (err);
 
171
 
 
172
        return noErr;
 
173
}
 
174
 
 
175
static CWResult Compile(CWPluginContext context)
 
176
{
 
177
        CWResult err = CWGetMainFileSpec(context, &gSourceFile);
 
178
        if (!CWSUCCESS(err))
 
179
                return (err);
 
180
 
 
181
        long fileNum;
 
182
        err = CWGetMainFileNumber(context, &fileNum);
 
183
        if (!CWSUCCESS(err))
 
184
                return (err);
 
185
 
 
186
        // get the name of the source file to compile.
 
187
        gSourcePath = p2c_strdup(gSourceFile.name);
 
188
        if (gSourcePath == NULL)
 
189
                return cwErrOutOfMemory;
 
190
        
 
191
        // build an argument list and call the compiler.
 
192
        XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeHeader, false, false };
 
193
        GetSettings(context, settings);
 
194
 
 
195
#if 0   
 
196
        // if generating .xpt files, let the IDE tell us where to put the output file.
 
197
        // otherwise, put them in the project's output directory.
 
198
        if (settings.mode == kXPIDLModeTypelib)
 
199
                err = CWGetSuggestedObjectFileSpec(context, fileNum, &gOutputFile);
 
200
        else
 
201
                err = CWGetOutputFileDirectory(gPluginContext, &gOutputFile);
 
202
#else
 
203
        // always generate the output file into the project target's data directory.
 
204
        err = CWGetSuggestedObjectFileSpec(context, fileNum, &gOutputFile);
 
205
#endif
 
206
        if (!CWSUCCESS(err))
 
207
                return (err);
 
208
        
 
209
        int argc = 3;
 
210
        char* modes[] = { "header", "java", "typelib", "doc" };
 
211
        char* argv[] = { "xpidl", "-m", modes[settings.mode - 1], NULL, NULL, NULL, NULL, };
 
212
        if (settings.warnings) argv[argc++] = "-w";
 
213
        if (settings.verbose) argv[argc++] = "-v";
 
214
        argv[argc++] = gSourcePath;
 
215
        
 
216
        if (setjmp(exit_jump) == 0) {
 
217
                if (xpidl_main(argc, argv) != 0)
 
218
                        err = cwErrRequestFailed;
 
219
        } else {
 
220
                // evidently the good old exit function got called.
 
221
                if (exit_status != 0)
 
222
                        err = cwErrRequestFailed;
 
223
        }
 
224
 
 
225
        // if the compilation succeeded, tell CodeWarrior about the output file.
 
226
        // this ensures several things:  1. if the output file is deleted by the user,
 
227
        // then the IDE will know to recompile it, which is good for dirty builds,
 
228
        // where the output files may be hand deleted; 2. if the user elects to remove
 
229
        // objects, the output files are deleted. Thanks to robv@metrowerks.com for
 
230
        // pointing this new CWPro4 API out.
 
231
        if (err == cwNoErr) {
 
232
                CWObjectData objectData;
 
233
                BlockZero(&objectData, sizeof(objectData));
 
234
                
 
235
                // for fun, show how large the output file is in the data area.
 
236
                long dataSize, rsrcSize;
 
237
                if (FSpGetFileSize(&gOutputFile, &dataSize, &rsrcSize) == noErr)
 
238
                        objectData.idatasize = dataSize;
 
239
                
 
240
                // tell the IDE that this file was generated by the compiler.
 
241
                objectData.objectfile = &gOutputFile;
 
242
                
 
243
                err = CWStoreObjectData(context, fileNum, &objectData);
 
244
        } else {
 
245
                // an error occured, delete the output file, which might be a partial file.
 
246
                if (gOutputFile.name[0] != 0) {
 
247
                        ::FSpDelete(&gOutputFile);
 
248
                }
 
249
        }
 
250
 
 
251
        delete[] gSourcePath;
 
252
        gSourcePath = NULL;
 
253
 
 
254
        return (err);
 
255
}
 
256
 
 
257
static CWResult Disassemble(CWPluginContext context)
 
258
{
 
259
        // the disassembly code has moved to the linker.
 
260
        return noErr;
 
261
}
 
262
 
 
263
static CWResult LocateFile(CWPluginContext context, const char* filename, FSSpec& file)
 
264
{
 
265
        /* prefill the CWFileInfo struct */
 
266
        CWFileInfo fileinfo;
 
267
        BlockZero(&fileinfo, sizeof(fileinfo));
 
268
        // memset(&fileinfo, 0, sizeof(fileinfo));
 
269
        fileinfo.fullsearch = true;
 
270
        fileinfo.suppressload = true;
 
271
        fileinfo.dependencyType = cwNormalDependency;
 
272
        fileinfo.isdependentoffile = kCurrentCompiledFile;
 
273
 
 
274
        /* locate the file name using the project's access paths */
 
275
        CWResult err = CWFindAndLoadFile(context, filename, &fileinfo);
 
276
        if (err == cwNoErr) {
 
277
                file = fileinfo.filespec;
 
278
        } else if (err == cwErrFileNotFound) {
 
279
                char errmsg[200];
 
280
                sprintf(errmsg, "Can't locate file \"%s\".", filename);
 
281
                CWResult callbackResult = CWReportMessage(context, 0, errmsg, 0, messagetypeError, 0);
 
282
        }
 
283
        
 
284
        return (err);
 
285
}
 
286
 
 
287
/**
 
288
 * Substitute for standard fopen, treats certain filenames specially,
 
289
 * and also considers the mode argument. If a file is being opened
 
290
 * for reading, the file is assumed to be locateable using CodeWarrior's
 
291
 * standard access paths. If it's for writing, the file is opened in
 
292
 * the current project's output directory.
 
293
 */
 
294
FILE* std::fopen(const char* filename, const char *mode)
 
295
{
 
296
        FSSpec filespec;
 
297
        CWResult err = noErr;
 
298
        do {
 
299
                if (filename == gSourcePath || strcmp(filename, gSourcePath) == 0) {
 
300
                        // opening the main source file.
 
301
                        filespec = gSourceFile;
 
302
                } else if (mode[0] == 'w') {
 
303
                        // if an output file, open it in the current compilation's output directory.
 
304
                        c2p_strcpy(filespec.name, filename);
 
305
                        filespec.vRefNum = gOutputFile.vRefNum;
 
306
                        filespec.parID = gOutputFile.parID;
 
307
                        c2p_strcpy(gOutputFile.name, filename);
 
308
                } else {
 
309
                        // an input file, use CodeWarrior's search paths to find the named source file.
 
310
                        err = LocateFile(gPluginContext, filename, filespec);
 
311
                }
 
312
        } while (0);
 
313
        // if all went well, we have a file to open.
 
314
        return (err == noErr ? FSp_fopen(&filespec, mode) : NULL);
 
315
}
 
316
 
 
317
/**
 
318
 * Returns the length of a file, assuming it is always located in the
 
319
 * project's output directory.
 
320
 */
 
321
size_t mac_get_file_length(const char* filename)
 
322
{
 
323
        long dataSize= 0, rsrcSize = 0;
 
324
        FSSpec filespec;
 
325
        if (CWGetOutputFileDirectory(gPluginContext, &filespec) != noErr)
 
326
                return 0;
 
327
        c2p_strcpy(filespec.name, filename);
 
328
        if (FSpGetFileSize(&filespec, &dataSize, &rsrcSize) != noErr)
 
329
                return 0;
 
330
        return dataSize;
 
331
}
 
332
 
 
333
void mac_warning(const char* warning_message)
 
334
{
 
335
        CWReportMessage(gPluginContext, 0, warning_message, 0, messagetypeWarning, 0);
 
336
}
 
337
 
 
338
void mac_error(const char* error_message)
 
339
{
 
340
        CWReportMessage(gPluginContext, 0, error_message, 0, messagetypeError, 0);
 
341
}
 
342
 
 
343
// plugin compiler exports.
 
344
 
 
345
#if CW_USE_PRAGMA_EXPORT
 
346
#pragma export on
 
347
#endif
 
348
 
 
349
CWPLUGIN_ENTRY(CWPlugin_GetDropInFlags)(const DropInFlags** flags, long* flagsSize)
 
350
{
 
351
        static const DropInFlags sFlags = {
 
352
                kCurrentDropInFlagsVersion,
 
353
                CWDROPINCOMPILERTYPE,
 
354
                DROPINCOMPILERLINKERAPIVERSION,
 
355
                (kGeneratescode | /* kCandisassemble | */ kCompMultiTargAware | kCompAlwaysReload),
 
356
                Lang_MISC,
 
357
                DROPINCOMPILERLINKERAPIVERSION
 
358
        };
 
359
        
 
360
        *flags = &sFlags;
 
361
        *flagsSize = sizeof(sFlags);
 
362
        
 
363
        return cwNoErr;
 
364
}
 
365
 
 
366
CWPLUGIN_ENTRY(CWPlugin_GetDropInName)(const char** dropinName)
 
367
{
 
368
        static const char* sDropInName = "xpidl";
 
369
        
 
370
        *dropinName = sDropInName;
 
371
        
 
372
        return cwNoErr;
 
373
}
 
374
 
 
375
CWPLUGIN_ENTRY(CWPlugin_GetDisplayName)(const char** displayName)
 
376
{
 
377
        static const char* sDisplayName = "xpidl";
 
378
        
 
379
        *displayName = sDisplayName;
 
380
        
 
381
        return cwNoErr;
 
382
}
 
383
 
 
384
CWPLUGIN_ENTRY(CWPlugin_GetPanelList)(const CWPanelList** panelList)
 
385
{
 
386
        static const char* sPanelName = kXPIDLPanelName;
 
387
        static CWPanelList sPanelList = { kCurrentCWPanelListVersion, 1, &sPanelName };
 
388
        
 
389
        *panelList = &sPanelList;
 
390
        
 
391
        return cwNoErr;
 
392
}
 
393
 
 
394
CWPLUGIN_ENTRY(CWPlugin_GetTargetList)(const CWTargetList** targetList)
 
395
{
 
396
        static CWDataType sCPU = '****';
 
397
        static CWDataType sOS = '****';
 
398
        static CWTargetList sTargetList = { kCurrentCWTargetListVersion, 1, &sCPU, 1, &sOS };
 
399
        
 
400
        *targetList = &sTargetList;
 
401
        
 
402
        return cwNoErr;
 
403
}
 
404
 
 
405
CWPLUGIN_ENTRY(CWPlugin_GetDefaultMappingList)(const CWExtMapList** defaultMappingList)
 
406
{
 
407
        static CWExtensionMapping sExtension = { 'TEXT', ".idl", 0 };
 
408
        static CWExtMapList sExtensionMapList = { kCurrentCWExtMapListVersion, 1, &sExtension };
 
409
        
 
410
        *defaultMappingList = &sExtensionMapList;
 
411
        
 
412
        return cwNoErr;
 
413
}
 
414
 
 
415
#if CW_USE_PRAGMA_EXPORT
 
416
#pragma export off
 
417
#endif