mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.4 KiB
70 lines
2.4 KiB
'use strict';
|
|
|
|
const { assert } = require('./assert');
|
|
const { assertBstr } = require('./bstr');
|
|
|
|
// Encode an integer into a C constant.
|
|
function cIntEncode(x) {
|
|
assert(typeof x === 'number');
|
|
// XXX: unsigned constants? DUK_I64_CONSTANT for LL?
|
|
if (x > 0x7fffffff || x < -0x80000000) {
|
|
return String(x) + 'LL';
|
|
} else if (x > 0x7fff || x < -0x8000) {
|
|
return String(x) + 'L';
|
|
} else {
|
|
return String(x);
|
|
}
|
|
}
|
|
exports.cIntEncode = cIntEncode;
|
|
|
|
// Encode a bstr into a C string constant. Split the constant at each
|
|
// escape sequence to avoid any ambiguity, e.g. 'foo\u00ffbar' =>
|
|
// ("foo" "\xff" "bar"). Consecutive hex escapes don't cause ambiguity
|
|
// so place them in the same C string part, e.g. 'foo\u00ff\u00febar' =>
|
|
// ("foo" "\xff\xfe" "bar").
|
|
function cStrEncode(x) {
|
|
assert(typeof x === 'string');
|
|
assertBstr(x);
|
|
|
|
// First alternative max matches characters that need quoting.
|
|
// Second alternative max matches characters that don't need quoting.
|
|
var re = /([\u0000-\u001f\u007e-\uffff\u0022\u005c]+)|([^\u0000-\u001f\u007e-\uffff\u0022\u005c]+)/g;
|
|
|
|
var parts = [];
|
|
void x.replace(re, (m, a, b) => {
|
|
if (typeof a === 'string') {
|
|
// Consecutive hex escapes cannot cause ambiguity, so place them in
|
|
// the same C string part.
|
|
parts.push('"' + Array.prototype.map.call(a, (x) => {
|
|
return '\\x' + ('00' + x.charCodeAt(0).toString(16)).substr(-2);
|
|
}).join('') + '"');
|
|
} else if (typeof b === 'string') {
|
|
parts.push('"' + b + '"');
|
|
} else {
|
|
throw new TypeError('internal error');
|
|
}
|
|
});
|
|
|
|
if (parts.length == 0) {
|
|
return '""';
|
|
} else if (parts.length == 1) {
|
|
return parts[0];
|
|
} else {
|
|
return '(' + parts.join(' ') + ')';
|
|
}
|
|
}
|
|
exports.cStrEncode = cStrEncode;
|
|
|
|
function cCommentEscape(x) {
|
|
return x.replace('*', 'x');
|
|
}
|
|
exports.cCommentEscape = cCommentEscape;
|
|
|
|
function test() {
|
|
assert(cStrEncode('') === '""');
|
|
assert(cStrEncode('foo') === '"foo"');
|
|
assert(cStrEncode('foo\u0009bar') === '("foo" "\\x09" "bar")');
|
|
assert(cStrEncode('foo\u0022\u005cbar') === '("foo" "\\x22\\x5c" "bar")');
|
|
assert(cStrEncode('foo\u00ff\u00febar\u00a9quux"\\\u0009z') == '("foo" "\\xff\\xfe" "bar" "\\xa9" "quux" "\\x22\\x5c\\x09" "z")');
|
|
}
|
|
exports.test = test;
|
|
|