gnuintfc.red 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. module gnuintfc; % REDUCE-gnuplot interface.
  2. % Authors: Anthony C. Hearn, Herbert Melenk, Arthur C. Norman.
  3. % The file complements the (notionally) generic file "gnuplot.red" to
  4. % provide system-specific interfaces between REDUCE and the gnuplot
  5. % package itself.
  6. fluid '(plotstyle!*);
  7. global '(!*plotinterrupts !*plotpause !*plotusepipe plotheader!*
  8. plotcleanup!* plottmp!*);
  9. !#if (member 'psl lispsystem!*)
  10. !#if (member 'unix lispsystem!*)
  11. !*plotusepipe:=t; % pipes: yes
  12. load pipes;
  13. !*plotpause:=nil; % pause: no
  14. plottmp!* := "/tmp/";
  15. if getenv "LOGNAME" then
  16. plottmp!* := bldmsg("%w%w.",plottmp!*,getenv "LOGNAME")
  17. else if getenv "USER" then
  18. plottmp!* := bldmsg("%w%w.",plottmp!*,getenv "USER");
  19. plotdta!* := for i:=1:10 collect
  20. bldmsg("%wplotdta%w*",plottmp!*,i); % scratch data files
  21. plotcmds!* :=bldmsg("%wplotcmds*",plottmp!*); % if pipes not accessible
  22. % select header lines for setting the appropriate GNUPLOT
  23. % terminal type.
  24. if null plotheader!* then
  25. << if null x then x:='(nil."dumb");
  26. plotheader!* := bldmsg("set term %w",cdr x);
  27. >>
  28. where x =
  29. assoc(getenv "TERM",
  30. '(
  31. %% You may want to extend or modify the terminal list above
  32. ("xterm" . "x11")
  33. ("sun-cmd" . "x11") ("sun" . "x11")
  34. ("hpterm" . "x11")
  35. ("vt52" . "tek40xx")
  36. ("vt100" . "tek40xx")
  37. ("vt102" . "tek40xx")
  38. ));
  39. % add $reduce/plot to the path when using X11 (gnuplot will load a child).
  40. plotcommand!*:=
  41. begin scalar p;
  42. if not(p:=getenv "gnuplot") then
  43. p:=bldmsg("%w/plot",getenv "reduce");
  44. return bldmsg("PATH=$PATH:%w;export PATH;gnuplot",p);
  45. end;
  46. plotcleanup!* := % delete scratch files
  47. {"rm /tmp/plotdt*","rm /tmp/plotcmds!*"};
  48. !*plotinterrupts := '(10002);
  49. !#elif (intersection '(dos os2 win32 winnt alphant) lispsystem!*)
  50. fluid '(!*!*windows);
  51. % the following system selection must be done at load time
  52. plottmp!* := bldmsg("%w\",getenv "tmp" or getenv "temp");
  53. if null plottmp!* then
  54. <<prin2t "warning: no TMP directory found. Using >C:<";
  55. plottmp!*:="c:";
  56. >>;
  57. !*plotpause:=nil; % no pause
  58. plotdta!* := for i:=1:10 collect
  59. bldmsg("%wplotdt%w.dat",plottmp!*,i); % scratch data files
  60. if member ('win95,lispsystem!*) then
  61. <<
  62. % for Win95 until we have something better
  63. % pass commands as parameter file
  64. % write command file and data to directory /tmp
  65. !*plotusepipe:=nil; % no pipes
  66. plotcmds!* := bldmsg("%w\plotcmds",plottmp!*);
  67. plotcommand!* :=
  68. % fnexpand bldmsg("$reduce\plot\wgnuplot.exe %w",plotcmds!*);
  69. fnexpand bldmsg("$reduce\wutil\win32\wgnuplot.exe %w",plotcmds!*);
  70. plotheader!* := "";
  71. plotcleanup!* := NIL; % delete scratch files
  72. !*plotpause := -1;
  73. copyd('plot!-exec,'system);
  74. flag('(plot!-exec),'lose);
  75. >> else
  76. if !*!*windows eq 1 or member('winnt,lispsystem!*)
  77. or member('win32 ,lispsystem!*) then
  78. <<
  79. % for windows:
  80. % use plot pipe
  81. load w!-pipes;
  82. !*plotusepipe:=t;
  83. plotcmds!* := bldmsg("%w\plotcmds",plottmp!*);;
  84. plotcommand!* := bldmsg(
  85. % "%w\plot\wgnupl32.exe;wgnuplot_parent;wgnuplot_text",
  86. % "%w\plot\wgnuplot.exe;wgnuplot_parent;wgnuplot_text",
  87. "%w\wutil\win32\wgnuplot.exe;wgnuplot_parent;wgnuplot_text",
  88. getenv("reduce"));
  89. plotheader!* := "";
  90. plotcleanup!* := % delete scratch files
  91. bldmsg("del %w",plotcmds!*) .
  92. for each f in plotdta!* collect bldmsg("del %w",f);
  93. >>
  94. else if member('os2,lispsystem!*) then
  95. <<
  96. !*plotusepipe:=nil; % no pipes
  97. plotcmds!* := bldmsg("%w\plotcmds",plottmp!*);
  98. plotcommand!* := "";
  99. plotheader!* := "";
  100. symbolic procedure plot!-exec u;
  101. <<
  102. prin2 "====> invoke GNUPLOT for file ";
  103. prin2t plotcmds!*;
  104. >>;
  105. loadtime flag('(plot!-exec),'lose);
  106. >>
  107. else
  108. <<
  109. % for dos:
  110. % pass commands as parameter file
  111. % write command file and data to directory /tmp
  112. !*plotusepipe:=nil; % no pipes
  113. plotcmds!* := bldmsg("%w\plotcmds",plottmp!*);
  114. plotcommand!* :=
  115. fnexpand bldmsg("$reduce\plot\gnuplot.exe %w",plotcmds!*);
  116. plotheader!* := "set term vga";
  117. plotcleanup!* := % delete scratch files
  118. bldmsg("del %w",plotcmds!*).
  119. for each f in plotdta!* collect bldmsg("del %w",f);
  120. >>;
  121. plotmax!* := 3e36; % IEEE single precision
  122. !*plotinterrupts := '(10002);
  123. !#elif (member 'vms lispsystem!*)
  124. !*plotusepipe:=NIL; % pipes: yes
  125. !*plotpause:=nil; % pause: no
  126. plottmp!* := "SYS$SCRATCH";
  127. plotdta!* := for i:=1:10 collect
  128. bldmsg("%w:plotdt%w",plottmp!*,i); % scratch data files
  129. plotcmds!* :=bldmsg("%w:plotcmds",plottmp!*); % if pipes not accessible
  130. plotcommand!* := bldmsg("gnuplot %w",plotcmds!*);
  131. plotheader!* := "set term x11"; % header: set terminal to X11
  132. plotcleanup!* := % delete scratch files
  133. {"del SYS$SCRATCH:plotdt*;*","del SYS$SCRATCH:plotcmds*;*"};
  134. !*plotinterrupts := '(10002);
  135. !#endif
  136. !#elif(member 'csl lispsystem!*)
  137. global '(plotdir!* dirchar!* opsys!* tempdir!*);
  138. symbolic procedure channelflush x;
  139. << x := wrs x; flush(); wrs x >>;
  140. symbolic procedure gtmpnam base;
  141. if null tempdir!* then base
  142. else compress ('!" . append(explodec tempdir!*,
  143. car explodec dirchar!* . cdr explode base));
  144. % In general I want the initialisation actions indicated here to be
  145. % obeyed at load-time. I achieve this by packaging them all inside
  146. % a function, which I then call. I could be even more CSL-specific by
  147. % using eval-when style options imported from the Common Lisp world...
  148. symbolic procedure init_gnuplot();
  149. <<
  150. !*plotpause := -1; % wait for newline from user
  151. % plotcleanup!* is a list of commands to be obeyed after a gnuplot run.
  152. % it is mainly needed to get rid of the data file (used even when pipes
  153. % are available).
  154. plotcleanup!* := {};
  155. tempdir!* := getenv 'tmp;
  156. if null tempdir!* then tempdir!* := getenv 'temp;
  157. dirchar!* := "/";
  158. plotcommand!* := "gnuplot";
  159. opsys!* := assoc('opsys, lispsystem!*);
  160. if null opsys!* then opsys!* := 'unknown
  161. else opsys!* := cdr opsys!*;
  162. % If a shell variable "gnuplot" is set it is expected to be the
  163. % directory within which gnuplot binaries can be found.
  164. if getenv "gnuplot" then plotdir!* := getenv "gnuplot"
  165. % Otherwise, and this is what I hope and expect to happen more often, I
  166. % will expect to find gnuplot in the same directory that REDUCE was
  167. % loaded from. This will all work wonderfully under Windows, but under Unix
  168. % there is a much greater chance that I will need to set an environment
  169. % variable "gnuplot". However, I still want to leave open the possibility
  170. % of plotdir!* being set.
  171. else if null plotdir!* and not (opsys!* = 'unix)
  172. then plotdir!* := get!-lisp!-directory();
  173. if opsys!* = 'win32 then <<
  174. % For Microsoft Windows use I try to use "wgnuplot" rather than "gnuplot",
  175. % and the options provided are copied from the PSL case above.
  176. plotcommand!* := "wgnuplot";
  177. plotheader!* := "";
  178. dirchar!* := "\";
  179. plotdta!* := for each n in
  180. {"gnutmp.tm1", "gnutmp.tm2", "gnutmp.tm3", "gnutmp.tm4",
  181. "gnutmp.tm5", "gnutmp.tm6", "gnutmp.tm7", "gnutmp.tm8"}
  182. collect gtmpnam n;
  183. plotcleanup!* := if null tempdir!* then {"erase gnutmp.tm*"}
  184. else {bldmsg("erase %w\gnutmp.tm*", tempdir!*)} >>
  185. else if opsys!* = 'msdos then <<
  186. % Under MSDOS the PSL version sets a VGA screen explicitly - that seems to
  187. % upset the version of gnuplot that I have to test. Also I find "tmpnam"
  188. % somewhat unhelpful, I can do a bit better (I hope) here.
  189. plotheader!* := ""; % ?? "set term vga";
  190. dirchar!* := "\";
  191. plotdta!* := for each n in
  192. {"gnutmp.tm1", "gnutmp.tm2", "gnutmp.tm3", "gnutmp.tm4",
  193. "gnutmp.tm5", "gnutmp.tm6", "gnutmp.tm7", "gnutmp.tm8"}
  194. collect gtmpnam n;
  195. plotcmds!*:= gtmpnam "gnutmp.tm0";
  196. plotcleanup!* := if null tempdir!* then {"erase gnutmp.tm*"}
  197. else {bldmsg("erase %w\gnutmp.tm*", tempdir!*)} >>
  198. else if opsys!* = 'riscos then <<
  199. % Under RiscOS I need to be running under the window system for GNUPLOT
  200. % to be available. I will not test for that here but will expect the
  201. % "PLOT" command to fail if run from the command line.
  202. plotheader!* := "";
  203. dirchar!* := ".";
  204. plotdta!* := for i:=1:10 collect tmpnam();
  205. plotcmds!*:= tmpnam();
  206. plotcleanup!* :=
  207. bldmsg("remove %w", plotcmds!*) .
  208. for each f in plotdta!* collect bldmsg("remove %w", f)
  209. >>
  210. else if opsys!* = 'unix then <<
  211. % For Unix I assume X11.
  212. plotheader!* := "set term x11";
  213. plotdta!* := for i:=1:10 collect tmpnam();
  214. plotcmds!*:= tmpnam();
  215. plotcleanup!* :=
  216. bldmsg("rm %w", plotcmds!*) .
  217. for each f in plotdta!* collect bldmsg("rm %w", f) >>
  218. else <<
  219. % Other systems set up for a dumb terminal. This is probably unsatisfactory,
  220. % but you can easily change the source here to adjust for what you want.
  221. % If you just comment out the "rederr" line you will have gnuplot working
  222. % in dumb-terminal mode.
  223. rederr bldmsg("gnuplot for %w not available yet", opsys!*);
  224. plotdta!* := for i:=1:10 collect tmpnam();
  225. plotcmds!*:= tmpnam();
  226. plotheader!* := "set term dumb" >>;
  227. % If there are no pipes available gnuplot will need a command-line
  228. % argument indicating where its input file is.
  229. if 'pipes member lispsystem!* then !*plotusepipe:=t
  230. else plotcommand!* := bldmsg("%w %w", plotcommand!*, plotcmds!*);
  231. % If I have a directory to look for gnuplot in I either just give a
  232. % full path or (under Unix) I temporarily switch current directories
  233. % to there.
  234. if plotdir!* then
  235. plotcommand!* := bldmsg("%w%w%w",
  236. plotdir!*, dirchar!*, plotcommand!*);
  237. % Under Windows 95 I want the plotting sub-task to finish before I
  238. % resume running REDUCE (and delete the temporary files). This may be an
  239. % area where Windows 95 and NT are not compatible. If so tough luck for now.
  240. % Actually if I am going to call wgnuplot rather than gnuplot this is
  241. % not a useful thing to do after all...
  242. % if 'win95 member lispsystem!* then
  243. % plotcommand!* := bldmsg("start /w %w", plotcommand!*);
  244. nil >>;
  245. init_gnuplot();
  246. !#endif
  247. endmodule;
  248. end;