parent
							
								
									dc687f5ed0
								
							
						
					
					
						commit
						e1e33f9cb6
					
				
							
								
								
									
										40
									
								
								.spelling
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										40
									
								
								.spelling
									
									
									
									
									
										Normal file
									
								
							| @ -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
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							| @ -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 | ||||
| 
 | ||||
| @ -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}'`"';" > $@ | ||||
| @ -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 | ||||
|  | ||||
							
								
								
									
										136
									
								
								README.md
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										136
									
								
								README.md
									
									
									
									
									
								
							| @ -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): | ||||
| @ -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 | ||||
| 
 | ||||
| @ -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` | | ||||
| @ -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: | ||||
| 
 | ||||
| @ -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)                  | | ||||
| @ -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 ) | ||||
| @ -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  | | ||||
| @ -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) | ||||
| 
 | ||||
| @ -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: | ||||
| @ -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. | ||||
| 
 | ||||
| @ -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`. | ||||
| @ -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 | ||||
|  | ||||
| @ -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 */ | ||||
| @ -27,3 +32,4 @@ var PRINTJ/*:PRINTJModule*/; | ||||
| 	/*jshint ignore:end */ | ||||
| }(function(PRINTJ/*:PRINTJModule*/) { | ||||
| #include "01_version.js" | ||||
| #endif | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| PRINTJ.version = '1.1.2'; | ||||
| PRINTJ.version = '1.2.0'; | ||||
|  | ||||
| @ -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>*/ = []; | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
							
								
								
									
										1
									
								
								bits/99_esmfoot.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								bits/99_esmfoot.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| export { sprintf, vsprintf }; | ||||
| @ -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)) | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										8
									
								
								bits/loop_code.mjs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										8
									
								
								bits/loop_code.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -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" | ||||
							
								
								
									
										582
									
								
								lib/loop_code.mjs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										582
									
								
								lib/loop_code.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,582 @@ | ||||
| /* printj.js (C) 2016-present SheetJS -- http://sheetjs.com */ | ||||
| /* vim: set ts=2: */ | ||||
| /*jshint sub:true, eqnull:true */ | ||||
| /*exported PRINTJ */ | ||||
| /*:: declare var DO_NOT_EXPORT_PRINTJ:?boolean; */ | ||||
| /*:: declare function define(cb:()=>any):void; */ | ||||
| 
 | ||||
| var PRINTJ/*:PRINTJModule*/ = /*::(*/{}/*:: :any)*/; | ||||
| 
 | ||||
| PRINTJ.version = '1.2.0'; | ||||
| 
 | ||||
| export const version = PRINTJ.version; | ||||
| 
 | ||||
| function tokenize(fmt/*:string*/)/*:ParsedFmt*/ { | ||||
| 	var out/*:ParsedFmt*/ = []; | ||||
| 	var start/*:number*/ = 0; | ||||
| 
 | ||||
| 	var i/*:number*/ = 0; | ||||
| 	var infmt/*:boolean*/ = false; | ||||
| 	var fmtparam/*:string*/ = "", fmtflags/*:string*/ = "", fmtwidth/*:string*/ = "", fmtprec/*:string*/ = "", fmtlen/*:string*/ = ""; | ||||
| 
 | ||||
| 	var c/*:number*/ = 0; | ||||
| 
 | ||||
| 	var L/*:number*/ = fmt.length; | ||||
| 
 | ||||
| 	for(; i < L; ++i) { | ||||
| 		c = fmt.charCodeAt(i); | ||||
| 		if(!infmt) { | ||||
| 
 | ||||
| 			if(c !== 37) continue; | ||||
| 
 | ||||
| 			if(start < i) out.push(["L", fmt.substring(start, i)]); | ||||
| 			start = i; | ||||
| 			infmt = true; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if(c >= 48 && c < 58)	{ | ||||
| 				if(fmtprec.length) fmtprec += String.fromCharCode(c); | ||||
| 				else if(c == 48 && !fmtwidth.length) fmtflags += String.fromCharCode(c); | ||||
| 				else fmtwidth += String.fromCharCode(c); | ||||
| 		} else switch(c) { | ||||
| 			/* positional */ | ||||
| 			case 36: | ||||
| 				if(fmtprec.length) fmtprec += "$"; | ||||
| 				else if(fmtwidth.charAt(0) == "*") fmtwidth += "$"; | ||||
| 				else { fmtparam = fmtwidth + "$"; fmtwidth = ""; } | ||||
| 				break; | ||||
| 
 | ||||
| 			/* flags */ | ||||
| 			case 39: fmtflags += "'"; break; | ||||
| 			case 45: fmtflags += "-"; break; | ||||
| 			case 43: fmtflags += "+"; break; | ||||
| 			case 32: fmtflags += " "; break; | ||||
| 			case 35: fmtflags += "#"; break; | ||||
| 
 | ||||
| 			/* width and precision */ | ||||
| 			case 46: fmtprec = "."; break; | ||||
| 			case 42: | ||||
| 				if(fmtprec.charAt(0) == ".") fmtprec += "*"; | ||||
| 				else fmtwidth += "*"; | ||||
| 				break; | ||||
| 
 | ||||
| 			/* length */ | ||||
| 			case 104: | ||||
| 			case 108: | ||||
| 				if(fmtlen.length > 1) throw "bad length " + fmtlen + String(c); | ||||
| 				fmtlen += String.fromCharCode(c); | ||||
| 				break; | ||||
| 
 | ||||
| 			case  76: | ||||
| 			case 106: | ||||
| 			case 122: | ||||
| 			case 116: | ||||
| 			case 113: | ||||
| 			case  90: | ||||
| 			case 119: | ||||
| 				if(fmtlen !== "") throw "bad length " + fmtlen + String.fromCharCode(c); | ||||
| 				fmtlen = String.fromCharCode(c); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 73: | ||||
| 				if(fmtlen !== "") throw "bad length " + fmtlen + 'I'; | ||||
| 				fmtlen = 'I'; | ||||
| 				break; | ||||
| 
 | ||||
| 			/* conversion */ | ||||
| 			case 100: | ||||
| 			case 105: | ||||
| 			case 111: | ||||
| 			case 117: | ||||
| 			case 120: | ||||
| 			case 88: | ||||
| 			case 102: | ||||
| 			case 70: | ||||
| 			case 101: | ||||
| 			case 69: | ||||
| 			case 103: | ||||
| 			case 71: | ||||
| 			case 97: | ||||
| 			case 65: | ||||
| 			case 99: | ||||
| 			case 67: | ||||
| 			case 115: | ||||
| 			case 83: | ||||
| 			case 112: | ||||
| 			case 110: | ||||
| 			case 68: | ||||
| 			case 85: | ||||
| 			case 79: | ||||
| 			case 109: | ||||
| 			case 98: | ||||
| 			case 66: | ||||
| 			case 121: | ||||
| 			case 89: | ||||
| 			case 74: | ||||
| 			case 86: | ||||
| 			case 84: | ||||
| 			case 37: | ||||
| 				infmt = false; | ||||
| 				if(fmtprec.length > 1) fmtprec = fmtprec.substr(1); | ||||
| 				out.push([String.fromCharCode(c), fmt.substring(start, i+1), fmtparam, fmtflags, fmtwidth, fmtprec, fmtlen]); | ||||
| 				start = i+1; | ||||
| 				fmtlen = fmtprec = fmtwidth = fmtflags = fmtparam = ""; | ||||
| 				break; | ||||
| 			default: | ||||
| 				throw new Error("Invalid format string starting with |" + fmt.substring(start, i+1) + "|"); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	if(start < fmt.length) out.push(["L", fmt.substring(start)]); | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| //#define PAD_(x,c) (x >= 0 ? new Array(((x)|0) + 1).join((c)) : "")
 | ||||
| var padstr/*:{[s:string]:string}*/ = { | ||||
| 	" ": "                                 ", | ||||
| 	"0": "000000000000000000000000000000000", | ||||
| 	"7": "777777777777777777777777777777777", | ||||
| 	"f": "fffffffffffffffffffffffffffffffff" | ||||
| }; | ||||
| 
 | ||||
| var u_inspect/*:(o:any)=>string*/ = JSON.stringify; | ||||
| 
 | ||||
| function doit(t/*:ParsedFmt*/, args/*:Array<any>*/)/*:string*/ { | ||||
| 	var o/*:Array<string>*/ = []; | ||||
| 	var argidx/*:number*/ = 0, idx/*:number*/ = 0; | ||||
| 	var Vnum/*:number*/ = 0; | ||||
| 	var pad/*:string*/ = ""; | ||||
| 	for(var i/*:number*/ = 0; i < t.length; ++i) { | ||||
| 		var m/*:ParsedEntry*/ = t[i], c/*:number*/ = (m[0]/*:string*/).charCodeAt(0); | ||||
| 		/* m order: conv full param flags width prec length */ | ||||
| 
 | ||||
| 		if(c === /*L*/ 76) { o.push(m[1]); continue; } | ||||
| 		if(c === /*%*/ 37) { o.push("%"); continue; } | ||||
| 
 | ||||
| 		var O/*:string*/ = ""; | ||||
| 		var isnum/*:number*/ = 0, radix/*:number*/ = 10, bytes/*:number*/ = 4, sign/*:boolean*/ = false; | ||||
| 
 | ||||
| 		/* flags */ | ||||
| 		var flags/*:string*/ = m[3]||""; | ||||
| 		var alt/*:boolean*/ = flags.indexOf("#") > -1; | ||||
| 
 | ||||
| 		/* position */ | ||||
| 		if(m[2]) argidx = parseInt(m[2])-1; | ||||
| 		/* %m special case */ | ||||
| 		else if(c === /*m*/ 109 && !alt) { o.push("Success"); continue; } | ||||
| 
 | ||||
| 		/* grab width */ | ||||
| 		var width =  0; if(m[ 4] != null && m[ 4].length > 0) { if(m[ 4].charAt(0) !== '*') width = parseInt(m[ 4], 10); else if(m[ 4].length === 1) width = args[idx++]; else width = args[parseInt(m[ 4].substr(1), 10)-1]; } | ||||
| 
 | ||||
| 		/* grab precision */ | ||||
| 		var prec =  -1; if(m[ 5] != null && m[ 5].length > 0) { if(m[ 5].charAt(0) !== '*') prec = parseInt(m[ 5], 10); else if(m[ 5].length === 1) prec = args[idx++]; else prec = args[parseInt(m[ 5].substr(1), 10)-1]; } | ||||
| 
 | ||||
| 		/* position not specified */ | ||||
| 		if(!m[2]) argidx = idx++; | ||||
| 
 | ||||
| 		/* grab argument */ | ||||
| 		var arg/*:any*/ = args[argidx]; | ||||
| 
 | ||||
| 		/* grab length */ | ||||
| 		var len/*:string*/ = m[6] || ""; | ||||
| 
 | ||||
| 		switch(c) { | ||||
| 			/* str cCsS */ | ||||
| 
 | ||||
| 			case /*S*/  83: | ||||
| 			case /*s*/ 115: | ||||
| 				/* only valid flag is "-" for left justification */ | ||||
| 				O = String(arg); | ||||
| 				if( prec >= 0) O = O.substr(0,  prec); | ||||
| 				if( width > O.length || - width > O.length) { if(( flags.indexOf("-") == -1 ||  width < 0) &&  flags.indexOf("0") != -1) { pad = ( width - O.length >= 0 ? padstr["0"].substr(0, width - O.length) : ""); O = pad + O; } else { pad = ( width - O.length >= 0 ? padstr[" "].substr(0, width - O.length) : ""); O =  flags.indexOf("-") > -1 ? O + pad : pad + O; } } | ||||
| 				break; | ||||
| 
 | ||||
| 			/* first char of string or convert */ | ||||
| 			case /*C*/  67: | ||||
| 			case /*c*/  99: | ||||
| 				switch(typeof arg) { | ||||
| 					case "number": | ||||
| 						var cc/*:number*/ = arg; | ||||
| 						if(c == 67 || len.charCodeAt(0) === /*l*/ 108) {  cc &= 0xFFFFFFFF; O = String.fromCharCode( cc); } | ||||
| 						else {  cc &= 0xFF; O = String.fromCharCode( cc); } | ||||
| 						break; | ||||
| 					case "string": O = /*::(*/arg/*:: :string)*/.charAt(0); break; | ||||
| 					default: O = String(arg).charAt(0); | ||||
| 				} | ||||
| 				if( width > O.length || - width > O.length) { if(( flags.indexOf("-") == -1 ||  width < 0) &&  flags.indexOf("0") != -1) { pad = ( width - O.length >= 0 ? padstr["0"].substr(0, width - O.length) : ""); O = pad + O; } else { pad = ( width - O.length >= 0 ? padstr[" "].substr(0, width - O.length) : ""); O =  flags.indexOf("-") > -1 ? O + pad : pad + O; } } | ||||
| 				break; | ||||
| 
 | ||||
| 			/* int diDuUoOxXbB */ | ||||
| 
 | ||||
| 			/* signed integer */ | ||||
| 			case /*D*/  68: bytes = 8; | ||||
| 			/* falls through */ | ||||
| 			case /*d*/ 100: | ||||
| 			case /*i*/ 105: isnum = -1; sign = true; break; | ||||
| 
 | ||||
| 			/* unsigned integer */ | ||||
| 			case /*U*/  85: bytes = 8; | ||||
| 			/* falls through */ | ||||
| 			case /*u*/ 117: isnum = -1; break; | ||||
| 
 | ||||
| 			/* unsigned octal */ | ||||
| 			case /*O*/  79: bytes = 8; | ||||
| 			/* falls through */ | ||||
| 			case /*o*/ 111: isnum = -1; radix = (8); break; | ||||
| 
 | ||||
| 			/* unsigned hex */ | ||||
| 			case /*x*/ 120: isnum = -1; radix = (-16); break; | ||||
| 			case /*X*/  88: isnum = -1; radix = (16); break; | ||||
| 
 | ||||
| 			/* unsigned binary (extension) */ | ||||
| 			case /*B*/  66: bytes = 8; | ||||
| 			/* falls through */ | ||||
| 			case /*b*/  98: isnum = -1; radix = (2); break; | ||||
| 
 | ||||
| 			/* flt fegFEGaA */ | ||||
| 
 | ||||
| 			/* floating point logic */ | ||||
| 			case /*F*/  70: | ||||
| 			case /*f*/ 102: isnum = (1); break; | ||||
| 
 | ||||
| 			case /*E*/  69: | ||||
| 			case /*e*/ 101: isnum = (2); break; | ||||
| 
 | ||||
| 			case /*G*/  71: | ||||
| 			case /*g*/ 103: isnum = (3); break; | ||||
| 
 | ||||
| 			/* floating hex */ | ||||
| 			case /*A*/  65: | ||||
| 			case /*a*/  97: isnum = (4); break; | ||||
| 
 | ||||
| 			/* misc pnmJVTyY */ | ||||
| 
 | ||||
| 			/* JS has no concept of pointers so interpret the `l` key as an address */ | ||||
| 			case /*p*/ 112: | ||||
| 				Vnum = typeof arg == "number" ? arg : arg ? Number(arg.l) : -1; | ||||
| 				if(isNaN(Vnum)) Vnum = -1; | ||||
| 				if(alt) O = Vnum.toString(10); | ||||
| 				else { | ||||
| 					Vnum = Math.abs(Vnum); | ||||
| 					O = "0x" + Vnum.toString(16).toLowerCase(); | ||||
| 				} | ||||
| 				break; | ||||
| 
 | ||||
| 			/* store length in the `len` key */ | ||||
| 			case /*n*/ 110: | ||||
| 				if(arg) { arg.len=0; for(var oo/*:number*/ = 0; oo < o.length; ++oo) arg.len += o[oo].length; } | ||||
| 				continue; | ||||
| 
 | ||||
| 			/* process error */ | ||||
| 			case /*m*/ 109: | ||||
| 				if(!(arg instanceof Error)) O = "Success"; | ||||
| 				else if(arg.message) O = arg.message; | ||||
| 				else if(arg.errno) O = "Error number " + arg.errno; | ||||
| 				else O = "Error " + String(arg); | ||||
| 				break; | ||||
| 
 | ||||
| 			/* JS-specific conversions (extension) */ | ||||
| 			case /*J*/  74: O = (alt ? u_inspect : JSON.stringify)(arg); break; | ||||
| 			case /*V*/  86: O = arg == null ? "null" : String(arg.valueOf()); break; | ||||
| 			case /*T*/  84: | ||||
| 				if(alt) { /* from '[object %s]' extract %s */ | ||||
| 					O = Object.prototype.toString.call(arg).substr(8); | ||||
| 					O = O.substr(0, O.length - 1); | ||||
| 				} else O = typeof arg; | ||||
| 				break; | ||||
| 
 | ||||
| 			/* boolean (extension) */ | ||||
| 			case /*Y*/  89: | ||||
| 			case /*y*/ 121: | ||||
| 				O = (arg) ? (alt ? "yes" : "true") : (alt ? "no" : "false"); | ||||
| 				if(c == /*Y*/ 89) O = O.toUpperCase(); | ||||
| 				if( prec >= 0) O = O.substr(0,  prec); | ||||
| 				if( width > O.length || - width > O.length) { if(( flags.indexOf("-") == -1 ||  width < 0) &&  flags.indexOf("0") != -1) { pad = ( width - O.length >= 0 ? padstr["0"].substr(0, width - O.length) : ""); O = pad + O; } else { pad = ( width - O.length >= 0 ? padstr[" "].substr(0, width - O.length) : ""); O =  flags.indexOf("-") > -1 ? O + pad : pad + O; } } | ||||
| 				break; | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		if(width < 0) { width = -width; flags += "-"; } | ||||
| 
 | ||||
| 		if(isnum == -1) { | ||||
| 
 | ||||
| 			Vnum = Number(arg); | ||||
| 
 | ||||
| 			/* parse byte length field */ | ||||
| 
 | ||||
| 			switch(len) { | ||||
| 				/* char */ | ||||
| 				case "hh": { bytes = 1; } break; | ||||
| 				/* short */ | ||||
| 				case "h":  { bytes = 2; } break; | ||||
| 
 | ||||
| 				/* long */ | ||||
| 				case "l":  { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* long long */ | ||||
| 				case "L": | ||||
| 				case "q": | ||||
| 				case "ll": { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* intmax_t */ | ||||
| 				case "j":  { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* ptrdiff_t */ | ||||
| 				case "t":  { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* size_t */ | ||||
| 				case "z": | ||||
| 				case "Z":  { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* CRT size_t or ptrdiff_t */ | ||||
| 				case "I": | ||||
| 
 | ||||
| 					{ if(bytes == 4) bytes = 8; } | ||||
| 
 | ||||
| 					break; | ||||
| 
 | ||||
| 				/* CRT wchar_t */ | ||||
| 				case "w": break; | ||||
| 			} | ||||
| 
 | ||||
| 			/* restrict value */ | ||||
| 
 | ||||
| 			switch(bytes) { | ||||
| 				case 1: Vnum = (Vnum & 0xFF); if(sign && (Vnum >  0x7F)) Vnum -= (0xFF + 1); break; | ||||
| 				case 2: Vnum = (Vnum & 0xFFFF); if(sign && (Vnum >  0x7FFF)) Vnum -= (0xFFFF + 1); break; | ||||
| 				case 4: Vnum = sign ? (Vnum | 0) : (Vnum >>> 0); break; | ||||
| 				default: Vnum = isNaN(Vnum) ? 0 : Math.round(Vnum); break; | ||||
| 			} | ||||
| 
 | ||||
| 			/* generate string */ | ||||
| 			if(bytes > 4 && Vnum < 0 && !sign) { | ||||
| 				if(radix == 16 || radix == -16) { | ||||
| 					O = (Vnum>>>0).toString(16); | ||||
| 					Vnum = Math.floor((Vnum - (Vnum >>> 0)) / Math.pow(2,32)); | ||||
| 					O = (Vnum>>>0).toString(16) + (8 - O.length >= 0 ? padstr[ "0"].substr(0,8 - O.length) : "") + O; | ||||
| 					O = (16 - O.length >= 0 ? padstr[ "f"].substr(0,16 - O.length) : "") + O; | ||||
| 					if(radix == 16) O = O.toUpperCase(); | ||||
| 				} else if(radix == 8) { | ||||
| 					O = (Vnum>>>0).toString(8); | ||||
| 					O = (10 - O.length >= 0 ? padstr[ "0"].substr(0,10 - O.length) : "") + O; | ||||
| 					Vnum = Math.floor((Vnum - ((Vnum >>> 0)&0x3FFFFFFF)) / Math.pow(2,30)); | ||||
| 					O = (Vnum>>>0).toString(8) + O.substr(O.length - 10); | ||||
| 					O = O.substr(O.length - 20); | ||||
| 					O = "1" + (21 - O.length >= 0 ? padstr[ "7"].substr(0,21 - O.length) : "") + O; | ||||
| 				} else { | ||||
| 					Vnum = (-Vnum) % 1e16; | ||||
| 					var d1/*:Array<number>*/ = [1,8,4,4,6,7,4,4,0,7,3,7,0,9,5,5,1,6,1,6]; | ||||
| 					var di/*:number*/ = d1.length - 1; | ||||
| 					while(Vnum > 0) { | ||||
| 						if((d1[di] -= (Vnum % 10)) < 0) { d1[di] += 10; d1[di-1]--; } | ||||
| 						--di; Vnum = Math.floor(Vnum / 10); | ||||
| 					} | ||||
| 					O = d1.join(""); | ||||
| 				} | ||||
| 			} else { | ||||
| 				if(radix === -16) O = Vnum.toString(16).toLowerCase(); | ||||
| 				else if(radix === 16) O = Vnum.toString(16).toUpperCase(); | ||||
| 				else O = Vnum.toString(radix); | ||||
| 			} | ||||
| 
 | ||||
| 			/* apply precision */ | ||||
| 			if(prec ===0 && O == "0" && !(radix == 8 && alt)) O = ""; /* bail out */ | ||||
| 			else { | ||||
| 				if(O.length < prec + (O.substr(0,1) == "-" ? 1 : 0)) { | ||||
| 					if(O.substr(0,1) != "-") O = (prec - O.length >= 0 ? padstr[ "0"].substr(0,prec - O.length) : "") + O; | ||||
| 					else O = O.substr(0,1) + (prec + 1 - O.length >= 0 ? padstr[ "0"].substr(0,prec + 1 - O.length) : "") + O.substr(1); | ||||
| 				} | ||||
| 
 | ||||
| 				/* add prefix for # form */ | ||||
| 				if(!sign && alt && Vnum !== 0) switch(radix) { | ||||
| 					case -16: O = "0x" + O; break; | ||||
| 					case  16: O = "0X" + O; break; | ||||
| 					case   8: if(O.charAt(0) != "0") O =  "0" + O; break; | ||||
| 					case   2: O = "0b" + O; break; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			/* add sign character */ | ||||
| 			if(sign && O.charAt(0) != "-") { | ||||
| 				if(flags.indexOf("+") > -1) O = "+" + O; | ||||
| 				else if(flags.indexOf(" ") > -1) O = " " + O; | ||||
| 			} | ||||
| 			/* width */ | ||||
| 			if(width > 0) { | ||||
| 				if(O.length < width) { | ||||
| 					if(flags.indexOf("-") > -1) { | ||||
| 						O = O + ((width - O.length) >= 0 ? padstr[ " "].substr(0,(width - O.length)) : ""); | ||||
| 					} else if(flags.indexOf("0") > -1 && prec < 0 && O.length > 0) { | ||||
| 						if(prec > O.length) O = ((prec - O.length) >= 0 ? padstr[ "0"].substr(0,(prec - O.length)) : "") + O; | ||||
| 						pad = ((width - O.length) >= 0 ? padstr[ (prec > 0 ? " " : "0")].substr(0,(width - O.length)) : ""); | ||||
| 						if(O.charCodeAt(0) < 48) { | ||||
| 							if(O.charAt(2).toLowerCase() == "x") O = O.substr(0,3) + pad + O.substring(3); | ||||
| 							else O = O.substr(0,1) + pad + O.substring(1); | ||||
| 						} | ||||
| 						else if(O.charAt(1).toLowerCase() == "x") O = O.substr(0,2) + pad + O.substring(2); | ||||
| 						else O = pad + O; | ||||
| 					} else { | ||||
| 						O = ((width - O.length) >= 0 ? padstr[ " "].substr(0,(width - O.length)) : "") + O; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 		} else if(isnum > 0) { | ||||
| 
 | ||||
| 			Vnum = Number(arg); | ||||
| 			if(arg === null) Vnum = 0/0; | ||||
| 			if(len == "L") bytes = 12; | ||||
| 			var isf/*:boolean*/ = isFinite(Vnum); | ||||
| 			if(!isf) { /* Infinity or NaN */ | ||||
| 				if(Vnum < 0) O = "-"; | ||||
| 				else if(flags.indexOf("+") > -1) O = "+"; | ||||
| 				else if(flags.indexOf(" ") > -1) O = " "; | ||||
| 				O += (isNaN(Vnum)) ? "nan" : "inf"; | ||||
| 			} else { | ||||
| 				var E/*:number*/ = 0; | ||||
| 
 | ||||
| 				if(prec == -1 && isnum != 4) prec = 6; | ||||
| 
 | ||||
| 				/* g/G conditional behavior */ | ||||
| 				if(isnum == 3) { | ||||
| 					O = Vnum.toExponential(1); | ||||
| 					E = +O.substr(O.indexOf("e") + 1); | ||||
| 					if(prec === 0) prec = 1; | ||||
| 					if(prec > E && E >= -4) { isnum = (11); prec = prec -(E + 1); } | ||||
| 					else { isnum = (12); prec = prec - 1; } | ||||
| 				} | ||||
| 
 | ||||
| 				/* sign: workaround for negative zero */ | ||||
| 				var sg/*:string*/ = (Vnum < 0 || 1/Vnum == -Infinity) ? "-" : ""; | ||||
| 				if(Vnum < 0) Vnum = -Vnum; | ||||
| 
 | ||||
| 				switch(isnum) { | ||||
| 					/* f/F standard */ | ||||
| 					case 1: case 11: | ||||
| 						if(Vnum < 1e21) { | ||||
| 							O = Vnum.toFixed(prec); | ||||
| 							if(isnum == 1) { if(prec===0 &&alt&& O.indexOf(".")==-1) O+="."; } | ||||
| 							else if(!alt) O=O.replace(/(\.\d*[1-9])0*$/,"$1").replace(/\.0*$/,""); | ||||
| 							else if(O.indexOf(".") == -1) O+= "."; | ||||
| 							break; | ||||
| 						} | ||||
| 						O = Vnum.toExponential(20); | ||||
| 						E = +O.substr(O.indexOf("e")+1); | ||||
| 						O = O.charAt(0) + O.substr(2,O.indexOf("e")-2); | ||||
| 						O = O + (E - O.length + 1 >= 0 ? padstr[ "0"].substr(0,E - O.length + 1) : ""); | ||||
| 						if(alt || (prec > 0 && isnum !== 11)) O = O + "." + (prec >= 0 ? padstr[ "0"].substr(0,prec) : ""); | ||||
| 						break; | ||||
| 
 | ||||
| 					/* e/E exponential */ | ||||
| 					case 2: case 12: | ||||
| 						O = Vnum.toExponential(prec); | ||||
| 						E = O.indexOf("e"); | ||||
| 						if(O.length - E === 3) O = O.substr(0, E+2) + "0" + O.substr(E+2); | ||||
| 						if(alt && O.indexOf(".") == -1) O = O.substr(0,E) +"."+ O.substr(E); | ||||
| 						else if(!alt && isnum == 12) O = O.replace(/\.0*e/, "e").replace(/\.(\d*[1-9])0*e/, ".$1e"); | ||||
| 						break; | ||||
| 
 | ||||
| 					/* a/A hex */ | ||||
| 					case 4: | ||||
| 						if(Vnum===0){O= "0x0"+((alt||prec>0)?"."+(prec >= 0 ? padstr["0"].substr(0,prec) : ""):"")+"p+0"; break;} | ||||
| 						O = Vnum.toString(16); | ||||
| 						/* First char 0-9 */ | ||||
| 						var ac/*:number*/ = O.charCodeAt(0); | ||||
| 						if(ac == 48) { | ||||
| 							ac = 2; E = -4; Vnum *= 16; | ||||
| 							while(O.charCodeAt(ac++) == 48) { E -= 4; Vnum *= 16; } | ||||
| 							O = Vnum.toString(16); | ||||
| 							ac = O.charCodeAt(0); | ||||
| 						} | ||||
| 
 | ||||
| 						var ai/*:number*/ = O.indexOf("."); | ||||
| 						if(O.indexOf("(") > -1) { | ||||
| 							/* IE exponential form */ | ||||
| 							var am/*:?Array<any>*/ = O.match(/\(e(.*)\)/); | ||||
| 							var ae/*:number*/ = am ? (+am[1]) : 0; | ||||
| 							E += 4 * ae; Vnum /= Math.pow(16, ae); | ||||
| 						} else if(ai > 1) { | ||||
| 							E += 4 * (ai - 1); Vnum /= Math.pow(16, ai - 1); | ||||
| 						} else if(ai == -1) { | ||||
| 							E += 4 * (O.length - 1); Vnum /= Math.pow(16, O.length - 1); | ||||
| 						} | ||||
| 
 | ||||
| 						/* at this point 1 <= Vnum < 16 */ | ||||
| 
 | ||||
| 						if(bytes > 8) { | ||||
| 							if(ac < 50) { E -= 3; Vnum *= 8; } | ||||
| 							else if(ac < 52) { E -= 2; Vnum *= 4; } | ||||
| 							else if(ac < 56) { E -= 1; Vnum *= 2; } | ||||
| 							/* at this point 8 <= Vnum < 16 */ | ||||
| 						} else { | ||||
| 							if(ac >= 56) { E += 3; Vnum /= 8; } | ||||
| 							else if(ac >= 52) { E += 2; Vnum /= 4; } | ||||
| 							else if(ac >= 50) { E += 1; Vnum /= 2; } | ||||
| 							/* at this point 1 <= Vnum < 2 */ | ||||
| 						} | ||||
| 
 | ||||
| 						O = Vnum.toString(16); | ||||
| 						if(O.length > 1) { | ||||
| 							if(O.length > prec+2 && O.charCodeAt(prec+2) >= 56) { | ||||
| 								var _f/*:boolean*/ = O.charCodeAt(0) == 102; | ||||
| 								O = (Vnum + 8 * Math.pow(16, -prec-1)).toString(16); | ||||
| 								if(_f && O.charCodeAt(0) == 49) E += 4; | ||||
| 							} | ||||
| 							if(prec > 0) { | ||||
| 								O = O.substr(0, prec + 2); | ||||
| 								if(O.length < prec + 2) { | ||||
| 									if(O.charCodeAt(0) < 48) O = O.charAt(0) + ((prec + 2 - O.length) >= 0 ? padstr[ "0"].substr(0,(prec + 2 - O.length)) : "") + O.substr(1); | ||||
| 									else O += ((prec + 2 - O.length) >= 0 ? padstr[ "0"].substr(0,(prec + 2 - O.length)) : ""); | ||||
| 								} | ||||
| 							} else if(prec === 0) O = O.charAt(0) + (alt ? "." : ""); | ||||
| 						} else if(prec > 0) O = O + "." + (prec >= 0 ? padstr["0"].substr(0,prec) : ""); | ||||
| 						else if(alt) O = O + "."; | ||||
| 						O = "0x" + O + "p" + (E>=0 ? "+" + E : E); | ||||
| 						break; | ||||
| 				} | ||||
| 
 | ||||
| 				if(sg === "") { | ||||
| 					if(flags.indexOf("+") > -1) sg = "+"; | ||||
| 					else if(flags.indexOf(" ") > -1) sg = " "; | ||||
| 				} | ||||
| 
 | ||||
| 				O = sg + O; | ||||
| 			} | ||||
| 
 | ||||
| 			/* width */ | ||||
| 			if(width > O.length) { | ||||
| 				if(flags.indexOf("-") > -1) { | ||||
| 					O = O + ((width - O.length) >= 0 ? padstr[ " "].substr(0,(width - O.length)) : ""); | ||||
| 				} else if(flags.indexOf("0") > -1 && O.length > 0 && isf) { | ||||
| 					pad = ((width - O.length) >= 0 ? padstr[ "0"].substr(0,(width - O.length)) : ""); | ||||
| 					if(O.charCodeAt(0) < 48) { | ||||
| 						if(O.charAt(2).toLowerCase() == "x") O = O.substr(0,3) + pad + O.substring(3); | ||||
| 						else O = O.substr(0,1) + pad + O.substring(1); | ||||
| 					} | ||||
| 					else if(O.charAt(1).toLowerCase() == "x") O = O.substr(0,2) + pad + O.substring(2); | ||||
| 					else O = pad + O; | ||||
| 				} else { | ||||
| 					O = ((width - O.length) >= 0 ? padstr[ " "].substr(0,(width - O.length)) : "") + O; | ||||
| 				} | ||||
| 			} | ||||
| 			if(c < 96) O = O.toUpperCase(); | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		o.push(O); | ||||
| 	} | ||||
| 	return o.join(""); | ||||
| } | ||||
| 
 | ||||
| function vsprintf(fmt/*:string*/, args/*:Args*/)/*:string*/ { return doit(tokenize(fmt), args); } | ||||
| 
 | ||||
| function sprintf(/*:: ...argz*/)/*:string*/ { | ||||
| 	var args/*:Array<any>*/ = new Array(arguments.length - 1); | ||||
| 	for(var i/*:number*/ = 0; i < args.length; ++i) args[i] = arguments[i+1]; | ||||
| 	return doit(tokenize(arguments[0]), args); | ||||
| } | ||||
| 
 | ||||
| export { sprintf, vsprintf }; | ||||
| 
 | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
| 	"name": "printj", | ||||
| 	"version": "1.1.2", | ||||
| 	"version": "1.2.0", | ||||
| 	"author": "sheetjs", | ||||
| 	"description": "Pure-JS printf", | ||||
| 	"keywords": [ | ||||
| @ -49,7 +49,7 @@ | ||||
| 		] | ||||
| 	}, | ||||
| 	"homepage": "http://sheetjs.com/opensource", | ||||
| 	"files": ["printj.js", "bin/printj.njs", "LICENSE", "README.md", "dist/*.js", "dist/*.map", "dist/LICENSE", "types/index.d.ts", "types/*.json"], | ||||
| 	"files": ["printj.js", "printj.mjs", "bin/printj.njs", "LICENSE", "README.md", "dist/*.js", "dist/*.map", "dist/LICENSE", "types/index.d.ts", "types/*.json"], | ||||
| 	"bugs": { | ||||
| 		"url": "https://github.com/SheetJS/printj/issues" | ||||
| 	}, | ||||
|  | ||||
| @ -4,6 +4,7 @@ | ||||
| /*exported PRINTJ */ | ||||
| /*:: declare var DO_NOT_EXPORT_PRINTJ:?boolean; */ | ||||
| /*:: declare function define(cb:()=>any):void; */ | ||||
| 
 | ||||
| var PRINTJ/*:PRINTJModule*/; | ||||
| (function (factory/*:(a:any)=>void*/)/*:void*/ { | ||||
| 	/*jshint ignore:start */ | ||||
| @ -27,7 +28,7 @@ var PRINTJ/*:PRINTJModule*/; | ||||
| 	/*jshint ignore:end */ | ||||
| }(function(PRINTJ/*:PRINTJModule*/) { | ||||
| 
 | ||||
| PRINTJ.version = '1.1.2'; | ||||
| PRINTJ.version = '1.2.0'; | ||||
| 
 | ||||
| function tokenize(fmt/*:string*/)/*:ParsedFmt*/ { | ||||
| 	var out/*:ParsedFmt*/ = []; | ||||
| @ -311,7 +312,7 @@ function doit(t/*:ParsedFmt*/, args/*:Array<any>*/)/*:string*/ { | ||||
| 			/* 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(); | ||||
| 				if( prec >= 0) O = O.substr(0,  prec); | ||||
| 				if( width > O.length || - width > O.length) { if(( flags.indexOf("-") == -1 ||  width < 0) &&  flags.indexOf("0") != -1) { pad = ( width - O.length >= 0 ? padstr["0"].substr(0, width - O.length) : ""); O = pad + O; } else { pad = ( width - O.length >= 0 ? padstr[" "].substr(0, width - O.length) : ""); O =  flags.indexOf("-") > -1 ? O + pad : pad + O; } } | ||||
|  | ||||
| @ -25,7 +25,7 @@ var PRINTJ; | ||||
| 	/*jshint ignore:end */ | ||||
| }(function(PRINTJ) { | ||||
| 
 | ||||
| PRINTJ.version = '1.1.2'; | ||||
| PRINTJ.version = '1.2.0'; | ||||
| 
 | ||||
| function tokenize(fmt) { | ||||
| 	var out = []; | ||||
| @ -308,7 +308,7 @@ function doit(t, args) { | ||||
| 			/* 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(); | ||||
| 				if( prec >= 0) O = O.substr(0,  prec); | ||||
| 				if( width > O.length || - width > O.length) { if(( flags.indexOf("-") == -1 ||  width < 0) &&  flags.indexOf("0") != -1) { pad = ( width - O.length >= 0 ? padstr["0"].substr(0, width - O.length) : ""); O = pad + O; } else { pad = ( width - O.length >= 0 ? padstr[" "].substr(0, width - O.length) : ""); O =  flags.indexOf("-") > -1 ? O + pad : pad + O; } } | ||||
|  | ||||
							
								
								
									
										582
									
								
								printj.mjs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										582
									
								
								printj.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,582 @@ | ||||
| /* printj.js (C) 2016-present SheetJS -- http://sheetjs.com */ | ||||
| /* vim: set ts=2: */ | ||||
| /*jshint sub:true, eqnull:true */ | ||||
| /*exported PRINTJ */ | ||||
| /*:: declare var DO_NOT_EXPORT_PRINTJ:?boolean; */ | ||||
| /*:: declare function define(cb:()=>any):void; */ | ||||
| 
 | ||||
| var PRINTJ/*:PRINTJModule*/ = /*::(*/{}/*:: :any)*/; | ||||
| 
 | ||||
| PRINTJ.version = '1.2.0'; | ||||
| 
 | ||||
| export const version = PRINTJ.version; | ||||
| 
 | ||||
| function tokenize(fmt/*:string*/)/*:ParsedFmt*/ { | ||||
| 	var out/*:ParsedFmt*/ = []; | ||||
| 	var start/*:number*/ = 0; | ||||
| 
 | ||||
| 	var i/*:number*/ = 0; | ||||
| 	var infmt/*:boolean*/ = false; | ||||
| 	var fmtparam/*:string*/ = "", fmtflags/*:string*/ = "", fmtwidth/*:string*/ = "", fmtprec/*:string*/ = "", fmtlen/*:string*/ = ""; | ||||
| 
 | ||||
| 	var c/*:number*/ = 0; | ||||
| 
 | ||||
| 	var L/*:number*/ = fmt.length; | ||||
| 
 | ||||
| 	for(; i < L; ++i) { | ||||
| 		c = fmt.charCodeAt(i); | ||||
| 		if(!infmt) { | ||||
| 
 | ||||
| 			if(c !== 37) continue; | ||||
| 
 | ||||
| 			if(start < i) out.push(["L", fmt.substring(start, i)]); | ||||
| 			start = i; | ||||
| 			infmt = true; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if(c >= 48 && c < 58)	{ | ||||
| 				if(fmtprec.length) fmtprec += String.fromCharCode(c); | ||||
| 				else if(c == 48 && !fmtwidth.length) fmtflags += String.fromCharCode(c); | ||||
| 				else fmtwidth += String.fromCharCode(c); | ||||
| 		} else switch(c) { | ||||
| 			/* positional */ | ||||
| 			case 36: | ||||
| 				if(fmtprec.length) fmtprec += "$"; | ||||
| 				else if(fmtwidth.charAt(0) == "*") fmtwidth += "$"; | ||||
| 				else { fmtparam = fmtwidth + "$"; fmtwidth = ""; } | ||||
| 				break; | ||||
| 
 | ||||
| 			/* flags */ | ||||
| 			case 39: fmtflags += "'"; break; | ||||
| 			case 45: fmtflags += "-"; break; | ||||
| 			case 43: fmtflags += "+"; break; | ||||
| 			case 32: fmtflags += " "; break; | ||||
| 			case 35: fmtflags += "#"; break; | ||||
| 
 | ||||
| 			/* width and precision */ | ||||
| 			case 46: fmtprec = "."; break; | ||||
| 			case 42: | ||||
| 				if(fmtprec.charAt(0) == ".") fmtprec += "*"; | ||||
| 				else fmtwidth += "*"; | ||||
| 				break; | ||||
| 
 | ||||
| 			/* length */ | ||||
| 			case 104: | ||||
| 			case 108: | ||||
| 				if(fmtlen.length > 1) throw "bad length " + fmtlen + String(c); | ||||
| 				fmtlen += String.fromCharCode(c); | ||||
| 				break; | ||||
| 
 | ||||
| 			case  76: | ||||
| 			case 106: | ||||
| 			case 122: | ||||
| 			case 116: | ||||
| 			case 113: | ||||
| 			case  90: | ||||
| 			case 119: | ||||
| 				if(fmtlen !== "") throw "bad length " + fmtlen + String.fromCharCode(c); | ||||
| 				fmtlen = String.fromCharCode(c); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 73: | ||||
| 				if(fmtlen !== "") throw "bad length " + fmtlen + 'I'; | ||||
| 				fmtlen = 'I'; | ||||
| 				break; | ||||
| 
 | ||||
| 			/* conversion */ | ||||
| 			case 100: | ||||
| 			case 105: | ||||
| 			case 111: | ||||
| 			case 117: | ||||
| 			case 120: | ||||
| 			case 88: | ||||
| 			case 102: | ||||
| 			case 70: | ||||
| 			case 101: | ||||
| 			case 69: | ||||
| 			case 103: | ||||
| 			case 71: | ||||
| 			case 97: | ||||
| 			case 65: | ||||
| 			case 99: | ||||
| 			case 67: | ||||
| 			case 115: | ||||
| 			case 83: | ||||
| 			case 112: | ||||
| 			case 110: | ||||
| 			case 68: | ||||
| 			case 85: | ||||
| 			case 79: | ||||
| 			case 109: | ||||
| 			case 98: | ||||
| 			case 66: | ||||
| 			case 121: | ||||
| 			case 89: | ||||
| 			case 74: | ||||
| 			case 86: | ||||
| 			case 84: | ||||
| 			case 37: | ||||
| 				infmt = false; | ||||
| 				if(fmtprec.length > 1) fmtprec = fmtprec.substr(1); | ||||
| 				out.push([String.fromCharCode(c), fmt.substring(start, i+1), fmtparam, fmtflags, fmtwidth, fmtprec, fmtlen]); | ||||
| 				start = i+1; | ||||
| 				fmtlen = fmtprec = fmtwidth = fmtflags = fmtparam = ""; | ||||
| 				break; | ||||
| 			default: | ||||
| 				throw new Error("Invalid format string starting with |" + fmt.substring(start, i+1) + "|"); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	if(start < fmt.length) out.push(["L", fmt.substring(start)]); | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| //#define PAD_(x,c) (x >= 0 ? new Array(((x)|0) + 1).join((c)) : "")
 | ||||
| var padstr/*:{[s:string]:string}*/ = { | ||||
| 	" ": "                                 ", | ||||
| 	"0": "000000000000000000000000000000000", | ||||
| 	"7": "777777777777777777777777777777777", | ||||
| 	"f": "fffffffffffffffffffffffffffffffff" | ||||
| }; | ||||
| 
 | ||||
| var u_inspect/*:(o:any)=>string*/ = JSON.stringify; | ||||
| 
 | ||||
| function doit(t/*:ParsedFmt*/, args/*:Array<any>*/)/*:string*/ { | ||||
| 	var o/*:Array<string>*/ = []; | ||||
| 	var argidx/*:number*/ = 0, idx/*:number*/ = 0; | ||||
| 	var Vnum/*:number*/ = 0; | ||||
| 	var pad/*:string*/ = ""; | ||||
| 	for(var i/*:number*/ = 0; i < t.length; ++i) { | ||||
| 		var m/*:ParsedEntry*/ = t[i], c/*:number*/ = (m[0]/*:string*/).charCodeAt(0); | ||||
| 		/* m order: conv full param flags width prec length */ | ||||
| 
 | ||||
| 		if(c === /*L*/ 76) { o.push(m[1]); continue; } | ||||
| 		if(c === /*%*/ 37) { o.push("%"); continue; } | ||||
| 
 | ||||
| 		var O/*:string*/ = ""; | ||||
| 		var isnum/*:number*/ = 0, radix/*:number*/ = 10, bytes/*:number*/ = 4, sign/*:boolean*/ = false; | ||||
| 
 | ||||
| 		/* flags */ | ||||
| 		var flags/*:string*/ = m[3]||""; | ||||
| 		var alt/*:boolean*/ = flags.indexOf("#") > -1; | ||||
| 
 | ||||
| 		/* position */ | ||||
| 		if(m[2]) argidx = parseInt(m[2])-1; | ||||
| 		/* %m special case */ | ||||
| 		else if(c === /*m*/ 109 && !alt) { o.push("Success"); continue; } | ||||
| 
 | ||||
| 		/* grab width */ | ||||
| 		var width =  0; if(m[ 4] != null && m[ 4].length > 0) { if(m[ 4].charAt(0) !== '*') width = parseInt(m[ 4], 10); else if(m[ 4].length === 1) width = args[idx++]; else width = args[parseInt(m[ 4].substr(1), 10)-1]; } | ||||
| 
 | ||||
| 		/* grab precision */ | ||||
| 		var prec =  -1; if(m[ 5] != null && m[ 5].length > 0) { if(m[ 5].charAt(0) !== '*') prec = parseInt(m[ 5], 10); else if(m[ 5].length === 1) prec = args[idx++]; else prec = args[parseInt(m[ 5].substr(1), 10)-1]; } | ||||
| 
 | ||||
| 		/* position not specified */ | ||||
| 		if(!m[2]) argidx = idx++; | ||||
| 
 | ||||
| 		/* grab argument */ | ||||
| 		var arg/*:any*/ = args[argidx]; | ||||
| 
 | ||||
| 		/* grab length */ | ||||
| 		var len/*:string*/ = m[6] || ""; | ||||
| 
 | ||||
| 		switch(c) { | ||||
| 			/* str cCsS */ | ||||
| 
 | ||||
| 			case /*S*/  83: | ||||
| 			case /*s*/ 115: | ||||
| 				/* only valid flag is "-" for left justification */ | ||||
| 				O = String(arg); | ||||
| 				if( prec >= 0) O = O.substr(0,  prec); | ||||
| 				if( width > O.length || - width > O.length) { if(( flags.indexOf("-") == -1 ||  width < 0) &&  flags.indexOf("0") != -1) { pad = ( width - O.length >= 0 ? padstr["0"].substr(0, width - O.length) : ""); O = pad + O; } else { pad = ( width - O.length >= 0 ? padstr[" "].substr(0, width - O.length) : ""); O =  flags.indexOf("-") > -1 ? O + pad : pad + O; } } | ||||
| 				break; | ||||
| 
 | ||||
| 			/* first char of string or convert */ | ||||
| 			case /*C*/  67: | ||||
| 			case /*c*/  99: | ||||
| 				switch(typeof arg) { | ||||
| 					case "number": | ||||
| 						var cc/*:number*/ = arg; | ||||
| 						if(c == 67 || len.charCodeAt(0) === /*l*/ 108) {  cc &= 0xFFFFFFFF; O = String.fromCharCode( cc); } | ||||
| 						else {  cc &= 0xFF; O = String.fromCharCode( cc); } | ||||
| 						break; | ||||
| 					case "string": O = /*::(*/arg/*:: :string)*/.charAt(0); break; | ||||
| 					default: O = String(arg).charAt(0); | ||||
| 				} | ||||
| 				if( width > O.length || - width > O.length) { if(( flags.indexOf("-") == -1 ||  width < 0) &&  flags.indexOf("0") != -1) { pad = ( width - O.length >= 0 ? padstr["0"].substr(0, width - O.length) : ""); O = pad + O; } else { pad = ( width - O.length >= 0 ? padstr[" "].substr(0, width - O.length) : ""); O =  flags.indexOf("-") > -1 ? O + pad : pad + O; } } | ||||
| 				break; | ||||
| 
 | ||||
| 			/* int diDuUoOxXbB */ | ||||
| 
 | ||||
| 			/* signed integer */ | ||||
| 			case /*D*/  68: bytes = 8; | ||||
| 			/* falls through */ | ||||
| 			case /*d*/ 100: | ||||
| 			case /*i*/ 105: isnum = -1; sign = true; break; | ||||
| 
 | ||||
| 			/* unsigned integer */ | ||||
| 			case /*U*/  85: bytes = 8; | ||||
| 			/* falls through */ | ||||
| 			case /*u*/ 117: isnum = -1; break; | ||||
| 
 | ||||
| 			/* unsigned octal */ | ||||
| 			case /*O*/  79: bytes = 8; | ||||
| 			/* falls through */ | ||||
| 			case /*o*/ 111: isnum = -1; radix = (8); break; | ||||
| 
 | ||||
| 			/* unsigned hex */ | ||||
| 			case /*x*/ 120: isnum = -1; radix = (-16); break; | ||||
| 			case /*X*/  88: isnum = -1; radix = (16); break; | ||||
| 
 | ||||
| 			/* unsigned binary (extension) */ | ||||
| 			case /*B*/  66: bytes = 8; | ||||
| 			/* falls through */ | ||||
| 			case /*b*/  98: isnum = -1; radix = (2); break; | ||||
| 
 | ||||
| 			/* flt fegFEGaA */ | ||||
| 
 | ||||
| 			/* floating point logic */ | ||||
| 			case /*F*/  70: | ||||
| 			case /*f*/ 102: isnum = (1); break; | ||||
| 
 | ||||
| 			case /*E*/  69: | ||||
| 			case /*e*/ 101: isnum = (2); break; | ||||
| 
 | ||||
| 			case /*G*/  71: | ||||
| 			case /*g*/ 103: isnum = (3); break; | ||||
| 
 | ||||
| 			/* floating hex */ | ||||
| 			case /*A*/  65: | ||||
| 			case /*a*/  97: isnum = (4); break; | ||||
| 
 | ||||
| 			/* misc pnmJVTyY */ | ||||
| 
 | ||||
| 			/* JS has no concept of pointers so interpret the `l` key as an address */ | ||||
| 			case /*p*/ 112: | ||||
| 				Vnum = typeof arg == "number" ? arg : arg ? Number(arg.l) : -1; | ||||
| 				if(isNaN(Vnum)) Vnum = -1; | ||||
| 				if(alt) O = Vnum.toString(10); | ||||
| 				else { | ||||
| 					Vnum = Math.abs(Vnum); | ||||
| 					O = "0x" + Vnum.toString(16).toLowerCase(); | ||||
| 				} | ||||
| 				break; | ||||
| 
 | ||||
| 			/* store length in the `len` key */ | ||||
| 			case /*n*/ 110: | ||||
| 				if(arg) { arg.len=0; for(var oo/*:number*/ = 0; oo < o.length; ++oo) arg.len += o[oo].length; } | ||||
| 				continue; | ||||
| 
 | ||||
| 			/* process error */ | ||||
| 			case /*m*/ 109: | ||||
| 				if(!(arg instanceof Error)) O = "Success"; | ||||
| 				else if(arg.message) O = arg.message; | ||||
| 				else if(arg.errno) O = "Error number " + arg.errno; | ||||
| 				else O = "Error " + String(arg); | ||||
| 				break; | ||||
| 
 | ||||
| 			/* JS-specific conversions (extension) */ | ||||
| 			case /*J*/  74: O = (alt ? u_inspect : JSON.stringify)(arg); break; | ||||
| 			case /*V*/  86: O = arg == null ? "null" : String(arg.valueOf()); break; | ||||
| 			case /*T*/  84: | ||||
| 				if(alt) { /* from '[object %s]' extract %s */ | ||||
| 					O = Object.prototype.toString.call(arg).substr(8); | ||||
| 					O = O.substr(0, O.length - 1); | ||||
| 				} else O = typeof arg; | ||||
| 				break; | ||||
| 
 | ||||
| 			/* boolean (extension) */ | ||||
| 			case /*Y*/  89: | ||||
| 			case /*y*/ 121: | ||||
| 				O = (arg) ? (alt ? "yes" : "true") : (alt ? "no" : "false"); | ||||
| 				if(c == /*Y*/ 89) O = O.toUpperCase(); | ||||
| 				if( prec >= 0) O = O.substr(0,  prec); | ||||
| 				if( width > O.length || - width > O.length) { if(( flags.indexOf("-") == -1 ||  width < 0) &&  flags.indexOf("0") != -1) { pad = ( width - O.length >= 0 ? padstr["0"].substr(0, width - O.length) : ""); O = pad + O; } else { pad = ( width - O.length >= 0 ? padstr[" "].substr(0, width - O.length) : ""); O =  flags.indexOf("-") > -1 ? O + pad : pad + O; } } | ||||
| 				break; | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		if(width < 0) { width = -width; flags += "-"; } | ||||
| 
 | ||||
| 		if(isnum == -1) { | ||||
| 
 | ||||
| 			Vnum = Number(arg); | ||||
| 
 | ||||
| 			/* parse byte length field */ | ||||
| 
 | ||||
| 			switch(len) { | ||||
| 				/* char */ | ||||
| 				case "hh": { bytes = 1; } break; | ||||
| 				/* short */ | ||||
| 				case "h":  { bytes = 2; } break; | ||||
| 
 | ||||
| 				/* long */ | ||||
| 				case "l":  { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* long long */ | ||||
| 				case "L": | ||||
| 				case "q": | ||||
| 				case "ll": { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* intmax_t */ | ||||
| 				case "j":  { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* ptrdiff_t */ | ||||
| 				case "t":  { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* size_t */ | ||||
| 				case "z": | ||||
| 				case "Z":  { if(bytes == 4) bytes = 8; } break; | ||||
| 
 | ||||
| 				/* CRT size_t or ptrdiff_t */ | ||||
| 				case "I": | ||||
| 
 | ||||
| 					{ if(bytes == 4) bytes = 8; } | ||||
| 
 | ||||
| 					break; | ||||
| 
 | ||||
| 				/* CRT wchar_t */ | ||||
| 				case "w": break; | ||||
| 			} | ||||
| 
 | ||||
| 			/* restrict value */ | ||||
| 
 | ||||
| 			switch(bytes) { | ||||
| 				case 1: Vnum = (Vnum & 0xFF); if(sign && (Vnum >  0x7F)) Vnum -= (0xFF + 1); break; | ||||
| 				case 2: Vnum = (Vnum & 0xFFFF); if(sign && (Vnum >  0x7FFF)) Vnum -= (0xFFFF + 1); break; | ||||
| 				case 4: Vnum = sign ? (Vnum | 0) : (Vnum >>> 0); break; | ||||
| 				default: Vnum = isNaN(Vnum) ? 0 : Math.round(Vnum); break; | ||||
| 			} | ||||
| 
 | ||||
| 			/* generate string */ | ||||
| 			if(bytes > 4 && Vnum < 0 && !sign) { | ||||
| 				if(radix == 16 || radix == -16) { | ||||
| 					O = (Vnum>>>0).toString(16); | ||||
| 					Vnum = Math.floor((Vnum - (Vnum >>> 0)) / Math.pow(2,32)); | ||||
| 					O = (Vnum>>>0).toString(16) + (8 - O.length >= 0 ? padstr[ "0"].substr(0,8 - O.length) : "") + O; | ||||
| 					O = (16 - O.length >= 0 ? padstr[ "f"].substr(0,16 - O.length) : "") + O; | ||||
| 					if(radix == 16) O = O.toUpperCase(); | ||||
| 				} else if(radix == 8) { | ||||
| 					O = (Vnum>>>0).toString(8); | ||||
| 					O = (10 - O.length >= 0 ? padstr[ "0"].substr(0,10 - O.length) : "") + O; | ||||
| 					Vnum = Math.floor((Vnum - ((Vnum >>> 0)&0x3FFFFFFF)) / Math.pow(2,30)); | ||||
| 					O = (Vnum>>>0).toString(8) + O.substr(O.length - 10); | ||||
| 					O = O.substr(O.length - 20); | ||||
| 					O = "1" + (21 - O.length >= 0 ? padstr[ "7"].substr(0,21 - O.length) : "") + O; | ||||
| 				} else { | ||||
| 					Vnum = (-Vnum) % 1e16; | ||||
| 					var d1/*:Array<number>*/ = [1,8,4,4,6,7,4,4,0,7,3,7,0,9,5,5,1,6,1,6]; | ||||
| 					var di/*:number*/ = d1.length - 1; | ||||
| 					while(Vnum > 0) { | ||||
| 						if((d1[di] -= (Vnum % 10)) < 0) { d1[di] += 10; d1[di-1]--; } | ||||
| 						--di; Vnum = Math.floor(Vnum / 10); | ||||
| 					} | ||||
| 					O = d1.join(""); | ||||
| 				} | ||||
| 			} else { | ||||
| 				if(radix === -16) O = Vnum.toString(16).toLowerCase(); | ||||
| 				else if(radix === 16) O = Vnum.toString(16).toUpperCase(); | ||||
| 				else O = Vnum.toString(radix); | ||||
| 			} | ||||
| 
 | ||||
| 			/* apply precision */ | ||||
| 			if(prec ===0 && O == "0" && !(radix == 8 && alt)) O = ""; /* bail out */ | ||||
| 			else { | ||||
| 				if(O.length < prec + (O.substr(0,1) == "-" ? 1 : 0)) { | ||||
| 					if(O.substr(0,1) != "-") O = (prec - O.length >= 0 ? padstr[ "0"].substr(0,prec - O.length) : "") + O; | ||||
| 					else O = O.substr(0,1) + (prec + 1 - O.length >= 0 ? padstr[ "0"].substr(0,prec + 1 - O.length) : "") + O.substr(1); | ||||
| 				} | ||||
| 
 | ||||
| 				/* add prefix for # form */ | ||||
| 				if(!sign && alt && Vnum !== 0) switch(radix) { | ||||
| 					case -16: O = "0x" + O; break; | ||||
| 					case  16: O = "0X" + O; break; | ||||
| 					case   8: if(O.charAt(0) != "0") O =  "0" + O; break; | ||||
| 					case   2: O = "0b" + O; break; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			/* add sign character */ | ||||
| 			if(sign && O.charAt(0) != "-") { | ||||
| 				if(flags.indexOf("+") > -1) O = "+" + O; | ||||
| 				else if(flags.indexOf(" ") > -1) O = " " + O; | ||||
| 			} | ||||
| 			/* width */ | ||||
| 			if(width > 0) { | ||||
| 				if(O.length < width) { | ||||
| 					if(flags.indexOf("-") > -1) { | ||||
| 						O = O + ((width - O.length) >= 0 ? padstr[ " "].substr(0,(width - O.length)) : ""); | ||||
| 					} else if(flags.indexOf("0") > -1 && prec < 0 && O.length > 0) { | ||||
| 						if(prec > O.length) O = ((prec - O.length) >= 0 ? padstr[ "0"].substr(0,(prec - O.length)) : "") + O; | ||||
| 						pad = ((width - O.length) >= 0 ? padstr[ (prec > 0 ? " " : "0")].substr(0,(width - O.length)) : ""); | ||||
| 						if(O.charCodeAt(0) < 48) { | ||||
| 							if(O.charAt(2).toLowerCase() == "x") O = O.substr(0,3) + pad + O.substring(3); | ||||
| 							else O = O.substr(0,1) + pad + O.substring(1); | ||||
| 						} | ||||
| 						else if(O.charAt(1).toLowerCase() == "x") O = O.substr(0,2) + pad + O.substring(2); | ||||
| 						else O = pad + O; | ||||
| 					} else { | ||||
| 						O = ((width - O.length) >= 0 ? padstr[ " "].substr(0,(width - O.length)) : "") + O; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 		} else if(isnum > 0) { | ||||
| 
 | ||||
| 			Vnum = Number(arg); | ||||
| 			if(arg === null) Vnum = 0/0; | ||||
| 			if(len == "L") bytes = 12; | ||||
| 			var isf/*:boolean*/ = isFinite(Vnum); | ||||
| 			if(!isf) { /* Infinity or NaN */ | ||||
| 				if(Vnum < 0) O = "-"; | ||||
| 				else if(flags.indexOf("+") > -1) O = "+"; | ||||
| 				else if(flags.indexOf(" ") > -1) O = " "; | ||||
| 				O += (isNaN(Vnum)) ? "nan" : "inf"; | ||||
| 			} else { | ||||
| 				var E/*:number*/ = 0; | ||||
| 
 | ||||
| 				if(prec == -1 && isnum != 4) prec = 6; | ||||
| 
 | ||||
| 				/* g/G conditional behavior */ | ||||
| 				if(isnum == 3) { | ||||
| 					O = Vnum.toExponential(1); | ||||
| 					E = +O.substr(O.indexOf("e") + 1); | ||||
| 					if(prec === 0) prec = 1; | ||||
| 					if(prec > E && E >= -4) { isnum = (11); prec = prec -(E + 1); } | ||||
| 					else { isnum = (12); prec = prec - 1; } | ||||
| 				} | ||||
| 
 | ||||
| 				/* sign: workaround for negative zero */ | ||||
| 				var sg/*:string*/ = (Vnum < 0 || 1/Vnum == -Infinity) ? "-" : ""; | ||||
| 				if(Vnum < 0) Vnum = -Vnum; | ||||
| 
 | ||||
| 				switch(isnum) { | ||||
| 					/* f/F standard */ | ||||
| 					case 1: case 11: | ||||
| 						if(Vnum < 1e21) { | ||||
| 							O = Vnum.toFixed(prec); | ||||
| 							if(isnum == 1) { if(prec===0 &&alt&& O.indexOf(".")==-1) O+="."; } | ||||
| 							else if(!alt) O=O.replace(/(\.\d*[1-9])0*$/,"$1").replace(/\.0*$/,""); | ||||
| 							else if(O.indexOf(".") == -1) O+= "."; | ||||
| 							break; | ||||
| 						} | ||||
| 						O = Vnum.toExponential(20); | ||||
| 						E = +O.substr(O.indexOf("e")+1); | ||||
| 						O = O.charAt(0) + O.substr(2,O.indexOf("e")-2); | ||||
| 						O = O + (E - O.length + 1 >= 0 ? padstr[ "0"].substr(0,E - O.length + 1) : ""); | ||||
| 						if(alt || (prec > 0 && isnum !== 11)) O = O + "." + (prec >= 0 ? padstr[ "0"].substr(0,prec) : ""); | ||||
| 						break; | ||||
| 
 | ||||
| 					/* e/E exponential */ | ||||
| 					case 2: case 12: | ||||
| 						O = Vnum.toExponential(prec); | ||||
| 						E = O.indexOf("e"); | ||||
| 						if(O.length - E === 3) O = O.substr(0, E+2) + "0" + O.substr(E+2); | ||||
| 						if(alt && O.indexOf(".") == -1) O = O.substr(0,E) +"."+ O.substr(E); | ||||
| 						else if(!alt && isnum == 12) O = O.replace(/\.0*e/, "e").replace(/\.(\d*[1-9])0*e/, ".$1e"); | ||||
| 						break; | ||||
| 
 | ||||
| 					/* a/A hex */ | ||||
| 					case 4: | ||||
| 						if(Vnum===0){O= "0x0"+((alt||prec>0)?"."+(prec >= 0 ? padstr["0"].substr(0,prec) : ""):"")+"p+0"; break;} | ||||
| 						O = Vnum.toString(16); | ||||
| 						/* First char 0-9 */ | ||||
| 						var ac/*:number*/ = O.charCodeAt(0); | ||||
| 						if(ac == 48) { | ||||
| 							ac = 2; E = -4; Vnum *= 16; | ||||
| 							while(O.charCodeAt(ac++) == 48) { E -= 4; Vnum *= 16; } | ||||
| 							O = Vnum.toString(16); | ||||
| 							ac = O.charCodeAt(0); | ||||
| 						} | ||||
| 
 | ||||
| 						var ai/*:number*/ = O.indexOf("."); | ||||
| 						if(O.indexOf("(") > -1) { | ||||
| 							/* IE exponential form */ | ||||
| 							var am/*:?Array<any>*/ = O.match(/\(e(.*)\)/); | ||||
| 							var ae/*:number*/ = am ? (+am[1]) : 0; | ||||
| 							E += 4 * ae; Vnum /= Math.pow(16, ae); | ||||
| 						} else if(ai > 1) { | ||||
| 							E += 4 * (ai - 1); Vnum /= Math.pow(16, ai - 1); | ||||
| 						} else if(ai == -1) { | ||||
| 							E += 4 * (O.length - 1); Vnum /= Math.pow(16, O.length - 1); | ||||
| 						} | ||||
| 
 | ||||
| 						/* at this point 1 <= Vnum < 16 */ | ||||
| 
 | ||||
| 						if(bytes > 8) { | ||||
| 							if(ac < 50) { E -= 3; Vnum *= 8; } | ||||
| 							else if(ac < 52) { E -= 2; Vnum *= 4; } | ||||
| 							else if(ac < 56) { E -= 1; Vnum *= 2; } | ||||
| 							/* at this point 8 <= Vnum < 16 */ | ||||
| 						} else { | ||||
| 							if(ac >= 56) { E += 3; Vnum /= 8; } | ||||
| 							else if(ac >= 52) { E += 2; Vnum /= 4; } | ||||
| 							else if(ac >= 50) { E += 1; Vnum /= 2; } | ||||
| 							/* at this point 1 <= Vnum < 2 */ | ||||
| 						} | ||||
| 
 | ||||
| 						O = Vnum.toString(16); | ||||
| 						if(O.length > 1) { | ||||
| 							if(O.length > prec+2 && O.charCodeAt(prec+2) >= 56) { | ||||
| 								var _f/*:boolean*/ = O.charCodeAt(0) == 102; | ||||
| 								O = (Vnum + 8 * Math.pow(16, -prec-1)).toString(16); | ||||
| 								if(_f && O.charCodeAt(0) == 49) E += 4; | ||||
| 							} | ||||
| 							if(prec > 0) { | ||||
| 								O = O.substr(0, prec + 2); | ||||
| 								if(O.length < prec + 2) { | ||||
| 									if(O.charCodeAt(0) < 48) O = O.charAt(0) + ((prec + 2 - O.length) >= 0 ? padstr[ "0"].substr(0,(prec + 2 - O.length)) : "") + O.substr(1); | ||||
| 									else O += ((prec + 2 - O.length) >= 0 ? padstr[ "0"].substr(0,(prec + 2 - O.length)) : ""); | ||||
| 								} | ||||
| 							} else if(prec === 0) O = O.charAt(0) + (alt ? "." : ""); | ||||
| 						} else if(prec > 0) O = O + "." + (prec >= 0 ? padstr["0"].substr(0,prec) : ""); | ||||
| 						else if(alt) O = O + "."; | ||||
| 						O = "0x" + O + "p" + (E>=0 ? "+" + E : E); | ||||
| 						break; | ||||
| 				} | ||||
| 
 | ||||
| 				if(sg === "") { | ||||
| 					if(flags.indexOf("+") > -1) sg = "+"; | ||||
| 					else if(flags.indexOf(" ") > -1) sg = " "; | ||||
| 				} | ||||
| 
 | ||||
| 				O = sg + O; | ||||
| 			} | ||||
| 
 | ||||
| 			/* width */ | ||||
| 			if(width > O.length) { | ||||
| 				if(flags.indexOf("-") > -1) { | ||||
| 					O = O + ((width - O.length) >= 0 ? padstr[ " "].substr(0,(width - O.length)) : ""); | ||||
| 				} else if(flags.indexOf("0") > -1 && O.length > 0 && isf) { | ||||
| 					pad = ((width - O.length) >= 0 ? padstr[ "0"].substr(0,(width - O.length)) : ""); | ||||
| 					if(O.charCodeAt(0) < 48) { | ||||
| 						if(O.charAt(2).toLowerCase() == "x") O = O.substr(0,3) + pad + O.substring(3); | ||||
| 						else O = O.substr(0,1) + pad + O.substring(1); | ||||
| 					} | ||||
| 					else if(O.charAt(1).toLowerCase() == "x") O = O.substr(0,2) + pad + O.substring(2); | ||||
| 					else O = pad + O; | ||||
| 				} else { | ||||
| 					O = ((width - O.length) >= 0 ? padstr[ " "].substr(0,(width - O.length)) : "") + O; | ||||
| 				} | ||||
| 			} | ||||
| 			if(c < 96) O = O.toUpperCase(); | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		o.push(O); | ||||
| 	} | ||||
| 	return o.join(""); | ||||
| } | ||||
| 
 | ||||
| function vsprintf(fmt/*:string*/, args/*:Args*/)/*:string*/ { return doit(tokenize(fmt), args); } | ||||
| 
 | ||||
| function sprintf(/*:: ...argz*/)/*:string*/ { | ||||
| 	var args/*:Array<any>*/ = new Array(arguments.length - 1); | ||||
| 	for(var i/*:number*/ = 0; i < args.length; ++i) args[i] = arguments[i+1]; | ||||
| 	return doit(tokenize(arguments[0]), args); | ||||
| } | ||||
| 
 | ||||
| export { sprintf, vsprintf }; | ||||
| 
 | ||||
							
								
								
									
										70
									
								
								tests/mjs.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										70
									
								
								tests/mjs.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| <!DOCTYPE html> | ||||
| <!-- printj.js (C) 2016-present SheetJS http://sheetjs.com --> | ||||
| <!-- vim: set ts=2: --> | ||||
| <html> | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||||
| <title>PRINTJ Live Demo</title> | ||||
| <style> | ||||
| table, td { | ||||
| 	border: 1px dotted black; | ||||
| 	text-align: left; | ||||
| } | ||||
| </style> | ||||
| </head> | ||||
| <body> | ||||
| <b>PRINTJ ESM Live Demo</b><br /> | ||||
| <a href="https://git.io/printj">Source Code Repo</a><br /> | ||||
| <a href="https://git.io/printj_issues">Issues?  Something look weird?  Click here and report an issue</a><br /> | ||||
| <br /> | ||||
| <pre> | ||||
| usage: import { sprintf as printf } from './printj.mjs'; | ||||
| 
 | ||||
| This implementation supports the full POSIX set of conversions.  Consult the enclosed README for full details. | ||||
| </pre> | ||||
| <div><a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html">POSIX documentation</a></div><br /> | ||||
| <table id="data"> | ||||
| <tr><th>example</th><th>result</th></tr> | ||||
| </table> | ||||
| <script type="module"> | ||||
| /* eslint-env browser */ | ||||
| /*global PRINTJ */ | ||||
| import { sprintf as printf } from './printj.mjs'; | ||||
| var table = document.getElementById("data"); | ||||
| var ex = [ | ||||
| 	'printf("|Hello %s|", "SheetJS")', | ||||
| 	'printf("|%1$d %1$o %1$u %1$x %1$X|", 1234)', | ||||
| 	'printf("|%1$d %1$o %1$u %1$x %1$X|", -1234)', | ||||
| 	'printf("|%1$d %1$o %1$u %1$x %1$X %1$lld|", 2813308004)', | ||||
| 	'printf("|%1$f %1$F %1$e %1$E %1$g %1$G %1$a %1$A|", 1.2)', | ||||
| 	'printf("|%1$f %1$F %1$e %1$E %1$g %1$G %1$a %1$A|", Math.PI)', | ||||
| 	'printf("|%1$f %1$F %1$e %1$E %1$g %1$G %1$a %1$A|", Math.LOG2E)', | ||||
| 	'printf("|%1$f %1$F %1$e %1$E %1$g %1$G %1$a %1$A|", -Math.LOG10E)', | ||||
| 	'printf("|%1$f %1$F %1$e %1$E %1$g %1$G %1$a %1$A|", Infinity)', | ||||
| 	'printf("|%1$f %1$F %1$e %1$E %1$g %1$G %1$a %1$A|", -0)', | ||||
| 	'printf("|%012s|", "SheetJS")', | ||||
| 	'printf("|%-12s|", "SheetJS")', | ||||
| 	'printf("|%1$f %1$F %1$e %1$E %1$g %1$G %1$a %1$A|", 1.4142E69)', | ||||
| 	'printf("%%")' | ||||
| ]; | ||||
| window.onload = function() { | ||||
| 	printf("Hello %s", "world"); | ||||
| 	ex.forEach(function(m) { | ||||
| 		var row = table.insertRow(table.rows.length); | ||||
| 		var c1 = row.insertCell(0); c1.innerHTML = "<pre>" + m + "</pre>"; | ||||
| 		var c2 = row.insertCell(1); c2.innerHTML = "<pre>" + eval(m) + "</pre>"; | ||||
| 	}); | ||||
| }; | ||||
| 	var _gaq = _gaq || []; | ||||
| 	_gaq.push(['_setAccount', 'UA-36810333-1']); | ||||
| 	_gaq.push(['_trackPageview']); | ||||
| 
 | ||||
| 	(function() { | ||||
| 		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | ||||
| 		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | ||||
| 		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | ||||
| 	})(); | ||||
| </script> | ||||
| </body> | ||||
| </html> | ||||
| 
 | ||||
							
								
								
									
										5
									
								
								tests/node.mjs
									
									
									
									
									
										Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										5
									
								
								tests/node.mjs
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,5 @@ | ||||
| #!/usr/bin/env node --experimental-modules
 | ||||
| 
 | ||||
| import { version, sprintf } from '../printj.mjs' | ||||
| 
 | ||||
| console.log(sprintf("PRINTJ version %s, 123 = 0x%02hhx", version, 123)); | ||||
							
								
								
									
										1
									
								
								tests/printj.mjs
									
									
									
									
									
										Symbolic link
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								tests/printj.mjs
									
									
									
									
									
										Symbolic link
									
								
							| @ -0,0 +1 @@ | ||||
| ../printj.mjs | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user