/* Copyright 1996 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* File: messages.c * Purpose: accessing an Object modules messages file (inc error reporting) * Author: Timothy Roddis * History: 24-Jan-94: IDJ: created from original TGR sources */ #include #include #include #include #include "kernel.h" #include "swis.h" #include "const.h" #include "macros.h" #include "objects.toolbox.h" #include "services.h" #include "debug.h" #include "mem.h" #include "twimp.h" #include "style.h" #include "messages.h" static int messages_fd[4]; /* the messages file descriptor */ static _kernel_oserror global_error_block={0,0}; /* ------------------------------------ raising errors ---------------------------------------- */ extern _kernel_oserror *make_error (int err_num, int num_args, ...) { /* * Generate a RISC OS error block. */ va_list ap; char *s, token [4]; int i=4; _kernel_oserror *e; _kernel_swi_regs regs = {0,0,0,0,0,0,0,0}; global_error_block.errnum = err_num; num_args = (num_args>4)?4:num_args; for (va_start (ap, num_args); num_args--; i++) { s = va_arg (ap, char *); regs.r[i] = (int) ((s && *s) ? s : NULL); /* copy (pointer to args)s into registers */ } sprintf (token, "E%02x", err_num&0x3f); DEBUG debug_output ("error", "make_error: looking for %s\n", token); regs.r[0] = (int) messages_fd; regs.r[1] = (int) token; regs.r[2] = (int) global_error_block.errmess; regs.r[3] = sizeof global_error_block - sizeof global_error_block.errnum; /* 252! */ e = _kernel_swi (MessageTrans_Lookup, ®s, ®s); /* Hope this doesn't return an error */ DEBUG { if (e != NULL) debug_output ("error", "make_error: msgtrans error (%s)\n", e->errmess); } va_end (ap); return &global_error_block; } extern _kernel_oserror *make_error_hex (int err_num, int num_args, ...) { /* * Generate a RISC OS error block, with integer params printed in hex. */ va_list ap; char arg[4][11] = { "\0","\0","\0","\0" }; int i, n; num_args = (num_args>4)?4:num_args; va_start (ap, num_args); for (i=0; i4)?4:num_args; for (va_start (ap, num_args); num_args--; i++) { s = va_arg (ap, char *); regs.r[i] = (int) ((s && *s) ? s : NULL); /* copy (pointer to args)s into registers */ } regs.r[0] = (int) messages_fd; regs.r[1] = (int) token; regs.r[2] = (int) error_block.errmess; regs.r[3] = sizeof global_error_block - sizeof global_error_block.errnum; /* 252! */ e = _kernel_swi (MessageTrans_Lookup, ®s, ®s); /* Hope this doesn't return an error */ error_block.hdr.event_code = Toolbox_Error; regs.r[0] = 0; regs.r[1] = (int) object_id; regs.r[2] = component_id; regs.r[3] = (int) &error_block; e = _kernel_swi (Toolbox_RaiseToolboxEvent, ®s, ®s); va_end (ap); } extern void raise_toolbox_error_hex (int err_num, ObjectID object_id, ComponentID component_id, int num_args, ...) { /* * Raise a Toolbox_Error event, with integer parameters printed in hex */ va_list ap; char arg[4][11] = { "\0","\0","\0","\0" }; int i=0, n; num_args = (num_args>4)?4:num_args; va_start (ap, num_args); for (i=0; ierrnum; strcpy (error_block.errmess, e->errmess); error_block.hdr.event_code = Toolbox_Error; error_block.hdr.size = 256-20-sizeof(ToolboxEventHeader)-sizeof(ObjectID)-sizeof(ComponentID); regs.r[0] = 0; regs.r[1] = (int) object_id; regs.r[2] = component_id; regs.r[3] = (int) &error_block; e = _kernel_swi (Toolbox_RaiseToolboxEvent, ®s, ®s); } /* --------------------------------------- message file handling ------------------------------ */ extern _kernel_oserror *messages_file_open (char *messages_filename) { return _swix(MessageTrans_OpenFile, _INR(0,2), messages_fd, messages_filename, 0 /* use RMA */); } extern _kernel_oserror *messages_file_close (void) { return _swix (MessageTrans_CloseFile, _IN(0), messages_fd); } extern _kernel_oserror *messages_file_lookup (char *token, char *buffer, int *buffer_size, int num_args, ...) { va_list ap; char *s; int i = 4; _kernel_oserror *e = NULL; _kernel_swi_regs regs = {0,0,0,0,0,0,0,0}; num_args = (num_args>4)?4:num_args; for (va_start (ap, num_args); num_args--; i++) { s = va_arg (ap, char *); regs.r[i] = (int) ((s && *s) ? s : NULL); /* copy (pointer to args)s into registers */ } regs.r[0] = (int) messages_fd; regs.r[1] = (int) token; regs.r[2] = (int) buffer; regs.r[3] = (buffer && buffer_size)?*buffer_size:0; e = _kernel_swi (MessageTrans_Lookup, ®s, ®s); /* Hope this doesn't return an error */ if (buffer == NULL && buffer_size != NULL) *buffer_size = regs.r[3]+1; /* add one to allow for terminator */ va_end (ap); return e; }