pax_global_header00006660000000000000000000000064141403115330014505gustar00rootroot0000000000000052 comment=27a4e35093004edb6865d5c318d9f54c60126f31 node-extsprintf-1.4.1/000077500000000000000000000000001414031153300146415ustar00rootroot00000000000000node-extsprintf-1.4.1/.gitmodules000066400000000000000000000001261414031153300170150ustar00rootroot00000000000000[submodule "deps/catest"] path = deps/catest url = https://github.com/joyent/catest node-extsprintf-1.4.1/.npmignore000066400000000000000000000000201414031153300166300ustar00rootroot00000000000000/deps /examples node-extsprintf-1.4.1/CHANGES.md000066400000000000000000000002451414031153300162340ustar00rootroot00000000000000# Changelog ## Not yet released None yet. ## v1.4.0 * #13 could provide better error messages for programmer errors * #14 bring extsprintf into the modern world node-extsprintf-1.4.1/CONTRIBUTING.md000066400000000000000000000010301414031153300170640ustar00rootroot00000000000000# Contributing This repository uses GitHub pull requests for code review. See the [Joyent Engineering Guidelines](https://github.com/joyent/eng/blob/master/docs/index.md) for general best practices expected in this repository. Contributions should be "make prepush" clean. This target requires separate tools: * https://github.com/davepacheco/jsstyle * https://github.com/davepacheco/javascriptlint * https://github.com/joyent/catest If you're changing something non-trivial or user-facing, you may want to submit an issue first. node-extsprintf-1.4.1/LICENSE000066400000000000000000000020651414031153300156510ustar00rootroot00000000000000Copyright (c) 2012, Joyent, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE node-extsprintf-1.4.1/Makefile000066400000000000000000000011561414031153300163040ustar00rootroot00000000000000# # Copyright (c) 2017, Joyent, Inc. All rights reserved. # # Makefile: top-level Makefile # # This Makefile contains only repo-specific logic and uses included makefiles # to supply common targets (javascriptlint, jsstyle, restdown, etc.), which are # used by other repos as well. # # # Files # CATEST = deps/catest/catest JSL = jsl JSSTYLE = jsstyle JS_FILES := $(shell find examples lib -name '*.js') JSL_FILES_NODE = $(JS_FILES) JSSTYLE_FILES = $(JS_FILES) JSL_CONF_NODE = jsl.node.conf # Default target is "check" check: test: | $(CATEST) $(CATEST) -a CATEST: deps/catest/.git include ./Makefile.targ node-extsprintf-1.4.1/Makefile.targ000066400000000000000000000203061414031153300172360ustar00rootroot00000000000000# -*- mode: makefile -*- # # Copyright (c) 2012, Joyent, Inc. All rights reserved. # # Makefile.targ: common targets. # # NOTE: This makefile comes from the "eng" repo. It's designed to be dropped # into other repos as-is without requiring any modifications. If you find # yourself changing this file, you should instead update the original copy in # eng.git and then update your repo to use the new version. # # This Makefile defines several useful targets and rules. You can use it by # including it from a Makefile that specifies some of the variables below. # # Targets defined in this Makefile: # # check Checks JavaScript files for lint and style # Checks bash scripts for syntax # Checks SMF manifests for validity against the SMF DTD # # clean Removes built files # # docs Builds restdown documentation in docs/ # # prepush Depends on "check" and "test" # # test Does nothing (you should override this) # # xref Generates cscope (source cross-reference index) # # For details on what these targets are supposed to do, see the Joyent # Engineering Guide. # # To make use of these targets, you'll need to set some of these variables. Any # variables left unset will simply not be used. # # BASH_FILES Bash scripts to check for syntax # (paths relative to top-level Makefile) # # CLEAN_FILES Files to remove as part of the "clean" target. Note # that files generated by targets in this Makefile are # automatically included in CLEAN_FILES. These include # restdown-generated HTML and JSON files. # # DOC_FILES Restdown (documentation source) files. These are # assumed to be contained in "docs/", and must NOT # contain the "docs/" prefix. # # JSL_CONF_NODE Specify JavaScriptLint configuration files # JSL_CONF_WEB (paths relative to top-level Makefile) # # Node.js and Web configuration files are separate # because you'll usually want different global variable # configurations. If no file is specified, none is given # to jsl, which causes it to use a default configuration, # which probably isn't what you want. # # JSL_FILES_NODE JavaScript files to check with Node config file. # JSL_FILES_WEB JavaScript files to check with Web config file. # # You can also override these variables: # # BASH Path to bash (default: bash) # # CSCOPE_DIRS Directories to search for source files for the cscope # index. (default: ".") # # JSL Path to JavaScriptLint (default: "jsl") # # JSL_FLAGS_NODE Additional flags to pass through to JSL # JSL_FLAGS_WEB # JSL_FLAGS # # JSSTYLE Path to jsstyle (default: jsstyle) # # JSSTYLE_FLAGS Additional flags to pass through to jsstyle # # # Defaults for the various tools we use. # BASH ?= bash BASHSTYLE ?= tools/bashstyle CP ?= cp CSCOPE ?= cscope CSCOPE_DIRS ?= . JSL ?= jsl JSSTYLE ?= jsstyle MKDIR ?= mkdir -p MV ?= mv RESTDOWN_FLAGS ?= RMTREE ?= rm -rf JSL_FLAGS ?= --nologo --nosummary ifeq ($(shell uname -s),SunOS) TAR ?= gtar else TAR ?= tar endif # # Defaults for other fixed values. # BUILD = build DISTCLEAN_FILES += $(BUILD) DOC_BUILD = $(BUILD)/docs/public # # Configure JSL_FLAGS_{NODE,WEB} based on JSL_CONF_{NODE,WEB}. # ifneq ($(origin JSL_CONF_NODE), undefined) JSL_FLAGS_NODE += --conf=$(JSL_CONF_NODE) endif ifneq ($(origin JSL_CONF_WEB), undefined) JSL_FLAGS_WEB += --conf=$(JSL_CONF_WEB) endif # # Targets. For descriptions on what these are supposed to do, see the # Joyent Engineering Guide. # # # Instruct make to keep around temporary files. We have rules below that # automatically update git submodules as needed, but they employ a deps/*/.git # temporary file. Without this directive, make tries to remove these .git # directories after the build has completed. # .SECONDARY: $($(wildcard deps/*):%=%/.git) # # This rule enables other rules that use files from a git submodule to have # those files depend on deps/module/.git and have "make" automatically check # out the submodule as needed. # deps/%/.git: git submodule update --init deps/$* # # These recipes make heavy use of dynamically-created phony targets. The parent # Makefile defines a list of input files like BASH_FILES. We then say that each # of these files depends on a fake target called filename.bashchk, and then we # define a pattern rule for those targets that runs bash in check-syntax-only # mode. This mechanism has the nice properties that if you specify zero files, # the rule becomes a noop (unlike a single rule to check all bash files, which # would invoke bash with zero files), and you can check individual files from # the command line with "make filename.bashchk". # .PHONY: check-bash check-bash: $(BASH_FILES:%=%.bashchk) $(BASH_FILES:%=%.bashstyle) %.bashchk: % $(BASH) -n $^ %.bashstyle: % $(BASHSTYLE) $^ .PHONY: check-jsl check-jsl-node check-jsl-web check-jsl: check-jsl-node check-jsl-web check-jsl-node: $(JSL_FILES_NODE:%=%.jslnodechk) check-jsl-web: $(JSL_FILES_WEB:%=%.jslwebchk) %.jslnodechk: % $(JSL_EXEC) $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_NODE) $< %.jslwebchk: % $(JSL_EXEC) $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_WEB) $< .PHONY: check-jsstyle check-jsstyle: $(JSSTYLE_FILES:%=%.jsstylechk) %.jsstylechk: % $(JSSTYLE_EXEC) $(JSSTYLE) $(JSSTYLE_FLAGS) $< .PHONY: check check: check-jsl check-jsstyle check-bash @echo check ok .PHONY: clean clean:: -$(RMTREE) $(CLEAN_FILES) .PHONY: distclean distclean:: clean -$(RMTREE) $(DISTCLEAN_FILES) CSCOPE_FILES = cscope.in.out cscope.out cscope.po.out CLEAN_FILES += $(CSCOPE_FILES) .PHONY: xref xref: cscope.files $(CSCOPE) -bqR .PHONY: cscope.files cscope.files: find $(CSCOPE_DIRS) -name '*.c' -o -name '*.h' -o -name '*.cc' \ -o -name '*.js' -o -name '*.s' -o -name '*.cpp' > $@ # # The "docs" target is complicated because we do several things here: # # (1) Use restdown to build HTML and JSON files from each of DOC_FILES. # # (2) Copy these files into $(DOC_BUILD) (build/docs/public), which # functions as a complete copy of the documentation that could be # mirrored or served over HTTP. # # (3) Then copy any directories and media from docs/media into # $(DOC_BUILD)/media. This allows projects to include their own media, # including files that will override same-named files provided by # restdown. # # Step (3) is the surprisingly complex part: in order to do this, we need to # identify the subdirectories in docs/media, recreate them in # $(DOC_BUILD)/media, then do the same with the files. # DOC_MEDIA_DIRS := $(shell find docs/media -type d 2>/dev/null | grep -v "^docs/media$$") DOC_MEDIA_DIRS := $(DOC_MEDIA_DIRS:docs/media/%=%) DOC_MEDIA_DIRS_BUILD := $(DOC_MEDIA_DIRS:%=$(DOC_BUILD)/media/%) DOC_MEDIA_FILES := $(shell find docs/media -type f 2>/dev/null) DOC_MEDIA_FILES := $(DOC_MEDIA_FILES:docs/media/%=%) DOC_MEDIA_FILES_BUILD := $(DOC_MEDIA_FILES:%=$(DOC_BUILD)/media/%) # # Like the other targets, "docs" just depends on the final files we want to # create in $(DOC_BUILD), leveraging other targets and recipes to define how # to get there. # .PHONY: docs docs: \ $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.html) \ $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.json) \ $(DOC_MEDIA_FILES_BUILD) # # We keep the intermediate files so that the next build can see whether the # files in DOC_BUILD are up to date. # .PRECIOUS: \ $(DOC_FILES:%.restdown=docs/%.html) \ $(DOC_FILES:%.restdown=docs/%json) # # We do clean those intermediate files, as well as all of DOC_BUILD. # CLEAN_FILES += \ $(DOC_BUILD) \ $(DOC_FILES:%.restdown=docs/%.html) \ $(DOC_FILES:%.restdown=docs/%.json) # # Before installing the files, we must make sure the directories exist. The | # syntax tells make that the dependency need only exist, not be up to date. # Otherwise, it might try to rebuild spuriously because the directory itself # appears out of date. # $(DOC_MEDIA_FILES_BUILD): | $(DOC_MEDIA_DIRS_BUILD) $(DOC_BUILD)/%: docs/% | $(DOC_BUILD) $(CP) $< $@ docs/%.json docs/%.html: docs/%.restdown | $(DOC_BUILD) $(RESTDOWN_EXEC) $(RESTDOWN) $(RESTDOWN_FLAGS) -m $(DOC_BUILD) $< $(DOC_BUILD): $(MKDIR) $@ $(DOC_MEDIA_DIRS_BUILD): $(MKDIR) $@ # # The default "test" target does nothing. This should usually be overridden by # the parent Makefile. It's included here so we can define "prepush" without # requiring the repo to define "test". # .PHONY: test test: .PHONY: prepush prepush: check test node-extsprintf-1.4.1/README.md000066400000000000000000000025151414031153300161230ustar00rootroot00000000000000# extsprintf: extended POSIX-style sprintf Stripped down version of s[n]printf(3c). We make a best effort to throw an exception when given a format string we don't understand, rather than ignoring it, so that we won't break existing programs if/when we go implement the rest of this. This implementation currently supports specifying * field alignment ('-' flag), * zero-pad ('0' flag) * always show numeric sign ('+' flag), * field width * conversions for strings, decimal integers, and floats (numbers). * argument size specifiers. These are all accepted but ignored, since Javascript has no notion of the physical size of an argument. Everything else is currently unsupported, most notably: precision, unsigned numbers, non-decimal numbers, and characters. Besides the usual POSIX conversions, this implementation supports: * `%j`: pretty-print a JSON object (using node's "inspect") * `%r`: pretty-print an Error object # Example First, install it: # npm install extsprintf Now, use it: var mod_extsprintf = require('extsprintf'); console.log(mod_extsprintf.sprintf('hello %25s', 'world')); outputs: hello world # Also supported **printf**: same args as sprintf, but prints the result to stdout **fprintf**: same args as sprintf, preceded by a Node stream. Prints the result to the given stream. node-extsprintf-1.4.1/deps/000077500000000000000000000000001414031153300155745ustar00rootroot00000000000000node-extsprintf-1.4.1/deps/catest/000077500000000000000000000000001414031153300170575ustar00rootroot00000000000000node-extsprintf-1.4.1/examples/000077500000000000000000000000001414031153300164575ustar00rootroot00000000000000node-extsprintf-1.4.1/examples/simple.js000066400000000000000000000003551414031153300203110ustar00rootroot00000000000000var mod_extsprintf = require('extsprintf'); console.log(mod_extsprintf.sprintf('hello %25s', 'world')); mod_extsprintf.printf('hi there\nvia %20s\n', 'printf'); mod_extsprintf.fprintf(process.stderr, 'sent to std%6s %03d\n', 'err', 7); node-extsprintf-1.4.1/jsl.node.conf000066400000000000000000000155061414031153300172330ustar00rootroot00000000000000# # Configuration File for JavaScript Lint # # This configuration file can be used to lint a collection of scripts, or to enable # or disable warnings for scripts that are linted via the command line. # ### Warnings # Enable or disable warnings based on requirements. # Use "+WarningName" to display or "-WarningName" to suppress. # +ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent +ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity +ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement +anon_no_return_value # anonymous function does not always return value +assign_to_function_call # assignment to a function call -block_without_braces # block statement without curly braces +comma_separated_stmts # multiple statements separated by commas (use semicolons?) +comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==) +default_not_at_end # the default case is not at the end of the switch statement +dup_option_explicit # duplicate "option explicit" control comment +duplicate_case_in_switch # duplicate case in switch statement +duplicate_formal # duplicate formal argument {name} +empty_statement # empty statement or extra semicolon +identifier_hides_another # identifer {name} hides an identifier in a parent scope -inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement +incorrect_version # Expected /*jsl:content-type*/ control comment. The script was parsed with the wrong version. +invalid_fallthru # unexpected "fallthru" control comment +invalid_pass # unexpected "pass" control comment +jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax +leading_decimal_point # leading decimal point may indicate a number or an object member +legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax +meaningless_block # meaningless block; curly braces have no impact +mismatch_ctrl_comments # mismatched control comment; "ignore" and "end" control comments must have a one-to-one correspondence +misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma +missing_break # missing break statement +missing_break_for_last_case # missing break statement for last case in switch +missing_default_case # missing default case in switch statement +missing_option_explicit # the "option explicit" control comment is missing +missing_semicolon # missing semicolon +missing_semicolon_for_lambda # missing semicolon for lambda assignment +multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs +nested_comment # nested comment +no_return_value # function {name} does not always return a value +octal_number # leading zeros make an octal number +parseint_missing_radix # parseInt missing radix parameter +partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag +redeclared_var # redeclaration of {name} +trailing_comma_in_array # extra comma is not recommended in array initializers +trailing_decimal_point # trailing decimal point may indicate a number or an object member +undeclared_identifier # undeclared identifier: {name} +unreachable_code # unreachable code -unreferenced_argument # argument declared but never referenced: {name} -unreferenced_function # function is declared but never referenced: {name} +unreferenced_variable # variable is declared but never referenced: {name} +unsupported_version # JavaScript {version} is not supported +use_of_label # use of label +useless_assign # useless assignment +useless_comparison # useless comparison; comparing identical expressions -useless_quotes # the quotation marks are unnecessary +useless_void # use of the void type may be unnecessary (void is always undefined) +var_hides_arg # variable {name} hides argument +want_assign_or_call # expected an assignment or function call +with_statement # with statement hides undeclared variables; use temporary variable instead ### Output format # Customize the format of the error message. # __FILE__ indicates current file path # __FILENAME__ indicates current file name # __LINE__ indicates current line # __COL__ indicates current column # __ERROR__ indicates error message (__ERROR_PREFIX__: __ERROR_MSG__) # __ERROR_NAME__ indicates error name (used in configuration file) # __ERROR_PREFIX__ indicates error prefix # __ERROR_MSG__ indicates error message # # For machine-friendly output, the output format can be prefixed with # "encode:". If specified, all items will be encoded with C-slashes. # # Visual Studio syntax (default): +output-format __FILE__(__LINE__): __ERROR__ # Alternative syntax: #+output-format __FILE__:__LINE__: __ERROR__ ### Context # Show the in-line position of the error. # Use "+context" to display or "-context" to suppress. # +context ### Control Comments # Both JavaScript Lint and the JScript interpreter confuse each other with the syntax for # the /*@keyword@*/ control comments and JScript conditional comments. (The latter is # enabled in JScript with @cc_on@). The /*jsl:keyword*/ syntax is preferred for this reason, # although legacy control comments are enabled by default for backward compatibility. # -legacy_control_comments ### Defining identifiers # By default, "option explicit" is enabled on a per-file basis. # To enable this for all files, use "+always_use_option_explicit" -always_use_option_explicit # Define certain identifiers of which the lint is not aware. # (Use this in conjunction with the "undeclared identifier" warning.) # # Common uses for webpages might be: +define __dirname +define clearInterval +define clearTimeout +define console +define exports +define global +define process +define require +define setInterval +define setTimeout +define Buffer +define JSON +define Math ### JavaScript Version # To change the default JavaScript version: #+default-type text/javascript;version=1.5 #+default-type text/javascript;e4x=1 ### Files # Specify which files to lint # Use "+recurse" to enable recursion (disabled by default). # To add a set of files, use "+process FileName", "+process Folder\Path\*.js", # or "+process Folder\Path\*.htm". # node-extsprintf-1.4.1/lib/000077500000000000000000000000001414031153300154075ustar00rootroot00000000000000node-extsprintf-1.4.1/lib/extsprintf.js000066400000000000000000000125701414031153300201600ustar00rootroot00000000000000/* * extsprintf.js: extended POSIX-style sprintf */ var mod_assert = require('assert'); var mod_util = require('util'); /* * Public interface */ exports.sprintf = jsSprintf; exports.printf = jsPrintf; exports.fprintf = jsFprintf; /* * Stripped down version of s[n]printf(3c). We make a best effort to throw an * exception when given a format string we don't understand, rather than * ignoring it, so that we won't break existing programs if/when we go implement * the rest of this. * * This implementation currently supports specifying * - field alignment ('-' flag), * - zero-pad ('0' flag) * - always show numeric sign ('+' flag), * - field width * - conversions for strings, decimal integers, and floats (numbers). * - argument size specifiers. These are all accepted but ignored, since * Javascript has no notion of the physical size of an argument. * * Everything else is currently unsupported, most notably precision, unsigned * numbers, non-decimal numbers, and characters. */ function jsSprintf(ofmt) { var regex = [ '([^%]*)', /* normal text */ '%', /* start of format */ '([\'\\-+ #0]*?)', /* flags (optional) */ '([1-9]\\d*)?', /* width (optional) */ '(\\.([1-9]\\d*))?', /* precision (optional) */ '[lhjztL]*?', /* length mods (ignored) */ '([diouxXfFeEgGaAcCsSp%jr])' /* conversion */ ].join(''); var re = new RegExp(regex); /* variadic arguments used to fill in conversion specifiers */ var args = Array.prototype.slice.call(arguments, 1); /* remaining format string */ var fmt = ofmt; /* components of the current conversion specifier */ var flags, width, precision, conversion; var left, pad, sign, arg, match; /* return value */ var ret = ''; /* current variadic argument (1-based) */ var argn = 1; /* 0-based position in the format string that we've read */ var posn = 0; /* 1-based position in the format string of the current conversion */ var convposn; /* current conversion specifier */ var curconv; mod_assert.equal('string', typeof (fmt), 'first argument must be a format string'); while ((match = re.exec(fmt)) !== null) { ret += match[1]; fmt = fmt.substring(match[0].length); /* * Update flags related to the current conversion specifier's * position so that we can report clear error messages. */ curconv = match[0].substring(match[1].length); convposn = posn + match[1].length + 1; posn += match[0].length; flags = match[2] || ''; width = match[3] || 0; precision = match[4] || ''; conversion = match[6]; left = false; sign = false; pad = ' '; if (conversion == '%') { ret += '%'; continue; } if (args.length === 0) { throw (jsError(ofmt, convposn, curconv, 'has no matching argument ' + '(too few arguments passed)')); } arg = args.shift(); argn++; if (flags.match(/[\' #]/)) { throw (jsError(ofmt, convposn, curconv, 'uses unsupported flags')); } if (precision.length > 0) { throw (jsError(ofmt, convposn, curconv, 'uses non-zero precision (not supported)')); } if (flags.match(/-/)) left = true; if (flags.match(/0/)) pad = '0'; if (flags.match(/\+/)) sign = true; switch (conversion) { case 's': if (arg === undefined || arg === null) { throw (jsError(ofmt, convposn, curconv, 'attempted to print undefined or null ' + 'as a string (argument ' + argn + ' to ' + 'sprintf)')); } ret += doPad(pad, width, left, arg.toString()); break; case 'd': arg = Math.floor(arg); /*jsl:fallthru*/ case 'f': sign = sign && arg > 0 ? '+' : ''; ret += sign + doPad(pad, width, left, arg.toString()); break; case 'x': ret += doPad(pad, width, left, arg.toString(16)); break; case 'j': /* non-standard */ if (width === 0) width = 10; ret += mod_util.inspect(arg, false, width); break; case 'r': /* non-standard */ ret += dumpException(arg); break; default: throw (jsError(ofmt, convposn, curconv, 'is not supported')); } } ret += fmt; return (ret); } function jsError(fmtstr, convposn, curconv, reason) { mod_assert.equal(typeof (fmtstr), 'string'); mod_assert.equal(typeof (curconv), 'string'); mod_assert.equal(typeof (convposn), 'number'); mod_assert.equal(typeof (reason), 'string'); return (new Error('format string "' + fmtstr + '": conversion specifier "' + curconv + '" at character ' + convposn + ' ' + reason)); } function jsPrintf() { var args = Array.prototype.slice.call(arguments); args.unshift(process.stdout); jsFprintf.apply(null, args); } function jsFprintf(stream) { var args = Array.prototype.slice.call(arguments, 1); return (stream.write(jsSprintf.apply(this, args))); } function doPad(chr, width, left, str) { var ret = str; while (ret.length < width) { if (left) ret += chr; else ret = chr + ret; } return (ret); } /* * This function dumps long stack traces for exceptions having a cause() method. * See node-verror for an example. */ function dumpException(ex) { var ret; if (!(ex instanceof Error)) throw (new Error(jsSprintf('invalid type for %%r: %j', ex))); /* Note that V8 prepends "ex.stack" with ex.toString(). */ ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack; if (ex.cause && typeof (ex.cause) === 'function') { var cex = ex.cause(); if (cex) { ret += '\nCaused by: ' + dumpException(cex); } } return (ret); } node-extsprintf-1.4.1/package.json000066400000000000000000000004311414031153300171250ustar00rootroot00000000000000{ "name": "extsprintf", "version": "1.4.1", "description": "extended POSIX-style sprintf", "main": "./lib/extsprintf.js", "repository": { "type": "git", "url": "https://github.com/davepacheco/node-extsprintf.git" }, "engines": [ "node >=0.6.0" ], "license": "MIT" } node-extsprintf-1.4.1/test/000077500000000000000000000000001414031153300156205ustar00rootroot00000000000000node-extsprintf-1.4.1/test/tst.basic.js000066400000000000000000000054551414031153300200610ustar00rootroot00000000000000/* * tst.basic.js: tests various valid invocation */ var mod_assert = require('assert'); var mod_extsprintf = require('../lib/extsprintf'); var mod_path = require('path'); var sprintf = mod_extsprintf.sprintf; var testcases = [ { 'name': 'empty string', 'args': [ '' ], 'result': '' }, { 'name': '%s: basic', 'args': [ '%s', 'foo' ], 'result': 'foo' }, { 'name': '%s: not first', 'args': [ 'hello %s\n', 'world' ], 'result': 'hello world\n' }, { 'name': '%s: right-aligned', 'args': [ 'hello %10s\n', 'world' ], 'result': 'hello world\n' }, { 'name': '%s: left-aligned', 'args': [ 'hello %-10sagain\n', 'world' ], 'result': 'hello world again\n' }, { 'name': '%d: basic, positive', 'args': [ '%d', 17 ], 'result': '17' }, { 'name': '%d: basic, zero', 'args': [ '%d', 0 ], 'result': '0' }, { 'name': '%d: basic, floating point value', 'args': [ '%d', 17.3 ], 'result': '17' }, { 'name': '%d: basic, negative', 'args': [ '%d', -3 ], 'result': '-3' }, { 'name': '%d: right-aligned', 'args': [ '%4d', 17 ], 'result': ' 17' }, { 'name': '%d: right-aligned, zero-padded', 'args': [ '%04d', 17 ], 'result': '0017' }, { 'name': '%d: left-aligned', 'args': [ '%-4d', 17 ], 'result': '17 ' }, { 'name': '%x: basic', 'args': [ '%x', 18], 'result': '12' }, { 'name': '%x: zero-padded, right-aligned', 'args': [ '%08x', 0xfeedface ], 'result': 'feedface' }, { 'name': '%d: with plus sign', 'args': [ '%+d', 17 ], 'result': '+17' }, { 'name': '%f: basic', 'args': [ '%f', 3.2 ], 'result': '3.2' }, { 'name': '%f: right-aligned', 'args': [ '%5f', 3.2 ], 'result': ' 3.2' }, { 'name': '%%: basic', 'args': [ '%%' ], 'result': '%' }, { 'name': 'complex', 'args': [ 'one %s %8s %-3d bytes past 0x%04x, which was %6f%%%s%5s', 'program', 'wrote', -2, 0x30, 3.7, ' plus', 'over' ], 'result': 'one program wrote -2 bytes past 0x0030, which was ' + '3.7% plus over' } ]; function main(verbose) { /* * Create one test case with a very large input string. */ var input = '1234'; while (input.length < 100 * 1024) { input += input; } testcases.push({ 'name': 'long string argument (' + input.length + ' characters)', 'args': [ '%s', input ], 'result': input }); testcases.forEach(function (tc) { var result; console.error('test case: %s', tc.name); result = sprintf.apply(null, tc.args); if (verbose) { console.error(' args: %s', JSON.stringify(tc.args)); console.error(' result: %s', result); } mod_assert.equal(tc.result, result); }); console.log('%s tests passed', mod_path.basename(__filename)); } main(process.argv.length > 2 && process.argv[2] == '-v'); node-extsprintf-1.4.1/test/tst.invalid.js000066400000000000000000000046751414031153300204310ustar00rootroot00000000000000/* * tst.invalid.js: tests invalid invocations */ var mod_assert = require('assert'); var mod_extsprintf = require('../lib/extsprintf'); var mod_path = require('path'); var sprintf = mod_extsprintf.sprintf; var testcases = [ { 'name': 'missing all arguments', 'args': [], 'errmsg': /first argument must be a format string$/ }, { 'name': 'missing argument for format specifier (first char and specifier)', 'args': [ '%s' ], 'errmsg': new RegExp( 'format string "%s": conversion specifier "%s" at character 1 ' + 'has no matching argument \\(too few arguments passed\\)') }, { 'name': 'missing argument for format specifier (later in string)', 'args': [ 'hello %s world %13d', 'big' ], 'errmsg': new RegExp( 'format string "hello %s world %13d": conversion specifier "%13d" at ' + 'character 16 has no matching argument \\(too few arguments passed\\)') }, { 'name': 'printing null as string', 'args': [ '%d cookies %3s', 15, null ], 'errmsg': new RegExp( 'format string "%d cookies %3s": conversion specifier "%3s" at ' + 'character 12 attempted to print undefined or null as a string ' + '\\(argument 3 to sprintf\\)') }, { 'name': 'printing undefined as string', 'args': [ '%d cookies %3s ah %d', 15, undefined, 7 ], 'errmsg': new RegExp( 'format string "%d cookies %3s ah %d": conversion specifier "%3s" at ' + 'character 12 attempted to print undefined or null as a string ' + '\\(argument 3 to sprintf\\)') }, { 'name': 'unsupported format character', 'args': [ 'do not use %X', 13 ], 'errmsg': new RegExp( 'format string "do not use %X": conversion ' + 'specifier "%X" at character 12 is not supported$') }, { 'name': 'unsupported flags', 'args': [ '%#x', 13 ], 'errmsg': new RegExp( 'format string "%#x": conversion ' + 'specifier "%#x" at character 1 uses unsupported flags$') } ]; function main(verbose) { testcases.forEach(function (tc) { var error; console.error('test case: %s', tc.name); if (verbose) { console.error(' args: %s', JSON.stringify(tc.args)); } mod_assert.throws(function () { try { sprintf.apply(null, tc.args); } catch (ex) { error = ex; throw (ex); } }, tc.errmsg); if (verbose && error) { console.error(' error: %s', error.message); } }); console.log('%s tests passed', mod_path.basename(__filename)); } main(process.argv.length > 2 && process.argv[2] == '-v');