home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / tcpp / examples / grep2msg.c < prev    next >
Text File  |  1990-06-09  |  9KB  |  260 lines

  1. /*
  2.    BEISPIELQUELLCODE FÜR DAS GREP FILTERPROGRAMM
  3.  
  4.    Grep2Msg.C
  5.    Copyright (c) 1990 Borland International, Inc.
  6.    Alle Rechte vorbehalten.
  7.  
  8.    Grep2Msg - Nachrichtenfilter von Turbo Grep zum Turbo C++
  9.               IDE-Nachrichtenfenster (message window)
  10.  
  11.    Dieser Filter akzeptiert Eingaben über den Standard-Eingabe-Stream,
  12.    konvertiert sie und gibt sie über den Standard-Ausgabe-Stream aus.
  13.    Die Streams sind über Pipes miteinander verbunden: der
  14.    Eingabe-Stream ist die Ausgabe von GREP, und der Ausgabe-Stream ist
  15.    mit dem Nachrichtenfenster der Turbo C++ Entwicklungsumgebung
  16.    verbunden. Der Filter wird mit folgendem Befehl aufgerufen:
  17.  
  18.             grep <commands> | grep2msg | TC IDE
  19.  
  20.     Kompiliert wird mit Turbo C++'s Speichermodell LARGE:
  21.  
  22.     tcc -ml grep2msg
  23. */
  24.  
  25. #include <dir.h>
  26. #include <stdlib.h>
  27. #include <fcntl.h>
  28. #include <string.h>
  29. #include <alloc.h>
  30. #include <io.h>
  31. #include <dos.h>
  32. #include "filter.h"
  33.  
  34. #define TRUE  1
  35. #define FALSE 0
  36.  
  37. char     NewFileText[] = "File ";
  38. unsigned BufSize,CurBufLen;
  39. char     *InBuffer,
  40.          *OutBuffer,
  41.          *CurInPtr,
  42.          *CurOutPtr,
  43.          *LinePtr;
  44. char     Line[133];
  45. long int InOff;
  46. char     EndMark;
  47. int      NoLines;
  48.  
  49. /************************************************************************
  50. Funktion  : NextChar
  51. Parameter : Keine
  52. Rückgabe  : nächstes Zeichen im Eingabepuffer oder 0 für Dateiende
  53.  
  54. Eingaben der Standard-Eingabe werden im globalen Puffer InBuffer, für den
  55. in main Speicher reserviert wird, abgelegt. NextChar gibt das nächste Zeichen
  56. des Puffers zurück und liest von der Standard-Eingabe, wenn der Puffer
  57. leer ist.
  58. ************************************************************************/
  59. char NextChar(void)
  60. {
  61.    if (CurInPtr < InBuffer+CurBufLen)   /* der Puffer ist nicht leer */
  62.    {
  63.       return *(CurInPtr++);             /* die nächste Information */
  64.    }
  65.    else
  66.    {
  67.       CurInPtr = InBuffer;              /* Pointer auf Pufferbeginn setzen */
  68.       lseek(0,InOff,0);                 /* Nächsten Leseabschnitt suchen */
  69.       InOff += BufSize;                 /* Pointer zeigt auf nächsten Block */
  70.       if ((CurBufLen = read(0,InBuffer,BufSize)) !=0)
  71.          return NextChar();             /* Rekursiver Aufruf gibt das erste
  72.                                            Zeichen im Puffer zurück */
  73.       return 0;                         /* Gibt 0 bei Dateiende zurück */
  74.    }
  75. }
  76.  
  77. /*************************************************************************
  78. Funktion  : flushOut
  79. Parameter : Size   Die Anzahl der Zeichen, die geschrieben werden
  80. Rückgabe  : nichts
  81.  
  82. Strings, die zum Nachrichtenfenster geschickt werden, stehen im Puffer
  83. OutBuffer. Ein Aufruf dieser Funktion bewirkt, daß Size Bytes an die
  84. Standard-Ausgabe geschrieben werden; der Pointer auf den Ausgabepuffer wird
  85. auf den Beginn des Puffers zurückgesetzt. Jede weitere Information im Puffer
  86. geht daher verloren.
  87. **************************************************************************/
  88. void flushOut(unsigned Size)
  89. {
  90.   if (Size != 0)                 /* Keinen leeren Puffer weitergeben */
  91.   {
  92.     CurOutPtr = OutBuffer;       /* Pointer auf Pufferbeginn zurücksetzen */
  93.     lseek(1,0,2);                /* Ausgabe bis zum Ende absuchen */
  94.     write(1,OutBuffer,Size);     /* Size (Anzahl der Bytes) ausgeben */
  95.   }
  96. }
  97.  
  98. /**************************************************************************
  99. Funktion  : Put
  100. Parameter : S     Pointer auf einen Zeichenstring
  101.             Len   Länge des Strings in Zeichen
  102. Rückgabe  : nichts
  103.  
  104. Put schreibt Zeichen in den OutBuffer, die dann später mit flushOut zur
  105. Standardausgabe weitergegeben werden.
  106. *************************************************************************/
  107. void Put(char *S,int Len)
  108. {
  109.   int i;
  110.  
  111.   for (i = 0; i < Len; i++)
  112.   {
  113.     *CurOutPtr++ = S[i];                /* Ein Byte in den Puffer schreiben */
  114.     if (CurOutPtr >= OutBuffer+BufSize) /* Wenn der Puffer voll ist, Inhalt */
  115.       flushOut(BufSize);                /* zur Standard-Ausgabe geben */
  116.   }
  117. }
  118.  
  119. /**************************************************************************
  120. Funktion  : ProcessLine
  121. Parameter : Line   Pointer auf die Zeile, die analysiert wird
  122. Returns   : nichts
  123.  
  124. Konvertiert Zeilen, die von GREP kommen, in das Format des Turbo C++
  125. Nachrichtenfensters. Die Zeilen werden einfach weitergegeben, ergänzt
  126. durch Formatierungszeichen für das Nachrichtenfenster.
  127. **************************************************************************/
  128. void ProcessLine(char *Line)
  129. {
  130.   char Type;
  131.   unsigned i;
  132.   char *s;
  133.  
  134.   if (Line[0] == 0)                            /* Leerzeilen ignorieren */
  135.     return;
  136.  
  137.   /* check for new file name */
  138.   if (strncmp(Line,NewFileText,strlen(NewFileText)) == 0)
  139.   {
  140.     if (NoLines)                            /* Keine Zeilen aus der letzten */
  141.     {
  142.       Type = MsgNewLine;                    /* Datei: Leerzeichen ausgeben */
  143.       i = 1;
  144.       Put(&Type,1);
  145.       Put((char *)&i,2);
  146.       Put((char *)&i,2);
  147.       Put(" ",2);
  148.     }
  149.     Type = MsgNewFile;                       /* Neue Datei */
  150.     Line[strlen(Line)-1] = 0;                /* ":" entfernen */
  151.     memmove(Line,&Line[strlen(NewFileText)],strlen(Line));
  152.     Put(&Type,1);
  153.     Put(Line,strlen(Line)+1);                /* Dateinamen schreiben */
  154.     NoLines = TRUE;
  155.   }
  156.   else
  157.   {
  158.     NoLines = FALSE;
  159.     Type = MsgNewLine;                      /* neue Zeile im Nachrichtenfenster */
  160.     s = strchr(Line,' ');
  161.     if (s != NULL)
  162.     {
  163.       s++;
  164.       if (strncmp(s,"lines match",11) == 0) /* Spezialfall: Zeilen stimmen */
  165.       {                                     /* überein */
  166.         i = 1;
  167.         Put(&Type,1);                        /* 2 Zeilen ausgeben */
  168.         Put((char *)&i,2);
  169.         Put((char *)&i,2);                   /* zum Nachrichtenfenster */
  170.         Put(Line,strlen(Line)+1);
  171.       }
  172.       else
  173.       {
  174.         s--;
  175.         *s = 0;
  176.         i = atoi(Line);
  177.         *s = ' ';
  178.         if (i != 0)
  179.         {
  180.           Put(&Type,1);
  181.           Put((char *)&i,2);                 /* Ausgabe Zeilennummer */
  182.           i = 1;                             /* Spalte */
  183.           Put((char *)&i,2);
  184.           s++;
  185.           memmove(Line,s,strlen(s)+1);
  186.           while (Line[0] == ' ' && Line[0] != 0)  /* Führende Leerzeichen  */
  187.             memmove(Line,&Line[1],strlen(Line));  /* aus der Zeile entfer- */
  188.           Put(Line,strlen(Line)+1);               /* nen, Zeile ausgeben   */
  189.         }
  190.       }
  191.     }
  192.   }
  193. }
  194.  
  195. /************************************************************************
  196. Funktion  : main
  197.  
  198. Rückgabe  : 0, falls erfolgreich
  199.             3, falls ein Fehler aufgetreten ist
  200.  
  201. Die Routine main reserviert Speicher für die Ein-/Ausgabe-Puffer. Zeichen
  202. werden aus dem Eingabe-Puffer gelesen und in den Zeilen-Puffer geschrieben,
  203. der zum Filter geschickt wird. Die Zeilen werden gelesen und gefiltert, bis
  204. das Eingabeende erreicht ist.
  205. ************************************************************************/
  206. int main(void)
  207. {
  208.    char c;
  209.    int i, Type;
  210.    unsigned long core;
  211.  
  212.    setmode(1,O_BINARY);               /* Standard ist Binär-Modus */
  213.    NoLines = FALSE;                   /* Noch keine Zeilen gelesen */
  214.    core = farcoreleft();              /* freien Speicher bestimmen */
  215.    if (core > 64000U)                 /* Puffer auf max. 64000 Bytes be- */
  216.       BufSize = 64000U;               /* grenzen */
  217.    else
  218.       BufSize = (unsigned)core;
  219.    if ((InBuffer = malloc(BufSize)) == NULL) /* Pufferspeicher reservieren */
  220.       exit(3);                      /* Abbruch bei Fehler */
  221.    CurInPtr = InBuffer;             /* Puffer zwischen Eingabe- und */
  222.    BufSize = BufSize/2;             /* ausgabe-Puffer aufteilen */
  223.    OutBuffer = InBuffer + BufSize;
  224.    CurOutPtr = OutBuffer;
  225.    LinePtr = Line;                  /* Pointer des Zeilenpuffers init. */
  226.    CurBufLen = 0;                   /* und Puffer auf Null zurücksetzen */
  227.    Put(PipeId,PipeIdLen);           /* Mitteilung an das Nachrichtenfenster */
  228.    while ((c = NextChar()) != 0)    /* Zeichen lesen */
  229.    {
  230.       if ((c == 13) || (c == 10))   /* Zeile aufbauen, bis NeueZeile kommt */
  231.       {
  232.          *LinePtr = 0;
  233.          ProcessLine(Line);         /* dann die Zeile filtern */
  234.          LinePtr = Line;
  235.       }
  236.       /* Nur bis zu 132 Zeichen werden in eine Zeile geschrieben */
  237.       else if ((FP_OFF(LinePtr) - FP_OFF(&Line)) < 132)
  238.       {
  239.          *LinePtr = c;
  240.          LinePtr++;
  241.       }
  242.    }
  243.    *LinePtr = 0;
  244.    ProcessLine(Line);                  /* Letzte Zeile bearbeiten */
  245.    if (NoLines)                        /* Wenn keine Zeilen: */
  246.    {
  247.       Type = MsgNewLine;               /* irgendwas an das Nachrichten- */
  248.       i = 1;                           /* fenster schicken */
  249.       Put((char *)&Type,1);
  250.       Put((char *)&i,2);
  251.       Put((char *)&i,2);
  252.       Put(" ",2);
  253.    }
  254.    EndMark = MsgEoFile;                /* Mitteilung über das Eingabeende */
  255.    Put(&EndMark,1);                    /* an das Nachrichtenfenster */
  256.    flushOut((unsigned)(CurOutPtr-OutBuffer));  /* Restpuffer weitergeben */
  257.  
  258.    return  0;                          /* Alles ist gut gegangen */
  259. }
  260.