Detach parseFragmentHeader from parser struct

This operates on a single line and doesn't need any parser state.
This commit is contained in:
Billy Keyes
2019-03-14 21:55:06 -07:00
parent 4ddf1d962d
commit bca8d0806e
2 changed files with 38 additions and 40 deletions
+37 -36
View File
@@ -75,7 +75,7 @@ func (p *parser) ParseNextFileHeader() (file *File, err error) {
// check for disconnected fragment headers (corrupt patch)
if isMaybeFragmentHeader(line) {
var frag Fragment
if err := p.ParseFragmentHeader(&frag, line); err != nil {
if err := parseFragmentHeader(&frag, line); err != nil {
// not a valid header, nothing to worry about
continue
}
@@ -134,41 +134,6 @@ func (p *parser) ParseTraditionalFileHeader(f *File, oldFile, newFile string) er
panic("unimplemented")
}
func (p *parser) ParseFragmentHeader(f *Fragment, header string) error {
match := fragmentHeaderRegexp.FindStringSubmatch(header)
if len(match) < 5 {
return p.Errorf("invalid fragment header")
}
parseInt := func(s string, v *int64) (err error) {
if *v, err = strconv.ParseInt(s, 10, 64); err != nil {
nerr := err.(*strconv.NumError)
return p.Errorf("invalid fragment header value: %s: %v", s, nerr.Err)
}
return
}
if err := parseInt(match[1], &f.OldPosition); err != nil {
return err
}
if err := parseInt(match[2], &f.OldLines); err != nil {
return err
}
if err := parseInt(match[3], &f.NewPosition); err != nil {
return err
}
f.NewLines = 1
if match[4] != "" {
if err := parseInt(match[4], &f.NewLines); err != nil {
return err
}
}
return nil
}
// Line reads and returns the next line. The first call to Line after a call to
// PeekLine will never retrun an error.
func (p *parser) Line() (line string, err error) {
@@ -202,3 +167,39 @@ func isMaybeFragmentHeader(line string) bool {
shortestValidHeader := "@@ -0,0 +1 @@\n"
return len(line) >= len(shortestValidHeader) && strings.HasPrefix(line, fragmentHeaderPrefix)
}
func parseFragmentHeader(f *Fragment, header string) error {
// TODO(bkeyes): use strings.FieldsFunc instead of regexp
match := fragmentHeaderRegexp.FindStringSubmatch(header)
if len(match) < 5 {
return fmt.Errorf("invalid fragment header")
}
parseInt := func(s string, v *int64) (err error) {
if *v, err = strconv.ParseInt(s, 10, 64); err != nil {
nerr := err.(*strconv.NumError)
return fmt.Errorf("invalid fragment header value: %s: %v", s, nerr.Err)
}
return
}
if err := parseInt(match[1], &f.OldPosition); err != nil {
return err
}
if err := parseInt(match[2], &f.OldLines); err != nil {
return err
}
if err := parseInt(match[3], &f.NewPosition); err != nil {
return err
}
f.NewLines = 1
if match[4] != "" {
if err := parseInt(match[4], &f.NewLines); err != nil {
return err
}
}
return nil
}
+1 -4
View File
@@ -109,11 +109,8 @@ func TestParseFragmentHeader(t *testing.T) {
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
p := &parser{r: bufio.NewReader(strings.NewReader(test.Input))}
line, _ := p.Line()
var frag Fragment
err := p.ParseFragmentHeader(&frag, line)
err := parseFragmentHeader(&frag, test.Input)
if test.Invalid {
if err == nil {