@jdeighan/coffee-utils 7.0.59 → 7.0.62

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": "7.0.59",
4
+ "version": "7.0.62",
5
5
  "description": "A set of utility functions for CoffeeScript",
6
6
  "main": "coffee_utils.js",
7
7
  "exports": {
package/src/arrow.coffee CHANGED
@@ -1,6 +1,6 @@
1
1
  # arrow.coffee
2
2
 
3
- import {undef, OL, setCharsAt} from '@jdeighan/coffee-utils'
3
+ import {undef, assert, OL, setCharsAt} from '@jdeighan/coffee-utils'
4
4
 
5
5
  # --- We use spaces here because Windows Terminal handles TAB chars badly
6
6
 
@@ -16,50 +16,41 @@ export clearIndent = space + space + space + space
16
16
 
17
17
  # ---------------------------------------------------------------------------
18
18
 
19
- export getPrefix = (level, option='none') ->
19
+ export prefix = (level, option='none') ->
20
20
 
21
- if level==0
22
- if (option == 'object')
23
- return clearIndent
24
- else
25
- return ''
26
21
  switch option
27
22
  when 'withArrow'
28
- result = oneIndent.repeat(level-1) + arrow
29
- when 'object'
30
- result = oneIndent.repeat(level) + clearIndent
31
- when 'none'
32
- result = oneIndent.repeat(level)
23
+ if (level == 0)
24
+ return arrow
25
+ else
26
+ return oneIndent.repeat(level-1) + arrow
27
+ when 'noLastVbar'
28
+ assert (level >= 1), "prefix(), noLastVbar but level=#{OL(level)}"
29
+ return oneIndent.repeat(level-1) + clearIndent
30
+ when 'noLast2Vbars'
31
+ assert (level >= 2), "prefix(), noLast2Vbars but level=#{OL(level)}"
32
+ return oneIndent.repeat(level-2) + clearIndent + clearIndent
33
33
  else
34
- throw new Error("getPrefix(): Bad option: '#{option}'")
35
- if result.length % 4 != 0
36
- throw new Error("getPrefix(): Bad prefix '#{result}'")
37
- return result
34
+ return oneIndent.repeat(level)
38
35
 
39
36
  # ---------------------------------------------------------------------------
40
37
 
41
38
  export addArrow = (prefix) ->
42
39
 
43
- # console.log "in addArrow(#{OL(prefix)})"
44
40
  pos = prefix.lastIndexOf(vbar)
45
- # console.log "pos = #{pos}"
46
41
  if (pos == -1)
47
42
  result = prefix
48
43
  else
49
44
  result = setCharsAt(prefix, pos, arrow)
50
- # console.log "result = #{OL(result)}"
51
45
  return result
52
46
 
53
47
  # ---------------------------------------------------------------------------
54
48
 
55
49
  export removeLastVbar = (prefix) ->
56
50
 
57
- # console.log "in removeLastVbar(#{OL(prefix)})"
58
51
  pos = prefix.lastIndexOf(vbar)
59
- # console.log "pos = #{pos}"
60
52
  if (pos == -1)
61
53
  result = prefix
62
54
  else
63
55
  result = setCharsAt(prefix, pos, ' ')
64
- # console.log "result = #{OL(result)}"
65
56
  return result
package/src/arrow.js CHANGED
@@ -2,6 +2,7 @@
2
2
  // arrow.coffee
3
3
  import {
4
4
  undef,
5
+ assert,
5
6
  OL,
6
7
  setCharsAt
7
8
  } from '@jdeighan/coffee-utils';
@@ -24,60 +25,46 @@ export var arrow = corner + hbar + arrowhead + space;
24
25
  export var clearIndent = space + space + space + space;
25
26
 
26
27
  // ---------------------------------------------------------------------------
27
- export var getPrefix = function(level, option = 'none') {
28
- var result;
29
- if (level === 0) {
30
- if (option === 'object') {
31
- return clearIndent;
32
- } else {
33
- return '';
34
- }
35
- }
28
+ export var prefix = function(level, option = 'none') {
36
29
  switch (option) {
37
30
  case 'withArrow':
38
- result = oneIndent.repeat(level - 1) + arrow;
39
- break;
40
- case 'object':
41
- result = oneIndent.repeat(level) + clearIndent;
42
- break;
43
- case 'none':
44
- result = oneIndent.repeat(level);
31
+ if (level === 0) {
32
+ return arrow;
33
+ } else {
34
+ return oneIndent.repeat(level - 1) + arrow;
35
+ }
45
36
  break;
37
+ case 'noLastVbar':
38
+ assert(level >= 1, `prefix(), noLastVbar but level=${OL(level)}`);
39
+ return oneIndent.repeat(level - 1) + clearIndent;
40
+ case 'noLast2Vbars':
41
+ assert(level >= 2, `prefix(), noLast2Vbars but level=${OL(level)}`);
42
+ return oneIndent.repeat(level - 2) + clearIndent + clearIndent;
46
43
  default:
47
- throw new Error(`getPrefix(): Bad option: '${option}'`);
44
+ return oneIndent.repeat(level);
48
45
  }
49
- if (result.length % 4 !== 0) {
50
- throw new Error(`getPrefix(): Bad prefix '${result}'`);
51
- }
52
- return result;
53
46
  };
54
47
 
55
48
  // ---------------------------------------------------------------------------
56
49
  export var addArrow = function(prefix) {
57
50
  var pos, result;
58
- // console.log "in addArrow(#{OL(prefix)})"
59
51
  pos = prefix.lastIndexOf(vbar);
60
- // console.log "pos = #{pos}"
61
52
  if (pos === -1) {
62
53
  result = prefix;
63
54
  } else {
64
55
  result = setCharsAt(prefix, pos, arrow);
65
56
  }
66
- // console.log "result = #{OL(result)}"
67
57
  return result;
68
58
  };
69
59
 
70
60
  // ---------------------------------------------------------------------------
71
61
  export var removeLastVbar = function(prefix) {
72
62
  var pos, result;
73
- // console.log "in removeLastVbar(#{OL(prefix)})"
74
63
  pos = prefix.lastIndexOf(vbar);
75
- // console.log "pos = #{pos}"
76
64
  if (pos === -1) {
77
65
  result = prefix;
78
66
  } else {
79
67
  result = setCharsAt(prefix, pos, ' ');
80
68
  }
81
- // console.log "result = #{OL(result)}"
82
69
  return result;
83
70
  };
@@ -1,10 +1,10 @@
1
1
  # call_stack.coffee
2
2
 
3
3
  import {
4
- undef, defined, croak, assert, OL, isBoolean, escapeStr,
4
+ undef, defined, croak, assert, OL, escapeStr, deepCopy,
5
+ isArray, isBoolean,
5
6
  } from '@jdeighan/coffee-utils'
6
- import {log, LOG} from '@jdeighan/coffee-utils/log'
7
- import {getPrefix} from '@jdeighan/coffee-utils/arrow'
7
+ import {LOG} from '@jdeighan/coffee-utils/log'
8
8
 
9
9
  doDebugStack = false
10
10
 
@@ -22,7 +22,6 @@ export class CallStack
22
22
  constructor: () ->
23
23
 
24
24
  @lStack = []
25
- @level = 0
26
25
 
27
26
  # ........................................................................
28
27
 
@@ -31,14 +30,16 @@ export class CallStack
31
30
  if doDebugStack
32
31
  LOG "RESET STACK"
33
32
  @lStack = []
34
- @level = 0
35
33
  return
36
34
 
37
35
  # ........................................................................
38
36
 
39
- enter: (funcName) ->
37
+ enter: (funcName, lArgs=[], isLogged) ->
40
38
  # --- funcName might be <object>.<method>
41
39
 
40
+ assert isArray(lArgs), "missing lArgs"
41
+ assert isBoolean(isLogged), "missing isLogged"
42
+
42
43
  if doDebugStack
43
44
  LOG "[--> ENTER #{funcName}]"
44
45
 
@@ -52,24 +53,31 @@ export class CallStack
52
53
  assert defined(lMatches), "Bad funcName: #{OL(funcName)}"
53
54
  [_, ident1, ident2] = lMatches
54
55
  if ident2
55
- @lStack.push({
56
+ hStackItem = {
56
57
  fullName: funcName # "#{ident1}.#{ident2}"
57
58
  funcName: ident2
58
- isLogged: false
59
- })
59
+ isLogged
60
+ lArgs: deepCopy(lArgs)
61
+ }
60
62
  else
61
- @lStack.push({
63
+ hStackItem = {
62
64
  fullName: funcName
63
65
  funcName: ident1
64
- isLogged: false
65
- })
66
- return
66
+ isLogged
67
+ lArgs: deepCopy(lArgs)
68
+ }
69
+ @lStack.push hStackItem
70
+ return hStackItem
67
71
 
68
72
  # ........................................................................
69
73
 
70
74
  getLevel: () ->
71
75
 
72
- return @level
76
+ level = 0
77
+ for item in @lStack
78
+ if item.isLogged
79
+ level += 1
80
+ return level
73
81
 
74
82
  # ........................................................................
75
83
 
@@ -80,32 +88,6 @@ export class CallStack
80
88
  else
81
89
  return @lStack[@lStack.length - 1].isLogged
82
90
 
83
- # ........................................................................
84
-
85
- isLoggingPrev: () ->
86
-
87
- if (@lStack.length < 2)
88
- return false
89
- else
90
- return @lStack[@lStack.length - 2].isLogged
91
-
92
- # ........................................................................
93
-
94
- logCurFunc: (funcName) ->
95
-
96
- # --- funcName must be the current function
97
- # and the isLogged flag must currently be false
98
-
99
- cur = @lStack[@lStack.length - 1]
100
- assert (cur.isLogged == false), "isLogged is already true"
101
- if (funcName != cur.fullName)
102
- LOG "cur func #{cur.fullName} is not #{funcName}"
103
- LOG @dump()
104
- croak "BAD"
105
- cur.isLogged = true
106
- @level += 1
107
- return
108
-
109
91
  # ........................................................................
110
92
  # --- if stack is empty, log the error, but continue
111
93
 
@@ -119,19 +101,10 @@ export class CallStack
119
101
  return
120
102
 
121
103
  {fullName, isLogged} = @lStack.pop()
122
- if isLogged && (@level > 0)
123
- @level -= 1
124
-
125
- # --- This should do nothing
126
- while (fullName != fName) && (@lStack.length > 0)
127
- LOG "[MISSING RETURN FROM #{fullName} (return from #{fName})]"
128
- {fullName, isLogged} = @lStack.pop()
129
- if isLogged && (@level > 0)
130
- @level -= 1
131
-
132
- if fullName != fName
133
- @dump()
134
- LOG "BAD BAD BAD BAD returnFrom('#{fName}')"
104
+ if (fullName != fName)
105
+ LOG "ERROR: returnFrom('#{fName}') but TOS is #{fullName}"
106
+ return
107
+
135
108
  return
136
109
 
137
110
  # ........................................................................
@@ -156,15 +129,25 @@ export class CallStack
156
129
 
157
130
  # ........................................................................
158
131
 
159
- dump: (prefix='', label='CALL STACK') ->
132
+ dump: (label="CALL STACK") ->
160
133
 
161
- lLines = ["#{label}:"]
134
+ lLines = [label]
162
135
  if @lStack.length == 0
163
136
  lLines.push " <EMPTY>"
164
137
  else
165
138
  for item, i in @lStack
166
- lLines.push " #{i}: #{item.fullName} #{item.isLogged}"
167
- return lLines.join("\n") + "\n"
139
+ lLines.push " " + @callStr(i, item)
140
+ return lLines.join("\n")
141
+
142
+ # ........................................................................
143
+
144
+ callStr: (i, item) ->
145
+
146
+ sym = if item.isLogged then '*' else '-'
147
+ str = "#{i}: #{sym}#{item.fullName}"
148
+ for arg in item.lArgs
149
+ str += " #{OL(arg)}"
150
+ return str
168
151
 
169
152
  # ........................................................................
170
153
 
package/src/call_stack.js CHANGED
@@ -8,19 +8,16 @@ import {
8
8
  croak,
9
9
  assert,
10
10
  OL,
11
- isBoolean,
12
- escapeStr
11
+ escapeStr,
12
+ deepCopy,
13
+ isArray,
14
+ isBoolean
13
15
  } from '@jdeighan/coffee-utils';
14
16
 
15
17
  import {
16
- log,
17
18
  LOG
18
19
  } from '@jdeighan/coffee-utils/log';
19
20
 
20
- import {
21
- getPrefix
22
- } from '@jdeighan/coffee-utils/arrow';
23
-
24
21
  doDebugStack = false;
25
22
 
26
23
  // ---------------------------------------------------------------------------
@@ -32,7 +29,6 @@ export var debugStack = function(flag = true) {
32
29
  export var CallStack = class CallStack {
33
30
  constructor() {
34
31
  this.lStack = [];
35
- this.level = 0;
36
32
  }
37
33
 
38
34
  // ........................................................................
@@ -41,13 +37,14 @@ export var CallStack = class CallStack {
41
37
  LOG("RESET STACK");
42
38
  }
43
39
  this.lStack = [];
44
- this.level = 0;
45
40
  }
46
41
 
47
42
  // ........................................................................
48
- enter(funcName) {
49
- var _, ident1, ident2, lMatches;
43
+ enter(funcName, lArgs = [], isLogged) {
44
+ var _, hStackItem, ident1, ident2, lMatches;
50
45
  // --- funcName might be <object>.<method>
46
+ assert(isArray(lArgs), "missing lArgs");
47
+ assert(isBoolean(isLogged), "missing isLogged");
51
48
  if (doDebugStack) {
52
49
  LOG(`[--> ENTER ${funcName}]`);
53
50
  }
@@ -55,23 +52,36 @@ export var CallStack = class CallStack {
55
52
  assert(defined(lMatches), `Bad funcName: ${OL(funcName)}`);
56
53
  [_, ident1, ident2] = lMatches;
57
54
  if (ident2) {
58
- this.lStack.push({
55
+ hStackItem = {
59
56
  fullName: funcName, // "#{ident1}.#{ident2}"
60
57
  funcName: ident2,
61
- isLogged: false
62
- });
58
+ isLogged,
59
+ lArgs: deepCopy(lArgs)
60
+ };
63
61
  } else {
64
- this.lStack.push({
62
+ hStackItem = {
65
63
  fullName: funcName,
66
64
  funcName: ident1,
67
- isLogged: false
68
- });
65
+ isLogged,
66
+ lArgs: deepCopy(lArgs)
67
+ };
69
68
  }
69
+ this.lStack.push(hStackItem);
70
+ return hStackItem;
70
71
  }
71
72
 
72
73
  // ........................................................................
73
74
  getLevel() {
74
- return this.level;
75
+ var item, j, len, level, ref;
76
+ level = 0;
77
+ ref = this.lStack;
78
+ for (j = 0, len = ref.length; j < len; j++) {
79
+ item = ref[j];
80
+ if (item.isLogged) {
81
+ level += 1;
82
+ }
83
+ }
84
+ return level;
75
85
  }
76
86
 
77
87
  // ........................................................................
@@ -83,31 +93,6 @@ export var CallStack = class CallStack {
83
93
  }
84
94
  }
85
95
 
86
- // ........................................................................
87
- isLoggingPrev() {
88
- if (this.lStack.length < 2) {
89
- return false;
90
- } else {
91
- return this.lStack[this.lStack.length - 2].isLogged;
92
- }
93
- }
94
-
95
- // ........................................................................
96
- logCurFunc(funcName) {
97
- var cur;
98
- // --- funcName must be the current function
99
- // and the isLogged flag must currently be false
100
- cur = this.lStack[this.lStack.length - 1];
101
- assert(cur.isLogged === false, "isLogged is already true");
102
- if (funcName !== cur.fullName) {
103
- LOG(`cur func ${cur.fullName} is not ${funcName}`);
104
- LOG(this.dump());
105
- croak("BAD");
106
- }
107
- cur.isLogged = true;
108
- this.level += 1;
109
- }
110
-
111
96
  // ........................................................................
112
97
  // --- if stack is empty, log the error, but continue
113
98
  returnFrom(fName) {
@@ -120,20 +105,9 @@ export var CallStack = class CallStack {
120
105
  return;
121
106
  }
122
107
  ({fullName, isLogged} = this.lStack.pop());
123
- if (isLogged && (this.level > 0)) {
124
- this.level -= 1;
125
- }
126
- // --- This should do nothing
127
- while ((fullName !== fName) && (this.lStack.length > 0)) {
128
- LOG(`[MISSING RETURN FROM ${fullName} (return from ${fName})]`);
129
- ({fullName, isLogged} = this.lStack.pop());
130
- if (isLogged && (this.level > 0)) {
131
- this.level -= 1;
132
- }
133
- }
134
108
  if (fullName !== fName) {
135
- this.dump();
136
- LOG(`BAD BAD BAD BAD returnFrom('${fName}')`);
109
+ LOG(`ERROR: returnFrom('${fName}') but TOS is ${fullName}`);
110
+ return;
137
111
  }
138
112
  }
139
113
 
@@ -162,19 +136,32 @@ export var CallStack = class CallStack {
162
136
  }
163
137
 
164
138
  // ........................................................................
165
- dump(prefix = '', label = 'CALL STACK') {
139
+ dump(label = "CALL STACK") {
166
140
  var i, item, j, lLines, len, ref;
167
- lLines = [`${label}:`];
141
+ lLines = [label];
168
142
  if (this.lStack.length === 0) {
169
143
  lLines.push(" <EMPTY>");
170
144
  } else {
171
145
  ref = this.lStack;
172
146
  for (i = j = 0, len = ref.length; j < len; i = ++j) {
173
147
  item = ref[i];
174
- lLines.push(` ${i}: ${item.fullName} ${item.isLogged}`);
148
+ lLines.push(" " + this.callStr(i, item));
175
149
  }
176
150
  }
177
- return lLines.join("\n") + "\n";
151
+ return lLines.join("\n");
152
+ }
153
+
154
+ // ........................................................................
155
+ callStr(i, item) {
156
+ var arg, j, len, ref, str, sym;
157
+ sym = item.isLogged ? '*' : '-';
158
+ str = `${i}: ${sym}${item.fullName}`;
159
+ ref = item.lArgs;
160
+ for (j = 0, len = ref.length; j < len; j++) {
161
+ arg = ref[j];
162
+ str += ` ${OL(arg)}`;
163
+ }
164
+ return str;
178
165
  }
179
166
 
180
167
  // ........................................................................
@@ -73,17 +73,11 @@ getCallers = (stackTrace, lExclude=[]) ->
73
73
  export assert = (cond, msg) ->
74
74
 
75
75
  if ! cond
76
- # try
77
- # throw new Error()
78
- # catch e
79
- # stackTrace = e.stack
80
76
  stackTrace = new Error().stack
81
77
  lCallers = getCallers(stackTrace, ['assert'])
82
78
 
83
- # console.log 'STACK'
84
- # console.log stackTrace
85
79
  console.log '--------------------'
86
- console.log 'CALL STACK:'
80
+ console.log 'JavaScript CALL STACK:'
87
81
  for caller in lCallers
88
82
  console.log " #{caller}"
89
83
  console.log '--------------------'
@@ -118,6 +112,16 @@ export getClassName = (obj) ->
118
112
 
119
113
  # ---------------------------------------------------------------------------
120
114
 
115
+ export patchStr = (bigstr, pos, str) ->
116
+
117
+ endpos = pos + str.length
118
+ if (endpos < bigstr.length)
119
+ return bigstr.substring(0, pos) + str + bigstr.substring(endpos)
120
+ else
121
+ return bigstr.substring(0, pos) + str
122
+
123
+ # ---------------------------------------------------------------------------
124
+
121
125
  export isString = (x) ->
122
126
 
123
127
  return typeof x == 'string' || x instanceof String
@@ -349,7 +353,15 @@ export ltrunc = (str, nChars) ->
349
353
 
350
354
  export deepCopy = (obj) ->
351
355
 
352
- return JSON.parse(JSON.stringify(obj))
356
+ if (obj == undef)
357
+ return undef
358
+ objStr = JSON.stringify(obj)
359
+ try
360
+ newObj = JSON.parse(objStr)
361
+ catch err
362
+ croak "ERROR: err.message", objStr
363
+
364
+ return newObj
353
365
 
354
366
  # ---------------------------------------------------------------------------
355
367
  # escapeStr - escape newlines, TAB chars, etc.
@@ -68,16 +68,10 @@ getCallers = function(stackTrace, lExclude = []) {
68
68
  export var assert = function(cond, msg) {
69
69
  var caller, i, lCallers, len, stackTrace;
70
70
  if (!cond) {
71
- // try
72
- // throw new Error()
73
- // catch e
74
- // stackTrace = e.stack
75
71
  stackTrace = new Error().stack;
76
72
  lCallers = getCallers(stackTrace, ['assert']);
77
- // console.log 'STACK'
78
- // console.log stackTrace
79
73
  console.log('--------------------');
80
- console.log('CALL STACK:');
74
+ console.log('JavaScript CALL STACK:');
81
75
  for (i = 0, len = lCallers.length; i < len; i++) {
82
76
  caller = lCallers[i];
83
77
  console.log(` ${caller}`);
@@ -112,6 +106,17 @@ export var getClassName = function(obj) {
112
106
  return obj.constructor.name;
113
107
  };
114
108
 
109
+ // ---------------------------------------------------------------------------
110
+ export var patchStr = function(bigstr, pos, str) {
111
+ var endpos;
112
+ endpos = pos + str.length;
113
+ if (endpos < bigstr.length) {
114
+ return bigstr.substring(0, pos) + str + bigstr.substring(endpos);
115
+ } else {
116
+ return bigstr.substring(0, pos) + str;
117
+ }
118
+ };
119
+
115
120
  // ---------------------------------------------------------------------------
116
121
  export var isString = function(x) {
117
122
  return typeof x === 'string' || x instanceof String;
@@ -347,7 +352,18 @@ export var ltrunc = function(str, nChars) {
347
352
  // ---------------------------------------------------------------------------
348
353
  // deepCopy - deep copy an array or object
349
354
  export var deepCopy = function(obj) {
350
- return JSON.parse(JSON.stringify(obj));
355
+ var err, newObj, objStr;
356
+ if (obj === undef) {
357
+ return undef;
358
+ }
359
+ objStr = JSON.stringify(obj);
360
+ try {
361
+ newObj = JSON.parse(objStr);
362
+ } catch (error1) {
363
+ err = error1;
364
+ croak("ERROR: err.message", objStr);
365
+ }
366
+ return newObj;
351
367
  };
352
368
 
353
369
  // ---------------------------------------------------------------------------