Author: jmorlan
Date: Thu Mar 12 07:37:01 2009
New Revision: 39973
URL:
http://svn.reactos.org/svn/reactos?rev=39973&view=rev
Log:
Instead of having DOSKEY print something when it successfully adds an alias, print an
error message when it fails. Also implement some options that were missing.
Added:
trunk/reactos/base/applications/cmdutils/doskey/doskey.h (with props)
trunk/reactos/base/applications/cmdutils/doskey/lang/
trunk/reactos/base/applications/cmdutils/doskey/lang/en-US.rc (with props)
Modified:
trunk/reactos/base/applications/cmdutils/doskey/doskey.c
trunk/reactos/base/applications/cmdutils/doskey/doskey.rbuild
trunk/reactos/base/applications/cmdutils/doskey/doskey.rc
Modified: trunk/reactos/base/applications/cmdutils/doskey/doskey.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/doskey/doskey.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/doskey/doskey.c [iso-8859-1] Thu Mar 12
07:37:01 2009
@@ -1,71 +1,95 @@
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
-
-static VOID
-PrintAlias (VOID)
-{
- LPTSTR Aliases;
- LPTSTR ptr;
- DWORD len;
-
- len = GetConsoleAliasesLength(_T("cmd.exe"));
- if (len <= 0)
- return;
-
- /* allocate memory for an extra \0 char to make parsing easier */
- ptr = HeapAlloc(GetProcessHeap(), 0, (len + sizeof(TCHAR)));
- if (!ptr)
- return;
-
- Aliases = ptr;
-
- ZeroMemory(Aliases, len + sizeof(TCHAR));
-
- if (GetConsoleAliases(Aliases, len, _T("cmd.exe")) != 0)
- {
- while (*Aliases != '\0')
- {
- _tprintf(_T("%s\n"), Aliases);
- Aliases = Aliases + lstrlen(Aliases);
- Aliases++;
- }
- }
- HeapFree(GetProcessHeap(), 0 , ptr);
-}
-
-INT SetMacro (LPTSTR param)
-{
- LPTSTR ptr, text;
-
- while (*param == _T(' '))
- param++;
+#include "doskey.h"
+
+#define MAX_STRING 2000
+TCHAR szStringBuf[MAX_STRING];
+LPTSTR pszExeName = _T("cmd.exe");
+
+static VOID SetInsert(DWORD dwFlag)
+{
+ DWORD dwMode;
+ HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
+ GetConsoleMode(hConsole, &dwMode);
+ dwMode |= ENABLE_EXTENDED_FLAGS;
+ SetConsoleMode(hConsole, (dwMode & ~ENABLE_INSERT_MODE) | dwFlag);
+}
+
+static VOID PrintHistory(VOID)
+{
+ DWORD Length = GetConsoleCommandHistoryLength(pszExeName);
+ /* On Windows, the ANSI version of GetConsoleCommandHistory requires
+ * a buffer twice as large as the actual history length. */
+ BYTE HistBuf[Length * (sizeof(WCHAR) / sizeof(TCHAR))];
+ TCHAR *Hist = (TCHAR *)HistBuf;
+ TCHAR *HistEnd = (TCHAR *)&HistBuf[Length];
+
+ if (GetConsoleCommandHistory(Hist, sizeof HistBuf, pszExeName))
+ for (; Hist < HistEnd; Hist += _tcslen(Hist) + 1)
+ _tprintf(_T("%s\n"), Hist);
+}
+
+static INT SetMacro(LPTSTR definition)
+{
+ TCHAR *name, *nameend, *text, temp;
+
+ name = definition;
+ while (*name == _T(' '))
+ name++;
/* error if no '=' found */
- if ((ptr = _tcschr (param, _T('='))) == 0)
- return 1;
-
- text = ptr + 1;
- while (*text == _T(' '))
- text++;
-
- while (ptr > param && ptr[-1] == _T(' '))
- ptr--;
-
- /* Split rest into name and substitute */
- *ptr++ = _T('\0');
-
- if (*param == _T('\0') || _tcschr(param, _T(' ')))
- return 1;
-
- _tprintf(_T("%s, %s\n"), text, param);
-
- if (ptr[0] == _T('\0'))
- AddConsoleAlias(param, NULL, _T("cmd.exe"));
- else
- AddConsoleAlias(param, text, _T("cmd.exe"));
-
- return 0;
+ if ((nameend = _tcschr(name, _T('='))) != NULL)
+ {
+ text = nameend + 1;
+ while (*text == _T(' '))
+ text++;
+
+ while (nameend > name && nameend[-1] == _T(' '))
+ nameend--;
+
+ /* Split rest into name and substitute */
+ temp = *nameend;
+ *nameend = _T('\0');
+ /* Don't allow spaces in the name, since such a macro would be unusable */
+ if (!_tcschr(name, _T(' ')) && AddConsoleAlias(name, text,
pszExeName))
+ return 0;
+ *nameend = temp;
+ }
+
+ LoadString(GetModuleHandle(NULL), IDS_INVALID_MACRO_DEF, szStringBuf, MAX_STRING);
+ _tprintf(szStringBuf, definition);
+ return 1;
+}
+
+static VOID PrintMacros(LPTSTR pszExeName, LPTSTR Indent)
+{
+ DWORD Length = GetConsoleAliasesLength(pszExeName);
+ BYTE AliasBuf[Length];
+ TCHAR *Alias = (TCHAR *)AliasBuf;
+ TCHAR *AliasEnd = (TCHAR *)&AliasBuf[Length];
+
+ if (GetConsoleAliases(Alias, sizeof AliasBuf, pszExeName))
+ for (; Alias < AliasEnd; Alias += _tcslen(Alias) + 1)
+ _tprintf(_T("%s%s\n"), Indent, Alias);
+}
+
+static VOID PrintAllMacros(VOID)
+{
+ DWORD Length = GetConsoleAliasExesLength();
+ BYTE ExeNameBuf[Length];
+ TCHAR *ExeName = (TCHAR *)ExeNameBuf;
+ TCHAR *ExeNameEnd = (TCHAR *)&ExeNameBuf[Length];
+
+ if (GetConsoleAliasExes(ExeName, sizeof ExeNameBuf))
+ {
+ for (; ExeName < ExeNameEnd; ExeName += _tcslen(ExeName) + 1)
+ {
+ _tprintf(_T("[%s]\n"), ExeName);
+ PrintMacros(ExeName, _T(" "));
+ _tprintf(_T("\n"));
+ }
+ }
}
static VOID ReadFromFile(LPTSTR param)
@@ -73,10 +97,16 @@
FILE* fp;
TCHAR line[MAX_PATH];
- /* Skip the "/macrofile=" prefix */
- param += 11;
-
fp = _tfopen(param, _T("r"));
+ if (!fp)
+ {
+#ifdef UNICODE
+ _wperror(param);
+#else
+ perror(param);
+#endif
+ return;
+ }
while ( _fgetts(line, MAX_PATH, fp) != NULL)
{
@@ -85,53 +115,122 @@
if (*end == _T('\n'))
*end = _T('\0');
- SetMacro(line);
+ if (*line)
+ SetMacro(line);
}
fclose(fp);
return;
}
+/* Get the start and end of the next command-line argument. */
+static BOOL GetArg(TCHAR **pStart, TCHAR **pEnd)
+{
+ BOOL bInQuotes = FALSE;
+ TCHAR *p = *pEnd;
+ p += _tcsspn(p, _T(" \t"));
+ if (!*p)
+ return FALSE;
+ *pStart = p;
+ do
+ {
+ if (!bInQuotes && (*p == _T(' ') || *p == _T('\t')))
+ break;
+ bInQuotes ^= (*p++ == _T('"'));
+ } while (*p);
+ *pEnd = p;
+ return TRUE;
+}
+
+/* Remove starting and ending quotes from a string, if present */
+static LPTSTR RemoveQuotes(LPTSTR str)
+{
+ TCHAR *end;
+ if (*str == _T('"') && *(end = str + _tcslen(str) - 1) ==
_T('"'))
+ {
+ str++;
+ *end = _T('\0');
+ }
+ return str;
+}
+
int
-_tmain (int argc, LPTSTR argv[])
-{
- if (argc < 2)
- return 0;
-
- if (argv[1][0] == '/')
- {
- if (_tcsnicmp(argv[1], _T("/macrofile"), 10) == 0)
- ReadFromFile(argv[1]);
- if (_tcscmp(argv[1], _T("/macros")) == 0)
- PrintAlias();
- }
- else
- {
- /* Get the full command line using GetCommandLine().
- We can't just pass argv[1] here, because then a parameter like
"gotoroot=cd \" wouldn't be passed completely. */
- TCHAR* szCommandLine = GetCommandLine();
-
- /* Skip the application name */
- if(*szCommandLine == '\"')
- {
- do
- {
- szCommandLine++;
- }
- while(*szCommandLine != '\"');
- szCommandLine++;
+_tmain(VOID)
+{
+ /* Get the full command line using GetCommandLine(). We can't just use argv,
+ * because then a parameter like "gotoroot=cd \" wouldn't be passed
completely. */
+ TCHAR *pArgStart;
+ TCHAR *pArgEnd = GetCommandLine();
+
+ /* Skip the application name */
+ GetArg(&pArgStart, &pArgEnd);
+
+ while (GetArg(&pArgStart, &pArgEnd))
+ {
+ /* NUL-terminate this argument to make processing easier */
+ TCHAR tmp = *pArgEnd;
+ *pArgEnd = _T('\0');
+
+ if (!_tcscmp(pArgStart, _T("/?")))
+ {
+ LoadString(GetModuleHandle(NULL), IDS_HELP, szStringBuf, MAX_STRING);
+ _tprintf(szStringBuf);
+ break;
+ }
+ else if (!_tcsnicmp(pArgStart, _T("/EXENAME="), 9))
+ {
+ pszExeName = RemoveQuotes(pArgStart + 9);
+ }
+ else if (!_tcsicmp(pArgStart, _T("/H")) ||
+ !_tcsicmp(pArgStart, _T("/HISTORY")))
+ {
+ PrintHistory();
+ }
+ else if (!_tcsnicmp(pArgStart, _T("/LISTSIZE="), 10))
+ {
+ SetConsoleNumberOfCommands(_ttoi(pArgStart + 10), pszExeName);
+ }
+ else if (!_tcsicmp(pArgStart, _T("/REINSTALL")))
+ {
+ ExpungeConsoleCommandHistory(pszExeName);
+ }
+ else if (!_tcsicmp(pArgStart, _T("/INSERT")))
+ {
+ SetInsert(ENABLE_INSERT_MODE);
+ }
+ else if (!_tcsicmp(pArgStart, _T("/OVERSTRIKE")))
+ {
+ SetInsert(0);
+ }
+ else if (!_tcsicmp(pArgStart, _T("/M")) ||
+ !_tcsicmp(pArgStart, _T("/MACROS")))
+ {
+ PrintMacros(pszExeName, _T(""));
+ }
+ else if (!_tcsnicmp(pArgStart, _T("/M:"), 3) ||
+ !_tcsnicmp(pArgStart, _T("/MACROS:"), 8))
+ {
+ LPTSTR exe = RemoveQuotes(_tcschr(pArgStart, _T(':')) + 1);
+ if (!_tcsicmp(exe, _T("ALL")))
+ PrintAllMacros();
+ else
+ PrintMacros(exe, _T(""));
+ }
+ else if (!_tcsnicmp(pArgStart, _T("/MACROFILE="), 11))
+ {
+ ReadFromFile(RemoveQuotes(pArgStart + 11));
}
else
{
- do
- {
- szCommandLine++;
- }
- while(*szCommandLine != ' ');
- }
-
- /* Skip the leading whitespace and pass the command line to SetMacro */
- SetMacro(szCommandLine + _tcsspn(szCommandLine, _T(" \t")));
+ /* This is the beginning of a macro definition. It includes
+ * the entire remainder of the line, so first put back the
+ * character that we replaced with NUL. */
+ *pArgEnd = tmp;
+ return SetMacro(pArgStart);
+ }
+
+ if (!tmp) break;
+ pArgEnd++;
}
return 0;
Added: trunk/reactos/base/applications/cmdutils/doskey/doskey.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/doskey/doskey.h (added)
+++ trunk/reactos/base/applications/cmdutils/doskey/doskey.h [iso-8859-1] Thu Mar 12
07:37:01 2009
@@ -1,0 +1,67 @@
+#define IDS_HELP 0
+#define IDS_INVALID_MACRO_DEF 1
+
+#ifndef RC_INVOKED
+
+#ifdef UNICODE
+#define TNAME(x) x##W
+#else
+#define TNAME(x) x##A
+#endif
+
+/* Missing from include/psdk/wincon.h */
+#ifndef ENABLE_INSERT_MODE
+#define ENABLE_INSERT_MODE 0x20
+#endif
+#ifndef ENABLE_EXTENDED_FLAGS
+#define ENABLE_EXTENDED_FLAGS 0x80
+#endif
+
+/* Undocumented APIs */
+#ifndef AddConsoleAlias
+BOOL WINAPI AddConsoleAliasA(LPSTR, LPSTR, LPSTR);
+BOOL WINAPI AddConsoleAliasW(LPWSTR, LPWSTR, LPWSTR);
+#define AddConsoleAlias TNAME(AddConsoleAlias)
+#endif
+#ifndef ExpungeConsoleCommandHistory
+BOOL WINAPI ExpungeConsoleCommandHistoryA(LPSTR);
+BOOL WINAPI ExpungeConsoleCommandHistoryW(LPWSTR);
+#define ExpungeConsoleCommandHistory TNAME(ExpungeConsoleCommandHistory)
+#endif
+#ifndef GetConsoleAliases
+DWORD WINAPI GetConsoleAliasesA(LPSTR, DWORD, LPSTR);
+DWORD WINAPI GetConsoleAliasesW(LPWSTR, DWORD, LPWSTR);
+#define GetConsoleAliases TNAME(GetConsoleAliases)
+#endif
+#ifndef GetConsoleAliasesLength
+DWORD WINAPI GetConsoleAliasesLengthA(LPSTR);
+DWORD WINAPI GetConsoleAliasesLengthW(LPWSTR);
+#define GetConsoleAliasesLength TNAME(GetConsoleAliasesLength)
+#endif
+#ifndef GetConsoleAliasExes
+DWORD WINAPI GetConsoleAliasExesA(LPSTR, DWORD);
+DWORD WINAPI GetConsoleAliasExesW(LPWSTR, DWORD);
+#define GetConsoleAliasExes TNAME(GetConsoleAliasExes)
+#endif
+#ifndef GetConsoleAliasExesLength
+DWORD WINAPI GetConsoleAliasExesLengthA(VOID);
+DWORD WINAPI GetConsoleAliasExesLengthW(VOID);
+#define GetConsoleAliasExesLength TNAME(GetConsoleAliasExesLength)
+#endif
+#ifndef GetConsoleCommandHistory
+DWORD WINAPI GetConsoleCommandHistoryA(LPSTR, DWORD, LPSTR);
+DWORD WINAPI GetConsoleCommandHistoryW(LPWSTR, DWORD, LPWSTR);
+#define GetConsoleCommandHistory TNAME(GetConsoleCommandHistory)
+#endif
+#ifndef GetConsoleCommandHistoryLength
+DWORD WINAPI GetConsoleCommandHistoryLengthA(LPSTR);
+DWORD WINAPI GetConsoleCommandHistoryLengthW(LPWSTR);
+#define GetConsoleCommandHistoryLength TNAME(GetConsoleCommandHistoryLength)
+#endif
+#ifndef SetConsoleNumberOfCommands
+BOOL WINAPI SetConsoleNumberOfCommandsA(DWORD, LPSTR);
+BOOL WINAPI SetConsoleNumberOfCommandsW(DWORD, LPWSTR);
+#define SetConsoleNumberOfCommands TNAME(SetConsoleNumberOfCommands)
+#endif
+
+#endif /* RC_INVOKED */
Propchange: trunk/reactos/base/applications/cmdutils/doskey/doskey.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/base/applications/cmdutils/doskey/doskey.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/doskey/doskey.rbuild [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/doskey/doskey.rbuild [iso-8859-1] Thu Mar 12
07:37:01 2009
@@ -2,6 +2,7 @@
<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
<module name="doskey" type="win32cui"
installbase="system32" installname="doskey.exe"
unicode="yes">
<library>kernel32</library>
+ <library>user32</library>
<file>doskey.c</file>
<file>doskey.rc</file>
</module>
Modified: trunk/reactos/base/applications/cmdutils/doskey/doskey.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/doskey/doskey.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/doskey/doskey.rc [iso-8859-1] Thu Mar 12
07:37:01 2009
@@ -1,7 +1,8 @@
-/* $Id: find.rc 28350 2007-08-15 14:46:36Z fireball $ */
-
#define REACTOS_STR_FILE_DESCRIPTION "W32 doskey command\0"
#define REACTOS_STR_INTERNAL_NAME "doskey\0"
#define REACTOS_STR_ORIGINAL_FILENAME "doskey.exe\0"
#include <reactos/version.rc>
+#include <windows.h>
+#include "doskey.h"
+#include "lang/en-US.rc"
Added: trunk/reactos/base/applications/cmdutils/doskey/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/doskey/lang/en-US.rc (added)
+++ trunk/reactos/base/applications/cmdutils/doskey/lang/en-US.rc [iso-8859-1] Thu Mar 12
07:37:01 2009
@@ -1,0 +1,27 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_HELP, "Manages command-line editing settings, history, and macros.\n\
+\n\
+DOSKEY [/INSERT | /OVERSTRIKE] [/EXENAME=exe] [/HISTORY] [/LISTSIZE=size]\n\
+ [/REINSTALL] [/MACROS[:exe | :ALL]] [/MACROFILE=file] [macroname=[text]]\n\
+\n\
+ /INSERT Enables insert mode.\n\
+ /OVERSTRIKE Disables insert mode.\n\
+ /EXENAME=exename Sets the name of the program to view/change history\n\
+ and macros for. The default is cmd.exe.\n\
+ /HISTORY Displays the command history.\n\
+ /LISTSIZE=size Sets the number of commands per history buffer.\n\
+ /REINSTALL Clears the command history.\n\
+ /MACROS Displays macro definitions.\n\
+ /MACROS:exename Displays macro definitions for a specific program.\n\
+ /MACROS:ALL Displays macro definitions for all programs.\n\
+ /MACROFILE=filename Loads macro definitions from a file.\n\
+ macroname Specifies the name of a macro to create.\n\
+ text Specifies the replacement text for the macro.\n"
+
+IDS_INVALID_MACRO_DEF, "Invalid macro definition: %s\n"
+
+END
Propchange: trunk/reactos/base/applications/cmdutils/doskey/lang/en-US.rc
------------------------------------------------------------------------------
svn:eol-style = native