home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / make_1 / !make_c_Input < prev    next >
Encoding:
Text File  |  1992-12-07  |  6.3 KB  |  334 lines

  1. /* > c.Input 
  2.  * Parse a makefile
  3.  */
  4.  
  5.  
  6. #include <stdio.h>
  7. #include "h.h"
  8.  
  9.  
  10. struct name  namehead;
  11. struct name *  firstname;
  12.  
  13. char    str1[LZ];  /*   General store  */
  14. char   str2[LZ];
  15.  
  16.  
  17. /*
  18.  * Intern a name.  Return a pointer to the name struct
  19.  */
  20. struct name *
  21. newname(char * name)
  22. {
  23.  register struct name * rp;
  24.  register struct name * rrp;
  25.  register char *  cp;
  26.  
  27.  
  28.  for
  29.  (
  30.   rp = namehead.n_next, rrp = &namehead;
  31.   rp;
  32.   rp = rp->n_next, rrp = rrp->n_next
  33.  )
  34.   if (strcmp(name, rp->n_name) == 0)
  35.    return rp;
  36.  
  37.  if ((rp = (struct name *)malloc(sizeof (struct name)))
  38.     == (struct name *)0)
  39.   fatal("No memory for name");
  40.  rrp->n_next = rp;
  41.  rp->n_next = (struct name *)0;
  42.  if ((cp = malloc(strlen(name)+1)) == (char *)0)
  43.   fatal("No memory for name");
  44.  strcpy(cp, name);
  45.  rp->n_name = cp;
  46.  rp->n_line = (struct line *)0;
  47.  rp->n_time = (time_t)0;
  48.  rp->n_flag = 0;
  49.  
  50.  return rp;
  51. }
  52.  
  53.  
  54. /*
  55.  * Add a dependant to the end of the supplied list of dependants.
  56.  * Return the new head pointer for that list.
  57.  */
  58. struct depend *
  59. newdep(struct name * np,struct depend * dp)
  60.  
  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(char * str, struct cmd * cp)
  90.  
  91. {
  92.  register struct cmd * rp;
  93.  register struct cmd * rrp;
  94.  register char *  rcp;
  95.  
  96.  
  97.  if (rcp = rindex(str, '\n'))
  98.   *rcp = '\0';  /*  Loose newline  */
  99.  
  100.  while (isspace(*str))
  101.   str++;
  102.  
  103.  if (*str == '\0')  /*  If nothing left, the exit  */
  104.   return 0 ;
  105.  
  106.  if ((rp = (struct cmd *)malloc(sizeof (struct cmd)))
  107.     == (struct cmd *)0)
  108.   fatal("No memory for command");
  109.  rp->c_next = (struct cmd *)0;
  110.  if ((rcp = malloc(strlen(str)+1)) == (char *)0)
  111.   fatal("No memory for command");
  112.  strcpy(rcp, str);
  113.  rp->c_cmd = rcp;
  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(struct name * np,
  143.         struct depend *dp,
  144.         struct cmd * cp,
  145.         int flag)
  146.  
  147. {
  148.  bool   hascmds = FALSE;  /*  Target has commands  */
  149.  register struct line * rp;
  150.  register struct line * rrp;
  151.  
  152.  
  153.  /* Handle the .SUFFIXES case */
  154.  if (np->n_name[0] == '.' && !dp && !cp)
  155.  {
  156.   for (rp = np->n_line; rp; rp = rrp)
  157.   {
  158.    rrp = rp->l_next;
  159.    free(rp);
  160.   }
  161.   np->n_line = (struct line *)0;
  162.   np->n_flag &= ~N_TARG;
  163.   return;
  164.  }
  165.  
  166.  /* This loop must happen since rrp is used later. */
  167.  for
  168.  (
  169.   rp = np->n_line, rrp = (struct line *)0;
  170.   rp;
  171.   rrp = rp, rp = rp->l_next
  172.  )
  173.   if (rp->l_cmd)
  174.    hascmds = TRUE;
  175.  
  176.  if (hascmds && cp && !(np->n_flag & N_DOUBLE))
  177.   {
  178.   /* Handle the implicit rules redefinition case */
  179.   if (np->n_name[0] == '.' && dp == (struct depend *)0)
  180.    {
  181.    np->n_line->l_cmd = cp;
  182.    return;
  183.    }
  184.   else
  185.    report_error("Commands defined twice for target %s", np->n_name);
  186.   };
  187.  
  188.  if (np->n_flag & N_TARG)
  189.   if (!(np->n_flag & N_DOUBLE) != !flag)  /* like xor */
  190.    report_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(FILE *fd)
  216.  
  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.  
  232.   if (*str1 == '\t') /*  Rules without targets  */
  233.    report_error("Rules not allowed here");
  234.  
  235.   p = str1;
  236.  
  237.   while (isspace(*p)) /*  Find first target  */
  238.    p++;
  239.  
  240.   while (((q = index(p, '=')) != (char *)0) &&
  241.       (p != q) && (q[-1] == '\\')) /*  Find value */
  242.   {
  243.    register char *  a;
  244.  
  245.    a = q - 1; /*  Del \ chr; move rest back  */
  246.    p = q;
  247.    while(*a++ = *q++)
  248.     ;
  249.   }
  250.  
  251.   if (q != (char *)0)
  252.   {
  253.    register char *  a;
  254.  
  255.    *q++ = '\0';  /*  Separate name and val  */
  256.    while (isspace(*q))
  257.     q++;
  258.    if (p = rindex(q, '\n'))
  259.     *p = '\0';
  260.  
  261.    p = str1;
  262.    if ((a = gettok(&p)) == (char *)0)
  263.     report_error("No macro name");
  264.  
  265.    setmacro(a, q);
  266.  
  267.    if (getline(str1, fd))
  268.     return;
  269.     continue;
  270.   }
  271.  
  272.   expand(str1);
  273.   p = str1;
  274.  
  275.   while (((q = index(p, ':')) != (char *)0) &&
  276.       (p != q) && (q[-1] == '\\')) /*  Find dependents  */
  277.   {
  278.    register char *  a;
  279.  
  280.    a = q - 1; /*  Del \ chr; move rest back  */
  281.    p = q;
  282.    while(*a++ = *q++)
  283.     ;
  284.   }
  285.  
  286.   if (q == (char *)0)
  287.   report_error("No targets provided");
  288.  
  289.   *q++ = '\0'; /*  Separate targets and dependents  */
  290.  
  291.   if (*q == ':')  /* Double colon */
  292.   {
  293.    dbl = 1;
  294.    q++;
  295.   }
  296.   else
  297.    dbl = 0;
  298.  
  299.   for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
  300.      /*  get list of dep's */
  301.   {
  302.    np = newname(p);  /*  Intern name  */
  303.    dp = newdep(np, dp);  /*  Add to dep list */
  304.   }
  305.  
  306.   *((q = str1) + strlen(str1) + 1) = '\0';
  307.    /*  Need two nulls for gettok (Remember separation)  */
  308.  
  309.   cp = (struct cmd *)0;
  310.   if (getline(str2, fd) == FALSE)  /*  Get commands  */
  311.   {
  312.    while (*str2 == '\t')
  313.    {
  314.     cp = newcmd(&str2[0], cp);
  315.     if (getline(str2, fd))
  316.      break;
  317.    }
  318.   }
  319.  
  320.   while ((p = gettok(&q)) != (char *)0) /* Get list of targ's */
  321.   {
  322.    np = newname(p);  /*  Intern name  */
  323.    newline(np, dp, cp, dbl);
  324.    if (!firstname && p[0] != '.')
  325.     firstname = np;
  326.   }
  327.  
  328.   if (feof(fd))    /*  EOF?  */
  329.    return;
  330.  
  331.   strcpy(str1, str2);
  332.  }
  333. }
  334.