ReactOS 0.4.16-dev-927-g467dec4
batch.c File Reference
#include <windows.h>
#include <stdio.h>
#include "wine/test.h"
Include dependency graph for batch.c:

Go to the source code of this file.

Functions

static const charconvert_input_data (const char *data, DWORD size, DWORD *new_size)
 
static BOOL run_cmd (const char *cmd_data, DWORD cmd_size)
 
static DWORD map_file (const char *file_name, const char **ret)
 
static const charcompare_line (const char *out_line, const char *out_end, const char *exp_line, const char *exp_end)
 
static void test_output (const char *out_data, DWORD out_size, const char *exp_data, DWORD exp_size)
 
static void run_test (const char *cmd_data, DWORD cmd_size, const char *exp_data, DWORD exp_size)
 
static void run_from_file (const char *file_name)
 
static DWORD load_resource (const char *name, const char *type, const char **ret)
 
static BOOL WINAPI test_enum_proc (HMODULE module, LPCSTR type, LPSTR name, LONG_PTR param)
 
static int cmd_available (void)
 
 START_TEST (batch)
 

Variables

static char workdir [MAX_PATH]
 
static DWORD workdir_len
 
static char drive [2]
 
static const DWORD drive_len = ARRAY_SIZE(drive)
 
static char path [MAX_PATH]
 
static DWORD path_len
 
static char shortpath [MAX_PATH]
 
static DWORD shortpath_len
 

Function Documentation

◆ cmd_available()

static int cmd_available ( void  )
static

Definition at line 442 of file batch.c.

443{
444 STARTUPINFOA si;
446 char cmd[] = "cmd /c exit 0";
447
448 memset(&si, 0, sizeof(si));
449 si.cb = sizeof(si);
450 if (CreateProcessA(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
451 CloseHandle(pi.hThread);
452 CloseHandle(pi.hProcess);
453 return TRUE;
454 }
455 return FALSE;
456}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4747
static refpint_t pi[]
Definition: server.c:96
#define memset(x, y, z)
Definition: compat.h:39
DWORD cb
Definition: winbase.h:856
Definition: ftp_var.h:139

◆ compare_line()

static const char * compare_line ( const char out_line,
const char out_end,
const char exp_line,
const char exp_end 
)
static

Definition at line 157 of file batch.c.

159{
160 const char *out_ptr = out_line, *exp_ptr = exp_line;
161 const char *err = NULL;
162
163 static const char pwd_cmd[] = {'@','p','w','d','@'};
164 static const char drive_cmd[] = {'@','d','r','i','v','e','@'};
165 static const char path_cmd[] = {'@','p','a','t','h','@'};
166 static const char shortpath_cmd[] = {'@','s','h','o','r','t','p','a','t','h','@'};
167 static const char space_cmd[] = {'@','s','p','a','c','e','@'};
168 static const char spaces_cmd[] = {'@','s','p','a','c','e','s','@'};
169 static const char tab_cmd[] = {'@','t','a','b','@'};
170 static const char or_broken_cmd[] = {'@','o','r','_','b','r','o','k','e','n','@'};
171
172 while(exp_ptr < exp_end) {
173 if(*exp_ptr == '@') {
174 if(exp_ptr+sizeof(pwd_cmd) <= exp_end
175 && !memcmp(exp_ptr, pwd_cmd, sizeof(pwd_cmd))) {
176 exp_ptr += sizeof(pwd_cmd);
177 if(out_end-out_ptr < workdir_len
180 err = out_ptr;
181 }else {
182 out_ptr += workdir_len;
183 continue;
184 }
185 } else if(exp_ptr+sizeof(drive_cmd) <= exp_end
186 && !memcmp(exp_ptr, drive_cmd, sizeof(drive_cmd))) {
187 exp_ptr += sizeof(drive_cmd);
188 if(out_end-out_ptr < drive_len
190 out_ptr, drive_len, drive, drive_len) != CSTR_EQUAL)) {
191 err = out_ptr;
192 }else {
193 out_ptr += drive_len;
194 continue;
195 }
196 } else if(exp_ptr+sizeof(path_cmd) <= exp_end
197 && !memcmp(exp_ptr, path_cmd, sizeof(path_cmd))) {
198 exp_ptr += sizeof(path_cmd);
199 if(out_end-out_ptr < path_len
201 out_ptr, path_len, path, path_len) != CSTR_EQUAL)) {
202 err = out_ptr;
203 }else {
204 out_ptr += path_len;
205 continue;
206 }
207 } else if(exp_ptr+sizeof(shortpath_cmd) <= exp_end
208 && !memcmp(exp_ptr, shortpath_cmd, sizeof(shortpath_cmd))) {
209 exp_ptr += sizeof(shortpath_cmd);
210 if(out_end-out_ptr < shortpath_len
213 err = out_ptr;
214 }else {
215 out_ptr += shortpath_len;
216 continue;
217 }
218 }else if(exp_ptr+sizeof(space_cmd) <= exp_end
219 && !memcmp(exp_ptr, space_cmd, sizeof(space_cmd))) {
220 exp_ptr += sizeof(space_cmd);
221 if(out_ptr < out_end && *out_ptr == ' ') {
222 out_ptr++;
223 continue;
224 } else {
225 err = out_end;
226 }
227 }else if(exp_ptr+sizeof(spaces_cmd) <= exp_end
228 && !memcmp(exp_ptr, spaces_cmd, sizeof(spaces_cmd))) {
229 exp_ptr += sizeof(spaces_cmd);
230 if(out_ptr < out_end && *out_ptr == ' ') {
231 while (out_ptr < out_end && *out_ptr == ' ') out_ptr++;
232 continue;
233 } else {
234 err = out_end;
235 }
236 }else if(exp_ptr+sizeof(tab_cmd) <= exp_end
237 && !memcmp(exp_ptr, tab_cmd, sizeof(tab_cmd))) {
238 exp_ptr += sizeof(tab_cmd);
239 if(out_ptr < out_end && *out_ptr == '\t') {
240 out_ptr++;
241 continue;
242 } else {
243 err = out_end;
244 }
245 }else if(exp_ptr+sizeof(or_broken_cmd) <= exp_end
246 && !memcmp(exp_ptr, or_broken_cmd, sizeof(or_broken_cmd))) {
247 if(out_ptr == out_end)
248 return NULL;
249 else
250 err = out_ptr;
251 }else if(out_ptr == out_end || *out_ptr != *exp_ptr)
252 err = out_ptr;
253 }else if(out_ptr == out_end || *out_ptr != *exp_ptr) {
254 err = out_ptr;
255 }
256
257 if(err) {
258 if(!broken(1))
259 return err;
260
261 while(exp_ptr+sizeof(or_broken_cmd) <= exp_end && memcmp(exp_ptr, or_broken_cmd, sizeof(or_broken_cmd)))
262 exp_ptr++;
263 exp_ptr += sizeof(or_broken_cmd);
264 if (exp_ptr > exp_end) return err;
265 out_ptr = out_line;
266 err = NULL;
267 continue;
268 }
269
270 exp_ptr++;
271 out_ptr++;
272 }
273
274 if(exp_ptr != exp_end)
275 return out_ptr;
276 else if(out_ptr != out_end)
277 return exp_end;
278
279 return NULL;
280}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define broken(x)
Definition: atltest.h:178
INT WINAPI CompareStringA(LCID lcid, DWORD flags, LPCSTR str1, INT len1, LPCSTR str2, INT len2)
Definition: locale.c:4083
static const DWORD drive_len
Definition: batch.c:29
static char workdir[MAX_PATH]
Definition: batch.c:26
static DWORD workdir_len
Definition: batch.c:27
static DWORD path_len
Definition: batch.c:31
static DWORD shortpath_len
Definition: batch.c:33
static char shortpath[MAX_PATH]
Definition: batch.c:32
#define LOCALE_SYSTEM_DEFAULT
#define err(...)
#define NORM_IGNORECASE
Definition: winnls.h:178
#define CSTR_EQUAL
Definition: winnls.h:458

◆ convert_input_data()

static const char * convert_input_data ( const char data,
DWORD  size,
DWORD new_size 
)
static

Definition at line 35 of file batch.c.

36{
37 static const char escaped_space[] = {'@','s','p','a','c','e','@'};
38 static const char escaped_tab[] = {'@','t','a','b','@'};
39 DWORD i, eol_count = 0;
40 char *ptr, *new_data;
41
42 for (i = 0; i < size; i++)
43 if (data[i] == '\n') eol_count++;
44
45 ptr = new_data = HeapAlloc(GetProcessHeap(), 0, size + eol_count + 1);
46
47 for (i = 0; i < size; i++) {
48 switch (data[i]) {
49 case '\n':
50 if (data[i-1] != '\r')
51 *ptr++ = '\r';
52 *ptr++ = '\n';
53 break;
54 case '@':
55 if (data + i + sizeof(escaped_space) - 1 < data + size
56 && !memcmp(data + i, escaped_space, sizeof(escaped_space))) {
57 *ptr++ = ' ';
58 i += sizeof(escaped_space) - 1;
59 } else if (data + i + sizeof(escaped_tab) - 1 < data + size
60 && !memcmp(data + i, escaped_tab, sizeof(escaped_tab))) {
61 *ptr++ = '\t';
62 i += sizeof(escaped_tab) - 1;
63 } else {
64 *ptr++ = data[i];
65 }
66 break;
67 default:
68 *ptr++ = data[i];
69 }
70 }
71 *ptr = '\0';
72
73 *new_size = strlen(new_data);
74 return new_data;
75}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
size_t const new_size
Definition: expand.cpp:66
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static PVOID ptr
Definition: dispmode.c:27

◆ load_resource()

static DWORD load_resource ( const char name,
const char type,
const char **  ret 
)
static

Definition at line 401 of file batch.c.

402{
403 const char *res;
404 HRSRC src;
405 DWORD size;
406
408 ok(src != NULL, "Could not find resource %s: %u\n", name, GetLastError());
409 if(!src)
410 return 0;
411
414 while(size && !res[size-1])
415 size--;
416
417 *ret = res;
418 return size;
419}
#define ok(value,...)
Definition: atltest.h:57
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
Definition: name.c:39
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

◆ map_file()

static DWORD map_file ( const char file_name,
const char **  ret 
)
static

Definition at line 130 of file batch.c.

131{
132 HANDLE file, map;
133 DWORD size;
134
136 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %08x\n", GetLastError());
138 return 0;
139
141
144 ok(map != NULL, "CreateFileMappingA(%s) failed: %u\n", file_name, GetLastError());
145 if(!map)
146 return 0;
147
148 *ret = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
149 ok(*ret != NULL, "MapViewOfFile failed: %u\n", GetLastError());
151 if(!*ret)
152 return 0;
153
154 return size;
155}
Definition: _map.h:48
#define PAGE_READONLY
Definition: compat.h:138
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define FILE_MAP_READ
Definition: compat.h:776
#define MapViewOfFile
Definition: compat.h:745
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
HANDLE NTAPI CreateFileMappingA(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, IN DWORD flProtect, IN DWORD dwMaximumSizeHigh, IN DWORD dwMaximumSizeLow, IN LPCSTR lpName)
Definition: filemap.c:23
static LPCWSTR file_name
Definition: protocol.c:147
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
Definition: fci.c:127

◆ run_cmd()

static BOOL run_cmd ( const char cmd_data,
DWORD  cmd_size 
)
static

Definition at line 77 of file batch.c.

78{
79 SECURITY_ATTRIBUTES sa = {sizeof(sa), 0, TRUE};
80 char command[] = "test.cmd";
81 STARTUPINFOA si = {sizeof(si)};
83 HANDLE file,fileerr;
84 DWORD size;
85 BOOL bres;
86
89 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
91 return FALSE;
92
93 bres = WriteFile(file, cmd_data, cmd_size, &size, NULL);
95 ok(bres, "Could not write to file: %u\n", GetLastError());
96 if(!bres)
97 return FALSE;
98
101 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
103 return FALSE;
104
107 ok(fileerr != INVALID_HANDLE_VALUE, "CreateFile stderr failed\n");
108 if(fileerr == INVALID_HANDLE_VALUE)
109 return FALSE;
110
112 si.hStdOutput = file;
113 si.hStdError = fileerr;
114 bres = CreateProcessA(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
115 ok(bres, "CreateProcess failed: %u\n", GetLastError());
116 if(!bres) {
117 DeleteFileA("test.out");
118 return FALSE;
119 }
120
122 CloseHandle(pi.hThread);
123 CloseHandle(pi.hProcess);
125 CloseHandle(fileerr);
126 DeleteFileA("test.cmd");
127 return TRUE;
128}
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
#define CREATE_ALWAYS
Definition: disk.h:72
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define GENERIC_WRITE
Definition: nt_native.h:90
HANDLE hStdOutput
Definition: winbase.h:872
HANDLE hStdError
Definition: winbase.h:873
DWORD dwFlags
Definition: winbase.h:867
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define STARTF_USESTDHANDLES
Definition: winbase.h:525

◆ run_from_file()

static void run_from_file ( const char file_name)
static

Definition at line 375 of file batch.c.

376{
377 char out_name[MAX_PATH];
378 const char *test_data, *out_data;
380
382 if(!test_size) {
383 ok(0, "Could not map file %s: %u\n", file_name, GetLastError());
384 return;
385 }
386
387 sprintf(out_name, "%s.exp", file_name);
388 out_size = map_file(out_name, &out_data);
389 if(!out_size) {
390 ok(0, "Could not map file %s: %u\n", out_name, GetLastError());
392 return;
393 }
394
396
398 UnmapViewOfFile(out_data);
399}
#define UnmapViewOfFile
Definition: compat.h:746
#define MAX_PATH
Definition: compat.h:34
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static DWORD map_file(const char *file_name, const char **ret)
Definition: batch.c:135
static void test_size(void)
Definition: monthcal.c:1559
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:100
#define run_test(test)
Definition: ms_seh.c:71

◆ run_test()

static void run_test ( const char cmd_data,
DWORD  cmd_size,
const char exp_data,
DWORD  exp_size 
)
static

Definition at line 351 of file batch.c.

352{
353 const char *out_data, *actual_cmd_data;
354 DWORD out_size, actual_cmd_size;
355
356 actual_cmd_data = convert_input_data(cmd_data, cmd_size, &actual_cmd_size);
357 if(!actual_cmd_size || !actual_cmd_data)
358 goto cleanup;
359
360 if(!run_cmd(actual_cmd_data, actual_cmd_size))
361 goto cleanup;
362
363 out_size = map_file("test.out", &out_data);
364 if(out_size) {
365 test_output(out_data, out_size, exp_data, exp_size);
366 UnmapViewOfFile(out_data);
367 }
368 DeleteFileA("test.out");
369 DeleteFileA("test.err");
370
371cleanup:
372 HeapFree(GetProcessHeap(), 0, (LPVOID)actual_cmd_data);
373}
#define HeapFree(x, y, z)
Definition: compat.h:735
static void cleanup(void)
Definition: main.c:1335
static BOOL run_cmd(const char *cmd_data, DWORD cmd_size)
Definition: batch.c:82
static const char * convert_input_data(const char *data, DWORD size, DWORD *new_size)
Definition: batch.c:36
static void test_output(const char *out_data, DWORD out_size, const char *exp_data, DWORD exp_size)
Definition: batch.c:287
struct ChNotifyTest * exp_data
Definition: shlfolder.c:4868

◆ START_TEST()

START_TEST ( batch  )

Definition at line 458 of file batch.c.

459{
460 int argc;
461 char **argv;
462
463 if (!cmd_available()) {
464 win_skip("cmd not installed, skipping cmd tests\n");
465 return;
466 }
467
469 drive[0] = workdir[0];
470 drive[1] = workdir[1]; /* Should be ':' */
471 memcpy(path, workdir + drive_len, (workdir_len - drive_len) * sizeof(drive[0]));
472
473 /* Only add trailing backslash to 'path' for non-root directory */
474 if (workdir_len - drive_len > 1) {
475 path[workdir_len - drive_len] = '\\';
477 } else {
478 path_len = 1; /* \ */
479 }
481
483 if(argc > 2)
485 else
486 EnumResourceNamesA(NULL, "TESTCMD", test_enum_proc, 0);
487}
static int argc
Definition: ServiceArgs.c:12
#define ARRAY_SIZE(A)
Definition: main.h:20
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
DWORD WINAPI GetShortPathNameA(IN LPCSTR lpszLongPath, OUT LPSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1752
BOOL WINAPI EnumResourceNamesA(HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG_PTR lparam)
Definition: res.c:285
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static int cmd_available(void)
Definition: batch.c:447
static void run_from_file(const char *file_name)
Definition: batch.c:380
static BOOL WINAPI test_enum_proc(HMODULE module, LPCSTR type, LPSTR name, LONG_PTR param)
Definition: batch.c:426
#define argv
Definition: mplay32.c:18
#define win_skip
Definition: test.h:164
int winetest_get_mainargs(char ***pargv)

◆ test_enum_proc()

static BOOL WINAPI test_enum_proc ( HMODULE  module,
LPCSTR  type,
LPSTR  name,
LONG_PTR  param 
)
static

Definition at line 421 of file batch.c.

422{
423 const char *cmd_data, *out_data;
424 DWORD cmd_size, out_size;
425 char res_name[100];
426
427 trace("running %s test...\n", name);
428
429 cmd_size = load_resource(name, type, &cmd_data);
430 if(!cmd_size)
431 return TRUE;
432
433 sprintf(res_name, "%s.exp", name);
434 out_size = load_resource(res_name, "TESTOUT", &out_data);
435 if(!out_size)
436 return TRUE;
437
438 run_test(cmd_data, cmd_size, out_data, out_size);
439 return TRUE;
440}
#define trace
Definition: atltest.h:70
static DWORD load_resource(const char *name, const char *type, const char **ret)
Definition: batch.c:406

◆ test_output()

static void test_output ( const char out_data,
DWORD  out_size,
const char exp_data,
DWORD  exp_size 
)
static

Definition at line 282 of file batch.c.

283{
284 const char *out_ptr = out_data, *exp_ptr = exp_data, *out_nl, *exp_nl, *err = NULL;
285 DWORD line = 0;
286 static const char todo_wine_cmd[] = {'@','t','o','d','o','_','w','i','n','e','@'};
287 static const char resync_cmd[] = {'-','-','-'};
288 BOOL is_todo_wine, is_out_resync = FALSE, is_exp_resync = FALSE;
289
290 while(out_ptr < out_data+out_size && exp_ptr < exp_data+exp_size) {
291 line++;
292
293 for(exp_nl = exp_ptr; exp_nl < exp_data+exp_size && *exp_nl != '\r' && *exp_nl != '\n'; exp_nl++);
294 for(out_nl = out_ptr; out_nl < out_data+out_size && *out_nl != '\r' && *out_nl != '\n'; out_nl++);
295
296 is_todo_wine = (exp_ptr+sizeof(todo_wine_cmd) <= exp_nl &&
297 !memcmp(exp_ptr, todo_wine_cmd, sizeof(todo_wine_cmd)));
298 if (is_todo_wine)
299 exp_ptr += sizeof(todo_wine_cmd);
300
301 todo_wine_if(is_todo_wine)
302 {
303 is_exp_resync=(exp_ptr+sizeof(resync_cmd) <= exp_nl &&
304 !memcmp(exp_ptr, resync_cmd, sizeof(resync_cmd)));
305 is_out_resync=(out_ptr+sizeof(resync_cmd) <= out_nl &&
306 !memcmp(out_ptr, resync_cmd, sizeof(resync_cmd)));
307
308 err = compare_line(out_ptr, out_nl, exp_ptr, exp_nl);
309 if(err == out_nl)
310 ok(0, "unexpected end of line %d (got '%.*s', wanted '%.*s')\n",
311 line, (int)(out_nl-out_ptr), out_ptr, (int)(exp_nl-exp_ptr), exp_ptr);
312 else if(err == exp_nl)
313 ok(0, "excess characters on line %d (got '%.*s', wanted '%.*s')\n",
314 line, (int)(out_nl-out_ptr), out_ptr, (int)(exp_nl-exp_ptr), exp_ptr);
315 else if (!err && is_todo_wine && is_out_resync && is_exp_resync)
316 /* Consider that the todo_wine was to deal with extra lines,
317 * not for the resync line itself
318 */
319 err = NULL;
320 else
321 ok(!err, "unexpected char 0x%x position %d in line %d (got '%.*s', wanted '%.*s')\n",
322 (err ? *err : 0), (err ? (int)(err-out_ptr) : -1), line, (int)(out_nl-out_ptr), out_ptr, (int)(exp_nl-exp_ptr), exp_ptr);
323 }
324
325 if (is_exp_resync && err && is_todo_wine)
326 {
327 exp_ptr -= sizeof(todo_wine_cmd);
328 /* If we rewind to the beginning of the line, don't increment line number */
329 line--;
330 }
331 else if (!is_exp_resync || !err ||
332 (is_exp_resync && is_out_resync && err))
333 {
334 exp_ptr = exp_nl+1;
335 if(exp_nl+1 < exp_data+exp_size && exp_nl[0] == '\r' && exp_nl[1] == '\n')
336 exp_ptr++;
337 }
338
339 if (!is_out_resync || !err)
340 {
341 out_ptr = out_nl+1;
342 if(out_nl+1 < out_data+out_size && out_nl[0] == '\r' && out_nl[1] == '\n')
343 out_ptr++;
344 }
345 }
346
347 ok(exp_ptr >= exp_data+exp_size, "unexpected end of output in line %d, missing %s\n", line, exp_ptr);
348 ok(out_ptr >= out_data+out_size, "too long output, got additional %s\n", out_ptr);
349}
static const char * compare_line(const char *out_line, const char *out_end, const char *exp_line, const char *exp_end)
Definition: batch.c:162
#define todo_wine_if(is_todo)
Definition: custom.c:86
Definition: parser.c:49

Variable Documentation

◆ drive

char drive[2]
static

Definition at line 27 of file batch.c.

◆ drive_len

const DWORD drive_len = ARRAY_SIZE(drive)
static

Definition at line 28 of file batch.c.

◆ path

char path[MAX_PATH]
static

Definition at line 29 of file batch.c.

◆ path_len

DWORD path_len
static

Definition at line 30 of file batch.c.

◆ shortpath

char shortpath[MAX_PATH]
static

Definition at line 31 of file batch.c.

◆ shortpath_len

DWORD shortpath_len
static

Definition at line 32 of file batch.c.

◆ workdir

char workdir[MAX_PATH]
static

Definition at line 25 of file batch.c.

◆ workdir_len

DWORD workdir_len
static

Definition at line 26 of file batch.c.