Skip to content

Commit

Permalink
110 glob (#111)
Browse files Browse the repository at this point in the history
* Fixed the glob-handling for virtual files.

This pull-request closes #110 by fixing the handling of globs for
our virtual files.  We've updated to use the single routine for file matching, and fixed the issues that made that broken.
  • Loading branch information
skx authored Jun 1, 2024
1 parent 1af28ee commit 003024d
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 70 deletions.
78 changes: 11 additions & 67 deletions fcb/fcb.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"strings"
"unicode"
)

// SIZE contains the size of the FCB structure
Expand Down Expand Up @@ -90,11 +91,13 @@ func (f *FCB) GetType() string {
t := ""

for _, c := range f.Type {
if c != 0x00 {
if unicode.IsPrint(rune(c)) {
t += string(c)
} else {
t += " "
}
}
return strings.TrimSpace(t)
return t
}

// AsBytes returns the entry of the FCB in a format suitable
Expand Down Expand Up @@ -276,10 +279,6 @@ func FromBytes(bytes []uint8) FCB {

// DoesMatch returns true if the filename specified matches the pattern in the FCB.
func (f *FCB) DoesMatch(name string) bool {
t := string(f.Type[0]) + string(f.Type[1]) + string(f.Type[2])
if t == "" || t == " " {
t = "???"
}

// Having a .extension is fine, but if the
// suffix is longer than three characters we're
Expand Down Expand Up @@ -311,7 +310,7 @@ func (f *FCB) DoesMatch(name string) bool {

// Repeat for the suffix.
for i, c := range f.Type {
if (t[i] != c) && (t[i] != '?') {
if (tmp.Type[i] != c) && (f.Type[i] != '?') {
return false
}
}
Expand All @@ -327,11 +326,6 @@ func (f *FCB) DoesMatch(name string) bool {
func (f *FCB) GetMatches(prefix string) ([]FCBFind, error) {
var ret []FCBFind

t := string(f.Type[0]) + string(f.Type[1]) + string(f.Type[2])
if t == "" || t == " " {
t = "???"
}

// Find files in the directory
files, err := os.ReadDir(prefix)
if err != nil {
Expand All @@ -346,65 +340,15 @@ func (f *FCB) GetMatches(prefix string) ([]FCBFind, error) {
continue
}

// Create the new record, in case this entry matches.
var ent FCBFind

// Populate the host-path before we do anything else.
ent.Host = filepath.Join(prefix, file.Name())

// Name needs to be upper-cased
name := strings.ToUpper(file.Name())
if f.DoesMatch(name) {

// is the name too long?
if len(name) > 8+3 {
continue
}

// Having a .extension is fine, but if the
// suffix is longer than three characters we're
// not going to use it.
parts := strings.Split(name, ".")
if len(parts) == 2 {
// filename is over 8 characters
if len(parts[0]) > 8 {
continue
}
// suffix is over 3 characters
if len(parts[1]) > 3 {
continue
}
}

// Default to included the file, now the basics
// have matched - filename/extension lengths and
// being a non-directory.
include := true

// OK make an fcb
tmp := FromString(name)

// Now test if the name we've got matches that in the
// search-pattern: Name.
//
// Either a literal match, or a wildcard match with "?".
for i, c := range tmp.Name {
if (f.Name[i] != c) && (f.Name[i] != '?') {
include = false
}
}

// Repeat for the suffix.
for i, c := range tmp.Type {
if (t[i] != c) && (t[i] != '?') {
include = false
}
}
var ent FCBFind

// Does it match? Then add the entry, with the
// CP/M visible name.
if include {
// Populate the host-path before we do anything else.
ent.Host = filepath.Join(prefix, file.Name())

// populate
// populate the name, but note it needs to be upper-cased
ent.Name = name

// append
Expand Down
61 changes: 58 additions & 3 deletions fcb/fcb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"
)

// TestFCBSize ensures our size matches expectations.
func TestFCBSize(t *testing.T) {
x := FromString("blah")
b := x.AsBytes()
Expand Down Expand Up @@ -70,7 +71,7 @@ func TestFCBFromString(t *testing.T) {
if f.GetName() != "FOO" {
t.Fatalf("name wrong, got '%v'", f.GetName())
}
if f.GetType() != "" {
if f.GetType() != " " {
t.Fatalf("unexpected suffix '%v'", f.GetType())
}

Expand All @@ -82,7 +83,7 @@ func TestFCBFromString(t *testing.T) {
if f.GetName() != "THIS-IS-" {
t.Fatalf("name wrong, got '%v'", f.GetName())
}
if f.GetType() != "" {
if f.GetType() != " " {
t.Fatalf("unexpected suffix '%v'", f.GetType())
}

Expand All @@ -99,13 +100,16 @@ func TestFCBFromString(t *testing.T) {
}

// wildcard
f = FromString("c:steve*")
f = FromString("c:steve*.*")
if f.Drive != 2 {
t.Fatalf("drive wrong")
}
if f.GetName() != "STEVE???" {
t.Fatalf("name wrong, got '%v'", f.GetName())
}
if f.GetType() != "???" {
t.Fatalf("type wrong, got '%v'", f.GetName())
}

f = FromString("c:test.C*")
if f.Drive != 2 {
Expand All @@ -119,3 +123,54 @@ func TestFCBFromString(t *testing.T) {
}

}

func TestDoesMatch(t *testing.T) {

type testcase struct {
// pattern contains a pattern
pattern string

// yes contains a list of filenames that should match that pattern
yes []string

// no contains a list of filenames that should NOT match that pattern
no []string
}

tests := []testcase{
{
pattern: "*.com",
yes: []string{"A.COM", "B:FOO.COM"},
no: []string{"A", "BOB", "C.GO"},
},
{
pattern: "A*",
yes: []string{"ANIMAL", "B:AUGUST"},
no: []string{"ANIMAL.COM", "BOB", "AURORA.COM"},
},
{
pattern: "A*.*",
yes: []string{"ANIMAL.com", "B:AUGUST.com", "AURORA"},
no: []string{"Test", "BOB"},
},
}

for _, test := range tests {

f := FromString(test.pattern)

for _, ei := range test.no {

if f.DoesMatch(ei) {
t.Fatalf("file %s matched pattern %s and it should not have done", ei, test.pattern)
}
}

for _, joo := range test.yes {

if !f.DoesMatch(joo) {
t.Fatalf("file %s did not match pattern %s and it should have done", joo, test.pattern)
}
}
}
}

0 comments on commit 003024d

Please sign in to comment.