home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR9 / WIZTOO.ZIP / INSTREAM.CPP < prev    next >
C/C++ Source or Header  |  1993-09-20  |  6KB  |  239 lines

  1. //  Module: INSTREAM.CPP
  2.  
  3. //                                                   September 20, 1993
  4. //                                                   Fairfield, Iowa
  5.  
  6. //          Aerosoft  (R)  Broadcast Channel Wizard   Version 1.0
  7. //          Copyright (c)  Aerosoft 1993     All rights reserved.
  8.  
  9. //          This software source code is FREEWARE.  You may be use the
  10. //          source code or redistribute the source code free of charge.
  11. //          However, you cannot sell this source code or any alteration of
  12. //          the source code.
  13.  
  14. //  This module implements the member functions of class InStream.
  15. //  See file BCWIZ.TXT for more details.
  16.  
  17. #include    <stdio.h>
  18. #include    <process.h>
  19. #include    <ctype.h>
  20.  
  21. #include    "INSTREAM.H"
  22.  
  23.  
  24. InStream::InStream (char *cpName)
  25. {
  26.     if ((fid=fopen(cpName, "rt"))==NULL)
  27.     {
  28.         printf("*** Execution error: Can't open file %s. ***\n", cpName);
  29.         exit(0);
  30.     }
  31.  
  32.     iNextCharToRead = 0;
  33.     iParsePoint = 0;
  34.     iLine = 1;
  35.     iColumn = 0;
  36.     iLen = 0;
  37.     iParenDepth = 0;
  38. }
  39.  
  40. void InStream::ResetParsing (void)
  41. {
  42.     iNextCharToRead = 0;
  43.     iParsePoint = 0;
  44.     iLen = 0;
  45.     iParenDepth = 0;
  46.     for (int i=0; i<BUFFSIZE; i++) caBuff[i] = '\0';    // facilitate program testing
  47. }
  48.  
  49. int InStream::ReadyBuffer (int iPoint)
  50. {
  51.     while (iPoint >= iNextCharToRead)
  52.     {
  53.         if (iNextCharToRead >= BUFFSIZE)
  54.         {
  55.             printf("*** Execution error: (%d:%d) Channel spec too long. ***\n",
  56.                         iLine, iColumn);
  57.             exit(0);
  58.         }
  59.  
  60.         if (fread(&caBuff[iNextCharToRead], 1, 1, fid) != 1) return 0;
  61.  
  62.         if (caBuff[iNextCharToRead] == '\n')
  63.         {
  64.             iLine++;
  65.             iColumn = 0;
  66.         }
  67.         else
  68.             iColumn++;
  69.  
  70.         iNextCharToRead++;
  71.     }
  72.  
  73.     return 1;
  74. }
  75.  
  76. static int IsWhiteSpace (char c)
  77. {
  78.     if (c == ' ')   return 1;
  79.     if (c == '\t')  return 1;
  80.     if (c == '\n')  return 1;
  81.     if (c == '\r')  return 1;
  82.  
  83.     return 0;
  84. }
  85.  
  86. static int IsLabel (char c)
  87. {
  88.     if (isalnum(c)) return 1;
  89.     if (c == '_') return 1;
  90.  
  91.     return 0;
  92. }
  93.  
  94. static int IsFirstOfLabel (char c)
  95. {
  96.     if (isalpha(c)) return 1;
  97.     if (c == '_') return 1;
  98.  
  99.     return 0;
  100. }
  101.  
  102. //  Nested parenthesis are removed by an inductive algorithm:
  103. //
  104. //        basis: the first opening parenthesis '(' is not removed.
  105. //             the white-space after the next to last ')' is removed.
  106. //               NOTE: the last closing parenthesis ')' is never seen here.
  107. //
  108. //        induction: advance parse point
  109. //                   SkipNestedParen
  110. int InStream::SkipNestedParen (void)
  111. {
  112.     if (caBuff[iParsePoint] == '(')
  113.     {
  114.         if (++iParenDepth < 2) return 1;
  115.     }    
  116.     else if (caBuff[iParsePoint] == ')')
  117.     {
  118.         if (--iParenDepth < 2)
  119.         {
  120.             // Skip any white-space here
  121.             if (!ReadyBuffer(++iParsePoint)) return 0;
  122.             while (IsWhiteSpace(caBuff[iParsePoint]))
  123.                 if (!ReadyBuffer(++iParsePoint)) return NULL;
  124.                 
  125.             return 1;
  126.         }
  127.     }
  128.         
  129.     if (!ReadyBuffer(++iParsePoint)) return 0;
  130.     return SkipNestedParen();
  131. }    
  132.  
  133. char *InStream::ParseForward (int &iLenArg)
  134. {
  135.     // Advance to 1 past last token
  136.     iParsePoint += iLen;
  137.     if (!ReadyBuffer(iParsePoint)) return NULL;
  138.     
  139.     // Skip any white-space here
  140.     while (IsWhiteSpace(caBuff[iParsePoint]))
  141.         if (!ReadyBuffer(++iParsePoint)) return NULL;
  142.     
  143.     // Keep track of parenthesis nesting.  Once inside a nested parenthesis,
  144.     // skip everything until past the closing parenthesis.
  145.     if (caBuff[iParsePoint] == '(')
  146.            if (!SkipNestedParen()) return NULL;
  147.     
  148.     // Non-label tokens always have lenght=1
  149.     if (!IsFirstOfLabel(caBuff[iParsePoint]))
  150.     {
  151.         iLen = 1;
  152.         iLenArg = 1;
  153.         return &caBuff[iParsePoint];
  154.     }
  155.     
  156.     // Determine length of label token
  157.     int iDelimPoint = iParsePoint+1;
  158.     if (!ReadyBuffer(iDelimPoint)) return NULL;
  159.     while (IsLabel(caBuff[iDelimPoint]))
  160.         if (!ReadyBuffer(++iDelimPoint)) return NULL;
  161.  
  162.     iLen = iDelimPoint - iParsePoint;
  163.     iLenArg = iLen;
  164.  
  165.     return &caBuff[iParsePoint];
  166. }
  167.     
  168. char *InStream::ParseNumber (int &iLenArg)
  169. {
  170.     // Advance to 1 past last token
  171.     iParsePoint += iLen;
  172.     if (!ReadyBuffer(iParsePoint)) return NULL;
  173.     
  174.     // Skip any white-space here
  175.     while (IsWhiteSpace(caBuff[iParsePoint]))
  176.         if (!ReadyBuffer(++iParsePoint)) return NULL;
  177.     
  178.     if (!isdigit(caBuff[iParsePoint]))
  179.     {
  180.         iLen = 0;
  181.         iLenArg = 0;
  182.         return &caBuff[iParsePoint];
  183.     }
  184.         
  185.     // Determine length of number token
  186.     int iDelimPoint = iParsePoint+1;
  187.     if (!ReadyBuffer(iDelimPoint)) return NULL;
  188.     while (isdigit(caBuff[iDelimPoint]))
  189.         if (!ReadyBuffer(++iDelimPoint)) return NULL;
  190.  
  191.     iLen = iDelimPoint - iParsePoint;
  192.     iLenArg = iLen;
  193.  
  194.     return &caBuff[iParsePoint];
  195. }
  196.  
  197. char *InStream::ParseBackward (int &iLenArg)
  198. {
  199.     int iEndPoint = iParsePoint-1;
  200.  
  201.     if (iEndPoint < 0) 
  202.     {
  203.         iLenArg = 0;
  204.         return caBuff;
  205.     }
  206.  
  207.     while (IsWhiteSpace(caBuff[iEndPoint]))
  208.         if (--iEndPoint < 0) 
  209.         {
  210.             iLenArg = 0;
  211.             return caBuff;
  212.         }
  213.  
  214.     if (!IsLabel(caBuff[iEndPoint]))
  215.     {
  216.         iLenArg = 0;
  217.         return &caBuff[iEndPoint];
  218.     }
  219.     
  220.     int iScanPoint = iEndPoint-1;
  221.     if (iScanPoint < 0) 
  222.     {
  223.         iLenArg = iEndPoint-iScanPoint+1;
  224.         return caBuff;
  225.     }
  226.  
  227.     while (IsLabel(caBuff[iScanPoint]))
  228.         if (--iScanPoint < 0) 
  229.         {
  230.             iLenArg = iEndPoint-iScanPoint+1;
  231.             return caBuff;
  232.         }
  233.  
  234.     iLenArg = iEndPoint-iScanPoint;
  235.  
  236.     return &caBuff[iScanPoint+1];
  237. }
  238.  
  239.