home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / EDITORS / EHP12 / MAIN.C < prev    next >
C/C++ Source or Header  |  1993-11-22  |  38KB  |  1,036 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  main.c                                          */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - pe_or (Fehlertext ausgeben ohne refresh)      */
  7. /*              - print_err (Fehlertext ausgeben)               */
  8. /*              - wart_ret (warte auf RETURN)                   */
  9. /*              - no_mem_err (Fehlermeldung, wenn kein Speicher)*/
  10. /*              - reserve_mem (Speicher reservieren)            */
  11. /*              - save_text (Textzeile sichern)                 */
  12. /*              - line_free (Zeile freigeben)                   */
  13. /*              - revcpy (String von hinten kopieren)           */
  14. /*              - fwdcpy (String von vorne kopieren)            */
  15. /*              - swap_int (zwei integer vertauschen)           */
  16. /*              - ja_nein (Lese JA/NEIN Abfrage)                */
  17. /*              - set_lines_cols (Zeilen- und Spaltenz.ermitteln*/
  18. /*              - check_env (Environment checken)               */
  19. /*              - catchsig (Signal abfangen)                    */
  20. /*              - init (initialisieren)                         */
  21. /*              - ende (Editor beenden)                         */
  22. /*              - save_all (alle geaenderten Texte abspeichern) */
  23. /*              - alles_frei (alle Speicherbereiche freigeben)  */
  24. /*              - do_wildcard_expansion (Wildcards expandieren) */
  25. /*              - hndl_params (Parameter verarbeiten)           */
  26. /*              - main (Hauptprogramm)                          */
  27. /*                                                              */
  28. /****************************************************************/
  29.  
  30. #define aktdef  /* Damit in defs.h nicht lokales als extern deklariert wird */
  31.  
  32. #ifdef OS2
  33. #define INCL_DOSPROCESS
  34. #define INCL_DOSSEMAPHORES
  35. #include <os2.h>
  36. #else
  37. #pragma inline
  38. #include <dir.h>
  39. #endif
  40. #include "defs.h"
  41. #include <signal.h>
  42.  
  43. extern char *getenv(),*sd_line,helpflag;
  44. #undef getch()
  45. extern int read_config();
  46. #ifdef MOUSE
  47. extern int mouse_jn; /* Variable für Maus in ja_nein */
  48. #ifdef OS2
  49. extern char mouse_active;
  50. extern short int mouse_handle;
  51. extern TID mouse_ThreadID, mouse_jn_ThreadID;
  52. #endif /* OS2 */
  53. #endif /* MOUSE */
  54.  
  55. void wart_ret(), ende(int, char);
  56.  
  57. /* *** globale Daten und Initialisierung *** */
  58. win_typ    *akt_winp;            /* Aktuelles Fenster                     */
  59. WINDOW     *status;              /* Statusfenster                         */
  60. short int  aktcode;              /* Aktueller Befehlstastencode           */
  61. short int  *keystack,            /* Zeiger auf aktuelles Pufferzeichen    */
  62.        *e_keystack,          /* Zeiger auf Pufferende                 */
  63.        mc_index;             /* Anzahl der Tastenkombinationen-1      */
  64. int        ks_index = -1;        /* Index des aktuellen Puffers           */
  65. int        blockattr,            /* Attribut zum Highlighten eines Blocks */
  66.        ersetzaddr,           /* Attribut fuer zu ersetzenden String   */
  67.        def_tab = STD_TAB;    /* Laenge eines Tabulatorsprungs         */
  68. char       highblockflag = TRUE, /* Sollen Bloecke gehighlighted werden ? */
  69.        backupflag=TRUE,      /* Es sollen .bak-Files erzeugt werden   */
  70.        regexflag=TRUE,       /* Es soll Patternmatching angew. werden */
  71.        def_aiflag = FALSE;   /* Normalerweise kein Autoindent         */
  72. char       *conffile = PF_CONFIG,/* Pfad der Config-Datei                 */
  73.        *loadfile = PF_LOAD;  /* Pfad des Loadfiles                    */
  74. block_typ  global_block;         /* Paste-Puffer fuer globalen Block      */
  75. marker_typ marker[ANZ_MARKER];   /* Feld fuer alle Marker                 */
  76. puff_typ   macro[ANZ_MACROS];    /* Feld fuer alle Macros                 */
  77. char       clear_buff = FALSE,   /* soll Puffer bei naechsten newwgetch() */
  78.                  /* geloescht werden? */
  79.        *tasten_inf = PF_TASTEN; /* Name des Tastenbelegungsfiles      */
  80. #ifdef OS2
  81. HMTX       sem_handle;           /* Handle für Semaphor, der Zusammelspiel*/
  82. #else                            /* von Tastatur uns Maus synchronisiert  */
  83. long       old_int;              /* Zwischenspeicher Vektor des Break-Ints*/
  84. #endif
  85.  
  86. /*****************************************************************************
  87. *
  88. *  Funktion       Fehlertext ausgeben ohne setz_cursor() (pe_or)
  89. *  --------
  90. *
  91. *  Parameter    : fehlertext:
  92. *                   Typ          : char*
  93. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  94. *                   Bedeutung    : Auszugebender Fehlertext
  95. *
  96. *  Beschreibung : Der Fehlertext wird mit print_stat() ausgegeben, anschlie-
  97. *                 ssend wird ein wart_ret ausgefuehrt, dann wird das Status-
  98. *                 fenster geloescht.
  99. *
  100. *****************************************************************************/
  101.  
  102. void pe_or(fehlertext)
  103. char *fehlertext;
  104. {
  105.   print_stat(fehlertext);  /* Text im Statusfenster anzeigen */
  106.   wart_ret();              /* Auf RETURN warten              */
  107.   clear_stat();            /* Statuszeile wieder loeschen    */
  108. }
  109.  
  110. /*****************************************************************************
  111. *
  112. *  Funktion       Fehlertext ausgeben (print_err)
  113. *  --------
  114. *
  115. *  Parameter    : fehlertext:
  116. *                   Typ          : char*
  117. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  118. *                   Bedeutung    : Auszugebender Fehlertext
  119. *
  120. *  Beschreibung : Der Fehlertext wird mit pe_or ausgegeben, anschliessend
  121. *                 wird der Cursor wieder positioniert.
  122. *
  123. *****************************************************************************/
  124.  
  125. void print_err(fehlertext)
  126. char *fehlertext;
  127. {
  128.   pe_or(fehlertext);    /* Fehlermeldung ausgeben und aus RETURN warten */
  129.   if(akt_winp->winp)    /* nur wenn schon ein window angefordert wurde  */
  130.     setz_cursor(W_AKT);      /* s. koppel_win() */
  131. }
  132.  
  133. /*****************************************************************************
  134. *
  135. *  Funktion       warte auf RETURN (wart_ret)
  136. *  --------
  137. *
  138. *  Beschreibung : Der Text " Bitte RETURN druecken..." wird in der
  139. *                 Statuszeile ausgegeben, anschliessend wird auf RETURN
  140. *                 gewartet.
  141. *
  142. *****************************************************************************/
  143.  
  144. void wart_ret()
  145. {
  146.   /* *** interne Daten *** */
  147.   char dummy; /* "String", der mit read_stat eingelesen wird */
  148.  
  149.   print_stat (PROMPT_ENTER);
  150.   read_stat(&dummy,0,GS_ANY); /* String der Laenge 0 einlesen */
  151.   clear_stat();               /* Statuszeile wieder loeschen  */
  152. }
  153.  
  154. /*****************************************************************************
  155. *
  156. *  Funktion       "Kein Speicher" - Fehlermeldung (no_mem_err)
  157. *  --------
  158. *
  159. *  Beschreibung : Eine Fehlermeldung wird ausgegeben und nach einer Rueck-
  160. *                 frage die Dateien gespeichert und das Programm beendet.
  161. *
  162. *****************************************************************************/
  163.  
  164. void no_mem_err()
  165. {
  166.   win_typ *w = akt_winp->next->next; /* Zum Freigeben der Fenster */
  167.  
  168.   while(w!=akt_winp)  /* Alle WINDOW-Strukturen aller Fenster freigeben */
  169.   {                   /* um Speicherplatz zu gewinnen */
  170.     delwin(w->winp); /* Damit Fenster nicht nochmals von delwin freigegeben */
  171.     w->winp = NULL;  /* wird, Pointer auf NULL setzen */
  172.     w = w->next;     /* Zum nächsten Fenster */
  173.   }
  174.   clear_stat();
  175.   print_stat(PROMPT_OUTOFMEM);
  176.   if(ja_nein(PROMPT_SAVE)) /* Abfrage */
  177.     save_all();                  /* Alle geaenderten Dateien sichern */
  178.   ende(1, TRUE);  /* Editor beenden, Rueckgabewert 1 */
  179. }
  180.  
  181. /*****************************************************************************
  182. *
  183. *  Funktion       Speicher reservieren (reserve_mem)
  184. *  --------
  185. *
  186. *  Parameter    : laenge    :
  187. *                   Typ          : int
  188. *                   Wertebereich : 0 - MAX_INT
  189. *                   Bedeutung    : Laenge des zu reservierenden Speicher-
  190. *                                  bereiches in Bytes
  191. *
  192. *  Ergebnis     :
  193. *                   Typ          : char*
  194. *                   Wertebereich : Pointer auf Speicherbereich
  195. *                   Bedeutung    : Pointer auf reservierten Speicherbereich
  196. *
  197. *  Beschreibung : Es wird versucht, ueber malloc den angeforderten Speicher-
  198. *                 bereich zu allozieren. Falls dies fehlschlaegt, wird
  199. *                 eine Fehlermeldung ausgegeben, alle Files gesichert und
  200. *                 das Programm abgebrochen.
  201. *
  202. *****************************************************************************/
  203.  
  204. char *reserve_mem (laenge)
  205. int laenge;
  206. {
  207.   /* *** interne Daten *** */
  208.   register char *hilf; /* Rueckgabewert der Funktion */
  209.  
  210.   if (hilf = malloc (laenge)) /* Speicher anfordern */
  211.     return (hilf); /* klappte, Adresse zurueckgeben */
  212.   else             /* Sonst Fehlermeldung und Ende  */
  213.     no_mem_err();
  214. }
  215.  
  216. /*****************************************************************************
  217. *
  218. *  Funktion       Textzeile sichern (save_text)
  219. *  --------
  220. *
  221. *  Parameter    : txt       :
  222. *                   Typ          : char*
  223. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  224. *                   Bedeutung    : Zu sichernder String
  225. *
  226. *  Ergebnis     :
  227. *                   Typ          : char*
  228. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  229. *                   Bedeutung    : Pointer auf gesicherten String
  230. *
  231. *  Beschreibung : Fuer den uebergebenen String wird, falls der String
  232. *                 eine Laenge ungleich 0 hat und txt != NULL ist, Speicher
  233. *                 alloziert, der uebergebene String wird dorthin kopiert
  234. *                 und der Pointer auf den Bereich zurueckgegeben.
  235. *                 Ist die Stringlaenge 0 oder txt NULL, so wird ein
  236. *                 NULL-Pointer zurueckgegeben.
  237. *
  238. *****************************************************************************/
  239.  
  240. char *save_text(txt)
  241. register char *txt;
  242. {
  243.   /* *** interne Daten *** */
  244.   register int len; /* Laenge des abzuspeichernden Textes */
  245.  
  246.   if (!txt) /* Falls String leer, NULL-Pointer zurueckgeben */
  247.     return (NULL);
  248.   return ((len=strlen(txt))?strcpy(reserve_mem(len+1),txt):NULL);
  249. }
  250.  
  251. /*****************************************************************************
  252. *
  253. *  Funktion       Zeile freigeben (line_free)
  254. *  --------
  255. *
  256. *  Parameter    : txt       :
  257. *                   Typ          : char*
  258. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  259. *                   Bedeutung    : Freizugebende Zeile
  260. *
  261. *  Beschreibung : Falls der Pointer nicht gleich NULL ist, wird der Spei-
  262. *                 cherbereich, auf den er zeigt, freigegeben.
  263. *
  264. *****************************************************************************/
  265.  
  266. void line_free(txt)
  267. char *txt;
  268. {
  269.   if(txt)
  270.     free(txt);
  271. }
  272.  
  273. /*****************************************************************************
  274. *
  275. *  Funktion       String von hinten kopieren (revcpy)
  276. *  --------
  277. *
  278. *  Parameter    : s1         :
  279. *                   Typ          : char *
  280. *                   Wertebereich : Pointer auf Speicherbereich
  281. *                   Bedeutung    : Platz, an den zu kopierender String
  282. *                                  kopiert wird
  283. *                 s2         :
  284. *                   Typ          : char *
  285. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  286. *                   Bedeutung    : zu kopierender String
  287. *
  288. *  Ergebnis     :
  289. *                   Typ          : char *
  290. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  291. *                   Bedeutung    : s1
  292. *
  293. *  Beschreibung : s2 wird, von hinten beginnend, nach s1 kopiert.  Dies ist
  294. *                 zum Beispiel nuetzlich, wenn s2 und s1 gemeinsame Speicher-
  295. *                 bereiche haben und s2 nach s1 beginnt.
  296. *
  297. *****************************************************************************/
  298.  
  299. char *revcpy(s1,s2)
  300. register char *s1,*s2;
  301. {
  302.   /* *** interne Daten und Initialierung *** */
  303.   register char *s2e = s2 + strlen(s2); /* Zeiger auf Stringende */
  304.  
  305.   for(s1+=s2e-s2;s2e >= s2;*s1-- = *s2e--);
  306.   return(s1);
  307. }
  308.  
  309. /*****************************************************************************
  310. *
  311. *  Funktion       String vorwaerts kopieren (fwdcpy)
  312. *  --------
  313. *
  314. *  Parameter    : s1         :
  315. *                   Typ          : char *
  316. *                   Wertebereich : Pointer auf Speicherbereich
  317. *                   Bedeutung    : Platz, an den zu kopierender String
  318. *                                  kopiert wird
  319. *                 s2         :
  320. *                   Typ          : char *
  321. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  322. *                   Bedeutung    : zu kopierender String
  323. *
  324. *  Ergebnis     :
  325. *                   Typ          : char *
  326. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  327. *                   Bedeutung    : s1
  328. *
  329. *  Beschreibung : s2 wird, von vorne beginnend, nach s1 kopiert.
  330. *                 Diese Funktion wird bei ueberlappenden Strings benoetigt,
  331. *                 da strcpy keine Garantie fuer die Kopierrichtung gibt.
  332. *
  333. *****************************************************************************/
  334.  
  335. char *fwdcpy(s1,s2)
  336. register char *s1,*s2;
  337. {
  338.   if(!s2)                       /* wie strcpy */
  339.   {
  340.     if(s1)
  341.       *s1 = '\0';
  342.   }
  343.   else
  344.     while (*s1++ = *s2++);
  345.   return(s1);
  346. }
  347.  
  348. /*****************************************************************************
  349. *
  350. *  Funktion       Zwei Integer vertauschen (swap_int)
  351. *  --------
  352. *
  353. *  Parameter    : a         :
  354. *                   Typ          : int *
  355. *                   Wertebereich : Pointer auf Integer
  356. *                   Bedeutung    : zu vertauschender Integer
  357. *
  358. *               : b         :
  359. *                   Typ          : int *
  360. *                   Wertebereich : Pointer auf Integer
  361. *                   Bedeutung    : zu vertauschender Integer
  362. *
  363. *  Beschreibung : Die Integer, auf die die Pointer a und b zeigen, werden
  364. *                 mittels einer Hilfsvariable vertauscht.
  365. *
  366. ******************************************************************************/
  367.  
  368. void swap_int(a,b)
  369. int *a,*b;
  370. {
  371.   /* *** interne Daten *** */
  372.   int hilf; /* Hilfsvariable zum Vertauschen */
  373.  
  374.   hilf = *a;
  375.   *a = *b;
  376.   *b = hilf;
  377. }
  378.  
  379. /*****************************************************************************
  380. *
  381. *  Funktion       Lese JA/NEIN Abfrage (ja_nein)
  382. *  --------
  383. *
  384. *  Parameter    : s         :
  385. *                   Typ          : char *
  386. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  387. *                   Bedeutung    : Text der Abfrage
  388. *
  389. *  Ergebnis     :
  390. *                   Typ          : int
  391. *                   Wertebereich : TRUE,FALSE
  392. *                   Bedeutung    : Ergebnis der Abfrage: ja = TRUE
  393. *                                                        nein = FALSE
  394. *
  395. *  Beschreibung : s wird in der Statuszeile ausgegeben, danach ein Zeichen,
  396. *                 terminiert durch RETURN eingelesen. Ist das Zeichen nicht
  397. *                 in "JjNn" wird die Abfrage wiederholt.  Es wird FALSE
  398. *                 zurueckgegeben, falls das Zeichen 'n' oder 'N' war,
  399. *                 ansonsten ist der Returnwert TRUE.
  400. *
  401. *****************************************************************************/
  402.  
  403. int ja_nein (s)
  404. char *s;
  405. {
  406.   /* *** interne Daten *** */
  407.   short int jn; /* einzulesendes Zeichen */
  408.  
  409.   print_stat (s);           /* Uebergebenen String ausgeben   */
  410.   print_stat(PROMPT_YES_NO);  /* Zusatz anhaengen               */
  411. #ifdef MOUSE
  412.   mouse_jn_init(TRUE);      /* Maus für ja_nein aktivieren    */
  413. #endif
  414.   nodelay(status,TRUE); /* Fenster wg. Maus auf NODELAY schalten */
  415.   do                        /* Solange ein Zeichen lesen, bis */
  416.   { jn = newwgetch(status); /* es eins von j,J,y,Y,n,N ist        */
  417. #ifdef OS2
  418.     if (jn == -1)
  419.       DosSleep (10);
  420. #endif
  421.   } while (!strchr ("jny,YJN",(char)jn)
  422. #ifdef MOUSE
  423.      && mouse_jn == NO_KLICK
  424. #endif
  425.                 );
  426.   nodelay(status,FALSE);  /* Wieder DELAY einschalten */
  427. #ifdef MOUSE
  428.   mouse_jn_init(FALSE);     /* Maus für ja_nein deaktivieren  */
  429. #endif
  430.   clear_stat();             /* Statuszeile wieder loeschen    */
  431.  
  432.   if (jn == 'n' || jn == 'N'
  433. #ifdef MOUSE
  434.  || mouse_jn == KLICK_RIGHT
  435. #endif
  436.                )
  437.     return (FALSE);
  438.   return (TRUE);
  439. }
  440.  
  441. #ifdef OWN_CURSES
  442. /******************************************************************************
  443. *
  444. * Funktion     : Zeilen- und Spaltenzahl ermitteln (set_lines_cols)
  445. * --------------
  446. *
  447. * Parameter    : modus       :
  448. *                  Typ          : char *
  449. *                  Wertebereich : Pointer auf ASCII-Zeichenkette
  450. *                  Bedeutung    : Aus der Umgebungsvariablen EHPINIT
  451. *                                 extrahierter Teil
  452. *
  453. * Beschreibung : Der aus der Umgebungsvariable stammende Teil hinter
  454. *                dem Bezeichner "screen" muß die Syntax <Spalten>x<Zeilen>
  455. *                haben. Das 'x' darf auch groa geschrieben sein.
  456. *                Ist der übergebene String syntaktisch korrekt so werden die
  457. *                Curses-Variablen LINES und COLS entsprechend gesetzt.
  458. *
  459. ******************************************************************************/
  460.  
  461. void set_lines_cols(modus)
  462. char *modus;
  463. {
  464.   char *zeil_str; /* Zeiger auf Tokenteil, der Zeilenzahl angibt */
  465.   int  lines,     /* Anzahl der Bildschirmzeilen */
  466.        cols;      /* Anzahl der Bildschirmspalten */
  467.  
  468.   if(!(zeil_str = strchr(modus,'x')) && !(zeil_str = strchr(modus,'X')))
  469.     return;  /* Falsches Format, Bildschirmgröße wird nicht verändert */
  470.   *zeil_str++ = '\0'; /* 'x' bzw. 'X' löschen, String in 2 Teile teilen */
  471.   cols = atoi(modus); /* Erste Zahl steht für die Spaltenangabe */
  472.   if(cols != 40 && cols != 80 && cols != 100 && cols != 132) /* Es werden nur die */
  473.     return;            /* Spaltenzahlen 40, 80, 100 und 132 unterstützt */
  474.   lines = atoi(zeil_str); /* Zweite Zahl des Strings steht für Zeilenangabe */
  475.   LINES = lines; /* Curses-Variablen LINES und COLS setzen */
  476.   COLS  = cols;
  477. }
  478. #endif
  479.  
  480. /*****************************************************************************
  481. *
  482. *  Funktion       Environment checken (check_env)
  483. *  --------
  484. *
  485. *  Beschreibung : Die Umgebung wird nach der Variablen EHPINIT abgesucht.
  486. *                 Wird sie gefunden, so wird der Inhalt analysiert.
  487. *                 Folgende Token haben folgenden Effekt:
  488. *                   deftab <n>   : Default-Tablaenge auf <n> setzen
  489. *                   nohelp       : Hilfstexte defaultmaessig ausgeschaltet
  490. *                   autoind      : Autoindentmodus defaultmaessig eingesch.
  491. *                   noshowblock  : Blockhervorhebung defaultmaessig eing.
  492. *                   conffile <f> : Name des Config-Files auf <f> setzen
  493. *                   loadfile <f> : Name des Load-Files auf <f> setzen
  494. *                   nobak        : Defaultmaessig keine .bak-Files
  495. *                   screen <mode>: Bildschirmgröße in Zeilen und Spalten
  496. *                   keys <f>     : Name des Tastaturbeschreibungsfiles = <f>
  497. *
  498. ****************************************************************************/
  499.  
  500. void check_env()
  501. {
  502.   /* *** interne Daten *** */ 
  503.   char *ehp_init, /* Zeiger auf Inhalt der Umgebungsvariable     */
  504.        *konv,     /* Zeiger zur Konvertierung in Kleinbuchstaben */
  505.        *token;    /* Zeiger auf aktuellen Parameter              */
  506.   int  i;         /* Integerwert der Tablaenge                   */
  507.  
  508.   if(ehp_init = getenv("EHPINIT"))
  509.     while(token = strtok(ehp_init," "))
  510.     {
  511.       ehp_init = NULL;  /* fuer strtok */
  512.       for (konv = token; *konv; konv++)
  513.     *konv = tolower (*konv); /* Token in Kleinbuchstaben konvertieren */
  514.       if(!strcmp("deftab",token))
  515.       {
  516.     if(!(token = strtok(ehp_init," ")))
  517.       break;        /* war letzter token */
  518.     if((i = atoi(token)) > 0 && i < MAXLENGTH)
  519.     {
  520.       def_tab = i;
  521.       continue;
  522.     }
  523.       }
  524.       if(!strcmp("nohelp",token))
  525.     helpflag = FALSE;
  526.       else
  527.     if(!strcmp("autoind",token))
  528.       def_aiflag = TRUE;
  529.     else
  530.       if(!strcmp("noshowblock",token))
  531.         highblockflag = FALSE;
  532.       else
  533.         if(!strcmp("conffile",token))
  534.         {
  535.           if(!(token = strtok(ehp_init," ")))
  536.         break;        /* war letzter token */
  537.           conffile = token;
  538.         }
  539.         else
  540.           if(!strcmp("loadfile",token))
  541.           {
  542.         if(!(token = strtok(ehp_init," ")))
  543.           break;        /* war letzter token */
  544.         loadfile = token;
  545.           }
  546.           else
  547.         if(!strcmp("nobak",token))
  548.           backupflag = FALSE;
  549.  
  550. #ifdef OWN_CURSES /* Bildschirmgröße läßt sich nur mit dem eigenen Curses
  551.              anpassen ! */
  552.         else
  553.           if(!strcmp("screen",token))
  554.           {
  555.             if(!(token = strtok(ehp_init," ")))
  556.               break;        /* war letzter token */
  557.             set_lines_cols(token); /* Bildschirmgröße setzen */
  558.           }
  559. #endif
  560.           else
  561.             if(!strcmp("keys", token))
  562.             {
  563.               if(!(token = strtok(ehp_init," ")))
  564.             break;      /* war letzer Token */
  565.               tasten_inf = strcpy(reserve_mem (strlen(token)),token);
  566.             }
  567.             else
  568.               if(!strcmp("noregex", token))
  569.             regexflag = FALSE;
  570.     }
  571. }
  572.  
  573. /******************************************************************************
  574. *
  575. * Funktion     : Signal abfangen (catchsig)
  576. * --------------
  577. *
  578. * Beschreibung : Diese Funktion wird beim Auftreten des Break-Interruptes
  579. *                (Nummer 27) aufgerufen. Es wird das clear_buff-Flag gesetzt,
  580. *                wodurch beim nächsten Aufruf von newwgetch alle Puffer und
  581. *                Macros abgebrochen werden.
  582. *
  583. ******************************************************************************/
  584.  
  585. void catchsig(sig)
  586. int sig;
  587. {
  588.   /* Um ein waehrend der Abarbeitung dieser Routine auftretendes */
  589.   /* Signal abzufangen, wird das Signal auf SIG_IGN umgeleitet   */
  590.  
  591.   signal(sig,SIG_IGN);
  592. #ifdef OS2
  593.   if(sig == SIGINT || sig == SIGQUIT || sig == SIGBREAK)
  594. #else
  595.   if(sig == SIGINT || sig == SIGTERM)
  596. #endif
  597.     clear_buff = TRUE;  /* Macro- und Repeatpuffer loeschen */
  598.   else
  599.   {
  600.     if(ja_nein(PROMPT_FATAL))
  601.       save_all();
  602.     ende(sig, TRUE);     /* Speicherbereiche werden automat. v. Unix freigegeben */
  603.   }
  604.   signal(sig, catchsig); /* Adresse dieser Funktion wieder eintragen */
  605. }
  606.  
  607. /*****************************************************************************
  608. *
  609. *  Funktion       initialisieren (init)
  610. *  --------
  611. *
  612. *  Beschreibung : Die CURSES-Funktionen initscr(),noecho() und raw() werden
  613. *                 aufgerufen, um CURSES zu initialisieren, echo abzuschalten,
  614. *                 und die Abfrage von einzelnen Zeichen zu ermoeglichen.
  615. *                 Dann wird das Dummyelement der Windowliste initialisiert.
  616. *                 Es ist _w_i_c_h_t_i_g, daa check_env von initscr aufgerufen wird.
  617. *                 In check_env werden nämlich evtl. die Variablen LINES
  618. *                 und COLS angepaat, was vor der Bildschirminitalisierung
  619. *                 stattfinden mua. Ebenfalls in initscr können sich diese
  620. *                 beiden Werte nochmals ändern.
  621. *
  622. *****************************************************************************/
  623.  
  624. void init()
  625. {
  626.   /* *** interne Daten *** */
  627.   int i;    /* Fuer Eingabe der Terminaltypen */
  628.  
  629.   /* Pruefen, ob IO des Prozesses umgelenkt wurde */
  630.   if(!isatty(0) || !isatty(1) || !isatty(2))
  631.   {
  632.     fputs(PROMPT_IO_REDIR,stderr);
  633.     exit(1);
  634.   }
  635.  
  636. #ifdef OS2
  637.   set_os2_raw (TRUE);       /* !!! muß erste Aktion sein !!! */
  638. #endif
  639.   check_env();              /* Umgebungsvariable bearbeiten */
  640.   initscr();                /* Curses "einschalten" */
  641.   noecho();
  642.   raw(); /* Zeichen direkt, keine Signale verarbeiten */
  643.   nonl(); /* \r soll nicht in \n umgewandelt werden */
  644.   status = newwin(1,COLS,LINES-1,0); /* Statusfenster oeffnen */
  645.   lies_tasten();        /* Tastaturbelegung laden */
  646.   akt_winp = (win_typ*) reserve_mem (sizeof (win_typ)); /* Dummyfenster */
  647.   akt_winp->next = akt_winp->prev = akt_winp;           /* allozieren   */
  648.   akt_winp->filename = NULL; /* damit print_err testen kann, ob es */
  649.   akt_winp->winp = NULL;     /* schon ein Fenster gibt */
  650.  
  651.   /* Terminal stellt zu ersetzende Begriffe blinkend dar, */
  652.   /* Bloecke halbhell.                                    */
  653.   ersetzaddr = A_BLINK;
  654.   blockattr = A_BOLD;
  655.  
  656.   global_block.e_line = global_block.s_line = -1;
  657.   global_block.bstart = NULL;   /* PASTE-Puffer leer */
  658.   for(i=0;i<ANZ_MARKER;i++)     /* Marker loeschen   */
  659.     marker[i].window = marker[i].line = marker[i].col = -1;
  660.   for(i=0;i<ANZ_MACROS;i++)     /* Macros loeschen   */
  661.     macro[i].begin = macro[i].end = NULL;
  662. #ifdef MOUSE
  663.   init_mouse();
  664. #endif
  665.  
  666.   signal (SIGINT, catchsig); /* kommt wohl nicht durch, da CTRL-c im raw- */
  667. #ifdef OS2
  668.   signal (SIGBUS, catchsig); /* Modus nicht als Signal verarbeitet wird.  */
  669.   signal (SIGQUIT, catchsig);
  670.   signal (SIGBREAK, catchsig);
  671.   /* Jetzt muß der Semaphor erzeugt werden, der verhindert, daß sich von der
  672.      Maus und von der Tastatur empfangene Kommandos behindern. Dieser Sema-
  673.      phor wird als "owned" geöffnet, muß also erst "released" werden, damit
  674.      ein Kommando akzeptiert werden kann. */
  675.   DosCreateMutexSem (NULL, &sem_handle, DC_SEM_SHARED, TRUE);
  676. #else
  677.   signal (SIGABRT, catchsig);
  678.   signal (SIGTERM, catchsig);
  679.   signal (SIGSEGV, catchsig);
  680. #endif
  681. }
  682.  
  683. /*****************************************************************************
  684. *
  685. *  Funktion       editor beenden (ende)
  686. *  --------
  687. *
  688. *  Parameter    : r         :
  689. *                   Typ          : int
  690. *                   Wertebereich : -MAX_INT - +MAX_INT
  691. *                   Bedeutung    : Rueckgabewert des Programms
  692. *
  693. *                 wait_mouse: (Nur OS/2)
  694. *                   Typ          : char
  695. *                   Wertebereich : FALSE, TRUE
  696. *                   Bedeutung    : TRUE:  Warte auf die Beendigung des
  697. *                                         Mausthreads
  698. *                                  FALSE: Nicht auf Mausthread warten.
  699. *
  700. *  Beschreibung : Die Fenster werden mittels endwin() geschlossen und danach
  701. *                 exit aufgerufen.
  702. *
  703. *****************************************************************************/
  704.  
  705. void ende(r, wait_mouse)
  706. int r;
  707. char wait_mouse;
  708. {
  709.   clear();      /* Bildschirm loeschen */
  710.   refresh();
  711.   endwin();     /* Curses beenden */
  712. #ifdef MOUSE
  713. #ifdef OS2
  714.   mouse_active = FALSE;  /* Maus nicht mehr benötigt */
  715.   /* Durch Setzen von mouse_active=FALSE beendet sich der Mouse-Thread
  716.      selbständig und die Maus wird geschlossen. Hier muß dann nur noch
  717.      auf die Terminierung des Threads gewartet werden. */
  718.   if (wait_mouse)
  719.   {
  720.     DosWaitThread (&mouse_ThreadID, DCWW_WAIT);
  721.     if (mouse_jn_ThreadID) /* Wurde schon einmal ja_nein aufgerufen? */
  722.       DosWaitThread (&mouse_jn_ThreadID, DCWW_WAIT);
  723.   }
  724. #else
  725.   set_mouse_int(0); /* Mausroutine maskieren */
  726. #endif
  727. #endif
  728. #ifndef OS2
  729.   *(long*)(27*4) = old_int; /* Vektor des Break-Interruptes restaurieren */
  730. #endif
  731.   exit(r);
  732. }
  733.  
  734.  
  735. /*****************************************************************************
  736. *
  737. *  Funktion       pruefen, ob Texte geaendert wurden
  738. *  --------
  739. *
  740. *  Ergebnis     : TRUE: Es wurde mindestens eine Datei geaendert
  741. *                 FALSE: Alle Dateien sind ungeaendert
  742. *
  743. *  Beschreibung : Es wird ueber alle bestehenden Fenster iteriert und
  744. *                 das changeflag geprueft. Ist eines TRUE, so wird
  745. *                 sofort mit TRUE zurueckgekehrt.
  746. *
  747. *****************************************************************************/
  748.  
  749. int did_anything_change()
  750. {
  751.   win_typ *p = akt_winp->next->next;
  752.  
  753.   while (p != akt_winp->next)
  754.   {
  755.     if (p->changeflag)
  756.       return TRUE;
  757.     p = p->next;
  758.   }
  759.   return FALSE;
  760. }
  761.  
  762. /*****************************************************************************
  763. *
  764. *  Funktion       alle geaenderten Texte abspeichern (save_all)
  765. *  --------
  766. *
  767. *  Ergebnis     : TRUE: alle Dateien konnten abgespeichert werden.
  768. *                 FALSE: nicht alle Dateien ...
  769. *
  770. *  Beschreibung : Die zu den Fenstern gehoerigen Files werden abgespeichert,
  771. *                 sofern sie veraendert wurden.
  772. *
  773. *****************************************************************************/
  774.  
  775. int save_all()
  776. {
  777.   /* *** interne Daten und Initialisierung *** */
  778.   int     no_errflag = TRUE;   /* Zeigt Fehler beim Abspeichern an */
  779.   win_typ *d = akt_winp->next; /* Zeiger auf Dummy-Fenster         */
  780.  
  781.   check_buff();
  782.   akt_winp = d->next;
  783.   while (akt_winp != d)
  784.   {
  785.     if(akt_winp->changeflag && !schreib_file())
  786.       no_errflag = FALSE; /* schreib_file lieferte Fehler */
  787.     akt_winp = akt_winp->next;
  788.   }
  789.   akt_winp = d->prev; /* akt_winp restaurieren */
  790.   return(no_errflag);
  791. }
  792.  
  793. /*****************************************************************************
  794. *
  795. *  Funktion       Text und Fenster freigeben (alles_frei)
  796. *  --------
  797. *
  798. *  Beschreibung : Der fuer Texte und Fenster allozierte Speicherplatz wird
  799. *                 freigegeben.
  800. *
  801. *****************************************************************************/
  802.  
  803. void alles_frei()
  804. {
  805.   while(akt_winp != akt_winp->next)     /* noch ein Fenster da? */
  806.   {
  807.     free_text();  /* Text des Fensters freigeben */
  808.     delwin(akt_winp->winp); /* Fenster fuer Curses freigeben */
  809.     gb_win_frei(); /* gb_win_frei loescht Fenster aus Liste und */
  810.   }                /* macht akt_winp zu ->prev */
  811.   if(global_block.bstart)     /* globalen Block evtl. freigeben */
  812.     block_free(global_block.bstart);
  813.   line_free(sd_line);      /* zuletzt geloeschte Zeile freigeben */
  814.   free(akt_winp);          /* dummy auch freigeben */
  815. }
  816.  
  817. #ifndef OS2
  818. /*****************************************************************************
  819. *
  820. *  Funktion       Wildcards expandieren (do_wildcard_expansion)
  821. *  --------
  822. *
  823. *  Parameter    : argc         :
  824. *                   Typ          : int *
  825. *                   Wertebereich : Zeiger auf Integer
  826. *                   Bedeutung    : Zeiger auf bisherige Anzahl der Parameter
  827. *
  828. *                 argv         :
  829. *                   Typ          : char **[]
  830. *                   Wertebereich : Pointer auf Pointer auf Array von Pointer
  831. *                                  auf Parametern
  832. *                   Bedeutung    : 1. Parameter: Programmname
  833. *                                  restliche Parameter: zu expandierende
  834. *                                  Dateinamen
  835. *
  836. *  Beschreibung : Mittels der Funktionen findfirst und findnext werden
  837. *                 die als Parameter angegebenen Dateinamenmuster zu
  838. *                 vollständigen Dateinamen expandiert. argc aud argv
  839. *                 werden auf das entstehende Erbebnis gesetzt, das keine
  840. *                 Wildcards mehr enthält.
  841. *
  842. *****************************************************************************/
  843.  
  844. void do_wildcard_expansion(argc, argv)
  845. int *argc;
  846. char **argv[];
  847. {
  848.   int ende,               /* Kein weiteres File zum Pattern ?        */
  849.       complete_length,    /* Summe aller Stringlängen                */
  850.       new_argc,           /* Neue Parameteranzahl                    */
  851.       new_argv_index,     /* Index in neues Argumentarray            */
  852.       argv_index;         /* Index in argv, zählt die Dateiparameter */
  853.   struct ffblk file_info; /* Struktur für findfirst und findnext     */
  854.   struct filenamelist     /* Für die Konstruktion der neuen Liste    */
  855.   {
  856.     char                *name;
  857.     struct filenamelist *next;
  858.   } *p, *q, *first;       /* Laufzeiger und Listenstart              */
  859.   char **new_argv;        /* Neues Feld für Parameter                */
  860.  
  861.   if (*argc > 1) /* Nur etwas machen, wenn auch Parameter angegeben wurden */
  862.   {
  863.     /* Zunächst ein Dummy-Element für die Namenliste anlegen: */
  864.     first = p = (struct filenamelist *) reserve_mem (sizeof (struct filenamelist));
  865.     p->next = NULL;
  866.     argv_index = 0;
  867.     new_argc = 1; /* Zumindest der Kommandoname */
  868.     complete_length = strlen ((*argv) [0]); /* Länge des Kommandos ! */
  869.     while (++argv_index < *argc)
  870.     {
  871.       ende = findfirst ((*argv) [argv_index], &file_info, 0);
  872.       if (ende)
  873.       { /* Überhaupt keinen passenden Namen, dann neue Datei! */
  874.     p->next =
  875.       (struct filenamelist *) reserve_mem (sizeof (struct filenamelist));
  876.     p = p->next;
  877.     p->next = NULL;
  878.     p->name = strcpy ((char*) reserve_mem (strlen ((*argv) [argv_index])),
  879.               (*argv) [argv_index]);
  880.     complete_length += strlen ((*argv) [argv_index]) + 1;
  881.     new_argc++;
  882.       }
  883.       else
  884.     while (!ende)
  885.     {
  886.       p->next = 
  887.         (struct filenamelist *) reserve_mem (sizeof (struct filenamelist));
  888.       p = p->next;
  889.       p->next = NULL;
  890.       p->name = strcpy ((char*) reserve_mem(strlen (file_info.ff_name)+1),
  891.                 file_info.ff_name);
  892.       complete_length += strlen (file_info.ff_name) + 1;
  893.       new_argc++;
  894.       ende = findnext (&file_info);
  895.     }
  896.     }
  897.  
  898.     /* Jetzt die aufgebaute Liste in ein Array vom Typ char *[] verwandeln */
  899.     /* Achtung: Letzter Pointer muß NULL-Pointer sein! */
  900.     new_argv = (char **) reserve_mem ((new_argc+1) * sizeof (char*));
  901.     new_argv[0] = (*argv)[0];
  902.     new_argv_index = 1;
  903.     p = first->next;
  904.     while (p)
  905.     {
  906.       new_argv [new_argv_index++] = p->name;
  907.       p = p->next;
  908.     }
  909.     new_argv [new_argv_index] = NULL; /* Am Ende der Argumentliste muß ein NULL-Pointer stehen */
  910.     *argc = new_argc;
  911.     *argv = new_argv;
  912.     /* Jetzt temporäre Liste freigeben! */
  913.     p = first;
  914.     while (p)
  915.     {
  916.       q = p->next;
  917.       free (p);
  918.       p = q;
  919.     }
  920.   }
  921. }
  922. #endif
  923.  
  924.  
  925.  
  926. /*****************************************************************************
  927. *
  928. *  Funktion       parameter verarbeiten (hndl_params)
  929. *  --------
  930. *
  931. *  Parameter    : argc         :
  932. *                   Typ          : int
  933. *                   Wertebereich : 1 - maxint
  934. *                   Bedeutung    : Anzahl der Parameter
  935. *
  936. *                 argv         :
  937. *                   Typ          : char **
  938. *                   Wertebereich : Pointer auf Array von Pointer auf
  939. *                                  Parametern
  940. *                   Bedeutung    : 1. Parameter: Programmname
  941. *                                  restliche Parameter: zu edierende Dateien
  942. *
  943. *                 anz_files    :
  944. *                   Typ          : int
  945. *                   Wertebereich : 0 - maxint
  946. *                   Bedeutung    : Anzahl der schon eingelesenen Dateien
  947. *
  948. *  Beschreibung : Die Kommandozeilenparameter werden als Filenamen interpre-
  949. *                 tiert und in den Editor geladen.
  950. *                 Konnten keine Files geladen werden, so wird das Programm
  951. *                 abgebrochen.
  952. *
  953. *****************************************************************************/
  954.  
  955. void hndl_params(argc,argv,anz_files)
  956. int argc,anz_files;
  957. char **argv;
  958. {
  959. #ifdef OS2                  /* OS/2 stellt _wildcard zur Verfügung, */
  960.   _wildcard (&argc, &argv); /* um Patterns zu expandieren */
  961. #else
  962.   do_wildcard_expansion (&argc, &argv);
  963. #endif
  964.   if(argc>1)   /* Wurden Parameter angegeben ? */
  965.   {
  966.     while(--argc) /* Fuer jeden Parameter ein Fenster oeffnen */
  967.     {
  968.       if (koppel_win())
  969.       {
  970.     akt_winp->filename = save_text(argv[argc]);
  971.     if(!lies_file()) /* und versuchen, die Datei zu laden */
  972.     {
  973.       free(akt_winp->dummyp);
  974.       gb_win_frei(); /* klappt das nicht, Fenster wieder schliessen */
  975.     }
  976.     else
  977.     {
  978.       anz_files++;   /* Sonst Anzahl der geladenen Files erhoehen */
  979.       open_window(); /* und Fenster initialisieren */
  980.     }
  981.       }
  982.       else /* Konnte Fenster nicht geoeffnet werden, Fehlermeldung */
  983.       {
  984.     print_err(W_COUNT_ERRTEXT);
  985.     break;
  986.       }
  987.     }
  988.     if(!anz_files) /* Wenn keines der angegebenen Files geladen werden  */
  989.     {              /* konnte, Fehlermeldung ausgeben und Editor beenden */
  990.       print_stat(PROMPT_NO_FILE);
  991.       wart_ret();
  992.       ende(0, TRUE);
  993.     }
  994.     setz_cursor(W_AKT);  /* falls letzte Datei nicht geladen werden konnte, */
  995.   }                 /* wird kein setz_cursor gemacht */
  996.   else              /* Wurden keine Parameter angegeben und konnte    */
  997.     if(!anz_files && !laden()) /* kein File geladen werden, versuchen */
  998.       ende(0, TRUE);   /* Dateinamen vom User zu holen. Falls Fehler, Ende */
  999. }
  1000.  
  1001.  
  1002. /*****************************************************************************
  1003. *
  1004. *  Funktion       main (main)
  1005. *  --------
  1006. *
  1007. *  Parameter    : argc         :
  1008. *                   Typ          : int
  1009. *                   Wertebereich : 1 - maxint
  1010. *                   Bedeutung    : Anzahl der Parameter
  1011. *
  1012. *  Parameter    : argv         :
  1013. *                   Typ          : char **
  1014. *                   Wertebereich : Pointer auf Array von Pointer auf
  1015. *                                  Parametern
  1016. *                   Bedeutung    : 1. Parameter: Programmname
  1017. *                                  restliche Parameter: zu edierende Dateien
  1018. *
  1019. *  Beschreibung : main() startet den Editor und enthaelt die Hauptschleife, die
  1020. *                 einen Befehl holt und diesen ausfuehrt, bis das Programm
  1021. *                 beendet werden soll.
  1022. *
  1023. *****************************************************************************/
  1024.  
  1025. int main (argc,argv)
  1026. int argc;
  1027. char **argv;
  1028. {
  1029.   init();  /* Tastaturbelegung laden, Variablen initialisieren, Umgebungs- */
  1030.        /* variable bearbeiten, Signale abfangen, Curses initialisieren */
  1031.   hndl_params(argc,argv,read_config(argc)); /* Config-Datei lesen und Para-*/
  1032.                         /* meter auswerten             */
  1033.   while (1)
  1034.     auswertung (aktcode = taste(akt_winp->winp)); /* Tastenkombination lesen */
  1035. }                                                 /* und auswerten           */
  1036.