@jdeighan/coffee-utils 7.0.49 → 7.0.52
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.
- package/package.json +2 -2
- package/src/arrow.coffee +40 -4
- package/src/arrow.js +46 -5
- package/src/call_stack.coffee +93 -46
- package/src/call_stack.js +94 -47
- package/src/coffee_utils.coffee +12 -0
- package/src/coffee_utils.js +11 -0
- package/src/debug_utils.coffee +211 -145
- package/src/debug_utils.js +245 -138
- package/src/log_utils.coffee +49 -26
- package/src/log_utils.js +48 -27
package/src/debug_utils.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
2
2
|
// debug_utils.coffee
|
3
|
-
var
|
3
|
+
var callStack, doDebugDebug, reMethod, resetDebugging;
|
4
4
|
|
5
5
|
import {
|
6
6
|
assert,
|
@@ -8,9 +8,11 @@ import {
|
|
8
8
|
error,
|
9
9
|
croak,
|
10
10
|
warn,
|
11
|
+
defined,
|
11
12
|
isString,
|
12
13
|
isFunction,
|
13
14
|
isBoolean,
|
15
|
+
sep_dash,
|
14
16
|
OL,
|
15
17
|
escapeStr,
|
16
18
|
isNumber,
|
@@ -35,28 +37,170 @@ import {
|
|
35
37
|
CallStack
|
36
38
|
} from '@jdeighan/coffee-utils/stack';
|
37
39
|
|
40
|
+
import {
|
41
|
+
getPrefix,
|
42
|
+
addArrow,
|
43
|
+
removeLastVbar
|
44
|
+
} from '@jdeighan/coffee-utils/arrow';
|
45
|
+
|
38
46
|
import {
|
39
47
|
log,
|
40
48
|
logItem,
|
41
49
|
LOG,
|
42
|
-
|
43
|
-
orderedStringify
|
50
|
+
shortEnough
|
44
51
|
} from '@jdeighan/coffee-utils/log';
|
45
52
|
|
46
|
-
|
47
|
-
export var debugging = false;
|
53
|
+
callStack = new CallStack();
|
48
54
|
|
49
|
-
|
50
|
-
|
51
|
-
|
55
|
+
doDebugDebug = false;
|
56
|
+
|
57
|
+
export var shouldLog = undef; // set in resetDebugging() and setDebugging()
|
58
|
+
|
59
|
+
export var lFuncList = [];
|
52
60
|
|
53
|
-
|
54
|
-
|
61
|
+
// ---------------------------------------------------------------------------
|
62
|
+
export var debug = function(label, ...lObjects) {
|
63
|
+
var doLog, funcName, i, j, k, l, len1, len2, len3, level, nObjects, obj, prefix, type;
|
64
|
+
assert(isString(label), `1st arg ${OL(label)} should be a string`);
|
65
|
+
// --- We want to allow objects to be undef. Therefore, we need to
|
66
|
+
// distinguish between 1 arg sent vs. 2 or more args sent
|
67
|
+
nObjects = lObjects.length;
|
68
|
+
// --- funcName is only set for types 'enter' and 'return'
|
69
|
+
[type, funcName] = getType(label, nObjects);
|
70
|
+
if (doDebugDebug) {
|
71
|
+
LOG(`debug(): type = ${OL(type)}`);
|
72
|
+
LOG(`debug(): funcName = ${OL(funcName)}`);
|
73
|
+
}
|
74
|
+
switch (type) {
|
75
|
+
case 'enter':
|
76
|
+
callStack.enter(funcName);
|
77
|
+
label = shouldLog(label, type, funcName, callStack);
|
78
|
+
break;
|
79
|
+
case 'return':
|
80
|
+
label = shouldLog(label, type, funcName, callStack);
|
81
|
+
break;
|
82
|
+
case 'string':
|
83
|
+
label = shouldLog(label, type, undef, callStack);
|
84
|
+
assert(nObjects === 0, `multiple objects only not allowed for ${OL(type)}`);
|
85
|
+
break;
|
86
|
+
case 'objects':
|
87
|
+
label = shouldLog(label, type, undef, callStack);
|
88
|
+
assert(nObjects > 0, `multiple objects only not allowed for ${OL(type)}`);
|
89
|
+
}
|
90
|
+
doLog = defined(label);
|
91
|
+
if (doDebugDebug) {
|
92
|
+
if (nObjects === 0) {
|
93
|
+
LOG(`debug(${OL(label)}) - 1 arg`);
|
94
|
+
} else {
|
95
|
+
LOG(`debug(${OL(label)}), ${nObjects} args`);
|
96
|
+
}
|
97
|
+
LOG(`doLog = ${OL(doLog)}`);
|
98
|
+
}
|
99
|
+
if (doLog) {
|
100
|
+
level = callStack.getLevel();
|
101
|
+
prefix = getPrefix(level);
|
102
|
+
if (doDebugDebug) {
|
103
|
+
LOG("callStack", callStack);
|
104
|
+
LOG(`level = ${OL(level)}`);
|
105
|
+
LOG(`prefix = ${OL(prefix)}`);
|
106
|
+
}
|
107
|
+
switch (type) {
|
108
|
+
case 'enter':
|
109
|
+
log(label, {prefix});
|
110
|
+
for (i = j = 0, len1 = lObjects.length; j < len1; i = ++j) {
|
111
|
+
obj = lObjects[i];
|
112
|
+
if (i > 0) {
|
113
|
+
log(sep_dash, {
|
114
|
+
prefix: removeLastVbar(prefix)
|
115
|
+
});
|
116
|
+
}
|
117
|
+
logItem(undef, obj, {
|
118
|
+
prefix: removeLastVbar(prefix)
|
119
|
+
});
|
120
|
+
}
|
121
|
+
break;
|
122
|
+
case 'return':
|
123
|
+
log(label, {
|
124
|
+
prefix: addArrow(prefix)
|
125
|
+
});
|
126
|
+
for (i = k = 0, len2 = lObjects.length; k < len2; i = ++k) {
|
127
|
+
obj = lObjects[i];
|
128
|
+
if (i > 0) {
|
129
|
+
log(sep_dash, {
|
130
|
+
prefix: removeLastVbar(prefix)
|
131
|
+
});
|
132
|
+
}
|
133
|
+
logItem(undef, obj, {
|
134
|
+
prefix: removeLastVbar(prefix)
|
135
|
+
});
|
136
|
+
}
|
137
|
+
break;
|
138
|
+
case 'string':
|
139
|
+
log(label, {prefix});
|
140
|
+
break;
|
141
|
+
case 'objects':
|
142
|
+
if ((nObjects === 1) && shortEnough(label, lObjects[0])) {
|
143
|
+
logItem(label, lObjects[0], {prefix});
|
144
|
+
} else {
|
145
|
+
if (label.indexOf(':') !== label.length - 1) {
|
146
|
+
label += ':';
|
147
|
+
}
|
148
|
+
log(label, {prefix});
|
149
|
+
for (l = 0, len3 = lObjects.length; l < len3; l++) {
|
150
|
+
obj = lObjects[l];
|
151
|
+
logItem(undef, obj, {prefix});
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}
|
155
|
+
}
|
156
|
+
if ((type === 'enter') && doLog) {
|
157
|
+
callStack.logCurFunc();
|
158
|
+
} else if (type === 'return') {
|
159
|
+
callStack.returnFrom(funcName);
|
160
|
+
}
|
161
|
+
return true; // allow use in boolean expressions
|
55
162
|
};
|
56
163
|
|
57
|
-
stack = new CallStack();
|
58
164
|
|
59
|
-
|
165
|
+
// ---------------------------------------------------------------------------
|
166
|
+
export var stdShouldLog = function(label, type, funcName, stack) {
|
167
|
+
// --- if type is 'enter', then funcName won't be on the stack yet
|
168
|
+
// returns the (possibly modified) label to log
|
169
|
+
|
170
|
+
// --- If we're logging now,
|
171
|
+
// but we won't be logging when funcName is activated
|
172
|
+
// then change 'enter' to 'call'
|
173
|
+
assert(isString(label), `label ${OL(label)} not a string`);
|
174
|
+
assert(isString(type), `type ${OL(type)} not a string`);
|
175
|
+
if ((type === 'enter') || (type === 'return')) {
|
176
|
+
assert(isString(funcName), `func name ${OL(funcName)} not a string`);
|
177
|
+
} else {
|
178
|
+
assert(funcName === undef, `func name ${OL(funcName)} not undef`);
|
179
|
+
}
|
180
|
+
assert(stack instanceof CallStack, "not a call stack object");
|
181
|
+
if (doDebugDebug) {
|
182
|
+
LOG(`stdShouldLog(${OL(label)}, ${OL(type)}, ${OL(funcName)}, stack)`);
|
183
|
+
LOG("stack", stack);
|
184
|
+
LOG("lFuncList", lFuncList);
|
185
|
+
}
|
186
|
+
switch (type) {
|
187
|
+
case 'enter':
|
188
|
+
if (funcMatch(stack, lFuncList)) {
|
189
|
+
return label;
|
190
|
+
// --- As a special case, if we enter a function where we will not
|
191
|
+
// be logging, but we were logging in the calling function,
|
192
|
+
// we'll log out the call itself
|
193
|
+
} else if (stack.isLoggingPrev()) {
|
194
|
+
return label.replace('enter', 'call');
|
195
|
+
}
|
196
|
+
break;
|
197
|
+
default:
|
198
|
+
if (funcMatch(stack, lFuncList)) {
|
199
|
+
return label;
|
200
|
+
}
|
201
|
+
}
|
202
|
+
return undef;
|
203
|
+
};
|
60
204
|
|
61
205
|
// ---------------------------------------------------------------------------
|
62
206
|
export var debugDebug = function(flag = true) {
|
@@ -68,174 +212,137 @@ export var debugDebug = function(flag = true) {
|
|
68
212
|
|
69
213
|
// ---------------------------------------------------------------------------
|
70
214
|
resetDebugging = function() {
|
71
|
-
debugging = false;
|
72
215
|
if (doDebugDebug) {
|
73
|
-
LOG("resetDebugging()
|
216
|
+
LOG("resetDebugging()");
|
74
217
|
}
|
75
|
-
|
76
|
-
|
77
|
-
return
|
78
|
-
};
|
79
|
-
shouldLogString = function(str) {
|
80
|
-
return debugging;
|
218
|
+
callStack.reset();
|
219
|
+
shouldLog = function(label, type, funcName, stack) {
|
220
|
+
return undef;
|
81
221
|
};
|
82
222
|
};
|
83
223
|
|
84
224
|
// ---------------------------------------------------------------------------
|
85
|
-
export var setDebugging = function(
|
86
|
-
var lFuncNames;
|
225
|
+
export var setDebugging = function(option) {
|
87
226
|
resetDebugging();
|
88
|
-
if (isBoolean(
|
89
|
-
|
227
|
+
if (isBoolean(option)) {
|
228
|
+
if (option) {
|
229
|
+
shouldLog = function(label, type, funcName, stack) {
|
230
|
+
return label;
|
231
|
+
};
|
232
|
+
} else {
|
233
|
+
shouldLog = function(label, type, funcName, stack) {
|
234
|
+
return undef;
|
235
|
+
};
|
236
|
+
}
|
90
237
|
if (doDebugDebug) {
|
91
|
-
LOG(`setDebugging
|
238
|
+
LOG(`setDebugging = ${option}`);
|
92
239
|
}
|
93
|
-
} else if (isString(
|
94
|
-
|
95
|
-
|
96
|
-
assert(isArray(lFuncNames), `words('${funcDoDebug}') returned non-array`);
|
97
|
-
shouldLogFunc = function(funcName) {
|
98
|
-
return funcMatch(funcName, lFuncNames);
|
99
|
-
};
|
240
|
+
} else if (isString(option)) {
|
241
|
+
lFuncList = getFuncList(option);
|
242
|
+
shouldLog = stdShouldLog;
|
100
243
|
if (doDebugDebug) {
|
101
|
-
LOG(`setDebugging FUNCS: ${
|
244
|
+
LOG(`setDebugging FUNCS: ${option}`);
|
245
|
+
LOG('lFuncList', lFuncList);
|
102
246
|
}
|
103
|
-
} else if (isFunction(
|
104
|
-
|
247
|
+
} else if (isFunction(option)) {
|
248
|
+
shouldLog = option;
|
105
249
|
if (doDebugDebug) {
|
106
250
|
LOG("setDebugging to custom func");
|
107
251
|
}
|
108
252
|
} else {
|
109
|
-
croak(`
|
110
|
-
}
|
111
|
-
if (funcDoLog) {
|
112
|
-
assert(isFunction(funcDoLog), "setDebugging: arg 2 not a function");
|
113
|
-
shouldLogString = funcDoLog;
|
253
|
+
croak(`bad parameter ${OL(option)}`);
|
114
254
|
}
|
115
255
|
};
|
116
256
|
|
117
257
|
// ---------------------------------------------------------------------------
|
118
258
|
// --- export only to allow unit tests
|
119
|
-
export var
|
120
|
-
var _,
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
hEnv = {debugging, shouldLogFunc, shouldLogString};
|
142
|
-
debugging = shouldLogFunc(curFunc);
|
143
|
-
if (doDebugDebug) {
|
144
|
-
trans = `${hEnv.debugging} => ${debugging}`;
|
145
|
-
LOG(` ENTER ${curFunc}, debugging: ${trans}`);
|
146
|
-
}
|
147
|
-
[mainPre, auxPre, _] = stack.call(curFunc, hEnv, debugging);
|
148
|
-
return [mainPre, auxPre, undef, shouldLogFunc(curFunc) ? 'enter' : undef];
|
149
|
-
} else if ((lMatches = str.match(/^\s*return.+from\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
|
150
|
-
curFunc = lMatches[1];
|
151
|
-
[mainPre, auxPre, hEnv] = stack.returnFrom(curFunc);
|
152
|
-
if (doDebugDebug) {
|
153
|
-
LOG(` RETURN FROM ${curFunc}`);
|
259
|
+
export var getFuncList = function(str) {
|
260
|
+
var _, ident1, ident2, j, lMatches, len1, plus, ref, word;
|
261
|
+
lFuncList = [];
|
262
|
+
ref = words(str);
|
263
|
+
for (j = 0, len1 = ref.length; j < len1; j++) {
|
264
|
+
word = ref[j];
|
265
|
+
if (lMatches = word.match(/^([A-Za-z_][A-Za-z0-9_]*)(?:\.([A-Za-z_][A-Za-z0-9_]*))?(\+)?$/)) {
|
266
|
+
[_, ident1, ident2, plus] = lMatches;
|
267
|
+
if (ident2) {
|
268
|
+
lFuncList.push({
|
269
|
+
name: ident2,
|
270
|
+
object: ident1,
|
271
|
+
plus: plus === '+'
|
272
|
+
});
|
273
|
+
} else {
|
274
|
+
lFuncList.push({
|
275
|
+
name: ident1,
|
276
|
+
plus: plus === '+'
|
277
|
+
});
|
278
|
+
}
|
279
|
+
} else {
|
280
|
+
croak(`Bad word in func list: ${OL(word)}`);
|
154
281
|
}
|
155
|
-
return [mainPre, auxPre, hEnv, shouldLogFunc(curFunc) ? 'return' : undef];
|
156
|
-
} else {
|
157
|
-
[mainPre, auxPre, _] = stack.logStr();
|
158
|
-
return [mainPre, auxPre, undef, shouldLogString(str) ? 'string' : undef];
|
159
282
|
}
|
283
|
+
return lFuncList;
|
160
284
|
};
|
161
285
|
|
162
286
|
// ---------------------------------------------------------------------------
|
163
|
-
export
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
assert((nArgs === 1) || (nArgs === 2), `debug(): ${nArgs} args`);
|
169
|
-
[label, item] = lArgs;
|
170
|
-
assert(isString(label), `debug(): 1st arg ${OL(label)} should be a string`);
|
171
|
-
if (doDebugDebug) {
|
172
|
-
if (nArgs === 1) {
|
173
|
-
LOG(`debug('${escapeStr(label)}') - 1 arg`);
|
174
|
-
} else {
|
175
|
-
LOG(`debug('${escapeStr(label)}', ${typeof item}) - 2 args`);
|
176
|
-
}
|
177
|
-
LOG(`debugging flag = ${OL(debugging)}`);
|
178
|
-
}
|
179
|
-
// --- We always need to manipulate the stack when we encounter
|
180
|
-
// either "enter X" or "return from X", so we can't short-circuit
|
181
|
-
// when debugging is off
|
182
|
-
lResult = adjustStack(label);
|
287
|
+
// --- export only to allow unit tests
|
288
|
+
export var funcMatch = function(stack, lFuncList) {
|
289
|
+
var curFunc, h, j, len1, name, object, plus;
|
290
|
+
assert(isArray(lFuncList), `not an array ${OL(lFuncList)}`);
|
291
|
+
curFunc = stack.curFunc();
|
183
292
|
if (doDebugDebug) {
|
184
|
-
LOG(
|
293
|
+
LOG(`funcMatch(): curFunc = ${OL(curFunc)}`);
|
294
|
+
stack.dump(' ');
|
295
|
+
LOG('lFuncList', lFuncList);
|
185
296
|
}
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
itemPrefix: auxPre
|
193
|
-
};
|
194
|
-
switch (type) {
|
195
|
-
case 'enter':
|
196
|
-
log(label, hOptions);
|
197
|
-
if (nArgs === 2) {
|
198
|
-
// --- don't repeat the label
|
199
|
-
logItem(undef, item, hOptions);
|
200
|
-
}
|
201
|
-
break;
|
202
|
-
case 'return':
|
203
|
-
log(label, hOptions);
|
204
|
-
if (nArgs === 2) {
|
205
|
-
// --- don't repeat the label
|
206
|
-
logItem(undef, item, hOptions);
|
297
|
+
for (j = 0, len1 = lFuncList.length; j < len1; j++) {
|
298
|
+
h = lFuncList[j];
|
299
|
+
({name, object, plus} = h);
|
300
|
+
if (name === curFunc) {
|
301
|
+
if (doDebugDebug) {
|
302
|
+
LOG(" curFunc in lFuncList - match successful");
|
207
303
|
}
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
log(label, hOptions);
|
304
|
+
return true;
|
305
|
+
}
|
306
|
+
if (plus && stack.isActive(name)) {
|
307
|
+
if (doDebugDebug) {
|
308
|
+
LOG(` func ${OL(name)} is active - match successful`);
|
214
309
|
}
|
215
|
-
|
216
|
-
if (hEnv) {
|
217
|
-
orgDebugging = debugging;
|
218
|
-
({debugging, shouldLogFunc, shouldLogString} = hEnv);
|
219
|
-
if (doDebugDebug) {
|
220
|
-
trans = `${orgDebugging} => ${debugging}`;
|
221
|
-
LOG(` Restore hEnv: debugging: ${trans}`);
|
310
|
+
return true;
|
222
311
|
}
|
223
312
|
}
|
224
|
-
|
313
|
+
if (doDebugDebug) {
|
314
|
+
LOG(" - no match");
|
315
|
+
}
|
316
|
+
return false;
|
225
317
|
};
|
226
318
|
|
319
|
+
// ---------------------------------------------------------------------------
|
320
|
+
// --- type is one of: 'enter', 'return', 'string', 'object'
|
321
|
+
export var getType = function(str, nObjects) {
|
322
|
+
var lMatches;
|
323
|
+
if (lMatches = str.match(/^\s*enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
|
324
|
+
// --- We are entering function curFunc
|
325
|
+
return ['enter', lMatches[1]];
|
326
|
+
} else if (lMatches = str.match(/^\s*return.+from\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
|
327
|
+
return ['return', lMatches[1]];
|
328
|
+
} else if (nObjects > 0) {
|
329
|
+
return ['objects', undef];
|
330
|
+
} else {
|
331
|
+
return ['string', undef];
|
332
|
+
}
|
333
|
+
};
|
227
334
|
|
228
335
|
// ---------------------------------------------------------------------------
|
229
336
|
reMethod = /^([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)$/;
|
230
337
|
|
231
338
|
// ---------------------------------------------------------------------------
|
232
339
|
export var checkTrace = function(block) {
|
233
|
-
var funcName,
|
340
|
+
var funcName, j, lMatches, lStack, len, len1, line, ref;
|
234
341
|
// --- export only to allow unit tests
|
235
342
|
lStack = [];
|
236
343
|
ref = blockToArray(block);
|
237
|
-
for (
|
238
|
-
line = ref[
|
344
|
+
for (j = 0, len1 = ref.length; j < len1; j++) {
|
345
|
+
line = ref[j];
|
239
346
|
if (lMatches = line.match(/enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
|
240
347
|
funcName = lMatches[1];
|
241
348
|
lStack.push(funcName);
|
package/src/log_utils.coffee
CHANGED
@@ -4,15 +4,28 @@ import yaml from 'js-yaml'
|
|
4
4
|
|
5
5
|
import {
|
6
6
|
assert, undef, isNumber, isInteger, isString, isHash, isFunction,
|
7
|
-
escapeStr, sep_eq, sep_dash, pass
|
7
|
+
escapeStr, sep_eq, sep_dash, pass, OL,
|
8
8
|
} from '@jdeighan/coffee-utils'
|
9
9
|
import {blockToArray} from '@jdeighan/coffee-utils/block'
|
10
|
-
import {
|
10
|
+
import {
|
11
|
+
tabify, untabify, indentation, indented,
|
12
|
+
} from '@jdeighan/coffee-utils/indent'
|
11
13
|
|
12
14
|
# --- This logger only ever gets passed a single string argument
|
13
15
|
putstr = undef
|
16
|
+
doDebugLog = false
|
14
17
|
|
15
18
|
export stringify = undef
|
19
|
+
fourSpaces = ' '
|
20
|
+
|
21
|
+
# ---------------------------------------------------------------------------
|
22
|
+
|
23
|
+
export debugLog = (flag=true) ->
|
24
|
+
|
25
|
+
doDebugLog = flag
|
26
|
+
if doDebugLog
|
27
|
+
LOG "doDebugLog = #{flag}"
|
28
|
+
return
|
16
29
|
|
17
30
|
# ---------------------------------------------------------------------------
|
18
31
|
# This is useful for debugging
|
@@ -23,9 +36,9 @@ export LOG = (lArgs...) ->
|
|
23
36
|
if lArgs.length > 1
|
24
37
|
# --- There's both a label and an item
|
25
38
|
if (item == undef)
|
26
|
-
console.log "#{label}
|
39
|
+
console.log "#{label} = undef"
|
27
40
|
else if (item == null)
|
28
|
-
console.log "#{label}
|
41
|
+
console.log "#{label} = null"
|
29
42
|
else
|
30
43
|
console.log sep_dash
|
31
44
|
console.log "#{label}:"
|
@@ -112,19 +125,6 @@ maxOneLine = 32
|
|
112
125
|
|
113
126
|
# ---------------------------------------------------------------------------
|
114
127
|
|
115
|
-
fixStr = (str) ->
|
116
|
-
|
117
|
-
if !str
|
118
|
-
return ''
|
119
|
-
|
120
|
-
# --- If putstr is console.log, we'll convert TAB char to 3 spaces
|
121
|
-
if putstr == console.log
|
122
|
-
return untabify(str)
|
123
|
-
else
|
124
|
-
return str
|
125
|
-
|
126
|
-
# ---------------------------------------------------------------------------
|
127
|
-
|
128
128
|
export log = (str, hOptions={}) ->
|
129
129
|
# --- valid options:
|
130
130
|
# prefix
|
@@ -132,8 +132,11 @@ export log = (str, hOptions={}) ->
|
|
132
132
|
assert isFunction(putstr), "putstr not properly set"
|
133
133
|
assert isString(str), "log(): not a string"
|
134
134
|
assert isHash(hOptions), "log(): arg 2 not a hash"
|
135
|
+
prefix = fixForTerminal(hOptions.prefix)
|
136
|
+
|
137
|
+
if doDebugLog
|
138
|
+
LOG "CALL log(#{OL(str)}), prefix = #{OL(prefix)}"
|
135
139
|
|
136
|
-
prefix = fixStr(hOptions.prefix)
|
137
140
|
putstr "#{prefix}#{str}"
|
138
141
|
return true # to allow use in boolean expressions
|
139
142
|
|
@@ -141,15 +144,20 @@ export log = (str, hOptions={}) ->
|
|
141
144
|
|
142
145
|
export logItem = (label, item, hOptions={}) ->
|
143
146
|
# --- valid options:
|
144
|
-
# prefix
|
145
|
-
# itemPrefix - always used
|
147
|
+
# prefix
|
146
148
|
|
147
149
|
assert isFunction(putstr), "putstr not properly set"
|
148
150
|
assert !label || isString(label), "label a non-string"
|
149
151
|
assert isHash(hOptions), "arg 3 not a hash"
|
150
152
|
|
151
|
-
label =
|
152
|
-
prefix =
|
153
|
+
label = fixForTerminal(label)
|
154
|
+
prefix = fixForTerminal(hOptions.prefix)
|
155
|
+
assert prefix.indexOf("\t") == -1, "prefix has TAB"
|
156
|
+
|
157
|
+
if doDebugLog
|
158
|
+
LOG "CALL logItem(#{OL(label)}, #{OL(item)})"
|
159
|
+
LOG "prefix = #{OL(prefix)}"
|
160
|
+
|
153
161
|
labelStr = if label then "#{label} = " else ""
|
154
162
|
|
155
163
|
if (item == undef)
|
@@ -162,21 +170,36 @@ export logItem = (label, item, hOptions={}) ->
|
|
162
170
|
else
|
163
171
|
if label
|
164
172
|
putstr "#{prefix}#{label}:"
|
165
|
-
putBlock item, prefix
|
173
|
+
putBlock item, prefix + fourSpaces
|
166
174
|
else if isNumber(item)
|
167
175
|
putstr "#{prefix}#{labelStr}#{item}"
|
168
176
|
else
|
169
|
-
putstr "#{prefix}#{sep_dash}"
|
170
177
|
if label
|
171
178
|
putstr "#{prefix}#{label}:"
|
172
179
|
for str in blockToArray(stringify(item, true)) # escape special chars
|
173
|
-
putstr "#{prefix}#{
|
174
|
-
putstr "#{prefix}#{sep_dash}"
|
180
|
+
putstr "#{prefix + fourSpaces}#{fixForTerminal(str)}"
|
175
181
|
|
176
182
|
return true
|
177
183
|
|
178
184
|
# ---------------------------------------------------------------------------
|
179
185
|
|
186
|
+
export shortEnough = (label, value) ->
|
187
|
+
|
188
|
+
return (value == undef)
|
189
|
+
|
190
|
+
# ---------------------------------------------------------------------------
|
191
|
+
# --- needed because Windows Terminal handles TAB chars badly
|
192
|
+
|
193
|
+
fixForTerminal = (str) ->
|
194
|
+
|
195
|
+
if !str
|
196
|
+
return ''
|
197
|
+
|
198
|
+
# --- convert TAB char to 4 spaces
|
199
|
+
return str.replace(/\t/g, fourSpaces)
|
200
|
+
|
201
|
+
# ---------------------------------------------------------------------------
|
202
|
+
|
180
203
|
putBlock = (item, prefix='') ->
|
181
204
|
|
182
205
|
putstr "#{prefix}#{sep_eq}"
|