mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2024-06-15 19:17:34 -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
|
||||
// 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
|
||||
// environment, usually by pressing ctrl-c)
|
||||
|
|
|
@ -18,7 +18,7 @@ func (dsm *Disassembly) flowDisassembly(mc *cpu.CPU) error {
|
|||
return err
|
||||
}
|
||||
|
||||
switch err.(errors.AtariError).Errno {
|
||||
switch err.(errors.AtariError).Head {
|
||||
case errors.ProgramCounterCycled:
|
||||
// originally, a cycled program counter caused the
|
||||
// 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"
|
||||
)
|
||||
|
||||
// Errno is used specified the specific error
|
||||
type Errno int
|
||||
|
||||
// Values is the type used to specify arguments for FormattedErrors
|
||||
type Values []interface{}
|
||||
|
||||
// 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.
|
||||
type AtariError struct {
|
||||
Errno Errno
|
||||
Head string
|
||||
Values Values
|
||||
}
|
||||
|
||||
// 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{
|
||||
Errno: errno,
|
||||
Head: head,
|
||||
Values: values,
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +26,7 @@ func New(errno Errno, values ...interface{}) AtariError {
|
|||
// Error returns the normalised error message. Most usefully, it compresses
|
||||
// duplicate adjacent AtariError instances.
|
||||
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
|
||||
p := strings.SplitN(s, ": ", 3)
|
||||
|
@ -40,16 +37,17 @@ func (er AtariError) Error() string {
|
|||
return strings.Join(p, ": ")
|
||||
}
|
||||
|
||||
// Is checks if most recently wrapped error is an AtariError with a specific errno
|
||||
func Is(err error, errno Errno) bool {
|
||||
// Is checks if most recently wrapped error is an AtariError with a specific
|
||||
// head
|
||||
func Is(err error, head string) bool {
|
||||
switch er := err.(type) {
|
||||
case AtariError:
|
||||
return er.Errno == errno
|
||||
return er.Head == head
|
||||
}
|
||||
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 {
|
||||
switch err.(type) {
|
||||
case AtariError:
|
||||
|
@ -58,16 +56,16 @@ func IsAny(err error) bool {
|
|||
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
|
||||
func Has(err error, errno Errno) bool {
|
||||
if Is(err, errno) {
|
||||
func Has(err error, head string) bool {
|
||||
if Is(err, head) {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := range err.(AtariError).Values {
|
||||
if e, ok := err.(AtariError).Values[i].(error); ok {
|
||||
if Has(e, errno) {
|
||||
if Has(e, head) {
|
||||
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
|
||||
|
||||
var messages = map[Errno]string{
|
||||
// error messages
|
||||
const (
|
||||
// panics
|
||||
PanicError: "panic: %v: %v",
|
||||
PanicError = "panic: %v: %v"
|
||||
|
||||
// sentinals
|
||||
UserInterrupt: "user interrupt",
|
||||
UserSuspend: "user suspend",
|
||||
ScriptEnd: "end of script (%v)",
|
||||
PowerOff: "emulated machine has been powered off",
|
||||
InputDeviceUnplugged: "controller unplugged from %v",
|
||||
TVOutOfSpec: "tv out of spec: %v",
|
||||
UserInterrupt = "user interrupt"
|
||||
UserSuspend = "user suspend"
|
||||
ScriptEnd = "end of script (%v)"
|
||||
PowerOff = "emulated machine has been powered off"
|
||||
InputDeviceUnplugged = "controller unplugged from %v"
|
||||
TVOutOfSpec = "tv out of spec: %v"
|
||||
|
||||
// program modes
|
||||
PlayError: "error emulating vcs: %v",
|
||||
DebuggerError: "error debugging vcs: %v",
|
||||
PerformanceError: "error during performance profiling: %v",
|
||||
DisassemblyError: "error debugging disassembly: %v",
|
||||
PlayError = "error emulating vcs: %v"
|
||||
DebuggerError = "error debugging vcs: %v"
|
||||
PerformanceError = "error during performance profiling: %v"
|
||||
DisassemblyError = "error debugging disassembly: %v"
|
||||
|
||||
// debugger
|
||||
ParserError: "parser error: %v: %v (char %d)", // first placeholder is the command definition
|
||||
ValidationError: "%v for %v",
|
||||
InvalidTarget: "invalid target (%v)",
|
||||
CommandError: "%v",
|
||||
TerminalError: "%v",
|
||||
GUIEventError: "%v",
|
||||
ReflectionNotRunning: "reflection process is not running",
|
||||
ParserError = "parser error: %v: %v (char %d)" // first placeholder is the command definition
|
||||
ValidationError = "%v for %v"
|
||||
InvalidTarget = "invalid target (%v)"
|
||||
CommandError = "%v"
|
||||
TerminalError = "%v"
|
||||
GUIEventError = "%v"
|
||||
ReflectionNotRunning = "reflection process is not running"
|
||||
|
||||
// dissassembly
|
||||
DisasmError: "disassembly error: %v",
|
||||
DisasmError = "disassembly error: %v"
|
||||
|
||||
// script
|
||||
ScriptFileError: "script error: %v",
|
||||
ScriptFileUnavailable: "script error: cannot open script file (%v)",
|
||||
ScriptRunError: "script error: use of '%v' is not allowed in scripts [%v::%d]",
|
||||
ScriptScribeError: "script scribe error: %v",
|
||||
ScriptFileError = "script error: %v"
|
||||
ScriptFileUnavailable = "script error: cannot open script file (%v)"
|
||||
ScriptRunError = "script error: use of '%v' is not allowed in scripts [%v::%d]"
|
||||
ScriptScribeError = "script scribe error: %v"
|
||||
|
||||
// recorder
|
||||
RecordingError: "controller recording error: %v",
|
||||
PlaybackError: "controller playback error: %v",
|
||||
PlaybackHashError: "controller playback error: hash error: %v",
|
||||
RecordingError = "controller recording error: %v"
|
||||
PlaybackError = "controller playback error: %v"
|
||||
PlaybackHashError = "controller playback error: hash error: %v"
|
||||
|
||||
// database
|
||||
DatabaseError: "database error: %v",
|
||||
DatabaseReadError: "datbase error: %v [line %d]",
|
||||
DatabaseSelectEmpty: "database error: no selected entries",
|
||||
DatabaseKeyError: "database error: no such key in database [%v]",
|
||||
DatabaseFileUnavailable: "database error: cannot open database (%v)",
|
||||
DatabaseError = "database error: %v"
|
||||
DatabaseReadError = "datbase error: %v [line %d]"
|
||||
DatabaseSelectEmpty = "database error: no selected entries"
|
||||
DatabaseKeyError = "database error: no such key in database [%v]"
|
||||
DatabaseFileUnavailable = "database error: cannot open database (%v)"
|
||||
|
||||
// regression
|
||||
RegressionError: "regression test error: %v",
|
||||
RegressionDigestError: "digest entry: %v",
|
||||
RegressionPlaybackError: "playback entry: %v",
|
||||
RegressionError = "regression test error: %v"
|
||||
RegressionDigestError = "digest entry: %v"
|
||||
RegressionPlaybackError = "playback entry: %v"
|
||||
|
||||
// setup
|
||||
SetupError: "setup error: %v",
|
||||
SetupPanelError: "setup error: panel entry: %v",
|
||||
SetupError = "setup error: %v"
|
||||
SetupPanelError = "setup error: panel entry: %v"
|
||||
|
||||
// symbols
|
||||
SymbolsFileError: "symbols error: error processing symbols file: %v",
|
||||
SymbolsFileUnavailable: "symbols error: no symbols file for %v",
|
||||
SymbolUnknown: "symbols error: unrecognised symbol (%v)",
|
||||
SymbolsFileError = "symbols error: error processing symbols file: %v"
|
||||
SymbolsFileUnavailable = "symbols error: no symbols file for %v"
|
||||
SymbolUnknown = "symbols error: unrecognised symbol (%v)"
|
||||
|
||||
// cartridgeloader
|
||||
CartridgeLoader: "cartridge loading error: %v",
|
||||
CartridgeLoader = "cartridge loading error: %v"
|
||||
|
||||
// vcs
|
||||
VCSError: "vcs error: %v",
|
||||
PolycounterError: "polycounter error: %v",
|
||||
VCSError = "vcs error: %v"
|
||||
PolycounterError = "polycounter error: %v"
|
||||
|
||||
// cpu
|
||||
UnimplementedInstruction: "cpu error: unimplemented instruction (%#02x) at (%#04x)",
|
||||
InvalidResult: "cpu error: %v",
|
||||
ProgramCounterCycled: "cpu error: program counter cycled back to 0x0000",
|
||||
InvalidOperationMidInstruction: "cpu error: invalid operation mid-instruction (%v)",
|
||||
UnimplementedInstruction = "cpu error: unimplemented instruction (%#02x) at (%#04x)"
|
||||
InvalidResult = "cpu error: %v"
|
||||
ProgramCounterCycled = "cpu error: program counter cycled back to 0x0000"
|
||||
InvalidOperationMidInstruction = "cpu error: invalid operation mid-instruction (%v)"
|
||||
|
||||
// memory
|
||||
MemoryError: "memory error: %v",
|
||||
UnreadableAddress: "memory error: memory location is not readable (%#04x)",
|
||||
UnwritableAddress: "memory error: memory location is not writable (%#04x)",
|
||||
UnpokeableAddress: "memory error: cannot poke address (%v)",
|
||||
UnpeekableAddress: "memory error: cannot peek address (%v)",
|
||||
MemoryError = "memory error: %v"
|
||||
UnreadableAddress = "memory error: memory location is not readable (%#04x)"
|
||||
UnwritableAddress = "memory error: memory location is not writable (%#04x)"
|
||||
UnpokeableAddress = "memory error: cannot poke address (%v)"
|
||||
UnpeekableAddress = "memory error: cannot peek address (%v)"
|
||||
|
||||
// cartridges
|
||||
CartridgeError: "cartridge error: %v",
|
||||
CartridgeEjected: "cartridge error: no cartridge attached",
|
||||
CartridgeError = "cartridge error: %v"
|
||||
CartridgeEjected = "cartridge error: no cartridge attached"
|
||||
|
||||
// input
|
||||
InputDeviceUnavailable: "input error: controller hardware unavailable (%v)",
|
||||
UnknownInputEvent: "input error: %v: unsupported event (%v)",
|
||||
InputDeviceUnavailable = "input error: controller hardware unavailable (%v)"
|
||||
UnknownInputEvent = "input error: %v: unsupported event (%v)"
|
||||
|
||||
// television
|
||||
UnknownTVRequest: "television error: unsupported request (%v)",
|
||||
Television: "television error: %v",
|
||||
UnknownTVRequest = "television error: unsupported request (%v)"
|
||||
Television = "television error: %v"
|
||||
|
||||
// digests
|
||||
VideoDigest: "video digest: %v",
|
||||
AudioDigest: "audio digest: %v",
|
||||
VideoDigest = "video digest: %v"
|
||||
AudioDigest = "audio digest: %v"
|
||||
|
||||
// audio2wav
|
||||
WavWriter: "wav writer: %v",
|
||||
WavWriter = "wav writer: %v"
|
||||
|
||||
// gui
|
||||
UnsupportedGUIRequest: "gui error: unsupported request (%v)",
|
||||
SDL: "SDL: %v",
|
||||
}
|
||||
UnsupportedGUIRequest = "gui error: unsupported request (%v)"
|
||||
SDL = "SDL: %v"
|
||||
)
|
||||
|
|
|
@ -576,7 +576,7 @@ func testStrictAddressing(t *testing.T, mc *cpu.CPU, mem *mockMem) {
|
|||
if err == nil {
|
||||
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
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
|
||||
switch err.(errors.AtariError).Errno {
|
||||
switch err.(errors.AtariError).Head {
|
||||
// the PowerOff error is expected. if we receive it then that means
|
||||
// the regression test has succeeded
|
||||
case errors.PowerOff:
|
||||
|
|
Loading…
Reference in a new issue