home *** CD-ROM | disk | FTP | other *** search
- /*
- BEISPIELQUELLCODE FÜR DAS GREP FILTERPROGRAMM
-
- Grep2Msg.C
- Copyright (c) 1990 Borland International, Inc.
- Alle Rechte vorbehalten.
-
- Grep2Msg - Nachrichtenfilter von Turbo Grep zum Turbo C++
- IDE-Nachrichtenfenster (message window)
-
- Dieser Filter akzeptiert Eingaben über den Standard-Eingabe-Stream,
- konvertiert sie und gibt sie über den Standard-Ausgabe-Stream aus.
- Die Streams sind über Pipes miteinander verbunden: der
- Eingabe-Stream ist die Ausgabe von GREP, und der Ausgabe-Stream ist
- mit dem Nachrichtenfenster der Turbo C++ Entwicklungsumgebung
- verbunden. Der Filter wird mit folgendem Befehl aufgerufen:
-
- grep <commands> | grep2msg | TC IDE
-
- Kompiliert wird mit Turbo C++'s Speichermodell LARGE:
-
- tcc -ml grep2msg
- */
-
- #include <dir.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <string.h>
- #include <alloc.h>
- #include <io.h>
- #include <dos.h>
- #include "filter.h"
-
- #define TRUE 1
- #define FALSE 0
-
- char NewFileText[] = "File ";
- unsigned BufSize,CurBufLen;
- char *InBuffer,
- *OutBuffer,
- *CurInPtr,
- *CurOutPtr,
- *LinePtr;
- char Line[133];
- long int InOff;
- char EndMark;
- int NoLines;
-
- /************************************************************************
- Funktion : NextChar
- Parameter : Keine
- Rückgabe : nächstes Zeichen im Eingabepuffer oder 0 für Dateiende
-
- Eingaben der Standard-Eingabe werden im globalen Puffer InBuffer, für den
- in main Speicher reserviert wird, abgelegt. NextChar gibt das nächste Zeichen
- des Puffers zurück und liest von der Standard-Eingabe, wenn der Puffer
- leer ist.
- ************************************************************************/
- char NextChar(void)
- {
- if (CurInPtr < InBuffer+CurBufLen) /* der Puffer ist nicht leer */
- {
- return *(CurInPtr++); /* die nächste Information */
- }
- else
- {
- CurInPtr = InBuffer; /* Pointer auf Pufferbeginn setzen */
- lseek(0,InOff,0); /* Nächsten Leseabschnitt suchen */
- InOff += BufSize; /* Pointer zeigt auf nächsten Block */
- if ((CurBufLen = read(0,InBuffer,BufSize)) !=0)
- return NextChar(); /* Rekursiver Aufruf gibt das erste
- Zeichen im Puffer zurück */
- return 0; /* Gibt 0 bei Dateiende zurück */
- }
- }
-
- /*************************************************************************
- Funktion : flushOut
- Parameter : Size Die Anzahl der Zeichen, die geschrieben werden
- Rückgabe : nichts
-
- Strings, die zum Nachrichtenfenster geschickt werden, stehen im Puffer
- OutBuffer. Ein Aufruf dieser Funktion bewirkt, daß Size Bytes an die
- Standard-Ausgabe geschrieben werden; der Pointer auf den Ausgabepuffer wird
- auf den Beginn des Puffers zurückgesetzt. Jede weitere Information im Puffer
- geht daher verloren.
- **************************************************************************/
- void flushOut(unsigned Size)
- {
- if (Size != 0) /* Keinen leeren Puffer weitergeben */
- {
- CurOutPtr = OutBuffer; /* Pointer auf Pufferbeginn zurücksetzen */
- lseek(1,0,2); /* Ausgabe bis zum Ende absuchen */
- write(1,OutBuffer,Size); /* Size (Anzahl der Bytes) ausgeben */
- }
- }
-
- /**************************************************************************
- Funktion : Put
- Parameter : S Pointer auf einen Zeichenstring
- Len Länge des Strings in Zeichen
- Rückgabe : nichts
-
- Put schreibt Zeichen in den OutBuffer, die dann später mit flushOut zur
- Standardausgabe weitergegeben werden.
- *************************************************************************/
- void Put(char *S,int Len)
- {
- int i;
-
- for (i = 0; i < Len; i++)
- {
- *CurOutPtr++ = S[i]; /* Ein Byte in den Puffer schreiben */
- if (CurOutPtr >= OutBuffer+BufSize) /* Wenn der Puffer voll ist, Inhalt */
- flushOut(BufSize); /* zur Standard-Ausgabe geben */
- }
- }
-
- /**************************************************************************
- Funktion : ProcessLine
- Parameter : Line Pointer auf die Zeile, die analysiert wird
- Returns : nichts
-
- Konvertiert Zeilen, die von GREP kommen, in das Format des Turbo C++
- Nachrichtenfensters. Die Zeilen werden einfach weitergegeben, ergänzt
- durch Formatierungszeichen für das Nachrichtenfenster.
- **************************************************************************/
- void ProcessLine(char *Line)
- {
- char Type;
- unsigned i;
- char *s;
-
- if (Line[0] == 0) /* Leerzeilen ignorieren */
- return;
-
- /* check for new file name */
- if (strncmp(Line,NewFileText,strlen(NewFileText)) == 0)
- {
- if (NoLines) /* Keine Zeilen aus der letzten */
- {
- Type = MsgNewLine; /* Datei: Leerzeichen ausgeben */
- i = 1;
- Put(&Type,1);
- Put((char *)&i,2);
- Put((char *)&i,2);
- Put(" ",2);
- }
- Type = MsgNewFile; /* Neue Datei */
- Line[strlen(Line)-1] = 0; /* ":" entfernen */
- memmove(Line,&Line[strlen(NewFileText)],strlen(Line));
- Put(&Type,1);
- Put(Line,strlen(Line)+1); /* Dateinamen schreiben */
- NoLines = TRUE;
- }
- else
- {
- NoLines = FALSE;
- Type = MsgNewLine; /* neue Zeile im Nachrichtenfenster */
- s = strchr(Line,' ');
- if (s != NULL)
- {
- s++;
- if (strncmp(s,"lines match",11) == 0) /* Spezialfall: Zeilen stimmen */
- { /* überein */
- i = 1;
- Put(&Type,1); /* 2 Zeilen ausgeben */
- Put((char *)&i,2);
- Put((char *)&i,2); /* zum Nachrichtenfenster */
- Put(Line,strlen(Line)+1);
- }
- else
- {
- s--;
- *s = 0;
- i = atoi(Line);
- *s = ' ';
- if (i != 0)
- {
- Put(&Type,1);
- Put((char *)&i,2); /* Ausgabe Zeilennummer */
- i = 1; /* Spalte */
- Put((char *)&i,2);
- s++;
- memmove(Line,s,strlen(s)+1);
- while (Line[0] == ' ' && Line[0] != 0) /* Führende Leerzeichen */
- memmove(Line,&Line[1],strlen(Line)); /* aus der Zeile entfer- */
- Put(Line,strlen(Line)+1); /* nen, Zeile ausgeben */
- }
- }
- }
- }
- }
-
- /************************************************************************
- Funktion : main
-
- Rückgabe : 0, falls erfolgreich
- 3, falls ein Fehler aufgetreten ist
-
- Die Routine main reserviert Speicher für die Ein-/Ausgabe-Puffer. Zeichen
- werden aus dem Eingabe-Puffer gelesen und in den Zeilen-Puffer geschrieben,
- der zum Filter geschickt wird. Die Zeilen werden gelesen und gefiltert, bis
- das Eingabeende erreicht ist.
- ************************************************************************/
- int main(void)
- {
- char c;
- int i, Type;
- unsigned long core;
-
- setmode(1,O_BINARY); /* Standard ist Binär-Modus */
- NoLines = FALSE; /* Noch keine Zeilen gelesen */
- core = farcoreleft(); /* freien Speicher bestimmen */
- if (core > 64000U) /* Puffer auf max. 64000 Bytes be- */
- BufSize = 64000U; /* grenzen */
- else
- BufSize = (unsigned)core;
- if ((InBuffer = malloc(BufSize)) == NULL) /* Pufferspeicher reservieren */
- exit(3); /* Abbruch bei Fehler */
- CurInPtr = InBuffer; /* Puffer zwischen Eingabe- und */
- BufSize = BufSize/2; /* ausgabe-Puffer aufteilen */
- OutBuffer = InBuffer + BufSize;
- CurOutPtr = OutBuffer;
- LinePtr = Line; /* Pointer des Zeilenpuffers init. */
- CurBufLen = 0; /* und Puffer auf Null zurücksetzen */
- Put(PipeId,PipeIdLen); /* Mitteilung an das Nachrichtenfenster */
- while ((c = NextChar()) != 0) /* Zeichen lesen */
- {
- if ((c == 13) || (c == 10)) /* Zeile aufbauen, bis NeueZeile kommt */
- {
- *LinePtr = 0;
- ProcessLine(Line); /* dann die Zeile filtern */
- LinePtr = Line;
- }
- /* Nur bis zu 132 Zeichen werden in eine Zeile geschrieben */
- else if ((FP_OFF(LinePtr) - FP_OFF(&Line)) < 132)
- {
- *LinePtr = c;
- LinePtr++;
- }
- }
- *LinePtr = 0;
- ProcessLine(Line); /* Letzte Zeile bearbeiten */
- if (NoLines) /* Wenn keine Zeilen: */
- {
- Type = MsgNewLine; /* irgendwas an das Nachrichten- */
- i = 1; /* fenster schicken */
- Put((char *)&Type,1);
- Put((char *)&i,2);
- Put((char *)&i,2);
- Put(" ",2);
- }
- EndMark = MsgEoFile; /* Mitteilung über das Eingabeende */
- Put(&EndMark,1); /* an das Nachrichtenfenster */
- flushOut((unsigned)(CurOutPtr-OutBuffer)); /* Restpuffer weitergeben */
-
- return 0; /* Alles ist gut gegangen */
- }