command line parsing progress

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@2910 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2010-03-05 03:36:35 +00:00
parent 1318b87478
commit f3ccaf2158
3 changed files with 168 additions and 13 deletions
+3 -6
View File
@@ -1860,20 +1860,17 @@ NTSTATUS PhIsExecutablePacked(
typedef struct _PH_COMMAND_LINE_OPTION
{
ULONG Id;
PWSTR LongName;
PWSTR ShortName;
PWSTR Name;
BOOLEAN AcceptArgument;
PWSTR Description;
} PH_COMMAND_LINE_OPTION, *PPH_COMMAND_LINE_OPTION;
typedef VOID (NTAPI *PPH_COMMAND_LINE_CALLBACK)(
__in PPH_COMMAND_LINE_OPTION Option,
__in PPH_STRING Value,
__in_opt PPH_STRING Value,
__in PVOID Context
);
VOID PhParseCommandLine(
BOOLEAN PhParseCommandLine(
__in PPH_STRINGREF CommandLine,
__in PPH_COMMAND_LINE_OPTION Options,
__in ULONG NumberOfOptions,
+21
View File
@@ -313,6 +313,27 @@ FORCEINLINE PH_STRINGREF PhCreateStringRef(
return string;
}
FORCEINLINE INT PhStringRefCompare2(
__in PPH_STRINGREF String1,
__in PWSTR String2,
__in BOOLEAN IgnoreCase
)
{
if (!IgnoreCase)
return wcsncmp(String1->Buffer, String2, String1->Length / sizeof(WCHAR));
else
return wcsnicmp(String1->Buffer, String2, String1->Length / sizeof(WCHAR));
}
FORCEINLINE BOOLEAN PhStringRefEquals2(
__in PPH_STRINGREF String1,
__in PWSTR String2,
__in BOOLEAN IgnoreCase
)
{
return PhStringRefCompare2(String1, String2, IgnoreCase) == 0;
}
/**
* A Unicode string object.
*/
+144 -7
View File
@@ -1724,7 +1724,7 @@ CleanupExit:
return status;
}
VOID PhParseCommandLine(
BOOLEAN PhParseCommandLine(
__in PPH_STRINGREF CommandLine,
__in PPH_COMMAND_LINE_OPTION Options,
__in ULONG NumberOfOptions,
@@ -1733,19 +1733,156 @@ VOID PhParseCommandLine(
)
{
ULONG i;
ULONG j;
ULONG length;
PPH_STRING_BUILDER stringBuilder;
BOOLEAN cont;
ULONG optionNameLength;
PH_STRINGREF optionName;
PPH_COMMAND_LINE_OPTION option;
PPH_STRING_BUILDER optionValueBuilder;
BOOLEAN inEscape;
BOOLEAN inQuote;
BOOLEAN endOfValue;
if (CommandLine->Length == 0)
return TRUE;
stringBuilder = PhCreateStringBuilder(10);
i = 0;
length = CommandLine->Length / 2;
while (TRUE)
while (i < length)
{
// Check for an option specifier.
if (i < length)
// Skip spaces.
while (i < length && CommandLine->Buffer[i] == ' ')
i++;
if (option && option->AcceptArgument)
{
// Read the value.
optionValueBuilder = PhCreateStringBuilder(10);
inEscape = FALSE;
inQuote = FALSE;
endOfValue = FALSE;
for (; i < length; i++)
{
if (inEscape)
{
switch (CommandLine->Buffer[i])
{
case '\\':
case '\"':
case '\'':
PhStringBuilderAppendEx(
optionValueBuilder,
&CommandLine->Buffer[i],
2
);
break;
default:
// Unknown escape. Append both the backslash and
// escape character.
PhStringBuilderAppendEx(
optionValueBuilder,
&CommandLine->Buffer[i - 1],
4
);
break;
}
inEscape = FALSE;
}
else
{
switch (CommandLine->Buffer[i])
{
case '\"':
case '\'':
if (!inQuote)
inQuote = TRUE;
else
inQuote = FALSE;
break;
default:
if (CommandLine->Buffer[i] == ' ' && !inQuote)
{
endOfValue = TRUE;
}
else
{
PhStringBuilderAppendEx(
optionValueBuilder,
&CommandLine->Buffer[i],
2
);
}
break;
}
}
if (endOfValue)
break;
}
cont = Callback(option, optionValueBuilder->String, Context);
PhDereferenceObject(optionValueBuilder);
if (!cont)
return TRUE;
option = NULL;
}
else if (CommandLine->Buffer[i] == '-')
{
// Read the option (only alphanumeric characters allowed).
optionNameLength = 0;
// Skip the dash.
i++;
for (; i < length; i++)
{
if (!iswalnum(CommandLine->Buffer[i]))
break;
}
optionName.Buffer = &CommandLine->Buffer[i - optionNameLength];
optionName.Length = optionNameLength * 2;
// Find the option descriptor.
option = NULL;
for (j = 0; j < NumberOfOptions; j++)
{
if (PhStringRefEquals2(&optionName, Options[i].Name, FALSE))
{
option = &Options[i];
break;
}
}
if (!option)
return FALSE;
if (!option->AcceptArgument)
{
cont = Callback(option, NULL, Context);
if (!cont)
return TRUE;
option = NULL;
}
}
}
return TRUE;
}