#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#ifndef EXIT_FAILURE
#ifdef VMS
#define EXIT_FAILURE 0
#else
#define EXIT_FAILURE -1
#endif
#endif
#define LINEBUFFERSIZE 1024
#define NUMTILDESUBS 30
#define NUMCONFIGSUBS 1500
#define TOKENBUFFERSIZE 80
typedef
struct
{
char
Tag[TOKENBUFFERSIZE];
char
Value[512];
} Translate;
void
tilde_sub(
char
[], Translate [],
int
);
int
main(
int
argc,
char
*argv[])
{
int
c, i;
char
*ifile = NULL;
char
WorkString[LINEBUFFERSIZE];
FILE
*ConfigSH, *Config_H, *Extra_Subs;
char
LineBuffer[LINEBUFFERSIZE], *TempValue, *StartTilde, *EndTilde;
char
SecondaryLineBuffer[LINEBUFFERSIZE], OutBuf[LINEBUFFERSIZE];
char
TokenBuffer[TOKENBUFFERSIZE];
int
LineBufferLength, TempLength, DummyVariable, LineBufferLoop;
int
TokenBufferLoop, ConfigSubLoop, GotIt, OutBufPos;
Translate TildeSub[NUMTILDESUBS];
Translate ConfigSub[NUMCONFIGSUBS];
int
TildeSubCount = 0, ConfigSubCount = 0;
if
(argc < 3) {
printf
(
"Usage: munchconfig config.sh config_h.sh [-f file] [foo=bar [baz=xyzzy [...]]]\n"
);
exit
(EXIT_FAILURE);
}
optind = 3;
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);
}
}
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);
}
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);
}
if
(argc > optind) {
for
(i=optind; i < argc && argv[i]; i++) {
strcpy
(WorkString, argv[i]);
TempValue =
strchr
(WorkString,
'='
);
*TempValue++ =
'\0'
;
strcpy
(TildeSub[TildeSubCount].Tag, WorkString);
strcpy
(TildeSub[TildeSubCount].Value, TempValue);
TildeSubCount++;
}
}
while
(ifile &&
fgets
(LineBuffer, LINEBUFFERSIZE - 1, Extra_Subs)) {
LineBuffer[LINEBUFFERSIZE - 1] =
'\0'
;
LineBufferLength =
strlen
(LineBuffer);
while
((LineBufferLength > 0) && (LineBuffer[LineBufferLength-1] <
' '
)) {
LineBuffer[LineBufferLength - 1] =
'\0'
;
LineBufferLength--;
}
if
(!*LineBuffer)
continue
;
strcpy
(WorkString, LineBuffer);
TempValue =
strchr
(WorkString,
'='
);
*TempValue++ =
'\0'
;
strcpy
(TildeSub[TildeSubCount].Tag, WorkString);
strcpy
(TildeSub[TildeSubCount].Value, TempValue);
TildeSubCount++;
}
while
(
fgets
(LineBuffer, LINEBUFFERSIZE - 1, ConfigSH)) {
LineBuffer[LINEBUFFERSIZE - 1] =
'\0'
;
LineBufferLength =
strlen
(LineBuffer);
while
((LineBufferLength > 0) && (LineBuffer[LineBufferLength-1] <
' '
)) {
LineBuffer[LineBufferLength - 1] =
'\0'
;
LineBufferLength--;
}
if
(!*LineBuffer)
continue
;
if
((LineBuffer[0] ==
' '
) || (LineBuffer[0] ==
'#'
))
continue
;
tilde_sub(LineBuffer, TildeSub, TildeSubCount);
TempValue =
strchr
(LineBuffer,
'='
);
*TempValue++ =
'\0'
;
*TempValue++ =
'\0'
;
TempLength =
strlen
(TempValue);
while
((TempValue[TempLength-1] !=
'\''
) &&
(TempValue[TempLength-1] !=
'"'
)) {
fgets
(SecondaryLineBuffer, LINEBUFFERSIZE - 1, ConfigSH);
SecondaryLineBuffer[LINEBUFFERSIZE - 1] =
'\0'
;
tilde_sub(SecondaryLineBuffer, TildeSub, TildeSubCount);
strcat
(TempValue,
"\n"
);
strcat
(TempValue, SecondaryLineBuffer);
TempLength =
strlen
(TempValue);
while
((TempLength > 0) && (TempValue[TempLength-1] <
' '
)) {
TempValue[TempLength - 1] =
'\0'
;
TempLength--;
}
}
TempValue[TempLength-1] =
'\0'
;
if
(*TempValue) {
strcpy
(ConfigSub[ConfigSubCount].Tag, LineBuffer);
strcpy
(ConfigSub[ConfigSubCount].Value, TempValue);
ConfigSubCount++;
}
}
while
(!
strstr
(
fgets
(LineBuffer, LINEBUFFERSIZE, Config_H),
"!GROK!THIS!"
)) {
DummyVariable++;
}
while
(!
strstr
(
fgets
(LineBuffer, LINEBUFFERSIZE, Config_H),
"!GROK!THIS!"
)) {
LineBuffer[LINEBUFFERSIZE - 1] =
'\0'
;
tilde_sub(LineBuffer, TildeSub, TildeSubCount);
LineBufferLength =
strlen
(LineBuffer);
while
((LineBufferLength > 0) && (LineBuffer[LineBufferLength-1] <
' '
)) {
LineBuffer[LineBufferLength - 1] =
'\0'
;
LineBufferLength--;
}
OutBufPos = 0;
for
(LineBufferLoop = 0; LineBufferLoop < LineBufferLength;
LineBufferLoop++) {
if
(
'$'
!= LineBuffer[LineBufferLoop]) {
OutBuf[OutBufPos++] = LineBuffer[LineBufferLoop];
}
else
{
if
((LineBufferLoop > 0) && (
'\\'
== LineBuffer[LineBufferLoop -
1])) {
OutBuf[OutBufPos++] = LineBuffer[LineBufferLoop];
}
else
{
TokenBufferLoop = 0;
LineBufferLoop++;
while
((LineBufferLoop < LineBufferLength) &&
((
isalnum
(LineBuffer[LineBufferLoop]) || (
'_'
==
LineBuffer[LineBufferLoop])))) {
TokenBuffer[TokenBufferLoop] = LineBuffer[LineBufferLoop];
LineBufferLoop++;
TokenBufferLoop++;
}
TokenBuffer[TokenBufferLoop] =
'\0'
;
LineBufferLoop--;
if
(TokenBufferLoop) {
GotIt = 0;
for
(ConfigSubLoop = 0; ConfigSubLoop < ConfigSubCount;
ConfigSubLoop++) {
if
(!
strcmp
(TokenBuffer, ConfigSub[ConfigSubLoop].Tag)) {
char
*cp = ConfigSub[ConfigSubLoop].Value;
GotIt = 1;
while
(*cp) OutBuf[OutBufPos++] = *(cp++);
break
;
}
}
if
(!GotIt) {
char
*cp = TokenBuffer;
OutBuf[OutBufPos++] =
'$'
;
while
(*cp) OutBuf[OutBufPos++] = *(cp++);
}
}
else
{
OutBuf[OutBufPos++] =
'$'
;
}
}
}
}
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);
}
}
fclose
(ConfigSH);
fclose
(Config_H);
if
(ifile)
fclose
(Extra_Subs);
}
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);
for
(TildeLoop = 0; TildeLoop < TempLength; TildeLoop++) {
if
(InTilde) {
if
(LineBuffer[TildeLoop] ==
'~'
) {
InTilde = 0;
GotIt = 0;
TempTilde[TildeBufferLength] =
'\0'
;
for
( k=0; k < TildeSubCount; k++) {
if
(!
strcmp
(TildeSub[k].Tag, TempTilde)) {
GotIt = 1;
TempBuffer[CopiedBufferLength] =
'\0'
;
strcat
(TempBuffer, TildeSub[k].Value);
CopiedBufferLength =
strlen
(TempBuffer);
}
}
if
(GotIt == 0) {
TempBuffer[CopiedBufferLength] =
'\0'
;
TempBuffer[CopiedBufferLength++] =
'~'
;
TempBuffer[CopiedBufferLength] =
'\0'
;
strcat
(TempBuffer, TempTilde);
strcat
(TempBuffer,
"~"
);
CopiedBufferLength =
strlen
(TempBuffer);
}
}
else
{
if
(
isalnum
(LineBuffer[TildeLoop]) ||
(LineBuffer[TildeLoop] ==
'-'
)) {
TempTilde[TildeBufferLength++] = LineBuffer[TildeLoop];
}
else
{
TempBuffer[CopiedBufferLength++] =
'~'
;
TempBuffer[CopiedBufferLength] =
'\0'
;
TempTilde[TildeBufferLength] =
'\0'
;
strcat
(TempBuffer, TempTilde);
CopiedBufferLength += TildeBufferLength;
InTilde = 0;
}
}
}
else
{
if
(LineBuffer[TildeLoop] ==
'~'
) {
InTilde = 1;
TildeBufferLength = 0;
}
else
{
TempBuffer[CopiedBufferLength++] = LineBuffer[TildeLoop];
}
}
}
if
(InTilde) {
TempBuffer[CopiedBufferLength++] =
'~'
;
TempBuffer[CopiedBufferLength] =
'\0'
;
TempTilde[TildeBufferLength] =
'\0'
;
strcat
(TempBuffer, TempTilde);
CopiedBufferLength += TildeBufferLength;
}
else
{
TempBuffer[CopiedBufferLength] =
'\0'
;
}
strcpy
(LineBuffer, TempBuffer);
}