diff --git a/src/common/bitstring.c b/src/common/bitstring.c index 66f421bf927994005a9eb6bd44a2b99ac85c5c62..7c14452cf0ba01730deb2f3da1c4301b6da65a8a 100644 --- a/src/common/bitstring.c +++ b/src/common/bitstring.c @@ -1159,6 +1159,49 @@ int inx2bitstr(bitstr_t *b, int32_t *inx) return rc; } +/* + * convert a bitstring to inx format + * returns an xmalloc()'d array of int32_t that must be xfree()'d + */ +int32_t *bitstr2inx(bitstr_t *b) +{ + bitoff_t start, bit, pos = 0; + int32_t *bit_inx; + + if (!b) { + bit_inx = xmalloc(sizeof(int32_t)); + bit_inx[0] = -1; + return bit_inx; + } + + /* worst case: every other bit set, resulting in an array of length + * bitstr_bits(b) + 1 (if an odd number of elements) + * + 1 (for trailing -1) */ + bit_inx = xmalloc_nz(sizeof(int32_t) * (_bitstr_bits(b) + 2)); + + for (bit = 0; bit < _bitstr_bits(b); ) { + /* skip past empty words */ + if (!b[_bit_word(bit)]) { + bit += sizeof(bitstr_t) * 8; + continue; + } + + if (bit_test(b, bit)) { + start = bit; + while (bit + 1 < _bitstr_bits(b) + && bit_test(b, bit + 1)) + bit++; + bit_inx[pos++] = start; + bit_inx[pos++] = bit; + } + bit++; + } + /* terminate array with -1 */ + bit_inx[pos] = -1; + + return bit_inx; +} + /* bit_fmt_hexmask * * Given a bitstr_t, allocate and return a string in the form of: diff --git a/src/common/bitstring.h b/src/common/bitstring.h index b287e1cfbaaf8770028fa288c7d3d678e9f7970c..14cb9e572064629f56bc73fbf204332fcceb6a3c 100644 --- a/src/common/bitstring.h +++ b/src/common/bitstring.h @@ -127,6 +127,7 @@ int bit_unfmt(bitstr_t *b, char *str); int32_t *bitfmt2int (char *bit_str_ptr); char * inx2bitfmt (int32_t *inx); int inx2bitstr(bitstr_t *b, int32_t *inx); +int32_t *bitstr2inx(bitstr_t *b); char *bit_fmt_hexmask(bitstr_t *b); int bit_unfmt_hexmask(bitstr_t *b, const char *str); char *bit_fmt_binmask(bitstr_t *b);