/* db2tex.c - data base to TeX; UKE/EDV, Bernd Paradies, 18.10.90
* Kleinere �nderungen: H. Astheimer, UKE-Kinderklinik, 16.4.91
* Gr��ere �nderungen: K. Rath, UKE-Kinderklinik, 20.1.92
*
*
* Copyright (c) 1990, 1991, 1992
* Universit�ts Krankenhaus Eppendorf
* Abt. f. H�matologie und Onkologie
* Kinderklinik
* Martinistra�e 52
* 2000 Hamburg 20
*
*
* AUTHOR: Bernd Paradies
*
* SYNTAX: dbtex [-hq][-n rep-lines] [-o output-file] [TeX-file] [rep-file]
*
* DESCRIPTION:
* dbtex setzt f�r Spaltennamen in TeX-Dateien den entsprechenden
* Spalteninhalt ein. Die Spalteninhalte werden �ber eine Datei im
* 'Standard'-Report-Format eingelesen, wobei f�r jede Zeile der
* Report-Datei eine TeX-Datei mit den Spaltendaten erzeugt wird.
* Eine typische Anwendung f�r dbtex w�re z.B. ein Serienbrief, bei
* dem der Adressenkopf variiert.
*
* OPTIONS:
*
* -n : setzt die maximale Anzahl der Zeilen, die von der Report-Datei
* eingelesen wird.
* -o : setzt einen neuen Namen f�r die Ausgabe-Dateien.
* dbtex -o brief.deu erzwingt Ausgabe in brief.deu
* (statt dbtex.def) und brief.deu2 (statt dbtex.inp).
* -q : unterdr�ckt die Ausgabe.
* -c : nur Compilieren
* -h : Hilfstext und Copyright
*
*
* INTERNAS:
* Es wird zun�chst ein Text-Rumpf erstellt und im zweiten
* Durchgang die Report-Datei Zeile f�r Zeile ausgewertet (GetReport).
* Dabei werden die Spalteninhalte dem Rumpf als Macros zugewiesen.
*
* FILES:
* db2tex.h: header-file
* db2tex.c: main
* db_tex.c: Routinen f�r die Behandlung von TeX-Dateien
*
* BUGS:
* - beim L�schen der tempor�ren Dateien wird keine weitere
* �berpr�fung vorgenommen, ob z.B. das Original gel�scht wird.
* - die Fehlermeldungen und Warnungen sind in deutsch und englisch.
* 27.12.90:
* - "dbtex a.tex a.rep" stellt nicht a.rep her.
* -
*
*/
static char sccsid[] = "@(#)db2tex ; v1.30/bp+kr ; 01/92";
#include "db2tex.h"
char SpTab[MAXSPALTEN][50];
int SpLen[MAXSPALTEN];
int SpNr = 0;
int TxtZeilen, GetRepZeilen, RepZeilen, DefZeilen, InpZeilen;
int MaxReport = MAXREP;
BOOL BeginDocument = FALSE;
BOOL EndDocument = FALSE;
FILE *InpFile = NULL;
FILE *DefFile = NULL;
FILE *ShFile = NULL;
FILE *stdlog = stderr;
int OptQuiet = FALSE;
int OptCompile = FALSE;
int OptOutput = FALSE;
char *prgname = NULL;
char *prgpath = NULL;
#define DelFile(nm) if (!OptQuiet) printf("L�sche: %s\n",nm); unlink(nm);
/* ====================================================================== */
PUBLIC FILE *_fopen(name, mode)
char *name;
char *mode;
{
FILE *Txt;
char Err[80];
if ( (Txt = fopen (name, mode)) == NULL )
{
strcpy (Err, "Can't open file: ");
strcat (Err, name);
error (Err);
}
return (Txt);
}
/* ---------------------------------------------------------------------- */
PUBLIC char *strtoupper(Str)
char *Str;
{
REG ii;
for (ii=0; ii != strlen (Str); ii++)
Str[ii] = toupper (Str[ii]);
return (Str);
}
/* ---------------------------------------------------------------------- */
PUBLIC char *delblank(Str)
char *Str;
{
char *Text;
Text = Str;
while (*Text == BLANK) /* die vorderen Leerzeichen entfernen */
Text++;
strcpy (Str, Text);
Text = Str + strlen(Str) - 1;
while ( (*Text == BLANK) && (Text != Str) )
{
*Text = 0; /* die hinteren entfernen */
Text--;
}
return (Str);
}
/* ---------------------------------------------------------------------- */
PUBLIC char *ChkName(Name)
char *Name;
{
char UpName[MAXZEILE];
REG ii;
strtoupper(strcpy (UpName, Name)); /* alles in Gro�-Buchstaben */
for (ii=0; ii != SpNr; ii++)
if (strncmp (SpTab[ii], UpName, strlen (SpTab[ii])) == 0)
return (SpTab[ii]); /* gefunden ! */
return (NULL); /* nicht gefunden */
}
/* ---------------------------------------------------------------------- */
PUBLIC int GetSQL(Zeile)
char *Zeile;
{
char *Zptr;
char SpNamen[MAXZEILE];
if ( (Zeile[0] != '%') || (Zeile[1] != '$') )
error ("Falsches db2tex-Format: fehlende Spaltenbeschreibung in Zeile(1)");
Zeile[strlen(Zeile)-1] = 0; /* \n l�schen */
Zptr = strtok (strcpy (SpNamen, strtoupper (Zeile)), " ");
while ( Zptr != NULL )
{
if (SpNr > MAXSPALTEN)
error ("Zuviele Spalten !");
if ( (Zptr = strtok (NULL, " ")) != NULL )
strcpy (SpTab[SpNr++], Zptr);
}
if (SpNr == 0)
error ("Keine Spalten zu verarbeiten !\n");
return (0);
}
/* ---------------------------------------------------------------------- */
PUBLIC int GetReport(Nr,Zeile)
int Nr;
char *Zeile;
{
int NameNr = 0;
char *Sptr;
REG ii;
if (Nr >= (MaxReport)) return (0);
switch (Nr)
{
case 1: Sptr = strtok (Zeile, " ");
while ( (Sptr != NULL) && (NameNr++ < SpNr) )
Sptr = strtok (NULL, " ");
if (SpNr > NameNr)
warning ("Es fehlen Spalten in der Report-Datei. Anzahl",
(SpNr-NameNr) );
break;
case 2: for (ii=0; ii != SpNr; ii++)
SpLen[ii] = (ii==0) ? strlen (strtok (Zeile, SEP))
: strlen (strtok (NULL, SEP));
break;
default: PutTexRep(Nr, Zeile);
GetRepZeilen++;
break;
}
return (0);
}
/* ---------------------------------------------------------------------- */
PUBLIC int WalkFile(Fname,Action)
char *Fname;
int (*Action)();
{
FILE *Txt;
char Zeile[MAXZEILE];
int Nr = 0;
Txt = _fopen (Fname, "r");
while ( fgets (Zeile, MAXZEILE, Txt) != NULL )
Action (++Nr, Zeile);
fclose (Txt);
return (Nr); /* liefere Anzahl der gelesenen Zeilen zur�ck */
}
/* ---------------------------------------------------------------------- */
#define KEY_ZAHL 16
char *KeyWords[KEY_ZAHL] =
{ /* File-Parameter:
0 1 2 3 4 5 */
"TEXT", "REPORT", "DEF", "INPUT", "DVI", "OUTPUT",
/* TeX-Parameter:
6 7 8 9 10 11 */
"DVITPS", "DVITTY", "PRINTER", "TEXPOOL", "VIRTEX", "UMLT2TEX",
/* Sonstiges:
12 13 14 15 */
"QUIET", "COMPILE_ONLY", "SEP", "OUTDEV"};
PUBLIC int GetIni(IniFile)
FILE *IniFile;
{
int DateiEnde = NULL;
int ConfigCounter = NULL;
char zbuf[80];
char *tbuf;
int Zaehler;
int EndLine = 0;
while ( !DateiEnde )
{
DateiEnde = feof(IniFile);
if ( DateiEnde )
{
continue;
}
zbuf[0] = '\0';
fgets(zbuf,80,IniFile);
zbuf[strlen(zbuf)-1] = '\0'; /* Strip LF */
if ( (strlen(zbuf) < 2) || (zbuf[0] == '#') ) /*Kommentare,Leerzeilen*/
{
continue;
}
tbuf = (char *)strtok(zbuf,"=");
for ( Zaehler = 0 ; Zaehler < KEY_ZAHL ; Zaehler++ )
{
if ( strcmp(tbuf,KeyWords[Zaehler]) == NULL )
{
ConfigCounter++;
tbuf = (char *)NULL;
tbuf = (char *)strtok(NULL," ");
switch ( Zaehler )
{
case 0: /* TEXT */
strcpy(TxtName,tbuf);
break;
case 1: /* REPORT */
strcpy(RepName,tbuf);
break;
case 2: /* DEF */
strcpy(DefName,tbuf);
break;
case 3: /* INPUT */
strcpy(InpName,tbuf);
break;
case 4: /* DVI */
strcpy(DviName,tbuf);
break;
case 5: /* OUTPUT */
OptOutput = TRUE;
strcpy(OutName,tbuf);
break;
case 6: /* DVITPS */
DVITPS[0] = '\0';
sprintf(DVITPS,"%s/%s",TEXPOOL,tbuf);
EndLine = 0;
while ( !EndLine )
{
tbuf = (char *)NULL;
if ( (tbuf = (char *)strtok(NULL," ")) == NULL )
{
EndLine++;
continue;
}
strcat(DVITPS," ");
strcat(DVITPS,tbuf);
} /* ENDE: while */
break;
case 7: /* DVITTY */
DVITTY[0] = '\0';
sprintf(DVITTY,"%s/%s",TEXPOOL,tbuf);
EndLine = 0;
while ( !EndLine )
{
tbuf = (char *)NULL;
if ( (tbuf = (char *)strtok(NULL," ")) == NULL )
{
EndLine++;
continue;
}
strcat(DVITTY," ");
strcat(DVITTY,tbuf);
} /* ENDE: while */
break;
case 8: /* PRINTER */
PRINTER[0] = '\0';
if ( tbuf[0] == '$' )
strcpy(PRINTER,getenv(&tbuf[1]));
else
strcpy(PRINTER,tbuf);
break;
case 9: /* TEXPOOL */
TEXPOOL[0] = '\0';
if ( tbuf[0] == '$' )
strcpy(TEXPOOL,getenv(&tbuf[1]));
else
strcpy(TEXPOOL,tbuf);
break;
case 10: /* VIRTEX */
VIRTEX[0] = '\0';
sprintf(VIRTEX,"%s/%s",TEXPOOL,tbuf);
EndLine = 0;
while ( !EndLine )
{
tbuf = (char *)NULL;
if ( (tbuf = (char *)strtok(NULL," ")) == NULL )
{
EndLine++;
continue;
}
strcat(VIRTEX," ");
strcat(VIRTEX,tbuf);
} /* ENDE: while */
break;
case 11: /* UMLT2TEX */
UMLT2TEX[0] = '\0';
sprintf(UMLT2TEX,"%s/%s",TEXPOOL,tbuf);
break;
case 12: /* QUIET */
if ( strcmp(tbuf,"yes") == NULL )
OptQuiet = TRUE;
break;
case 13: /* COMPILE_ONLY */
if ( strcmp(tbuf,"yes") == NULL )
OptCompile = TRUE;
break;
case 14: /* SEP */
SEP[0] = '\0';
/* strcpy(SEP,tbuf);*/
if (tbuf[0] == '\'' || tbuf[0] == '\"')
SEP[0] = ' ';
else
SEP[0] = tbuf[0];
SEP[1] = '\0';
break;
case 15: /* OUTDEV */
OUTDEV[0] = '\0';
strcpy(OUTDEV,tbuf);
break;
default: break; /* Alles andere ignorieren */
} /* ENDE: switch(Zaehler) */
break;
} /* ENDE: if(strcmp()) */
} /* ENDE: for(Zaehler) */
} /* ENDE: while(DateiEnde) */
return(ConfigCounter);
} /* ENDE: GetIni() */
/* ---------------------------------------------------------------------- */
PRIVATE info(void)
{
REG ii;
if (!OptQuiet)
{
printf ("\n%s:\n", prgname);
printf ("\t EINGABE: %s (Textdatei, Z:%i)\n", TxtName, TxtZeilen);
printf ("\t EINGABE: %s (Reportdatei, Z:%i von %i)\n\n",
RepName, GetRepZeilen, RepZeilen);
if (!OptCompile)
printf ("\t AUSGABE: %s\n", OptOutput ? OutName : "(interaktiv)");
else
{
printf ("\t AUSGABE: %s (Zwischendatei, Z:%i)\n", InpName,InpZeilen);
printf ("\t AUSGABE: %s (Zwischendatei, Z:%i)\n", DefName, DefZeilen);
}
printf ("\n\t Max. Report-Zeilen: %i\n", MaxReport-3);
if (SpNr != 0)
{
printf ("\t Benutzte Spalten: ");
for (ii=0; ii!=SpNr; ii++)
printf ("%s ", SpTab[ii]);
printf ("\n");
}
printf ("\n");
}
}
/* ---------------------------------------------------------------------- */
PRIVATE usage(void)
{
printf ("\n");
printf ("(c) UKE-Kinderklinik, Abt.f. H�matologie und Onkologie, ");
printf ("AG EDV & Statistik\n\n");
printf ("%s Ver 1.30, 24.01.92\n","db2tex - data base to TeX.", prgname);
printf ("Usage: %s [-hqc][-n report-lines] [-o output-file] ", prgname);
printf ("[TeX-file] [report-file] \n");
printf ("Options:\n");
printf ("\t -c : compile only\n");
printf ("\t -n : set max. report lines\n");
printf ("\t -o : set output file name\n");
printf ("\t -q : quiet running\n");
printf ("\t -h : this help text\n\n");
printf ("Default file name: %s\n", TxtName);
printf ("\n");
}
/* ---------------------------------------------------------------------- */
PRIVATE void atexit(void)
{
/*
if (MemBlocks != 0)
warning ("missing free ! - MemBlocks: ", MemBlocks);
*/
}
/* ---------------------------------------------------------------------- */
PUBLIC int main(argc,argv,envp)
int argc;
char *argv[];
char *envp[];
{
IMPORT char *optarg;
IMPORT int optind;
IMPORT int opterr;
REG int Opt;
FILE *IniFile;
char IniFileName_1[60];
char IniFileName_2[20];
/* -- Initialsierung */
prgname = (char *)basename(argv[0]); /* Eigenen Namen feststellen */
prgpath = (char *)dirname(argv[0]); /* wo bin gestartet ? */
sprintf(IniFileName_1,"%s/%s.ini",prgpath,prgname);
sprintf(IniFileName_2,"%s.ini",prgname);
TxtZeilen = GetRepZeilen = RepZeilen = DefZeilen = InpZeilen = 0;
/* -- Diverse Variable vorbelegen, danach die Standard-Startdatei suchen, */
/* -- anschlie�end evtl. eine individuelle Startdatei. Die Variablen wer- */
/* -- in dieser Reihenfolge belegt und ggfls. �berschrieben! */
/* -- Eingestellte Optionen werden von Kommandozeilen-Parametern evtl. */
/* -- nocheinmal �berschrieben !!! */
/* Default-Belegung :
*/
sprintf (TxtName, "%s.%s", prgname, STDTEXNAME);
sprintf (RepName, "%s.%s", prgname, STDREPNAME);
sprintf (DefName, "%s.%s", prgname, STDDEFNAME);
sprintf (InpName, "%s.%s", prgname, STDINPNAME);
sprintf (DviName, "%s.dvi", prgname);
strcpy (OutName, "");
strcpy (TEXPOOL, STDTEXPOOL);
sprintf (VIRTEX, "%s/%s", TEXPOOL, STDVIRTEX);
sprintf (DVITPS, "%s/%s", TEXPOOL, STDDVITPS);
sprintf (DVITTY, "%s/%s", TEXPOOL, STDDVITTY);
sprintf (PRINTER, "%s", STDPRINTER);
/* Nach .ini-Datei erst im Start- und dann im aktuellen Verzeichnis
** suchen :
*/
if ( IniFile = fopen(IniFileName_1,"r") )
{
GetIni(IniFile);
fclose(IniFile);
}
else
{
fprintf(stderr,"\n%s: Standard-Startdatei %s nicht gefunden!\n");
} /* ENDE: if(IniFileName_1) */
if ( IniFile = fopen(IniFileName_2,"r") )
{
GetIni(IniFile);
fclose(IniFile);
} /* ENDE: if(IniFileName_2) */
/* -- Parameter-Auswertung */
while ( (Opt = getopt (argc, argv, "hcqo:n:")) != EOF)
switch (Opt)
{
case 'h' : usage(); exit (0); break;
case 'q' : OptQuiet = TRUE; break;/*i*/
case 'n' : MaxReport = atoi (optarg); break;
case 'c' : OptCompile = TRUE; break;/*i*/
case 'o' : OptOutput = TRUE; strcpy(OutName, optarg); break;/*i*/
default : usage(); error ("Unbekannte option"); break;
}
if (argv[optind] != NULL)
{
strcpy (TxtName, argv[optind]);
if (argv[optind+1] != NULL)
strcpy (RepName, argv[optind+1]);
}
/* -- Informationen */
MaxReport += 3;
info();
/* -- GetTex und GetReport */
do_tex();
/* -- Abschlu�-Statistik */
DefZeilen += 5;
info();
if (!OptCompile)
{
if (!OptQuiet)
printf ("Zwischendateien werden wieder gel�scht !\n");
DelFile(DefName);
DelFile(InpName);
DelFile(DviName);
}
atexit();
return (0);
}
/* -- end of file ------------------------------------------------------- */