<commit_before>package doctor

// This file defines the EditSet interface and a default implementation,
// including the NewEditSet method.

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"syscall"
)

// An EditSet is a collection of changes to be made to a text file.  Each
// edit is comprised of an offset, a length, and a replacement string.
//
// The EditSet is populated by invoking the Add method.  Each edit replaces 0
// or more characters at a given offset with a given string.  Characters can be
// inserted by using a position with length 0; characters can be deleted by
// using "" for the replacement string.
//
// Edits can be applied by invoking one of the ApplyTo methods.
//
// ApplyTo reads a stream of characters from the given io.Reader, applying the
// edits in the EditSet to the stream and writing the result to the given
// io.Writer.
//
// ApplyToFile applies the edits in the EditSet to the given file, writing the
// result to the given io.Writer.
//
// ApplyToString is intended for testing purposes only.  It applies the edits
// in the EditSet to a given string, returning the resulting string; or if an
// error occurs, a description of the error is returned, rather than the
// modified string contents.
//
// The String method returns a description of this EditSet (for debugging).
type EditSet interface {
	Add(file string, position OffsetLength, replacement string)
	ApplyTo(key string, in io.Reader, out io.Writer) error
	ApplyToAllFiles(out io.Writer) error
	WriteToAllFiles() error
	ApplyToFile(filename string, out io.Writer) error
	ApplyToString(s string) (string, error)
	String() string
}

type edit struct {
	OffsetLength
	replacement string
}

type editSet struct {
	edits map[string][]edit
}

// NewEditSet returns a new, empty EditSet.
func NewEditSet() EditSet {
	return &editSet{edits: make(map[string][]edit, 1)}
}

//Adds an edit to the editset, mapping to the appropriate file
//
func (e *editSet) Add(file string, position OffsetLength, replacement string) {
	//TODO see if need to malloc fedits?
	//TODO meh, kind of don't like that it's not in place, but [index][index] is bad
	fedits := e.edits[file]

	var pos int = len(fedits)
	for i := len(fedits) - 1; i >= 0; i-- {
		if fedits[i].offset > position.offset {
			pos = i
		} else {
			break
		}
	}
	newEdit := edit{position, replacement}
	fedits = append(fedits, newEdit)
	copy(fedits[pos+1:], fedits[pos:])
	fedits[pos] = newEdit

	e.edits[file] = fedits
}

func (e *edit) String() string {
	return "Replace " + e.OffsetLength.String() +
		" with \"" + e.replacement + "\""
}

func (e *editSet) String() string {
	var buffer bytes.Buffer
	for _, edits := range e.edits {
		for _, edit := range edits {
			buffer.WriteString(edit.String())
			buffer.WriteString("\n")
		}
	}
	return buffer.String()
}<commit_msg>Added filename to EditSet String() method<commit_after>package doctor

// This file defines the EditSet interface and a default implementation,
// including the NewEditSet method.

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"syscall"
)

// An EditSet is a collection of changes to be made to a text file.  Each
// edit is comprised of an offset, a length, and a replacement string.
//
// The EditSet is populated by invoking the Add method.  Each edit replaces 0
// or more characters at a given offset with a given string.  Characters can be
// inserted by using a position with length 0; characters can be deleted by
// using "" for the replacement string.
//
// Edits can be applied by invoking one of the ApplyTo methods.
//
// ApplyTo reads a stream of characters from the given io.Reader, applying the
// edits in the EditSet to the stream and writing the result to the given
// io.Writer.
//
// ApplyToFile applies the edits in the EditSet to the given file, writing the
// result to the given io.Writer.
//
// ApplyToString is intended for testing purposes only.  It applies the edits
// in the EditSet to a given string, returning the resulting string; or if an
// error occurs, a description of the error is returned, rather than the
// modified string contents.
//
// The String method returns a description of this EditSet (for debugging).
type EditSet interface {
	Add(file string, position OffsetLength, replacement string)
	ApplyTo(key string, in io.Reader, out io.Writer) error
	ApplyToAllFiles(out io.Writer) error
	WriteToAllFiles() error
	ApplyToFile(filename string, out io.Writer) error
	ApplyToString(s string) (string, error)
	String() string
}

type edit struct {
	OffsetLength
	replacement string
}

type editSet struct {
	edits map[string][]edit
}

// NewEditSet returns a new, empty EditSet.
func NewEditSet() EditSet {
	return &editSet{edits: make(map[string][]edit, 1)}
}

//Adds an edit to the editset, mapping to the appropriate file
//
func (e *editSet) Add(file string, position OffsetLength, replacement string) {
	//TODO see if need to malloc fedits?
	//TODO meh, kind of don't like that it's not in place, but [index][index] is bad
	fedits := e.edits[file]

	var pos int = len(fedits)
	for i := len(fedits) - 1; i >= 0; i-- {
		if fedits[i].offset > position.offset {
			pos = i
		} else {
			break
		}
	}
	newEdit := edit{position, replacement}
	fedits = append(fedits, newEdit)
	copy(fedits[pos+1:], fedits[pos:])
	fedits[pos] = newEdit

	e.edits[file] = fedits
}

func (e *edit) String() string {
	return "Replace " + e.OffsetLength.String() +
		" with \"" + e.replacement + "\""
}

func (e *editSet) String() string {
	var buffer bytes.Buffer
	for filename, edits := range e.edits {
		buffer.WriteString("Edits for ")
		buffer.WriteString(filename)
		buffer.WriteString(":\n")
		for _, edit := range edits {
			buffer.WriteString("    ")
			buffer.WriteString(edit.String())
			buffer.WriteString("\n")
		}
	}
	return buffer.String()
}
{'fraction_non_alphanumeric': 0.10680771199454019, 'fraction_numerical': 0.002047432178809077, 'mean_word_length': 3.6450079239302693, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2917848', 'n_tokens_mistral': 1891, 'n_tokens_neox': 1819, 'n_words': 741}