[PATCH 2 4/7] programs/cmd/tests: added support for multi-line input

Eric Pouech eric.pouech at gmail.com
Wed Feb 2 11:38:48 CST 2022


- added a @more@ keyword to detect the 'More?' localized string
  (first occurence is stored, when all subsequent occurences are
  compared against the stored value)
- some basic tests

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 programs/cmd/tests/batch.c                      |   47 +++++++++++++++++++++++
 programs/cmd/tests/interactive_builtins.cmd     |   24 ++++++++++++
 programs/cmd/tests/interactive_builtins.cmd.exp |   36 ++++++++++++++++++
 programs/cmd/wcmdmain.c                         |    7 +++
 4 files changed, 114 insertions(+)

diff --git a/programs/cmd/tests/batch.c b/programs/cmd/tests/batch.c
index 0d6832df30f..bcaeb0190ac 100644
--- a/programs/cmd/tests/batch.c
+++ b/programs/cmd/tests/batch.c
@@ -30,6 +30,8 @@ static char path[MAX_PATH];
 static DWORD path_len;
 static char shortpath[MAX_PATH];
 static DWORD shortpath_len;
+static char more[MAX_PATH];
+static DWORD more_len;
 
 /* Convert to DOS line endings, and substitute escaped whitespace chars with real ones */
 static const char* convert_input_data(const char *data, DWORD size, DWORD *new_size)
@@ -164,6 +166,31 @@ static DWORD map_file(const char *file_name, const char **ret)
     return size;
 }
 
+static const char *compare_line(const char *out_line, const char *out_end, const char *exp_line,
+                                const char *exp_end);
+
+static BOOL guess_string(const char *out_ptr, const char *out_end,
+                         const char *exp_ptr, const char *exp_end,
+                         char* storage, DWORD* storage_len)
+{
+    /* as some output depends on locale (like 'More? ', 'Are you sure (Y|N)? '...), try to guess its value from first input */
+    const char* out_try = out_ptr;
+    if (exp_ptr == exp_end)
+    {
+        *storage_len = min(out_end - out_ptr, MAX_PATH);
+        memcpy(storage, out_ptr, *storage_len);
+        return TRUE;
+    }
+    while (out_try < out_end)
+    {
+        storage[(*storage_len)++] = *out_try++;
+        if (compare_line(out_try, out_end, exp_ptr, exp_end) == NULL)
+            return TRUE;
+    }
+    *storage_len = 0;
+    return FALSE;
+}
+
 static const char *compare_line(const char *out_line, const char *out_end, const char *exp_line,
         const char *exp_end)
 {
@@ -174,6 +201,7 @@ static const char *compare_line(const char *out_line, const char *out_end, const
     static const char drive_cmd[] = {'@','d','r','i','v','e','@'};
     static const char path_cmd[]  = {'@','p','a','t','h','@'};
     static const char shortpath_cmd[]  = {'@','s','h','o','r','t','p','a','t','h','@'};
+    static const char more_cmd[]  = {'@','m','o','r','e','@'};
     static const char space_cmd[] = {'@','s','p','a','c','e','@'};
     static const char spaces_cmd[] = {'@','s','p','a','c','e','s','@'};
     static const char tab_cmd[]   = {'@','t','a','b','@'};
@@ -225,6 +253,25 @@ static const char *compare_line(const char *out_line, const char *out_end, const
                     out_ptr += shortpath_len;
                     continue;
                 }
+            } else if(exp_ptr+sizeof(more_cmd) <= exp_end
+                    && !memcmp(exp_ptr, more_cmd, sizeof(more_cmd))) {
+                exp_ptr += sizeof(more_cmd);
+                if (!more_len)
+                {
+                    if (guess_string(out_ptr, out_end, exp_ptr, exp_end, more, &more_len))
+                    {
+                        trace("match @more@ with [%.*s]\n", more_len, more);
+                        return NULL;
+                    }
+                    err = out_ptr;
+                }else if(out_end-out_ptr < more_len
+                   || (CompareStringA(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
+                                      out_ptr, more_len, more, more_len) != CSTR_EQUAL)) {
+                    err = out_ptr;
+                }else {
+                    out_ptr += more_len;
+                    continue;
+                }
             }else if(exp_ptr+sizeof(space_cmd) <= exp_end
                     && !memcmp(exp_ptr, space_cmd, sizeof(space_cmd))) {
                 exp_ptr += sizeof(space_cmd);
diff --git a/programs/cmd/tests/interactive_builtins.cmd b/programs/cmd/tests/interactive_builtins.cmd
index d1e308f159a..f5ab45d7bb1 100644
--- a/programs/cmd/tests/interactive_builtins.cmd
+++ b/programs/cmd/tests/interactive_builtins.cmd
@@ -1,8 +1,32 @@
 @echo --------- testing echo
 echo foo
 @echo foo
+if exist c:\windows (
+  echo bar
+)
+ at if exist c:\windows (
+  echo bar
+)
+if exist c:\windows (
+  @echo bar
+)
+ at if exist c:\windows (
+  @echo bar
+)
 echo off
 echo foo
 @echo foo
+if exist c:\windows (
+  echo bar
+)
+ at if exist c:\windows (
+  echo bar
+)
+if exist c:\windows (
+  @echo bar
+)
+ at if exist c:\windows (
+  @echo bar
+)
 echo --------- done
 exit 0
diff --git a/programs/cmd/tests/interactive_builtins.cmd.exp b/programs/cmd/tests/interactive_builtins.cmd.exp
index 64482e85c04..4280ec186c9 100644
--- a/programs/cmd/tests/interactive_builtins.cmd.exp
+++ b/programs/cmd/tests/interactive_builtins.cmd.exp
@@ -7,11 +7,47 @@ foo
 @pwd@>@echo foo
 foo
 
+ at pwd@>if exist c:\windows (
+ at more@  echo bar
+ at more@)
+bar
+
+ at pwd@>@if exist c:\windows (
+ at more@  echo bar
+ at more@)
+bar
+
+ at pwd@>if exist c:\windows (
+ at more@  @echo bar
+ at more@)
+bar
+
+ at pwd@>@if exist c:\windows (
+ at more@  @echo bar
+ at more@)
+bar
+
 @pwd@>echo off
 echo foo
 foo
 @echo foo
 foo
+if exist c:\windows (
+ at more@  echo bar
+ at more@)
+bar
+ at if exist c:\windows (
+ at more@  echo bar
+ at more@)
+bar
+if exist c:\windows (
+ at more@  @echo bar
+ at more@)
+bar
+ at if exist c:\windows (
+ at more@  @echo bar
+ at more@)
+bar
 echo --------- done
 --------- done
 exit 0
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index ee863856ec9..286dc6b9ff0 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -2315,6 +2315,13 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
           if (!WCMD_fgets(extraData, MAXSTRING, readFrom))
             break;
 
+          /* echo input stream if naturally not echoed */
+          if (!context && !optionalcmd && GetFileType(readFrom) != FILE_TYPE_CHAR)
+          {
+              WCMD_output_asis(extraData);
+              WCMD_output_asis(L"\r\n");
+          }
+
           /* Edge case for carets - a completely blank line (i.e. was just
              CRLF) is oddly added as an LF but then more data is received (but
              only once more!) */




More information about the wine-devel mailing list