1/*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 *	All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 */
9
10#pragma ident	"%Z%%M%	%I%	%E% SMI"
11
12#include <sm/gen.h>
13SM_IDSTR(id, "@(#)$Id: t-exc.c,v 1.18 2001/07/05 22:46:35 gshapiro Exp $")
14
15#include <string.h>
16#include <sm/heap.h>
17#include <sm/io.h>
18#include <sm/test.h>
19
20const SM_EXC_TYPE_T EtypeTest1 =
21{
22	SmExcTypeMagic,
23	"E:test1",
24	"i",
25	sm_etype_printf,
26	"test1 exception argv[0]=%0",
27};
28
29const SM_EXC_TYPE_T EtypeTest2 =
30{
31	SmExcTypeMagic,
32	"E:test2",
33	"i",
34	sm_etype_printf,
35	"test2 exception argv[0]=%0",
36};
37
38int
39main(argc, argv)
40	int argc;
41	char **argv;
42{
43	void *p;
44	int volatile x;
45	char *unknown, *cant;
46
47	sm_test_begin(argc, argv, "test exception handling");
48
49	/*
50	**  SM_TRY
51	*/
52
53	cant = "can't happen";
54	x = 0;
55	SM_TRY
56		x = 1;
57	SM_END_TRY
58	SM_TEST(x == 1);
59
60	/*
61	**  SM_FINALLY-0
62	*/
63
64	x = 0;
65	SM_TRY
66		x = 1;
67	SM_FINALLY
68		x = 2;
69	SM_END_TRY
70	SM_TEST(x == 2);
71
72	/*
73	**  SM_FINALLY-1
74	*/
75
76	x = 0;
77	SM_TRY
78		SM_TRY
79			x = 1;
80			sm_exc_raisenew_x(&EtypeTest1, 17);
81		SM_FINALLY
82			x = 2;
83			sm_exc_raisenew_x(&EtypeTest2, 42);
84		SM_END_TRY
85	SM_EXCEPT(exc, "E:test2")
86		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
87			 "got exception test2: can't happen\n");
88	SM_EXCEPT(exc, "E:test1")
89		SM_TEST(x == 2 && exc->exc_argv[0].v_int == 17);
90		if (!(x == 2 && exc->exc_argv[0].v_int == 17))
91		{
92			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
93				"can't happen: x=%d argv[0]=%d\n",
94				x, exc->exc_argv[0].v_int);
95		}
96	SM_EXCEPT(exc, "*")
97	{
98		unknown = "unknown exception: ";
99		SM_TEST(strcmp(unknown, cant) == 0);
100	}
101	SM_END_TRY
102
103	x = 3;
104	SM_TRY
105		x = 4;
106		sm_exc_raisenew_x(&EtypeTest1, 94);
107	SM_FINALLY
108		x = 5;
109		sm_exc_raisenew_x(&EtypeTest2, 95);
110	SM_EXCEPT(exc, "E:test2")
111	{
112		unknown = "got exception test2: ";
113		SM_TEST(strcmp(unknown, cant) == 0);
114	}
115	SM_EXCEPT(exc, "E:test1")
116		SM_TEST(x == 5 && exc->exc_argv[0].v_int == 94);
117		if (!(x == 5 && exc->exc_argv[0].v_int == 94))
118		{
119			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
120				"can't happen: x=%d argv[0]=%d\n",
121				x, exc->exc_argv[0].v_int);
122		}
123	SM_EXCEPT(exc, "*")
124	{
125		unknown = "unknown exception: ";
126		SM_TEST(strcmp(unknown, cant) == 0);
127	}
128	SM_END_TRY
129
130	SM_TRY
131		sm_exc_raisenew_x(&SmEtypeErr, "test %d", 0);
132	SM_EXCEPT(exc, "*")
133#if DEBUG
134		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
135			"test 0 got an exception, as expected:\n");
136		sm_exc_print(exc, smioout);
137#endif /* DEBUG */
138		return sm_test_end();
139	SM_END_TRY
140
141	p = sm_malloc_x((size_t)(-1));
142	(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
143		"sm_malloc_x unexpectedly succeeded, returning %p\n", p);
144	unknown = "sm_malloc_x unexpectedly succeeded";
145	SM_TEST(strcmp(unknown, cant) == 0);
146	return sm_test_end();
147}
148