home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / make / INPUT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-26  |  6.7 KB  |  327 lines

  1. /*
  2.  *    Parse a makefile
  3.  */
  4.  
  5.  
  6. #include "h.h"
  7.  
  8.  
  9. struct name        namehead;
  10. struct name *        firstname;
  11.  
  12. char             str1[LZ];        /*  General store  */
  13. char            str2[LZ];
  14.  
  15.  
  16. /*
  17.  *    Intern a name.  Return a pointer to the name struct
  18.  */
  19. struct name *
  20. newname(name)
  21. char *            name;
  22. {
  23.     register struct name *    rp;
  24.     register struct name *    rrp;
  25.  
  26.  
  27.     for
  28.     (
  29.         rp = namehead.n_next, rrp = &namehead;
  30.         rp;
  31.         rp = rp->n_next, rrp = rrp->n_next
  32.     )
  33.         if (strcmp(name, rp->n_name) == 0)
  34.             return rp;
  35.  
  36.     if ((rp = (struct name *)malloc(sizeof (struct name)))
  37.                 == (struct name *)0)
  38.         fatal("No memory for name");
  39.     rrp->n_next = rp;
  40.     rp->n_next = (struct name *)0;
  41.  
  42.     if ((rp->n_name = strdup(name)) == NULL)
  43.         fatal("No memory for name '%s'",name);
  44.  
  45.     rp->n_line = (struct line *)0;
  46.     rp->n_time = (time_t)0;
  47.     rp->n_flag = 0;
  48.  
  49.     return rp;
  50. }
  51.  
  52.  
  53. /*
  54.  *    Add a dependant to the end of the supplied list of dependants.
  55.  *    Return the new head pointer for that list.
  56.  */
  57. struct depend *
  58. newdep(np, dp)
  59. struct name *        np;
  60. struct depend *        dp;
  61. {
  62.     register struct depend *    rp;
  63.     register struct depend *    rrp;
  64.  
  65.  
  66.     if ((rp = (struct depend *)malloc(sizeof (struct depend)))
  67.                 == (struct depend *)0)
  68.         fatal("No memory for dependant");
  69.     rp->d_next = (struct depend *)0;
  70.     rp->d_name = np;
  71.  
  72.     if (dp == (struct depend *)0)
  73.         return rp;
  74.  
  75.     for (rrp = dp; rrp->d_next; rrp = rrp->d_next)
  76.         ;
  77.  
  78.     rrp->d_next = rp;
  79.  
  80.     return dp;
  81. }
  82.  
  83.  
  84. /*
  85.  *    Add a command to the end of the supplied list of commands.
  86.  *    Return the new head pointer for that list.
  87.  */
  88. struct cmd *
  89. newcmd(str, cp)
  90. char *            str;
  91. struct cmd *        cp;
  92. {
  93.     register struct cmd *    rp;
  94.     register struct cmd *    rrp;
  95.     register char *        rcp;
  96.  
  97.  
  98.     if (rcp = strrchr(str, '\n'))
  99.         *rcp = '\0';        /*  Loose newline  */
  100.  
  101.     while (isspace(*str))
  102.         str++;
  103.  
  104.     if (*str == '\0')        /*  If nothing left, the exit  */
  105.         return NULL;
  106.  
  107.     if ((rp = (struct cmd *)malloc(sizeof (struct cmd)))
  108.                 == (struct cmd *)0)
  109.         fatal("No memory for command");
  110.     rp->c_next = (struct cmd *)0;
  111.  
  112.     if ((rp->c_cmd = strdup(str)) == NULL)
  113.         fatal("No memory for command '%s'",str);
  114.  
  115.     if (cp == (struct cmd *)0)
  116.         return rp;
  117.  
  118.     for (rrp = cp; rrp->c_next; rrp = rrp->c_next)
  119.         ;
  120.  
  121.     rrp->c_next = rp;
  122.  
  123.     return cp;
  124. }
  125.  
  126.  
  127. /*
  128.  *    Add a new 'line' of stuff to a target.  This check to see
  129.  *    if commands already exist for the target.  If flag is set,
  130.  *    the line is a double colon target.
  131.  *
  132.  *    Kludges:
  133.  *    i)  If the new name begins with a '.', and there are no dependents,
  134.  *        then the target must cease to be a target.  This is for .SUFFIXES.
  135.  *    ii) If the new name begins with a '.', with no dependents and has
  136.  *        commands, then replace the current commands.  This is for
  137.  *        redefining commands for a default rule.
  138.  *    Neither of these free the space used by dependents or commands,
  139.  *    since they could be used by another target.
  140.  */
  141. void
  142. newline(np, dp, cp, flag)
  143. struct name *        np;
  144. struct depend *        dp;
  145. struct cmd *        cp;
  146. {
  147.     bool            hascmds = FALSE;  /*  Target has commands  */
  148.     register struct line *    rp;
  149.     register struct line *    rrp;
  150.  
  151.  
  152.     /* Handle the .SUFFIXES case */
  153.     if (np->n_name[0] == '.' && !dp && !cp)
  154.     {
  155.         for (rp = np->n_line; rp; rp = rrp)
  156.         {
  157.             rrp = rp->l_next;
  158.             free(rp);
  159.         }
  160.         np->n_line = (struct line *)0;
  161.         np->n_flag &= ~N_TARG;
  162.         return;
  163.     }
  164.  
  165.     /* This loop must happen since rrp is used later. */
  166.     for
  167.     (
  168.         rp = np->n_line, rrp = (struct line *)0;
  169.         rp;
  170.         rrp = rp, rp = rp->l_next
  171.     )
  172.         if (rp->l_cmd)
  173.             hascmds = TRUE;
  174.  
  175.     if (hascmds && cp && !(np->n_flag & N_DOUBLE))
  176.         /* Handle the implicit rules redefinition case */
  177.         if (np->n_name[0] == '.' && dp == (struct depend *)0)
  178.         {
  179.             np->n_line->l_cmd = cp;
  180.             return;
  181.         }
  182.         else
  183.             error("Commands defined twice for target %s", np->n_name);
  184.     if (np->n_flag & N_TARG)
  185.         if (!(np->n_flag & N_DOUBLE) != !flag)        /* like xor */
  186.             error("Inconsistent rules for target %s", np->n_name);
  187.  
  188.     if ((rp = (struct line *)malloc(sizeof (struct line)))
  189.                 == (struct line *)0)
  190.         fatal("No memory for line");
  191.     rp->l_next = (struct line *)0;
  192.     rp->l_dep = dp;
  193.     rp->l_cmd = cp;
  194.  
  195.     if (rrp)
  196.         rrp->l_next = rp;
  197.     else
  198.         np->n_line = rp;
  199.  
  200.     np->n_flag |= N_TARG;
  201.     if (flag)
  202.         np->n_flag |= N_DOUBLE;
  203. }
  204.  
  205.  
  206. /*
  207.  *    Parse input from the makefile, and construct a tree structure
  208.  *    of it.
  209.  */
  210. void input(FILE *fd)
  211. {
  212.   char *            p;        /*  General  */
  213.   char *            q;
  214.   struct name *        np;
  215.   struct depend *        dp;
  216.   struct cmd *        cp;
  217.   bool            dbl;
  218.   
  219.   
  220.   if (getline(str1, fd))    /*  Read the first line  */
  221.     return;
  222.   
  223.   for(;;)
  224.     {
  225.       if (*str1 == '\t')    /*  Rules without targets  */
  226.     error("Rules not allowed here");
  227.       
  228.       p = str1;
  229.       
  230.       while (isspace(*p))    /*  Find first target  */
  231.     p++;
  232.       
  233.       while (((q = strchr(p, '=')) != (char *)0) &&
  234.          (p != q) && (q[-1] == '\\'))    /*  Find value */
  235.     {
  236.       register char *        a;
  237.       
  238.       a = q - 1;    /*  Del \ chr; move rest back  */
  239.       p = q;
  240.       while(*a++ = *q++)
  241.         ;
  242.     }
  243.       
  244.       if (q != (char *)0)
  245.     {
  246.       register char *        a;
  247.       
  248.       *q++ = '\0';        /*  Separate name and val  */
  249.       while (isspace(*q))
  250.         q++;
  251.       if (p = strrchr(q, '\n'))
  252.         *p = '\0';
  253.       
  254.       p = str1;
  255.       if ((a = gettok(&p)) == (char *)0)
  256.         error("No macro name");
  257.       
  258.       setmacro(a, q);
  259.       
  260.       if (getline(str1, fd))
  261.         return;
  262.       continue;
  263.     }
  264.       
  265.       expand(str1);
  266.       p = str1;
  267.       
  268.       while (((q = strchr(p, ':')) != (char *)0) &&
  269.          (p != q) && (q[-1] == '\\'))    /*  Find dependents  */
  270.     {
  271.       register char *        a;
  272.       
  273.       a = q - 1;    /*  Del \ chr; move rest back  */
  274.       p = q;
  275.       while(*a++ = *q++)
  276.         ;
  277.     }
  278.       
  279.       if (q == (char *)0)
  280.     error("No targets provided");
  281.       
  282.       *q++ = '\0';    /*  Separate targets and dependents  */
  283.       
  284.       if (*q == ':')        /* Double colon */
  285.     {
  286.       dbl = 1;
  287.       q++;
  288.     }
  289.       else
  290.     dbl = 0;
  291.       
  292.       for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
  293.     /*  get list of dep's */
  294.     {
  295.       np = newname(p);        /*  Intern name  */
  296.       dp = newdep(np, dp);        /*  Add to dep list */
  297.     }
  298.       
  299.       *((q = str1) + strlen(str1) + 1) = '\0';
  300.       /*  Need two nulls for gettok (Remember separation)  */
  301.       
  302.       cp = (struct cmd *)0;
  303.       if (getline(str2, fd) == FALSE)        /*  Get commands  */
  304.     {
  305.       while (*str2 == '\t')
  306.         {
  307.           cp = newcmd(&str2[0], cp);
  308.           if (getline(str2, fd))
  309.         break;
  310.         }
  311.     }
  312.       
  313.       while ((p = gettok(&q)) != (char *)0)    /* Get list of targ's */
  314.     {
  315.       np = newname(p);        /*  Intern name  */
  316.       newline(np, dp, cp, dbl);
  317.       if (!firstname && p[0] != '.')
  318.         firstname = np;
  319.     }
  320.       
  321.       if (feof(fd))                /*  EOF?  */
  322.     return;
  323.       
  324.       strcpy(str1, str2);
  325.     }
  326. }
  327.