char * ambsalign (const char *src, size_t *width, mbs_align_t align, int flags) { size_t orig_width = *width; size_t size = *width; /* Start with enough for unibyte mode. */ size_t req = size; char *buf = NULL; while (req >= size) { size = req + 1; /* Space for NUL. */ char *nbuf = realloc (buf, size); if (nbuf == NULL) { free (buf); buf = NULL; break; } buf = nbuf; *width = orig_width; req = mbsalign (src, buf, size, width, align, flags); if (req == (size_t) -1) { free (buf); buf = NULL; break; } } return buf; }
int main (void) { char dest[4 * 16 + 1]; size_t width, n; /* Test unibyte truncation. */ width = 4; n = mbsalign ("t\tés", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0); ASSERT (n == 4); /* Test center alignment. */ width = 4; n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER, 0); ASSERT (*dest == ' ' && *(dest + n - 1) == ' '); ASSERT (n == 4); /* Test center alignment, with no trailing padding. */ width = 4; n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER, MBA_NO_RIGHT_PAD); ASSERT (n == 3); ASSERT (*dest == ' ' && *(dest + n - 1) == 's'); /* Test left alignment, with no trailing padding. (truncate only). */ width = 4; n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_LEFT, MBA_NO_RIGHT_PAD); ASSERT (n == 2); ASSERT (*dest == 'e' && *(dest + n - 1) == 's'); /* Test center alignment, with no padding. (truncate only). */ width = 4; n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER, MBA_NO_LEFT_PAD | MBA_NO_RIGHT_PAD); ASSERT (n == 2); ASSERT (*dest == 'e' && *(dest + n - 1) == 's'); /* Test center alignment, with no left padding. (may be useful for RTL?) */ width = 4; n = mbsalign ("es", dest, sizeof dest, &width, MBS_ALIGN_CENTER, MBA_NO_LEFT_PAD); ASSERT (n == 3); ASSERT (*dest == 'e' && *(dest + n - 1) == ' '); if (setlocale (LC_ALL, "en_US.UTF8")) { /* Check invalid input is flagged. */ width = 4; n = mbsalign ("t\xe1\xe2s", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0); ASSERT (n == (size_t) -1); /* Check invalid input is treated as unibyte */ width = 4; n = mbsalign ("t\xe1\xe2s", dest, sizeof dest, &width, MBS_ALIGN_LEFT, MBA_UNIBYTE_FALLBACK); ASSERT (n == 4); /* Test multibyte center alignment. */ width = 4; n = mbsalign ("és", dest, sizeof dest, &width, MBS_ALIGN_CENTER, 0); ASSERT (n == 5); ASSERT (*dest == ' ' && *(dest + n - 1) == ' '); /* Test multibyte left alignment. */ width = 4; n = mbsalign ("és", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0); ASSERT (n == 5); ASSERT (*(dest + n - 1) == ' ' && *(dest + n - 2) == ' '); /* Test multibyte right alignment. */ width = 4; n = mbsalign ("és", dest, sizeof dest, &width, MBS_ALIGN_RIGHT, 0); ASSERT (n == 5); ASSERT (*(dest) == ' ' && *(dest + 1) == ' '); /* multibyte multicell truncation. */ width = 4; /* cells */ n = mbsalign ("日月火水", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0); ASSERT (n == 6); /* 2 characters */ /* multibyte unicell truncation. */ width = 3; /* cells */ n = mbsalign ("¹²³⁴", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0); ASSERT (n == 6); /* 3 characters */ /* Check independence from dest buffer. */ width = 4; /* cells */ n = mbsalign ("¹²³⁴", dest, 0, &width, MBS_ALIGN_LEFT, 0); ASSERT (n == 9); /* 4 characters */ /* Check that width is updated with cells required before padding. */ width = 4; /* cells */ n = mbsalign ("¹²³", dest, 0, &width, MBS_ALIGN_LEFT, 0); ASSERT (width == 3); /* Test case where output is larger than input (as tab converted to multi byte replacement char). */ width = 4; n = mbsalign ("t\tés" /* 6 including NUL */ , dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0); ASSERT (n == 7); /* Test forced unibyte truncation. */ width = 4; n = mbsalign ("t\tés", dest, sizeof dest, &width, MBS_ALIGN_LEFT, MBA_UNIBYTE_ONLY); ASSERT (n == 4); } return 0; }
void list_partition_types(struct fdisk_context *cxt) { struct fdisk_parttype *types; size_t ntypes = 0; if (!cxt || !cxt->label || !cxt->label->parttypes) return; types = cxt->label->parttypes; ntypes = cxt->label->nparttypes; if (types[0].typestr == NULL) { /* * Prints in 4 columns in format <hex> <name> */ size_t last[4], done = 0, next = 0, size; int i; size = ntypes; if (types[ntypes - 1].name == NULL) size--; for (i = 3; i >= 0; i--) last[3 - i] = done += (size + i - done) / (i + 1); i = done = 0; do { #define NAME_WIDTH 15 char name[NAME_WIDTH * MB_LEN_MAX]; size_t width = NAME_WIDTH; struct fdisk_parttype *t = &types[next]; size_t ret; if (t->name) { printf("%c%2x ", i ? ' ' : '\n', t->type); ret = mbsalign(_(t->name), name, sizeof(name), &width, MBS_ALIGN_LEFT, 0); if (ret == (size_t)-1 || ret >= sizeof(name)) printf("%-15.15s", _(t->name)); else fputs(name, stdout); } next = last[i++] + done; if (i > 3 || next >= last[i]) { i = 0; next = ++done; } } while (done < last[0]); } else { /* * Prints 1 column in format <idx> <name> <typestr> */ struct fdisk_parttype *t; size_t i; for (i = 0, t = types; t && i < ntypes; t++, i++) { if (t->name) printf("%3zu %-30s %s\n", i + 1, t->name, t->typestr); } } putchar('\n'); }