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 | }
|
---|