129 lines
2.4 KiB
C
129 lines
2.4 KiB
C
#include "util/cmdline.h"
|
|
#include "util/mem.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <windows.h>
|
|
|
|
static void
|
|
push_argv(int *argc, char ***argv, const char *begin, const char *end)
|
|
{
|
|
size_t nchars;
|
|
char *str;
|
|
|
|
(*argc)++;
|
|
*argv = xrealloc(*argv, *argc * sizeof(char **));
|
|
|
|
nchars = end - begin;
|
|
str = xmalloc(nchars + 1);
|
|
memcpy(str, begin, nchars);
|
|
str[nchars] = '\0';
|
|
|
|
(*argv)[*argc - 1] = str;
|
|
}
|
|
|
|
void args_recover(int *argc_out, char ***argv_out)
|
|
{
|
|
int argc;
|
|
char **argv;
|
|
const char *begin;
|
|
const char *pos;
|
|
bool quote;
|
|
|
|
argc = 0;
|
|
argv = NULL;
|
|
quote = false;
|
|
|
|
for (begin = pos = GetCommandLine(); *pos; pos++) {
|
|
switch (*pos) {
|
|
case '"':
|
|
if (!quote) {
|
|
quote = true;
|
|
begin = pos + 1;
|
|
} else {
|
|
push_argv(&argc, &argv, begin, pos);
|
|
|
|
quote = false;
|
|
begin = NULL;
|
|
}
|
|
|
|
break;
|
|
|
|
case ' ':
|
|
if (!quote && begin != NULL) {
|
|
push_argv(&argc, &argv, begin, pos);
|
|
begin = NULL;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
if (begin == NULL) {
|
|
begin = pos;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (begin != NULL && !quote) {
|
|
push_argv(&argc, &argv, begin, pos);
|
|
}
|
|
|
|
*argc_out = argc;
|
|
*argv_out = argv;
|
|
}
|
|
|
|
void args_free(int argc, char **argv)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
free(argv[i]);
|
|
}
|
|
|
|
free(argv);
|
|
}
|
|
|
|
char *args_join(int argc, char **argv)
|
|
{
|
|
char *pos;
|
|
char *str;
|
|
uint32_t nchars;
|
|
uint32_t part_len;
|
|
int i;
|
|
|
|
nchars = 0;
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
/* 3 = leading space plus two surrounding quotes.
|
|
The first element has no leading space, but this is counterbalanced
|
|
by the fact that the string needs a NUL terminator. */
|
|
nchars += 3 + strlen(argv[i]);
|
|
}
|
|
|
|
str = xmalloc(nchars);
|
|
pos = str;
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
if (i != 0) {
|
|
*pos++ = ' ';
|
|
}
|
|
|
|
*pos++ = '"';
|
|
|
|
part_len = strlen(argv[i]);
|
|
memcpy(pos, argv[i], part_len);
|
|
pos += part_len;
|
|
|
|
*pos++ = '"';
|
|
}
|
|
|
|
*pos = '\0';
|
|
|
|
return str;
|
|
}
|