Skip to content

Commit

Permalink
version bump 1.2.0: ESM version
Browse files Browse the repository at this point in the history
Fixes #3 h/t @75lb
  • Loading branch information
SheetJSDev committed Sep 4, 2018
1 parent dc687f5 commit e1e33f9
Show file tree
Hide file tree
Showing 18 changed files with 1,411 additions and 50 deletions.
40 changes: 40 additions & 0 deletions .spelling
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# printj (C) 2016-present SheetJS -- http://sheetjs.com
SheetJS
printj
printf

# printf-related terms
16-bit
32-bit
52-bit
64-bit
base-10
fmt

# Third-party
AltiVec
FreeBSD
glibc
libc
nodejs
npm
unicode

# Other terms
CommonJS
NaN
UTF-16
accessor
bitwise
codepages
conformant
errno
falsy
runtime
trigraphs
truthy
typeof
valueOf
variadic
whitespace

4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ ULIB=$(shell echo $(LIB) | tr a-z A-Z)
DEPS=$(sort $(wildcard bits/*.js))
TARGET=$(LIB).js
FLOWTARGET=$(LIB).flow.js
MJSTARGET=$(LIB).mjs
FLOWTGTS=$(TARGET) $(AUXTARGETS)
CLOSURE=/usr/local/lib/node_modules/google-closure-compiler/compiler.jar

Expand All @@ -26,6 +27,7 @@ $(FLOWTGTS): %.js : %.flow.js

$(FLOWTARGET): $(DEPS) lib
cp lib/$(REQS).js $(FLOWTARGET)
cp lib/$(REQS).mjs $(MJSTARGET)

bits/01_version.js: package.json
echo "$(ULIB).version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@
Expand Down Expand Up @@ -75,7 +77,7 @@ fullint: lint old-lint tslint flow mdlint ## Run all checks

.PHONY: lint
lint: $(TARGET) ## Run eslint checks
@eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json bower.json
@eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json
if [ -e $(CLOSURE) ]; then java -jar $(CLOSURE) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi

.PHONY: old-lint
Expand Down
136 changes: 98 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,67 @@ A self-contained specification of the printf format string is included below in
[support against various printf implementations](#support-summary)


## Table of Contents

<details>
<summary><b>Table of Contents</b> (click to show)</summary>

<!-- toc -->

* [Installation](#installation)
* [Usage](#usage)
* [Testing](#testing)
* [License](#license)
* [Badges](#badges)
- [printf format string specification](#printf-format-string-specification)
+ [Original C Interface](#original-c-interface)
+ [JS and C strings](#js-and-c-strings)
+ [JS Interface](#js-interface)
* [Specifier heritage and regular expression](#specifier-heritage-and-regular-expression)
* [Conversion Specifier Quick Reference Table](#conversion-specifier-quick-reference-table)
* [Parameter Selection](#parameter-selection)
* [Dynamic Specifiers](#dynamic-specifiers)
- [C Data Model](#c-data-model)
+ [Integer Types](#integer-types)
+ [Character and String Types](#character-and-string-types)
+ [Floating Point Number Types](#floating-point-number-types)
* [Implementation](#implementation)
- [Integer Conversions](#integer-conversions)
* [Restricting Integer Values](#restricting-integer-values)
* [Length Specifiers for Integer Conversions](#length-specifiers-for-integer-conversions)
* [Rendering Unsigned Integers in Base 10 ("u" and "U" conversions)](#rendering-unsigned-integers-in-base-10-u-and-u-conversions)
* [Rendering Unsigned Integers in Base 8 ("o" and "O" conversions)](#rendering-unsigned-integers-in-base-8-o-and-o-conversions)
* [Rendering Unsigned Integers in Base 16 ("x" and "X" conversions)](#rendering-unsigned-integers-in-base-16-x-and-x-conversions)
* [Rendering Signed Integers in Base 10 ("d" "i" and "D" conversions)](#rendering-signed-integers-in-base-10-d-i-and-d-conversions)
- [Floating Point Conversions](#floating-point-conversions)
* [Infinity, NaN, and Negative Zero](#infinity-nan-and-negative-zero)
* [Exponential Form ("e" and "E" conversions)](#exponential-form-e-and-e-conversions)
* [Standard Form ("f" and "F" conversions)](#standard-form-f-and-f-conversions)
* [Value-dependent Form ("g" and "G" conversions)](#value-dependent-form-g-and-g-conversions)
* [Hex-Mantissa Decimal-Binary-Exponent Form ("a" and "A" conversions)](#hex-mantissa-decimal-binary-exponent-form-a-and-a-conversions)
- [Character Conversions](#character-conversions)
* [Rendering Strings ("s" and "S" conversions)](#rendering-strings-s-and-s-conversions)
* [Rendering Characters ("c" and "C" conversions)](#rendering-characters-c-and-c-conversions)
- [Non-Numeric Conversions](#non-numeric-conversions)
* [The literal "%" symbol ("%" conversion)](#the-literal-%25-symbol-%25-conversion)
* [Interpreting and Rendering Pointers ("p" conversion)](#interpreting-and-rendering-pointers-p-conversion)
* [Extracting length of a partial conversion ("n" conversion)](#extracting-length-of-a-partial-conversion-n-conversion)
* [Error messages ("m" conversion)](#error-messages-m-conversion)
- [Extensions](#extensions)
* [Rendering Boolean Values ("y" and "Y" conversions)](#rendering-boolean-values-y-and-y-conversions)
* [Rendering JSON ("J" conversion)](#rendering-json-j-conversion)
* [JS typeof and valueOf ("T" and "V" conversion)](#js-typeof-and-valueof-t-and-v-conversion)
* [Rendering Unsigned Integers in Base 2 ("b" and "B" conversions)](#rendering-unsigned-integers-in-base-2-b-and-b-conversions)
- [Miscellaneous Notes](#miscellaneous-notes)
* [Format Characters](#format-characters)
* [JS and C strings](#js-and-c-strings-1)
* [Browser Deviations](#browser-deviations)
* [Support Summary](#support-summary)

<!-- tocstop -->

</details>

## Installation

With [npm](https://www.npmjs.org/package/printj):
Expand All @@ -30,9 +91,8 @@ The browser exposes a variable `PRINTJ`
When installed globally, npm installs a script `printj` that renders the format
string with the given arguments. Running the script with `-h` displays help.

The script will manipulate `module.exports` if available (e.g. in a CommonJS
`require` context). This is not always desirable. To prevent the behavior,
define `DO_NOT_EXPORT_PRINTJ`
The script will manipulate `module.exports` if available. This is not always
desirable. To prevent the behavior, define `DO_NOT_EXPORT_PRINTJ`

## Usage

Expand Down Expand Up @@ -125,8 +185,8 @@ but have different interfaces reflecting different input and output behaviors.
Some functions have wide variants that use wide `wchar_t *` strings rather than
normal C `char *`. The following variants are required by the POSIX spec:

| function | max length | output destination | vintage | wide ver |
|------------|------------|-----------------------|---------|------------|
| function | max length | output destination | vintage | wide form |
|:-----------|:-----------|:----------------------|:--------|:-----------|
| `printf` | unbounded | standard output | K&R | `wprintf` |
| `fprintf` | unbounded | stream (`FILE *`) | K&R | `fwprintf` |
| `sprintf` | unbounded | string (`char *`) | K&R | `swprintf` |
Expand Down Expand Up @@ -185,7 +245,7 @@ various string functions are included at the end of the document.

## Specifier heritage and regular expression

Note: The regular expressions follow perl `/x` style. Whitespace characters
Note: The regular expressions follow Perl `/x` style. Whitespace characters
outside of character classes are ignored. `#` is a comment character and every
character until the end of the line is ignored. To convert to a standard regex:

Expand Down Expand Up @@ -298,7 +358,7 @@ This implementation explicitly does not support certain non-standard extensions:
| `i` | integral | cast to C `int`, standard form decimal (alias of `d`) |
| `J` | extended | prints objects using JSON or `util.inspect` |
| `m` | misc | prints info about Error objects (JS equivalent of `errno`) |
| `n` | misc | do not print! stores number of chars written to arg `.len` |
| `n` | misc | do not print! store number of chars written to `.len` field |
| `o` | integral | cast to C `unsigned int`, standard form octal |
| `O` | integral | cast to C `unsigned long`, standard form octal |
| `p` | misc | print `"l"` field of object (fake pointer) |
Expand All @@ -323,8 +383,8 @@ printf("Count to 3: %d %d %d", 1, 2, 3); // Count to 3: 1 2 3
```
POSIX `printf` permits explicit argument selection, bypassing the standard
behavior of using the arguments in order. To select the `n`-th argument, use
`n$` immediately after the `%` token to select an argument for the conversion:
behavior of consuming arguments in order. To specify the argument at position
`n`, use `n$` immediately after the `%` token:
```C
printf("%d %d %d", 1, 2, 3); // 1 2 3 (implicit order 1, 2, 3 )
Expand Down Expand Up @@ -463,11 +523,11 @@ Numerous "C data models", specifying the bit/byte sizes of the various types,
have been and continue to be used. For example, OSX and other modern 64-bit
UNIX flavors use the "LP64" C data model. 64-bit Windows currently uses the
"LLP64" model. 32-bit systems generally use the "ILP32" model. The 8-bit byte
sizes for the various types under the various models are defined in ctypes.json
sizes for the data types under the various models are defined in `ctypes.json`
in the `Models` object as per the following table:
| type | ctypes.json | LP64 | ILP32 | LLP64 |
|-------------|-------------|-----:|------:|------:|
| type | JSON key | LP64 | ILP32 | LLP64 |
|:------------|:------------|-----:|------:|------:|
| `char` | `char` | 1 | 1 | 1 |
| `short` | `short` | 2 | 2 | 2 |
| `int` | `int` | 4 | 4 | 4 |
Expand Down Expand Up @@ -555,16 +615,16 @@ is signed or unsigned according to the conversion specifier. If a length is
specified, it overrides the implied length of the conversion. The following
table describes the behavior of this implementation:
| implied C type | ctypes.json | length | conv default |
|:------------------------------------|:------------|:------:|:-------------|
| `int` or `unsigned int` | `int` | (none) | d i o u x X |
| `char` or `unsigned char` | `char` | hh |
| `short` or `unsigned short` | `short` | h |
| `long` or `unsigned long` | `long` | l | D U O |
| `long long` or `unsigned long long` | `longlong` | L ll q |
| `intmax_t` or `uintmax_t` | `intmax_t` | j |
| `size_t` or `ssize_t` | `size_t` | z Z |
| `ptrdiff_t` or unsigned variant | `ptrdiff_t` | t |
| implied C type | JSON key | length | conversion default |
|:-----------------------------|:------------|:--------:|:-------------------|
| `[unsigned] int` | `int` | (none) | `d i o u x X` |
| `[unsigned] char` | `char` | `hh` |
| `[unsigned] short` | `short` | `h` |
| `[unsigned] long` | `long` | `l` | `D U O` |
| `[unsigned] long long` | `longlong` | `L ll q` |
| `intmax_t` or `uintmax_t` | `intmax_t` | `j` |
| `size_t` or `ssize_t` | `size_t` | `z Z` |
| `ptrdiff_t` or unsigned form | `ptrdiff_t` | `t` |
## Rendering Unsigned Integers in Base 10 ("u" and "U" conversions)
Expand Down Expand Up @@ -615,7 +675,7 @@ JS recognizes a few special IEEE754 values, as described in the following table:
|------------:|:--------------|:-----------------------------------------------|
| `Infinity` | `1./0.` | Positive limiting value `lim{x->0+} 1/x` |
| `-Infinity` | `-1./0.` | Negative limiting value `lim{x->0+} -1/x` |
| `NaN` | `0./0.` | Placeholder for "not-a-number" e.g. `0./0.` |
| `NaN` | `0./0.` | Placeholder for "not-a-number" such as `0./0.` |
| `-0.` | `-1/Infinity` | Negative limiting value `lim{x->0-} x` |
JS `Number` methods render different strings from the POSIX spec:
Expand All @@ -625,7 +685,7 @@ JS `Number` methods render different strings from the POSIX spec:
| `Infinity` | `"inf" "INF"` or `"infinity" "INFINITY"` | `"Infinity"` |
| `-Infinity` | `"-inf" "-INF"` or `"-infinity" "-INFINITY"` | `"-Infinity"` |
| `NaN` | `"[-]nan" "[-]NAN"` w/opt parenthesized chars | `"NaN"` |
| `-0.` | uses negative sign (e.g. `"-0"` under `"%f"`) | same as `+0.` |
| `-0.` | uses negative sign (`"-0"` under `"%f"`) | same as `+0.` |
This implementation performs the required adjustments.
Expand Down Expand Up @@ -656,12 +716,12 @@ The final form (exponential or standard) is determined based on the value. The
threshold is different from the JS `toString` / `toPrecision` thresholds and
depends on the specified precision as well as the base-10 exponent:
| Value | `"%.3g"` | `toPrecision(3)` |
|----------:|:-----------|:-----------------|
| 1.2345e-4 | `0.000123` | `0.000123` |
| 1.2345e-5 | `1.23e-05` | `0.0000123` |
| 1.2345e-6 | `1.23e-06` | `0.00000123` |
| 1.2345e-7 | `1.23e-07` | `1.23e-7` |
| Value | `"%.3g"` | `toPrecision(3)` |
|------------:|:-----------|:-----------------|
| `1.2345e-4` | `0.000123` | `0.000123` |
| `1.2345e-5` | `1.23e-05` | `0.0000123` |
| `1.2345e-6` | `1.23e-06` | `0.00000123` |
| `1.2345e-7` | `1.23e-07` | `1.23e-7` |
According to JS spec, `toPrecision` uses standard form when `precision > E` and
`E >= -6`. For printf standard form is used when `precision > E` and `E >= -4`.
Expand All @@ -673,20 +733,20 @@ the exponent expression, and radix of the exponent expression. The standard
exponential form uses decimal for all three parts. For base 16, there are quite
a few reasonable combinations. Consider the value `1.234567e-80`:
| Mant | Exp Base | Radix-10 (sigil `";"`) | Radix-16 (sigil `";"`) |
|:----:|:--------:|:-----------------------|:-----------------------|
| 10 | 10 | `1.234567;-80` | `1.234567;-50` |
| 16 | 10 | `1.3c0c9539b8887;-80` | `1.3c0c9539b8887;-50` |
| 16 | 16 | `5.daf8c8f5f4104;-67` | `5.daf8c8f5f4104;-43` |
| 16 | 4 | `1.76be323d7d041;-133` | `1.76be323d7d041;-85` |
| 16 | 2 | `1.76be323d7d041;-266` | `1.76be323d7d041;-10a` |
| Mantissa | Exp Base | Radix 10 (sigil `";"`) | Radix 16 (sigil `";"`) |
|:--------:|:--------:|:-----------------------|:-----------------------|
| 10 | 10 | `1.234567;-80` | `1.234567;-50` |
| 16 | 10 | `1.3c0c9539b8887;-80` | `1.3c0c9539b8887;-50` |
| 16 | 16 | `5.daf8c8f5f4104;-67` | `5.daf8c8f5f4104;-43` |
| 16 | 4 | `1.76be323d7d041;-133` | `1.76be323d7d041;-85` |
| 16 | 2 | `1.76be323d7d041;-266` | `1.76be323d7d041;-10a` |
POSIX `"%a"` uses a hex mantissa (16), decimal exponent radix (10), and binary
exponent base (2). The general normalized form requires that the integral part
of the mantissa to exceed 0 and not to exceed `exponent base - 1` except in the
special case of `0`. The sigil is `p` and exponent sign is always used.
JS `num.toString(radix)` is implementation-dependent for valid non-10 radices
JS `num.toString(radix)` is implementation-dependent for radices other than 10
(`2-9, 11-36`). IE uses hex-mantissa decimal-hex-exponent form when the
absolute value of the base-2 exponent exceeds 60. Otherwise, IE uses an exact
standard hexadecimal form. Chrome, Safari and other browsers always use the
Expand Down
6 changes: 6 additions & 0 deletions bits/00_header.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
/*exported PRINTJ */
/*:: declare var DO_NOT_EXPORT_PRINTJ:?boolean; */
/*:: declare function define(cb:()=>any):void; */
#ifdef USE_ESM
var PRINTJ/*:PRINTJModule*/ = /*::(*/{}/*:: :any)*/;
#include "01_version.js"
export const version = PRINTJ.version;
#else
var PRINTJ/*:PRINTJModule*/;
(function (factory/*:(a:any)=>void*/)/*:void*/ {
/*jshint ignore:start */
Expand All @@ -27,3 +32,4 @@ var PRINTJ/*:PRINTJModule*/;
/*jshint ignore:end */
}(function(PRINTJ/*:PRINTJModule*/) {
#include "01_version.js"
#endif
2 changes: 1 addition & 1 deletion bits/01_version.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
PRINTJ.version = '1.1.2';
PRINTJ.version = '1.2.0';
5 changes: 4 additions & 1 deletion bits/50_doit.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#include "30_ctypes.js"
#include "40_macros.js"
#ifdef USE_ESM
var u_inspect/*:(o:any)=>string*/ = JSON.stringify;
#else
/*:: var util = require('util'); */
/*global process:true, util:true, require:true */
if(typeof process !== 'undefined' && !!process.versions && !!process.versions.node) util=require("util");
var u_inspect/*:(o:any)=>string*/ = (typeof util != 'undefined') ? util.inspect : JSON.stringify;

#endif

function doit(t/*:ParsedFmt*/, args/*:Array<any>*/)/*:string*/ {
var o/*:Array<string>*/ = [];
Expand Down
2 changes: 1 addition & 1 deletion bits/54_convmisc.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
/* boolean (extension) */
case /*Y*/ 89:
case /*y*/ 121:
O = Boolean(arg) ? (alt ? "yes" : "true") : (alt ? "no" : "false");
O = (arg) ? (alt ? "yes" : "true") : (alt ? "no" : "false");
if(c == /*Y*/ 89) O = O.toUpperCase();
PREC_STR(O, prec)
WIDTH(O, width, flags)
Expand Down
1 change: 1 addition & 0 deletions bits/99_esmfoot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { sprintf, vsprintf };
4 changes: 2 additions & 2 deletions bits/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ ifndef OUTDIR
OUTDIR=$(PWD)/lib
endif

JSFILES=$(wildcard *.js)
LIBS=$(filter-out $(wildcard [0-9]*_*.js),$(wildcard *.js))
JSFILES=$(wildcard *.js) $(wildcard *.mjs)
LIBS=$(filter-out $(wildcard [0-9]*_*.js),$(JSFILES))

OUTLIBS=$(patsubst %,$(OUTDIR)/%,$(LIBS))

Expand Down
8 changes: 8 additions & 0 deletions bits/loop_code.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#define USE_ESM
#include "00_header.js"
#define USE_LOOP
#define USE_CODE
#include "10_tokenize.js"
#include "50_doit.js"
#include "80_wrapper.js"
#include "99_esmfoot.js"
Loading

0 comments on commit e1e33f9

Please sign in to comment.