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