[ros-diffs] [jmorlan] 39973: 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.

jmorlan at svn.reactos.org jmorlan at svn.reactos.org
Thu Mar 12 05:37:02 CET 2009


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/doskey/doskey.c?rev=39973&r1=39972&r2=39973&view=diff
==============================================================================
--- 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/doskey/doskey.h?rev=39973&view=auto
==============================================================================
--- 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/doskey/doskey.rbuild?rev=39973&r1=39972&r2=39973&view=diff
==============================================================================
--- 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/doskey/doskey.rc?rev=39973&r1=39972&r2=39973&view=diff
==============================================================================
--- 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/doskey/lang/en-US.rc?rev=39973&view=auto
==============================================================================
--- 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



More information about the Ros-diffs mailing list