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