Skip to content

Commit

Permalink
Merge pull request #38 from 200sc/release/v0.5.0
Browse files Browse the repository at this point in the history
Release/v0.5.0
  • Loading branch information
200sc authored Nov 10, 2023
2 parents 9a94cc8 + a5f547a commit 568459e
Show file tree
Hide file tree
Showing 84 changed files with 1,627 additions and 949 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ jobs:
- name: Lint
uses: golangci/golangci-lint-action@v3
with:
args: "--disable-all -E misspell -E deadcode -E govet"
args: "-E misspell -E thelper -E errname -E goimports"
2 changes: 1 addition & 1 deletion bebop.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
package bebop

// Version is the library version. Should be used by CLI tools when passed a '--version' flag.
const Version = "v0.4.0"
const Version = "v0.5.0"

// A File is a structured representation of a .bop file.
type File struct {
Expand Down
4 changes: 2 additions & 2 deletions compatibility_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestIncompatibilityExpectations_200sc(t *testing.T) {
continue
}
filename := f.Name()
if !strings.HasSuffix(filename, ".bop") {
if !strings.HasSuffix(filename, fileExt) {
continue
}
t.Run(filename, func(t *testing.T) {
Expand Down Expand Up @@ -158,7 +158,7 @@ func TestIncompatibilityExpectations_Rainway(t *testing.T) {
continue
}
filename := f.Name()
if !strings.HasSuffix(filename, ".bop") {
if !strings.HasSuffix(filename, fileExt) {
continue
}
t.Run(filename, func(t *testing.T) {
Expand Down
41 changes: 24 additions & 17 deletions format.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@ package bebop

import (
"io"

"github.com/200sc/bebop/iohelp"
)

// Format reads a .bop file from r and writes out a formatted version of that file to out.
func Format(r io.Reader, out io.Writer) {
format(newTokenReader(r), out)
func Format(r io.Reader, out io.Writer) error {
return format(newTokenReader(r), out)
}

func format(tr *tokenReader, w io.Writer) {
func format(tr *tokenReader, w io.Writer) error {
ew := iohelp.NewErrorWriter(w)
var readOnly bool
var newlineBeforeNextRecord bool
for tr.Next() {
if ew.Err != nil {
return ew.Err
}
t := tr.Token()
switch t.kind {
case tokenKindOpenSquare:
if newlineBeforeNextRecord {
w.Write([]byte{'\n'})
ew.SafeWrite([]byte{'\n'})
}
// opcode, next tokens are 'opcode', '(', hex or string lit, ')', ']'
opCodeBytes := t.concrete
Expand All @@ -27,53 +33,54 @@ func format(tr *tokenReader, w io.Writer) {
}
// inject newline after opcodes
opCodeBytes = append(opCodeBytes, '\n')
w.Write(opCodeBytes)
ew.SafeWrite(opCodeBytes)
newlineBeforeNextRecord = false
case tokenKindLineComment:
cmtBytes := t.concrete
w.Write(cmtBytes)
ew.SafeWrite(cmtBytes)
newlineBeforeNextRecord = false
case tokenKindBlockComment:
cmtBytes := t.concrete
cmtBytes = append(cmtBytes, []byte("\n")...)
w.Write(cmtBytes)
ew.SafeWrite(cmtBytes)
newlineBeforeNextRecord = false
case tokenKindReadOnly:
readOnly = true
continue
case tokenKindEnum:
if newlineBeforeNextRecord {
w.Write([]byte{'\n'})
ew.SafeWrite([]byte{'\n'})
}
w.Write(formatEnum(tr))
ew.SafeWrite(formatEnum(tr))
newlineBeforeNextRecord = true
case tokenKindConst:
if newlineBeforeNextRecord {
w.Write([]byte{'\n'})
ew.SafeWrite([]byte{'\n'})
}
w.Write(formatConst(tr))
ew.SafeWrite(formatConst(tr))
newlineBeforeNextRecord = true
case tokenKindStruct:
if newlineBeforeNextRecord {
w.Write([]byte{'\n'})
ew.SafeWrite([]byte{'\n'})
}
w.Write(formatStruct(tr, readOnly, "\t"))
ew.SafeWrite(formatStruct(tr, readOnly, "\t"))
newlineBeforeNextRecord = true
case tokenKindMessage:
if newlineBeforeNextRecord {
w.Write([]byte{'\n'})
ew.SafeWrite([]byte{'\n'})
}
w.Write(formatMessage(tr, "\t"))
ew.SafeWrite(formatMessage(tr, "\t"))
newlineBeforeNextRecord = true
case tokenKindUnion:
if newlineBeforeNextRecord {
w.Write([]byte{'\n'})
ew.SafeWrite([]byte{'\n'})
}
w.Write(formatUnion(tr, "\t"))
ew.SafeWrite(formatUnion(tr, "\t"))
newlineBeforeNextRecord = true
}
readOnly = false
}
return nil
}

func formatEnum(tr *tokenReader) []byte {
Expand Down
77 changes: 35 additions & 42 deletions format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,15 @@ var testFormatFiles = []string{
"union",
}

const fileExt = ".bop"

func TestTokenizeFormat(t *testing.T) {
t.Parallel()
for _, filename := range testFormatFiles {
filename := filename
t.Run(filename, func(t *testing.T) {
t.Parallel()
f, err := os.Open(filepath.Join("testdata", "base", filename+".bop"))
if err != nil {
t.Fatalf("failed to open test file %s: %v", filename+".bop", err)
}
if _, _, err := ReadFile(f); err != nil {
f.Close()
t.Fatalf("can not format unparseable files")
}
f.Close()
f, err = os.Open(filepath.Join("testdata", "base", filename+".bop"))
if err != nil {
t.Fatalf("failed to open test file (for format) %s: %v", filename+".bop", err)
}

tr := newTokenReader(f)
out, err := os.Create(filepath.Join("testdata", "formatted", filename+"_formatted.bop"))
if err != nil {
t.Fatalf("failed to open out file %s: %v", filename+"_formatted.bop", err)
}
defer out.Close()
format(tr, out)
formatFile(t, "base", filename)
})
}
}
Expand All @@ -65,27 +47,38 @@ func TestTokenizeFormatIncompatible(t *testing.T) {
filename := filename
t.Run(filename, func(t *testing.T) {
t.Parallel()
f, err := os.Open(filepath.Join("testdata", "incompatible", filename+".bop"))
if err != nil {
t.Fatalf("failed to open test file %s: %v", filename+".bop", err)
}
if _, _, err := ReadFile(f); err != nil {
f.Close()
t.Fatalf("can not format unparseable files")
}
f.Close()
f, err = os.Open(filepath.Join("testdata", "incompatible", filename+".bop"))
if err != nil {
t.Fatalf("failed to open test file (for format) %s: %v", filename+".bop", err)
}

tr := newTokenReader(f)
out, err := os.Create(filepath.Join("testdata", "formatted", filename+"_formatted.bop"))
if err != nil {
t.Fatalf("failed to open out file %s: %v", filename+"_formatted.bop", err)
}
defer out.Close()
format(tr, out)
formatFile(t, "incompatible", filename)
})
}
}

func formatFile(t *testing.T, subdir, filename string) {
t.Helper()
const formattedExt = "_formatted.bop"

f, err := os.Open(filepath.Join("testdata", subdir, filename+fileExt))
if err != nil {
t.Fatalf("failed to open test file %s: %v", filename+fileExt, err)
}

if _, _, err := ReadFile(f); err != nil {
f.Close()
t.Fatalf("can not format unparsable files")
}
f.Close()
f, err = os.Open(filepath.Join("testdata", subdir, filename+fileExt))
if err != nil {
t.Fatalf("failed to open test file (for format) %s: %v", filename+fileExt, err)
}

tr := newTokenReader(f)
out, err := os.Create(filepath.Join("testdata", "formatted", filename+formattedExt))
if err != nil {
t.Fatalf("failed to open out file %s: %v", filename+formattedExt, err)
}
defer out.Close()
err = format(tr, out)
if err != nil {
t.Fatalf("failed to format %s: %v", filename+formattedExt, err)
}
}
Loading

0 comments on commit 568459e

Please sign in to comment.