Update of /cvsroot/ro-oslib/OSLib/!OsLib/Tools/support In directory sc8-pr-cvs1:/tmp/cvs-serv28678/!OsLib/Tools/support Added Files: Tag: unix-build callback.c callback.h hostfs.h lookup.c lookup.h m.c m.h realloc.c realloc.h resource.c resource.h riscos.c riscos.h riscosa.s trace.c trace.h unix.c unix.h x.c x.h Log Message: Unix Build --- NEW FILE: callback.c --- /*callback.c - dynamically extensible multi-way, multi-level switch facility*/ /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ /* First implementation: hold callbacks in a tree structure reflecting their structure. Note: since all callbacks are called back with non-null |unclaimed| pointer, and this is initialised to TRUE, you never need to assign TRUE to |unclaimed|. You can assign FALSE to it without checking for nullness, too. */ /*From CLib*/ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> /*From OSLib*/ #include "oslib/types.h" /*From Support*/ #include "callback.h" #include "m.h" #include "riscos.h" #include "trace.h" #ifdef TRACE /*#define XTRACE*/ #endif /* Useful types needed by |callback_| Type Fn == (the type of a callback function); Type SH == (the type of the static handle); Type DH == (the type of the dynamic handle) Type Level == List [Fn × SH] × List [Int × Level]; implemented in C via Type Function == List [Fn × SH]; Type Entry == List [Int × Level]; (where List [T] == Opt [T × List [T]]) */ struct callback_l {struct Level *root;}; typedef struct Function { callback_fn *fn; void *sh; struct Function *next; } *Function; typedef struct Entry { int key; struct Level *level; struct Entry *next; } *Entry; typedef struct Level { struct Function *fns; struct Entry *list; } *Level; #if TRACE /*------------------------------------------------------------------------*/ /*The name of a function.*/ static char *Function_Name ( callback_fn *fn ) { char *name = (char *) fn - 4; static char Fn [80 + 1]; if (name [3] == 0xFF) riscos_strncpy (Fn, name - *name, 80); else sprintf (Fn, "(unnamed at 0x%X)" _ (unsigned) fn); return Fn; } #endif /*------------------------------------------------------------------------*/ os_error *callback_new ( callback_l *l_out ) { callback_l l; os_error *error = NULL; tracef ("callback_new\n"); if ((l = m_ALLOC (sizeof *l)) == NULL) { error = riscos_error_lookup (os_GLOBAL_NO_MEM, "NoMem"); goto finish; } l->root = NULL; if (l_out != NULL) *l_out = l; finish: return error; } /*------------------------------------------------------------------------*/ static void Delete_Function ( Function f ) { if (f != NULL) { #ifdef XTRACE tracef ("Delete_Function\n"); #endif Delete_Function (f->next); m_FREE (f, sizeof *f); } } /*------------------------------------------------------------------------*/ static void Delete_Level (Level); /*------------------------------------------------------------------------*/ void Delete_Entry ( Entry e ) { if (e != NULL) { #ifdef XTRACE tracef ("Delete_Entry\n"); #endif Delete_Level (e->level); Delete_Entry (e->next); m_FREE (e, sizeof *e); } } /*------------------------------------------------------------------------*/ void Delete_Level ( Level level ) { if (level != NULL) { #ifdef XTRACE tracef ("Delete_Level\n"); #endif Delete_Function (level->fns); Delete_Entry (level->list); m_FREE (level, sizeof *level); } } /*------------------------------------------------------------------------*/ os_error *callback_delete ( callback_l l ) { tracef ("callback_delete\n"); if (l != NULL) { Delete_Level (l->root); m_FREE (l, sizeof *l); } return NULL; } /*------------------------------------------------------------------------*/ static os_error *Callback ( void *dh, Level level, osbool *unclaimed, int limit, int *k ) { Function f; osbool u = TRUE; os_error *error = NULL; #ifdef XTRACE { int i; tracef ("Callback: dh 0x%X, level 0x%X, limit %d, key {" _ dh _ level _ limit); for (i = 0; i < limit; i++) trace_f (NULL _ 0 _ "%s%d" _ i == 0? "": ", " _ k [i]); trace_f (NULL _ 0 _ "} ...\n"); } #endif if (level != NULL) { if (limit > 0) { /*Try to match this key.*/ Entry e; /*It's important that we process the deepest ones first, as they are the most specialised for their purpose (all in a highly abstract sense ...).*/ for (e = level->list; e != NULL; e = e->next) if (e->key == *k) { if ((error = Callback (dh, e->level, &u, limit - 1, k + 1)) != NULL) goto finish; if (!u) break; } } if (u) /*Reached the end of the line - call all the functions until one handles the keys.*/ for (f = level->fns; f != NULL; f = f->next) { tracef ("callback %s (0x%X, 0x%X, 0x%X)\n" _ Function_Name (f->fn) _ f->sh _ dh _ &u); if ((error = (*f->fn) (f->sh, dh, &u)) != NULL) goto finish; tracef ("callback %s\n" _ u? "unclaimed": "claimed"); if (!u) break; } } if (!u) *unclaimed = FALSE; finish: return error; } /*------------------------------------------------------------------------*/ os_error *callback ( callback_l l, void *dh, osbool *unclaimed, int limit, ... ) { /*Makes the non-portable assumption that the arguments after |limit| are on the stack in order of increasing address.*/ osbool u = TRUE; os_error *error = NULL; tracef ("callback ...\n"); if ((error = Callback (dh, l->root, &u, limit, &limit + 1)) != NULL) goto finish; if (unclaimed != NULL) *unclaimed = u; finish: return error; } /*------------------------------------------------------------------------*/ os_error *callback_register ( callback_l l, callback_fn *fn, void *sh, int limit, ... ) { /*Makes the non-portable assumption that the arguments after |limit| are on the stack in order of increasing address.*/ Level *level; int i, *k = &limit + 1; os_error *error = NULL; tracef ("callback_register\n"); /*Descend the hierarchy, creating new |Level|'s if necessary.*/ level = &l->root; for (i = 0; i < limit; i++) { Entry e; osbool found = FALSE; if (*level == NULL) { /*Need a new one for this level. First create the new |Level|.*/ Level t; if ((t = m_ALLOC (sizeof *t)) == NULL) { error = riscos_error_lookup (os_GLOBAL_NO_MEM, "NoMem"); goto finish; } t->fns = NULL; t->list = NULL; *level = t; } /*Now look along the current level for the given key. This won't take long if the level was just created.*/ for (e = (*level)->list; e != NULL; e = e->next) if (e->key == k [i]) { found = TRUE; break; } if (!found) { /*Must create a new entry for this key.*/ if ((e = m_ALLOC (sizeof *e)) == NULL) { error = riscos_error_lookup (os_GLOBAL_NO_MEM, "NoMem"); goto finish; } e->key = k [i]; e->level = NULL; e->next = (*level)->list; (*level)->list = e; } level = &e->level; } if (*level == NULL) { /*Need a new one here too.*/ Level t; if ((t = m_ALLOC (sizeof *t)) == NULL) { error = riscos_error_lookup (os_GLOBAL_NO_MEM, "NoMem"); goto finish; } t->fns = NULL; t->list = NULL; *level = t; } /*Append the new function to the function list for |level|.*/ #if 1 /*this adds it at the end*/ { Function *f; for (f = &(*level)->fns; *f != NULL; f = &(*f)->next) ; if ((*f = m_ALLOC (sizeof **f)) == NULL) { error = riscos_error_lookup (os_GLOBAL_NO_MEM, "NoMem"); goto finish; } (*f)->fn = fn; (*f)->sh = sh; (*f)->next = NULL; } #else /*this adds it at the beginning*/ { Function f; if ((f = m_ALLOC (sizeof *f)) == NULL) { error = riscos_error_lookup (os_GLOBAL_NO_MEM, "NoMem"); goto finish; } f->fn = fn; f->sh = sh; f->next = (*level)->fns; (*level)->fns = f; } #endif finish: return error; } /*------------------------------------------------------------------------*/ static void Deregister_Level (Level *l, void *sh), Deregister_Entry (Entry *e, void *sh); /*------------------------------------------------------------------------*/ static void Deregister_Function ( Function *ff, void *sh ) { Function f = *ff; if (f != NULL) { #ifdef XTRACE tracef ("Deregister_Function\n"); #endif Deregister_Function (&f->next, sh); if (f->sh == sh) { *ff = f->next; m_FREE (f, sizeof *f); } } } /*------------------------------------------------------------------------*/ void Deregister_Entry (Entry *ee, void *sh) { Entry e = *ee; if (e != NULL) { #ifdef XTRACE tracef ("Deregister_Entry\n"); #endif Deregister_Level (&e->level, sh); Deregister_Entry (&e->next, sh); if (e->level == NULL) { *ee = e->next; m_FREE (e, sizeof *e); } } } /*------------------------------------------------------------------------*/ void Deregister_Level ( Level *ll, void *sh ) { Level l = *ll; if (l != NULL) { #ifdef XTRACE tracef ("Deregister_Level\n"); #endif Deregister_Function (&l->fns, sh); Deregister_Entry (&l->list, sh); if (l->fns == NULL && l->list == NULL) { *ll = NULL; m_FREE (l, sizeof *l); } } } /*------------------------------------------------------------------------*/ os_error *callback_deregister ( callback_l l, void *sh, int limit, ... ) { /*Makes the non-portable assumption that the arguments after |limit| are on the stack in order of increasing address.*/ /*No error is flagged if the given (fn, handle, keys) combination does not exist.*/ /*We only free the |Function|'s that record this callback, though it would be possible to free the |Level| that they depend on (provided that there were no sub-|Level|'s or other |Function|'s).*/ Level *ll; Entry *ee = NULL; int i, *k = &limit + 1; os_error *error = NULL; tracef ("callback_deregister\n"); /*Descend the hierarchy.*/ ll = &l->root; for (i = 0; i < limit && *ll != NULL; i++) { /*Look along the current level for the given key.*/ for (ee = &(*ll)->list; *ee != NULL; ee = &(*ee)->next) if ((*ee)->key == k [i]) break; if (*ee == NULL) goto finish; ll = &(*ee)->level; } Deregister_Level (ll, sh); if (*ll == NULL && ee != NULL) { /*We've just killed the level of a certain entry, so we should remove it too.*/ Entry e = *ee; *ee = e->next; m_FREE (e, sizeof *e); } finish: return error; } /*------------------------------------------------------------------------*/ #if TRACE static void Trace_Level (Level, int); void Trace_Entry ( Entry entry, int indent ) { if (entry != NULL) { trace_f (NULL _ 0 _ "%*s%d:\n" _ indent _ "" _ entry->key); Trace_Level (entry->level, indent + 3); Trace_Entry (entry->next, indent); } } /*------------------------------------------------------------------------*/ static void Trace_Function ( Function fns, int indent ) { Function f; osbool first = TRUE; for (f = fns; f != NULL; f = f->next) { if (first) { trace_f (NULL _ 0 _ "%*sFunctions:" _ indent _ ""); first = FALSE; } else trace_f (NULL _ 0 _ ", "); trace_f (NULL _ 0 _ " %s (0x%X,)" _ Function_Name (f->fn) _ f->sh); } if (first) trace_f (NULL _ 0 _ "%*sNo functions" _ indent _ ""); trace_f (NULL _ 0 _ "\n"); } /*------------------------------------------------------------------------*/ void Trace_Level ( Level level, int indent ) { if (level != NULL) { Trace_Function (level->fns, indent); Trace_Entry (level->list, indent); } } /*------------------------------------------------------------------------*/ void callback_trace ( callback_l l ) { tracef ("callback_trace\n"); if (l != NULL) Trace_Level (l->root, 0); } #endif --- NEW FILE: callback.h --- #ifndef callback_H #define callback_H /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ /* Changed by J R C 16th Aug 1994 to return |os_error *|. TV 20000503 |bool| replaced by |osbool| */ #if !defined types_H #include "oslib/types.h" #endif #ifndef os_H #include "oslib/os.h" #endif #ifndef trace_H #include "trace.h" #endif /* The type of a callback function. */ typedef os_error *callback_fn (void *, void *, osbool *); /* The type of a callback list. */ typedef struct callback_l *callback_l; /* Function to create a new, empty callback list. */ extern os_error *callback_new (callback_l *); /* Function to delete a callback list. */ extern os_error *callback_delete (callback_l); /* Function to make all the callbacks registered in a given list for * the given key values. * * callback_l the callback list to be scanned * void * a handle to be passed to the functions called * int the number of key values to be matched * ... the keys themselves * * Every function registered in the callback list with the given key * values will be called, and passed the given handle, until * one is claimed. */ extern os_error *callback (callback_l, void *, osbool *, int, ...); /* Function to register a new callback function. * * callback_l the callback list to be extended * callback_fn * the function to call * void * a handle to be passed to the function when it is called * int the number of key values provided * ... a list of integer key values * * The function and handle will be registered in the callback list. */ extern os_error *callback_register (callback_l, callback_fn *, void *, int, ...); /* Function to deregister a callback function. The callback list is * scanned for a single match to the (function, handle) pair at the given * key values, and it is deleted. */ extern os_error *callback_deregister (callback_l, void *, int, ...); #if TRACE extern void callback_trace (callback_l); #else #define callback_trace(l) SKIP #endif #endif --- NEW FILE: hostfs.h --- #ifndef hostfs_H #define hostfs_H /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ #ifndef types_H #include "oslib/types.h" #endif #ifndef os_H #include "oslib/os.h" #endif /********************************** * SWI names and SWI reason codes * **********************************/ #undef HostFS_HostVdu #define HostFS_HostVdu 0x40100 #undef XHostFS_HostVdu #define XHostFS_HostVdu 0x60100 #undef HostFS_TubeVdu #define HostFS_TubeVdu 0x40101 #undef XHostFS_TubeVdu #define XHostFS_TubeVdu 0x60101 #undef HostFS_WriteC #define HostFS_WriteC 0x40102 #undef XHostFS_WriteC #define XHostFS_WriteC 0x60102 /************************* * Function declarations * *************************/ #ifdef __cplusplus extern "C" { #endif /* ------------------------------------------------------------------------ * Function: hostfs_host_vdu() * * Description: Calls SWI 0x40100 */ extern os_error *xhostfs_host_vdu (void); __swi (0x40100) void hostfs_host_vdu (void); /* ------------------------------------------------------------------------ * Function: hostfs_tube_vdu() * * Description: Calls SWI 0x40101 */ extern os_error *xhostfs_tube_vdu (void); __swi (0x40101) void hostfs_tube_vdu (void); /* ------------------------------------------------------------------------ * Function: hostfs_writec() * * Description: Calls SWI 0x40102 * * Input: c - value of R0 on entry */ extern os_error *xhostfs_writec (char c); __swi (0x40102) void hostfs_writec (char c); #ifdef __cplusplus } #endif #endif --- NEW FILE: lookup.c --- (This appears to be a binary file; contents omitted.) --- NEW FILE: lookup.h --- #ifndef lookup_H #define lookup_H /*lookup.h - simple lookup facilities*/ /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ #ifndef os_H #include "oslib/os.h" #endif /* Implement ation of an abstract lookup table consisting of a token ** and a pointer to an associated data item */ typedef struct lookup_t *lookup_t; /* create a new abstract lookup table */ extern os_error *lookup_new( lookup_t *, /* updated with pointer to new table */ int /* initial size of table */ ); /* delete the entire table */ extern os_error *lookup_delete (lookup_t); /* search the table for a specific item */ extern os_error *lookup(lookup_t, /* pointer to table */ char *, /* token to match */ void ** /* pointer to destination for result: NULL if entry not found else pointer to data item */ ); /* add an entry to the table */ extern os_error *lookup_insert( lookup_t, /* table */ char *, /* pointer to token */ void * /* pointer to data item */ ); /* sequentially retrieve all tokens in the table */ extern os_error *lookup_enumerate( lookup_t, /* table */ char **, /* destination for pointer to token */ void **, /* destination for pointer to data item */ void ** /* context pointer; start with 0; ** updated to for each iteration ** 0 if no more found */ ); #endif --- NEW FILE: m.c --- (This appears to be a binary file; contents omitted.) --- NEW FILE: m.h --- #ifndef m_H #define m_H /*m.h - redirection for memory allocation functions*/ /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ /*From CLib*/ #include <stdlib.h> /*From Support*/ #ifndef realloc_H #include "realloc.h" #endif #ifndef trace_H #include "trace.h" #endif /*To use this module, you must call m_ALLOC, m_FREE, m_REALLOC in place of malloc, free, realloc at ALL PLACES in the programme. Then it is possible to change your allocation discipline by changing the values of these macros.*/ #if TRACE extern void *m_alloc (char *file, int line, int); extern void *m_calloc (char *file, int line, int, int); extern void m_free (char *file, int line, void *ptr, int size); extern void *m_realloc (char *file, int line, void *ptr, int old_size, int size); extern void m_summary (char *file, int line); extern void *m_validate_address (char *file, int line, void *ptr); #define m_ALLOC(size) \ m_alloc (__FILE__, __LINE__, size) #define m_CALLOC(count, size) \ m_calloc (__FILE__, __LINE__, count, size) #define m_FREE(ptr, size) \ m_free (__FILE__, __LINE__, ptr, size) #define m_REALLOC(ptr, old_size, size) \ m_realloc (__FILE__, __LINE__, ptr, old_size, size) #define m_SUMMARY() \ m_summary (__FILE__, __LINE__) #define m_VALIDATE_ADDRESS(ptr) \ m_validate_address (__FILE__, __LINE__, ptr) #else #define m_ALLOC(size) malloc (size) #define m_CALLOC(count, size) calloc (count, size) #define m_FREE(ptr, size) free (ptr) #define m_REALLOC(ptr, old_size, size) REALLOC (ptr, size) #define m_SUMMARY() SKIP #define m_VALIDATE_ADDRESS(ptr) ((void *) (ptr)) #endif #endif --- NEW FILE: realloc.c --- (This appears to be a binary file; contents omitted.) --- NEW FILE: realloc.h --- #ifndef realloc_H #define realloc_H /*realloc.c - portable realloc with no bugs!*/ /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ #include <stddef.h> extern void *REALLOC (void *ptr, size_t size); #endif --- NEW FILE: resource.c --- (This appears to be a binary file; contents omitted.) --- NEW FILE: resource.h --- #ifndef resource_H #define resource_H /*resource.h---generic handling of resources*/ /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ #ifndef os_H #include "oslib/os.h" #endif #ifndef wimp_H #include "oslib/wimp.h" #endif #ifndef lookup_H #include "lookup.h" #endif /* Types for the functions declared in this header. */ typedef os_error *resource_loader (lookup_t, char *); typedef os_error *resource_unloader (lookup_t); typedef struct resource_template { int data_size; char *data; wimp_window window; /*data lives here*/ } resource_template; /* Function to open a message file and copy it into memory if neccesary. All the tokens in the file are added to the lookup table: if the file was on disc, the lookup table will contain pointers into a block of heap memory, oherwise into the R M A or ROM. The message file is then closed, which means that MessageTrans_Lookup etc cannot be used. */ extern resource_loader resource_messages_alloc; /* Function to free the memory used by a messages resource. It is the client's responsibility to delete the lookup table. */ extern resource_unloader resource_messages_free; /* Function to open a sprite file and read it into memory if necessary, merging it with any sprite ares there may be from earlier calls to this function, using OSSpriteOp_MergeSpriteFile. All the sprite names in the merged file are inserted into the lookup table: the result of looking them up is a pointer to the OSSpriteOp_Header structure, ready to be passed to any OSSpriteOp SWI that requires one. */ extern resource_loader resource_sprites_alloc; /* Function to frees the memory used by this sprite resource. It is the client's responsibility to delete the lookup table. */ extern resource_unloader resource_sprites_free; /* Function to open a template file and read it into memory. Because of the way the WIMP works, a copy must be made even if the original is in memory already. Each template in the file is inserted into the lookup table, and stored in a block of malloc memory along with its indirected data. The result of looking up a name is a pointer to a structure containing the wimp_window and the indirected data. Resource_create_window() should be used to open the window. */ extern resource_loader resource_templates_alloc; /* Function to free the memory used by a template resource. It is the client's responsibility to delete the lookup table. */ extern resource_unloader resource_templates_free; extern os_error *resource_create_window (resource_template *, wimp_w *, char **); extern os_error *resource_delete_window (wimp_w, char *); extern os_error *resource_error_lookup (lookup_t, bits errnum, char *token, ...); extern os_error *resource_lookup (lookup_t, char *s, int n, char *token, ...); #endif --- NEW FILE: riscos.c --- (This appears to be a binary file; contents omitted.) --- NEW FILE: riscos.h --- #ifndef riscos_H #define riscos_H /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ /*From OSLib*/ #ifndef os_H #include "oslib/os.h" #endif #ifndef territory_H #include "oslib/territory.h" #endif /* Function to change the territory in use for |riscos_{scan/format}_fixed. */ extern os_error *riscos_territory (territory_t); /* Macro to provide an assertion facility using Wimp_ReportError. */ #define riscos_assert(c) \ (!(c)? riscos__assert (__FILE__, __LINE__, #c): (void) SKIP) /* Function to be used by |riscos_assert()| - not for external use. */ extern void riscos__assert (char *file, int line, char *msg); /* Function to return an |os_error *| from an error token in the global * messages file. */ extern os_error *riscos_error_lookup (int errnum, char *token, ...); /* Trivial functions to do things "the RISC O S way" rather than "the C * way." This means treating strings as control-char terminated, rather * than 0-terminated. These can be printed using a format of * "%.*s" and passing in the length of the string, as calculated by * |riscos_strlen|, as a argument to the printing function. Note that * riscos_strncpy() is not like strncpy(): it always terminates its output. */ extern int riscos_strlen (char *s); extern char *riscos_strcpy (char *s1, char *s); extern int riscos_strcmp (char *s0, char *s1); extern char *riscos_strncpy (char *s1, char *s, int n); /* Useful string processing functions, designed to allow safe in-line use * by taking a buffer argument, the pointer to which they return. */ extern char *riscos_format_dec (char *s, int i, int width, int prec); /*sprintf (s, "%*.*d", width, prec, i)*/ extern char *riscos_format_hex (char *s, int i, int width, int prec); /*sprintf (s, "%*.*X", width, prec, i)*/ extern char *riscos_format_char (char *s, char c); /*sprintf (s, "%c", c)*/ extern char *riscos_format_fixed (char *s, int mul, int div, int width, int prec); /*sprintf (s, "*.*f", width, prec, mul/div)*/ /* Functions to read back the items above - these return the number of * characters successfully read, 0 for error. */ extern int riscos_scan_dec (char *s, int *i_out); /*sscanf (s, "%d", i)*/ extern int riscos_scan_hex (char *s, int *i_out); /*sscanf (s, "%x", i)*/ extern int riscos_scan_fixed (char *s, int *mul_out, int div); /*sscanf (s, "%lf", mul), mul *= div*/ extern os_error *riscos_var_val_alloc (char *var, char **val); /*returns a new heap pointer to the value, or NULL if not found*/ extern int riscos_var_len (char *var, os_var_type); /*length of variable value, or -1 if not found*/ extern os_error *riscos_vdu (int vdu, ...); /*Performs a single V D U sequence, as follows.*/ /*riscos_vdu (os_VDU_CHAR_TO_PRINTER, c)*/ /*riscos_vdu (os_VDU_SET_TEXT_COLOUR, colour)*/ /*riscos_vdu (os_VDU_MODE, mode)*/ /*riscos_vdu (os_VDU_SET_GCOL, action, colour)*/ /*riscos_vdu (os_VDU_SET_TEXT_CURSOR, x, y)*/ /*riscos_vdu (os_VDU_SET_PALETTE, colour, mode, red, green, blue)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_INTERLACE, action, mode)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_CURSOR_MOVEMENT, eor_value, and_value)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_CURSOR, mode)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_ON, duration)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_OFF, duration)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_ECFx, ecf)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_DOT_STYLE, style)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_UNPACKED_ECFx, ecf)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SCROLL, extent, direction, movement)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_CLEAR_REGION, start, end, x0, y0, x1, y1)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_BBCEOF)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_TEXT_FG_TINT, tint)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_TEXT_FG_TINT, tint)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_TEXT_FG_TINT, tint)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_TEXT_FG_TINT, tint)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_ECF_INTERPRETATION, patterns)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_INVERT_TEXT)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_ECF_ORIGIN, x, y)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_CHAR_SIZE, flags, x, y)*/ /*riscos_vdu (os_VDU_MISC, c, definition)*/ /*riscos_vdu (os_VDU_SET_GRAPHICS_WINDOW, x0, y0, x1, y1)*/ /*riscos_vdu (os_VDU_PLOT, plot_type, x, y)*/ /*riscos_vdu (os_VDU_SET_TEXT_WINDOW, x0, y0, x1, y1)*/ /*riscos_vdu (os_VDU_SET_GRAPHICS_ORIGIN, x, y)*/ #endif --- NEW FILE: riscosa.s --- ;riscosa.asm - length of a variable ;written by Jonathan Coxhead, 15th Aug 1995 ;OSLib---efficient, type-safe, transparent, extensible, ; register-safe A P I coverage of RISC O S ;Copyright © 1994 Jonathan Coxhead ; ; OSLib is free software; you can redistribute it and/or modify ;it under the terms of the GNU General Public License as published by ;the Free Software Foundation; either version 1, or (at your option) ;any later version. ; ; OSLib is distributed in the hope that it will be useful, ;but WITHOUT ANY WARRANTY; without even the implied warranty of ;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ;along with this programme; if not, write to the Free Software ;Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. GET Hdr.OS EXPORT riscos_var_len AREA |C$$code|, CODE, READONLY riscos_var_len ROUT ;Entry R0 -> name of a variable ; R1 = variable type (os_VARTYPE_EXPANDED or 0) ;Exit R0 = length of variable value, or -1 if not found STMFD SP!, {R4, LR} MOV R4, R1 MOV R3, #0 MOV R2, #1 << 31 MOV R1, #Null SWI XOS_ReadVarVal ;Ignore error MVN R0, R2 [ {CONFIG}=26 LDMFD SP!, {R4, PC}^ | LDMFD SP!, {R4, PC} ] END --- NEW FILE: trace.c --- (This appears to be a binary file; contents omitted.) --- NEW FILE: trace.h --- #ifndef trace_H #define trace_H /*tracef.h*/ /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ #ifndef TRACE #define TRACE 0 #endif #ifndef os_H #include "oslib/os.h" #endif #if TRACE #define tracef(args) trace_f (__FILE__, __LINE__, args) #define tracevdu(s, n) trace_vdu (s, n) #define tracewait(t) trace_wait (__FILE__, __LINE__, t) #define trace_FINISH \ { trace_file = __FILE__; \ trace_line = __LINE__; \ goto finish; \ } #define trace_ASSIGN(e, f) \ { if (((e) = (f)) != NULL) \ { trace_file = __FILE__; \ trace_line = __LINE__; \ } } #define trace_RETURN(e) \ { if ((e) != NULL) \ trace_f (trace_file, trace_line, "<%s>\n", \ (e)->errmess); \ return e; \ } #define trace_ERROR(e) \ { if ((e) != NULL) \ trace_f (trace_file, trace_line, "<%s>\n", \ (e)->errmess); \ } extern os_error *trace_initialise (char *var); extern os_error *trace_terminate (void); extern void trace_f (char *file, int line, char *, ...); extern void trace_vdu (char *, int); extern void trace_wait (char *file, int line, int t); extern char *trace_file; extern int trace_line; #else #define tracef(args) #define tracevdu(args) #define tracewait(args) #define trace_initialise(var) #define trace_terminate() #define trace_f(args) #define trace_vdu(s, n) #define trace_wait(t) #define trace_FINISH {goto finish;} #define trace_ASSIGN(e,f) {(e) = (f);} #define trace_RETURN(e) {return e;} #define trace_ERROR(e) ; #endif #endif --- NEW FILE: unix.c --- (This appears to be a binary file; contents omitted.) --- NEW FILE: unix.h --- #ifndef unix_H #define unix_H /*OSLib---efficient, type-safe, transparent, extensible,\n" register-safe A P I coverage of RISC O S*/ /*Copyright © 1994 Jonathan Coxhead*/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ /*From OSLib*/ #ifndef os_H #include "oslib/os.h" #endif #ifndef territory_H #include "oslib/territory.h" #endif /* Function to change the territory in use for |riscos_{scan/format}_fixed. */ extern os_error *riscos_territory (territory_t); /* Macro to provide an assertion facility using Wimp_ReportError. */ #define riscos_assert(c) \ (!(c)? riscos__assert (__FILE__, __LINE__, #c): (void) SKIP) /* Function to be used by |riscos_assert()| - not for external use. */ extern void riscos__assert (char *file, int line, char *msg); /* Function to return an |os_error *| from an error token in the global * messages file. */ extern os_error *riscos_error_lookup (int errnum, char *token, ...); /* Trivial functions to do things "the RISC O S way" rather than "the C * way." This means treating strings as control-char terminated, rather * than 0-terminated. These can be printed using a format of * "%.*s" and passing in the length of the string, as calculated by * |riscos_strlen|, as a argument to the printing function. Note that * riscos_strncpy() is not like strncpy(): it always terminates its output. */ extern int riscos_strlen (char *s); extern char *riscos_strcpy (char *s1, char *s); extern int riscos_strcmp (char *s0, char *s1); extern char *riscos_strncpy (char *s1, char *s, int n); /* Useful string processing functions, designed to allow safe in-line use * by taking a buffer argument, the pointer to which they return. */ extern char *riscos_format_dec (char *s, int i, int width, int prec); /*sprintf (s, "%*.*d", width, prec, i)*/ extern char *riscos_format_hex (char *s, int i, int width, int prec); /*sprintf (s, "%*.*X", width, prec, i)*/ extern char *riscos_format_char (char *s, char c); /*sprintf (s, "%c", c)*/ extern char *riscos_format_fixed (char *s, int mul, int div, int width, int prec); /*sprintf (s, "*.*f", width, prec, mul/div)*/ /* Functions to read back the items above - these return the number of * characters successfully read, 0 for error. */ extern int riscos_scan_dec (char *s, int *i_out); /*sscanf (s, "%d", i)*/ extern int riscos_scan_hex (char *s, int *i_out); /*sscanf (s, "%x", i)*/ extern int riscos_scan_fixed (char *s, int *mul_out, int div); /*sscanf (s, "%lf", mul), mul *= div*/ extern os_error *riscos_var_val_alloc (char *var, char **val); /*returns a new heap pointer to the value, or NULL if not found*/ extern int riscos_var_len (char *var, os_var_type); /*length of variable value, or -1 if not found*/ extern os_error *riscos_vdu (int vdu, ...); /*Performs a single V D U sequence, as follows.*/ /*riscos_vdu (os_VDU_CHAR_TO_PRINTER, c)*/ /*riscos_vdu (os_VDU_SET_TEXT_COLOUR, colour)*/ /*riscos_vdu (os_VDU_MODE, mode)*/ /*riscos_vdu (os_VDU_SET_GCOL, action, colour)*/ /*riscos_vdu (os_VDU_SET_TEXT_CURSOR, x, y)*/ /*riscos_vdu (os_VDU_SET_PALETTE, colour, mode, red, green, blue)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_INTERLACE, action, mode)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_CURSOR_MOVEMENT, eor_value, and_value)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_CURSOR, mode)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_ON, duration)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_OFF, duration)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_ECFx, ecf)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_DOT_STYLE, style)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_UNPACKED_ECFx, ecf)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SCROLL, extent, direction, movement)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_CLEAR_REGION, start, end, x0, y0, x1, y1)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_SET_BBCEOF)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_TEXT_FG_TINT, tint)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_TEXT_FG_TINT, tint)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_TEXT_FG_TINT, tint)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_TEXT_FG_TINT, tint)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_ECF_INTERPRETATION, patterns)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_INVERT_TEXT)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_ECF_ORIGIN, x, y)*/ /*riscos_vdu (os_VDU_MISC, os_MISC_MISC, os_MISC_SET_CHAR_SIZE, flags, x, y)*/ /*riscos_vdu (os_VDU_MISC, c, definition)*/ /*riscos_vdu (os_VDU_SET_GRAPHICS_WINDOW, x0, y0, x1, y1)*/ /*riscos_vdu (os_VDU_PLOT, plot_type, x, y)*/ /*riscos_vdu (os_VDU_SET_TEXT_WINDOW, x0, y0, x1, y1)*/ /*riscos_vdu (os_VDU_SET_GRAPHICS_ORIGIN, x, y)*/ #endif --- NEW FILE: x.c --- /**************************************************************** ** Title : SupportLib.c.x.c.x ** ** Purpose: RiscOs Exception Handling ** ** Copyright: ©OSLib ** ** History: 970913 TV Port from OSLib x with StrongArm amendments ** 981221 TV fixed bug giving wrong offsets in International_Error ** *****************************************************************/ /* OSLib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. OSLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this programme; if not, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A. */ /*x.c*/ /*From CLib*/ #include "kernel.h" #include <setjmp.h> #include <signal.h> #include <stdlib.h> #include <string.h> /*From OSLib*/ #include "oslib/macros.h" #include "oslib/messagetrans.h" #include "oslib/os.h" /*From Support*/ #include "x.h" /* For bootstrap builds */ #ifndef error_ESCAPE # define error_ESCAPE 0x11u #endif #ifndef error_STK_OFLO # define error_STK_OFLO 0x163u #endif typedef struct { os_error* dflt; os_error* token; } International_Error; /*A macro to declare them*/ #define LOCAL_INTERNATIONAL_ERROR(id, token, num, mess) \ static struct \ { \ bits defaultnum; \ char errmess [sizeof mess + 1]; \ } id ## _dflt_ = { num, mess }; \ \ static struct \ { \ bits errnum; \ char errtoken [sizeof token + 1]; \ } id ## _token_ = {num, token}; \ \ static International_Error id ## _ = { ( os_error *) &id ## _dflt_ , (os_error*) &id ## _token_ }; \ static International_Error *id = &id ## _ #if 0 /* international error blocks (for use with Copy_Error())*/ LOCAL_INTERNATIONAL_ERROR( Error_Stack, "C64", error_STK_OFLO, "Not enough memory, allocate failed" ); #endif LOCAL_INTERNATIONAL_ERROR( Error_Unknown, "C35", 1, "No error (errno = 0)" ); /* synchronisation error */ x_LOCAL_ERROR( Error_Sync, 1 + (1U<<30), "Try/Catch Synchronisation Error" ); /* exception stack overflow */ x_LOCAL_ERROR( Error_XStack, 2 + (1U<<30), "Too many nested x_TRY blocks" ); /* error blocks with tokens in (for use with MessageTrans).*/ x_LOCAL_ERROR( Error_Escape, error_ESCAPE, "Escape" ); x_LOCAL_ERROR( Error_No_Memory, os_GLOBAL_NO_MEM, "NoMem" ); static int Signals [] = { SIGINT, #ifdef SIGSTAK SIGSTAK, #endif SIGOSERROR }; /*------------------------------------------------------------------------*/ static os_error *Copy_Error (International_Error *ie) { #ifndef EXECUTE_ON_UNIX messagetrans_control_block cb; #endif os_error *e; /*This code is what the SharedCLibrary does, except that this happens every time a message is to be looked up, and the module only opens the file at most once. We don't really care about this.*/ #ifndef EXECUTE_ON_UNIX if( xmessagetrans_open_file( &cb, "SharedCLibrary:Messages", NULL ) == NULL ) { e = xmessagetrans_error_lookup( ie -> token, &cb, NULL, 0, "SharedCLibrary", NULL, NULL, NULL ); xmessagetrans_close_file( &cb ); } else #endif e = ie -> dflt; return e; } // start off with a stack chunk of adequate size to hold initial exception blocks static x_exception* gapxX[ x_MAXDEPTH ]; // stack static x_exception** gppxX = gapxX; // stack pointer /*------------------------------------------------------------------------*/ // signal handler static void SigHandler( int iSignal ) { os_error *pxError = NULL /**/; /*Save this condition in the buffer.*/ switch( iSignal ) { case SIGINT: #ifdef EXECUTE_ON_UNIX pxError = Error_Escape; #else pxError = xmessagetrans_error_lookup( Error_Escape, NULL, NULL, 0, SKIP, SKIP, SKIP, SKIP ); #endif break; #ifdef SIGSTAK case SIGSTAK: pxError = Copy_Error( Error_Stack ); break; #endif case SIGOSERROR: pxError = x__last_error(); break; } /*Longjump back to the x_TRY() call.*/ longjmp( (*(gppxX - 1)) -> buf, (int)( (*(gppxX - 1)) -> error = pxError)); } /*------------------------------------------------------------------------*/ void x__try( x_exception* pxX ) { int sig; // enter on exception stack if( gppxX < gapxX + x_MAXDEPTH ) *gppxX++ = pxX; else x_THROW( Error_XStack ); // throw an error on exception stack overflow /* Register handlers for each of the signal types which we're prepared to handle ** We maintain a record of the previous handlers so that we can restore them. ** It is more efficient to place the pointers on the caller's stack than to ** allocate our own memory */ for( sig = 0; sig < COUNT (Signals); sig++ ) { pxX -> previous[sig] = signal( Signals[sig], SigHandler ); if( pxX -> previous[sig] == SIG_ERR ) pxX -> previous[sig] = NULL; } /*error*/ pxX -> error = NULL; /*buf*/ /*Done in calling macro.*/ } /*------------------------------------------------------------------------*/ void x__catch( x_exception* pxX ) { int sig; /*Restore the caller's handlers.*/ for( sig = 0; sig < COUNT (Signals); sig++ ) { if( pxX -> previous[sig] != NULL ) signal( Signals [sig], pxX -> previous [sig] ); } /* remove the x_exception entry from the exception stack */ if( pxX == *(--gppxX) ) *gppxX = NULL; else x_THROW( Error_Sync ); // try/catch blocks out of sync } /*------------------------------------------------------------------------*/ os_error *x__last_error (void) { os_error *last_error; static os_error *Last_Error; /*Messing about here because _kernel_last_oserror() returns NULL the second time it's called*/ if ((last_error = (os_error *) _kernel_last_oserror() ) != NULL ) Last_Error = last_error; if (Last_Error == NULL) Last_Error = Copy_Error (Error_Unknown); return Last_Error; /*never NULL*/ } /*------------------------------------------------------------------------*/ void *x__alloc (int size) { void *ptr; if ((ptr = malloc (size)) == NULL && size != 0) { #ifndef EXECUTE_ON_UNIX messagetrans_error_lookup (Error_No_Memory, NULL, NULL, 0, SKIP, SKIP, SKIP, SKIP); #else os_generate_error( Error_No_Memory ); #endif } return ptr; } /*------------------------------------------------------------------------*/ void *x__calloc (int count, int size) { void *ptr; if ((ptr = calloc (count, size)) == NULL && size != 0 && count != 0) { #ifndef EXECUTE_ON_UNIX messagetrans_error_lookup (Error_No_Memory, NULL, NULL, 0, SKIP, SKIP, SKIP, SKIP); #else os_generate_error( Error_No_Memory ); #endif } return ptr; } /*------------------------------------------------------------------------*/ void x__free (void *ptr, int size) {NOT_USED (size) free (ptr);} /*------------------------------------------------------------------------*/ void *x__realloc (void *ptr, int old_size, int size) { // NOT_USED (old_size) // NOT_USED (size) if ((ptr = realloc (ptr, size)) == NULL && size != 0) { #ifndef EXECUTE_ON_UNIX messagetrans_error_lookup (Error_No_Memory, NULL, NULL, 0, SKIP, SKIP, SKIP, SKIP); #else os_generate_error( Error_No_Memory ); #endif } return ptr; } --- NEW FILE: x.h --- #ifndef x_H #define x_H /* x.h - exception handling header */ // Revision History: // From OSLib // 970926 TV Strongarm Compatible version // #include <stdio.h> #include <stdlib.h> #include <setjmp.h> #include <signal.h> #ifndef os_H #include "oslib/os.h" #endif #define x_MAXDEPTH 256 //#define TRACE 0 #ifdef EXECUTE_ON_UNIX # define SIGOSERROR (SIGUSR1) #else /* the following signals are defined in CLib, but not in UNIXLib */ /* Stack overflow. */ # if !defined SIGSTAK # define SIGSTAK 7 # endif /* Operating system error. */ # if !defined SIGOSERROR # define SIGOSERROR 10 # endif #endif typedef struct x_exception { void (*previous [3]) (int); os_error *error; jmp_buf buf; } x_exception; #ifdef __cplusplus extern "C" { #endif /* (Pseudo-)function to be called before a group of statements which * could throw an exception. */ #define x_TRY(x) \ if (x__try (x), setjmp ((x)->buf) == 0) extern void x__try (x_exception *); /* Function to allow the exception type to be examined. MUST be * called to balance a call to x_TRY. */ #define x_CATCH(x) \ if (x__catch (x), (x)->error != NULL) extern void x__catch (x_exception *); /* Function to re-throw exceptions. Used in exception handlers or in tidy- * up code to throw the error to the next-higher level that needs it. If * there was no exception, this does nothing. */ #define x_RETHROW(x) \ (((x)->error) != NULL ? ((void)os_generate_error((x)->error)):((void) SKIP)) /* Strange pseudo-declaration thing to make an |os_error *| from an error * number and a message. Declares |id| to be an |os_error *| pointing at the * block {num, mess}, without wasting 252 bytes of empty error block. Can * also be used if you want an international message that will be passed to * messagetrans_error_lookup. */ #define x_LOCAL_ERROR(id, num, mess) \ static struct {int errnum; char errmess [sizeof mess + 1];} id ## _ = \ {num, mess}; \ static os_error *id = (os_error *) &id ## _ /* Another declaration, to make an |os_error *| from an error * number and a message. Declares |id| to be an |os_error *| pointing at the * block {num, mess}, without wasting 252 bytes of empty error block. Can * also be used if you want an international message that will be passed to * messagetrans_error_lookup. */ #define x_GLOBAL_ERROR(id, num, mess) \ static struct {int errnum; char errmess [sizeof mess + 1];} id ## _ = \ {num, mess}; \ os_error *id = (os_error *) &id ## _; /* Function to throw exceptions. Used anywhere that obtains an * |os_error *| (usually from x_LOCAL_ERROR), and wants to turn it into an * exception. Undefined if its argument is NULL. */ #define x_THROW(error) \ os_generate_error (error) /* Function to throw an error after one has been detected by the run-time * system. Use after (e g) fopen, printf fail. */ #define x_THROW_LAST_ERROR() \ os_generate_error (x__last_error ()) extern os_error *x__last_error (void); /* Function to give the error responsible. Useful only at the top, where the * error is be reported. */ #define x_ERROR(x) ((x)->error) /* Function to exit from the programme, with an appropriate message and * return value (not useful for desktop programmes). */ #define x_EXIT(x) \ ( (x)->error != NULL? \ ( fprintf (stderr, "%s\n", (x)->error->errmess), \ exit (EXIT_FAILURE) \ ): \ exit (0) \ ) /* Function to exit from a desktop programme with an appropriate message and * return value. */ #define x_REPORT_EXIT(x, programme) \ ( (x)->error != NULL? \ ( wimp_report_error ((x)->error, NONE, programme), \ exit (EXIT_FAILURE) \ ): \ exit (0) \ ) /* A set of functions to do exception-throwing memory allocation. If they * return, they have succeeded, so they can be used in expressions, etc. */ extern os_error *x_no_memory; #if 0 #if TRACE #define x_ALLOC(size) x__alloc (size) #define x_CALLOC(count, size) x__calloc (count, size) #define x_FREE(ptr, size) x__free (ptr, size) #define x_REALLOC(ptr, old_size, size) x__realloc (ptr, old_size, size) #endif #else #define x_ALLOC(size) x__alloc (size) #define x_CALLOC(count, size) x__calloc (count, size) #define x_FREE(ptr) x__free (ptr, 0) #define x_REALLOC(ptr, size) x__realloc (ptr, 0, size) #endif extern void *x__alloc (int size); extern void *x__calloc (int count, int size); extern void x__free (void *ptr, int size); extern void *x__realloc (void *ptr, int old_size, int size); #ifdef __cplusplus } #endif #endif |