Browse Source

Allow vcprintf() to be called by external code such as the curses library.

Also trim another eight bytes from vsprintf.o.  :)
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
84a493b88d
2 changed files with 67 additions and 38 deletions
  1. 38
    38
      src/core/vsprintf.c
  2. 29
    0
      src/include/vsprintf.h

+ 38
- 38
src/core/vsprintf.c View File

@@ -40,32 +40,6 @@ static uint8_t type_sizes[] = {
40 40
 	[SIZE_T_LEN]	= sizeof ( size_t ),
41 41
 };
42 42
 
43
-/**
44
- * A printf context
45
- *
46
- * Contexts are used in order to be able to share code between
47
- * vprintf() and vsnprintf(), without requiring the allocation of a
48
- * buffer for vprintf().
49
- */
50
-struct printf_context {
51
-	/**
52
-	 * Character handler
53
-	 *
54
-	 * @v ctx	Context
55
-	 * @v c		Character
56
-	 *
57
-	 * This method is called for each character written to the
58
-	 * formatted string.  It must increment @len.
59
-	 */
60
-	void ( * handler ) ( struct printf_context *ctx, unsigned int c );
61
-	/** Length of formatted string */
62
-	size_t len;
63
-	/** Buffer for formatted string (used by printf_sputc()) */
64
-	char *buf;
65
-	/** Buffer length (used by printf_sputc()) */
66
-	size_t max_len;
67
-};
68
-
69 43
 /**
70 44
  * Use lower-case for hexadecimal digits
71 45
  *
@@ -163,6 +137,20 @@ static char * format_decimal ( char *end, signed long num, int width ) {
163 137
 	return ptr;
164 138
 }
165 139
 
140
+/**
141
+ * Print character via a printf context
142
+ *
143
+ * @v ctx		Context
144
+ * @v c			Character
145
+ *
146
+ * Call's the printf_context::handler() method and increments
147
+ * printf_context::len.
148
+ */
149
+static inline void cputchar ( struct printf_context *ctx, unsigned int c ) {
150
+	ctx->handler ( ctx, c );
151
+	++ctx->len;
152
+}
153
+
166 154
 /**
167 155
  * Write a formatted string to a printf context
168 156
  *
@@ -185,7 +173,7 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
185 173
 	for ( ; *fmt ; fmt++ ) {
186 174
 		/* Pass through ordinary characters */
187 175
 		if ( *fmt != '%' ) {
188
-			ctx->handler ( ctx, *fmt );
176
+			cputchar ( ctx, *fmt );
189 177
 			continue;
190 178
 		}
191 179
 		fmt++;
@@ -228,7 +216,7 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
228 216
 		ptr = tmp_buf + sizeof ( tmp_buf ) - 1;
229 217
 		*ptr = '\0';
230 218
 		if ( *fmt == 'c' ) {
231
-			ctx->handler ( ctx, va_arg ( args, unsigned int ) );
219
+			cputchar ( ctx, va_arg ( args, unsigned int ) );
232 220
 		} else if ( *fmt == 's' ) {
233 221
 			ptr = va_arg ( args, char * );
234 222
 		} else if ( *fmt == 'p' ) {
@@ -263,13 +251,22 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
263 251
 		}
264 252
 		/* Write out conversion result */
265 253
 		for ( ; *ptr ; ptr++ ) {
266
-			ctx->handler ( ctx, *ptr );
254
+			cputchar ( ctx, *ptr );
267 255
 		}
268 256
 	}
269 257
 
270 258
 	return ctx->len;
271 259
 }
272 260
 
261
+/** Context used by vsnprintf() and friends */
262
+struct sputc_context {
263
+	struct printf_context ctx;
264
+	/** Buffer for formatted string (used by printf_sputc()) */
265
+	char *buf;
266
+	/** Buffer length (used by printf_sputc()) */
267
+	size_t max_len;	
268
+};
269
+
273 270
 /**
274 271
  * Write character to buffer
275 272
  *
@@ -277,8 +274,11 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
277 274
  * @v c			Character
278 275
  */
279 276
 static void printf_sputc ( struct printf_context *ctx, unsigned int c ) {
280
-	if ( ++ctx->len < ctx->max_len )
281
-		ctx->buf[ctx->len-1] = c;
277
+	struct sputc_context * sctx =
278
+		container_of ( ctx, struct sputc_context, ctx );
279
+
280
+	if ( ctx->len <= sctx->max_len )
281
+		sctx->buf[ctx->len] = c;
282 282
 }
283 283
 
284 284
 /**
@@ -295,15 +295,15 @@ static void printf_sputc ( struct printf_context *ctx, unsigned int c ) {
295 295
  * been available.
296 296
  */
297 297
 int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args ) {
298
-	struct printf_context ctx;
298
+	struct sputc_context sctx;
299 299
 	size_t len;
300 300
 	size_t end;
301 301
 
302 302
 	/* Hand off to vcprintf */
303
-	ctx.handler = printf_sputc;
304
-	ctx.buf = buf;
305
-	ctx.max_len = size;
306
-	len = vcprintf ( &ctx, fmt, args );
303
+	sctx.ctx.handler = printf_sputc;
304
+	sctx.buf = buf;
305
+	sctx.max_len = size;
306
+	len = vcprintf ( &sctx.ctx, fmt, args );
307 307
 
308 308
 	/* Add trailing NUL */
309 309
 	if ( size ) {
@@ -341,8 +341,8 @@ int snprintf ( char *buf, size_t size, const char *fmt, ... ) {
341 341
  * @v ctx		Context
342 342
  * @v c			Character
343 343
  */
344
-static void printf_putchar ( struct printf_context *ctx, unsigned int c ) {
345
-	++ctx->len;
344
+static void printf_putchar ( struct printf_context *ctx __unused,
345
+			     unsigned int c ) {
346 346
 	putchar ( c );
347 347
 }
348 348
 

+ 29
- 0
src/include/vsprintf.h View File

@@ -35,6 +35,35 @@
35 35
 
36 36
 #define PRINTF_NO_LENGTH ( ( size_t ) -1 )
37 37
 
38
+/**
39
+ * A printf context
40
+ *
41
+ * Contexts are used in order to be able to share code between
42
+ * vprintf() and vsnprintf(), without requiring the allocation of a
43
+ * buffer for vprintf().
44
+ */
45
+struct printf_context {
46
+	/**
47
+	 * Character handler
48
+	 *
49
+	 * @v ctx	Context
50
+	 * @v c		Character
51
+	 *
52
+	 * This method is called for each character written to the
53
+	 * formatted string.
54
+	 */
55
+	void ( * handler ) ( struct printf_context *ctx, unsigned int c );
56
+	/** Length of formatted string
57
+	 *
58
+	 * When handler() is called, @len will be set to the number of
59
+	 * characters written so far (i.e. zero for the first call to
60
+	 * handler()).
61
+	 */
62
+	size_t len;
63
+};
64
+
65
+extern size_t vcprintf ( struct printf_context *ctx, const char *fmt,
66
+			 va_list args );
38 67
 extern int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args );
39 68
 extern int vprintf ( const char *fmt, va_list args );
40 69
 

Loading…
Cancel
Save