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

📄 printf.c

📁 一个dos操作系统DRDOS的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
;    File              : $Workfile: PRINTF.C$
;
;    Description       :
;
;    Original Author   : DIGITAL RESEARCH
;
;    Last Edited By    : $CALDERA$
;
;-----------------------------------------------------------------------;
;    Copyright Work of Caldera, Inc. All Rights Reserved.
;      
;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
;    CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
;    *** Current Edit History ***
;    *** End of Current Edit History ***
;
;    $Log$
;
;    ENDLOG
*/

/*
 * 26 Apr 88 Modify the Long conversion routine to display all 10
 *           digits of a 32 bit integer when displayed in decimal
 * 27 May 88 Added string undefs.
 * 1? Jun 88 Support for CODE relative messages using the FARPTR routine.
 * 05 Jun 89 Add EPRINTF routine to display messages on STDERR
 * 30 Oct 89 dispense with digits & uc_digits in resident portion
 *  8 Nov 89 Replaced ASCII calculation with to_dec(), etc. as used
 *           in APPALIB printf module. Much faster (eg dir /l 10% faster).
 *  8 Jan 90 Added parameter order indexing option.
 *  6-Mar-90 Watcom C v 7.0
 * 26-Mar-90 Make _printf CDECL again, otherwise arg processing screws up
 * 23-May-90 increase printf buffers from 128 to 130
 * 02-Dec-90 Re-work, to flush buffer on \n to allow large input strings
 * 28-May-91 local buffer is now on the stack instead of static. Reduces
 *           resident size by 128 bytes.
 * 29-Jul-91 Buffer is now a far one, so output redirection to a file works
 *           on a NOVELL drive when we are in seg FFFF.
 */

#include	"defines.h"
#include	<string.h>

#if defined(MWC) && defined(strlen)
#undef strcmp			/* These are defined as macros in string.h */
#undef strcpy			/* which are expaneded in line under */
#undef strlen			/* Metaware C. These undefs avoid this. */
#endif

#include	<portab.h>
#include	"command.h"
#include	"dosif.h"
#include	"global.h"

#define     PRINTF      -1
#define     EPRINTF     -2
#define     SPRINTF     -3

EXTERN VOID		c_write		(BYTE *, WORD);	
EXTERN BYTE FAR * CDECL farptr		(BYTE *);
EXTERN BOOLEAN		isdigit		(BYTE);
EXTERN BOOLEAN		err_flag;

/* forward references */
MLOCAL UWORD CDECL 	_printf		(BYTE *, UWORD *, UWORD);
MLOCAL VOID		arg_ptrs	(BYTE FAR *, UWORD *, UWORD **);
MLOCAL BYTE FAR *	arg_siz		(BYTE FAR *, UBYTE *);
MLOCAL BYTE FAR *	arg_num		(BYTE FAR *, UWORD *);
MLOCAL BYTE * 		to_hex		(ULONG, BYTE *, BYTE);
MLOCAL BYTE *  		to_dec		(ULONG, BYTE *);
MLOCAL BYTE *  		to_udec		(ULONG, BYTE *);

#define			UPPER_CASE	('A'-10)
#define			LOWER_CASE	('a'-10)

#define			MAX_ARG_NUM	10	/* max args with order indxs */

MLOCAL  BYTE FAR	*buff 		= NULLPTR;

/*GLOBAL  BYTE		str[130];*/
MLOCAL	BYTE FAR	*str;

GLOBAL WORD CDECL printf(fmt,args)
BYTE	*fmt;
UWORD	args;
{
	UWORD	totlen,len;
	/*BYTE	local_buff[130];*/
	UWORD	bufsize;

	/*str = (BYTE FAR *) local_buff;*/
	str = gp_far_buff;

	buff = str; 			/* use local buffer for printing */
	totlen = _printf (fmt,&args,PRINTF);		/* build up output string */
        len=(UWORD) buff - (UWORD) str;
        if(len)				/* if anything in the buffer   */
	    far_write(err_flag ? STDERR:STDOUT, str, len);
	    				/* then flush it */

	return totlen+len;			/* Return the String Length	*/

}

GLOBAL WORD CDECL eprintf(fmt,args)
BYTE	*fmt;
UWORD	args;
{
	UWORD	totlen, len;
	BYTE	local_buff[130];

	str = (BYTE FAR *) local_buff;

	buff = str; 			/* use local buffer for printing */
        err_flag = TRUE;
	totlen = _printf (fmt,&args,EPRINTF);		/* build up output string */
        len = buff-str;
        if(len)	{			/* if anything in the buffer   */
            far_write(STDERR,str,len);
 	}
	err_flag = FALSE;

	return totlen+len;			/* Return the String Length	*/

}

GLOBAL WORD CDECL fprintf(handle, fmt, args)
UWORD	handle;
BYTE	*fmt;
UWORD	args;
{
	UWORD	totlen,len;
	UWORD	bufsize;
	
	str = gp_far_buff;

	buff = str; 			/* use local buffer for printing */
	totlen =_printf (fmt,&args,handle);		/* build up output string */
        len = (UWORD) buff - (UWORD) str;
        if(len)				/* if anything in the buffer   */
	    far_write(handle, str, len);	/* then flush it */

	return totlen+len;			/* Return the String Length	*/

}

GLOBAL WORD CDECL sprintf(strg, fmt, args)
BYTE	*strg;
BYTE	*fmt;
UWORD	args;
{
	buff = (BYTE FAR *) strg;		/* Point buffer at String	*/
	return _printf (fmt,&args,SPRINTF); 	/* Generate the String		*/
}

MLOCAL UWORD CDECL 	_printf(fmt_near, args, type)
BYTE		*fmt_near;
UWORD	   	*args;
UWORD        type;
{
	BYTE FAR *fmt;
	WORD rjust;			/* if string/number is right justified */
	WORD maxwidth, width;
	BOOLEAN	long_arg;		/* true if next argument is long */
	ULONG value;
	UWORD uvalue;
	WORD i, k;
	BYTE FAR *cp;
	BYTE c, filler;
	BYTE s[40], *sp;
	LONG *lp;
	UWORD *arg_list[MAX_ARG_NUM];
	UWORD arg_idx;
        UWORD totlen=0;

	fmt = farptr(fmt_near);		/* get full address of format string */
	arg_ptrs(fmt, args, arg_list);	/* init table of argument addresses */

	while ((c = *fmt++) != 0)	/* scan format string */
	{
	    if (c == '%') {		/* formatting code found */
		    s[14] = 0;
		    rjust = YES;
		    filler = ' ';
		    maxwidth = 0x7fff;

		    fmt = arg_num(fmt, &arg_idx);	/* get argument index */
		    if (arg_idx < MAX_ARG_NUM) {	/* valid index? */
		        fmt++;			/*  yes - skip '%' */
		        args = arg_list[arg_idx];	/* lookup address of arg */
		    }

		    if ((c = *fmt) == '-') {	/* string is left justified */
		        rjust = NO;		/*   ... not right justified */
		        c = *fmt++;		/* get the next character */
		    }

		    if (c == '0')		/* if leading zeroes desired */
		        filler = '0';	/*    use '0' instead of ' ' */

		    if (*fmt == '*') {	/* if formatting width is parameter */
		            			/*    then get it from parameters */
		        width = (WORD)*args++;
		        fmt++;		/* skip the asterisk */
		        c = *fmt++;		/* get next character */
		    }
		    else			/* get full width */
		        for (width = 0; (c = *fmt++) >= '0' && c <= '9'; )
			        width = width*10 + c - '0';

		    if (c == '.') {		/* if decimal places specified */
		        if (*fmt == '*') {	/* if width is a parameter */
			        maxwidth = (WORD)*args++;
			        fmt++;		/* skip the asterisk */
			        c = *fmt++;	/* get next character */
		        }
		        else		/* get decimal places */
			        for (maxwidth = 0; (c = *fmt++) >= '0' && c <= '9' ;)
			            maxwidth = maxwidth*10 + c - '0';
		    }

			/* "%ld", "%lu", "lx" specified */
		    long_arg = (c == 'l');	/* is the argument supplied long? */
		    if (long_arg)		/* if long argument */
		        c = *fmt++;		/* then skip the 'l' character */

		    switch (c)	{
		        case 'd':		/* signed argument */
		            if (!long_arg)
			            value = (WORD) *args++;
		            else {
			            lp = (LONG *) args;
			            value = *lp++;
			            args = (UWORD *) lp;
		            }
		            break;

		    case 'u':		/* unsigned argument */
		    case 'x':
		    case 'X':
		        if (!long_arg)
			        value = (UWORD) *args++;
		        else {
			        lp = (LONG *) args;
			        value = (ULONG) *lp++;
			        args = (UWORD *) lp;
		        }
		        break;

		    default:			/* "%s", "%c" */
		        uvalue = (UWORD) *args++;	/* get string address of char */
		    }


		    switch (c) {		/* now convert to ASCII */
		        case 'd':		/* signed decimal */
		    	    sp = to_dec(value, s+14);
		    	    break;

		        case 'u':		/* unsigned decimal */
		    	    sp = to_udec(value, s+14);
		    	    break;

		        case 'x':		/* unsigned hexadecimal, lower case */
		    	    sp = to_hex(value, s+14, LOWER_CASE);

⌨️ 快捷键说明

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