fioLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:82k
- /* fioLib.c - formatted I/O library */
- /* Copyright 1984-2002 Wind River Systems, Inc. */
- #include "copyright_wrs.h"
- /*
- modification history
- --------------------
- 06c,24jul02,tpr Remove sarcastic comment of fioFormatV.
- 06b,14mar02,pfl changed long long arg support to use 'll' format
- 06a,21dec01,an enabled long long arg support for printf/scanf using 'L' format flag
- 05z,17dec01,max Simple change just to make WRS doctool happy
- 05y,20jun01,kab Code review cleanup
- 05x,19apr01,max printf & scanf support for ALTIVEC vector data types
- 05w,14jun99,pai removed blocking call to printErr() in printExc() (SPR 22735).
- 05v,14mar99,jdi doc: removed refs to config.h and/or configAll.h (SPR 25663).
- 05v,05sep97,dgp doc: fix SPR 9258, remove NOTE from sprintf()
- 05u,04oct95,kvk fix for PPC architecture varargs float problem.
- 05t,21sep95,jdi doc tweak of man page for fioLibInit().
- 05s,14may95,p_m added fioLibInit().
- 05r,03feb95,jdi doc format tweaks.
- 05q,24jan95,rhp doc: avoid 'L' in printf() and sscanf(), no long doubles
- in VxWorks (see SPR#3886)
- 05p,13jan95,rhp make self-refs in sscanf man page refer to sscanf, not fscanf
- 05o,12jan95,rhp fix RETURNS section of fioRdString() man page (SPR#2511)
- 05n,21nov94,kdl made scanCharSet() NOMANUAL.
- 05m,19jul94,dvs doc tweak - added stdio.h to list of include files (SPR #2391).
- 05l,02dec93,pad temporary fixed fioFormatV() to avoid a cc29k problem.
- 05k,17aug94,ism fixed problem with assignment suppression (SPR#2562)
- -fixed problem with [] not failing when no characters are scanned
- -(SPR#3561)
- 05j,21oct93,jmm fixed return value for scanCharSet
- 05i,10mar93,jdi more documentation cleanup for 5.1.
- 05h,22jan93,jdi documentation cleanup for 5.1.
- 05g,13nov92,dnw added include of taskLib.h
- 05f,29oct92,jcf bumped BUF to 400 to format real big numbers.
- 05e,01oct92,jcf fixed printExc().
- 05d,02aug92,jcf moved printExc() to here.
- 05c,30jul92,kdl prevent printing leading zeroes for "Inf", "Nan".
- 05b,30jul92,jcf redone for the new stdio library.
- +smb
- 05a,26may92,rrr the tree shuffle
- 04z,10feb92,kdl fixed scanf %n problems (SPR 1172).
- 04y,29jan92,kdl made fioRdString return EOF in case of read error (SPR 1142);
- changed copyright date.
- 04x,10dec91,gae removed some ANSI warnings.
- 04w,04dec91,rrr removed VARARG_OK, no longer needed with ansi c.
- 04v,19nov91,rrr shut up some ansi warnings.
- 04u,04oct91,rrr passed through the ansification filter
- -changed functions to ansi style
- -changed includes to have absolute path from h/
- -changed VOID to void
- -changed copyright notice
- 04t,14jul91,del removed va_end in fioScanV.
- 04s,09jun91,del integrated Intel's mods to interface to floatLib.c.
- 04r,18may91,gae fixed sscanf/varargs for 960.
- redid conditionals with VARARG_OK.
- 04q,05may91,jdi documentation tweak.
- 04p,05apr91,jdi documentation -- removed header parens and x-ref numbers;
- doc review by dnw.
- 04o,24mar91,del made functions work with gnu960 tools for I960 architecture.
- 04n,06feb91,jaa documentation cleanup.
- 04m,05oct90,dnw documentation
- 04l,18sep90,kdl removed forward declarations for digtobin and fioToUpper.
- 04k,08aug90,dnw changed to call floatFormat with &vaList instead of vaList.
- changed to call floatFormat with sizeof(buffer)-prefix instead
- of sizeof(buffer)
- 04j,04jun90,dnw extensive rewrite/reorg of printf/scanf family of rtns:
- - consolidation and clean-up,
- - adherence to ANSI definitions for format semantics,
- - use varargs correctly,
- - removed all floating pt refs.
- BUG FIXES:
- spr 501: fixed printf precision bug
- spr 640: printf, fdprintf, printErr return num chars printed
- spr 754: vararg routines no longer limited to 16 args
- spr 766: deleted obsolete fioStd{In,Out,Err} routines
- spr 767: scanf, sscanf, fscanf return EOF properly
- unreported: printf with both "left justify" & "0 fill" flags
- would 0 fill to the right! ("5000" instead of "5 ")
- ANSI STANDARD CHANGES, *NOT* COMPATIBLE WITH 4.0.2:
- - scanf %EFG now same as %efg (no longer means "double"!)
- - sprintf returns number of chars in buffer NOT INCLUDING
- EOS (4.0.2 included EOS in count)
- - printf precision parameter only has effect on %s and %efg
- ANSI STANDARD CHANGES, BACKWARD COMPATIBLE:
- - added vprintf, vfprintf, vsprintf vararg routines
- - printf now supports %i %p %n
- - scanf now supports %i %p %n %% %X
- - scanf now allows optional leading "0x"
- OTHER CHANGES:
- - deleted unused internal routines fioToUpper() & digtobin()
- - fioRead() doesn't set S_fioLib_UNEXPECTED_EOF anymore
- - changes to allow void be defined as void
- 04i,07mar90,jdi documentation cleanup.
- 04h,09aug89,gae did varargs stuff right.
- 06jul89,ecs updated to track 4.0.2.
- 07sep88,ecs varargs.
- added include of varargs.h.
- 04g,19aug88,gae documentation.
- 04f,13aug88,gae fixed bug in convert() for E and F.
- 04e,30jun88,gae fixed bug in sscanf () and convert() for number specifier.
- 04d,30may88,dnw changed to v4 names.
- 04c,28may88,dnw removed NOT_GENERIC stuff.
- removed obsolete rtns: bcdtoi,itobcd,atoi,atow,atos,bprintf
- removed obsolete: fioSet{In,Out,Err},
- removed skipHexSpecifier to bootConfig.
- removed skipSpace to bootConfig and bootLib.
- made itob NOMANUAL.
- made digtobin LOCAL.
- 04b,21apr88,gae added conversion of 'g' for scanf().
- 04a,02apr88,gae rewrote convert and support routines to work with stdio.
- changed fprintf() to fdprintf().
- changed fio{Std,Set}{In,Out,Err}() to use new 0,1,2 I/O scheme.
- made putbuf() local.
- 03i,16mar88,gae fixed bug in convert() to return FALSE for invalid specifier.
- fixed fatal bug in atos() of not handling unterminated table.
- made atos() return ERROR when given invalid table.
- sscanf can now do flag: "<*>".
- sscanf can now do specifiers: "E|F|c|u|o".
- printf can now do flags: "<+><sp><#>".
- printf can now do specifiers: "u|E|G|X".
- added nindex() and fioToUpper().
- 03h,16feb88,llk fixed sscanf so that it handles double precision floats.
- 03g,10dec87,gae changed some VARARGS routines to have standard "args"
- parameter for parsing by C interface generator.
- 03f,16nov87,jcf added skipHexSpecifier to aid in hex parsing
- 03e,05nov87,jlf documentation
- 03d,12oct87,jlf added [...] strings to scanf.
- 03c,01aug87,gae moved floating-point support to fltLib.c.
- added fioFltInstall().
- 03b,31jul87,gae replaced homebrew atof() with the real thing.
- renamed gcvtb() to gcvt(). fixed bug in ftob().
- 03a,07may87,jlf added floating point support, with #ifdef's.
- +gae This involved: %e and %f to format() and convert().
- New routines: ecvtb, fcvtb, gcvt, atof, atoe, ftob, etob,
- frexp, ldexp, and modf.
- 02x,04apr87,dnw fixed bug in format() that limited fields to 128 characters.
- 02w,23mar87,jlf documentation.
- 02v,17jan87,gae made timeConvert and format handle 12 hour clock time code.
- 02u,20dec86,dnw changed to not get include files from default directories.
- 02t,10oct86,dnw documentation.
- 02s,04sep86,jlf documentation.
- 02r,29jul86,llk documentation changes
- 02q,27jul86,llk added standard error file descriptor (std_err)
- added fioSetErr, fioStdErr, printErr
- 02p,01jul86,jlf minor documentation
- 02o,27mar86,ecs changed timeConvert to check for legality of time entered.
- changed timeDecode to return integer rather than bcd.
- 02n,11mar86,jlf changed GENERIC stuff to NOT_GENERIC.
- */
- /*
- DESCRIPTION
- This library provides the basic formatting and scanning I/O functions. It
- includes some routines from the ANSI-compliant printf()/scanf()
- family of routines. It also includes several utility routines.
- If the floating-point format specifications `e', `E', `f', `g', and `G' are
- to be used with these routines, the routine floatInit() must be called
- first. If the configuration macro INCLUDE_FLOATING_POINT is defined,
- floatInit() is called by the root task, usrRoot(), in usrConfig.c.
- These routines do not use the buffered I/O facilities provided by the
- standard I/O facility. Thus, they can be invoked even if the standard I/O
- package has not been included. This includes printf(), which in most UNIX
- systems is part of the buffered standard I/O facilities. Because printf()
- is so commonly used, it has been implemented as an unbuffered I/O function.
- This allows minimal formatted I/O to be achieved without the overhead of
- the entire standard I/O package. For more information, see the manual
- entry for ansiStdio.
- INCLUDE FILES: fioLib.h, stdio.h
- SEE ALSO: ansiStdio, floatLib,
- .pG "I/O System"
- */
- #include "vxWorks.h"
- #include "ctype.h"
- #include "errno.h"
- #include "ioLib.h"
- #include "string.h"
- #include "stdarg.h"
- #include "limits.h"
- #include "stdio.h"
- #include "stdlib.h"
- #include "unistd.h"
- #include "fioLib.h"
- #include "intLib.h"
- #include "sysLib.h"
- #include "qLib.h"
- #include "taskLib.h"
- #include "private/kernelLibP.h"
- #include "private/vmLibP.h"
- #include "private/floatioP.h"
- /* Macros for converting digits to letters and vice versa */
- #define BUF 400 /* buffer for %dfg etc */
- #define PADSIZE 16 /* pad chunk size */
- #define to_digit(c) ((c) - '0')
- #define is_digit(c) ((unsigned)to_digit(c) <= 9)
- #define to_char(n) ((n) + '0')
- #define PAD(howmany, with)
- {
- if ((n = (howmany)) > 0)
- {
- while (n > PADSIZE)
- {
- if ((*outRoutine) (with, PADSIZE, outarg) != OK)
- return (ERROR);
- n -= PADSIZE;
- }
- if ((*outRoutine) (with, n, outarg) != OK)
- return (ERROR);
- }
- }
- /* to extend shorts, signed and unsigned arg extraction methods are needed */
- #define SARG() ((doLongLongInt) ? (long long) va_arg(vaList, long long) :
- (doLongInt) ? (long long)(long)va_arg(vaList, long) :
- (doShortInt) ? (long long)(short)va_arg(vaList, int) :
- (long long)(int) va_arg(vaList, int))
- #define UARG() ((doLongLongInt) ? (unsigned long long) va_arg(vaList, unsigned long long) :
- (doLongInt) ? (unsigned long long)(ulong_t)va_arg(vaList,ulong_t):
- (doShortInt) ? (unsigned long long)(ushort_t)va_arg(vaList,int):
- (unsigned long long)(uint_t) va_arg(vaList, uint_t))
- #define GET_CHAR(ch, ix) ((ix)++, (ch) = (* getRtn) (getArg, -1))
- #define ll 1 /* long long format */
- /* globals */
- /* The fieldSzIncludeSign indicates whether the sign should be included
- * in the precision of a number.
- */
- BOOL fieldSzIncludeSign = TRUE;
- /* locals */
- LOCAL FUNCPTR fioFltFormatRtn;
- LOCAL FUNCPTR fioFltScanRtn;
- /* Choose PADSIZE to trade efficiency vs size. If larger printf fields occur
- * frequently, increase PADSIZE (and make the initialisers below longer).
- */
- LOCAL char blanks[PADSIZE] =
- {
- ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '
- };
- LOCAL char zeroes[PADSIZE] =
- {
- '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'
- };
- /* forwards */
- LOCAL int getbuf (char ** str);
- LOCAL STATUS putbuf (char *inbuf, int length, char ** outptr);
- LOCAL STATUS printbuf (char *buf, int nbytes, int fd);
- /*LOCAL*/ BOOL scanField (const char **ppFmt, void *pReturn, FUNCPTR getRtn,
- int getArg, BOOL *pSuppress, int *pCh, int *pNchars);
- LOCAL BOOL scanChar (char *pResult, int fieldwidth, FUNCPTR getRtn,
- int getArg, int *pCh, int *pNchars);
- LOCAL BOOL scanString (char *pResult, int fieldwidth, FUNCPTR getRtn,
- int getArg, int *pCh, int *pNchars);
- /*LOCAL*/ BOOL scanCharSet (char *pResult, int fieldwidth,
- const char *charsAllowed, FUNCPTR getRtn,
- int getArg, int *pCh, int *pNchars);
- LOCAL BOOL scanNum (int base, void *pReturn, int returnSpec, int fieldwidth,
- FUNCPTR getRtn, int getArg, int *pCh, int *pNchars);
- /*******************************************************************************
- *
- * fioLibInit - initialize the formatted I/O support library
- *
- * This routine initializes the formatted I/O support library. It should be
- * called once in usrRoot() when formatted I/O functions such as printf() and
- * scanf() are used.
- *
- * RETURNS: N/A
- */
- void fioLibInit (void)
- {
- _func_printErr = (FUNCPTR) printErr;
- }
- /*******************************************************************************
- *
- * fioFltInstall - install routines to print and scan floating-point numbers
- *
- * This routine is a hook for floatLib to install its special floating-point
- * formatting & scanning routines. It should only be called by floatInit().
- *
- * NOMANUAL
- */
- void fioFltInstall
- (
- FUNCPTR formatRtn, /* routine to format floats for output */
- FUNCPTR scanRtn /* routine to scan input for floats */
- )
- {
- fioFltFormatRtn = formatRtn;
- fioFltScanRtn = scanRtn;
- }
- /*******************************************************************************
- *
- * printf - write a formatted string to the standard output stream (ANSI)
- *
- * This routine writes output to standard output under control of the string
- * <fmt>. The string <fmt> contains ordinary characters, which are written
- * unchanged, plus conversion specifications, which cause the arguments that
- * follow <fmt> to be converted and printed as part of the formatted string.
- *
- * The number of arguments for the format is arbitrary, but they must
- * correspond to the conversion specifications in <fmt>. If there are
- * insufficient arguments, the behavior is undefined. If the format is
- * exhausted while arguments remain, the excess arguments are evaluated but
- * otherwise ignored. The routine returns when the end of the format string
- * is encountered.
- *
- * The format is a multibyte character sequence, beginning and ending in its
- * initial shift state. The format is composed of zero or more directives:
- * ordinary multibyte characters (not `%') that are copied unchanged to the
- * output stream; and conversion specification, each of which results in
- * fetching zero or more subsequent arguments. Each conversion specification
- * is introduced by the `%' character. After the `%', the following appear in
- * sequence:
- * .iP "" 4
- * Zero or more flags (in any order) that modify the meaning of the
- * conversion specification.
- * .iP
- * An optional minimum field width. If the converted value has fewer
- * characters than the field width, it will be padded with spaces (by
- * default) on the left (or right, if the left adjustment flag,
- * described later, has been given) to the field width. The field
- * width takes the form of an asterisk (`*') (described later) or a decimal
- * integer.
- * .iP
- * An optional precision that gives the minimum number of digits to
- * appear for the `d', `i', `o', `u', `x', and `X' conversions, the number of
- * digits to appear after the decimal-point character for `e', `E', and `f'
- * conversions, the maximum number of significant digits for the `g' and
- * `G' conversions, or the maximum number of characters to be written
- * from a string in the `s' conversion. The precision takes the form of a
- * period (`.') followed either by an asterisk (`*') (described later) or by
- * an optional decimal integer; if only the period is specified, the
- * precision is taken as zero. If a precision appears with any other
- * conversion specifier, the behavior is undefined.
- * .iP
- * An optional `h' specifying that a following `d', `i', `o', `u', `x', and
- * `X' conversion specifier applies to a `short int' or `unsigned short int'
- * argument (the argument will have been promoted according to the integral
- * promotions, and its value converted to `short int' or `unsigned short int'
- * before printing); an optional `h' specifying that a following `n'
- * conversion specifier applies to a pointer to a `short int' argument. An
- * optional `l' (ell) specifying that a following `d', `i', `o', `u', `x', and
- * `X' conversion specifier applies to a `long int' or `unsigned long int'
- * argument; or an optional `l' specifying that a following `n' conversion
- * specifier applies to a pointer to a `long int' argument. An optional `ll'
- * (ell-ell) specifying that a following `d', `i', `o', `u', `x', and
- * `X' conversion specifier applies to a `long long int' or `unsigned long
- * long int' argument; or an optional `ll' specifying that a following `n'
- * conversion specifier applies to a pointer to a `long long int' argument.
- * If a `h', `l' or `ll' appears with any other conversion specifier, the
- * behavior is undefined.
- * .iP
- * &WARNING: ANSI C also specifies an optional `L' in some of the same
- * contexts as `l' above, corresponding to a `long double' argument.
- * However, the current release of the VxWorks libraries does not support
- * `long double' data; using the optional `L' gives unpredictable results.
- * .iP
- * A character that specifies the type of conversion to be applied.
- * .LP
- *
- * As noted above, a field width, or precision, or both, can be indicated by
- * an asterisk (`*'). In this case, an `int' argument supplies the field width
- * or precision. The arguments specifying field width, or precision, or both,
- * should appear (in that order) before the argument (if any) to be converted.
- * A negative field width argument is taken as a `-' flag followed by a positive
- * field width. A negative precision argument is taken as if the precision
- * were omitted.
- *
- * The flag characters and their meanings are:
- * .iP `-'
- * The result of the conversion will be left-justified within the field.
- * (it will be right-justified if this flag is not specified.)
- * .iP `+'
- * The result of a signed conversion will always begin with a plus or
- * minus sign. (It will begin with a sign only when a negative value
- * is converted if this flag is not specified.)
- * .iP `space'
- * If the first character of a signed conversion is not a sign, or
- * if a signed conversion results in no characters, a space will be
- * prefixed to the result. If the `space' and `+' flags both appear, the
- * `space' flag will be ignored.
- * .iP `#'
- * The result is to be converted to an "alternate form." For `o' conversion
- * it increases the precision to force the first digit of the result to be a
- * zero. For `x' (or `X') conversion, a non-zero result will have "0x" (or
- * "0X") prefixed to it. For `e', `E', `f', `g', and `g' conversions, the
- * result will always contain a decimal-point character, even if no digits
- * follow it. (Normally, a decimal-point character appears in the result of
- * these conversions only if no digit follows it). For `g' and `G'
- * conversions, trailing zeros will not be removed from the result. For
- * other conversions, the behavior is undefined.
- * .iP `0'
- * For `d', `i', `o', `u', `x', `X', `e', `E', `f', `g', and `G' conversions,
- * leading zeros (following any indication of sign or base) are used to pad
- * to the field width; no space padding is performed. If the `0' and `-'
- * flags both appear, the `0' flag will be ignored. For `d', `i', `o', `u',
- * `x', and `X' conversions, if a precision is specified, the `0' flag will
- * be ignored. For other conversions, the behavior is undefined.
- * .LP
- *
- * The conversion specifiers and their meanings are:
- * .iP "`d', `i'"
- * The `int' argument is converted to signed decimal in the style
- * `[-]dddd'. The precision specifies the minimum number of digits
- * to appear; if the value being converted can be represented in
- * fewer digits, it will be expanded with leading zeros. The
- * default precision is 1. The result of converting a zero value
- * with a precision of zero is no characters.
- * .iP "`o', `u', `x', `X'"
- * The `unsigned int' argument is converted to unsigned octal (`o'),
- * unsigned decimal (`u'), or unsigned hexadecimal notation (`x' or `X')
- * in the style `dddd'; the letters abcdef are used for `x' conversion
- * and the letters ABCDEF for `X' conversion. The precision specifies
- * the minimum number of digits to appear; if the value being
- * converted can be represented in fewer digits, it will be
- * expanded with leading zeros. The default precision is 1. The
- * result of converting a zero value with a precision of zero is
- * no characters.
- * .iP `f'
- * The `double' argument is converted to decimal notation in the
- * style `[-]ddd.ddd', where the number of digits after the decimal
- * point character is equal to the precision specification. If the
- * precision is missing, it is taken as 6; if the precision is zero
- * and the `#' flag is not specified, no decimal-point character
- * appears. If a decimal-point character appears, at least one
- * digit appears before it. The value is rounded to the appropriate
- * number of digits.
- * .iP "`e', `E'"
- * The `double' argument is converted in the style `[-]d.ddde+/-dd',
- * where there is one digit before the decimal-point character
- * (which is non-zero if the argument is non-zero) and the number
- * of digits after it is equal to the precision; if the precision
- * is missing, it is taken as 6; if the precision is zero and the
- * `#' flag is not specified, no decimal-point character appears. The
- * value is rounded to the appropriate number of digits. The `E'
- * conversion specifier will produce a number with `E' instead of `e'
- * introducing the exponent. The exponent always contains at least
- * two digits. If the value is zero, the exponent is zero.
- * .iP "`g', `G'"
- * The `double' argument is converted in style `f' or `e' (or in style
- * `E' in the case of a `G' conversion specifier), with the precision
- * specifying the number of significant digits. If the precision
- * is zero, it is taken as 1. The style used depends on the
- * value converted; style `e' (or `E') will be used only if the
- * exponent resulting from such a conversion is less than -4 or
- * greater than or equal to the precision. Trailing zeros are
- * removed from the fractional portion of the result; a decimal-point
- * character appears only if it is followed by a digit.
- * .iP `c'
- * The `int' argument is converted to an `unsigned char', and the
- * resulting character is written.
- * .iP `s'
- * The argument should be a pointer to an array of character type.
- * Characters from the array are written up to (but not including)
- * a terminating null character; if the precision is specified,
- * no more than that many characters are written. If the precision
- * is not specified or is greater than the size of the array, the
- * array will contain a null character.
- * .iP `p'
- * The argument should be a pointer to `void'. The value of the
- * pointer is converted to a sequence of printable characters,
- * in hexadecimal representation (prefixed with "0x").
- * .iP `n'
- * The argument should be a pointer to an integer into which
- * the number of characters written to the output stream
- * so far by this call to fprintf() is written. No argument is converted.
- * .iP `%'
- * A `%' is written. No argument is converted. The complete
- * conversion specification is %%.
- * .LP
- *
- * If a conversion specification is invalid, the behavior is undefined.
- *
- * If any argument is, or points to, a union or an aggregate (except for an
- * array of character type using `s' conversion, or a pointer using `p'
- * conversion), the behavior is undefined.
- *
- * In no case does a non-existent or small field width cause truncation of a
- * field if the result of a conversion is wider than the field width, the
- * field is expanded to contain the conversion result.
- *
- * INCLUDE FILES: fioLib.h
- *
- * RETURNS:
- * The number of characters written, or a negative value if an
- * output error occurs.
- *
- * SEE ALSO: fprintf(),
- * .I "American National Standard for Information Systems -"
- * .I "Programming Language - C, ANSI X3.159-1989: Input/Output (stdio.h)"
- *
- * VARARGS1
- */
- int printf
- (
- const char * fmt, /* format string to write */
- ... /* optional arguments to format string */
- )
- {
- va_list vaList; /* traverses argument list */
- int nChars;
- va_start (vaList, fmt);
- nChars = fioFormatV (fmt, vaList, printbuf, 1);
- va_end (vaList);
- return (nChars);
- }
- /*******************************************************************************
- *
- * printErr - write a formatted string to the standard error stream
- *
- * This routine writes a formatted string to standard error. Its function and
- * syntax are otherwise identical to printf().
- *
- * RETURNS: The number of characters output, or ERROR if there is an error
- * during output.
- *
- * SEE ALSO: printf()
- *
- * VARARGS1
- */
- int printErr
- (
- const char * fmt, /* format string to write */
- ... /* optional arguments to format */
- )
- {
- va_list vaList; /* traverses argument list */
- int nChars;
- va_start (vaList, fmt);
- nChars = fioFormatV (fmt, vaList, printbuf, 2);
- va_end (vaList);
- return (nChars);
- }
- /*******************************************************************************
- *
- * printExc - print error message
- *
- * If at interrupt level or other invalid/fatal state, then "print"
- * into System Exception Message area.
- *
- * NOMANUAL
- */
- void printExc (fmt, arg1, arg2, arg3, arg4, arg5)
- char *fmt; /* format string */
- int arg1;
- int arg2;
- int arg3;
- int arg4;
- int arg5;
- {
- UINT state;
- int pageSize;
- char * pageAddr;
- if ((INT_CONTEXT ()) || (Q_FIRST (&activeQHead) == NULL))
- {
- /* Exception happened during exception processing, or before
- * any task could be initialized. Tack the message onto the end
- * of a well-known location.
- */
- /* see if we need to write enable the memory */
- if (vmLibInfo.vmLibInstalled)
- {
- pageSize = VM_PAGE_SIZE_GET();
- pageAddr = (char *) ((UINT) sysExcMsg / pageSize * pageSize);
- if ((VM_STATE_GET (NULL, (void *) pageAddr, &state) != ERROR) &&
- ((state & VM_STATE_MASK_WRITABLE) == VM_STATE_WRITABLE_NOT))
- {
- TASK_SAFE(); /* safe from deletion */
- VM_STATE_SET (NULL, pageAddr, pageSize, VM_STATE_MASK_WRITABLE,
- VM_STATE_WRITABLE);
- sysExcMsg += sprintf (sysExcMsg,fmt,arg1,arg2,arg3,arg4,arg5);
- VM_STATE_SET (NULL, pageAddr, pageSize, VM_STATE_MASK_WRITABLE,
- VM_STATE_WRITABLE_NOT);
- TASK_UNSAFE(); /* unsafe from deletion */
- return;
- }
- }
- sysExcMsg += sprintf (sysExcMsg, fmt, arg1, arg2, arg3, arg4, arg5);
- }
- else
- {
- /* queue printErr() so that we do not block here (SPR 22735) */
- excJobAdd ((VOIDFUNCPTR)printErr, (int)fmt, arg1,arg2,arg3,arg4,arg5);
- }
- }
- /*******************************************************************************
- *
- * fdprintf - write a formatted string to a file descriptor
- *
- * This routine writes a formatted string to a specified file descriptor. Its
- * function and syntax are otherwise identical to printf().
- *
- * RETURNS: The number of characters output, or ERROR if there is an error
- * during output.
- *
- * SEE ALSO: printf()
- *
- * VARARGS2
- */
- int fdprintf
- (
- int fd, /* file descriptor to write to */
- const char * fmt, /* format string to write */
- ... /* optional arguments to format */
- )
- {
- va_list vaList; /* traverses argument list */
- int nChars;
- va_start (vaList, fmt);
- nChars = fioFormatV (fmt, vaList, printbuf, fd);
- va_end (vaList);
- return (nChars);
- }
- /*******************************************************************************
- *
- * sprintf - write a formatted string to a buffer (ANSI)
- *
- * This routine copies a formatted string to a specified buffer, which is
- * null-terminated. Its function and syntax are otherwise identical
- * to printf().
- *
- * RETURNS:
- * The number of characters copied to <buffer>, not including the NULL
- * terminator.
- *
- * SEE ALSO: printf(),
- * .I "American National Standard for Information Systems -"
- * .I "Programming Language - C, ANSI X3.159-1989: Input/Output (stdio.h)"
- *
- * VARARGS2
- */
- int sprintf
- (
- char * buffer, /* buffer to write to */
- const char * fmt, /* format string */
- ... /* optional arguments to format */
- )
- {
- va_list vaList; /* traverses argument list */
- int nChars;
- va_start (vaList, fmt);
- nChars = fioFormatV (fmt, vaList, putbuf, (int) &buffer);
- va_end (vaList);
- *buffer = EOS;
- return (nChars);
- }
- /*******************************************************************************
- *
- * vprintf - write a string formatted with a variable argument list to standard output (ANSI)
- *
- * This routine prints a string formatted with a variable argument list to
- * standard output. It is identical to printf(), except that it takes
- * the variable arguments to be formatted as a list <vaList> of type `va_list'
- * rather than as in-line arguments.
- *
- * RETURNS: The number of characters output, or ERROR if there is an error
- * during output.
- *
- * SEE ALSO: printf(),
- * .I "American National Standard for Information Systems -"
- * .I "Programming Language - C, ANSI X3.159-1989: Input/Output (stdio.h)"
- */
- int vprintf
- (
- const char * fmt, /* format string to write */
- va_list vaList /* arguments to format */
- )
- {
- return (fioFormatV (fmt, vaList, printbuf, 1));
- }
- /*******************************************************************************
- *
- * vfdprintf - write a string formatted with a variable argument list to a file descriptor
- *
- * This routine prints a string formatted with a variable argument list to a
- * specified file descriptor. It is identical to fdprintf(), except
- * that it takes the variable arguments to be formatted as a list <vaList> of
- * type `va_list' rather than as in-line arguments.
- *
- * RETURNS: The number of characters output, or ERROR if there is an error
- * during output.
- *
- * SEE ALSO: fdprintf()
- */
- int vfdprintf
- (
- int fd, /* file descriptor to print to */
- const char * fmt, /* format string for print */
- va_list vaList /* optional arguments to format */
- )
- {
- return (fioFormatV (fmt, vaList, printbuf, fd));
- }
- /*******************************************************************************
- *
- * vsprintf - write a string formatted with a variable argument list to a buffer (ANSI)
- *
- * This routine copies a string formatted with a variable argument list to
- * a specified buffer. This routine is identical to sprintf(), except that it
- * takes the variable arguments to be formatted as a list <vaList> of type
- * `va_list' rather than as in-line arguments.
- *
- * RETURNS:
- * The number of characters copied to <buffer>, not including the NULL
- * terminator.
- *
- * SEE ALSO: sprintf(),
- * .I "American National Standard for Information Systems -"
- * .I "Programming Language - C, ANSI X3.159-1989: Input/Output (stdio.h)"
- */
- int vsprintf
- (
- char * buffer, /* buffer to write to */
- const char * fmt, /* format string */
- va_list vaList /* optional arguments to format */
- )
- {
- int nChars;
- nChars = fioFormatV (fmt, vaList, putbuf, (int) &buffer);
- *buffer = EOS;
- return (nChars);
- }
- #ifdef _WRS_ALTIVEC_SUPPORT
- typedef union {
- __vector unsigned long vul;
- float f32[4];
- unsigned long u32[4];
- unsigned short u16[8];
- unsigned char u8[16];
- signed long s32[4];
- signed short s16[8];
- signed char s8[16];
- } VECTOR;
- #endif /* _WRS_ALTIVEC_SUPPORT */
- /*******************************************************************************
- *
- * fioFormatV - convert a format string
- *
- * This routine is used by the printf() family of routines to handle the
- * actual conversion of a format string. The first argument is a format
- * string, as described in the entry for printf(). The second argument is a
- * variable argument list <vaList> that was previously established.
- *
- * As the format string is processed, the result will be passed to the output
- * routine whose address is passed as the third parameter, <outRoutine>.
- * This output routine may output the result to a device, or put it in a
- * buffer. In addition to the buffer and length to output, the fourth
- * argument, <outarg>, will be passed through as the third parameter to the
- * output routine. This parameter could be a file descriptor, a buffer
- * address, or any other value that can be passed in an "int".
- *
- * The output routine should be declared as follows:
- * .CS
- * STATUS outRoutine
- * (
- * char *buffer, /@ buffer passed to routine @/
- * int nchars, /@ length of buffer @/
- * int outarg /@ arbitrary arg passed to fmt routine @/
- * )
- * .CE
- * The output routine should return OK if successful, or ERROR if unsuccessful.
- *
- * RETURNS:
- * The number of characters output, or ERROR if the output routine
- * returned ERROR.
- *
- * INTERNAL
- * Warning, this routine is extremely complex and its integrity is easily
- * destroyed. Do not change this code without absolute understanding of all
- * ramifications and consequences.
- */
- int fioFormatV
- (
- FAST const char *fmt, /* format string */
- va_list vaList, /* pointer to varargs list */
- FUNCPTR outRoutine, /* handler for args as they're formatted */
- int outarg /* argument to routine */
- )
- {
- FAST int ch; /* character from fmt */
- FAST int n; /* handy integer (short term usage) */
- FAST char * cp; /* handy char pointer (short term usage) */
- int width; /* width from format (%8d), or 0 */
- char sign; /* sign prefix (' ', '+', '-', or