Rewrite and improve formatted output routines.
[pspp-builds.git] / src / libpspp / str.c
index 6d25c339fad9550d618f63d6f33f9ba3f442eec7..965e3b301b5c67326390383d5e23c66d77c50280 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <libpspp/alloc.h>
 #include <libpspp/message.h>
+#include <libpspp/pool.h>
 
 #include "minmax.h"
 #include "size_max.h"
@@ -157,6 +158,22 @@ buf_copy_str_lpad (char *dst, size_t dst_size, const char *src)
     }
 }
 
+/* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes.
+   DST is truncated to DST_SIZE bytes or padded on the left with
+   spaces as needed. */
+void
+buf_copy_lpad (char *dst, size_t dst_size,
+               const char *src, size_t src_size)
+{
+  if (src_size >= dst_size)
+    memmove (dst, src, dst_size);
+  else
+    {
+      memset (dst, ' ', dst_size - src_size);
+      memmove (&dst[dst_size - src_size], src, src_size);
+    }
+}
+
 /* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes.
    DST is truncated to DST_SIZE bytes or padded on the right with
    spaces as needed. */
@@ -252,6 +269,15 @@ spprintf (char *dst, const char *format, ...)
 
   return dst + count;
 }
+
+/* Sets the SIZE bytes starting at BLOCK to C,
+   and returns the byte following BLOCK. */
+void *
+mempset (void *block, int c, size_t size) 
+{
+  memset (block, c, size);
+  return (char *) block + size;
+}
 \f
 /* Substrings. */
 
@@ -676,6 +702,30 @@ ds_swap (struct string *a, struct string *b)
   *b = tmp;
 }
 
+/* Helper function for ds_register_pool. */
+static void
+free_string (void *st_) 
+{
+  struct string *st = st_;
+  ds_destroy (st);
+}
+
+/* Arranges for ST to be destroyed automatically as part of
+   POOL. */
+void
+ds_register_pool (struct string *st, struct pool *pool) 
+{
+  pool_register (pool, free_string, st);
+}
+
+/* Cancels the arrangement for ST to be destroyed automatically
+   as part of POOL. */
+void
+ds_unregister_pool (struct string *st, struct pool *pool)
+{
+  pool_unregister (pool, st);
+}
+
 /* Copies SRC into DST.
    DST and SRC may be the same string. */
 void
@@ -860,6 +910,18 @@ ds_rpad (struct string *st, size_t length, char pad)
     ds_put_char_multiple (st, pad, length - st->ss.length);
 }
 
+/* Sets the length of ST to exactly NEW_LENGTH,
+   either by truncating characters from the end,
+   or by padding on the right with PAD. */
+void
+ds_set_length (struct string *st, size_t new_length, char pad)
+{
+  if (st->ss.length < new_length)
+    ds_rpad (st, new_length, pad);
+  else
+    st->ss.length = new_length;
+}
+
 /* Returns true if ST is empty, false otherwise. */
 bool
 ds_is_empty (const struct string *st)