Implement general purpose CLI tool
This commit is contained in:
parent
6ffaa66158
commit
aef38e01f3
2 changed files with 109 additions and 4 deletions
6
Makefile
Normal file
6
Makefile
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
.PHONY: examples
|
||||||
|
|
||||||
|
examples: examples/example_cli.c
|
||||||
|
|
||||||
|
examples/example_cli.c:
|
||||||
|
clang -Wall -g -Isrc -o examples/empack_cli src/empack.c examples/empack_cli.c
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "empack.h"
|
#include "empack.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define USAGE \
|
#define USAGE \
|
||||||
"empack_cli [OPTIONS] <file | msgpack hex>\r\n" \
|
"empack_cli [OPTIONS] <file | msgpack hex>\r\n" \
|
||||||
" file: File to read binary Msgpack data from, \"-\" for stdin\r\n" \
|
" file: File to read binary Msgpack data from, \"-\" for stdin\r\n" \
|
||||||
|
|
@ -14,25 +16,121 @@
|
||||||
"OPTIONS\r\n" \
|
"OPTIONS\r\n" \
|
||||||
" -h/--help: Print this message\r\n"
|
" -h/--help: Print this message\r\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
char_to_nibble(char c, uint8_t *nibble)
|
||||||
|
{
|
||||||
|
if ((c >= '0') && (c <= '9')) {
|
||||||
|
(*nibble) = c - '0';
|
||||||
|
} else if ((c >= 'a') && (c <= 'f')) {
|
||||||
|
(*nibble) = c - 'a' + 0x0a;
|
||||||
|
} else if ((c >= 'A') && (c <= 'F')) {
|
||||||
|
(*nibble) = c - 'A' + 0x0a;
|
||||||
|
} else {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_func(const char *buf, uint32_t buflen, void *arg)
|
print_func(const char *buf, uint32_t buflen, void *arg)
|
||||||
{
|
{
|
||||||
printf("%.*s", buflen, buf);
|
printf("%.*s", buflen, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const uint8_t input[] = { 0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00 };
|
|
||||||
size_t input_len = sizeof(input);
|
|
||||||
empack_t empack;
|
empack_t empack;
|
||||||
uint8_t arena[256];
|
uint8_t arena[0x4000];
|
||||||
uint32_t chars_printed;
|
struct stat file_stat;
|
||||||
|
uint8_t *input = NULL;
|
||||||
|
size_t input_len = 0;
|
||||||
|
size_t input_bufsz = 0;
|
||||||
|
uint32_t chars_printed = 0;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, USAGE);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!strcmp(argv[1], "-h")) || (!strcmp(argv[1], "--help"))) {
|
||||||
|
printf(USAGE);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "-")) {
|
||||||
|
/* read bytes from stdin */
|
||||||
|
while (1) {
|
||||||
|
size_t read;
|
||||||
|
|
||||||
|
input_bufsz += 1024;
|
||||||
|
input = realloc(input, input_bufsz);
|
||||||
|
|
||||||
|
read = fread(&input[input_len], 1, input_bufsz, stdin);
|
||||||
|
if (read == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
input_len += read;
|
||||||
|
}
|
||||||
|
} else if (stat(argv[1], &file_stat) == 0) {
|
||||||
|
/* read bytes from a file */
|
||||||
|
FILE *fd = fopen(argv[1], "r");
|
||||||
|
if (fd == NULL) {
|
||||||
|
fprintf(stderr, "Failed to open file \"%s\"\r\n", argv[1]);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_bufsz = file_stat.st_size;
|
||||||
|
input = malloc(input_bufsz);
|
||||||
|
input_len = fread(input, 1, input_bufsz, fd);
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
if (input_len != input_bufsz) {
|
||||||
|
fprintf(stderr, "Failed to read file \"%s\"\r\n", argv[1]);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* interpret argument as hex data */
|
||||||
|
size_t arg_sz = strlen(argv[1]);
|
||||||
|
if ((arg_sz % 2) != 0) {
|
||||||
|
fprintf(stderr, "Invalid hex data - odd number of characters\r\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_bufsz = arg_sz / 2;
|
||||||
|
input = malloc(input_bufsz);
|
||||||
|
if (input == NULL) {
|
||||||
|
fprintf(stderr, "Failed to allocate appropriate resources\r\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < arg_sz; i += 2) {
|
||||||
|
uint8_t hi;
|
||||||
|
uint8_t lo;
|
||||||
|
|
||||||
|
if (char_to_nibble(argv[1][i], &hi) ||
|
||||||
|
char_to_nibble(argv[1][i+1], &lo)) {
|
||||||
|
fprintf(stderr, "Invalid hex byte at offset %u\r\n", (uint32_t)(i / 2));
|
||||||
|
free(input);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[input_len] = (hi << 4) | lo;
|
||||||
|
input_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
empack_init(&empack, arena, sizeof(arena));
|
empack_init(&empack, arena, sizeof(arena));
|
||||||
|
|
||||||
if (empack_parse(&empack, input, input_len)) {
|
if (empack_parse(&empack, input, input_len)) {
|
||||||
fprintf(stderr, "Parsing error\r\n");
|
fprintf(stderr, "Parsing error\r\n");
|
||||||
|
free(input);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,5 +144,6 @@ main(int argc, char **argv)
|
||||||
empack.arena_sz,
|
empack.arena_sz,
|
||||||
(empack.arena_used * 100) / empack.arena_sz);
|
(empack.arena_used * 100) / empack.arena_sz);
|
||||||
|
|
||||||
|
free(input);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue