mirror of
https://github.com/nodejs/node.git
synced 2025-05-01 08:42:45 +00:00
intl: Add more versions from ICU
* Adds process.versions.cldr, .tz, and .unicode * Changes how process.versions.icu is loaded * Lazy loads the process.versions.* values for these * add an exception to util.js to cause 'node -p process.versions' to still work * update process.version docs Fixes: https://github.com/nodejs/node/issues/9237
This commit is contained in:
parent
97dfcede2b
commit
4fb27d43f0
@ -1643,8 +1643,10 @@ Will generate output similar to:
|
||||
ares: '1.10.0-DEV',
|
||||
modules: '43',
|
||||
icu: '55.1',
|
||||
openssl: '1.0.1k'
|
||||
}
|
||||
openssl: '1.0.1k',
|
||||
unicode: '8.0',
|
||||
cldr: '29.0',
|
||||
tz: '2016b' }
|
||||
```
|
||||
|
||||
## Exit Codes
|
||||
|
32
lib/internal/bootstrap_node.js
vendored
32
lib/internal/bootstrap_node.js
vendored
@ -26,6 +26,8 @@
|
||||
// do this good and early, since it handles errors.
|
||||
setupProcessFatal();
|
||||
|
||||
setupProcessICUVersions();
|
||||
|
||||
setupGlobalVariables();
|
||||
if (!process._noBrowserGlobals) {
|
||||
setupGlobalTimeouts();
|
||||
@ -304,6 +306,36 @@
|
||||
};
|
||||
}
|
||||
|
||||
function setupProcessICUVersions() {
|
||||
const icu = process.binding('config').hasIntl ?
|
||||
process.binding('icu') : undefined;
|
||||
if (!icu) return; // no Intl/ICU: nothing to add here.
|
||||
// With no argument, getVersion() returns a comma separated list
|
||||
// of possible types.
|
||||
const versionTypes = icu.getVersion().split(',');
|
||||
versionTypes.forEach((name) => {
|
||||
// Copied from module.js:addBuiltinLibsToObject
|
||||
Object.defineProperty(process.versions, name, {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: () => {
|
||||
// With an argument, getVersion(type) returns
|
||||
// the actual version string.
|
||||
const version = icu.getVersion(name);
|
||||
// Replace the current getter with a new
|
||||
// property.
|
||||
delete process.versions[name];
|
||||
Object.defineProperty(process.versions, name, {
|
||||
value: version,
|
||||
writable: false,
|
||||
enumerable: true
|
||||
});
|
||||
return version;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function tryGetCwd(path) {
|
||||
var threw = true;
|
||||
var cwd;
|
||||
|
@ -1049,3 +1049,7 @@ exports._exceptionWithHostPort = function(err,
|
||||
}
|
||||
return ex;
|
||||
};
|
||||
|
||||
// process.versions needs a custom function as some values are lazy-evaluated.
|
||||
process.versions[exports.inspect.custom] =
|
||||
(depth) => exports.format(JSON.parse(JSON.stringify(process.versions)));
|
||||
|
@ -3032,9 +3032,7 @@ void SetupProcessObject(Environment* env,
|
||||
FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
|
||||
|
||||
#if defined(NODE_HAVE_I18N_SUPPORT) && defined(U_ICU_VERSION)
|
||||
READONLY_PROPERTY(versions,
|
||||
"icu",
|
||||
OneByteString(env->isolate(), U_ICU_VERSION));
|
||||
// ICU-related versions are now handled on the js side, see bootstrap_node.js
|
||||
|
||||
if (icu_data_dir != nullptr) {
|
||||
// Did the user attempt (via env var or parameter) to set an ICU path?
|
||||
|
@ -31,14 +31,18 @@
|
||||
#include "util-inl.h"
|
||||
#include "v8.h"
|
||||
|
||||
#include <unicode/utypes.h>
|
||||
#include <unicode/putil.h>
|
||||
#include <unicode/uchar.h>
|
||||
#include <unicode/udata.h>
|
||||
#include <unicode/uidna.h>
|
||||
#include <unicode/utypes.h>
|
||||
#include <unicode/ucnv.h>
|
||||
#include <unicode/utf8.h>
|
||||
#include <unicode/utf16.h>
|
||||
#include <unicode/timezone.h>
|
||||
#include <unicode/ulocdata.h>
|
||||
#include <unicode/uvernum.h>
|
||||
#include <unicode/uversion.h>
|
||||
|
||||
#ifdef NODE_HAVE_SMALL_ICU
|
||||
/* if this is defined, we have a 'secondary' entry point.
|
||||
@ -339,6 +343,67 @@ static void ICUErrorName(const FunctionCallbackInfo<Value>& args) {
|
||||
v8::NewStringType::kNormal).ToLocalChecked());
|
||||
}
|
||||
|
||||
#define TYPE_ICU "icu"
|
||||
#define TYPE_UNICODE "unicode"
|
||||
#define TYPE_CLDR "cldr"
|
||||
#define TYPE_TZ "tz"
|
||||
|
||||
/**
|
||||
* This is the workhorse function that deals with the actual version info.
|
||||
* Get an ICU version.
|
||||
* @param type the type of version to get. One of VERSION_TYPES
|
||||
* @param buf optional buffer for result
|
||||
* @param status ICU error status. If failure, assume result is undefined.
|
||||
* @return version number, or NULL. May or may not be buf.
|
||||
*/
|
||||
static const char* GetVersion(const char* type,
|
||||
char buf[U_MAX_VERSION_STRING_LENGTH],
|
||||
UErrorCode* status) {
|
||||
if (!strcmp(type, TYPE_ICU)) {
|
||||
return U_ICU_VERSION;
|
||||
} else if (!strcmp(type, TYPE_UNICODE)) {
|
||||
return U_UNICODE_VERSION;
|
||||
} else if (!strcmp(type, TYPE_TZ)) {
|
||||
return TimeZone::getTZDataVersion(*status);
|
||||
} else if (!strcmp(type, TYPE_CLDR)) {
|
||||
UVersionInfo versionArray;
|
||||
ulocdata_getCLDRVersion(versionArray, status);
|
||||
if (U_SUCCESS(*status)) {
|
||||
u_versionToString(versionArray, buf);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
// Fall through - unknown type or error case
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void GetVersion(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
if ( args.Length() == 0 ) {
|
||||
// With no args - return a comma-separated list of allowed values
|
||||
args.GetReturnValue().Set(
|
||||
String::NewFromUtf8(env->isolate(),
|
||||
TYPE_ICU ","
|
||||
TYPE_UNICODE ","
|
||||
TYPE_CLDR ","
|
||||
TYPE_TZ));
|
||||
} else {
|
||||
CHECK_GE(args.Length(), 1);
|
||||
CHECK(args[0]->IsString());
|
||||
Utf8Value val(env->isolate(), args[0]);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
char buf[U_MAX_VERSION_STRING_LENGTH] = ""; // Possible output buffer.
|
||||
const char* versionString = GetVersion(*val, buf, &status);
|
||||
|
||||
if (U_SUCCESS(status) && versionString) {
|
||||
// Success.
|
||||
args.GetReturnValue().Set(
|
||||
String::NewFromUtf8(env->isolate(),
|
||||
versionString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool InitializeICUDirectory(const char* icu_data_path) {
|
||||
if (icu_data_path != nullptr) {
|
||||
flag_icu_data_dir = true;
|
||||
@ -558,6 +623,7 @@ void Init(Local<Object> target,
|
||||
env->SetMethod(target, "toUnicode", ToUnicode);
|
||||
env->SetMethod(target, "toASCII", ToASCII);
|
||||
env->SetMethod(target, "getStringWidth", GetStringWidth);
|
||||
env->SetMethod(target, "getVersion", GetVersion);
|
||||
|
||||
// One-shot converters
|
||||
env->SetMethod(target, "icuErrName", ICUErrorName);
|
||||
|
@ -11,6 +11,9 @@ if (common.hasCrypto) {
|
||||
|
||||
if (common.hasIntl) {
|
||||
expected_keys.push('icu');
|
||||
expected_keys.push('cldr');
|
||||
expected_keys.push('tz');
|
||||
expected_keys.push('unicode');
|
||||
}
|
||||
|
||||
expected_keys.sort();
|
||||
|
Loading…
Reference in New Issue
Block a user