Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
3
 * It is copyright by its individual contributors, as recorded in the
4
 * project's Git history.  See COPYING.txt at the top level for license
5
 * terms and a link to the Git history.
6
 */
7
 
8
#pragma once
9
#include <cstdio>
10
#include <inttypes.h>
11
#include "valptridx.h"
12
#include <memory>
13
 
14
namespace {
15
namespace untyped_index_mismatch_exception
16
{
17
#ifdef DXX_VALPTRIDX_ENABLE_REPORT_FILENAME
18
#define REPORT_STANDARD_LEADER_TEXT	"%s:%u: "
19
#else
20
#define REPORT_STANDARD_LEADER_TEXT
21
#endif
22
#define REPORT_STANDARD_FORMAT	" base=%p size=%lu"
23
#define REPORT_STANDARD_ARGUMENTS	array_base, array_size
24
#define REPORT_STANDARD_SIZE	(	\
25
		sizeof(REPORT_FORMAT_STRING) +	\
26
		42 /* length of longest filename in `git ls-files` */ +	\
27
		sizeof("65535") + /* USHORT_MAX for lineno */	\
28
		sizeof("0x0000000000000000") + /* for pointer from base=%p */	\
29
		sizeof("18446744073709551615") /* for size from size=%lu */	\
30
	)
31
#define REPORT_FORMAT_STRING	REPORT_STANDARD_LEADER_TEXT "pointer/index mismatch:" REPORT_STANDARD_FORMAT " index=%li expected=%p actual=%p"
32
	static constexpr std::size_t report_buffer_size = REPORT_STANDARD_SIZE + (sizeof("0x0000000000000000") * 2) + sizeof("18446744073709551615");
33
	__attribute_cold
34
	__attribute_unused
35
	static void prepare_report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const void *const array_base, const long supplied_index, const void *const expected_pointer, const void *const actual_pointer, char (&buf)[report_buffer_size], const unsigned long array_size)
36
	{
37
		snprintf(buf, sizeof(buf), REPORT_FORMAT_STRING, DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS REPORT_STANDARD_ARGUMENTS, supplied_index, expected_pointer, actual_pointer);
38
	}
39
#undef REPORT_FORMAT_STRING
40
}
41
 
42
namespace untyped_index_range_exception
43
{
44
#define REPORT_FORMAT_STRING	REPORT_STANDARD_LEADER_TEXT "invalid index used in array subscript:" REPORT_STANDARD_FORMAT " index=%li"
45
	static constexpr std::size_t report_buffer_size = REPORT_STANDARD_SIZE + sizeof("18446744073709551615");
46
	__attribute_cold
47
	__attribute_unused
48
	static void prepare_report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const void *const array_base, const long supplied_index, char (&buf)[report_buffer_size], const unsigned long array_size)
49
	{
50
		snprintf(buf, sizeof(buf), REPORT_FORMAT_STRING, DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS REPORT_STANDARD_ARGUMENTS, supplied_index);
51
	}
52
#undef REPORT_FORMAT_STRING
53
}
54
 
55
namespace untyped_null_pointer_conversion_exception
56
{
57
#define REPORT_FORMAT_STRING	REPORT_STANDARD_LEADER_TEXT "NULL pointer converted"
58
	static constexpr std::size_t report_buffer_size = REPORT_STANDARD_SIZE;
59
	__attribute_cold
60
	__attribute_unused
61
	static void prepare_report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS char (&buf)[report_buffer_size])
62
	{
63
		snprintf(buf, sizeof(buf), REPORT_FORMAT_STRING DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_L_PASS_VARS);
64
	}
65
#undef REPORT_FORMAT_STRING
66
}
67
 
68
namespace untyped_null_pointer_exception
69
{
70
#define REPORT_FORMAT_STRING	REPORT_STANDARD_LEADER_TEXT "NULL pointer used:" REPORT_STANDARD_FORMAT
71
	static constexpr std::size_t report_buffer_size = REPORT_STANDARD_SIZE;
72
	__attribute_cold
73
	__attribute_unused
74
	static void prepare_report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const void *const array_base, char (&buf)[report_buffer_size], const unsigned long array_size)
75
	{
76
		snprintf(buf, sizeof(buf), REPORT_FORMAT_STRING, DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS REPORT_STANDARD_ARGUMENTS);
77
	}
78
#undef REPORT_FORMAT_STRING
79
#undef REPORT_STANDARD_LEADER_TEXT
80
#undef REPORT_STANDARD_SIZE
81
#undef REPORT_STANDARD_ARGUMENTS
82
#undef REPORT_STANDARD_FORMAT
83
}
84
}
85
 
86
template <typename managed_type>
87
void valptridx<managed_type>::index_mismatch_exception::report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const array_managed_type *const array, const index_type supplied_index, const const_pointer_type expected_pointer, const const_pointer_type actual_pointer)
88
{
89
	using namespace untyped_index_mismatch_exception;
90
	char buf[report_buffer_size];
91
	prepare_report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS array, supplied_index, expected_pointer, actual_pointer, buf, array_size);
92
	throw index_mismatch_exception(buf);
93
}
94
 
95
template <typename managed_type>
96
void valptridx<managed_type>::index_range_exception::report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const array_managed_type *array, const long supplied_index)
97
{
98
	using namespace untyped_index_range_exception;
99
	char buf[report_buffer_size];
100
	prepare_report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS array, supplied_index, buf, array_size);
101
	throw index_range_exception(buf);
102
}
103
 
104
template <typename managed_type>
105
void valptridx<managed_type>::null_pointer_exception::report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_N_DEFN_VARS)
106
{
107
	using namespace untyped_null_pointer_conversion_exception;
108
	char buf[report_buffer_size];
109
	prepare_report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS buf);
110
	throw null_pointer_exception(buf);
111
}
112
 
113
template <typename managed_type>
114
void valptridx<managed_type>::null_pointer_exception::report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const array_managed_type *const array)
115
{
116
	using namespace untyped_null_pointer_exception;
117
	char buf[report_buffer_size];
118
	prepare_report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS array, buf, array_size);
119
	throw null_pointer_exception(buf);
120
}