home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 20 / dos_txl / source / database.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-19  |  10.4 KB  |  557 lines

  1. /* DATABASE.C
  2.    Datenbanken für TXL-Interpreter
  3.    (c) 1991 Elmar Warken  */
  4.  
  5. #include <stdlib.h>
  6. #include <fcntl.h>
  7. #include <mem.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <conio.h>
  11. #include <alloc.h>
  12. #include "interp.h"
  13. #include "db.h"
  14.  
  15. #define STRFELD 0
  16. #define INTFELD 1
  17. #define MAXFELDER 20
  18. #define MAXBANKEN 3
  19.  
  20. extern    int        Steuer;                
  21. extern    char    ScanBuffer[ZEILENLAENGE]; 
  22.  
  23. typedef struct feld
  24.   int typ,      /*** Typ (INTFELD oder STRFELD         ***/
  25.       strlen,   /*** für Strings : Länge         ***/    
  26.       offset;    /*** Offset innerhalb eines Satzes    ***/
  27. } Feld;
  28.  
  29. typedef struct key /*** Binärer Baum von Strings ***/
  30. {
  31.   char *str;
  32.   long filepos;
  33.   struct key *R,*L; /** rechter und linker Ast **/
  34. } Key;
  35.  
  36. typedef struct dfile
  37. {
  38.   Feld Felder[MAXFELDER];
  39.   int felder,satzlaenge;
  40.   FILE *f;
  41.   char *satz;   /* aktueller Datensatz */
  42.   long satzpos; /* Position des Datensatzes */
  43.   int initialized;
  44.   char dateiname[50];
  45.   Key *wurzel;
  46.   int keyfeld;  /* Welches Feld ist im Baum sortiert ? */
  47. } DFile;
  48.  
  49. /***** Globale Variablen für DATABASE.C *****/
  50.  
  51. DFile defs[MAXBANKEN];
  52. int WEITER; /** Flag für Durchsuchfunktion (nicht bei DurchsucheTree) **/
  53. int AktFeld,AktDef; /** intern benötigt **/
  54.  
  55. void AddDefinition(int defnr, int typ, int len)
  56. {
  57.   DFile *d;
  58.   Feld *f;
  59.  
  60.   d=&defs[defnr];
  61.   if (d->felder<MAXFELDER)
  62.   {
  63.     f=&d->Felder[d->felder];
  64.     f->typ=typ;
  65.     f->strlen=len;
  66.     f->offset=d->satzlaenge;
  67.     if (typ==STRFELD)
  68.       d->satzlaenge+=len;
  69.     else d->satzlaenge+=sizeof(int);
  70.     d->felder++;
  71.   }
  72. }
  73.  
  74. int OpenFile(int defnr, char *name)
  75. {       
  76.   DFile *d;
  77.   Feld NewFeld,*f;
  78.   char vollname[60];
  79.   FILE *F;
  80.         
  81.   d=&defs[defnr];
  82.   d->felder=0;
  83.   d->satzlaenge=1; /* Statusbyte : Satz zum Löschen markiert ? */
  84.   strcpy(vollname,name);
  85.   strcat(vollname,".DEF");
  86.   if ((F=fopen(vollname,"rb"))==NULL) return(FALSE);
  87.   while (fread(&NewFeld,sizeof(Feld),1,F) > 0)
  88.   {
  89.     f=&d->Felder[d->felder];
  90.     *f=NewFeld;
  91.     d->felder++;
  92.     if (f->typ==STRFELD)
  93.       d->satzlaenge+=f->strlen;
  94.     else d->satzlaenge+=sizeof(int);
  95.   }
  96.   fclose(F);
  97.  
  98.   strcpy(d->dateiname,name);
  99.   d->satz=malloc(defs[defnr].satzlaenge);
  100.   strcpy(vollname,name);
  101.   strcat(vollname,".DAT");
  102.   if ((d->f=fopen(vollname,"r+b"))==NULL) 
  103.     return(FALSE);
  104.   d->initialized=1;
  105.   *((char *)(d->satz+d->satzlaenge-1))=0;
  106.   return(OK);
  107. }
  108.  
  109. int CreateFile(int defnr, char *name)
  110. {
  111.   DFile *d;
  112.   int i;
  113.   char vollname[60],help[3];
  114.   FILE *f;
  115.             
  116.   strcpy(vollname,name);
  117.   strcat(vollname,".DEF");
  118.   d=&defs[defnr];
  119.   if ((f=fopen(vollname, "wb"))==NULL) 
  120.     return(FALSE);
  121.  
  122.   errno=0;
  123.   for (i=0; i<d->felder && 
  124.           (fwrite(&d->Felder[i],sizeof(Feld),1,f) != 0); i++);
  125.   if (errno) return(FALSE);
  126.   fclose(f);
  127.  
  128.   strcpy(d->dateiname,name);
  129.   d->satzlaenge+=1; /* Gelöscht-Bit */
  130.   d->satz=malloc(defs[defnr].satzlaenge);
  131.  
  132.   strcpy(vollname,name);
  133.   strcat(vollname,".DAT");
  134.   if ((d->f=fopen(vollname, "w+b"))==NULL) 
  135.     return(FALSE);  
  136.  
  137.   d->initialized=1;
  138.   *((char *)(d->satz+d->satzlaenge-1))=0;
  139.   return(OK);
  140. }
  141.  
  142. void BeschreibeSatz(int defnr, int feldnr, char *str, int wert)
  143. {
  144.   DFile *d;
  145.   Feld *f;
  146.  
  147.   d=&defs[defnr];
  148.   if (d->felder>=feldnr)
  149.   {
  150.     f=&d->Felder[feldnr-1];
  151.     if (f->typ==STRFELD)
  152.       strcpy((char *)(d->satz+f->offset),str);
  153.     else *(int *)(d->satz+f->offset)=wert;
  154.   }
  155.   *((char *)(d->satz+d->satzlaenge-1))=0;
  156. }
  157.  
  158. void LeseSatz(int defnr, int feldnr, char *str, int *wert)
  159. {
  160.   DFile *d;
  161.   Feld *f;
  162.  
  163.   d=&defs[defnr];
  164.   if (d->felder>=feldnr)
  165.   {
  166.     f=&d->Felder[feldnr-1];
  167.     if (f->typ==STRFELD)
  168.       strcpy(str,(char *)(d->satz+f->offset));
  169.     else *wert=*(int *)(d->satz+f->offset);
  170.   }
  171. }
  172.  
  173. void WriteToFile(int defnr)
  174. {
  175.   DFile *d;
  176.  
  177.   d=&defs[defnr];
  178.   if (d->f)
  179.   {
  180.     fseek(d->f,d->satzpos,SEEK_SET);
  181.     fwrite(d->satz,d->satzlaenge,1,d->f);
  182.   }
  183.   d->satzpos=ftell(d->f);
  184. }  
  185.  
  186. void GotoFileEnd(int defnr)
  187. {
  188.   DFile *d;
  189.   int i;
  190.  
  191.   d=&defs[defnr];
  192.   if (d->f)
  193.   {
  194.     fseek(d->f,0L,SEEK_END);
  195.     d->satzpos=ftell(d->f);
  196.   }
  197.   *(char *)(d->satz+d->satzlaenge-1)=0;
  198. }
  199.  
  200. void GotoFileBegin(int defnr)
  201. {
  202.   DFile *d;
  203.   int i;
  204.  
  205.   d=&defs[defnr];
  206.   if (d->f)
  207.   {
  208.     fseek(d->f,0L,SEEK_SET);
  209.     d->satzpos=ftell(d->f);
  210.     fread(d->satz,d->satzlaenge,1,d->f);
  211.   }
  212. }
  213.  
  214. void GoForward(int defnr)
  215. {
  216.   DFile *d;
  217.   int i;
  218.  
  219.   d=&defs[defnr];
  220.   if (d->f)
  221.   {
  222.     d->satzpos+=d->satzlaenge;
  223.     fseek(d->f,d->satzpos,SEEK_SET);
  224.     d->satzpos=ftell(d->f);
  225.     fread(d->satz,d->satzlaenge,1,d->f);
  226.   }
  227. }
  228.  
  229. void GoBackward(int defnr)
  230. {
  231.   DFile *d;
  232.   int i;
  233.  
  234.   d=&defs[defnr];
  235.   if (d->f && d->satzpos)  /** wenn Position bereits 0, dann Abbrechen **/
  236.   {
  237.     d->satzpos-=d->satzlaenge;
  238.     fseek(d->f,d->satzpos,SEEK_SET);
  239.     d->satzpos=ftell(d->f);
  240.     fread(d->satz,d->satzlaenge,1,d->f);
  241.   }
  242. }
  243.  
  244. void GoTo(int defnr, long satzpos)
  245. {
  246.   DFile *d;
  247.   int i;
  248.  
  249.   d=&defs[defnr];
  250.   if (d->f) 
  251.   {
  252.     d->satzpos=satzpos;
  253.     fseek(d->f,d->satzpos,SEEK_SET);
  254.     d->satzpos=ftell(d->f);
  255.     fread(d->satz,d->satzlaenge,1,d->f);
  256.   }
  257. }
  258.  
  259. void GoToNr(int defnr, int satznr)
  260. {
  261.   GoTo(defnr, defs[defnr].satzlaenge*satznr);
  262. }
  263.  
  264. void MarkCurrent(int defnr, int Mark_On)
  265. {
  266.   DFile *d;
  267.   int i;
  268.  
  269.   d=&defs[defnr];
  270.   if (d->f)
  271.     *(char *)(d->satz+d->satzlaenge-1)=Mark_On;
  272.   WriteToFile(defnr);
  273. }
  274.  
  275. void CloseFile(int defnr)
  276. {
  277.   DFile *d;
  278.   int i;
  279.  
  280.   d=&defs[defnr];
  281.  
  282.   if (d->f)
  283.     fclose(d->f);
  284.   d->f=NULL;
  285.   free(d->satz);
  286. }
  287.  
  288. int T_ImmerWahr() { return(1==1); }
  289.  
  290. void A_AddTree()
  291. {
  292.   char str[30];
  293.   int i;
  294.  
  295.   LeseSatz(AktDef,AktFeld,str,&i);
  296.   AddTree(AktDef,defs[AktDef].satzpos,str);
  297. }
  298.  
  299. void DurchSuche(int defnr, TestFunktion t, AusgabeFunktion a)
  300. {
  301.   DFile *d;
  302.   Feld *f;
  303.   long p;
  304.  
  305.   WEITER=1;
  306.   d=&defs[defnr];
  307.   if (d->f)
  308.   {
  309.     rewind(d->f);
  310.     d->satzpos=ftell(d->f);
  311.     while (fread(d->satz,d->satzlaenge,1,d->f) && WEITER) 
  312.       if (!*(char *)(d->satz+d->satzlaenge-1))
  313.       { 
  314.     p=ftell(d->f);
  315.     if (t())  a();
  316.     d->satzpos=p;
  317.     fseek(d->f,p,SEEK_SET);
  318.       }
  319.   }
  320. }
  321.  
  322. void UnMarkAll(int defnr)
  323. {
  324.   DFile *d;
  325.   Feld *f;
  326.   long p;
  327.  
  328.   d=&defs[defnr];
  329.   if (d->f)
  330.   {
  331.     rewind(d->f);
  332.     d->satzpos=ftell(d->f);
  333.     while (fread(d->satz,d->satzlaenge,1,d->f)) 
  334.       if (*(char *)(d->satz+d->satzlaenge-1))
  335.       { 
  336.     *((char *)(d->satz+d->satzlaenge-1))=0;
  337.     p=ftell(d->f);
  338.     WriteToFile(defnr);
  339.     d->satzpos=p;
  340.     fseek(d->f,p,SEEK_SET);
  341.       }
  342.   }
  343. }
  344.  
  345. void DelMarked(int defnr)
  346. {
  347.   FILE *new;
  348.   DFile *d;
  349.   Feld *f;
  350.   char newname[60],oldname[60];
  351.  
  352.   d=&defs[defnr];
  353.   fclose(d->f);
  354.   strcpy(newname,d->dateiname);
  355.   strcat(newname,".ALT");
  356.   strcpy(oldname,d->dateiname);
  357.   strcat(oldname,".DAT");
  358.  
  359.   if (rename(oldname,newname)==-1) return;
  360.   if ((d->f=fopen(oldname,"wb"))==NULL) 
  361.   { remove(newname);  return;  }
  362.   if ((new=fopen(newname,"rb"))==NULL) 
  363.   { remove(newname);  return;  }
  364.  
  365.   while (fread(d->satz,d->satzlaenge,1,new)) 
  366.     if (!*(char *)(d->satz+d->satzlaenge-1))
  367.       fwrite(d->satz,d->satzlaenge,1,d->f);
  368.  
  369.   fclose(new);
  370.   remove(newname);
  371. }
  372.  
  373.  
  374. /*****************************************************************/
  375. /**********  Funktionen für die Sortierung in Bäumen *************/
  376. /*****************************************************************/
  377.  
  378. void MakeTree(int defnr, int feldnr)
  379. {
  380.   AktDef=defnr;
  381.   AktFeld=feldnr;
  382.   if (CreateTree(defnr,feldnr))
  383.     DurchSuche(defnr,T_ImmerWahr,A_AddTree);
  384. }
  385.  
  386. void _del(Key *k)
  387. {
  388.   if (k)
  389.   {
  390.     _del(k->L);
  391.     _del(k->R);
  392.     free(k->str);
  393.     free(k);
  394.   }
  395. }
  396.  
  397. void DelTree(int defnr)
  398. {
  399.   DFile *d;
  400.   d=&defs[defnr];
  401.   _del(d->wurzel);
  402.   d->wurzel=NULL;
  403.   d->keyfeld=0;
  404. }
  405.  
  406. void _list(Key *k)
  407. {
  408.   if (k)
  409.   {
  410.     _list(k->L);
  411.     puts(k->str);
  412.     _list(k->R);
  413.   }
  414. }
  415.  
  416. void ListTree(int defnr)
  417. {
  418.   if (defs[defnr].keyfeld)
  419.     _list(defs[defnr].wurzel);
  420. }
  421.  
  422. void _durch(int defnr, Key *k, TestFunktion t, AusgabeFunktion a)
  423. {
  424.   if (k)
  425.   {
  426.     _durch(defnr,k->L,t,a);
  427.     GoTo(defnr, k->filepos);
  428.     if (t()) a();
  429.     _durch(defnr,k->R,t,a);
  430.   }
  431. }
  432.  
  433. void DurchsucheTree(int defnr, TestFunktion t, AusgabeFunktion a)
  434. {
  435.   if (defs[defnr].keyfeld)
  436.     _durch(defnr,defs[defnr].wurzel,t,a);
  437. }
  438.  
  439. int CreateTree(int defnr, int feldnr)
  440. {
  441.   DFile *d;
  442.   Feld *f;
  443.  
  444.   d=&defs[defnr];
  445.   if (d->keyfeld!=0) DelTree(defnr);
  446.   if (feldnr<=d->felder)
  447.   {
  448.     f=&d->Felder[d->felder];
  449.     if (f->typ==STRFELD) 
  450.     {
  451.       d->keyfeld=feldnr;
  452.       return(OK);
  453.     }
  454.   }
  455.   return(FALSE);
  456. }
  457.  
  458. int _add(Key **k, long filepos, char *str)
  459. {
  460.   if (!*k)
  461.   {
  462.     if ((*k=malloc(sizeof(Key)))==NULL) return(FALSE);
  463.     if (((*k)->str=malloc(strlen(str)+1))==NULL) return(FALSE);
  464.     strcpy((*k)->str,str);
  465.     (*k)->filepos=filepos;
  466.     (*k)->R=NULL; (*k)->L=NULL;
  467.   } else
  468.   {
  469.     if (strcmp(str,(*k)->str) > 0)
  470.       return(_add(&(*k)->R,filepos,str));
  471.     else return(_add(&(*k)->L,filepos,str));
  472.   }
  473.   return(OK);
  474. }
  475.  
  476. int AddTree(int defnr, long filepos, char *str)
  477. {
  478.   if (defs[defnr].keyfeld)
  479.     return(_add(&defs[defnr].wurzel,filepos,str));
  480.   return(FALSE);
  481. }
  482.  
  483. int _search(Key *k, long *filepos, char *str)
  484. {
  485.   int compare;
  486.  
  487.   if (!k) return(FALSE);
  488.   compare=strcmp(k->str,str);
  489.   if (compare==0)
  490.   {
  491.     *filepos=k->filepos;
  492.     return(OK);
  493.   } else 
  494.   if (compare<0)
  495.     return(_search(k->R, filepos, str));
  496.   else return(_search(k->L, filepos, str));
  497. }
  498.  
  499. int SearchTree(int defnr, long *filepos, char *str)
  500. {
  501.   if (defs[defnr].keyfeld)
  502.     if (_search(defs[defnr].wurzel, filepos, str))
  503.     {
  504.       GoTo(0,*filepos);
  505.       return(OK);
  506.     }
  507.   return(FALSE);
  508. }
  509.  
  510. int cReadDBFormat(void)
  511. {
  512.   long dbnr,feldnr;
  513.   int zahl,i,max;
  514.   char str[300],*p;
  515.   char VarName1[50];
  516.  
  517.  
  518.   if ( GetIntegerParam(&dbnr) &&
  519.        GetIntegerParam(&feldnr) )
  520.   { 
  521.     Scan();
  522.     if (Steuer == ALPHA) {
  523.       strcpy (VarName1,ScanBuffer);    
  524.  
  525.       LeseSatz(dbnr,feldnr,str,&zahl);
  526.  
  527.       if (defs[dbnr].Felder[feldnr-1].typ==STRFELD)
  528.         max=defs[dbnr].Felder[feldnr-1].strlen;
  529.       else {
  530.         max=6;
  531.         itoa(zahl,str,10);
  532.       }
  533.  
  534.       p=str; i=0;
  535.       while (*p++) i++;
  536.       p--; i--;
  537.       while (i++ < max) *p++=' ';
  538.       *p=0;
  539.  
  540.       SetVarStr(VarName1,str);
  541.     } 
  542.     else 
  543.     {
  544.       serror ("Variablenname erwartet! ");
  545.       return(FALSE);
  546.     }
  547.   }
  548.   else 
  549.   {
  550.     serror(" Parameterfehler bei 'ReadDBForm'! ");
  551.     return(FALSE);
  552.   }
  553.  
  554.   return(OK);
  555. }
  556.