@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.
@@ -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
- getPrefix, addArrow, removeLastVbar,
13
+ prefix, addArrow, removeLastVbar, vbar,
14
14
  } from '@jdeighan/coffee-utils/arrow'
15
15
  import {
16
- log, logItem, LOG, shortEnough, dashes,
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 dumpCallStack = () ->
33
-
34
- LOG callStack.dump()
35
- return
36
-
37
- # ---------------------------------------------------------------------------
28
+ export debug = (orgLabel, lObjects...) ->
38
29
 
39
- export setDebugDebugging = (value=true) ->
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
- if isBoolean(value)
43
- doDebugDebug = value
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
- assert defined(funcName), "type enter, funcName = undef"
69
- callStack.enter funcName, lObjects
70
- doLog = (lFunctions == undef) || (funcName in lFunctions)
38
+ if defined(label)
39
+ doTheLogging type, label, lObjects
40
+ callStack.enter funcName, lObjects, defined(label)
71
41
 
72
- when 'return'
73
- assert defined(funcName), "type return, funcName = undef"
74
- doLog = (lFunctions == undef) || (funcName in lFunctions)
42
+ debug2 "enter debug()", orgLabel, lObjects
43
+ debug2 "type = #{OL(type)}, funcName = #{OL(funcName)}"
44
+ debug2 "return from debug()"
75
45
 
76
- when 'string'
77
- assert (funcName == undef), "type string, funcName defined"
78
- assert (nObjects == 0), "Objects not allowed for #{OL(type)}"
79
- doLog = true
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
- when 'objects'
82
- assert (funcName == undef), "type objects, funcName defined"
83
- assert (nObjects > 0), "Objects required for #{OL(type)}"
84
- dolog = true
51
+ if defined(label)
52
+ doTheLogging type, label, lObjects
53
+ callStack.returnFrom funcName
85
54
 
86
- if doLog
87
- doTheLogging type, label, lObjects
55
+ when 'string'
56
+ debug2 "enter debug()", orgLabel, lObjects
57
+ debug2 "type = #{OL(type)}, funcName = #{OL(funcName)}"
88
58
 
89
- if (type == 'enter') && doLog
90
- callStack.logCurFunc(funcName)
91
- else if (type == 'return')
92
- callStack.returnFrom funcName
59
+ if defined(label)
60
+ doTheLogging type, label, lObjects
61
+ debug2 "return from debug()"
93
62
 
94
- doDebugDebug = true
95
- return
63
+ return true # allow use in boolean expressions
96
64
 
97
65
  # ---------------------------------------------------------------------------
98
66
 
99
- export debug = (label, lObjects...) ->
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
- debugDebug "enter debug(#{OL(label)})", lObjects...
111
- debugDebug "type = #{OL(type)}"
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
- label = shouldLog(label, type, funcName, callStack)
120
- when 'return'
121
- label = shouldLog(label, type, funcName, callStack)
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
- if doLog
138
- doTheLogging type, label, lObjects
139
-
140
- if (type == 'enter') && doLog && (label.indexOf('call') == -1)
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
- if (type == 'return')
147
- callStack.returnFrom funcName
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, {prefix}
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
- if (i > 0)
172
- log sep
173
- logItem undef, obj, {itemPrefix}
107
+ logItem "arg[#{i}]", obj, pre, itemPre
108
+
174
109
  when 'return'
175
- log label, {prefix: addArrow(prefix)}
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
- if (i > 0)
178
- log sep
179
- logItem undef, obj, {itemPrefix}
114
+ logItem "ret[#{i}]", obj, pre, itemPre
180
115
  when 'string'
181
- log label, {prefix}
182
- when 'objects'
183
- if (lObjects.length==1) && shortEnough(label, lObjects[0])
184
- logItem label, lObjects[0], {prefix}
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, {prefix}
125
+ log label, pre
189
126
  for obj in lObjects
190
- logItem undef, obj, {prefix}
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
- debugDebug "enter stdShouldLog(#{OL(label)}, #{OL(type)}, #{OL(funcName)}, stack)"
144
+ if funcMatch(funcName || stack.curFunc())
145
+ return label
212
146
 
213
- switch type
214
- when 'enter'
215
- if funcMatch()
216
- debugDebug "return #{OL(label)} from stdShouldLog() - funcMatch"
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
- else
220
- # --- As a special case, if we enter a function where we will not
221
- # be logging, but we were logging in the calling function,
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 = (label, type, funcName, stack) -> label
181
+ shouldLog = trueShouldLog
244
182
  else
245
- shouldLog = (label, type, funcName, stack) -> undef
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 == curFunc)
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', 'object'
240
+ # --- type is one of: 'enter', 'return', 'string'
311
241
 
312
- export getType = (str, nObjects) ->
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
+ # ---------------------------------------------------------------------------