home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / fp / ifp_unix.lzh / ifp / interp / command.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-23  |  9.6 KB  |  432 lines

  1.  
  2. /****** command.c *****************************************************/
  3. /**                                                                  **/
  4. /**                    University of Illinois                        **/
  5. /**                                                                  **/
  6. /**                Department of Computer Science                    **/
  7. /**                                                                  **/
  8. /**   Tool: IFP                         Version: 0.5                 **/
  9. /**                                                                  **/
  10. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  11. /**                                                                  **/
  12. /**   Revised by: Arch D. Robison       Date:  Jan 28, 1987          **/
  13. /**                                                                  **/
  14. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  15. /**                            Prof. W. J. Kubitz                    **/
  16. /**                                                                  **/
  17. /**                                                                  **/
  18. /**------------------------------------------------------------------**/
  19. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  20. /**                       All Rights Reserved.                       **/
  21. /**********************************************************************/
  22.  
  23. /*************************** Command Interpreter **************************/
  24.  
  25.  
  26. #include <stdio.h>
  27. #include <errno.h>
  28. #include "struct.h"
  29. #include "node.h"
  30. #include "umax.h"
  31. #include "inob.h"
  32. #include "cache.h"
  33. #include "stats.h"
  34.  
  35. #if OPSYS==UNIX
  36. #include <strings.h>
  37. #include <sys/wait.h>
  38. #endif
  39.  
  40. #if OPSYS==MSDOS
  41. #include "/usr/include/dos/spawn.h"     /* Full name so lint can find it */
  42. #include "/usr/include/dos/string.h"
  43. #endif
  44.  
  45. extern char EditorPath [],*EdCommand;
  46. extern char *getenv ();
  47.  
  48. extern boolean RefCheck ();        /* from apply.c */
  49.  
  50. #if OPSYS==UNIX
  51. extern fork (),execl ();
  52. #endif
  53.  
  54. InDesc UserIn;
  55.  
  56. /*
  57.  * ReadNode
  58.  */
  59. private NodePtr ReadNode (U)
  60.    InDesc *U;
  61.    {
  62.       Object S;
  63.  
  64.       if (!InNode (U,&S,NIL)) return NULL;
  65.       LinkPath (&S);
  66.       if (S.Tag == NODE) return S.Node;
  67.       else {
  68.      printf ("Error: ");
  69.      OutString (S.String);
  70.      printf (" not defined\n");
  71.      return NULL;
  72.       }
  73.    }
  74.  
  75. #if REFCHECK
  76. /*
  77.  * ShowRefCheck
  78.  */
  79. void ShowRefCheck ()
  80.    {
  81.       Object F;
  82.       register InDesc *U;
  83.  
  84.       U = &UserIn;
  85.       F.Tag = BOTTOM;
  86.  
  87.       (void) InComp (U,&F,NIL);
  88.       (void) RefCheck ((NodePtr) NULL,&F);
  89.       RepTag (&F,BOTTOM);
  90.    }
  91. #endif
  92.  
  93.  
  94. /*
  95.  * ShowApply
  96.  */
  97. private void ShowApply (OutGraph)
  98.    int OutGraph;
  99.    {
  100.       Object X,F;
  101.       register InDesc *U;
  102.  
  103.       U = &UserIn;
  104.       X.Tag = BOTTOM;
  105.       F.Tag = BOTTOM;
  106.       if (InObject (U,&X)) {
  107.  
  108.      if (!IsTok (U,":")) (void) InError (U,"colon expected");
  109.      else {
  110.         (void) InComp (U,&F,NIL);
  111.         if (Debug & DebugFile) {
  112.            printf ("Object = "); OutObject (&X); printf ("\n");
  113.            printf ("Function = "); OutFun (&F,MaxInt); printf ("\n");
  114.         }
  115.  
  116.         if (*U->InPtr) (void) InError (U,"extra character on line");
  117.         else {
  118.            U->InPtr++;
  119.               ClearCache ();
  120.               Apply (&X,&F);
  121. #ifdef GRAPHICS
  122.               if (OutGraph) DrawObject (&X);
  123.               else OutPretty (&X,0);
  124. #else
  125.               OutPretty (&X,0);
  126.               printf ("\n");
  127. #endif
  128.         }
  129.      }
  130.       }
  131.       RepTag (&X,BOTTOM);
  132.       RepTag (&F,BOTTOM);
  133.    }
  134.  
  135. /*
  136.  * ExecFile
  137.  *
  138.  * Execute a file
  139.  *
  140.  * Input
  141.  *      Prog = program to be executed
  142.  *      Arg  = argument string
  143.  */
  144. void ExecFile (Prog,Arg)
  145.    char *Prog,*Arg;
  146.    {
  147.       if (Debug & DebugFile) printf ("ExecFile (%s,%s)\n",Prog,Arg);
  148. #if OPSYS==UNIX
  149.       if (fork ()) (void) wait ((union wait *)NULL);
  150.       else {
  151.      if (Debug & DebugFile) printf ("prepare to flush\n");
  152.      (void) fflush (stdout);
  153.      execl (Prog,Prog,Arg,(char *)NULL);
  154.      perror (Prog);
  155.      exit (1);
  156.       }
  157. #endif
  158. #if OPSYS==MSDOS
  159.       if (spawnl (P_WAIT,Prog,Prog,Arg,(char *)NULL)) perror (Prog);
  160. #endif
  161.    }
  162.  
  163. void ExecEdit (FileName)
  164.    char *FileName;
  165.    {
  166.       if (Debug & DebugFile) printf ("ExecEdit (%s)\n",FileName);
  167. #if OPSYS==UNIX
  168.       ExecFile (EditorPath,FileName);
  169. #endif
  170. #if OPSYS==MSDOS
  171.       {
  172.      extern char *PathSplit ();
  173.      char *T;
  174.      T = PathSplit (FileName);
  175.      if (T != NULL) ExecFile (EditorPath,T);
  176.       }
  177. #endif
  178.    }
  179.  
  180. /*
  181.  * EditRm
  182.  *
  183.  * Action depends on ``Edit'' flag:
  184.  *
  185.  * Edit
  186.  *     Apply the user's editor to a function or import file.  If a function,
  187.  *     delete the function definition from memory. If %IMPORT file, reread it.
  188.  *
  189.  * !Edit
  190.  *     Remove a function definition or %IMPORT file.
  191.  */
  192. private void EditRm (U,Edit)
  193.    register InDesc *U;
  194.    boolean Edit;
  195.    {
  196.       Object N;
  197.       char Buf[MAXPATH+1];
  198.       static char *Import = "%IMPORT";
  199.    
  200.       if (Debug & DebugFile) printf ("EditRm (%s,%d)\n",U->InPtr,Edit);
  201.  
  202.       if (IsTok (U,Import)) {
  203.  
  204.      if (Edit) ExecFile (EditorPath,Import);
  205.      else 
  206.         if (unlink (Import)) perror (Import);
  207.      DelImport (U->InDefMod);
  208.      ReadImport (U->InDefMod);
  209.  
  210.       } else {
  211.  
  212.      N.Tag = BOTTOM;
  213.      (void) InNode (U,&N,NIL);
  214.      LinkPath (&N);
  215.  
  216.      /* Kill old source code definition */
  217.      if (N.Tag == NODE)
  218.         switch (N.Node->NodeType) {
  219.            case DEF:
  220.           RepTag (&N.Node->NodeData.NodeDef.DefCode,BOTTOM);
  221.           break;
  222.            case MODULE:
  223.           break;
  224.         }
  225.  
  226.      FormPath (&N,Buf,&Buf[MAXPATH]);
  227.      RepTag (&N,BOTTOM);
  228.      if (Edit) ExecEdit (Buf);
  229.      else
  230.         if (unlink (Buf)) perror (Buf);
  231.       }
  232.    }
  233.  
  234. #if OPSYS==UNIX
  235. /*
  236.  * Shell
  237.  *
  238.  * Execute a shell command
  239.  */
  240. void Shell (U)
  241.    register InDesc *U;
  242.    {
  243.       if (Debug & DebugFile) printf ("Shell: '%s'\n",U->InPtr);
  244.       if (fork ()) (void) wait ((union wait *)NULL);
  245.       else {
  246.      (void) fflush (stdout);
  247.      execl ("/bin/sh","sh","-c",U->InPtr,(char *)NULL);
  248.       }
  249.    }
  250. #endif
  251. #if OPSYS==MSDOS
  252. /*
  253.  * ChDirToCWD
  254.  *
  255.  * Set DOS current working directory to IFP current working directory.
  256.  *
  257.  * This procedure is a necessary KLUDGE because the current directory
  258.  * cache mechanism changes the current working directory all over the place.
  259.  */
  260. void ChDirToCWD ()
  261.    {
  262.       char Buf[MAXPATH];
  263.       extern char *FormNPath ();
  264.  
  265.       (void) FormPath (CurWorkDir,Buf,&Buf[MAXPATH]);
  266.       chdir (Buf);
  267.    }
  268.  
  269. /*
  270.  * Directory
  271.  *
  272.  * Show the current directory
  273.  */
  274. void Directory (U)
  275.    register InDesc *U;
  276.    {
  277.       extern char DirPath[];
  278.  
  279.       ChDirToCWD ();
  280.       ExecFile (DirPath,U->InPtr);
  281.    }
  282. #endif
  283.  
  284. /*
  285.  * SetDepth
  286.  *
  287.  * Set function printing depth used for printing.
  288.  */
  289. SetDepth (U)
  290.    register InDesc *U;
  291.    {
  292.       Object X;
  293.       FPint N;
  294.       extern int TraceDepth;
  295.  
  296.       X.Tag = BOTTOM;
  297.       (void) InObject (U,&X);
  298.       if (GetFPInt (&X,&N) || N < 0 || N > MaxInt)
  299.      printf ("Error: depth must be integer in range 0..%d\n",MaxInt);
  300.       else TraceDepth = N;
  301.    }
  302.  
  303.  
  304. /*
  305.  * SetTrace
  306.  *
  307.  * Set or reset function trace flags.
  308.  */
  309. private void SetTrace (U)
  310.    register InDesc *U;
  311.    {
  312.       NodePtr N;
  313.       int T;       /* phone home */
  314.  
  315.       if (IsTok (U,"on")) T=1;
  316.       else if (IsTok (U,"off")) T=0;
  317.       else {
  318.      printf ("trace [on|off] f1 f2 f3 ... \n");
  319.      return;
  320.       }
  321.       while (*U->InPtr) {
  322.      N = ReadNode (U);
  323.      if (N != NULL) {
  324.         if (T) N->NodeData.NodeDef.DefFlags |= TRACE;
  325.         else   N->NodeData.NodeDef.DefFlags &= ~TRACE;
  326.      } else break;
  327.       }
  328.    }
  329.  
  330. #if DUMP
  331. extern void DumpNode();
  332. #endif
  333.  
  334. #if DEBUG
  335. void DumpFreeLength ()
  336.    {
  337.       extern StrPtr FreeString;
  338.       long k;
  339.       StrPtr S;
  340.       extern ListPtr FreeList;
  341.       printf ("length (FreeList) = %ld\n",ListLength (FreeList));
  342.       for (S=FreeString, k=0; S!=NULL; S=S->StrNext) k++;
  343.       printf ("length (FreeString) = %ld\n",k);
  344.    }
  345. #endif /* DEBUG */
  346.  
  347. /*
  348.  * UserLoop
  349.  *
  350.  * This is the top level loop of the IFP interpreter.  
  351.  * Each iteration reads a user command from stdin and executes it.
  352.  *
  353.  * Under UNIX, unrecoginized commands are passed on to 'sh'.
  354.  */
  355. void UserLoop ()
  356.    {
  357.       register InDesc *U;
  358.       int N;
  359.  
  360.       U = &UserIn;
  361.       while (1) {
  362.      extern char FPprompt [], *gets();
  363.      extern void ResetExcept();
  364. #if OPSYS==MSDOS
  365.      extern char CWDCache [];
  366.      CWDCache [0] = '\0';        /* Clear current directory cache */
  367. #endif
  368.      ResetExcept ();
  369. #if DEBUG
  370.      if (Debug & DebugAlloc) DumpFreeLength ();
  371. #endif
  372.      printf ("%s",FPprompt);
  373.      (void) fflush (stdout);
  374.      InitIn (U,CurWorkDir,stdin,-1);
  375.      /* Copy prompt so that error message '^' will point correctly. */
  376.      U->InPtr += N = strlen (strcpy (U->InPtr,FPprompt));
  377.      (void) fgets (U->InPtr, INBUFSIZE-N, stdin);
  378.  
  379.      if (!*U->InPtr || IsTok (U,"exit")) {
  380. #if OPSYS==MSDOS
  381.         ChDirToCWD ();
  382. #endif
  383.         return;
  384.      }
  385.      else if (IsTok (U,"depth")) SetDepth (U);
  386.      else if (IsTok (U,"show")) ShowApply (0);
  387. #if HYPERCUBE
  388.      else if (IsTok (U,"send")) {
  389.         Object X;
  390.         ForkFP ();
  391.         InObject (U,&X); 
  392.         OutBinObject (&X);
  393.      }
  394. #endif
  395. #if COMPILE
  396.      else if (CompilerFlag && IsTok (U,"c")) Compile (U);
  397. #endif
  398. #if REFCHECK
  399.      else if (IsTok (U,"check")) ShowRefCheck ();
  400. #endif
  401. #if ECACHE
  402.      else if (IsTok (U,"cache")) ShowCache ();
  403. #endif
  404. #if STATS
  405.      else if (IsTok (U,"stats")) ShowStats ();
  406. #endif
  407.      else if (IsTok (U,"trace")) SetTrace (U);
  408.      else if (IsTok (U,EdCommand)) EditRm (U,1);
  409. #if DUMP
  410.      else if (IsTok (U,"dump")) DumpNode (CurWorkDir,0);
  411. #endif
  412. #ifdef GRAPHICS
  413.      else if (IsTok (U,"graph")) ShowApply (1);
  414. #endif
  415.      /* else if (IsTok (U,"test")) Test (U); */
  416. #if OPSYS==UNIX
  417.      else if (IsTok (U,"rm")) EditRm (U,0);
  418.      else Shell (U);
  419. #endif
  420. #if OPSYS==MSDOS
  421.      else if (IsTok (U,"del")) EditRm (U,0);
  422.      else if (IsTok (U,"dir")) Directory (U);
  423. #endif
  424. #if OPSYS==MSDOS || OPSYS==CTSS
  425.      else printf ("Unknown command: %s\n",U->InPtr);
  426. #endif
  427.       }
  428.    }
  429.  
  430.  
  431. /************************** end of command.c **************************/
  432.