summaryrefslogtreecommitdiff
path: root/vms/munchconfig.c
diff options
context:
space:
mode:
authorHans Mulder <hansmu@xs4all.nl>1998-06-08 08:38:28 -0700
committerGurusamy Sarathy <gsar@cpan.org>1998-06-10 05:38:11 +0000
commit97abc6adffcd3efcbaee73cbdad2055b2d06be4f (patch)
tree5d55b2348ca41dc8d14ac1b58e655f3259d88bee /vms/munchconfig.c
parentcfc02341d853e4bc320d3abf8ac8ac1c7c3ecaa5 (diff)
downloadperl-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.c365
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);
+
+}
+