[9] | 1 | /*************************************************************************
|
---|
| 2 | *
|
---|
| 3 | * m a k e : m a c r o . c
|
---|
| 4 | *
|
---|
| 5 | * Macro control for make
|
---|
| 6 | *========================================================================
|
---|
| 7 | * Edition history
|
---|
| 8 | *
|
---|
| 9 | * # Date Comments By
|
---|
| 10 | * --- -------- ---------------------------------------------------- ---
|
---|
| 11 | * 1 ?? ??
|
---|
| 12 | * 2 23.08.89 Error message corrected RAL
|
---|
| 13 | * 3 30.08.89 macro flags added, indention ch. PSH,RAL
|
---|
| 14 | * 4 03.09.89 fixed LZ eliminated, doexp(...) changed RAL
|
---|
| 15 | * 5 06.09.89 M_MAKE added, setDFmacro added RAL
|
---|
| 16 | * 6 20.09.89 work around for Minix PC ACK bug BE,RAL
|
---|
| 17 | * ------------ Version 2.0 released ------------------------------- RAL
|
---|
| 18 | *
|
---|
| 19 | *************************************************************************/
|
---|
| 20 |
|
---|
| 21 | #include "h.h"
|
---|
| 22 |
|
---|
| 23 |
|
---|
| 24 | static char buf[256];
|
---|
| 25 |
|
---|
| 26 | struct macro *getmp(name)
|
---|
| 27 | char *name;
|
---|
| 28 | {
|
---|
| 29 | register struct macro *rp;
|
---|
| 30 |
|
---|
| 31 | for (rp = macrohead; rp; rp = rp->m_next)
|
---|
| 32 | if (strcmp(name, rp->m_name) == 0)
|
---|
| 33 | return rp;
|
---|
| 34 | return (struct macro *)0;
|
---|
| 35 | }
|
---|
| 36 |
|
---|
| 37 |
|
---|
| 38 | char *getmacro(name)
|
---|
| 39 | char *name;
|
---|
| 40 | {
|
---|
| 41 | struct macro *mp;
|
---|
| 42 |
|
---|
| 43 | if (mp = getmp(name))
|
---|
| 44 | return mp->m_val;
|
---|
| 45 | /* else*/
|
---|
| 46 | return "";
|
---|
| 47 | }
|
---|
| 48 |
|
---|
| 49 |
|
---|
| 50 | struct macro *setmacro(name, val)
|
---|
| 51 | char *name;
|
---|
| 52 | char *val;
|
---|
| 53 | {
|
---|
| 54 | register struct macro *rp;
|
---|
| 55 | register char *cp;
|
---|
| 56 |
|
---|
| 57 |
|
---|
| 58 | /* Replace macro definition if it exists */
|
---|
| 59 | for (rp = macrohead; rp; rp = rp->m_next)
|
---|
| 60 | if (strcmp(name, rp->m_name) == 0) {
|
---|
| 61 | if(rp->m_flag & M_OVERRIDE) return rp; /* mustn't change */
|
---|
| 62 | free(rp->m_val); /* Free space from old */
|
---|
| 63 | break;
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | if (!rp) /* If not defined, allocate space for new */
|
---|
| 67 | {
|
---|
| 68 | if ((rp = (struct macro *)malloc(sizeof (struct macro)))
|
---|
| 69 | == (struct macro *)0)
|
---|
| 70 | fatal("No memory for macro",(char *)0,0);
|
---|
| 71 |
|
---|
| 72 | rp->m_next = macrohead;
|
---|
| 73 | macrohead = rp;
|
---|
| 74 | rp->m_flag = FALSE;
|
---|
| 75 |
|
---|
| 76 | if ((cp = (char *) malloc(strlen(name)+1)) == (char *)0)
|
---|
| 77 | fatal("No memory for macro",(char *)0,0);
|
---|
| 78 | strcpy(cp, name);
|
---|
| 79 | rp->m_name = cp;
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | if ((cp = (char *) malloc(strlen(val)+1)) == (char *)0)
|
---|
| 83 | fatal("No memory for macro",(char *)0,0);
|
---|
| 84 | strcpy(cp, val); /* Copy in new value */
|
---|
| 85 | rp->m_val = cp;
|
---|
| 86 |
|
---|
| 87 | return rp;
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 |
|
---|
| 91 | void setDFmacro(name, val)
|
---|
| 92 | char *name;
|
---|
| 93 | char *val;
|
---|
| 94 | {
|
---|
| 95 | char *c,*tmp;
|
---|
| 96 | int len;
|
---|
| 97 | static char filename[]="@F";
|
---|
| 98 | static char dirname[] ="@D";
|
---|
| 99 |
|
---|
| 100 | setmacro(name,val);
|
---|
| 101 | *filename = *name;
|
---|
| 102 | *dirname = *name;
|
---|
| 103 | /* Null string -- not defined macro */
|
---|
| 104 | if ( !(*val)) {
|
---|
| 105 | setmacro(filename,"");
|
---|
| 106 | setmacro(dirname,"");
|
---|
| 107 | return;
|
---|
| 108 | }
|
---|
| 109 | if (!(c = strrchr(val,(int)'/'))) {
|
---|
| 110 | setmacro(filename,val);
|
---|
| 111 | setmacro(dirname,"./");
|
---|
| 112 | return;
|
---|
| 113 | }
|
---|
| 114 | setmacro(filename,c+1);
|
---|
| 115 | len = c - val + 1;
|
---|
| 116 | if((tmp = (char *) malloc(len + 1)) == (char *) 0)
|
---|
| 117 | fatal("No memory for tmp",(char *)0,0);
|
---|
| 118 | strncpy(tmp,val,len);
|
---|
| 119 | tmp[len] = '\0';
|
---|
| 120 | setmacro(dirname,tmp);
|
---|
| 121 | free(tmp);
|
---|
| 122 | return;
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | /*
|
---|
| 126 | * Do the dirty work for expand
|
---|
| 127 | */
|
---|
| 128 | void doexp(to, from)
|
---|
| 129 | struct str *to;
|
---|
| 130 | char *from;
|
---|
| 131 | {
|
---|
| 132 | register char *rp;
|
---|
| 133 | register char *p;
|
---|
| 134 | char *q;
|
---|
| 135 | struct macro *mp;
|
---|
| 136 |
|
---|
| 137 |
|
---|
| 138 | rp = from;
|
---|
| 139 | p = &(*to->ptr)[to->pos];
|
---|
| 140 | while (*rp) {
|
---|
| 141 | if (*rp != '$') {
|
---|
| 142 | *p++ = *rp++;
|
---|
| 143 | to->pos++;
|
---|
| 144 | }
|
---|
| 145 | else {
|
---|
| 146 | q = buf;
|
---|
| 147 | if (*++rp == '{')
|
---|
| 148 | while (*++rp && *rp != '}')
|
---|
| 149 | *q++ = *rp;
|
---|
| 150 | else if (*rp == '(')
|
---|
| 151 | while (*++rp && *rp != ')')
|
---|
| 152 | *q++ = *rp;
|
---|
| 153 | else if (!*rp) {
|
---|
| 154 | *p++ = '$';
|
---|
| 155 | to->pos++;
|
---|
| 156 | goto bail;
|
---|
| 157 | }
|
---|
| 158 | else
|
---|
| 159 | *q++ = *rp;
|
---|
| 160 | *q = '\0';
|
---|
| 161 | if (*rp)
|
---|
| 162 | rp++;
|
---|
| 163 | if (!(mp = getmp(buf)))
|
---|
| 164 | mp = setmacro(buf, "");
|
---|
| 165 | if (mp->m_flag & M_MARK)
|
---|
| 166 | fatal("Infinitely recursive macro %s", mp->m_name,0);
|
---|
| 167 | mp->m_flag |= M_MARK;
|
---|
| 168 | if ( mp->m_flag & M_MAKE) expmake = TRUE;
|
---|
| 169 | doexp(to, mp->m_val);
|
---|
| 170 | p = &(*to->ptr)[to->pos];
|
---|
| 171 | mp->m_flag &= ~M_MARK;
|
---|
| 172 | }
|
---|
| 173 | bail:
|
---|
| 174 | if (to->pos >= to->len) {
|
---|
| 175 | strrealloc(to);
|
---|
| 176 | p = &(*to->ptr)[to->pos];
|
---|
| 177 | }
|
---|
| 178 | }
|
---|
| 179 | *p = '\0';
|
---|
| 180 | }
|
---|
| 181 |
|
---|
| 182 |
|
---|
| 183 | /*
|
---|
| 184 | * Expand any macros in str.
|
---|
| 185 | */
|
---|
| 186 | void expand(strs)
|
---|
| 187 | struct str *strs;
|
---|
| 188 | {
|
---|
| 189 | char *a;
|
---|
| 190 |
|
---|
| 191 | if ((a = (char *) malloc(strlen(*strs->ptr)+1)) == (char *)0)
|
---|
| 192 | fatal("No memory for temporary string",(char *)0,0);
|
---|
| 193 | strcpy(a, *strs->ptr);
|
---|
| 194 | strs->pos = 0;
|
---|
| 195 | doexp(strs, a);
|
---|
| 196 | free(a);
|
---|
| 197 | }
|
---|