home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / e_mac / e_system.c < prev    next >
Encoding:
Text File  |  1997-07-25  |  5.9 KB  |  231 lines  |  [TEXT/CWIE]

  1. // e_system.c
  2. // 16May1997 e
  3.  
  4. // OSA AppleScript: compile, execute, display, error, dispose
  5. // system() uses OSA AppleScript to execute its script arg
  6.  
  7. // see: IM: Interapplication Communication chapter 10
  8.  
  9. #include "memory.h"
  10. #include "str.h"
  11. #include <errno.h>
  12. #include <string.h>
  13.  
  14. static ComponentInstance gScriptingComponent;
  15.  
  16. static void eOpenCompilingComponent( void )
  17. {
  18.   ComponentDescription     descr;
  19.   Component               aComponent;
  20.   ComponentInstance     aScriptingComponent;
  21.   
  22. #ifndef __MC68K__
  23.  
  24.   if( OSACompile == NULL ) // kUnresolvedSymbolAddress
  25.   {
  26.     gScriptingComponent = NULL; // for good measure
  27.     return;
  28.   }
  29. #endif
  30.  
  31.     descr.componentType         = kOSAComponentType;
  32.     descr.componentSubType      = kAppleScriptSubtype;
  33.     descr.componentManufacturer = (OSType) 0;
  34.     descr.componentFlags        = kOSASupportsCompiling + 
  35.                                 kOSASupportsAECoercion + 
  36.                                 kOSASupportsAESending +
  37.                                 kOSASupportsConvenience +
  38.                                 kOSASupportsEventHandling;
  39.     descr.componentFlagsMask    = descr.componentFlags;
  40.     
  41.     aComponent = FindNextComponent( NULL, &descr );
  42.         
  43.     if ( aComponent )
  44.         aScriptingComponent = OpenComponent( aComponent );
  45.         if ( aScriptingComponent )
  46.         gScriptingComponent = aScriptingComponent;
  47. }
  48.  
  49. #define CHECK_INIT_OSA \
  50.   if( !gScriptingComponent ) \
  51.   { eOpenCompilingComponent(); \
  52.     if( !gScriptingComponent ) { err = errOSACantOpenComponent; goto done; } }
  53.  
  54. /// ******************************* system *********************************
  55.  
  56. int e_system( const char *script )
  57. {
  58.   OSAError err;
  59.   long len;
  60.   AEDesc src = { typeNull, NULL };
  61.   OSAID res = kOSANullScript;
  62.   OSAID obj = kOSANullScript;
  63.   
  64.   CHECK_INIT_OSA
  65.  
  66.   len = strlen( script );
  67.   /*
  68.   src.dataHandle = NewHandle( len );
  69.   src.descriptorType = typeChar;
  70.   if( ! src.dataHandle )
  71.     return -1;
  72.   HLock( src.dataHandle );
  73.   memcpy( *src.dataHandle, script, len );
  74.   HUnlock( src.dataHandle );
  75.   */
  76.   err = AECreateDesc( typeChar, script, len, &src );
  77.   if( err != noErr ) goto done;
  78.   
  79.   // err = OSACompileExecute( gScriptingComponent, &src, kOSANullScript, kOSAModeNull, &rsv );
  80.   // the above would work, but the following is better for MW debugging
  81.   
  82.   err = OSACompile( gScriptingComponent, &src, kOSAModeNull, &obj );
  83.   if( err == noErr )
  84.   {
  85.     err = OSAExecute( gScriptingComponent, obj, kOSANullScript, kOSAModeNull, &res );
  86.   }
  87.   else
  88.   {
  89.     AEDesc dsc;
  90.     OSAScriptError( gScriptingComponent, kOSAErrorMessage, typeChar, &dsc );
  91.     AEDisposeDesc( &dsc );
  92.   }
  93.   OSADispose( gScriptingComponent, obj );
  94.   OSADispose( gScriptingComponent, res );
  95. done:
  96.   AEDisposeDesc( &src );
  97.   if( err < 0 )
  98.   {
  99.     errno = err;
  100.     return -1;
  101.   }
  102.   return 0;
  103. }
  104.  
  105. /// ******************************* scripting *********************************
  106.  
  107. /*
  108. OSAID : double;
  109. OSAError : int;
  110. OSA_oid : { err : OSAError,  id : OSAID  };
  111. OSA_str : { err : OSAError, str : string };
  112. mac_OSACompile : string -> OSA_oid
  113. mac_OSAExecute : OSAID  -> OSA_oid
  114. mac_OSADisplay : OSAID  -> OSA_str
  115. mac_OSAScriptError :  _ -> OSA_str
  116. mac_OSADispose : OSAID  -> OSAError
  117. */
  118.  
  119. #define OSA_REC_SIZE 2
  120. #define OSA_REC_ERR 0
  121. #define OSA_REC_ID  1
  122. #define OSA_REC_STR 1
  123.  
  124. value mac_OSACompile( value v )
  125. {
  126.   OSAError err;
  127.   char *script;
  128.   AEDesc src = { typeNull, NULL };
  129.   long len;
  130.   value res;
  131.   OSAID obj = kOSANullScript;
  132.   Push_roots(r, 2);
  133.   r[1] = v;
  134.   r[0] = alloc( OSA_REC_SIZE, 0 );  
  135.   CHECK_INIT_OSA
  136.   len = strlen( (script = String_val( r[1] )) );
  137.   err = AECreateDesc( typeChar, script, len, &src );
  138.   if( err == noErr )
  139.     err = OSACompile( gScriptingComponent, &src, kOSAModeNull, &obj );
  140.   AEDisposeDesc( &src );
  141. done:
  142.   Field (r[0], OSA_REC_ERR) = Val_long( (short )err );
  143.   Field (r[0], OSA_REC_ID)  = copy_double( (double )obj );
  144.   res = r[0];
  145.   Pop_roots();
  146.   return res;
  147. }
  148.  
  149. value mac_OSAExecute( value v )
  150. {
  151.   OSAError err;
  152.   OSAID rsv = kOSANullScript;
  153.   OSAID scp = (OSAID )Double_val( v );
  154.   value res;
  155.   Push_roots(r, 1);
  156.   r[0] = alloc( OSA_REC_SIZE, 0 );  
  157.   CHECK_INIT_OSA
  158.   err = OSAExecute( gScriptingComponent, scp, kOSANullScript, kOSAModeNull, &rsv );
  159. done:
  160.   Field (r[0], OSA_REC_ERR) = Val_long( (short )err );
  161.   Field (r[0], OSA_REC_ID)  = copy_double( (double )rsv );
  162.   res = r[0];
  163.   Pop_roots();
  164.   return res;
  165. }
  166.  
  167. value mac_OSADispose( value v )
  168. {
  169.   OSAError err;
  170.   OSAID rsv = (OSAID )Double_val( v );
  171.   CHECK_INIT_OSA
  172.   err = OSADispose( gScriptingComponent, rsv );
  173. done:
  174.   return Val_long( (short )err );;
  175. }
  176.  
  177. static value copy_handle( Handle h )
  178. {
  179.   long len = GetHandleSize( h );
  180.   value str = alloc_string( len );
  181.   HLock( h );
  182.   bcopy( *h, String_val( str ), len );
  183.   HUnlock( h );
  184.   return str;
  185. }
  186.  
  187. value mac_OSADisplay( value v ) // kOSAModeDisplayForHumans option?
  188. {
  189.   OSAError err;
  190.   value res, str;
  191.   OSAID rsv = (OSAID )Double_val( v );
  192.   AEDesc dsc = { typeNull, NULL };
  193.   Push_roots(r, 1);
  194.   r[0] = alloc( OSA_REC_SIZE, 0 );  
  195.   CHECK_INIT_OSA
  196.   err = OSADisplay( gScriptingComponent, rsv, typeChar, kOSAModeNull, &dsc );
  197.   str = ( err == noErr ) ? copy_handle( dsc.dataHandle ) : copy_string( "" );
  198.   AEDisposeDesc( &dsc );
  199. done:
  200.   Field (r[0], OSA_REC_ERR) = Val_long( (short )err );
  201.   Field (r[0], OSA_REC_STR) = str;
  202.   res = r[0];
  203.   Pop_roots();
  204.   return res;
  205. }
  206.  
  207. value mac_OSAScriptError( value v )
  208. {
  209.   #pragma unused( v )
  210.   OSAError err;
  211.   value res, str;
  212.   AEDesc dsc = { typeNull, NULL };
  213.   Push_roots(r, 1);
  214.   r[0] = alloc( OSA_REC_SIZE, 0 );  
  215.   CHECK_INIT_OSA
  216.   err = OSAScriptError( gScriptingComponent, kOSAErrorMessage, typeChar, &dsc );
  217.   str = ( err == noErr ) ? copy_handle( dsc.dataHandle ) : copy_string( "" );
  218.   AEDisposeDesc( &dsc );
  219.   err = OSAScriptError( gScriptingComponent, kOSAErrorNumber, typeShortInteger, &dsc );
  220.   if( err == noErr ) err = **(short **)dsc.dataHandle;
  221.   AEDisposeDesc( &dsc );
  222. done:
  223.   Field (r[0], OSA_REC_ERR) = Val_long( (short )err );
  224.   Field (r[0], OSA_REC_STR) = str;
  225.   res = r[0];
  226.   Pop_roots();
  227.   return res;
  228. }
  229.  
  230. // end.
  231.