test.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:11k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: test.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:27:14  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #include <ncbi_pch.hpp>
  10. #include <corelib/ncbiapp.hpp>
  11. #include <corelib/ncbienv.hpp>
  12. #include <serial/strbuffer.hpp>
  13. USING_NCBI_SCOPE;
  14. class CTest : public CNcbiApplication
  15. {
  16. public:
  17.     int Run(void);
  18. };
  19. int main(int argc, char** argv)
  20. {
  21.     return CTest().AppMain(argc, argv);
  22. }
  23. inline
  24. bool FirstIdChar(char c)
  25. {
  26.     return isalpha(c) || c == '_';
  27. }
  28. inline
  29. bool IdChar(char c)
  30. {
  31.     return isalnum(c) || c == '_' || c == '.';
  32. }
  33. inline
  34. void SkipEndOfLine(CStreamBuffer& b, char lastChar)
  35. {
  36.     b.SkipEndOfLine(lastChar);
  37. }
  38. void SkipComments(CStreamBuffer& b)
  39. {
  40.     ERR_POST("SkipComments @ " << b.GetLine());
  41.     try {
  42.         for ( ;; ) {
  43.             char c = b.GetChar();
  44.             switch ( c ) {
  45.             case 'r':
  46.             case 'n':
  47.                 SkipEndOfLine(b, c);
  48.                 ERR_POST("-SkipComments @ " << b.GetLine());
  49.                 return;
  50.             case '-':
  51.                 c = b.GetChar();
  52.                 switch ( c ) {
  53.                 case 'r':
  54.                 case 'n':
  55.                     SkipEndOfLine(b, c);
  56.                     ERR_POST("-SkipComments @ " << b.GetLine());
  57.                     return;
  58.                 case '-':
  59.                     ERR_POST("-SkipComments @ " << b.GetLine());
  60.                     return;
  61.                 }
  62.                 continue;
  63.             default:
  64.                 continue;
  65.             }
  66.         }
  67.     }
  68.     catch ( CSerialEofException& /* ignored */ ) {
  69.         ERR_POST("-SkipComments @ " << b.GetLine());
  70.         return;
  71.     }
  72. }
  73. #if 1
  74. #undef ERR_POST
  75. #define ERR_POST(m)
  76. #endif
  77. char SkipWhiteSpace(CStreamBuffer& b)
  78. {
  79.     ERR_POST("SkipWhiteSpaceAndGetChar @ " << b.GetLine());
  80.     for ( ;; ) {
  81. char c = b.SkipSpaces();
  82.         switch ( c ) {
  83.         case 't':
  84.             b.SkipChar();
  85.             continue;
  86.         case 'r':
  87.         case 'n':
  88.             b.SkipChar();
  89.             SkipEndOfLine(b, c);
  90.             continue;
  91.         case '-':
  92.             // check for comments
  93.             if ( b.PeekChar(1) != '-' ) {
  94.                 ERR_POST("-SkipWhiteSpaceAndGetChar @ " << b.GetLine());
  95.                 return '-';
  96.             }
  97.             b.SkipChars(2);
  98.             // skip comments
  99.             SkipComments(b);
  100.             continue;
  101.         default:
  102.             ERR_POST("-SkipWhiteSpaceAndGetChar @ " << b.GetLine());
  103.             return c;
  104.         }
  105.     }
  106. }
  107. inline
  108. char SkipWhiteSpaceAndGetChar(CStreamBuffer& b)
  109. {
  110.     char c = SkipWhiteSpace(b);
  111.     b.SkipChar();
  112.     return c;
  113. }
  114. inline
  115. void UngetNonWhiteSpace(CStreamBuffer& b, char c)
  116. {
  117.     switch ( c ) {
  118.     case ' ':
  119.     case 't':
  120.         break;
  121.     case 'r':
  122.     case 'n':
  123.         SkipEndOfLine(b, c);
  124.         break;
  125.     default:
  126.         b.UngetChar();
  127.         break;
  128.     }
  129. }
  130. size_t ReadId(CStreamBuffer& b)
  131. {
  132.     ERR_POST("ReadId @ " << b.GetLine());
  133.     char c = SkipWhiteSpace(b);
  134.     if ( c == '[' ) {
  135.         for ( size_t i = 1; ; ++i ) {
  136.             switch ( b.PeekChar(i) ) {
  137.             case 'r':
  138.             case 'n':
  139.                 b.UngetChar();
  140.                 THROW1_TRACE(runtime_error, "end of line: expected ']'");
  141.                 break;
  142.             case ']':
  143.                 b.SkipChars(i + 1);
  144.                 ERR_POST("-ReadId @ " << b.GetLine());
  145.                 return i;
  146.             }
  147.         }
  148.     }
  149. else {
  150.         if ( !FirstIdChar(c) ) {
  151.             ERR_POST("-ReadId @ " << b.GetLine());
  152.             return 0;
  153.         }
  154.         else {
  155.             for ( size_t i = 1; ; ++i ) {
  156.                 c = b.PeekChar(i);
  157.                 if ( !IdChar(c) &&
  158.                      (c != '-' || !IdChar(b.PeekChar(i + 1))) ) {
  159.                     b.SkipChars(i);
  160.                     ERR_POST("-ReadId @ " << b.GetLine());
  161.                     return i;
  162.                 }
  163.             }
  164.         }
  165. }
  166. }
  167. void ReadNumber(CStreamBuffer& b)
  168. {
  169.     char c = SkipWhiteSpaceAndGetChar(b);
  170.     switch ( c ) {
  171.     case '-':
  172.         c = b.GetChar();
  173.         break;
  174.     case '+':
  175.         c = b.GetChar();
  176.         break;
  177.     }
  178.     if ( c < '0' || c > '9' ) {
  179.         b.UngetChar();
  180.         THROW1_TRACE(runtime_error, "bad number start");
  181.     }
  182.     for (;;) {
  183.         c = b.PeekChar();
  184.         if ( c < '0' || c > '9' ) {
  185.             return;
  186.         }
  187.         b.SkipChar();
  188.     }
  189. }
  190. void ReadString(CStreamBuffer& b)
  191. {
  192.     ERR_POST("ReadStrign @ " << b.GetLine());
  193.     string s;
  194.     s.erase();
  195.     for (;;) {
  196.         char c = b.GetChar();
  197.         switch ( c ) {
  198.         case 'r':
  199.         case 'n':
  200.             SkipEndOfLine(b, c);
  201.             ERR_POST("line: " << b.GetLine());
  202.             continue;
  203.         case '"':
  204.             if ( b.PeekChar() == '"' ) {
  205.                 // double quote -> one quote
  206.                 b.SkipChar();
  207.                 s += '"';
  208.             }
  209.             else {
  210.                 // end of string
  211.                 ERR_POST("-ReadStrign @ " << b.GetLine());
  212.                 return;
  213.             }
  214.             continue;
  215.         default:
  216.             if ( c < ' ' && c >= 0 ) {
  217.                 b.UngetChar();
  218.                 THROW1_TRACE(runtime_error,
  219.                              "bad char in string: " + NStr::IntToString(c));
  220.             }
  221.             else {
  222.                 s += c;
  223.             }
  224.             continue;
  225.         }
  226.     }
  227. }
  228. int GetHexChar(CStreamBuffer& b)
  229. {
  230.     for ( ;; ) {
  231.         char c = b.GetChar();
  232.         if ( c >= '0' && c <= '9' ) {
  233.             return c - '0';
  234.         }
  235.         else if ( c >= 'A' && c <= 'Z' ) {
  236.             return c - 'A' + 10;
  237.         }
  238.         else if ( c >= 'a' && c <= 'z' ) {
  239.             return c - 'a' + 10;
  240.         }
  241.         switch ( c ) {
  242.         case ''':
  243.             return -1;
  244.         case 'r':
  245.         case 'n':
  246.             SkipEndOfLine(b, c);
  247.             ERR_POST("line: " << b.GetLine());
  248.             break;
  249.         default:
  250.             b.UngetChar();
  251.             THROW1_TRACE(runtime_error,
  252.                          string("bad char in octet string: '") + c + "'");
  253.         }
  254.     }
  255. }
  256. pair<size_t, bool> ReadBytes(CStreamBuffer& b, char* dst, size_t length)
  257. {
  258. size_t count = 0;
  259. while ( length-- > 0 ) {
  260.         int c1 = GetHexChar(b);
  261.         if ( c1 < 0 ) {
  262.             return make_pair(count, true);
  263.         }
  264.         int c2 = GetHexChar(b);
  265.         if ( c2 < 0 ) {
  266.             *dst++ = c1 << 4;
  267.             count++;
  268.             return make_pair(count, true);
  269.         }
  270.         else {
  271.             *dst++ = (c1 << 4) | c2;
  272.             count++;
  273.         }
  274. }
  275. return make_pair(count, false);
  276. }
  277. void ReadOctetString(CStreamBuffer& b)
  278. {
  279.     ERR_POST("ReadOctetString @ " << b.GetLine());
  280.     char buffer[1024];
  281.     while ( !ReadBytes(b, buffer, sizeof(buffer)).second ) {
  282.     }
  283.     if ( SkipWhiteSpaceAndGetChar(b) != 'H' ) {
  284.         b.UngetChar();
  285.         THROW1_TRACE(runtime_error, "no tailing 'H' in octet string");
  286.     }
  287.     ERR_POST("-ReadOctentStrign @ " << b.GetLine());
  288. }
  289. void ReadBlock(CStreamBuffer& b);
  290. void ReadValue(CStreamBuffer& b);
  291. void ReadValue(CStreamBuffer& b)
  292. {
  293.     ERR_POST("ReadValue @ " << b.GetLine());
  294.     char c = SkipWhiteSpace(b);
  295.     switch ( c ) {
  296.     case '{':
  297.         b.SkipChar();
  298.         ReadBlock(b);
  299.         break;
  300.     case '-':
  301.         ReadNumber(b);
  302.         break;
  303.     case '[':
  304.         ReadId(b);
  305.         break;
  306.     case ',':
  307.     case '}':
  308.         return;
  309.     case ''':
  310.         b.SkipChar();
  311.         ReadOctetString(b);
  312.         break;
  313.     case '"':
  314.         b.SkipChar();
  315.         ReadString(b);
  316.         break;
  317.     default:
  318.         if ( c >= '0' && c <= '9' ) {
  319.             ReadNumber(b);
  320.         }
  321.         else if ( c >= 'a' && c <= 'z' ) {
  322.             ReadId(b);
  323.             ReadValue(b);
  324.         }
  325.         else if ( c >= 'A' && c <= 'Z' ) {
  326.             ReadId(b);
  327.         }
  328.         break;
  329.     }
  330.     ERR_POST("-ReadValue @ " << b.GetLine());
  331. }
  332. void ReadBlock(CStreamBuffer& b)
  333. {
  334.     ERR_POST("ReadBlock @ " << b.GetLine());
  335.     if ( SkipWhiteSpace(b) == '}' ) {
  336.         b.SkipChar();
  337.         ERR_POST("-ReadBlock @ " << b.GetLine());
  338.         return;
  339.     }
  340.     for (;;) {
  341.         ReadValue(b);
  342.         switch ( SkipWhiteSpaceAndGetChar(b) ) {
  343.         case ',':
  344.             break;
  345.         case '}':
  346.             ERR_POST("-ReadBlock @ " << b.GetLine());
  347.             return;
  348.         default:
  349.             b.UngetChar();
  350.             THROW1_TRACE(runtime_error,
  351.                          string("invalid block char: ") + b.PeekChar());
  352.         }
  353.     }
  354. }
  355. int CTest::Run(void)
  356. {
  357.     CNcbiIstream* in = &NcbiCin;
  358.     enum EType {
  359.         eByteType,
  360.         eCharType,
  361.         eWhiteSpaceType,
  362.         eFullParseType
  363.     } type = eFullParseType;
  364.     for ( size_t i = 1; i < GetArguments().Size(); ++i ) {
  365.         if ( GetArguments()[i] == "-f" )
  366.             type = eFullParseType;
  367.         else if ( GetArguments()[i] == "-w" )
  368.             type = eWhiteSpaceType;
  369.         else if ( GetArguments()[i] == "-c" )
  370.             type = eCharType;
  371.         else if ( GetArguments()[i] == "-b" )
  372.             type = eByteType;
  373.         else {
  374.             CNcbiIstream* fin = new CNcbiIfstream(GetArguments()[i].c_str());
  375.             in = fin;
  376.         }
  377.     }
  378.     CStreamBuffer b(*in);
  379.     try {
  380.         switch ( type ) {
  381.         case eByteType:
  382.             {
  383.                 size_t count = 0;
  384.                 char buffer[8192];
  385.                 for (;;) {
  386.                     in->read(buffer, sizeof(buffer));
  387.                     size_t c = in->gcount();
  388.                     if ( c == 0 )
  389.                         break;
  390.                     count += c;
  391.                 }
  392.                 NcbiCout << count << " chars" << NcbiEndl;
  393.             }
  394.             break;
  395.         case eCharType:
  396.             {
  397.                 size_t count = 0;
  398.                 try {
  399.                     for (;;) {
  400.                         b.GetChar();
  401.                         ++count;
  402.                     }
  403.                 }
  404.                 catch ( CSerialEofException& /*exc*/ ) {
  405.                 }
  406.                 NcbiCout << count << " chars" << NcbiEndl;
  407.             }
  408.             break;
  409.         case eWhiteSpaceType:
  410.             try {
  411.                 for (;;) {
  412.                     SkipWhiteSpaceAndGetChar(b);
  413.                 }
  414.             }
  415.             catch ( CSerialEofException& /*exc*/ ) {
  416.             }
  417.             break;
  418.         case eFullParseType:
  419.             ReadId(b);
  420.             if ( SkipWhiteSpaceAndGetChar(b) != ':' ||
  421.                  b.GetChar() != ':' || b.GetChar() != '=' ) {
  422.                 b.UngetChar();
  423.                 THROW1_TRACE(runtime_error, ""::=" expected");
  424.             }
  425.             ReadValue(b);
  426.             break;
  427.         }
  428.     }
  429.     catch (exception& exc) {
  430.         NcbiCerr << exc.what() << NcbiEndl;
  431.     }
  432.     NcbiCout << b.GetLine() << " lines" << NcbiEndl;
  433.     return 0;
  434. }