@jdeighan/coffee-utils 6.0.0 → 6.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jdeighan/coffee-utils",
3
3
  "type": "module",
4
- "version": "6.0.0",
4
+ "version": "6.0.3",
5
5
  "description": "A set of utility functions for CoffeeScript",
6
6
  "main": "coffee_utils.js",
7
7
  "exports": {
@@ -14,6 +14,7 @@
14
14
  "./indent": "./src/indent_utils.js",
15
15
  "./stack": "./src/call_stack.js",
16
16
  "./debug": "./src/debug_utils.js",
17
+ "./arrow": "./src/arrow.js",
17
18
  "./svelte": "./src/svelte_utils.js",
18
19
  "./store": "./src/DataStores.js",
19
20
  "./taml": "./src/taml.js",
@@ -46,6 +47,7 @@
46
47
  "dependencies": {
47
48
  "cross-env": "^7.0.3",
48
49
  "js-yaml": "^4.1.0",
50
+ "n-readlines": "^1.0.1",
49
51
  "readline-sync": "^1.4.10",
50
52
  "svelte": "^3.46.4"
51
53
  },
@@ -0,0 +1,39 @@
1
+ # arrow.coffee
2
+
3
+ vbar = '│' # unicode 2502
4
+ hbar = '─' # unicode 2500
5
+ corner = '└' # unicode 2514
6
+ arrowhead = '>'
7
+
8
+ oneIndent = vbar + ' '
9
+ export arrow = corner + hbar + arrowhead + ' '
10
+
11
+ # ---------------------------------------------------------------------------
12
+
13
+ export getPrefix = (level, withArrow) ->
14
+
15
+ if withArrow
16
+ return oneIndent.repeat(level-1) + arrow
17
+ else
18
+ return oneIndent.repeat(level)
19
+ return
20
+
21
+ # ---------------------------------------------------------------------------
22
+
23
+ export hasArrow = (str) ->
24
+
25
+ return str.indexOf(arrow) > -1
26
+
27
+ # ---------------------------------------------------------------------------
28
+
29
+ export removeArrow = (str, useVbar) ->
30
+
31
+ if hasArrow(str)
32
+ if useVbar
33
+ return str.replace(arrow, oneIndent)
34
+ else
35
+ return str.replace(arrow, ' ')
36
+ else
37
+ return str
38
+
39
+ # ---------------------------------------------------------------------------
package/src/arrow.js ADDED
@@ -0,0 +1,44 @@
1
+ // Generated by CoffeeScript 2.6.1
2
+ // arrow.coffee
3
+ var arrowhead, corner, hbar, oneIndent, vbar;
4
+
5
+ vbar = '│'; // unicode 2502
6
+
7
+ hbar = '─'; // unicode 2500
8
+
9
+ corner = '└'; // unicode 2514
10
+
11
+ arrowhead = '>';
12
+
13
+ oneIndent = vbar + ' ';
14
+
15
+ export var arrow = corner + hbar + arrowhead + ' ';
16
+
17
+ // ---------------------------------------------------------------------------
18
+ export var getPrefix = function(level, withArrow) {
19
+ if (withArrow) {
20
+ return oneIndent.repeat(level - 1) + arrow;
21
+ } else {
22
+ return oneIndent.repeat(level);
23
+ }
24
+ };
25
+
26
+ // ---------------------------------------------------------------------------
27
+ export var hasArrow = function(str) {
28
+ return str.indexOf(arrow) > -1;
29
+ };
30
+
31
+ // ---------------------------------------------------------------------------
32
+ export var removeArrow = function(str, useVbar) {
33
+ if (hasArrow(str)) {
34
+ if (useVbar) {
35
+ return str.replace(arrow, oneIndent);
36
+ } else {
37
+ return str.replace(arrow, ' ');
38
+ }
39
+ } else {
40
+ return str;
41
+ }
42
+ };
43
+
44
+ // ---------------------------------------------------------------------------
@@ -1,7 +1,7 @@
1
1
  # debug_utils.coffee
2
2
 
3
3
  import {
4
- assert, error, croak, warn, isString, isFunction, isBoolean,
4
+ assert, undef, error, croak, warn, isString, isFunction, isBoolean,
5
5
  oneline, escapeStr, isNumber, isArray, words,
6
6
  } from '@jdeighan/coffee-utils'
7
7
  import {blockToArray} from '@jdeighan/coffee-utils/block'
@@ -9,25 +9,32 @@ import {untabify} from '@jdeighan/coffee-utils/indent'
9
9
  import {slurp} from '@jdeighan/coffee-utils/fs'
10
10
  import {CallStack} from '@jdeighan/coffee-utils/stack'
11
11
  import {
12
- log, setStringifier, orderedStringify,
12
+ log, LOG, setStringifier, orderedStringify,
13
13
  } from '@jdeighan/coffee-utils/log'
14
-
15
- undef = undefined
16
- vbar = '│' # unicode 2502
17
- hbar = '─' # unicode 2500
18
- corner = '└' # unicode 2514
19
- arrowhead = '>'
20
-
21
- indent = vbar + ' '
22
- arrow = corner + hbar + arrowhead + ' '
14
+ import {getPrefix, arrow, removeArrow} from '@jdeighan/coffee-utils/arrow'
23
15
 
24
16
  debugLevel = 0 # controls amount of indentation - we ensure it's never < 0
25
17
 
26
18
  # --- These are saved/restored on the call stack
27
19
  export debugging = false
28
- shouldDebug = shouldLog = undef
20
+
21
+ # --- By default, when entering a function, keep the debugging flag
22
+ # as it was
23
+ shouldDebugFunc = (func) -> debugging
24
+
25
+ # --- By default, log everything when debugging flag is on
26
+ shouldLogString = (str) -> debugging
29
27
 
30
28
  stack = new CallStack()
29
+ DEBUGDEBUG = false
30
+
31
+ # ---------------------------------------------------------------------------
32
+
33
+ export setDEBUGDEBUG = (flag=true) ->
34
+
35
+ DEBUGDEBUG = flag
36
+ console.log "DEBUGDEBUG = #{flag}"
37
+ return
31
38
 
32
39
  # ---------------------------------------------------------------------------
33
40
 
@@ -36,8 +43,8 @@ export resetDebugging = (funcDoDebug=undef, funcDoLog=undef) ->
36
43
  debugging = false
37
44
  debugLevel = 0
38
45
  stack.reset()
39
- shouldDebug = (funcName, curDebugging) -> curDebugging
40
- shouldLog = (str) -> debugging || process.env.DEBUG
46
+ shouldDebugFunc = (func) -> debugging
47
+ shouldLogString = (str) -> debugging
41
48
  if funcDoDebug
42
49
  setDebugging funcDoDebug, funcDoLog
43
50
  return
@@ -47,21 +54,27 @@ export resetDebugging = (funcDoDebug=undef, funcDoLog=undef) ->
47
54
  export setDebugging = (funcDoDebug=undef, funcDoLog=undef) ->
48
55
 
49
56
  if isBoolean(funcDoDebug)
57
+ if DEBUGDEBUG
58
+ console.log "setDebugging #{funcDoDebug}"
50
59
  debugging = funcDoDebug
51
60
  else if isString(funcDoDebug)
52
61
  debugging = false
53
62
  lFuncNames = words(funcDoDebug)
54
63
  assert isArray(lFuncNames), "words('#{funcDoDebug}') returned non-array"
55
- shouldDebug = (funcName, curDebugging) ->
56
- curDebugging || funcMatch(funcName, lFuncNames)
64
+ shouldDebugFunc = (funcName) ->
65
+ funcMatch(funcName, lFuncNames)
66
+ if DEBUGDEBUG
67
+ console.log "setDebugging FUNCS: #{lFuncNames.join(',')}"
57
68
  else if isFunction(funcDoDebug)
58
- shouldDebug = funcDoDebug
69
+ shouldDebugFunc = funcDoDebug
70
+ if DEBUGDEBUG
71
+ console.log "setDebugging to custom func"
59
72
  else
60
73
  croak "setDebugging(): bad parameter #{oneline(funcDoDebug)}"
61
74
 
62
75
  if funcDoLog
63
76
  assert isFunction(funcDoLog), "setDebugging: arg 2 not a function"
64
- shouldLog = funcDoLog
77
+ shouldLogString = funcDoLog
65
78
  return
66
79
 
67
80
  # ---------------------------------------------------------------------------
@@ -84,71 +97,37 @@ export funcMatch = (curFunc, lFuncNames) ->
84
97
 
85
98
  curEnv = () ->
86
99
 
87
- return {debugging, shouldDebug, shouldLog}
100
+ return {debugging, shouldDebugFunc, shouldLogString}
88
101
 
89
102
  # ---------------------------------------------------------------------------
90
103
 
91
104
  setEnv = (hEnv) ->
92
105
 
93
- {debugging, shouldDebug, shouldLog} = hEnv
94
- return
95
-
96
- # ---------------------------------------------------------------------------
97
- # --- 2 possible signatures:
98
- # (item) - just log out the string
99
- # (item, hOptions) - log out the object, with a label
100
-
101
- logger = (item, hOptions=undef) ->
102
-
103
- log item, hOptions
106
+ {debugging, shouldDebugFunc, shouldLogString} = hEnv
104
107
  return
105
108
 
106
109
  # ---------------------------------------------------------------------------
107
110
 
108
- getPrefix = (level) ->
109
-
110
- if (level < 0)
111
- warn "You have mismatched debug 'enter'/'return' somewhere!"
112
- return ''
113
- return ' '.repeat(level)
114
-
115
- # ---------------------------------------------------------------------------
116
-
117
- envSaysDebug = (curFunc) ->
118
-
119
- if process.env.DEBUG_FUNC?
120
- return curFunc == process.env.DEBUG_FUNC
121
- else if process.env.DEBUG_FUNCS?
122
- return process.env.DEBUG_FUNCS.split(',').indexOf(curFunc) > -1
123
- else
124
- return false
125
-
126
- # ---------------------------------------------------------------------------
127
-
128
111
  export debug = (lArgs...) ->
129
- # --- either 1 or 2 args
112
+
113
+ # --- We want to allow item to be undef. Therefore, we need to
114
+ # distinguish between 1 arg sent vs. 2+ args sent
115
+ nArgs = lArgs.length
116
+ if DEBUGDEBUG
117
+ LOG "debug() called with #{nArgs} args"
118
+ [label, item] = lArgs
130
119
 
131
120
  # --- We always need to manipulate the stack when we encounter
132
121
  # either "enter X" or "return from X", so we can't short-circuit
133
122
  # when debugging is off
134
123
 
135
- nArgs = lArgs.length
136
- assert ((nArgs == 1) || (nArgs == 2)), "debug(); Bad # args #{nArgs}"
137
- str = lArgs[0]
138
-
139
- # --- str must always be a string
140
- # if 2 args, then str is meant to be a label for the item
141
-
142
- assert isString(str),
143
- "debug(): 1st arg #{oneline(str)} should be a string"
144
-
145
- if (nArgs==2)
146
- item = lArgs[1]
124
+ assert isString(label),
125
+ "debug(): 1st arg #{oneline(label)} should be a string"
147
126
 
148
127
  # --- determine if we're entering or returning from a function
149
128
  entering = returning = false
150
129
  curFunc = undef
151
- if (lMatches = str.match(///^
130
+ if (lMatches = label.match(///^
152
131
  \s*
153
132
  enter
154
133
  \s+
@@ -157,8 +136,10 @@ export debug = (lArgs...) ->
157
136
  entering = true
158
137
  curFunc = lMatches[1]
159
138
  stack.call(curFunc, curEnv())
160
- debugging = envSaysDebug(curFunc) || shouldDebug(curFunc, debugging)
161
- else if (lMatches = str.match(///^
139
+ debugging = shouldDebugFunc(curFunc)
140
+ if DEBUGDEBUG
141
+ LOG "ENTER #{curFunc}, debugging = #{debugging}"
142
+ else if (lMatches = label.match(///^
162
143
  \s*
163
144
  return
164
145
  .+
@@ -169,31 +150,32 @@ export debug = (lArgs...) ->
169
150
  returning = true
170
151
  curFunc = lMatches[1]
171
152
  hInfo = stack.returnFrom(curFunc)
153
+ if DEBUGDEBUG
154
+ LOG "RETURN FROM #{curFunc}, debugging = #{hInfo.debugging}"
172
155
 
173
- if shouldLog(str)
174
-
156
+ if shouldLogString(label)
175
157
  # --- set the prefix, i.e. indentation to use
176
158
  if returning
177
159
  if (debugLevel==0)
178
160
  prefix = arrow
179
161
  else
180
- prefix = indent.repeat(debugLevel-1) + arrow
162
+ prefix = getPrefix(debugLevel, true) # with arrow
181
163
  else
182
- prefix = indent.repeat(debugLevel)
164
+ prefix = getPrefix(debugLevel, false) # no arrow
183
165
 
184
166
  if (nArgs==1)
185
- logger str, {
186
- prefix: prefix
187
- }
167
+ log label, {prefix}
188
168
  else
189
- itemPrefix = prefix.replace(arrow, ' ')
190
- logger item, {
191
- label: str
192
- prefix: prefix
169
+ itemPrefix = removeArrow(prefix, false)
170
+ log item, {
171
+ label
172
+ prefix
193
173
  itemPrefix
194
174
  }
175
+ else if DEBUGDEBUG
176
+ LOG "shouldLogString('#{label}') returned FALSE"
195
177
 
196
- # --- Adjust debug level
178
+ # --- Adjust debug level & contents of hInfo
197
179
  if returning
198
180
  if debugLevel > 0
199
181
  debugLevel -= 1
@@ -236,15 +218,15 @@ export checkTrace = (block) ->
236
218
  funcName = lMatches[1]
237
219
  len = lStack.length
238
220
  if (len == 0)
239
- logger "return from #{funcName} with empty stack"
221
+ log "return from #{funcName} with empty stack"
240
222
  else if (lStack[len-1] == funcName)
241
223
  lStack.pop()
242
224
  else if (lStack[len-2] == funcName)
243
- logger "missing return from #{lStack[len-2]}"
225
+ log "missing return from #{lStack[len-2]}"
244
226
  lStack.pop()
245
227
  lStack.pop()
246
228
  else
247
- logger "return from #{funcName} - not found on stack"
229
+ log "return from #{funcName} - not found on stack"
248
230
  return
249
231
 
250
232
  # ---------------------------------------------------------------------------
@@ -1,9 +1,10 @@
1
1
  // Generated by CoffeeScript 2.6.1
2
2
  // debug_utils.coffee
3
- var arrow, arrowhead, corner, curEnv, debugLevel, envSaysDebug, getPrefix, hbar, indent, logger, reMethod, setEnv, shouldDebug, shouldLog, stack, undef, vbar;
3
+ var DEBUGDEBUG, curEnv, debugLevel, reMethod, setEnv, shouldDebugFunc, shouldLogString, stack;
4
4
 
5
5
  import {
6
6
  assert,
7
+ undef,
7
8
  error,
8
9
  croak,
9
10
  warn,
@@ -35,23 +36,16 @@ import {
35
36
 
36
37
  import {
37
38
  log,
39
+ LOG,
38
40
  setStringifier,
39
41
  orderedStringify
40
42
  } from '@jdeighan/coffee-utils/log';
41
43
 
42
- undef = void 0;
43
-
44
- vbar = '│'; // unicode 2502
45
-
46
- hbar = ''; // unicode 2500
47
-
48
- corner = '└'; // unicode 2514
49
-
50
- arrowhead = '>';
51
-
52
- indent = vbar + ' ';
53
-
54
- arrow = corner + hbar + arrowhead + ' ';
44
+ import {
45
+ getPrefix,
46
+ arrow,
47
+ removeArrow
48
+ } from '@jdeighan/coffee-utils/arrow';
55
49
 
56
50
  debugLevel = 0; // controls amount of indentation - we ensure it's never < 0
57
51
 
@@ -59,20 +53,37 @@ debugLevel = 0; // controls amount of indentation - we ensure it's never < 0
59
53
  // --- These are saved/restored on the call stack
60
54
  export var debugging = false;
61
55
 
62
- shouldDebug = shouldLog = undef;
56
+ // --- By default, when entering a function, keep the debugging flag
57
+ // as it was
58
+ shouldDebugFunc = function(func) {
59
+ return debugging;
60
+ };
61
+
62
+ // --- By default, log everything when debugging flag is on
63
+ shouldLogString = function(str) {
64
+ return debugging;
65
+ };
63
66
 
64
67
  stack = new CallStack();
65
68
 
69
+ DEBUGDEBUG = false;
70
+
71
+ // ---------------------------------------------------------------------------
72
+ export var setDEBUGDEBUG = function(flag = true) {
73
+ DEBUGDEBUG = flag;
74
+ console.log(`DEBUGDEBUG = ${flag}`);
75
+ };
76
+
66
77
  // ---------------------------------------------------------------------------
67
78
  export var resetDebugging = function(funcDoDebug = undef, funcDoLog = undef) {
68
79
  debugging = false;
69
80
  debugLevel = 0;
70
81
  stack.reset();
71
- shouldDebug = function(funcName, curDebugging) {
72
- return curDebugging;
82
+ shouldDebugFunc = function(func) {
83
+ return debugging;
73
84
  };
74
- shouldLog = function(str) {
75
- return debugging || process.env.DEBUG;
85
+ shouldLogString = function(str) {
86
+ return debugging;
76
87
  };
77
88
  if (funcDoDebug) {
78
89
  setDebugging(funcDoDebug, funcDoLog);
@@ -83,22 +94,31 @@ export var resetDebugging = function(funcDoDebug = undef, funcDoLog = undef) {
83
94
  export var setDebugging = function(funcDoDebug = undef, funcDoLog = undef) {
84
95
  var lFuncNames;
85
96
  if (isBoolean(funcDoDebug)) {
97
+ if (DEBUGDEBUG) {
98
+ console.log(`setDebugging ${funcDoDebug}`);
99
+ }
86
100
  debugging = funcDoDebug;
87
101
  } else if (isString(funcDoDebug)) {
88
102
  debugging = false;
89
103
  lFuncNames = words(funcDoDebug);
90
104
  assert(isArray(lFuncNames), `words('${funcDoDebug}') returned non-array`);
91
- shouldDebug = function(funcName, curDebugging) {
92
- return curDebugging || funcMatch(funcName, lFuncNames);
105
+ shouldDebugFunc = function(funcName) {
106
+ return funcMatch(funcName, lFuncNames);
93
107
  };
108
+ if (DEBUGDEBUG) {
109
+ console.log(`setDebugging FUNCS: ${lFuncNames.join(',')}`);
110
+ }
94
111
  } else if (isFunction(funcDoDebug)) {
95
- shouldDebug = funcDoDebug;
112
+ shouldDebugFunc = funcDoDebug;
113
+ if (DEBUGDEBUG) {
114
+ console.log("setDebugging to custom func");
115
+ }
96
116
  } else {
97
117
  croak(`setDebugging(): bad parameter ${oneline(funcDoDebug)}`);
98
118
  }
99
119
  if (funcDoLog) {
100
120
  assert(isFunction(funcDoLog), "setDebugging: arg 2 not a function");
101
- shouldLog = funcDoLog;
121
+ shouldLogString = funcDoLog;
102
122
  }
103
123
  };
104
124
 
@@ -119,97 +139,68 @@ export var funcMatch = function(curFunc, lFuncNames) {
119
139
 
120
140
  // ---------------------------------------------------------------------------
121
141
  curEnv = function() {
122
- return {debugging, shouldDebug, shouldLog};
142
+ return {debugging, shouldDebugFunc, shouldLogString};
123
143
  };
124
144
 
125
145
  // ---------------------------------------------------------------------------
126
146
  setEnv = function(hEnv) {
127
- ({debugging, shouldDebug, shouldLog} = hEnv);
128
- };
129
-
130
- // ---------------------------------------------------------------------------
131
- // --- 2 possible signatures:
132
- // (item) - just log out the string
133
- // (item, hOptions) - log out the object, with a label
134
- logger = function(item, hOptions = undef) {
135
- log(item, hOptions);
136
- };
137
-
138
- // ---------------------------------------------------------------------------
139
- getPrefix = function(level) {
140
- if (level < 0) {
141
- warn("You have mismatched debug 'enter'/'return' somewhere!");
142
- return '';
143
- }
144
- return ' '.repeat(level);
145
- };
146
-
147
- // ---------------------------------------------------------------------------
148
- envSaysDebug = function(curFunc) {
149
- if (process.env.DEBUG_FUNC != null) {
150
- return curFunc === process.env.DEBUG_FUNC;
151
- } else if (process.env.DEBUG_FUNCS != null) {
152
- return process.env.DEBUG_FUNCS.split(',').indexOf(curFunc) > -1;
153
- } else {
154
- return false;
155
- }
147
+ ({debugging, shouldDebugFunc, shouldLogString} = hEnv);
156
148
  };
157
149
 
158
150
  // ---------------------------------------------------------------------------
159
151
  export var debug = function(...lArgs) {
160
- var curFunc, entering, hInfo, item, itemPrefix, lMatches, nArgs, prefix, returning, str;
161
- // --- either 1 or 2 args
162
-
152
+ var curFunc, entering, hInfo, item, itemPrefix, lMatches, label, nArgs, prefix, returning;
153
+ // --- We want to allow item to be undef. Therefore, we need to
154
+ // distinguish between 1 arg sent vs. 2+ args sent
155
+ nArgs = lArgs.length;
156
+ if (DEBUGDEBUG) {
157
+ LOG(`debug() called with ${nArgs} args`);
158
+ }
159
+ [label, item] = lArgs;
163
160
  // --- We always need to manipulate the stack when we encounter
164
161
  // either "enter X" or "return from X", so we can't short-circuit
165
162
  // when debugging is off
166
- nArgs = lArgs.length;
167
- assert((nArgs === 1) || (nArgs === 2), `debug(); Bad # args ${nArgs}`);
168
- str = lArgs[0];
169
- // --- str must always be a string
170
- // if 2 args, then str is meant to be a label for the item
171
- assert(isString(str), `debug(): 1st arg ${oneline(str)} should be a string`);
172
- if (nArgs === 2) {
173
- item = lArgs[1];
174
- }
163
+ assert(isString(label), `debug(): 1st arg ${oneline(label)} should be a string`);
175
164
  // --- determine if we're entering or returning from a function
176
165
  entering = returning = false;
177
166
  curFunc = undef;
178
- if ((lMatches = str.match(/^\s*enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
167
+ if ((lMatches = label.match(/^\s*enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
179
168
  entering = true;
180
169
  curFunc = lMatches[1];
181
170
  stack.call(curFunc, curEnv());
182
- debugging = envSaysDebug(curFunc) || shouldDebug(curFunc, debugging);
183
- } else if ((lMatches = str.match(/^\s*return.+from\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
171
+ debugging = shouldDebugFunc(curFunc);
172
+ if (DEBUGDEBUG) {
173
+ LOG(`ENTER ${curFunc}, debugging = ${debugging}`);
174
+ }
175
+ } else if ((lMatches = label.match(/^\s*return.+from\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
184
176
  returning = true;
185
177
  curFunc = lMatches[1];
186
178
  hInfo = stack.returnFrom(curFunc);
179
+ if (DEBUGDEBUG) {
180
+ LOG(`RETURN FROM ${curFunc}, debugging = ${hInfo.debugging}`);
181
+ }
187
182
  }
188
- if (shouldLog(str)) {
183
+ if (shouldLogString(label)) {
189
184
  // --- set the prefix, i.e. indentation to use
190
185
  if (returning) {
191
186
  if (debugLevel === 0) {
192
187
  prefix = arrow;
193
188
  } else {
194
- prefix = indent.repeat(debugLevel - 1) + arrow;
189
+ prefix = getPrefix(debugLevel, true); // with arrow
195
190
  }
196
191
  } else {
197
- prefix = indent.repeat(debugLevel);
192
+ prefix = getPrefix(debugLevel, false); // no arrow
198
193
  }
199
194
  if (nArgs === 1) {
200
- logger(str, {
201
- prefix: prefix
202
- });
195
+ log(label, {prefix});
203
196
  } else {
204
- itemPrefix = prefix.replace(arrow, ' ');
205
- logger(item, {
206
- label: str,
207
- prefix: prefix,
208
- itemPrefix
209
- });
197
+ itemPrefix = removeArrow(prefix, false);
198
+ log(item, {label, prefix, itemPrefix});
210
199
  }
200
+ } else if (DEBUGDEBUG) {
201
+ LOG(`shouldLogString('${label}') returned FALSE`);
211
202
  }
212
- // --- Adjust debug level
203
+ // --- Adjust debug level & contents of hInfo
213
204
  if (returning) {
214
205
  if (debugLevel > 0) {
215
206
  debugLevel -= 1;
@@ -240,15 +231,15 @@ export var checkTrace = function(block) {
240
231
  funcName = lMatches[1];
241
232
  len = lStack.length;
242
233
  if (len === 0) {
243
- logger(`return from ${funcName} with empty stack`);
234
+ log(`return from ${funcName} with empty stack`);
244
235
  } else if (lStack[len - 1] === funcName) {
245
236
  lStack.pop();
246
237
  } else if (lStack[len - 2] === funcName) {
247
- logger(`missing return from ${lStack[len - 2]}`);
238
+ log(`missing return from ${lStack[len - 2]}`);
248
239
  lStack.pop();
249
240
  lStack.pop();
250
241
  } else {
251
- logger(`return from ${funcName} - not found on stack`);
242
+ log(`return from ${funcName} - not found on stack`);
252
243
  }
253
244
  }
254
245
  }
@@ -3,12 +3,13 @@
3
3
  import pathlib from 'path'
4
4
  import urllib from 'url'
5
5
  import fs from 'fs'
6
+ import NReadLines from 'n-readlines'
6
7
 
7
8
  import {
8
9
  assert, undef, pass, rtrim, error, nonEmpty,
9
10
  isString, isRegExp, isFunction, croak,
10
11
  } from '@jdeighan/coffee-utils'
11
- import {log} from '@jdeighan/coffee-utils/log'
12
+ import {log, LOG} from '@jdeighan/coffee-utils/log'
12
13
  import {debug} from '@jdeighan/coffee-utils/debug'
13
14
 
14
15
  # ---------------------------------------------------------------------------
@@ -98,14 +99,36 @@ export backup = (file, from, to, report=false) ->
98
99
  else
99
100
  fs.copyFileSync(src, dest)
100
101
 
102
+ # ---------------------------------------------------------------------------
103
+
104
+ export forEachLineInFile = (filepath, func) ->
105
+
106
+ reader = new NReadLines(filepath)
107
+ nLines = 0
108
+
109
+ while (buffer = reader.next())
110
+ nLines += 1
111
+ # --- text is split on \n chars, we also need to remove \r chars
112
+ line = buffer.toString().replace(/\r/g, '')
113
+ if func(line, nLines) == 'EOF'
114
+ reader.close() # allow premature termination
115
+ return
116
+
101
117
  # ---------------------------------------------------------------------------
102
118
  # slurp - read an entire file into a string
103
119
 
104
- export slurp = (filepath) ->
120
+ export slurp = (filepath, maxLines=undef) ->
105
121
 
106
122
  debug "enter slurp('#{filepath}')"
107
- filepath = filepath.replace(/\//g, "\\")
108
- contents = fs.readFileSync(filepath, 'utf8').toString()
123
+ if maxLines?
124
+ lLines = []
125
+ forEachLineInFile filepath, (line, nLines) ->
126
+ lLines.push line
127
+ return if nLines >= maxLines then 'EOF' else undef
128
+ contents = lLines.join("\n")
129
+ else
130
+ filepath = filepath.replace(/\//g, "\\")
131
+ contents = fs.readFileSync(filepath, 'utf8').toString()
109
132
  debug "return from slurp()", contents
110
133
  return contents
111
134
 
package/src/fs_utils.js CHANGED
@@ -6,6 +6,8 @@ import urllib from 'url';
6
6
 
7
7
  import fs from 'fs';
8
8
 
9
+ import NReadLines from 'n-readlines';
10
+
9
11
  import {
10
12
  assert,
11
13
  undef,
@@ -20,7 +22,8 @@ import {
20
22
  } from '@jdeighan/coffee-utils';
21
23
 
22
24
  import {
23
- log
25
+ log,
26
+ LOG
24
27
  } from '@jdeighan/coffee-utils/log';
25
28
 
26
29
  import {
@@ -117,13 +120,41 @@ export var backup = function(file, from, to, report = false) {
117
120
  }
118
121
  };
119
122
 
123
+ // ---------------------------------------------------------------------------
124
+ export var forEachLineInFile = function(filepath, func) {
125
+ var buffer, line, nLines, reader;
126
+ reader = new NReadLines(filepath);
127
+ nLines = 0;
128
+ while ((buffer = reader.next())) {
129
+ nLines += 1;
130
+ // --- text is split on \n chars, we also need to remove \r chars
131
+ line = buffer.toString().replace(/\r/g, '');
132
+ if (func(line, nLines) === 'EOF') {
133
+ reader.close(); // allow premature termination
134
+ }
135
+ }
136
+ };
137
+
120
138
  // ---------------------------------------------------------------------------
121
139
  // slurp - read an entire file into a string
122
- export var slurp = function(filepath) {
123
- var contents;
140
+ export var slurp = function(filepath, maxLines = undef) {
141
+ var contents, lLines;
124
142
  debug(`enter slurp('${filepath}')`);
125
- filepath = filepath.replace(/\//g, "\\");
126
- contents = fs.readFileSync(filepath, 'utf8').toString();
143
+ if (maxLines != null) {
144
+ lLines = [];
145
+ forEachLineInFile(filepath, function(line, nLines) {
146
+ lLines.push(line);
147
+ if (nLines >= maxLines) {
148
+ return 'EOF';
149
+ } else {
150
+ return undef;
151
+ }
152
+ });
153
+ contents = lLines.join("\n");
154
+ } else {
155
+ filepath = filepath.replace(/\//g, "\\");
156
+ contents = fs.readFileSync(filepath, 'utf8').toString();
157
+ }
127
158
  debug("return from slurp()", contents);
128
159
  return contents;
129
160
  };
@@ -133,7 +133,7 @@ export tabify = (str, numSpaces=undef) ->
133
133
  # ---------------------------------------------------------------------------
134
134
  # untabify - convert leading TABs to spaces
135
135
 
136
- export untabify = (str, numSpaces=3) ->
136
+ untabify_old = (str, numSpaces=3) ->
137
137
 
138
138
  oneIndent = ' '.repeat(numSpaces)
139
139
  lLines = []
@@ -145,3 +145,10 @@ export untabify = (str, numSpaces=3) ->
145
145
  else
146
146
  lLines.push oneIndent.repeat(prefix.length) + theRest
147
147
  return arrayToBlock(lLines)
148
+
149
+ # ---------------------------------------------------------------------------
150
+ # untabify - convert ALL TABs to spaces
151
+
152
+ export untabify = (str, numSpaces=3) ->
153
+
154
+ return str.replace(/\t/g, ' '.repeat(numSpaces))
@@ -1,5 +1,7 @@
1
1
  // Generated by CoffeeScript 2.6.1
2
- // indent_utils.coffee
2
+ // indent_utils.coffee
3
+ var untabify_old;
4
+
3
5
  import {
4
6
  assert,
5
7
  undef,
@@ -162,7 +164,7 @@ export var tabify = function(str, numSpaces = undef) {
162
164
 
163
165
  // ---------------------------------------------------------------------------
164
166
  // untabify - convert leading TABs to spaces
165
- export var untabify = function(str, numSpaces = 3) {
167
+ untabify_old = function(str, numSpaces = 3) {
166
168
  var _, i, lLines, lMatches, len, oneIndent, prefix, ref, theRest;
167
169
  oneIndent = ' '.repeat(numSpaces);
168
170
  lLines = [];
@@ -179,3 +181,9 @@ export var untabify = function(str, numSpaces = 3) {
179
181
  }
180
182
  return arrayToBlock(lLines);
181
183
  };
184
+
185
+ // ---------------------------------------------------------------------------
186
+ // untabify - convert ALL TABs to spaces
187
+ export var untabify = function(str, numSpaces = 3) {
188
+ return str.replace(/\t/g, ' '.repeat(numSpaces));
189
+ };
@@ -7,23 +7,29 @@ import {
7
7
  escapeStr, sep_eq, sep_dash
8
8
  } from '@jdeighan/coffee-utils'
9
9
  import {blockToArray} from '@jdeighan/coffee-utils/block'
10
- import {tabify, untabify} from '@jdeighan/coffee-utils/indent'
10
+ import {tabify, untabify, indentation} from '@jdeighan/coffee-utils/indent'
11
+ import {arrow, hasArrow, removeArrow} from '@jdeighan/coffee-utils/arrow'
11
12
 
12
13
  # --- This logger only ever gets passed a single string argument
13
- logger = undef
14
+ putstr = undef
15
+
14
16
  export stringify = undef
15
- export id = 42
17
+ objSep = '-'.repeat(42)
16
18
 
17
19
  # ---------------------------------------------------------------------------
18
20
  # This is useful for debugging and easy to remove after debugging
19
21
 
20
- export LOG = (label, item, ch='=') ->
22
+ export LOG = (lArgs...) ->
21
23
 
22
- if item
23
- console.log ch.repeat(42)
24
- console.log "[#{label}]:"
25
- console.log untabify(orderedStringify(item))
26
- console.log ch.repeat(42)
24
+ [label, item] = lArgs
25
+ if lArgs.length > 1
26
+ console.log objSep
27
+ if item?
28
+ console.log "#{label}:"
29
+ console.log untabify(orderedStringify(item))
30
+ else
31
+ console.log "[#{label}]: UNDEFINED"
32
+ console.log objSep
27
33
  else
28
34
  console.log label
29
35
  return
@@ -47,9 +53,9 @@ export resetStringifier = () ->
47
53
 
48
54
  export setLogger = (func) ->
49
55
 
50
- orgLogger = logger
51
56
  assert isFunction(func), "setLogger() arg is not a function"
52
- logger = func
57
+ orgLogger = putstr
58
+ putstr = func
53
59
  return orgLogger
54
60
 
55
61
  # ---------------------------------------------------------------------------
@@ -99,55 +105,61 @@ maxOneLine = 32
99
105
 
100
106
  # ---------------------------------------------------------------------------
101
107
 
102
- export log = (item, hOptions=undef) ->
108
+ export log = (item, hOptions={}) ->
103
109
  # --- valid options:
104
- # label
105
- # prefix
106
- # escape
107
-
108
- assert isFunction(logger), "logger not properly set"
109
- prefix = itemPrefix = label = ''
110
- if hOptions?
111
- if isString(hOptions)
112
- label = hOptions
113
- else
114
- assert isHash(hOptions), "log(): 2nd arg must be a string or hash"
115
- if hOptions.prefix?
116
- prefix = hOptions.prefix
117
- if hOptions.itemPrefix?
118
- itemPrefix = hOptions.itemPrefix
119
- else
120
- itemPrefix = prefix
121
- if hOptions.label?
122
- label = hOptions.label
110
+ # label
111
+ # prefix
112
+ # itemPrefix
113
+ # escape
114
+
115
+ assert isFunction(putstr), "putstr not properly set"
116
+ if isString(hOptions)
117
+ label = hOptions
118
+ prefix = itemPrefix = ''
119
+ else
120
+ assert isHash(hOptions), "log(): 2nd arg must be a string or hash"
121
+ label = hOptions.label || ''
122
+ prefix = hOptions.prefix || ''
123
+ itemPrefix = hOptions.itemPrefix || prefix || ''
124
+
125
+ # --- If putstr is console.log, we'll convert TAB char to 3 spaces
126
+ if putstr == console.log
127
+ label = untabify(label)
128
+ prefix = untabify(prefix)
129
+ itemPrefix = untabify(itemPrefix)
123
130
 
124
131
  if isString(item) && (label == '')
125
- if hOptions? && hOptions.escape
126
- logger "#{prefix}#{escapeStr(item)}"
132
+ if hOptions.escape
133
+ putstr "#{prefix}#{escapeStr(item)}"
127
134
  else
128
- logger "#{prefix}#{item}"
135
+ putstr "#{prefix}#{item}"
129
136
  return
130
137
 
131
138
  if (label == '')
132
139
  label = 'ITEM'
133
140
 
134
141
  if (item == undef)
135
- logger "#{prefix}#{label} = undef"
142
+ putstr "#{prefix}#{label} = undef"
136
143
  else if isString(item)
137
144
  if (item.length <= maxOneLine)
138
- logger "#{prefix}#{label} = '#{escapeStr(item)}'"
145
+ putstr "#{prefix}#{label} = '#{escapeStr(item)}'"
139
146
  else
140
- logger "#{prefix}#{label}:"
141
- logger "#{itemPrefix}#{sep_eq}"
147
+ putstr "#{prefix}#{label}:"
148
+ putstr "#{itemPrefix}#{sep_eq}"
142
149
  for line in blockToArray(item)
143
- logger "#{itemPrefix}#{escapeStr(line)}"
144
- logger "#{itemPrefix}#{sep_eq}"
150
+ putstr "#{itemPrefix}#{escapeStr(line)}"
151
+ putstr "#{itemPrefix}#{sep_eq}"
145
152
  else if isNumber(item)
146
- logger "#{prefix}#{label} = #{item}"
153
+ putstr "#{prefix}#{label} = #{item}"
147
154
  else
148
- logger "#{prefix}#{label}:"
155
+ putstr "#{removeArrow(prefix, true)}#{objSep}"
156
+ putstr "#{prefix}#{label}:"
149
157
  for str in blockToArray(stringify(item, true))
150
- logger "#{itemPrefix}\t#{str}"
158
+ if putstr == console.log
159
+ putstr "#{itemPrefix} #{untabify(str)}"
160
+ else
161
+ putstr "#{itemPrefix}#{indentation(1)}#{str}"
162
+ putstr "#{removeArrow(prefix, false)}#{objSep}"
151
163
  return
152
164
 
153
165
  # ---------------------------------------------------------------------------
package/src/log_utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // Generated by CoffeeScript 2.6.1
2
2
  // log_utils.coffee
3
- var escReplacer, loaded, logger, maxOneLine;
3
+ var escReplacer, loaded, maxOneLine, objSep, putstr;
4
4
 
5
5
  import yaml from 'js-yaml';
6
6
 
@@ -23,24 +23,37 @@ import {
23
23
 
24
24
  import {
25
25
  tabify,
26
- untabify
26
+ untabify,
27
+ indentation
27
28
  } from '@jdeighan/coffee-utils/indent';
28
29
 
30
+ import {
31
+ arrow,
32
+ hasArrow,
33
+ removeArrow
34
+ } from '@jdeighan/coffee-utils/arrow';
35
+
29
36
  // --- This logger only ever gets passed a single string argument
30
- logger = undef;
37
+ putstr = undef;
31
38
 
32
39
  export var stringify = undef;
33
40
 
34
- export var id = 42;
41
+ objSep = '-'.repeat(42);
35
42
 
36
43
  // ---------------------------------------------------------------------------
37
44
  // This is useful for debugging and easy to remove after debugging
38
- export var LOG = function(label, item, ch = '=') {
39
- if (item) {
40
- console.log(ch.repeat(42));
41
- console.log(`[${label}]:`);
42
- console.log(untabify(orderedStringify(item)));
43
- console.log(ch.repeat(42));
45
+ export var LOG = function(...lArgs) {
46
+ var item, label;
47
+ [label, item] = lArgs;
48
+ if (lArgs.length > 1) {
49
+ console.log(objSep);
50
+ if (item != null) {
51
+ console.log(`${label}:`);
52
+ console.log(untabify(orderedStringify(item)));
53
+ } else {
54
+ console.log(`[${label}]: UNDEFINED`);
55
+ }
56
+ console.log(objSep);
44
57
  } else {
45
58
  console.log(label);
46
59
  }
@@ -63,9 +76,9 @@ export var resetStringifier = function() {
63
76
  // ---------------------------------------------------------------------------
64
77
  export var setLogger = function(func) {
65
78
  var orgLogger;
66
- orgLogger = logger;
67
79
  assert(isFunction(func), "setLogger() arg is not a function");
68
- logger = func;
80
+ orgLogger = putstr;
81
+ putstr = func;
69
82
  return orgLogger;
70
83
  };
71
84
 
@@ -116,37 +129,34 @@ export var orderedStringify = function(obj, escape = false) {
116
129
  maxOneLine = 32;
117
130
 
118
131
  // ---------------------------------------------------------------------------
119
- export var log = function(item, hOptions = undef) {
132
+ export var log = function(item, hOptions = {}) {
120
133
  var i, itemPrefix, j, label, len, len1, line, prefix, ref, ref1, str;
121
134
  // --- valid options:
122
- // label
123
- // prefix
124
- // escape
125
- assert(isFunction(logger), "logger not properly set");
126
- prefix = itemPrefix = label = '';
127
- if (hOptions != null) {
128
- if (isString(hOptions)) {
129
- label = hOptions;
130
- } else {
131
- assert(isHash(hOptions), "log(): 2nd arg must be a string or hash");
132
- if (hOptions.prefix != null) {
133
- prefix = hOptions.prefix;
134
- }
135
- if (hOptions.itemPrefix != null) {
136
- itemPrefix = hOptions.itemPrefix;
137
- } else {
138
- itemPrefix = prefix;
139
- }
140
- if (hOptions.label != null) {
141
- label = hOptions.label;
142
- }
143
- }
135
+ // label
136
+ // prefix
137
+ // itemPrefix
138
+ // escape
139
+ assert(isFunction(putstr), "putstr not properly set");
140
+ if (isString(hOptions)) {
141
+ label = hOptions;
142
+ prefix = itemPrefix = '';
143
+ } else {
144
+ assert(isHash(hOptions), "log(): 2nd arg must be a string or hash");
145
+ label = hOptions.label || '';
146
+ prefix = hOptions.prefix || '';
147
+ itemPrefix = hOptions.itemPrefix || prefix || '';
148
+ }
149
+ // --- If putstr is console.log, we'll convert TAB char to 3 spaces
150
+ if (putstr === console.log) {
151
+ label = untabify(label);
152
+ prefix = untabify(prefix);
153
+ itemPrefix = untabify(itemPrefix);
144
154
  }
145
155
  if (isString(item) && (label === '')) {
146
- if ((hOptions != null) && hOptions.escape) {
147
- logger(`${prefix}${escapeStr(item)}`);
156
+ if (hOptions.escape) {
157
+ putstr(`${prefix}${escapeStr(item)}`);
148
158
  } else {
149
- logger(`${prefix}${item}`);
159
+ putstr(`${prefix}${item}`);
150
160
  }
151
161
  return;
152
162
  }
@@ -154,29 +164,35 @@ export var log = function(item, hOptions = undef) {
154
164
  label = 'ITEM';
155
165
  }
156
166
  if (item === undef) {
157
- logger(`${prefix}${label} = undef`);
167
+ putstr(`${prefix}${label} = undef`);
158
168
  } else if (isString(item)) {
159
169
  if (item.length <= maxOneLine) {
160
- logger(`${prefix}${label} = '${escapeStr(item)}'`);
170
+ putstr(`${prefix}${label} = '${escapeStr(item)}'`);
161
171
  } else {
162
- logger(`${prefix}${label}:`);
163
- logger(`${itemPrefix}${sep_eq}`);
172
+ putstr(`${prefix}${label}:`);
173
+ putstr(`${itemPrefix}${sep_eq}`);
164
174
  ref = blockToArray(item);
165
175
  for (i = 0, len = ref.length; i < len; i++) {
166
176
  line = ref[i];
167
- logger(`${itemPrefix}${escapeStr(line)}`);
177
+ putstr(`${itemPrefix}${escapeStr(line)}`);
168
178
  }
169
- logger(`${itemPrefix}${sep_eq}`);
179
+ putstr(`${itemPrefix}${sep_eq}`);
170
180
  }
171
181
  } else if (isNumber(item)) {
172
- logger(`${prefix}${label} = ${item}`);
182
+ putstr(`${prefix}${label} = ${item}`);
173
183
  } else {
174
- logger(`${prefix}${label}:`);
184
+ putstr(`${removeArrow(prefix, true)}${objSep}`);
185
+ putstr(`${prefix}${label}:`);
175
186
  ref1 = blockToArray(stringify(item, true));
176
187
  for (j = 0, len1 = ref1.length; j < len1; j++) {
177
188
  str = ref1[j];
178
- logger(`${itemPrefix}\t${str}`);
189
+ if (putstr === console.log) {
190
+ putstr(`${itemPrefix} ${untabify(str)}`);
191
+ } else {
192
+ putstr(`${itemPrefix}${indentation(1)}${str}`);
193
+ }
179
194
  }
195
+ putstr(`${removeArrow(prefix, false)}${objSep}`);
180
196
  }
181
197
  };
182
198