home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / wp / ehp10.zip / BLOCK_2.C < prev    next >
C/C++ Source or Header  |  1992-12-14  |  31KB  |  742 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  block_2.c                                       */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - block_free (Blocktext freigeben)              */
  7. /*              - block_defined (Testen, ob Block definiert)    */
  8. /*              - nl_blockadapt (Anpassung Block nach newline)  */
  9. /*              - dl_blockadapt (Anpassung Block nach delline)  */
  10. /*              - insdel_blockadapt (Anpssg. nach insert/delete)*/
  11. /*              - lies_block (Block aus Datei einlesen)         */
  12. /*              - schr_block (Block in Datei schreiben)         */
  13. /*              - get_f_name (Filternamen einlesen)             */
  14. /*              - bl_to_fil (Block an Filter uebergeben)        */
  15. /*              - to_shell (Zeile an Shell uebergeben)          */
  16. /****************************************************************/
  17.  
  18. #include "defs.h"
  19. #include <process.h>
  20.  
  21. extern char *getenv(),*mktemp(),space,*reserve_mem(),*fastzeichen();
  22. extern marker_typ marker[];
  23. extern bzeil_typ *save_rechteck(),*save_normal();
  24.  
  25. /*****************************************************************************
  26. *
  27. *  Funktion       aktuellen Blocktext freigeben (block_free)
  28. *  --------
  29. *
  30. *  Parameter    : blockstart :
  31. *                   Typ          : bzeil_typ*
  32. *                   Wertebereich : Pointer auf Blockzeilenliste
  33. *                   Bedeutung    : Freizugebender Blocktext
  34. *
  35. *  Beschreibung : Die Speicherplatz fuer die uebergebene Liste und den in
  36. *                 ihr enthaltenen Text wrd freigegeben.
  37. *
  38. *****************************************************************************/
  39.  
  40. void block_free(blockstart)
  41. bzeil_typ *blockstart;
  42. {
  43.   /* *** interne Daten *** */
  44.   register bzeil_typ *hilf;  /* Zeiger auf naechste Blockzeile */
  45.  
  46.   while(blockstart)
  47.   {
  48.     hilf = blockstart->next;
  49.     line_free(blockstart->text); /* Speicher der Zeile freigeben */
  50.     free(blockstart);            /* Zeilenstruktur freigeben     */
  51.     blockstart = hilf;
  52.   }
  53. }
  54.  
  55. /*****************************************************************************
  56. *
  57. *  Funktion       Testen, ob Block definiert ist (block_defined)
  58. *  --------
  59. *
  60. *  Ergebnis     :
  61. *                   Typ          : int
  62. *                   Wertebereich : TRUE,FALSE
  63. *                   Bedeutung    : TRUE = Block ist definiert
  64. *                                  FALSE = Block ist nicht definiert
  65. *
  66. *  Beschreibung : Falls Bockanfang und Blockende definiert sind und der Block-
  67. *                 anfang vor dem Blockende liegt, wird TRUE zurueckgegeben.
  68. *                 Sonst wird FALSE zurueckgegeben.
  69. *
  70. *****************************************************************************/
  71.  
  72. int block_defined()
  73. {
  74.   /* *** interne Daten und Initialisierung *** */
  75.   register block_typ *bl = &akt_winp->block; /* Aktueller Block */
  76.  
  77.   return(bl->e_line != -1 && bl->s_line != -1 && (bl->e_line > bl->s_line
  78.      || (bl->s_line == bl->e_line && bl->e_col > bl->s_col)));
  79. }
  80.  
  81. /*****************************************************************************
  82. *
  83. *  Funktion       Anpassung des Blocks nach newline (nl_blockadapt)
  84. *  --------
  85. *
  86. *  Beschreibung : Falls ein Block definiert ist, werden, abhaengig von der
  87. *                 Cursorposition relativ zum Block, die Blockkoordinaten,
  88. *                 die letzte Position und die Marker angepasst.
  89. *                 Handelt es sich um einen normalen Block, so koennen unter
  90. *                 Umstaenden auch die col-Koordinaten angepasst werden.
  91. *
  92. *****************************************************************************/
  93.  
  94. void nl_blockadapt()
  95. {
  96.   /* *** interne Daten und Initialisierung *** */
  97.   register int i, /* Zaehler fuer Schleife bei Markeranpassung              */
  98.            ib = in_block(akt_winp->textline,akt_winp->screencol);
  99.           /* ib gibt die Position des Cursors relativ zum Block an  */
  100.  
  101.   if(block_defined()) /* Blockkoordinaten nur aendern, falls Block markiert */
  102.     if(ib & B_IN_BLOCK  /* Wenn der Cursor im Block steht oder der Block    */
  103.     || (akt_winp->block.typ == BT_RECHTECK  /* rechteckig ist und der       */
  104.     && ib & B_LINE                          /* Cursor in einer Blockzeile   */
  105.     && !(ib & B_BEFORE) && !(ib & B_AFTER))) /* und nicht vor oder hinter   */
  106.                         /* dem Block steht              */
  107.     {                                       /* dann wird die Blockendzeile  */
  108.       akt_winp->block.e_line++;             /* inkrementiert.               */
  109.       /* Stand der Cursor in der letzten Zeile eines normalen Blocks, dann  */
  110.       /* wird die Blockendspalte angepasst.                                 */
  111.       if(akt_winp->block.typ == BT_NORMAL)
  112.       {
  113.     if(ib & B_LAST_LINE)
  114.       akt_winp->block.e_col -= akt_winp->screencol;
  115.     /* Steht man auf dem ersten Zeichen eines normalen Blocks, dann */
  116.     /* wird die Startzeile und die Startspalte angepasst.           */
  117.     if(ib & B_FIRST_CHAR)
  118.     {
  119.       akt_winp->block.s_line++;
  120.       akt_winp->block.s_col -= akt_winp->screencol;
  121.     }
  122.       }
  123.     }
  124.     else /* Steht der Cursor nicht im Block, wird getestet, ob er davor steht */
  125.       if(ib & B_BEFORE)
  126.       {
  127.     akt_winp->block.e_line++; /* Wenn ja, werden sowohl Blockstart- als   */
  128.     akt_winp->block.s_line++; /* auch -endzeile angepasst.                */
  129.     /* Ist Cursorzeile erste Blockzeile, dann Startspalte anpassen,       */
  130.     /* Ist Cursorzeile letzte Blockzeile, dann Endspalte anpassen.        */
  131.     if(akt_winp->block.typ == BT_NORMAL)
  132.     {
  133.       if (ib & B_FIRST_LINE)
  134.         akt_winp->block.s_col -= akt_winp->screencol;
  135.       if (ib & B_LAST_LINE)
  136.         akt_winp->block.e_col -= akt_winp->screencol;
  137.     }
  138.       }
  139.  
  140.   /* lastpos anpassen */
  141.   if(akt_winp->textline < akt_winp->lastline)  /* Cursor vor lastpos ? */
  142.     akt_winp->lastline++;           /* dann Zeile von lastpos anpassen */
  143.   if(akt_winp->textline == akt_winp->lastline  /* Cursor in lastposzeile */
  144.   && akt_winp->screencol <= akt_winp->lastcol) /* vor lastpos, dann      */
  145.   { /* Zeile und Spalte von lastpos anpassen */
  146.     akt_winp->lastline++;
  147.     akt_winp->lastcol -= akt_winp->screencol;
  148.   }
  149.  
  150.   /* Marker anpassen */
  151.   for(i=0;i<ANZ_MARKER;i++)
  152.     if(marker[i].window == akt_winp->wini)  /* richtiges Fenster ? */
  153.     {
  154.       if (akt_winp->textline < marker[i].line) /* Cursor vor Markerzeile */
  155.     marker[i].line++;
  156.       if(akt_winp->textline == marker[i].line  /* Cursor in Markerzeile */
  157.       && akt_winp->screencol <= marker[i].col) /* vor Marker, dann      */
  158.       { /* Markerzeile und -spalte anpassen */
  159.     marker[i].line++;
  160.     marker[i].col -= akt_winp->screencol;
  161.       }
  162.     }
  163. }
  164.  
  165. /*****************************************************************************
  166. *
  167. *  Funktion       Anpassung des Blocks nach del_line (dl_blockadapt)
  168. *  --------
  169. *
  170. *  Beschreibung : Falls ein Block definiert ist, werden, abhaengig von der
  171. *                 Cursorposition relativ zum Block die Blockkoordinaten,
  172. *                 die letzte Position und die Marker angepasst.
  173. *                 Handelt es sich um einen normalen Block, so koennen unter
  174. *                 Umstaenden auch die col-Koordinaten angepasst werden.
  175. *
  176. *****************************************************************************/
  177.  
  178. void dl_blockadapt()
  179. {
  180.   /* *** interne Daten *** */
  181.   register int i,  /* Zaehler fuer Schleife bei Markeranpassung */
  182.            ib; /* Position des Cursors relativ zum Block    */
  183.  
  184.   if(block_defined())  /* Nur anpassen, wenn ein Block markiert ist */
  185.   {
  186.     /* berechnen, wo Cursor relativ zum Block steht und testen, ob  */
  187.     /* er davor steht.                                              */
  188.     if((ib = in_block(akt_winp->textline,akt_winp->screencol)) & B_BEFORE)
  189.     {
  190.       akt_winp->block.e_line--;   /* Ja, dann Endzeile -1 */
  191.       if(ib & B_FIRST_LINE)       /* In erster Zeile vor Block ? */
  192.       {                           /* ja, dann bei normalem Block Anfangs- */
  193.     if(akt_winp->block.typ == BT_NORMAL) /* spalte auf 0 */
  194.       akt_winp->block.s_col = 0;
  195.       }
  196.       else                        /* Steht man in einer Zeile vor dem Block, */
  197.     if (!(ib & B_LINE))       /* dann Startzeile -1 */
  198.       akt_winp->block.s_line--;
  199.     }
  200.     else                          /* Wenn man nicht davor steht: */
  201.       if(ib & B_LINE)             /* Steht man in einer Blockzeile ? */
  202.       {
  203.     akt_winp->block.e_line--; /* ja, dann Endzeile -1 */
  204.     if(akt_winp->block.typ == BT_NORMAL) /* Bei normalem Block */
  205.     {                         /* evtl. Spalten anpassen        */
  206.       if(ib & B_LAST_LINE)    /* falls man in der letzten Blockzeile steht */
  207.       {
  208.         check_buff();         /* Pufferinhalt muss evtl. in Text */
  209.         /* Endspalte wird hinter letzte Spalte der darueberliegenden */
  210.         /* Zeile gesetzt                                             */
  211.         akt_winp->block.e_col = fastll(akt_winp->alinep->prev->text);
  212.       }
  213.       if(ib & B_FIRST_LINE)   /* Steht man in der ersten Zeile, wird */
  214.         akt_winp->block.s_col = 0; /* Startspalte auf 0 gesetzt */
  215.     }
  216.       }
  217.  
  218.     /* Testen, ob der Block komplett geloescht wurde, und falls ja, dann */
  219.     /* Start- und Endzeile auf -1 setzen (Block unmarkieren) und Fenster-*/
  220.     /* inhalt neu zeichnen.                                              */
  221.     if (akt_winp->block.e_line < akt_winp->block.s_line
  222.     || (akt_winp->block.e_line == akt_winp->block.s_line
  223.     && akt_winp->block.e_col <= akt_winp->block.s_col))
  224.       akt_winp->block.s_line = akt_winp->block.e_line = -1;
  225.   }
  226.   /* jetzt marker und lastpos anpassen */
  227.   if(akt_winp->textline < akt_winp->lastline)
  228.     akt_winp->lastline--;
  229.   for(i=0;i<ANZ_MARKER;i++)
  230.     if(marker[i].window == akt_winp->wini && akt_winp->textline < marker[i].line)
  231.       marker[i].line--;
  232. }
  233.  
  234. /*****************************************************************************
  235. *
  236. *  Funktion       Anpassung des Blocks nach insert/delete (insdel_blockadapt)
  237. *  --------
  238. *
  239. *  Parameter    : offset    :
  240. *                   Typ          : int
  241. *                   Wertebereich : 0 - MAXLENGTH-1
  242. *                   Bedeutung    : Anzahl der Einfuegungen/Loeschungen
  243. *
  244. *  Beschreibung : Falls ein Block definiert ist, werden, abhaengig von der
  245. *                 Cursorposition relativ zum Block, bei einem normalen Block
  246. *                 die Blockkoordinaten angepasst. Desweiteren werden evtl.
  247. *                 die letzte Position und die Marker angepasst.
  248. *
  249. *****************************************************************************/
  250.  
  251. void insdel_blockadapt(offset)
  252. int offset;
  253. {
  254.   /* interne Daten und Initialisierung *** */
  255.   register int i,  /* Schleifenzaehler fuer Markeranpassung          */
  256.        obd,    /* Ergebnis des Tests, ob ein Block definiert ist */
  257.        sc = akt_winp->screencol, /* Alte Cursorspalte            */
  258.        ib;     /* Position des Cursors relativ zum Block         */
  259.  
  260.   ib = in_block(akt_winp->textline,sc);
  261.  
  262.   /* Testen, ob ein Block markiert ist, und wenn ja, ob es ein normaler ist */
  263.   if ((obd=block_defined()) && akt_winp->block.typ == BT_NORMAL)
  264.   {
  265.     /* Falls eine Spalte zu weit angepasst wird, d.h. anschliessend links vom  */
  266.     /* Cursor steht, dann wird die Spalte auf die Cursorspalte gesetzt.        */
  267.  
  268.     if (ib & B_FIRST_LINE && ib & (B_BEFORE | B_FIRST_CHAR))
  269.     { /* Steht man in der ersten Zeile vor oder auf dem  Blockanfang? */
  270.       if((akt_winp->block.s_col+=offset)<sc)  /* Ja, dann Startspalte anpassen */
  271.     akt_winp->block.s_col = sc;
  272.       if (ib & B_LAST_LINE)                   /* Liegt in der Zeile auch */
  273.     if((akt_winp->block.e_col+=offset)<sc)/* das Blockende, dann End-*/
  274.       akt_winp->block.e_col = sc;         /* spalte auch anpassen    */
  275.     }
  276.     else                                      /* Nicht in der ersten Blockzeile */
  277.       if (ib & B_LAST_LINE && ib & B_IN_BLOCK)/* Letzte Bockzeile und im Block? */
  278.     if((akt_winp->block.e_col+=offset)<sc)/* Ja, dann Endspalte anpassen    */
  279.       akt_winp->block.e_col = sc;
  280.   }
  281.   /* checken, ob einzeiliger Block nun nicht mehr existiert */
  282.   if (obd && akt_winp->block.e_line == akt_winp->block.s_line && akt_winp->block.e_col <= akt_winp->block.s_col)
  283.     akt_winp->block.s_line = akt_winp->block.e_line = -1;
  284.  
  285.   /* jetzt marker und lastpos anpassen */
  286.   /* nur bis col = screencol  (bei delete wichtig) */
  287.   if(akt_winp->textline == akt_winp->lastline && sc <= akt_winp->lastcol)
  288.     /* Wenn man nicht auf der letzten Position steht oder eingefuegt wurde */
  289.     /* (nicht geloescht, offset > 0), dann wird der offset auf die Spalte  */
  290.     /* der letzten Position addiert. Gelangt man dadurch nach links der    */
  291.     /* aktuellen Position, wird die Spalte der letzten Position auf die    */
  292.     /* aktuelle Spalte gesetzt. Gleiches gilt fuer die Marker.             */
  293.     if((akt_winp->lastcol != sc || offset > 0) && (akt_winp->lastcol += offset) < sc)
  294.       akt_winp->lastcol = sc;
  295.  
  296.   for(i=0;i<ANZ_MARKER;i++)
  297.     if(marker[i].window == akt_winp->wini && akt_winp->textline == marker[i].line && sc <= marker[i].col)
  298.       if((marker[i].col != sc || offset > 0) && (marker[i].col += offset) < sc)
  299.     marker[i].col = sc;
  300. }
  301.  
  302. /*****************************************************************************
  303. *
  304. *  Funktion       Block einlesen (lies_block)
  305. *  --------
  306. *
  307. *  Parameter    : bl      :
  308. *                   Typ          : block_typ*
  309. *                   Wertebereich : Pointer auf Blockstruktr
  310. *                   Bedeutung    : Spaeter der eingelesene Block
  311. *
  312. *               : f          :
  313. *                   Typ          : FILE*
  314. *                   Wertebereich : Pointer auf Datei
  315. *                   Bedeutung    : Datei, aus der Text geladen werden soll
  316. *
  317. *  Ergebnis     :
  318. *                   Typ          : int
  319. *                   Wertebereich : TRUE,FALSE
  320. *                   Bedeutung    : TRUE: Es konnten Zeichen gelesen werden
  321. *
  322. *  Beschreibung : Aus der uebergebenen Datei wird der Text geladen und in
  323. *                 die Blocktextliste der uebergebenen Blockstruktur ge-
  324. *                 schrieben.
  325. *                 Evtl. vorkommende Tabs werden expandiert.
  326. *
  327. *****************************************************************************/
  328.  
  329. int lies_block(bl,f)
  330. block_typ *bl;
  331. FILE *f;
  332. {
  333.   /* *** interne Daten *** */
  334.   char buff[3*MAXLENGTH+2],  /* Puffer fuer Zeile aus Datei */
  335.        buff2[3*MAXLENGTH+2], /* Puffer fuer in Block zu     */
  336.                  /* uebernehmende Zeile         */
  337.        nlflag;               /* Zeigt an, ob die letzte ge- */
  338.                  /* lesene Zeile vollstaendig   */
  339.                  /* war ('\n' am Ende)          */
  340.   int  len,    /* Laenge der eingelesenen Zeile      */
  341.        in,     /* Index in Eingabepuffer buff        */
  342.        out,    /* Index in Ausgabepuffer buff2       */
  343.        sc,     /* Laenge von buff2 im screencol-Mass */
  344.        max;    /* Laenge der laengsten Zeile bei     */
  345.            /* rechteckigem Block, sonst Laenge   */
  346.            /* der letzten Blockzeile             */
  347.   register bzeil_typ *p,     /* aktuelle Blockzeile  */
  348.              *p_old; /* vorige Blockzeile    */
  349.  
  350.   bl->s_col = akt_winp->screencol;  /* Aktuelle Position als */
  351.   bl->s_line = akt_winp->textline;  /* Blockstart merken     */
  352.   bl->laenge = -1;                  /* Laenge noch nicht bekannt */
  353.   bl->bstart = p = p_old = (bzeil_typ*) reserve_mem (sizeof (bzeil_typ));
  354.   p->text = NULL;
  355.   p->next = NULL;
  356.   out = sc = max = 0;
  357.  
  358.   while (fgets(buff,3*MAXLENGTH + 1,f))  /* Zeile aus Datei einlesen */
  359.   {
  360.     if(buff[(len = strlen(buff))-1] == '\n') /* Schloss Zeile mit '\n' ab ? */
  361.     {
  362.       nlflag = TRUE;
  363.       buff[--len] = '\0'; /* '\n' streichen */
  364.     }
  365.     else
  366.       nlflag = FALSE;
  367.     in = 0;
  368.     while(in < len)  /* Alle Zeichen des eingelesenen Strings durchgehen */
  369.     {
  370.       if (buff[in] == '_' && buff[in+1] == '' && buff[in+2])
  371.       {                            /* Fand man ein unterstrichenes Zeichen, */
  372.     buff2[out++] = buff[in++]; /* dann Unterstrich und Backspace ueber- */
  373.     buff2[out++] = buff[in++]; /* nehmen                                */
  374.       }
  375.       if(buff[in] == '\t')         /* Ein Tab wird zu Spaces expandiert     */
  376.     tab_in_buff(buff2,&sc,&out);
  377.       else                         /* Alle anderen Zeichen normal in Aus-   */
  378.       {                            /* gebapuffer kopieren.                  */
  379.     buff2[out++] = buff[in];
  380.     sc++;
  381.       }
  382.       in++;
  383.       if(sc > max || bl->typ == BT_NORMAL) /* bei normalem Block ist max    */
  384.     max = sc;                          /* laenge der letzten Zeile      */
  385.       if(sc == MAXLENGTH)       /* Ist die Ausgabezeile voll, */
  386.       {
  387.     buff2[out] = '\0';      /* dann Puffer abschliessen   */
  388.     sc = out = 0;
  389.     p->text = save_text(buff2); /* Zeile in Blocktextstruktur merken */
  390.     p->next = (bzeil_typ*) reserve_mem(sizeof(bzeil_typ)); /* neue Zeile */
  391.     p_old = p;
  392.     p = p->next;
  393.     p->next = NULL;
  394.     bl->laenge++; /* eine Zeile mehr im Block */
  395.       }
  396.     }
  397.  
  398.     /* Eingelesene Zeile jetzt in Blocktextstruktur ablegen, */
  399.     /* falls die eingelesene Zeile durch ein Newline abge-   */
  400.     /* schlossen wurde (nlflag).                             */
  401.     if(nlflag && !(!sc && len))         /* falls gerade volle Zeile abge- */
  402.     {                                   /* speichert wurde, nicht noch    */
  403.       buff2[out] = '\0';                /* einmal abspeichern             */
  404.       sc = out = 0;
  405.       p->text = save_text(buff2);
  406.       p->next = (bzeil_typ*) reserve_mem(sizeof(bzeil_typ));
  407.       p_old = p;
  408.       p = p->next;
  409.       p->next = NULL;
  410.       bl->laenge++; /* Eine Zeile mehr im Block */
  411.     }
  412.   }
  413.  
  414.   if(p_old != p)                        /* wenn eine Zeile zuviel alloziert */
  415.   {                                     /* diese freigeben */
  416.     free(p);
  417.     p_old->next = NULL;
  418.   }
  419.   /* Endspalte des Blockes ausrechnen: Dazu wird bei einem rechteckigen */
  420.   /* Block die Laenge der laengsten Zeile auf die Startspalte addiert,  */
  421.   /* bei einem normalen Block ist es lediglich die Laenge der letzten   */
  422.   /* Zeile.                                                             */
  423.   bl->e_col = (bl->typ == BT_RECHTECK ? bl->s_col + max : max);
  424.   if(bl->laenge != -1)  /* Endzeile ist Startzeile + Laenge */
  425.   {
  426.     bl->e_line = bl->s_line + bl->laenge;
  427.     akt_winp->changeflag = TRUE;
  428.     return(TRUE);
  429.   }
  430.   bl->s_line = bl->e_line = -1; /* War der Block leer, Block unmarkieren, */
  431.   return(FALSE);                /* FALSE zurueckgeben                     */
  432. }
  433.  
  434. /*****************************************************************************
  435. *
  436. *  Funktion       Schreib Block auf Platte (schr_block)
  437. *  --------
  438. *
  439. *  Parameter    : p          :
  440. *                   Typ          : bzeil_typ*
  441. *                   Wertebereich : Pointer auf Textliste
  442. *                   Bedeutung    : abzuspeichernder Text
  443. *
  444. *               : f          :
  445. *                   Typ          : FILE*
  446. *                   Wertebereich : Pointer auf Datei
  447. *                   Bedeutung    : Datei, in der Text gesichert werden soll
  448. *
  449. *  Beschreibung : Der aktuelle Block wird in die zu dem uebergebenen File-
  450. *                 pointer gehoerige Datei geschrieben.
  451. *
  452. *****************************************************************************/
  453.  
  454. void schr_block(p,f)
  455. register bzeil_typ *p;
  456. FILE      *f;
  457. {
  458.   check_buff();   /* Pufferinhalt evtl. in Text uebernehmen */
  459.   while(p)
  460.   {
  461.     if (p->text)
  462.       put_zeile(p->text,f); /* Zeile in Datei schreiben, Tabs evtl. kompr. */
  463.     putc('\n',f);
  464.     p = p->next;
  465.   }
  466. }
  467.  
  468. /*****************************************************************************
  469. *
  470. *  Funktion       Filternamen einlesen (get_f_name)
  471. *  --------
  472. *
  473. *  Parameter    : old_fil     :
  474. *                   Typ          : char *
  475. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  476. *                   Bedeutung    : alter Filtername (min. 61 Bytes Puffer)
  477. *
  478. *  Ergebnis     :
  479. *                   Typ          : int
  480. *                   Wertebereich : TRUE, FALSE
  481. *                   Bedeutung    : TRUE: Filtername vorhanden
  482. *                                  FALSE: kein Filter gewaehlt
  483. *
  484. *  Beschreibung : Ein Filtername wird eingelesen. Ist dessen Laenge Null, so
  485. *                 wird der urspruengliche Filtername beibehalten. Ist dann jedoch
  486. *                 kein alter Filtername vorhanden, wird FALSE zurueckgegeben.
  487. *
  488. *****************************************************************************/
  489.  
  490. int get_f_name(old_fil)
  491. char *old_fil;
  492. {
  493.   /* *** interne Daten *** */
  494.   char command[61]; /* String zur Eingabe des Filternamens */
  495.  
  496.   if(!*old_fil) /* Existiert noch kein Filtername, auf jeden Fall fragen */
  497.     strcpy(command,PROMPT_FILTNAME);
  498.   else          /* Sonst den Default mit angeben */
  499.     sprintf(command,PROMPT_FLTNMDFLT,old_fil);
  500.   print_stat(command);
  501.   read_stat(command,60,GS_ANY);  /* Filtername einlesen */
  502.   clear_stat();
  503.   setz_cursor(W_AKT);
  504.   if (*command)
  505.     strcpy(old_fil,command);
  506.   return(*old_fil != '\0');
  507. }
  508.  
  509. /*****************************************************************************
  510. *
  511. *  Funktion       Block an Filter uebergeben (bl_to_fil)
  512. *  --------
  513. *
  514. *  Ergebnis     :
  515. *                   Typ          : int
  516. *                   Wertebereich : TRUE, FALSE
  517. *                   Bedeutung    : TRUE: Block wurde ersetzt
  518. *                                  FALSE: Text wurde nicht veraendert
  519. *
  520. *  Beschreibung : Es werden die Namen für zwei temporäre Dateien generiert.
  521. *                 In die erste wird der Block geschrieben. Dann wird mit
  522. *                 der Funktion system das gewünschte Filterprogramm aufge-
  523. *                 rufen. Die Eingabe wird dabei aus der ersten temporären
  524. *                 Datei gelesen, die Ausgabe wird in die zweite temporäre
  525. *                 Datei geschrieben. Nachdem system zurückkehrt, wird aus
  526. *                 der zweiten temporären Datei der Block gelesen und in den
  527. *                 Text eingefügt.
  528. *                 Tritt ein Fehler auf, so wird eine Fehlermeldung ausgegeben.
  529. *
  530. *****************************************************************************/
  531.  
  532. int bl_to_fil()
  533. {
  534.   /* *** interne Daten und Initialisierung *** */
  535.   /* filt_name ist der Name des Filterprogramms */
  536.   static char filt_name[256],
  537.           filt_name_needs_init = TRUE;
  538.   char        dummy[80],   /* Zum Zusammensetzen des Kommandos */
  539.           fn_in [12],  /* Name der Temorärren Datei für Eingabe */
  540.           fn_out [12]; /* Name der temporären Datei für Eingabe */
  541.   FILE        *f;          /* Pointer auf Datei */
  542.   int         ret,         /* Returnwert der Blockfunktionen */
  543.           old_sc,      /* Alte Cursorposition Spalte */
  544.           old_tl,      /* Alte Cursorposition Zeile  */
  545.           error=FALSE; /* Flag, ob Fehler aufgetreten ist */
  546.   block_typ   hilf;  /* Block, der aus der Datei gelesen wird              */
  547.  
  548.   if (filt_name_needs_init)
  549.   {
  550.      *filt_name = '\0';
  551.      filt_name_needs_init = FALSE;
  552.   }
  553.  
  554.   mktemp(strcpy(fn_in,"tmpinXXXXXX")); /* Namen für temporäre */
  555.   mktemp(strcpy(fn_in,"tmpotXXXXXX")); /* Dateien erzeugen */
  556.  
  557.   if(!get_f_name(filt_name))  /* Filtername einlesen */
  558.     error = TRUE;
  559.   else
  560.   {
  561.     if(!(f = fopen(fn_in,"w")))  /* Temporäre Datei zum Schreiben öffnen */
  562.     {
  563.       print_err(PROMPT_ERRTMPOPN);
  564.       error = TRUE; /* Fehlermeldung ausgeben */
  565.     }
  566.     else
  567.     {
  568.       print_stat(PROMPT_WORKING);
  569.       /* Blocktext aus dem Text kopieren */
  570.       akt_winp->block.bstart = akt_winp->block.typ == BT_NORMAL? save_normal():save_rechteck();
  571.       schr_block(akt_winp->block.bstart,f); /* und in die Ausgabe-Datei schreiben */
  572.       fclose (f);                           /* Ausgabedatei schließen */
  573.       block_free(akt_winp->block.bstart);   /* Block freigeben */
  574.  
  575.       sprintf(dummy,"%s <%s >%s",filt_name,fn_in,fn_out); /* Kommando erstellen */
  576.       if(system(dummy) == -1) /* Shell starten */
  577.       {
  578.     clear_stat();
  579.     print_err(PROMPT_ERRSHELL);
  580.     error = TRUE;
  581.       }
  582.       else /* Fehler beim Ausführen des Filters */
  583.       {
  584.     /* Shell-Ausgabe wird als normaler Block eingefuegt */
  585.     if(!(f = fopen(fn_out,"r")))  /* Ausgabedatei zum Lesen öffnen */
  586.     {
  587.       print_err(PROMPT_TMPNOTFND);
  588.       error = TRUE;
  589.     }
  590.     else
  591.     {
  592.       old_tl = akt_winp->textline;   /* Cursorposition merken */
  593.       old_sc = akt_winp->screencol;
  594.       gotox(akt_winp->block.s_line); /* Cursor an Blockanfang, da lies_block */
  595.       akt_winp->screencol = akt_winp->block.s_col; /* Blockstart setzt */
  596.       hilf.typ = akt_winp->block.typ;/* muss fuer lies_block gesetzt werden */
  597.       ret = lies_block(&hilf,f);     /* Block aus Datei lesen */
  598.       gotox(old_tl);                 /* Cursorposition restaurieren */
  599.       akt_winp->screencol = old_sc;
  600.       fclose (f);                    /* Datei schliessen */
  601.     } /* end of else kein Fehler beim Öffnen der 2. temporären Datei */
  602.     clear_stat();                  /* filter fertig */
  603.       } /* end of else kein Fehler beim Ausführen des Filters */
  604.     } /* end of else kein Fehler beim öffnen der ersten temporären Datei */
  605.   } /* end of else kein Fehler bei get_f_name */
  606.  
  607.   unlink(fn_in);  /* temporäre Dateien löschen */
  608.   unlink(fn_out);
  609.  
  610.   if(error)         /* Trat bisher ein Fehler auf, dann Funktion verlassen */
  611.     return(FALSE);
  612.  
  613.   /* Jetzt Block aus Text loeschen. Dabei werden Marker, Cursor und letzte */
  614.   /* Position automatisch angepasst. */
  615.   if (akt_winp->block.typ == BT_RECHTECK)
  616.     del_rechteck();
  617.   else
  618.     del_normal();
  619.   if(ret) /* Block nicht leer? */
  620.   {
  621.     old_tl = akt_winp->textline;   /* Cursorposition merken */
  622.     old_sc = akt_winp->screencol;
  623.     gotox(akt_winp->block.s_line);       /* Block muss an Position des alten */
  624.     akt_winp->screencol = akt_winp->block.s_col; /* Blocks eingefuegt werden */
  625.     ret = akt_winp->block.typ == BT_NORMAL?ins_normal(&hilf):ins_rechteck(&hilf);
  626.     block_free(hilf.bstart);   /* eingefuegten Block freigeben */
  627.  
  628.     /* Wurde der Block vor der Cursorposition eingefügt, dann Cursorzeile */
  629.     /* um die Länge des Blocks (in Zeilen) erhöhen */
  630.     if(old_tl > akt_winp->block.s_line)
  631.       old_tl += akt_winp->block.laenge;
  632.     gotox(old_tl);             /* Cursorposition restaurieren  */
  633.     akt_winp->screencol = old_sc;
  634.     if(!ret) /* Konnte Block nicht eingefuegt werden, dann   */
  635.     {        /* Fehlermeldung ausgeben und Block unmarkieren */
  636.       pe_or(PROMPT_FILTINSRT);
  637.       akt_winp->block.s_line = akt_winp->block.e_line = -1;
  638.     }
  639.     return(TRUE);  /* alter Block ist auf jeden Fall geloescht */
  640.   }
  641.   else      /* bei leerem Block sind s_line und e_line korrekt auf -1 */
  642.   {
  643.     akt_winp->block.e_line = akt_winp->block.s_line = -1;
  644.     print_err(PROMPT_EMPTFILT);
  645.     return(TRUE);
  646.   }
  647. }
  648.  
  649. /*****************************************************************************
  650. *
  651. *  Funktion       Zeile an Shell uebergeben (to_shell)
  652. *  --------
  653. *
  654. *  Parameter    : line      :
  655. *                   Typ          : char *
  656. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  657. *                   Bedeutung    : an Shell zu uebergebende Kommandozeile
  658. *
  659. *  Ergebnis     :
  660. *                   Typ          : int
  661. *                   Wertebereich : TRUE, FALSE
  662. *                   Bedeutung    : TRUE : Alles funktionierte
  663. *                                  FALSE: es wurde keine Ausgabe eingefuegt
  664. *
  665. *  Beschreibung : line wird in eine temporäre Datei geschrieben. Dahinter
  666. *                 wird das Kommando exit plaziert. Anschließend wird eine
  667. *                 Shell gestartet, die die Eingabe aus dieser temporären
  668. *                 Datei liest. Die Shellausgabe wird in eine weitere tempo-
  669. *                 räre Datei geschrieben. Diese wird anschließend zum Lesen
  670. *                 geöffnet und der Inhalt als Block in den Text eingefügt.
  671. *
  672. *****************************************************************************/
  673.  
  674. int to_shell(line)
  675. char *line;
  676. {
  677.   /* *** interne Daten und Initialisierung *** */
  678.   FILE *f;          /* Filepointer fuer Temporäre Dateien */
  679.   int  ret = TRUE;  /* Returnwert der Funktion            */
  680.   char *shell_name, /* Name des Kommandointerpreters      */
  681.        dummy[80],   /* String zum Zusammenbasteln der Kommandozeile */
  682.        fn_in [12],  /* Name der Temorärren Datei für Eingabe */
  683.        fn_out[12];  /* Name der temporären Datei für Eingabe */
  684.  
  685.   mktemp(strcpy(fn_in,"tmpinXXXXXX"));
  686.   mktemp(strcpy(fn_out,"tmpotXXXXXX"));
  687.  
  688.   if(!(f = fopen(fn_in,"w")))  /* Temporäre Datei zum Schreiben öffnen */
  689.   {
  690.     print_err(PROMPT_ERRTMPOPN);
  691.     ret = FALSE;
  692.   }
  693.   else /* Kein Fehler beim Öffnen der Datei */
  694.   {
  695.     fprintf(f,"%s\n",line); /* An Shell zu übergebende Zeile in Datei schreiben */
  696.     fprintf(f,"exit\n");    /* Damit aufgerufene Shell terminiert wird */
  697.     fclose(f);
  698.  
  699.     if(!(shell_name = getenv("COMSPEC"))) /* Name des Kommandointerpreters */
  700.       shell_name = STD_SHELL;             /* ermitteln */
  701.  
  702.     sprintf(dummy,"%s <%s >%s",shell_name,fn_in,fn_out); /* Kommando erstellen */
  703.     print_stat(PROMPT_WORKING);
  704.     if(system(dummy) == -1) /* Shell starten */
  705.     {
  706.       clear_stat();
  707.       print_err(PROMPT_ERRSHELL);
  708.     }
  709.  
  710.     /* Shell-Ausgabe wird als normaler Block eingefuegt */
  711.     if(!(f = fopen(fn_out,"r")))  /* Ausgabedatei zum Lesen öffnen */
  712.     {
  713.       clear_stat();
  714.       print_err(PROMPT_TMPNOTFND);
  715.       ret = FALSE;
  716.     }
  717.     else
  718.     {
  719.       akt_winp->block.typ = BT_NORMAL;
  720.       if(!lies_block(&akt_winp->block,f))        /* Block aus Datei lesen */
  721.     ret = FALSE;  /* keine shell-ausgabe */
  722.       else            /* Lesen aus Datei klappte */
  723.     if(!ins_normal(&akt_winp->block))       /* Block einfuegen       */
  724.     { /* klappte das Einfuegen nicht, Block unmarkieren und raus     */
  725.       clear_stat(); /* Statuszeile loeschen */
  726.       ret = FALSE;
  727.       akt_winp->block.s_line = akt_winp->block.e_line = -1;
  728.       pe_or(PROMPT_SHELINSRT);
  729.     }
  730.       block_free(akt_winp->block.bstart);     /* Block freigeben    */
  731.       clear_stat();  /* shell fertig */
  732.     } /* End of else kein Fehler beim Öffnen der tmpot-Datei */
  733.   } /* End of else kein Fehler beim Öffnen der tmpin-Datei */
  734.   unlink(fn_in);  /* Temporäre Dateien wieder löschen */
  735.   unlink(fn_out);
  736.   if (f)
  737.     fclose(f);
  738.   return(ret);
  739. }
  740.  
  741.  
  742.