home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / PAMAKE18.ZIP / MACRO.C < prev    next >
C/C++ Source or Header  |  1989-09-30  |  6KB  |  232 lines

  1. /*************************************************************************
  2. |                                                                        |
  3. |   MACRO.C                                                     31.08.89 |
  4. |   PAMAKE Utility:  macro control functions                             |
  5. |                                                                        |
  6. *************************************************************************/
  7.  
  8. #ifdef VMS
  9. #include stdio
  10. #include string
  11. #include stdlib
  12. #include "h.h"
  13. #else
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include "h.h"
  18. #endif
  19.  
  20. /*****  do not include <ctypes.h> */
  21.  
  22. struct macro *          macrohead;
  23.  
  24. /*****  get macro, do substitutions */
  25.  
  26. struct macro *
  27. getmp(name)
  28. char *          name;
  29. {
  30.     register struct macro * rp;
  31.     char *                  p;
  32.     char *                  q;
  33.     char *                  qq;
  34.     char *                  qqq;
  35.     char *                  sub1 = NULL;
  36.     char *                  sub2 = NULL;
  37.     char *                  a;
  38.  
  39.     p = strchr(name,':');
  40.     if (p)
  41.     {
  42.         sub1 = p+1;
  43.         *p = '\0';
  44.         sub2 = strchr(sub1,'=');
  45.         if (sub2) *sub2++ = '\0';
  46.         else sub2 = "";
  47.     }
  48.  
  49.     for (rp = macrohead; rp; rp = rp->m_next)
  50.         if (strcmp(name, rp->m_name) == 0)
  51.         {
  52.             rp->m_sub = NULL;
  53.             if (sub1)
  54.             {
  55.                 a = malloc(LZ);
  56.                 if (!a) fatal("No memory for macro substitution");
  57.                 p = a;
  58.                 q = rp->m_val;
  59.                 while ((qq = pstrstr(q,sub1)) != (char *)0)
  60.                 {
  61.                     for (qqq = q; qqq < qq;) *p++ = *qqq++;
  62.                     q = qq + strlen(sub1);
  63.                     qqq = sub2;
  64.                     while (*qqq) *p++ = *qqq++;
  65.                 }
  66.                 if (q != rp->m_val)
  67.                 {
  68.                     strcpy(p,q);
  69.                     rp->m_sub = a;
  70.                 }
  71.                 else
  72.                     free(a);
  73.             }
  74.             return rp;
  75.         }
  76.     return (struct macro *)0;
  77. }
  78.  
  79. /*****  Do the dirty work for expand */
  80.  
  81. void
  82. doexp(to, from, len, buf)
  83. char * *        to;
  84. char *          from;
  85. int *           len;
  86. char *          buf;
  87. {
  88.     register char *         rp;
  89.     register char *         p;
  90.     register char *         q;
  91.     register struct macro * mp;
  92.  
  93.     rp = from;
  94.     p = *to;
  95.     while (*rp)
  96.     {
  97.         if (*rp != '$')
  98.         {
  99.             *p++ = *rp++;
  100.             (*len)--;
  101.         }
  102.         else
  103.         {
  104.             q = buf;
  105.             if (*++rp == '{')
  106.                 while (*++rp && *rp != '}')
  107.                     *q++ = *rp;
  108.             else if (*rp == '(')
  109.                 while (*++rp && *rp != ')')
  110.                     *q++ = *rp;
  111.             else if (!*rp)
  112.             {
  113.                 *p++ = '$';
  114.                 break;
  115.             }
  116.             else
  117.                 *q++ = *rp;
  118.             *q = '\0';
  119.             if (*rp)
  120.                 rp++;
  121.             if (!(mp = getmp(buf)))
  122.                 mp = setmacro(buf, "");
  123.             if (mp->m_flag & M_LOOPCHK)
  124.                 fatal("Macro %s cannot be expanded: infinite recursion", mp->m_name);
  125.             mp->m_flag = M_LOOPCHK;
  126.             *to = p;
  127.             if (mp->m_sub)
  128.             {
  129.                 doexp(to, mp->m_sub, len, buf);
  130.                 free(mp->m_sub);
  131.             }
  132.             else
  133.                 doexp(to, mp->m_val, len, buf);
  134.             p = *to;
  135.             mp->m_flag &= ~M_LOOPCHK;
  136.         }
  137.         if (*len <= 0)
  138.             error("Macro expansion too long");
  139.     }
  140.     *p = '\0';
  141.     *to = p;
  142. }
  143.  
  144. /*****  expand any macros in str */
  145.  
  146. void
  147. expand(str)
  148. char *          str;
  149. {
  150.     static char             a[LZ];
  151.     static char             b[LZ];
  152.     char *                  p = str;
  153.     int                     len = LZ-1;
  154.  
  155.     strcpy(a, str);
  156.     doexp(&p, a, &len, b);
  157. }
  158.  
  159.  
  160. /*****  mark all M_ENV macros as permanent (M_PERM) */
  161.  
  162. void
  163. markmacros()
  164. {
  165.     register struct macro * rp;
  166.  
  167.     for (rp = macrohead; rp; rp = rp->m_next)
  168.     {
  169.         if (rp->m_flag & M_ENV) rp->m_flag |= M_PERM;
  170.     }
  171. }
  172.  
  173. /*****  set macro value */
  174.  
  175. struct macro *
  176. setmacro(name, val)
  177. char *          name;
  178. char *          val;
  179. {
  180.     register struct macro * rp;
  181.     register char *         cp;
  182.     register int            i,j;
  183.     static char             buf[LZ];
  184.     static char             macerr[] = {"Cannot allocate memory for macro"};
  185.  
  186.     if (*name == '+') 
  187.     {
  188.         name++;
  189.         if ( (strlen(name) + strlen(val)) < 126)
  190.         {
  191.             for (i = 0, j = 0; name[j]; ) buf[i++] = (char)(toupper(*(name+(j++))));
  192.             buf[i++] = '=';
  193.             for (j = 0; *(val+j); ) buf[i++] = *(val+(j++));
  194.             buf[i++] = '\0';
  195.             expand(buf);
  196. #ifndef VMS
  197.             putenv(strdup(buf));
  198. #endif            
  199.         }
  200.     }
  201.  
  202. /*****  replace macro definition if it exists  */
  203. /*****  don't let macros derived from external env. be replaced if -e given */
  204.  
  205.     for (rp = macrohead; rp; rp = rp->m_next)
  206.         if (strcmp(name, rp->m_name) == 0)
  207.         {
  208.             if (rp->m_flag & M_PERM) return rp;
  209.             free(rp->m_val);        /*  Free space from old  */
  210.             break;
  211.         }
  212.  
  213.     if (!rp)                /*  If not defined, allocate space for new  */
  214.     {
  215.         if ((rp = (struct macro *)malloc(sizeof (struct macro)))
  216.             == (struct macro *)0) fatal(macerr);
  217.         rp->m_next = macrohead;
  218.         macrohead = rp;
  219.         rp->m_sub = NULL;
  220.         if ((cp = malloc(strlen(name)+1)) == (char *)0) fatal(macerr);
  221.         strcpy(cp, name);
  222.         rp->m_name = cp;
  223.     }
  224.  
  225.     if ((cp = malloc(strlen(val)+1)) == (char *)0) fatal(macerr);
  226.     strcpy(cp, val);                /*  Copy in new value  */
  227.     rp->m_val = cp;
  228.     rp->m_flag = macrotype;
  229.  
  230.     return rp;
  231. }
  232.