mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2024-06-22 22:42:25 -04:00
o errors
- removed ErrorID, using the error message as the ID - works just as well and simplifies maintenance - the messages should be moved to the relevant packages OR to a locale package. not sure which yet.
This commit is contained in:
parent
bdb4fe6a83
commit
d7cdfcfe61
|
@ -164,7 +164,7 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, videoCycle bool) error {
|
||||||
|
|
||||||
// we now know the we have an Atari Error so we can safely
|
// we now know the we have an Atari Error so we can safely
|
||||||
// switch on the internal Errno
|
// switch on the internal Errno
|
||||||
switch err.(errors.AtariError).Errno {
|
switch err.(errors.AtariError).Head {
|
||||||
|
|
||||||
// user interrupts are triggered by the user (in a terminal
|
// user interrupts are triggered by the user (in a terminal
|
||||||
// environment, usually by pressing ctrl-c)
|
// environment, usually by pressing ctrl-c)
|
||||||
|
|
|
@ -18,7 +18,7 @@ func (dsm *Disassembly) flowDisassembly(mc *cpu.CPU) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch err.(errors.AtariError).Errno {
|
switch err.(errors.AtariError).Head {
|
||||||
case errors.ProgramCounterCycled:
|
case errors.ProgramCounterCycled:
|
||||||
// originally, a cycled program counter caused the
|
// originally, a cycled program counter caused the
|
||||||
// disassembly to end but thinking about it a bit more,
|
// disassembly to end but thinking about it a bit more,
|
||||||
|
|
|
@ -1,120 +0,0 @@
|
||||||
package errors
|
|
||||||
|
|
||||||
// list of error numbers
|
|
||||||
const (
|
|
||||||
// PanicErrors should be used only as an alternative to panic(). that is
|
|
||||||
// errors where there is no good response beyond suggesting that a terrible
|
|
||||||
// mistake has been made. PanicErrors should be treated like actual
|
|
||||||
// panic()s and cause the program (or the sub-system) to cease as soon as
|
|
||||||
// possible.
|
|
||||||
//
|
|
||||||
// if is not practical to cause the program to cease then at the very
|
|
||||||
// least, the PanicError should result in the display of the error message
|
|
||||||
// in big, friendly letters.
|
|
||||||
//
|
|
||||||
// actual panic()s should only be used when the mistake is so heinous that
|
|
||||||
// it suggests a fundamental misunderstanding has taken place and so, as it
|
|
||||||
// were, all bets are off.
|
|
||||||
PanicError Errno = iota
|
|
||||||
|
|
||||||
// sentinal
|
|
||||||
UserInterrupt
|
|
||||||
UserSuspend
|
|
||||||
ScriptEnd
|
|
||||||
PowerOff
|
|
||||||
InputDeviceUnplugged
|
|
||||||
TVOutOfSpec
|
|
||||||
|
|
||||||
// program modes
|
|
||||||
PlayError
|
|
||||||
DebuggerError
|
|
||||||
PerformanceError
|
|
||||||
DisassemblyError
|
|
||||||
|
|
||||||
// debugger
|
|
||||||
ParserError
|
|
||||||
ValidationError
|
|
||||||
InvalidTarget
|
|
||||||
CommandError
|
|
||||||
TerminalError
|
|
||||||
GUIEventError
|
|
||||||
ReflectionNotRunning
|
|
||||||
|
|
||||||
// disassembly
|
|
||||||
DisasmError
|
|
||||||
|
|
||||||
// script
|
|
||||||
ScriptScribeError
|
|
||||||
ScriptFileUnavailable
|
|
||||||
ScriptFileError
|
|
||||||
ScriptRunError
|
|
||||||
|
|
||||||
// recorder
|
|
||||||
RecordingError
|
|
||||||
PlaybackError
|
|
||||||
PlaybackHashError
|
|
||||||
|
|
||||||
// database
|
|
||||||
DatabaseError
|
|
||||||
DatabaseReadError
|
|
||||||
DatabaseSelectEmpty
|
|
||||||
DatabaseKeyError
|
|
||||||
DatabaseFileUnavailable
|
|
||||||
|
|
||||||
// regression
|
|
||||||
RegressionError
|
|
||||||
RegressionDigestError
|
|
||||||
RegressionPlaybackError
|
|
||||||
|
|
||||||
// setup
|
|
||||||
SetupError
|
|
||||||
SetupPanelError
|
|
||||||
|
|
||||||
// symbols
|
|
||||||
SymbolsFileUnavailable
|
|
||||||
SymbolsFileError
|
|
||||||
SymbolUnknown
|
|
||||||
|
|
||||||
// cartridgeloader
|
|
||||||
CartridgeLoader
|
|
||||||
|
|
||||||
// vcs
|
|
||||||
VCSError
|
|
||||||
PolycounterError
|
|
||||||
|
|
||||||
// cpu
|
|
||||||
UnimplementedInstruction
|
|
||||||
InvalidResult
|
|
||||||
ProgramCounterCycled
|
|
||||||
InvalidOperationMidInstruction
|
|
||||||
|
|
||||||
// memory
|
|
||||||
MemoryError
|
|
||||||
UnreadableAddress
|
|
||||||
UnwritableAddress
|
|
||||||
UnpokeableAddress
|
|
||||||
UnpeekableAddress
|
|
||||||
|
|
||||||
// cartridges
|
|
||||||
CartridgeError
|
|
||||||
CartridgeEjected
|
|
||||||
|
|
||||||
// input
|
|
||||||
InputDeviceUnavailable
|
|
||||||
UnknownInputEvent
|
|
||||||
|
|
||||||
// tv
|
|
||||||
UnknownTVRequest
|
|
||||||
Television
|
|
||||||
|
|
||||||
// digests
|
|
||||||
VideoDigest
|
|
||||||
AudioDigest
|
|
||||||
|
|
||||||
// wavwriter
|
|
||||||
WavWriter
|
|
||||||
|
|
||||||
// gui
|
|
||||||
UnsupportedGUIRequest
|
|
||||||
SDL
|
|
||||||
)
|
|
|
@ -5,23 +5,20 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Errno is used specified the specific error
|
|
||||||
type Errno int
|
|
||||||
|
|
||||||
// Values is the type used to specify arguments for FormattedErrors
|
// Values is the type used to specify arguments for FormattedErrors
|
||||||
type Values []interface{}
|
type Values []interface{}
|
||||||
|
|
||||||
// AtariError allows code to specify a predefined error and not worry too much about the
|
// AtariError allows code to specify a predefined error and not worry too much about the
|
||||||
// message behind that error and how the message will be formatted on output.
|
// message behind that error and how the message will be formatted on output.
|
||||||
type AtariError struct {
|
type AtariError struct {
|
||||||
Errno Errno
|
Head string
|
||||||
Values Values
|
Values Values
|
||||||
}
|
}
|
||||||
|
|
||||||
// New is used to create a new instance of an AtariError.
|
// New is used to create a new instance of an AtariError.
|
||||||
func New(errno Errno, values ...interface{}) AtariError {
|
func New(head string, values ...interface{}) AtariError {
|
||||||
return AtariError{
|
return AtariError{
|
||||||
Errno: errno,
|
Head: head,
|
||||||
Values: values,
|
Values: values,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +26,7 @@ func New(errno Errno, values ...interface{}) AtariError {
|
||||||
// Error returns the normalised error message. Most usefully, it compresses
|
// Error returns the normalised error message. Most usefully, it compresses
|
||||||
// duplicate adjacent AtariError instances.
|
// duplicate adjacent AtariError instances.
|
||||||
func (er AtariError) Error() string {
|
func (er AtariError) Error() string {
|
||||||
s := fmt.Sprintf(messages[er.Errno], er.Values...)
|
s := fmt.Sprintf(er.Head, er.Values...)
|
||||||
|
|
||||||
// de-duplicate error message parts
|
// de-duplicate error message parts
|
||||||
p := strings.SplitN(s, ": ", 3)
|
p := strings.SplitN(s, ": ", 3)
|
||||||
|
@ -40,16 +37,17 @@ func (er AtariError) Error() string {
|
||||||
return strings.Join(p, ": ")
|
return strings.Join(p, ": ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is checks if most recently wrapped error is an AtariError with a specific errno
|
// Is checks if most recently wrapped error is an AtariError with a specific
|
||||||
func Is(err error, errno Errno) bool {
|
// head
|
||||||
|
func Is(err error, head string) bool {
|
||||||
switch er := err.(type) {
|
switch er := err.(type) {
|
||||||
case AtariError:
|
case AtariError:
|
||||||
return er.Errno == errno
|
return er.Head == head
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAny checks if most recently wrapped error is an AtariError, with any errno
|
// IsAny checks if most recently wrapped error is an AtariError, with any head
|
||||||
func IsAny(err error) bool {
|
func IsAny(err error) bool {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case AtariError:
|
case AtariError:
|
||||||
|
@ -58,16 +56,16 @@ func IsAny(err error) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has checks to see if the specified AtariError errno appears somewhere in the
|
// Has checks to see if the specified AtariError head appears somewhere in the
|
||||||
// sequence of wrapped errors
|
// sequence of wrapped errors
|
||||||
func Has(err error, errno Errno) bool {
|
func Has(err error, head string) bool {
|
||||||
if Is(err, errno) {
|
if Is(err, head) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range err.(AtariError).Values {
|
for i := range err.(AtariError).Values {
|
||||||
if e, ok := err.(AtariError).Values[i].(error); ok {
|
if e, ok := err.(AtariError).Values[i].(error); ok {
|
||||||
if Has(e, errno) {
|
if Has(e, head) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
errors/errors_test.go
Normal file
22
errors/errors_test.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package errors_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"gopher2600/errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestError(t *testing.T) {
|
||||||
|
e := errors.New(errors.SetupError, "foo")
|
||||||
|
if e.Error() != "setup error: foo" {
|
||||||
|
t.Errorf("unexpected error message")
|
||||||
|
}
|
||||||
|
|
||||||
|
// packing errors of the same type next to each other causes
|
||||||
|
// one of them to be dropped
|
||||||
|
f := errors.New(errors.SetupError, e)
|
||||||
|
fmt.Println(f.Error())
|
||||||
|
if f.Error() != "setup error: foo" {
|
||||||
|
t.Errorf("unexpected duplicate error message")
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,107 +1,108 @@
|
||||||
package errors
|
package errors
|
||||||
|
|
||||||
var messages = map[Errno]string{
|
// error messages
|
||||||
|
const (
|
||||||
// panics
|
// panics
|
||||||
PanicError: "panic: %v: %v",
|
PanicError = "panic: %v: %v"
|
||||||
|
|
||||||
// sentinals
|
// sentinals
|
||||||
UserInterrupt: "user interrupt",
|
UserInterrupt = "user interrupt"
|
||||||
UserSuspend: "user suspend",
|
UserSuspend = "user suspend"
|
||||||
ScriptEnd: "end of script (%v)",
|
ScriptEnd = "end of script (%v)"
|
||||||
PowerOff: "emulated machine has been powered off",
|
PowerOff = "emulated machine has been powered off"
|
||||||
InputDeviceUnplugged: "controller unplugged from %v",
|
InputDeviceUnplugged = "controller unplugged from %v"
|
||||||
TVOutOfSpec: "tv out of spec: %v",
|
TVOutOfSpec = "tv out of spec: %v"
|
||||||
|
|
||||||
// program modes
|
// program modes
|
||||||
PlayError: "error emulating vcs: %v",
|
PlayError = "error emulating vcs: %v"
|
||||||
DebuggerError: "error debugging vcs: %v",
|
DebuggerError = "error debugging vcs: %v"
|
||||||
PerformanceError: "error during performance profiling: %v",
|
PerformanceError = "error during performance profiling: %v"
|
||||||
DisassemblyError: "error debugging disassembly: %v",
|
DisassemblyError = "error debugging disassembly: %v"
|
||||||
|
|
||||||
// debugger
|
// debugger
|
||||||
ParserError: "parser error: %v: %v (char %d)", // first placeholder is the command definition
|
ParserError = "parser error: %v: %v (char %d)" // first placeholder is the command definition
|
||||||
ValidationError: "%v for %v",
|
ValidationError = "%v for %v"
|
||||||
InvalidTarget: "invalid target (%v)",
|
InvalidTarget = "invalid target (%v)"
|
||||||
CommandError: "%v",
|
CommandError = "%v"
|
||||||
TerminalError: "%v",
|
TerminalError = "%v"
|
||||||
GUIEventError: "%v",
|
GUIEventError = "%v"
|
||||||
ReflectionNotRunning: "reflection process is not running",
|
ReflectionNotRunning = "reflection process is not running"
|
||||||
|
|
||||||
// dissassembly
|
// dissassembly
|
||||||
DisasmError: "disassembly error: %v",
|
DisasmError = "disassembly error: %v"
|
||||||
|
|
||||||
// script
|
// script
|
||||||
ScriptFileError: "script error: %v",
|
ScriptFileError = "script error: %v"
|
||||||
ScriptFileUnavailable: "script error: cannot open script file (%v)",
|
ScriptFileUnavailable = "script error: cannot open script file (%v)"
|
||||||
ScriptRunError: "script error: use of '%v' is not allowed in scripts [%v::%d]",
|
ScriptRunError = "script error: use of '%v' is not allowed in scripts [%v::%d]"
|
||||||
ScriptScribeError: "script scribe error: %v",
|
ScriptScribeError = "script scribe error: %v"
|
||||||
|
|
||||||
// recorder
|
// recorder
|
||||||
RecordingError: "controller recording error: %v",
|
RecordingError = "controller recording error: %v"
|
||||||
PlaybackError: "controller playback error: %v",
|
PlaybackError = "controller playback error: %v"
|
||||||
PlaybackHashError: "controller playback error: hash error: %v",
|
PlaybackHashError = "controller playback error: hash error: %v"
|
||||||
|
|
||||||
// database
|
// database
|
||||||
DatabaseError: "database error: %v",
|
DatabaseError = "database error: %v"
|
||||||
DatabaseReadError: "datbase error: %v [line %d]",
|
DatabaseReadError = "datbase error: %v [line %d]"
|
||||||
DatabaseSelectEmpty: "database error: no selected entries",
|
DatabaseSelectEmpty = "database error: no selected entries"
|
||||||
DatabaseKeyError: "database error: no such key in database [%v]",
|
DatabaseKeyError = "database error: no such key in database [%v]"
|
||||||
DatabaseFileUnavailable: "database error: cannot open database (%v)",
|
DatabaseFileUnavailable = "database error: cannot open database (%v)"
|
||||||
|
|
||||||
// regression
|
// regression
|
||||||
RegressionError: "regression test error: %v",
|
RegressionError = "regression test error: %v"
|
||||||
RegressionDigestError: "digest entry: %v",
|
RegressionDigestError = "digest entry: %v"
|
||||||
RegressionPlaybackError: "playback entry: %v",
|
RegressionPlaybackError = "playback entry: %v"
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
SetupError: "setup error: %v",
|
SetupError = "setup error: %v"
|
||||||
SetupPanelError: "setup error: panel entry: %v",
|
SetupPanelError = "setup error: panel entry: %v"
|
||||||
|
|
||||||
// symbols
|
// symbols
|
||||||
SymbolsFileError: "symbols error: error processing symbols file: %v",
|
SymbolsFileError = "symbols error: error processing symbols file: %v"
|
||||||
SymbolsFileUnavailable: "symbols error: no symbols file for %v",
|
SymbolsFileUnavailable = "symbols error: no symbols file for %v"
|
||||||
SymbolUnknown: "symbols error: unrecognised symbol (%v)",
|
SymbolUnknown = "symbols error: unrecognised symbol (%v)"
|
||||||
|
|
||||||
// cartridgeloader
|
// cartridgeloader
|
||||||
CartridgeLoader: "cartridge loading error: %v",
|
CartridgeLoader = "cartridge loading error: %v"
|
||||||
|
|
||||||
// vcs
|
// vcs
|
||||||
VCSError: "vcs error: %v",
|
VCSError = "vcs error: %v"
|
||||||
PolycounterError: "polycounter error: %v",
|
PolycounterError = "polycounter error: %v"
|
||||||
|
|
||||||
// cpu
|
// cpu
|
||||||
UnimplementedInstruction: "cpu error: unimplemented instruction (%#02x) at (%#04x)",
|
UnimplementedInstruction = "cpu error: unimplemented instruction (%#02x) at (%#04x)"
|
||||||
InvalidResult: "cpu error: %v",
|
InvalidResult = "cpu error: %v"
|
||||||
ProgramCounterCycled: "cpu error: program counter cycled back to 0x0000",
|
ProgramCounterCycled = "cpu error: program counter cycled back to 0x0000"
|
||||||
InvalidOperationMidInstruction: "cpu error: invalid operation mid-instruction (%v)",
|
InvalidOperationMidInstruction = "cpu error: invalid operation mid-instruction (%v)"
|
||||||
|
|
||||||
// memory
|
// memory
|
||||||
MemoryError: "memory error: %v",
|
MemoryError = "memory error: %v"
|
||||||
UnreadableAddress: "memory error: memory location is not readable (%#04x)",
|
UnreadableAddress = "memory error: memory location is not readable (%#04x)"
|
||||||
UnwritableAddress: "memory error: memory location is not writable (%#04x)",
|
UnwritableAddress = "memory error: memory location is not writable (%#04x)"
|
||||||
UnpokeableAddress: "memory error: cannot poke address (%v)",
|
UnpokeableAddress = "memory error: cannot poke address (%v)"
|
||||||
UnpeekableAddress: "memory error: cannot peek address (%v)",
|
UnpeekableAddress = "memory error: cannot peek address (%v)"
|
||||||
|
|
||||||
// cartridges
|
// cartridges
|
||||||
CartridgeError: "cartridge error: %v",
|
CartridgeError = "cartridge error: %v"
|
||||||
CartridgeEjected: "cartridge error: no cartridge attached",
|
CartridgeEjected = "cartridge error: no cartridge attached"
|
||||||
|
|
||||||
// input
|
// input
|
||||||
InputDeviceUnavailable: "input error: controller hardware unavailable (%v)",
|
InputDeviceUnavailable = "input error: controller hardware unavailable (%v)"
|
||||||
UnknownInputEvent: "input error: %v: unsupported event (%v)",
|
UnknownInputEvent = "input error: %v: unsupported event (%v)"
|
||||||
|
|
||||||
// television
|
// television
|
||||||
UnknownTVRequest: "television error: unsupported request (%v)",
|
UnknownTVRequest = "television error: unsupported request (%v)"
|
||||||
Television: "television error: %v",
|
Television = "television error: %v"
|
||||||
|
|
||||||
// digests
|
// digests
|
||||||
VideoDigest: "video digest: %v",
|
VideoDigest = "video digest: %v"
|
||||||
AudioDigest: "audio digest: %v",
|
AudioDigest = "audio digest: %v"
|
||||||
|
|
||||||
// audio2wav
|
// audio2wav
|
||||||
WavWriter: "wav writer: %v",
|
WavWriter = "wav writer: %v"
|
||||||
|
|
||||||
// gui
|
// gui
|
||||||
UnsupportedGUIRequest: "gui error: unsupported request (%v)",
|
UnsupportedGUIRequest = "gui error: unsupported request (%v)"
|
||||||
SDL: "SDL: %v",
|
SDL = "SDL: %v"
|
||||||
}
|
)
|
||||||
|
|
|
@ -576,7 +576,7 @@ func testStrictAddressing(t *testing.T, mc *cpu.CPU, mem *mockMem) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("not recieved an UnreadableAddress error when we should")
|
t.Fatalf("not recieved an UnreadableAddress error when we should")
|
||||||
}
|
}
|
||||||
if err.(errors.AtariError).Errno == errors.UnreadableAddress {
|
if err.(errors.AtariError).Head == errors.UnreadableAddress {
|
||||||
// this is okay
|
// this is okay
|
||||||
} else {
|
} else {
|
||||||
t.Fatalf("error during CPU step (%v)\n", err)
|
t.Fatalf("error during CPU step (%v)\n", err)
|
||||||
|
|
0
patch/doc.go
Normal file
0
patch/doc.go
Normal file
0
patch/patch.go
Normal file
0
patch/patch.go
Normal file
|
@ -148,7 +148,7 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
|
||||||
return false, "", errors.New(errors.RegressionPlaybackError, err)
|
return false, "", errors.New(errors.RegressionPlaybackError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch err.(errors.AtariError).Errno {
|
switch err.(errors.AtariError).Head {
|
||||||
// the PowerOff error is expected. if we receive it then that means
|
// the PowerOff error is expected. if we receive it then that means
|
||||||
// the regression test has succeeded
|
// the regression test has succeeded
|
||||||
case errors.PowerOff:
|
case errors.PowerOff:
|
||||||
|
|
Loading…
Reference in a new issue