forked from Mirrors/wine-wine
regedit: Tokenize command-line input.
Signed-off-by: Hugh McMaster <hugh.mcmaster@outlook.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>oldstable
parent
493b5aab22
commit
53c9a78970
|
@ -56,81 +56,23 @@ static const char *usage =
|
||||||
"regedit.\n";
|
"regedit.\n";
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
|
ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
|
||||||
} REGEDIT_ACTION;
|
} REGEDIT_ACTION;
|
||||||
|
|
||||||
/******************************************************************************
|
static BOOL PerformRegAction(REGEDIT_ACTION action, char **argv, int *i)
|
||||||
* 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(CHAR **command_line, CHAR *file_name)
|
|
||||||
{
|
|
||||||
CHAR *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, "regedit: Unexpected end of file name!\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while(s[0] && !isspace(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] && isspace(s[0])) {
|
|
||||||
s++;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
(*command_line) += pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
|
|
||||||
{
|
{
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ACTION_ADD: {
|
case ACTION_ADD: {
|
||||||
CHAR filename[MAX_PATH];
|
char *filename = argv[*i];
|
||||||
FILE *reg_file;
|
FILE *reg_file;
|
||||||
|
|
||||||
get_file_name(&s, filename);
|
|
||||||
if (!filename[0]) {
|
if (!filename[0]) {
|
||||||
fprintf(stderr, "regedit: No file name was specified\n");
|
fprintf(stderr, "regedit: No file name was specified\n");
|
||||||
fprintf(stderr,usage);
|
fprintf(stderr,usage);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(filename[0]) {
|
if (filename[0]) {
|
||||||
char* realname = NULL;
|
char* realname = NULL;
|
||||||
|
|
||||||
if (strcmp(filename, "-") == 0)
|
if (strcmp(filename, "-") == 0)
|
||||||
|
@ -167,14 +109,12 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
|
||||||
HeapFree(GetProcessHeap(),0,realname);
|
HeapFree(GetProcessHeap(),0,realname);
|
||||||
fclose(reg_file);
|
fclose(reg_file);
|
||||||
}
|
}
|
||||||
get_file_name(&s, filename);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_DELETE: {
|
case ACTION_DELETE: {
|
||||||
CHAR reg_key_name[KEY_MAX_LEN];
|
char *reg_key_name = argv[*i];
|
||||||
|
|
||||||
get_file_name(&s, reg_key_name);
|
|
||||||
if (!reg_key_name[0]) {
|
if (!reg_key_name[0]) {
|
||||||
fprintf(stderr, "regedit: No registry key was specified for removal\n");
|
fprintf(stderr, "regedit: No registry key was specified for removal\n");
|
||||||
fprintf(stderr,usage);
|
fprintf(stderr,usage);
|
||||||
|
@ -188,11 +128,9 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_EXPORT: {
|
case ACTION_EXPORT: {
|
||||||
CHAR filename[MAX_PATH];
|
char *filename = argv[*i];
|
||||||
WCHAR* filenameW;
|
WCHAR* filenameW;
|
||||||
|
|
||||||
filename[0] = '\0';
|
|
||||||
get_file_name(&s, filename);
|
|
||||||
if (!filename[0]) {
|
if (!filename[0]) {
|
||||||
fprintf(stderr, "regedit: No filename was specified\n");
|
fprintf(stderr, "regedit: No filename was specified\n");
|
||||||
fprintf(stderr,usage);
|
fprintf(stderr,usage);
|
||||||
|
@ -200,11 +138,10 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
|
||||||
}
|
}
|
||||||
|
|
||||||
filenameW = GetWideString(filename);
|
filenameW = GetWideString(filename);
|
||||||
if (s[0]) {
|
if (filenameW[0]) {
|
||||||
CHAR reg_key_name[KEY_MAX_LEN];
|
char *reg_key_name = argv[++(*i)];
|
||||||
WCHAR* reg_key_nameW;
|
WCHAR* reg_key_nameW;
|
||||||
|
|
||||||
get_file_name(&s, reg_key_name);
|
|
||||||
reg_key_nameW = GetWideString(reg_key_name);
|
reg_key_nameW = GetWideString(reg_key_name);
|
||||||
export_registry_key(filenameW, reg_key_nameW, REG_FORMAT_4);
|
export_registry_key(filenameW, reg_key_nameW, REG_FORMAT_4);
|
||||||
HeapFree(GetProcessHeap(), 0, reg_key_nameW);
|
HeapFree(GetProcessHeap(), 0, reg_key_nameW);
|
||||||
|
@ -222,83 +159,117 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL ProcessCmdLine(LPSTR lpCmdLine)
|
char *get_token(char *input, char **next)
|
||||||
{
|
{
|
||||||
REGEDIT_ACTION action = ACTION_UNDEF;
|
char *ch = input;
|
||||||
LPSTR s = lpCmdLine; /* command line pointer */
|
char *str;
|
||||||
CHAR ch = *s; /* current character */
|
|
||||||
|
|
||||||
while (ch && ((ch == '-') || (ch == '/'))) {
|
while (*ch && isspace(*ch))
|
||||||
char chu;
|
ch++;
|
||||||
char ch2;
|
|
||||||
|
|
||||||
s++;
|
str = ch;
|
||||||
ch = *s;
|
|
||||||
if (!ch || isspace(ch))
|
if (*ch == '"') {
|
||||||
{
|
ch++;
|
||||||
/* '-' is a file name. It indicates we should use stdin */
|
str = ch;
|
||||||
s--;
|
for (;;) {
|
||||||
|
while (*ch && (*ch != '"'))
|
||||||
|
ch++;
|
||||||
|
|
||||||
|
if (!*ch)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (*(ch - 1) == '\\') {
|
||||||
|
ch++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ch2 = *(s+1);
|
}
|
||||||
chu = toupper(ch);
|
else {
|
||||||
if (!ch2 || isspace(ch2)) {
|
while (*ch && !isspace(*ch))
|
||||||
if (chu == 'S' || chu == 'V') {
|
ch++;
|
||||||
/* ignore these switches */
|
}
|
||||||
} else {
|
|
||||||
switch (chu) {
|
if (*ch) {
|
||||||
case 'D':
|
*ch = 0;
|
||||||
action = ACTION_DELETE;
|
ch++;
|
||||||
break;
|
}
|
||||||
case 'E':
|
|
||||||
action = ACTION_EXPORT;
|
*next = ch;
|
||||||
break;
|
return str;
|
||||||
case '?':
|
}
|
||||||
fprintf(stderr,usage);
|
|
||||||
exit(0);
|
BOOL ProcessCmdLine(LPSTR lpCmdLine)
|
||||||
break;
|
{
|
||||||
default:
|
char *s = lpCmdLine;
|
||||||
fprintf(stderr, "regedit: Invalid or unrecognized switch [/%c]\n", chu);
|
char **argv;
|
||||||
exit(1);
|
char *tok;
|
||||||
break;
|
int argc = 0, i = 1;
|
||||||
}
|
REGEDIT_ACTION action = ACTION_ADD;
|
||||||
}
|
|
||||||
s++;
|
if (!*lpCmdLine)
|
||||||
} else {
|
return FALSE;
|
||||||
if (ch2 == ':') {
|
|
||||||
switch (chu) {
|
while (*s) {
|
||||||
case 'L':
|
if (isspace(*s))
|
||||||
/* fall through */
|
i++;
|
||||||
case 'R':
|
s++;
|
||||||
s += 2;
|
}
|
||||||
while (*s && !isspace(*s)) {
|
|
||||||
s++;
|
s = lpCmdLine;
|
||||||
}
|
argv = HeapAlloc(GetProcessHeap(), 0, i * sizeof(char *));
|
||||||
break;
|
|
||||||
default:
|
for (i = 0; *s; i++)
|
||||||
fprintf(stderr, "regedit: Invalid or unrecognized switch [/%c]\n", chu);
|
{
|
||||||
exit(1);
|
tok = get_token(s, &s);
|
||||||
break;
|
argv[i] = HeapAlloc(GetProcessHeap(), 0, strlen(tok) + 1);
|
||||||
}
|
strcpy(argv[i], tok);
|
||||||
} else {
|
argc++;
|
||||||
/* this is a file name, starting from '/' */
|
}
|
||||||
s--;
|
|
||||||
break;
|
for (i = 0; i < argc; i++)
|
||||||
}
|
{
|
||||||
}
|
if (argv[i][0] != '/' && argv[i][0] != '-')
|
||||||
/* skip spaces to the next parameter */
|
break; /* No flags specified. */
|
||||||
ch = *s;
|
|
||||||
while (ch && isspace(ch)) {
|
if (!argv[i][1] && argv[i][0] == '-')
|
||||||
s++;
|
break; /* '-' is a filename. It indicates we should use stdin. */
|
||||||
ch = *s;
|
|
||||||
|
if (argv[i][1] && argv[i][2] && argv[i][2] != ':')
|
||||||
|
break; /* This is a file path beginning with '/'. */
|
||||||
|
|
||||||
|
switch (toupper(argv[i][1]))
|
||||||
|
{
|
||||||
|
case '?':
|
||||||
|
fprintf(stderr, usage);
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
action = ACTION_DELETE;
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
action = ACTION_EXPORT;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
case 'R':
|
||||||
|
/* unhandled */;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
case 'V':
|
||||||
|
/* ignored */;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "regedit: Invalid switch [%ls]\n", argv[i]);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*s && action == ACTION_UNDEF)
|
PerformRegAction(action, argv, &i);
|
||||||
action = ACTION_ADD;
|
|
||||||
|
|
||||||
if (action == ACTION_UNDEF)
|
for (i = 0; i < argc; i++)
|
||||||
return FALSE;
|
HeapFree(GetProcessHeap(), 0, argv[i]);
|
||||||
|
HeapFree(GetProcessHeap(), 0, argv);
|
||||||
|
|
||||||
return PerformRegAction(action, s);
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue