static CWResult Disassemble(CWPluginContext context) { 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; }
static CWResult LinkTypeLib(CWPluginContext context, XPIDLSettings& settings) { // 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; }
static CWResult LinkHeaders(CWPluginContext context, XPIDLSettings& settings) { // 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; }
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); long fileNum; err = CWGetMainFileNumber(context, &fileNum); if (!CWSUCCESS(err)) return (err); // get the name of the source file to compile. 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); #if 0 // if generating .xpt files, let the IDE tell us where to put the output file. // otherwise, put them in the project's output directory. if (settings.mode == kXPIDLModeTypelib) err = CWGetSuggestedObjectFileSpec(context, fileNum, &gOutputFile); else err = CWGetOutputFileDirectory(gPluginContext, &gOutputFile); #else // always generate the output file into the project target's data directory. err = CWGetSuggestedObjectFileSpec(context, fileNum, &gOutputFile); #endif if (!CWSUCCESS(err)) return (err); int argc = 3; char* modes[] = { "header", "java", "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; if (setjmp(exit_jump) == 0) { if (xpidl_main(argc, argv) != 0) err = cwErrRequestFailed; } else { // evidently the good old exit function got called. if (exit_status != 0) err = cwErrRequestFailed; } // if the compilation succeeded, tell CodeWarrior about the output file. // this ensures several things: 1. if the output file is deleted by the user, // then the IDE will know to recompile it, which is good for dirty builds, // where the output files may be hand deleted; 2. if the user elects to remove // objects, the output files are deleted. Thanks to [email protected] for // pointing this new CWPro4 API out. if (err == cwNoErr) { CWObjectData objectData; BlockZero(&objectData, sizeof(objectData)); // for fun, show how large the output file is in the data area. long dataSize, rsrcSize; if (FSpGetFileSize(&gOutputFile, &dataSize, &rsrcSize) == noErr) objectData.idatasize = dataSize; // tell the IDE that this file was generated by the compiler. objectData.objectfile = &gOutputFile; err = CWStoreObjectData(context, fileNum, &objectData); } else { // an error occured, delete the output file, which might be a partial file. if (gOutputFile.name[0] != 0) { ::FSpDelete(&gOutputFile); } } delete[] gSourcePath; gSourcePath = NULL; return (err); }
static CWResult mocify(CWPluginContext context, const QCString &source) { CWDisplayLines(context, line_count++); source.stripWhiteSpace(); CWResult err; bool dotmoc=false; QCString stem = source, ext; int dotpos = stem.findRev('.'); if(dotpos != -1) { ext = stem.right(stem.length() - (dotpos+1)); stem = stem.left(dotpos); if(ext == "cpp") dotmoc = true; } else { //whoa! } QCString dest; if(dotmoc) dest = stem + ".moc"; else dest = "moc_" + stem + ".cpp"; //moc it CWFileSpec destSpec; moc_status mocd = do_moc(context, source, dest, &destSpec, dotmoc); #if 0 QCString derr = "Weird"; switch(mocd) { case moc_success: derr = "Success"; break; case moc_parse_error: derr = "Parser Error"; break; case moc_no_qobject:derr = "No QOBJECT"; break; case moc_not_time: derr = "Not Time"; break; case moc_no_source: derr = "No Source"; break; case moc_general_error: derr = "General Error"; break; } char dmsg[200]; sprintf(dmsg, "\"%s\" %s", source.data(), derr.data()); CWReportMessage(context, NULL, dmsg, NULL, messagetypeError, 0); #endif //handle project if(mocd == moc_no_qobject) { char msg[400]; sprintf(msg, "\"%s\" No relevant classes found. No output generated.", source.data()); CWReportMessage(context, NULL, msg, NULL, messagetypeWarning, 0); } else if ((mocd == moc_success || mocd == moc_not_time) && !dotmoc) { long whichFile; CWNewProjectEntryInfo ei; memset(&ei, '\0', sizeof(ei)); ei.groupPath = "QtGenerated"; err = CWAddProjectEntry(context, &destSpec, true, &ei, &whichFile); if (!CWSUCCESS(err)) { char msg[200]; sprintf(msg, "\"%s\" not added", dest.data()); CWReportMessage(context, NULL, msg, NULL, messagetypeWarning, 0); } if(mocd == moc_success) CWSetModDate(context, &destSpec, NULL, true); } return cwNoErr; }