📄 ttyio.c
字号:
/* * FILENAME: ttyio.c * * Copyright 1995-2004 InterNiche Technologies Inc. All rights reserved. * Portions Copyright 1990-1994 by NetPort Software * * This printf was * originally designed to work on large model C on Intel 80x86 CPUs * even if the stack segment != data segment. It assumes a "dputchar" * that does \n expansions and puts chars to stdout. An sprintf cound * be built by redirecting dputchar() to a buffer. (ie "#define * dputchar(c) bufchar(c, buf)"). * * It currently understands: %d, %x, %u, %ld, %lx, %s, %c, %p. * %lu is treated as %ld; This only works for values up to 2147483647. * * This code is is NOT reentrant or sharable. It * is designed for DOS TSRs, device drivers, etc. not for a system * library. If you are working on an embedded system which already * supports a printf, you should try to use that. Field width support * is switchable via FIELDWIDTH below. This files routines take about * 928 bytes with FIELDWIDTH switched out and about 720 bytes more * with it switched in. (Compiled without stack probes on Microsoft c * 5.1 small model ). Numerics are not trucated to fit field widths. * * MODULE: NTF * * ROUTINES: declong(), doprint(), dprintf(), fplen(), hexbyte(), * ROUTINES: hexword(), printf(), setnum(), snprintf(), sprintf(), * ROUTINES: vsnprintf(), * * PORTABLE: yes */#define _IN_TTYIO_ 1 /* switch to help out ipport.h */#include "license.h"#include "ipport.h"#ifdef PRINTF_STDARG#include <stdarg.h>#endif/* if target should not use target build environment's printf */#ifndef NATIVE_PRINTF#define FIELDWIDTH 1 /* flag to switch in Field Width code */#define LINESIZE 144 /* max # chars per field */int maxfieldlen = LINESIZE; /* this can be set to control precision */#ifdef FIELDWIDTHint setnum(char **); /* fetch fieldwidth value from string */int fplen(char *, void *); /* get field length of var */#endif /* FIELDWIDTH */char digits[] = {"0123456789ABCDEF"};#ifdef PRINTF_STDARGint doprint(char * target, unsigned tlen, char * sp, va_list va);#elseint doprint(char * target, unsigned tlen, char * sp, int * vp);#endifvoid dputchar(int chr); /* port-defined putchar substitue */#ifdef dprintf#undef dprintf#endif#ifdef printf#undef printf#endif#define doputchar(c) { \ outctxp->outlen++; \ if(outctxp->target) { \ if(outctxp->outlen < outctxp->tlen) \ *(outctxp->target++) = c; \ else \ c; \ } \ else \ dputchar(c); \}#ifdef PRINTF_STDARG/* FUNCTION: dprintf() * * PARAM1: char * fmt * PARAM2: ... * * RETURNS: */void dprintf(char * fmt, ...){ va_list a; va_start(a, fmt); doprint(NULL, 32767, fmt, a); va_end(a);}/* FUNCTION: printf() * * PARAM1: char * fmt * PARAM2: ... * * RETURNS: */void printf(char * fmt, ...){ va_list a; va_start(a, fmt); doprint(NULL, 32767, fmt, a); va_end(a);}#ifndef NATIVE_SPRINTF/* FUNCTION: sprintf() * * PARAM1: char * buf * PARAM2: char * fmt * PARAM3: ... * * RETURNS: */void sprintf(char * buf, char * fmt, ...){ va_list a; va_start(a, fmt); doprint(buf, 32767, fmt, a); va_end(a);}#endif /* NATIVE_SPRINTF */#ifndef NATIVE_SNPRINTF/* FUNCTION: snprintf() * * PARAM1: char * buf * PARAM2: unsigned buflen * PARAM3: char * fmt * PARAM4: ... * * RETURNS: */intsnprintf(char * buf, unsigned buflen, char * fmt, ...){ va_list a; int len; va_start(a, fmt); len = doprint(buf, buflen, fmt, a); va_end(a); return len;}/* FUNCTION: vsnprintf() * * PARAM1: char * buf * PARAM2: unsigned buflen * PARAM3: char * fmt * PARAM4: va_list a * * RETURNS: */intvsnprintf(char * buf, unsigned buflen, char * fmt, va_list a){ return doprint(buf, buflen, fmt, a);}#endif /* NATIVE_SNPRINTF */#else /* PRINTF_STDARG *//* FUNCTION: dprintf() * * PARAM1: char *sp * PARAM2: int var * * RETURNS: */voiddprintf(char * sp, /* pointer to format string */ int var) /* 1st of n variables on stack */{ doprint(NULL, 32767, sp, &var); /* printf to stdio */}/* FUNCTION: printf() * * PARAM1: char *sp * PARAM2: int var * * RETURNS: */voidprintf(char * sp, /* pointer to format string */ int var) /* 1st of n variables on stack */{ doprint(NULL, 32767, sp, &var); /* printf to stdio */}#ifndef NATIVE_SPRINTF/* FUNCTION: sprintf() * * PARAM1: char * buf * PARAM2: char * fmt * PARAM3: int arg1 * * RETURNS: */voidsprintf(char * buf, char * fmt, int arg1){ doprint(buf, 32767, fmt, &arg1);}#endif /* NATIVE_SPRINTF */#ifndef NATIVE_SNPRINTF/* FUNCTION: snprintf() * * PARAM1: char * buf * PARAM2: unsigned buflen * PARAM3: char * fmt * PARAM4: int arg1 * * RETURNS: */intsnprintf(char * buf, unsigned buflen, char * fmt, int arg1){ return doprint(buf, buflen, fmt, &arg1);}#endif /* NATIVE_SNPRINTF */#endif /* PRINTF_STDARG *//* struct output_ctx - output context, used by doprint() and * its helper functions */struct output_ctx { char * target; unsigned tlen; unsigned outlen;};/* local doprint helper routines. All take target as in doprint() */static void hexbyte(struct output_ctx * outctxp, unsigned x);static void hexword(struct output_ctx * outctxp, unsigned x);static void declong(struct output_ctx * outctxp, long lg);/* FUNCTION: doprint() * * PARAM1: char * target; NULL for output to stdio, else buffer pointer * PARAM2: int tlen; target buffer length in bytes (ignored for stdio) * PARAM3: char * sp; printf()-style format string * PARAM4: va_list va; pointer to variables * * RETURNS: number of characters that would have been printed in a * target buffer of infinite length, not including the * trailing '\0' */intdoprint(char * target, unsigned tlen, char * sp,#ifdef PRINTF_STDARG va_list va)#else int * vp) /* pointer to variables for tools w/o <stdarg.h> */ #endif /* PRINTF_STDARG */{ char * cp; unsigned prefill, postfill, fieldlen; /* varibles for field len padding */ int swap; /* flag and temp holder for prefill-postfill swap */ unsigned char fillchar; unsigned minfieldlen; int i = 0; unsigned tmp = 0; unsigned long lng = 0; struct output_ctx outctx; struct output_ctx * outctxp = &outctx;#ifdef PRINTF_STDARG unsigned w0 = 0;#ifdef SEG16_16 unsigned w1;#endif int i0 = 0; unsigned char c = 0; char * cap = 0; void * varp;#endif /* PRINTF_STDARG */ outctx.target = target; outctx.tlen = tlen; outctx.outlen = 0; while (*sp) { if (*sp != '%') {#ifdef CRLF if ( *sp == '\n' ) doputchar('\r');#endif /* CRLF */ doputchar(*sp++); continue; } /* fall to here if sp ==> '%' */ sp++; /* point past '%' */ /* see if any field width control stuff is present */ cp = sp; /* save pointer to filed width data in cp */ while (*sp == '-' || (*sp >= '0' && *sp <= '9') || *sp == '.') sp++; /* scan past field control goodies */#ifdef PRINTF_STDARG switch (*sp) { case 'p': /* '%p' - pointer */#ifdef SEG16_16 /* do seg:offset variety */ w0 = va_arg(va, unsigned); w1 = va_arg(va, unsigned);#else /* 32 bit flat */ lng = va_arg(va, unsigned long);#endif /* SEG16_16 */ /* else fall to 32 bit code */ break; case 'x': /* '%x' - this always does 0 prefill */ tmp = va_arg(va, unsigned); break; case 'd': /* '%d' */ i0 = va_arg(va, int); break; case 'u': /* '%u' */ w0 = va_arg(va, unsigned); break; case 'c': /* '%c' */ c = (unsigned char)va_arg(va, unsigned); break; case 's': /* '%s' */ cap = va_arg(va, char *); break; case 'l': if (sp[1] == 'x' || sp[1] == 'd' || sp[1] == 'u') /* '%lx', '%ld', or '%lu' */ { lng = va_arg(va, unsigned long); } /* else '%l?', ignore it */ break; default: /* %?, ignore it */ break; } /* end switch *sp */#endif /* PRINTF_STDARG */#ifdef FIELDWIDTH prefill = postfill = 0; /* default to no filling */ fillchar = ' '; /* ...but fill with spaces, if filling */ swap = TRUE; /* ...and swap prefill & postfill */ if (sp != cp) /* if there's field control stuff... */ { if (*cp == '-') /* field is to be left adjusted */ { swap = FALSE; /* leave pXXfill unswaped */ cp++; } else swap = TRUE; /* we will swap prefill & postfill later */ /* set prefill, postfill for left adjustment */ if (*cp == '0') /* fill char is '0', not space default */ { cp++; fillchar = '0'; } else fillchar = ' '; minfieldlen = setnum(&cp); /* get number, advance cp */#ifdef PRINTF_STDARG switch (*sp) { case 's': varp = (void *)∩ break; case 'd': varp = (void *)&i0; break; case 'u':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -