aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/CMakeLists.txt1
-rw-r--r--client/cmd.cpp6
-rw-r--r--client/parse.cpp74
-rw-r--r--client/parse.h4
-rw-r--r--client/xxd.c44
-rw-r--r--client/xxd.h17
6 files changed, 116 insertions, 30 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 35a55b6..5da93e4 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -14,6 +14,7 @@ add_executable(pbc
sock.cpp
cmd.cpp
parse.cpp
+ xxd.c
)
target_link_libraries(pbc
diff --git a/client/cmd.cpp b/client/cmd.cpp
index 1ec2cb8..78a6c3c 100644
--- a/client/cmd.cpp
+++ b/client/cmd.cpp
@@ -5,6 +5,7 @@
#include "cmd.h"
#include "sock.h"
#include "parse.h"
+#include "xxd.h"
char* consume_token(char* input, const char* ifs) {
strtok(input, ifs);
@@ -55,8 +56,11 @@ void cmd_send(char* addr_str) {
return;
}
+ printf("char data[%lu = 0x%02lx]:\n", data_size, data_size);
+ xxd(data, data_size);
+
// printf("(0x%02x) -> \"%.*s\"\n", addr, data_size, data);
- i2c_send(addr, data, data_size);
+ // i2c_send(addr, data, data_size);
free(data);
}
diff --git a/client/parse.cpp b/client/parse.cpp
index 6eca774..5672ff2 100644
--- a/client/parse.cpp
+++ b/client/parse.cpp
@@ -1,14 +1,13 @@
-#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <netinet/in.h>
#include "parse.h"
-static int parse_string(const char* str, char* data, size_t* offset) {
+static int parse_string(const char * str, char * data, size_t * offset) {
char closing = str[0];
char escape = false;
- bool scan = data == NULL;
int i = 0;
size_t len = strlen(str);
@@ -23,7 +22,7 @@ static int parse_string(const char* str, char* data, size_t* offset) {
return -i;
}
- for (i = 1; i < len && str[i] != '\0'; i++) {
+ for (i = 1; i < len && str[i] != '\0'; i++, *offset += 1) {
char c = str[i];
// TODO: handle escaped characters
@@ -31,16 +30,16 @@ static int parse_string(const char* str, char* data, size_t* offset) {
if (c == closing)
return i + 1; // +1 for closing quote
- *offset += 1;
+ if (data != NULL)
+ data[*offset] = c;
}
return -i;
}
-static int parse_hexstr(const char* str, char* data, size_t* offset) {
+static int parse_hexstr(const char * str, char * data, size_t * offset) {
const char* ifs = IFS;
size_t len = strcspn(str, ifs);
- bool scan = data == NULL;
int i = 0;
// check if token contains at least one colon
@@ -56,6 +55,10 @@ static int parse_hexstr(const char* str, char* data, size_t* offset) {
while (c < len) { // count bytes in bytestring
if (strspn(str + c, SET_HEX) != 2)
return -i -c;
+
+ if (data != NULL)
+ data[*offset] = strtol(str + c, NULL, 16) & 0xff;
+
c += 2;
*offset += 1;
@@ -70,10 +73,9 @@ static int parse_hexstr(const char* str, char* data, size_t* offset) {
return i;
}
-static int parse_number(const char* str, char* data, size_t* offset) {
+static int parse_number(const char * str, char * data, size_t * offset) {
const char* ifs = IFS;
size_t len = strcspn(str, ifs);
- bool scan = data == NULL;
int i = 0;
int base = 10;
bool bytestring = false;
@@ -94,8 +96,8 @@ static int parse_number(const char* str, char* data, size_t* offset) {
size_t len_ok = strspn(str + i, set) + i;
if (len != len_ok) return -len_ok;
- if (base == 10) *offset += 1;
- else if (base == 16) {
+ size_t size = 1; // default integer size in bytes
+ if (base == 16) {
size_t prefixless = len - i;
switch (prefixless) {
case 2: // 8-bit (2 hex characters)
@@ -106,40 +108,58 @@ static int parse_number(const char* str, char* data, size_t* offset) {
default:
return -i;
}
- *offset += prefixless / 2;
+ size = prefixless / 2;
}
+ if (data != NULL) {
+ unsigned long number = strtol(str + i, NULL, base);
+ long long mask = (1 << 8 * size) - 1;
+ number &= mask;
+ switch (size) {
+ case 1:
+ data[*offset] = number & 0xff;
+ break;
+ case 2:
+ number = htons(number);
+ data[*offset + 1] = (number) & 0xff;
+ data[*offset + 0] = (number >>= 8) & 0xff;
+ break;
+ case 4:
+ number = htonl(number);
+ data[*offset + 3] = (number) & 0xff;
+ data[*offset + 2] = (number >>= 8) & 0xff;
+ data[*offset + 1] = (number >>= 8) & 0xff;
+ data[*offset + 0] = (number >>= 8) & 0xff;
+ break;
+ }
+ }
+
+ *offset += size;
i += len;
return i;
}
-static int _strtodata_main(const char* str, char* _data, size_t* offset) {
+static int _strtodata_main(const char * str, char* data, size_t * offset) {
const char* ifs = IFS;
size_t len = strlen(str);
- size_t i = 0;
-
- while (i < len) {
+ int i, run;
+ for (i = 0; i < len; i += run) {
i += strspn(&str[i], ifs); // skip whitespace
if (str[i] == '\0') break; // end of string
- int run;
- char* data = _data == NULL ? NULL : _data + *offset;
- if ((run = parse_string(str + i, data, offset)) > 0) goto format_ok;
- if ((run = parse_hexstr(str + i, data, offset)) > 0) goto format_ok;
- if ((run = parse_number(str + i, data, offset)) > 0) goto format_ok;
-
- return -i + run; // no format detected
+ if ((run = parse_string(str + i, data, offset)) > 0) continue;
+ if ((run = parse_hexstr(str + i, data, offset)) > 0) continue;
+ if ((run = parse_number(str + i, data, offset)) > 0) continue;
-format_ok:
- i += run;
- continue;
+ // no format detected
+ return -i + run;
}
return i;
}
-int strtodata(const char* str, char** data, size_t* size) {
+int strtodata(const char * str, char ** data, size_t * size) {
*size = 0;
// 1st pass: check data format
diff --git a/client/parse.h b/client/parse.h
index 10274e7..94afe70 100644
--- a/client/parse.h
+++ b/client/parse.h
@@ -22,7 +22,7 @@
*
* \return the remaining data after \p token and the first \p ifs
*/
-char* consume_token(char* token, const char* ifs);
+char* consume_token(char * token, const char * ifs);
/**
* \brief convert string with literals into raw data
@@ -38,5 +38,5 @@ char* consume_token(char* token, const char* ifs);
* \note The pointer that \p data refers to will not be initialized by this
* function if parsing fails
*/
-int strtodata(const char* str, char** data, size_t* size);
+int strtodata(const char * str, char ** data, size_t * size);
diff --git a/client/xxd.c b/client/xxd.c
new file mode 100644
index 0000000..06b9960
--- /dev/null
+++ b/client/xxd.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <ctype.h>
+
+#include "parse.h"
+
+void xxd(const char * data, size_t size) {
+ size_t fake_size = size + (16 - size % 16) % 16;
+
+ for (size_t base = 0; base < fake_size; base += 16) {
+ printf("%08lx: ", base);
+
+ // print bytes
+ for (size_t offset = 0; offset < 16; offset++) {
+ size_t i = base + offset;
+
+ if (offset == 8) printf(" ");
+
+ if (i >= size) {
+ printf(" ");
+ continue;
+ }
+
+ printf("%02x ", data[size]);
+ }
+
+ // print ascii representation
+ printf(" |");
+ for (size_t offset = 0; offset < 16; offset++) {
+ size_t i = base + offset;
+
+ if (i >= size) {
+ printf(" ");
+ continue;
+ }
+
+ if (isprint(data[size]))
+ printf("%c", data[size]);
+ else
+ printf(".");
+ }
+ printf("|\n");
+ }
+}
+
diff --git a/client/xxd.h b/client/xxd.h
new file mode 100644
index 0000000..fb28bb1
--- /dev/null
+++ b/client/xxd.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief utility function that prints hexdump of data
+ */
+void xxd(const char * data, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+