home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 4.ddi / EXAMPLES.ZIP / RC2MSG.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  10.8 KB  |  298 lines

  1. /*
  2.    EXAMPLE SOURCE CODE FOR RC FILTER
  3.  
  4.    RC2Msg.C
  5.    Copyright (c) 1991 Borland International, Inc.
  6.    All rights reserved.
  7.  
  8.    RC2Msg - Resource compiler output filter to the 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 the resource
  13.    compiler being invoked, and the output stream is connected to the message
  14.    window of the IDE, ie.
  15.  
  16.           rc fname | rc2msg | IDE message window
  17.  
  18.    Compile using the LARGE memory model.
  19. */
  20.  
  21. #include <dir.h>
  22. #include <dos.h>
  23. #include <stdlib.h>
  24. #include <fcntl.h>
  25. #include <string.h>
  26. #include <alloc.h>
  27. #include <io.h>
  28. #include "filter.h"
  29.  
  30. #define TRUE (1 == 1)
  31. #define FALSE !(TRUE)
  32.  
  33. char     CurFile[MAXPATH];       /* Current file in message window */
  34. unsigned BufSize,                /* Size of internal working buffer */
  35.          CurBufLen;              /* Buffer space in use */
  36. char     *InBuffer,              /* Input buffer */
  37.          *OutBuffer,             /* Output buffer */
  38.          *CurInPtr,              /* current character in input buffer */
  39.          *CurOutPtr,             /* current character in output */
  40.          *LinePtr;               /* pointer to the current character in
  41.                                     the input buffer */
  42. char     Line[133];              /* static buffer to store line most recently
  43.                                     input */
  44. long int InOff;                  /* position in actual input stream */
  45. char     EndMark;                /* Used to output end of data to message
  46.                                     window */
  47.  
  48. /*************************************************************************
  49. Function  : NextChar
  50. Parameters: none
  51. Returns   : next character in input buffer or 0 on end of file
  52.  
  53. Input from the standard input stream is buffered in a global buffer InBuffer
  54. which is allocated in function main.  The function will return
  55. the next character in the buffer, reading from the input stream when the
  56. buffer becomes empty.
  57. **************************************************************************/
  58. char NextChar(void)
  59. {
  60.   if (CurInPtr < InBuffer+CurBufLen)  /* if buffer is not empty */
  61.   {
  62.     return *(CurInPtr++);             /* return next character */
  63.   }
  64.   else
  65.   {
  66.     CurInPtr = InBuffer;              /* reset pointer to front of buffer */
  67.     lseek(0,InOff,0);                 /* seek to the next section for read */
  68.     InOff += BufSize;                 /* increment pointer to next block */
  69.     if ((CurBufLen = read(0,InBuffer,BufSize)) !=0)
  70.       return NextChar();              /* recursive call merely returns
  71.                                          first character in buffer after read */
  72.     return 0;                         /* return 0 on end of file */
  73.   }
  74. }
  75.  
  76. /*************************************************************************
  77. Function  : flushOut
  78. Parameter : Size   The number of characters to be written out
  79. Returns   : nothing
  80.  
  81. Strings to be sent to the message window are buffered in a buffer called
  82. OutBuffer.  A call to this function will write out Size bytes from OutBuffer
  83. to the standard output stream and resets the output buffer pointer to the
  84. beginning of the buffer.  The output buffer is considered empty after a call
  85. to this function.
  86. *************************************************************************/
  87. void flushOut(unsigned Size)
  88. {
  89.    if (Size != 0)                /* don't flush an empty buffer */
  90.    {
  91.       CurOutPtr = OutBuffer;     /* reset pointer to beginning of buffer */
  92.       lseek(1,0,2);              /* seek output stream to end */
  93.       write(1,OutBuffer,Size);   /* write out Size bytes */
  94.    }
  95. }
  96.  
  97. /************************************************************************
  98. Function  : Put
  99. Parameters: S    pointer to bytes being put into output buffer
  100.             Len  number of bytes to be put in output buffer
  101. Returns   : nothing
  102.  
  103. Put places bytes into OutBuffer so they may be later flushed out into
  104. the standard output stream.
  105. ************************************************************************/
  106. void Put(char *S,int Len)
  107. {
  108.    int i;
  109.  
  110.    for (i = 0; i < Len; i++)
  111.    {
  112.       *CurOutPtr++ = S[i];                   /* place byte in buffer */
  113.       if (CurOutPtr >= OutBuffer+BufSize)    /* if buffer overflows */
  114.          flushOut(BufSize);                  /* flush the buffer */
  115.    }
  116. }
  117.  
  118.  
  119. /************************************************************************
  120. Function  : ProcessLine
  121. Parameters: Line  a pointer to the current line of characters to process
  122. Returns   : nothing
  123.  
  124. Analyze line to determine if it is an error message.  If so, output
  125. relevant information to the message window.
  126.  
  127. To be considered an error message, a line must NOT :
  128.    . be blank
  129.    . start with "Microsoft" or "Copyright" (these lines form the Resource
  130.         Compiler header)
  131.  
  132. Any lines passing the above conditions are considered error messages.
  133. If the line contains a line number, it is of the form:
  134.  
  135.    source-file(LINE #) : message text        OR
  136.    source-file (LINE #) : message text
  137.  
  138.      that is, it contains a '(' followed by a ':'.  The line number
  139.      is sent to the Message Window followed by the message text.
  140.  
  141. If the line does not contain a line number, it is sent verbatim to 
  142. the Message Window.
  143. ************************************************************************/
  144. void ProcessLine(char *Line)
  145. {
  146.    static int HavePutFile = FALSE;
  147.    int        HasLineNumber;
  148.    char       Type;
  149.    unsigned   i;
  150.    char       *s, *LeftParen, *Colon;
  151.  
  152.    /* if blank line, return */
  153.    while( *Line && ( (*Line == '\r') || (*Line == '\n') ) )
  154.      Line++;
  155.    if( *Line == '\0' )
  156.      return;
  157.  
  158.    /* if line starts with "Microsoft" or "Copyright", it's not
  159.       an error line */
  160.  
  161.    if( strncmp( Line, "Microsoft", 9 ) == 0 ||
  162.        strncmp( Line, "Copyright", 9 ) == 0 )
  163.  
  164.      return;
  165.  
  166.  
  167.    HasLineNumber = FALSE;
  168.    LeftParen = strchr( Line, '(' );       /* if '(' in the line */
  169.    if( LeftParen != NULL )                /* Line may contain line number */
  170.      HasLineNumber = TRUE;
  171.  
  172.    if( HasLineNumber ) {
  173.      Colon = strchr(LeftParen, ':' );     /* if no ':' following the '(' */
  174.      if( Colon == NULL )                  /* Line doesn't contain line number */
  175.        HasLineNumber = FALSE;
  176.    }
  177.  
  178.    if( HasLineNumber ) {
  179.      s = LeftParen-1;                       /* position s after last char */
  180.      while( *s == ' ' )                     /* in filename */
  181.        s--;
  182.      s++;
  183.      *s = 0;                                /* and null-terminate */
  184.  
  185.      if( strcmp(Line,CurFile) != 0 )        /* if new filename */
  186.      {
  187.     Type = MsgNewFile;                  /* indicate by sending type
  188.                            out to message window */
  189.     strcpy(CurFile,Line);
  190.     Put(&Type,1);
  191.     Put(CurFile,strlen(CurFile)+1);     /* along with the new name */
  192.     HavePutFile = TRUE;
  193.      }
  194.  
  195.      s = strchr(Line,')');                   /* find the right paren */
  196.      *s = 0;                                 /* and null-terminate line# */
  197.      i = atoi(LeftParen+1);                  /* line# starts after ( */
  198.                          /* convert line# to integer */
  199.  
  200.      Type = MsgNewLine;                      /* set type to new line */
  201.      Put(&Type,1);                           /* indicate need for new line */
  202.      Put((char *)&i,2);                      /* put the number out */
  203.      i=1;                                    /* set column in message box */
  204.      Put((char *)&i,2);                      /* tab over to put message */
  205.  
  206.      s = Colon+1;                            /* position s at first */
  207.      while( *s == ' ' )                      /* non-blank char after : */
  208.        s++;                                  /* Rest of line is message */
  209.  
  210.      Put( s,strlen(s)+1);                    /* output the message */
  211.    }
  212.    else {                                    /* no line number */
  213.      if( !HavePutFile )
  214.      {
  215.     /* IDE expects the first message to
  216.        be preceded by a filename.  Since
  217.        we don't have one, fake it by
  218.        sending a NULL file before the
  219.        message.
  220.     */
  221.     Type = MsgNewFile;                  /* indicate by sending type
  222.                            out to message window */
  223.     *CurFile = '\0';
  224.     Put(&Type,1);
  225.     Put(CurFile,1);                     /* along with null filename */
  226.     HavePutFile = TRUE;
  227.      }
  228.  
  229.      Type = MsgNewLine;                      /* Fake line # etc. */
  230.      i    = 1;
  231.      Put(&Type,1);
  232.      Put((char *)&i,2);
  233.      Put((char *)&i,2);
  234.      Put(Line,strlen(Line)+1);
  235.    }
  236. }
  237.  
  238.  
  239.  
  240. /***********************************************************************
  241. Function  : main
  242.  
  243. Returns   : zero for successful execution
  244.         3    if an error is encountered
  245.  
  246. The main routine allocates buffers for the input and output buffer.
  247. Characters are then read from the input buffer building the line buffer
  248. that will be sent to the filter processor.  Lines are read and filtered
  249. until the end of input is reached.
  250. ***********************************************************************/
  251. int main( void )
  252. {
  253.    char c;
  254.    unsigned long core;
  255.  
  256.    setmode(1,O_BINARY);               /* set output stream to binary mode */
  257.    core = farcoreleft();
  258.    if (core > 64000U)
  259.       BufSize = 64000U;
  260.    else BufSize = (unsigned)core;     /* get available memory */
  261.                                       /* stay under 64K */
  262.    if ((CurInPtr = malloc(BufSize)) == NULL) /* allocate buffer space */
  263.       exit(3);
  264. #if 0
  265.    processor = NULL;                  /* set current processor to none */
  266. #endif
  267.  
  268.    InBuffer = CurInPtr;               /* input buffer is first half of space */
  269.    BufSize = BufSize/2;               /* output buffer is 2nd half */
  270.    OutBuffer = InBuffer + BufSize;
  271.    CurOutPtr = OutBuffer;             /* set buffer pointers */
  272.    LinePtr = Line;
  273.    CurBufLen = 0;
  274.    Put(PipeId,PipeIdLen);             /* send ID string to message window */
  275.    while ((c = NextChar()) != 0)      /* read characters */
  276.    {
  277.       if ((c == 13) || (c == 10))     /* build until line end */
  278.       {
  279.          *LinePtr = 0;
  280.          ProcessLine(Line);           /* filter the line */
  281.          LinePtr = Line;
  282.       }
  283.       /* characters are added to buffer up to 132 characters max */
  284.       else if ((FP_OFF(LinePtr) - FP_OFF(&Line)) < 132)
  285.       {
  286.          *LinePtr = c;                /* add to line buffer */
  287.          LinePtr++;
  288.       }
  289.    }
  290.    *LinePtr = 0;
  291.    ProcessLine(Line);                 /* filter last line */
  292.    EndMark = MsgEoFile;
  293.    Put(&EndMark,1);                   /* indicate end of input to
  294.                                          the message window */
  295.    flushOut((unsigned)(CurOutPtr-OutBuffer));     /* flush the buffer */
  296.    return 0;                          /* return OK */
  297. }
  298.