Files
djhackersdev_bemanitools/src/main/util/cmdline.c
T

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;
}