jnand_printf.c
来自「QUALCOMM JNAND DRIVER」· C语言 代码 · 共 803 行 · 第 1/2 页
C
803 行
#ifdef COMPILE_PRINTF
#define DISABLE_TERM
/*
* Mach Operating System
* Copyright (c) 1993 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* HISTORY
*
* 02/06/03 pg Moved from ASWP402 server to ASWP401 server.
* Added #ifdef COMPILE_PRINTF around it.
*
* $Log: printf.c,v $
* Revision 1.1 1999/01/20 18:32:11 qcdb
* Initial checkin.
*
* Revision 1.1 1995/06/07 20:42:08 dbrown
* MK83 distribution from CMU
*
* Revision 2.15 93/03/09 10:55:12 danner
* Lint to quiet GCC.
* [93/03/07 13:25:20 af]
*
* A better, MP-safe sprintf.
* [93/03/05 af]
*
* Revision 2.14 93/01/27 09:34:37 danner
* printf_init(), sprintf() are void.
* [93/01/25 jfriedl]
*
* Updated copyright.
* [93/01/12 berman]
* Wrote a version of sprintf() for general use.
* [92/03/18 berman]
*
* Revision 2.13 93/01/14 17:35:37 danner
* 64bit cleanup. Tuned up doprnt slightly.
* [92/12/01 af]
*
* Revision 2.12 92/08/03 17:38:32 jfriedl
* removed silly prototypes
* [92/08/02 jfriedl]
*
* Revision 2.11 92/05/21 17:14:57 jfriedl
* Cleanup to quiet gcc warnings.
* Changed PUTC arg of _doprnt, etc. to be VOID (which it is)
* [92/05/16 jfriedl]
*
* Revision 2.10 92/04/01 19:33:21 rpd
* Renamed gets to safe_gets.
* [92/03/31 rpd]
*
* Revision 2.9 91/06/06 17:07:22 jsb
* Added gets (derived from boot_gets).
* [91/05/14 09:18:50 jsb]
*
* Revision 2.8 91/05/14 16:44:59 mrt
* Correcting copyright
*
* Revision 2.7 91/02/05 17:28:14 mrt
* Changed to new Mach copyright
* [91/02/01 16:15:41 mrt]
*
* Revision 2.6 90/10/25 14:45:18 rwd
* Purged uprintf.
* [90/10/21 rpd]
*
* Revision 2.5 90/08/27 22:03:08 dbg
* Add extra formats to printf: '#- ' prefixes, %z (signed hex),
* %r and %n (signed and unsigned, current radix).
* [90/08/20 dbg]
*
* Revision 2.4 90/01/11 11:43:44 dbg
* De-linted.
* [90/01/03 dbg]
*
* Revision 2.3 89/11/29 14:09:06 af
* Ooops, a typo.
* [89/10/29 09:34:26 af]
*
* Changed the case for %c to load ints and not chars. Or
* else it is byte-order dependent since C passes char as ints.
* [89/10/13 af]
*
* Turned the unused 'file descriptor' field for _doprnt and putchar
* into a more useful pointer to an (optional) specialized putchar
* routine. This can be used, for instance, to divert debugging
* printouts to some specialized interface or IOP.
* [89/10/09 af]
*
* Revision 2.2 89/09/25 11:00:58 rwd
* Added case 'X' same as 'x' for now.
* [89/09/20 rwd]
*
* Revision 2.1 89/08/03 15:51:14 rwd
* Created.
*
* 8-Aug-88 David Golub (dbg) at Carnegie-Mellon University
* Converted for MACH kernel use. Removed %r, %R, %b; added %b
* from Berkeley's kernel to print bit fields in device registers;
* changed to use varargs.
*
*/
/*
* Common code for printf et al.
*
* The calling routine typically takes a variable number of arguments,
* and passes the address of the first one. This implementation
* assumes a straightforward, stack implementation, aligned to the
* machine's wordsize. Increasing addresses are assumed to point to
* successive arguments (left-to-right), as is the case for a machine
* with a downward-growing stack with arguments pushed right-to-left.
*
* To write, for example, fprintf() using this routine, the code
*
* fprintf(fd, format, args)
* FILE *fd;
* char *format;
* {
* _doprnt(format, &args, fd);
* }
*
* would suffice. (This example does not handle the fprintf's "return
* value" correctly, but who looks at the return value of fprintf
* anyway?)
*
* This version implements the following printf features:
*
* %d decimal conversion
* %u unsigned conversion
* %x hexadecimal conversion
* %X hexadecimal conversion with capital letters
* %o octal conversion
* %c character
* %s string
* %m.n field width, precision
* %-m.n left adjustment
* %0m.n zero-padding
* %*.* width and precision taken from arguments
*
* This version does not implement %f, %e, or %g. It accepts, but
* ignores, an `l' as in %ld, %lo, %lx, and %lu, and therefore will not
* work correctly on machines for which sizeof(long) != sizeof(int).
* It does not even parse %D, %O, or %U; you should be using %ld, %o and
* %lu if you mean long conversion.
*
* As mentioned, this version does not return any reasonable value.
*
* Permission is granted to use, modify, or propagate this code as
* long as this notice is incorporated.
*
* Steve Summit 3/25/87
*/
/*
* Added formats for decoding device registers:
*
* printf("reg = %b", regval, "<base><arg>*")
*
* where <base> is the output base expressed as a control character:
* i.e. '\10' gives octal, '\20' gives hex. Each <arg> is a sequence of
* characters, the first of which gives the bit number to be inspected
* (origin 1), and the rest (up to a control character (<= 32)) give the
* name of the register. Thus
* printf("reg = %b\n", 3, "\10\2BITTWO\1BITONE")
* would produce
* reg = 3<BITTWO,BITONE>
*
* If the second character in <arg> is also a control character, it
* indicates the last bit of a bit field. In this case, printf will extract
* bits <1> to <2> and print it. Characters following the second control
* character are printed before the bit field.
* printf("reg = %b\n", 0xb, "\10\4\3FIELD1=\2BITTWO\1BITONE")
* would produce
* reg = b<FIELD1=2,BITONE>
*/
/*
* Added for general use:
* # prefix for alternate format:
* 0x (0X) for hex
* leading 0 for octal
* + print '+' if positive
* blank print ' ' if positive
*
* z signed hexadecimal
* r signed, 'radix'
* n unsigned, 'radix'
*
* D,U,O,Z same as corresponding lower-case versions
* (compatibility)
*/
#include "string.h"
//#include "varargs.h"
#include "stdarg.h"
extern void term_put(char);
/* Needed CMU junk. */
typedef unsigned long vm_offset_t;
typedef int boolean_t;
#define FALSE 0
#define TRUE 1
#define isdigit(d) ((d) >= '0' && (d) <= '9')
#define Ctod(c) ((c) - '0')
#define MAXBUF (sizeof(long int) * 8) /* enough for binary */
void printnum(
register unsigned long u,
register int base,
void (*putc)( char ch, vm_offset_t fake),
vm_offset_t putc_arg)
{
char buf[MAXBUF]; /* build number here */
register char * p = &buf[MAXBUF-1];
static char digs[] = "0123456789abcdef";
do {
*p-- = digs[u % base];
u /= base;
} while (u != 0);
while (++p != &buf[MAXBUF])
(*putc)(*p, putc_arg);
}
boolean_t _doprnt_truncates = FALSE;
#if 0
decl_simple_lock_data(,_doprnt_lock)
#endif
#if 0
void printf_init()
{
simple_lock_init(&_doprnt_lock);
}
#endif
void _doprnt(
register char *fmt,
va_list *argp,
/* character output routine */
void (*putc)( char, vm_offset_t),
int radix, /* default radix - for '%r' */
vm_offset_t putc_arg)
{
int length;
int prec;
boolean_t ladjust;
char padc;
long n;
unsigned long u;
int plus_sign;
int sign_char;
boolean_t altfmt, truncate;
int base;
register char c;
#if 0
#if 0
/* Make sure that we get *some* printout, no matter what */
simple_lock(&_doprnt_lock);
#else
{
register int i = 0;
while (i < 1*1024*1024) {
if (simple_lock_try(&_doprnt_lock))
break;
i++;
}
}
#endif
#endif
while ((c = *fmt) != '\0') {
if (c != '%') {
(*putc)(c, putc_arg);
fmt++;
continue;
}
fmt++;
length = 0;
prec = -1;
ladjust = FALSE;
padc = ' ';
plus_sign = 0;
sign_char = 0;
altfmt = FALSE;
while (TRUE) {
c = *fmt;
if (c == '#') {
altfmt = TRUE;
}
else if (c == '-') {
ladjust = TRUE;
}
else if (c == '+') {
plus_sign = '+';
}
else if (c == ' ') {
if (plus_sign == 0)
plus_sign = ' ';
}
else
break;
fmt++;
}
if (c == '0') {
padc = '0';
c = *++fmt;
}
if (isdigit(c)) {
while(isdigit(c)) {
length = 10 * length + Ctod(c);
c = *++fmt;
}
}
else if (c == '*') {
length = va_arg(*argp, int);
c = *++fmt;
if (length < 0) {
ladjust = !ladjust;
length = -length;
}
}
if (c == '.') {
c = *++fmt;
if (isdigit(c)) {
prec = 0;
while(isdigit(c)) {
prec = 10 * prec + Ctod(c);
c = *++fmt;
}
}
else if (c == '*') {
prec = va_arg(*argp, int);
c = *++fmt;
}
}
if (c == 'l')
c = *++fmt; /* need it if sizeof(int) < sizeof(long) */
truncate = FALSE;
switch(c) {
case 'b':
case 'B':
{
register char *p;
boolean_t any;
register int i;
u = va_arg(*argp, unsigned long);
p = va_arg(*argp, char *);
base = *p++;
printnum(u, base, putc, putc_arg);
if (u == 0)
break;
any = FALSE;
while ((i = *p++) != 0) {
/* NOTE: The '32' here is because ascii space */
if (*p <= 32) {
/*
* Bit field
*/
register int j;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?