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