home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / e / e032 / 3.ddi / FILES / PRELOAD.PAK / INSTALL.M < prev    next >
Encoding:
Text File  |  1992-07-29  |  3.4 KB  |  117 lines

  1.  
  2. Begin["System`"]
  3.  
  4. Install::usage = "Install[\"command\"] starts an external program and
  5. installs Mathematica definitions to call functions in it."
  6.  
  7. Reinstall::usage = "Reinstall[link] un-installs the specified external
  8. package and installs it again."
  9.  
  10. Uninstall::usage = "Uninstall[link] terminates an external program started
  11. by Install, and removes Mathematica definitions set up by it."
  12.  
  13. ThisLink::usage = "ThisLink is used in patterns for external packages
  14. to distinguish between several instances of the same package."
  15.  
  16. LinkPatterns::usage = "LinkPatterns[link] gives the list of patterns
  17. defined in the external package which is accessed via the specified link."
  18.  
  19.     
  20. ExternalCall DefineExternal CallPacket ReturnPacket EvaluatePacket
  21.  
  22. Begin["`Private`"]
  23.  
  24. Install[name_String, options___] := Block[ {$Context, ThisLink}, 
  25.     ThisLink = LinkOpen[name, options]; 
  26.     If[ThisLink === $Failed || Head[ThisLink] === LinkOpen,
  27.         ThisLink, 
  28.         ThisLink = ConnectToExternalPackage[ThisLink];
  29.         defineLinkObject[First[ThisLink], ThisLink];
  30.         ThisLink
  31.         ]
  32.     ]
  33.  
  34. Install[link_LinkObject] := Block[ {$Context, ThisLink = link}, 
  35.     ThisLink = ConnectToExternalPackage[ThisLink];
  36.     defineLinkObject[First[ThisLink], ThisLink];
  37.     ThisLink
  38.     ]
  39.  
  40. ConnectToExternalPackage[link_LinkObject] :=
  41.     Block[{ e, defined = {}, msgs}, 
  42.         msgs = Messages[General];
  43.         Off[General::spell1];
  44.         Off[General::spell];
  45.           While[
  46.             (e = LinkRead[link]) =!= End && e =!= $Failed, 
  47.              If[ StringQ[e], ToExpression[e]]
  48.         ];
  49.         SetDelayed @@ { LinkPatterns[link], defined};
  50.         Messages[General] = msgs;
  51.         link
  52.     ] 
  53.  
  54. ConnectToExternalPackage[_] := $Failed
  55.  
  56. defineLinkObject[s_String, link_LinkObject] := ( 
  57.     If[  Length[LinkObject[s]] != 1,
  58.         LinkObject[s]=.
  59.     ];
  60.     LinkObject[s] = link
  61.     )
  62.  
  63. defineLinkObject[__] = $Failed
  64.           
  65. DefineExternal[p_String, a_, n_] := Module[ {e},
  66.     e = Hold[_ :=  ExternalCall[ _, CallPacket[_, _]]] ;
  67.     e = ReplaceHeldPart[ e, ToHeldExpression[p], {1,1}];
  68.     e = ReplacePart    [ e, ThisLink, {1,2,1}];
  69.     e = ReplacePart    [ e, n, {1,2,2,1}];
  70.     e = ReplaceHeldPart[ e, ToHeldExpression[a], {1,2,2,2}];
  71.     ReleaseHold[e];
  72.     defined = Append[defined,
  73.         HoldForm @@ ToHeldExpression[p] /. Literal[ThisLink]->ThisLink]
  74.     ]
  75.  
  76.  
  77. ExternalCall[ link_LinkObject, packet_CallPacket] := 
  78.     If [LinkWrite[link, packet] =!= $Failed, 
  79.         ExternalAnswer[link, LinkRead[link]]
  80.     ]
  81.     (* Initial call - the link will answer either with 
  82.         ReturnPacket (final result), or with  EvaluatePacket *)
  83.         
  84. ExternalAnswer[ link_LinkObject, EvaluatePacket[expr_]] := 
  85.     If [LinkWrite[link, ReturnPacket[expr]] =!= $Failed, 
  86.         ExternalAnswer[ link, LinkRead[link]]
  87.     ]
  88.     (* having sent a ReturnPacket we get to the same state as after
  89.        the initial CallPacket. *)
  90.  
  91. ExternalAnswer[ link_LinkObject, ReturnPacket[result_]] := result
  92.  
  93. ExternalAnswer[ link_LinkObject, result_] := result
  94.  
  95. Uninstall[link_LinkObject] := ( LinkClose[link];
  96.     LinkPatterns[link] //. HoldForm -> Unset;
  97.     unset[linkPatterns[link]] //. {unset->Unset, linkPatterns -> LinkPatterns};
  98.     First[link]
  99.     )
  100.  
  101. Uninstall::unlink = "External package `1` has not been installed."
  102.  
  103. Uninstall[comm_String] := Module[{link = LinkObject[comm]},
  104.     If[ Length[link] > 1,
  105.         Uninstall[link]; ReleaseHold[Hold[LinkObject[x]=.]/. x :> comm]; comm,
  106.         Message[Uninstall::unlink, comm]
  107.     ] ]
  108.  
  109. Reinstall[l_] := Module[ {name = Uninstall[l]},
  110.     If [StringQ[name], Install[name]]
  111.     ]
  112.  
  113. End[]
  114.  
  115. End[]
  116.  
  117.