From owner-freebsd-arch Sat Jan 27 14:43:37 2001 Delivered-To: freebsd-arch@freebsd.org Received: from flood.ping.uio.no (flood.ping.uio.no [129.240.78.31]) by hub.freebsd.org (Postfix) with ESMTP id 9E91B37B400 for ; Sat, 27 Jan 2001 14:43:10 -0800 (PST) Received: (from des@localhost) by flood.ping.uio.no (8.9.3/8.9.3) id XAA02930; Sat, 27 Jan 2001 23:43:02 +0100 (CET) (envelope-from des@ofug.org) X-URL: http://www.ofug.org/~des/ X-Disclaimer: The views expressed in this message do not necessarily coincide with those of any organisation or company with which I am or have been affiliated. To: "Justin T. Gibbs" Cc: freebsd-arch@FreeBSD.ORG Subject: Re: Proposed change to sbuf semantics References: <200101272230.f0RMUWO30395@aslan.scsiguy.com> From: Dag-Erling Smorgrav Date: 27 Jan 2001 23:43:02 +0100 In-Reply-To: "Justin T. Gibbs"'s message of "Sat, 27 Jan 2001 15:30:32 -0700" Message-ID: Lines: 12 User-Agent: Gnus/5.0802 (Gnus v5.8.2) Emacs/20.4 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --=-=-= "Justin T. Gibbs" writes: > >Is this acceptable to you? > I still would need an "sbuf_empty()" type method. This better? DES -- Dag-Erling Smorgrav - des@ofug.org --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=sbuf.diff Content-Description: sbuf patch Index: sys/kern/subr_sbuf.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_sbuf.c,v retrieving revision 1.1 diff -u -r1.1 subr_sbuf.c --- sys/kern/subr_sbuf.c 2000/12/13 19:51:07 1.1 +++ sys/kern/subr_sbuf.c 2001/01/27 22:41:08 @@ -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 @@ * 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 @@ } /* + * 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 @@ 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 @@ 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 @@ } /* - * 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 @@ 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; } Index: sys/sys/sbuf.h =================================================================== RCS file: /home/ncvs/src/sys/sys/sbuf.h,v retrieving revision 1.1 diff -u -r1.1 sbuf.h --- sys/sys/sbuf.h 2000/12/13 19:51:07 1.1 +++ sys/sys/sbuf.h 2001/01/27 22:35:52 @@ -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 @@ }; /* - * 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 Index: share/man/man9/sbuf.9 =================================================================== RCS file: /home/ncvs/src/share/man/man9/sbuf.9,v retrieving revision 1.2 diff -u -r1.2 sbuf.9 --- share/man/man9/sbuf.9 2000/12/14 09:36:49 1.2 +++ share/man/man9/sbuf.9 2001/01/27 22:40:33 @@ -30,11 +30,13 @@ .Os FreeBSD .Sh NAME .Nm sbuf_new , +.Nm sbuf_clear , .Nm sbuf_setpos , .Nm sbuf_cat , .Nm sbuf_cpy , .Nm sbuf_printf , .Nm sbuf_putc , +.Nm sbuf_overflowed , .Nm sbuf_finish , .Nm sbuf_data , .Nm sbuf_len , @@ -43,9 +45,11 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn sbuf_new "struct sbuf *s" "char *buf" "size_t length" "int flags" +.Fn sbuf_new "struct sbuf *s" "char *buf" "int length" "int flags" +.Ft void +.Fn sbuf_clear "struct sbuf *s" .Ft int -.Fn sbuf_setpos "struct sbuf *s" "size_t pos" +.Fn sbuf_setpos "struct sbuf *s" "int pos" .Ft int .Fn sbuf_cat "struct sbuf *s" "char *str" .Ft int @@ -55,10 +59,12 @@ .Ft int .Fn sbuf_putc "struct sbuf *s" "int c" .Ft int +.Fn sbuf_overflowed "struct sbuf *s" +.Ft void .Fn sbuf_finish "struct sbuf *s" .Ft char * .Fn sbuf_data "struct sbuf *s" -.Ft size_t +.Ft int .Fn sbuf_len "struct sbuf *s" .Ft void .Fn sbuf_delete "struct sbuf *s" @@ -102,6 +108,12 @@ characters. .Pp The +.Fn sbuf_clear +function invalidates the contents of the +.Fa sbuf +and resets its position to zero. +.Pp +The .Fn sbuf_setpos function sets the .Fa sbuf Ns 's @@ -129,6 +141,8 @@ with a fresh .Fa sbuf or one which position has been reset to zero with +.Fn sbuf_clear +or .Fn sbuf_setpos . .Pp The @@ -149,6 +163,12 @@ at the current position. .Pp The +.Fn sbuf_overflowed +function returns a non-zero value if the +.Fa sbuf +overflowed. +.Pp +The .Fn sbuf_finish function null-terminates the .Fa sbuf @@ -165,8 +185,9 @@ .Fn sbuf_data and .Fn sbuf_len -functions return the actual string and its length, respectively, and -only work on a finished and non-overflowed +functions return the actual string and its length, respectively; +.Fn sbuf_data +only works on a finished .Fa sbuf . .Pp Finally, the @@ -178,12 +199,14 @@ .Sh NOTES If an operation caused an .Fa sbuf -to overflow, most subsequent operations (including -.Fn sbuf_finish ) -on it will fail until the -.Fa sbuf Ns 's -position is reset to a value between 0 and one less than the size of -its storage buffer using +to overflow, most subsequent operations on it will fail until the +.Fa sbuf +is finished using +.Fn sbuf_finish +or reset using +.Fn sbuf_clear , +or its position is reset to a value between 0 and one less than the +size of its storage buffer using .Fn sbuf_setpos , or it is reinitialized to a sufficiently short string using .Fn sbuf_cpy . @@ -200,17 +223,19 @@ .Fn sbuf_cat , .Fn sbuf_cpy , .Fn sbuf_printf , -.Fn sbuf_putc , and -.Fn sbuf_finish +.Fn sbuf_putc all return \-1 if the buffer overflowed, and zero otherwise. .Pp +.Fn sbuf_overflowed +returns a non-zero value if the buffer overflowed, and zero otherwise. +.Pp .Fn sbuf_data and .Fn sbuf_len return .Dv NULL -and 0, respectively, if the buffer overflowed. +and \-1, respectively, if the buffer overflowed. .Sh SEE ALSO .Xr printf 3 , .Xr strcat 3 , --=-=-=-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message