home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Add-Ons / CodeWarrior / Script Executor 1.0b2 / Compiler / Script Executor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-19  |  9.1 KB  |  419 lines  |  [TEXT/CWIE]

  1.  
  2. /*
  3.  *    Script Executor.c
  4.  *
  5.  *  © 1997 Michael Schuerig
  6.  *
  7.  */
  8.  
  9. /* system headers */
  10. #include <OSA.h>
  11. #include <Resources.h>
  12. #include <TextUtils.h>
  13.  
  14. /* compiler headers */
  15. #include <A4Stuff.h>
  16. #include <DropInCompilerLinker.h>
  17.  
  18. #define kScriptResID 128
  19. #define kStringsID 1000
  20. #define kScriptInd 1
  21. #define kFolderInd 2
  22.  
  23. #define kScriptExEventClass 'ScEx'
  24. #define kCompileEventID 'Comp'
  25. #define keyDestFolder 'dFld'
  26.  
  27.  
  28. /* prototypes of local functions */
  29. static OSErr    Compile(const CompilerLinkerParameterBlock* cpb);
  30. static OSErr    ProcessFile(const CompilerLinkerParameterBlock* cpb, const FSSpecPtr srcFile, const FSSpecPtr destDir);
  31.  
  32. static OSErr    LoadScriptingComponent(void);
  33. static OSErr    ReleaseScriptingComponent(void);
  34. static OSErr    LoadScript(const CompilerLinkerParamBlkPtr cpb);
  35. static OSErr    ReleaseScript(void);
  36.  
  37. static OSErr    CreateCompileEvent(const FSSpecPtr sourceFile, const FSSpecPtr destFolder, AppleEvent* compileEvent);
  38. static OSErr    HandleCompileError(const CompilerLinkerParameterBlock* cpb);
  39.  
  40. static OSErr    SetupTempFileTemplate(const CompilerLinkerParamBlkPtr cpb, FSSpecPtr tempFileTmpl);
  41. static OSErr    FindWorkFile(const CompilerLinkerParameterBlock* cpb, FSSpecPtr workFile);
  42.  
  43.  
  44. /* local variables */
  45. static FSSpec gScriptFile;
  46. static FSSpec gTempFileTmpl;
  47. static ComponentInstance gScriptingComponent;
  48. static OSAID gScript;
  49.  
  50. #define kNoFile -1
  51.  
  52. #define CheckErr(e)        \
  53.     do { if ((e) != noErr) { err = (e); goto exit; } } while (0)
  54.  
  55.  
  56. /*
  57.  *    main    -    main entry-point for Drop-In ScriptEx Tool
  58.  *
  59.  */
  60.  
  61. pascal short main(CompilerLinkerParameterBlockPtr cpb)
  62. {
  63.     short        result;
  64.     
  65.     /* set up global world (68K only) */
  66.     EnterCodeResource();
  67.     
  68.     result = noErr;
  69.         
  70.     /* dispatch on compiler request */
  71.     switch (cpb->request)
  72.     {
  73.     case reqInitCompiler:
  74.         /* compiler has just been loaded into memory */
  75.         result = LoadScriptingComponent();
  76.         if (result == noErr)
  77.             result = LoadScript(cpb);
  78.         
  79.         if (result == noErr)
  80.             result = SetupTempFileTemplate(cpb, &gTempFileTmpl);
  81.         break;
  82.         
  83.     case reqTermCompiler:
  84.         /* compiler is about to be unloaded from memory */
  85.         result = ReleaseScript();
  86.         if (result == noErr)
  87.             result = ReleaseScriptingComponent();
  88.         
  89.         break;
  90.         
  91.     case reqCompile:
  92.         /* compile a source file */
  93.         result = (Compile(cpb) == noErr);
  94.         break;
  95.         
  96.     default:
  97.         result = paramErr;
  98.         break;
  99.     }
  100.     
  101.     /* tear down global world (68K only) */
  102.     ExitCodeResource();
  103.     
  104.     /* return result code */
  105.     return result;
  106. }
  107.  
  108.  
  109. static OSErr    Compile(const CompilerLinkerParameterBlock* cpb)
  110. {
  111.     FSSpec    workFile;
  112.     FSSpec    destFolder;
  113.     OSErr    err;
  114.  
  115.     err = FSMakeFSSpec((cpb->sourcefile).vRefNum, (cpb->sourcefile).parID, "\p", &destFolder);
  116.     CheckErr(err);
  117.     
  118.     err = FindWorkFile(cpb, &workFile);
  119.     CheckErr(err);
  120.     
  121.     err = ProcessFile(cpb, &workFile, &destFolder);
  122.  
  123. exit:    
  124.     return err;
  125. }
  126.  
  127.  
  128. static OSErr    ProcessFile(const CompilerLinkerParameterBlock* cpb, const FSSpecPtr srcFile, const FSSpecPtr destFolder)
  129. {
  130.     AppleEvent    compileEvent;
  131.     OSAID        scriptResult = kOSANullScript;
  132.     OSErr        err = noErr;
  133.     
  134.     compileEvent.descriptorType = typeNull;
  135.     compileEvent.dataHandle = nil;
  136.  
  137.     err = CreateCompileEvent(srcFile, destFolder, &compileEvent);
  138.     CheckErr(err);
  139.     
  140.     err = (OSErr)OSAExecuteEvent(gScriptingComponent, &compileEvent, gScript, kOSAModeNull, &scriptResult);
  141.     if (err == errOSAScriptError)
  142.     {
  143.         err = HandleCompileError(cpb);
  144.     }
  145.     
  146.     CheckErr(err);
  147.     
  148.     
  149. exit:
  150.     OSADispose(gScriptingComponent, scriptResult);
  151.  
  152.     if (compileEvent.dataHandle != nil)
  153.         AEDisposeDesc(&compileEvent);
  154.  
  155.     return err;
  156. }
  157.  
  158.  
  159. static OSErr    LoadScriptingComponent(void)
  160. {
  161.     OSErr    err = noErr;
  162.  
  163.     gScriptingComponent = OpenDefaultComponent(kOSAComponentType, kOSAGenericScriptingComponentSubtype);
  164.  
  165.     if (gScriptingComponent == nil)
  166.         err = (OSErr)errOSACantOpenComponent;
  167.  
  168.     return err;
  169. }
  170.  
  171.  
  172. static OSErr    ReleaseScriptingComponent(void)
  173. {
  174.     OSErr    err = noErr;
  175.     
  176.     err = (OSErr)CloseComponent(gScriptingComponent);
  177.  
  178.     return err;
  179. }
  180.  
  181.  
  182. static OSErr    LoadScript(const CompilerLinkerParamBlkPtr cpb)
  183. {
  184.     FSSpecPtr    project = &cpb->targetfile;
  185.     Str255        scriptFileName;
  186.     short        scriptFileRef = kNoFile;
  187.     AEDesc        scriptDesc = { typeNull, nil };
  188.     OSErr        err = noErr;
  189.     
  190.     
  191.     GetIndString(scriptFileName, kStringsID, kScriptInd);
  192.     CheckErr(ResError());
  193.     
  194.     
  195.     err = FSMakeFSSpec(project->vRefNum, project->parID, scriptFileName, &gScriptFile);
  196.     CheckErr(err);
  197.     
  198.  
  199.     scriptFileRef = FSpOpenResFile(&gScriptFile, fsRdWrPerm);
  200.     CheckErr(ResError());
  201.  
  202.  
  203.     scriptDesc.descriptorType = typeOSAGenericStorage;
  204.     scriptDesc.dataHandle = Get1Resource(kOSAScriptResourceType, kScriptResID);
  205.     CheckErr(ResError());    
  206.     
  207.     err = OSALoad(gScriptingComponent, &scriptDesc, kOSAModeNull, &gScript);
  208.     
  209. exit:
  210.     if (scriptDesc.dataHandle != nil)
  211.         ReleaseResource(scriptDesc.dataHandle);
  212.     
  213.     if (scriptFileRef != kNoFile)
  214.         CloseResFile(scriptFileRef);
  215.  
  216.     return err;
  217. }
  218.  
  219.  
  220. static OSErr    ReleaseScript(void)
  221. {
  222.     long    hasChanged;
  223.     AEDesc    scriptDesc = { typeNull, nil };
  224.     short    scriptFileRef = kNoFile;
  225.     Handle    scriptRes = nil;
  226.     OSErr    err = noErr;
  227.     
  228.         
  229.     err = (OSErr)OSAGetScriptInfo(gScriptingComponent, gScript, kOSAScriptIsModified, &hasChanged);
  230.     
  231.     if (hasChanged)
  232.     {                
  233.         err = (OSErr)OSAStore(gScriptingComponent, gScript, typeOSAGenericStorage, kOSAModeNull, &scriptDesc);
  234.         CheckErr(err);
  235.  
  236.  
  237.         scriptFileRef = FSpOpenResFile(&gScriptFile, fsRdWrPerm);
  238.         CheckErr(ResError());
  239.                 
  240.         scriptRes = Get1Resource(kOSAScriptResourceType, kScriptResID);        
  241.         CheckErr(ResError());
  242.         
  243.         SetHandleSize(scriptRes, 0);
  244.         
  245.         HLock(scriptDesc.dataHandle);
  246.         err = HandAndHand(scriptDesc.dataHandle, scriptRes);        
  247.         HUnlock(scriptDesc.dataHandle);
  248.             
  249.         if (err == noErr)
  250.         {
  251.             ChangedResource(scriptRes);
  252.             WriteResource(scriptRes);
  253.             ReleaseResource(scriptRes);
  254.         }
  255.     }
  256.     
  257. exit:
  258.  
  259.     if (gScript != kOSANullScript)
  260.         OSADispose(gScriptingComponent, gScript);
  261.  
  262.  
  263.     if (scriptDesc.dataHandle != nil)
  264.         AEDisposeDesc(&scriptDesc);
  265.         
  266.     if (scriptFileRef != kNoFile)
  267.         CloseResFile(scriptFileRef);
  268.  
  269.     return err;
  270. }
  271.  
  272.  
  273. static OSErr    CreateCompileEvent(const FSSpecPtr sourceFile, const FSSpecPtr destFolder, AppleEvent *compileEvent)
  274. {
  275.     AEAddressDesc    target = { typeNull, nil };
  276.     OSErr            err;
  277.     
  278.     err = AECreateAppleEvent(kScriptExEventClass, kCompileEventID, &target, kAutoGenerateReturnID, kAnyTransactionID, compileEvent);
  279.     CheckErr(err);
  280.     
  281.     err = AEPutParamPtr(compileEvent, keyDirectObject, typeFSS, sourceFile, sizeof(*sourceFile));
  282.     CheckErr(err);
  283.     
  284.     err = AEPutParamPtr(compileEvent, keyDestFolder, typeFSS, destFolder, sizeof(*destFolder));
  285.     CheckErr(err);
  286.  
  287. exit:
  288.     return err;
  289. }
  290.  
  291.  
  292. static OSErr    HandleCompileError(const CompilerLinkerParameterBlock* cpb)
  293. {
  294.     AEDesc    errMsg = { typeNull, nil };
  295.     AEDesc    errNum = { typeNull, nil };
  296.     OSErr    err;
  297.         
  298.     err = OSAScriptError(gScriptingComponent, kOSAErrorMessage, typeChar, &errMsg);
  299.     CheckErr(err);
  300.     
  301.     {
  302.         char EOS = '\0';
  303.         err = PtrAndHand(&EOS, errMsg.dataHandle, 1);
  304.         CheckErr(err);
  305.     }
  306.     
  307.     err = OSAScriptError(gScriptingComponent, kOSAErrorNumber, typeShortInteger, &errNum);
  308.     CheckErr(err);
  309.     
  310.     HLock(errMsg.dataHandle);
  311.     HLock(errNum.dataHandle);
  312.     err = CWOSErrorMessage(cpb, *(errMsg.dataHandle), **(short**)(errNum.dataHandle), kCompilerMessage);
  313.     HUnlock(errMsg.dataHandle);
  314.     HUnlock(errNum.dataHandle);
  315.     if (err == userCanceledErr)
  316.         err = noErr;
  317.  
  318.     
  319. exit:
  320.  
  321.     if (errMsg.dataHandle != nil)
  322.         AEDisposeDesc(&errMsg);
  323.  
  324.     if (errNum.dataHandle != nil)
  325.         AEDisposeDesc(&errNum);
  326.  
  327.     return err;
  328. }
  329.  
  330.  
  331. static OSErr    SetupTempFileTemplate(const CompilerLinkerParamBlkPtr cpb, FSSpecPtr tempFileTmpl)
  332. {
  333.     FSSpecPtr    project = &cpb->targetfile;
  334.     Str255        tempFolderName;
  335.     FSSpec        tempFolder;
  336.     OSErr        err = noErr;
  337.     
  338.     GetIndString(tempFolderName, kStringsID, kFolderInd);
  339.     CheckErr(ResError());
  340.     
  341.     
  342.     err = FSMakeFSSpec(project->vRefNum, project->parID, tempFolderName, &tempFolder);
  343.     if (err == fnfErr)
  344.     {
  345.         err = FSpDirCreate(&tempFolder, smSystemScript, &(tempFileTmpl->parID));
  346.     }
  347.     else if (err == noErr)
  348.     {
  349.         CInfoPBRec    cInfo;
  350.  
  351.         cInfo.dirInfo.ioCompletion = nil;
  352.         cInfo.dirInfo.ioNamePtr = (StringPtr)&(tempFolder.name);
  353.         cInfo.dirInfo.ioVRefNum = tempFolder.vRefNum;
  354.         cInfo.dirInfo.ioDrDirID = tempFolder.parID;
  355.         cInfo.dirInfo.ioFDirIndex = 0;
  356.         
  357.         err = PBGetCatInfoSync(&cInfo);
  358.         CheckErr(err);
  359.         
  360.         tempFileTmpl->vRefNum = cInfo.dirInfo.ioVRefNum;
  361.         tempFileTmpl->parID = cInfo.dirInfo.ioDrDirID;
  362.     }
  363.     
  364. exit:
  365.     return err;
  366. }
  367.  
  368.  
  369. static OSErr    FindWorkFile(const CompilerLinkerParameterBlock* cpb, FSSpecPtr workFile)
  370. {
  371.     Handle    source = cpb->sourcehandle;
  372.     OSErr    err = noErr;
  373.     
  374.     
  375.     if (source == nil)
  376.     {
  377.         // File is *not* open in the IDE so use it
  378.         BlockMoveData(&(cpb->sourcefile), workFile, sizeof(FSSpec));        
  379.     }
  380.     else
  381.     {
  382.         short    refNum;
  383.         long    inOutCount = cpb->sourcehandlesize;
  384.         OSErr    err2;
  385.         
  386.         // File *is* open in the IDE, make a working copy
  387.         
  388.         err = FSMakeFSSpec(gTempFileTmpl.vRefNum, gTempFileTmpl.parID, (cpb->sourcefile).name, workFile);
  389.         if (err == fnfErr)
  390.         {
  391.             FInfo    fndrInfo;
  392.             
  393.             err = FSpGetFInfo(&(cpb->sourcefile), &fndrInfo);
  394.             CheckErr(err);
  395.             err = FSpCreate(workFile, fndrInfo.fdCreator, fndrInfo.fdType, smSystemScript);
  396.         }
  397.         CheckErr(err);
  398.         
  399.         err = FSpOpenDF(workFile, fsRdWrPerm, &refNum);
  400.         CheckErr(err);
  401.         
  402.         err = SetEOF(refNum, inOutCount); // !
  403.         CheckErr(0);
  404.         
  405.         HLock(source);
  406.         err = FSWrite(refNum, &inOutCount, *source);
  407.         HUnlock(source);
  408.         
  409.         err2 = FSClose(refNum);
  410.         err = (err != noErr) ? err : err2;
  411.         
  412.         // ••• FlushVol?
  413.     }
  414.  
  415. exit:
  416.     return err;
  417. }
  418.  
  419.