@jdeighan/coffee-utils 4.1.11 → 4.1.15
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +2 -1
- package/src/UnitTester.coffee +5 -1
- package/src/UnitTester.js +6 -1
- package/src/block_utils.coffee +1 -4
- package/src/block_utils.js +1 -5
- package/src/call_stack.coffee +43 -0
- package/src/call_stack.js +49 -0
- package/src/coffee_utils.coffee +7 -1
- package/src/coffee_utils.js +6 -1
- package/src/debug_utils.coffee +77 -91
- package/src/debug_utils.js +90 -87
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@jdeighan/coffee-utils",
|
3
3
|
"type": "module",
|
4
|
-
"version": "4.1.
|
4
|
+
"version": "4.1.15",
|
5
5
|
"description": "A set of utility functions for CoffeeScript",
|
6
6
|
"main": "coffee_utils.js",
|
7
7
|
"exports": {
|
@@ -10,6 +10,7 @@
|
|
10
10
|
"./log": "./src/log_utils.js",
|
11
11
|
"./block": "./src/block_utils.js",
|
12
12
|
"./indent": "./src/indent_utils.js",
|
13
|
+
"./stack": "./src/call_stack.js",
|
13
14
|
"./debug": "./src/debug_utils.js",
|
14
15
|
"./svelte": "./src/svelte_utils.js",
|
15
16
|
"./test": "./src/UnitTester.js",
|
package/src/UnitTester.coffee
CHANGED
@@ -176,6 +176,10 @@ export class UnitTester
|
|
176
176
|
assert isInteger(lineNum),
|
177
177
|
"UnitTester.test(): arg 1 must be an integer"
|
178
178
|
|
179
|
+
if process.env.TEST_LINE_NUMBER
|
180
|
+
if Math.abs(lineNum) != parseInt(process.env.TEST_LINE_NUMBER)
|
181
|
+
return
|
182
|
+
|
179
183
|
@initialize()
|
180
184
|
@lineNum = lineNum # set an object property
|
181
185
|
|
@@ -196,7 +200,7 @@ export class UnitTester
|
|
196
200
|
got = @normalize(got)
|
197
201
|
catch err
|
198
202
|
errMsg = err.message || 'UNKNOWN ERROR'
|
199
|
-
log "got ERROR: #{errMsg}"
|
203
|
+
log "got ERROR in unit test: #{errMsg}"
|
200
204
|
|
201
205
|
expected = @transformExpected(expected)
|
202
206
|
if isString(expected)
|
package/src/UnitTester.js
CHANGED
@@ -186,6 +186,11 @@ export var UnitTester = class UnitTester {
|
|
186
186
|
test(lineNum, input, expected) {
|
187
187
|
var err, errMsg, got, whichTest;
|
188
188
|
assert(isInteger(lineNum), "UnitTester.test(): arg 1 must be an integer");
|
189
|
+
if (process.env.TEST_LINE_NUMBER) {
|
190
|
+
if (Math.abs(lineNum) !== parseInt(process.env.TEST_LINE_NUMBER)) {
|
191
|
+
return;
|
192
|
+
}
|
193
|
+
}
|
189
194
|
this.initialize();
|
190
195
|
this.lineNum = lineNum; // set an object property
|
191
196
|
if ((lineNum < 0) && process.env.FINALTEST) {
|
@@ -207,7 +212,7 @@ export var UnitTester = class UnitTester {
|
|
207
212
|
} catch (error1) {
|
208
213
|
err = error1;
|
209
214
|
errMsg = err.message || 'UNKNOWN ERROR';
|
210
|
-
log(`got ERROR: ${errMsg}`);
|
215
|
+
log(`got ERROR in unit test: ${errMsg}`);
|
211
216
|
}
|
212
217
|
expected = this.transformExpected(expected);
|
213
218
|
if (isString(expected)) {
|
package/src/block_utils.coffee
CHANGED
@@ -86,10 +86,7 @@ export joinBlocks = (lBlocks...) ->
|
|
86
86
|
|
87
87
|
lNonEmptyBlocks = []
|
88
88
|
for block in lBlocks
|
89
|
-
|
90
|
-
log "NOT A BLOCK"
|
91
|
-
log 'bad block', block
|
92
|
-
process.exit()
|
89
|
+
assert isString(block), "joinBlocks(): #{block} is not a string"
|
93
90
|
if nonEmpty(block)
|
94
91
|
lNonEmptyBlocks.push block
|
95
92
|
return lNonEmptyBlocks.join('\n')
|
package/src/block_utils.js
CHANGED
@@ -110,11 +110,7 @@ export var joinBlocks = function(...lBlocks) {
|
|
110
110
|
lNonEmptyBlocks = [];
|
111
111
|
for (i = 0, len1 = lBlocks.length; i < len1; i++) {
|
112
112
|
block = lBlocks[i];
|
113
|
-
|
114
|
-
log("NOT A BLOCK");
|
115
|
-
log('bad block', block);
|
116
|
-
process.exit();
|
117
|
-
}
|
113
|
+
assert(isString(block), `joinBlocks(): ${block} is not a string`);
|
118
114
|
if (nonEmpty(block)) {
|
119
115
|
lNonEmptyBlocks.push(block);
|
120
116
|
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# call_stack.coffee
|
2
|
+
|
3
|
+
import {undef, croak} from '@jdeighan/coffee-utils'
|
4
|
+
import {log} from '@jdeighan/coffee-utils/log'
|
5
|
+
|
6
|
+
# ---------------------------------------------------------------------------
|
7
|
+
|
8
|
+
export class CallStack
|
9
|
+
|
10
|
+
constructor: () ->
|
11
|
+
|
12
|
+
@reset()
|
13
|
+
|
14
|
+
# ........................................................................
|
15
|
+
|
16
|
+
call: (funcName, hInfo) ->
|
17
|
+
|
18
|
+
@lStack.push({funcName, hInfo})
|
19
|
+
return
|
20
|
+
|
21
|
+
# ........................................................................
|
22
|
+
|
23
|
+
returnFrom: (fName) ->
|
24
|
+
|
25
|
+
{funcName, hInfo} = @lStack.pop()
|
26
|
+
if funcName != fName
|
27
|
+
croak "returnFrom('#{fName}') but TOS is '#{funcName}'"
|
28
|
+
return hInfo
|
29
|
+
|
30
|
+
# ........................................................................
|
31
|
+
|
32
|
+
reset: () ->
|
33
|
+
|
34
|
+
@lStack = []
|
35
|
+
|
36
|
+
# ........................................................................
|
37
|
+
|
38
|
+
dump: (label='CALL STACK') ->
|
39
|
+
|
40
|
+
log "#{label}:"
|
41
|
+
for item, i in @lStack
|
42
|
+
log "#{i}: #{JSON.stringify(item)}"
|
43
|
+
return
|
@@ -0,0 +1,49 @@
|
|
1
|
+
// Generated by CoffeeScript 2.6.1
|
2
|
+
// call_stack.coffee
|
3
|
+
import {
|
4
|
+
undef,
|
5
|
+
croak
|
6
|
+
} from '@jdeighan/coffee-utils';
|
7
|
+
|
8
|
+
import {
|
9
|
+
log
|
10
|
+
} from '@jdeighan/coffee-utils/log';
|
11
|
+
|
12
|
+
// ---------------------------------------------------------------------------
|
13
|
+
export var CallStack = class CallStack {
|
14
|
+
constructor() {
|
15
|
+
this.reset();
|
16
|
+
}
|
17
|
+
|
18
|
+
// ........................................................................
|
19
|
+
call(funcName, hInfo) {
|
20
|
+
this.lStack.push({funcName, hInfo});
|
21
|
+
}
|
22
|
+
|
23
|
+
// ........................................................................
|
24
|
+
returnFrom(fName) {
|
25
|
+
var funcName, hInfo;
|
26
|
+
({funcName, hInfo} = this.lStack.pop());
|
27
|
+
if (funcName !== fName) {
|
28
|
+
croak(`returnFrom('${fName}') but TOS is '${funcName}'`);
|
29
|
+
}
|
30
|
+
return hInfo;
|
31
|
+
}
|
32
|
+
|
33
|
+
// ........................................................................
|
34
|
+
reset() {
|
35
|
+
return this.lStack = [];
|
36
|
+
}
|
37
|
+
|
38
|
+
// ........................................................................
|
39
|
+
dump(label = 'CALL STACK') {
|
40
|
+
var i, item, j, len, ref;
|
41
|
+
log(`${label}:`);
|
42
|
+
ref = this.lStack;
|
43
|
+
for (i = j = 0, len = ref.length; j < len; i = ++j) {
|
44
|
+
item = ref[i];
|
45
|
+
log(`${i}: ${JSON.stringify(item)}`);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
};
|
package/src/coffee_utils.coffee
CHANGED
@@ -34,7 +34,7 @@ export assert = (cond, msg) ->
|
|
34
34
|
export croak = (err, label, obj) ->
|
35
35
|
|
36
36
|
message = if (typeof err == 'object') then err.message else err
|
37
|
-
log "ERROR: #{message}"
|
37
|
+
log "ERROR (croak): #{message}"
|
38
38
|
log label, obj
|
39
39
|
if (typeof err == 'object')
|
40
40
|
throw err
|
@@ -74,6 +74,12 @@ export isString = (x) ->
|
|
74
74
|
|
75
75
|
# ---------------------------------------------------------------------------
|
76
76
|
|
77
|
+
export isBoolean = (x) ->
|
78
|
+
|
79
|
+
return typeof x == 'boolean'
|
80
|
+
|
81
|
+
# ---------------------------------------------------------------------------
|
82
|
+
|
77
83
|
export isNumber = (x) ->
|
78
84
|
|
79
85
|
return typeof x == 'number' || x instanceof Number
|
package/src/coffee_utils.js
CHANGED
@@ -37,7 +37,7 @@ export var assert = function(cond, msg) {
|
|
37
37
|
export var croak = function(err, label, obj) {
|
38
38
|
var message;
|
39
39
|
message = (typeof err === 'object') ? err.message : err;
|
40
|
-
log(`ERROR: ${message}`);
|
40
|
+
log(`ERROR (croak): ${message}`);
|
41
41
|
log(label, obj);
|
42
42
|
if (typeof err === 'object') {
|
43
43
|
throw err;
|
@@ -77,6 +77,11 @@ export var isString = function(x) {
|
|
77
77
|
return typeof x === 'string' || x instanceof String;
|
78
78
|
};
|
79
79
|
|
80
|
+
// ---------------------------------------------------------------------------
|
81
|
+
export var isBoolean = function(x) {
|
82
|
+
return typeof x === 'boolean';
|
83
|
+
};
|
84
|
+
|
80
85
|
// ---------------------------------------------------------------------------
|
81
86
|
export var isNumber = function(x) {
|
82
87
|
return typeof x === 'number' || x instanceof Number;
|
package/src/debug_utils.coffee
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# debug_utils.coffee
|
2
2
|
|
3
3
|
import {
|
4
|
-
assert, undef, error, croak, warn,
|
5
|
-
oneline, escapeStr, isNumber, isArray,
|
4
|
+
assert, undef, error, croak, warn, isString, isFunction, isBoolean,
|
5
|
+
oneline, escapeStr, isNumber, isArray, words,
|
6
6
|
} from '@jdeighan/coffee-utils'
|
7
7
|
import {blockToArray} from '@jdeighan/coffee-utils/block'
|
8
8
|
import {log, setLogger} from '@jdeighan/coffee-utils/log'
|
9
9
|
import {slurp} from '@jdeighan/coffee-utils/fs'
|
10
|
+
import {CallStack} from '@jdeighan/coffee-utils/stack'
|
10
11
|
|
11
12
|
vbar = '│' # unicode 2502
|
12
13
|
hbar = '─' # unicode 2500
|
@@ -17,91 +18,105 @@ indent = vbar + ' '
|
|
17
18
|
arrow = corner + hbar + arrowhead + ' '
|
18
19
|
|
19
20
|
debugLevel = 0 # controls amount of indentation - we ensure it's never < 0
|
21
|
+
stdLogger = false
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
# --- These are saved/restored in lDebugStack
|
23
|
+
# --- These are saved/restored on the call stack
|
24
24
|
export debugging = false
|
25
|
-
|
26
|
-
lDebugFuncs = undef # --- names of functions to debug
|
25
|
+
shouldDebug = shouldLog = undef
|
27
26
|
|
28
|
-
|
27
|
+
stack = new CallStack()
|
29
28
|
|
30
29
|
# ---------------------------------------------------------------------------
|
31
30
|
|
32
|
-
export
|
31
|
+
export resetDebugging = (funcDoDebug=undef, funcDoLog=undef) ->
|
33
32
|
|
34
|
-
|
33
|
+
debugging = false
|
34
|
+
debugLevel = 0
|
35
|
+
stack.reset()
|
36
|
+
shouldDebug = (funcName) -> debugging
|
37
|
+
shouldLog = (str) -> debugging
|
38
|
+
if funcDoDebug
|
39
|
+
setDebugging funcDoDebug, funcDoLog
|
35
40
|
return
|
36
41
|
|
37
42
|
# ---------------------------------------------------------------------------
|
38
43
|
|
39
|
-
|
44
|
+
export setDebugging = (funcDoDebug=undef, funcDoLog=undef) ->
|
40
45
|
|
41
|
-
if
|
42
|
-
|
46
|
+
if isBoolean(funcDoDebug)
|
47
|
+
debugging = funcDoDebug
|
48
|
+
else if isString(funcDoDebug)
|
49
|
+
debugging = false
|
50
|
+
lFuncNames = words(funcDoDebug)
|
51
|
+
assert isArray(lFuncNames), "words('#{funcDoDebug}') returned non-array"
|
52
|
+
shouldDebug = (funcName) ->
|
53
|
+
debugging || funcMatch(funcName, lFuncNames)
|
54
|
+
else if isFunction(funcDoDebug)
|
55
|
+
shouldDebug = funcDoDebug
|
43
56
|
else
|
44
|
-
|
45
|
-
|
46
|
-
|
57
|
+
croak "setDebugging(): bad parameter #{oneline(funcDoDebug)}"
|
58
|
+
|
59
|
+
if funcDoLog
|
60
|
+
assert isFunction(funcDoLog), "setDebugging: arg 2 not a function"
|
61
|
+
shouldLog = funcDoLog
|
47
62
|
return
|
48
63
|
|
49
64
|
# ---------------------------------------------------------------------------
|
65
|
+
# --- export only to allow unit tests
|
50
66
|
|
51
|
-
|
67
|
+
export funcMatch = (curFunc, lFuncNames) ->
|
52
68
|
|
53
|
-
|
69
|
+
assert isString(curFunc), "funcMatch(): not a string"
|
70
|
+
assert isArray(lFuncNames), "funcMatch(): bad array #{lFuncNames}"
|
71
|
+
if lFuncNames.includes(curFunc)
|
72
|
+
return true
|
73
|
+
else if (lMatches = curFunc.match(reMethod)) \
|
74
|
+
&& ([_, cls, meth] = lMatches) \
|
75
|
+
&& lFuncNames.includes(meth)
|
76
|
+
return true
|
77
|
+
else
|
78
|
+
return false
|
54
79
|
|
55
80
|
# ---------------------------------------------------------------------------
|
56
81
|
|
57
|
-
|
82
|
+
curEnv = () ->
|
58
83
|
|
59
|
-
|
60
|
-
return
|
84
|
+
return {debugging, shouldDebug, shouldLog}
|
61
85
|
|
62
86
|
# ---------------------------------------------------------------------------
|
63
87
|
|
64
|
-
|
88
|
+
setEnv = (hEnv) ->
|
65
89
|
|
66
|
-
|
67
|
-
debugging,
|
68
|
-
ifMatches,
|
69
|
-
lDebugFuncs,
|
70
|
-
})
|
90
|
+
{debugging, shouldDebug, shouldLog} = hEnv
|
71
91
|
return
|
72
92
|
|
73
|
-
|
93
|
+
# ---------------------------------------------------------------------------
|
74
94
|
|
75
|
-
|
76
|
-
debugging = false
|
77
|
-
ifMatches = undef
|
78
|
-
lDebugFuncs = undef
|
79
|
-
else
|
80
|
-
h = lDebugStack.pop()
|
81
|
-
{debugging, ifMatches, lDebugFuncs} = h
|
95
|
+
export useStdLogger = (flag=true) ->
|
82
96
|
|
97
|
+
stdLogger = flag
|
83
98
|
return
|
84
99
|
|
85
100
|
# ---------------------------------------------------------------------------
|
86
101
|
|
87
|
-
|
102
|
+
logger = (lArgs...) ->
|
88
103
|
|
89
|
-
if
|
90
|
-
|
104
|
+
if stdLogger
|
105
|
+
log lArgs...
|
91
106
|
else
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
debugging = true
|
96
|
-
else if isString(x)
|
97
|
-
debugging = false
|
98
|
-
lDebugFuncs = words(x)
|
99
|
-
else
|
100
|
-
croak "setDebugging(): bad parameter #{oneline(x)}"
|
107
|
+
orgLogger = setLogger(console.log)
|
108
|
+
log lArgs...
|
109
|
+
setLogger(orgLogger)
|
101
110
|
return
|
102
111
|
|
103
112
|
# ---------------------------------------------------------------------------
|
104
113
|
|
114
|
+
stripArrow = (prefix) ->
|
115
|
+
|
116
|
+
return prefix.replace(arrow, ' ')
|
117
|
+
|
118
|
+
# ---------------------------------------------------------------------------
|
119
|
+
|
105
120
|
getPrefix = (level) ->
|
106
121
|
|
107
122
|
if (level < 0)
|
@@ -111,17 +126,6 @@ getPrefix = (level) ->
|
|
111
126
|
|
112
127
|
# ---------------------------------------------------------------------------
|
113
128
|
|
114
|
-
export resetDebugging = () ->
|
115
|
-
|
116
|
-
debugging = false
|
117
|
-
debugLevel = 0
|
118
|
-
ifMatches = undef
|
119
|
-
lDebugFuncs = undef
|
120
|
-
lDebugStack = []
|
121
|
-
return
|
122
|
-
|
123
|
-
# ---------------------------------------------------------------------------
|
124
|
-
|
125
129
|
export debug = (lArgs...) ->
|
126
130
|
# --- either 1 or 2 args
|
127
131
|
|
@@ -130,7 +134,7 @@ export debug = (lArgs...) ->
|
|
130
134
|
# when debugging is off
|
131
135
|
|
132
136
|
nArgs = lArgs.length
|
133
|
-
assert ((nArgs
|
137
|
+
assert ((nArgs == 1) || (nArgs == 2)), "debug(); Bad # args #{nArgs}"
|
134
138
|
str = lArgs[0]
|
135
139
|
|
136
140
|
# --- str must always be a string
|
@@ -153,21 +157,21 @@ export debug = (lArgs...) ->
|
|
153
157
|
///))
|
154
158
|
entering = true
|
155
159
|
curFunc = lMatches[1]
|
160
|
+
stack.call(curFunc, curEnv())
|
161
|
+
debugging = shouldDebug(curFunc, debugging)
|
156
162
|
else if (lMatches = str.match(///^
|
157
163
|
\s*
|
158
164
|
return
|
159
|
-
|
165
|
+
.+
|
160
166
|
from
|
161
167
|
\s+
|
162
168
|
([A-Za-z_][A-Za-z0-9_\.]*)
|
163
169
|
///))
|
164
170
|
returning = true
|
165
171
|
curFunc = lMatches[1]
|
172
|
+
hInfo = stack.returnFrom(curFunc)
|
166
173
|
|
167
|
-
if
|
168
|
-
setDebugging true
|
169
|
-
|
170
|
-
if debugging && (! ifMatches? || str.match(ifMatches))
|
174
|
+
if debugging && shouldLog(str)
|
171
175
|
|
172
176
|
# --- set the prefix, i.e. indentation to use
|
173
177
|
if returning
|
@@ -186,14 +190,15 @@ export debug = (lArgs...) ->
|
|
186
190
|
logItem: true,
|
187
191
|
itemPrefix: stripArrow(prefix),
|
188
192
|
}
|
189
|
-
if returning && (debugLevel > 0)
|
190
|
-
debugLevel -= 1
|
191
193
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
194
|
+
# --- Adjust debug level
|
195
|
+
if returning
|
196
|
+
if debugLevel > 0
|
197
|
+
debugLevel -= 1
|
198
|
+
setEnv(hInfo)
|
199
|
+
else if entering
|
200
|
+
if debugging
|
201
|
+
debugLevel += 1
|
197
202
|
return
|
198
203
|
|
199
204
|
# ---------------------------------------------------------------------------
|
@@ -204,21 +209,6 @@ reMethod = ///^
|
|
204
209
|
([A-Za-z_][A-Za-z0-9_]*)
|
205
210
|
$///
|
206
211
|
|
207
|
-
# ---------------------------------------------------------------------------
|
208
|
-
# --- export only to allow unit tests
|
209
|
-
|
210
|
-
export funcMatch = (curFunc) ->
|
211
|
-
|
212
|
-
assert isString(curFunc), "funcMatch(): not a string"
|
213
|
-
if lDebugFuncs.includes(curFunc)
|
214
|
-
return true
|
215
|
-
else if (lMatches = curFunc.match(reMethod)) \
|
216
|
-
&& ([_, cls, meth] = lMatches) \
|
217
|
-
&& lDebugFuncs.includes(meth)
|
218
|
-
return true
|
219
|
-
else
|
220
|
-
return false
|
221
|
-
|
222
212
|
# ---------------------------------------------------------------------------
|
223
213
|
|
224
214
|
export checkTrace = (block) ->
|
@@ -256,9 +246,5 @@ export checkTrace = (block) ->
|
|
256
246
|
return
|
257
247
|
|
258
248
|
# ---------------------------------------------------------------------------
|
259
|
-
# --- export only to allow unit tests
|
260
249
|
|
261
|
-
|
262
|
-
|
263
|
-
checkTrace(slurp(filepath))
|
264
|
-
return
|
250
|
+
resetDebugging()
|
package/src/debug_utils.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
// Generated by CoffeeScript 2.6.1
|
2
2
|
// debug_utils.coffee
|
3
|
-
var arrow, arrowhead, corner, debugLevel, getPrefix, hbar,
|
3
|
+
var arrow, arrowhead, corner, curEnv, debugLevel, getPrefix, hbar, indent, logger, reMethod, setEnv, shouldDebug, shouldLog, stack, stdLogger, stripArrow, vbar;
|
4
4
|
|
5
5
|
import {
|
6
6
|
assert,
|
@@ -8,13 +8,14 @@ import {
|
|
8
8
|
error,
|
9
9
|
croak,
|
10
10
|
warn,
|
11
|
-
words,
|
12
11
|
isString,
|
13
12
|
isFunction,
|
13
|
+
isBoolean,
|
14
14
|
oneline,
|
15
15
|
escapeStr,
|
16
16
|
isNumber,
|
17
|
-
isArray
|
17
|
+
isArray,
|
18
|
+
words
|
18
19
|
} from '@jdeighan/coffee-utils';
|
19
20
|
|
20
21
|
import {
|
@@ -30,6 +31,10 @@ import {
|
|
30
31
|
slurp
|
31
32
|
} from '@jdeighan/coffee-utils/fs';
|
32
33
|
|
34
|
+
import {
|
35
|
+
CallStack
|
36
|
+
} from '@jdeighan/coffee-utils/stack';
|
37
|
+
|
33
38
|
vbar = '│'; // unicode 2502
|
34
39
|
|
35
40
|
hbar = '─'; // unicode 2500
|
@@ -44,77 +49,99 @@ arrow = corner + hbar + arrowhead + ' ';
|
|
44
49
|
|
45
50
|
debugLevel = 0; // controls amount of indentation - we ensure it's never < 0
|
46
51
|
|
47
|
-
|
52
|
+
stdLogger = false;
|
48
53
|
|
49
|
-
// --- These are saved/restored
|
54
|
+
// --- These are saved/restored on the call stack
|
50
55
|
export var debugging = false;
|
51
56
|
|
52
|
-
|
57
|
+
shouldDebug = shouldLog = undef;
|
53
58
|
|
54
|
-
|
59
|
+
stack = new CallStack();
|
55
60
|
|
56
|
-
|
61
|
+
// ---------------------------------------------------------------------------
|
62
|
+
export var resetDebugging = function(funcDoDebug = undef, funcDoLog = undef) {
|
63
|
+
debugging = false;
|
64
|
+
debugLevel = 0;
|
65
|
+
stack.reset();
|
66
|
+
shouldDebug = function(funcName) {
|
67
|
+
return debugging;
|
68
|
+
};
|
69
|
+
shouldLog = function(str) {
|
70
|
+
return debugging;
|
71
|
+
};
|
72
|
+
if (funcDoDebug) {
|
73
|
+
setDebugging(funcDoDebug, funcDoLog);
|
74
|
+
}
|
75
|
+
};
|
57
76
|
|
58
77
|
// ---------------------------------------------------------------------------
|
59
|
-
export var
|
60
|
-
|
78
|
+
export var setDebugging = function(funcDoDebug = undef, funcDoLog = undef) {
|
79
|
+
var lFuncNames;
|
80
|
+
if (isBoolean(funcDoDebug)) {
|
81
|
+
debugging = funcDoDebug;
|
82
|
+
} else if (isString(funcDoDebug)) {
|
83
|
+
debugging = false;
|
84
|
+
lFuncNames = words(funcDoDebug);
|
85
|
+
assert(isArray(lFuncNames), `words('${funcDoDebug}') returned non-array`);
|
86
|
+
shouldDebug = function(funcName) {
|
87
|
+
return debugging || funcMatch(funcName, lFuncNames);
|
88
|
+
};
|
89
|
+
} else if (isFunction(funcDoDebug)) {
|
90
|
+
shouldDebug = funcDoDebug;
|
91
|
+
} else {
|
92
|
+
croak(`setDebugging(): bad parameter ${oneline(funcDoDebug)}`);
|
93
|
+
}
|
94
|
+
if (funcDoLog) {
|
95
|
+
assert(isFunction(funcDoLog), "setDebugging: arg 2 not a function");
|
96
|
+
shouldLog = funcDoLog;
|
97
|
+
}
|
61
98
|
};
|
62
99
|
|
63
100
|
// ---------------------------------------------------------------------------
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
101
|
+
// --- export only to allow unit tests
|
102
|
+
export var funcMatch = function(curFunc, lFuncNames) {
|
103
|
+
var _, cls, lMatches, meth;
|
104
|
+
assert(isString(curFunc), "funcMatch(): not a string");
|
105
|
+
assert(isArray(lFuncNames), `funcMatch(): bad array ${lFuncNames}`);
|
106
|
+
if (lFuncNames.includes(curFunc)) {
|
107
|
+
return true;
|
108
|
+
} else if ((lMatches = curFunc.match(reMethod)) && ([_, cls, meth] = lMatches) && lFuncNames.includes(meth)) {
|
109
|
+
return true;
|
68
110
|
} else {
|
69
|
-
|
70
|
-
log(...lArgs);
|
71
|
-
setLogger(orgLogger);
|
111
|
+
return false;
|
72
112
|
}
|
73
113
|
};
|
74
114
|
|
75
115
|
// ---------------------------------------------------------------------------
|
76
|
-
|
77
|
-
return
|
116
|
+
curEnv = function() {
|
117
|
+
return {debugging, shouldDebug, shouldLog};
|
78
118
|
};
|
79
119
|
|
80
120
|
// ---------------------------------------------------------------------------
|
81
|
-
|
82
|
-
|
121
|
+
setEnv = function(hEnv) {
|
122
|
+
({debugging, shouldDebug, shouldLog} = hEnv);
|
83
123
|
};
|
84
124
|
|
85
125
|
// ---------------------------------------------------------------------------
|
86
|
-
|
87
|
-
|
126
|
+
export var useStdLogger = function(flag = true) {
|
127
|
+
stdLogger = flag;
|
88
128
|
};
|
89
129
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
lDebugFuncs = undef;
|
130
|
+
// ---------------------------------------------------------------------------
|
131
|
+
logger = function(...lArgs) {
|
132
|
+
var orgLogger;
|
133
|
+
if (stdLogger) {
|
134
|
+
log(...lArgs);
|
96
135
|
} else {
|
97
|
-
|
98
|
-
(
|
136
|
+
orgLogger = setLogger(console.log);
|
137
|
+
log(...lArgs);
|
138
|
+
setLogger(orgLogger);
|
99
139
|
}
|
100
140
|
};
|
101
141
|
|
102
142
|
// ---------------------------------------------------------------------------
|
103
|
-
|
104
|
-
|
105
|
-
restoreDebugEnv();
|
106
|
-
} else {
|
107
|
-
// --- save current setting
|
108
|
-
saveDebugEnv();
|
109
|
-
if (x === true) {
|
110
|
-
debugging = true;
|
111
|
-
} else if (isString(x)) {
|
112
|
-
debugging = false;
|
113
|
-
lDebugFuncs = words(x);
|
114
|
-
} else {
|
115
|
-
croak(`setDebugging(): bad parameter ${oneline(x)}`);
|
116
|
-
}
|
117
|
-
}
|
143
|
+
stripArrow = function(prefix) {
|
144
|
+
return prefix.replace(arrow, ' ');
|
118
145
|
};
|
119
146
|
|
120
147
|
// ---------------------------------------------------------------------------
|
@@ -126,25 +153,16 @@ getPrefix = function(level) {
|
|
126
153
|
return ' '.repeat(level);
|
127
154
|
};
|
128
155
|
|
129
|
-
// ---------------------------------------------------------------------------
|
130
|
-
export var resetDebugging = function() {
|
131
|
-
debugging = false;
|
132
|
-
debugLevel = 0;
|
133
|
-
ifMatches = undef;
|
134
|
-
lDebugFuncs = undef;
|
135
|
-
lDebugStack = [];
|
136
|
-
};
|
137
|
-
|
138
156
|
// ---------------------------------------------------------------------------
|
139
157
|
export var debug = function(...lArgs) {
|
140
|
-
var curFunc, entering, item, lMatches, nArgs, prefix, returning, str;
|
158
|
+
var curFunc, entering, hInfo, item, lMatches, nArgs, prefix, returning, str;
|
141
159
|
// --- either 1 or 2 args
|
142
160
|
|
143
161
|
// --- We always need to manipulate the stack when we encounter
|
144
162
|
// either "enter X" or "return from X", so we can't short-circuit
|
145
163
|
// when debugging is off
|
146
164
|
nArgs = lArgs.length;
|
147
|
-
assert((nArgs
|
165
|
+
assert((nArgs === 1) || (nArgs === 2), `debug(); Bad # args ${nArgs}`);
|
148
166
|
str = lArgs[0];
|
149
167
|
// --- str must always be a string
|
150
168
|
// if 2 args, then str is meant to be a label for the item
|
@@ -158,14 +176,14 @@ export var debug = function(...lArgs) {
|
|
158
176
|
if ((lMatches = str.match(/^\s*enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
|
159
177
|
entering = true;
|
160
178
|
curFunc = lMatches[1];
|
161
|
-
|
179
|
+
stack.call(curFunc, curEnv());
|
180
|
+
debugging = shouldDebug(curFunc, debugging);
|
181
|
+
} else if ((lMatches = str.match(/^\s*return.+from\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
|
162
182
|
returning = true;
|
163
183
|
curFunc = lMatches[1];
|
184
|
+
hInfo = stack.returnFrom(curFunc);
|
164
185
|
}
|
165
|
-
if (
|
166
|
-
setDebugging(true);
|
167
|
-
}
|
168
|
-
if (debugging && ((ifMatches == null) || str.match(ifMatches))) {
|
186
|
+
if (debugging && shouldLog(str)) {
|
169
187
|
// --- set the prefix, i.e. indentation to use
|
170
188
|
if (returning) {
|
171
189
|
if (debugLevel === 0) {
|
@@ -185,35 +203,23 @@ export var debug = function(...lArgs) {
|
|
185
203
|
itemPrefix: stripArrow(prefix)
|
186
204
|
});
|
187
205
|
}
|
188
|
-
|
206
|
+
}
|
207
|
+
// --- Adjust debug level
|
208
|
+
if (returning) {
|
209
|
+
if (debugLevel > 0) {
|
189
210
|
debugLevel -= 1;
|
190
211
|
}
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
debugLevel += 1;
|
212
|
+
setEnv(hInfo);
|
213
|
+
} else if (entering) {
|
214
|
+
if (debugging) {
|
215
|
+
debugLevel += 1;
|
216
|
+
}
|
197
217
|
}
|
198
218
|
};
|
199
219
|
|
200
220
|
// ---------------------------------------------------------------------------
|
201
221
|
reMethod = /^([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)$/;
|
202
222
|
|
203
|
-
// ---------------------------------------------------------------------------
|
204
|
-
// --- export only to allow unit tests
|
205
|
-
export var funcMatch = function(curFunc) {
|
206
|
-
var _, cls, lMatches, meth;
|
207
|
-
assert(isString(curFunc), "funcMatch(): not a string");
|
208
|
-
if (lDebugFuncs.includes(curFunc)) {
|
209
|
-
return true;
|
210
|
-
} else if ((lMatches = curFunc.match(reMethod)) && ([_, cls, meth] = lMatches) && lDebugFuncs.includes(meth)) {
|
211
|
-
return true;
|
212
|
-
} else {
|
213
|
-
return false;
|
214
|
-
}
|
215
|
-
};
|
216
|
-
|
217
223
|
// ---------------------------------------------------------------------------
|
218
224
|
export var checkTrace = function(block) {
|
219
225
|
var funcName, i, lMatches, lStack, len, len1, line, ref;
|
@@ -244,7 +250,4 @@ export var checkTrace = function(block) {
|
|
244
250
|
};
|
245
251
|
|
246
252
|
// ---------------------------------------------------------------------------
|
247
|
-
|
248
|
-
export var checkTraceFile = function(filepath) {
|
249
|
-
checkTrace(slurp(filepath));
|
250
|
-
};
|
253
|
+
resetDebugging();
|