@jdeighan/coffee-utils 7.0.60 → 7.0.61

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.60",
4
+ "version": "7.0.61",
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, deepCopy,
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, lArgs=[]) ->
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,26 +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
+ isLogged
59
60
  lArgs: deepCopy(lArgs)
60
- })
61
+ }
61
62
  else
62
- @lStack.push({
63
+ hStackItem = {
63
64
  fullName: funcName
64
65
  funcName: ident1
65
- isLogged: false
66
+ isLogged
66
67
  lArgs: deepCopy(lArgs)
67
- })
68
- return
68
+ }
69
+ @lStack.push hStackItem
70
+ return hStackItem
69
71
 
70
72
  # ........................................................................
71
73
 
72
74
  getLevel: () ->
73
75
 
74
- return @level
76
+ level = 0
77
+ for item in @lStack
78
+ if item.isLogged
79
+ level += 1
80
+ return level
75
81
 
76
82
  # ........................................................................
77
83
 
@@ -82,32 +88,6 @@ export class CallStack
82
88
  else
83
89
  return @lStack[@lStack.length - 1].isLogged
84
90
 
85
- # ........................................................................
86
-
87
- isLoggingPrev: () ->
88
-
89
- if (@lStack.length < 2)
90
- return false
91
- else
92
- return @lStack[@lStack.length - 2].isLogged
93
-
94
- # ........................................................................
95
-
96
- logCurFunc: (funcName) ->
97
-
98
- # --- funcName must be the current function
99
- # and the isLogged flag must currently be false
100
-
101
- cur = @lStack[@lStack.length - 1]
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"
107
- cur.isLogged = true
108
- @level += 1
109
- return
110
-
111
91
  # ........................................................................
112
92
  # --- if stack is empty, log the error, but continue
113
93
 
@@ -121,19 +101,10 @@ export class CallStack
121
101
  return
122
102
 
123
103
  {fullName, isLogged} = @lStack.pop()
124
- if isLogged && (@level > 0)
125
- @level -= 1
126
-
127
- # --- This should do nothing
128
- while (fullName != fName) && (@lStack.length > 0)
129
- LOG "[MISSING RETURN FROM #{fullName} (return from #{fName})]"
130
- {fullName, isLogged} = @lStack.pop()
131
- if isLogged && (@level > 0)
132
- @level -= 1
133
-
134
- if fullName != fName
135
- @dump()
136
- LOG "BAD BAD BAD BAD returnFrom('#{fName}')"
104
+ if (fullName != fName)
105
+ LOG "ERROR: returnFrom('#{fName}') but TOS is #{fullName}"
106
+ return
107
+
137
108
  return
138
109
 
139
110
  # ........................................................................
@@ -158,9 +129,9 @@ export class CallStack
158
129
 
159
130
  # ........................................................................
160
131
 
161
- dump: () ->
132
+ dump: (label="CALL STACK") ->
162
133
 
163
- lLines = ["CALL STACK:"]
134
+ lLines = [label]
164
135
  if @lStack.length == 0
165
136
  lLines.push " <EMPTY>"
166
137
  else
@@ -172,8 +143,8 @@ export class CallStack
172
143
 
173
144
  callStr: (i, item) ->
174
145
 
175
- sym = if item.isLogged then '*' else ''
176
- str = "#{i}#{sym}: #{item.fullName}"
146
+ sym = if item.isLogged then '*' else '-'
147
+ str = "#{i}: #{sym}#{item.fullName}"
177
148
  for arg in item.lArgs
178
149
  str += " #{OL(arg)}"
179
150
  return str
package/src/call_stack.js CHANGED
@@ -8,20 +8,16 @@ import {
8
8
  croak,
9
9
  assert,
10
10
  OL,
11
- isBoolean,
12
11
  escapeStr,
13
- deepCopy
12
+ deepCopy,
13
+ isArray,
14
+ isBoolean
14
15
  } from '@jdeighan/coffee-utils';
15
16
 
16
17
  import {
17
- log,
18
18
  LOG
19
19
  } from '@jdeighan/coffee-utils/log';
20
20
 
21
- import {
22
- getPrefix
23
- } from '@jdeighan/coffee-utils/arrow';
24
-
25
21
  doDebugStack = false;
26
22
 
27
23
  // ---------------------------------------------------------------------------
@@ -33,7 +29,6 @@ export var debugStack = function(flag = true) {
33
29
  export var CallStack = class CallStack {
34
30
  constructor() {
35
31
  this.lStack = [];
36
- this.level = 0;
37
32
  }
38
33
 
39
34
  // ........................................................................
@@ -42,13 +37,14 @@ export var CallStack = class CallStack {
42
37
  LOG("RESET STACK");
43
38
  }
44
39
  this.lStack = [];
45
- this.level = 0;
46
40
  }
47
41
 
48
42
  // ........................................................................
49
- enter(funcName, lArgs = []) {
50
- var _, ident1, ident2, lMatches;
43
+ enter(funcName, lArgs = [], isLogged) {
44
+ var _, hStackItem, ident1, ident2, lMatches;
51
45
  // --- funcName might be <object>.<method>
46
+ assert(isArray(lArgs), "missing lArgs");
47
+ assert(isBoolean(isLogged), "missing isLogged");
52
48
  if (doDebugStack) {
53
49
  LOG(`[--> ENTER ${funcName}]`);
54
50
  }
@@ -56,25 +52,36 @@ export var CallStack = class CallStack {
56
52
  assert(defined(lMatches), `Bad funcName: ${OL(funcName)}`);
57
53
  [_, ident1, ident2] = lMatches;
58
54
  if (ident2) {
59
- this.lStack.push({
55
+ hStackItem = {
60
56
  fullName: funcName, // "#{ident1}.#{ident2}"
61
57
  funcName: ident2,
62
- isLogged: false,
58
+ isLogged,
63
59
  lArgs: deepCopy(lArgs)
64
- });
60
+ };
65
61
  } else {
66
- this.lStack.push({
62
+ hStackItem = {
67
63
  fullName: funcName,
68
64
  funcName: ident1,
69
- isLogged: false,
65
+ isLogged,
70
66
  lArgs: deepCopy(lArgs)
71
- });
67
+ };
72
68
  }
69
+ this.lStack.push(hStackItem);
70
+ return hStackItem;
73
71
  }
74
72
 
75
73
  // ........................................................................
76
74
  getLevel() {
77
- 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;
78
85
  }
79
86
 
80
87
  // ........................................................................
@@ -86,31 +93,6 @@ export var CallStack = class CallStack {
86
93
  }
87
94
  }
88
95
 
89
- // ........................................................................
90
- isLoggingPrev() {
91
- if (this.lStack.length < 2) {
92
- return false;
93
- } else {
94
- return this.lStack[this.lStack.length - 2].isLogged;
95
- }
96
- }
97
-
98
- // ........................................................................
99
- logCurFunc(funcName) {
100
- var cur;
101
- // --- funcName must be the current function
102
- // and the isLogged flag must currently be false
103
- cur = this.lStack[this.lStack.length - 1];
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
- }
110
- cur.isLogged = true;
111
- this.level += 1;
112
- }
113
-
114
96
  // ........................................................................
115
97
  // --- if stack is empty, log the error, but continue
116
98
  returnFrom(fName) {
@@ -123,20 +105,9 @@ export var CallStack = class CallStack {
123
105
  return;
124
106
  }
125
107
  ({fullName, isLogged} = this.lStack.pop());
126
- if (isLogged && (this.level > 0)) {
127
- this.level -= 1;
128
- }
129
- // --- This should do nothing
130
- while ((fullName !== fName) && (this.lStack.length > 0)) {
131
- LOG(`[MISSING RETURN FROM ${fullName} (return from ${fName})]`);
132
- ({fullName, isLogged} = this.lStack.pop());
133
- if (isLogged && (this.level > 0)) {
134
- this.level -= 1;
135
- }
136
- }
137
108
  if (fullName !== fName) {
138
- this.dump();
139
- LOG(`BAD BAD BAD BAD returnFrom('${fName}')`);
109
+ LOG(`ERROR: returnFrom('${fName}') but TOS is ${fullName}`);
110
+ return;
140
111
  }
141
112
  }
142
113
 
@@ -165,9 +136,9 @@ export var CallStack = class CallStack {
165
136
  }
166
137
 
167
138
  // ........................................................................
168
- dump() {
139
+ dump(label = "CALL STACK") {
169
140
  var i, item, j, lLines, len, ref;
170
- lLines = ["CALL STACK:"];
141
+ lLines = [label];
171
142
  if (this.lStack.length === 0) {
172
143
  lLines.push(" <EMPTY>");
173
144
  } else {
@@ -183,8 +154,8 @@ export var CallStack = class CallStack {
183
154
  // ........................................................................
184
155
  callStr(i, item) {
185
156
  var arg, j, len, ref, str, sym;
186
- sym = item.isLogged ? '*' : '';
187
- str = `${i}${sym}: ${item.fullName}`;
157
+ sym = item.isLogged ? '*' : '-';
158
+ str = `${i}: ${sym}${item.fullName}`;
188
159
  ref = item.lArgs;
189
160
  for (j = 0, len = ref.length; j < len; j++) {
190
161
  arg = ref[j];
@@ -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
@@ -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;