home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / CPM3 / CPMMAKE.ARK / INPUT.C < prev    next >
C/C++ Source or Header  |  1986-08-31  |  6KB  |  316 lines

  1. /*
  2.  *    Parse a makefile
  3.  */
  4.  
  5.  
  6. #include "c:stdio.h"
  7. #include "h.h"
  8.  
  9. extern int endoffile;
  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 (no_case_cmp(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.
  134.  */
  135. void
  136. newline(np, dp, cp)
  137. struct name *        np;
  138. struct depend *        dp;
  139. struct cmd *        cp;
  140. {
  141.     bool            hascmds = FALSE;  /*  Target has commands  */
  142.     register struct line *    rp;
  143.     register struct line *    rrp;
  144.  
  145.  
  146.     for
  147.     (
  148.         rp = np->n_line, rrp = (struct line *)0;
  149.         rp;
  150.         rrp = rp, rp = rp->l_next
  151.     )
  152.         if (rp->l_cmd)
  153.             hascmds = TRUE;
  154.  
  155.     if (hascmds && cp)
  156.         error("Commands defined twice for target %s", np->n_name);
  157.  
  158.     if ((rp = (struct line *)malloc(sizeof (struct line)))
  159.                 == (struct line *)0)
  160.         fatal("No memory for line");
  161.     rp->l_next = (struct line *)0;
  162.     rp->l_dep = dp;
  163.     rp->l_cmd = cp;
  164.  
  165.     if (rrp)
  166.         rrp->l_next = rp;
  167.     else
  168.         np->n_line = rp;
  169.  
  170.     np->n_flag |= N_TARG;
  171. }
  172.  
  173.  
  174. /*
  175.  *    Parse input from the makefile, and construct a tree structure
  176.  *    of it.
  177.  */
  178. void
  179. input(fd)
  180. FILE *            fd;
  181. {
  182.     char *            p;        /*  General  */
  183.     char *            q;
  184.     struct name *        np;
  185.     struct depend *        dp;
  186.     struct cmd *        cp;
  187.  
  188.  
  189.     if (getline(str1, fd))    /*  Read the first line  */
  190.         return;
  191.  
  192.     for(;;)
  193.     {
  194.         if (*str1 == '\t')    /*  Rules without targets  */
  195.             error("Rules not allowed here");
  196.  
  197.         p = str1;
  198.  
  199.         while (isspace(*p))    /*  Find first target  */
  200.             p++;
  201.  
  202.         while (((q = index(p, '=')) != (char *)0) &&
  203.             (p != q) && (q[-1] == '\\'))    /*  Find value */
  204.         {
  205.             register char *        a;
  206.  
  207.             a = q - 1;    /*  Del \ chr; move rest back  */
  208.             p = q;
  209.             while(*a++ = *q++)
  210.                 ;
  211.         }
  212.  
  213.         if (q != (char *)0)
  214.         {
  215.             register char *        a;
  216.  
  217.             *q++ = '\0';        /*  Separate name and val  */
  218.             while (isspace(*q))
  219.                 q++;
  220.             if (p = rindex(q, '\n'))
  221.                 *p = '\0';
  222.  
  223.             p = str1;
  224.             if ((a = gettok(&p)) == (char *)0)
  225.                 error("No macro name");
  226.  
  227.             setmacro(a, q);
  228.  
  229.             if (getline(str1, fd))
  230.                 return;
  231.             continue;
  232.         }
  233.  
  234.         expand(str1);
  235.         p = str1;
  236.  
  237.         while (((q = index(p, ':')) != (char *)0) &&
  238.             (p != q) && (q[-1] == '\\'))    /*  Find dependents  */
  239.         {
  240.             register char *        a;
  241.  
  242.             a = q - 1;    /*  Del \ chr; move rest back  */
  243.             p = q;
  244.             while(*a++ = *q++)
  245.                 ;
  246.         }
  247.  
  248.         if (q == (char *)0)
  249.             error("No targets provided");
  250.  
  251.         *q++ = '\0';    /*  Separate targets and dependents  */
  252.  
  253.         for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
  254.                     /*  get list of dep's */
  255.         {
  256.             np = newname(p);        /*  Intern name  */
  257.             dp = newdep(np, dp);        /*  Add to dep list */
  258.         }
  259.  
  260.         *((q = str1) + strlen(str1) + 1) = '\0';
  261.             /*  Need two nulls for gettok (Remember separation)  */
  262.  
  263.         cp = (struct cmd *)0;
  264.         if (getline(str2, fd) == FALSE)        /*  Get commands  */
  265.         {
  266.             while (*str2 == '\t')
  267.             {
  268.                 cp = newcmd(&str2[0], cp);
  269.                 if (getline(str2, fd))
  270.                     break;
  271.             }
  272.         }
  273.  
  274.         while ((p = gettok(&q)) != (char *)0)    /* Get list of targ's */
  275.         {
  276.             np = newname(p);        /*  Intern name  */
  277.             newline(np, dp, cp);
  278.             if (!firstname)
  279.                 firstname = np;
  280.         }
  281.  
  282.         if (feof(fd) != 0  || endoffile == TRUE)    /*  EOF?  */
  283.             return;
  284.  
  285.         strcpy(str1, str2);
  286.     }
  287. }
  288.  
  289.  
  290. /*
  291.  * Case insensitive strcmp() then used for = or != purposes.
  292.  *
  293.  * This makes cp/m makefile usage a bit simpler
  294.  *
  295.  *                        -mdk
  296.  */
  297.  
  298. no_case_cmp(first,second)
  299. char *first;
  300. char *second;
  301. {
  302.     register char *p1,*p2;
  303.  
  304.     for (p1=first,p2=second ; *p1 != '\0' ; p1++, p2++) {
  305.         if ((islower(*p1) ? tolower(*p1) : *p1) != 
  306.                 (islower(*p2) ? tolower(*p2) : *p2) ) {
  307.             break;
  308.         }
  309.     }
  310.  
  311.     if (*p1 == '\0' && *p2 == '\0') {
  312.         return(0);
  313.     }
  314.     return(1);
  315. }
  316.