Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/working/exception/impl/test-main.c

    r6a48cc9 r35dd0f42  
    11#include "exception.h"
    22
    3 // Use: gcc -fexceptions -Wall -Werror -g exception.c test-main.c
    4 
    53#include <stdio.h>
    6 #include <stdbool.h>
    74
    85// Translation Helpers:
     
    107        struct __cleanup_hook __hidden_hook __attribute__((cleanup(function)))
    118
    12 #define SET_UP_RESUME_NODE(handler_function) \
    13         struct __try_resume_node node \
    14                 __attribute__((cleanup(__try_resume_node_delete))); \
    15         __try_resume_node_new(&node, handler_function)
    16 
    17 void __try_resume_node_new(struct __try_resume_node * node,
    18         _Bool (*handler)(exception except)) {
    19     node->next = shared_stack.top_resume;
    20     shared_stack.top_resume = node;
    21     node->try_to_handle = handler;
    22 }
    23 
    24 void __try_resume_node_delete(struct __try_resume_node * node) {
    25     shared_stack.top_resume = node->next;
    26 }
    279
    2810// Local Print On Exit:
     
    3719#define raii_t __attribute__((cleanup(raii_dtor))) struct raii_base_type
    3820
    39 // ===========================================================================
    4021// Runtime code (post-translation).
    4122void terminate(int except_value) {
     
    5334// Termination Test: Two handlers: no catch, catch
    5435void bar() {
    55         raii_t a = {"bar function"};
    56         {
    57                 void bar_try1() {
    58                         terminate(4);
     36        void bar_try1() {
     37                terminate(4);
     38        }
     39        void bar_catch1(int index, exception except) {
     40                switch(except) {
     41                case 1:
     42                        printf("bar caught exception.\n");
     43                        break;
     44                default:
     45                        printf("INVALID INDEX in bar: %d\n", except);
    5946                }
    60                 void bar_catch1(int index, exception except) {
    61                         switch(except) {
    62                         case 1:
    63                                 printf("bar caught exception 3.\n");
    64                                 break;
    65                         default:
    66                                 printf("INVALID INDEX in bar: %d (%d)\n", index, except);
    67                         }
     47        }
     48        int bar_match1(exception except) {
     49                if (3 == except) {
     50                        return 1;
     51                } else {
     52                        return 0;
    6853                }
    69                 int bar_match1(exception except) {
    70                         if (3 == except) {
    71                                 return 1;
    72                         } else {
    73                                 return 0;
    74                         }
    75                 }
    76                 __try_terminate(bar_try1, bar_catch1, bar_match1);
    7754        }
     55        __try_terminate(bar_try1, bar_catch1, bar_match1);
    7856}
    7957
    8058void foo() {
    81         raii_t a = {"foo function"};
    82         {
    83                 void foo_try1() {
    84                         bar();
     59        void foo_try1() {
     60                bar();
     61        }
     62        void foo_catch1(int index, exception except) {
     63                switch(except) {
     64                case 1:
     65                        printf("foo caught exception 4.\n");
     66                        break;
     67                case 2:
     68                        printf("foo caught exception 2.\n");
     69                        break;
     70                default:
     71                        printf("INVALID INDEX in foo: %d\n", except);
    8572                }
    86                 void foo_catch1(int index, exception except) {
    87                         switch(index) {
    88                         case 1:
    89                                 printf("foo caught exception 4.\n");
    90                                 break;
    91                         case 2:
    92                                 printf("foo caught exception 2.\n");
    93                                 break;
    94                         default:
    95                                 printf("INVALID INDEX in foo: %d (%d)\n", index, except);
    96                         }
     73        }
     74        int foo_match1(exception except) {
     75                if (4 == except) {
     76                        return 1;
     77                } else if (2 == except) {
     78                        return 2;
     79                } else {
     80                        return 0;
    9781                }
    98                 int foo_match1(exception except) {
    99                         if (4 == except) {
    100                                 return 1;
    101                         } else if (2 == except) {
    102                                 return 2;
    103                         } else {
    104                                 return 0;
    105                         }
    106                 }
    107                 __try_terminate(foo_try1, foo_catch1, foo_match1);
    10882        }
     83        __try_terminate(foo_try1, foo_catch1, foo_match1);
    10984}
    11085
    111 // Resumption Two Handler Test: no catch, catch.
    112 void beta() {
    113         raii_t a = {"beta function"};
    114         {
    115                 bool beta_handle1(exception except) {
    116                         if (3 == except) {
    117                                 printf("beta caught exception 3\n");
    118                                 return true;
    119                         } else {
    120                                 return false;
    121                         }
    122                 }
    123                 struct __try_resume_node node
    124                         __attribute__((cleanup(__try_resume_node_delete)));
    125                 __try_resume_node_new(&node, beta_handle1);
    126                 {
    127                         resume(4);
    128                 }
    129         }
    130 }
    131 void alpha() {
    132         raii_t a = {"alpha function"};
    133         {
    134                 bool alpha_handle1(exception except) {
    135                         if (2 == except) {
    136                                 printf("alpha caught exception 2\n");
    137                                 return true;
    138                         } else if (4 == except) {
    139                                 printf("alpha caught exception 4\n");
    140                                 return true;
    141                         } else {
    142                                 return false;
    143                         }
    144                 }
    145                 struct __try_resume_node node
    146                         __attribute__((cleanup(__try_resume_node_delete)));
    147                 __try_resume_node_new(&node, alpha_handle1);
    148                 {
    149                         beta();
    150                 }
    151         }
    152 }
    153 
    154 // Finally Test:
    155 void farewell() {
    156         {
    157                 void farewell_finally1() {
    158                         printf("See you next time\n");
    159                 }
    160                 struct __cleanup_hook __hidden_hook
    161                         __attribute__((cleanup(farewell_finally1)));
    162                 {
    163                         printf("walk out of farewell\n");
    164                 }
    165         }
    166 }
    167 
    168 // Resume-to-Terminate Test:
    169 void fallback() {
    170         {
    171                 void fallback_try1() {
    172                         resume(1);
    173                 }
    174                 void fallback_catch1(int index, exception except) {
    175                         switch (index) {
    176                         case 1:
    177                                 printf("fallback caught termination 1\n");
    178                                 break;
    179                         default:
    180                                 printf("INVALID INDEX in fallback: %d (%d)\n", index, except);
    181                         }
    182                 }
    183                 int fallback_match1(exception except) {
    184                         if (1 == except) {
    185                                 return 1;
    186                         } else {
    187                                 return 0;
    188                         }
    189                 }
    190                 __try_terminate(fallback_try1, fallback_catch1, fallback_match1);
    191         }
    192 }
    193 
    194 // Terminate Throw New Exception:
    195 void terminate_swap() {
    196         raii_t a = {"terminate_swap"};
    197         {
    198                 void fn_try1() {
    199                         terminate(2);
    200                 }
    201                 void fn_catch1(int index, exception except) {
    202                         switch (index) {
    203                         case 1:
    204                                 terminate(1);
    205                                 break;
    206                         default:
    207                                 printf("INVALID INDEX in terminate_swap: %d (%d)\n",
    208                                         index, except);
    209                         }
    210                 }
    211                 int fn_match1(exception except) {
    212                         if (2 == except) {
    213                                 return 1;
    214                         } else {
    215                                 return 0;
    216                         }
    217                 }
    218                 __try_terminate(fn_try1, fn_catch1, fn_match1);
    219         }
    220 }
    221 
    222 void terminate_swapped() {
    223         raii_t a = {"terminate_swapped"};
    224         {
    225                 void fn_try1() {
    226                         terminate_swap();
    227                 }
    228                 void fn_catch1(int index, exception except) {
    229                         switch (index) {
    230                         case 1:
    231                                 printf("terminate_swapped caught exception 1\n");
    232                                 break;
    233                         default:
    234                                 printf("INVALID INDEX in terminate_swapped: %d (%d)\n",
    235                                         index, except);
    236                         }
    237                 }
    238                 int fn_match1(exception except) {
    239                         if (1 == except) {
    240                                 return 1;
    241                         } else {
    242                                 return 0;
    243                         }
    244                 }
    245                 __try_terminate(fn_try1, fn_catch1, fn_match1);
    246         }
    247 }
    248 
    249 // Resume Throw New Exception:
    250 void resume_swap() {
    251         raii_t a = {"terminate_swap"};
    252         {
    253                 bool fn_handle1(exception except) {
    254                         if (2 == except) {
    255                                 resume(1);
    256                                 return true;
    257                         } else {
    258                                 return false;
    259                         }
    260                 }
    261                 struct __try_resume_node node
    262                         __attribute__((cleanup(__try_resume_node_delete)));
    263                 __try_resume_node_new(&node, fn_handle1);
    264                 {
    265                         resume(2);
    266                 }
    267         }
    268 }
    269 
    270 void resume_swapped() {
    271         {
    272                 bool fn_handle1(exception except) {
    273                         if (1 == except) {
    274                                 printf("resume_swapped caught exception 1\n");
    275                                 return true;
    276                         } else {
    277                                 return false;
    278                         }
    279                 }
    280                 struct __try_resume_node node
    281                         __attribute__((cleanup(__try_resume_node_delete)));
    282                 __try_resume_node_new(&node, fn_handle1);
    283                 {
    284                         resume_swap();
    285                 }
    286         }
    287 }
    288 
    289 // Terminate Rethrow:
    290 // I don't have an implementation for this.
    291 
    292 // Resume Rethrow:
    293 void reresume() {
    294         {
    295                 bool reresume_handle1(exception except) {
    296                         if (1 == except) {
    297                                 printf("reresume 1 caught exception 1\n");
    298                                 return true;
    299                         } else {
    300                                 return false;
    301                         }
    302                 }
    303                 struct __try_resume_node node
    304                         __attribute__((cleanup(__try_resume_node_delete)));
    305                 __try_resume_node_new(&node, reresume_handle1);
    306                 {
    307                         bool reresume_handle2(exception except) {
    308                                 if (1 == except) {
    309                                         printf("reresume 2 caught and rethrows exception 1\n");
    310                                         return false;
    311                                 } else {
    312                                         return false;
    313                                 }
    314                         }
    315                         struct __try_resume_node node
    316                                 __attribute__((cleanup(__try_resume_node_delete)));
    317                         __try_resume_node_new(&node, reresume_handle2);
    318                         {
    319                                 resume(1);
    320                         }
    321                 }
    322         }
    323 }
    324 
    325 // Terminate-Resume interaction:
    326 void fum() {
    327         // terminate block, call resume
    328         {
    329                 void fum_try1() {
    330                         resume(3);
    331                 }
    332                 void fum_catch1(int index, exception except) {
    333                         switch (index) {
    334                         case 1:
    335                                 printf("fum caught exception 3\n");
    336                                 break;
    337                         default:
    338                                 printf("INVALID INDEX in fum: %d (%d)\n", index, except);
    339                         }
    340                 }
    341                 int fum_match1(exception except) {
    342                         if (3 == except) {
    343                                 return 1;
    344                         } else {
    345                                 return 0;
    346                         }
    347                 }
    348                 __try_terminate(fum_try1, fum_catch1, fum_match1);
    349         }
    350 }
    351 
    352 void foe() {
    353         // resume block, call terminate
    354         {
    355                 bool foe_handle1(exception except) {
    356                         if (3 == except) {
    357                                 printf("foe caught exception 3\n");
    358                                 return true;
    359                         } else {
    360                                 return false;
    361                         }
    362                 }
    363                 struct __try_resume_node node
    364                         __attribute__((cleanup(__try_resume_node_delete)));
    365                 __try_resume_node_new(&node, foe_handle1);
    366                 {
    367                         terminate(3);
    368                 }
    369         }
    370 }
    371 
    372 void fy() {
    373         // terminate block calls fum, call foe
    374         {
    375                 void fy_try1() {
    376                         foe();
    377                 }
    378                 void fy_catch1(int index, exception except) {
    379                         switch (index) {
    380                         case 1:
    381                                 printf("fy caught exception 3\n");
    382                                 fum();
    383                                 break;
    384                         default:
    385                                 printf("INVALID INDEX in fy: %d (%d)\n", index, except);
    386                         }
    387                 }
    388                 int fy_match1(exception except) {
    389                         if (3 == except) {
    390                                 return 1;
    391                         } else {
    392                                 return 0;
    393                         }
    394                 }
    395                 __try_terminate(fy_try1, fy_catch1, fy_match1);
    396         }
    397 }
    398 
    399 void fee() {
    400         // resume block, call fy
    401         {
    402                 bool fee_handle1(exception except) {
    403                         if (3 == except) {
    404                                 printf("fee caught exception 3\n");
    405                                 return true;
    406                         } else {
    407                                 return false;
    408                         }
    409                 }
    410                 struct __try_resume_node node
    411                         __attribute__((cleanup(__try_resume_node_delete)));
    412                 __try_resume_node_new(&node, fee_handle1);
    413                 {
    414                         fy();
    415                 }
    416         }
    417 }
    418 
    419 
    420 // main: choose which tests to run
    42186int main(int argc, char * argv[]) {
    42287        raii_t a = {"main function"};
    42388
    424         foo(); printf("\n");
    425         alpha(); printf("\n");
    426         farewell(); printf("\n");
    427         fallback(); printf("\n");
    428         terminate_swapped(); printf("\n");
    429         resume_swapped(); printf("\n");
    430         reresume(); printf("\n");
    431         fee(); printf("\n");
    432         // Uncaught termination test.
    433         terminate(7);
     89        foo();
    43490}
Note: See TracChangeset for help on using the changeset viewer.