summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2001-01-28 00:13:01 +0000
committerdes <des@FreeBSD.org>2001-01-28 00:13:01 +0000
commitba6b6e22f55bc3879df3d7e1ddcf477229670098 (patch)
treeacadf9c9903869d9ab5d644419fb18c697b186d4
parent5790cce92db5d94e0d0692cd4d28d5d7e7bb61b6 (diff)
downloadFreeBSD-src-ba6b6e22f55bc3879df3d7e1ddcf477229670098.zip
FreeBSD-src-ba6b6e22f55bc3879df3d7e1ddcf477229670098.tar.gz
Add sbuf_clear() and sbuf_overflowed().
Move the helper macros from sbuf.h to sbuf.c Use ints instead of size_ts. Relax the requirements for sbuf_finish(): it is now possible to finish an overflowed buffer. Make sbuf_len() return -1 instead of 0 if the sbuf overflowed. Requested by: gibbs
-rw-r--r--sys/kern/subr_sbuf.c62
-rw-r--r--sys/sys/sbuf.h27
2 files changed, 57 insertions, 32 deletions
diff --git a/sys/kern/subr_sbuf.c b/sys/kern/subr_sbuf.c
index 9e537a8..c59cea7 100644
--- a/sys/kern/subr_sbuf.c
+++ b/sys/kern/subr_sbuf.c
@@ -38,6 +38,23 @@
MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
+/*
+ * Predicates
+ */
+#define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC)
+#define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED)
+#define SBUF_HASOVERFLOWED(s) ((s)->s_flags & SBUF_OVERFLOWED)
+#define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1)
+
+/*
+ * Set / clear flags
+ */
+#define SBUF_SETFLAG(s, f) do { (s)->s_flags |= (f); } while (0)
+#define SBUF_CLEARFLAG(s, f) do { (s)->s_flags &= ~(f); } while (0)
+
+/*
+ * Debugging support
+ */
#ifdef INVARIANTS
static void
assert_sbuf_integrity(struct sbuf *s)
@@ -68,8 +85,10 @@ assert_sbuf_state(struct sbuf *s, int state)
* big enough to hold at least length characters.
*/
int
-sbuf_new(struct sbuf *s, char *buf, size_t length, int flags)
+sbuf_new(struct sbuf *s, char *buf, int length, int flags)
{
+ KASSERT(length >= 0,
+ ("attempt to create an sbuf of negative length (%d)", length));
KASSERT(flags == 0,
(__FUNCTION__ " called with non-zero flags"));
KASSERT(s != NULL,
@@ -89,10 +108,23 @@ sbuf_new(struct sbuf *s, char *buf, size_t length, int flags)
}
/*
+ * Clear an sbuf and reset its position
+ */
+void
+sbuf_clear(struct sbuf *s)
+{
+ assert_sbuf_integrity(s);
+
+ SBUF_CLEARFLAG(s, SBUF_FINISHED);
+ SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
+ s->s_len = 0;
+}
+
+/*
* Set the sbuf's position to an arbitrary value
*/
int
-sbuf_setpos(struct sbuf *s, size_t pos)
+sbuf_setpos(struct sbuf *s, int pos)
{
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
@@ -138,7 +170,7 @@ sbuf_cpy(struct sbuf *s, char *str)
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
- s->s_len = 0;
+ sbuf_clear(s);
return (sbuf_cat(s, str));
}
@@ -168,7 +200,7 @@ int
sbuf_printf(struct sbuf *s, char *fmt, ...)
{
va_list ap;
- size_t len;
+ int len;
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
@@ -212,20 +244,26 @@ sbuf_putc(struct sbuf *s, int c)
}
/*
- * Finish off an sbuf.
+ * Check if an sbuf overflowed
*/
int
+sbuf_overflowed(struct sbuf *s)
+{
+ return SBUF_HASOVERFLOWED(s);
+}
+
+/*
+ * Finish off an sbuf.
+ */
+void
sbuf_finish(struct sbuf *s)
{
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
- if (SBUF_HASOVERFLOWED(s))
- return (-1);
-
s->s_buf[s->s_len++] = '\0';
+ SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
SBUF_SETFLAG(s, SBUF_FINISHED);
- return (0);
}
/*
@@ -237,22 +275,20 @@ sbuf_data(struct sbuf *s)
assert_sbuf_integrity(s);
assert_sbuf_state(s, SBUF_FINISHED);
- if (SBUF_HASOVERFLOWED(s))
- return (NULL);
return s->s_buf;
}
/*
* Return the length of the sbuf data.
*/
-size_t
+int
sbuf_len(struct sbuf *s)
{
assert_sbuf_integrity(s);
assert_sbuf_state(s, SBUF_FINISHED);
if (SBUF_HASOVERFLOWED(s))
- return (0);
+ return (-1);
return s->s_len;
}
diff --git a/sys/sys/sbuf.h b/sys/sys/sbuf.h
index 5995ec1..0244466 100644
--- a/sys/sys/sbuf.h
+++ b/sys/sys/sbuf.h
@@ -37,8 +37,8 @@
struct sbuf {
char *s_buf; /* storage buffer */
struct sbuf *s_next; /* next in chain */
- size_t s_size; /* size of storage buffer */
- size_t s_len; /* current length of string */
+ int s_size; /* size of storage buffer */
+ int s_len; /* current length of string */
#define SBUF_AUTOEXTEND 0x00000001 /* automatically extend buffer */
#define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */
#define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */
@@ -47,30 +47,19 @@ struct sbuf {
};
/*
- * Predicates
- */
-#define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC)
-#define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED)
-#define SBUF_HASOVERFLOWED(s) ((s)->s_flags & SBUF_OVERFLOWED)
-#define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1)
-
-/*
- * Other macros
- */
-#define SBUF_SETFLAG(s, f) do { (s)->s_flags |= (f); } while (0)
-
-/*
* API functions
*/
-int sbuf_new(struct sbuf *s, char *buf, size_t length, int flags);
-int sbuf_setpos(struct sbuf *s, size_t pos);
+int sbuf_new(struct sbuf *s, char *buf, int length, int flags);
+void sbuf_clear(struct sbuf *s);
+int sbuf_setpos(struct sbuf *s, int pos);
int sbuf_cat(struct sbuf *s, char *str);
int sbuf_cpy(struct sbuf *s, char *str);
int sbuf_printf(struct sbuf *s, char *fmt, ...);
int sbuf_putc(struct sbuf *s, int c);
-int sbuf_finish(struct sbuf *s);
+int sbuf_overflowed(struct sbuf *s);
+void sbuf_finish(struct sbuf *s);
char *sbuf_data(struct sbuf *s);
-size_t sbuf_len(struct sbuf *s);
+int sbuf_len(struct sbuf *s);
void sbuf_delete(struct sbuf *s);
#endif
OpenPOWER on IntegriCloud