diff options
author | Hans Mulder <hansmu@xs4all.nl> | 1998-06-08 08:38:28 -0700 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1998-06-10 05:38:11 +0000 |
commit | 97abc6adffcd3efcbaee73cbdad2055b2d06be4f (patch) | |
tree | 5d55b2348ca41dc8d14ac1b58e655f3259d88bee /vms/munchconfig.c | |
parent | cfc02341d853e4bc320d3abf8ac8ac1c7c3ecaa5 (diff) | |
download | perl-97abc6adffcd3efcbaee73cbdad2055b2d06be4f.tar.gz |
A configuration system for VMS perl
Message-Id: <3.0.5.32.19980608153828.00a81ea0@ous.edu>
p4raw-id: //depot/perl@1084
Diffstat (limited to 'vms/munchconfig.c')
-rw-r--r-- | vms/munchconfig.c | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/vms/munchconfig.c b/vms/munchconfig.c new file mode 100644 index 0000000000..714cab7ea5 --- /dev/null +++ b/vms/munchconfig.c @@ -0,0 +1,365 @@ +/* munchconfig.c + + A very, very (very!) simple program to process a config_h.sh file on + non-unix systems. + + usage: + munchconfig config.sh config_h.sh [foo=bar [baz=xyzzy [...]]] >config.h + + which is to say, it takes as its firt parameter a config.sh (or + equivalent), as its second a config_h.sh (or equvalent), and a list of + optional tag=value pairs. + + It spits the processed config.h out to STDOUT. + + */ + +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +/* The failure code to exit with */ +#ifndef EXIT_FAILURE +#ifdef VMS +#define EXIT_FAILURE 0 +#else +#define EXIT_FAILURE -1 +#endif +#endif + +/* The biggest line we can read in from a file */ +#define LINEBUFFERSIZE 400 +#define NUMTILDESUBS 30 +#define NUMCONFIGSUBS 1000 +#define TOKENBUFFERSIZE 80 + +typedef struct { + char Tag[TOKENBUFFERSIZE]; + char Value[512]; +} Translate; + +void tilde_sub(char [], Translate [], int); + +int +main(int argc, char *argv[]) +{ + FILE *ConfigSH, *Config_H; + char LineBuffer[LINEBUFFERSIZE], *TempValue, *StartTilde, *EndTilde; + char SecondaryLineBuffer[LINEBUFFERSIZE]; + char TokenBuffer[TOKENBUFFERSIZE]; + int LineBufferLength, TempLength, DummyVariable, LineBufferLoop; + int TokenBufferLoop, ConfigSubLoop, GotIt; + Translate TildeSub[NUMTILDESUBS]; /* Holds the tilde (~FOO~) */ + /* substitutions */ + Translate ConfigSub[NUMCONFIGSUBS]; /* Holds the substitutions from */ + /* config.sh */ + int TildeSubCount = 0, ConfigSubCount = 0; /* # of tilde substitutions */ + /* and config substitutions, */ + /* respectively */ + if (argc < 3) { + printf("Usage: munchconfig config.sh config_h.sh [foo=bar [baz=xyzzy [...]]]\n"); + exit(EXIT_FAILURE); + } + + + /* First, open the input files */ + if (NULL == (ConfigSH = fopen(argv[1], "r"))) { + printf("Error %i trying to open config.sh file %s\n", errno, argv[1]); + exit(EXIT_FAILURE); + } + + if (NULL == (Config_H = fopen(argv[2], "r"))) { + printf("Error %i trying to open config_h.sh file %s\n", errno, argv[2]); + exit(EXIT_FAILURE); + } + + /* Any tag/value pairs on the command line? */ + if (argc > 3) { + int i; + char WorkString[80]; + for (i=3; i < argc && argv[i]; i++) { + + /* Local copy */ + strcpy(WorkString, argv[i]); + /* Stick a NULL over the = */ + TempValue = strchr(WorkString, '='); + *TempValue++ = '\0'; + + /* Copy the tag and value into the holding array */ + strcpy(TildeSub[TildeSubCount].Tag, WorkString); + strcpy(TildeSub[TildeSubCount].Value, TempValue); + TildeSubCount++; + } + } + + /* Now read in the config.sh file. */ + while(fgets(LineBuffer, LINEBUFFERSIZE - 1, ConfigSH)) { + /* Force a trailing null, just in case */ + LineBuffer[LINEBUFFERSIZE - 1] = '\0'; + + LineBufferLength = strlen(LineBuffer); + + /* Chop trailing control characters */ + while((LineBufferLength > 0) && (LineBuffer[LineBufferLength-1] < ' ')) { + LineBuffer[LineBufferLength - 1] = '\0'; + LineBufferLength--; + } + + /* If it's empty, then try again */ + if (!*LineBuffer) + continue; + + /* If the line begins with a '#' or ' ', skip */ + if ((LineBuffer[0] == ' ') || (LineBuffer[0] == '#')) + continue; + + /* We've got something. Guess we need to actually handle it */ + /* Do the tilde substitution */ + tilde_sub(LineBuffer, TildeSub, TildeSubCount); + + /* Stick a NULL over the = */ + TempValue = strchr(LineBuffer, '='); + *TempValue++ = '\0'; + /* And another over the leading ', which better be there */ + *TempValue++ = '\0'; + + /* Check to see if there's a trailing '. If not, add a newline to the */ + /* buffer and grab another line. */ + TempLength = strlen(TempValue); + while (TempValue[TempLength-1] != '\'') { + fgets(SecondaryLineBuffer, LINEBUFFERSIZE - 1, ConfigSH); + /* Force a trailing null, just in case */ + SecondaryLineBuffer[LINEBUFFERSIZE - 1] = '\0'; + /* Go substitute */ + tilde_sub(SecondaryLineBuffer, TildeSub, TildeSubCount); + /* Tack a nweline on the end of our primary buffer */ + strcat(TempValue, "\n"); + /* Concat the new line we just read */ + strcat(TempValue, SecondaryLineBuffer); + + /* Refigure the length */ + TempLength = strlen(TempValue); + + /* Chop trailing control characters */ + while((TempLength > 0) && (TempValue[TempLength-1] < ' ')) { + TempValue[TempLength - 1] = '\0'; + TempLength--; + } + } + + /* And finally one over the trailing ' */ + TempValue[TempLength-1] = '\0'; + + /* Is there even anything left? */ + if(*TempValue) { + /* Copy the tag over */ + strcpy(ConfigSub[ConfigSubCount].Tag, LineBuffer); + /* Copy the value over */ + strcpy(ConfigSub[ConfigSubCount].Value, TempValue); + + /* Up the count */ + ConfigSubCount++; + + } + } + + /* Okay, we've read in all the substititions from our config.sh */ + /* equivalent. Read in the config_h.sh equiv and start the substitution */ + + /* First, eat all the lines until we get to one with !GROK!THIS! in it */ + while(!strstr(fgets(LineBuffer, LINEBUFFERSIZE, Config_H), + "!GROK!THIS!")) { + + /* Dummy statement to shut up any compiler that'll whine about an empty */ + /* loop */ + DummyVariable++; + } + + /* Right, we've read all the lines through the first one with !GROK!THIS! */ + /* in it. That gets us through the beginning stuff. Now start in earnest */ + /* with our translations, which run until we get to another !GROK!THIS! */ + while(!strstr(fgets(LineBuffer, LINEBUFFERSIZE, Config_H), + "!GROK!THIS!")) { + /* Force a trailing null, just in case */ + LineBuffer[LINEBUFFERSIZE - 1] = '\0'; + + /* Tilde Substitute */ + tilde_sub(LineBuffer, TildeSub, TildeSubCount); + + LineBufferLength = strlen(LineBuffer); + + /* Chop trailing control characters */ + while((LineBufferLength > 0) && (LineBuffer[LineBufferLength-1] < ' ')) { + LineBuffer[LineBufferLength - 1] = '\0'; + LineBufferLength--; + } + + /* Right. Go looking for $s. */ + for(LineBufferLoop = 0; LineBufferLoop < LineBufferLength; + LineBufferLoop++) { + /* Did we find one? */ + if ('$' != LineBuffer[LineBufferLoop]) { + /* Nope, spit out the value */ + putchar(LineBuffer[LineBufferLoop]); + } else { + /* Yes, we did. Is it escaped? */ + if ((LineBufferLoop > 0) && ('\\' == LineBuffer[LineBufferLoop - + 1])) { + /* Yup. Spit it out */ + putchar(LineBuffer[LineBufferLoop]); + } else { + /* Nope. Go grab us a token */ + TokenBufferLoop = 0; + /* Advance to the next character in the input stream */ + LineBufferLoop++; + while((LineBufferLoop < LineBufferLength) && + ((isalnum(LineBuffer[LineBufferLoop]) || ('_' == + LineBuffer[LineBufferLoop])))) { + TokenBuffer[TokenBufferLoop] = LineBuffer[LineBufferLoop]; + LineBufferLoop++; + TokenBufferLoop++; + } + + /* Trailing null on the token buffer */ + TokenBuffer[TokenBufferLoop] = '\0'; + + /* Back the line buffer pointer up one */ + LineBufferLoop--; + + /* Right, we're done grabbing a token. Check to make sure we got */ + /* something */ + if (TokenBufferLoop) { + /* Well, we do. Run through all the tokens we've got in the */ + /* ConfigSub array and see if any match */ + GotIt = 0; + for(ConfigSubLoop = 0; ConfigSubLoop < ConfigSubCount; + ConfigSubLoop++) { + if (!strcmp(TokenBuffer, ConfigSub[ConfigSubLoop].Tag)) { + GotIt = 1; + printf("%s", ConfigSub[ConfigSubLoop].Value); + break; + } + } + + /* Did we find something? If not, spit out what was in our */ + /* buffer */ + if (!GotIt) { + printf("$%s", TokenBuffer); + } + + } else { + /* Just a bare $. Spit it out */ + putchar('$'); + } + } + } + } + + /* We're all done. Spit out an EOL */ + printf("\n"); + + + } + + /* Close the files */ + fclose(ConfigSH); + fclose(Config_H); +} + +void +tilde_sub(char LineBuffer[], Translate TildeSub[], int TildeSubCount) +{ + char TempBuffer[LINEBUFFERSIZE], TempTilde[TOKENBUFFERSIZE]; + int TildeLoop, InTilde, CopiedBufferLength, TildeBufferLength, k, GotIt; + int TempLength; + InTilde = 0; + CopiedBufferLength = 0; + TildeBufferLength = 0; + TempLength = strlen(LineBuffer); + + /* Grovel over our input looking for ~foo~ constructs */ + for(TildeLoop = 0; TildeLoop < TempLength; TildeLoop++) { + /* Are we in a tilde? */ + if (InTilde) { + /* Yup. Is the current character a tilde? */ + if (LineBuffer[TildeLoop] == '~') { + /* Yup. That means we're ready to do a substitution */ + InTilde = 0; + GotIt = 0; + /* Trailing null */ + TempTilde[TildeBufferLength] = '\0'; + for( k=0; k < TildeSubCount; k++) { + if (!strcmp(TildeSub[k].Tag, TempTilde)) { + GotIt = 1; + /* Tack on the trailing null to the main buffer */ + TempBuffer[CopiedBufferLength] = '\0'; + /* Copy the tilde substitution over */ + strcat(TempBuffer, TildeSub[k].Value); + CopiedBufferLength = strlen(TempBuffer); + } + } + + /* Did we find anything? */ + if (GotIt == 0) { + /* Guess not. Copy the whole thing out verbatim */ + TempBuffer[CopiedBufferLength] = '\0'; + TempBuffer[CopiedBufferLength++] = '~'; + TempBuffer[CopiedBufferLength] = '\0'; + strcat(TempBuffer, TempTilde); + strcat(TempBuffer, "~"); + CopiedBufferLength = strlen(TempBuffer); + } + + } else { + /* 'Kay, not a tilde. Is it a word character? */ + if (isalnum(LineBuffer[TildeLoop]) || (LineBuffer[TildeLoop] = + '-') || + (LineBuffer[TildeLoop] == '-')) { + TempTilde[TildeBufferLength++] = LineBuffer[TildeLoop]; + } else { + /* No, it's not a tilde character. For shame! We've got a */ + /* bogus token. Copy a ~ into the output buffer, then append */ + /* whatever we've got in our token buffer */ + TempBuffer[CopiedBufferLength++] = '~'; + TempBuffer[CopiedBufferLength] = '\0'; + TempTilde[TildeBufferLength] = '\0'; + strcat(TempBuffer, TempTilde); + CopiedBufferLength += TildeBufferLength; + InTilde = 0; + } + } + } else { + /* We're not in a tilde. Do we want to be? */ + if (LineBuffer[TildeLoop] == '~') { + /* Guess so */ + InTilde = 1; + TildeBufferLength = 0; + } else { + /* Nope. Copy the character to the output buffer */ + TempBuffer[CopiedBufferLength++] = LineBuffer[TildeLoop]; + } + } + } + + /* Out of the loop. First, double-check to see if there was anything */ + /* pending. */ + if (InTilde) { + /* bogus token. Copy a ~ into the output buffer, then append */ + /* whatever we've got in our token buffer */ + TempBuffer[CopiedBufferLength++] = '~'; + TempBuffer[CopiedBufferLength] = '\0'; + TempTilde[TildeBufferLength] = '\0'; + strcat(TempBuffer, TempTilde); + CopiedBufferLength += TildeBufferLength; + } else { + /* Nope, nothing pensing. Tack on a \0 */ + TempBuffer[CopiedBufferLength] = '\0'; + } + + /* Okay, we're done. Copy the temp buffer back into the line buffer */ + strcpy(LineBuffer, TempBuffer); + +} + |