@jdeighan/coffee-utils 7.0.57 → 7.0.60

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jdeighan/coffee-utils",
3
3
  "type": "module",
4
- "version": "7.0.57",
4
+ "version": "7.0.60",
5
5
  "description": "A set of utility functions for CoffeeScript",
6
6
  "main": "coffee_utils.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  # call_stack.coffee
2
2
 
3
3
  import {
4
- undef, defined, croak, assert, OL, isBoolean, escapeStr,
4
+ undef, defined, croak, assert, OL, isBoolean, escapeStr, deepCopy,
5
5
  } from '@jdeighan/coffee-utils'
6
6
  import {log, LOG} from '@jdeighan/coffee-utils/log'
7
7
  import {getPrefix} from '@jdeighan/coffee-utils/arrow'
@@ -36,10 +36,9 @@ export class CallStack
36
36
 
37
37
  # ........................................................................
38
38
 
39
- enter: (funcName, oldFlag=undef) ->
39
+ enter: (funcName, lArgs=[]) ->
40
40
  # --- funcName might be <object>.<method>
41
41
 
42
- assert (oldFlag == undef), "enter() takes only 1 arg"
43
42
  if doDebugStack
44
43
  LOG "[--> ENTER #{funcName}]"
45
44
 
@@ -54,20 +53,28 @@ export class CallStack
54
53
  [_, ident1, ident2] = lMatches
55
54
  if ident2
56
55
  @lStack.push({
57
- fullName: "#{ident1}.#{ident2}"
56
+ fullName: funcName # "#{ident1}.#{ident2}"
58
57
  funcName: ident2
59
58
  isLogged: false
59
+ lArgs: deepCopy(lArgs)
60
60
  })
61
61
  else
62
62
  @lStack.push({
63
- fullName: ident1
63
+ fullName: funcName
64
64
  funcName: ident1
65
65
  isLogged: false
66
+ lArgs: deepCopy(lArgs)
66
67
  })
67
68
  return
68
69
 
69
70
  # ........................................................................
70
71
 
72
+ getLevel: () ->
73
+
74
+ return @level
75
+
76
+ # ........................................................................
77
+
71
78
  isLogging: () ->
72
79
 
73
80
  if (@lStack.length == 0)
@@ -86,12 +93,17 @@ export class CallStack
86
93
 
87
94
  # ........................................................................
88
95
 
89
- logCurFunc: () ->
96
+ logCurFunc: (funcName) ->
90
97
 
91
98
  # --- funcName must be the current function
92
99
  # and the isLogged flag must currently be false
100
+
93
101
  cur = @lStack[@lStack.length - 1]
94
102
  assert (cur.isLogged == false), "isLogged is already true"
103
+ if (funcName != cur.fullName)
104
+ LOG "cur func #{cur.fullName} is not #{funcName}"
105
+ LOG @dump()
106
+ croak "BAD"
95
107
  cur.isLogged = true
96
108
  @level += 1
97
109
  return
@@ -126,12 +138,6 @@ export class CallStack
126
138
 
127
139
  # ........................................................................
128
140
 
129
- getLevel: () ->
130
-
131
- return @level
132
-
133
- # ........................................................................
134
-
135
141
  curFunc: () ->
136
142
 
137
143
  if (@lStack.length == 0)
@@ -151,14 +157,38 @@ export class CallStack
151
157
  return false
152
158
 
153
159
  # ........................................................................
154
- # ........................................................................
155
160
 
156
- dump: (prefix='', label='CALL STACK') ->
161
+ dump: () ->
157
162
 
158
- lLines = ["#{label}:"]
163
+ lLines = ["CALL STACK:"]
159
164
  if @lStack.length == 0
160
165
  lLines.push " <EMPTY>"
161
166
  else
162
167
  for item, i in @lStack
163
- lLines.push " #{i}: #{item.fullName} #{item.isLogged}"
164
- return lLines.join("\n") + "\n"
168
+ lLines.push " " + @callStr(i, item)
169
+ return lLines.join("\n")
170
+
171
+ # ........................................................................
172
+
173
+ callStr: (i, item) ->
174
+
175
+ sym = if item.isLogged then '*' else ''
176
+ str = "#{i}#{sym}: #{item.fullName}"
177
+ for arg in item.lArgs
178
+ str += " #{OL(arg)}"
179
+ return str
180
+
181
+ # ........................................................................
182
+
183
+ sdump: (label='CALL STACK') ->
184
+
185
+ lFuncNames = []
186
+ for item in @lStack
187
+ if item.isLogged
188
+ lFuncNames.push '*' + item.fullName
189
+ else
190
+ lFuncNames.push item.fullName
191
+ if @lStack.length == 0
192
+ return "#{label} <EMPTY>"
193
+ else
194
+ return "#{label} #{lFuncNames.join(' ')}"
package/src/call_stack.js CHANGED
@@ -9,7 +9,8 @@ import {
9
9
  assert,
10
10
  OL,
11
11
  isBoolean,
12
- escapeStr
12
+ escapeStr,
13
+ deepCopy
13
14
  } from '@jdeighan/coffee-utils';
14
15
 
15
16
  import {
@@ -45,10 +46,9 @@ export var CallStack = class CallStack {
45
46
  }
46
47
 
47
48
  // ........................................................................
48
- enter(funcName, oldFlag = undef) {
49
+ enter(funcName, lArgs = []) {
49
50
  var _, ident1, ident2, lMatches;
50
51
  // --- funcName might be <object>.<method>
51
- assert(oldFlag === undef, "enter() takes only 1 arg");
52
52
  if (doDebugStack) {
53
53
  LOG(`[--> ENTER ${funcName}]`);
54
54
  }
@@ -57,19 +57,26 @@ export var CallStack = class CallStack {
57
57
  [_, ident1, ident2] = lMatches;
58
58
  if (ident2) {
59
59
  this.lStack.push({
60
- fullName: `${ident1}.${ident2}`,
60
+ fullName: funcName, // "#{ident1}.#{ident2}"
61
61
  funcName: ident2,
62
- isLogged: false
62
+ isLogged: false,
63
+ lArgs: deepCopy(lArgs)
63
64
  });
64
65
  } else {
65
66
  this.lStack.push({
66
- fullName: ident1,
67
+ fullName: funcName,
67
68
  funcName: ident1,
68
- isLogged: false
69
+ isLogged: false,
70
+ lArgs: deepCopy(lArgs)
69
71
  });
70
72
  }
71
73
  }
72
74
 
75
+ // ........................................................................
76
+ getLevel() {
77
+ return this.level;
78
+ }
79
+
73
80
  // ........................................................................
74
81
  isLogging() {
75
82
  if (this.lStack.length === 0) {
@@ -89,12 +96,17 @@ export var CallStack = class CallStack {
89
96
  }
90
97
 
91
98
  // ........................................................................
92
- logCurFunc() {
99
+ logCurFunc(funcName) {
93
100
  var cur;
94
101
  // --- funcName must be the current function
95
102
  // and the isLogged flag must currently be false
96
103
  cur = this.lStack[this.lStack.length - 1];
97
104
  assert(cur.isLogged === false, "isLogged is already true");
105
+ if (funcName !== cur.fullName) {
106
+ LOG(`cur func ${cur.fullName} is not ${funcName}`);
107
+ LOG(this.dump());
108
+ croak("BAD");
109
+ }
98
110
  cur.isLogged = true;
99
111
  this.level += 1;
100
112
  }
@@ -128,11 +140,6 @@ export var CallStack = class CallStack {
128
140
  }
129
141
  }
130
142
 
131
- // ........................................................................
132
- getLevel() {
133
- return this.level;
134
- }
135
-
136
143
  // ........................................................................
137
144
  curFunc() {
138
145
  if (this.lStack.length === 0) {
@@ -158,20 +165,52 @@ export var CallStack = class CallStack {
158
165
  }
159
166
 
160
167
  // ........................................................................
161
- // ........................................................................
162
- dump(prefix = '', label = 'CALL STACK') {
168
+ dump() {
163
169
  var i, item, j, lLines, len, ref;
164
- lLines = [`${label}:`];
170
+ lLines = ["CALL STACK:"];
165
171
  if (this.lStack.length === 0) {
166
172
  lLines.push(" <EMPTY>");
167
173
  } else {
168
174
  ref = this.lStack;
169
175
  for (i = j = 0, len = ref.length; j < len; i = ++j) {
170
176
  item = ref[i];
171
- lLines.push(` ${i}: ${item.fullName} ${item.isLogged}`);
177
+ lLines.push(" " + this.callStr(i, item));
172
178
  }
173
179
  }
174
- return lLines.join("\n") + "\n";
180
+ return lLines.join("\n");
181
+ }
182
+
183
+ // ........................................................................
184
+ callStr(i, item) {
185
+ var arg, j, len, ref, str, sym;
186
+ sym = item.isLogged ? '*' : '';
187
+ str = `${i}${sym}: ${item.fullName}`;
188
+ ref = item.lArgs;
189
+ for (j = 0, len = ref.length; j < len; j++) {
190
+ arg = ref[j];
191
+ str += ` ${OL(arg)}`;
192
+ }
193
+ return str;
194
+ }
195
+
196
+ // ........................................................................
197
+ sdump(label = 'CALL STACK') {
198
+ var item, j, lFuncNames, len, ref;
199
+ lFuncNames = [];
200
+ ref = this.lStack;
201
+ for (j = 0, len = ref.length; j < len; j++) {
202
+ item = ref[j];
203
+ if (item.isLogged) {
204
+ lFuncNames.push('*' + item.fullName);
205
+ } else {
206
+ lFuncNames.push(item.fullName);
207
+ }
208
+ }
209
+ if (this.lStack.length === 0) {
210
+ return `${label} <EMPTY>`;
211
+ } else {
212
+ return `${label} ${lFuncNames.join(' ')}`;
213
+ }
175
214
  }
176
215
 
177
216
  };
@@ -349,7 +349,15 @@ export ltrunc = (str, nChars) ->
349
349
 
350
350
  export deepCopy = (obj) ->
351
351
 
352
- return JSON.parse(JSON.stringify(obj))
352
+ if (obj == undef)
353
+ return undef
354
+ objStr = JSON.stringify(obj)
355
+ try
356
+ newObj = JSON.parse(objStr)
357
+ catch err
358
+ croak "ERROR: err.message", objStr
359
+
360
+ return newObj
353
361
 
354
362
  # ---------------------------------------------------------------------------
355
363
  # escapeStr - escape newlines, TAB chars, etc.
@@ -347,7 +347,18 @@ export var ltrunc = function(str, nChars) {
347
347
  // ---------------------------------------------------------------------------
348
348
  // deepCopy - deep copy an array or object
349
349
  export var deepCopy = function(obj) {
350
- return JSON.parse(JSON.stringify(obj));
350
+ var err, newObj, objStr;
351
+ if (obj === undef) {
352
+ return undef;
353
+ }
354
+ objStr = JSON.stringify(obj);
355
+ try {
356
+ newObj = JSON.parse(objStr);
357
+ } catch (error1) {
358
+ err = error1;
359
+ croak("ERROR: err.message", objStr);
360
+ }
361
+ return newObj;
351
362
  };
352
363
 
353
364
  // ---------------------------------------------------------------------------
@@ -16,11 +16,12 @@ import {
16
16
  log, logItem, LOG, shortEnough, dashes,
17
17
  } from '@jdeighan/coffee-utils/log'
18
18
 
19
- callStack = new CallStack()
20
-
21
19
  # --- set in resetDebugging() and setDebugging()
20
+ export callStack = new CallStack()
22
21
  export shouldLog = () -> undef
23
- export lFuncList = []
22
+
23
+ lFuncList = []
24
+ strFuncList = undef # original string
24
25
 
25
26
  # --- internal debugging
26
27
  doDebugDebug = false
@@ -28,6 +29,13 @@ lFunctions = undef # --- only used when doDebugDebug is true
28
29
 
29
30
  # ---------------------------------------------------------------------------
30
31
 
32
+ export dumpCallStack = () ->
33
+
34
+ LOG callStack.dump()
35
+ return
36
+
37
+ # ---------------------------------------------------------------------------
38
+
31
39
  export setDebugDebugging = (value=true) ->
32
40
  # --- value can be a boolean or string of words
33
41
 
@@ -42,54 +50,72 @@ export setDebugDebugging = (value=true) ->
42
50
 
43
51
  # ---------------------------------------------------------------------------
44
52
 
45
- logif = (label, lObjects...) ->
53
+ debugDebug = (label, lObjects...) ->
54
+ # --- For debugging functions in this module
46
55
 
47
56
  if ! doDebugDebug
48
57
  return
49
58
 
59
+ # --- At this point, doDebugDebug is true
60
+ doDebugDebug = false # temp - reset before returning
61
+
50
62
  assert isString(label), "1st arg #{OL(label)} should be a string"
51
63
  nObjects = lObjects.length
52
64
  [type, funcName] = getType(label, nObjects)
65
+
53
66
  switch type
54
67
  when 'enter'
55
- if defined(lFunctions) && (funcName not in lFunctions)
56
- return
57
- callStack.enter funcName
58
- log label, lObjects...
68
+ assert defined(funcName), "type enter, funcName = undef"
69
+ callStack.enter funcName, lObjects
70
+ doLog = (lFunctions == undef) || (funcName in lFunctions)
71
+
59
72
  when 'return'
60
- if defined(lFunctions) && (funcName not in lFunctions)
61
- return
62
- log label, lObjects...
63
- callStack.returnFrom funcName
73
+ assert defined(funcName), "type return, funcName = undef"
74
+ doLog = (lFunctions == undef) || (funcName in lFunctions)
75
+
64
76
  when 'string'
65
- log label, lObjects...
77
+ assert (funcName == undef), "type string, funcName defined"
78
+ assert (nObjects == 0), "Objects not allowed for #{OL(type)}"
79
+ doLog = true
80
+
66
81
  when 'objects'
67
- log label, lObjects...
82
+ assert (funcName == undef), "type objects, funcName defined"
83
+ assert (nObjects > 0), "Objects required for #{OL(type)}"
84
+ dolog = true
85
+
86
+ if doLog
87
+ doTheLogging type, label, lObjects
88
+
89
+ if (type == 'enter') && doLog
90
+ callStack.logCurFunc(funcName)
91
+ else if (type == 'return')
92
+ callStack.returnFrom funcName
93
+
94
+ doDebugDebug = true
68
95
  return
69
96
 
70
97
  # ---------------------------------------------------------------------------
71
98
 
72
99
  export debug = (label, lObjects...) ->
73
100
 
74
- logif "enter debug(#{OL(label)})", lObjects...
75
-
76
101
  assert isString(label), "1st arg #{OL(label)} should be a string"
77
102
 
78
- # --- We want to allow objects to be undef. Therefore, we need to
79
- # distinguish between 1 arg sent vs. 2 or more args sent
103
+ # --- If label is "enter <funcname>, we need to put that on the stack
104
+ # BEFORE we do any internal logging
80
105
  nObjects = lObjects.length
81
-
82
- # --- funcName is only set for types 'enter' and 'return'
83
106
  [type, funcName] = getType(label, nObjects)
84
- logif "type = #{OL(type)}"
85
- logif "funcName = #{OL(funcName)}"
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)}"
86
113
 
87
114
  # --- function shouldLog() returns the (possibly modified) label
88
115
  # if we should log this, else it returns undef
89
116
 
90
117
  switch type
91
118
  when 'enter'
92
- callStack.enter funcName
93
119
  label = shouldLog(label, type, funcName, callStack)
94
120
  when 'return'
95
121
  label = shouldLog(label, type, funcName, callStack)
@@ -105,57 +131,67 @@ export debug = (label, lObjects...) ->
105
131
  assert (label == undef) || isString(label),
106
132
  "label not a string: #{OL(label)}"
107
133
  doLog = defined(label)
108
- logif "doLog = #{OL(doLog)}"
109
- logif "#{nObjects} objects"
134
+ debugDebug "doLog = #{OL(doLog)}"
135
+ debugDebug "#{nObjects} objects"
110
136
 
111
137
  if doLog
112
- level = callStack.getLevel()
113
- prefix = getPrefix(level)
114
- itemPrefix = removeLastVbar(prefix)
115
- sep = dashes(itemPrefix, 40)
116
- assert isString(sep), "sep is not a string"
117
-
118
- logif "callStack", callStack
119
- logif "level = #{OL(level)}"
120
- logif "prefix = #{OL(prefix)}"
121
- logif "itemPrefix = #{OL(itemPrefix)}"
122
- logif "sep = #{OL(sep)}"
123
-
124
- switch type
125
- when 'enter'
126
- log label, {prefix}
127
- for obj,i in lObjects
128
- if (i > 0)
129
- log sep
130
- logItem undef, obj, {itemPrefix}
131
- when 'return'
132
- log label, {prefix: addArrow(prefix)}
133
- for obj,i in lObjects
134
- if (i > 0)
135
- log sep
136
- logItem undef, obj, {itemPrefix}
137
- when 'string'
138
- log label, {prefix}
139
- when 'objects'
140
- if (nObjects==1) && shortEnough(label, lObjects[0])
141
- logItem label, lObjects[0], {prefix}
142
- else
143
- if (label.indexOf(':') != label.length - 1)
144
- label += ':'
145
- log label, {prefix}
146
- for obj in lObjects
147
- logItem undef, obj, {prefix}
138
+ doTheLogging type, label, lObjects
148
139
 
149
140
  if (type == 'enter') && doLog && (label.indexOf('call') == -1)
150
- callStack.logCurFunc()
151
- else if (type == 'return')
141
+ callStack.logCurFunc(funcName)
142
+
143
+ # --- This must be called BEFORE we return from funcName
144
+ debugDebug "return from debug()"
145
+
146
+ if (type == 'return')
152
147
  callStack.returnFrom funcName
153
148
 
154
- logif "return from debug()"
155
149
  return true # allow use in boolean expressions
156
150
 
157
151
  # ---------------------------------------------------------------------------
158
152
 
153
+ export doTheLogging = (type, label, lObjects) ->
154
+
155
+ 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
+
167
+ switch type
168
+ when 'enter'
169
+ log label, {prefix}
170
+ for obj,i in lObjects
171
+ if (i > 0)
172
+ log sep
173
+ logItem undef, obj, {itemPrefix}
174
+ when 'return'
175
+ log label, {prefix: addArrow(prefix)}
176
+ for obj,i in lObjects
177
+ if (i > 0)
178
+ log sep
179
+ logItem undef, obj, {itemPrefix}
180
+ when 'string'
181
+ log label, {prefix}
182
+ when 'objects'
183
+ if (lObjects.length==1) && shortEnough(label, lObjects[0])
184
+ logItem label, lObjects[0], {prefix}
185
+ else
186
+ if (label.indexOf(':') != label.length - 1)
187
+ label += ':'
188
+ log label, {prefix}
189
+ for obj in lObjects
190
+ logItem undef, obj, {prefix}
191
+ return
192
+
193
+ # ---------------------------------------------------------------------------
194
+
159
195
  export stdShouldLog = (label, type, funcName, stack) ->
160
196
  # --- if type is 'enter', then funcName won't be on the stack yet
161
197
  # returns the (possibly modified) label to log
@@ -172,13 +208,12 @@ export stdShouldLog = (label, type, funcName, stack) ->
172
208
  assert funcName == undef, "func name #{OL(funcName)} not undef"
173
209
  assert stack instanceof CallStack, "not a call stack object"
174
210
 
175
- logif "stdShouldLog(#{OL(label)}, #{OL(type)}, #{OL(funcName)}, stack)"
176
- logif "stack", stack
177
- logif "lFuncList", lFuncList
211
+ debugDebug "enter stdShouldLog(#{OL(label)}, #{OL(type)}, #{OL(funcName)}, stack)"
178
212
 
179
213
  switch type
180
214
  when 'enter'
181
- if funcMatch(stack, lFuncList)
215
+ if funcMatch()
216
+ debugDebug "return #{OL(label)} from stdShouldLog() - funcMatch"
182
217
  return label
183
218
 
184
219
  else
@@ -188,10 +223,14 @@ export stdShouldLog = (label, type, funcName, stack) ->
188
223
 
189
224
  prevLogged = stack.isLoggingPrev()
190
225
  if prevLogged
191
- return label.replace('enter', 'call')
226
+ result = label.replace('enter', 'call')
227
+ debugDebug "return #{OL(result)} from stdShouldLog() - s/enter/call/"
228
+ return result
192
229
  else
193
- if funcMatch(stack, lFuncList)
230
+ if funcMatch()
231
+ debugDebug "return #{OL(label)} from stdShouldLog()"
194
232
  return label
233
+ debugDebug "return undef from stdShouldLog()"
195
234
  return undef
196
235
 
197
236
  # ---------------------------------------------------------------------------
@@ -218,6 +257,7 @@ export setDebugging = (option) ->
218
257
 
219
258
  export getFuncList = (str) ->
220
259
 
260
+ strFuncList = str # store original string for debugging
221
261
  lFuncList = []
222
262
  for word in words(str)
223
263
  if lMatches = word.match(///^
@@ -247,23 +287,23 @@ export getFuncList = (str) ->
247
287
  # ---------------------------------------------------------------------------
248
288
  # --- export only to allow unit tests
249
289
 
250
- export funcMatch = (stack, lFuncList) ->
290
+ export funcMatch = () ->
251
291
 
252
292
  assert isArray(lFuncList), "not an array #{OL(lFuncList)}"
253
293
 
254
- curFunc = stack.curFunc()
255
- logif "funcMatch(): curFunc = #{OL(curFunc)}"
256
- logif stack.dump(' ')
257
- logif 'lFuncList', lFuncList
294
+ debugDebug "enter funcMatch()"
295
+ curFunc = callStack.curFunc()
296
+ debugDebug "curFunc = #{OL(curFunc)}"
297
+ debugDebug "lFuncList = #{strFuncList}"
258
298
  for h in lFuncList
259
299
  {name, object, plus} = h
260
300
  if (name == curFunc)
261
- logif " curFunc in lFuncList - match successful"
301
+ debugDebug "return from funcMatch() - curFunc in lFuncList"
262
302
  return true
263
- if plus && stack.isActive(name)
264
- logif " func #{OL(name)} is active - match successful"
303
+ if plus && callStack.isActive(name)
304
+ debugDebug "return from funcMatch() - func #{OL(name)} is active"
265
305
  return true
266
- logif " - no match"
306
+ debugDebug "return from funcMatch() - no match"
267
307
  return false
268
308
 
269
309
  # ---------------------------------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  // Generated by CoffeeScript 2.7.0
2
2
  // debug_utils.coffee
3
- var callStack, doDebugDebug, lFunctions, logif, reMethod,
3
+ var debugDebug, doDebugDebug, lFuncList, lFunctions, reMethod, strFuncList,
4
4
  indexOf = [].indexOf;
5
5
 
6
6
  import {
@@ -51,14 +51,17 @@ import {
51
51
  dashes
52
52
  } from '@jdeighan/coffee-utils/log';
53
53
 
54
- callStack = new CallStack();
55
-
56
54
  // --- set in resetDebugging() and setDebugging()
55
+ export var callStack = new CallStack();
56
+
57
57
  export var shouldLog = function() {
58
58
  return undef;
59
59
  };
60
60
 
61
- export var lFuncList = [];
61
+ lFuncList = [];
62
+
63
+ strFuncList = undef; // original string
64
+
62
65
 
63
66
  // --- internal debugging
64
67
  doDebugDebug = false;
@@ -66,6 +69,11 @@ doDebugDebug = false;
66
69
  lFunctions = undef; // --- only used when doDebugDebug is true
67
70
 
68
71
 
72
+ // ---------------------------------------------------------------------------
73
+ export var dumpCallStack = function() {
74
+ LOG(callStack.dump());
75
+ };
76
+
69
77
  // ---------------------------------------------------------------------------
70
78
  export var setDebugDebugging = function(value = true) {
71
79
  // --- value can be a boolean or string of words
@@ -80,54 +88,65 @@ export var setDebugDebugging = function(value = true) {
80
88
  };
81
89
 
82
90
  // ---------------------------------------------------------------------------
83
- logif = function(label, ...lObjects) {
84
- var funcName, nObjects, type;
91
+ debugDebug = function(label, ...lObjects) {
92
+ var doLog, dolog, funcName, nObjects, type;
85
93
  if (!doDebugDebug) {
86
94
  return;
87
95
  }
96
+ // --- At this point, doDebugDebug is true
97
+ doDebugDebug = false; // temp - reset before returning
88
98
  assert(isString(label), `1st arg ${OL(label)} should be a string`);
89
99
  nObjects = lObjects.length;
90
100
  [type, funcName] = getType(label, nObjects);
91
101
  switch (type) {
92
102
  case 'enter':
93
- if (defined(lFunctions) && (indexOf.call(lFunctions, funcName) < 0)) {
94
- return;
95
- }
96
- callStack.enter(funcName);
97
- log(label, ...lObjects);
103
+ assert(defined(funcName), "type enter, funcName = undef");
104
+ callStack.enter(funcName, lObjects);
105
+ doLog = (lFunctions === undef) || (indexOf.call(lFunctions, funcName) >= 0);
98
106
  break;
99
107
  case 'return':
100
- if (defined(lFunctions) && (indexOf.call(lFunctions, funcName) < 0)) {
101
- return;
102
- }
103
- log(label, ...lObjects);
104
- callStack.returnFrom(funcName);
108
+ assert(defined(funcName), "type return, funcName = undef");
109
+ doLog = (lFunctions === undef) || (indexOf.call(lFunctions, funcName) >= 0);
105
110
  break;
106
111
  case 'string':
107
- log(label, ...lObjects);
112
+ assert(funcName === undef, "type string, funcName defined");
113
+ assert(nObjects === 0, `Objects not allowed for ${OL(type)}`);
114
+ doLog = true;
108
115
  break;
109
116
  case 'objects':
110
- log(label, ...lObjects);
117
+ assert(funcName === undef, "type objects, funcName defined");
118
+ assert(nObjects > 0, `Objects required for ${OL(type)}`);
119
+ dolog = true;
120
+ }
121
+ if (doLog) {
122
+ doTheLogging(type, label, lObjects);
123
+ }
124
+ if ((type === 'enter') && doLog) {
125
+ callStack.logCurFunc(funcName);
126
+ } else if (type === 'return') {
127
+ callStack.returnFrom(funcName);
111
128
  }
129
+ doDebugDebug = true;
112
130
  };
113
131
 
114
132
  // ---------------------------------------------------------------------------
115
133
  export var debug = function(label, ...lObjects) {
116
- var doLog, funcName, i, itemPrefix, j, k, l, len, len1, len2, level, nObjects, obj, prefix, sep, type;
117
- logif(`enter debug(${OL(label)})`, ...lObjects);
134
+ var doLog, funcName, nObjects, type;
118
135
  assert(isString(label), `1st arg ${OL(label)} should be a string`);
119
- // --- We want to allow objects to be undef. Therefore, we need to
120
- // distinguish between 1 arg sent vs. 2 or more args sent
136
+ // --- If label is "enter <funcname>, we need to put that on the stack
137
+ // BEFORE we do any internal logging
121
138
  nObjects = lObjects.length;
122
- // --- funcName is only set for types 'enter' and 'return'
123
139
  [type, funcName] = getType(label, nObjects);
124
- logif(`type = ${OL(type)}`);
125
- logif(`funcName = ${OL(funcName)}`);
140
+ if (type === 'enter') {
141
+ callStack.enter(funcName, lObjects);
142
+ }
143
+ debugDebug(`enter debug(${OL(label)})`, ...lObjects);
144
+ debugDebug(`type = ${OL(type)}`);
145
+ debugDebug(`funcName = ${OL(funcName)}`);
126
146
  // --- function shouldLog() returns the (possibly modified) label
127
147
  // if we should log this, else it returns undef
128
148
  switch (type) {
129
149
  case 'enter':
130
- callStack.enter(funcName);
131
150
  label = shouldLog(label, type, funcName, callStack);
132
151
  break;
133
152
  case 'return':
@@ -143,73 +162,81 @@ export var debug = function(label, ...lObjects) {
143
162
  }
144
163
  assert((label === undef) || isString(label), `label not a string: ${OL(label)}`);
145
164
  doLog = defined(label);
146
- logif(`doLog = ${OL(doLog)}`);
147
- logif(`${nObjects} objects`);
165
+ debugDebug(`doLog = ${OL(doLog)}`);
166
+ debugDebug(`${nObjects} objects`);
148
167
  if (doLog) {
149
- level = callStack.getLevel();
150
- prefix = getPrefix(level);
151
- itemPrefix = removeLastVbar(prefix);
152
- sep = dashes(itemPrefix, 40);
153
- assert(isString(sep), "sep is not a string");
154
- logif("callStack", callStack);
155
- logif(`level = ${OL(level)}`);
156
- logif(`prefix = ${OL(prefix)}`);
157
- logif(`itemPrefix = ${OL(itemPrefix)}`);
158
- logif(`sep = ${OL(sep)}`);
159
- switch (type) {
160
- case 'enter':
161
- log(label, {prefix});
162
- for (i = j = 0, len = lObjects.length; j < len; i = ++j) {
163
- obj = lObjects[i];
164
- if (i > 0) {
165
- log(sep);
166
- }
167
- logItem(undef, obj, {itemPrefix});
168
- }
169
- break;
170
- case 'return':
171
- log(label, {
172
- prefix: addArrow(prefix)
173
- });
174
- for (i = k = 0, len1 = lObjects.length; k < len1; i = ++k) {
175
- obj = lObjects[i];
176
- if (i > 0) {
177
- log(sep);
178
- }
179
- logItem(undef, obj, {itemPrefix});
180
- }
181
- break;
182
- case 'string':
183
- log(label, {prefix});
184
- break;
185
- case 'objects':
186
- if ((nObjects === 1) && shortEnough(label, lObjects[0])) {
187
- logItem(label, lObjects[0], {prefix});
188
- } else {
189
- if (label.indexOf(':') !== label.length - 1) {
190
- label += ':';
191
- }
192
- log(label, {prefix});
193
- for (l = 0, len2 = lObjects.length; l < len2; l++) {
194
- obj = lObjects[l];
195
- logItem(undef, obj, {prefix});
196
- }
197
- }
198
- }
168
+ doTheLogging(type, label, lObjects);
199
169
  }
200
170
  if ((type === 'enter') && doLog && (label.indexOf('call') === -1)) {
201
- callStack.logCurFunc();
202
- } else if (type === 'return') {
171
+ callStack.logCurFunc(funcName);
172
+ }
173
+ // --- This must be called BEFORE we return from funcName
174
+ debugDebug("return from debug()");
175
+ if (type === 'return') {
203
176
  callStack.returnFrom(funcName);
204
177
  }
205
- logif("return from debug()");
206
178
  return true; // allow use in boolean expressions
207
179
  };
208
180
 
209
181
 
182
+ // ---------------------------------------------------------------------------
183
+ export var doTheLogging = function(type, label, lObjects) {
184
+ var i, itemPrefix, j, k, l, len, len1, len2, level, obj, prefix, sep;
185
+ level = callStack.getLevel();
186
+ prefix = getPrefix(level);
187
+ itemPrefix = removeLastVbar(prefix);
188
+ sep = dashes(itemPrefix, 40);
189
+ assert(isString(sep), "sep is not a string");
190
+ debugDebug("callStack", callStack);
191
+ debugDebug(`level = ${OL(level)}`);
192
+ debugDebug(`prefix = ${OL(prefix)}`);
193
+ debugDebug(`itemPrefix = ${OL(itemPrefix)}`);
194
+ debugDebug(`sep = ${OL(sep)}`);
195
+ switch (type) {
196
+ case 'enter':
197
+ log(label, {prefix});
198
+ for (i = j = 0, len = lObjects.length; j < len; i = ++j) {
199
+ obj = lObjects[i];
200
+ if (i > 0) {
201
+ log(sep);
202
+ }
203
+ logItem(undef, obj, {itemPrefix});
204
+ }
205
+ break;
206
+ case 'return':
207
+ log(label, {
208
+ prefix: addArrow(prefix)
209
+ });
210
+ for (i = k = 0, len1 = lObjects.length; k < len1; i = ++k) {
211
+ obj = lObjects[i];
212
+ if (i > 0) {
213
+ log(sep);
214
+ }
215
+ logItem(undef, obj, {itemPrefix});
216
+ }
217
+ break;
218
+ case 'string':
219
+ log(label, {prefix});
220
+ break;
221
+ case 'objects':
222
+ if ((lObjects.length === 1) && shortEnough(label, lObjects[0])) {
223
+ logItem(label, lObjects[0], {prefix});
224
+ } else {
225
+ if (label.indexOf(':') !== label.length - 1) {
226
+ label += ':';
227
+ }
228
+ log(label, {prefix});
229
+ for (l = 0, len2 = lObjects.length; l < len2; l++) {
230
+ obj = lObjects[l];
231
+ logItem(undef, obj, {prefix});
232
+ }
233
+ }
234
+ }
235
+ };
236
+
210
237
  // ---------------------------------------------------------------------------
211
238
  export var stdShouldLog = function(label, type, funcName, stack) {
212
- var prevLogged;
239
+ var prevLogged, result;
213
240
  // --- if type is 'enter', then funcName won't be on the stack yet
214
241
  // returns the (possibly modified) label to log
215
242
 
@@ -224,12 +251,11 @@ export var stdShouldLog = function(label, type, funcName, stack) {
224
251
  assert(funcName === undef, `func name ${OL(funcName)} not undef`);
225
252
  }
226
253
  assert(stack instanceof CallStack, "not a call stack object");
227
- logif(`stdShouldLog(${OL(label)}, ${OL(type)}, ${OL(funcName)}, stack)`);
228
- logif("stack", stack);
229
- logif("lFuncList", lFuncList);
254
+ debugDebug(`enter stdShouldLog(${OL(label)}, ${OL(type)}, ${OL(funcName)}, stack)`);
230
255
  switch (type) {
231
256
  case 'enter':
232
- if (funcMatch(stack, lFuncList)) {
257
+ if (funcMatch()) {
258
+ debugDebug(`return ${OL(label)} from stdShouldLog() - funcMatch`);
233
259
  return label;
234
260
  } else {
235
261
  // --- As a special case, if we enter a function where we will not
@@ -237,15 +263,19 @@ export var stdShouldLog = function(label, type, funcName, stack) {
237
263
  // we'll log out the call itself
238
264
  prevLogged = stack.isLoggingPrev();
239
265
  if (prevLogged) {
240
- return label.replace('enter', 'call');
266
+ result = label.replace('enter', 'call');
267
+ debugDebug(`return ${OL(result)} from stdShouldLog() - s/enter/call/`);
268
+ return result;
241
269
  }
242
270
  }
243
271
  break;
244
272
  default:
245
- if (funcMatch(stack, lFuncList)) {
273
+ if (funcMatch()) {
274
+ debugDebug(`return ${OL(label)} from stdShouldLog()`);
246
275
  return label;
247
276
  }
248
277
  }
278
+ debugDebug("return undef from stdShouldLog()");
249
279
  return undef;
250
280
  };
251
281
 
@@ -276,6 +306,7 @@ export var setDebugging = function(option) {
276
306
  // --- export only to allow unit tests
277
307
  export var getFuncList = function(str) {
278
308
  var _, ident1, ident2, j, lMatches, len, plus, ref, word;
309
+ strFuncList = str; // store original string for debugging
279
310
  lFuncList = [];
280
311
  ref = words(str);
281
312
  for (j = 0, len = ref.length; j < len; j++) {
@@ -303,26 +334,26 @@ export var getFuncList = function(str) {
303
334
 
304
335
  // ---------------------------------------------------------------------------
305
336
  // --- export only to allow unit tests
306
- export var funcMatch = function(stack, lFuncList) {
337
+ export var funcMatch = function() {
307
338
  var curFunc, h, j, len, name, object, plus;
308
339
  assert(isArray(lFuncList), `not an array ${OL(lFuncList)}`);
309
- curFunc = stack.curFunc();
310
- logif(`funcMatch(): curFunc = ${OL(curFunc)}`);
311
- logif(stack.dump(' '));
312
- logif('lFuncList', lFuncList);
340
+ debugDebug("enter funcMatch()");
341
+ curFunc = callStack.curFunc();
342
+ debugDebug(`curFunc = ${OL(curFunc)}`);
343
+ debugDebug(`lFuncList = ${strFuncList}`);
313
344
  for (j = 0, len = lFuncList.length; j < len; j++) {
314
345
  h = lFuncList[j];
315
346
  ({name, object, plus} = h);
316
347
  if (name === curFunc) {
317
- logif(" curFunc in lFuncList - match successful");
348
+ debugDebug("return from funcMatch() - curFunc in lFuncList");
318
349
  return true;
319
350
  }
320
- if (plus && stack.isActive(name)) {
321
- logif(` func ${OL(name)} is active - match successful`);
351
+ if (plus && callStack.isActive(name)) {
352
+ debugDebug(`return from funcMatch() - func ${OL(name)} is active`);
322
353
  return true;
323
354
  }
324
355
  }
325
- logif(" - no match");
356
+ debugDebug("return from funcMatch() - no match");
326
357
  return false;
327
358
  };
328
359