This is part XIV of cmd engine rewrite.
It mainly tests and sets return code for a couple of directory related commands (CD, MKDIR/MD, PUSHD, DIR). It's on purpose that POPD isn't included in this MR: it will require (as RMDIR) some changes not directly related to command itself (more on next MR).
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd | 42 ++++++++++++++++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 24 ++++++++++++++ 2 files changed, 66 insertions(+)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index ccdddd289bd..d5f8cef8eab 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -524,6 +524,48 @@ call :setError 666 & (erase i\dont\exist\at\all.txt &&echo SUCCESS !errorlevel!| call :setError 666 & (erase file* i\dont\exist\at\all.txt &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) cd .. && rd /q /s foo
+echo --- success/failure for MKDIR,MD command +mkdir foo & cd foo +call :setError 666 & (mkdir &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (mkdir abc &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (mkdir abc &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (mkdir @:\cba\abc &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (mkdir NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +cd .. && rd /q /s foo + +echo --- success/failure for CD command +mkdir foo & cd foo +mkdir abc +call :setError 666 & (cd abc >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (cd abc >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (cd .. >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (cd >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +cd .. && rd /q /s foo + +echo --- success/failure for PUSHD/POPD commands +mkdir foo & cd foo +mkdir abc +call :setError 666 & (pushd &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (pushd abc &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (pushd abc &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (popd abc &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (popd &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +cd .. && rd /q /s foo + +echo --- success/failure for DIR command +mkdir foo & cd foo +echo a > fileA +echo b > fileB +mkdir dir +echo b > dir\fileB +call :setError 666 & (dir /e >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (dir zzz >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (dir fileA zzz >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (dir zzz fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (dir dir\zzz >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (dir file* >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +cd .. && rd /q /s foo + echo --- setlocal DisableDelayedExpansion echo ------------ Testing 'set' ------------ diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 8b281907624..8be714a9158 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -496,6 +496,30 @@ FAILURE 1 SUCCESS 0 FAILURE 1 FAILURE 1 +--- success/failure for MKDIR,MD command +@todo_wine@FAILURE 1 +@todo_wine@SUCCESS 0 +@todo_wine@FAILURE 1 +@todo_wine@FAILURE 1 +@todo_wine@SUCCESS 0 +--- success/failure for CD command +@todo_wine@SUCCESS 0 +@todo_wine@FAILURE 1 +@todo_wine@SUCCESS 0 +@todo_wine@SUCCESS 0 +--- success/failure for PUSHD/POPD commands +@todo_wine@SUCCESS 0 +SUCCESS 0 +@todo_wine@FAILURE 1 +@todo_wine@SUCCESS 666 +@todo_wine@FAILURE 1 +@todo_wine@--- success/failure for DIR command +@todo_wine@FAILURE 1 +@todo_wine@FAILURE 1 +SUCCESS 0 +SUCCESS 0 +@todo_wine@FAILURE 1 +SUCCESS 0 @todo_wine@--- ------------ Testing 'set' ------------ 1
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/builtins.c | 21 ++++++++++++++------- programs/cmd/tests/test_builtins.cmd.exp | 10 +++++----- programs/cmd/wcmd.h | 2 +- programs/cmd/wcmdmain.c | 2 +- 4 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index faff537be73..7a023ba917c 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1158,23 +1158,30 @@ static BOOL create_full_path(WCHAR* path) return FALSE; }
-void WCMD_create_dir (WCHAR *args) { +RETURN_CODE WCMD_create_dir(WCHAR *args) +{ int argno = 0; WCHAR *argN = args; + RETURN_CODE return_code;
- if (param1[0] == 0x00) { + if (param1[0] == L'\0') + { WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOARG)); - return; + return errorlevel = ERROR_INVALID_FUNCTION; } + return_code = NO_ERROR; /* Loop through all args */ - while (TRUE) { + for (;;) + { WCHAR *thisArg = WCMD_parameter(args, argno++, &argN, FALSE, FALSE); if (!argN) break; - if (!create_full_path(thisArg)) { - WCMD_print_error (); - errorlevel = ERROR_INVALID_FUNCTION; + if (!create_full_path(thisArg)) + { + WCMD_print_error(); + return_code = ERROR_INVALID_FUNCTION; } } + return errorlevel = return_code; }
/* Parse the /A options given by the user on the commandline diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 8be714a9158..ef93def2732 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -497,11 +497,11 @@ SUCCESS 0 FAILURE 1 FAILURE 1 --- success/failure for MKDIR,MD command -@todo_wine@FAILURE 1 -@todo_wine@SUCCESS 0 -@todo_wine@FAILURE 1 -@todo_wine@FAILURE 1 -@todo_wine@SUCCESS 0 +FAILURE 1 +SUCCESS 0 +FAILURE 1 +FAILURE 1 +SUCCESS 0 --- success/failure for CD command @todo_wine@SUCCESS 0 @todo_wine@FAILURE 1 diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 0b0a96c5fb8..8fe2eb3f322 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -167,7 +167,7 @@ void WCMD_choice (const WCHAR *); void WCMD_clear_screen (void); void WCMD_color (void); RETURN_CODE WCMD_copy(WCHAR *); -void WCMD_create_dir (WCHAR *); +RETURN_CODE WCMD_create_dir(WCHAR *); RETURN_CODE WCMD_delete(WCHAR *); void WCMD_directory (WCHAR *); RETURN_CODE WCMD_echo(const WCHAR *); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index c096abe3431..ededdcd2177 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1849,7 +1849,7 @@ static RETURN_CODE execute_single_command(const WCHAR *command) break; case WCMD_MD: case WCMD_MKDIR: - WCMD_create_dir (parms_start); + return_code = WCMD_create_dir(parms_start); break; case WCMD_MOVE: return_code = WCMD_move();
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/builtins.c | 17 ++++++++++------- programs/cmd/tests/test_builtins.cmd.exp | 8 ++++---- programs/cmd/wcmd.h | 2 +- programs/cmd/wcmdmain.c | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 7a023ba917c..7b4bc3b61bb 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -2414,8 +2414,9 @@ void WCMD_endlocal (void) { * Set/Show the current default directory */
-void WCMD_setshow_default (const WCHAR *args) { - +RETURN_CODE WCMD_setshow_default(const WCHAR *args) +{ + RETURN_CODE return_code; BOOL status; WCHAR string[1024]; WCHAR cwd[1024]; @@ -2436,6 +2437,7 @@ void WCMD_setshow_default (const WCHAR *args) { }
GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd); + return_code = NO_ERROR;
if (!*args) { lstrcatW(cwd, L"\r\n"); @@ -2466,7 +2468,9 @@ void WCMD_setshow_default (const WCHAR *args) { WCHAR ext[MAX_PATH];
/* Convert path into actual directory spec */ - if (!WCMD_get_fullpath(string, ARRAY_SIZE(fpath), fpath, NULL)) return; + if (!WCMD_get_fullpath(string, ARRAY_SIZE(fpath), fpath, NULL)) + return errorlevel = ERROR_INVALID_FUNCTION; + _wsplitpath(fpath, drive, dir, fname, ext);
/* Rebuild path */ @@ -2482,9 +2486,8 @@ void WCMD_setshow_default (const WCHAR *args) {
status = SetCurrentDirectoryW(string); if (!status) { - errorlevel = ERROR_INVALID_FUNCTION; WCMD_print_error (); - return; + return_code = ERROR_INVALID_FUNCTION; } else {
/* Save away the actual new directory, to store as current location */ @@ -2511,8 +2514,8 @@ void WCMD_setshow_default (const WCHAR *args) { SetEnvironmentVariableW(env, string); }
- } - return; + } + return errorlevel = return_code; }
/**************************************************************************** diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index ef93def2732..0397311cf85 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -503,10 +503,10 @@ FAILURE 1 FAILURE 1 SUCCESS 0 --- success/failure for CD command -@todo_wine@SUCCESS 0 -@todo_wine@FAILURE 1 -@todo_wine@SUCCESS 0 -@todo_wine@SUCCESS 0 +SUCCESS 0 +FAILURE 1 +SUCCESS 0 +SUCCESS 0 --- success/failure for PUSHD/POPD commands @todo_wine@SUCCESS 0 SUCCESS 0 diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 8fe2eb3f322..f538d3069bb 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -194,7 +194,7 @@ RETURN_CODE WCMD_rename(void); void WCMD_run_program (WCHAR *command, BOOL called); void WCMD_setlocal (const WCHAR *args); void WCMD_setshow_date (void); -void WCMD_setshow_default (const WCHAR *args); +RETURN_CODE WCMD_setshow_default(const WCHAR *args); void WCMD_setshow_env (WCHAR *command); void WCMD_setshow_path (const WCHAR *args); void WCMD_setshow_prompt (void); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index ededdcd2177..2228593157e 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1814,7 +1814,7 @@ static RETURN_CODE execute_single_command(const WCHAR *command) break; case WCMD_CD: case WCMD_CHDIR: - WCMD_setshow_default (parms_start); + return_code = WCMD_setshow_default(parms_start); break; case WCMD_CLS: WCMD_clear_screen ();
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/directory.c | 23 ++++++++++++++--------- programs/cmd/tests/test_builtins.cmd.exp | 6 +++--- programs/cmd/wcmd.h | 2 +- programs/cmd/wcmdmain.c | 2 +- 4 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c index 72542538d5b..fdcae9f6a94 100644 --- a/programs/cmd/directory.c +++ b/programs/cmd/directory.c @@ -631,7 +631,7 @@ static void init_time_format(void) * */
-void WCMD_directory (WCHAR *args) +RETURN_CODE WCMD_directory(WCHAR *args) { WCHAR path[MAX_PATH], cwd[MAX_PATH]; DWORD status; @@ -649,6 +649,7 @@ void WCMD_directory (WCHAR *args) WCHAR dir[MAX_PATH]; WCHAR fname[MAX_PATH]; WCHAR ext[MAX_PATH]; + unsigned num_empty = 0, num_with_data = 0;
errorlevel = NO_ERROR;
@@ -736,8 +737,7 @@ void WCMD_directory (WCHAR *args) } else { SetLastError(ERROR_INVALID_PARAMETER); WCMD_print_error(); - errorlevel = ERROR_INVALID_FUNCTION; - return; + return errorlevel = ERROR_INVALID_FUNCTION; } break; case 'O': p = p + 1; @@ -756,8 +756,7 @@ void WCMD_directory (WCHAR *args) default: SetLastError(ERROR_INVALID_PARAMETER); WCMD_print_error(); - errorlevel = ERROR_INVALID_FUNCTION; - return; + return errorlevel = ERROR_INVALID_FUNCTION; } p++; } @@ -787,8 +786,7 @@ void WCMD_directory (WCHAR *args) default: SetLastError(ERROR_INVALID_PARAMETER); WCMD_print_error(); - errorlevel = ERROR_INVALID_FUNCTION; - return; + return errorlevel = ERROR_INVALID_FUNCTION; }
/* Keep running list of bits we care about */ @@ -806,8 +804,7 @@ void WCMD_directory (WCHAR *args) default: SetLastError(ERROR_INVALID_PARAMETER); WCMD_print_error(); - errorlevel = ERROR_INVALID_FUNCTION; - return; + return errorlevel = ERROR_INVALID_FUNCTION; } p = p + 1; } @@ -957,6 +954,10 @@ void WCMD_directory (WCHAR *args) errorlevel = NO_ERROR; prevEntry = thisEntry; thisEntry = WCMD_list_directory (thisEntry, 0); + if (errorlevel) + num_empty++; + else + num_with_data++; }
/* Trailer Information */ @@ -964,6 +965,8 @@ void WCMD_directory (WCHAR *args) WCMD_dir_trailer(prevEntry->dirName); }
+ if (num_empty && !num_with_data) + errorlevel = ERROR_INVALID_FUNCTION; exit: if (paged_mode) WCMD_leave_paged_mode();
@@ -975,4 +978,6 @@ exit: free(prevEntry->fileName); free(prevEntry); } + + return errorlevel; } diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 0397311cf85..8d5926580d9 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -514,11 +514,11 @@ SUCCESS 0 @todo_wine@SUCCESS 666 @todo_wine@FAILURE 1 @todo_wine@--- success/failure for DIR command -@todo_wine@FAILURE 1 -@todo_wine@FAILURE 1 +FAILURE 1 +FAILURE 1 SUCCESS 0 SUCCESS 0 -@todo_wine@FAILURE 1 +FAILURE 1 SUCCESS 0 @todo_wine@--- ------------ Testing 'set' ------------ diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index f538d3069bb..0ca14e9f2ac 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -169,7 +169,7 @@ void WCMD_color (void); RETURN_CODE WCMD_copy(WCHAR *); RETURN_CODE WCMD_create_dir(WCHAR *); RETURN_CODE WCMD_delete(WCHAR *); -void WCMD_directory (WCHAR *); +RETURN_CODE WCMD_directory(WCHAR *); RETURN_CODE WCMD_echo(const WCHAR *); void WCMD_endlocal (void); void WCMD_enter_paged_mode(const WCHAR *); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 2228593157e..dc7da5979be 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1833,7 +1833,7 @@ static RETURN_CODE execute_single_command(const WCHAR *command) return_code = WCMD_delete(parms_start); break; case WCMD_DIR: - WCMD_directory (parms_start); + return_code = WCMD_directory(parms_start); break; case WCMD_ECHO: return_code = WCMD_echo(&whichcmd[count]);
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/builtins.c | 20 +++++++++++++------- programs/cmd/tests/test_builtins.cmd.exp | 8 ++++---- programs/cmd/wcmd.h | 2 +- programs/cmd/wcmdmain.c | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 7b4bc3b61bb..6e0a7830900 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1875,15 +1875,19 @@ RETURN_CODE WCMD_goto(void) * Push a directory onto the stack */
-void WCMD_pushd (const WCHAR *args) +RETURN_CODE WCMD_pushd(const WCHAR *args) { struct env_stack *curdir; WCHAR *thisdir; + RETURN_CODE return_code; + + if (!*args) + return errorlevel = NO_ERROR;
if (wcschr(args, '/') != NULL) { SetLastError(ERROR_INVALID_PARAMETER); WCMD_print_error(); - return; + return errorlevel = ERROR_INVALID_FUNCTION; }
curdir = LocalAlloc (LMEM_FIXED, sizeof (struct env_stack)); @@ -1892,18 +1896,19 @@ void WCMD_pushd (const WCHAR *args) LocalFree(curdir); LocalFree(thisdir); WINE_ERR ("out of memory\n"); - return; + return errorlevel = ERROR_INVALID_FUNCTION; }
/* Change directory using CD code with /D parameter */ lstrcpyW(quals, L"/D"); GetCurrentDirectoryW (1024, thisdir); - errorlevel = NO_ERROR; - WCMD_setshow_default(args); - if (errorlevel) { + + return_code = WCMD_setshow_default(args); + if (return_code != NO_ERROR) + { LocalFree(curdir); LocalFree(thisdir); - return; + return errorlevel = ERROR_INVALID_FUNCTION; } else { curdir -> next = pushd_directories; curdir -> strings = thisdir; @@ -1914,6 +1919,7 @@ void WCMD_pushd (const WCHAR *args) } pushd_directories = curdir; } + return errorlevel = return_code; }
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 8d5926580d9..eb6abb14dea 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -508,12 +508,12 @@ FAILURE 1 SUCCESS 0 SUCCESS 0 --- success/failure for PUSHD/POPD commands -@todo_wine@SUCCESS 0 SUCCESS 0 +SUCCESS 0 +FAILURE 1 +SUCCESS 666 @todo_wine@FAILURE 1 -@todo_wine@SUCCESS 666 -@todo_wine@FAILURE 1 -@todo_wine@--- success/failure for DIR command +--- success/failure for DIR command FAILURE 1 FAILURE 1 SUCCESS 0 diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 0ca14e9f2ac..93620f05656 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -188,7 +188,7 @@ void WCMD_output_asis_stderr (const WCHAR *message); void WCMD_pause (void); void WCMD_popd (void); void WCMD_print_error (void); -void WCMD_pushd (const WCHAR *args); +RETURN_CODE WCMD_pushd(const WCHAR *args); void WCMD_remove_dir (WCHAR *command); RETURN_CODE WCMD_rename(void); void WCMD_run_program (WCHAR *command, BOOL called); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index dc7da5979be..f8a08878fcb 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1909,7 +1909,7 @@ static RETURN_CODE execute_single_command(const WCHAR *command) WCMD_volume (FALSE, parms_start); break; case WCMD_PUSHD: - WCMD_pushd(parms_start); + return_code = WCMD_pushd(parms_start); break; case WCMD_POPD: WCMD_popd();
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146791
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/winegstreamer/wg_transform.c:131 error: patch failed: dlls/winegstreamer/wg_transform.c:82 error: patch failed: dlls/winegstreamer/wg_transform.c:61 error: patch failed: dlls/winegstreamer/wg_transform.c:53 error: patch failed: programs/cmd/tests/test_builtins.cmd.exp:508 Task: Patch failed to apply
=== debian11 (build log) ===
error: patch failed: dlls/winegstreamer/wg_transform.c:131 error: patch failed: dlls/winegstreamer/wg_transform.c:82 error: patch failed: dlls/winegstreamer/wg_transform.c:61 error: patch failed: dlls/winegstreamer/wg_transform.c:53 error: patch failed: programs/cmd/tests/test_builtins.cmd.exp:508 Task: Patch failed to apply
=== debian11b (build log) ===
error: patch failed: dlls/winegstreamer/wg_transform.c:131 error: patch failed: dlls/winegstreamer/wg_transform.c:82 error: patch failed: dlls/winegstreamer/wg_transform.c:61 error: patch failed: dlls/winegstreamer/wg_transform.c:53 error: patch failed: programs/cmd/tests/test_builtins.cmd.exp:508 Task: Patch failed to apply