[PATCH 2/2] regedit: Clean up command-line argument handling
Hugh McMaster
hugh.mcmaster at outlook.com
Fri Jun 17 04:06:01 CDT 2016
Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
programs/regedit/main.c | 2 +-
programs/regedit/regedit.c | 307 ++++++++++++++-------------------------------
2 files changed, 96 insertions(+), 213 deletions(-)
diff --git a/programs/regedit/main.c b/programs/regedit/main.c
index 3f9e432..36f7454 100644
--- a/programs/regedit/main.c
+++ b/programs/regedit/main.c
@@ -139,7 +139,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, WCHAR *lpCmdLi
MSG msg;
HACCEL hAccel;
- if (ProcessCmdLine(lpCmdLine)) {
+ if (ProcessCmdLine(GetCommandLineW())) {
return 0;
}
diff --git a/programs/regedit/regedit.c b/programs/regedit/regedit.c
index 3ce25ce..f2af1c0 100644
--- a/programs/regedit/regedit.c
+++ b/programs/regedit/regedit.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
+#include <shellapi.h>
#include "wine/unicode.h"
#include "regproc.h"
@@ -57,7 +58,7 @@ static const char *usage =
"regedit.\n";
typedef enum {
- ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
+ ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
} REGEDIT_ACTION;
@@ -66,154 +67,63 @@ const CHAR *getAppName(void)
return "regedit";
}
-/******************************************************************************
- * Copies file name from command line string to the buffer.
- * Rewinds the command line string pointer to the next non-space character
- * after the file name.
- * Buffer contains an empty string if no filename was found;
- *
- * params:
- * command_line - command line current position pointer
- * where *s[0] is the first symbol of the file name.
- * file_name - buffer to write the file name to.
- */
-static void get_file_name(WCHAR **command_line, WCHAR *file_name)
-{
- WCHAR *s = *command_line;
- int pos = 0; /* position of pointer "s" in *command_line */
- file_name[0] = 0;
-
- if (!s[0]) {
- return;
- }
-
- if (s[0] == '"') {
- s++;
- (*command_line)++;
- while(s[0] != '"') {
- if (!s[0]) {
- fprintf(stderr,"%s: Unexpected end of file name!\n",
- getAppName());
- exit(1);
- }
- s++;
- pos++;
- }
- } else {
- while(s[0] && !isspaceW(s[0])) {
- s++;
- pos++;
- }
- }
- memcpy(file_name, *command_line, pos * sizeof((*command_line)[0]));
- /* Terminate the string and remove the trailing backslash */
- if (pos > 0 && file_name[pos - 1] == '\\') {
- file_name[pos - 1] = '\0';
- } else {
- file_name[pos] = '\0';
- }
-
- if (s[0]) {
- s++;
- pos++;
- }
- while(s[0] && isspaceW(s[0])) {
- s++;
- pos++;
- }
- (*command_line) += pos;
-}
-
-static BOOL PerformRegAction(REGEDIT_ACTION action, WCHAR *s)
+static BOOL PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i)
{
switch (action) {
case ACTION_ADD: {
- WCHAR filename[MAX_PATH];
- FILE *reg_file;
+ WCHAR *filename = argv[*i];
WCHAR hyphenW[] = {'-',0};
+ WCHAR *realname = NULL;
+ FILE *reg_file;
- get_file_name(&s, filename);
- if (!filename[0]) {
- fprintf(stderr,"%s: No file name was specified\n", getAppName());
- fprintf(stderr,usage);
- exit(1);
+ if (!strcmpW(filename, hyphenW))
+ {
+ reg_file = stdin;
}
+ else
+ {
+ int size;
+ WCHAR rb_modeW[] = {'r','b',0};
- while(filename[0]) {
- WCHAR *realname = NULL;
-
- if (!strcmpW(filename, hyphenW))
+ size = SearchPathW(NULL, filename, NULL, 0, NULL, NULL);
+ if (size > 0)
{
- reg_file = stdin;
+ realname = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
+ size = SearchPathW(NULL, filename, NULL, size, realname, NULL);
}
- else
+ if (size == 0)
{
- int size;
- WCHAR rb_modeW[] = {'r','b',0};
-
- size = SearchPathW(NULL, filename, NULL, 0, NULL, NULL);
- if (size > 0)
- {
- realname = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
- size = SearchPathW(NULL, filename, NULL, size, realname, NULL);
- }
- if (size == 0)
- {
- fprintf(stderr, "%s: File not found \"%ls\" (%d)\n",
- getAppName(), filename, GetLastError());
- exit(1);
- }
- reg_file = _wfopen(realname, rb_modeW);
- if (reg_file == NULL)
- {
- perror("");
- fprintf(stderr, "%s: Can't open file \"%ls\"\n", getAppName(), filename);
- exit(1);
- }
+ fprintf(stderr, "regedit: File not found \"%ls\" (%d)\n",
+ filename, GetLastError());
+ exit(1);
}
- import_registry_file(reg_file);
- if (realname)
+ reg_file = _wfopen(realname, rb_modeW);
+ if (reg_file == NULL)
{
- HeapFree(GetProcessHeap(),0,realname);
- fclose(reg_file);
+ perror("");
+ fprintf(stderr, "regedit: Can't open file \"%ls\"\n", filename);
+ exit(1);
}
- get_file_name(&s, filename);
}
- break;
- }
- case ACTION_DELETE: {
- WCHAR reg_key_name[KEY_MAX_LEN];
-
- get_file_name(&s, reg_key_name);
- if (!reg_key_name[0]) {
- fprintf(stderr,"%s: No registry key was specified for removal\n",
- getAppName());
- fprintf(stderr,usage);
- exit(1);
- } else {
- delete_registry_key(reg_key_name);
+ import_registry_file(reg_file);
+ if (realname)
+ {
+ fclose(reg_file);
+ HeapFree(GetProcessHeap(),0,realname);
}
break;
}
+ case ACTION_DELETE:
+ delete_registry_key(argv[*i]);
+ break;
case ACTION_EXPORT: {
- WCHAR filename[MAX_PATH];
-
- filename[0] = '\0';
- get_file_name(&s, filename);
- if (!filename[0]) {
- fprintf(stderr,"%s: No file name was specified\n", getAppName());
- fprintf(stderr,usage);
- exit(1);
- }
+ WCHAR *filename = argv[*i];
+ WCHAR *reg_key_name = argv[++(*i)];
- if (s[0]) {
- WCHAR reg_key_name[KEY_MAX_LEN];
-
- get_file_name(&s, reg_key_name);
+ if (reg_key_name)
export_registry_key(filename, reg_key_name, REG_FORMAT_4);
- } else {
+ else
export_registry_key(filename, NULL, REG_FORMAT_4);
- }
break;
}
default:
@@ -224,99 +134,72 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, WCHAR *s)
return TRUE;
}
-/**
- * Process unknown switch.
- *
- * Params:
- * chu - the switch character in upper-case.
- * s - the command line string where s points to the switch character.
- */
-static void error_unknown_switch(WCHAR chu, WCHAR *s)
-{
- if (isalphaW(chu)) {
- fprintf(stderr,"%s: Undefined switch /%lc!\n", getAppName(), chu);
- } else {
- fprintf(stderr,"%s: Alphabetic character is expected after '%lc' "
- "in switch specification\n", getAppName(), *(s - 1));
- }
- exit(1);
-}
-
BOOL ProcessCmdLine(WCHAR *lpCmdLine)
{
- REGEDIT_ACTION action = ACTION_UNDEF;
- WCHAR *s = lpCmdLine; /* command line pointer */
- WCHAR ch = *s; /* current character */
+ WCHAR **argv;
+ int argc, i;
+ REGEDIT_ACTION action = ACTION_ADD;
+
+ argv = CommandLineToArgvW(lpCmdLine, &argc);
+
+ if (argc == 1)
+ return FALSE;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] != '/' && argv[i][0] != '-')
+ break; /* No flags specified. */
- while (ch && ((ch == '-') || (ch == '/'))) {
- WCHAR chu;
- WCHAR ch2;
+ if (!argv[i][1] && argv[i][0] == '-')
+ break; /* '-' is a filename. It indicates we should use stdin. */
- s++;
- ch = *s;
- if (!ch || isspaceW(ch))
+ if (argv[i][2] && argv[i][2] != ':')
+ break; /* This is a file path beginning with '/'. */
+
+ switch (toupperW(argv[i][1]))
{
- /* '-' is a file name. It indicates we should use stdin */
- s--;
+ case '?':
+ fprintf(stderr, usage);
+ exit(0);
break;
- }
- ch2 = *(s+1);
- chu = toupperW(ch);
- if (!ch2 || isspaceW(ch2)) {
- if (chu == 'S' || chu == 'V') {
- /* ignore these switches */
- } else {
- switch (chu) {
- case 'D':
- action = ACTION_DELETE;
- break;
- case 'E':
- action = ACTION_EXPORT;
- break;
- case '?':
- fprintf(stderr,usage);
- exit(0);
- break;
- default:
- error_unknown_switch(chu, s);
- break;
- }
- }
- s++;
- } else {
- if (ch2 == ':') {
- switch (chu) {
- case 'L':
- /* fall through */
- case 'R':
- s += 2;
- while (*s && !isspaceW(*s)) {
- s++;
- }
- break;
- default:
- error_unknown_switch(chu, s);
- break;
- }
- } else {
- /* this is a file name, starting from '/' */
- s--;
- break;
- }
- }
- /* skip spaces to the next parameter */
- ch = *s;
- while (ch && isspaceW(ch)) {
- s++;
- ch = *s;
+ case 'S':
+ case 'V':
+ /* ignored */;
+ break;
+ case 'D':
+ action = ACTION_DELETE;
+ break;
+ case 'E':
+ action = ACTION_EXPORT;
+ break;
+ case 'L':
+ case 'R':
+ /* unhandled */;
+ break;
+ default:
+ fprintf(stderr, "regedit: Invalid switch [%ls]\n", argv[i]);
+ exit(1);
}
}
- if (*s && action == ACTION_UNDEF)
- action = ACTION_ADD;
+ if (i == argc)
+ {
+ switch (action)
+ {
+ case ACTION_ADD:
+ case ACTION_EXPORT:
+ fprintf(stderr, "regedit: No file name was specified\n\n");
+ break;
+ case ACTION_DELETE:
+ fprintf(stderr,"regedit: No registry key was specified for removal\n\n");
+ break;
+ }
+ fprintf(stderr, usage);
+ exit(1);
+ }
- if (action == ACTION_UNDEF)
- return FALSE;
+ for (; i < argc; i++)
+ PerformRegAction(action, argv, &i);
- return PerformRegAction(action, s);
+ return TRUE;
}
--
2.7.4
More information about the wine-patches
mailing list