This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
newer Getopt/Long.pm from public distribution cited in:
[perl5.git] / vms / munchconfig.c
CommitLineData
97abc6ad
HM
1/* munchconfig.c
2
3 A very, very (very!) simple program to process a config_h.sh file on
4 non-unix systems.
5
6 usage:
7 munchconfig config.sh config_h.sh [foo=bar [baz=xyzzy [...]]] >config.h
8
9 which is to say, it takes as its firt parameter a config.sh (or
10 equivalent), as its second a config_h.sh (or equvalent), and a list of
11 optional tag=value pairs.
12
13 It spits the processed config.h out to STDOUT.
14
15 */
16
17#include <stdio.h>
18#include <errno.h>
19#include <stdlib.h>
20#include <string.h>
21#include <ctype.h>
22
23/* The failure code to exit with */
24#ifndef EXIT_FAILURE
25#ifdef VMS
26#define EXIT_FAILURE 0
27#else
28#define EXIT_FAILURE -1
29#endif
30#endif
31
32/* The biggest line we can read in from a file */
33#define LINEBUFFERSIZE 400
34#define NUMTILDESUBS 30
35#define NUMCONFIGSUBS 1000
36#define TOKENBUFFERSIZE 80
37
38typedef struct {
39 char Tag[TOKENBUFFERSIZE];
40 char Value[512];
41} Translate;
42
43void tilde_sub(char [], Translate [], int);
44
45int
46main(int argc, char *argv[])
47{
48 FILE *ConfigSH, *Config_H;
49 char LineBuffer[LINEBUFFERSIZE], *TempValue, *StartTilde, *EndTilde;
50 char SecondaryLineBuffer[LINEBUFFERSIZE];
51 char TokenBuffer[TOKENBUFFERSIZE];
52 int LineBufferLength, TempLength, DummyVariable, LineBufferLoop;
53 int TokenBufferLoop, ConfigSubLoop, GotIt;
54 Translate TildeSub[NUMTILDESUBS]; /* Holds the tilde (~FOO~) */
55 /* substitutions */
56 Translate ConfigSub[NUMCONFIGSUBS]; /* Holds the substitutions from */
57 /* config.sh */
58 int TildeSubCount = 0, ConfigSubCount = 0; /* # of tilde substitutions */
59 /* and config substitutions, */
60 /* respectively */
61 if (argc < 3) {
62 printf("Usage: munchconfig config.sh config_h.sh [foo=bar [baz=xyzzy [...]]]\n");
63 exit(EXIT_FAILURE);
64 }
65
66
67 /* First, open the input files */
68 if (NULL == (ConfigSH = fopen(argv[1], "r"))) {
69 printf("Error %i trying to open config.sh file %s\n", errno, argv[1]);
70 exit(EXIT_FAILURE);
71 }
72
73 if (NULL == (Config_H = fopen(argv[2], "r"))) {
74 printf("Error %i trying to open config_h.sh file %s\n", errno, argv[2]);
75 exit(EXIT_FAILURE);
76 }
77
78 /* Any tag/value pairs on the command line? */
79 if (argc > 3) {
80 int i;
81 char WorkString[80];
82 for (i=3; i < argc && argv[i]; i++) {
83
84 /* Local copy */
85 strcpy(WorkString, argv[i]);
86 /* Stick a NULL over the = */
87 TempValue = strchr(WorkString, '=');
88 *TempValue++ = '\0';
89
90 /* Copy the tag and value into the holding array */
91 strcpy(TildeSub[TildeSubCount].Tag, WorkString);
92 strcpy(TildeSub[TildeSubCount].Value, TempValue);
93 TildeSubCount++;
94 }
95 }
96
97 /* Now read in the config.sh file. */
98 while(fgets(LineBuffer, LINEBUFFERSIZE - 1, ConfigSH)) {
99 /* Force a trailing null, just in case */
100 LineBuffer[LINEBUFFERSIZE - 1] = '\0';
101
102 LineBufferLength = strlen(LineBuffer);
103
104 /* Chop trailing control characters */
105 while((LineBufferLength > 0) && (LineBuffer[LineBufferLength-1] < ' ')) {
106 LineBuffer[LineBufferLength - 1] = '\0';
107 LineBufferLength--;
108 }
109
110 /* If it's empty, then try again */
111 if (!*LineBuffer)
112 continue;
113
114 /* If the line begins with a '#' or ' ', skip */
115 if ((LineBuffer[0] == ' ') || (LineBuffer[0] == '#'))
116 continue;
117
118 /* We've got something. Guess we need to actually handle it */
119 /* Do the tilde substitution */
120 tilde_sub(LineBuffer, TildeSub, TildeSubCount);
121
122 /* Stick a NULL over the = */
123 TempValue = strchr(LineBuffer, '=');
124 *TempValue++ = '\0';
125 /* And another over the leading ', which better be there */
126 *TempValue++ = '\0';
127
128 /* Check to see if there's a trailing '. If not, add a newline to the */
129 /* buffer and grab another line. */
130 TempLength = strlen(TempValue);
131 while (TempValue[TempLength-1] != '\'') {
132 fgets(SecondaryLineBuffer, LINEBUFFERSIZE - 1, ConfigSH);
133 /* Force a trailing null, just in case */
134 SecondaryLineBuffer[LINEBUFFERSIZE - 1] = '\0';
135 /* Go substitute */
136 tilde_sub(SecondaryLineBuffer, TildeSub, TildeSubCount);
137 /* Tack a nweline on the end of our primary buffer */
138 strcat(TempValue, "\n");
139 /* Concat the new line we just read */
140 strcat(TempValue, SecondaryLineBuffer);
141
142 /* Refigure the length */
143 TempLength = strlen(TempValue);
144
145 /* Chop trailing control characters */
146 while((TempLength > 0) && (TempValue[TempLength-1] < ' ')) {
147 TempValue[TempLength - 1] = '\0';
148 TempLength--;
149 }
150 }
151
152 /* And finally one over the trailing ' */
153 TempValue[TempLength-1] = '\0';
154
155 /* Is there even anything left? */
156 if(*TempValue) {
157 /* Copy the tag over */
158 strcpy(ConfigSub[ConfigSubCount].Tag, LineBuffer);
159 /* Copy the value over */
160 strcpy(ConfigSub[ConfigSubCount].Value, TempValue);
161
162 /* Up the count */
163 ConfigSubCount++;
164
165 }
166 }
167
168 /* Okay, we've read in all the substititions from our config.sh */
169 /* equivalent. Read in the config_h.sh equiv and start the substitution */
170
171 /* First, eat all the lines until we get to one with !GROK!THIS! in it */
172 while(!strstr(fgets(LineBuffer, LINEBUFFERSIZE, Config_H),
173 "!GROK!THIS!")) {
174
175 /* Dummy statement to shut up any compiler that'll whine about an empty */
176 /* loop */
177 DummyVariable++;
178 }
179
180 /* Right, we've read all the lines through the first one with !GROK!THIS! */
181 /* in it. That gets us through the beginning stuff. Now start in earnest */
182 /* with our translations, which run until we get to another !GROK!THIS! */
183 while(!strstr(fgets(LineBuffer, LINEBUFFERSIZE, Config_H),
184 "!GROK!THIS!")) {
185 /* Force a trailing null, just in case */
186 LineBuffer[LINEBUFFERSIZE - 1] = '\0';
187
188 /* Tilde Substitute */
189 tilde_sub(LineBuffer, TildeSub, TildeSubCount);
190
191 LineBufferLength = strlen(LineBuffer);
192
193 /* Chop trailing control characters */
194 while((LineBufferLength > 0) && (LineBuffer[LineBufferLength-1] < ' ')) {
195 LineBuffer[LineBufferLength - 1] = '\0';
196 LineBufferLength--;
197 }
198
199 /* Right. Go looking for $s. */
200 for(LineBufferLoop = 0; LineBufferLoop < LineBufferLength;
201 LineBufferLoop++) {
202 /* Did we find one? */
203 if ('$' != LineBuffer[LineBufferLoop]) {
204 /* Nope, spit out the value */
205 putchar(LineBuffer[LineBufferLoop]);
206 } else {
207 /* Yes, we did. Is it escaped? */
208 if ((LineBufferLoop > 0) && ('\\' == LineBuffer[LineBufferLoop -
209 1])) {
210 /* Yup. Spit it out */
211 putchar(LineBuffer[LineBufferLoop]);
212 } else {
213 /* Nope. Go grab us a token */
214 TokenBufferLoop = 0;
215 /* Advance to the next character in the input stream */
216 LineBufferLoop++;
217 while((LineBufferLoop < LineBufferLength) &&
218 ((isalnum(LineBuffer[LineBufferLoop]) || ('_' ==
219 LineBuffer[LineBufferLoop])))) {
220 TokenBuffer[TokenBufferLoop] = LineBuffer[LineBufferLoop];
221 LineBufferLoop++;
222 TokenBufferLoop++;
223 }
224
225 /* Trailing null on the token buffer */
226 TokenBuffer[TokenBufferLoop] = '\0';
227
228 /* Back the line buffer pointer up one */
229 LineBufferLoop--;
230
231 /* Right, we're done grabbing a token. Check to make sure we got */
232 /* something */
233 if (TokenBufferLoop) {
234 /* Well, we do. Run through all the tokens we've got in the */
235 /* ConfigSub array and see if any match */
236 GotIt = 0;
237 for(ConfigSubLoop = 0; ConfigSubLoop < ConfigSubCount;
238 ConfigSubLoop++) {
239 if (!strcmp(TokenBuffer, ConfigSub[ConfigSubLoop].Tag)) {
240 GotIt = 1;
241 printf("%s", ConfigSub[ConfigSubLoop].Value);
242 break;
243 }
244 }
245
246 /* Did we find something? If not, spit out what was in our */
247 /* buffer */
248 if (!GotIt) {
249 printf("$%s", TokenBuffer);
250 }
251
252 } else {
253 /* Just a bare $. Spit it out */
254 putchar('$');
255 }
256 }
257 }
258 }
259
260 /* We're all done. Spit out an EOL */
261 printf("\n");
262
263
264 }
265
266 /* Close the files */
267 fclose(ConfigSH);
268 fclose(Config_H);
269}
270
271void
272tilde_sub(char LineBuffer[], Translate TildeSub[], int TildeSubCount)
273{
274 char TempBuffer[LINEBUFFERSIZE], TempTilde[TOKENBUFFERSIZE];
275 int TildeLoop, InTilde, CopiedBufferLength, TildeBufferLength, k, GotIt;
276 int TempLength;
277 InTilde = 0;
278 CopiedBufferLength = 0;
279 TildeBufferLength = 0;
280 TempLength = strlen(LineBuffer);
281
282 /* Grovel over our input looking for ~foo~ constructs */
283 for(TildeLoop = 0; TildeLoop < TempLength; TildeLoop++) {
284 /* Are we in a tilde? */
285 if (InTilde) {
286 /* Yup. Is the current character a tilde? */
287 if (LineBuffer[TildeLoop] == '~') {
288 /* Yup. That means we're ready to do a substitution */
289 InTilde = 0;
290 GotIt = 0;
291 /* Trailing null */
292 TempTilde[TildeBufferLength] = '\0';
293 for( k=0; k < TildeSubCount; k++) {
294 if (!strcmp(TildeSub[k].Tag, TempTilde)) {
295 GotIt = 1;
296 /* Tack on the trailing null to the main buffer */
297 TempBuffer[CopiedBufferLength] = '\0';
298 /* Copy the tilde substitution over */
299 strcat(TempBuffer, TildeSub[k].Value);
300 CopiedBufferLength = strlen(TempBuffer);
301 }
302 }
303
304 /* Did we find anything? */
305 if (GotIt == 0) {
306 /* Guess not. Copy the whole thing out verbatim */
307 TempBuffer[CopiedBufferLength] = '\0';
308 TempBuffer[CopiedBufferLength++] = '~';
309 TempBuffer[CopiedBufferLength] = '\0';
310 strcat(TempBuffer, TempTilde);
311 strcat(TempBuffer, "~");
312 CopiedBufferLength = strlen(TempBuffer);
313 }
314
315 } else {
316 /* 'Kay, not a tilde. Is it a word character? */
317 if (isalnum(LineBuffer[TildeLoop]) || (LineBuffer[TildeLoop] =
318 '-') ||
319 (LineBuffer[TildeLoop] == '-')) {
320 TempTilde[TildeBufferLength++] = LineBuffer[TildeLoop];
321 } else {
322 /* No, it's not a tilde character. For shame! We've got a */
323 /* bogus token. Copy a ~ into the output buffer, then append */
324 /* whatever we've got in our token buffer */
325 TempBuffer[CopiedBufferLength++] = '~';
326 TempBuffer[CopiedBufferLength] = '\0';
327 TempTilde[TildeBufferLength] = '\0';
328 strcat(TempBuffer, TempTilde);
329 CopiedBufferLength += TildeBufferLength;
330 InTilde = 0;
331 }
332 }
333 } else {
334 /* We're not in a tilde. Do we want to be? */
335 if (LineBuffer[TildeLoop] == '~') {
336 /* Guess so */
337 InTilde = 1;
338 TildeBufferLength = 0;
339 } else {
340 /* Nope. Copy the character to the output buffer */
341 TempBuffer[CopiedBufferLength++] = LineBuffer[TildeLoop];
342 }
343 }
344 }
345
346 /* Out of the loop. First, double-check to see if there was anything */
347 /* pending. */
348 if (InTilde) {
349 /* bogus token. Copy a ~ into the output buffer, then append */
350 /* whatever we've got in our token buffer */
351 TempBuffer[CopiedBufferLength++] = '~';
352 TempBuffer[CopiedBufferLength] = '\0';
353 TempTilde[TildeBufferLength] = '\0';
354 strcat(TempBuffer, TempTilde);
355 CopiedBufferLength += TildeBufferLength;
356 } else {
357 /* Nope, nothing pensing. Tack on a \0 */
358 TempBuffer[CopiedBufferLength] = '\0';
359 }
360
361 /* Okay, we're done. Copy the temp buffer back into the line buffer */
362 strcpy(LineBuffer, TempBuffer);
363
364}
365