mirror of
https://github.com/zellyn/diskii.git
synced 2025-01-13 03:29:49 +00:00
todos and lint fixes; added hermit
This commit is contained in:
parent
7d036244af
commit
116f3781b5
15
README.md
15
README.md
@ -98,15 +98,16 @@ operations matrix is listed below. Anything that an actual user needs
|
||||
will be likely to get priority.
|
||||
|
||||
- [ ] Make `put` accept load address for appropriate filetypes.
|
||||
- [ ] Fix `golint` errors
|
||||
- [ ] Implement `GetFile` for prodos
|
||||
- [x] Build per-platform binaries for Linux, MacOS, Windows.
|
||||
- [x] Implement `GetFile` for DOS 3.3
|
||||
- [ ] Implement `Delete` for Super-Mon
|
||||
- [ ] Implement `Delete` for DOS 3.3
|
||||
- [ ] Implement `Delete` for ProDOS
|
||||
- [ ] Add and implement the `-l` flag for `ls`
|
||||
- [x] Add `Delete` to the `disk.Operator` interface
|
||||
- [ ] Implement it for Super-Mon
|
||||
- [ ] Implement it for DOS 3.3
|
||||
- [ ] Add ProDOS support for all commands
|
||||
- [x] Make `filetypes` command use a tabwriter to write as a table
|
||||
- [ ] Make `OperatorFactory.SeemsToMatch` more sophisticated for ProDOS
|
||||
- [ ] Make `OperatorFactory.SeemsToMatch` more sophisticated for DOS 3.3
|
||||
- [ ] Make `OperatorFactory.SeemsToMatch` more sophisticated for NakedOS
|
||||
- [x] Build per-platform binaries for Linux, MacOS, Windows.
|
||||
|
||||
# Related tools
|
||||
|
||||
|
@ -186,6 +186,7 @@ func Decode(raw []byte) (Listing, error) {
|
||||
return listing, nil
|
||||
}
|
||||
|
||||
/*
|
||||
const (
|
||||
tokenREM = 0x5D
|
||||
tokenUnaryPlus = 0x35
|
||||
@ -193,6 +194,7 @@ const (
|
||||
tokenQuoteStart = 0x28
|
||||
tokenQuoteEnd = 0x29
|
||||
)
|
||||
*/
|
||||
|
||||
func isalnum(b byte) bool {
|
||||
switch {
|
||||
|
@ -39,6 +39,7 @@ var helloListing = ` 10 REM THIS IS A COMMENT
|
||||
// TestParse tests the full parsing and output of a basic program from
|
||||
// bytes.
|
||||
func TestParse(t *testing.T) {
|
||||
t.Skip("ignoring for now")
|
||||
listing, err := Decode(helloBinary)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -46,6 +47,6 @@ func TestParse(t *testing.T) {
|
||||
text := basic.ChevronControlCodes(listing.String())
|
||||
if text != helloListing {
|
||||
// TODO(zellyn): actually test, once we understand how adding spaces works.
|
||||
// t.Fatalf("Wrong listing; want:\n%s\ngot:\n%s", helloListing, text)
|
||||
t.Fatalf("Wrong listing; want:\n%s\ngot:\n%s", helloListing, text)
|
||||
}
|
||||
}
|
||||
|
1
bin/.golangci-lint-1.41.1.pkg
Symbolic link
1
bin/.golangci-lint-1.41.1.pkg
Symbolic link
@ -0,0 +1 @@
|
||||
hermit
|
7
bin/README.hermit.md
Normal file
7
bin/README.hermit.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Hermit environment
|
||||
|
||||
This is a [Hermit](https://github.com/cashapp/hermit) bin directory.
|
||||
|
||||
The symlinks in this directory are managed by Hermit and will automatically
|
||||
download and install Hermit itself as well as packages. These packages are
|
||||
local to this environment.
|
19
bin/activate-hermit
Executable file
19
bin/activate-hermit
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# This file must be used with "source bin/activate-hermit" from bash or zsh.
|
||||
# You cannot run it directly
|
||||
|
||||
if [ "${BASH_SOURCE-}" = "$0" ]; then
|
||||
echo "You must source this script: \$ source $0" >&2
|
||||
exit 33
|
||||
fi
|
||||
|
||||
BIN_DIR="$(dirname "${BASH_SOURCE[0]:-${(%):-%x}}")"
|
||||
if "${BIN_DIR}/hermit" noop > /dev/null; then
|
||||
eval "$("${BIN_DIR}/hermit" activate "${BIN_DIR}/..")"
|
||||
|
||||
if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ]; then
|
||||
hash -r 2>/dev/null
|
||||
fi
|
||||
|
||||
echo "Hermit environment $("${HERMIT_ENV}"/bin/hermit env HERMIT_ENV) activated"
|
||||
fi
|
1
bin/golangci-lint
Symbolic link
1
bin/golangci-lint
Symbolic link
@ -0,0 +1 @@
|
||||
.golangci-lint-1.41.1.pkg
|
26
bin/hermit
Executable file
26
bin/hermit
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
if [ -z "${HERMIT_STATE_DIR}" ]; then
|
||||
case "$(uname -s)" in
|
||||
Darwin)
|
||||
export HERMIT_STATE_DIR="${HOME}/Library/Caches/hermit"
|
||||
;;
|
||||
Linux)
|
||||
export HERMIT_STATE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/hermit"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
export HERMIT_DIST_URL="${HERMIT_DIST_URL:-https://d1abdrezunyhdp.cloudfront.net/square}"
|
||||
HERMIT_CHANNEL="$(basename "${HERMIT_DIST_URL}")"
|
||||
export HERMIT_CHANNEL
|
||||
export HERMIT_EXE=${HERMIT_EXE:-${HERMIT_STATE_DIR}/pkg/hermit@${HERMIT_CHANNEL}/hermit}
|
||||
|
||||
if [ ! -x "${HERMIT_EXE}" ]; then
|
||||
echo "Bootstrapping ${HERMIT_EXE} from ${HERMIT_DIST_URL}" 1>&2
|
||||
curl -fsSL "${HERMIT_DIST_URL}/install.sh" | /bin/bash 1>&2
|
||||
fi
|
||||
|
||||
exec "${HERMIT_EXE}" --level=fatal exec "$0" -- "$@"
|
0
bin/hermit.hcl
Normal file
0
bin/hermit.hcl
Normal file
@ -12,13 +12,21 @@ import (
|
||||
|
||||
type LsCmd struct {
|
||||
Order types.DiskOrder `kong:"default='auto',enum='auto,do,po',help='Logical-to-physical sector order.'"`
|
||||
System string `kong:"default='auto',enum='auto,dos3',help='DOS system used for image.'"`
|
||||
System string `kong:"default='auto',enum='auto,dos3,prodos,nakedos',help='DOS system used for image.'"`
|
||||
|
||||
ShortNames bool `kong:"short='s',help='Whether to print short filenames (only makes a difference on Super-Mon disks).'"`
|
||||
Image *os.File `kong:"arg,required,help='Disk/device image to read.'"`
|
||||
Directory string `kong:"arg,optional,help='Directory to list (ProDOS only).'"`
|
||||
}
|
||||
|
||||
func (l LsCmd) Help() string {
|
||||
return `Examples:
|
||||
# Simple ls of a disk image
|
||||
diskii ls games.dsk
|
||||
# Get really explicit about disk order and system
|
||||
diskii ls --order do --system nakedos Super-Mon-2.0.dsk`
|
||||
}
|
||||
|
||||
func (l *LsCmd) Run(globals *types.Globals) error {
|
||||
op, order, err := disk.OpenFile(l.Image, l.Order, l.System, globals.DiskOperatorFactories, globals.Debug)
|
||||
if err != nil {
|
||||
|
@ -32,7 +32,7 @@ func (ds DiskSector) GetTrack() byte {
|
||||
}
|
||||
|
||||
// SetTrack sets the track that a DiskSector was loaded from.
|
||||
func (ds DiskSector) SetTrack(track byte) {
|
||||
func (ds *DiskSector) SetTrack(track byte) {
|
||||
ds.Track = track
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ func (ds DiskSector) GetSector() byte {
|
||||
}
|
||||
|
||||
// SetSector sets the sector that a DiskSector was loaded from.
|
||||
func (ds DiskSector) SetSector(sector byte) {
|
||||
func (ds *DiskSector) SetSector(sector byte) {
|
||||
ds.Sector = sector
|
||||
}
|
||||
|
||||
@ -695,10 +695,7 @@ func (of OperatorFactory) Name() string {
|
||||
func (of OperatorFactory) SeemsToMatch(diskbytes []byte, debug bool) bool {
|
||||
// For now, just return true if we can run Catalog successfully.
|
||||
_, _, err := ReadCatalog(diskbytes, debug)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Operator returns an Operator for the []byte disk image.
|
||||
|
@ -10,11 +10,14 @@ import (
|
||||
// TestVTOCMarshalRoundtrip checks a simple roundtrip of VTOC data.
|
||||
func TestVTOCMarshalRoundtrip(t *testing.T) {
|
||||
buf := make([]byte, 256)
|
||||
rand.Read(buf)
|
||||
_, _ = rand.Read(buf)
|
||||
buf1 := make([]byte, 256)
|
||||
copy(buf1, buf)
|
||||
vtoc1 := &VTOC{}
|
||||
vtoc1.FromSector(buf1)
|
||||
err := vtoc1.FromSector(buf1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
buf2, err := vtoc1.ToSector()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -23,7 +26,10 @@ func TestVTOCMarshalRoundtrip(t *testing.T) {
|
||||
t.Errorf("Buffers differ: %v != %v", buf, buf2)
|
||||
}
|
||||
vtoc2 := &VTOC{}
|
||||
vtoc2.FromSector(buf2)
|
||||
err = vtoc2.FromSector(buf2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if *vtoc1 != *vtoc2 {
|
||||
t.Errorf("Structs differ: %v != %v", vtoc1, vtoc2)
|
||||
}
|
||||
@ -32,11 +38,14 @@ func TestVTOCMarshalRoundtrip(t *testing.T) {
|
||||
// TestCatalogSectorMarshalRoundtrip checks a simple roundtrip of CatalogSector data.
|
||||
func TestCatalogSectorMarshalRoundtrip(t *testing.T) {
|
||||
buf := make([]byte, 256)
|
||||
rand.Read(buf)
|
||||
_, _ = rand.Read(buf)
|
||||
buf1 := make([]byte, 256)
|
||||
copy(buf1, buf)
|
||||
cs1 := &CatalogSector{}
|
||||
cs1.FromSector(buf1)
|
||||
err := cs1.FromSector(buf1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
buf2, err := cs1.ToSector()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -45,7 +54,10 @@ func TestCatalogSectorMarshalRoundtrip(t *testing.T) {
|
||||
t.Errorf("Buffers differ: %v != %v", buf, buf2)
|
||||
}
|
||||
cs2 := &CatalogSector{}
|
||||
cs2.FromSector(buf2)
|
||||
err = cs2.FromSector(buf2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if *cs1 != *cs2 {
|
||||
t.Errorf("Structs differ: %v != %v", cs1, cs2)
|
||||
}
|
||||
@ -54,11 +66,14 @@ func TestCatalogSectorMarshalRoundtrip(t *testing.T) {
|
||||
// TestTrackSectorListMarshalRoundtrip checks a simple roundtrip of TrackSectorList data.
|
||||
func TestTrackSectorListMarshalRoundtrip(t *testing.T) {
|
||||
buf := make([]byte, 256)
|
||||
rand.Read(buf)
|
||||
_, _ = rand.Read(buf)
|
||||
buf1 := make([]byte, 256)
|
||||
copy(buf1, buf)
|
||||
cs1 := &TrackSectorList{}
|
||||
cs1.FromSector(buf1)
|
||||
err := cs1.FromSector(buf1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
buf2, err := cs1.ToSector()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -67,7 +82,10 @@ func TestTrackSectorListMarshalRoundtrip(t *testing.T) {
|
||||
t.Errorf("Buffers differ: %v != %v", buf, buf2)
|
||||
}
|
||||
cs2 := &TrackSectorList{}
|
||||
cs2.FromSector(buf2)
|
||||
err = cs2.FromSector(buf2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if *cs1 != *cs2 {
|
||||
t.Errorf("Structs differ: %v != %v", cs1, cs2)
|
||||
}
|
||||
|
@ -926,10 +926,7 @@ func (of OperatorFactory) Name() string {
|
||||
func (of OperatorFactory) SeemsToMatch(devicebytes []byte, debug bool) bool {
|
||||
// For now, just return true if we can run Catalog successfully.
|
||||
_, err := readVolume(devicebytes, 2, debug)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Operator returns an Operator for the []byte disk image.
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
|
||||
func randomBlock() disk.Block {
|
||||
var b1 disk.Block
|
||||
rand.Read(b1[:])
|
||||
_, _ = rand.Read(b1[:])
|
||||
return b1
|
||||
}
|
||||
|
||||
@ -19,7 +19,10 @@ func randomBlock() disk.Block {
|
||||
func TestVolumeDirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
|
||||
b1 := randomBlock()
|
||||
vdkb := &VolumeDirectoryKeyBlock{}
|
||||
vdkb.FromBlock(b1)
|
||||
err := vdkb.FromBlock(b1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b2, err := vdkb.ToBlock()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -28,7 +31,10 @@ func TestVolumeDirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
|
||||
t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; "))
|
||||
}
|
||||
vdkb2 := &VolumeDirectoryKeyBlock{}
|
||||
vdkb2.FromBlock(b2)
|
||||
err = vdkb2.FromBlock(b2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if *vdkb != *vdkb2 {
|
||||
t.Errorf("Structs differ: %v != %v", vdkb, vdkb2)
|
||||
}
|
||||
@ -38,7 +44,10 @@ func TestVolumeDirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
|
||||
func TestVolumeDirectoryBlockMarshalRoundtrip(t *testing.T) {
|
||||
b1 := randomBlock()
|
||||
vdb := &VolumeDirectoryBlock{}
|
||||
vdb.FromBlock(b1)
|
||||
err := vdb.FromBlock(b1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b2, err := vdb.ToBlock()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -47,7 +56,10 @@ func TestVolumeDirectoryBlockMarshalRoundtrip(t *testing.T) {
|
||||
t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; "))
|
||||
}
|
||||
vdb2 := &VolumeDirectoryBlock{}
|
||||
vdb2.FromBlock(b2)
|
||||
err = vdb2.FromBlock(b2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if *vdb != *vdb2 {
|
||||
t.Errorf("Structs differ: %v != %v", vdb, vdb2)
|
||||
}
|
||||
@ -57,7 +69,10 @@ func TestVolumeDirectoryBlockMarshalRoundtrip(t *testing.T) {
|
||||
func TestSubdirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
|
||||
b1 := randomBlock()
|
||||
skb := &SubdirectoryKeyBlock{}
|
||||
skb.FromBlock(b1)
|
||||
err := skb.FromBlock(b1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b2, err := skb.ToBlock()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -66,7 +81,10 @@ func TestSubdirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
|
||||
t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; "))
|
||||
}
|
||||
skb2 := &SubdirectoryKeyBlock{}
|
||||
skb2.FromBlock(b2)
|
||||
err = skb2.FromBlock(b2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if *skb != *skb2 {
|
||||
t.Errorf("Structs differ: %v != %v", skb, skb2)
|
||||
}
|
||||
@ -76,7 +94,10 @@ func TestSubdirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
|
||||
func TestSubdirectoryBlockMarshalRoundtrip(t *testing.T) {
|
||||
b1 := randomBlock()
|
||||
sb := &SubdirectoryBlock{}
|
||||
sb.FromBlock(b1)
|
||||
err := sb.FromBlock(b1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b2, err := sb.ToBlock()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -85,7 +106,10 @@ func TestSubdirectoryBlockMarshalRoundtrip(t *testing.T) {
|
||||
t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; "))
|
||||
}
|
||||
sb2 := &SubdirectoryBlock{}
|
||||
sb2.FromBlock(b2)
|
||||
err = sb2.FromBlock(b2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if *sb != *sb2 {
|
||||
t.Errorf("Structs differ: %v != %v", sb, sb2)
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func (sm SectorMap) FirstFreeFile() byte {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Persist writes the current contenst of a sector map back back to
|
||||
// Persist writes the current contents of a sector map back back to
|
||||
// disk.
|
||||
func (sm SectorMap) Persist(diskbytes []byte) error {
|
||||
sector09, err := disk.ReadSector(diskbytes, 0, 9)
|
||||
|
@ -129,8 +129,6 @@ func (d *decoder) parseChunk() (done bool, err error) {
|
||||
default:
|
||||
return false, d.parseUnknown(string(d.tmp[:4]), length)
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (d *decoder) parseINFO(length uint32) error {
|
||||
|
Loading…
x
Reference in New Issue
Block a user