home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / TC-300 / EXAMPLES / GREP2MSG.C < prev    next >
C/C++ Source or Header  |  1992-02-17  |  9KB  |  259 lines

  1. /*
  2.    EXAMPLE SOURCE CODE FOR GREP FILTER
  3.  
  4.    Grep2Msg.C
  5.    Copyright (c) 1990, 1991 Borland International, Inc.
  6.    All rights reserved.
  7.  
  8.    Grep2Msg - Message filter from Turbo Grep to Turbo C++ IDE message window
  9.  
  10.    This filter accepts input through the standard input stream, converts
  11.    it and outputs it to the standard output stream.  The streams are linked
  12.    through pipes, such that the input stream is the output from GREP, and
  13.    the output stream is connected to the message window of the Turbo C++ IDE.
  14.    This filter is invoked through the Turbo C++ IDE transfer mechanism as
  15.  
  16.             grep <commands> | grep2msg | TC IDE
  17.  
  18.     Compile using Turbo C++ in the LARGE memory model
  19.  
  20.     tcc -ml grep2msg
  21. */
  22.  
  23. #include <dir.h>
  24. #include <stdlib.h>
  25. #include <fcntl.h>
  26. #include <string.h>
  27. #include <alloc.h>
  28. #include <io.h>
  29. #include <dos.h>
  30. #include "filter.h"
  31.  
  32. #define TRUE  1
  33. #define FALSE 0
  34.  
  35. char     NewFileText[] = "File ";
  36. unsigned BufSize,CurBufLen;
  37. char     *InBuffer,
  38.          *OutBuffer,
  39.          *CurInPtr,
  40.          *CurOutPtr,
  41.          *LinePtr;
  42. char     Line[133];
  43. long int InOff;
  44. char     EndMark;
  45. int      NoLines;
  46.  
  47. /************************************************************************
  48. Function  : NextChar
  49. Parameters: None
  50. Returns   : next character in input buffer or 0 for end of file
  51.  
  52. Input from the standard input stream is buffered in a global buffer InBuffer
  53. which is allocated in function main.  NextChar function will return
  54. the next character in the buffer, reading from the input stream when the
  55. buffer becomes empty.
  56. ************************************************************************/
  57. char NextChar(void)
  58. {
  59.    if (CurInPtr < InBuffer+CurBufLen)   /* if buffer is not empty */
  60.    {
  61.       return *(CurInPtr++);             /* return next information */
  62.    }
  63.    else
  64.    {
  65.       CurInPtr = InBuffer;              /* reset pointer to front of buffer */
  66.       lseek(0,InOff,0);                 /* seek to the next section for read */
  67.       InOff += BufSize;                 /* increment pointer to next block */
  68.       if ((CurBufLen = read(0,InBuffer,BufSize)) !=0)
  69.          return NextChar();             /* recursive call returns first
  70.                                            character in buffer after read */
  71.       return 0;                         /* return 0 on end of file */
  72.    }
  73. }
  74.  
  75. /*************************************************************************
  76. Function  : flushOut
  77. Parameters: Size   The number of characters to be written out
  78. Returns   : nothing
  79.  
  80. Strings to be sent to the message window are placed in a buffer called
  81. OutBuffer.  A call to this function will write Size bytes to the
  82. standard output stream and reset the output buffer pointer to the
  83. beginning of the buffer.  Any additional information in the buffer is
  84. thus lost.
  85. **************************************************************************/
  86. void flushOut(unsigned Size)
  87. {
  88.   if (Size != 0)                 /* don't flush an empty buffer */
  89.   {
  90.     CurOutPtr = OutBuffer;       /* reset pointer to beginning of buffer */
  91.     lseek(1,0,2);                /* seek output stream to end */
  92.     write(1,OutBuffer,Size);     /* write out Size bytes */
  93.   }
  94. }
  95.  
  96. /**************************************************************************
  97. Function  : Put
  98. Parameters: S     pointer to a string of characters
  99.             Len   length of the string of characters
  100. Returns   : Nothing.
  101.  
  102. Put places bytes into OutBuffer so they may be later flushed out into the
  103. standard output stream using flushOut.
  104. *************************************************************************/
  105. void Put(char *S,int Len)
  106. {
  107.   int i;
  108.  
  109.   for (i = 0; i < Len; i++)
  110.   {
  111.     *CurOutPtr++ = S[i];                     /* place byte in buffer */
  112.     if (CurOutPtr >= OutBuffer+BufSize)      /* if buffer overflows */
  113.       flushOut(BufSize);                     /* flush to the stream */
  114.   }
  115. }
  116.  
  117. /**************************************************************************
  118. Function  : ProcessLine
  119. Parameters: Line   a pointer to the character line to be analyzed
  120. Returns   : Nothing.
  121.  
  122. Filters lines output from grep into a format usable in the Turbo C++
  123. environment message window.  Lines are simply sent straight through
  124. with format characters for the message window.
  125. **************************************************************************/
  126. void ProcessLine(char *Line)
  127. {
  128.   char Type;
  129.   unsigned i;
  130.   char *s;
  131.  
  132.   if (Line[0] == 0)                            /* ignore blank line */
  133.     return;
  134.  
  135.   /* check for new file name */
  136.   if (strncmp(Line,NewFileText,strlen(NewFileText)) == 0)
  137.   {
  138.     if (NoLines)                             /* if no lines from last file */
  139.     {
  140.       Type = MsgNewLine;                     /* put some space in window */
  141.       i = 1;
  142.       Put(&Type,1);
  143.       Put((char *)&i,2);
  144.       Put((char *)&i,2);
  145.       Put(" ",2);
  146.     }
  147.     Type = MsgNewFile;                       /* indicate new file */
  148.     Line[strlen(Line)-1] = 0;                /* remove ":" */
  149.     memmove(Line,&Line[strlen(NewFileText)],strlen(Line));
  150.     Put(&Type,1);
  151.     Put(Line,strlen(Line)+1);                /* write filename */
  152.     NoLines = TRUE;
  153.   }
  154.   else
  155.   {
  156.     NoLines = FALSE;                         /* message lines output */
  157.     Type = MsgNewLine;                       /* new line in message window */
  158.     s = strchr(Line,' ');
  159.     if (s != NULL)
  160.     {
  161.       s++;
  162.       if (strncmp(s,"lines match",11) == 0)  /* special case lines matching */
  163.       {
  164.         i = 1;
  165.         Put(&Type,1);                        /* output two newlines */
  166.         Put((char *)&i,2);
  167.         Put((char *)&i,2);                   /* to message window */
  168.         Put(Line,strlen(Line)+1);            /* and the line */
  169.       }
  170.       else
  171.       {
  172.         s--;
  173.         *s = 0;
  174.         i = atoi(Line);
  175.         *s = ' ';
  176.         if (i != 0)
  177.         {
  178.           Put(&Type,1);
  179.           Put((char *)&i,2);                 /* output line number */
  180.           i = 1;                             /* Column */
  181.           Put((char *)&i,2);                 /* set column over */
  182.           s++;
  183.           memmove(Line,s,strlen(s)+1);
  184.           while (Line[0] == ' ' && Line[0] != 0)  /* strip leading spaces */
  185.             memmove(Line,&Line[1],strlen(Line));  /* from remaining line */
  186.           Put(Line,strlen(Line)+1);               /* and put out the line */
  187.         }
  188.       }
  189.     }
  190.   }
  191. }
  192.  
  193. /************************************************************************
  194. Function  : Main
  195.  
  196. Returns   : zero on successful execution
  197.                3 on an error condition
  198.  
  199. The main routine allocates memory for the input and output buffers.
  200. Characters are then read from the input buffer building the line buffer
  201. that will be sent to the filter processor.  Lines are read and filtered
  202. until the end of input is reached.
  203. ************************************************************************/
  204. int main(void)
  205. {
  206.    char c;
  207.    int i, Type;
  208.    unsigned long core;
  209.  
  210.    setmode(1,O_BINARY);               /* set standard out to binary mode */
  211.    NoLines = FALSE;                   /* No lines have been read yet */
  212.    core = farcoreleft();              /* get available memory */
  213.    if (core > 64000U)                 /* limit buffers to total of 64000 */
  214.       BufSize = 64000U;               /* bytes */
  215.    else
  216.       BufSize = (unsigned)core;
  217.    if ((InBuffer = malloc(BufSize)) == NULL) /* allocate buffer space */
  218.       exit(3);                        /* abort if error occured */
  219.    CurInPtr = InBuffer;               /* split buffer */
  220.    BufSize = BufSize/2;               /* between input and output buffers */
  221.    OutBuffer = InBuffer + BufSize;
  222.    CurOutPtr = OutBuffer;
  223.    LinePtr = Line;                    /* set line buffer pointer */
  224.    CurBufLen = 0;                     /* and reset buffer size to zero */
  225.    Put(PipeId,PipeIdLen);             /* Identify process to message window */
  226.    while ((c = NextChar()) != 0)      /* read characters */
  227.    {
  228.       if ((c == 13) || (c == 10))     /* build line until new line is seen */
  229.       {
  230.          *LinePtr = 0;
  231.          ProcessLine(Line);           /* then filter the line */
  232.          LinePtr = Line;
  233.       }
  234.       /* characters are added to line only up to 132 characters */
  235.       else if ((FP_OFF(LinePtr) - FP_OFF(&Line)) < 132)
  236.       {
  237.          *LinePtr = c;
  238.          LinePtr++;
  239.       }
  240.    }
  241.    *LinePtr = 0;
  242.    ProcessLine(Line);                  /* filter last line */
  243.    if (NoLines)                        /* if no lines */
  244.    {
  245.       Type = MsgNewLine;               /* send something to the */
  246.       i = 1;                           /* message window */
  247.       Put((char *)&Type,1);
  248.       Put((char *)&i,2);
  249.       Put((char *)&i,2);
  250.       Put(" ",2);
  251.    }
  252.    EndMark = MsgEoFile;                /* indicate end of input to */
  253.    Put(&EndMark,1);                    /* message window */
  254.    flushOut((unsigned)(CurOutPtr-OutBuffer));  /* flush out remaining buffer */
  255.  
  256.    return  0;                          /* everything went ok */
  257. }
  258.  
  259.