convert-from-bsd-to-posix-string-and-memory-functions-20010807
[openafs.git] / src / mpp / mpp.c
1 /*
2  *      (C) Copyright 10/17/86 by Carnegie Mellon University
3  */
4 #include <stdio.h>
5
6 extern char *malloc();
7
8 #define maxinputdepth   16
9 #define maxlinesize     1024
10 #define macrohashsize   1023
11 #define macronamesize   32
12 #define maxnestdepth    128
13
14 #define inline  xxinline
15
16 struct nest
17 {
18         int     status;
19 };
20
21 struct file
22 {
23         char    *name;
24         FILE    *stream;
25         int     lineno;
26 };
27
28 struct macro
29 {
30         struct macro    *next;
31         enum macromode { rdwr, rdonly } mode;
32         char            *name;
33         char            *value;
34 };
35
36 static stripcomments = 0;
37 static specialchar = '%';
38 static struct nest nests[maxnestdepth];
39 static struct nest *nestp = &nests[0];
40 static struct nest *lastnestp = &nests[maxnestdepth-1];
41
42 static struct file files[maxinputdepth];
43 static struct file *lastfilep = &files[maxinputdepth-1];
44 static struct file *filep = &files[0];
45
46 static char inline[maxlinesize];
47 static char outline[maxlinesize];
48 static struct macro *macrohashtable[macrohashsize];
49
50 static error(a0,a1)
51         char    *a0,*a1;
52 {
53         fprintf(stderr,a0,a1);
54         putc('\n',stderr);
55         exit(1);
56 }
57 static fileerror(a0,a1)
58         char    *a0,*a1;
59 {
60         fprintf(stderr,"%s; line %d: ",filep->name,filep->lineno);
61         error(a0,a1);
62 }
63
64 static char *strsav(s)
65         char    *s;
66 {
67         char    *p;
68
69         if ((p = malloc(strlen(s)+1)) == NULL)
70                 error("Out of Memory");
71         strcpy(p,s);
72         return p;
73 }
74
75 static struct macro **macrolookup(name)
76         char    *name;
77 {
78         register struct macro **mpp, *mp;
79         register char *cp;
80         register unsigned hv;
81
82         for (cp = name, hv = 0; *cp; hv += *cp++)
83                 ;
84         mpp = &macrohashtable[hv % macrohashsize];
85         while ((mp = *mpp) && strcmp(mp->name,name))
86                 mpp = &mp->next;
87         return mpp;
88 }
89
90 static macroundefine(name)
91         char    *name;
92 {
93         register struct macro **mpp, *mp;
94
95         mpp = macrolookup(name);
96         if (mp = *mpp)
97         {
98                 *mpp = mp->next;
99                 free(mp->value);
100                 free(mp->name);
101                 free(mp);
102         }
103 }
104
105 static macrodefine(name,value,mode)
106         char    *name;
107         char    *value;
108         enum macromode mode;
109 {
110         register struct macro **mpp, *mp;
111
112         mpp = macrolookup(name);
113         if (mp = *mpp)
114         {
115                 if (mp->mode == rdonly)
116                         return;
117                 free(mp->value);
118         }
119         else
120         {
121                 if ((mp = (struct macro *)malloc(sizeof(struct macro))) == 0)
122                         error("Out of memory");
123                 mp->name = strsav(name);
124                 mp->next = 0;
125                 *mpp = mp;
126         }
127         mp->mode = mode;
128         mp->value = strsav(value);
129 }
130
131
132 static char *macroexpand(dst,src)
133         register char *dst, *src;
134 {
135         char    name[macronamesize];
136         register char *np;
137         register struct macro *mp;
138
139         while (*src)
140         {
141                 if (*src != '$')
142                 {
143                         *dst++ = *src++;
144                         continue;
145                 }
146                 src++;
147                 if (*src == '$')
148                 {
149                         *dst++ = '$';
150                         src++;
151                         continue;
152                 }
153                 np = name;
154                 if (*src == '{' || *src == '(')
155                 {
156                         src++;
157                         while (*src)
158                         {
159                                 if (*src == '}' || *src == ')')
160                                 {
161                                         src++;
162                                         break;
163                                 }
164                                 if (np >= &name[macronamesize])
165                                         src++;
166                                 else
167                                         *np++ = *src++;
168                         }
169                 }
170                 else
171                 {
172                         *np++ = *src++;
173                 }
174                 *np = 0;
175                 if (mp = *macrolookup(name))
176                         dst = macroexpand(dst,mp->value);
177         }
178         *dst = 0;
179         return dst;
180 }
181
182
183
184 static readline(line)
185         char    *line;
186 {
187         while (filep >= &files[0])
188         {
189                 filep->lineno++;
190                 if (fgets(line,maxlinesize,filep->stream) != NULL)
191                         return -1;
192                 if (fclose(filep->stream) == EOF)
193                         error("Error closing %s",filep->name);
194                 free(filep->name);
195                 if (filep == &files[0])
196                         return 0;
197                 filep--;
198         }
199         return 0;
200 }
201
202 static writeline(line)
203         char    *line;
204 {
205         fputs(line,stdout);
206 }
207
208
209 static directive(what)
210         char    *what;
211 {
212         char    *arg[ 3 ], *cp;
213         int     n;
214
215         if (*what++ != specialchar)
216                 return nestp->status;
217         if (cp = strrchr(what, '\n'))
218                 *cp = 0;
219         for (n = 0; n < 2; n++)
220         {
221                 while (*what == ' ' || *what == '\t')
222                         what++;
223                 arg[n] = what;
224                 while (*what != ' ' && *what != '\t' && *what != 0)
225                         what++;
226                 if (*what)
227                         *what++ = 0;
228         }
229         while (*what == ' ' || *what == '\t')
230                 what++;
231         arg[2] = what;
232         if (strcmp(arg[0],"ifdef") == 0)
233         {
234                 if (nestp == lastnestp)
235                         fileerror("If Depth overflow");
236                 if (nestp->status == 2 || nestp->status == 1)
237                 {
238                         nestp++;
239                         nestp->status = 2;
240                         return 1;
241                 }
242                 nestp++;
243                 nestp->status = (*macrolookup(arg[1])) ? 0 : 1;
244                 return 1;
245         }
246         if (strcmp(arg[0],"ifndef") == 0)
247         {
248                 if (nestp == lastnestp)
249                         fileerror("If Depth overflow");
250                 if (nestp->status == 2 || nestp->status == 1)
251                 {
252                         nestp++;
253                         nestp->status = 2;
254                         return 1;
255                 }
256                 nestp++;
257                 nestp->status = (*macrolookup(arg[1])) ? 1 : 0;
258                 return 1;
259         }
260         if (strcmp(arg[0],"else") == 0)
261         {
262                 if (nestp->status == 2)
263                         return 1;
264                 if (nestp == &nests[0])
265                         fileerror("If less else");
266                 nestp->status = nestp->status ? 0 : 1;
267                 return 1;
268         }
269         if (strcmp(arg[0],"endif") == 0)
270         {
271                 if (nestp == &nests[0])
272                         fileerror("If less endif");
273                 nestp--;
274                 return 1;
275         }
276         if (nestp->status)
277                 return 1;
278         if (strcmp(arg[0],"include") == 0)
279         {
280                 if (filep == lastfilep)
281                         fileerror("Include file overflow");
282                 filep++;
283                 if ((filep->stream = fopen(arg[1],"r")) == NULL)
284                 {
285                         filep--;
286                         fileerror("Can't open %s",arg[1]);
287                 }
288                 filep->name = strsav(arg[1]);
289                 filep->lineno = 0;
290                 return 1;
291         }
292         if (strcmp(arg[0],"define") == 0)
293         {
294                 macrodefine(arg[1],arg[2],rdwr);
295                 return 1;
296         }
297         if (strcmp(arg[0],"undef") == 0)
298         {
299                 macroundefine(arg[1]);
300                 return 1;
301         }
302         fileerror("Unknown directive %s",arg[0]);
303 }
304
305 expandfile(name)
306         char    *name;
307 {
308         if (strcmp(name,"-") == 0)
309         {
310                 filep->stream = stdin;
311                 filep->name = strsav("(stdin)");
312         }
313         else
314         {
315                 if ((filep->stream = fopen(name,"r")) == NULL)
316                 {
317                         fileerror("Can't open %s",name);
318                         exit(1);
319                 }
320                 filep->name = strsav(name);
321         }
322         filep->lineno = 0;
323         while (readline(inline))
324         {
325                 if (stripcomments)
326                 {
327                         char    *cp;
328                         for (cp = inline; *cp != 0 && *cp != '#'; cp++)
329                                 continue;
330                         *cp = 0;
331                         if (cp == inline)
332                                 continue;
333                 }
334                 (void)macroexpand(outline,inline);
335                 if (directive(outline))
336                         continue;
337                 writeline(outline);
338         }
339 }
340
341 static usage()
342 {
343         fprintf(stderr,
344                 "Usage: mpp [-cC][-s][-Dname=value][-Uname][-][files]\n");
345         exit(1);
346 }
347
348 #include "AFS_component_version_number.c"
349
350 main( argc, argv )
351         int     argc;
352         char    **argv;
353 {
354         argv++, argc--;
355         if (argc == 0)
356                 usage();
357         while (argc > 0)
358         {
359                 if (**argv == '-')
360                 {
361                         if (strcmp(*argv,"-s") == 0)
362                         {
363                                 stripcomments++;
364                                 argv++, argc--;
365                                 continue;
366                         }
367                         if (strncmp(*argv,"-c",sizeof("-c")-1) == 0)
368                         {
369                                 specialchar = argv[0][sizeof("-c")];
370                                 argv++, argc--;
371                                 continue;
372                         }
373                         if (strncmp(*argv,"-U",sizeof("-U")-1) == 0)
374                         {
375                                 macroundefine(&argv[0][sizeof("-U")]);
376                                 argv++, argc--;
377                                 continue;
378                         }
379                         if (strncmp(*argv,"-D",sizeof("-D")-1) == 0)
380                         {
381                                 char    *cp, *cp2;
382
383                                 cp = &argv[0][sizeof("-D")-1];
384                                 if (cp2 = strrchr(cp, '='))
385                                         *cp2++ = 0;
386                                 if (cp2 == 0)
387                                         cp2 = "";
388                                 macrodefine(cp,cp2,rdonly);
389                                 argv++, argc--;
390                                 continue;
391                         }
392                         if (strcmp(*argv,"-"))
393                                 usage();
394                 }
395                 expandfile(*argv);
396                 argv++, argc--;
397         }
398         exit(0);
399 }
400