home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / ifp / part06 / interp / inimport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-07-06  |  6.7 KB  |  262 lines

  1.  
  2. /****** inimport.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:  Oct 28, 1985          **/
  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.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include "struct.h"
  27. #include "node.h"
  28. #include "string.h"
  29. #include "inob.h"
  30.  
  31. /*
  32.  * DoubleDot
  33.  *
  34.  * Append a ".." to path list by deleting last element.
  35.  *       
  36.  * Input
  37.  *      *F = file descriptor
  38.  *      *C = pointer to path list 
  39.  *
  40.  * Output
  41.  *      result = pointer to last null field, null if error.
  42.  */
  43. MetaPtr DoubleDot (F,C)           
  44.    InDesc *F;
  45.    register MetaPtr C;
  46.    {
  47.       register MetaPtr A;
  48.  
  49.       if (*C == NULL) {
  50.      (void) InError (F,"Too many ..'s.");
  51.      return NULL;
  52.       } else {        /* Remove last element from path list R */
  53.      do {
  54.         A = C;
  55.         C = &(*A)->Next;
  56.      } while (*C != NULL);
  57.      DelLPtr (*A);
  58.      *A = NULL;
  59.      return A;
  60.       }
  61.    }
  62.  
  63. /*
  64.  * NodeDelim is the set of pathname delimiters.  Note that '>' and '<' are not
  65.  * in the set since they are (perversely) legal function names.  
  66.  */
  67. char NodeDelim[] = " ,[](){}|;:/\t\n";
  68.  
  69. /*
  70.  * InNode
  71.  *
  72.  * Input a path.  A path may represent a module, function, or functional
  73.  * variable.  Local functions are linked if possible to save time and space.
  74.  *
  75.  * The EBNF production definition for a node is:
  76.  *
  77.  *    ["/"] string { "/" (string | "..") }
  78.  *
  79.  * Input
  80.  *    *F = input descriptor pointing to path
  81.  *    Env = environment
  82.  *
  83.  * Output
  84.  *      InOut = node (path list or node format) or functional variable (string)
  85.  *    *F = input descriptor pointing to next token after path
  86.  *
  87.  * A SysError may occur, in which case InOut is unchanged.
  88.  */
  89. boolean InNode (F,InOut,Env)
  90.    InDesc *F;
  91.    ObjectPtr InOut;
  92.    ListPtr Env;
  93.    {
  94.       ListPtr R = NULL;        /* path list accumulator                       */
  95.       register MetaPtr A = &R; /* pointer to Next field at end of accumulator */
  96.       register NodePtr N;
  97.       boolean FirstSlash;
  98.    
  99.       if (Debug & DebugParse) printf ("InNode: '%s'",F->InPtr); 
  100.       if (!(FirstSlash = *F->InPtr == '/')) {
  101.  
  102.      if (IsTok (F,"..")) {
  103.         if (F->InDefMod != NULL) R = MakePath (F->InDefMod);
  104.         if (NULL == (A = DoubleDot (F,&R))) goto Error;
  105.      } else {
  106.  
  107.         Object S;                       /* relative path */
  108.         S.Tag = BOTTOM;
  109.         if (NULL == InString (F,&S,NodeDelim,0)) {
  110.            if (!SysError) (void) InError (F,"path expected");
  111.            goto Error;
  112.         }    
  113.         if (!IsTok (F,"/")) {
  114.  
  115.            for (; Env!=NULL; Env=Env->Next) 
  116.           if (ObEqual (&Env->Val,&S)) {
  117.              RepObject (InOut,&Env->Val);     /* functional variable */
  118.              return 1;
  119.           }
  120.  
  121.            N = FindNode (F->InDefMod,S.String);   /* local function */
  122.            if (N != NULL) {
  123.           if (N->NodeType == IMPORT) {
  124.  
  125.              /* Imported function - resolve alias */
  126.              RepObject (InOut,&N->NodeData.NodeImp.ImpDef);
  127.  
  128.           } else { /* Local function already linked */
  129.      
  130.              RepTag (InOut,NODE);
  131.              InOut->Node = CopyNPtr (N);
  132.           }
  133.           RepTag (&S,BOTTOM);
  134.           return 1;
  135.            }
  136.         }
  137.         if (F->InDefMod != NULL) R = MakePath (F->InDefMod);
  138.         while (*A != NULL) A = &(*A)->Next;
  139.         NewList (A,1L);
  140.         (*A)->Val.Tag = STRING;
  141.         (*A)->Val.String = S.String;
  142.      }
  143.       }
  144.  
  145.       while (IsTok (F,"/")) {
  146.      if (IsTok (F,".."))
  147.         if (NULL == (A = DoubleDot (F,&R))) return 0;
  148.         else continue;
  149.      else {
  150.         NewList (A,1L);
  151.         if (SysError) goto Error;
  152.         if (NULL == InString (F,&(*A)->Val,NodeDelim,0)) {
  153.            if (SysError) goto Error;
  154.            else if (*F->InPtr != '/' && FirstSlash) {
  155.           (void) DoubleDot (F,&R);
  156.           break;
  157.            } else {
  158.           (void) InError (F,"Invalid path name");
  159.           goto Error;
  160.            }
  161.         }
  162.         A = &(*A)->Next;
  163.      }
  164.      FirstSlash = 0;
  165.       }
  166.  
  167.       RepTag (InOut,LIST);
  168.       InOut->List = R;
  169.       return 1;
  170.  
  171. Error:
  172.       DelLPtr (R);
  173.       return 0;
  174.    }
  175.  
  176. /*
  177.  * InImport
  178.  *
  179.  * Input from an import file.
  180.  *
  181.  * An import file has the following format:
  182.  *
  183.  *      { 'FROM' path 'IMPORT' string {,string} ';' }
  184.  *
  185.  * Input
  186.  *      F = input
  187.  *      M = pointer to module node
  188.  */
  189. void InImport (F,M)
  190.    register InDesc *F;
  191.    register NodePtr M;
  192.    {
  193.       Object Path,Def;
  194.       register NodePtr N;
  195.       MetaPtr A;
  196.  
  197.       F->InDefFun = NULL;
  198.       Path.Tag = BOTTOM;
  199.       Def.Tag = BOTTOM;
  200.  
  201.       while (*F->InPtr) {
  202.  
  203.      if (!IsTok (F,"FROM")) {
  204.         (void) InError (F,"FROM expected");
  205.         break;
  206.      }
  207.  
  208.      (void) InNode (F,&Path,NIL); 
  209.      if (!IsTok (F,"IMPORT")) {
  210.         (void) InError (F,"IMPORT expected");
  211.         break;
  212.      }
  213.  
  214.      while (1) {
  215.  
  216.         if (NULL == InString (F,&Def," ,;\n",0)) {
  217.            if (!SysError) (void) InError (F,"function name expected");
  218.            goto Return;
  219.         }
  220.  
  221.         N = MakeChild (M,Def.String);
  222.  
  223.         switch (N->NodeType) {
  224.  
  225.            case IMPORT:
  226.           (void) InError (F,"duplicate imported identifier");
  227.           break;
  228.  
  229.            case DEF:
  230.           if (N->NRef > 1) {
  231.              (void) InError (F,"identifies function elsewhere");
  232.              break;
  233.           } /* else continue on down to NEWNODE */
  234.  
  235.            case NEWNODE: {
  236.           extern MetaPtr MakeCopy ();
  237.           N->NodeType = IMPORT;
  238.           N->NodeData.NodeImp.ImpDef.Tag = LIST;
  239.           A = MakeCopy (&N->NodeData.NodeImp.ImpDef.List, Path.List);
  240.           NewList (A,1L);
  241.           RepObject (&(*A)->Val,&Def);
  242.           break;
  243.            }
  244.         }
  245.         
  246.         if (IsTok (F,";")) break;
  247.         if (!IsTok (F,",")) {
  248.            (void) InError (F,"comma or semicolon expected");
  249.            goto Return;
  250.         }
  251.      }
  252.       }
  253. Return:
  254.       RepTag (&Path,BOTTOM);
  255.       RepTag (&Def,BOTTOM);
  256.       return;
  257.    }
  258.  
  259.  
  260. /******************************* inimport.c *******************************/
  261.  
  262.