c实现异常捕获try-catch组件

发布时间 2023-06-08 14:25:33作者: 墨尔基阿德斯

前言

  本文用纯c的代码,实现异常捕获try-catch组件。阅读本文需要时刻牢记setjmp和longjmp的对应关系。

  本专栏知识点是通过零声教育的线上课学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接 C/C++后台高级服务器课程介绍 详细查看课程的服务。

try / catch / finally / throw 介绍

  在java,python,c++里面都有try catch异常捕获。在try代码块里面执行的函数,如果出错有异常了,就会throw把异常抛出来,抛出来的异常被catch接收进行处理,而finally意味着无论有没有异常,都会执行finally代码块内的代码。

try{
    connect_sql();//throw
}catch(){

}finally {

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如何实现try-catch这一机制?

  关于跳转,有两个跳转。那么在这里我们必然选用长跳转。

  1. goto:函数内跳转,短跳转
  2. setjmp/longjmp:跨函数跳转,长跳转

  setjmp/longjmp这两个函数是不存在压栈出栈的,也就是说longjmp跳转到setjmp的地方后,会覆盖之前的栈。

setjmp/longjmp使用介绍(重点)

  • setjmp(env):设置跳转的位置,第一次返回0,后续返回longjmp的第二个参数
  • longjmp(env, idx):跳转到设置env的位置,第二个参数就是setjmp()的返回值
#include <stdio.h>
#include <setjmp.h>

jmp_buf env;
int count = 0;

void sub_func(int idx) {
printf("sub_func -->idx : %d\n", idx);
//第二个参数就是setjmp()的返回值
longjmp(env, idx);
}

int main() {
int idx = 0;
//设置跳转标签,第一次返回0
count = setjmp(env);
if (count 0) {
printf("count : %d\n", count);
sub_func(++idx);
}
else if (count 1) {
printf("count : %d\n", count);
sub_func(++idx);
}
else if (count == 2) {
printf("count : %d\n", count);
sub_func(++idx);
}
else {
printf("other count \n");
}

<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
count : 0
sub_func -->idx : 1
count : 1
sub_func -->idx : 2
count : 2
sub_func -->idx : 3
other count 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

try-catch 和 setjmp/longjmp 的关系

try ---> setjmp(env)

throw ---> longjmp(env,Exception)

catch(Exception)

  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

  我们其实可以分析出来,setjmp和count==0的地方,相当于try,后面的else if 相当于catch,最后一个else,其实并不是finally,因为finally是不管怎么样都会执行,上图我标注的其实是误导的。应该是下图这样才对。

在这里插入图片描述
在这里插入图片描述

宏定义实现try-catch Demo

  4个关键字分析出来它们的关系之后,其实我们就能用宏定义来实现了。

#include <stdio.h>
#include <setjmp.h>

typedef struct _Exception {
jmp_buf env;
int exceptype;
} Exception;

#define Try(excep) if((excep.exceptype=setjmp(excep.env))0)
#define Catch(excep, ExcepType) else if(excep.exceptypeExcepType)
#define Throw(excep, ExcepType) longjmp(excep.env,ExcepType)
#define Finally

void throw_func(Exception ex, int idx) {
printf("throw_func -->idx : %d\n", idx);
Throw(ex, idx);
}

int main() {
int idx = 0;

Exception ex<span class="token punctuation">;</span>
<span class="token function">Try</span><span class="token punctuation">(</span>ex<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"ex.exceptype : %d\n"</span><span class="token punctuation">,</span> ex<span class="token punctuation">.</span>exceptype<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">throw_func</span><span class="token punctuation">(</span>ex<span class="token punctuation">,</span> <span class="token operator">++</span>idx<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">Catch</span><span class="token punctuation">(</span>ex<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"ex.exceptype : %d\n"</span><span class="token punctuation">,</span> ex<span class="token punctuation">.</span>exceptype<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">Catch</span><span class="token punctuation">(</span>ex<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"ex.exceptype : %d\n"</span><span class="token punctuation">,</span> ex<span class="token punctuation">.</span>exceptype<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">Catch</span><span class="token punctuation">(</span>ex<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"ex.exceptype : %d\n"</span><span class="token punctuation">,</span> ex<span class="token punctuation">.</span>exceptype<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
Finally<span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Finally\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
ex.exceptype : 0
throw_func -->idx : 1
ex.exceptype : 1
Finally
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

实现try-catch的三个问题

  虽然现在demo版看起来像这么回事了,但是还是有两个问题:

  1. 在哪个文件哪个函数哪个行抛的异常?
  2. try-catch嵌套怎么做?
  3. try-catch线程安全怎么做?

1. 在哪个文件哪个函数哪个行抛的异常

  系统提供了三个宏可以供我们使用,如果我们没有catch到异常,我们就可以打印出来

__func__, __FILE__, __LINE__
  • 1

2. try-catch嵌套怎么做?

  我们知道try-catch是可以嵌套的,那么这就形成了一个栈的数据结构,现在下面有三个try,每个setjmp对应的都是不同的jmp_buf,那么我们可以定义一个jmp_buf的栈。

try{
    try{
        try{
    <span class="token punctuation">}</span><span class="token keyword">catch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>

    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token keyword">catch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>

<span class="token punctuation">}</span>

}catch(){

}finally{

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

  那么我们很容易能写出来,既然是栈,try的时候我们就插入一个结点,catch的时候我们就pop一个出来。

#define EXCEPTION_MESSAGE_LENGTH                512

typedef struct _ntyException {
const char *name;
} ntyException;

ntyException SQLException = {"SQLException"};
ntyException TimeoutException = {"TimeoutException"};

typedef struct _ntyExceptionFrame {
jmp_buf env;

<span class="token keyword">int</span> line<span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>func<span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>file<span class="token punctuation">;</span>

ntyException <span class="token operator">*</span>exception<span class="token punctuation">;</span>
<span class="token keyword">struct</span> <span class="token class-name">_ntyExceptionFrame</span> <span class="token operator">*</span>next<span class="token punctuation">;</span>

<span class="token keyword">char</span> message<span class="token punctuation">[</span>EXCEPTION_MESSAGE_LENGTH <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

} ntyExceptionFrame;

enum {
ExceptionEntered = 0,//0
ExceptionThrown, //1
ExceptionHandled, //2
ExceptionFinalized//3
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

3. try-catch线程安全

  每个线程都可以try-catch,但是我们以及知道了是个栈结构,既ExceptionStack,那么每个线程是独有一个ExceptionStack呢?还是共享同一个ExceptionStack?很明显,A线程的异常应该有A的处理,而不是由B线程处理。那么我们就使用Linux线程私有数据Thread-specific Data(TSD) 详解来做。

/* ** **** ******** **************** Thread safety **************** ******** **** ** */

#define ntyThreadLocalData pthread_key_t
#define ntyThreadLocalDataSet(key, value) pthread_setspecific((key), (value))
#define ntyThreadLocalDataGet(key) pthread_getspecific((key))
#define ntyThreadLocalDataCreate(key) pthread_key_create(&(key), NULL)

ntyThreadLocalData ExceptionStack;

static void init_once(void) {
ntyThreadLocalDataCreate(ExceptionStack);
}

static pthread_once_t once_control = PTHREAD_ONCE_INIT;

void ntyExceptionInit(void) {
pthread_once(&once_control, init_once);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

代码实现与解释

try

  首先创建一个新节点入栈,然后setjmp设置一个标记,接下来就是大括号里面的操作了,如果有异常,那么就会被throw抛出来,为什么这里最后一行是if?因为longjmp的时候,返回的地方是setjmp,不要忘了!要时刻扣住longjmp和setjmp。

#define Try do {                                                                        \
            volatile int Exception_flag;                                                \
            ntyExceptionFrame frame;                                                    \
            frame.message[0] = 0;                                                       \
            frame.next = (ntyExceptionFrame*)ntyThreadLocalDataGet(ExceptionStack);     \
            ntyThreadLocalDataSet(ExceptionStack, &frame);                              \
            Exception_flag = setjmp(frame.env);                                         \
            if (Exception_flag == ExceptionEntered) {
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
Try{
	//...
    Throw(A, "A");
}
  • 1
  • 2
  • 3
  • 4

throw

  在这里,我们不应该把throw定义成宏,而应该定义成函数。这里分两类,一类是try里面的throw,一类是没有try直接throw。

  • 对于try里面的异常,我们将其状态变成ExceptionThrown,然后longjmp到setjmp的地方,由catch处理
  • 对于直接抛的异常,必然没有catch去捕获,那么我们直接打印出来
  • 如果第一种情况的异常,没有被catch捕获到怎么办呢?后面会被ReThrow出来,对于再次被抛出,我们就直接进行打印异常

  这里的##__VA_ARGS__是可变参数,具体不多介绍了,不是本文重点。

#define ReThrow                    ntyExceptionThrow(frame.exception, frame.func, frame.file, frame.line, NULL)
#define Throw(e, cause, ...)    ntyExceptionThrow(&(e), __func__, __FILE__, __LINE__, cause, ##__VA_ARGS__,NULL)
  • 1
  • 2
void ntyExceptionThrow(ntyException *excep, const char *func, const char *file, int line, const char *cause, ...) {
    va_list ap;
    ntyExceptionFrame *frame = (ntyExceptionFrame *) ntyThreadLocalDataGet(ExceptionStack);
<span class="token keyword">if</span> <span class="token punctuation">(</span>frame<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token comment">//异常名</span>
    frame<span class="token operator">-&gt;</span>exception <span class="token operator">=</span> excep<span class="token punctuation">;</span>
    frame<span class="token operator">-&gt;</span>func <span class="token operator">=</span> func<span class="token punctuation">;</span>
    frame<span class="token operator">-&gt;</span>file <span class="token operator">=</span> file<span class="token punctuation">;</span>
    frame<span class="token operator">-&gt;</span>line <span class="token operator">=</span> line<span class="token punctuation">;</span>
    <span class="token comment">//异常打印的信息</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>cause<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        <span class="token function">va_start</span><span class="token punctuation">(</span>ap<span class="token punctuation">,</span> cause<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">vsnprintf</span><span class="token punctuation">(</span>frame<span class="token operator">-&gt;</span>message<span class="token punctuation">,</span> EXCEPTION_MESSAGE_LENGTH<span class="token punctuation">,</span> cause<span class="token punctuation">,</span> ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">va_end</span><span class="token punctuation">(</span>ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    ntyExceptionPopStack<span class="token punctuation">;</span>

    <span class="token function">longjmp</span><span class="token punctuation">(</span>frame<span class="token operator">-&gt;</span>env<span class="token punctuation">,</span> ExceptionThrown<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
    <span class="token comment">//没有被catch,直接throw</span>
<span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cause<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token keyword">char</span> message<span class="token punctuation">[</span>EXCEPTION_MESSAGE_LENGTH <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

    <span class="token function">va_start</span><span class="token punctuation">(</span>ap<span class="token punctuation">,</span> cause<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">vsnprintf</span><span class="token punctuation">(</span>message<span class="token punctuation">,</span> EXCEPTION_MESSAGE_LENGTH<span class="token punctuation">,</span> cause<span class="token punctuation">,</span> ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">va_end</span><span class="token punctuation">(</span>ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%s: %s\n raised in %s at %s:%d\n"</span><span class="token punctuation">,</span> excep<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> message<span class="token punctuation">,</span> func <span class="token operator">?</span> func <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> file <span class="token operator">?</span> file <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%s: %p\n raised in %s at %s:%d\n"</span><span class="token punctuation">,</span> excep<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> excep<span class="token punctuation">,</span> func <span class="token operator">?</span> func <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> file <span class="token operator">?</span> file <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

Catch

  如果还是ExceptionEntered状态,说明没有异常,没有throw。如果捕获到异常了,那么其状态就是ExceptionHandled。

#define Catch(nty_exception) \
                if (Exception_flag == ExceptionEntered) ntyExceptionPopStack; \
            } else if (frame.exception == &(nty_exception)) { \
                Exception_flag = ExceptionHandled;
  • 1
  • 2
  • 3
  • 4

Finally

  finally也是一样,如果还是ExceptionEntered状态,说明没有异常没有捕获,那么现在状态是终止阶段。

#define Finally \
                if (Exception_flag == ExceptionEntered) ntyExceptionPopStack; \
            } { \
                if (Exception_flag == ExceptionEntered)    \
                    Exception_flag = ExceptionFinalized;
  • 1
  • 2
  • 3
  • 4
  • 5

EndTry

  有些人看到EndTry可能会有疑问,try-catch一共不就4个关键字吗?怎么你多了一个。我们先来看看EndTry做了什么,首先如果是ExceptionEntered状态,那意味着什么?意味着没有throw,没有catch,没有finally,只有try,我们需要对这种情况进行处理,要出栈。还有一种情况,如果是ExceptionThrown状态,说明什么?没有被catch捕获到,那么我们就再次抛出,进行打印错误。至于为什么多个EndTry,写起来方便呗~

#define EndTry \
                if (Exception_flag == ExceptionEntered) ntyExceptionPopStack; \
            } if (Exception_flag == ExceptionThrown) {ReThrow;} \
            } while (0)
  • 1
  • 2
  • 3
  • 4

try-catch代码

/* ** **** ******** **************** try / catch / finally / throw **************** ******** **** ** */

#define EXCEPTION_MESSAGE_LENGTH 512

typedef struct _ntyException {
const char *name;
} ntyException;

ntyException SQLException = {"SQLException"};
ntyException TimeoutException = {"TimeoutException"};

typedef struct _ntyExceptionFrame {
jmp_buf env;

<span class="token keyword">int</span> line<span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>func<span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>file<span class="token punctuation">;</span>

ntyException <span class="token operator">*</span>exception<span class="token punctuation">;</span>
<span class="token keyword">struct</span> <span class="token class-name">_ntyExceptionFrame</span> <span class="token operator">*</span>next<span class="token punctuation">;</span>

<span class="token keyword">char</span> message<span class="token punctuation">[</span>EXCEPTION_MESSAGE_LENGTH <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

} ntyExceptionFrame;

enum {
ExceptionEntered = 0,//0
ExceptionThrown, //1
ExceptionHandled, //2
ExceptionFinalized//3
};

#define ntyExceptionPopStack </span>
ntyThreadLocalDataSet(ExceptionStack, ((ntyExceptionFrame*)ntyThreadLocalDataGet(ExceptionStack))->next)

#define ReThrow ntyExceptionThrow(frame.exception, frame.func, frame.file, frame.line, NULL)
#define Throw(e, cause, ...) ntyExceptionThrow(&(e), func, FILE, LINE, cause, ##VA_ARGS,NULL)

#define Try do { </span>
volatile int Exception_flag; </span>
ntyExceptionFrame frame; </span>
frame.message[0] = 0; </span>
frame.next = (ntyExceptionFrame*)ntyThreadLocalDataGet(ExceptionStack); </span>
ntyThreadLocalDataSet(ExceptionStack, &frame); </span>
Exception_flag = setjmp(frame.env); </span>
if (Exception_flag == ExceptionEntered) {

#define Catch(nty_exception) </span>
if (Exception_flag ExceptionEntered) ntyExceptionPopStack; </span>
} else if (frame.exception &(nty_exception)) { </span>
Exception_flag = ExceptionHandled;

#define Finally </span>
if (Exception_flag ExceptionEntered) ntyExceptionPopStack; </span>
} { </span>
if (Exception_flag ExceptionEntered) </span>
Exception_flag = ExceptionFinalized;

#define EndTry </span>
if (Exception_flag ExceptionEntered) ntyExceptionPopStack; </span>
} if (Exception_flag ExceptionThrown) {ReThrow;} </span>
} while (0)

void ntyExceptionThrow(ntyException excep, const char func, const char file, int line, const char cause, ...) {
va_list ap;
ntyExceptionFrame frame = (ntyExceptionFrame ) ntyThreadLocalDataGet(ExceptionStack);

<span class="token keyword">if</span> <span class="token punctuation">(</span>frame<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token comment">//异常名</span>
    frame<span class="token operator">-&gt;</span>exception <span class="token operator">=</span> excep<span class="token punctuation">;</span>
    frame<span class="token operator">-&gt;</span>func <span class="token operator">=</span> func<span class="token punctuation">;</span>
    frame<span class="token operator">-&gt;</span>file <span class="token operator">=</span> file<span class="token punctuation">;</span>
    frame<span class="token operator">-&gt;</span>line <span class="token operator">=</span> line<span class="token punctuation">;</span>
    <span class="token comment">//异常打印的信息</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>cause<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        <span class="token function">va_start</span><span class="token punctuation">(</span>ap<span class="token punctuation">,</span> cause<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">vsnprintf</span><span class="token punctuation">(</span>frame<span class="token operator">-&gt;</span>message<span class="token punctuation">,</span> EXCEPTION_MESSAGE_LENGTH<span class="token punctuation">,</span> cause<span class="token punctuation">,</span> ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">va_end</span><span class="token punctuation">(</span>ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    ntyExceptionPopStack<span class="token punctuation">;</span>

    <span class="token function">longjmp</span><span class="token punctuation">(</span>frame<span class="token operator">-&gt;</span>env<span class="token punctuation">,</span> ExceptionThrown<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
    <span class="token comment">//没有被catch,直接throw</span>
<span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cause<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token keyword">char</span> message<span class="token punctuation">[</span>EXCEPTION_MESSAGE_LENGTH <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

    <span class="token function">va_start</span><span class="token punctuation">(</span>ap<span class="token punctuation">,</span> cause<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">vsnprintf</span><span class="token punctuation">(</span>message<span class="token punctuation">,</span> EXCEPTION_MESSAGE_LENGTH<span class="token punctuation">,</span> cause<span class="token punctuation">,</span> ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">va_end</span><span class="token punctuation">(</span>ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%s: %s\n raised in %s at %s:%d\n"</span><span class="token punctuation">,</span> excep<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> message<span class="token punctuation">,</span> func <span class="token operator">?</span> func <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> file <span class="token operator">?</span> file <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%s: %p\n raised in %s at %s:%d\n"</span><span class="token punctuation">,</span> excep<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> excep<span class="token punctuation">,</span> func <span class="token operator">?</span> func <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> file <span class="token operator">?</span> file <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99

Debug测试代码


/* ** **** ******** **************** debug **************** ******** **** ** */

ntyException A = {"AException"};
ntyException B = {"BException"};
ntyException C = {"CException"};
ntyException D = {"DException"};

void thread(void args) {
pthread_t selfid = pthread_self();
Try
{
Throw(A, "A");
}
Catch (A)
{
printf("catch A : %ld\n", selfid);
}
EndTry;

Try
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>B<span class="token punctuation">,</span> <span class="token string">"B"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>B<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
EndTry<span class="token punctuation">;</span>

Try
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>C<span class="token punctuation">,</span> <span class="token string">"C"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>C<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch C : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
EndTry<span class="token punctuation">;</span>

Try
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>D<span class="token punctuation">,</span> <span class="token string">"D"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>D<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch D : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
EndTry<span class="token punctuation">;</span>

Try
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token string">"A Again"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>B<span class="token punctuation">,</span> <span class="token string">"B Again"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>C<span class="token punctuation">,</span> <span class="token string">"C Again"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>D<span class="token punctuation">,</span> <span class="token string">"D Again"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>A<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch A again : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>B<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B again : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>C<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch C again : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>D<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B again : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
EndTry<span class="token punctuation">;</span>

}

#define PTHREAD_NUM 8

int main(void) {
ntyExceptionInit();

<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test1: Throw\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    <span class="token function">Throw</span><span class="token punctuation">(</span>D<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment">//ntyExceptionThrow(&amp;(D), "_function_name_", "_file_name_", 202, ((void *) 0), ((void *) 0))</span>
    <span class="token function">Throw</span><span class="token punctuation">(</span>C<span class="token punctuation">,</span> <span class="token string">"null C"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//ntyExceptionThrow(&amp;(C), "_function_name_", "_file_name_", 203, "null C", ((void *) 0))</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test1: Ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test2: Try-Catch Double Nesting\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    Try
            <span class="token punctuation">{<!-- --></span>
                Try
                        <span class="token punctuation">{<!-- --></span>
                            <span class="token function">Throw</span><span class="token punctuation">(</span>B<span class="token punctuation">,</span> <span class="token string">"call B"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                    <span class="token function">Catch</span> <span class="token punctuation">(</span>B<span class="token punctuation">)</span>
                        <span class="token punctuation">{<!-- --></span>
                            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B \n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                EndTry<span class="token punctuation">;</span>
                <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token function">Catch</span><span class="token punctuation">(</span>A<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch A \n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Result: Ok\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    EndTry<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test2: Ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test3: Try-Catch Triple  Nesting\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    Try
            <span class="token punctuation">{<!-- --></span>
                Try
                        <span class="token punctuation">{<!-- --></span>

                            Try
                                    <span class="token punctuation">{<!-- --></span>
                                        <span class="token function">Throw</span><span class="token punctuation">(</span>C<span class="token punctuation">,</span> <span class="token string">"call C"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                                    <span class="token punctuation">}</span>
                                <span class="token function">Catch</span> <span class="token punctuation">(</span>C<span class="token punctuation">)</span>
                                    <span class="token punctuation">{<!-- --></span>
                                        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch C\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                                    <span class="token punctuation">}</span>
                            EndTry<span class="token punctuation">;</span>
                            <span class="token function">Throw</span><span class="token punctuation">(</span>B<span class="token punctuation">,</span> <span class="token string">"call B"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                    <span class="token function">Catch</span> <span class="token punctuation">(</span>B<span class="token punctuation">)</span>
                        <span class="token punctuation">{<!-- --></span>
                            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                EndTry<span class="token punctuation">;</span>
                <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token function">Catch</span><span class="token punctuation">(</span>A<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch A\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    EndTry<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test3: Ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test4: Test Thread-safeness\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
pthread_t th_id<span class="token punctuation">[</span>PTHREAD_NUM<span class="token punctuation">]</span><span class="token punctuation">;</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> PTHREAD_NUM<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">pthread_create</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>th_id<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> thread<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> PTHREAD_NUM<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">pthread_join</span><span class="token punctuation">(</span>th_id<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test4: Ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test5: No Success Catch\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    Try
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token string">"no catch A ,should Rethrow"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    EndTry<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test5: Rethrow Success\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test6: Normal Test\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    Try
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token string">"call A"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token function">Catch</span><span class="token punctuation">(</span>A<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch A\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token punctuation">}</span>
        Finally
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"wxf nb\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">;</span>
    EndTry<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test6: ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192

线程安全、try-catch、Debug测试代码 汇总

#include <stdio.h>
#include <setjmp.h>
#include <pthread.h>
#include <stdarg.h>

/* ** **** ******** **************** Thread safety **************** ******** **** ** */

#define ntyThreadLocalData pthread_key_t
#define ntyThreadLocalDataSet(key, value) pthread_setspecific((key), (value))
#define ntyThreadLocalDataGet(key) pthread_getspecific((key))
#define ntyThreadLocalDataCreate(key) pthread_key_create(&(key), NULL)

ntyThreadLocalData ExceptionStack;

static void init_once(void) {
ntyThreadLocalDataCreate(ExceptionStack);
}

static pthread_once_t once_control = PTHREAD_ONCE_INIT;

void ntyExceptionInit(void) {
pthread_once(&once_control, init_once);
}

/* ** **** ******** **************** try / catch / finally / throw **************** ******** **** ** */

#define EXCEPTION_MESSAGE_LENGTH 512

typedef struct _ntyException {
const char *name;
} ntyException;

ntyException SQLException = {"SQLException"};
ntyException TimeoutException = {"TimeoutException"};

typedef struct _ntyExceptionFrame {
jmp_buf env;

<span class="token keyword">int</span> line<span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>func<span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>file<span class="token punctuation">;</span>

ntyException <span class="token operator">*</span>exception<span class="token punctuation">;</span>
<span class="token keyword">struct</span> <span class="token class-name">_ntyExceptionFrame</span> <span class="token operator">*</span>next<span class="token punctuation">;</span>

<span class="token keyword">char</span> message<span class="token punctuation">[</span>EXCEPTION_MESSAGE_LENGTH <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

} ntyExceptionFrame;

enum {
ExceptionEntered = 0,//0
ExceptionThrown, //1
ExceptionHandled, //2
ExceptionFinalized//3
};

#define ntyExceptionPopStack </span>
ntyThreadLocalDataSet(ExceptionStack, ((ntyExceptionFrame*)ntyThreadLocalDataGet(ExceptionStack))->next)

#define ReThrow ntyExceptionThrow(frame.exception, frame.func, frame.file, frame.line, NULL)
#define Throw(e, cause, ...) ntyExceptionThrow(&(e), func, FILE, LINE, cause, ##VA_ARGS,NULL)

#define Try do { </span>
volatile int Exception_flag; </span>
ntyExceptionFrame frame; </span>
frame.message[0] = 0; </span>
frame.next = (ntyExceptionFrame*)ntyThreadLocalDataGet(ExceptionStack); </span>
ntyThreadLocalDataSet(ExceptionStack, &frame); </span>
Exception_flag = setjmp(frame.env); </span>
if (Exception_flag == ExceptionEntered) {

#define Catch(nty_exception) </span>
if (Exception_flag ExceptionEntered) ntyExceptionPopStack; </span>
} else if (frame.exception &(nty_exception)) { </span>
Exception_flag = ExceptionHandled;

#define Finally </span>
if (Exception_flag ExceptionEntered) ntyExceptionPopStack; </span>
} { </span>
if (Exception_flag ExceptionEntered) </span>
Exception_flag = ExceptionFinalized;

#define EndTry </span>
if (Exception_flag ExceptionEntered) ntyExceptionPopStack; </span>
} if (Exception_flag ExceptionThrown) {ReThrow;} </span>
} while (0)

void ntyExceptionThrow(ntyException excep, const char func, const char file, int line, const char cause, ...) {
va_list ap;
ntyExceptionFrame frame = (ntyExceptionFrame ) ntyThreadLocalDataGet(ExceptionStack);

<span class="token keyword">if</span> <span class="token punctuation">(</span>frame<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token comment">//异常名</span>
    frame<span class="token operator">-&gt;</span>exception <span class="token operator">=</span> excep<span class="token punctuation">;</span>
    frame<span class="token operator">-&gt;</span>func <span class="token operator">=</span> func<span class="token punctuation">;</span>
    frame<span class="token operator">-&gt;</span>file <span class="token operator">=</span> file<span class="token punctuation">;</span>
    frame<span class="token operator">-&gt;</span>line <span class="token operator">=</span> line<span class="token punctuation">;</span>
    <span class="token comment">//异常打印的信息</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>cause<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        <span class="token function">va_start</span><span class="token punctuation">(</span>ap<span class="token punctuation">,</span> cause<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">vsnprintf</span><span class="token punctuation">(</span>frame<span class="token operator">-&gt;</span>message<span class="token punctuation">,</span> EXCEPTION_MESSAGE_LENGTH<span class="token punctuation">,</span> cause<span class="token punctuation">,</span> ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">va_end</span><span class="token punctuation">(</span>ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    ntyExceptionPopStack<span class="token punctuation">;</span>

    <span class="token function">longjmp</span><span class="token punctuation">(</span>frame<span class="token operator">-&gt;</span>env<span class="token punctuation">,</span> ExceptionThrown<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
    <span class="token comment">//没有被catch,直接throw</span>
<span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cause<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token keyword">char</span> message<span class="token punctuation">[</span>EXCEPTION_MESSAGE_LENGTH <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

    <span class="token function">va_start</span><span class="token punctuation">(</span>ap<span class="token punctuation">,</span> cause<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">vsnprintf</span><span class="token punctuation">(</span>message<span class="token punctuation">,</span> EXCEPTION_MESSAGE_LENGTH<span class="token punctuation">,</span> cause<span class="token punctuation">,</span> ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">va_end</span><span class="token punctuation">(</span>ap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%s: %s\n raised in %s at %s:%d\n"</span><span class="token punctuation">,</span> excep<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> message<span class="token punctuation">,</span> func <span class="token operator">?</span> func <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> file <span class="token operator">?</span> file <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%s: %p\n raised in %s at %s:%d\n"</span><span class="token punctuation">,</span> excep<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> excep<span class="token punctuation">,</span> func <span class="token operator">?</span> func <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> file <span class="token operator">?</span> file <span class="token operator">:</span> <span class="token string">"?"</span><span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

/* ** **** ******** **************** debug **************** ******** **** ** */

ntyException A = {"AException"};
ntyException B = {"BException"};
ntyException C = {"CException"};
ntyException D = {"DException"};

void thread(void args) {
pthread_t selfid = pthread_self();
Try
{
Throw(A, "A");
}
Catch (A)
{
printf("catch A : %ld\n", selfid);
}
EndTry;

Try
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>B<span class="token punctuation">,</span> <span class="token string">"B"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>B<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
EndTry<span class="token punctuation">;</span>

Try
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>C<span class="token punctuation">,</span> <span class="token string">"C"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>C<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch C : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
EndTry<span class="token punctuation">;</span>

Try
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>D<span class="token punctuation">,</span> <span class="token string">"D"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>D<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch D : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
EndTry<span class="token punctuation">;</span>

Try
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token string">"A Again"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>B<span class="token punctuation">,</span> <span class="token string">"B Again"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>C<span class="token punctuation">,</span> <span class="token string">"C Again"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">Throw</span><span class="token punctuation">(</span>D<span class="token punctuation">,</span> <span class="token string">"D Again"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>A<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch A again : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>B<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B again : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>C<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch C again : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token function">Catch</span> <span class="token punctuation">(</span>D<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B again : %ld\n"</span><span class="token punctuation">,</span> selfid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
EndTry<span class="token punctuation">;</span>

}

#define PTHREAD_NUM 8

int main(void) {
ntyExceptionInit();

<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test1: Throw\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    <span class="token function">Throw</span><span class="token punctuation">(</span>D<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment">//ntyExceptionThrow(&amp;(D), "_function_name_", "_file_name_", 202, ((void *) 0), ((void *) 0))</span>
    <span class="token function">Throw</span><span class="token punctuation">(</span>C<span class="token punctuation">,</span> <span class="token string">"null C"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//ntyExceptionThrow(&amp;(C), "_function_name_", "_file_name_", 203, "null C", ((void *) 0))</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test1: Ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test2: Try-Catch Double Nesting\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    Try
            <span class="token punctuation">{<!-- --></span>
                Try
                        <span class="token punctuation">{<!-- --></span>
                            <span class="token function">Throw</span><span class="token punctuation">(</span>B<span class="token punctuation">,</span> <span class="token string">"call B"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                    <span class="token function">Catch</span> <span class="token punctuation">(</span>B<span class="token punctuation">)</span>
                        <span class="token punctuation">{<!-- --></span>
                            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B \n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                EndTry<span class="token punctuation">;</span>
                <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token function">Catch</span><span class="token punctuation">(</span>A<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch A \n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Result: Ok\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    EndTry<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test2: Ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test3: Try-Catch Triple  Nesting\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    Try
            <span class="token punctuation">{<!-- --></span>
                Try
                        <span class="token punctuation">{<!-- --></span>

                            Try
                                    <span class="token punctuation">{<!-- --></span>
                                        <span class="token function">Throw</span><span class="token punctuation">(</span>C<span class="token punctuation">,</span> <span class="token string">"call C"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                                    <span class="token punctuation">}</span>
                                <span class="token function">Catch</span> <span class="token punctuation">(</span>C<span class="token punctuation">)</span>
                                    <span class="token punctuation">{<!-- --></span>
                                        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch C\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                                    <span class="token punctuation">}</span>
                            EndTry<span class="token punctuation">;</span>
                            <span class="token function">Throw</span><span class="token punctuation">(</span>B<span class="token punctuation">,</span> <span class="token string">"call B"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                    <span class="token function">Catch</span> <span class="token punctuation">(</span>B<span class="token punctuation">)</span>
                        <span class="token punctuation">{<!-- --></span>
                            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch B\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                EndTry<span class="token punctuation">;</span>
                <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token function">Catch</span><span class="token punctuation">(</span>A<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch A\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    EndTry<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test3: Ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test4: Test Thread-safeness\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
pthread_t th_id<span class="token punctuation">[</span>PTHREAD_NUM<span class="token punctuation">]</span><span class="token punctuation">;</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> PTHREAD_NUM<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">pthread_create</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>th_id<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> thread<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> PTHREAD_NUM<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">pthread_join</span><span class="token punctuation">(</span>th_id<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test4: Ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test5: No Success Catch\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    Try
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token string">"no catch A ,should Rethrow"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    EndTry<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test5: Rethrow Success\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\n\n=&gt; Test6: Normal Test\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{<!-- --></span>
    Try
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">Throw</span><span class="token punctuation">(</span>A<span class="token punctuation">,</span> <span class="token string">"call A"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token function">Catch</span><span class="token punctuation">(</span>A<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"catch A\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token punctuation">}</span>
        Finally
            <span class="token punctuation">{<!-- --></span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"wxf nb\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">;</span>
    EndTry<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"=&gt; Test6: ok\n\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

void all() {
///try
do {
volatile int Exception_flag;
ntyExceptionFrame frame;
frame.message[0] = 0;
frame.next = (ntyExceptionFrame ) pthread_getspecific((ExceptionStack));
pthread_setspecific((ExceptionStack), (&frame));
Exception_flag = _setjmp(frame.env);
if (Exception_flag == ExceptionEntered) {
///
{
///try
do {
volatile int Exception_flag;
ntyExceptionFrame frame;
frame.message[0] = 0;
frame.next = (ntyExceptionFrame
) pthread_getspecific((ExceptionStack));
pthread_setspecific((ExceptionStack), (&frame));
Exception_flag = _setjmp(frame.env);
if (Exception_flag ExceptionEntered) {
///
{
///Throw(B, "recall B"); --->longjmp ExceptionThrown
ntyExceptionThrow(&(B), "function_name", "file_name", 302, "recall B", ((void *) 0));
///
}
///Catch (B)
if (Exception_flag ExceptionEntered)
ntyExceptionPopStack;
}
else if (frame.exception &(B)) {
Exception_flag = ExceptionHandled;
///
{ ///
printf("recall B \n");
///
}
fin
if (Exception_flag ExceptionEntered)
ntyExceptionPopStack;
if (Exception_flag ExceptionEntered)
Exception_flag = ExceptionFinalized;
/{
{
printf("fin\n");
};
}
///EndTry;
if (Exception_flag ExceptionEntered)
ntyExceptionPopStack;
}
if (Exception_flag ExceptionThrown)
ntyExceptionThrow(frame.exception, frame.func, frame.file, frame.line, ((void ) 0));
} while (0);
///Throw(A, NULL); longjmp ExceptionThrown
ntyExceptionThrow(&(A), "function_name", "file_name", 329, ((void
) 0), ((void *) 0));
///
}
///Catch(A)
if (Exception_flag ExceptionEntered)
ntyExceptionPopStack;
}
else if (frame.exception &(A)) {
Exception_flag = ExceptionHandled;
///
{
///
printf("\tResult: Ok\n");
///
}
/// EndTry;
if (Exception_flag ExceptionEntered)
ntyExceptionPopStack;
}
if (Exception_flag == ExceptionThrown)
ntyExceptionThrow(frame.exception, frame.func, frame.file, frame.line, ((void *) 0));
} while (0);
///
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397