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
 	[SIZE_T_LEN]	= sizeof ( size_t ),
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
  * Use lower-case for hexadecimal digits
44
  * Use lower-case for hexadecimal digits
71
  *
45
  *
163
 	return ptr;
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
  * Write a formatted string to a printf context
155
  * Write a formatted string to a printf context
168
  *
156
  *
185
 	for ( ; *fmt ; fmt++ ) {
173
 	for ( ; *fmt ; fmt++ ) {
186
 		/* Pass through ordinary characters */
174
 		/* Pass through ordinary characters */
187
 		if ( *fmt != '%' ) {
175
 		if ( *fmt != '%' ) {
188
-			ctx->handler ( ctx, *fmt );
176
+			cputchar ( ctx, *fmt );
189
 			continue;
177
 			continue;
190
 		}
178
 		}
191
 		fmt++;
179
 		fmt++;
228
 		ptr = tmp_buf + sizeof ( tmp_buf ) - 1;
216
 		ptr = tmp_buf + sizeof ( tmp_buf ) - 1;
229
 		*ptr = '\0';
217
 		*ptr = '\0';
230
 		if ( *fmt == 'c' ) {
218
 		if ( *fmt == 'c' ) {
231
-			ctx->handler ( ctx, va_arg ( args, unsigned int ) );
219
+			cputchar ( ctx, va_arg ( args, unsigned int ) );
232
 		} else if ( *fmt == 's' ) {
220
 		} else if ( *fmt == 's' ) {
233
 			ptr = va_arg ( args, char * );
221
 			ptr = va_arg ( args, char * );
234
 		} else if ( *fmt == 'p' ) {
222
 		} else if ( *fmt == 'p' ) {
263
 		}
251
 		}
264
 		/* Write out conversion result */
252
 		/* Write out conversion result */
265
 		for ( ; *ptr ; ptr++ ) {
253
 		for ( ; *ptr ; ptr++ ) {
266
-			ctx->handler ( ctx, *ptr );
254
+			cputchar ( ctx, *ptr );
267
 		}
255
 		}
268
 	}
256
 	}
269
 
257
 
270
 	return ctx->len;
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
  * Write character to buffer
271
  * Write character to buffer
275
  *
272
  *
277
  * @v c			Character
274
  * @v c			Character
278
  */
275
  */
279
 static void printf_sputc ( struct printf_context *ctx, unsigned int c ) {
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
  * been available.
295
  * been available.
296
  */
296
  */
297
 int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args ) {
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
 	size_t len;
299
 	size_t len;
300
 	size_t end;
300
 	size_t end;
301
 
301
 
302
 	/* Hand off to vcprintf */
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
 	/* Add trailing NUL */
308
 	/* Add trailing NUL */
309
 	if ( size ) {
309
 	if ( size ) {
341
  * @v ctx		Context
341
  * @v ctx		Context
342
  * @v c			Character
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
 	putchar ( c );
346
 	putchar ( c );
347
 }
347
 }
348
 
348
 

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

35
 
35
 
36
 #define PRINTF_NO_LENGTH ( ( size_t ) -1 )
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
 extern int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args );
67
 extern int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args );
39
 extern int vprintf ( const char *fmt, va_list args );
68
 extern int vprintf ( const char *fmt, va_list args );
40
 
69
 

Loading…
Cancel
Save