summaryrefslogtreecommitdiffstats
path: root/lib/libtabular/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libtabular/src/util.c')
-rw-r--r--lib/libtabular/src/util.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/lib/libtabular/src/util.c b/lib/libtabular/src/util.c
new file mode 100644
index 0000000..c2baa24
--- /dev/null
+++ b/lib/libtabular/src/util.c
@@ -0,0 +1,146 @@
+#include "util.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+size_t
+u8strlen(const char *str)
+{
+ size_t i, len;
+
+ if (!str) return 0;
+
+ len = 0;
+ for (i = 0; str[i]; i++) {
+ if ((str[i] & 0xC0) != 0x80)
+ len += 1;
+ }
+
+ return len;
+}
+
+size_t
+u8strnlen(const char *str, size_t max)
+{
+ size_t i, len;
+
+ if (!str) return 0;
+
+ len = 0;
+ for (i = 0; str[i] && i < max; i++) {
+ if ((str[i] & 0xC0) != 0x80)
+ len += 1;
+ }
+
+ return len;
+}
+
+size_t
+u8rawlen(const char *str, size_t max)
+{
+ size_t i, len;
+
+ if (!str) return 0;
+
+ len = 0;
+ for (i = 0; str[i] && len < max; i++)
+ if ((str[i] & 0xC0) != 0x80) {
+ len += 1;
+ }
+
+ return i;
+}
+
+size_t
+print_pad(FILE *file, size_t len)
+{
+ fprintf(file, "%*.s", (int) len, "");
+
+ return len;
+}
+
+size_t
+print_hex(FILE *file, const void *bytes, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++)
+ fprintf(file, "%02X", *(uint8_t *)(bytes + i));
+
+ return len * 2;
+}
+
+size_t
+print_trunc(FILE *file, const char *str, size_t width)
+{
+ size_t len;
+
+ len = u8strlen(str);
+ if (len > width && width >= 2) {
+ fprintf(file, "%*.*s..", (int) width - 2, (int) width - 2, str);
+ } else if (len > width&& width < 2) {
+ fprintf(file, "%*.*s", (int) width, (int) width, "..");
+ } else {
+ fprintf(file, "%s", str);
+ }
+
+ return MIN(len, width);
+}
+
+size_t
+print_left(FILE *file, const char *str, size_t width, size_t padwidth)
+{
+ size_t rawlen, u8len;
+ ssize_t ret;
+
+ u8len = MIN(u8strlen(str), width);
+ rawlen = u8rawlen(str, u8len);
+
+ /* make up for invisible bytes */
+ padwidth += rawlen - u8len;
+
+ ret = fprintf(file, "%-*.*s", (int) padwidth, (int) rawlen, str);
+
+ return (size_t) MAX(0, ret);
+}
+
+size_t
+print_center(FILE *file, const char *str, size_t width, size_t padwidth)
+{
+ size_t u8len, rawlen;
+ size_t lpad, rpad;
+ ssize_t ret;
+
+ u8len = MIN(width, u8strlen(str));
+ rawlen = u8rawlen(str, u8len);
+ lpad = MAX(padwidth - u8len, 0) / 2;
+ rpad = MAX(padwidth - u8len - lpad, 0);
+
+ /* make up for invisible bytes */
+ rpad += rawlen - u8len;
+
+ ret = fprintf(file, "%*s%*.*s%*s", (int) lpad, "",
+ (int) rawlen, (int) rawlen, str, (int) rpad, "");
+
+ return (size_t) MAX(0, ret);
+}
+
+size_t
+print_right(FILE *file, const char *str, size_t width, size_t padwidth)
+{
+ size_t rawlen, u8len;
+ ssize_t ret;
+
+ u8len = MIN(width, u8strlen(str));
+ rawlen = u8rawlen(str, u8len);
+
+ /* make up for invisible bytes */
+ padwidth += rawlen - u8len;
+
+ ret = fprintf(file, "%*.*s", (int) padwidth, (int) rawlen, str);
+
+ return (size_t) MAX(0, ret);
+}
+