home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / sozobon / scsrc20 / make / input.c < prev    next >
C/C++ Source or Header  |  1988-10-13  |  8KB  |  335 lines

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