libtrycatch  Check-in [6d268ced53]

Overview
Comment:Initial import
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | descendants | trunk
Files: files | file ages | folders
SHA3-256: 6d268ced53418c1c53e0788daab93912c72627932f4c641b1deaa5cfd4adf6af
User & Date: js on 2014-05-14 21:20:55
Other Links: manifest | tags
Context
2017-01-22
15:48
Rename the include guard check-in: 86d6342f24 user: js tags: trunk
2014-05-14
21:20
Initial import check-in: 6d268ced53 user: js tags: trunk
Changes

Added Makefile version [3d1998ff41].



























>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
CC ?= clang
CFLAGS ?= -Weverything -std=c11

## For C11
#CFLAGS += -DTRYCATCH_THREAD_LOCAL=_Thread_local
## For GCC / Clang
#CFLAGS += -DTRYCATCH_THREAD_LOCAL=__thread

libtrycatch.a: trycatch.o
	ar cr $@ $<

example: example.o libtrycatch.a
	${CC} -L. -ltrycatch -o $@ $<

Added README version [1e0ef6dba3].





>
>
1
2
This is a small library providing C++-like try/catch for C with almost
exactly the same syntax, see example.c.

Added example.c version [97c5c8de55].



















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * Copyright (c) 2014, Jonathan Schleifer <js@webkeks.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include "trycatch.h"

int
main()
{
	try {
		puts("try1");

		try {
			puts("try2");
		} catch (ex) {
			(void)ex;
			puts("this should not be called");
		}

		throw(5);
	} catch (ex) {
		printf("caught %d (should be 5)\n", ex);
	}

	try {
		throw(1);
		return 1;
	} catch (ex) {
		(void)ex;
	}

	return 0;
}

Added trycatch.c version [f4adc5ccdf].



















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * Copyright (c) 2014, Jonathan Schleifer <js@webkeks.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>

#include "trycatch.h"

#ifndef TRYCATCH_THREAD_LOCAL
# define TRYCATCH_THREAD_LOCAL
#endif

static TRYCATCH_THREAD_LOCAL struct trycatch_frame *trycatch_frames = NULL;

struct trycatch_frame*
trycatch_frame_push()
{
	struct trycatch_frame *frame;

	if ((frame = malloc(sizeof(*frame))) == NULL) {
		fputs("Not enough memory to allocate exception frame!\n",
		    stderr);
		abort();
	}

	frame->prev = trycatch_frames;
	trycatch_frames = frame;

	return frame;
}

void
trycatch_frame_pop()
{
	struct trycatch_frame *frame = trycatch_frames;
	trycatch_frames = frame->prev;
	free(frame);
}

void _Noreturn
trycatch_throw(int ex)
{
	if (trycatch_frames == NULL) {
		fputs("Exception with no handler!\n", stderr);
		abort();
	}

	longjmp(*trycatch_frames->jmpbuf, ex);
}

Added trycatch.h version [ed53b12ee4].



































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * Copyright (c) 2014, Jonathan Schleifer <js@webkeks.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __TRYCATCH_H__
#define __TRYCATCH_H__

#include <setjmp.h>
#include <stdnoreturn.h>

#define TRYCATCH_CONCAT2(a, b) a ## b
#define TRYCATCH_CONCAT(a, b) TRYCATCH_CONCAT2(a, b)
#ifndef TRYCATCH_NORETURN
# define TRYCATCH_NORETURN
#endif
#define try								   \
	struct trycatch_frame *TRYCATCH_CONCAT(trycatch_frame, __LINE__);  \
	jmp_buf TRYCATCH_CONCAT(trycatch_jmpbuf, __LINE__);		   \
	TRYCATCH_CONCAT(trycatch_frame, __LINE__) = trycatch_frame_push(); \
	trycatch_ex = setjmp(TRYCATCH_CONCAT(trycatch_jmpbuf, __LINE__));  \
	if (trycatch_ex == 0)						   \
		TRYCATCH_CONCAT(trycatch_frame, __LINE__)->jmpbuf =	   \
		    &TRYCATCH_CONCAT(trycatch_jmpbuf, __LINE__);	   \
	if (trycatch_ex == 0)
#define catch(ex)							\
	trycatch_frame_pop();						\
	for (int ex = trycatch_ex; trycatch_ex != 0; trycatch_ex = 0)
#define throw(ex) trycatch_throw(ex)
#define rethrow trycatch_throw(trycatch_ex)

struct trycatch_frame {
	jmp_buf *jmpbuf;
	struct trycatch_frame *prev;
};

static int trycatch_ex;

struct trycatch_frame *trycatch_frame_push(void);
void trycatch_frame_pop(void);
void TRYCATCH_NORETURN trycatch_throw(int ex);

#endif