Skip to content

Commit e1e33f9

Browse files
committed
version bump 1.2.0: ESM version
Fixes #3 h/t @75lb
1 parent dc687f5 commit e1e33f9

18 files changed

+1411
-50
lines changed

.spelling

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# printj (C) 2016-present SheetJS -- http://sheetjs.com
2+
SheetJS
3+
printj
4+
printf
5+
6+
# printf-related terms
7+
16-bit
8+
32-bit
9+
52-bit
10+
64-bit
11+
base-10
12+
fmt
13+
14+
# Third-party
15+
AltiVec
16+
FreeBSD
17+
glibc
18+
libc
19+
nodejs
20+
npm
21+
unicode
22+
23+
# Other terms
24+
CommonJS
25+
NaN
26+
UTF-16
27+
accessor
28+
bitwise
29+
codepages
30+
conformant
31+
errno
32+
falsy
33+
runtime
34+
trigraphs
35+
truthy
36+
typeof
37+
valueOf
38+
variadic
39+
whitespace
40+

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ULIB=$(shell echo $(LIB) | tr a-z A-Z)
99
DEPS=$(sort $(wildcard bits/*.js))
1010
TARGET=$(LIB).js
1111
FLOWTARGET=$(LIB).flow.js
12+
MJSTARGET=$(LIB).mjs
1213
FLOWTGTS=$(TARGET) $(AUXTARGETS)
1314
CLOSURE=/usr/local/lib/node_modules/google-closure-compiler/compiler.jar
1415

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

2728
$(FLOWTARGET): $(DEPS) lib
2829
cp lib/$(REQS).js $(FLOWTARGET)
30+
cp lib/$(REQS).mjs $(MJSTARGET)
2931

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

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

8183
.PHONY: old-lint

README.md

Lines changed: 98 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,67 @@ A self-contained specification of the printf format string is included below in
1111
[support against various printf implementations](#support-summary)
1212

1313

14+
## Table of Contents
15+
16+
<details>
17+
<summary><b>Table of Contents</b> (click to show)</summary>
18+
19+
<!-- toc -->
20+
21+
* [Installation](#installation)
22+
* [Usage](#usage)
23+
* [Testing](#testing)
24+
* [License](#license)
25+
* [Badges](#badges)
26+
- [printf format string specification](#printf-format-string-specification)
27+
+ [Original C Interface](#original-c-interface)
28+
+ [JS and C strings](#js-and-c-strings)
29+
+ [JS Interface](#js-interface)
30+
* [Specifier heritage and regular expression](#specifier-heritage-and-regular-expression)
31+
* [Conversion Specifier Quick Reference Table](#conversion-specifier-quick-reference-table)
32+
* [Parameter Selection](#parameter-selection)
33+
* [Dynamic Specifiers](#dynamic-specifiers)
34+
- [C Data Model](#c-data-model)
35+
+ [Integer Types](#integer-types)
36+
+ [Character and String Types](#character-and-string-types)
37+
+ [Floating Point Number Types](#floating-point-number-types)
38+
* [Implementation](#implementation)
39+
- [Integer Conversions](#integer-conversions)
40+
* [Restricting Integer Values](#restricting-integer-values)
41+
* [Length Specifiers for Integer Conversions](#length-specifiers-for-integer-conversions)
42+
* [Rendering Unsigned Integers in Base 10 ("u" and "U" conversions)](#rendering-unsigned-integers-in-base-10-u-and-u-conversions)
43+
* [Rendering Unsigned Integers in Base 8 ("o" and "O" conversions)](#rendering-unsigned-integers-in-base-8-o-and-o-conversions)
44+
* [Rendering Unsigned Integers in Base 16 ("x" and "X" conversions)](#rendering-unsigned-integers-in-base-16-x-and-x-conversions)
45+
* [Rendering Signed Integers in Base 10 ("d" "i" and "D" conversions)](#rendering-signed-integers-in-base-10-d-i-and-d-conversions)
46+
- [Floating Point Conversions](#floating-point-conversions)
47+
* [Infinity, NaN, and Negative Zero](#infinity-nan-and-negative-zero)
48+
* [Exponential Form ("e" and "E" conversions)](#exponential-form-e-and-e-conversions)
49+
* [Standard Form ("f" and "F" conversions)](#standard-form-f-and-f-conversions)
50+
* [Value-dependent Form ("g" and "G" conversions)](#value-dependent-form-g-and-g-conversions)
51+
* [Hex-Mantissa Decimal-Binary-Exponent Form ("a" and "A" conversions)](#hex-mantissa-decimal-binary-exponent-form-a-and-a-conversions)
52+
- [Character Conversions](#character-conversions)
53+
* [Rendering Strings ("s" and "S" conversions)](#rendering-strings-s-and-s-conversions)
54+
* [Rendering Characters ("c" and "C" conversions)](#rendering-characters-c-and-c-conversions)
55+
- [Non-Numeric Conversions](#non-numeric-conversions)
56+
* [The literal "%" symbol ("%" conversion)](#the-literal-%25-symbol-%25-conversion)
57+
* [Interpreting and Rendering Pointers ("p" conversion)](#interpreting-and-rendering-pointers-p-conversion)
58+
* [Extracting length of a partial conversion ("n" conversion)](#extracting-length-of-a-partial-conversion-n-conversion)
59+
* [Error messages ("m" conversion)](#error-messages-m-conversion)
60+
- [Extensions](#extensions)
61+
* [Rendering Boolean Values ("y" and "Y" conversions)](#rendering-boolean-values-y-and-y-conversions)
62+
* [Rendering JSON ("J" conversion)](#rendering-json-j-conversion)
63+
* [JS typeof and valueOf ("T" and "V" conversion)](#js-typeof-and-valueof-t-and-v-conversion)
64+
* [Rendering Unsigned Integers in Base 2 ("b" and "B" conversions)](#rendering-unsigned-integers-in-base-2-b-and-b-conversions)
65+
- [Miscellaneous Notes](#miscellaneous-notes)
66+
* [Format Characters](#format-characters)
67+
* [JS and C strings](#js-and-c-strings-1)
68+
* [Browser Deviations](#browser-deviations)
69+
* [Support Summary](#support-summary)
70+
71+
<!-- tocstop -->
72+
73+
</details>
74+
1475
## Installation
1576

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

33-
The script will manipulate `module.exports` if available (e.g. in a CommonJS
34-
`require` context). This is not always desirable. To prevent the behavior,
35-
define `DO_NOT_EXPORT_PRINTJ`
94+
The script will manipulate `module.exports` if available. This is not always
95+
desirable. To prevent the behavior, define `DO_NOT_EXPORT_PRINTJ`
3696

3797
## Usage
3898

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

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

186246
## Specifier heritage and regular expression
187247

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

@@ -298,7 +358,7 @@ This implementation explicitly does not support certain non-standard extensions:
298358
| `i` | integral | cast to C `int`, standard form decimal (alias of `d`) |
299359
| `J` | extended | prints objects using JSON or `util.inspect` |
300360
| `m` | misc | prints info about Error objects (JS equivalent of `errno`) |
301-
| `n` | misc | do not print! stores number of chars written to arg `.len` |
361+
| `n` | misc | do not print! store number of chars written to `.len` field |
302362
| `o` | integral | cast to C `unsigned int`, standard form octal |
303363
| `O` | integral | cast to C `unsigned long`, standard form octal |
304364
| `p` | misc | print `"l"` field of object (fake pointer) |
@@ -323,8 +383,8 @@ printf("Count to 3: %d %d %d", 1, 2, 3); // Count to 3: 1 2 3
323383
```
324384
325385
POSIX `printf` permits explicit argument selection, bypassing the standard
326-
behavior of using the arguments in order. To select the `n`-th argument, use
327-
`n$` immediately after the `%` token to select an argument for the conversion:
386+
behavior of consuming arguments in order. To specify the argument at position
387+
`n`, use `n$` immediately after the `%` token:
328388
329389
```C
330390
printf("%d %d %d", 1, 2, 3); // 1 2 3 (implicit order 1, 2, 3 )
@@ -463,11 +523,11 @@ Numerous "C data models", specifying the bit/byte sizes of the various types,
463523
have been and continue to be used. For example, OSX and other modern 64-bit
464524
UNIX flavors use the "LP64" C data model. 64-bit Windows currently uses the
465525
"LLP64" model. 32-bit systems generally use the "ILP32" model. The 8-bit byte
466-
sizes for the various types under the various models are defined in ctypes.json
526+
sizes for the data types under the various models are defined in `ctypes.json`
467527
in the `Models` object as per the following table:
468528
469-
| type | ctypes.json | LP64 | ILP32 | LLP64 |
470-
|-------------|-------------|-----:|------:|------:|
529+
| type | JSON key | LP64 | ILP32 | LLP64 |
530+
|:------------|:------------|-----:|------:|------:|
471531
| `char` | `char` | 1 | 1 | 1 |
472532
| `short` | `short` | 2 | 2 | 2 |
473533
| `int` | `int` | 4 | 4 | 4 |
@@ -555,16 +615,16 @@ is signed or unsigned according to the conversion specifier. If a length is
555615
specified, it overrides the implied length of the conversion. The following
556616
table describes the behavior of this implementation:
557617
558-
| implied C type | ctypes.json | length | conv default |
559-
|:------------------------------------|:------------|:------:|:-------------|
560-
| `int` or `unsigned int` | `int` | (none) | d i o u x X |
561-
| `char` or `unsigned char` | `char` | hh |
562-
| `short` or `unsigned short` | `short` | h |
563-
| `long` or `unsigned long` | `long` | l | D U O |
564-
| `long long` or `unsigned long long` | `longlong` | L ll q |
565-
| `intmax_t` or `uintmax_t` | `intmax_t` | j |
566-
| `size_t` or `ssize_t` | `size_t` | z Z |
567-
| `ptrdiff_t` or unsigned variant | `ptrdiff_t` | t |
618+
| implied C type | JSON key | length | conversion default |
619+
|:-----------------------------|:------------|:--------:|:-------------------|
620+
| `[unsigned] int` | `int` | (none) | `d i o u x X` |
621+
| `[unsigned] char` | `char` | `hh` |
622+
| `[unsigned] short` | `short` | `h` |
623+
| `[unsigned] long` | `long` | `l` | `D U O` |
624+
| `[unsigned] long long` | `longlong` | `L ll q` |
625+
| `intmax_t` or `uintmax_t` | `intmax_t` | `j` |
626+
| `size_t` or `ssize_t` | `size_t` | `z Z` |
627+
| `ptrdiff_t` or unsigned form | `ptrdiff_t` | `t` |
568628
569629
## Rendering Unsigned Integers in Base 10 ("u" and "U" conversions)
570630
@@ -615,7 +675,7 @@ JS recognizes a few special IEEE754 values, as described in the following table:
615675
|------------:|:--------------|:-----------------------------------------------|
616676
| `Infinity` | `1./0.` | Positive limiting value `lim{x->0+} 1/x` |
617677
| `-Infinity` | `-1./0.` | Negative limiting value `lim{x->0+} -1/x` |
618-
| `NaN` | `0./0.` | Placeholder for "not-a-number" e.g. `0./0.` |
678+
| `NaN` | `0./0.` | Placeholder for "not-a-number" such as `0./0.` |
619679
| `-0.` | `-1/Infinity` | Negative limiting value `lim{x->0-} x` |
620680
621681
JS `Number` methods render different strings from the POSIX spec:
@@ -625,7 +685,7 @@ JS `Number` methods render different strings from the POSIX spec:
625685
| `Infinity` | `"inf" "INF"` or `"infinity" "INFINITY"` | `"Infinity"` |
626686
| `-Infinity` | `"-inf" "-INF"` or `"-infinity" "-INFINITY"` | `"-Infinity"` |
627687
| `NaN` | `"[-]nan" "[-]NAN"` w/opt parenthesized chars | `"NaN"` |
628-
| `-0.` | uses negative sign (e.g. `"-0"` under `"%f"`) | same as `+0.` |
688+
| `-0.` | uses negative sign (`"-0"` under `"%f"`) | same as `+0.` |
629689
630690
This implementation performs the required adjustments.
631691
@@ -656,12 +716,12 @@ The final form (exponential or standard) is determined based on the value. The
656716
threshold is different from the JS `toString` / `toPrecision` thresholds and
657717
depends on the specified precision as well as the base-10 exponent:
658718
659-
| Value | `"%.3g"` | `toPrecision(3)` |
660-
|----------:|:-----------|:-----------------|
661-
| 1.2345e-4 | `0.000123` | `0.000123` |
662-
| 1.2345e-5 | `1.23e-05` | `0.0000123` |
663-
| 1.2345e-6 | `1.23e-06` | `0.00000123` |
664-
| 1.2345e-7 | `1.23e-07` | `1.23e-7` |
719+
| Value | `"%.3g"` | `toPrecision(3)` |
720+
|------------:|:-----------|:-----------------|
721+
| `1.2345e-4` | `0.000123` | `0.000123` |
722+
| `1.2345e-5` | `1.23e-05` | `0.0000123` |
723+
| `1.2345e-6` | `1.23e-06` | `0.00000123` |
724+
| `1.2345e-7` | `1.23e-07` | `1.23e-7` |
665725
666726
According to JS spec, `toPrecision` uses standard form when `precision > E` and
667727
`E >= -6`. For printf standard form is used when `precision > E` and `E >= -4`.
@@ -673,20 +733,20 @@ the exponent expression, and radix of the exponent expression. The standard
673733
exponential form uses decimal for all three parts. For base 16, there are quite
674734
a few reasonable combinations. Consider the value `1.234567e-80`:
675735
676-
| Mant | Exp Base | Radix-10 (sigil `";"`) | Radix-16 (sigil `";"`) |
677-
|:----:|:--------:|:-----------------------|:-----------------------|
678-
| 10 | 10 | `1.234567;-80` | `1.234567;-50` |
679-
| 16 | 10 | `1.3c0c9539b8887;-80` | `1.3c0c9539b8887;-50` |
680-
| 16 | 16 | `5.daf8c8f5f4104;-67` | `5.daf8c8f5f4104;-43` |
681-
| 16 | 4 | `1.76be323d7d041;-133` | `1.76be323d7d041;-85` |
682-
| 16 | 2 | `1.76be323d7d041;-266` | `1.76be323d7d041;-10a` |
736+
| Mantissa | Exp Base | Radix 10 (sigil `";"`) | Radix 16 (sigil `";"`) |
737+
|:--------:|:--------:|:-----------------------|:-----------------------|
738+
| 10 | 10 | `1.234567;-80` | `1.234567;-50` |
739+
| 16 | 10 | `1.3c0c9539b8887;-80` | `1.3c0c9539b8887;-50` |
740+
| 16 | 16 | `5.daf8c8f5f4104;-67` | `5.daf8c8f5f4104;-43` |
741+
| 16 | 4 | `1.76be323d7d041;-133` | `1.76be323d7d041;-85` |
742+
| 16 | 2 | `1.76be323d7d041;-266` | `1.76be323d7d041;-10a` |
683743
684744
POSIX `"%a"` uses a hex mantissa (16), decimal exponent radix (10), and binary
685745
exponent base (2). The general normalized form requires that the integral part
686746
of the mantissa to exceed 0 and not to exceed `exponent base - 1` except in the
687747
special case of `0`. The sigil is `p` and exponent sign is always used.
688748
689-
JS `num.toString(radix)` is implementation-dependent for valid non-10 radices
749+
JS `num.toString(radix)` is implementation-dependent for radices other than 10
690750
(`2-9, 11-36`). IE uses hex-mantissa decimal-hex-exponent form when the
691751
absolute value of the base-2 exponent exceeds 60. Otherwise, IE uses an exact
692752
standard hexadecimal form. Chrome, Safari and other browsers always use the

bits/00_header.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
/*exported PRINTJ */
55
/*:: declare var DO_NOT_EXPORT_PRINTJ:?boolean; */
66
/*:: declare function define(cb:()=>any):void; */
7+
#ifdef USE_ESM
8+
var PRINTJ/*:PRINTJModule*/ = /*::(*/{}/*:: :any)*/;
9+
#include "01_version.js"
10+
export const version = PRINTJ.version;
11+
#else
712
var PRINTJ/*:PRINTJModule*/;
813
(function (factory/*:(a:any)=>void*/)/*:void*/ {
914
/*jshint ignore:start */
@@ -27,3 +32,4 @@ var PRINTJ/*:PRINTJModule*/;
2732
/*jshint ignore:end */
2833
}(function(PRINTJ/*:PRINTJModule*/) {
2934
#include "01_version.js"
35+
#endif

bits/01_version.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
PRINTJ.version = '1.1.2';
1+
PRINTJ.version = '1.2.0';

bits/50_doit.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
#include "30_ctypes.js"
22
#include "40_macros.js"
3+
#ifdef USE_ESM
4+
var u_inspect/*:(o:any)=>string*/ = JSON.stringify;
5+
#else
36
/*:: var util = require('util'); */
47
/*global process:true, util:true, require:true */
58
if(typeof process !== 'undefined' && !!process.versions && !!process.versions.node) util=require("util");
69
var u_inspect/*:(o:any)=>string*/ = (typeof util != 'undefined') ? util.inspect : JSON.stringify;
7-
10+
#endif
811

912
function doit(t/*:ParsedFmt*/, args/*:Array<any>*/)/*:string*/ {
1013
var o/*:Array<string>*/ = [];

bits/54_convmisc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
/* boolean (extension) */
3636
case /*Y*/ 89:
3737
case /*y*/ 121:
38-
O = Boolean(arg) ? (alt ? "yes" : "true") : (alt ? "no" : "false");
38+
O = (arg) ? (alt ? "yes" : "true") : (alt ? "no" : "false");
3939
if(c == /*Y*/ 89) O = O.toUpperCase();
4040
PREC_STR(O, prec)
4141
WIDTH(O, width, flags)

bits/99_esmfoot.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { sprintf, vsprintf };

bits/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ ifndef OUTDIR
22
OUTDIR=$(PWD)/lib
33
endif
44

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

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

bits/loop_code.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#define USE_ESM
2+
#include "00_header.js"
3+
#define USE_LOOP
4+
#define USE_CODE
5+
#include "10_tokenize.js"
6+
#include "50_doit.js"
7+
#include "80_wrapper.js"
8+
#include "99_esmfoot.js"

0 commit comments

Comments
 (0)