mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libwinpr-utils: improved command-line API
This commit is contained in:
@@ -33,9 +33,9 @@
|
||||
#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_BOOL 0x00000008
|
||||
|
||||
#define COMMAND_LINE_ALIAS 0x00000100
|
||||
#define COMMAND_LINE_FINAL_ARGUMENT 0x00000100
|
||||
|
||||
/* Command-Line Argument Output Flags */
|
||||
|
||||
@@ -65,6 +65,13 @@
|
||||
#define COMMAND_LINE_ERROR_9 -1009
|
||||
#define COMMAND_LINE_ERROR_10 -1010
|
||||
|
||||
/* Command-Line Macros */
|
||||
|
||||
#define CommandLineSwitchStart(_arg) if (0) { }
|
||||
#define CommandLineSwitchCase(_arg, _name) else if (strcmp(_arg->Name, _name) == 0)
|
||||
#define CommandLineSwitchDefault(_arg) else
|
||||
#define CommandLineSwitchEnd(_arg)
|
||||
|
||||
typedef struct _COMMAND_LINE_ARGUMENT_A COMMAND_LINE_ARGUMENT_A;
|
||||
typedef struct _COMMAND_LINE_ARGUMENT_W COMMAND_LINE_ARGUMENT_W;
|
||||
|
||||
@@ -74,6 +81,7 @@ struct _COMMAND_LINE_ARGUMENT_A
|
||||
DWORD Flags;
|
||||
LPSTR Value;
|
||||
LPCSTR Alias;
|
||||
LPCSTR Text;
|
||||
};
|
||||
|
||||
struct _COMMAND_LINE_ARGUMENT_W
|
||||
@@ -82,6 +90,7 @@ struct _COMMAND_LINE_ARGUMENT_W
|
||||
DWORD Flags;
|
||||
LPWSTR Value;
|
||||
LPCWSTR Alias;
|
||||
LPCWSTR Text;
|
||||
};
|
||||
|
||||
#ifdef UNICODE
|
||||
@@ -99,6 +108,8 @@ WINPR_API int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_A
|
||||
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);
|
||||
|
||||
WINPR_API COMMAND_LINE_ARGUMENT_A* CommandLineFindNextArgumentA(COMMAND_LINE_ARGUMENT_A* argument);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define CommandLineClearArguments CommandLineClearArgumentsW
|
||||
#define CommandLineParseArguments CommandLineParseArgumentsW
|
||||
|
||||
@@ -108,11 +108,19 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
sigil = (char*) &argv[i][sigil_index];
|
||||
length = strlen(argv[i]);
|
||||
|
||||
if ((sigil[sigil_index] == '/') && (flags & COMMAND_LINE_SIGIL_SLASH))
|
||||
if ((sigil[0] == '/') && (flags & COMMAND_LINE_SIGIL_SLASH))
|
||||
{
|
||||
sigil_length = 1;
|
||||
}
|
||||
else if ((sigil[sigil_index] == '-') && (flags & COMMAND_LINE_SIGIL_DASH))
|
||||
else if ((sigil[0] == '-') && (flags & COMMAND_LINE_SIGIL_DASH))
|
||||
{
|
||||
sigil_length = 1;
|
||||
}
|
||||
else if ((sigil[0] == '+') && (flags & COMMAND_LINE_SIGIL_PLUS_MINUS))
|
||||
{
|
||||
sigil_length = 1;
|
||||
}
|
||||
else if ((sigil[0] == '-') && (flags & COMMAND_LINE_SIGIL_PLUS_MINUS))
|
||||
{
|
||||
sigil_length = 1;
|
||||
}
|
||||
@@ -143,7 +151,6 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
separator_index = (separator - argv[i]);
|
||||
|
||||
keyword_length = (separator - keyword);
|
||||
printf("option: %.*s ", keyword_length, keyword);
|
||||
|
||||
value_index = separator_index + separator_length;
|
||||
value = (char*) &argv[i][value_index];
|
||||
@@ -155,7 +162,6 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
separator_index = -1;
|
||||
|
||||
keyword_length = (length - keyword_index);
|
||||
printf("option: %.*s ", keyword_length, keyword);
|
||||
|
||||
value_index = -1;
|
||||
value = NULL;
|
||||
@@ -209,6 +215,17 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
options[j].Value = (LPSTR) 1;
|
||||
options[j].Flags |= COMMAND_LINE_VALUE_PRESENT;
|
||||
}
|
||||
else if (options[j].Flags & COMMAND_LINE_VALUE_BOOL)
|
||||
{
|
||||
if (sigil[0] == '+')
|
||||
options[j].Value = (LPSTR) 1;
|
||||
else if (sigil[0] == '-')
|
||||
options[j].Value = (LPSTR) 0;
|
||||
else
|
||||
options[j].Value = (LPSTR) 1;
|
||||
|
||||
options[j].Flags |= COMMAND_LINE_VALUE_PRESENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -285,3 +302,15 @@ COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMENT_W* optio
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
COMMAND_LINE_ARGUMENT_A* CommandLineFindNextArgumentA(COMMAND_LINE_ARGUMENT_A* argument)
|
||||
{
|
||||
COMMAND_LINE_ARGUMENT_A* nextArgument;
|
||||
|
||||
nextArgument = &argument[1];
|
||||
|
||||
if (nextArgument->Name == NULL)
|
||||
return NULL;
|
||||
|
||||
return nextArgument;
|
||||
}
|
||||
|
||||
@@ -6,23 +6,51 @@
|
||||
const char* testArgv[] =
|
||||
{
|
||||
"mstsc.exe",
|
||||
"+z",
|
||||
"/w:1024",
|
||||
"/h:768",
|
||||
"/bpp:32",
|
||||
"/admin",
|
||||
"/multimon",
|
||||
"+fonts",
|
||||
"-wallpaper",
|
||||
"/v:localhost:3389"
|
||||
};
|
||||
|
||||
COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{
|
||||
{ "w", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL },
|
||||
{ "h", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL },
|
||||
{ "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL },
|
||||
{ "admin", COMMAND_LINE_VALUE_FLAG, NULL, "console" },
|
||||
{ "multimon", COMMAND_LINE_VALUE_FLAG, NULL, NULL },
|
||||
{ "v", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL },
|
||||
{ "?", COMMAND_LINE_VALUE_FLAG, NULL, "help" },
|
||||
{ NULL, 0, NULL, NULL }
|
||||
{ "w", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "width" },
|
||||
{ "h", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "height" },
|
||||
{ "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, "fullscreen" },
|
||||
{ "bpp", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "session bpp (color depth)" },
|
||||
{ "v", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "destination server" },
|
||||
{ "admin", COMMAND_LINE_VALUE_FLAG, NULL, "console", "admin (or console) session" },
|
||||
{ "multimon", COMMAND_LINE_VALUE_FLAG, NULL, NULL, "multi-monitor" },
|
||||
{ "a", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "addin" },
|
||||
{ "u", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "username" },
|
||||
{ "p", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "password" },
|
||||
{ "d", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "domain" },
|
||||
{ "z", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "compression" },
|
||||
{ "audio", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "audio output mode" },
|
||||
{ "mic", COMMAND_LINE_VALUE_FLAG, NULL, NULL, "audio input (microphone)" },
|
||||
{ "fonts", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "smooth fonts (cleartype)" },
|
||||
{ "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "desktop composition" },
|
||||
{ "window-drag", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "full window drag" },
|
||||
{ "menu-anims", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "menu animations" },
|
||||
{ "themes", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "themes" },
|
||||
{ "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "wallpaper" },
|
||||
{ "codec", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "codec" },
|
||||
{ "nego", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "protocol security negotiation" },
|
||||
{ "sec", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "force specific protocol security" },
|
||||
{ "sec-rdp", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "rdp protocol security" },
|
||||
{ "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "tls protocol security" },
|
||||
{ "sec-nla", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "nla protocol security" },
|
||||
{ "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, NULL, "nla extended protocol security" },
|
||||
{ "cert-name", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, "certificate name" },
|
||||
{ "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, "ignore certificate" },
|
||||
{ "ver", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_FINAL_ARGUMENT, NULL, "version", "print version" },
|
||||
{ "?", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_FINAL_ARGUMENT, NULL, "help", "print help" },
|
||||
{ NULL, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
#define testArgc (sizeof(testArgv) / sizeof(testArgv[0]))
|
||||
@@ -31,9 +59,10 @@ int TestCmdLine(int argc, char* argv[])
|
||||
{
|
||||
int status;
|
||||
DWORD flags;
|
||||
int width, height;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
|
||||
flags = COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SEPARATOR_COLON;
|
||||
flags = COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_SIGIL_PLUS_MINUS;
|
||||
status = CommandLineParseArgumentsA(testArgc, testArgv, args, flags);
|
||||
|
||||
if (status != 0)
|
||||
@@ -90,6 +119,22 @@ int TestCmdLine(int argc, char* argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
arg = CommandLineFindArgumentA(args, "fonts");
|
||||
|
||||
if (!arg->Value)
|
||||
{
|
||||
printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
arg = CommandLineFindArgumentA(args, "wallpaper");
|
||||
|
||||
if (arg->Value)
|
||||
{
|
||||
printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
arg = CommandLineFindArgumentA(args, "?");
|
||||
|
||||
if (arg->Value)
|
||||
@@ -98,5 +143,43 @@ int TestCmdLine(int argc, char* argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
arg = args;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
|
||||
continue;
|
||||
|
||||
printf("Argument: %s\n", arg->Name);
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "v")
|
||||
{
|
||||
|
||||
}
|
||||
CommandLineSwitchCase(arg, "w")
|
||||
{
|
||||
width = atoi(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "h")
|
||||
{
|
||||
height = atoi(arg->Value);
|
||||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CommandLineSwitchEnd(arg)
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
||||
if ((width != 1024) || (height != 768))
|
||||
{
|
||||
printf("Unexpected width and height: Actual: (%dx%d), Expected: (%dx%d)\n", width, height, 1024, 768);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user