source of highlighter
plain | download
    1 #include <errno.h>
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #include <setjmp.h>
    5 #include <math.h>
    6 
    7 struct trycatch
    8 {
    9   jmp_buf * buf;
   10   struct trycatch * prev;
   11   void * exception;
   12 } __thread * current_trycatch = NULL;
   13 
   14 #define THROW_WITH_DATA(e,d) do { \
   15     current_trycatch->exception = d; \
   16     longjmp (*(current_trycatch->buf), e); \
   17   } while (0)
   18 
   19 #define THROW(e) do { \
   20     longjmp (*(current_trycatch->buf), e); \
   21   } while (0)
   22 
   23 #define TRY \
   24   do { \
   25     jmp_buf __bUf; \
   26     struct trycatch __tRy; \
   27     int __eRr; \
   28     __tRy.buf = &__bUf; \
   29     __tRy.prev = current_trycatch; \
   30     current_trycatch = &__tRy; \
   31     __eRr = setjmp (__bUf); \
   32     switch (__eRr) \
   33       { \
   34         case 0: \
   35           do {
   36 
   37 #define CATCH_WITH_DATA(e,d) \
   38           } while (0); \
   39           break; \
   40         case e: \
   41           do { \
   42             void * (d) = current_trycatch->exception;
   43 
   44 #define CATCH(e) \
   45           } while (0); \
   46           break; \
   47         case e: \
   48           do { \
   49 
   50 #define ENDTRY \
   51           } while (0); \
   52           break; \
   53         default: \
   54           if (current_trycatch->prev) \
   55             { \
   56               current_trycatch = current_trycatch->prev; \
   57               THROW_WITH_DATA(__eRr, __tRy.exception); \
   58             } \
   59           else \
   60             { \
   61               fprintf (stderr, "Unhandled exception %i!\n", __eRr); \
   62             } \
   63       } \
   64       current_trycatch = current_trycatch->prev; \
   65   } while (0);
   66 
   67 long int
   68 isqrt (long int par)
   69 {
   70   if (par < 0)
   71     THROW(EDOM);
   72 
   73   return (long int) sqrt((double) par);
   74 }
   75 
   76 void
   77 nested (char * arg)
   78 {
   79   long int res;
   80 
   81   TRY {
   82     char * end;
   83     long int number = strtol (arg, &end, 10);
   84 
   85     if (*end != '\0')
   86       THROW_WITH_DATA(EINVAL, (void *) "argument contains nondecadic characters!");
   87 
   88     res = isqrt (number);
   89     if (res > 1000)
   90       THROW(E2BIG);
   91   } CATCH (E2BIG) {
   92     printf ("number too big\n");
   93   } ENDTRY;
   94 
   95   printf("result = %li\n\n", res);
   96 }
   97 
   98 int
   99 main (int argc, char ** argv)
  100 {
  101   TRY {
  102     if (argc != 2)
  103       THROW_WITH_DATA(EINVAL, (void *) "bad argc!");
  104 
  105     nested (argv[1]);
  106 
  107   } CATCH_WITH_DATA (EINVAL, errstr) {
  108     printf("usage: trycatch arg   - (%s)\n\n", (char *) errstr);
  109   } ENDTRY;
  110 
  111   exit (EXIT_SUCCESS);
  112 }
  113