non-unix systems.
usage:
- munchconfig config.sh config_h.sh [foo=bar [baz=xyzzy [...]]] >config.h
+ munchconfig config.sh config_h.sh [-f file] [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.
+ which is to say, it takes as its first parameter a config.sh (or
+ equivalent), as its second a config_h.sh (or equivalent), an optional file
+ containing tag=value pairs (one on each line), and an optional list of
+ tag=value pairs on the command line.
It spits the processed config.h out to STDOUT.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <unistd.h>
/* The failure code to exit with */
#ifndef EXIT_FAILURE
#endif
/* The biggest line we can read in from a file */
-#define LINEBUFFERSIZE 400
+#define LINEBUFFERSIZE 1024
#define NUMTILDESUBS 30
#define NUMCONFIGSUBS 1000
#define TOKENBUFFERSIZE 80
int
main(int argc, char *argv[])
{
- FILE *ConfigSH, *Config_H;
+ int c, i;
+ char *ifile = NULL;
+ char WorkString[LINEBUFFERSIZE];
+ FILE *ConfigSH, *Config_H, *Extra_Subs;
char LineBuffer[LINEBUFFERSIZE], *TempValue, *StartTilde, *EndTilde;
- char SecondaryLineBuffer[LINEBUFFERSIZE];
+ char SecondaryLineBuffer[LINEBUFFERSIZE], OutBuf[LINEBUFFERSIZE];
char TokenBuffer[TOKENBUFFERSIZE];
int LineBufferLength, TempLength, DummyVariable, LineBufferLoop;
- int TokenBufferLoop, ConfigSubLoop, GotIt;
+ int TokenBufferLoop, ConfigSubLoop, GotIt, OutBufPos;
Translate TildeSub[NUMTILDESUBS]; /* Holds the tilde (~FOO~) */
/* substitutions */
Translate ConfigSub[NUMCONFIGSUBS]; /* Holds the substitutions from */
/* and config substitutions, */
/* respectively */
if (argc < 3) {
- printf("Usage: munchconfig config.sh config_h.sh [foo=bar [baz=xyzzy [...]]]\n");
+ printf("Usage: munchconfig config.sh config_h.sh [-f file] [foo=bar [baz=xyzzy [...]]]\n");
exit(EXIT_FAILURE);
}
-
+ optind = 3; /* skip config.sh and config_h.sh */
+ while ((c = getopt(argc, argv, "f:")) != -1) {
+ switch (c) {
+ case 'f':
+ ifile = optarg;
+ break;
+ case ':':
+ fprintf(stderr, "Option -%c requires an operand\n", optopt);
+ break;
+ case '?':
+ fprintf(stderr,"Unrecognised option: -%c\n", optopt);
+ }
+ }
+
/* 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 (ifile != NULL && NULL == (Extra_Subs = fopen(ifile, "r"))) {
+ printf("Error %i trying to open extra substitutions file %s\n", errno, ifile);
+ 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++) {
-
+ if (argc > optind) {
+ for (i=optind; i < argc && argv[i]; i++) {
/* Local copy */
strcpy(WorkString, argv[i]);
/* Stick a NULL over the = */
}
}
+ /* Now read in the tag/value pairs from the extra substitutions file, if any */
+ while(ifile && fgets(LineBuffer, LINEBUFFERSIZE - 1, Extra_Subs)) {
+ /* 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;
+
+ /* Local copy */
+ strcpy(WorkString, LineBuffer);
+ /* 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 */
/* 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. */
+ /* Check to see if there's a trailing ' or ". If not, add a newline to
+ the buffer and grab another line. */
TempLength = strlen(TempValue);
- while (TempValue[TempLength-1] != '\'') {
+ while ((TempValue[TempLength-1] != '\'') &&
+ (TempValue[TempLength-1] != '"')) {
fgets(SecondaryLineBuffer, LINEBUFFERSIZE - 1, ConfigSH);
/* Force a trailing null, just in case */
SecondaryLineBuffer[LINEBUFFERSIZE - 1] = '\0';
LineBufferLength--;
}
+ OutBufPos = 0;
/* 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]);
+ OutBuf[OutBufPos++] = LineBuffer[LineBufferLoop];
} else {
/* Yes, we did. Is it escaped? */
if ((LineBufferLoop > 0) && ('\\' == LineBuffer[LineBufferLoop -
1])) {
/* Yup. Spit it out */
- putchar(LineBuffer[LineBufferLoop]);
+ OutBuf[OutBufPos++] = LineBuffer[LineBufferLoop];
} else {
/* Nope. Go grab us a token */
TokenBufferLoop = 0;
for(ConfigSubLoop = 0; ConfigSubLoop < ConfigSubCount;
ConfigSubLoop++) {
if (!strcmp(TokenBuffer, ConfigSub[ConfigSubLoop].Tag)) {
- GotIt = 1;
- printf("%s", ConfigSub[ConfigSubLoop].Value);
+ char *cp = ConfigSub[ConfigSubLoop].Value;
+ GotIt = 1;
+ while (*cp) OutBuf[OutBufPos++] = *(cp++);
break;
}
}
/* Did we find something? If not, spit out what was in our */
/* buffer */
if (!GotIt) {
- printf("$%s", TokenBuffer);
+ char *cp = TokenBuffer;
+ OutBuf[OutBufPos++] = '$';
+ while (*cp) OutBuf[OutBufPos++] = *(cp++);
}
} else {
/* Just a bare $. Spit it out */
- putchar('$');
+ OutBuf[OutBufPos++] = '$';
}
}
}
}
- /* We're all done. Spit out an EOL */
- printf("\n");
-
-
+ /* If we've created an #undef line, make sure we don't output anthing
+ * after the "#undef FOO" besides comments. We could do this as we
+ * go by recognizing the #undef as it goes by, and thus avoid another
+ * use of a fixed-length buffer, but this is simpler.
+ */
+ if (!strncmp(OutBuf,"#undef",6)) {
+ char *cp = OutBuf;
+ int i, incomment = 0;
+ LineBufferLoop = 0;
+ OutBuf[OutBufPos] = '\0';
+ for (i = 0; i <= 1; i++) {
+ while (!isspace(*cp)) LineBuffer[LineBufferLoop++] = *(cp++);
+ while ( isspace(*cp)) LineBuffer[LineBufferLoop++] = *(cp++);
+ }
+ while (*cp) {
+ while (isspace(*cp)) LineBuffer[LineBufferLoop++] = *(cp++);
+ if (!incomment && *cp == '/' && *(cp+1) == '*') incomment = 1;
+ while (*cp && !isspace(*cp)) {
+ if (incomment) LineBuffer[LineBufferLoop++] = *cp;
+ cp++;
+ }
+ if (incomment && *cp == '*' && *(cp+1) == '/') incomment = 0;
+ }
+ LineBuffer[LineBufferLoop] = '\0';
+ puts(LineBuffer);
+ }
+ else {
+ OutBuf[OutBufPos] = '\0';
+ puts(OutBuf);
+ }
}
/* Close the files */
fclose(ConfigSH);
fclose(Config_H);
+ if (ifile) fclose(Extra_Subs);
}
void
} else {
/* 'Kay, not a tilde. Is it a word character? */
- if (isalnum(LineBuffer[TildeLoop]) || (LineBuffer[TildeLoop] =
- '-') ||
+ if (isalnum(LineBuffer[TildeLoop]) ||
(LineBuffer[TildeLoop] == '-')) {
TempTilde[TildeBufferLength++] = LineBuffer[TildeLoop];
} else {