@jdeighan/coffee-utils 7.0.60 → 7.0.63
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 +1 -1
- package/src/arrow.coffee +13 -22
- package/src/arrow.js +14 -27
- package/src/call_stack.coffee +28 -57
- package/src/call_stack.js +31 -60
- package/src/coffee_utils.coffee +18 -7
- package/src/coffee_utils.js +18 -7
- package/src/debug_utils.coffee +114 -172
- package/src/debug_utils.js +127 -177
- package/src/log_utils.coffee +41 -31
- package/src/log_utils.js +40 -32
package/src/debug_utils.coffee
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
assert, undef, error, croak, warn, defined,
|
|
5
|
-
isString, isFunction, isBoolean,
|
|
5
|
+
isString, isFunction, isBoolean, patchStr,
|
|
6
6
|
OL, escapeStr, isNumber, isArray, words, pass,
|
|
7
7
|
} from '@jdeighan/coffee-utils'
|
|
8
8
|
import {blockToArray} from '@jdeighan/coffee-utils/block'
|
|
@@ -10,141 +10,79 @@ import {untabify} from '@jdeighan/coffee-utils/indent'
|
|
|
10
10
|
import {slurp} from '@jdeighan/coffee-utils/fs'
|
|
11
11
|
import {CallStack} from '@jdeighan/coffee-utils/stack'
|
|
12
12
|
import {
|
|
13
|
-
|
|
13
|
+
prefix, addArrow, removeLastVbar, vbar,
|
|
14
14
|
} from '@jdeighan/coffee-utils/arrow'
|
|
15
15
|
import {
|
|
16
|
-
log, logItem, LOG, shortEnough,
|
|
16
|
+
log, logItem, logBareItem, LOG, shortEnough,
|
|
17
17
|
} from '@jdeighan/coffee-utils/log'
|
|
18
18
|
|
|
19
19
|
# --- set in resetDebugging() and setDebugging()
|
|
20
20
|
export callStack = new CallStack()
|
|
21
21
|
export shouldLog = () -> undef
|
|
22
22
|
|
|
23
|
-
lFuncList = []
|
|
23
|
+
lFuncList = [] # names of functions being debugged
|
|
24
24
|
strFuncList = undef # original string
|
|
25
25
|
|
|
26
|
-
# --- internal debugging
|
|
27
|
-
doDebugDebug = false
|
|
28
|
-
lFunctions = undef # --- only used when doDebugDebug is true
|
|
29
|
-
|
|
30
26
|
# ---------------------------------------------------------------------------
|
|
31
27
|
|
|
32
|
-
export
|
|
33
|
-
|
|
34
|
-
LOG callStack.dump()
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
# ---------------------------------------------------------------------------
|
|
28
|
+
export debug = (orgLabel, lObjects...) ->
|
|
38
29
|
|
|
39
|
-
|
|
40
|
-
# --- value can be a boolean or string of words
|
|
30
|
+
assert isString(orgLabel), "1st arg #{OL(orgLabel)} should be a string"
|
|
41
31
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
else if isString(value)
|
|
45
|
-
doDebugDebug = true
|
|
46
|
-
lFunctions = words(value)
|
|
47
|
-
else
|
|
48
|
-
croak "Bad value: #{OL(value)}"
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
# ---------------------------------------------------------------------------
|
|
52
|
-
|
|
53
|
-
debugDebug = (label, lObjects...) ->
|
|
54
|
-
# --- For debugging functions in this module
|
|
55
|
-
|
|
56
|
-
if ! doDebugDebug
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
# --- At this point, doDebugDebug is true
|
|
60
|
-
doDebugDebug = false # temp - reset before returning
|
|
61
|
-
|
|
62
|
-
assert isString(label), "1st arg #{OL(label)} should be a string"
|
|
63
|
-
nObjects = lObjects.length
|
|
64
|
-
[type, funcName] = getType(label, nObjects)
|
|
32
|
+
[type, funcName] = getType(orgLabel, lObjects)
|
|
33
|
+
label = shouldLog(orgLabel, type, funcName, callStack)
|
|
65
34
|
|
|
66
35
|
switch type
|
|
36
|
+
|
|
67
37
|
when 'enter'
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
38
|
+
if defined(label)
|
|
39
|
+
doTheLogging type, label, lObjects
|
|
40
|
+
callStack.enter funcName, lObjects, defined(label)
|
|
71
41
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
42
|
+
debug2 "enter debug()", orgLabel, lObjects
|
|
43
|
+
debug2 "type = #{OL(type)}, funcName = #{OL(funcName)}"
|
|
44
|
+
debug2 "return from debug()"
|
|
75
45
|
|
|
76
|
-
when '
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
46
|
+
when 'return'
|
|
47
|
+
debug2 "enter debug()", orgLabel, lObjects
|
|
48
|
+
debug2 "type = #{OL(type)}, funcName = #{OL(funcName)}"
|
|
49
|
+
debug2 "return from debug()"
|
|
80
50
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
dolog = true
|
|
51
|
+
if defined(label)
|
|
52
|
+
doTheLogging type, label, lObjects
|
|
53
|
+
callStack.returnFrom funcName
|
|
85
54
|
|
|
86
|
-
|
|
87
|
-
|
|
55
|
+
when 'string'
|
|
56
|
+
debug2 "enter debug()", orgLabel, lObjects
|
|
57
|
+
debug2 "type = #{OL(type)}, funcName = #{OL(funcName)}"
|
|
88
58
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
callStack.returnFrom funcName
|
|
59
|
+
if defined(label)
|
|
60
|
+
doTheLogging type, label, lObjects
|
|
61
|
+
debug2 "return from debug()"
|
|
93
62
|
|
|
94
|
-
|
|
95
|
-
return
|
|
63
|
+
return true # allow use in boolean expressions
|
|
96
64
|
|
|
97
65
|
# ---------------------------------------------------------------------------
|
|
98
66
|
|
|
99
|
-
export
|
|
100
|
-
|
|
101
|
-
assert isString(label), "1st arg #{OL(label)} should be a string"
|
|
102
|
-
|
|
103
|
-
# --- If label is "enter <funcname>, we need to put that on the stack
|
|
104
|
-
# BEFORE we do any internal logging
|
|
105
|
-
nObjects = lObjects.length
|
|
106
|
-
[type, funcName] = getType(label, nObjects)
|
|
107
|
-
if (type == 'enter')
|
|
108
|
-
callStack.enter funcName, lObjects
|
|
67
|
+
export debug2 = (orgLabel, lObjects...) ->
|
|
109
68
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
debugDebug "funcName = #{OL(funcName)}"
|
|
113
|
-
|
|
114
|
-
# --- function shouldLog() returns the (possibly modified) label
|
|
115
|
-
# if we should log this, else it returns undef
|
|
69
|
+
[type, funcName] = getType(orgLabel, lObjects)
|
|
70
|
+
label = shouldLog(orgLabel, type, funcName, callStack)
|
|
116
71
|
|
|
117
72
|
switch type
|
|
118
73
|
when 'enter'
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
when 'string'
|
|
123
|
-
label = shouldLog(label, type, undef, callStack)
|
|
124
|
-
assert (nObjects == 0),
|
|
125
|
-
"Objects not allowed for #{OL(type)}"
|
|
126
|
-
when 'objects'
|
|
127
|
-
label = shouldLog(label, type, undef, callStack)
|
|
128
|
-
assert (nObjects > 0),
|
|
129
|
-
"Objects required for #{OL(type)}"
|
|
130
|
-
|
|
131
|
-
assert (label == undef) || isString(label),
|
|
132
|
-
"label not a string: #{OL(label)}"
|
|
133
|
-
doLog = defined(label)
|
|
134
|
-
debugDebug "doLog = #{OL(doLog)}"
|
|
135
|
-
debugDebug "#{nObjects} objects"
|
|
74
|
+
if defined(label)
|
|
75
|
+
doTheLogging 'enter', label, lObjects
|
|
76
|
+
callStack.enter funcName, lObjects, defined(label)
|
|
136
77
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
callStack.logCurFunc(funcName)
|
|
142
|
-
|
|
143
|
-
# --- This must be called BEFORE we return from funcName
|
|
144
|
-
debugDebug "return from debug()"
|
|
78
|
+
when 'return'
|
|
79
|
+
if defined(label)
|
|
80
|
+
doTheLogging 'return', label, lObjects
|
|
81
|
+
callStack.returnFrom funcName
|
|
145
82
|
|
|
146
|
-
|
|
147
|
-
|
|
83
|
+
when 'string'
|
|
84
|
+
if defined(label)
|
|
85
|
+
doTheLogging 'string', label, lObjects
|
|
148
86
|
|
|
149
87
|
return true # allow use in boolean expressions
|
|
150
88
|
|
|
@@ -152,42 +90,41 @@ export debug = (label, lObjects...) ->
|
|
|
152
90
|
|
|
153
91
|
export doTheLogging = (type, label, lObjects) ->
|
|
154
92
|
|
|
93
|
+
assert isString(label), "non-string label #{OL(label)}"
|
|
155
94
|
level = callStack.getLevel()
|
|
156
|
-
prefix = getPrefix(level)
|
|
157
|
-
itemPrefix = removeLastVbar(prefix)
|
|
158
|
-
sep = dashes(itemPrefix, 40)
|
|
159
|
-
assert isString(sep), "sep is not a string"
|
|
160
|
-
|
|
161
|
-
debugDebug "callStack", callStack
|
|
162
|
-
debugDebug "level = #{OL(level)}"
|
|
163
|
-
debugDebug "prefix = #{OL(prefix)}"
|
|
164
|
-
debugDebug "itemPrefix = #{OL(itemPrefix)}"
|
|
165
|
-
debugDebug "sep = #{OL(sep)}"
|
|
166
95
|
|
|
167
96
|
switch type
|
|
97
|
+
|
|
168
98
|
when 'enter'
|
|
169
|
-
log label,
|
|
99
|
+
log label, prefix(level)
|
|
100
|
+
if label.match(///^ \s* call///)
|
|
101
|
+
pre = prefix(level+1, 'noLastVbar')
|
|
102
|
+
itemPre = prefix(level+2, 'noLast2Vbars')
|
|
103
|
+
else
|
|
104
|
+
pre = prefix(level+1)
|
|
105
|
+
itemPre = prefix(level+2, 'noLastVbar')
|
|
170
106
|
for obj,i in lObjects
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
logItem undef, obj, {itemPrefix}
|
|
107
|
+
logItem "arg[#{i}]", obj, pre, itemPre
|
|
108
|
+
|
|
174
109
|
when 'return'
|
|
175
|
-
log label,
|
|
110
|
+
log label, prefix(level, 'withArrow')
|
|
111
|
+
pre = prefix(level, 'noLastVbar')
|
|
112
|
+
itemPre = prefix(level+1, 'noLast2Vbars')
|
|
176
113
|
for obj,i in lObjects
|
|
177
|
-
|
|
178
|
-
log sep
|
|
179
|
-
logItem undef, obj, {itemPrefix}
|
|
114
|
+
logItem "ret[#{i}]", obj, pre, itemPre
|
|
180
115
|
when 'string'
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (lObjects.length==
|
|
184
|
-
|
|
116
|
+
pre = prefix(level)
|
|
117
|
+
itemPre = prefix(level+1, 'noLastVbar')
|
|
118
|
+
if (lObjects.length==0)
|
|
119
|
+
log label, pre
|
|
120
|
+
else if (lObjects.length==1) && shortEnough(label, lObjects[0])
|
|
121
|
+
logItem label, lObjects[0], pre
|
|
185
122
|
else
|
|
186
123
|
if (label.indexOf(':') != label.length - 1)
|
|
187
124
|
label += ':'
|
|
188
|
-
log label,
|
|
125
|
+
log label, pre
|
|
189
126
|
for obj in lObjects
|
|
190
|
-
|
|
127
|
+
logBareItem obj, itemPre
|
|
191
128
|
return
|
|
192
129
|
|
|
193
130
|
# ---------------------------------------------------------------------------
|
|
@@ -196,53 +133,54 @@ export stdShouldLog = (label, type, funcName, stack) ->
|
|
|
196
133
|
# --- if type is 'enter', then funcName won't be on the stack yet
|
|
197
134
|
# returns the (possibly modified) label to log
|
|
198
135
|
|
|
199
|
-
# --- If we're logging now,
|
|
200
|
-
# but we won't be logging when funcName is activated
|
|
201
|
-
# then change 'enter' to 'call'
|
|
202
|
-
|
|
203
136
|
assert isString(label), "label #{OL(label)} not a string"
|
|
204
137
|
assert isString(type), "type #{OL(type)} not a string"
|
|
138
|
+
assert stack instanceof CallStack, "not a call stack object"
|
|
205
139
|
if (type == 'enter') || (type == 'return')
|
|
206
140
|
assert isString(funcName), "func name #{OL(funcName)} not a string"
|
|
207
141
|
else
|
|
208
142
|
assert funcName == undef, "func name #{OL(funcName)} not undef"
|
|
209
|
-
assert stack instanceof CallStack, "not a call stack object"
|
|
210
143
|
|
|
211
|
-
|
|
144
|
+
if funcMatch(funcName || stack.curFunc())
|
|
145
|
+
return label
|
|
212
146
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return label
|
|
147
|
+
if (type == 'enter') && ! isMyFunc(funcName)
|
|
148
|
+
# --- As a special case, if we enter a function where we will not
|
|
149
|
+
# be logging, but we were logging in the calling function,
|
|
150
|
+
# we'll log out the call itself
|
|
218
151
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
# we'll log out the call itself
|
|
223
|
-
|
|
224
|
-
prevLogged = stack.isLoggingPrev()
|
|
225
|
-
if prevLogged
|
|
226
|
-
result = label.replace('enter', 'call')
|
|
227
|
-
debugDebug "return #{OL(result)} from stdShouldLog() - s/enter/call/"
|
|
228
|
-
return result
|
|
229
|
-
else
|
|
230
|
-
if funcMatch()
|
|
231
|
-
debugDebug "return #{OL(label)} from stdShouldLog()"
|
|
232
|
-
return label
|
|
233
|
-
debugDebug "return undef from stdShouldLog()"
|
|
152
|
+
if funcMatch(stack.curFunc())
|
|
153
|
+
result = label.replace('enter', 'call')
|
|
154
|
+
return result
|
|
234
155
|
return undef
|
|
235
156
|
|
|
236
157
|
# ---------------------------------------------------------------------------
|
|
237
158
|
|
|
159
|
+
export isMyFunc = (funcName) ->
|
|
160
|
+
|
|
161
|
+
return funcName in words('debug debug2 doTheLogging
|
|
162
|
+
stdShouldLog setDebugging getFuncList funcMatch
|
|
163
|
+
getType dumpCallStack')
|
|
164
|
+
|
|
165
|
+
# ---------------------------------------------------------------------------
|
|
166
|
+
|
|
167
|
+
export trueShouldLog = (label, type, funcName, stack) ->
|
|
168
|
+
|
|
169
|
+
if isMyFunc(funcName || stack.curFunc())
|
|
170
|
+
return undef
|
|
171
|
+
else
|
|
172
|
+
return label
|
|
173
|
+
|
|
174
|
+
# ---------------------------------------------------------------------------
|
|
175
|
+
|
|
238
176
|
export setDebugging = (option) ->
|
|
239
177
|
|
|
240
178
|
callStack.reset()
|
|
241
179
|
if isBoolean(option)
|
|
242
180
|
if option
|
|
243
|
-
shouldLog =
|
|
181
|
+
shouldLog = trueShouldLog
|
|
244
182
|
else
|
|
245
|
-
shouldLog = (
|
|
183
|
+
shouldLog = () -> return undef
|
|
246
184
|
else if isString(option)
|
|
247
185
|
lFuncList = getFuncList(option)
|
|
248
186
|
shouldLog = stdShouldLog
|
|
@@ -287,29 +225,21 @@ export getFuncList = (str) ->
|
|
|
287
225
|
# ---------------------------------------------------------------------------
|
|
288
226
|
# --- export only to allow unit tests
|
|
289
227
|
|
|
290
|
-
export funcMatch = () ->
|
|
228
|
+
export funcMatch = (funcName) ->
|
|
291
229
|
|
|
292
230
|
assert isArray(lFuncList), "not an array #{OL(lFuncList)}"
|
|
293
|
-
|
|
294
|
-
debugDebug "enter funcMatch()"
|
|
295
|
-
curFunc = callStack.curFunc()
|
|
296
|
-
debugDebug "curFunc = #{OL(curFunc)}"
|
|
297
|
-
debugDebug "lFuncList = #{strFuncList}"
|
|
298
231
|
for h in lFuncList
|
|
299
232
|
{name, object, plus} = h
|
|
300
|
-
if (name ==
|
|
301
|
-
debugDebug "return from funcMatch() - curFunc in lFuncList"
|
|
233
|
+
if (name == funcName)
|
|
302
234
|
return true
|
|
303
235
|
if plus && callStack.isActive(name)
|
|
304
|
-
debugDebug "return from funcMatch() - func #{OL(name)} is active"
|
|
305
236
|
return true
|
|
306
|
-
debugDebug "return from funcMatch() - no match"
|
|
307
237
|
return false
|
|
308
238
|
|
|
309
239
|
# ---------------------------------------------------------------------------
|
|
310
|
-
# --- type is one of: 'enter', 'return', 'string'
|
|
240
|
+
# --- type is one of: 'enter', 'return', 'string'
|
|
311
241
|
|
|
312
|
-
export getType = (str,
|
|
242
|
+
export getType = (str, lObjects) ->
|
|
313
243
|
|
|
314
244
|
if lMatches = str.match(///^
|
|
315
245
|
\s*
|
|
@@ -320,7 +250,6 @@ export getType = (str, nObjects) ->
|
|
|
320
250
|
|
|
321
251
|
# --- We are entering function curFunc
|
|
322
252
|
return ['enter', lMatches[1]]
|
|
323
|
-
|
|
324
253
|
else if lMatches = str.match(///^
|
|
325
254
|
\s*
|
|
326
255
|
return
|
|
@@ -330,9 +259,6 @@ export getType = (str, nObjects) ->
|
|
|
330
259
|
([A-Za-z_][A-Za-z0-9_\.]*)
|
|
331
260
|
///)
|
|
332
261
|
return ['return', lMatches[1]]
|
|
333
|
-
|
|
334
|
-
else if (nObjects > 0)
|
|
335
|
-
return ['objects', undef]
|
|
336
262
|
else
|
|
337
263
|
return ['string', undef]
|
|
338
264
|
|
|
@@ -346,3 +272,19 @@ reMethod = ///^
|
|
|
346
272
|
|
|
347
273
|
# ---------------------------------------------------------------------------
|
|
348
274
|
|
|
275
|
+
export dumpDebugGlobals = () ->
|
|
276
|
+
|
|
277
|
+
LOG '='.repeat(40)
|
|
278
|
+
LOG callStack.dump()
|
|
279
|
+
if shouldLog == stdShouldLog
|
|
280
|
+
LOG "using stdShouldLog"
|
|
281
|
+
else if shouldLog == trueShouldLog
|
|
282
|
+
LOG "using trueShouldLog"
|
|
283
|
+
else
|
|
284
|
+
LOG "using custom shouldLog"
|
|
285
|
+
LOG "lFuncList:"
|
|
286
|
+
for funcName in lFuncList
|
|
287
|
+
LOG " #{OL(funcName)}"
|
|
288
|
+
LOG '='.repeat(40)
|
|
289
|
+
|
|
290
|
+
# ---------------------------------------------------------------------------
|