ttyio.c
来自「在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LE」· C语言 代码 · 共 771 行 · 第 1/2 页
C
771 行
prefill = postfill;
postfill = (unsigned)swap;
}
while (prefill--)
{
doputchar(fillchar); /* do any pre-field padding */
}
#endif /* FIELDWIDTH */
#ifdef PRINTF_STDARG
switch (*sp)
{
case 'p': /* '%p' - pointer */
#ifdef SEG16_16 /* do seg:offset variety */
hexword(&target, w1); /* display segment word */
doputchar(':');
hexword(&target, w0); /* display offset word */
#else /* 32 bit flat */
hexword(&target, (unsigned)(lng >> 16));
hexword(&target, (unsigned)(lng & 0x0000FFFF));
#endif /* SEG16_16 */ /* else fall to 32 bit code */
break;
case 'x': /* '%x' - this always does 0 prefill */
if (tmp > 255)
hexword(&target, tmp);
else
hexbyte(&target, tmp);
break;
case 'd': /* '%d' */
declong(&target, (long) i0);
break;
case 'u': /* '%u' */
declong(&target, (unsigned long) w0);
break;
case 'c': /* '%c' */
doputchar(c);
break;
case 's': /* '%s' */
i = 0;
while (cap && (*cap) && (i++ < maxfieldlen))
doputchar(*cap++);
break;
case 'l':
sp++;
if (*sp == 'x') /* '%lx' */
{
hexword(&target, (unsigned)(lng >> 16));
hexword(&target, (unsigned)(lng & 0x0000FFFF));
}
else if(*sp == 'd' || *sp == 'u') /* '%ld' or '%lu' */
{
declong(&target, lng); /* we treat %lu as %ld. */
}
/* else '%l?', ignore it */
break;
default: /* %?, ignore it */
break;
} /* end switch *sp */
#else /* PRINTF_STDARG */
switch (*sp)
{
case 'p': /* '%p' - pointer */
#ifdef SEG16_16 /* do seg:offset variety */
hexword(&target, (unsigned)*(vp+1)); /* display segment word */
doputchar(':');
hexword(&target, (unsigned)*vp); /* display offset word */
vp += 2; /* bump var pointer past two words */
#else /* 32 bit flat */
lng = *vp;
hexword(&target, (unsigned)(lng >> 16));
hexword(&target, (unsigned)(lng & 0x0000FFFF));
vp += 4/sizeof(*vp); /* 2 or 1 */
#endif /* SEG16_16 */ /* else fall to 32 bit code */
break;
case 'x': /* '%x' - this always does 0 prefill */
tmp = *(unsigned *)vp++;
if (tmp > 255)
hexword(&target, tmp);
else
hexbyte(&target, tmp);
break;
case 'd': /* '%d' */
declong(&target, (long)*vp++);
break;
case 'u': /* '%u' */
declong(&target, (unsigned long)*(unsigned *)vp);
vp++;
break;
case 'c': /* '%c' */
doputchar((unsigned char)(*vp++));
break;
case 's': /* '%s' */
cp = *(char **)vp;
vp += sizeof(char*)/sizeof(int);
i = 0;
while (*cp && i++ < maxfieldlen)
doputchar(*cp++);
break;
case 'l':
sp++;
if (*sp == 'x') /* '%lx' */
{
/* lng = *vp; */
lng = *((unsigned long *) vp);
hexword(&target, (unsigned)(lng >> 16));
hexword(&target, (unsigned)(lng & 0x0000FFFF));
vp += 4/sizeof(*vp); /* 2 or 1 */
}
else if(*sp == 'd' || *sp == 'u') /* '%ld' or '%lu' */
{
declong(&target, *(long *)vp); /* we treat %lu as %ld. */
vp += 2;
}
/* else '%l?', ignore it */
break;
default: /* %?, ignore it */
break;
} /* end switch *sp */
#endif /* PRINTF_STDARG */
#ifdef FIELDWIDTH
while (postfill--)
{
doputchar(fillchar); /* do any post-field padding */
}
#endif /* FIELDWIDTH */
sp++; /* point past '%?' */
} /* end while *sp */
if ( target )
*target='\0' ; /* Null terminate the string */
}
/* FUNCTION: hexword()
*
* hexword(x) - print 16 bit value as hexadecimal
*
* PARAM1: char ** targ
* PARAM2: unsigned x
*
* RETURNS:
*/
static void
hexword(char ** targ, unsigned x)
{
char * target = * targ;
doputchar(digits[x >> 12]);
doputchar(digits[(x >> 8) & 0x0f]);
doputchar(digits[(x >> 4) & 0x0f]);
doputchar(digits[x & 0x0f]);
if (*targ)
(*targ) += 4;
}
/* FUNCTION: hexbyte()
*
* PARAM1: char ** targ
* PARAM2: unsigned x
*
* RETURNS:
*/
static void
hexbyte(char ** targ, unsigned x)
{
char * target = * targ;
doputchar(digits[(x >> 4) & 0x0f]);
doputchar(digits[x & 0x0f]);
if (*targ)
(*targ) += 2;
}
/* FUNCTION: declong()
*
* declong(char*, long) - print a long to target as a decimal number.
* Assumes signed, prepends '-' if negative.
*
*
* PARAM1: char ** targ
* PARAM2: long lg
*
* RETURNS:
*/
/* This should be local to declong, but Microsoft C 5.1
* breaks if it is. They use implicit lib calls to do long integer
* math, and the calls pass pointers to the longs, which assumes the
* longs are in local data space. Sheeeesh. -JB-
*/
long tens;
static void
declong(char ** targ, /* target buffer or NULL for stdio */
long lg)
{
int digit;
char * target = * targ;
if (lg == 0)
{
doputchar('0');
if (*targ)
(*targ) = target;
return;
}
else if(lg < 0L)
{
doputchar('-');
lg = -lg;
}
/* make "tens" the highest power of 10 smaller than lg */
tens = 1;
while ((lg/10) >= tens)
tens *= 10;
while (tens)
{
digit = (int)(lg/tens); /* get highest digit in lg */
doputchar(digits[digit]);
lg -= ((long)digit * tens);
tens /= 10;
}
if (*targ)
(*targ) = target;
}
#ifdef FIELDWIDTH
/* FUNCTION: setnum()
*
* returns the value of fieldwidth digits from a
* printf format string. fptr should be a pointer to a pointer to one
* or more fieldwidth digits. On return, is advanced past the digits
* and the value of the digits is returned as an int.
*
*
* PARAM1: char ** nptr
*
* RETURNS: returns the value of fieldwidth digits from a
* printf format string
*/
int snval; /* return value, breaks if on stack */
int
setnum(char ** nptr)
{
snval = 0;
while (**nptr >= '0' && **nptr <= '9') /* scan through digits */
{
snval *= 10; /* calculate return value */
snval += **nptr - '0';
/* bump pointer (not pointer to pointer) past valid digits */
(*nptr)++;
}
return(snval);
}
/* FUNCTION: fplen()
*
* fplen(sp, varp) - returns the number of chars required to print
* the value pointed to by varp when formatted accoring to the string
* pointer to by sp.
*
*
* PARAM1: char * sp
* PARAM2: void * varp
*
* RETURNS:
*/
long lng1, lng2; /* scratch value for longs */
int
fplen(char * sp, void * varp)
{
char * cp;
/* define the maximum digits needed to display a long value in
* decimal. Say , sizeof(long) = 4. So it has 8*4=32 bits.
* 2^10=1024. So for every 10 bits, we can show 3 digits. So for
* long, this value would be 32*3/10=96/10=9. And then we add one
* more digit for the roundoff. max_long_dig is used to prevent
* long overflow in lng1. There are better ways to prevent this,
* but very difficult to verify whether we made the perfect fix.
* Hence for now, this should do.
*/
static int max_long_dig = (8 * sizeof(long) * 3)/10+1;
snval = 0; /* use this for return value */
lng1 = 1; /* for figuring lengths of decimal numbers */
switch (*sp) /* switch on conversion char */
{
case 's':
cp = *(char**)varp;
while (*cp++) snval++;
return(snval);
case 'c':
return(1);
case 'x':
return(4);
case 'p':
return(9);
case 'd':
case 'u':
lng2 = *(long *)varp;
if (lng2 == 0) return(1);
if (lng2 < 0) /* if variable value is negative... */
{ if (*sp == 'd') /* format is signded decimal */
{ snval++; /* add space for '-' sign */
lng2 = -lng2;
}
else /* *sp == 'u' - format is unsigned */
lng2 &= 0xffff;
}
while (lng1 <= lng2)
{
lng1 *= 10;
snval++;
if ( snval >= max_long_dig )
{
/* If we don't stop now, there lng1 will have long overflow */
break;
}
}
return(snval);
case 'l':
switch (*(sp+1))
{
case 'x': /* '%lx' always 8 bytes */
return(8);
case 'u': /* treat %lu like %ld */
case 'd':
lng2 = (*(long *)(varp));
if (lng2 == 0) return(1);
if (lng2 < 0)
{
snval++; /* add space for '-' sign */
lng2 = -lng2;
}
while (lng1 <= lng2)
{
lng1 *= 10;
snval++;
if ( snval >= max_long_dig )
{
/* If we don't stop now, there lng1 will have long overflow */
break;
}
}
return(snval);
default:
return(0);
}
default:
return(0);
}
}
#endif /* FIELDWIDTH */
#endif /* NATIVE_PRINTF */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?