+static int debug = 0;
+static int verbose = 0;
+
+#define FLAG_LENGTH_BYTE (1<<0)
+#define FLAG_FORMAT_HEX (1<<1)
+#define FLAG_COMMA_BEFORE (1<<2)
+#define FLAG_COMMA_AFTER (1<<3)
+#define FLAG_NL (1<<4)
+#define FLAG_IGNORE_COMMAS (1<<5)
+
+#define CHECK_SPACE(x) if ((*outpos + x) > outend) { fprintf(stderr, "Not enough space!\n"); return 0; }
+#define CHECK_AVAIL(x) if ((*inpos + x) > inend) { fprintf(stderr, "Not enough input available!\n"); return 0; }
+
+static int format_part_out(uint8_t **inpos, int inlen, uint8_t **outpos, int outlen, int len, int flags)
+{
+ const uint8_t nibble[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'};
+ uint8_t *buf_out = *outpos;
+ uint8_t *outend = *outpos + outlen;
+ uint8_t *inend = *inpos + inlen;
+ int i;
+
+ if (flags & FLAG_COMMA_BEFORE) {
+ CHECK_SPACE(1);
+ **outpos=',';
+ *outpos += 1;
+ }
+
+ if (flags & FLAG_LENGTH_BYTE) {
+ CHECK_AVAIL(1);
+ len = **inpos;
+ *inpos += 1;
+ }
+
+ if (flags & FLAG_FORMAT_HEX) {
+ CHECK_AVAIL(len);
+ CHECK_SPACE(len*2);
+ for (i = 0; i < len; i++) {
+ **outpos = nibble[((**inpos) & 0xf0) >> 4];
+ *outpos += 1;
+ **outpos = nibble[((**inpos) & 0xf)];
+ *inpos += 1; *outpos += 1;
+ }
+ } else {
+ CHECK_AVAIL(len);
+ CHECK_SPACE(len);
+ memcpy(*outpos, *inpos, len);
+ *outpos += len;
+ *inpos += len;
+ }
+
+ if (flags & FLAG_COMMA_AFTER) {
+ CHECK_SPACE(1);
+ **outpos=',';
+ *outpos += 1;
+ }
+
+ if (flags & FLAG_NL) {
+ CHECK_SPACE(2);
+ **outpos='\r';
+ *outpos += 1;
+ **outpos='\n';
+ *outpos += 1;
+ }
+
+ return *outpos - buf_out;
+}
+
+static uint8_t ascii_to_nibble(uint8_t a)
+{
+ uint8_t c = 0x00;
+
+ if ((a >= '0') && (a <= '9')) {
+ c = a - '0';
+ } else if ((a >= 'A') && (a <= 'F')) {
+ c = (a - 'A') + 10;
+ } else if ((a >= 'a') && (a <= 'f')) {
+ c = (a - 'a') + 10;
+ }
+
+ return c;
+}
+
+static int parse_part_in(uint8_t **inpos, int inlen, uint8_t **outpos, int outlen, int flags)
+{
+ uint8_t *buf_out = *outpos;
+ uint8_t *outend = *outpos + outlen;
+ uint8_t *inend = *inpos + inlen;
+
+ if (flags & FLAG_LENGTH_BYTE) {
+ int len = 0;
+ uint8_t *ip;
+
+ ip = *inpos;
+ while(ip < inend) {
+ if (*ip == ',') {
+ ip++;
+ if (!(flags & FLAG_IGNORE_COMMAS))
+ break;
+
+ continue;
+ }
+ len++;
+ ip++;
+ }
+ CHECK_SPACE(1);
+ **outpos = (len / 2);
+ *outpos += 1;
+ }
+
+ while(*inpos < inend) {
+ if (**inpos == ',') {
+ *inpos += 1;
+ if (!(flags & FLAG_IGNORE_COMMAS))
+ break;
+
+ continue;
+ }
+
+ CHECK_SPACE(1);
+ CHECK_AVAIL(2);
+
+ **outpos = ascii_to_nibble(**inpos) << 4;
+ *inpos += 1;
+ **outpos |= ascii_to_nibble(**inpos);
+ *inpos += 1; *outpos += 1;
+ }
+
+ return *outpos - buf_out;
+}