fixes #3 ; make callback on trigger
This commit is contained in:
parent
bf6a8f5b63
commit
31bca500a0
@ -13,10 +13,10 @@ p.property('i8', 'command');
|
|||||||
p.property('i8', 'type');
|
p.property('i8', 'type');
|
||||||
p.property('i32', 'size');
|
p.property('i32', 'size');
|
||||||
p.property('i32', 'time');
|
p.property('i32', 'time');
|
||||||
p.property('i32', 'start');
|
|
||||||
p.property('i32', 'stop');
|
|
||||||
p.property('ptr', 'trigger');
|
p.property('ptr', 'trigger');
|
||||||
p.property('ptr', 'info');
|
p.property('ptr', 'info');
|
||||||
|
p.property('ptr', 'emit');
|
||||||
|
p.property('ptr', 'napi_env');
|
||||||
|
|
||||||
const scopeIdentifierSpan = p.span(p.code.span('scopeIdentifierSpan'));
|
const scopeIdentifierSpan = p.span(p.code.span('scopeIdentifierSpan'));
|
||||||
const varSizeSpan = p.span(p.code.span('varSizeSpan'));
|
const varSizeSpan = p.span(p.code.span('varSizeSpan'));
|
||||||
|
32
bin/find.js
32
bin/find.js
@ -1,38 +1,52 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const EventEmitter = require('events').EventEmitter;
|
||||||
|
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
|
||||||
const lib = require('../index.js');
|
const lib = require('../index.js');
|
||||||
|
|
||||||
const dir = './tmp/';
|
const dir = './tmp/';
|
||||||
|
|
||||||
fs.readdir(dir).then(files => {
|
fs.readdir(dir).then(files => {
|
||||||
const tt0 = Date.now();
|
const tt0 = Date.now();
|
||||||
async.eachLimit(files, 2, (fileName, callback) => {
|
async.eachLimit(files, 1, (fileName, callback) => {
|
||||||
let len = 0;
|
let len = 0;
|
||||||
let chunks = 0;
|
let chunks = 0;
|
||||||
let goodChunks = 0;
|
let goodChunks = 0;
|
||||||
|
let start = 0;
|
||||||
|
let stop = 0;
|
||||||
const t0 = Date.now();
|
const t0 = Date.now();
|
||||||
|
|
||||||
|
const ee = new EventEmitter();
|
||||||
|
|
||||||
const cxt = lib.init();
|
const cxt = lib.init();
|
||||||
lib.setTrigger(cxt, 'D1');
|
lib.setTrigger(cxt, 'D1');
|
||||||
|
ee.on('trigger', time => {
|
||||||
|
if (time < 10) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (start == 0) {
|
||||||
|
start = time;
|
||||||
|
} else {
|
||||||
|
stop = time;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const s = fs.createReadStream(dir + fileName);
|
const s = fs.createReadStream(dir + fileName);
|
||||||
s.on('data', chunk => {
|
s.on('data', chunk => {
|
||||||
if (lib.execute(cxt, chunk) === 0) {
|
if (lib.execute(cxt, ee.emit.bind(ee), chunk) === 0) {
|
||||||
goodChunks++;
|
goodChunks++;
|
||||||
}
|
}
|
||||||
len += chunk.length;
|
len += chunk.length;
|
||||||
chunks++;
|
chunks++;
|
||||||
});
|
});
|
||||||
s.on('end', () => {
|
s.on('end', () => {
|
||||||
const info = lib.getInfo(cxt);
|
// const info = lib.getInfo(cxt);
|
||||||
// console.log(info);
|
// console.log(info);
|
||||||
console.log(
|
console.log(fileName, chunks, len, goodChunks, (stop - start),
|
||||||
fileName,
|
|
||||||
chunks,
|
|
||||||
len,
|
|
||||||
goodChunks,
|
|
||||||
info.stop - info.start,
|
|
||||||
((Date.now() - t0) / 1000 + 's')
|
((Date.now() - t0) / 1000 + 's')
|
||||||
);
|
);
|
||||||
callback();
|
callback();
|
||||||
|
@ -15,7 +15,7 @@ describe('basic', () => {
|
|||||||
});
|
});
|
||||||
it('fail: foo bar', done => {
|
it('fail: foo bar', done => {
|
||||||
const cxt = lib.init();
|
const cxt = lib.init();
|
||||||
expect(lib.execute(cxt, Buffer.from(' foo bar ???'))).to.eq(1);
|
expect(lib.execute(cxt, () => {}, Buffer.from(' foo bar ???'))).to.eq(1);
|
||||||
expect(lib.getInfo(cxt)).to.deep.eq({
|
expect(lib.getInfo(cxt)).to.deep.eq({
|
||||||
error: 1,
|
error: 1,
|
||||||
reason: 'Expected declaration command',
|
reason: 'Expected declaration command',
|
||||||
@ -23,15 +23,13 @@ describe('basic', () => {
|
|||||||
type: 0,
|
type: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
time: 0,
|
time: 0,
|
||||||
start: 0,
|
|
||||||
stop: 0,
|
|
||||||
trigger: ''
|
trigger: ''
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
it('$comment', done => {
|
it('$comment', done => {
|
||||||
const cxt = lib.init();
|
const cxt = lib.init();
|
||||||
expect(lib.execute(cxt, Buffer.from(
|
expect(lib.execute(cxt, () => {}, Buffer.from(
|
||||||
' \n $comment some text $end $comment more text $end ???'
|
' \n $comment some text $end $comment more text $end ???'
|
||||||
))).to.eq(1);
|
))).to.eq(1);
|
||||||
expect(lib.getInfo(cxt)).to.deep.eq({
|
expect(lib.getInfo(cxt)).to.deep.eq({
|
||||||
@ -41,15 +39,13 @@ describe('basic', () => {
|
|||||||
type: 0,
|
type: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
time: 0,
|
time: 0,
|
||||||
start: 0,
|
|
||||||
stop: 0,
|
|
||||||
trigger: ''
|
trigger: ''
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
it('$version', done => {
|
it('$version', done => {
|
||||||
const cxt = lib.init();
|
const cxt = lib.init();
|
||||||
expect(lib.execute(cxt, Buffer.from(
|
expect(lib.execute(cxt, () => {}, Buffer.from(
|
||||||
`
|
`
|
||||||
$version Generated by VerilatedVcd $end
|
$version Generated by VerilatedVcd $end
|
||||||
$date Wed Sep 18 22:59:07 2019
|
$date Wed Sep 18 22:59:07 2019
|
||||||
@ -65,7 +61,7 @@ $timescale 1ns $end
|
|||||||
|
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
`
|
`
|
||||||
))).to.eq(0); expect(lib.execute(cxt, Buffer.from(
|
))).to.eq(0); expect(lib.execute(cxt, () => {}, Buffer.from(
|
||||||
`
|
`
|
||||||
|
|
||||||
#1
|
#1
|
||||||
@ -83,17 +79,17 @@ b0000000011110000 {u
|
|||||||
b0000000000001111 {u
|
b0000000000001111 {u
|
||||||
`
|
`
|
||||||
))).to.eq(0);
|
))).to.eq(0);
|
||||||
expect(lib.getInfo(cxt)).to.deep.eq({
|
// expect(lib.getInfo(cxt)).to.deep.eq({
|
||||||
error: 0,
|
// error: 0,
|
||||||
reason: 'NO REASON',
|
// reason: 'NO REASON',
|
||||||
command: 19,
|
// command: 19,
|
||||||
type: 17,
|
// type: 17,
|
||||||
size: 64,
|
// size: 64,
|
||||||
time: 303,
|
// time: 303,
|
||||||
start: 300,
|
// start: 300,
|
||||||
stop: 303,
|
// stop: 303,
|
||||||
trigger: ''
|
// trigger: ''
|
||||||
});
|
// });
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
126
vcd.c
126
vcd.c
@ -11,8 +11,7 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define METHOD(name) \
|
#define METHOD(name) napi_value name(napi_env env, napi_callback_info info)
|
||||||
napi_value name(napi_env env, napi_callback_info info)
|
|
||||||
|
|
||||||
#define ASSERT(val, expr) \
|
#define ASSERT(val, expr) \
|
||||||
if (expr != napi_ok) { \
|
if (expr != napi_ok) { \
|
||||||
@ -33,22 +32,6 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ASSERT_EXTERNAL(name, var) { \
|
|
||||||
napi_valuetype valuetype; \
|
|
||||||
if (napi_typeof(env, name, &valuetype) != napi_ok) { \
|
|
||||||
napi_throw(env, name); \
|
|
||||||
return 0; \
|
|
||||||
} \
|
|
||||||
if (valuetype != napi_external) { \
|
|
||||||
napi_throw_type_error(env, 0, "Wrong arguments"); \
|
|
||||||
return 0; \
|
|
||||||
} \
|
|
||||||
if (napi_get_value_external(env, name, (void **)(&var)) != napi_ok) { \
|
|
||||||
napi_throw(env, name); \
|
|
||||||
return 0; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ASSERT_BUFFER(name, var, len) \
|
#define ASSERT_BUFFER(name, var, len) \
|
||||||
const char * var; \
|
const char * var; \
|
||||||
size_t len; \
|
size_t len; \
|
||||||
@ -65,49 +48,84 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define ASSERT_STRING(name, var) \
|
#define ASSERT_STRING(name, var) \
|
||||||
{ \
|
{ \
|
||||||
napi_value tmp; \
|
napi_value tmp; \
|
||||||
if (napi_coerce_to_string(env, name, &tmp) != napi_ok) { \
|
if (napi_coerce_to_string(env, name, &tmp) != napi_ok) { \
|
||||||
napi_throw(env, name); \
|
napi_throw(env, name); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
size_t result; \
|
size_t result; \
|
||||||
if (napi_get_value_string_latin1(env, tmp, var, 256, &result) != napi_ok) { \
|
if (napi_get_value_string_latin1(env, tmp, var, 256, &result) != napi_ok) { \
|
||||||
napi_throw(env, name); \
|
napi_throw(env, name); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ASSERT_EXTERNAL(name, var) { \
|
||||||
|
napi_valuetype valuetype; \
|
||||||
|
if (napi_typeof(env, name, &valuetype) != napi_ok) { \
|
||||||
|
napi_throw(env, name); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
if (valuetype != napi_external) { \
|
||||||
|
napi_throw_type_error(env, 0, "Wrong arguments"); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
if (napi_get_value_external(env, name, (void **)(&var)) != napi_ok) { \
|
||||||
|
napi_throw(env, name); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_FUNCTION(name, var) { \
|
||||||
|
napi_valuetype valuetype; \
|
||||||
|
if (napi_typeof(env, name, &valuetype) != napi_ok) { \
|
||||||
|
napi_throw(env, name); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
if (valuetype != napi_function) { \
|
||||||
|
napi_throw_type_error(env, 0, "Wrong arguments"); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
var = name; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// napi_value * var;
|
||||||
|
|
||||||
|
|
||||||
METHOD(init) {
|
METHOD(init) {
|
||||||
struct vcd_parser_s *state = malloc(sizeof *state);
|
struct vcd_parser_s *state = malloc(sizeof *state);
|
||||||
|
|
||||||
const int32_t error = vcd_parser_init(state);
|
const int32_t error = vcd_parser_init(state);
|
||||||
|
|
||||||
static char triggerString [256];
|
static char triggerString [256];
|
||||||
|
|
||||||
state->trigger = triggerString;
|
state->trigger = triggerString;
|
||||||
state->reason = "NO REASON";
|
state->reason = "NO REASON";
|
||||||
|
|
||||||
napi_value res;
|
napi_value res;
|
||||||
if (error) {
|
if (error) {
|
||||||
ASSERT(res, napi_create_int32(env, error, &res))
|
ASSERT(res, napi_create_int32(env, error, &res))
|
||||||
} else {
|
} else {
|
||||||
ASSERT(res, napi_create_external(env, state, 0, 0, &res))
|
ASSERT(res, napi_create_external(env, state, 0, 0, &res))
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(execute) {
|
METHOD(execute) {
|
||||||
ASSERT_ARGC(2)
|
ASSERT_ARGC(3)
|
||||||
struct vcd_parser_s *state;
|
struct vcd_parser_s *state;
|
||||||
ASSERT_EXTERNAL(args[0], state)
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
ASSERT_BUFFER(args[1], p, plen)
|
ASSERT_FUNCTION(args[1], state->emit)
|
||||||
|
ASSERT_BUFFER(args[2], p, plen)
|
||||||
|
|
||||||
const int32_t error = vcd_parser_execute(state, p, p + plen);
|
state->napi_env = env;
|
||||||
|
|
||||||
napi_value res;
|
const int32_t error = vcd_parser_execute(state, p, p + plen);
|
||||||
ASSERT(res, napi_create_int32(env, error, &res))
|
|
||||||
return res;
|
napi_value res;
|
||||||
|
ASSERT(res, napi_create_int32(env, error, &res))
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(getInfo) {
|
METHOD(getInfo) {
|
||||||
@ -115,7 +133,7 @@ METHOD(getInfo) {
|
|||||||
struct vcd_parser_s *state;
|
struct vcd_parser_s *state;
|
||||||
ASSERT_EXTERNAL(args[0], state)
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
|
|
||||||
napi_value infObj, error, reason, command, type, size, time, start, stop, trigger;
|
napi_value infObj, error, reason, command, type, size, time, trigger;
|
||||||
ASSERT(infObj, napi_create_object(env, &infObj))
|
ASSERT(infObj, napi_create_object(env, &infObj))
|
||||||
|
|
||||||
ASSERT(error, napi_create_int32(env, state->error, &error))
|
ASSERT(error, napi_create_int32(env, state->error, &error))
|
||||||
@ -136,12 +154,6 @@ METHOD(getInfo) {
|
|||||||
ASSERT(time, napi_create_int32(env, state->time, &time))
|
ASSERT(time, napi_create_int32(env, state->time, &time))
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "time", time))
|
ASSERT(infObj, napi_set_named_property(env, infObj, "time", time))
|
||||||
|
|
||||||
ASSERT(start, napi_create_int32(env, state->start, &start))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "start", start))
|
|
||||||
|
|
||||||
ASSERT(stop, napi_create_int32(env, state->stop, &stop))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "stop", stop))
|
|
||||||
|
|
||||||
ASSERT(trigger, napi_create_string_latin1(env, state->trigger, NAPI_AUTO_LENGTH, &trigger))
|
ASSERT(trigger, napi_create_string_latin1(env, state->trigger, NAPI_AUTO_LENGTH, &trigger))
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "trigger", trigger))
|
ASSERT(infObj, napi_set_named_property(env, infObj, "trigger", trigger))
|
||||||
|
|
||||||
|
39
vcd_spans.c
39
vcd_spans.c
@ -1,12 +1,16 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "vcd_parser.h"
|
#include "vcd_parser.h"
|
||||||
|
#include <node_api.h>
|
||||||
|
|
||||||
int stringEq (
|
int stringEq (
|
||||||
const unsigned char* gold,
|
const unsigned char* gold,
|
||||||
const unsigned char* p,
|
const unsigned char* p,
|
||||||
const unsigned char* endp
|
const unsigned char* endp
|
||||||
) {
|
) {
|
||||||
|
if (gold[0] == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
for (size_t i = 0; gold[i] != 0; i++) {
|
for (size_t i = 0; gold[i] != 0; i++) {
|
||||||
if (gold[i] != p[i]) {
|
if (gold[i] != p[i]) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -16,12 +20,10 @@ int stringEq (
|
|||||||
}
|
}
|
||||||
|
|
||||||
int commandSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
int commandSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
||||||
// printf("(%d:%d:%d:%d)(%.*s)\n", s->time, s->command, s->type, s->size, (int)(endp - p), p);
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int scopeIdentifierSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
int scopeIdentifierSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
||||||
// printf("{%.*s}", (int)(endp - p - 1), p);
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,16 +32,32 @@ int varSizeSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* en
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int idSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
// printf("{%.*s}", (int)(endp - p - 1), p);
|
if (stringEq((state->trigger), p, endp)) {
|
||||||
if (stringEq((s->trigger), p, endp)) {
|
napi_value undefined;
|
||||||
if (s->time < 10) {
|
if (napi_get_undefined(state->napi_env, &undefined) != napi_ok) {
|
||||||
|
napi_throw(state->napi_env, undefined);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (s->start == 0) {
|
|
||||||
s->start = s->time;
|
napi_value eventName;
|
||||||
} else {
|
if (napi_create_string_latin1(state->napi_env, "trigger", NAPI_AUTO_LENGTH, &eventName) != napi_ok) {
|
||||||
s->stop = s->time;
|
napi_throw(state->napi_env, eventName);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
napi_value eventPayload;
|
||||||
|
if (napi_create_int32(state->napi_env, state->time, &eventPayload) != napi_ok) {
|
||||||
|
napi_throw(state->napi_env, eventPayload);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
napi_value* argv[] = { &eventName, &eventPayload };
|
||||||
|
|
||||||
|
napi_value return_val;
|
||||||
|
if (napi_call_function(state->napi_env, undefined, state->emit, 2, *argv, &return_val) != napi_ok) {
|
||||||
|
napi_throw(state->napi_env, state->emit);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -52,6 +70,5 @@ int vectorSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* end
|
|||||||
|
|
||||||
int timeSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
int timeSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
||||||
s->time = strtol((const char *)p, (char **)&endp, 10);
|
s->time = strtol((const char *)p, (char **)&endp, 10);
|
||||||
// printf("%d\n", s->time);
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user