cpp

Coverage Report

Created: 2022-08-03 12:23

/home/andy/git/oilshell/oil/mycpp/leaky_types.cc
Line
Count
Source (jump to first uncovered line)
1
#ifdef LEAKY_BINDINGS
2
  #include "mycpp/mylib_old.h"
3
using gc_heap::StackRoots;  // no-op
4
using mylib::AllocStr;
5
#else
6
  #include "mycpp/gc_builtins.h"
7
  #include "mycpp/gc_types.h"
8
using gc_heap::kEmptyString;
9
using gc_heap::StackRoots;
10
using gc_heap::Str;
11
#endif
12
13
#include <ctype.h>  // isalpha(), isdigit()
14
15
#ifndef LEAKY_BINDINGS
16
namespace gc_heap {
17
#endif
18
19
enum class StripWhere {
20
  Left,
21
  Right,
22
  Both,
23
};
24
25
const int kWhitespace = -1;
26
27
61
bool OmitChar(uint8_t ch, int what) {
28
61
  if (what == kWhitespace) {
29
51
    return isspace(ch);
30
51
  } else {
31
10
    return what == ch;
32
10
  }
33
61
}
_ZN7gc_heap8OmitCharEhi
Line
Count
Source
27
55
bool OmitChar(uint8_t ch, int what) {
28
55
  if (what == kWhitespace) {
29
45
    return isspace(ch);
30
45
  } else {
31
10
    return what == ch;
32
10
  }
33
55
}
_Z8OmitCharhi
Line
Count
Source
27
6
bool OmitChar(uint8_t ch, int what) {
28
6
  if (what == kWhitespace) {
29
6
    return isspace(ch);
30
6
  } else {
31
0
    return what == ch;
32
0
  }
33
6
}
34
35
// StripAny is modeled after CPython's do_strip() in stringobject.c, and can
36
// implement 6 functions:
37
//
38
//   strip / lstrip / rstrip
39
//   strip(char) / lstrip(char) / rstrip(char)
40
//
41
// Args:
42
//   where: which ends to strip from
43
//   what: kWhitespace, or an ASCII code 0-255
44
45
24
Str* StripAny(Str* s, StripWhere where, int what) {
46
24
  StackRoots _roots({&s});
47
48
24
  int length = len(s);
49
24
  const char* char_data = s->data();
50
51
24
  int i = 0;
52
24
  if (where != StripWhere::Right) {
53
21
    while (i < length && OmitChar(char_data[i], what)) {
54
9
      i++;
55
9
    }
56
12
  }
57
58
24
  int j = length;
59
24
  if (where != StripWhere::Left) {
60
51
    do {
61
51
      j--;
62
51
    } while (j >= i && OmitChar(char_data[j], what));
63
24
    j++;
64
24
  }
65
66
24
  if (i == j) {  // Optimization to reuse existing object
67
7
    return kEmptyString;
68
7
  }
69
70
17
  if (i == 0 && j == length) {  // nothing stripped
71
3
    return s;
72
3
  }
73
74
  // Note: makes a copy in leaky version, and will in GC version too
75
14
  int new_len = j - i;
76
14
  Str* result = AllocStr(new_len);
77
14
  memcpy(result->data(), s->data() + i, new_len);
78
14
  return result;
79
17
}
_ZN7gc_heap8StripAnyEPNS_3StrENS_10StripWhereEi
Line
Count
Source
45
22
Str* StripAny(Str* s, StripWhere where, int what) {
46
22
  StackRoots _roots({&s});
47
48
22
  int length = len(s);
49
22
  const char* char_data = s->data();
50
51
22
  int i = 0;
52
22
  if (where != StripWhere::Right) {
53
19
    while (i < length && OmitChar(char_data[i], what)) {
54
9
      i++;
55
9
    }
56
10
  }
57
58
22
  int j = length;
59
22
  if (where != StripWhere::Left) {
60
47
    do {
61
47
      j--;
62
47
    } while (j >= i && OmitChar(char_data[j], what));
63
22
    j++;
64
22
  }
65
66
22
  if (i == j) {  // Optimization to reuse existing object
67
7
    return kEmptyString;
68
7
  }
69
70
15
  if (i == 0 && j == length) {  // nothing stripped
71
3
    return s;
72
3
  }
73
74
  // Note: makes a copy in leaky version, and will in GC version too
75
12
  int new_len = j - i;
76
12
  Str* result = AllocStr(new_len);
77
12
  memcpy(result->data(), s->data() + i, new_len);
78
12
  return result;
79
15
}
_Z8StripAnyP3Str10StripWherei
Line
Count
Source
45
2
Str* StripAny(Str* s, StripWhere where, int what) {
46
2
  StackRoots _roots({&s});
47
48
2
  int length = len(s);
49
2
  const char* char_data = s->data();
50
51
2
  int i = 0;
52
2
  if (where != StripWhere::Right) {
53
2
    while (i < length && OmitChar(char_data[i], what)) {
54
0
      i++;
55
0
    }
56
2
  }
57
58
2
  int j = length;
59
2
  if (where != StripWhere::Left) {
60
4
    do {
61
4
      j--;
62
4
    } while (j >= i && OmitChar(char_data[j], what));
63
2
    j++;
64
2
  }
65
66
2
  if (i == j) {  // Optimization to reuse existing object
67
0
    return kEmptyString;
68
0
  }
69
70
2
  if (i == 0 && j == length) {  // nothing stripped
71
0
    return s;
72
0
  }
73
74
  // Note: makes a copy in leaky version, and will in GC version too
75
2
  int new_len = j - i;
76
2
  Str* result = AllocStr(new_len);
77
2
  memcpy(result->data(), s->data() + i, new_len);
78
2
  return result;
79
2
}
80
81
12
Str* Str::strip() {
82
12
  return StripAny(this, StripWhere::Both, kWhitespace);
83
12
}
_ZN7gc_heap3Str5stripEv
Line
Count
Source
81
10
Str* Str::strip() {
82
10
  return StripAny(this, StripWhere::Both, kWhitespace);
83
10
}
_ZN3Str5stripEv
Line
Count
Source
81
2
Str* Str::strip() {
82
2
  return StripAny(this, StripWhere::Both, kWhitespace);
83
2
}
84
85
// Used for CommandSub in osh/cmd_exec.py
86
4
Str* Str::rstrip(Str* chars) {
87
4
  assert(len(chars) == 1);
88
0
  int c = chars->data_[0];
89
4
  return StripAny(this, StripWhere::Right, c);
90
4
}
_ZN7gc_heap3Str6rstripEPS0_
Line
Count
Source
86
4
Str* Str::rstrip(Str* chars) {
87
4
  assert(len(chars) == 1);
88
0
  int c = chars->data_[0];
89
4
  return StripAny(this, StripWhere::Right, c);
90
4
}
Unexecuted instantiation: _ZN3Str6rstripEPS_
91
92
8
Str* Str::rstrip() {
93
8
  return StripAny(this, StripWhere::Right, kWhitespace);
94
8
}
_ZN7gc_heap3Str6rstripEv
Line
Count
Source
92
8
Str* Str::rstrip() {
93
8
  return StripAny(this, StripWhere::Right, kWhitespace);
94
8
}
Unexecuted instantiation: _ZN3Str6rstripEv
95
96
#if 0
97
Str* Str::lstrip(Str* chars) {
98
  assert(len(chars) == 1);
99
  int c = chars->data_[0];
100
  return StripAny(this, StripWhere::Left, c);
101
}
102
103
Str* Str::lstrip() {
104
  return StripAny(this, StripWhere::Left, kWhitespace);
105
}
106
#endif
107
108
#ifndef LEAKY_BINDINGS
109
}  // namespace gc_heap
110
#endif