Add filetypes, and filetypes and put commands

This commit is contained in:
Zellyn Hunter 2016-11-30 21:42:42 -05:00
parent 300358e9bd
commit 10d2a1e027
7 changed files with 152 additions and 58 deletions

View File

@ -12,6 +12,8 @@ import (
_ "github.com/zellyn/diskii/lib/supermon"
)
var missingok bool // flag for whether to consider deleting a nonexistent file okay
// deleteCmd represents the delete command, used to delete a file.
var deleteCmd = &cobra.Command{
Use: "delete",
@ -30,6 +32,7 @@ delete disk-image.dsk HELLO
func init() {
RootCmd.AddCommand(deleteCmd)
deleteCmd.Flags().BoolVarP(&missingok, "missingok", "f", false, "if true, don't consider deleting a nonexistent file an error")
}
// runDelete performs the actual delete logic.
@ -49,8 +52,7 @@ func runDelete(args []string) error {
if err != nil {
return err
}
if !deleted {
// TODO(zellyn): implement -f flag to not warn on nonexistence.
if !deleted && !missingok {
return fmt.Errorf("file %q not found", args[1])
}
f, err := os.Create(args[0])

45
cmd/filetypes.go Normal file
View File

@ -0,0 +1,45 @@
// Copyright © 2016 Zellyn Hunter <zellyn@gmail.com>
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/zellyn/diskii/lib/disk"
_ "github.com/zellyn/diskii/lib/dos3"
_ "github.com/zellyn/diskii/lib/supermon"
)
var all bool // flag for whether to show all filetypes
// filetypesCmd represents the filetypes command, used to display
// valid filetypes recognized by diskii.
var filetypesCmd = &cobra.Command{
Use: "filetypes",
Short: "print a list of filetypes",
Long: `Print a list of filetypes understood by diskii`,
Run: func(cmd *cobra.Command, args []string) {
if err := runFiletypes(args); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(-1)
}
},
}
func init() {
RootCmd.AddCommand(filetypesCmd)
filetypesCmd.Flags().BoolVarP(&all, "all", "a", false, "display all types, including SOS types and reserved ranges")
}
// runFiletypes performs the actual listing of filetypes.
func runFiletypes(args []string) error {
if len(args) != 0 {
return fmt.Errorf("filetypes expects no arguments")
}
for _, typ := range disk.FiletypeNames(all) {
fmt.Println(typ)
}
return nil
}

View File

@ -13,6 +13,9 @@ import (
_ "github.com/zellyn/diskii/lib/supermon"
)
var filetypeName string // flag for file type
var overwrite bool // flag for whether to overwrite
// putCmd represents the put command, used to put the raw contents
// of a file.
var putCmd = &cobra.Command{
@ -32,12 +35,14 @@ put disk-image.dsk HELLO <name of file with contents>
func init() {
RootCmd.AddCommand(putCmd)
putCmd.Flags().StringVarP(&filetypeName, "type", "t", "B", "Type of file (`diskii filetypes` to list)")
putCmd.Flags().BoolVarP(&overwrite, "overwrite", "f", false, "whether to overwrite existing files")
}
// runPut performs the actual put logic.
func runPut(args []string) error {
if len(args) != 3 {
return fmt.Errorf("put expects a disk image filename, an disk-image filename, and a filename to read the contents from")
return fmt.Errorf("usage: put <disk image> <target filename> <source filename>")
}
sd, err := disk.Open(args[0])
if err != nil {
@ -52,5 +57,33 @@ func runPut(args []string) error {
return err
}
filetype, err := disk.FiletypeForName(filetypeName)
if err != nil {
return err
}
fileInfo := disk.FileInfo{
Descriptor: disk.Descriptor{
Name: args[1],
Length: len(contents),
Type: filetype,
},
Data: contents,
}
_, err = op.PutFile(fileInfo, overwrite)
if err != nil {
return err
}
f, err := os.Create(args[0])
if err != nil {
return err
}
_, err = sd.Write(f)
if err != nil {
return err
}
if err = f.Close(); err != nil {
return err
}
return nil
}

View File

@ -48,8 +48,8 @@ const (
FiletypeRelocatable Filetype = 0xFE // REL | ProDOS | EDASM relocatable object module file
FiletypeSystem Filetype = 0xFF // SYS | ProDOS | System file
FiletypeS Filetype = 0x100 // DOS 3.3 Type "S"
FiletypeA Filetype = 0x101 // DOS 3.3 Type "new A"
FiletypeB Filetype = 0x102 // DOS 3.3 Type "new B"
FiletypeNewA Filetype = 0x101 // DOS 3.3 Type "new A"
FiletypeNewB Filetype = 0x102 // DOS 3.3 Type "new B"
// | 0D-0E | SOS | SOS reserved for future use
// | 12-18 | SOS | SOS reserved for future use
// | 1C-BF | SOS | SOS reserved for future use
@ -64,52 +64,54 @@ type filetypeInfo struct {
OneLetter string // The one-letter abbreviation (DOS 3.x)
Desc string // The description of the type
Stringified string // (Generated) result of calling String() on the Constant
Extra bool // If true, exclude from normal display listing
}
// names of Filetype constants above
var filetypeInfos = []filetypeInfo{
{FiletypeTypeless, "Typeless", "", "", "Typeless file", ""},
{FiletypeBadBlocks, "BadBlocks", "", "", "Bad blocks file", ""},
{FiletypeSOSPascalCode, "SOSPascalCode", "", "", "PASCAL code file", ""},
{FiletypeSOSPascalText, "SOSPascalText", "", "", "PASCAL text file", ""},
{FiletypeASCIIText, "ASCIIText", "T", "TXT", "ASCII text file", ""},
{FiletypeSOSPascalText2, "SOSPascalText2", "", "", "PASCAL text file", ""},
{FiletypeBinary, "Binary", "B", "BIN", "Binary file", ""},
{FiletypeFont, "Font", "", "", "Font file", ""},
{FiletypeGraphicsScreen, "GraphicsScreen", "", "", "Graphics screen file", ""},
{FiletypeBusinessBASIC, "BusinessBASIC", "", "", "Business BASIC program file", ""},
{FiletypeBusinessBASICData, "BusinessBASICData", "", "", "Business BASIC data file", ""},
{FiletypeSOSWordProcessor, "SOSWordProcessor", "", "", "Word processor file", ""},
{FiletypeSOSSystem, "SOSSystem", "", "", "SOS system file", ""},
{FiletypeDirectory, "Directory", "", "DIR", "Directory file", ""},
{FiletypeRPSData, "RPSData", "", "", "RPS data file", ""},
{FiletypeRPSIndex, "RPSIndex", "", "", "RPS index file", ""},
{FiletypeAppleWorksDatabase, "AppleWorksDatabase", "", "ADB", "AppleWorks data base file", ""},
{FiletypeAppleWorksWordProcessor, "AppleWorksWordProcessor", "", "AWP", "AppleWorks word processing file", ""},
{FiletypeAppleWorksSpreadsheet, "AppleWorksSpreadsheet", "", "ASP", "AppleWorks spreadsheet file", ""},
{FiletypePascal, "Pascal", "", "PAS", "ProDOS PASCAL file", ""},
{FiletypeCommand, "Command", "", "CMD", "Added command file", ""},
{FiletypeUserDefinedF1, "UserDefinedF1", "", "", "ProDOS user defined file type F1", ""},
{FiletypeUserDefinedF2, "UserDefinedF2", "", "", "ProDOS user defined file type F2", ""},
{FiletypeUserDefinedF3, "UserDefinedF3", "", "", "ProDOS user defined file type F3", ""},
{FiletypeUserDefinedF4, "UserDefinedF4", "", "", "ProDOS user defined file type F4", ""},
{FiletypeUserDefinedF5, "UserDefinedF5", "", "", "ProDOS user defined file type F5", ""},
{FiletypeUserDefinedF6, "UserDefinedF6", "", "", "ProDOS user defined file type F6", ""},
{FiletypeUserDefinedF7, "UserDefinedF7", "", "", "ProDOS user defined file type F7", ""},
{FiletypeUserDefinedF8, "UserDefinedF8", "", "", "ProDOS user defined file type F8", ""},
{FiletypeIntegerBASIC, "IntegerBASIC", "I", "INT", "Integer BASIC program file", ""},
{FiletypeIntegerBASICVariables, "IntegerBASICVariables", "", "IVR", "Integer BASIC variables file", ""},
{FiletypeApplesoftBASIC, "ApplesoftBASIC", "A", "BAS", "Applesoft BASIC program file", ""},
{FiletypeApplesoftBASICVariables, "ApplesoftBASICVariables", "", "VAR", "Applesoft BASIC variables file", ""},
{FiletypeRelocatable, "Relocatable", "R", "REL", "EDASM relocatable object module file", ""},
{FiletypeSystem, "System", "", "SYS", "System file", ""},
{FiletypeS, "S", "S", "", `DOS 3.3 Type "S"`, ""},
{FiletypeA, "A", "A", "", `DOS 3.3 Type "new A"`, ""},
{FiletypeB, "B", "B", "", `DOS 3.3 Type "new B"`, ""},
{FiletypeTypeless, "Typeless", "", "", "Typeless file", "", false},
{FiletypeBadBlocks, "BadBlocks", "", "", "Bad blocks file", "", false},
{FiletypeSOSPascalCode, "SOSPascalCode", "", "", "PASCAL code file", "", true},
{FiletypeSOSPascalText, "SOSPascalText", "", "", "PASCAL text file", "", true},
{FiletypeASCIIText, "ASCIIText", "T", "TXT", "ASCII text file", "", false},
{FiletypeSOSPascalText2, "SOSPascalText2", "", "", "PASCAL text file", "", true},
{FiletypeBinary, "Binary", "B", "BIN", "Binary file", "", false},
{FiletypeFont, "Font", "", "", "Font file", "", true},
{FiletypeGraphicsScreen, "GraphicsScreen", "", "", "Graphics screen file", "", true},
{FiletypeBusinessBASIC, "BusinessBASIC", "", "", "Business BASIC program file", "", true},
{FiletypeBusinessBASICData, "BusinessBASICData", "", "", "Business BASIC data file", "", true},
{FiletypeSOSWordProcessor, "SOSWordProcessor", "", "", "Word processor file", "", true},
{FiletypeSOSSystem, "SOSSystem", "", "", "SOS system file", "", true},
{FiletypeDirectory, "Directory", "", "DIR", "Directory file", "", false},
{FiletypeRPSData, "RPSData", "", "", "RPS data file", "", true},
{FiletypeRPSIndex, "RPSIndex", "", "", "RPS index file", "", true},
{FiletypeAppleWorksDatabase, "AppleWorksDatabase", "", "ADB", "AppleWorks data base file", "", false},
{FiletypeAppleWorksWordProcessor, "AppleWorksWordProcessor", "", "AWP", "AppleWorks word processing file", "", false},
{FiletypeAppleWorksSpreadsheet, "AppleWorksSpreadsheet", "", "ASP", "AppleWorks spreadsheet file", "", false},
{FiletypePascal, "Pascal", "", "PAS", "ProDOS PASCAL file", "", false},
{FiletypeCommand, "Command", "", "CMD", "Added command file", "", false},
{FiletypeUserDefinedF1, "UserDefinedF1", "", "", "ProDOS user defined file type F1", "", true},
{FiletypeUserDefinedF2, "UserDefinedF2", "", "", "ProDOS user defined file type F2", "", true},
{FiletypeUserDefinedF3, "UserDefinedF3", "", "", "ProDOS user defined file type F3", "", true},
{FiletypeUserDefinedF4, "UserDefinedF4", "", "", "ProDOS user defined file type F4", "", true},
{FiletypeUserDefinedF5, "UserDefinedF5", "", "", "ProDOS user defined file type F5", "", true},
{FiletypeUserDefinedF6, "UserDefinedF6", "", "", "ProDOS user defined file type F6", "", true},
{FiletypeUserDefinedF7, "UserDefinedF7", "", "", "ProDOS user defined file type F7", "", true},
{FiletypeUserDefinedF8, "UserDefinedF8", "", "", "ProDOS user defined file type F8", "", true},
{FiletypeIntegerBASIC, "IntegerBASIC", "I", "INT", "Integer BASIC program file", "", false},
{FiletypeIntegerBASICVariables, "IntegerBASICVariables", "", "IVR", "Integer BASIC variables file", "", false},
{FiletypeApplesoftBASIC, "ApplesoftBASIC", "A", "BAS", "Applesoft BASIC program file", "", false},
{FiletypeApplesoftBASICVariables, "ApplesoftBASICVariables", "", "VAR", "Applesoft BASIC variables file", "", false},
{FiletypeRelocatable, "Relocatable", "R", "REL", "EDASM relocatable object module file", "", false},
{FiletypeSystem, "System", "", "SYS", "System file", "", false},
{FiletypeS, "S", "", "S", `DOS 3.3 Type "S"`, "", false},
{FiletypeNewA, "NewA", "", "A", `DOS 3.3 Type "new A"`, "", false},
{FiletypeNewB, "NewB", "", "B", `DOS 3.3 Type "new B"`, "", false},
}
var filetypeInfosMap map[Filetype]filetypeInfo
var filetypeNames []string
var filetypeNamesExtras []string
func init() {
sosReserved := []Filetype{0x0D, 0x0E, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}
@ -123,37 +125,46 @@ func init() {
for _, typ := range sosReserved {
info := filetypeInfo{
Type: typ,
Name: fmt.Sprintf("SOSReserved%02X", typ),
Name: fmt.Sprintf("SOSReserved%02X", int(typ)),
ThreeLetter: "",
OneLetter: "",
Desc: fmt.Sprintf("SOS reserved for future use %02X", typ),
Desc: fmt.Sprintf("SOS reserved for future use %02X", int(typ)),
Extra: true,
}
filetypeInfos = append(filetypeInfos, info)
}
for _, typ := range prodosReserved {
info := filetypeInfo{
Type: typ,
Name: fmt.Sprintf("ProDOSReserved%02X", typ),
Name: fmt.Sprintf("ProDOSReserved%02X", int(typ)),
ThreeLetter: "",
OneLetter: "",
Desc: fmt.Sprintf("ProDOS reserved for future use %02X", typ),
Desc: fmt.Sprintf("ProDOS reserved for future use %02X", int(typ)),
Extra: true,
}
filetypeInfos = append(filetypeInfos, info)
}
seen := map[string]bool{}
filetypeInfosMap = make(map[Filetype]filetypeInfo, len(filetypeInfos))
for i, info := range filetypeInfos {
info.Stringified = info.Desc + " (" + info.Name
if info.ThreeLetter != "" {
if info.ThreeLetter != "" && !seen[info.ThreeLetter] {
info.Stringified += "|" + info.ThreeLetter
seen[info.ThreeLetter] = true
}
if info.OneLetter != "" {
if info.OneLetter != "" && info.OneLetter != info.Name && !seen[info.OneLetter] {
info.Stringified += "|" + info.OneLetter
seen[info.OneLetter] = true
}
info.Stringified += ")"
filetypeInfos[i] = info
filetypeInfosMap[info.Type] = info
filetypeNames = append(filetypeNames, info.Stringified)
filetypeNamesExtras = append(filetypeNamesExtras, info.Stringified)
if !info.Extra {
filetypeNames = append(filetypeNames, info.Stringified)
}
}
}
@ -161,7 +172,7 @@ func (f Filetype) String() string {
if info, found := filetypeInfosMap[f]; found {
return info.Stringified
}
return fmt.Sprintf("Invalid/unknown filetype %02X", f)
return fmt.Sprintf("Invalid/unknown filetype %02X", int(f))
}
// FiletypeForName returns the filetype for a full, three-letter, or
@ -176,6 +187,9 @@ func FiletypeForName(name string) (Filetype, error) {
}
// FiletypeNames returns a list of all filetype names.
func FiletypeNames() []string {
func FiletypeNames(all bool) []string {
if all {
return filetypeNamesExtras
}
return filetypeNames
}

View File

@ -40,7 +40,7 @@ type Operator interface {
// PutFile writes a file by name. If the file exists and overwrite
// is false, it returns with an error. Otherwise it returns true if
// an existing file was overwritten.
PutFile(filename string, fileInfo FileInfo, overwrite bool) (existed bool, err error)
PutFile(fileInfo FileInfo, overwrite bool) (existed bool, err error)
}
// FileInfo represents a file descriptor plus the content.

View File

@ -374,9 +374,9 @@ func (fd FileDesc) descriptor() disk.Descriptor {
case FiletypeRelocatable: // RELOCATABLE object module file
desc.Type = disk.FiletypeRelocatable
case FiletypeA: // A type file
desc.Type = disk.FiletypeA
desc.Type = disk.FiletypeNewA
case FiletypeB: // B type file
desc.Type = disk.FiletypeB
desc.Type = disk.FiletypeNewB
}
return desc
}
@ -660,7 +660,7 @@ func (o operator) Delete(filename string) (bool, error) {
// PutFile writes a file by name. If the file exists and overwrite
// is false, it returns with an error. Otherwise it returns true if
// an existing file was overwritten.
func (o operator) PutFile(filename string, fileInfo disk.FileInfo, overwrite bool) (existed bool, err error) {
func (o operator) PutFile(fileInfo disk.FileInfo, overwrite bool) (existed bool, err error) {
return false, fmt.Errorf("%s does not implement PutFile yet", operatorName)
}

View File

@ -662,7 +662,7 @@ func (o operator) Delete(filename string) (bool, error) {
// PutFile writes a file by name. If the file exists and overwrite
// is false, it returns with an error. Otherwise it returns true if
// an existing file was overwritten.
func (o operator) PutFile(filename string, fileInfo disk.FileInfo, overwrite bool) (existed bool, err error) {
func (o operator) PutFile(fileInfo disk.FileInfo, overwrite bool) (existed bool, err error) {
if fileInfo.Descriptor.Type != disk.FiletypeBinary {
return false, fmt.Errorf("%s: only binary file type supported", operatorName)
}
@ -670,7 +670,7 @@ func (o operator) PutFile(filename string, fileInfo disk.FileInfo, overwrite boo
return false, fmt.Errorf("mismatch between FileInfo.Descriptor.Length (%d) and actual length of FileInfo.Data field (%d)", fileInfo.Descriptor.Length, len(fileInfo.Data))
}
numFile, namedFile, symbol, err := o.st.FilesForCompoundName(filename)
numFile, namedFile, symbol, err := o.st.FilesForCompoundName(fileInfo.Descriptor.Name)
if err != nil {
return false, err
}