aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPartouf <partouf@gmail.com>2019-01-10 23:55:04 +0100
committerPartouf <partouf@gmail.com>2019-01-10 23:55:04 +0100
commit38d004a187f5ecb5441eceadfeb30e26d098aae6 (patch)
tree0e8d5a0b5866d69ed29b6f1e2829751b065d5545
parentd8c8ec433ad3d9886b0dc8b8024744dc66d577f9 (diff)
parente9bead3c04d853b1bbcad985159dd586e5ab21bb (diff)
downloadcompiler-explorer-38d004a187f5ecb5441eceadfeb30e26d098aae6.tar.gz
compiler-explorer-38d004a187f5ecb5441eceadfeb30e26d098aae6.zip
Merge remote-tracking branch 'matt/master' into compilerargs
-rw-r--r--etc/config/c++.amazon.properties41
-rw-r--r--etc/config/c++.defaults.properties2
-rwxr-xr-xetc/scripts/travis.sh2
-rw-r--r--lib/base-compiler.js4
-rw-r--r--lib/cfg.js17
-rw-r--r--lib/compilers/ispc.js4
-rw-r--r--lib/compilers/rust.js4
-rw-r--r--lib/compilers/swift.js4
-rw-r--r--lib/compilers/zig.js4
-rw-r--r--lib/utils.js8
-rw-r--r--static/thanks.html3
-rw-r--r--test/cases/cfg-clang.split.json190
-rw-r--r--test/cfg-tests.js2
-rw-r--r--test/utils-tests.js10
14 files changed, 278 insertions, 17 deletions
diff --git a/etc/config/c++.amazon.properties b/etc/config/c++.amazon.properties
index 787341f73..b3d4dcf81 100644
--- a/etc/config/c++.amazon.properties
+++ b/etc/config/c++.amazon.properties
@@ -1,4 +1,4 @@
-compilers=&gcc86:&icc:&clang:&rvclang:&cl:&cross:&ellcc:&zapcc:www.godbolt.ms@443
+compilers=&gcc86:&icc:&clang:&rvclang:&cl:&cross:&ellcc:&zapcc:www.godbolt.ms@443:&djggp
defaultCompiler=g82
demangler=/opt/compiler-explorer/gcc-8.2.0/bin/c++filt
objdumper=/opt/compiler-explorer/gcc-8.2.0/bin/objdump
@@ -90,7 +90,7 @@ compiler.g71.needsMulti=true
compiler.g72.needsMulti=true
# Clang for x86
-group.clang.compilers=clang30:clang31:clang32:clang33:clang341:clang350:clang351:clang37x:clang36x:clang371:clang380:clang381:clang390:clang391:clang400:clang401:clang500:clang600:clang700:clang_trunk:clang_concepts:clang_p1144:clang_autonsdmi:clang_lifetime
+group.clang.compilers=clang30:clang31:clang32:clang33:clang341:clang350:clang351:clang37x:clang36x:clang371:clang380:clang381:clang390:clang391:clang400:clang401:clang500:clang600:clang700:clang_trunk:clang_concepts:clang_p1144:clang_autonsdmi:clang_lifetime:clang_parmexpr
group.clang.intelAsm=-mllvm --x86-asm-syntax=intel
group.clang.options=--gcc-toolchain=/opt/compiler-explorer/gcc-7.2.0
group.clang.groupName=Clang x86-64
@@ -167,19 +167,23 @@ compiler.clang_trunk.options=--gcc-toolchain=/opt/compiler-explorer/gcc-8.2.0
compiler.clang_concepts.exe=/opt/compiler-explorer/clang-concepts-trunk/bin/clang++
compiler.clang_concepts.semver=(experimental concepts)
compiler.clang_concepts.options=-std=c++2a -Xclang -fconcepts-ts -stdlib=libc++
-compiler.clang_concepts.notification=Highly experimental compiler. Bug reports welcomed at <a href="https://github.com/saarraz/clang-concepts/issues" target="_blank" rel="noopener noreferrer">github.com/saarraz/clang-concepts/issues <sup><small class="glyphicon glyphicon-new-window opens-new-window" title="Opens in a new window"></small></sup></a>
+compiler.clang_concepts.notification=Highly experimental compiler. Bug reports welcomed at <a href="https://github.com/saarraz/clang-concepts/issues" target="_blank" rel="noopener noreferrer">github.com/saarraz/clang-concepts/issues <sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
compiler.clang_p1144.exe=/opt/compiler-explorer/clang-relocatable-trunk/bin/clang++
compiler.clang_p1144.semver=(experimental P1144)
compiler.clang_p1144.options=-std=c++2a -stdlib=libc++
-compiler.clang_p1144.notification=Experimental __is_trivially_relocatable; see <a href="https://quuxplusone.github.io/draft/d1144-object-relocation.html" target="_blank" rel="noopener noreferrer">P1144 <sup><small class="glyphicon glyphicon-new-window opens-new-window" title="Opens in a new window"></small></sup></a>
+compiler.clang_p1144.notification=Experimental __is_trivially_relocatable; see <a href="https://quuxplusone.github.io/draft/d1144-object-relocation.html" target="_blank" rel="noopener noreferrer">P1144 <sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
compiler.clang_autonsdmi.exe=/opt/compiler-explorer/clang-autonsdmi-trunk/bin/clang++
compiler.clang_autonsdmi.semver=(experimental auto NSDMI)
compiler.clang_autonsdmi.options=-std=c++2a -stdlib=libc++
-compiler.clang_autonsdmi.notification=Experimental auto NSDMI; see <a href="https://cor3ntin.github.io/posts/auto_nsdmi/" target="_blank" rel="noopener noreferrer">this blog post <sup><small class="glyphicon glyphicon-new-window opens-new-window" title="Opens in a new window"></small></sup></a> for more information
+compiler.clang_autonsdmi.notification=Experimental auto NSDMI; see <a href="https://cor3ntin.github.io/posts/auto_nsdmi/" target="_blank" rel="noopener noreferrer">this blog post <sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a> for more information
compiler.clang_lifetime.exe=/opt/compiler-explorer/clang-lifetime-trunk/bin/clang++
compiler.clang_lifetime.semver=(experimental -Wlifetime)
compiler.clang_lifetime.options=--gcc-toolchain=/opt/compiler-explorer/gcc-8.2.0 -Wlifetime
-compiler.clang_lifetime.notification=Lifetime profile checker based on Herb Sutter's paper; see <a href="https://herbsutter.com/2018/09/20/lifetime-profile-v1-0-posted/" target="_blank" rel="noopener noreferrer">this blog post <sup><small class="glyphicon glyphicon-new-window opens-new-window" title="Opens in a new window"></small></sup></a> for more information
+compiler.clang_lifetime.notification=Lifetime profile checker based on Herb Sutter's paper; see <a href="https://herbsutter.com/2018/09/20/lifetime-profile-v1-0-posted/" target="_blank" rel="noopener noreferrer">this blog post <sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a> for more information
+compiler.clang_parmexpr.exe=/opt/compiler-explorer/clang-parmexpr-trunk/bin/clang++
+compiler.clang_pamrexpr.semver=(experimental P1221)
+compiler.clang_parmexpr.options=-std=c++2a -stdlib=libc++
+compiler.clang_parmexpr.notification=Experimental Parametric Expressions; see <a href="https://github.com/ricejasonf/parametric_expressions/blob/master/d1221.md" target="_blank" rel="noopener noreferrer">P1221<sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
# Clang for RISC-V
group.rvclang.compilers=rv32clang
@@ -431,6 +435,24 @@ compiler.ellcc0134.alias=elcc0134
#################################
+# DJGGP
+group.djggp.compilers=djggp494:djggp550:djggp640:djggp720
+group.djggp.groupName=DJGGP x86
+group.djggp.baseName=x86 djggp
+group.djggp.isSemVer=true
+group.djggp.demangler=
+group.djggp.supportsBinary=false
+compiler.djggp720.exe=/opt/compiler-explorer/djgpp-7.2.0/bin/i586-pc-msdosdjgpp-g++
+compiler.djggp720.semver=7.2.0
+compiler.djggp640.exe=/opt/compiler-explorer/djgpp-6.4.0/bin/i586-pc-msdosdjgpp-g++
+compiler.djggp640.semver=6.4.0
+compiler.djggp550.exe=/opt/compiler-explorer/djgpp-5.5.0/bin/i586-pc-msdosdjgpp-g++
+compiler.djggp550.semver=5.5.0
+compiler.djggp494.exe=/opt/compiler-explorer/djgpp-4.9.4/bin/i586-pc-msdosdjgpp-g++
+compiler.djggp494.semver=4.9.4
+
+
+#################################
#################################
# Installed libs
libs=boost:brigand:kvasir:cmcstl2:ctbignum:gsl:expected_lite:nlohmann_json:xtl:xsimd:xtensor:abseil:blaze:ctre:eigen:benchmark:rangesv3:dlib:libguarded:cppcoro:fmt:hfsm:glm:llvm:catch2:doctest:eastl:vcl:outcome:cnl:googletest
@@ -699,11 +721,11 @@ libs.cnl.url=https://github.com/johnmcfarlane/cnl
libs.cnl.versions=trunk
libs.cnl.versions.trunk.version=trunk
libs.cnl.versions.trunk.path=/opt/compiler-explorer/libs/cnl/include
-libs.googletest.name=Google Testing and Mocking framework
+libs.googletest.name=Google Test
libs.googletest.versions=trunk
libs.googletest.url=https://github.com/google/googletest
libs.googletest.versions.trunk.version=trunk
-libs.googletest.versions.trunk.path=/opt/compiler-explorer/libs/googletest/googletest/include/gtest:/opt/compiler-explorer/libs/googletest/googlemock/include/gmock
+libs.googletest.versions.trunk.path=/opt/compiler-explorer/libs/googletest/googletest/include:/opt/compiler-explorer/libs/googletest/googlemock/include
#################################
@@ -723,9 +745,10 @@ tools.llvm-mcatrunk.name=llvm-mca
tools.llvm-mcatrunk.exe=/opt/compiler-explorer/clang-trunk/bin/llvm-mca
tools.llvm-mcatrunk.type=postcompilation
tools.llvm-mcatrunk.class=llvm-mca-tool
-tools.llvm-mcatrunk.exclude=avr:rv32:arm:aarch:mips:msp:ppc:cl19:cl_new
+tools.llvm-mcatrunk.exclude=avr:rv32:arm:aarch:mips:msp:ppc:cl19:cl_new:djggp
tools.pahole.name=pahole
tools.pahole.exe=/opt/compiler-explorer/pahole/bin/pahole
tools.pahole.type=postcompilation
tools.pahole.class=pahole-tool
+tools.pahole.exclude=djggp
diff --git a/etc/config/c++.defaults.properties b/etc/config/c++.defaults.properties
index be0ef9f77..e11978c94 100644
--- a/etc/config/c++.defaults.properties
+++ b/etc/config/c++.defaults.properties
@@ -8,7 +8,7 @@ objdumper=objdump
#androidNdk=/opt/google/android-ndk-r9c
options=
supportsBinary=true
-binaryHideFuncRe=^(__.*|_(init|start|fini)|(de)?register_tm_clones|call_gmon_start|frame_dummy|\.plt.*)$
+binaryHideFuncRe=^(__.*|_(init|start|fini)|(de)?register_tm_clones|call_gmon_start|frame_dummy|\.plt.*|_dl_relocate_static_pie)$
needsMulti=false
stubRe=\bmain\b
stubText=int main(void){return 0;/*stub provided by Compiler Explorer*/}
diff --git a/etc/scripts/travis.sh b/etc/scripts/travis.sh
index 3f14176e5..30da1d1bc 100755
--- a/etc/scripts/travis.sh
+++ b/etc/scripts/travis.sh
@@ -30,7 +30,7 @@ get_gdc() {
build=$2
mkdir ${OPT}/gdc
pushd ${OPT}/gdc
- fetch https://s3.amazonaws.com/compiler-explorer/public/gdc-5.2.0%2B2.066.1.tar.xz | tar Jxf -
+ fetch https://gdcproject.org/downloads/binaries/${vers}/x86_64-linux-gnu/gdc-${vers}+${build}.tar.xz | tar Jxf -
popd
}
diff --git a/lib/base-compiler.js b/lib/base-compiler.js
index 7626b3c1a..ada1f38b3 100644
--- a/lib/base-compiler.js
+++ b/lib/base-compiler.js
@@ -495,7 +495,8 @@ class BaseCompiler {
.then(result => filters.demangle ? this.postProcessAsm(result, filters) : result)
.then(result => {
if (this.compiler.supportsCfg && backendOptions && backendOptions.produceCfg) {
- result.cfg = cfg.generateStructure(this.compiler.version, result.asm);
+ result.cfg = cfg.generateStructure(this.compiler.compilerType,
+ this.compiler.version, result.asm);
}
return result;
})
@@ -568,6 +569,7 @@ class BaseCompiler {
isCfgCompiler(compilerVersion) {
return compilerVersion.includes("clang") ||
compilerVersion.indexOf("g++") === 0 ||
+ compilerVersion.indexOf("gcc") === 0 ||
compilerVersion.indexOf("gdc") === 0;
}
diff --git a/lib/cfg.js b/lib/cfg.js
index 96b29bffb..9305b6a7e 100644
--- a/lib/cfg.js
+++ b/lib/cfg.js
@@ -22,7 +22,8 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
const _ = require('underscore'),
- logger = require('./logger').logger;
+ logger = require('./logger').logger,
+ utils = require('./utils');
const InstructionType_jmp = 0;
const InstructionType_conditionalJmpInst = 1;
@@ -65,7 +66,7 @@ const clangX86 = {
const removeComments = x => {
const pos = x.text.indexOf('#');
if (pos !== -1)
- x.text = x.text.substring(0, pos - 1);
+ x.text = utils.trimRight(x.text.substring(0, pos));
return x;
};
@@ -273,9 +274,17 @@ function makeEdges(asmArr, arrOfCanonicalBasicBlock, rules) {
return edges;
}
+function isLLVMBased(compilerType, version) {
+ return version.includes('clang') ||
+ version.includes('LLVM') ||
+ version.includes('rustc') ||
+ compilerType === 'swift' ||
+ compilerType === 'zig' ||
+ compilerType === 'ispc';
+}
-function generateCfgStructure(version, asmArr) {
- const rules = (version.includes('clang') || version.includes('LLVM')) ? clangX86 : gccX86;
+function generateCfgStructure(compilerType, version, asmArr) {
+ const rules = isLLVMBased(compilerType, version) ? clangX86 : gccX86;
const code = rules.filterData(asmArr);
const funcs = splitToFunctions(code, rules.isFunctionEnd);
if (!funcs.length) {
diff --git a/lib/compilers/ispc.js b/lib/compilers/ispc.js
index 0ad177ecf..bb571dd8a 100644
--- a/lib/compilers/ispc.js
+++ b/lib/compilers/ispc.js
@@ -33,6 +33,10 @@ class ISPCCompiler extends BaseCompiler {
getArgumentParser() {
return argumentParsers.ISPC;
}
+
+ isCfgCompiler(/*compilerVersion*/) {
+ return true;
+ }
}
module.exports = ISPCCompiler;
diff --git a/lib/compilers/rust.js b/lib/compilers/rust.js
index 7715acf49..b0e51635c 100644
--- a/lib/compilers/rust.js
+++ b/lib/compilers/rust.js
@@ -50,6 +50,10 @@ class RustCompiler extends BaseCompiler {
getArgumentParser() {
return argumentParsers.Clang;
}
+
+ isCfgCompiler(/*compilerVersion*/) {
+ return true;
+ }
}
module.exports = RustCompiler;
diff --git a/lib/compilers/swift.js b/lib/compilers/swift.js
index 8a25ae949..71934d7e8 100644
--- a/lib/compilers/swift.js
+++ b/lib/compilers/swift.js
@@ -29,6 +29,10 @@ class SwiftCompiler extends BaseCompiler {
getArgumentParser() {
return argumentParsers.Clang;
}
+
+ isCfgCompiler(/*compilerVersion*/) {
+ return true;
+ }
}
module.exports = SwiftCompiler;
diff --git a/lib/compilers/zig.js b/lib/compilers/zig.js
index 52e67c8b0..396676c77 100644
--- a/lib/compilers/zig.js
+++ b/lib/compilers/zig.js
@@ -84,6 +84,10 @@ class ZigCompiler extends BaseCompiler {
const blacklist = /^(((--(cache-dir|name|output|verbose))|(-mllvm)).*)$/;
return _.filter(userOptions, option => !blacklist.test(option));
}
+
+ isCfgCompiler(/*compilerVersion*/) {
+ return true;
+ }
}
module.exports = ZigCompiler;
diff --git a/lib/utils.js b/lib/utils.js
index ce5fa5f21..8af638d3c 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -87,6 +87,14 @@ function padRight(name, len) {
exports.padRight = padRight;
+function trimRight(name) {
+ var l = name.length;
+ while (l > 0 && name[l-1] === ' ') l -= 1;
+ return name.substr(0, l);
+}
+
+exports.trimRight = trimRight;
+
/***
* Anonymizes given IP.
* For IPv4, it removes the last octet
diff --git a/static/thanks.html b/static/thanks.html
index 99d675ce7..4a69eb33c 100644
--- a/static/thanks.html
+++ b/static/thanks.html
@@ -76,6 +76,9 @@
<li>TocarIP</li>
<li>Solid Sands</li>
<li>Shane Clifford</li>
+ <li>Travis Geiselbrecht</li>
+ <li>Chris Kennelly</li>
+ <li>Tom Hulton-Harrop</li>
<li>Adenilson Cavalcanti</li>
<li>Wojciech Bartnik</li>
<li>Richard Powell</li>
diff --git a/test/cases/cfg-clang.split.json b/test/cases/cfg-clang.split.json
new file mode 100644
index 000000000..0298e01dc
--- /dev/null
+++ b/test/cases/cfg-clang.split.json
@@ -0,0 +1,190 @@
+{
+ "asm": [
+ {
+ "text": "remove_space(char const*, char*, unsigned long): # @remove_space(char const*, char*, unsigned long)",
+ "source": null
+ },
+ {
+ "text": " testq %rdx, %rdx",
+ "source": null
+ },
+ {
+ "text": " je .LBB0_6",
+ "source": null
+ },
+ {
+ "text": " xorl %eax, %eax",
+ "source": null
+ },
+ {
+ "text": ".LBB0_2: # =>This Inner Loop Header: Depth=1",
+ "source": null
+ },
+ {
+ "text": " movzbl (%rdi,%rax), %ecx",
+ "source": null
+ },
+ {
+ "text": " cmpb $97, %cl",
+ "source": null
+ },
+ {
+ "text": " je .LBB0_5",
+ "source": null
+ },
+ {
+ "text": " cmpb $122, %cl",
+ "source": null
+ },
+ {
+ "text": " je .LBB0_5",
+ "source": null
+ },
+ {
+ "text": " movb %cl, (%rsi)",
+ "source": null
+ },
+ {
+ "text": " addq $1, %rsi",
+ "source": null
+ },
+ {
+ "text": ".LBB0_5: # in Loop: Header=BB0_2 Depth=1",
+ "source": null
+ },
+ {
+ "text": " addq $1, %rax",
+ "source": null
+ },
+ {
+ "text": " cmpq %rax, %rdx",
+ "source": null
+ },
+ {
+ "text": " jne .LBB0_2",
+ "source": null
+ },
+ {
+ "text": ".LBB0_6:",
+ "source": null
+ },
+ {
+ "text": " movq %rsi, %rax",
+ "source": null
+ },
+ {
+ "text": " retq",
+ "source": null
+ }
+ ],
+ "cfg": {
+ "remove_space(char const*, char*, unsigned long):": {
+ "nodes": [
+ {
+ "id": "remove_space(char const*, char*, unsigned long):",
+ "label": "remove_space(char const*, char*, unsigned long):\n testq %rdx, %rdx\n je .LBB0_6",
+ "color": "#99ccff",
+ "shape": "box"
+ },
+ {
+ "id": "remove_space(char const*, char*, unsigned long):@3",
+ "label": "remove_space(char const*, char*, unsigned long):@3\n xorl %eax, %eax",
+ "color": "#99ccff",
+ "shape": "box"
+ },
+ {
+ "color": "#99ccff",
+ "id": ".LBB0_2:",
+ "label": ".LBB0_2:\n movzbl (%rdi,%rax), %ecx\n cmpb $97, %cl\n je .LBB0_5",
+ "shape": "box"
+ },
+ {
+ "color": "#99ccff",
+ "id": ".LBB0_2:@8",
+ "label": ".LBB0_2:@8\n cmpb $122, %cl\n je .LBB0_5",
+ "shape": "box"
+ },
+ {
+ "color": "#99ccff",
+ "id": ".LBB0_2:@10",
+ "label": ".LBB0_2:@10\n movb %cl, (%rsi)\n addq $1, %rsi",
+ "shape": "box"
+ },
+ {
+ "color": "#99ccff",
+ "id": ".LBB0_5:",
+ "label": ".LBB0_5:\n addq $1, %rax\n cmpq %rax, %rdx\n jne .LBB0_2",
+ "shape": "box"
+ },
+ {
+ "color": "#99ccff",
+ "id": ".LBB0_6:",
+ "label": ".LBB0_6:\n movq %rsi, %rax\n retq",
+ "shape": "box"
+ }
+ ],
+ "edges": [
+ {
+ "arrows": "to",
+ "color": "green",
+ "from": "remove_space(char const*, char*, unsigned long):",
+ "to": ".LBB0_6:"
+ },
+ {
+ "arrows": "to",
+ "color": "red",
+ "from": "remove_space(char const*, char*, unsigned long):",
+ "to": "remove_space(char const*, char*, unsigned long):@3"
+ },
+ {
+ "arrows": "to",
+ "color": "grey",
+ "from": "remove_space(char const*, char*, unsigned long):@3",
+ "to": ".LBB0_2:"
+ },
+ {
+ "arrows": "to",
+ "color": "green",
+ "from": ".LBB0_2:",
+ "to": ".LBB0_5:"
+ },
+ {
+ "arrows": "to",
+ "color": "red",
+ "from": ".LBB0_2:",
+ "to": ".LBB0_2:@8"
+ },
+ {
+ "arrows": "to",
+ "color": "green",
+ "from": ".LBB0_2:@8",
+ "to": ".LBB0_5:"
+ },
+ {
+ "arrows": "to",
+ "color": "red",
+ "from": ".LBB0_2:@8",
+ "to": ".LBB0_2:@10"
+ },
+ {
+ "arrows": "to",
+ "color": "grey",
+ "from": ".LBB0_2:@10",
+ "to": ".LBB0_5:"
+ },
+ {
+ "arrows": "to",
+ "color": "green",
+ "from": ".LBB0_5:",
+ "to": ".LBB0_2:"
+ },
+ {
+ "arrows": "to",
+ "color": "red",
+ "from": ".LBB0_5:",
+ "to": ".LBB0_6:"
+ }
+ ]
+ }
+ }
+}
diff --git a/test/cfg-tests.js b/test/cfg-tests.js
index 49c721aea..785e5554a 100644
--- a/test/cfg-tests.js
+++ b/test/cfg-tests.js
@@ -38,7 +38,7 @@ function common(cases, filterArg, cfgArg) {
const file = fs.readFileSync(filename, 'utf-8');
if (file) {
const contents = JSON.parse(file);
- assert.deepEqual(cfg.generateStructure(cfgArg, contents.asm), contents.cfg, `${filename}`);
+ assert.deepEqual(cfg.generateStructure('', cfgArg, contents.asm), contents.cfg, `${filename}`);
}
});
}
diff --git a/test/utils-tests.js b/test/utils-tests.js
index 7a0f5dafe..1e15e5f3f 100644
--- a/test/utils-tests.js
+++ b/test/utils-tests.js
@@ -187,6 +187,16 @@ describe('Pads right', () => {
});
});
+describe('Trim right', () => {
+ it('works', () => {
+ utils.trimRight(' ').should.equal('');
+ utils.trimRight('').should.equal('');
+ utils.trimRight(' ab ').should.equal(' ab');
+ utils.trimRight(' a b ').should.equal(' a b');
+ utils.trimRight('a ').should.equal('a');
+ });
+});
+
describe('Anonymizes all kind of IPs', () => {
it('Ignores localhost', () => {
utils.anonymizeIp('localhost').should.equal('localhost');