📄 fiolib.c
字号:
/* 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' format06a,21dec01,an enabled long long arg support for printf/scanf using 'L' format flag 05z,17dec01,max Simple change just to make WRS doctool happy05y,20jun01,kab Code review cleanup05x,19apr01,max printf & scanf support for ALTIVEC vector data types05w,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 fscanf05o,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 scanCharSet05i,10mar93,jdi more documentation cleanup for 5.1.05h,22jan93,jdi documentation cleanup for 5.1.05g,13nov92,dnw added include of taskLib.h05f,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. +smb05a,26may92,rrr the tree shuffle04z,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 notice04t,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 documentation04l,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 void04i,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 parsing03e,05nov87,jlf documentation03d,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 changes02q,27jul86,llk added standard error file descriptor (std_err) added fioSetErr, fioStdErr, printErr02p,01jul86,jlf minor documentation02o,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.*//*DESCRIPTIONThis library provides the basic formatting and scanning I/O functions. Itincludes 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' areto be used with these routines, the routine floatInit() must be calledfirst. 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 thestandard I/O facility. Thus, they can be invoked even if the standard I/Opackage has not been included. This includes printf(), which in most UNIXsystems 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 ofthe entire standard I/O package. For more information, see the manualentry for ansiStdio.INCLUDE FILES: fioLib.h, stdio.hSEE 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -