libwinpr-utils: extended command-line parsing api

This commit is contained in:
Marc-André Moreau 2012-11-02 00:58:32 -04:00
parent f62180ec2a
commit 37886515a0
3 changed files with 128 additions and 19 deletions

View File

@ -23,12 +23,26 @@
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
/* Command-Line Argument Flags */
#define COMMAND_LINE_INPUT_FLAG_MASK 0x0000FFFF
#define COMMAND_LINE_OUTPUT_FLAG_MASK 0xFFFF0000
#define COMMAND_LINE_VALUE_FLAG 0x00000001
#define COMMAND_LINE_VALUE_REQUIRED 0x00000002
#define COMMAND_LINE_VALUE_OPTIONAL 0x00000004
#define COMMAND_LINE_VALUE_BOOLEAN 0x00000008
#define COMMAND_LINE_VALUE_PRESENT 0x80000001
#define COMMAND_LINE_VALUE_PRESENT 0x80000000
/* Command-Line Parsing Flags */
#define COMMAND_LINE_SIGIL_SLASH 0x00000001
#define COMMAND_LINE_SIGIL_DASH 0x00000002
#define COMMAND_LINE_SIGIL_DOUBLE_DASH 0x00000004
#define COMMAND_LINE_SEPARATOR_COLON 0x00000100
#define COMMAND_LINE_SEPARATOR_EQUAL 0x00000200
struct _COMMAND_LINE_ARGUMENT_A
{
@ -52,13 +66,23 @@ typedef struct _COMMAND_LINE_ARGUMENT_W COMMAND_LINE_ARGUMENT_W;
#define COMMAND_LINE_ARGUMENT COMMAND_LINE_ARGUMENT_A
#endif
WINPR_API int CommandLineClearArgumentsA(COMMAND_LINE_ARGUMENT_A* options);
WINPR_API int CommandLineClearArgumentsW(COMMAND_LINE_ARGUMENT_W* options);
WINPR_API int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* options, DWORD flags);
WINPR_API int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W* options, DWORD flags);
WINPR_API COMMAND_LINE_ARGUMENT_A* CommandLineFindArgumentA(COMMAND_LINE_ARGUMENT_A* options, LPCSTR Name);
WINPR_API COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMENT_W* options, LPCWSTR Name);
#ifdef UNICODE
#define CommandLineClearArguments CommandLineClearArgumentsW
#define CommandLineParseArguments CommandLineParseArgumentsW
#define CommandLineFindArgument CommandLineFindArgumentW
#else
#define CommandLineClearArguments CommandLineClearArgumentsA
#define CommandLineParseArguments CommandLineParseArgumentsA
#define CommandLineFindArgument CommandLineFindArgumentA
#endif
#endif /* WINPR_CMDLINE_H */

View File

@ -103,20 +103,34 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
for (i = 1; i < argc; i++)
{
sigil_index = 0;
sigil_length = 0;
sigil = (char*) &argv[i][sigil_index];
length = strlen(argv[i]);
if (sigil[sigil_index] == '/')
if ((sigil[sigil_index] == '/') && (flags & COMMAND_LINE_SIGIL_SLASH))
{
sigil_length = 1;
}
else if ((sigil[sigil_index] == '-') && (flags & COMMAND_LINE_SIGIL_DASH))
{
sigil_length = 1;
}
if (sigil_length > 0)
{
if (length < (sigil_length + 1))
return -1;
keyword_index = sigil_index + sigil_length;
keyword = (char*) &argv[i][keyword_index];
separator = strchr(keyword, ':');
separator = NULL;
if ((flags & COMMAND_LINE_SEPARATOR_COLON) && (!separator))
separator = strchr(keyword, ':');
if ((flags & COMMAND_LINE_SEPARATOR_EQUAL) && (!separator))
separator = strchr(keyword, '=');
if (separator)
{
@ -188,3 +202,55 @@ int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W*
{
return 0;
}
int CommandLineClearArgumentsA(COMMAND_LINE_ARGUMENT_A* options)
{
int i;
for (i = 0; options[i].Name != NULL; i++)
{
options[i].Flags &= COMMAND_LINE_INPUT_FLAG_MASK;
options[i].Value = NULL;
}
return 0;
}
int CommandLineClearArgumentsW(COMMAND_LINE_ARGUMENT_W* options)
{
int i;
for (i = 0; options[i].Name != NULL; i++)
{
options[i].Flags &= COMMAND_LINE_INPUT_FLAG_MASK;
options[i].Value = NULL;
}
return 0;
}
COMMAND_LINE_ARGUMENT_A* CommandLineFindArgumentA(COMMAND_LINE_ARGUMENT_A* options, LPCSTR Name)
{
int i;
for (i = 0; options[i].Name != NULL; i++)
{
if (strcmp(options[i].Name, Name) == 0)
return &options[i];
}
return NULL;
}
COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMENT_W* options, LPCWSTR Name)
{
int i;
for (i = 0; options[i].Name != NULL; i++)
{
if (_wcscmp(options[i].Name, Name) == 0)
return &options[i];
}
return NULL;
}

View File

@ -15,42 +15,61 @@ const char* testArgv[] =
COMMAND_LINE_ARGUMENT_A args[] =
{
{ "w", COMMAND_LINE_VALUE_REQUIRED },
{ "h", COMMAND_LINE_VALUE_REQUIRED },
{ "f", COMMAND_LINE_VALUE_FLAG },
{ "admin", COMMAND_LINE_VALUE_FLAG },
{ "multimon", COMMAND_LINE_VALUE_FLAG },
{ "v", COMMAND_LINE_VALUE_REQUIRED },
{ "?", COMMAND_LINE_VALUE_FLAG },
{ NULL, 0 }
{ "w", COMMAND_LINE_VALUE_REQUIRED, NULL },
{ "h", COMMAND_LINE_VALUE_REQUIRED, NULL },
{ "f", COMMAND_LINE_VALUE_FLAG, NULL },
{ "admin", COMMAND_LINE_VALUE_FLAG, NULL },
{ "multimon", COMMAND_LINE_VALUE_FLAG, NULL },
{ "v", COMMAND_LINE_VALUE_REQUIRED, NULL },
{ "?", COMMAND_LINE_VALUE_FLAG, NULL },
{ NULL, 0, NULL }
};
#define testArgc (sizeof(testArgv) / sizeof(testArgv[0]))
int TestCmdLine(int argc, char* argv[])
{
if (CommandLineParseArgumentsA(testArgc, testArgv, args, 0) != 0)
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
flags = COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SEPARATOR_COLON;
if (CommandLineParseArgumentsA(testArgc, testArgv, args, flags) != 0)
return -1;
if (strcmp("1024", args[0].Value) != 0)
arg = CommandLineFindArgumentA(args, "w");
if (strcmp("1024", arg->Value) != 0)
return -1;
if (strcmp("768", args[1].Value) != 0)
arg = CommandLineFindArgumentA(args, "h");
if (strcmp("768", arg->Value) != 0)
return -1;
if (args[2].Value)
arg = CommandLineFindArgumentA(args, "f");
if (arg->Value)
return -1;
if (!args[3].Value)
arg = CommandLineFindArgumentA(args, "admin");
if (!arg->Value)
return -1;
if (!args[4].Value)
arg = CommandLineFindArgumentA(args, "multimon");
if (!arg->Value)
return -1;
if (strcmp("localhost:3389", args[5].Value) != 0)
arg = CommandLineFindArgumentA(args, "v");
if (strcmp("localhost:3389", arg->Value) != 0)
return -1;
if (args[6].Value)
arg = CommandLineFindArgumentA(args, "?");
if (arg->Value)
return -1;
return 0;