1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
/*************************************************************************/
/* Package name : Except. */
/* Version : 1.0 */
/* Completed : April 1993. */
/* Released : 29 September 1993. */
/* First created : This package was first created in April 1993. */
/* Summary : This package provides Ada-like exceptions for C. */
/* Components : except.fw - FunnelWeb source file. */
/* except.h - Exported header file. */
/* except.c - Implementation file. */
/* ex_test.c - C test program. */
/* Requires : style.h, as.h, as.c. */
/* Author : Ross N. Williams (ross@guest.adelaide.edu.au) */
/* Rocksoft^tm Pty Ltd */
/* 16 Lerwick Avenue, Hazelwood Park 5066, Australia. */
/* FTP Archive : This file can be found in */
/* "ftp.adelaide.edu.au/pub/funnelweb/examples/" */
/* Disclaimer : This program is distributed WITHOUT ANY WARRANTY; */
/* without even the implied warranty of MERCHANTABILITY */
/* or FITNESS FOR A PARTICULAR PURPOSE. */
/* Copyright : Copyright (C) Ross Williams 1993. */
/* However, permission is granted for anyone to copy, */
/* modify, and distribute this work for any purpose, */
/* commercial or non-commercial, so long as this notice */
/* is included verbatim, and so long as all */
/* modifications are recorded in the change log below. */
/* Changes : Please log any changes to this software either in the */
/* originating FunnelWeb source file, or, if you must, */
/* in the C source files produced from the FunnelWeb */
/* file. */
/* --<Start of Change Log>-- */
/* ??-Apr-93: RNW: Created this package. */
/* 29-Sep-93: RNW: Released this package. */
/* --<End of Change Log>-- */
/*************************************************************************/
#ifndef _EX_DONE
#define _EX_DONE 1
#include "style.h"
#include <setjmp.h>
typedef string p_ex_t;
#define EX_EXCEPT(NAME) extern const p_ex_t NAME
#define EX_EXPORT(NAME,DESC) const p_ex_t NAME = DESC
#define EX_LOCAL(NAME,DESC) static const p_ex_t NAME = DESC
#define _EX_FAST FALSE
/* Set _EX_FAST to TRUE to turn on inlining and turn off checking. */
#define _EX_THRD FALSE
/* To configure this package to work under a multi-threaded environment, */
/* set _EX_THRD to TRUE and modify the k_var calls later on in the file. */
typedef struct _ex_cxt_
{
#if !_EX_FAST
ulong _ex_mag1; /* Header magic number. */
#endif
jmp_buf _ex_jmbf; /* Exception block context. */
struct _ex_cxt_ *_ex_prev; /* Pointer to previous stack record. */
#if !_EX_FAST
ulong _ex_mag2; /* Trailer magic number. */
#endif
} _ex_cx_t;
#define _EX_MAG1 0xFB8A5D30
#define _EX_MAG2 0x09F2E7A2
#if !_EX_THRD
extern _ex_cx_t *_ex_curr;
extern p_ex_t _ex_id;
extern ptrint _ex_info;
#endif
#if !_EX_THRD
/* Non-threaded system macros simply point to variables. */
#define _EX_CURR _ex_curr
#define EX_ID ((p_ex_t) _ex_id)
#define _EX_ID _ex_id
#define EX_INFO _ex_info
#else
/* Threaded system macros translate to kernel calls. */
/* To make this package work in a multi-threaded environment, */
/* set _EX_THRD to TRUE and modify these definitions. */
/* Note: The kernel should initialize _EX_CURR to NULL. */
#define _EX_CURR (* ((_ex_cx_t *) k_var(51)))
#define EX_ID ((p_ex_t) (* ((p_ex_t *) k_var(52))))
#define _EX_ID (* ((p_ex_t *) k_var(52)))
#define EX_INFO (* ((ptrint *) k_var(53)))
#endif
#if _EX_FAST
#define EX_RAISE(P_EX) {_EX_ID = (P_EX); longjmp(_EX_CURR->_ex_jmbf,NON_ZERO);}
#else
#define EX_RAISE(P_EX) {_exrai(P_EX);}
#endif
#if _EX_FAST
#define EX_BEGIN \
{_ex_cx_t _ex_cxlc; \
_ex_cxlc._ex_prev = _EX_CURR; \
_EX_CURR = &_ex_cxlc; \
if (!setjmp(_ex_cxlc._ex_jmbf)) {
#define EX_FORGET ;EX_POP} else {EX_POP; if (FALSE) {
#define EX_WHEN(P_EX) } else if ((P_EX) == (EX_ID)) {
#define EX_OTHERS } else if (TRUE) {
#define EX_END } else longjmp(_EX_CURR->_ex_jmbf,NON_ZERO); }}
#define EX_POP {_EX_CURR = _EX_CURR->_ex_prev;}
#else
#define EX_BEGIN \
{_ex_cx_t _ex_cxlc; \
_ex_cxlc._ex_mag1 = _EX_MAG1; \
_ex_cxlc._ex_mag2 = _EX_MAG2; \
_ex_cxlc._ex_prev = _EX_CURR; \
_EX_CURR = &_ex_cxlc; \
if (!setjmp(_ex_cxlc._ex_jmbf)) {
#define EX_FORGET ;EX_POP} else {EX_POP; if (FALSE) {
#define EX_WHEN(P_EX) } else if ((P_EX) == (EX_ID)) {
#define EX_OTHERS } else if (TRUE) {
#define EX_END } else _exrai(EX_ID); }}
#define EX_POP {_expop(&_ex_cxlc);}
#endif
EXPORT string ex_str P_((p_ex_t));
EXPORT void _exrai P_((p_ex_t));
EXPORT void _expop P_((_ex_cx_t *));
#endif
|