⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 printf.c

📁 linux下用PCMCIA无线网卡虚拟无线AP的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This file based on printf.c from 'Dlibs' on the atari ST  (RdeBath) * *  *    Dale Schumacher                         399 Beacon Ave. *    (alias: Dalnefre')                      St. Paul, MN  55104 *    dal@syntel.UUCP                         United States of America *  "It's not reality that's important, but how you perceive things." *//* Altered to use stdarg, made the core function vfnprintf. * Hooked into the stdio package using 'inside information' * Altered sizeof() assumptions, now assumes all integers except chars * will be either *  sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) * * -RDB *//* *                    Manuel Novoa III   Dec 2000 * * The previous vfnprintf routine was almost completely rewritten with the * goal of fixing some shortcomings and reducing object size. * * The summary of changes: * * Converted print conversion specification parsing from one big switch *   to a method using string tables.  This new method verifies that the *   conversion flags, field width, precision, qualifier, and specifier *   appear in the correct order.  Many questionable specifications were *   accepted by the previous code.  This new method also resulted in a *   substantial reduction in object size of about 330 bytes (20%) from *   the old version (1627 bytes) on i386, even with the following *   improvements. * *     Implemented %n specifier as required by the standards. *     Implemented proper handling of precision for int types. *     Implemented # for hex and pointer, fixed error for octal rep of 0. *     Implemented return of -1 on stream error. * * Added optional support for the GNU extension %m which prints the string *   corresponding the errno. * * Added optional support for long long ints and unsigned long long ints *   using the conversion qualifiers "ll", "L", or "q" (like glibc). * * Added optional support for doubles in a very limited form.  None of *   the formating options are obeyed.  The string returned by __dtostr *   is printed directly. * * Converted to use my (un)signed long (long) to string routines, which are * smaller than the previous functions and don't require static buffers. * * Other Modifications: *   Modified sprintf, snprintf, vsprintf, vsnprintf to share on fake-file. *//* *                    Manuel Novoa III   Jan 2001 * * Removed fake file from *s*printf functions because of possible problems *    if called recursively.  Instead, have sprintf, snprintf, and vsprintf *    call vsnprintf which allocates a fake file on the stack. * Removed WANT_FPUTC option.  Always use standard putc macro to avoid *    problems with the fake file used by the *s*printf functions. * Fixed bug parsing flags -- did not restart scan. * Added function asprintf. * Fixed 0-pad prefixing bug. * Converted sizeof(int) == sizeof(long) tests to compile time vs run time. *    This saves 112 bytes of code on i386. * Fixed precision bug -- when negative set to default. * Added function fnprintf to support __dtostr. * Added floating point support for doubles.  Yeah! *  * * May 2001     Fixes from Johan Adolfsson (johan.adolfsson@axis.com) *    1) printf("%c",0) returned 0 instead of 1. *    2) unrolled loop in asprintf to reduce size and remove compile warning. * * * June 2001 *    1) fix %p so that "0x" is prepended to outputed hex val *    2) fix %p so that "(nil)" is output for (void *)0 to match glibc * *//*****************************************************************************//*                            OPTIONS                                        *//*****************************************************************************//* The optional support for long longs and doubles comes in two forms. * *   1) Normal (or partial for doubles) output support.  Set to 1 to turn on. *      Adds about 130 bytes for doubles, about 220 bytes for long longs, *      and about 275 for both to the base code size of 1163 on i386. *//* These are now set in uClibc_config.h based on Config. *//*#define __UCLIBC_HAS_LONG_LONG__         1#define __UCLIBC_HAS_FLOATS__            1*//*   2) An error message is inserted into the stream, an arg of the *      appropriate size is removed from the arglist, and processing *      continues.  This is adds less code and may be useful in some *      cases.  Set to 1 to turn on.  Adds about 50 bytes for doubles, *      about 140 bytes for long longs, and about 175 bytes for both *      to the base code size of 1163 on i386. */#define WANT_LONG_LONG_ERROR   0#define WANT_FLOAT_ERROR      0/* * Set to support GNU extension of %m to print string corresponding to errno. * * Warning: This adds about 50 bytes (i386) to the code but it also pulls in * strerror and the corresponding string table which together are about 3.8k. */#define WANT_GNU_ERRNO         0/**************************************************************************/#include <sys/types.h>#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <limits.h>#include <assert.h>#if WANT_GNU_ERRNO#include <errno.h>#endif#ifdef __STDC__#include <stdarg.h>#define va_strt      va_start#else#include <varargs.h>#define va_strt(p,i) va_start(p)#endif#include "stdio.h"extern int vfnprintf(FILE * op, size_t max_size,					 register __const char *fmt, register va_list ap);#ifdef L_printfint printf(const char *fmt, ...){	va_list ptr;	int rv;	va_strt(ptr, fmt);	rv = vfnprintf(stdout, -1, fmt, ptr);	va_end(ptr);	return rv;}#endif#ifdef L_asprintfint asprintf(char **app, const char *fmt, ...){	va_list ptr;	int rv;	char *p;	/*	 * First iteration - find out size of buffer required and allocate it.	 */	va_strt(ptr, fmt);	rv = vsnprintf(NULL, 0, fmt, ptr);	va_end(ptr);	p = malloc(++rv);			/* allocate the buffer */	*app = p;	if (!p) {		return -1;	}	/*	 * Second iteration - actually produce output.	 */	va_strt(ptr, fmt);	rv = vsnprintf(p, rv, fmt, ptr);	va_end(ptr);	return rv;}#endif#ifdef L_sprintfint sprintf(char *sp, const char *fmt, ...){	va_list ptr;	int rv;	va_strt(ptr, fmt);	rv = vsnprintf(sp, -1, fmt, ptr);	va_end(ptr);	return rv;}#endif#ifdef L_snprintfint snprintf(char *sp, size_t size, const char *fmt, ...){	va_list ptr;	int rv;	va_strt(ptr, fmt);	rv = vsnprintf(sp, size, fmt, ptr);	va_end(ptr);	return rv;}#endif#ifdef L_fprintfint fprintf(FILE * fp, const char *fmt, ...){	va_list ptr;	int rv;	va_strt(ptr, fmt);	rv = vfnprintf(fp, -1, fmt, ptr);	va_end(ptr);	return rv;}#endif#ifdef L_fnprintfint fnprintf(FILE * fp, size_t size, const char *fmt, ...){	va_list ptr;	int rv;	va_strt(ptr, fmt);	rv = vfnprintf(fp, size, fmt, ptr);	va_end(ptr);	return rv;}#endif#ifdef L_vprintfint vprintf(const char *fmt, va_list ap){	return vfprintf(stdout, fmt, ap);}#endif#ifdef L_vfprintfint vfprintf(FILE * op, register __const char *fmt, register va_list ap){	return vfnprintf(op, -1, fmt, ap);}#endif#ifdef L_vsprintfint vsprintf(char *sp, __const char *fmt, va_list ap){	return vsnprintf(sp, -1, fmt, ap);}#endif#ifdef L_vsnprintfint vsnprintf(char *sp, size_t size, __const char *fmt, va_list ap){	int rv;	FILE f;	/*	 * As we're only using the putc macro in vfnprintf, we don't need to	 * initialize all FILE f's fields.	 */	f.bufwrite = (char *) ((unsigned) -1);	f.bufpos = sp;	f.mode = _IOFBF;	rv = vfnprintf(&f, size, fmt, ap);	if (size) {					/* If this is going to a buffer, */		*(f.bufpos) = 0;		/* don't forget to nul-terminate. */	}	return rv;}#endif#ifdef L_vdprintf/* * Note: If fd has an associated buffered FILE, bad things happen. */extern int vdprintf(int fd, const char *fmt, va_list ap){	char buf[BUFSIZ];	FILE f = {buf, 0, buf+sizeof(buf), buf, buf+sizeof(buf), 0, fd, _IOFBF};	int rv;	rv = vfnprintf(&f, -1, fmt, ap);	if (fflush(&f)) {		return -1;	}	return rv;}#endif#ifdef L_vfnprintfextern char *__ultostr(char *buf, unsigned long uval, int base, int uppercase);extern char *__ltostr(char *buf, long val, int base, int uppercase);extern char *__ulltostr(char *buf, unsigned long long uval, int base, int uppercase);extern char *__lltostr(char *buf, long long val, int base, int uppercase);extern int __dtostr(FILE * fp, size_t size, long double x,				  char flag[], int width, int preci, char mode);enum {	FLAG_PLUS = 0,	FLAG_MINUS_LJUSTIFY,	FLAG_HASH,	FLAG_0_PAD,	FLAG_SPACE,};/* layout                   01234  */static const char spec[] = "+-#0 ";#if defined(__UCLIBC_HAS_LONG_LONG__) || WANT_LONG_LONG_ERRORstatic const char qual[] = "hlLq";#elsestatic const char qual[] = "hl";#endif#if !defined(__UCLIBC_HAS_LONG_LONG__) && WANT_LONG_LONG_ERRORstatic const char ll_err[] = "<LONG-LONG>";#endif#if !defined(__UCLIBC_HAS_FLOATS__) && WANT_FLOAT_ERRORstatic const char dbl_err[] = "<DOUBLE>";#endif#if defined(__UCLIBC_HAS_FLOATS__) || WANT_FLOAT_ERROR/* layout                     012345678901234567   */static const char u_spec[] = "%nbopxXudicsfgGeEaA";#else/* layout                     0123456789012   */static const char u_spec[] = "%nbopxXudics";#endif/* WARNING: u_spec and u_radix need to stay in agreement!!! *//* u_radix[i] <-> u_spec[i+2] for unsigned entries only */static const char u_radix[] = "\x02\x08\x10\x10\x10\x0a";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -