home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / PAMAKE18.ZIP / INPUT.C < prev    next >
C/C++ Source or Header  |  1989-08-31  |  12KB  |  431 lines

  1. /*************************************************************************
  2. |                                                                        |
  3. |   INPUT.C                                                     31.08.89 |
  4. |   PAMAKE Utility:  parse a makefile                                    |
  5. |                                                                        |
  6. *************************************************************************/
  7.  
  8. #ifdef VMS
  9. #include stdio
  10. #include string
  11. #include stdlib
  12. #include ctype
  13. #include "h.h"
  14. #else
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #include <ctype.h>
  19. #include "h.h"
  20. #endif
  21.  
  22. struct name     namehead;
  23. struct name *   firstname;
  24.  
  25. char            str1[LZ];               /* general store */
  26. char            str2[LZ];
  27.  
  28. /*****  intern a name - return a pointer to the name struct */
  29.  
  30. struct name *
  31. newname(name)
  32. char *          name;
  33. {
  34.     struct name *           rp;
  35.     struct name *           rrp;
  36.     char *                  cp;
  37.     register int            i;
  38.     register char *         q;
  39.  
  40.     static char namerr[] = {"Cannot allocate memory for name"}; 
  41.  
  42.     for
  43.         (
  44.         rp = namehead.n_next, rrp = &namehead;
  45.         rp;
  46.         rp = rp->n_next, rrp = rrp->n_next
  47.         )
  48.     {
  49.         i = 0;
  50.         q = rp->n_name;
  51.         while (name[i] == *(q+i))
  52.             if (name[i++] == '\0') return rp;
  53.     }
  54.  
  55.     if ((rp = (struct name *)malloc(sizeof(struct name))) == (struct name *)0)
  56.         fatal(namerr);
  57.     rrp->n_next = rp;
  58.     rp->n_next = (struct name *)0;
  59.     if ((cp = malloc(strlen(name)+1)) == (char *)0) fatal(namerr);
  60.     strcpy(cp, name);
  61.     rp->n_name = cp;
  62.     rp->n_line = (struct line *)0;
  63.     rp->n_time = (long)0;
  64.     rp->n_flag = 0;
  65.  
  66.     return rp;
  67. }
  68.  
  69.  
  70. /*****  add a dependant to the end of the supplied list of dependants */
  71. /*****  return the new head pointer for that list */
  72.  
  73. struct depend *
  74. newdep(np, dp)
  75. struct name *       np;
  76. struct depend *     dp;
  77. {
  78.     register struct depend *rp;
  79.     register struct depend *rrp;
  80.     static char deperr[] = {"Cannot allocate memory for dependant"}; 
  81.  
  82.     if ((rp = (struct depend *)malloc(sizeof(struct depend)))
  83.         == (struct depend *)0)
  84.         fatal(deperr);
  85.     rp->d_next = (struct depend *)0;
  86.     rp->d_name = np;
  87.  
  88.     if (dp == (struct depend *)0)
  89.         return rp;
  90.  
  91.     for (rrp = dp; rrp->d_next; rrp = rrp->d_next)
  92.         ;
  93.  
  94.     rrp->d_next = rp;
  95.     return dp;
  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, and save the */
  101. /*****  actual command structure created in case lif lines are found */
  102.  
  103. struct cmd *
  104. newcmd(str, cp, crp)
  105. char *              str;
  106. struct cmd *        cp;
  107. struct cmd * *      crp;
  108. {
  109.     register struct cmd *   rp;
  110.     register struct cmd *   rrp;
  111.     register char *         rcp;
  112.     static char comerr[] = {"Cannot allocate memory for command"}; 
  113.  
  114.     if ((rcp = strrchr(str, '\n')) != (char *)0) *rcp = '\0';   /* lose nl */
  115.     while (pspace(*str)) str++;
  116.  
  117.     if (*str == '\0')               /* if nothing left, then exit */
  118.     {
  119.         *crp = (struct cmd *)0;
  120.         return cp;
  121.     }
  122.  
  123.     if ((rp = (struct cmd *)malloc(sizeof(struct cmd))) == (struct cmd *)0)
  124.         fatal(comerr);
  125.     rp->c_next = (struct cmd *)0;
  126.     if ((rcp = malloc(strlen(str)+1)) == (char *)0) fatal(comerr);
  127.     strcpy(rcp, str);
  128.     rp->c_cmd = rcp;
  129.     rp->c_lif = (struct lif *)0;
  130.     *crp = rp;
  131.  
  132.     if (cp == (struct cmd *)0) return rp;
  133.  
  134.     for (rrp = cp; rrp->c_next; rrp = rrp->c_next)
  135.         ;
  136.  
  137.     rrp->c_next = rp;
  138.     return cp;
  139. }
  140.  
  141. /*****  add a lif line to the end of the supplied list of lif lines */
  142. /*****  return the new head pointer for that list */
  143.  
  144. struct lif *
  145. newlif(str, lp)
  146. char *          str;
  147. struct lif *    lp;
  148. {
  149.     register struct lif *   rp;
  150.     register struct lif *   rrp;
  151.     register char *         rlp;
  152.     static char liferr[] = {"Cannot allocate memory for local input file"}; 
  153.  
  154.     if ((rlp = strrchr(str, '\n')) != (char *)0) *rlp = '\0';   /* lose nl */
  155.  
  156.     if (*str == '\0') return lp;    /* if nothing left, then exit */
  157.  
  158.     if ((rp = (struct lif *)malloc(sizeof(struct lif))) == (struct lif *)0)
  159.         fatal(liferr);
  160.     rp->f_next = (struct lif *)0;
  161.     if ((rlp = malloc(strlen(str)+1)) == (char *)0) fatal(liferr);
  162.     strcpy(rlp, str);
  163.     rp->f_lif = rlp;
  164.  
  165.     if (lp == (struct lif *)0) return rp;
  166.     for (rrp = lp; rrp->f_next; rrp = rrp->f_next)
  167.         ;
  168.  
  169.     rrp->f_next = rp;
  170.     return lp;
  171. }
  172.  
  173.  
  174. /*****  add a new 'line' of stuff to a target */
  175. /*****  check to see if commands already exist for the target */
  176.  
  177. void
  178. newline(np, dp, cp, flag)
  179. struct name *   np;
  180. struct depend * dp;
  181. struct cmd *    cp;
  182. int             flag;
  183. {
  184.     bool                    hascmds = FALSE;  /*  Target has commands  */
  185.     register struct line *  rp;
  186.     register struct line *  rrp;
  187.     static char linerr[] = {"Cannot allocate memory for line"}; 
  188.  
  189.     if ( (!dp && !cp && !strcmp(np->n_name,".SUFFIXES")))
  190.     {
  191.         for (rp = np->n_line; rp; rp = rrp)
  192.         {
  193.             rrp = rp->l_next;
  194.             free(rp);
  195.         }
  196.         np->n_line = (struct line *)0;
  197.         np->n_flag &= ~N_TARG;
  198.         return;
  199.     }
  200.  
  201.     for
  202.         (
  203.         rp = np->n_line, rrp = (struct line *)0;
  204.         rp;
  205.         rrp = rp, rp = rp->l_next
  206.         )
  207.         if (rp->l_cmd)
  208.             hascmds = TRUE;
  209.  
  210. /*****  handle the implicit rules redefinition case */
  211.  
  212.     if (hascmds && cp && !(np->n_flag & N_DOUBLE))
  213.         if (np->n_name[0] == '.' && dp == (struct depend *)0)
  214.         {
  215.             np->n_line->l_cmd = cp;
  216.             return;
  217.         }
  218.         else
  219.             error("Multiple sets of commands for target %s", np->n_name);
  220.  
  221.     if (np->n_flag & N_TARG)
  222.         if (!(np->n_flag & N_DOUBLE) != !flag)          /* like xor */
  223.             error("Inconsistent rules for target %s", np->n_name);
  224.  
  225.     if ((rp = (struct line *)malloc(sizeof (struct line)))
  226.         == (struct line *)0)
  227.         fatal(linerr);
  228.     rp->l_next = (struct line *)0;
  229.     rp->l_dep = dp;
  230.     rp->l_cmd = cp;
  231.  
  232.     if (rrp)
  233.         rrp->l_next = rp;
  234.     else
  235.         np->n_line = rp;
  236.  
  237.     np->n_flag |= N_TARG;
  238.  
  239.     if (flag)
  240.         np->n_flag |= N_DOUBLE;
  241. }
  242.  
  243. /*****  check for the presence of a local input file */
  244.  
  245. void
  246. checklif(cp)
  247. struct cmd *    cp;
  248. {
  249.     register struct lif *   lp;
  250.  
  251.     lp = (struct lif *)0;
  252.     if (pstrstr(str2,"$-"))    /* lif follows */
  253.     {
  254.         for (;;)
  255.         {
  256.             if (getline(str2))
  257.                 fatal("Unterminated local input file");
  258.             if (str2[0] == '<') break;
  259.             lp = newlif(&str2[0],lp);
  260.         }
  261.     }
  262.     if (cp) cp->c_lif = lp;
  263. }
  264.  
  265. /* expand $* in dependencies, by creating a new dep for each */
  266.  
  267. void
  268. expast(struct name * np)
  269. {
  270.     register struct depend *dp;
  271.     register struct line *  lp;
  272.     struct name *           nnp;
  273.     struct depend * *       dpp;
  274.     char *                  p;
  275.     char *                  q;
  276.     char *                  r;
  277.     char *                  rr;
  278.     char *                  suff;
  279.     char                    expb[64];
  280.     static char             experr[] = {"Unable to expand $*"};
  281.  
  282.     for (lp = np->n_line; lp; lp = lp->l_next)
  283.     {
  284.         for (dp = lp->l_dep; dp; dp = dp->d_next)
  285.         {
  286.             rr = (char *)0;
  287.             p = r = dp->d_name->n_name;
  288.             while (*p)
  289.             {
  290.                 if ( ((*p & 0xff) == 0244) && ((*(p + 1) & 0xff) == 0244) )
  291.                 {
  292.                     rr = p;
  293.                     break;
  294.                 }
  295.                 p++;
  296.             }
  297.             if (rr != (char *)0)
  298.             {
  299.                 q = np->n_name;                 /* get target name */
  300.                 if ((strlen(q) + strlen(r)) > 60) fatal(experr);
  301.                 p = expb;
  302.                 while (r < rr) *p++ = *r++;
  303.                 suff = suffix(q);
  304.                 while (q < suff) *p++ = *q++;
  305.                 r += 2;                         /* skip special marker */
  306.                 while (*r) *p++ = *r++;
  307.                 *p = '\0';
  308.                 nnp = newname(expb);            /* make a new dependent */
  309.                 for (dpp = &(lp->l_dep); *dpp; dpp = &((*dpp)->d_next))
  310.                 {
  311.                     if (*dpp == dp)
  312.                     {
  313.                         *dpp = (struct depend *)malloc(sizeof(struct depend));
  314.                         if (*dpp == (struct depend *)0) fatal(experr);
  315.                         (*dpp)->d_next = dp->d_next;
  316.                         (*dpp)->d_name = nnp;
  317.                     }
  318.                 }
  319.             }
  320.         }
  321.     }
  322. }
  323.  
  324. /*****  parse input from the makefile, and construct a tree structure of it */
  325.  
  326. void
  327. input()
  328. {
  329.     char *                  p;              /*  General  */
  330.     char *                  q;
  331.     struct name *           np;
  332.     struct depend *         dp;
  333.     struct cmd *            cp;
  334.     struct cmd *            crp;
  335.     bool                    dbl;
  336.  
  337.     if (getline(str1)) return;      /* read the first line */
  338.     setmacro("*","\244\244");       /* special marker for $* */
  339.  
  340.     for(;;)
  341.     {
  342.         if (*str1 == '\t')          /* rules without targets */
  343.             error("Command found with no target/dependancy line");
  344.  
  345.         p = str1;
  346.         while (pspace(*p)) p++;    /* find first target */
  347.  
  348.         while (((q = strchr(p, '=')) != (char *)0) &&
  349.             (p != q) && (q[-1] == '\\'))        /*  Find value */
  350.         {
  351.             register char * a;
  352.  
  353.             a = q - 1;              /* del \ chr; move rest back */
  354.             p = q;
  355.             while ((*a++ = *q++) != '\0')
  356.                 ;
  357.         }
  358.  
  359.         if (q != (char *)0)
  360.         {
  361.             register char * a;
  362.  
  363.             *q++ = '\0';            /* separate name and val */
  364.             while (pspace(*q)) q++;
  365.             if ((p = strrchr(q, '\n')) != (char *)0) *p = '\0';
  366.             p = str1;
  367.             if ((a = gettok(&p)) == (char *)0)
  368.                 error("Macro definition without macro name");
  369.             setmacro(a, q);
  370.             if (getline(str1)) return;
  371.             continue;
  372.         }
  373.  
  374.         expand(str1);
  375.         p = str1;
  376.  
  377.         while (((q = strchr(p, ':')) != (char *)0) &&
  378.             (p != q) && (q[-1] == '\\'))        /*  Find dependents  */
  379.         {
  380.             register char * a;
  381.  
  382.             a = q - 1;      /* del \ chr; move rest back */
  383.             p = q;
  384.             while ((*a++ = *q++) != '\0')
  385.                 ;
  386.         }
  387.  
  388.         if (q == (char *)0) error("Cannot find any targets");
  389.  
  390.         *q++ = '\0';                /* separate targets and dependents */
  391.  
  392.         if (*q == ':')              /* double colon */
  393.         {
  394.             dbl = 1;
  395.             q++;
  396.         }
  397.         else
  398.             dbl = 0;
  399.  
  400.         for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
  401.          
  402.         {                           /* get list of dep's */
  403.             np = newname(p);        /* intern name */
  404.             dp = newdep(np, dp);    /* add to dep list */
  405.         }
  406.  
  407.         *((q = str1) + strlen(str1) + 1) = '\0';    /* two nulls for gettok */
  408.         cp = (struct cmd *)0;
  409.         if (getline(str2) == FALSE) /* get commands */
  410.         {
  411.             while (*str2 == '\t')
  412.             {
  413.                 cp = newcmd(&str2[0], cp, &crp);
  414.                 checklif(crp); 
  415.                 if (getline(str2)) break;
  416.             }
  417.         }
  418.  
  419.         while ((p = gettok(&q)) != (char *)0)   /* get list of targ's */
  420.         {
  421.             np = newname(p);                    /* intern name */
  422.             newline(np, dp, cp, dbl);
  423.             expast(np);                         /* expand $* in dep */
  424.             if (!firstname && p[0] != '.') firstname = np;
  425.         }
  426.  
  427.         if (nestlvl < 0) return;                /* eof? */
  428.         strcpy(str1, str2);
  429.     }
  430. }
  431.