/* 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 ------------------------------------------------------- */