sprintf
An implementation of sprintf, printf and fprintf
- raw LICENSE
- raw README.md
- raw history.txt
- raw package.4th
- raw printf-spec.md
- raw sprintf.fth
- raw sprintftest.fth
- raw tester.fr
Forth-sprintf
Many languages provide a family of PRINTF function either in a library or as part of the language. This package is an implementation of SPRINTF, PRINTF and FPRINTF in standard Forth 2012. The functionality is a substantial subset of C PRINTF as described at https://linux.die.net/man/3/printf with a few additions and differences. The detailed specification is in file printf-spec.md in this repository. A summary of the functionality provided follows.
It is assumed that the reader is familiar with PRINTF, if not there are tutorials and descriptions readily available on the internet.
See file history.txt for changes in the latest version.
User words
PRINTF ( arguments* format-string -- ) outputs the result to the user terminal
SPRINTF ( arguments* format-string -- caddr u ) outputs the result into a buffer, returns the result as a string
FPRINTF ( arguments* format-string fileid -- ) outputs the result into an opened file with identifier fileid.
SET-SPRINTF-BUFFER ( caddr size -- ) Sets the output buffer for SPRINTF only. It is not needed for PRINTF or FPRINTF. SET-SPRINTF-BUFFER must be used before SPRINTF is called for the first time following loading - a default buffer is not provided by the system. Several buffers may be used - it is the user's responsibility to manage multiple buffers
Installation and testing
Download the files and unzip the files into a directory of your choice.
Following installation it is best to check that it runs successfully on your system by including the test program sprintftests.fth which will include the tester and SPRINTF source files. Note that if using SwiftForth please type this definition before running the test program (see the Portability section below):
create swiftforth
Assuming the Forth system implements floating point, the test output should be:
Start of tests
**********************
Six error reports should be displayed:
------
Format string: "This specification %&d is bad"
^
SPRINTF error: Invalid character
------
Format string: "Not enough %d %d arguments"
^
SPRINTF error: Too few arguments on the stack
------
Format string: "%*.0u"
^
SPRINTF error: Output buffer overflow
------
Format string: "Buffer not set"
^
SPRINTF error: No sprintf buffer set, use SET-SPRINTF-BUFFER
------
Format string: "Not enough %e FP arguments"
^
SPRINTF error: Too few arguments on the FP stack
------
Format string: "Too many fp formats %f %e %g"
^
SPRINTF error: FP-ARGS array too small
------
End of tests
-----[ Report ]-------
Stack empty
FP stack depth: 0
Number of tests: 475
Number of errors: 0
----------------------
Usage
To use sprintf.fth simply include the file. Note that if your Forth system does not have the standard floating point word REPRESENT then it is assumed that floating point has not been implemented and floating point functionality is not compiled.
Example
s" Mary" 23 s" My sister %s is %d years old." printf
displays
My sister Mary is 23 years old.
The arguments must be in the same order as the conversion specifications in the format string. The test program contains many other examples of usage.
Configuration
There are some user configurable values that can be changed:
MAX-PRECISION the number of digits to be generated by REPRESENT, initially set to 15 for 64 bit floating point.
FP-SEP holds the character separating the integer and fractional parts of a floating point number. Initially set to '.'.
MAX-FP-ARGS The maximum number of floating point arguments used in a single PRINTF call, initially set to 10.
MAX-CONV-WIDTH an upper limit to PRINTF field width.
MAX-CONV-PREC an upper limit to a conversion's precision.
Exception codes may be changed if they clash with user error codes.
These are Forth VALUEs and may be set to other values in a user program instead of changing the sprintf.fth source file e.g.
10 to MAX-PRECISION
Portability
The SPRINTF test program has run successfully under Windows 10 on 32 and 64 bit GForth and Win32 Forth with no errors. It runs on VFX Forth and SwiftForth with 1 insignificant error as those systems seem to be unable to handle floating point -0. In addition some tests are disabled for SwiftForth as it crashes if attempts are made to test floating point NAN or INF (hence the advice to create a swiftforth definition above).
Conversion specifications
The following is just a summary of features, see file printf-spec.md for more details
A conversion specification starts with the character % and takes this form:
%<flags><width>.<precision><length><conversion type>
Except for the % character and <conversion type> the fields are optional.
The <flags> available are (these may be used in any order):.
#an alternative form0for left justified conversions the output is padded with 0 characters instead of spaces-the conversion is left justified+if a signed conversion positive numbers are preceded with a + character- ' ' (space character) if a signed conversion positive numbers are preceded with a space character
<width>, <precision> and <length> are:
<width>specifies the field width into which the conversion fits.<precision>specifies the minimum number of significant digits to be generated. If the precision is present it must be preceded by a.character.<length>specified by an l (lower case L) character means the argument is a double length integer. Ignored for floating point conversions
The <conversion types> available in this implementation are:
dfor a signed decimal integer conversionufor an unsigned decimal integer conversionxfor an unsigned hexadecimal integer conversion using the a to f charactersXas for x except that characters A to F are used in the resultofor an unsigned octal integer conversionbfor an unsigned binary integer conversionrfor an integer conversion where a radix (base) value in the range 2 to 36 is used to convert the integer to a string.Ras for r except that characters A to Z are used for digits >9cfor a single charactersfor a string%for a % character i.e. the full conversion specification is %%efor a floating point number in exponential form [-]d.dddde+/-dd where the d's are decimal digitsEas for e except that the form is [-]d.ddddE+/-ddffor a floating point number in fractional format in the style [-]dddd.dddgfor a floating point format where either the e or f type conversion is carried out.GAs for g except that style E or f is used.