258 lines
9.0 KiB
C
258 lines
9.0 KiB
C
/*
|
||
EXAMPLE SOURCE CODE FOR GREP FILTER
|
||
|
||
Grep2Msg.C
|
||
Copyright (c) 1990 Borland International, Inc.
|
||
All rights reserved.
|
||
|
||
Grep2Msg - Message filter from Turbo Grep to Turbo C++ IDE message window
|
||
|
||
This filter accepts input through the standard input stream, converts
|
||
it and outputs it to the standard output stream. The streams are linked
|
||
through pipes, such that the input stream is the output from GREP, and
|
||
the output stream is connected to the message window of the Turbo C++ IDE.
|
||
This filter is invoked through the Turbo C++ IDE transfer mechanism as
|
||
|
||
grep <commands> | grep2msg | TC IDE
|
||
|
||
Compile using Turbo C++ in the LARGE memory model
|
||
|
||
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;
|
||
|
||
/************************************************************************
|
||
Function : NextChar
|
||
Parameters: None
|
||
Returns : next character in input buffer or 0 for end of file
|
||
|
||
Input from the standard input stream is buffered in a global buffer InBuffer
|
||
which is allocated in function main. NextChar function will return
|
||
the next character in the buffer, reading from the input stream when the
|
||
buffer becomes empty.
|
||
************************************************************************/
|
||
char NextChar(void)
|
||
{
|
||
if (CurInPtr < InBuffer+CurBufLen) /* if buffer is not empty */
|
||
{
|
||
return *(CurInPtr++); /* return next information */
|
||
}
|
||
else
|
||
{
|
||
CurInPtr = InBuffer; /* reset pointer to front of buffer */
|
||
lseek(0,InOff,0); /* seek to the next section for read */
|
||
InOff += BufSize; /* increment pointer to next block */
|
||
if ((CurBufLen = read(0,InBuffer,BufSize)) !=0)
|
||
return NextChar(); /* recursive call returns first
|
||
character in buffer after read */
|
||
return 0; /* return 0 on end of file */
|
||
}
|
||
}
|
||
|
||
/*************************************************************************
|
||
Function : flushOut
|
||
Parameters: Size The number of characters to be written out
|
||
Returns : nothing
|
||
|
||
Strings to be sent to the message window are placed in a buffer called
|
||
OutBuffer. A call to this function will write Size bytes to the
|
||
standard output stream and reset the output buffer pointer to the
|
||
beginning of the buffer. Any additional information in the buffer is
|
||
thus lost.
|
||
**************************************************************************/
|
||
void flushOut(unsigned Size)
|
||
{
|
||
if (Size != 0) /* don't flush an empty buffer */
|
||
{
|
||
CurOutPtr = OutBuffer; /* reset pointer to beginning of buffer */
|
||
lseek(1,0,2); /* seek output stream to end */
|
||
write(1,OutBuffer,Size); /* write out Size bytes */
|
||
}
|
||
}
|
||
|
||
/**************************************************************************
|
||
Function : Put
|
||
Parameters: S pointer to a string of characters
|
||
Len length of the string of characters
|
||
Returns : Nothing.
|
||
|
||
Put places bytes into OutBuffer so they may be later flushed out into the
|
||
standard output stream using flushOut.
|
||
*************************************************************************/
|
||
void Put(char *S,int Len)
|
||
{
|
||
int i;
|
||
|
||
for (i = 0; i < Len; i++)
|
||
{
|
||
*CurOutPtr++ = S[i]; /* place byte in buffer */
|
||
if (CurOutPtr >= OutBuffer+BufSize) /* if buffer overflows */
|
||
flushOut(BufSize); /* flush to the stream */
|
||
}
|
||
}
|
||
|
||
/**************************************************************************
|
||
Function : ProcessLine
|
||
Parameters: Line a pointer to the character line to be analyzed
|
||
Returns : Nothing.
|
||
|
||
Filters lines output from grep into a format usable in the Turbo C++
|
||
environment message window. Lines are simply sent straight through
|
||
with format characters for the message window.
|
||
**************************************************************************/
|
||
void ProcessLine(char *Line)
|
||
{
|
||
char Type;
|
||
unsigned i;
|
||
char *s;
|
||
|
||
if (Line[0] == 0) /* ignore blank line */
|
||
return;
|
||
|
||
/* check for new file name */
|
||
if (strncmp(Line,NewFileText,strlen(NewFileText)) == 0)
|
||
{
|
||
if (NoLines) /* if no lines from last file */
|
||
{
|
||
Type = MsgNewLine; /* put some space in window */
|
||
i = 1;
|
||
Put(&Type,1);
|
||
Put((char *)&i,2);
|
||
Put((char *)&i,2);
|
||
Put(" ",2);
|
||
}
|
||
Type = MsgNewFile; /* indicate new file */
|
||
Line[strlen(Line)-1] = 0; /* remove ":" */
|
||
memmove(Line,&Line[strlen(NewFileText)],strlen(Line));
|
||
Put(&Type,1);
|
||
Put(Line,strlen(Line)+1); /* write filename */
|
||
NoLines = TRUE;
|
||
}
|
||
else
|
||
{
|
||
NoLines = FALSE; /* message lines output */
|
||
Type = MsgNewLine; /* new line in message window */
|
||
s = strchr(Line,' ');
|
||
if (s != NULL)
|
||
{
|
||
s++;
|
||
if (strncmp(s,"lines match",11) == 0) /* special case lines matching */
|
||
{
|
||
i = 1;
|
||
Put(&Type,1); /* output two newlines */
|
||
Put((char *)&i,2);
|
||
Put((char *)&i,2); /* to message window */
|
||
Put(Line,strlen(Line)+1); /* and the line */
|
||
}
|
||
else
|
||
{
|
||
s--;
|
||
*s = 0;
|
||
i = atoi(Line);
|
||
*s = ' ';
|
||
if (i != 0)
|
||
{
|
||
Put(&Type,1);
|
||
Put((char *)&i,2); /* output line number */
|
||
i = 1; /* Column */
|
||
Put((char *)&i,2); /* set column over */
|
||
s++;
|
||
memmove(Line,s,strlen(s)+1);
|
||
while (Line[0] == ' ' && Line[0] != 0) /* strip leading spaces */
|
||
memmove(Line,&Line[1],strlen(Line)); /* from remaining line */
|
||
Put(Line,strlen(Line)+1); /* and put out the line */
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
Function : Main
|
||
|
||
Returns : zero on successful execution
|
||
3 on an error condition
|
||
|
||
The main routine allocates memory for the input and output buffers.
|
||
Characters are then read from the input buffer building the line buffer
|
||
that will be sent to the filter processor. Lines are read and filtered
|
||
until the end of input is reached.
|
||
************************************************************************/
|
||
int main(void)
|
||
{
|
||
char c;
|
||
int i, Type;
|
||
unsigned long core;
|
||
|
||
setmode(1,O_BINARY); /* set standard out to binary mode */
|
||
NoLines = FALSE; /* No lines have been read yet */
|
||
core = farcoreleft(); /* get available memory */
|
||
if (core > 64000U) /* limit buffers to total of 64000 */
|
||
BufSize = 64000U; /* bytes */
|
||
else
|
||
BufSize = (unsigned)core;
|
||
if ((InBuffer = malloc(BufSize)) == NULL) /* allocate buffer space */
|
||
exit(3); /* abort if error occured */
|
||
CurInPtr = InBuffer; /* split buffer */
|
||
BufSize = BufSize/2; /* between input and output buffers */
|
||
OutBuffer = InBuffer + BufSize;
|
||
CurOutPtr = OutBuffer;
|
||
LinePtr = Line; /* set line buffer pointer */
|
||
CurBufLen = 0; /* and reset buffer size to zero */
|
||
Put(PipeId,PipeIdLen); /* Identify process to message window */
|
||
while ((c = NextChar()) != 0) /* read characters */
|
||
{
|
||
if ((c == 13) || (c == 10)) /* build line until new line is seen */
|
||
{
|
||
*LinePtr = 0;
|
||
ProcessLine(Line); /* then filter the line */
|
||
LinePtr = Line;
|
||
}
|
||
/* characters are added to line only up to 132 characters */
|
||
else if ((FP_OFF(LinePtr) - FP_OFF(&Line)) < 132)
|
||
{
|
||
*LinePtr = c;
|
||
LinePtr++;
|
||
}
|
||
}
|
||
*LinePtr = 0;
|
||
ProcessLine(Line); /* filter last line */
|
||
if (NoLines) /* if no lines */
|
||
{
|
||
Type = MsgNewLine; /* send something to the */
|
||
i = 1; /* message window */
|
||
Put((char *)&Type,1);
|
||
Put((char *)&i,2);
|
||
Put((char *)&i,2);
|
||
Put(" ",2);
|
||
}
|
||
EndMark = MsgEoFile; /* indicate end of input to */
|
||
Put(&EndMark,1); /* message window */
|
||
flushOut((unsigned)(CurOutPtr-OutBuffer)); /* flush out remaining buffer */
|
||
|
||
return 0; /* everything went ok */
|
||
}
|
||
|