Skip to content

Commit

Permalink
Apply fixes commented in PR, move string escape to string
Browse files Browse the repository at this point in the history
  • Loading branch information
lynzrand committed Mar 19, 2024
1 parent 41bde3c commit 4bb0097
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 42 deletions.
52 changes: 11 additions & 41 deletions coverage/coverage.mbt
Original file line number Diff line number Diff line change
@@ -1,92 +1,62 @@
pub struct CoverageCounter {
priv counter : Array[Int]
}
} derive(Show)

fn CoverageCounter::new(size : Int) -> CoverageCounter {
{ counter: Array::make(size, 0) }
}

fn CoverageCounter::incr(self : CoverageCounter, idx : Int) -> Unit {
let counter = self.counter[idx];
let counter = self.counter[idx]
if counter < 0x7fffffff { // prevent overflow
self.counter[idx] = counter + 1
}
}

fn CoverageCounter::to_string(self : CoverageCounter) -> String {
let mut s = "["
fn CoverageCounter::debug_write(self : CoverageCounter, buf : Buffer) -> Unit {
buf.write_char('[')
let mut i = 0
while i < self.counter.length() {
if i != 0 {
s += ", "
buf.write_string(", ")
}
s += self.counter[i].to_string()
self.counter[i].debug_write(buf)
i += 1
}
s += "]"
s
buf.write_char(']')
}

test "new_counter" {
let counter = CoverageCounter::new(2)
let result = counter.to_string()
if result != "[0, 0]" {
println(result)
abort("error")
}
@assertion.assert_eq(result, "[0, 0]")?
}

test "incr_counter" {
let counter = CoverageCounter::new(10)
counter.incr(0)
counter.incr(9)
let result = counter.to_string()
if result != "[1, 0, 0, 0, 0, 0, 0, 0, 0, 1]" {
println(result)
abort("error")
}
@assertion.assert_eq(result, "[1, 0, 0, 0, 0, 0, 0, 0, 0, 1]")?
}

let counters : Ref[List[(String, CoverageCounter)]] = { val: Nil }

fn escape_string(s : String) -> String {
let buf = Buffer::make(s.length())
let mut ix = 0
while ix < s.length() {
let ch = s[ix]
match ch {
'\"' | '\'' | '\\' => {
buf.write_char('\\')
buf.write_char(ch)
}
'\n' => {
buf.write_char('\\')
buf.write_char('n')
}
_ => {
buf.write_char(ch)
}
}
ix += 1
}
buf.to_string()
}

pub fn track(name : String, counter : CoverageCounter) -> Unit {
counters.val = Cons((name, counter), counters.val)
}

pub fn end() -> Unit {
println("----- BEGIN MOONBIT COVERAGE -----")
println("{")
let mut ix = 0;
let mut ix = 0
loop counters.val {
Cons((name, counter), xs) => {
if ix != 0 {
print(", ")
}
print('"')
print(escape_string(name))
print(name.escape())
print("\": ")
let counter_dump = counter.to_string()
println(counter_dump)
Expand Down
13 changes: 12 additions & 1 deletion coverage/moon.pkg.json
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
{}
{
"import": [
{
"path": "moonbitlang/core/assertion",
"alias": "assertion"
},
{
"path": "moonbitlang/core/string",
"alias": "string"
}
]
}
35 changes: 35 additions & 0 deletions string/string.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,38 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Escape a string using standard C escape sequences to the given buffer,
/// usually for quoting uses.
///
/// This method only escapes characters below 0x20 and the following charactes:
/// `"`, `'`, `\`.
pub fn escape_to(self : String, buf : Buffer) -> Unit {
let mut ix = 0
while ix < self.length() {
let ch = self[ix]
match ch {
'"' | '\'' | '\\' => {
buf.write_char('\\')
buf.write_char(ch)
}
'\n' => {
buf.write_char('\\')
buf.write_char('n')
}
_ => buf.write_char(ch)
}
ix += 1
}
}

/// Escape a string using standard C escape sequences and return the escaped string,
/// usually for quoting uses.
///
/// This method only escapes characters below 0x20 and the following charactes:
/// `"`, `'`, `\`.
pub fn escape(self : String) -> String {
let buf = Buffer::make(self.length())
self.escape_to(buf)
buf.to_string()
}

0 comments on commit 4bb0097

Please sign in to comment.