xref: /netbsd-src/external/gpl3/gcc.old/dist/libphobos/testsuite/libphobos.exceptions/chain.d (revision aef5eb5f59cdfe8314f1b5f78ac04eb144e44010)
1 // Author: Ali Çehreli
2 // See https://forum.dlang.org/post/o2n7f8$2p1t$1@digitalmars.com
3 
4 import core.stdc.stdio;
5 
6 class TestException : Exception
7 {
8     this(string msg)
9     {
10         super(typeof(this).stringof~": "~msg);
11     }
12 }
13 
14 class TestError : Error
15 {
16     this(string msg)
17     {
18         super(typeof(this).stringof~": "~msg);
19     }
20 }
21 
22 // Causes an exception chain where the node at index errorIndex is an
23 // Error (others are all Exceptions).
24 void causeExceptionChain(size_t chainLength, size_t errorIndex)
25 {
26     void throws(size_t n)
27     {
28         scope (exit)
29         {
30             string msg = [ cast(char)('a'+n) ].idup;
31             if (n == errorIndex)
32             {
33                 throw new TestError(msg);
34             }
35             else
36             {
37                 throw new TestException(msg);
38             }
39         }
40 
41         if (n != 0)
42         {
43             // Redundant 'return' keyword due to
44             // https://issues.dlang.org/show_bug.cgi?id=16960
45             return throws(n - 1);
46         }
47     }
48 
49     throws(chainLength - 1);
50 }
51 
52 void main()
53 {
54     try
55     {
56         // -1 would mean "no Error in the chain". Change this to a
57         // number between 0 and 4 (inclusive) then you will realize
58         // that the Exception below will not be caught.
59         size_t errorIndex = 3;
60         causeExceptionChain(5, errorIndex);
61     }
62     catch (Error original)
63     {
64         printf("Caught\n");
65         string prefix = "";
66         for ({ size_t i; Throwable ex = original; } ex; ex = ex.next, ++i)
67         {
68             printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr);
69             prefix = prefix~" ";
70         }
71         printf("Bypassed chain was:\n");
72         prefix = "";
73         for ({ size_t i; Throwable ex = original.bypassedException; } ex; ex = ex.next, ++i)
74         {
75             printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr);
76             prefix = prefix~" ";
77         }
78     }
79 }
80