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

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  text_1.c                                        */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - copy_to_buff (zeile in puffer kopieren)       */
  7. /*              - copy_from_buf (puffer zurueckschreiben)       */
  8. /*              - check_buff (evtl. puffer zurueckschreiben)    */
  9. /*              - fill_buff (evtl. Puffer besetzen)             */
  10. /*              - ul_char (ist aktuelles Zeichen unterstr. ?)   */
  11. /*              - akt_zeichen (aktuelles zeichen ermitteln)     */
  12. /*              - right (ein zeichen nach rechts)               */
  13. /*              - left (ein zeichen nach links)                 */
  14. /*              - wortende (testen, ob zeichen worttrenner)     */
  15. /*              - word_left (ein wort links)                    */
  16. /*              - word_right (ein wort rechts)                  */
  17. /*              - bol (an zeilenanfang)                         */
  18. /*              - eol (an zeilenende)                           */
  19. /*              - check_underl (teste auf _^H)                  */
  20. /*              - delete (aktuelles zeichen loeschen)           */
  21. /*              - mdelete (mehrere Zeichen loeschen)            */
  22. /*              - backspace (zeichen links loeschen)            */
  23. /*              - delete_word (wort rechts loeschen)            */
  24. /*              - delete_eol (Rest der Zeile loeschen)          */
  25. /*              - join (Zeilen verknuepfen)                     */
  26. /*              - up (eine zeile hoch)                          */
  27. /*              - down (eine zeile runter)                      */
  28. /****************************************************************/
  29.  
  30. #include "defs.h"
  31.  
  32. extern char backupflag;
  33. extern marker_typ marker[];
  34.  
  35. /* *** globale Daten und Initialisierung *** */
  36. char linebuff [3*MAXLENGTH+1]; /* Zeilenpuffer                  */
  37. char        bufflag = FALSE;   /* Flag, ob linebuff belegt ist           */
  38. char        *sd_line=NULL,     /* Zwischenspeicher fuer geloeschte Zeile */
  39.         space=' ';         /* Globales Leerzeichen                   */
  40. char        *fastzeichen();
  41.  
  42. /****************************************************************
  43. *
  44. * FUNKTION:     copy_to_buff()  (zeile in puffer kopieren)
  45. *
  46. * BESCHREIBUNG: - die aktuelle zeile wird nach linebuff kopiert;
  47. *               ist der textpointer NULL, so wird ein leerer
  48. *               puffer angelegt
  49. *               - dann wird der puffer bis zur maximallanege mit
  50. *               spaces aufgefuellt
  51. *               - das aktuelle zeichen wird gemaess
  52. *               akt_winp->screencol gesetzt
  53. *               - bufflag wird auf TRUE gesetzt
  54. *****************************************************************/
  55.  
  56. void copy_to_buff()
  57. {
  58.   /* *** interne Daten *** */
  59.   register int i; /* Zaehler fuer zu kopierende Zeichen */
  60.  
  61.   if (akt_winp->maxline == -1)  /* Wenn Datei leer, dann neue   */
  62.     new_line();                 /* Zeile einfuegen.             */
  63.   bufflag = TRUE;               /* Puffer als belegt markieren  */
  64.   if(akt_winp->alinep->text)    /* wenn Zeile nicht leer, dann     */
  65.     strcpy(linebuff,akt_winp->alinep->text); /* in Puffer kopieren */
  66.   else
  67.     linebuff[0] = '\0';         /* Sonst Pufferinhalt loeschen */
  68.  
  69.   /* Rest des Puffers mit Blanks auffuellen */
  70.   for (i=strlen (linebuff);i<3*MAXLENGTH;linebuff[i++] = ' ');
  71.   linebuff [3*MAXLENGTH] = '\0';
  72.   i = akt_winp->screencol;      /* bildschirmpos. speichern */
  73.  
  74.   /* Jetzt textcol setzen. Dazu screencol mal right aufrufen */
  75.   for (akt_winp->screencol = akt_winp->textcol = 0;i>0;i--)
  76.     right();
  77. }
  78.  
  79.  
  80. /****************************************************************
  81. *
  82. * FUNKTION:     copy_from_buf() (zeile zurueckschreiben)
  83. *
  84. * BESCHREIBUNG: - der inhalt von linebuff wird in die aktuelle
  85. *               zeile zurueckkopiert, dabei werden evtl. spaces
  86. *               am ende geloescht
  87. *               - ist die zeile leer, so wird der textpointer
  88. *               auf NULL gesetzt
  89. *****************************************************************/
  90.  
  91. void copy_from_buf()
  92. {
  93.   /* *** interne Daten *** */
  94.   register int i; /* Zaehler fuer Zeichen im Puffer */
  95.  
  96.   bufflag = FALSE; /* Puffer als leer markieren */
  97.   /* abschliessende Blanks skippen */
  98.   for (i=3*MAXLENGTH-1;i>=0 && linebuff [i] == ' ';i--);
  99.   /* Falls letztes Zeichen der Zeile ein unterstrichenes Space ist, so
  100.      wuerde der Puffer normal ein Zeichen zu frueh abgeschnitten. Diesen
  101.      Fall muss man also hier testen. */
  102.   if (i>0 && linebuff[i-1]=='_' && linebuff[i]=='')
  103.     linebuff[i+2] = '\0';
  104.   else
  105.     linebuff[i+1] = '\0';
  106.   line_free(akt_winp->alinep->text);            /* aktuelle Zeile durch  */
  107.   akt_winp->alinep->text = save_text(linebuff); /* Pufferinhalt ersetzen */
  108. }
  109.  
  110.  
  111. /****************************************************************
  112. *
  113. * FUNKTION:     check_buff()    (puffer evtl. zurueckschreiben)
  114. *
  115. * BESCHREIBUNG: - falls bufflag TRUE ist, wird copy_from_buf()
  116. *               aufgerufen
  117. *               - bufflag wird auf FALSE gesetzt
  118. *****************************************************************/
  119.  
  120. void check_buff()
  121. {
  122.   if (bufflag)
  123.     copy_from_buf(); /* Pufferinhalt in aktuelle Zeile uebernehmen */
  124. }
  125.  
  126. /****************************************************************
  127. *
  128. * FUNKTION:     fill_buff() (Puffer evtl. mit aktueller Zeile laden)
  129. *
  130. * BESCHREIBUNG: - falls bufflag FALSE ist, wird copy_to_buff()
  131. *               aufgerufen
  132. *****************************************************************/
  133.  
  134. void fill_buff()
  135. {
  136.   if (!bufflag)
  137.     copy_to_buff(); /* aktuelle Zeile in Puffer kopieren */
  138. }
  139.  
  140. /****************************************************************
  141. *
  142. * FUNKTION:     ist aktuelles zeichen unterstrichen? (ul_char)
  143. *
  144. * BESCHREIBUNG: - Es wird fill_buff aufgerufen.
  145. *               - ist das aktuelle zeichen unterstrichen, wird
  146. *               TRUE, sonst FALSE zurueckgeliefert
  147. *****************************************************************/
  148.  
  149. int ul_char()
  150. {
  151.   fill_buff(); /* Evtl. Zeile in Puffer kopieren */
  152.   if(linebuff[akt_winp->textcol] == '_'
  153.   && linebuff[akt_winp->textcol+1] == '' && linebuff[akt_winp->textcol+2])
  154.     return(TRUE);
  155.   return(FALSE);
  156. }
  157.  
  158. /****************************************************************
  159. *
  160. * FUNKTION:     akt_zeichen()   (aktuelles zeichen holen)
  161. *
  162. * BESCHREIBUNG: - Es wird fill_buff aufgerufen
  163. *               - das aktuelle zeichen wird zurueckgegeben
  164. *               - auch unterstrichene zeichen werden
  165. *               beruecksichtigt
  166. *****************************************************************/
  167.  
  168. char akt_zeichen()
  169. {
  170.   fill_buff(); /* evtl. aktuelle Zeile in Puffer kopieren */
  171.   if (ul_char()) /* Zeichen unterstrichen ? Dann 2 weiter rechts, da vor */
  172.     return (linebuff[akt_winp->textcol+2]); /* Zeichen _  steht. */
  173.   else
  174.     return(linebuff[akt_winp->textcol]); /* sonst an aktueller Pos. */
  175. }
  176.  
  177.  
  178. /****************************************************************
  179. *
  180. * FUNKTION:     right()         (ein zeichen rechts)
  181. * ERGEBNIS:     TRUE,FALSE
  182. * BESCHREIBUNG: - Es wird fill_buff aufgerufen
  183. *               - screencol wird um 1 inkrementiert
  184. *               - textcol wird auf den index des naechsten zeichens
  185. *               gesetzt (auch unterstrichene werden beruecksichtigt)
  186. *               - konnte nicht nach rechts gegangen werden, wird
  187. *               FALSE, sonst TRUE zurueckgeliefert.
  188. *****************************************************************/
  189.  
  190. int right()
  191. {
  192.   fill_buff(); /* evtl. aktuelle Zeile in Puffer kopieren */
  193.   if (akt_winp->screencol < MAXLENGTH) /* geht's noch nach rechts ? */
  194.   {
  195.     akt_winp->screencol++;
  196.     if (ul_char())            /* ist das aktuelle Zeichen unterstrichen, */
  197.       akt_winp->textcol += 3; /* muss intern Spalte um 3 erhoeht werden, */
  198.     else                      /* da '_' und '' geskippt werden muessen  */
  199.       akt_winp->textcol++;
  200.     return(TRUE);
  201.   }
  202.   return(FALSE);
  203. }
  204.  
  205.  
  206. /****************************************************************
  207. *
  208. * FUNKTION:     left()          (ein zeichen links)
  209. * ERGEBNIS:     TRUE,FALSE
  210. * BESCHREIBUNG: - Es wird fill_buff aufgerufen
  211. *               - screencol wird um 1 dekrementiert
  212. *               - textcol wird auf den index des vorigen zeichens
  213. *               gesetzt (auch unterstrichene werden beruecksichtigt)
  214. *               - konnte die aktuelle position nicht um einen schritt
  215. *               nach links bewegt werden, wird FALSE, sonst TRUE
  216. *               zurueckgeliefert.
  217. *****************************************************************/
  218.  
  219. int left()
  220. {
  221.   fill_buff(); /* evtl. aktuelle Zeile in Puffer kopieren */
  222.   if (akt_winp->textcol > 0) /* geht's noch nach links ? */
  223.   {
  224.     akt_winp->screencol--;
  225.     if (akt_winp->textcol >= 3) /* kann das anzuspringende Zeichen unter- */
  226.                 /* strichen sein ? */
  227.       if (linebuff [akt_winp->textcol-3] == '_' /* ist es denn auch */
  228.       && linebuff [akt_winp->textcol-2] == '') /* unterstrichen ?  */
  229.     akt_winp->textcol -= 3; /* ja, dann intern um 3 nach links  */
  230.       else
  231.     akt_winp->textcol--;    /* sonst nur um 1 nach links */
  232.     else
  233.       akt_winp->textcol--;
  234.     return(TRUE);
  235.   }
  236.   return(FALSE);
  237. }
  238.  
  239.  
  240. /****************************************************************
  241. *
  242. * FUNKTION:     wortende()  (ist zeichen worttrenner?)
  243. *
  244. * PARAMETER:    - char c : zu ueberpruefendes zeichen
  245. * ERGEBNIS:     - TRUE oder FALSE
  246. * BESCHREIBUNG: - es wird ueberprueft, ob c ein worttrennzeichen
  247. *               ist und entsprechend TRUE oder FALSE zurueckge-
  248. *               geben
  249. *****************************************************************/
  250.  
  251. int wortende (c)
  252. char c;
  253. {
  254.   return ((int) strchr (" \t.,#:;|@$&()[]{}!?\"'`/\\<>-+*^=",c));
  255. }
  256.  
  257. /****************************************************************
  258. *
  259. * FUNKTION:     word_left()     (ein wort links)
  260. * ERGEBNIS:     TRUE,FALSE
  261. * BESCHREIBUNG: - leading spaces und tabs werden uebersprungen
  262. *               - anschliessend werden screencol und textcol auf
  263. *               den beginn des naechsten wortes gesetzt
  264. *****************************************************************/
  265.  
  266. int word_left()
  267. {
  268.   /* *** interne Daten und Initialisierung *** */
  269.   register int old_sc = akt_winp->screencol, /* Zwischenspeicher Spalte */
  270.            ging=FALSE;           /* Rueckgabewert der Funktion left */
  271.  
  272.   while (left() && ((akt_zeichen() == ' ') || (akt_zeichen() == '\t')));
  273.   while (!wortende(akt_zeichen()) && (ging=left()));
  274.   if (ging)  /* Wenn man vor den Wortanfang gehen konnte, dann wieder */
  275.     right(); /* eins nach rechts auf den Wortanfang. */
  276.   if(old_sc == akt_winp->screencol) /* Cursorspalte restaurieren */
  277.     return(FALSE);
  278.   return(TRUE);
  279. }
  280.  
  281.  
  282. /****************************************************************
  283. *
  284. * FUNKTION:     word_right()    (ein wort rechts)
  285. * ERGEBNIS:     TRUE,FALSE
  286. * BESCHREIBUNG: - es wird bis zum wortende gesprungen
  287. *               - folgende spaces oder tabs werden ebenfalls
  288. *               uebersprungen
  289. *****************************************************************/
  290.  
  291. int word_right()
  292. {
  293.   /* *** interne Daten *** */
  294.   register int  old_sc, /* Zwischenspeicher Cursorspalte */
  295.         old_tc; /* Zwischenspeicher Cursorzeile  */
  296.   register char az;     /* aktuelles Zeichen             */
  297.  
  298.   fill_buff(); /* evtl. aktuelle Zeile in Puffer kopieren */
  299.   old_sc = akt_winp->screencol; /* Cursorposition merken */
  300.   old_tc = akt_winp->textcol;
  301.   if(wortende(akt_zeichen())) /* Steht man auf Worttrenner, */
  302.     right();                  /* dann eins nach rechts      */
  303.   else                        /* sonst Wort skippen         */
  304.     while ((az=akt_zeichen()) && !wortende (az) && right());
  305.   /* Jetzt die dem Wort folgenden Blanks und Tabs skippen */
  306.   while ((((az=akt_zeichen()) == ' ') || (az == '\t')) && right());
  307.  
  308.   if(akt_winp->screencol == MAXLENGTH) /* steht man am rechten */
  309.   { /* Rand, dann wieder zur alten Position zurueck */
  310.     akt_winp->screencol = old_sc;
  311.     akt_winp->textcol = old_tc;
  312.     return(FALSE);
  313.   }
  314.   return(TRUE);
  315. }
  316.  
  317.  
  318. /****************************************************************
  319. *
  320. * FUNKTION:     bol()   (an Zeilenanfang)
  321. *
  322. * BESCHREIBUNG: - es wird zum Zeilenanfang gesprungen
  323. *****************************************************************/
  324.  
  325. void bol()
  326. {
  327.   akt_winp->screencol = akt_winp->textcol = 0;
  328. }
  329.  
  330.  
  331. /****************************************************************
  332. *
  333. * FUNKTION:     eol()   (an Zeilenende)
  334. *
  335. * BESCHREIBUNG: - Es wird fill_buff aufgerufen
  336. *               - es wird zum Zeilenende gesprungen
  337. *               - spaces am ende werden ignoriert
  338. *****************************************************************/
  339.  
  340. void eol()
  341. {
  342.   /* *** interne Daten *** */
  343.   register int i; /* Index fuer linebuff */
  344.  
  345.   fill_buff(); /* evtl. aktuelle Zeile in Puffer kopieren */
  346.   for (i=3*MAXLENGTH-1;linebuff [i] == ' ';i--);
  347.   i++; /* Hinter letztes Zeichen gehen */
  348.   bol();  /* vom Anfang der Zeile so oft nach rechts, bis Cursor in */
  349.   while (akt_winp->textcol < i) /* richtiger interner Spalte steht. */
  350.     right();              /* Dadurch hat textcol den richtigen Wert */
  351. }
  352.  
  353.  
  354. /****************************************************************
  355. *
  356. * FUNKTION:     check_underl()  (teste auf _^H kombination)
  357. * ERGEBNIS:     TRUE, FALSE
  358. * BESCHREIBUNG: - falls das aktuelle Zeichen ein Backspace und
  359. *               das vorhergehende ein _ ist, oder das aktuelle
  360. *               Zeichen das zu unterstreichende und die Zeichen
  361. *               davor _ und  sind, werden screencol und
  362. *               textcol so dekrementiert, dass sie auf
  363. *               das _ zeigen
  364. *               - Falls ein solcher Fall auftrat, wird mit
  365. *               der Funktion lineout() die aktuelle Zeile auf dem
  366. *               Bildschirm restauriert und TRUE zurueckgegeben.
  367. *               Ansonsten wird FALSE zurueckgegeben.
  368. *
  369. *****************************************************************/
  370.  
  371. int check_underl()
  372. {
  373.   fill_buff(); /* evtl. aktuelle Zeile in Puffer kopieren */
  374.   if(akt_winp->textcol && linebuff[akt_winp->textcol+1] /* noch 2 Zeichen da ? */
  375.   && !strncmp(&linebuff[akt_winp->textcol-1],"_",2))       /* ^H eingefuegt? */
  376.   {
  377.     if (in_block(akt_winp->textline,akt_winp->screencol) & B_FIRST_CHAR)
  378.       insdel_blockadapt(-1);  /* Blockgrenzen anpassen (eee stimmt nicht ganz) */
  379.     else
  380.       insdel_blockadapt(-2);
  381.     akt_winp->textcol--;   /* Cursorposition korrigieren, da Cursor immer */
  382.     akt_winp->screencol--; /* auf dem Unterstrich stehen muss             */
  383.     return (TRUE);
  384.   }
  385.   else
  386.     if (!strncmp(&linebuff[akt_winp->textcol],"_",2) /* _ eingefuegt ? */
  387.     && linebuff [akt_winp->textcol+2]) /* und ein Zeichen dahinter ? */
  388.     {
  389.       insdel_blockadapt(-2); /* Blockgrenzen anpassen */
  390.       return (TRUE);
  391.     }
  392.   return (FALSE);
  393. }
  394.  
  395.  
  396. /****************************************************************
  397. *
  398. * FUNKTION:     delete()        (loesche aktuelles zeichen)
  399. * ERGEBNIS:     TRUE,FALSE
  400. * BESCHREIBUNG: - falls das aktuelle Zeichen nicht das Endzeichen
  401. *               ist, wird es geloescht (unterstrichene zeichen
  402. *               werden beruecksichtigt)
  403. *               - Die Blockgrenzen werden angepaßt
  404. *               - der restliche text wird rangezogen
  405. *               - danach wird check_underl() aufgerufen
  406. *****************************************************************/
  407.  
  408. int delete()
  409. {
  410.   /* *** interne Daten *** */
  411.   register char *in,     /* Zieladresse beim Verschieben  */
  412.         *out;    /* Startadresse beim Verschieben */
  413.   register int  anz_del; /* Anzahl zu loeschender Zeichen */
  414.  
  415.   if (akt_zeichen()) /* Letztes Zeichen (Abschlussnull) ? */
  416.   { /* akt_zeichen kopiert evtl. auch die Zeile in den Puffer */
  417.     insdel_blockadapt(-1); /* Blockgrenzen anpassen */
  418.     in = (out = &linebuff[akt_winp->textcol]) + (anz_del = 1 + 2*ul_char());
  419.     fwdcpy(out,in); /* Alles rechts vom Cursor eins ranziehen */
  420.     check_underl(); /* Ist dadurch ein neues unterstrichenes Zeichen entstd., */
  421.             /* wird alles korrekt angepasst */
  422.     /* Ende des Zeilenpuffers mit Blanks besetzen */
  423.     strncpy(&linebuff[3*MAXLENGTH-anz_del],"   ",anz_del);
  424.     akt_winp->changeflag = TRUE; /* Text als geaendert markieren */
  425.     return(TRUE);
  426.   }
  427.   return(FALSE);
  428. }
  429.  
  430. /*****************************************************************************
  431. *
  432. *  Funktion       mehrere Zeichen loeschen (mdelete)
  433. *  --------
  434. *
  435. *  Parameter    : n         :
  436. *                   Typ          : int
  437. *                   Wertebereich : 0 - MAXLENGTH
  438. *                   Bedeutung    : Anzahl zu loeschender Zeilen
  439. *
  440. *  Beschreibung : Es wird versucht, eine bestimmte Anzahl Zeichen von der
  441. *                 aktuellen Position ab zu loeschen. Ist dies nicht moeglich,
  442. *                 so werden so viele als moeglich geloescht.
  443. *
  444. *****************************************************************************/
  445.  
  446. void mdelete(n)
  447. int n;
  448. {
  449.   /* *** interne Daten und Initialisierung *** */
  450.   register char *p;        /* Zeiger in linebuff zum Auffuellen mit Blanks */
  451.   register int  i,         /* Anzahl loeschbarer Zeichen                   */
  452.         old_sc = akt_winp->screencol, /* alte Cursorspalte         */
  453.         old_tc;    /* alte Cursorspalte intern                     */
  454.  
  455.   fill_buff(); /* evtl. aktuelle Zeile in Puffer kopieren */
  456.   old_tc = akt_winp->textcol; /* Cursorspalte merken */
  457.   insdel_blockadapt(-n); /* Blockgrenzen anpassen */
  458.   for(i=0;i<n;i++) /* Berechnen, wieviele Zeichen geloescht */
  459.     if(!right())   /* werden koennen */
  460.       break;
  461.   /* kann maximal i Zeichen loeschen */
  462.   if(i)
  463.   {
  464.     akt_winp->changeflag = TRUE; /* Text als geaendert markieren */
  465.     /* Jetzt Zeilenrest nach links verschieben */
  466.     fwdcpy(&linebuff[old_tc],&linebuff[akt_winp->textcol]);
  467.     /* Ende des Puffers wieder mit Blanks besetzen */
  468.     p = linebuff + old_tc + strlen(linebuff + old_tc);
  469.     for(i = akt_winp->textcol - old_tc;i>0;i--)
  470.       *p++ = ' ';
  471.     *p='\0';
  472.   }
  473.   akt_winp->screencol = old_sc; /* Cursorspalte restaurieren */
  474.   akt_winp->textcol = old_tc;
  475. }
  476.  
  477. /****************************************************************
  478. *
  479. * FUNKTION:     backspace()     (loesche linkes zeichen)
  480. * ERGEBNIS:     TRUE,FALSE
  481. * BESCHREIBUNG: - falls der cursor sich nicht am linken rand be-
  482. *               findet, wird das links vom aktuellen zeichen be-
  483. *               findliche zeichen geloescht (mittels delete)
  484. *               - die aktuelle position ist nach backspace die des
  485. *               geloeschten zeichens
  486. *****************************************************************/
  487.  
  488. int backspace()
  489. {
  490.   if(left() && delete())
  491.     return(TRUE);
  492.   return(FALSE);
  493. }
  494.  
  495. /****************************************************************
  496. *
  497. * FUNKTION:     delete_word()   (wort loeschen)
  498. * ERGEBNIS:     TRUE,FALSE
  499. * BESCHREIBUNG: - das aktuelle zeichen wird deletet
  500. *               - solange, wie das aktuelle zeichen kein wort-
  501. *               trenner ist, wird es geloescht
  502. *               - folgende spaces und tabs werden ebenfalls ge-
  503. *               loescht
  504. *               - Durch die Verwendung von delete() werden die
  505. *               Blockgrenzen korrekt angepaßt
  506. *****************************************************************/
  507.  
  508. int delete_word()
  509. {
  510.   /* *** interne Daten *** */
  511.   register int  max_del; /* maximal zu loeschende Tabs und Blanks */
  512.   int           old_sc,  /* Alte Cursorposition Spalte            */
  513.         old_tc;  /* Alte Cursorposition Spalte intern     */
  514.   register char az;      /* Aktuelles Zeichen                     */
  515.  
  516.   /* Steht man auf einem Worttrenner, dann nur diesen loeschen */
  517.   if(wortende(az = akt_zeichen()) && az != ' ')
  518.     if (delete())
  519.       return(TRUE);
  520.     else   /* klappte das Loeschen nicht, False zurueckgeben */
  521.       return (FALSE);
  522.  
  523.   old_sc = akt_winp->screencol; /* Cursorspalte merken */
  524.   old_tc = akt_winp->textcol;
  525.  
  526.   /* Alle Zeichen bis zum naechsten Worttrenner skippen */
  527.   while ((az=akt_zeichen()) && !wortende(az))
  528.     right();
  529.  
  530.   swap_int(&old_sc,&akt_winp->screencol); /* Zur Anfangsposition zurueck */
  531.   akt_winp->textcol = old_tc;
  532.   mdelete(old_sc - akt_winp->screencol);  /* geskippte Zeichen loeschen */
  533.   max_del = MAXLENGTH - akt_winp->screencol;
  534.   old_sc = akt_winp->screencol;  /* Cursorspalte merken */
  535.   old_tc = akt_winp->textcol;
  536.  
  537.   /* Die dem Wort folgenden Blanks und Tabs werden auch geloescht */
  538.   while (max_del-- && ((az=akt_zeichen()) == ' ' || az == '\t'))
  539.     right();
  540.   swap_int(&old_sc,&akt_winp->screencol);
  541.   akt_winp->textcol = old_tc;
  542.   mdelete(old_sc - akt_winp->screencol);
  543.   return(TRUE);
  544. }
  545.  
  546. /****************************************************************
  547. *
  548. * FUNKTION:     delete_eol()    (Rest der Zeile loeschen)
  549. * ERGEBNIS:     TRUE, FALSE
  550. * BESCHREIBUNG: - Abhaengig von Bufflag wird entweder der Puffer-
  551. *               rest mit Blanks ueberschrieben oder an der ak-
  552. *               tuellen Position eine '\0' geschrieben. In diesem
  553. *               Fall wird fuer die neu entstandene Zeile neuer
  554. *               Speicher alloziert.
  555. *               - Falls sich die Zeile veraendert hat, wird TRUE,
  556. *               sonst FALSE zurueckgegeben.
  557. *****************************************************************/
  558.  
  559. int delete_eol()
  560. {
  561.   /* *** interne Daten *** */
  562.   register char *hilf,
  563.         *alt_poi;
  564.   register int  i;
  565.  
  566.   /* Steht Zeile schon im Puffer, dann im Puffer den Rest blanken */
  567.   if (bufflag)
  568.   {
  569.     for (i=akt_winp->textcol;i<3*MAXLENGTH;i++)
  570.       linebuff[i]=' ';
  571.     return (akt_winp->changeflag = TRUE);
  572.   }
  573.   else  /* Steht Zeile nicht im Puffer, dann Zeile selber modifizieren */
  574.   {
  575.     if (akt_winp->alinep->text)
  576.       if ((hilf=fastzeichen(akt_winp->screencol)) != &space)
  577.       {
  578.     if (hilf==akt_winp->alinep->text) /* ab erstem Zeichen, dann */
  579.     {                                 /* Zeilenihalt komplett loeschen */
  580.       free(akt_winp->alinep->text);
  581.       akt_winp->alinep->text = NULL;
  582.     }
  583.     else                              /* Sonst Zeile an Cursorposition */
  584.     {                                 /* abschneiden und neu sichern */
  585.       *hilf='\0';
  586.       alt_poi = akt_winp->alinep->text;
  587.       akt_winp->alinep->text = save_text(alt_poi);
  588.       free (alt_poi);
  589.     }
  590.     return (akt_winp->changeflag = TRUE);
  591.       }
  592.   }
  593.   return (FALSE);
  594. }
  595.  
  596. /*****************************************************************************
  597. *
  598. *  Funktion       Zeilen verknuepfen (join)
  599. *  --------
  600. *
  601. *  Parameter    : modus     :
  602. *                   Typ          : int
  603. *                   Wertebereich : IGNORE_COORS, ADAPT_COORS
  604. *                   Bedeutung    : IGNORE_COORS: join wird von Blockfunktion
  605. *                                  aufgerufen (wichtig fuer Aufruf del_line)
  606. *                                  ADAPT_COORS: join wird nicht von einer
  607. *                                  Blockfunktion aufgerufen
  608. *  Ergebnis     :
  609. *                   Typ          : int
  610. *                   Wertebereich : J_OK, J_TOOLONG, J_LASTLINE
  611. *                   Bedeutung    : J_OK      : Hat geklappt
  612. *                                  J_TOOLONG : Ging nicht, neue Zeile zu lang
  613. *                                  J_LASTLINE: Ging nicht, keine Zeile mehr
  614. *
  615. *  Beschreibung : Die nachfolgende Zeile wird an die aktuelle Zeile angehaengt.
  616. *                 Wird die Zeile dadurch zu lang oder existiert keine nach-
  617. *                 folgende Zeile, so wird der entsprechende Fehlerwert zu-
  618. *                 rueckgegeben.
  619. *
  620. *****************************************************************************/
  621.  
  622. int join(modus)
  623. int modus;
  624. {
  625.   /* *** interne Daten *** */
  626.   register int  l1,  /* Laenge der aktuellen Zeile       */
  627.         ib;  /* Cursorposition relativ zum Block */
  628.   register char *z1, /* Zeiger auf aktuelle Zeile        */
  629.         *z2; /* Zeiger auf nachfolgende Zeile    */
  630.  
  631.   check_buff();  /* evtl. Pufferinhalt in Text uebernehmen */
  632.   if (!(z1 = akt_winp->alinep->text)
  633.   && akt_winp->alinep->next != akt_winp->dummyp)
  634.     del_line(modus);          /* akt. zeile ist leer und nicht letzte z. */
  635.   else
  636.   {
  637.     if (down())         /* akt. zeile nicht letzte zeile? */
  638.     {
  639.       if (!(z2 = akt_winp->alinep->text)) /* naechste z. leer? */
  640.       {
  641.     if(del_line(modus) != LAST_LINE_DEL) /* wenn letzte Zeile geloescht */
  642.       up();                              /* machte del_line selbst up() */
  643.       }
  644.       else /* Wenn nachfolgende Zeile nicht leer war */
  645.       {
  646.     /* Blockspalten muessen evtl. bei normalem Block angepasst werden */
  647.     if(modus == ADAPT_COORS && block_defined()
  648.     && akt_winp->block.typ == BT_NORMAL)
  649.     {
  650.       ib = in_block(akt_winp->textline,akt_winp->screencol);
  651.       if(ib & B_FIRST_LINE) /* Enthaelt anzuhaengende Zeile Blockanfang ?  */
  652.       {                                      /* Ja, dann Laenge der ersten */
  653.         akt_winp->block.s_col += fastll(z1); /* Zeile aufaddieren          */
  654.         akt_winp->block.s_line--;            /* Block faengt eine Zeile    */
  655.       }                                      /* weiter oben an.            */
  656.       if(ib & B_LAST_LINE) /* Blockende in anzuhaengender Zeile ? */
  657.       {
  658.         akt_winp->block.e_col += fastll(z1); /* s.o. */
  659.         akt_winp->block.e_line--;
  660.       }
  661.     }
  662.  
  663.     up(); /* Wieder in urspruengliche Zeile zurueck */
  664.     if (fastll(z2) + fastll(z1) < MAXLENGTH) /* Neue Zeile zu lang ? */
  665.     { /* (Man verschenkt hier ein Zeichen (< statt <=), damit */
  666.       /* do_join() keine Probleme beim nachträglichen Einfügen */
  667.       /* eines Leerzeichens bekommt). */
  668.       /* Nein, dann Platz fuer neue Zeile schaffen */
  669.       /* und neue Zeile in Text eintragen          */
  670.       akt_winp->alinep->text = reserve_mem((l1=strlen(z1))+strlen(z2)+1);
  671.       strcpy(akt_winp->alinep->text,z1); /* Aktuelle Zeile und nach- */
  672.       strcpy(akt_winp->alinep->text + l1,z2); /* folgende zusammenkop. */
  673.       free(z1);
  674.       down();
  675.       if(del_line(modus) != LAST_LINE_DEL)       /* s.o. */
  676.         up();
  677.       return (J_OK);
  678.     }
  679.     else /* Wenn Zeile zu lang geworden waere */
  680.       return (J_TOOLONG);
  681.       }
  682.     }
  683.     else        /* Konnte keine Zeile nach unten gehen */
  684.       return (J_LASTLINE);
  685.   }
  686.   return (J_OK);
  687. }
  688.  
  689. /****************************************************************
  690. *
  691. * FUNKTION:     up()    (eine zeile hoch)
  692. *
  693. * BESCHREIBUNG: - die vorherige zeile wird zur aktuellen
  694. *****************************************************************/
  695.  
  696. int up()
  697. {
  698.   return(lines_up(1));
  699. }
  700.  
  701.  
  702. /****************************************************************
  703. *
  704. * FUNKTION:     down()  (eine zeile runter)
  705. *
  706. * BESCHREIBUNG: - die nachfolgende zeile wird zur aktuellen
  707. *****************************************************************/
  708.  
  709. int down()
  710. {
  711.   return(lines_down(1));
  712. }
  713.