Files
TerminalBasic/crates/tb-runtime/src/errors.rs

241 lines
10 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Laufzeitfehler: Codes und Meldungstexte kompatibel zum Vorbild.
//!
//! Die Codes und (englischen) Meldungstexte entsprechen dem Katalog des
//! Vorbilds (Original-Hilfe, Topic „Run-Time Error Codes"): klassische
//! Codes 176 (QB-Erbe), 8089 (ISAM), 260480 (Forms). Programme prüfen
//! `ERR` gegen diese Nummern, daher sind sie Teil des Kompatibilitäts-
//! vertrags. Nicht belegte Nummern liefern "Unprintable error" (wie im
//! Vorbild bei `ERROR n`); Nummer 105 ist im Vorbild intern reserviert.
/// Ein Laufzeitfehler des Dialekts, identifiziert durch seinen klassischen Code.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RuntimeError(pub u16);
impl RuntimeError {
pub const NEXT_WITHOUT_FOR: Self = Self(1);
pub const SYNTAX_ERROR: Self = Self(2);
pub const RETURN_WITHOUT_GOSUB: Self = Self(3);
pub const OUT_OF_DATA: Self = Self(4);
pub const ILLEGAL_FUNCTION_CALL: Self = Self(5);
pub const OVERFLOW: Self = Self(6);
pub const OUT_OF_MEMORY: Self = Self(7);
pub const LABEL_NOT_DEFINED: Self = Self(8);
pub const SUBSCRIPT_OUT_OF_RANGE: Self = Self(9);
pub const DUPLICATE_DEFINITION: Self = Self(10);
pub const DIVISION_BY_ZERO: Self = Self(11);
pub const ILLEGAL_IN_DIRECT_MODE: Self = Self(12);
pub const TYPE_MISMATCH: Self = Self(13);
pub const OUT_OF_STRING_SPACE: Self = Self(14);
pub const STRING_TOO_COMPLEX: Self = Self(16);
pub const CANNOT_CONTINUE: Self = Self(17);
pub const FUNCTION_NOT_DEFINED: Self = Self(18);
pub const NO_RESUME: Self = Self(19);
pub const RESUME_WITHOUT_ERROR: Self = Self(20);
pub const DEVICE_TIMEOUT: Self = Self(24);
pub const DEVICE_FAULT: Self = Self(25);
pub const FOR_WITHOUT_NEXT: Self = Self(26);
pub const OUT_OF_PAPER: Self = Self(27);
pub const WHILE_WITHOUT_WEND: Self = Self(29);
pub const WEND_WITHOUT_WHILE: Self = Self(30);
pub const DUPLICATE_LABEL: Self = Self(33);
pub const SUBPROGRAM_NOT_DEFINED: Self = Self(35);
pub const ARGUMENT_COUNT_MISMATCH: Self = Self(37);
pub const ARRAY_NOT_DEFINED: Self = Self(38);
pub const VARIABLE_REQUIRED: Self = Self(40);
pub const FIELD_OVERFLOW: Self = Self(50);
pub const INTERNAL_ERROR: Self = Self(51);
pub const BAD_FILE_NAME_OR_NUMBER: Self = Self(52);
pub const FILE_NOT_FOUND: Self = Self(53);
pub const BAD_FILE_MODE: Self = Self(54);
pub const FILE_ALREADY_OPEN: Self = Self(55);
pub const FIELD_STATEMENT_ACTIVE: Self = Self(56);
pub const DEVICE_IO_ERROR: Self = Self(57);
pub const FILE_ALREADY_EXISTS: Self = Self(58);
pub const BAD_RECORD_LENGTH: Self = Self(59);
pub const DISK_FULL: Self = Self(61);
pub const INPUT_PAST_END_OF_FILE: Self = Self(62);
pub const BAD_RECORD_NUMBER: Self = Self(63);
pub const BAD_FILE_NAME: Self = Self(64);
pub const TOO_MANY_FILES: Self = Self(67);
pub const DEVICE_UNAVAILABLE: Self = Self(68);
pub const COMM_BUFFER_OVERFLOW: Self = Self(69);
pub const PERMISSION_DENIED: Self = Self(70);
pub const DISK_NOT_READY: Self = Self(71);
pub const DISK_MEDIA_ERROR: Self = Self(72);
pub const FEATURE_UNAVAILABLE: Self = Self(73);
pub const RENAME_ACROSS_DISKS: Self = Self(74);
pub const PATH_FILE_ACCESS_ERROR: Self = Self(75);
pub const PATH_NOT_FOUND: Self = Self(76);
// Forms-Fehler (Auswahl mit benannten Konstanten; vollständige Texte in message()):
pub const INVALID_SCREEN_MODE: Self = Self(271);
pub const INVALID_WHEN_FORMS_SHOWING: Self = Self(272);
pub const INVALID_PROPERTY_VALUE: Self = Self(380);
pub const DESIGN_TIME_CONTROL: Self = Self(362);
pub const FORM_ALREADY_DISPLAYED: Self = Self(400);
pub const NON_MODAL_WHILE_MODAL: Self = Self(401);
pub const MODAL_NOT_TOPMOST: Self = Self(402);
pub const MDI_FORM_MODAL: Self = Self(403);
pub const NO_ACTIVE_CONTROL: Self = Self(430);
pub const NO_ACTIVE_FORM: Self = Self(431);
/// Klassischer Fehlercode für `ERR`.
pub fn code(self) -> u16 {
self.0
}
/// Meldungstext des Vorbilds; unbelegte Codes: "Unprintable error".
pub fn message(self) -> &'static str {
match self.0 {
1 => "NEXT without FOR",
2 => "Syntax error",
3 => "RETURN without GOSUB",
4 => "Out of DATA",
5 => "Illegal function call",
6 => "Overflow",
7 => "Out of memory",
8 => "Label not defined",
9 => "Subscript out of range",
10 => "Duplicate definition",
11 => "Division by zero",
12 => "Illegal in direct mode",
13 => "Type mismatch",
14 => "Out of string space",
16 => "String formula too complex",
17 => "Cannot continue",
18 => "Function not defined",
19 => "No RESUME",
20 => "RESUME without error",
24 => "Device timeout",
25 => "Device fault",
26 => "FOR without NEXT",
27 => "Out of paper",
29 => "WHILE without WEND",
30 => "WEND without WHILE",
33 => "Duplicate label",
35 => "Subprogram not defined",
37 => "Argument-count mismatch",
38 => "Array not defined",
40 => "Variable required",
50 => "FIELD overflow",
51 => "Internal error",
52 => "Bad file name or number",
53 => "File not found",
54 => "Bad file mode",
55 => "File already open",
56 => "FIELD statement active",
57 => "Device I/O error",
58 => "File already exists",
59 => "Bad record length",
61 => "Disk full",
62 => "Input past end of file",
63 => "Bad record number",
64 => "Bad file name",
67 => "Too many files",
68 => "Device unavailable",
69 => "Communication-buffer overflow",
70 => "Permission denied",
71 => "Disk not ready",
72 => "Disk-media error",
73 => "Feature unavailable",
74 => "Can't rename with different drive",
75 => "Path/File access error",
76 => "Path not found",
// ISAM (PDS-Erbe) — Terminal Basic implementiert ISAM nicht,
// die Codes/Texte gehören aber zum Kompatibilitätsvertrag.
80 => "Feature removed",
81 => "ISAM - Invalid name",
82 => "ISAM - Table not found",
83 => "ISAM - Index not found",
84 => "ISAM - Invalid column",
85 => "ISAM - No current record",
86 => "ISAM - Duplicate value for unique index",
87 => "ISAM - Invalid operation on NULL index",
88 => "ISAM - Database inconsistent",
89 => "ISAM - Insufficient ISAM buffers",
// Forms-Fehler des Vorbilds
260 => "No timer available",
271 => "Invalid screen mode",
272 => "Invalid when forms are showing",
340 => "Control array element does not exist",
341 => "Invalid object array index",
342 => "Not enough room to allocate control array",
343 => "Object not an array",
344 => "Must specify index for object array",
345 => "Reached limit: cannot create any more controls for this form",
360 => "Object already loaded",
361 => "Can't load or unload this object",
362 => "Can't unload controls created at design time",
363 => "Custom control not found",
364 => "Object was unloaded",
365 => "Unable to unload within this context",
380 => "Invalid property value",
381 => "Invalid property array index",
382 => "Property can't be set at run time",
383 => "Property is read-only",
384 => "Property can't be modified when form is minimized or maximized",
385 => "Must specify index when using property array",
386 => "Property not available at run time",
387 => "Property can't be set on this control",
400 => "Form already displayed; can't show form modally",
401 => "Can't show non-modal form when a modal form is being displayed",
402 => "Must close or hide topmost modal form first",
403 => "MDI form cannot be shown modally",
410 => "Property can't be modified on MDI form",
420 => "Invalid object reference",
421 => "Method not applicable for this object",
422 => "Property not found",
423 => "Property or control not found",
424 => "Object required",
425 => "Invalid object use",
430 => "No currently active control",
431 => "No currently active form",
480 => "Can't create AutoRedraw image",
_ => "Unprintable error",
}
}
}
impl std::fmt::Display for RuntimeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message())
}
}
impl std::error::Error for RuntimeError {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bekannte_codes() {
assert_eq!(RuntimeError::OVERFLOW.code(), 6);
assert_eq!(RuntimeError::OVERFLOW.message(), "Overflow");
assert_eq!(RuntimeError::SUBSCRIPT_OUT_OF_RANGE.code(), 9);
assert_eq!(RuntimeError::FILE_NOT_FOUND.message(), "File not found");
assert_eq!(RuntimeError::FEATURE_UNAVAILABLE.code(), 73);
}
#[test]
fn forms_und_isam_codes() {
assert_eq!(RuntimeError(80).message(), "Feature removed");
assert_eq!(
RuntimeError::INVALID_WHEN_FORMS_SHOWING.message(),
"Invalid when forms are showing"
);
assert_eq!(RuntimeError::NO_ACTIVE_FORM.code(), 431);
assert_eq!(
RuntimeError(403).message(),
"MDI form cannot be shown modally"
);
}
#[test]
fn unbelegte_codes_sind_unprintable() {
assert_eq!(RuntimeError(15).message(), "Unprintable error");
assert_eq!(RuntimeError(105).message(), "Unprintable error"); // intern reserviert
assert_eq!(RuntimeError(200).message(), "Unprintable error");
assert_eq!(RuntimeError(500).message(), "Unprintable error");
}
}