home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ehp14cs.zip / config.c < prev    next >
C/C++ Source or Header  |  1995-06-24  |  17KB  |  407 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  config.c                                        */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - save_read (aus Datei lesen)                   */
  7. /*              - check_koors (Koordinaten ueberpruefen)        */
  8. /*              - read_config (Config-Datei einlesen)           */
  9. /*              - save_write (in Datei schreiben)               */
  10. /*              - write_config (Config-Datei schreiben)         */
  11. /*                                                              */
  12. /****************************************************************/
  13.  
  14. #include <fcntl.h>
  15. #include "defs.h"
  16.  
  17. #define SH_SIZ (sizeof (short int))
  18.  
  19. extern char backupflag,helpflag,highblockflag,regexflag,
  20.         *reserve_mem(),*conffile;
  21. extern win_typ *akt_winp;
  22. extern marker_typ marker[];
  23. extern puff_typ macro[];
  24.  
  25. void write_config();
  26. int wc_errflag = FALSE;  /* Zeigt an, ob beim Lesen oder Schreiben */
  27.              /* der Config-Datei ein Fehler auftrat    */
  28.  
  29. /*****************************************************************************
  30. *
  31. *  Funktion       Aus Datei lesen mit Fehlerbehandlung (save_read)
  32. *  --------
  33. *
  34. *  Parameter    : f         :
  35. *                   Typ          : int
  36. *                   Wertebereich : Dateihandle
  37. *                   Bedeutung    : Datei, aus der gelesen werden soll
  38. *
  39. *                 b         :
  40. *                   Typ          : char *
  41. *                   Wertebereich : Pointer auf Speicherbereich
  42. *                   Bedeutung    : Puffer, in den Daten gelesen werden
  43. *
  44. *                 n         :
  45. *                   Typ          : int
  46. *                   Wertebereich : 0 - MAX_INT
  47. *                   Bedeutung    : Anzahl einzulesender Bytes
  48. *
  49. *  Beschreibung : Aus der Datei mit dem Handle f werden n Bytes in den
  50. *                 Puffer b gelesen. Ist dies nicht moeglich, so wird eine
  51. *                 Fehlermeldung ausgegeben und versucht, das Config-File
  52. *                 zu loeschen. Gelingt dies nicht, so wird eine entspre-
  53. *                 chende Meldung ausgegeben.
  54. *                 Diese Funktion wird nur von read_config() aufgerufen.
  55. *
  56. *****************************************************************************/
  57.  
  58. void save_read(f,b,n)
  59. int f,n;
  60. char *b;
  61. {
  62.   if(read(f,b,n) < n)  /* Falls Lesen fehlschlaegt, Meldung ausgeben */
  63.   {                    /* und Datei loeschen.                        */
  64.     pe_or(PROMPT_ERRCONF);
  65.     close (f);
  66.     if(unlink(conffile) < 0)
  67.       pe_or(PROMPT_ERRDELETE);
  68.     write_config(); /* Wenigstens versuchen, was bisher gelesen wurde zu retten */
  69.     ende(1, TRUE);  /* da noch nichts gemacht wurde, muss auch nichts gespeichert */
  70.   }                 /* werden */
  71. }
  72.  
  73. /*****************************************************************************
  74. *
  75. *  Funktion       Koordinaten ueberpruefen und ggf. anpassen (check_koors)
  76. *  --------
  77. *
  78. *  Parameter    : dy        :
  79. *                   Typ          : int *
  80. *                   Wertebereich : Pointer auf Integer-Variable
  81. *                   Bedeutung    : Hoehe des Bereichs in Bildschirmzeilen
  82. *
  83. *                 dx        :
  84. *                   Typ          : int *
  85. *                   Wertebereich : Pointer auf Integer-Variable
  86. *                   Bedeutung    : Breite des Bereichs in Spalten
  87. *
  88. *                 y         :
  89. *                   Typ          : int *
  90. *                   Wertebereich : Pointer auf Integer-Variable
  91. *                   Bedeutung    : Anfangszeile
  92. *
  93. *                 x         :
  94. *                   Typ          : int *
  95. *                   Wertebereich : Pointer auf Integer-Variable
  96. *                   Bedeutung    : Anfangsspalte
  97. *
  98. *  Beschreibung :   Es wird ueberprueft, ob ein Fenster mit den uebergebenen
  99. *                   Koordinaten vollstaendig auf dem Bildschirm dargestellt
  100. *                   werden koennte (die Groesse eines Rahmens wird intern
  101. *                   beruecksichtigt). Ist dies nicht der Fall, so werden
  102. *                   die Koordinaten angepasst.
  103. *
  104. *****************************************************************************/
  105.  
  106. void check_koors(dy,dx,y,x)
  107. int *dy,*dx,*y,*x;
  108. {
  109.   if(*dy > MAX_HEIGHT - 2)  /* -2 wg. rahmen */
  110.     *dy = MAX_HEIGHT - 2;
  111.  
  112.   if(*y + *dy > MAX_HEIGHT-2 + START_Y)
  113.     *y = MAX_HEIGHT - *dy - 2 + START_Y;
  114.  
  115.   if(*dx > MAX_WIDTH - 2)
  116.     *dx = MAX_WIDTH - 2;
  117.  
  118.   if(*x + *dx > MAX_WIDTH - 2 + START_X)
  119.     *x = MAX_WIDTH - *dx - 2 + START_X;
  120. }
  121.  
  122. /*****************************************************************************
  123. *
  124. *  Funktion       Config-Datei einlesen (read_config)
  125. *  --------
  126. *
  127. *  Parameter    : argc :
  128. *                   Typ          : int
  129. *                   Wertebereich : 1 - maxint
  130. *                   Bedeutung    : Anzahl v. Parameter in der Kommandozeile
  131. *
  132. *  Ergebnis     :
  133. *                   Typ          : int
  134. *                   Wertebereich : 0 - maxint
  135. *                   Bedeutung    : Anzahl eingelesener Dateien
  136. *
  137. *  Beschreibung :  Es wird versucht, eine Config-Datei einzulesen.
  138. *                  Existiert keine solche Datei, so wird 0 zurueckgegeben.
  139. *                  Die Config-Datei hat folgenden Aufbau:
  140. *                    char helpflag,backupflag,highblockflag;
  141. *                    short int Anzahl Macros in Datei
  142. *                    short int Anzahl short ints 1. Macro
  143. *                     <entsprechend viele short ints>
  144. *                    ... gleiches fuer alle anderen Macros
  145. *                    short int Anzahl der Fenster
  146. *                    <Anzahl der Fenster> Strukturen vom Typ win_typ
  147. *                    Hierbei ist zu beachten, dass in dem Struktur-
  148. *                    element filename die Laenge des Dateinamens in Byte
  149. *                    steht. Der Filename selbst folgt der jeweiligen
  150. *                    Struktur unmittelbar und ist nicht durch ein bes.
  151. *                    Zeichen terminiert.
  152. *                    Fuer jedes Fenster wird die entsprechende Datei
  153. *                    geladen und ein Fenster geoeffnet.
  154. *                    short int Anzahl Marker
  155. *                    <Anzahl Marker> Strukturen vom Typ marker_typ
  156. *                  Endet die Datei unerwartet, so wird eine Fehlermel-
  157. *                  dung ausgegeben und das Programm abgebrochen.
  158. *
  159. *****************************************************************************/
  160.  
  161. int read_config(argc)
  162. int argc;
  163. {
  164.   /* *** interne Daten und Initialisierung *** */
  165.   int       i,          /* Zähler für Fenster, Macros etc.           */
  166.         fh,         /* Filehandle fuer Config-Datei              */
  167.         mnum=0,     /* Schleifenzaehler fuer Einlesen der Macors */
  168.         msizeb,     /* Macrogroesse in Bytes                     */
  169.         old_tl,     /* Zwischenspeicher fuer Cursorzeile         */
  170.         old_sc,     /* Zwischenspeicher fuer Cursorspalte        */
  171.         namelen;    /* Laenge des Filenamens des aktuellen Fstr. */
  172.   short int msize,      /* Macrogroesse in short int gemessen        */
  173.         anz_win=0,  /* Anzahl der Fenster                        */
  174.         anz_marker, /* Anzahl der Marker                         */
  175.         anz_macros; /* Anzahl der Macros                         */
  176.   win_typ   *old_next,  /* Zwischenspeicher der Verzeigerung des ak- */
  177.         *old_prev,  /* tuell eingelesenen Fensters, da abgespei- */
  178.             /* cherte Verzeigerung jetzt falsch ist.     */
  179.         dummy;      /* Zum evtl. Skippen von Fenstereintraegen   */
  180.  
  181.   if(access(conffile,4))   /* Kann das Config-File gelesen werden ? */
  182.     return(0);             /* kein Config-File */
  183.   fh = open(conffile,O_RDONLY | O_BINARY);    /* Datei oeffnen */
  184.   save_read(fh,&helpflag,1);       /* Die vier globalen Flags einlesen */
  185.   save_read(fh,&backupflag,1);
  186.   save_read(fh,&highblockflag,1);
  187.   save_read(fh,®exflag,1);
  188.  
  189.   save_read(fh,&anz_macros,SH_SIZ); /* Anzahl der Macros einlesen */
  190.   for(i=anz_macros;i>0;i--)         /* Fuer alle Macros Groesse   */
  191.   {                                 /* und Inhalt einlesen        */
  192.     save_read(fh,&msize,SH_SIZ);
  193.     if(msize >= 0)
  194.       if(mnum < ANZ_MACROS)
  195.       {
  196.     if(!msize)
  197.       macro[mnum].begin = macro[mnum].end = NULL; /* leere Macros auf Null */
  198.     else
  199.     {
  200.       msizeb = msize * SH_SIZ;
  201.       save_read(fh,macro[mnum].begin = (short int *) reserve_mem(msizeb),msizeb);
  202.       macro[mnum].end = macro[mnum].begin + msize - 1;
  203.     }
  204.     mnum++;
  205.       }
  206.       else
  207.     lseek(fh,(long)(msize * SH_SIZ),1); /* Zum naechsten Macro in Datei */
  208.   }
  209.   if(argc == 1)         /* no params - use old windows and markers */
  210.   {
  211.     save_read(fh,&anz_win,SH_SIZ); /* Fensteranzahl einlesen */
  212.     for(i=anz_win;i>0;i--)
  213.     {
  214.       if(koppel_win())             /* Neues Fenster in Liste einhaengen */
  215.       {
  216.     old_next = akt_winp->next; /* Verzeigerung merken */
  217.     old_prev = akt_winp->prev;
  218.     save_read(fh,akt_winp,sizeof(win_typ)); /* Fensterdaten einlesen */
  219.     akt_winp->block.bstart = (bzeil_typ*) NULL; /* Blockzeiger löschen */
  220.     akt_winp->next = old_next; /* Verzeigerung wieder korrigieren    */
  221.     akt_winp->prev = old_prev;
  222.     akt_winp->filename = reserve_mem((namelen = (int)akt_winp->filename)+1);
  223.     save_read(fh,akt_winp->filename,namelen); /* Filenamen einlesen  */
  224.     akt_winp->filename[namelen] = '\0'; /* Filenamen abschliessen    */
  225.     old_tl = akt_winp->textline; /* Cursorposition zwischenspeichern */
  226.     old_sc = akt_winp->screencol;
  227.     if(!lies_file())             /* Dateitext einlesen */
  228.     {                            /* klappt das nicht, Fenster wieder */
  229.       gb_win_frei();             /* freigeben und Fensteranzahl um   */
  230.       anz_win--;                 /* eins reduzieren.                 */
  231.       setz_cursor(W_NOTAKT);     /* lies_file macht kein setz_cursor */
  232.     }
  233.     else  /* Einlesen des Textes hat geklappt */
  234.     {
  235.       /* Ueberpruefen, ob Fenster auf Bildschirm passt, ggf. anpassen */
  236.       check_koors(&akt_winp->dy,&akt_winp->dx,&akt_winp->y,&akt_winp->x);
  237.       check_koors(&akt_winp->ady,&akt_winp->adx,&akt_winp->ay,&akt_winp->ax);
  238.       if(old_tl > akt_winp->maxline)  /* nur wenn old_tl groesser maxline */
  239.       {                               /* kann auch ws_line zu gross sein  */
  240.         old_tl = akt_winp->maxline;
  241.         if(akt_winp->ws_line > akt_winp->maxline)
  242.           if((akt_winp->ws_line = akt_winp->maxline - akt_winp->dy + 1) < 0)
  243.         akt_winp->ws_line = 0;
  244.       }
  245.       gotox(old_tl); /* Cursorposition restaurieren */
  246.  
  247.       /* Wenn Cursorspalte zu gross, anpassen */
  248.       if((akt_winp->screencol = old_sc) > MAXLENGTH)
  249.         akt_winp->screencol = MAXLENGTH;
  250.       if(akt_winp->lastcol > MAXLENGTH)
  251.         akt_winp->lastcol = MAXLENGTH;
  252.  
  253.       /* Falls Cursor ausserhalb des Fensters steht, */
  254.       /* Fensterinhalt anpassen.                     */
  255.       if(akt_winp->ws_line + akt_winp->dy <= akt_winp->textline)
  256.         akt_winp->ws_line = akt_winp->textline - akt_winp->dy + 1;
  257.       if(akt_winp->ws_col + akt_winp->dx <= akt_winp->screencol)
  258.         akt_winp->ws_col = akt_winp->screencol - akt_winp->dx + 1;
  259.       akt_winp->winp = newwin(akt_winp->dy+2,akt_winp->dx+2,akt_winp->y,akt_winp->x);
  260.       init_win();  /* Fenster mit Curses anlegen und initialisieren */
  261.       show_win(W_NOTAKT); /* Fensterinhalt auf Bildschirm darstellen */
  262.     }
  263.       }
  264.       else  /* Falls kein Fenster mehr in Liste passte: */
  265.       {
  266.     print_err(W_COUNT_ERRTEXT);   /* Fehlermeldung ausgeben */
  267.     while(i--)                    /* Alle weiteren Fenstereintraege skippen */
  268.     {
  269.       save_read(fh,&dummy,sizeof(win_typ));
  270.       lseek(fh,(long)dummy.filename,1);
  271.     }
  272.     break;     /* keine weiteren Dateien lesen */
  273.       }
  274.     }
  275.  
  276.     rahmen(W_AKT); /* Cursor setzen, Rahmen highlighten */
  277.     setz_cursor(W_AKT); 
  278.  
  279.     save_read(fh,&anz_marker,SH_SIZ); /* Anzahl der Marker einlesen */
  280.     if(anz_marker > ANZ_MARKER)
  281.       anz_marker = ANZ_MARKER;
  282.     save_read(fh,marker,anz_marker * sizeof(marker_typ));
  283.     for(i=0;i<anz_marker;i++)
  284.       if(marker[i].col > MAXLENGTH)   /* falls EHP in der Zwischenzeit mit */
  285.       marker[i].col = MAXLENGTH;  /* einer Verringerung von MAXLENGTH  */
  286.   }                                   /* neu kompiliert wurde              */
  287.   close(fh);
  288.   return(anz_win);
  289. }
  290.  
  291. /*****************************************************************************
  292. *
  293. *  Funktion       In Datei schreiben mit Fehlerbehandlung (save_write)
  294. *  --------
  295. *
  296. *  Parameter    : f         :
  297. *                   Typ          : int
  298. *                   Wertebereich : Dateihandle
  299. *                   Bedeutung    : Datei, in die geschrieben werden soll
  300. *
  301. *                 b         :
  302. *                   Typ          : char *
  303. *                   Wertebereich : Pointer auf Speicherbereich
  304. *                   Bedeutung    : Puffer, aus dem Daten geschrieben werden
  305. *
  306. *                 n         :
  307. *                   Typ          : int
  308. *                   Wertebereich : 0 - MAX_INT
  309. *                   Bedeutung    : Anzahl zu schreibender Bytes
  310. *
  311. *  Beschreibung : In die Datei mit dem Handle f werden n Bytes aus dem
  312. *                 Puffer b gelesen. Ist dies nicht moeglich, so wird die
  313. *                 Variable wc_errflag gesetzt.
  314. *                 Ist wc_errflag schon gesetzt, wenn die Funktion aufge-
  315. *                 rufen wird, so wird nichts in die Datei geschrieben.
  316. *                 Diese Funktion wird nur von write_config() aufgerufen.
  317. *
  318. *****************************************************************************/
  319.                             
  320. void save_write(f,b,n)
  321. int f,n;
  322. char *b;
  323. {
  324.   if(!wc_errflag && (write(f,b,n) < n)) /* liefert write Fehler,   */
  325.     wc_errflag = TRUE;                  /* wird wc_errflag gesetzt */
  326. }
  327.  
  328. /*****************************************************************************
  329. *
  330. *  Funktion       Config-Datei schreiben (write_config)
  331. *  --------
  332. *
  333. *  Beschreibung : Das Config-File wird in dem in read_config beschriebenen
  334. *                 Format abgespeichert. Trat dabei ein Fehler auf, so wird
  335. *                 eine entsprechende Fehlermeldung ausgegeben und die Datei
  336. *                 geloescht.
  337. *
  338. *****************************************************************************/
  339.  
  340. void write_config()
  341. {
  342.   /* *** interne Daten *** */
  343.   int       fh,         /* Handle fuer Config-Datei               */
  344.         namelen,    /* Laenge des Filenamens fuer ein Fenster */
  345.         i;          /* Schleifenzaehler                       */
  346.   short int msize,      /* Macrogroesse                           */
  347.         anz_macros, /* Anzahl der belegten Macros             */
  348.         anz_win,    /* Anzahl der Fenster                     */
  349.         anz_marker; /* Anzahl der belegten Marker             */
  350.   char      *name;      /* Filename des zu schreibenden Fensters  */
  351.   win_typ   *w;         /* Pointer fuer Schleife ueber Windows    */
  352.  
  353.   if((fh = open(conffile,O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,0666)) < 0)
  354.   {
  355.     print_err(PROMPT_ERROPNCFG);
  356.     return;                /* kein Config-File */
  357.   }
  358.  
  359.   wc_errflag = FALSE; /* Fehlerflag zuruecksetzen */
  360.  
  361.   /* globale flags schreiben */
  362.   save_write(fh,&helpflag,1);
  363.   save_write(fh,&backupflag,1);
  364.   save_write(fh,&highblockflag,1);
  365.   save_write(fh,®exflag,1);
  366.  
  367.   /* macros schreiben */
  368.   for(anz_macros = ANZ_MACROS; !macro[anz_macros-1].begin; anz_macros--);
  369.   save_write(fh,&anz_macros,SH_SIZ);    /* falls hintere macros leer, nicht */
  370.   for(i=0;i<anz_macros;i++)             /* schreiben */
  371.   {
  372.     msize = macro[i].begin
  373.         ? macro[i].end - macro[i].begin + 1
  374.         : 0;                                 /* size in short ints */
  375.     save_write(fh,&msize,SH_SIZ);
  376.     if(msize > 0)
  377.       save_write(fh,macro[i].begin,msize * SH_SIZ); /* Inhalt schreiben */
  378.   }
  379.  
  380.   /* windows schreiben */
  381.   for(w=akt_winp->next->next,anz_win = 0;w != akt_winp->next;w=w->next,anz_win++);
  382.   save_write(fh,&anz_win,SH_SIZ);  /* Anzahl der Fenster schreiben */
  383.   for(w = akt_winp->next->next,i=anz_win;i>0;w = w->next,i--)
  384.   {
  385.     name = w->filename; /* Pointer auf Filename durch dessen Laenge ersetzen */
  386.     w->filename = (char*) (namelen = strlen(w->filename));
  387.     save_write(fh,w,sizeof(win_typ)); /* Fensterstruktur abspeichern */
  388.     save_write(fh,name,namelen); /* Dateinamen abspeichern */
  389.     w->filename = name;          /* Filenamen rekonstruieren */
  390.   }
  391.  
  392.   /* marker schreiben */
  393.   /* Zuerst Anzahl der belegten Marker ermitteln */
  394.   for(anz_marker = ANZ_MARKER; marker[anz_marker-1].window == -1; anz_marker--);
  395.   save_write(fh,&anz_marker,SH_SIZ); /* Anzahl der Marker schreiben */
  396.   /* Belegten Anteil des Markerfeldes abspeichern */
  397.   save_write(fh,marker,anz_marker * sizeof(marker_typ));
  398.  
  399.   close(fh);
  400.   if(wc_errflag)  /* trat beim Abspeichern ein Fehler auf, dann loeschen */
  401.   {
  402.     print_err(PROMPT_ERRWRTCFG);
  403.     if(unlink(conffile) < 0)
  404.       print_err(PROMPT_ERRUNLINK);
  405.   }
  406. }
  407.