-#define PUTDF(cp, num, wid, fill)\
- if (cp + wid < ep) {\
- if ((i = (num)) < 0)\
- i = -(num);\
- if ((c = (wid)) < 0)\
- c = -c;\
- sp = cp + c;\
- do {\
- *--sp = (i % 10) + '0';\
- i /= 10;\
- } while (i > 0 && sp > cp);\
- if (i > 0)\
- *sp = '?';\
- else if ((num) < 0 && sp > cp)\
- *--sp = '-';\
- while (sp > cp)\
- *--sp = fill;\
- cp += c;\
- }
-
-char * PUTSF(char *cp, char *str, unsigned int wid, char fill) {
-
- unsigned int i, j;
- unsigned int char_len;
- unsigned int term_len = 0;
+void
+cpnumber(charstring_t dest, int num, unsigned int wid, char fill, size_t max) {
+ if (wid < (num >= 0 ? max : max-1)) {
+ /* Build up the string representation of num in reverse. */
+ charstring_t rev = charstring_create (0);
+ int i = num >= 0 ? num : -num;
+
+ do {
+ charstring_push_back (rev, i % 10 + '0');
+ i /= 10;
+ } while (--wid > 0 && i > 0);
+ if (i > 0) {
+ /* Overflowed the field (wid). */
+ charstring_push_back (rev, '?');
+ } else if (num < 0 && wid > 0) {
+ /* Shouldn't need the wid > 0 check, that's why the condition
+ at the top checks wid < max-1 when num < 0. */
+ --wid;
+ if (fill == ' ') {
+ charstring_push_back (rev, '-');
+ }
+ }
+ while (wid-- > 0 && fill != 0) {
+ charstring_push_back (rev, fill);
+ }
+ if (num < 0 && fill == '0') {
+ charstring_push_back (rev, '-');
+ }
+
+ {
+ /* Output the string in reverse. */
+ size_t b = charstring_bytes (rev);
+ const char *cp = b ? &charstring_buffer (rev)[b] : NULL;
+
+ for (; b > 0; --b) {
+ charstring_push_back (dest, *--cp);
+ }
+ }
+
+ charstring_free (rev);
+ }
+}
+
+/*
+ * copy string from str to dest padding with the fill character to a
+ * size of wid characters. if wid is negative, the string is right
+ * aligned no more than max characters are copied
+ */
+void
+cptrimmed(charstring_t dest, char *str, int wid, char fill, size_t max) {
+ int remaining; /* remaining output width available */
+ int rjust;
+ struct charstring *trimmed;
+ size_t end; /* number of input bytes remaining in str */
+#ifdef MULTIBYTE_SUPPORT
+ int char_len; /* bytes in current character */
+ int w;