@jdeighan/coffee-utils 4.1.13 → 4.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -2
- package/src/call_stack.coffee +46 -0
- package/src/call_stack.js +53 -0
- package/src/coffee_utils.coffee +6 -0
- package/src/coffee_utils.js +5 -0
- 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.17",
|
|
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",
|
|
@@ -18,6 +19,9 @@
|
|
|
18
19
|
"engines": {
|
|
19
20
|
"node": ">=12.0.0"
|
|
20
21
|
},
|
|
22
|
+
"ava": {
|
|
23
|
+
"verbose": false
|
|
24
|
+
},
|
|
21
25
|
"scripts": {
|
|
22
26
|
"build": "cls && rm -f ./src/*.js && coffee -c ./src",
|
|
23
27
|
"old_pretest": "npm run build && rm -f ./test/*.js && rm -f ./test/*.coffee && cielo -fq ./test",
|
|
@@ -40,7 +44,7 @@
|
|
|
40
44
|
},
|
|
41
45
|
"homepage": "https://github.com/johndeighan/coffee-utils#readme",
|
|
42
46
|
"dependencies": {
|
|
43
|
-
"ava": "^
|
|
47
|
+
"ava": "^4.0.0",
|
|
44
48
|
"cross-env": "^7.0.3",
|
|
45
49
|
"js-yaml": "^4.1.0",
|
|
46
50
|
"readline-sync": "^1.4.10"
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
if @lStack.length == 0
|
|
26
|
+
croak "returnFrom('#{fName}') but stack is empty"
|
|
27
|
+
{funcName, hInfo} = @lStack.pop()
|
|
28
|
+
if funcName != fName
|
|
29
|
+
@dump()
|
|
30
|
+
croak "returnFrom('#{fName}') but TOS is '#{funcName}'"
|
|
31
|
+
return hInfo
|
|
32
|
+
|
|
33
|
+
# ........................................................................
|
|
34
|
+
|
|
35
|
+
reset: () ->
|
|
36
|
+
|
|
37
|
+
@lStack = []
|
|
38
|
+
|
|
39
|
+
# ........................................................................
|
|
40
|
+
|
|
41
|
+
dump: (label='CALL STACK') ->
|
|
42
|
+
|
|
43
|
+
console.log "#{label}:"
|
|
44
|
+
for item, i in @lStack
|
|
45
|
+
console.log "#{i}: #{JSON.stringify(item)}"
|
|
46
|
+
return
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
if (this.lStack.length === 0) {
|
|
27
|
+
croak(`returnFrom('${fName}') but stack is empty`);
|
|
28
|
+
}
|
|
29
|
+
({funcName, hInfo} = this.lStack.pop());
|
|
30
|
+
if (funcName !== fName) {
|
|
31
|
+
this.dump();
|
|
32
|
+
croak(`returnFrom('${fName}') but TOS is '${funcName}'`);
|
|
33
|
+
}
|
|
34
|
+
return hInfo;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ........................................................................
|
|
38
|
+
reset() {
|
|
39
|
+
return this.lStack = [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ........................................................................
|
|
43
|
+
dump(label = 'CALL STACK') {
|
|
44
|
+
var i, item, j, len, ref;
|
|
45
|
+
console.log(`${label}:`);
|
|
46
|
+
ref = this.lStack;
|
|
47
|
+
for (i = j = 0, len = ref.length; j < len; i = ++j) {
|
|
48
|
+
item = ref[i];
|
|
49
|
+
console.log(`${i}: ${JSON.stringify(item)}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
};
|
package/src/coffee_utils.coffee
CHANGED
|
@@ -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
|
@@ -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();
|