@jdeighan/coffee-utils 7.0.60 → 7.0.61

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"
67
+ export debug2 = (orgLabel, lObjects...) ->
102
68
 
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
109
-
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"
136
-
137
- if doLog
138
- doTheLogging type, label, lObjects
139
-
140
- if (type == 'enter') && doLog && (label.indexOf('call') == -1)
141
- callStack.logCurFunc(funcName)
74
+ if defined(label)
75
+ doTheLogging 'enter', label, lObjects
76
+ callStack.enter funcName, lObjects, defined(label)
142
77
 
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,38 @@ 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)}"
95
+ sep = '-'.repeat(40)
166
96
 
167
97
  switch type
98
+
168
99
  when 'enter'
169
- log label, {prefix}
100
+ log label, prefix(level)
101
+ pre = prefix(level+1)
102
+ itemPre = prefix(level+2, 'noLastVbar')
170
103
  for obj,i in lObjects
171
- if (i > 0)
172
- log sep
173
- logItem undef, obj, {itemPrefix}
104
+ logItem "arg[#{i}]", obj, pre, itemPre
105
+
174
106
  when 'return'
175
- log label, {prefix: addArrow(prefix)}
107
+ log label, prefix(level, 'withArrow')
108
+ pre = prefix(level, 'noLastVbar')
109
+ itemPre = prefix(level+1, 'noLast2Vbars')
176
110
  for obj,i in lObjects
177
- if (i > 0)
178
- log sep
179
- logItem undef, obj, {itemPrefix}
111
+ logItem "ret[#{i}]", obj, pre, itemPre
180
112
  when 'string'
181
- log label, {prefix}
182
- when 'objects'
183
- if (lObjects.length==1) && shortEnough(label, lObjects[0])
184
- logItem label, lObjects[0], {prefix}
113
+ pre = prefix(level)
114
+ itemPre = prefix(level+1, 'noLastVbar')
115
+ if (lObjects.length==0)
116
+ log label, pre
117
+ else if (lObjects.length==1) && shortEnough(label, lObjects[0])
118
+ logItem label, lObjects[0], pre
185
119
  else
186
120
  if (label.indexOf(':') != label.length - 1)
187
121
  label += ':'
188
- log label, {prefix}
122
+ log label, pre
189
123
  for obj in lObjects
190
- logItem undef, obj, {prefix}
124
+ logBareItem obj, itemPre
191
125
  return
192
126
 
193
127
  # ---------------------------------------------------------------------------
@@ -196,53 +130,54 @@ export stdShouldLog = (label, type, funcName, stack) ->
196
130
  # --- if type is 'enter', then funcName won't be on the stack yet
197
131
  # returns the (possibly modified) label to log
198
132
 
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
133
  assert isString(label), "label #{OL(label)} not a string"
204
134
  assert isString(type), "type #{OL(type)} not a string"
135
+ assert stack instanceof CallStack, "not a call stack object"
205
136
  if (type == 'enter') || (type == 'return')
206
137
  assert isString(funcName), "func name #{OL(funcName)} not a string"
207
138
  else
208
139
  assert funcName == undef, "func name #{OL(funcName)} not undef"
209
- assert stack instanceof CallStack, "not a call stack object"
210
140
 
211
- debugDebug "enter stdShouldLog(#{OL(label)}, #{OL(type)}, #{OL(funcName)}, stack)"
141
+ if funcMatch(funcName || stack.curFunc())
142
+ return label
212
143
 
213
- switch type
214
- when 'enter'
215
- if funcMatch()
216
- debugDebug "return #{OL(label)} from stdShouldLog() - funcMatch"
217
- return label
144
+ if (type == 'enter') && ! isMyFunc(funcName)
145
+ # --- As a special case, if we enter a function where we will not
146
+ # be logging, but we were logging in the calling function,
147
+ # we'll log out the call itself
218
148
 
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()"
149
+ if funcMatch(stack.curFunc())
150
+ result = label.replace('enter', 'call')
151
+ return result
234
152
  return undef
235
153
 
236
154
  # ---------------------------------------------------------------------------
237
155
 
156
+ export isMyFunc = (funcName) ->
157
+
158
+ return funcName in words('debug debug2 doTheLogging
159
+ stdShouldLog setDebugging getFuncList funcMatch
160
+ getType dumpCallStack')
161
+
162
+ # ---------------------------------------------------------------------------
163
+
164
+ export trueShouldLog = (label, type, funcName, stack) ->
165
+
166
+ if isMyFunc(funcName || stack.curFunc())
167
+ return undef
168
+ else
169
+ return label
170
+
171
+ # ---------------------------------------------------------------------------
172
+
238
173
  export setDebugging = (option) ->
239
174
 
240
175
  callStack.reset()
241
176
  if isBoolean(option)
242
177
  if option
243
- shouldLog = (label, type, funcName, stack) -> label
178
+ shouldLog = trueShouldLog
244
179
  else
245
- shouldLog = (label, type, funcName, stack) -> undef
180
+ shouldLog = () -> return undef
246
181
  else if isString(option)
247
182
  lFuncList = getFuncList(option)
248
183
  shouldLog = stdShouldLog
@@ -287,29 +222,21 @@ export getFuncList = (str) ->
287
222
  # ---------------------------------------------------------------------------
288
223
  # --- export only to allow unit tests
289
224
 
290
- export funcMatch = () ->
225
+ export funcMatch = (funcName) ->
291
226
 
292
227
  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
228
  for h in lFuncList
299
229
  {name, object, plus} = h
300
- if (name == curFunc)
301
- debugDebug "return from funcMatch() - curFunc in lFuncList"
230
+ if (name == funcName)
302
231
  return true
303
232
  if plus && callStack.isActive(name)
304
- debugDebug "return from funcMatch() - func #{OL(name)} is active"
305
233
  return true
306
- debugDebug "return from funcMatch() - no match"
307
234
  return false
308
235
 
309
236
  # ---------------------------------------------------------------------------
310
- # --- type is one of: 'enter', 'return', 'string', 'object'
237
+ # --- type is one of: 'enter', 'return', 'string'
311
238
 
312
- export getType = (str, nObjects) ->
239
+ export getType = (str, lObjects) ->
313
240
 
314
241
  if lMatches = str.match(///^
315
242
  \s*
@@ -320,7 +247,6 @@ export getType = (str, nObjects) ->
320
247
 
321
248
  # --- We are entering function curFunc
322
249
  return ['enter', lMatches[1]]
323
-
324
250
  else if lMatches = str.match(///^
325
251
  \s*
326
252
  return
@@ -330,9 +256,6 @@ export getType = (str, nObjects) ->
330
256
  ([A-Za-z_][A-Za-z0-9_\.]*)
331
257
  ///)
332
258
  return ['return', lMatches[1]]
333
-
334
- else if (nObjects > 0)
335
- return ['objects', undef]
336
259
  else
337
260
  return ['string', undef]
338
261
 
@@ -346,3 +269,19 @@ reMethod = ///^
346
269
 
347
270
  # ---------------------------------------------------------------------------
348
271
 
272
+ export dumpDebugGlobals = () ->
273
+
274
+ LOG '='.repeat(40)
275
+ LOG callStack.dump()
276
+ if shouldLog == stdShouldLog
277
+ LOG "using stdShouldLog"
278
+ else if shouldLog == trueShouldLog
279
+ LOG "using trueShouldLog"
280
+ else
281
+ LOG "using custom shouldLog"
282
+ LOG "lFuncList:"
283
+ for funcName in lFuncList
284
+ LOG " #{OL(funcName)}"
285
+ LOG '='.repeat(40)
286
+
287
+ # ---------------------------------------------------------------------------