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

'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;