Browse Source

Introduced space-separated read functions: readWords/readTokes, multilines read functions: readStrings/readLines

MikeMirzayanov 7 years ago
parent
commit
19720759c3
1 changed files with 125 additions and 34 deletions
  1. 125 34
      testlib.h

+ 125 - 34
testlib.h

@@ -63,6 +63,7 @@
  */
 
 const char* latestFeatures[] = {
+                          "Introduced space-separated read functions: readWords/readTokes, multilines read functions: readStrings/readLines",
                           "Introduced space-separated read functions: readInts/readIntegers/readLongs/readUnsignedLongs/readDoubles/readReals/readStrictDoubles/readStrictReals",
                           "Introduced split/tokenize functions to separate string by given char",
                           "Introduced InStream::readUnsignedLong and InStream::readLong with unsigned long long paramerters",
@@ -1733,9 +1734,13 @@ struct InStream
     /* The same as "readWord()", but ensures that token matches to given pattern. */
     std::string readWord(const std::string& ptrn, const std::string& variableName = "");
     std::string readWord(const pattern& p, const std::string& variableName = "");
+    std::vector<std::string> readWords(int size, const std::string& ptrn, const std::string& variablesName = "", int indexBase = 1);
+    std::vector<std::string> readWords(int size, const pattern& p, const std::string& variablesName = "", int indexBase = 1);
     /* The same as "readToken()", but ensures that token matches to given pattern. */
     std::string readToken(const std::string& ptrn, const std::string& variableName = "");
     std::string readToken(const pattern& p, const std::string& variableName = "");
+    std::vector<std::string> readTokens(int size, const std::string& ptrn, const std::string& variablesName = "", int indexBase = 1);
+    std::vector<std::string> readTokens(int size, const pattern& p, const std::string& variablesName = "", int indexBase = 1);
 
     void readWordTo(std::string& result);
     void readWordTo(std::string& result, const pattern& p, const std::string& variableName = "");
@@ -1825,12 +1830,18 @@ struct InStream
     
     /* As readLine(). */
     std::string readString();
+    /* Read many lines. */
+    std::vector<std::string> readStrings(int size, int indexBase = 1);
     /* See readLine(). */
     void readStringTo(std::string& result);
     /* The same as "readLine()/readString()", but ensures that line matches to the given pattern. */
     std::string readString(const pattern& p, const std::string& variableName = "");
     /* The same as "readLine()/readString()", but ensures that line matches to the given pattern. */
     std::string readString(const std::string& ptrn, const std::string& variableName = "");
+    /* Read many lines. */
+    std::vector<std::string> readStrings(int size, const pattern& p, const std::string& variableName = "", int indexBase = 1);
+    /* Read many lines. */
+    std::vector<std::string> readStrings(int size, const std::string& ptrn, const std::string& variableName = "", int indexBase = 1);
     /* The same as "readLine()/readString()", but ensures that line matches to the given pattern. */
     void readStringTo(std::string& result, const pattern& p, const std::string& variableName = "");
     /* The same as "readLine()/readString()", but ensures that line matches to the given pattern. */
@@ -1841,12 +1852,18 @@ struct InStream
      * the first character of the new line (if possible). 
      */
     std::string readLine();
+    /* Read many lines. */
+    std::vector<std::string> readLines(int size, int indexBase = 1);
     /* See readLine(). */
     void readLineTo(std::string& result);
     /* The same as "readLine()", but ensures that line matches to the given pattern. */
     std::string readLine(const pattern& p, const std::string& variableName = "");
     /* The same as "readLine()", but ensures that line matches to the given pattern. */
     std::string readLine(const std::string& ptrn, const std::string& variableName = "");
+    /* Read many lines. */
+    std::vector<std::string> readLines(int size, const pattern& p, const std::string& variableName = "", int indexBase = 1);
+    /* Read many lines. */
+    std::vector<std::string> readLines(int size, const std::string& ptrn, const std::string& variableName = "", int indexBase = 1);
     /* The same as "readLine()", but ensures that line matches to the given pattern. */
     void readLineTo(std::string& result, const pattern& p, const std::string& variableName = "");
     /* The same as "readLine()", but ensures that line matches to the given pattern. */
@@ -2579,34 +2596,86 @@ static std::string __testlib_part(const std::string& s)
         return s.substr(0, 30) + "..." + s.substr(s.length() - 31, 31);
 }
 
+#define __testlib_readMany(readMany, readOne, typeName, space)                  \
+    if (size < 0)                                                               \
+        quit(_fail, #readMany ": size should be non-negative.");                \
+    if (size > 100000000)                                                       \
+        quit(_fail, #readMany ": size should be at most 100000000.");           \
+                                                                                \
+    std::vector<typeName> result(size);                                         \
+    readManyIteration = indexBase;                                              \
+                                                                                \
+    for (int i = 0; i < size; i++)                                              \
+    {                                                                           \
+        result[i] = readOne;                                                    \
+        readManyIteration++;                                                    \
+        if (space && i + 1 < size)                                              \
+            readSpace();                                                        \
+    }                                                                           \
+                                                                                \
+    readManyIteration = NO_INDEX;                                               \
+    return result;                                                              \
+
 std::string InStream::readWord(const pattern& p, const std::string& variableName)
 {
     readWordTo(_tmpReadToken);
     if (!p.matches(_tmpReadToken))
     {
-        if (variableName.empty())
-            quit(_wa, ("Token \"" + __testlib_part(_tmpReadToken) + "\" doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+        if (readManyIteration == NO_INDEX)
+        {
+            if (variableName.empty())
+                quit(_wa, ("Token \"" + __testlib_part(_tmpReadToken) + "\" doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+            else
+                quit(_wa, ("Token parameter [name=" + variableName + "] equals to \"" + __testlib_part(_tmpReadToken) + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+        }
         else
-            quit(_wa, ("Token parameter [name=" + variableName + "] equals to \"" + __testlib_part(_tmpReadToken) + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+        {
+            if (variableName.empty())
+                quit(_wa, ("Token element [index=" + vtos(readManyIteration) + "] equals to \"" + __testlib_part(_tmpReadToken) + "\" doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+            else
+                quit(_wa, ("Token element " + variableName + "[" + vtos(readManyIteration) + "] equals to \"" + __testlib_part(_tmpReadToken) + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+        }
     }
     return _tmpReadToken;
 }
 
+std::vector<std::string> InStream::readWords(int size, const pattern& p, const std::string& variablesName, int indexBase)
+{
+    __testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
+}
+
 std::string InStream::readWord(const std::string& ptrn, const std::string& variableName)
 {
     return readWord(pattern(ptrn), variableName);
 }
 
+std::vector<std::string> InStream::readWords(int size, const std::string& ptrn, const std::string& variablesName, int indexBase)
+{
+    pattern p(ptrn);
+    __testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
+}
+
 std::string InStream::readToken(const pattern& p, const std::string& variableName)
 {
     return readWord(p, variableName);
 }
 
+std::vector<std::string> InStream::readTokens(int size, const pattern& p, const std::string& variablesName, int indexBase)
+{
+    __testlib_readMany(readTokens, readToken(p, variablesName), std::string, true);
+}
+
 std::string InStream::readToken(const std::string& ptrn, const std::string& variableName)
 {
     return readWord(ptrn, variableName);
 }
 
+std::vector<std::string> InStream::readTokens(int size, const std::string& ptrn, const std::string& variablesName, int indexBase)
+{
+    pattern p(ptrn);
+    __testlib_readMany(readTokens, readWord(p, variablesName), std::string, true);
+}
+
 void InStream::readWordTo(std::string& result, const pattern& p, const std::string& variableName)
 {
     readWordTo(result);
@@ -2967,29 +3036,9 @@ long long InStream::readLong(long long minv, long long maxv, const std::string&
     return result;
 }
 
-#define __testlib_readMany(readMany, readOne, typeName)                         \
-    if (size < 0)                                                               \
-        quit(_fail, #readMany ": size should be non-negative.");                \
-    if (size > 100000000)                                                       \
-        quit(_fail, #readMany ": size should be at most 100000000.");           \
-                                                                                \
-    std::vector<typeName> result(size);                                         \
-    readManyIteration = indexBase;                                              \
-                                                                                \
-    for (int i = 0; i < size; i++)                                              \
-    {                                                                           \
-        result[i] = readOne;                                                    \
-        readManyIteration++;                                                    \
-        if (i + 1 < size)                                                       \
-            readSpace();                                                        \
-    }                                                                           \
-                                                                                \
-    readManyIteration = NO_INDEX;                                               \
-    return result;                                                              \
-
 std::vector<long long> InStream::readLongs(int size, long long minv, long long maxv, const std::string& variablesName, int indexBase)
 {
-    __testlib_readMany(readLongs, readLong(minv, maxv, variablesName), long long)
+    __testlib_readMany(readLongs, readLong(minv, maxv, variablesName), long long, true)
 }
 
 unsigned long long InStream::readUnsignedLong(unsigned long long minv, unsigned long long maxv, const std::string& variableName)
@@ -3022,7 +3071,7 @@ unsigned long long InStream::readUnsignedLong(unsigned long long minv, unsigned
 
 std::vector<unsigned long long> InStream::readUnsignedLongs(int size, unsigned long long minv, unsigned long long maxv, const std::string& variablesName, int indexBase)
 {
-    __testlib_readMany(readUnsignedLongs, readUnsignedLong(minv, maxv, variablesName), unsigned long long)
+    __testlib_readMany(readUnsignedLongs, readUnsignedLong(minv, maxv, variablesName), unsigned long long, true)
 }
 
 unsigned long long InStream::readLong(unsigned long long minv, unsigned long long maxv, const std::string& variableName)
@@ -3070,12 +3119,12 @@ int InStream::readInteger(int minv, int maxv, const std::string& variableName)
 
 std::vector<int> InStream::readInts(int size, int minv, int maxv, const std::string& variablesName, int indexBase)
 {
-    __testlib_readMany(readInts, readInt(minv, maxv, variablesName), int)
+    __testlib_readMany(readInts, readInt(minv, maxv, variablesName), int, true)
 }
 
 std::vector<int> InStream::readIntegers(int size, int minv, int maxv, const std::string& variablesName, int indexBase)
 {
-    __testlib_readMany(readIntegers, readInt(minv, maxv, variablesName), int)
+    __testlib_readMany(readIntegers, readInt(minv, maxv, variablesName), int, true)
 }
 
 double InStream::readReal()
@@ -3124,7 +3173,7 @@ double InStream::readReal(double minv, double maxv, const std::string& variableN
 
 std::vector<double> InStream::readReals(int size, double minv, double maxv, const std::string& variablesName, int indexBase)
 {
-    __testlib_readMany(readReals, readReal(minv, maxv, variablesName), double)
+    __testlib_readMany(readReals, readReal(minv, maxv, variablesName), double, true)
 }
 
 double InStream::readDouble(double minv, double maxv, const std::string& variableName)
@@ -3134,7 +3183,7 @@ double InStream::readDouble(double minv, double maxv, const std::string& variabl
 
 std::vector<double> InStream::readDoubles(int size, double minv, double maxv, const std::string& variablesName, int indexBase)
 {
-    __testlib_readMany(readDoubles, readDouble(minv, maxv, variablesName), double)
+    __testlib_readMany(readDoubles, readDouble(minv, maxv, variablesName), double, true)
 }
 
 double InStream::readStrictReal(double minv, double maxv,
@@ -3178,7 +3227,7 @@ std::vector<double> InStream::readStrictReals(int size, double minv, double maxv
         int minAfterPointDigitCount, int maxAfterPointDigitCount,
         const std::string& variablesName, int indexBase)
 {
-    __testlib_readMany(readStrictReals, readStrictReal(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName), double)
+    __testlib_readMany(readStrictReals, readStrictReal(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName), double, true)
 }
 
 double InStream::readStrictDouble(double minv, double maxv,
@@ -3194,7 +3243,7 @@ std::vector<double> InStream::readStrictDoubles(int size, double minv, double ma
         int minAfterPointDigitCount, int maxAfterPointDigitCount,
         const std::string& variablesName, int indexBase)
 {
-    __testlib_readMany(readStrictDoubles, readStrictDouble(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName), double)
+    __testlib_readMany(readStrictDoubles, readStrictDouble(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName), double, true)
 }
 
 bool InStream::eof()
@@ -3343,15 +3392,30 @@ std::string InStream::readString()
     return _tmpReadToken;
 }
 
+std::vector<std::string> InStream::readStrings(int size, int indexBase)
+{
+    __testlib_readMany(readStrings, readString(), std::string, false)
+}
+
 void InStream::readStringTo(std::string& result, const pattern& p, const std::string& variableName)
 {
     readStringTo(result);
     if (!p.matches(result))
     {
-        if (variableName.empty())
-            quit(_wa, ("Line \"" + __testlib_part(result) + "\" doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+        if (readManyIteration == NO_INDEX)
+        {
+            if (variableName.empty())
+                quit(_wa, ("Line \"" + __testlib_part(result) + "\" doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+            else
+                quit(_wa, ("Line [name=" + variableName + "] equals to \"" + __testlib_part(result) + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+        }
         else
-            quit(_wa, ("Line [name=" + variableName + "] equals to \"" + __testlib_part(result) + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+        {
+            if (variableName.empty())
+                quit(_wa, ("Line element [index=" + vtos(readManyIteration) + "] equals to \"" + __testlib_part(result) + "\" doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+            else
+                quit(_wa, ("Line element " + std::string(variableName) + "[" + vtos(readManyIteration) + "] equals to \"" + __testlib_part(result) + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str());
+        }
     }
 }
 
@@ -3366,12 +3430,23 @@ std::string InStream::readString(const pattern& p, const std::string& variableNa
     return _tmpReadToken;
 }
 
+std::vector<std::string> InStream::readStrings(int size, const pattern& p, const std::string& variablesName, int indexBase)
+{
+    __testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
+}
+
 std::string InStream::readString(const std::string& ptrn, const std::string& variableName)
 {
     readStringTo(_tmpReadToken, ptrn, variableName);
     return _tmpReadToken;
 }
 
+std::vector<std::string> InStream::readStrings(int size, const std::string& ptrn, const std::string& variablesName, int indexBase)
+{
+    pattern p(ptrn);
+    __testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
+}
+
 void InStream::readLineTo(std::string& result)
 {
     readStringTo(result);
@@ -3382,6 +3457,11 @@ std::string InStream::readLine()
     return readString();
 }
 
+std::vector<std::string> InStream::readLines(int size, int indexBase)
+{
+    __testlib_readMany(readLines, readString(), std::string, false)
+}
+
 void InStream::readLineTo(std::string& result, const pattern& p, const std::string& variableName)
 {
     readStringTo(result, p, variableName);
@@ -3397,11 +3477,22 @@ std::string InStream::readLine(const pattern& p, const std::string& variableName
     return readString(p, variableName);
 }
 
+std::vector<std::string> InStream::readLines(int size, const pattern& p, const std::string& variablesName, int indexBase)
+{
+    __testlib_readMany(readLines, readString(p, variablesName), std::string, false)
+}
+
 std::string InStream::readLine(const std::string& ptrn, const std::string& variableName)
 {
     return readString(ptrn, variableName);
 }
 
+std::vector<std::string> InStream::readLines(int size, const std::string& ptrn, const std::string& variablesName, int indexBase)
+{
+    pattern p(ptrn);
+    __testlib_readMany(readLines, readString(p, variablesName), std::string, false)
+}
+
 void InStream::close()
 {
     if (NULL != reader)