@jdeighan/coffee-utils 7.0.60 → 7.0.61

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ # ---------------------------------------------------------------------------