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