@jdeighan/coffee-utils 7.0.55 → 7.0.58
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/Debugging.md +6 -0
- package/package.json +1 -1
- package/src/call_stack.coffee +5 -5
- package/src/call_stack.js +6 -5
- package/src/debug_utils.coffee +119 -126
- package/src/debug_utils.js +136 -151
- package/src/log_utils.coffee +2 -2
- package/src/log_utils.js +2 -2
package/Debugging.md
ADDED
package/package.json
CHANGED
package/src/call_stack.coffee
CHANGED
|
@@ -105,7 +105,7 @@ export class CallStack
|
|
|
105
105
|
LOG "[<-- BACK #{fName}]"
|
|
106
106
|
|
|
107
107
|
if @lStack.length == 0
|
|
108
|
-
LOG "ERROR: returnFrom('#{
|
|
108
|
+
LOG "ERROR: returnFrom('#{fName}') but stack is empty"
|
|
109
109
|
return
|
|
110
110
|
|
|
111
111
|
{fullName, isLogged} = @lStack.pop()
|
|
@@ -155,10 +155,10 @@ export class CallStack
|
|
|
155
155
|
|
|
156
156
|
dump: (prefix='', label='CALL STACK') ->
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
lLines = ["#{label}:"]
|
|
159
159
|
if @lStack.length == 0
|
|
160
|
-
|
|
160
|
+
lLines.push " <EMPTY>"
|
|
161
161
|
else
|
|
162
162
|
for item, i in @lStack
|
|
163
|
-
|
|
164
|
-
return
|
|
163
|
+
lLines.push " #{i}: #{item.fullName} #{item.isLogged}"
|
|
164
|
+
return lLines.join("\n") + "\n"
|
package/src/call_stack.js
CHANGED
|
@@ -107,7 +107,7 @@ export var CallStack = class CallStack {
|
|
|
107
107
|
LOG(`[<-- BACK ${fName}]`);
|
|
108
108
|
}
|
|
109
109
|
if (this.lStack.length === 0) {
|
|
110
|
-
LOG(`ERROR: returnFrom('${
|
|
110
|
+
LOG(`ERROR: returnFrom('${fName}') but stack is empty`);
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
113
113
|
({fullName, isLogged} = this.lStack.pop());
|
|
@@ -160,17 +160,18 @@ export var CallStack = class CallStack {
|
|
|
160
160
|
// ........................................................................
|
|
161
161
|
// ........................................................................
|
|
162
162
|
dump(prefix = '', label = 'CALL STACK') {
|
|
163
|
-
var i, item, j, len, ref;
|
|
164
|
-
|
|
163
|
+
var i, item, j, lLines, len, ref;
|
|
164
|
+
lLines = [`${label}:`];
|
|
165
165
|
if (this.lStack.length === 0) {
|
|
166
|
-
|
|
166
|
+
lLines.push(" <EMPTY>");
|
|
167
167
|
} else {
|
|
168
168
|
ref = this.lStack;
|
|
169
169
|
for (i = j = 0, len = ref.length; j < len; i = ++j) {
|
|
170
170
|
item = ref[i];
|
|
171
|
-
|
|
171
|
+
lLines.push(` ${i}: ${item.fullName} ${item.isLogged}`);
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
|
+
return lLines.join("\n") + "\n";
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
};
|
package/src/debug_utils.coffee
CHANGED
|
@@ -17,15 +17,66 @@ import {
|
|
|
17
17
|
} from '@jdeighan/coffee-utils/log'
|
|
18
18
|
|
|
19
19
|
callStack = new CallStack()
|
|
20
|
-
doDebugDebug = false
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
# --- set in resetDebugging() and setDebugging()
|
|
22
|
+
export shouldLog = () -> undef
|
|
23
23
|
export lFuncList = []
|
|
24
24
|
|
|
25
|
+
# --- internal debugging
|
|
26
|
+
doDebugDebug = false
|
|
27
|
+
lFunctions = undef # --- only used when doDebugDebug is true
|
|
28
|
+
|
|
29
|
+
# ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
export setDebugDebugging = (value=true) ->
|
|
32
|
+
# --- value can be a boolean or string of words
|
|
33
|
+
|
|
34
|
+
if isBoolean(value)
|
|
35
|
+
doDebugDebug = value
|
|
36
|
+
else if isString(value)
|
|
37
|
+
doDebugDebug = true
|
|
38
|
+
lFunctions = words(value)
|
|
39
|
+
else
|
|
40
|
+
croak "Bad value: #{OL(value)}"
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
# ---------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
logif = (label, lObjects...) ->
|
|
46
|
+
|
|
47
|
+
if ! doDebugDebug
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
assert isString(label), "1st arg #{OL(label)} should be a string"
|
|
51
|
+
nObjects = lObjects.length
|
|
52
|
+
[type, funcName] = getType(label, nObjects)
|
|
53
|
+
|
|
54
|
+
level = callStack.getLevel()
|
|
55
|
+
prefix = getPrefix(level)
|
|
56
|
+
itemPrefix = removeLastVbar(prefix)
|
|
57
|
+
sep = dashes(itemPrefix, 40)
|
|
58
|
+
|
|
59
|
+
if (type == 'enter')
|
|
60
|
+
if defined(lFunctions) && (funcName not in lFunctions)
|
|
61
|
+
return
|
|
62
|
+
callStack.enter funcName
|
|
63
|
+
else if (type == 'return')
|
|
64
|
+
if defined(lFunctions) && (funcName not in lFunctions)
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
doTheLogging type, label, lObjects
|
|
68
|
+
|
|
69
|
+
if (type == 'return')
|
|
70
|
+
callStack.returnFrom funcName
|
|
71
|
+
|
|
72
|
+
return
|
|
73
|
+
|
|
25
74
|
# ---------------------------------------------------------------------------
|
|
26
75
|
|
|
27
76
|
export debug = (label, lObjects...) ->
|
|
28
77
|
|
|
78
|
+
logif "enter debug(#{OL(label)})", lObjects...
|
|
79
|
+
|
|
29
80
|
assert isString(label), "1st arg #{OL(label)} should be a string"
|
|
30
81
|
|
|
31
82
|
# --- We want to allow objects to be undef. Therefore, we need to
|
|
@@ -34,9 +85,11 @@ export debug = (label, lObjects...) ->
|
|
|
34
85
|
|
|
35
86
|
# --- funcName is only set for types 'enter' and 'return'
|
|
36
87
|
[type, funcName] = getType(label, nObjects)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
88
|
+
logif "type = #{OL(type)}"
|
|
89
|
+
logif "funcName = #{OL(funcName)}"
|
|
90
|
+
|
|
91
|
+
# --- function shouldLog() returns the (possibly modified) label
|
|
92
|
+
# if we should log this, else it returns undef
|
|
40
93
|
|
|
41
94
|
switch type
|
|
42
95
|
when 'enter'
|
|
@@ -47,65 +100,73 @@ export debug = (label, lObjects...) ->
|
|
|
47
100
|
when 'string'
|
|
48
101
|
label = shouldLog(label, type, undef, callStack)
|
|
49
102
|
assert (nObjects == 0),
|
|
50
|
-
"
|
|
103
|
+
"Objects not allowed for #{OL(type)}"
|
|
51
104
|
when 'objects'
|
|
52
105
|
label = shouldLog(label, type, undef, callStack)
|
|
53
106
|
assert (nObjects > 0),
|
|
54
|
-
"
|
|
55
|
-
doLog = defined(label)
|
|
107
|
+
"Objects required for #{OL(type)}"
|
|
56
108
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
LOG "doLog = #{OL(doLog)}"
|
|
109
|
+
assert (label == undef) || isString(label),
|
|
110
|
+
"label not a string: #{OL(label)}"
|
|
111
|
+
doLog = defined(label)
|
|
112
|
+
logif "doLog = #{OL(doLog)}"
|
|
113
|
+
logif "#{nObjects} objects"
|
|
63
114
|
|
|
64
115
|
if doLog
|
|
65
|
-
|
|
66
|
-
prefix = getPrefix(level)
|
|
67
|
-
|
|
68
|
-
if doDebugDebug
|
|
69
|
-
LOG "callStack", callStack
|
|
70
|
-
LOG "level = #{OL(level)}"
|
|
71
|
-
LOG "prefix = #{OL(prefix)}"
|
|
72
|
-
|
|
73
|
-
switch type
|
|
74
|
-
when 'enter'
|
|
75
|
-
log label, {prefix}
|
|
76
|
-
prefix = removeLastVbar(prefix)
|
|
77
|
-
for obj,i in lObjects
|
|
78
|
-
if (i > 0)
|
|
79
|
-
log dashes(prefix)
|
|
80
|
-
logItem undef, obj, {prefix}
|
|
81
|
-
when 'return'
|
|
82
|
-
log label, {prefix: addArrow(prefix)}
|
|
83
|
-
prefix = removeLastVbar(prefix)
|
|
84
|
-
for obj,i in lObjects
|
|
85
|
-
if (i > 0)
|
|
86
|
-
log dashes(prefix)
|
|
87
|
-
logItem undef, obj, {prefix}
|
|
88
|
-
when 'string'
|
|
89
|
-
log label, {prefix}
|
|
90
|
-
when 'objects'
|
|
91
|
-
if (nObjects==1) && shortEnough(label, lObjects[0])
|
|
92
|
-
logItem label, lObjects[0], {prefix}
|
|
93
|
-
else
|
|
94
|
-
if (label.indexOf(':') != label.length - 1)
|
|
95
|
-
label += ':'
|
|
96
|
-
log label, {prefix}
|
|
97
|
-
for obj in lObjects
|
|
98
|
-
logItem undef, obj, {prefix}
|
|
116
|
+
doTheLogging type, label, lObjects
|
|
99
117
|
|
|
100
118
|
if (type == 'enter') && doLog && (label.indexOf('call') == -1)
|
|
101
119
|
callStack.logCurFunc()
|
|
102
120
|
else if (type == 'return')
|
|
103
121
|
callStack.returnFrom funcName
|
|
104
122
|
|
|
123
|
+
logif "return from debug()"
|
|
105
124
|
return true # allow use in boolean expressions
|
|
106
125
|
|
|
107
126
|
# ---------------------------------------------------------------------------
|
|
108
127
|
|
|
128
|
+
export doTheLogging = (type, label, lObjects) ->
|
|
129
|
+
|
|
130
|
+
level = callStack.getLevel()
|
|
131
|
+
prefix = getPrefix(level)
|
|
132
|
+
itemPrefix = removeLastVbar(prefix)
|
|
133
|
+
sep = dashes(itemPrefix, 40)
|
|
134
|
+
assert isString(sep), "sep is not a string"
|
|
135
|
+
|
|
136
|
+
logif "callStack", callStack
|
|
137
|
+
logif "level = #{OL(level)}"
|
|
138
|
+
logif "prefix = #{OL(prefix)}"
|
|
139
|
+
logif "itemPrefix = #{OL(itemPrefix)}"
|
|
140
|
+
logif "sep = #{OL(sep)}"
|
|
141
|
+
|
|
142
|
+
switch type
|
|
143
|
+
when 'enter'
|
|
144
|
+
log label, {prefix}
|
|
145
|
+
for obj,i in lObjects
|
|
146
|
+
if (i > 0)
|
|
147
|
+
log sep
|
|
148
|
+
logItem undef, obj, {itemPrefix}
|
|
149
|
+
when 'return'
|
|
150
|
+
log label, {prefix: addArrow(prefix)}
|
|
151
|
+
for obj,i in lObjects
|
|
152
|
+
if (i > 0)
|
|
153
|
+
log sep
|
|
154
|
+
logItem undef, obj, {itemPrefix}
|
|
155
|
+
when 'string'
|
|
156
|
+
log label, {prefix}
|
|
157
|
+
when 'objects'
|
|
158
|
+
if (lObjects.length==1) && shortEnough(label, lObjects[0])
|
|
159
|
+
logItem label, lObjects[0], {prefix}
|
|
160
|
+
else
|
|
161
|
+
if (label.indexOf(':') != label.length - 1)
|
|
162
|
+
label += ':'
|
|
163
|
+
log label, {prefix}
|
|
164
|
+
for obj in lObjects
|
|
165
|
+
logItem undef, obj, {prefix}
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
# ---------------------------------------------------------------------------
|
|
169
|
+
|
|
109
170
|
export stdShouldLog = (label, type, funcName, stack) ->
|
|
110
171
|
# --- if type is 'enter', then funcName won't be on the stack yet
|
|
111
172
|
# returns the (possibly modified) label to log
|
|
@@ -122,10 +183,9 @@ export stdShouldLog = (label, type, funcName, stack) ->
|
|
|
122
183
|
assert funcName == undef, "func name #{OL(funcName)} not undef"
|
|
123
184
|
assert stack instanceof CallStack, "not a call stack object"
|
|
124
185
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
LOG "lFuncList", lFuncList
|
|
186
|
+
logif "stdShouldLog(#{OL(label)}, #{OL(type)}, #{OL(funcName)}, stack)"
|
|
187
|
+
logif "stack", stack
|
|
188
|
+
logif "lFuncList", lFuncList
|
|
129
189
|
|
|
130
190
|
switch type
|
|
131
191
|
when 'enter'
|
|
@@ -147,45 +207,19 @@ export stdShouldLog = (label, type, funcName, stack) ->
|
|
|
147
207
|
|
|
148
208
|
# ---------------------------------------------------------------------------
|
|
149
209
|
|
|
150
|
-
export debugDebug = (flag=true) ->
|
|
151
|
-
|
|
152
|
-
doDebugDebug = flag
|
|
153
|
-
if doDebugDebug
|
|
154
|
-
LOG "doDebugDebug = #{flag}"
|
|
155
|
-
return
|
|
156
|
-
|
|
157
|
-
# ---------------------------------------------------------------------------
|
|
158
|
-
|
|
159
|
-
resetDebugging = () ->
|
|
160
|
-
|
|
161
|
-
if doDebugDebug
|
|
162
|
-
LOG "resetDebugging()"
|
|
163
|
-
callStack.reset()
|
|
164
|
-
shouldLog = (label, type, funcName, stack) -> undef
|
|
165
|
-
return
|
|
166
|
-
|
|
167
|
-
# ---------------------------------------------------------------------------
|
|
168
|
-
|
|
169
210
|
export setDebugging = (option) ->
|
|
170
211
|
|
|
171
|
-
|
|
212
|
+
callStack.reset()
|
|
172
213
|
if isBoolean(option)
|
|
173
214
|
if option
|
|
174
215
|
shouldLog = (label, type, funcName, stack) -> label
|
|
175
216
|
else
|
|
176
217
|
shouldLog = (label, type, funcName, stack) -> undef
|
|
177
|
-
if doDebugDebug
|
|
178
|
-
LOG "setDebugging = #{option}"
|
|
179
218
|
else if isString(option)
|
|
180
219
|
lFuncList = getFuncList(option)
|
|
181
220
|
shouldLog = stdShouldLog
|
|
182
|
-
if doDebugDebug
|
|
183
|
-
LOG "setDebugging FUNCS: #{option}"
|
|
184
|
-
LOG 'lFuncList', lFuncList
|
|
185
221
|
else if isFunction(option)
|
|
186
222
|
shouldLog = option
|
|
187
|
-
if doDebugDebug
|
|
188
|
-
LOG "setDebugging to custom func"
|
|
189
223
|
else
|
|
190
224
|
croak "bad parameter #{OL(option)}"
|
|
191
225
|
return
|
|
@@ -229,22 +263,18 @@ export funcMatch = (stack, lFuncList) ->
|
|
|
229
263
|
assert isArray(lFuncList), "not an array #{OL(lFuncList)}"
|
|
230
264
|
|
|
231
265
|
curFunc = stack.curFunc()
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
LOG 'lFuncList', lFuncList
|
|
266
|
+
logif "funcMatch(): curFunc = #{OL(curFunc)}"
|
|
267
|
+
logif stack.dump(' ')
|
|
268
|
+
logif 'lFuncList', lFuncList
|
|
236
269
|
for h in lFuncList
|
|
237
270
|
{name, object, plus} = h
|
|
238
271
|
if (name == curFunc)
|
|
239
|
-
|
|
240
|
-
LOG " curFunc in lFuncList - match successful"
|
|
272
|
+
logif " curFunc in lFuncList - match successful"
|
|
241
273
|
return true
|
|
242
274
|
if plus && stack.isActive(name)
|
|
243
|
-
|
|
244
|
-
LOG " func #{OL(name)} is active - match successful"
|
|
275
|
+
logif " func #{OL(name)} is active - match successful"
|
|
245
276
|
return true
|
|
246
|
-
|
|
247
|
-
LOG " - no match"
|
|
277
|
+
logif " - no match"
|
|
248
278
|
return false
|
|
249
279
|
|
|
250
280
|
# ---------------------------------------------------------------------------
|
|
@@ -287,40 +317,3 @@ reMethod = ///^
|
|
|
287
317
|
|
|
288
318
|
# ---------------------------------------------------------------------------
|
|
289
319
|
|
|
290
|
-
export checkTrace = (block) ->
|
|
291
|
-
# --- export only to allow unit tests
|
|
292
|
-
|
|
293
|
-
lStack = []
|
|
294
|
-
|
|
295
|
-
for line in blockToArray(block)
|
|
296
|
-
if lMatches = line.match(///
|
|
297
|
-
enter
|
|
298
|
-
\s+
|
|
299
|
-
([A-Za-z_][A-Za-z0-9_\.]*)
|
|
300
|
-
///)
|
|
301
|
-
funcName = lMatches[1]
|
|
302
|
-
lStack.push funcName
|
|
303
|
-
else if lMatches = line.match(///
|
|
304
|
-
return
|
|
305
|
-
.*
|
|
306
|
-
from
|
|
307
|
-
\s+
|
|
308
|
-
([A-Za-z_][A-Za-z0-9_\.]*)
|
|
309
|
-
///)
|
|
310
|
-
funcName = lMatches[1]
|
|
311
|
-
len = lStack.length
|
|
312
|
-
if (len == 0)
|
|
313
|
-
log "return from #{funcName} with empty stack"
|
|
314
|
-
else if (lStack[len-1] == funcName)
|
|
315
|
-
lStack.pop()
|
|
316
|
-
else if (lStack[len-2] == funcName)
|
|
317
|
-
log "missing return from #{lStack[len-2]}"
|
|
318
|
-
lStack.pop()
|
|
319
|
-
lStack.pop()
|
|
320
|
-
else
|
|
321
|
-
log "return from #{funcName} - not found on stack"
|
|
322
|
-
return
|
|
323
|
-
|
|
324
|
-
# ---------------------------------------------------------------------------
|
|
325
|
-
|
|
326
|
-
resetDebugging()
|
package/src/debug_utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
// debug_utils.coffee
|
|
3
|
-
var callStack, doDebugDebug, reMethod,
|
|
2
|
+
// debug_utils.coffee
|
|
3
|
+
var callStack, doDebugDebug, lFunctions, logif, reMethod,
|
|
4
|
+
indexOf = [].indexOf;
|
|
4
5
|
|
|
5
6
|
import {
|
|
6
7
|
assert,
|
|
@@ -52,25 +53,75 @@ import {
|
|
|
52
53
|
|
|
53
54
|
callStack = new CallStack();
|
|
54
55
|
|
|
56
|
+
// --- set in resetDebugging() and setDebugging()
|
|
57
|
+
export var shouldLog = function() {
|
|
58
|
+
return undef;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export var lFuncList = [];
|
|
62
|
+
|
|
63
|
+
// --- internal debugging
|
|
55
64
|
doDebugDebug = false;
|
|
56
65
|
|
|
57
|
-
|
|
66
|
+
lFunctions = undef; // --- only used when doDebugDebug is true
|
|
58
67
|
|
|
59
|
-
|
|
68
|
+
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
export var setDebugDebugging = function(value = true) {
|
|
71
|
+
// --- value can be a boolean or string of words
|
|
72
|
+
if (isBoolean(value)) {
|
|
73
|
+
doDebugDebug = value;
|
|
74
|
+
} else if (isString(value)) {
|
|
75
|
+
doDebugDebug = true;
|
|
76
|
+
lFunctions = words(value);
|
|
77
|
+
} else {
|
|
78
|
+
croak(`Bad value: ${OL(value)}`);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
logif = function(label, ...lObjects) {
|
|
84
|
+
var funcName, itemPrefix, level, nObjects, prefix, sep, type;
|
|
85
|
+
if (!doDebugDebug) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
assert(isString(label), `1st arg ${OL(label)} should be a string`);
|
|
89
|
+
nObjects = lObjects.length;
|
|
90
|
+
[type, funcName] = getType(label, nObjects);
|
|
91
|
+
level = callStack.getLevel();
|
|
92
|
+
prefix = getPrefix(level);
|
|
93
|
+
itemPrefix = removeLastVbar(prefix);
|
|
94
|
+
sep = dashes(itemPrefix, 40);
|
|
95
|
+
if (type === 'enter') {
|
|
96
|
+
if (defined(lFunctions) && (indexOf.call(lFunctions, funcName) < 0)) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
callStack.enter(funcName);
|
|
100
|
+
} else if (type === 'return') {
|
|
101
|
+
if (defined(lFunctions) && (indexOf.call(lFunctions, funcName) < 0)) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
doTheLogging(type, label, lObjects);
|
|
106
|
+
if (type === 'return') {
|
|
107
|
+
callStack.returnFrom(funcName);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
60
110
|
|
|
61
111
|
// ---------------------------------------------------------------------------
|
|
62
112
|
export var debug = function(label, ...lObjects) {
|
|
63
|
-
var doLog, funcName,
|
|
113
|
+
var doLog, funcName, nObjects, type;
|
|
114
|
+
logif(`enter debug(${OL(label)})`, ...lObjects);
|
|
64
115
|
assert(isString(label), `1st arg ${OL(label)} should be a string`);
|
|
65
116
|
// --- We want to allow objects to be undef. Therefore, we need to
|
|
66
117
|
// distinguish between 1 arg sent vs. 2 or more args sent
|
|
67
118
|
nObjects = lObjects.length;
|
|
68
119
|
// --- funcName is only set for types 'enter' and 'return'
|
|
69
120
|
[type, funcName] = getType(label, nObjects);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
121
|
+
logif(`type = ${OL(type)}`);
|
|
122
|
+
logif(`funcName = ${OL(funcName)}`);
|
|
123
|
+
// --- function shouldLog() returns the (possibly modified) label
|
|
124
|
+
// if we should log this, else it returns undef
|
|
74
125
|
switch (type) {
|
|
75
126
|
case 'enter':
|
|
76
127
|
callStack.enter(funcName);
|
|
@@ -81,81 +132,84 @@ export var debug = function(label, ...lObjects) {
|
|
|
81
132
|
break;
|
|
82
133
|
case 'string':
|
|
83
134
|
label = shouldLog(label, type, undef, callStack);
|
|
84
|
-
assert(nObjects === 0, `
|
|
135
|
+
assert(nObjects === 0, `Objects not allowed for ${OL(type)}`);
|
|
85
136
|
break;
|
|
86
137
|
case 'objects':
|
|
87
138
|
label = shouldLog(label, type, undef, callStack);
|
|
88
|
-
assert(nObjects > 0, `
|
|
139
|
+
assert(nObjects > 0, `Objects required for ${OL(type)}`);
|
|
89
140
|
}
|
|
141
|
+
assert((label === undef) || isString(label), `label not a string: ${OL(label)}`);
|
|
90
142
|
doLog = defined(label);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
LOG(`debug(${OL(label)}) - 1 arg`);
|
|
94
|
-
} else {
|
|
95
|
-
LOG(`debug(${OL(label)}), ${nObjects} args`);
|
|
96
|
-
}
|
|
97
|
-
LOG(`doLog = ${OL(doLog)}`);
|
|
98
|
-
}
|
|
143
|
+
logif(`doLog = ${OL(doLog)}`);
|
|
144
|
+
logif(`${nObjects} objects`);
|
|
99
145
|
if (doLog) {
|
|
100
|
-
|
|
101
|
-
prefix = getPrefix(level);
|
|
102
|
-
if (doDebugDebug) {
|
|
103
|
-
LOG("callStack", callStack);
|
|
104
|
-
LOG(`level = ${OL(level)}`);
|
|
105
|
-
LOG(`prefix = ${OL(prefix)}`);
|
|
106
|
-
}
|
|
107
|
-
switch (type) {
|
|
108
|
-
case 'enter':
|
|
109
|
-
log(label, {prefix});
|
|
110
|
-
prefix = removeLastVbar(prefix);
|
|
111
|
-
for (i = j = 0, len1 = lObjects.length; j < len1; i = ++j) {
|
|
112
|
-
obj = lObjects[i];
|
|
113
|
-
if (i > 0) {
|
|
114
|
-
log(dashes(prefix));
|
|
115
|
-
}
|
|
116
|
-
logItem(undef, obj, {prefix});
|
|
117
|
-
}
|
|
118
|
-
break;
|
|
119
|
-
case 'return':
|
|
120
|
-
log(label, {
|
|
121
|
-
prefix: addArrow(prefix)
|
|
122
|
-
});
|
|
123
|
-
prefix = removeLastVbar(prefix);
|
|
124
|
-
for (i = k = 0, len2 = lObjects.length; k < len2; i = ++k) {
|
|
125
|
-
obj = lObjects[i];
|
|
126
|
-
if (i > 0) {
|
|
127
|
-
log(dashes(prefix));
|
|
128
|
-
}
|
|
129
|
-
logItem(undef, obj, {prefix});
|
|
130
|
-
}
|
|
131
|
-
break;
|
|
132
|
-
case 'string':
|
|
133
|
-
log(label, {prefix});
|
|
134
|
-
break;
|
|
135
|
-
case 'objects':
|
|
136
|
-
if ((nObjects === 1) && shortEnough(label, lObjects[0])) {
|
|
137
|
-
logItem(label, lObjects[0], {prefix});
|
|
138
|
-
} else {
|
|
139
|
-
if (label.indexOf(':') !== label.length - 1) {
|
|
140
|
-
label += ':';
|
|
141
|
-
}
|
|
142
|
-
log(label, {prefix});
|
|
143
|
-
for (l = 0, len3 = lObjects.length; l < len3; l++) {
|
|
144
|
-
obj = lObjects[l];
|
|
145
|
-
logItem(undef, obj, {prefix});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
146
|
+
doTheLogging(type, label, lObjects);
|
|
149
147
|
}
|
|
150
148
|
if ((type === 'enter') && doLog && (label.indexOf('call') === -1)) {
|
|
151
149
|
callStack.logCurFunc();
|
|
152
150
|
} else if (type === 'return') {
|
|
153
151
|
callStack.returnFrom(funcName);
|
|
154
152
|
}
|
|
153
|
+
logif("return from debug()");
|
|
155
154
|
return true; // allow use in boolean expressions
|
|
156
155
|
};
|
|
157
156
|
|
|
158
157
|
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
export var doTheLogging = function(type, label, lObjects) {
|
|
160
|
+
var i, itemPrefix, j, k, l, len, len1, len2, level, obj, prefix, sep;
|
|
161
|
+
level = callStack.getLevel();
|
|
162
|
+
prefix = getPrefix(level);
|
|
163
|
+
itemPrefix = removeLastVbar(prefix);
|
|
164
|
+
sep = dashes(itemPrefix, 40);
|
|
165
|
+
assert(isString(sep), "sep is not a string");
|
|
166
|
+
logif("callStack", callStack);
|
|
167
|
+
logif(`level = ${OL(level)}`);
|
|
168
|
+
logif(`prefix = ${OL(prefix)}`);
|
|
169
|
+
logif(`itemPrefix = ${OL(itemPrefix)}`);
|
|
170
|
+
logif(`sep = ${OL(sep)}`);
|
|
171
|
+
switch (type) {
|
|
172
|
+
case 'enter':
|
|
173
|
+
log(label, {prefix});
|
|
174
|
+
for (i = j = 0, len = lObjects.length; j < len; i = ++j) {
|
|
175
|
+
obj = lObjects[i];
|
|
176
|
+
if (i > 0) {
|
|
177
|
+
log(sep);
|
|
178
|
+
}
|
|
179
|
+
logItem(undef, obj, {itemPrefix});
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
case 'return':
|
|
183
|
+
log(label, {
|
|
184
|
+
prefix: addArrow(prefix)
|
|
185
|
+
});
|
|
186
|
+
for (i = k = 0, len1 = lObjects.length; k < len1; i = ++k) {
|
|
187
|
+
obj = lObjects[i];
|
|
188
|
+
if (i > 0) {
|
|
189
|
+
log(sep);
|
|
190
|
+
}
|
|
191
|
+
logItem(undef, obj, {itemPrefix});
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
case 'string':
|
|
195
|
+
log(label, {prefix});
|
|
196
|
+
break;
|
|
197
|
+
case 'objects':
|
|
198
|
+
if ((lObjects.length === 1) && shortEnough(label, lObjects[0])) {
|
|
199
|
+
logItem(label, lObjects[0], {prefix});
|
|
200
|
+
} else {
|
|
201
|
+
if (label.indexOf(':') !== label.length - 1) {
|
|
202
|
+
label += ':';
|
|
203
|
+
}
|
|
204
|
+
log(label, {prefix});
|
|
205
|
+
for (l = 0, len2 = lObjects.length; l < len2; l++) {
|
|
206
|
+
obj = lObjects[l];
|
|
207
|
+
logItem(undef, obj, {prefix});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
159
213
|
// ---------------------------------------------------------------------------
|
|
160
214
|
export var stdShouldLog = function(label, type, funcName, stack) {
|
|
161
215
|
var prevLogged;
|
|
@@ -173,11 +227,9 @@ export var stdShouldLog = function(label, type, funcName, stack) {
|
|
|
173
227
|
assert(funcName === undef, `func name ${OL(funcName)} not undef`);
|
|
174
228
|
}
|
|
175
229
|
assert(stack instanceof CallStack, "not a call stack object");
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
LOG("lFuncList", lFuncList);
|
|
180
|
-
}
|
|
230
|
+
logif(`stdShouldLog(${OL(label)}, ${OL(type)}, ${OL(funcName)}, stack)`);
|
|
231
|
+
logif("stack", stack);
|
|
232
|
+
logif("lFuncList", lFuncList);
|
|
181
233
|
switch (type) {
|
|
182
234
|
case 'enter':
|
|
183
235
|
if (funcMatch(stack, lFuncList)) {
|
|
@@ -200,28 +252,9 @@ export var stdShouldLog = function(label, type, funcName, stack) {
|
|
|
200
252
|
return undef;
|
|
201
253
|
};
|
|
202
254
|
|
|
203
|
-
// ---------------------------------------------------------------------------
|
|
204
|
-
export var debugDebug = function(flag = true) {
|
|
205
|
-
doDebugDebug = flag;
|
|
206
|
-
if (doDebugDebug) {
|
|
207
|
-
LOG(`doDebugDebug = ${flag}`);
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
// ---------------------------------------------------------------------------
|
|
212
|
-
resetDebugging = function() {
|
|
213
|
-
if (doDebugDebug) {
|
|
214
|
-
LOG("resetDebugging()");
|
|
215
|
-
}
|
|
216
|
-
callStack.reset();
|
|
217
|
-
shouldLog = function(label, type, funcName, stack) {
|
|
218
|
-
return undef;
|
|
219
|
-
};
|
|
220
|
-
};
|
|
221
|
-
|
|
222
255
|
// ---------------------------------------------------------------------------
|
|
223
256
|
export var setDebugging = function(option) {
|
|
224
|
-
|
|
257
|
+
callStack.reset();
|
|
225
258
|
if (isBoolean(option)) {
|
|
226
259
|
if (option) {
|
|
227
260
|
shouldLog = function(label, type, funcName, stack) {
|
|
@@ -232,21 +265,11 @@ export var setDebugging = function(option) {
|
|
|
232
265
|
return undef;
|
|
233
266
|
};
|
|
234
267
|
}
|
|
235
|
-
if (doDebugDebug) {
|
|
236
|
-
LOG(`setDebugging = ${option}`);
|
|
237
|
-
}
|
|
238
268
|
} else if (isString(option)) {
|
|
239
269
|
lFuncList = getFuncList(option);
|
|
240
270
|
shouldLog = stdShouldLog;
|
|
241
|
-
if (doDebugDebug) {
|
|
242
|
-
LOG(`setDebugging FUNCS: ${option}`);
|
|
243
|
-
LOG('lFuncList', lFuncList);
|
|
244
|
-
}
|
|
245
271
|
} else if (isFunction(option)) {
|
|
246
272
|
shouldLog = option;
|
|
247
|
-
if (doDebugDebug) {
|
|
248
|
-
LOG("setDebugging to custom func");
|
|
249
|
-
}
|
|
250
273
|
} else {
|
|
251
274
|
croak(`bad parameter ${OL(option)}`);
|
|
252
275
|
}
|
|
@@ -255,10 +278,10 @@ export var setDebugging = function(option) {
|
|
|
255
278
|
// ---------------------------------------------------------------------------
|
|
256
279
|
// --- export only to allow unit tests
|
|
257
280
|
export var getFuncList = function(str) {
|
|
258
|
-
var _, ident1, ident2, j, lMatches,
|
|
281
|
+
var _, ident1, ident2, j, lMatches, len, plus, ref, word;
|
|
259
282
|
lFuncList = [];
|
|
260
283
|
ref = words(str);
|
|
261
|
-
for (j = 0,
|
|
284
|
+
for (j = 0, len = ref.length; j < len; j++) {
|
|
262
285
|
word = ref[j];
|
|
263
286
|
if (lMatches = word.match(/^([A-Za-z_][A-Za-z0-9_]*)(?:\.([A-Za-z_][A-Za-z0-9_]*))?(\+)?$/)) {
|
|
264
287
|
[_, ident1, ident2, plus] = lMatches;
|
|
@@ -284,33 +307,25 @@ export var getFuncList = function(str) {
|
|
|
284
307
|
// ---------------------------------------------------------------------------
|
|
285
308
|
// --- export only to allow unit tests
|
|
286
309
|
export var funcMatch = function(stack, lFuncList) {
|
|
287
|
-
var curFunc, h, j,
|
|
310
|
+
var curFunc, h, j, len, name, object, plus;
|
|
288
311
|
assert(isArray(lFuncList), `not an array ${OL(lFuncList)}`);
|
|
289
312
|
curFunc = stack.curFunc();
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
for (j = 0, len1 = lFuncList.length; j < len1; j++) {
|
|
313
|
+
logif(`funcMatch(): curFunc = ${OL(curFunc)}`);
|
|
314
|
+
logif(stack.dump(' '));
|
|
315
|
+
logif('lFuncList', lFuncList);
|
|
316
|
+
for (j = 0, len = lFuncList.length; j < len; j++) {
|
|
296
317
|
h = lFuncList[j];
|
|
297
318
|
({name, object, plus} = h);
|
|
298
319
|
if (name === curFunc) {
|
|
299
|
-
|
|
300
|
-
LOG(" curFunc in lFuncList - match successful");
|
|
301
|
-
}
|
|
320
|
+
logif(" curFunc in lFuncList - match successful");
|
|
302
321
|
return true;
|
|
303
322
|
}
|
|
304
323
|
if (plus && stack.isActive(name)) {
|
|
305
|
-
|
|
306
|
-
LOG(` func ${OL(name)} is active - match successful`);
|
|
307
|
-
}
|
|
324
|
+
logif(` func ${OL(name)} is active - match successful`);
|
|
308
325
|
return true;
|
|
309
326
|
}
|
|
310
327
|
}
|
|
311
|
-
|
|
312
|
-
LOG(" - no match");
|
|
313
|
-
}
|
|
328
|
+
logif(" - no match");
|
|
314
329
|
return false;
|
|
315
330
|
};
|
|
316
331
|
|
|
@@ -334,33 +349,3 @@ export var getType = function(str, nObjects) {
|
|
|
334
349
|
reMethod = /^([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)$/;
|
|
335
350
|
|
|
336
351
|
// ---------------------------------------------------------------------------
|
|
337
|
-
export var checkTrace = function(block) {
|
|
338
|
-
var funcName, j, lMatches, lStack, len, len1, line, ref;
|
|
339
|
-
// --- export only to allow unit tests
|
|
340
|
-
lStack = [];
|
|
341
|
-
ref = blockToArray(block);
|
|
342
|
-
for (j = 0, len1 = ref.length; j < len1; j++) {
|
|
343
|
-
line = ref[j];
|
|
344
|
-
if (lMatches = line.match(/enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
|
|
345
|
-
funcName = lMatches[1];
|
|
346
|
-
lStack.push(funcName);
|
|
347
|
-
} else if (lMatches = line.match(/return.*from\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
|
|
348
|
-
funcName = lMatches[1];
|
|
349
|
-
len = lStack.length;
|
|
350
|
-
if (len === 0) {
|
|
351
|
-
log(`return from ${funcName} with empty stack`);
|
|
352
|
-
} else if (lStack[len - 1] === funcName) {
|
|
353
|
-
lStack.pop();
|
|
354
|
-
} else if (lStack[len - 2] === funcName) {
|
|
355
|
-
log(`missing return from ${lStack[len - 2]}`);
|
|
356
|
-
lStack.pop();
|
|
357
|
-
lStack.pop();
|
|
358
|
-
} else {
|
|
359
|
-
log(`return from ${funcName} - not found on stack`);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
// ---------------------------------------------------------------------------
|
|
366
|
-
resetDebugging();
|
package/src/log_utils.coffee
CHANGED
|
@@ -135,9 +135,9 @@ export log = (str, hOptions={}) ->
|
|
|
135
135
|
# --- valid options:
|
|
136
136
|
# prefix
|
|
137
137
|
|
|
138
|
+
assert isString(str), "log(): not a string: #{OL(str)}"
|
|
138
139
|
assert isFunction(putstr), "putstr not properly set"
|
|
139
|
-
assert
|
|
140
|
-
assert isHash(hOptions), "log(): arg 2 not a hash"
|
|
140
|
+
assert isHash(hOptions), "log(): arg 2 not a hash: #{OL(hOptions)}"
|
|
141
141
|
prefix = fixForTerminal(hOptions.prefix)
|
|
142
142
|
|
|
143
143
|
if doDebugLog
|
package/src/log_utils.js
CHANGED
|
@@ -158,9 +158,9 @@ export var log = function(str, hOptions = {}) {
|
|
|
158
158
|
var prefix;
|
|
159
159
|
// --- valid options:
|
|
160
160
|
// prefix
|
|
161
|
+
assert(isString(str), `log(): not a string: ${OL(str)}`);
|
|
161
162
|
assert(isFunction(putstr), "putstr not properly set");
|
|
162
|
-
assert(
|
|
163
|
-
assert(isHash(hOptions), "log(): arg 2 not a hash");
|
|
163
|
+
assert(isHash(hOptions), `log(): arg 2 not a hash: ${OL(hOptions)}`);
|
|
164
164
|
prefix = fixForTerminal(hOptions.prefix);
|
|
165
165
|
if (doDebugLog) {
|
|
166
166
|
LOG(`CALL log(${OL(str)}), prefix = ${OL(prefix)}`);
|