home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / tools / make / make_pd / input.c < prev    next >
C/C++ Source or Header  |  1987-01-10  |  7KB  |  341 lines

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