src/helper: usage/help updates
[fw/openocd] / src / helper / binarybuffer.c
index d813ecf537e551c794abd8ed73a97ae85fbbb0df..081cc037ebd6c346ae2b360124f81f463914a99c 100644 (file)
@@ -48,102 +48,94 @@ const unsigned char bit_reverse_table256[] =
 };
 
 
-uint8_t* buf_cpy(const uint8_t *from, uint8_t *to, int size)
+void* buf_cpy(const void *from, void *_to, unsigned size)
 {
-       unsigned int num_bytes = CEIL(size, 8);
-       unsigned int i;
-
-       if (from == NULL)
+       if (NULL == from || NULL == _to)
                return NULL;
 
-       for (i = 0; i < num_bytes; i++)
-               to[i] = from[i];
+       // copy entire buffer
+       memcpy(_to, from, DIV_ROUND_UP(size, 8));
 
        /* mask out bits that don't belong to the buffer */
-       if (size % 8)
+       unsigned trailing_bits = size % 8;
+       if (trailing_bits)
        {
-               to[size / 8] &= (0xff >> (8 - (size % 8)));
+               uint8_t *to = _to;
+               to[size / 8] &= (1 << trailing_bits) - 1;
        }
+       return _to;
+}
 
-       return to;
+static bool buf_cmp_masked(uint8_t a, uint8_t b, uint8_t m)
+{
+       return (a & m) != (b & m);
+}
+static bool buf_cmp_trailing(uint8_t a, uint8_t b, uint8_t m, unsigned trailing)
+{
+       uint8_t mask = (1 << trailing) - 1;
+       return buf_cmp_masked(a, b, mask & m);
 }
 
-int buf_cmp(const uint8_t *buf1, const uint8_t *buf2, int size)
+bool buf_cmp(const void *_buf1, const void *_buf2, unsigned size)
 {
-       int num_bytes = CEIL(size, 8);
-       int i;
+       if (!_buf1 || !_buf2)
+               return _buf1 != _buf2;
 
-       if (!buf1 || !buf2)
-               return 1;
+       unsigned last = size / 8;
+       if (memcmp(_buf1, _buf2, last) != 0)
+               return false;
 
-       for (i = 0; i < num_bytes; i++)
-       {
-               /* last byte */
-               /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
-               if ((size % 8) && (i == num_bytes -1))
-               {
-                       if ((buf1[i] & ((1 << (size % 8)) - 1)) != (buf2[i] & ((1 << (size % 8)) - 1)))
-                               return 1;
-               }
-               else
-               {
-                       if (buf1[i] != buf2[i])
-                               return 1;
-               }
-       }
+       unsigned trailing = size % 8;
+       if (!trailing)
+               return false;
 
-       return 0;
+       const uint8_t *buf1 = _buf1, *buf2 = _buf2;
+       return buf_cmp_trailing(buf1[last], buf2[last], 0xff, trailing);
 }
 
-int buf_cmp_mask(const uint8_t *buf1, const uint8_t *buf2, const uint8_t *mask, int size)
+bool buf_cmp_mask(const void *_buf1, const void *_buf2,
+               const void *_mask, unsigned size)
 {
-       int num_bytes = CEIL(size, 8);
-       int i;
+       if (!_buf1 || !_buf2)
+               return _buf1 != _buf2 || _buf1 != _mask;
 
-       for (i = 0; i < num_bytes; i++)
+       const uint8_t *buf1 = _buf1, *buf2 = _buf2, *mask = _mask;
+       unsigned last = size / 8;
+       for (unsigned i = 0; i < last; i++)
        {
-               /* last byte */
-               /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
-               if ((size % 8) && (i == num_bytes -1))
-               {
-                       if ((buf1[i] & ((1 << (size % 8)) - 1) & mask[i]) !=
-                               (buf2[i] & ((1 << (size % 8)) - 1) & mask[i]))
-                               return 1;
-               }
-               else
-               {
-                       if ((buf1[i] & mask[i]) != (buf2[i] & mask[i]))
-                               return 1;
-               }
+               if (buf_cmp_masked(buf1[i], buf2[i], mask[i]))
+                       return true;
        }
-
-       return 0;
+       unsigned trailing = size % 8;
+       if (!trailing)
+               return false;
+       return buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing);
 }
 
-uint8_t* buf_set_ones(uint8_t *buf, int count)
+
+void* buf_set_ones(void *_buf, unsigned size)
 {
-       int num_bytes = CEIL(count, 8);
-       int i;
+       uint8_t *buf = _buf;
+       if (!buf)
+               return NULL;
 
-       for (i = 0; i < num_bytes; i++)
-       {
-               if (count >= 8)
-                       buf[i] = 0xff;
-               else
-                       buf[i] = (1 << count) - 1;
+       memset(buf, 0xff, size / 8);
 
-               count -= 8;
-       }
+       unsigned trailing_bits = size % 8;
+       if (trailing_bits)
+               buf[size / 8] = (1 << trailing_bits) - 1;
 
        return buf;
 }
 
-uint8_t* buf_set_buf(const uint8_t *src, int src_start, uint8_t *dst, int dst_start, int len)
+void* buf_set_buf(const void *_src, unsigned src_start,
+               void *_dst, unsigned dst_start, unsigned len)
 {
-       int src_idx = src_start, dst_idx = dst_start;
-       int i;
+       const uint8_t *src = _src;
+       uint8_t *dst = _dst;
 
-       for (i = 0; i < len; i++)
+       unsigned src_idx = src_start, dst_idx = dst_start;
+       for (unsigned i = 0; i < len; i++)
        {
                if (((src[src_idx / 8] >> (src_idx % 8)) & 1) == 1)
                        dst[dst_idx / 8] |= 1 << (dst_idx % 8);
@@ -158,9 +150,7 @@ uint8_t* buf_set_buf(const uint8_t *src, int src_start, uint8_t *dst, int dst_st
 
 uint32_t flip_u32(uint32_t value, unsigned int num)
 {
-       uint32_t c;
-
-       c = (bit_reverse_table256[value & 0xff] << 24) |
+       uint32_t c = (bit_reverse_table256[value & 0xff] << 24) |
                (bit_reverse_table256[(value >> 8) & 0xff] << 16) |
                (bit_reverse_table256[(value >> 16) & 0xff] << 8) |
                (bit_reverse_table256[(value >> 24) & 0xff]);
@@ -173,12 +163,10 @@ uint32_t flip_u32(uint32_t value, unsigned int num)
 
 int ceil_f_to_u32(float x)
 {
-       uint32_t y;
-
        if (x < 0)      /* return zero for negative numbers */
                return 0;
 
-       y = x;  /* cut off fraction */
+       uint32_t y = x; /* cut off fraction */
 
        if ((x - y) > 0.0) /* if there was a fractional part, increase by one */
                y++;
@@ -186,43 +174,36 @@ int ceil_f_to_u32(float x)
        return y;
 }
 
-char* buf_to_str(const uint8_t *buf, int buf_len, int radix)
+char* buf_to_str(const void *_buf, unsigned buf_len, unsigned radix)
 {
-       const char *DIGITS = "0123456789ABCDEF";
        float factor;
-       char *str;
-       int str_len;
-       int b256_len = CEIL(buf_len, 8);
-       uint32_t tmp;
-
-       int j; /* base-256 digits */
-       int i; /* output digits (radix) */
-
-       if (radix == 16)
-       {
+       switch (radix) {
+       case 16:
                factor = 2.0;   /* log(256) / log(16) = 2.0 */
-       }
-       else if (radix == 10)
-       {
+               break;
+       case 10:
                factor = 2.40824;   /* log(256) / log(10) = 2.40824 */
-       }
-       else if (radix == 8)
-       {
+               break;
+       case 8:
                factor = 2.66667;       /* log(256) / log(8) = 2.66667 */
-       }
-       else
+               break;
+       default:
                return NULL;
+       }
 
-       str_len = ceil_f_to_u32(CEIL(buf_len, 8) * factor);
-       str = calloc(str_len + 1, 1);
+       unsigned str_len = ceil_f_to_u32(DIV_ROUND_UP(buf_len, 8) * factor);
+       char *str = calloc(str_len + 1, 1);
 
-       for (i = b256_len - 1; i >= 0; i--)
+       const uint8_t *buf = _buf;
+       int b256_len = DIV_ROUND_UP(buf_len, 8);
+       for (int i = b256_len - 1; i >= 0; i--)
        {
-               tmp = buf[i];
-               if ((i == (buf_len / 8)) && (buf_len % 8))
+               uint32_t tmp = buf[i];
+               if (((unsigned)i == (buf_len / 8)) && (buf_len % 8))
                        tmp &= (0xff >> (8 - (buf_len % 8)));
 
-               for (j = str_len; j > 0; j--)
+               /* base-256 digits */
+               for (unsigned j = str_len; j > 0; j--)
                {
                        tmp += (uint32_t)str[j-1] * 256;
                        str[j-1] = (uint8_t)(tmp % radix);
@@ -230,44 +211,49 @@ char* buf_to_str(const uint8_t *buf, int buf_len, int radix)
                }
        }
 
-       for (j = 0; j < str_len; j++)
+       const char *DIGITS = "0123456789ABCDEF";
+       for (unsigned j = 0; j < str_len; j++)
                str[j] = DIGITS[(int)str[j]];
 
        return str;
 }
 
-int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radix)
+/// identify radix, and skip radix-prefix (0, 0x or 0X)
+static void str_radix_guess(const char **_str, unsigned *_str_len,
+               unsigned *_radix)
 {
-       char *charbuf;
-       uint32_t tmp;
-       float factor;
-       uint8_t *b256_buf;
-       int b256_len;
-
-       int j; /* base-256 digits */
-       int i; /* input digits (ASCII) */
-
-       if (radix == 0)
+       unsigned radix = *_radix;
+       if (0 != radix)
+               return;
+       const char *str = *_str;
+       unsigned str_len = *_str_len;   
+       if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
        {
-               /* identify radix, and skip radix-prefix (0, 0x or 0X) */
-               if ((str[0] == '0') && (str[1] && ((str[1] == 'x') || (str[1] == 'X'))))
-               {
-                       radix = 16;
-                       str += 2;
-                       str_len -= 2;
-               }
-               else if ((str[0] == '0') && (str_len != 1))
-               {
-                       radix = 8;
-                       str += 1;
-                       str_len -= 1;
-               }
-               else
-               {
-                       radix = 10;
-               }
+               radix = 16;
+               str += 2;
+               str_len -= 2;
+       }
+       else if ((str[0] == '0') && (str_len != 1))
+       {
+               radix = 8;
+               str += 1;
+               str_len -= 1;
        }
+       else
+       {
+               radix = 10;
+       }
+       *_str = str;
+       *_str_len = str_len;
+       *_radix = radix;
+}
 
+int str_to_buf(const char *str, unsigned str_len,
+               void *_buf, unsigned buf_len, unsigned radix)
+{
+       str_radix_guess(&str, &str_len, &radix);
+
+       float factor;
        if (radix == 16)
                factor = 0.5; /* log(16) / log(256) = 0.5 */
        else if (radix == 10)
@@ -278,18 +264,20 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi
                return 0;
 
        /* copy to zero-terminated buffer */
-       charbuf = malloc(str_len + 1);
+       char *charbuf = malloc(str_len + 1);
        memcpy(charbuf, str, str_len);
        charbuf[str_len] = '\0';
 
        /* number of digits in base-256 notation */
-       b256_len = ceil_f_to_u32(str_len * factor);
-       b256_buf = calloc(b256_len, 1);
+       unsigned b256_len = ceil_f_to_u32(str_len * factor);
+       uint8_t *b256_buf = calloc(b256_len, 1);
 
        /* go through zero terminated buffer */
+       /* input digits (ASCII) */
+       unsigned i;
        for (i = 0; charbuf[i]; i++)
        {
-               tmp = charbuf[i];
+               uint32_t tmp = charbuf[i];
                if ((tmp >= '0') && (tmp <= '9'))
                        tmp = (tmp - '0');
                else if ((tmp >= 'a') && (tmp <= 'f'))
@@ -298,10 +286,11 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi
                        tmp = (tmp - 'A' + 10);
                else continue;  /* skip characters other than [0-9,a-f,A-F] */
 
-               if (tmp >= (uint32_t)radix)
+               if (tmp >= radix)
                        continue;       /* skip digits invalid for the current radix */
 
-               for (j = 0; j < b256_len; j++)
+               /* base-256 digits */
+               for (unsigned j = 0; j < b256_len; j++)
                {
                        tmp += (uint32_t)b256_buf[j] * radix;
                        b256_buf[j] = (uint8_t)(tmp & 0xFF);
@@ -310,7 +299,8 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi
 
        }
 
-       for (j = 0; j < CEIL(buf_len, 8); j++)
+       uint8_t *buf = _buf;
+       for (unsigned j = 0; j < DIV_ROUND_UP(buf_len, 8); j++)
        {
                if (j < b256_len)
                        buf[j] = b256_buf[j];