1/*
2 * Copyright 2015 Canonical Limited
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * See the included COPYING file for more information.
10 *
11 * Author: Allison Ryan Lortie <desrt@desrt.ca>
12 */
13
14#include <glib.h>
15
16typedef struct
17{
18 gboolean success;
19 guint64 c, a, b;
20} Case;
21
22static void
23test_checked_guint_add (void)
24{
25 static const Case cases[] = {
26 /* success c = a + b */
27 { TRUE, 0, 0, 0 },
28 { TRUE, G_MAXINT, G_MAXINT, 0 },
29 { TRUE, G_MAXINT, 0, G_MAXINT },
30 { TRUE, G_MAXUINT, G_MAXUINT, 0 },
31 { TRUE, G_MAXUINT, 0, G_MAXUINT },
32 { TRUE, G_MAXUINT - 1, G_MAXINT, G_MAXINT },
33 { FALSE, 0, G_MAXUINT, 1 },
34 { FALSE, 0, 1, G_MAXUINT },
35 { FALSE, 0, G_MAXUINT, G_MAXUINT }
36 };
37 guint i;
38
39 for (i = 0; i < G_N_ELEMENTS (cases); i++)
40 {
41 guint result;
42
43 g_assert_cmpuint (cases[i].success, ==, g_uint_checked_add (&result, cases[i].a, cases[i].b));
44 if (cases[i].success)
45 g_assert_cmpuint (cases[i].c, ==, result);
46 }
47}
48
49static void
50test_checked_guint_mul (void)
51{
52 static const Case cases[] = {
53 /* success c = a * b */
54 { TRUE, 0, 0, 0 },
55 { TRUE, 0, G_MAXINT, 0 },
56 { TRUE, G_MAXINT, G_MAXINT, 1 },
57 { TRUE, 0, G_MAXUINT, 0 },
58 { TRUE, G_MAXUINT, G_MAXUINT, 1 },
59 { TRUE, 2 * (guint) G_MAXINT, 2, G_MAXINT },
60 { TRUE, 2 * (guint) G_MAXINT, G_MAXINT, 2 },
61 { FALSE, 0, 3, G_MAXINT },
62 { FALSE, 0, G_MAXINT, 3 }
63 };
64 guint i;
65
66 for (i = 0; i < G_N_ELEMENTS (cases); i++)
67 {
68 guint result;
69
70 g_assert_cmpuint (cases[i].success, ==, g_uint_checked_mul (&result, cases[i].a, cases[i].b));
71 if (cases[i].success)
72 g_assert_cmpuint (cases[i].c, ==, result);
73 }
74}
75
76
77static void
78test_checked_guint64_add (void)
79{
80 static const Case cases[] = {
81 /* success c = a + b */
82 { TRUE, 0, 0, 0 },
83 { TRUE, G_MAXINT64, G_MAXINT64, 0 },
84 { TRUE, G_MAXINT64, 0, G_MAXINT64 },
85 { TRUE, G_MAXUINT64, G_MAXUINT64, 0 },
86 { TRUE, G_MAXUINT64, 0, G_MAXUINT64 },
87 { TRUE, G_MAXUINT64 - 1, G_MAXINT64, G_MAXINT64 },
88 { FALSE, 0, G_MAXUINT64, 1 },
89 { FALSE, 0, 1, G_MAXUINT64 },
90 { FALSE, 0, G_MAXUINT64, G_MAXUINT64 }
91 };
92 guint i;
93
94 for (i = 0; i < G_N_ELEMENTS (cases); i++)
95 {
96 guint64 result;
97
98 g_assert_cmpuint (cases[i].success, ==, g_uint64_checked_add (&result, cases[i].a, cases[i].b));
99 if (cases[i].success)
100 g_assert_cmpuint (cases[i].c, ==, result);
101 }
102}
103
104static void
105test_checked_guint64_mul (void)
106{
107 static const Case cases[] = {
108 /* success c = a * b */
109 { TRUE, 0, 0, 0 },
110 { TRUE, 0, G_MAXINT64, 0 },
111 { TRUE, G_MAXINT64, G_MAXINT64, 1 },
112 { TRUE, 0, G_MAXUINT64, 0 },
113 { TRUE, G_MAXUINT64, G_MAXUINT64, 1 },
114 { TRUE, 2 * (guint64) G_MAXINT64, 2, G_MAXINT64 },
115 { TRUE, 2 * (guint64) G_MAXINT64, G_MAXINT64, 2 },
116 { FALSE, 0, 3, G_MAXINT64 },
117 { FALSE, 0, G_MAXINT64, 3 }
118 };
119 guint i;
120
121 for (i = 0; i < G_N_ELEMENTS (cases); i++)
122 {
123 guint64 result;
124
125 g_assert_cmpuint (cases[i].success, ==, g_uint64_checked_mul (&result, cases[i].a, cases[i].b));
126 if (cases[i].success)
127 g_assert_cmpuint (cases[i].c, ==, result);
128 }
129}
130
131
132static void
133test_checked_gsize_add (void)
134{
135 static const Case cases[] = {
136 /* success c = a + b */
137 { TRUE, 0, 0, 0 },
138 { TRUE, G_MAXSSIZE, G_MAXSSIZE, 0 },
139 { TRUE, G_MAXSSIZE, 0, G_MAXSSIZE },
140 { TRUE, G_MAXSIZE, G_MAXSIZE, 0 },
141 { TRUE, G_MAXSIZE, 0, G_MAXSIZE },
142 { TRUE, G_MAXSIZE - 1, G_MAXSSIZE, G_MAXSSIZE },
143 { FALSE, 0, G_MAXSIZE, 1 },
144 { FALSE, 0, 1, G_MAXSIZE },
145 { FALSE, 0, G_MAXSIZE, G_MAXSIZE }
146 };
147 guint i;
148
149 for (i = 0; i < G_N_ELEMENTS (cases); i++)
150 {
151 gsize result;
152
153 g_assert_cmpuint (cases[i].success, ==, g_size_checked_add (&result, cases[i].a, cases[i].b));
154 if (cases[i].success)
155 g_assert_cmpuint (cases[i].c, ==, result);
156 }
157}
158
159static void
160test_checked_gsize_mul (void)
161{
162 static const Case cases[] = {
163 /* success c = a * b */
164 { TRUE, 0, 0, 0 },
165 { TRUE, 0, G_MAXSSIZE, 0 },
166 { TRUE, G_MAXSSIZE, G_MAXSSIZE, 1 },
167 { TRUE, 0, G_MAXSIZE, 0 },
168 { TRUE, G_MAXSIZE, G_MAXSIZE, 1 },
169 { TRUE, 2 * (gsize) G_MAXSSIZE, 2, G_MAXSSIZE },
170 { TRUE, 2 * (gsize) G_MAXSSIZE, G_MAXSSIZE, 2 },
171 { FALSE, 0, 3, G_MAXSSIZE },
172 { FALSE, 0, G_MAXSSIZE, 3 }
173 };
174 guint i;
175
176 for (i = 0; i < G_N_ELEMENTS (cases); i++)
177 {
178 gsize result;
179
180 g_assert_cmpuint (cases[i].success, ==, g_size_checked_mul (&result, cases[i].a, cases[i].b));
181 if (cases[i].success)
182 g_assert_cmpuint (cases[i].c, ==, result);
183 }
184}
185
186int
187main (int argc, char **argv)
188{
189 g_test_init (argc: &argc, argv: &argv, NULL);
190
191 g_test_add_func (testpath: "/glib/checked-math/guint-add", test_func: test_checked_guint_add);
192 g_test_add_func (testpath: "/glib/checked-math/guint-mul", test_func: test_checked_guint_mul);
193 g_test_add_func (testpath: "/glib/checked-math/guint64-add", test_func: test_checked_guint64_add);
194 g_test_add_func (testpath: "/glib/checked-math/guint64-mul", test_func: test_checked_guint64_mul);
195 g_test_add_func (testpath: "/glib/checked-math/gsize-add", test_func: test_checked_gsize_add);
196 g_test_add_func (testpath: "/glib/checked-math/gsize-mul", test_func: test_checked_gsize_mul);
197
198 return g_test_run ();
199}
200

source code of gtk/subprojects/glib/glib/tests/overflow.c