mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 20:03:12 +00:00
[CMD][CMDUTILS][REPLACE] Make 'replace' command external (#7097)
JIRA issue: CORE-9444 - Delete 'replace' internal command. - Add 'replace' external command into base/applications/cmdutils/replace folder. - Add control break handler.
This commit is contained in:
parent
3dcae2ce0c
commit
1ffce3eb6d
57 changed files with 1786 additions and 870 deletions
282
base/applications/cmdutils/replace/util.c
Normal file
282
base/applications/cmdutils/replace/util.c
Normal file
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Replace Command
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Internal helpers. See cmd/internal.c
|
||||
* COPYRIGHT: Copyright Samuel Erdtman (samuel@erdtman.se)
|
||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#include "replace.h"
|
||||
|
||||
BOOL bCtrlBreak = FALSE; /* Ctrl-Break or Ctrl-C hit */
|
||||
|
||||
/*
|
||||
* Helper function for getting the current path from drive
|
||||
* without changing the drive. Return code: 0 = ok, 1 = fail.
|
||||
* 'InPath' can have any size; if the two first letters are
|
||||
* not a drive with ':' it will get the current path on
|
||||
* the current drive exactly as GetCurrentDirectory() does.
|
||||
*/
|
||||
INT
|
||||
GetRootPath(
|
||||
IN LPCTSTR InPath,
|
||||
OUT LPTSTR OutPath,
|
||||
IN INT size)
|
||||
{
|
||||
if (InPath[0] && InPath[1] == _T(':'))
|
||||
{
|
||||
INT t = 0;
|
||||
|
||||
if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9')))
|
||||
{
|
||||
t = (InPath[0] - _T('0')) + 28;
|
||||
}
|
||||
else if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z')))
|
||||
{
|
||||
t = (InPath[0] - _T('a')) + 1;
|
||||
}
|
||||
else if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z')))
|
||||
{
|
||||
t = (InPath[0] - _T('A')) + 1;
|
||||
}
|
||||
|
||||
return (_tgetdcwd(t, OutPath, size) == NULL);
|
||||
}
|
||||
|
||||
/* Get current directory */
|
||||
return !GetCurrentDirectory(size, OutPath);
|
||||
}
|
||||
|
||||
/*
|
||||
* Takes a path in and returns it with the correct case of the letters
|
||||
*/
|
||||
VOID GetPathCase( TCHAR * Path, TCHAR * OutPath)
|
||||
{
|
||||
UINT i = 0;
|
||||
TCHAR TempPath[MAX_PATH];
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
_tcscpy(TempPath, _T(""));
|
||||
_tcscpy(OutPath, _T(""));
|
||||
|
||||
for(i = 0; i < _tcslen(Path); i++)
|
||||
{
|
||||
if (Path[i] != _T('\\'))
|
||||
{
|
||||
_tcsncat(TempPath, &Path[i], 1);
|
||||
if (i != _tcslen(Path) - 1)
|
||||
continue;
|
||||
}
|
||||
/* Handle the base part of the path different.
|
||||
Because if you put it into findfirstfile, it will
|
||||
return your current folder */
|
||||
if (_tcslen(TempPath) == 2 && TempPath[1] == _T(':'))
|
||||
{
|
||||
_tcscat(OutPath, TempPath);
|
||||
_tcscat(OutPath, _T("\\"));
|
||||
_tcscat(TempPath, _T("\\"));
|
||||
}
|
||||
else
|
||||
{
|
||||
hFind = FindFirstFile(TempPath,&FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
_tcscpy(OutPath, Path);
|
||||
return;
|
||||
}
|
||||
_tcscat(TempPath, _T("\\"));
|
||||
_tcscat(OutPath, FindFileData.cFileName);
|
||||
_tcscat(OutPath, _T("\\"));
|
||||
FindClose(hFind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if a file exists (is accessible)
|
||||
*/
|
||||
BOOL IsExistingFile(IN LPCTSTR pszPath)
|
||||
{
|
||||
DWORD attr = GetFileAttributes(pszPath);
|
||||
return ((attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
BOOL IsExistingDirectory(IN LPCTSTR pszPath)
|
||||
{
|
||||
DWORD attr = GetFileAttributes(pszPath);
|
||||
return ((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
INT FilePromptYNA (UINT resID)
|
||||
{
|
||||
TCHAR szMsg[RC_STRING_MAX_SIZE];
|
||||
// TCHAR cKey = 0;
|
||||
// LPTSTR szKeys = _T("yna");
|
||||
|
||||
TCHAR szIn[10];
|
||||
LPTSTR p;
|
||||
|
||||
if (resID != 0)
|
||||
ConOutResPrintf (resID);
|
||||
|
||||
/* preliminary fix */
|
||||
ConInString(szIn, 10);
|
||||
|
||||
_tcsupr (szIn);
|
||||
for (p = szIn; _istspace (*p); p++)
|
||||
;
|
||||
|
||||
LoadString(NULL, STRING_COPY_OPTION, szMsg, ARRAYSIZE(szMsg));
|
||||
|
||||
if (_tcsncmp(p, &szMsg[0], 1) == 0)
|
||||
return PROMPT_YES;
|
||||
else if (_tcsncmp(p, &szMsg[1], 1) == 0)
|
||||
return PROMPT_NO;
|
||||
else if (_tcsncmp(p, &szMsg[2], 1) == 0)
|
||||
return PROMPT_ALL;
|
||||
#if 0
|
||||
else if (*p == _T('\03'))
|
||||
return PROMPT_BREAK;
|
||||
#endif
|
||||
|
||||
return PROMPT_NO;
|
||||
|
||||
/* unfinished solution */
|
||||
#if 0
|
||||
RemoveBreakHandler();
|
||||
ConInDisable();
|
||||
|
||||
do
|
||||
{
|
||||
ConInKey (&ir);
|
||||
cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar);
|
||||
if (_tcschr (szKeys, cKey[0]) == NULL)
|
||||
cKey = 0;
|
||||
}
|
||||
while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
|
||||
(ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) ||
|
||||
(ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL));
|
||||
|
||||
AddBreakHandler();
|
||||
ConInEnable();
|
||||
|
||||
if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
|
||||
((ir.Event.KeyEvent.wVirtualKeyCode == _T('C')) &&
|
||||
(ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))))
|
||||
return PROMPT_BREAK;
|
||||
|
||||
return PROMPT_YES;
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID ConInString(LPTSTR lpInput, DWORD dwLength)
|
||||
{
|
||||
DWORD dwOldMode;
|
||||
DWORD dwRead = 0;
|
||||
HANDLE hFile;
|
||||
|
||||
LPTSTR p;
|
||||
PCHAR pBuf;
|
||||
|
||||
#ifdef _UNICODE
|
||||
pBuf = (PCHAR)malloc(dwLength - 1);
|
||||
#else
|
||||
pBuf = lpInput;
|
||||
#endif
|
||||
ZeroMemory(lpInput, dwLength * sizeof(TCHAR));
|
||||
hFile = GetStdHandle(STD_INPUT_HANDLE);
|
||||
GetConsoleMode(hFile, &dwOldMode);
|
||||
|
||||
SetConsoleMode(hFile, ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
|
||||
|
||||
ReadFile(hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL);
|
||||
|
||||
#ifdef _UNICODE
|
||||
MultiByteToWideChar(GetConsoleCP(), 0, pBuf, dwRead, lpInput, dwLength - 1);
|
||||
free(pBuf);
|
||||
#endif
|
||||
for (p = lpInput; *p; p++)
|
||||
{
|
||||
if (*p == _T('\r')) // Terminate at the carriage-return.
|
||||
{
|
||||
*p = _T('\0');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetConsoleMode(hFile, dwOldMode);
|
||||
}
|
||||
|
||||
VOID msg_pause(VOID)
|
||||
{
|
||||
ConOutResPuts(STRING_ERROR_D_PAUSEMSG);
|
||||
}
|
||||
|
||||
VOID __cdecl ConFormatMessage(PCON_STREAM Stream, DWORD MessageId, ...)
|
||||
{
|
||||
INT Len;
|
||||
va_list arg_ptr;
|
||||
|
||||
va_start(arg_ptr, MessageId);
|
||||
Len = ConMsgPrintfV(Stream,
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
MessageId,
|
||||
LANG_USER_DEFAULT,
|
||||
&arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
|
||||
if (Len <= 0)
|
||||
ConResPrintf(Stream, STRING_CONSOLE_ERROR, MessageId);
|
||||
}
|
||||
|
||||
VOID ConOutChar(TCHAR c)
|
||||
{
|
||||
ConWrite(StdOut, &c, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* get a character out-of-band and honor Ctrl-Break characters
|
||||
*/
|
||||
TCHAR
|
||||
cgetchar (VOID)
|
||||
{
|
||||
HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
|
||||
INPUT_RECORD irBuffer;
|
||||
DWORD dwRead;
|
||||
|
||||
do
|
||||
{
|
||||
ReadConsoleInput (hInput, &irBuffer, 1, &dwRead);
|
||||
if ((irBuffer.EventType == KEY_EVENT) &&
|
||||
(irBuffer.Event.KeyEvent.bKeyDown != FALSE))
|
||||
{
|
||||
if (irBuffer.Event.KeyEvent.dwControlKeyState &
|
||||
(LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
{
|
||||
if (irBuffer.Event.KeyEvent.wVirtualKeyCode == 'C')
|
||||
{
|
||||
bCtrlBreak = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
|
||||
(irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_MENU) ||
|
||||
(irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL))
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (TRUE);
|
||||
|
||||
#ifndef _UNICODE
|
||||
return irBuffer.Event.KeyEvent.uChar.AsciiChar;
|
||||
#else
|
||||
return irBuffer.Event.KeyEvent.uChar.UnicodeChar;
|
||||
#endif /* _UNICODE */
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue