|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* WinPR: Windows Portable Runtime
|
|
Packit |
1fb8d4 |
* Command-Line Utils
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
Packit |
1fb8d4 |
* you may not use this file except in compliance with the License.
|
|
Packit |
1fb8d4 |
* You may obtain a copy of the License at
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
1fb8d4 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
1fb8d4 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
1fb8d4 |
* See the License for the specific language governing permissions and
|
|
Packit |
1fb8d4 |
* limitations under the License.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
1fb8d4 |
#include "config.h"
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <winpr/crt.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <winpr/cmdline.h>
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
#include "../log.h"
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
#define TAG WINPR_TAG("commandline")
|
|
Packit Service |
5a9772 |
|
|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* Command-line syntax: some basic concepts:
|
|
Packit |
1fb8d4 |
* https://pythonconquerstheuniverse.wordpress.com/2010/07/25/command-line-syntax-some-basic-concepts/
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* Command-Line Syntax:
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* <sigil><keyword><separator><value>
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* <sigil>: '/' or '-' or ('+' | '-')
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* <keyword>: option, named argument, flag
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* <separator>: ':' or '='
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* <value>: argument value
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
static void log_error(DWORD flags, LPCSTR message, int index, LPCSTR argv)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
if ((flags & COMMAND_LINE_SILENCE_PARSER) == 0)
|
|
Packit Service |
5a9772 |
WLog_ERR(TAG, message, index, argv);
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
int CommandLineParseArgumentsA(int argc, LPSTR* argv, COMMAND_LINE_ARGUMENT_A* options, DWORD flags,
|
|
Packit Service |
5a9772 |
void* context, COMMAND_LINE_PRE_FILTER_FN_A preFilter,
|
|
Packit Service |
5a9772 |
COMMAND_LINE_POST_FILTER_FN_A postFilter)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int i, j;
|
|
Packit |
1fb8d4 |
int status;
|
|
Packit |
1fb8d4 |
int count;
|
|
Packit |
1fb8d4 |
size_t length;
|
|
Packit |
1fb8d4 |
BOOL notescaped;
|
|
Packit |
1fb8d4 |
const char* sigil;
|
|
Packit |
1fb8d4 |
size_t sigil_length;
|
|
Packit |
1fb8d4 |
char* keyword;
|
|
Packit Service |
5a9772 |
size_t keyword_length;
|
|
Packit |
1fb8d4 |
SSIZE_T keyword_index;
|
|
Packit |
1fb8d4 |
char* separator;
|
|
Packit |
1fb8d4 |
char* value;
|
|
Packit |
1fb8d4 |
int toggle;
|
|
Packit |
1fb8d4 |
status = 0;
|
|
Packit |
1fb8d4 |
notescaped = FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!argv)
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (argc == 1)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (flags & COMMAND_LINE_IGN_UNKNOWN_KEYWORD)
|
|
Packit |
1fb8d4 |
status = 0;
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
status = COMMAND_LINE_STATUS_PRINT_HELP;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 1; i < argc; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL found = FALSE;
|
|
Packit |
1fb8d4 |
BOOL escaped = TRUE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (preFilter)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
count = preFilter(context, i, argc, argv);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (count < 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
log_error(flags, "Failed for index %d [%s]: PreFilter rule could not be applied", i,
|
|
Packit Service |
5a9772 |
argv[i]);
|
|
Packit |
1fb8d4 |
status = COMMAND_LINE_ERROR;
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (count > 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
i += (count - 1);
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
sigil = argv[i];
|
|
Packit |
1fb8d4 |
length = strlen(argv[i]);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((sigil[0] == '/') && (flags & COMMAND_LINE_SIGIL_SLASH))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
sigil_length = 1;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if ((sigil[0] == '-') && (flags & COMMAND_LINE_SIGIL_DASH))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
sigil_length = 1;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (length > 2)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if ((sigil[1] == '-') && (flags & COMMAND_LINE_SIGIL_DOUBLE_DASH))
|
|
Packit |
1fb8d4 |
sigil_length = 2;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if ((sigil[0] == '+') && (flags & COMMAND_LINE_SIGIL_PLUS_MINUS))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
sigil_length = 1;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if ((sigil[0] == '-') && (flags & COMMAND_LINE_SIGIL_PLUS_MINUS))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
sigil_length = 1;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if (flags & COMMAND_LINE_SIGIL_NONE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
sigil_length = 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if (flags & COMMAND_LINE_SIGIL_NOT_ESCAPED)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (notescaped)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
log_error(flags, "Failed at index %d [%s]: Unescaped sigil", i, argv[i]);
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_ERROR;
|
|
Packit Service |
5a9772 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
sigil_length = 0;
|
|
Packit |
1fb8d4 |
escaped = FALSE;
|
|
Packit |
1fb8d4 |
notescaped = TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
log_error(flags, "Failed at index %d [%s]: Invalid sigil", i, argv[i]);
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_ERROR;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((sigil_length > 0) || (flags & COMMAND_LINE_SIGIL_NONE) ||
|
|
Packit |
1fb8d4 |
(flags & COMMAND_LINE_SIGIL_NOT_ESCAPED))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (length < (sigil_length + 1))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if ((flags & COMMAND_LINE_IGN_UNKNOWN_KEYWORD))
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_ERROR_NO_KEYWORD;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
keyword_index = sigil_length;
|
|
Packit |
1fb8d4 |
keyword = &argv[i][keyword_index];
|
|
Packit |
1fb8d4 |
toggle = -1;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (flags & COMMAND_LINE_SIGIL_ENABLE_DISABLE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (strncmp(keyword, "enable-", 7) == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
toggle = TRUE;
|
|
Packit |
1fb8d4 |
keyword_index += 7;
|
|
Packit |
1fb8d4 |
keyword = &argv[i][keyword_index];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if (strncmp(keyword, "disable-", 8) == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
toggle = FALSE;
|
|
Packit |
1fb8d4 |
keyword_index += 8;
|
|
Packit |
1fb8d4 |
keyword = &argv[i][keyword_index];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
separator = NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((flags & COMMAND_LINE_SEPARATOR_COLON) && (!separator))
|
|
Packit |
1fb8d4 |
separator = strchr(keyword, ':');
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((flags & COMMAND_LINE_SEPARATOR_EQUAL) && (!separator))
|
|
Packit |
1fb8d4 |
separator = strchr(keyword, '=');
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (separator)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
SSIZE_T separator_index = (separator - argv[i]);
|
|
Packit |
1fb8d4 |
SSIZE_T value_index = separator_index + 1;
|
|
Packit |
1fb8d4 |
keyword_length = (separator - keyword);
|
|
Packit |
1fb8d4 |
value = &argv[i][value_index];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
keyword_length = (length - keyword_index);
|
|
Packit |
1fb8d4 |
value = NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!escaped)
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (j = 0; options[j].Name != NULL; j++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL match = FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (strncmp(options[j].Name, keyword, keyword_length) == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (strlen(options[j].Name) == keyword_length)
|
|
Packit |
1fb8d4 |
match = TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((!match) && (options[j].Alias != NULL))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (strncmp(options[j].Alias, keyword, keyword_length) == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (strlen(options[j].Alias) == keyword_length)
|
|
Packit |
1fb8d4 |
match = TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!match)
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
found = match;
|
|
Packit |
1fb8d4 |
options[j].Index = i;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((flags & COMMAND_LINE_SEPARATOR_SPACE) && ((i + 1) < argc))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL argument;
|
|
Packit |
1fb8d4 |
int value_present = 1;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (flags & COMMAND_LINE_SIGIL_DASH)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (strncmp(argv[i + 1], "-", 1) == 0)
|
|
Packit |
1fb8d4 |
value_present = 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (flags & COMMAND_LINE_SIGIL_DOUBLE_DASH)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (strncmp(argv[i + 1], "--", 2) == 0)
|
|
Packit |
1fb8d4 |
value_present = 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (flags & COMMAND_LINE_SIGIL_SLASH)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (strncmp(argv[i + 1], "/", 1) == 0)
|
|
Packit |
1fb8d4 |
value_present = 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((options[j].Flags & COMMAND_LINE_VALUE_REQUIRED) ||
|
|
Packit |
1fb8d4 |
(options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL))
|
|
Packit |
1fb8d4 |
argument = TRUE;
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
argument = FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (value_present && argument)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
i++;
|
|
Packit |
1fb8d4 |
value = argv[i];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if (!value_present && (options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
value = NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if (!value_present && argument)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
log_error(flags, "Failed at index %d [%s]: Argument required", i, argv[i]);
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_ERROR;
|
|
Packit Service |
5a9772 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!(flags & COMMAND_LINE_SEPARATOR_SPACE))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (value && (options[j].Flags & COMMAND_LINE_VALUE_FLAG))
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
log_error(flags, "Failed at index %d [%s]: Unexpected value", i, argv[i]);
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
|
Packit Service |
5a9772 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (value && (options[j].Flags & COMMAND_LINE_VALUE_FLAG))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
i--;
|
|
Packit |
1fb8d4 |
value = NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!value && (options[j].Flags & COMMAND_LINE_VALUE_REQUIRED))
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
log_error(flags, "Failed at index %d [%s]: Missing value", i, argv[i]);
|
|
Packit |
1fb8d4 |
status = COMMAND_LINE_ERROR_MISSING_VALUE;
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
options[j].Flags |= COMMAND_LINE_ARGUMENT_PRESENT;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (value)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (options[j].Flags & (COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_VALUE_BOOL))
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
log_error(flags, "Failed at index %d [%s]: Unexpected value", i, argv[i]);
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
|
Packit Service |
5a9772 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
options[j].Value = value;
|
|
Packit |
1fb8d4 |
options[j].Flags |= COMMAND_LINE_VALUE_PRESENT;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (options[j].Flags & COMMAND_LINE_VALUE_FLAG)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
options[j].Value = (LPSTR)1;
|
|
Packit |
1fb8d4 |
options[j].Flags |= COMMAND_LINE_VALUE_PRESENT;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if (options[j].Flags & COMMAND_LINE_VALUE_BOOL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (flags & COMMAND_LINE_SIGIL_ENABLE_DISABLE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (toggle == -1)
|
|
Packit |
1fb8d4 |
options[j].Value = BoolValueTrue;
|
|
Packit |
1fb8d4 |
else if (!toggle)
|
|
Packit |
1fb8d4 |
options[j].Value = BoolValueFalse;
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
options[j].Value = BoolValueTrue;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (sigil[0] == '+')
|
|
Packit |
1fb8d4 |
options[j].Value = BoolValueTrue;
|
|
Packit |
1fb8d4 |
else if (sigil[0] == '-')
|
|
Packit |
1fb8d4 |
options[j].Value = BoolValueFalse;
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
options[j].Value = BoolValueTrue;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
options[j].Flags |= COMMAND_LINE_VALUE_PRESENT;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (postFilter)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
count = postFilter(context, &options[j]);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (count < 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
log_error(flags,
|
|
Packit Service |
5a9772 |
"Failed at index %d [%s]: PostFilter rule could not be applied",
|
|
Packit Service |
5a9772 |
i, argv[i]);
|
|
Packit |
1fb8d4 |
status = COMMAND_LINE_ERROR;
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (options[j].Flags & COMMAND_LINE_PRINT)
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_STATUS_PRINT;
|
|
Packit |
1fb8d4 |
else if (options[j].Flags & COMMAND_LINE_PRINT_HELP)
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_STATUS_PRINT_HELP;
|
|
Packit |
1fb8d4 |
else if (options[j].Flags & COMMAND_LINE_PRINT_VERSION)
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_STATUS_PRINT_VERSION;
|
|
Packit |
1fb8d4 |
else if (options[j].Flags & COMMAND_LINE_PRINT_BUILDCONFIG)
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_STATUS_PRINT_BUILDCONFIG;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!found && (flags & COMMAND_LINE_IGN_UNKNOWN_KEYWORD) == 0)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
log_error(flags, "Failed at index %d [%s]: Unexpected keyword", i, argv[i]);
|
|
Packit |
1fb8d4 |
return COMMAND_LINE_ERROR_NO_KEYWORD;
|
|
Packit Service |
5a9772 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
int CommandLineParseArgumentsW(int argc, LPWSTR* argv, COMMAND_LINE_ARGUMENT_W* options,
|
|
Packit Service |
5a9772 |
DWORD flags, void* context, COMMAND_LINE_PRE_FILTER_FN_W preFilter,
|
|
Packit Service |
5a9772 |
COMMAND_LINE_POST_FILTER_FN_W postFilter)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
int CommandLineClearArgumentsA(COMMAND_LINE_ARGUMENT_A* options)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
size_t i;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; options[i].Name != NULL; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
options[i].Flags &= COMMAND_LINE_INPUT_FLAG_MASK;
|
|
Packit |
1fb8d4 |
options[i].Value = NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
int CommandLineClearArgumentsW(COMMAND_LINE_ARGUMENT_W* options)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int i;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; options[i].Name != NULL; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
options[i].Flags &= COMMAND_LINE_INPUT_FLAG_MASK;
|
|
Packit |
1fb8d4 |
options[i].Value = NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
COMMAND_LINE_ARGUMENT_A* CommandLineFindArgumentA(COMMAND_LINE_ARGUMENT_A* options, LPCSTR Name)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int i;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; options[i].Name != NULL; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (strcmp(options[i].Name, Name) == 0)
|
|
Packit |
1fb8d4 |
return &options[i];
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (options[i].Alias != NULL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (strcmp(options[i].Alias, Name) == 0)
|
|
Packit |
1fb8d4 |
return &options[i];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMENT_W* options, LPCWSTR Name)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int i;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; options[i].Name != NULL; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (_wcscmp(options[i].Name, Name) == 0)
|
|
Packit |
1fb8d4 |
return &options[i];
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (options[i].Alias != NULL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (_wcscmp(options[i].Alias, Name) == 0)
|
|
Packit |
1fb8d4 |
return &options[i];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
COMMAND_LINE_ARGUMENT_A* CommandLineFindNextArgumentA(COMMAND_LINE_ARGUMENT_A* argument)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
COMMAND_LINE_ARGUMENT_A* nextArgument;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!argument || !argument->Name)
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
nextArgument = &argument[1];
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (nextArgument->Name == NULL)
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return nextArgument;
|
|
Packit |
1fb8d4 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
char** CommandLineParseCommaSeparatedValuesEx(const char* name, const char* list, size_t* count)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
char** p;
|
|
Packit Service |
5a9772 |
char* str;
|
|
Packit Service |
5a9772 |
size_t nArgs;
|
|
Packit Service |
5a9772 |
size_t index;
|
|
Packit Service |
5a9772 |
size_t nCommas;
|
|
Packit Service |
5a9772 |
size_t prefix, len;
|
|
Packit Service |
5a9772 |
nCommas = 0;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (count == NULL)
|
|
Packit Service |
5a9772 |
return NULL;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
*count = 0;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (!list)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
if (name)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
size_t len = strlen(name);
|
|
Packit Service |
5a9772 |
p = (char**)calloc(2UL + len, sizeof(char*));
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (p)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
char* dst = (char*)&p[1];
|
|
Packit Service |
5a9772 |
p[0] = dst;
|
|
Packit Service |
5a9772 |
sprintf_s(dst, len + 1, "%s", name);
|
|
Packit Service |
5a9772 |
*count = 1;
|
|
Packit Service |
5a9772 |
return p;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
return NULL;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
const char* it = list;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
while ((it = strchr(it, ',')) != NULL)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
it++;
|
|
Packit Service |
5a9772 |
nCommas++;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
nArgs = nCommas + 1;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (name)
|
|
Packit Service |
5a9772 |
nArgs++;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
prefix = (nArgs + 1UL) * sizeof(char*);
|
|
Packit Service |
5a9772 |
len = strlen(list);
|
|
Packit Service |
5a9772 |
p = (char**)calloc(len + prefix + 1, sizeof(char*));
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (!p)
|
|
Packit Service |
5a9772 |
return NULL;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
str = &((char*)p)[prefix];
|
|
Packit Service |
5a9772 |
memcpy(str, list, len);
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (name)
|
|
Packit Service |
5a9772 |
p[0] = (char*)name;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
for (index = name ? 1 : 0; index < nArgs; index++)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
char* comma = strchr(str, ',');
|
|
Packit Service |
5a9772 |
p[index] = str;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (comma)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
str = comma + 1;
|
|
Packit Service |
5a9772 |
*comma = '\0';
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
*count = nArgs;
|
|
Packit Service |
5a9772 |
return p;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
char** CommandLineParseCommaSeparatedValues(const char* list, size_t* count)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
return CommandLineParseCommaSeparatedValuesEx(NULL, list, count);
|
|
Packit Service |
5a9772 |
}
|