Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
9171fd14
Commit
9171fd14
authored
Oct 22, 2012
by
Jason Edmeades
Committed by
Alexandre Julliard
Oct 24, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd: Add support for usebackq (for /f).
parent
293da2d0
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
90 additions
and
37 deletions
+90
-37
batch.c
programs/cmd/batch.c
+1
-0
builtins.c
programs/cmd/builtins.c
+74
-34
test_builtins.cmd
programs/cmd/tests/test_builtins.cmd
+11
-3
test_builtins.cmd.exp
programs/cmd/tests/test_builtins.cmd.exp
+4
-0
No files found.
programs/cmd/batch.c
View file @
9171fd14
...
...
@@ -113,6 +113,7 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
HeapFree
(
GetProcessHeap
(),
0
,
context
->
batchfileW
);
LocalFree
(
context
);
if
((
prev_context
!=
NULL
)
&&
(
!
called
))
{
WINE_TRACE
(
"Batch completed, but was not 'called' so skipping outer batch too
\n
"
);
prev_context
->
skip_rest
=
TRUE
;
context
=
prev_context
;
}
...
...
programs/cmd/builtins.c
View file @
9171fd14
...
...
@@ -1583,7 +1583,7 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
usebackqW
,
sizeof
(
usebackqW
)
/
sizeof
(
WCHAR
))
==
CSTR_EQUAL
)
{
*
usebackq
=
TRUE
;
pos
=
pos
+
sizeof
(
usebackqW
)
/
sizeof
(
WCHAR
);
WINE_
FIXM
E
(
"Found usebackq
\n
"
);
WINE_
TRAC
E
(
"Found usebackq
\n
"
);
/* Save the supplied delims. Slightly odd as space can be a delimiter but only
if you finish the optionsroot string with delims= otherwise the space is
...
...
@@ -1727,6 +1727,67 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
}
/**************************************************************************
* WCMD_forf_getinputhandle
*
* Return a file handle which can be used for reading the input lines,
* either to a specific file (which may be quote delimited as we have to
* read the parameters in raw mode) or to a command which we need to
* execute. The command being executed runs in its own shell and stores
* its data in a temporary file.
*
* Parameters:
* usebackq [I] - Indicates whether usebackq is in effect or not
* itemStr [I] - The item to be handled, either a filename or
* whole command string to execute
* iscmd [I] - Identifies whether this is a command or not
*
* Returns a file handle which can be used to read the input lines from.
*/
HANDLE
WCMD_forf_getinputhandle
(
BOOL
usebackq
,
WCHAR
*
itemstr
,
BOOL
iscmd
)
{
WCHAR
temp_str
[
MAX_PATH
];
WCHAR
temp_file
[
MAX_PATH
];
WCHAR
temp_cmd
[
MAXSTRING
];
HANDLE
hinput
=
INVALID_HANDLE_VALUE
;
static
const
WCHAR
redirOutW
[]
=
{
'>'
,
'%'
,
's'
,
'\0'
};
static
const
WCHAR
cmdW
[]
=
{
'C'
,
'M'
,
'D'
,
'\0'
};
static
const
WCHAR
cmdslashcW
[]
=
{
'C'
,
'M'
,
'D'
,
'.'
,
'E'
,
'X'
,
'E'
,
' '
,
'/'
,
'C'
,
' '
,
'"'
,
'%'
,
's'
,
'"'
,
'\0'
};
/* Remove leading and trailing character */
if
((
iscmd
&&
(
itemstr
[
0
]
==
'`'
&&
usebackq
))
||
(
iscmd
&&
(
itemstr
[
0
]
==
'\''
&&
!
usebackq
))
||
(
!
iscmd
&&
(
itemstr
[
0
]
==
'"'
&&
usebackq
)))
{
itemstr
[
strlenW
(
itemstr
)
-
1
]
=
0x00
;
itemstr
++
;
}
if
(
iscmd
)
{
/* Get temp filename */
GetTempPathW
(
sizeof
(
temp_str
)
/
sizeof
(
WCHAR
),
temp_str
);
GetTempFileNameW
(
temp_str
,
cmdW
,
0
,
temp_file
);
/* Redirect output to the temporary file */
wsprintfW
(
temp_str
,
redirOutW
,
temp_file
);
wsprintfW
(
temp_cmd
,
cmdslashcW
,
itemstr
);
WINE_TRACE
(
"Issuing '%s' with redirs '%s'
\n
"
,
wine_dbgstr_w
(
temp_cmd
),
wine_dbgstr_w
(
temp_str
));
WCMD_execute
(
temp_cmd
,
temp_str
,
NULL
,
NULL
,
NULL
,
FALSE
);
/* Open the file, read line by line and process */
hinput
=
CreateFileW
(
temp_file
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_FLAG_DELETE_ON_CLOSE
,
NULL
);
}
else
{
/* Open the file, read line by line and process */
WINE_TRACE
(
"Reading input to parse from '%s'
\n
"
,
wine_dbgstr_w
(
itemstr
));
hinput
=
CreateFileW
(
itemstr
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
}
return
hinput
;
}
/**************************************************************************
* WCMD_for
*
* Batch file loop processing.
...
...
@@ -1764,7 +1825,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
int
forf_skip
=
0
;
WCHAR
forf_delims
[
256
];
WCHAR
forf_tokens
[
MAXSTRING
];
BOOL
forf_usebackq
;
BOOL
forf_usebackq
=
FALSE
;
/* Handle optional qualifiers (multiple are allowed) */
WCHAR
*
thisArg
=
WCMD_parameter
(
p
,
parameterNo
++
,
NULL
,
NULL
,
FALSE
,
FALSE
);
...
...
@@ -1974,41 +2035,25 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
/* else ignore them! */
/* Filesets - either a list of files, or a command to run and parse the output */
}
else
if
(
doFileset
&&
*
itemStart
!=
'"'
)
{
}
else
if
(
doFileset
&&
((
!
forf_usebackq
&&
*
itemStart
!=
'"'
)
||
(
forf_usebackq
&&
*
itemStart
!=
'\''
)))
{
HANDLE
input
;
WCHAR
temp_file
[
MAX_PATH
];
WINE_TRACE
(
"Processing for filespec from item %d '%s'
\n
"
,
itemNum
,
wine_dbgstr_w
(
item
));
/* If backquote or single quote, we need to launch that command
and parse the results - use a temporary file */
if
(
*
itemStart
==
'`'
||
*
itemStart
==
'\''
)
{
WCHAR
temp_path
[
MAX_PATH
],
temp_cmd
[
MAXSTRING
];
static
const
WCHAR
redirOut
[]
=
{
'>'
,
'%'
,
's'
,
'\0'
};
static
const
WCHAR
cmdW
[]
=
{
'C'
,
'M'
,
'D'
,
'\0'
};
/* Remove trailing character */
itemStart
[
strlenW
(
itemStart
)
-
1
]
=
0x00
;
if
((
forf_usebackq
&&
*
itemStart
==
'`'
)
||
(
!
forf_usebackq
&&
*
itemStart
==
'\''
))
{
/* Get temp filename */
GetTempPathW
(
sizeof
(
temp_path
)
/
sizeof
(
WCHAR
),
temp_path
);
GetTempFileNameW
(
temp_path
,
cmdW
,
0
,
temp_file
);
/* Execute program and redirect output */
wsprintfW
(
temp_cmd
,
redirOut
,
(
itemStart
+
1
),
temp_file
);
WCMD_execute
(
itemStart
,
temp_cmd
,
NULL
,
NULL
,
NULL
,
FALSE
);
/* Open the file, read line by line and process */
input
=
CreateFileW
(
temp_file
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
/* Use itemstart because the command is the whole set, not just the first token */
input
=
WCMD_forf_getinputhandle
(
forf_usebackq
,
itemStart
,
TRUE
);
}
else
{
/* Open the file, read line by line and process */
input
=
CreateFileW
(
item
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
/* Use item because the file to process is just the first item in the set */
input
=
WCMD_forf_getinputhandle
(
forf_usebackq
,
item
,
FALSE
);
}
/* Process the input file */
...
...
@@ -2020,8 +2065,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
}
else
{
WCHAR
buffer
[
MAXSTRING
];
/* Read line by line until end of file */
while
(
WCMD_fgets
(
buffer
,
sizeof
(
buffer
)
/
sizeof
(
WCHAR
),
input
))
{
WCMD_parse_line
(
cmdStart
,
firstCmd
,
&
cmdEnd
,
variable
,
buffer
,
&
doExecuted
,
&
forf_skip
,
forf_eol
);
...
...
@@ -2030,13 +2074,9 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
CloseHandle
(
input
);
}
/* Delete the temporary file */
if
(
*
itemStart
==
'`'
||
*
itemStart
==
'\''
)
{
DeleteFileW
(
temp_file
);
}
/* Filesets - A string literal */
}
else
if
(
doFileset
&&
*
itemStart
==
'"'
)
{
}
else
if
(
doFileset
&&
((
!
forf_usebackq
&&
*
itemStart
==
'"'
)
||
(
forf_usebackq
&&
*
itemStart
==
'\''
)))
{
/* Copy the item away from the global buffer used by WCMD_parameter */
strcpyW
(
buffer
,
item
);
...
...
programs/cmd/tests/test_builtins.cmd
View file @
9171fd14
...
...
@@ -1147,9 +1147,17 @@ echo.>> bar
echo kkk>>bar
for /f %%k in (foo bar) do echo %%k
for /f %%k in (bar foo) do echo %%k
rem echo ------ command argument
rem Not implemented on NT4
rem FIXME: Not testable right now in wine: not implemented and would need
echo ------ command argument
rem Not implemented on NT4, need to skip it as no way to get output otherwise
if "%CD%"=="" goto :SkipFORFcmdNT4
for /f %%i in ('echo.Passed1') do echo %%i
for /f "usebackq" %%i in (`echo.Passed2`) do echo %%i
for /f usebackq %%i in (`echo.Passed3`) do echo %%i
goto :ContinueFORF
:SkipFORFcmdNT4
for /l %%i in (1,1,3) do echo Missing functionality - Broken%%i
:ContinueFORF
rem FIXME: Rest not testable right now in wine: not implemented and would need
rem preliminary grep-like program implementation (e.g. like findstr or fc) even
rem for a simple todo_wine test
rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported
...
...
programs/cmd/tests/test_builtins.cmd.exp
View file @
9171fd14
...
...
@@ -809,6 +809,10 @@ kkk
a
b
c
------ command argument
Passed1@or_broken@Missing functionality - Broken1
Passed2@or_broken@Missing functionality - Broken2
Passed3@or_broken@Missing functionality - Broken3
------ eol option
and@or_broken@Broken NT4 functionality1
Line@or_broken@Broken NT4 functionality2
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment