@jdeighan/coffee-utils 7.0.59 → 7.0.62

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 = (label) ->
33
-
34
- LOG callStack.dump('', label)
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
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
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
+ # ---------------------------------------------------------------------------