1import sys
2
3HEAD = """\
4#include "macros.h"
5
6/* Typecasting inline functions that assert that cast values are within
7   range of the cast-to type.
8   Format is cast_<source type>_<target type>()
9   where each of <source type> and <target type> are one of
10   ulong	for unsigned long int
11   uint		for unsigned int
12   long		for long int
13   int		for int
14   ushort	for unsigned short int
15   short	for short int
16   uchar	for unsigned char
17   char		for char
18   size		for size_t
19
20   For each function, there is also a
21   cast_<source type>_<target type>_fast()
22   variant which asserts range validity only if WANT_ASSERT_CONVERSION is
23   defined. Thus the non-fast variant should be used in code that is not
24   speed critical, and the fast variant in code that is.
25*/
26
27#ifdef WANT_ASSERT_CONVERSION
28#define ASSERT_CONVERSION(x) assert(x)
29#else
30#define ASSERT_CONVERSION(x)
31#endif
32
33"""
34
35SRC_NAMES = ("srctype", "srctype_c", "srcmin", "srcmax")
36DST_NAMES = ("dsttype", "dsttype_c", "dstmin", "dstmax")
37TYPES = (
38  ("ulong", "unsigned long int", "0", "ULONG_MAX"),
39  ("uint", "unsigned int", "0", "UINT_MAX"),
40  ("long", "long int", "LONG_MIN", "LONG_MAX"),
41  ("int", "int", "INT_MIN", "INT_MAX"),
42  ("ushort", "unsigned short int", "0", "USHRT_MAX"), # The 'O' would have made it excessively long?
43  ("short", "short int", "SHRT_MIN", "SHRT_MAX"),
44  ("uchar", "unsigned char", "0", "UCHAR_MAX"), # The 'O' would have made it excessively long?
45  ("char", "char", "CHAR_MIN", "CHAR_MAX"),
46  ("size", "size_t", "0", "SIZE_MAX")
47)
48
49TEMPLATE1 = """\
50static inline {dsttype_c}
51cast_{srctype}_{dsttype}{fast}({srctype_c} x)
52{{
53"""
54TEMPLATE2 = """\
55#if {srcmin} < {dstmin}
56    {assert}(x >= {dstmin});
57#endif
58"""
59TEMPLATE3 = """\
60#if {srcmax} > {dstmax}
61    {assert}(x <= {dstmax});
62#endif
63"""
64TEMPLATE4 = """\
65  return ({dsttype_c}) x;
66}}
67"""
68
69SLOW = [("assert", "ASSERT"), ("fast", "")]
70FAST = [("assert", "ASSERT_CONVERSION"), ("fast", "_fast")]
71
72def print_template(d):
73  sys.stdout.write(TEMPLATE1.format(**d))
74  if not d["srcmin"] == d["dstmin"]:
75    sys.stdout.write(TEMPLATE2.format(**d))
76  if not d["srcmax"] == d["dstmax"]:
77    sys.stdout.write(TEMPLATE3.format(**d))
78  sys.stdout.write(TEMPLATE4.format(**d))
79  sys.stdout.write("\n")
80
81print(HEAD)
82for srctype in TYPES:
83  for dsttype in TYPES:
84    if srctype is dsttype:
85      continue
86    values = list(zip(SRC_NAMES, srctype)) + list(zip(DST_NAMES, dsttype))
87    print_template(dict(values + SLOW))
88    print_template(dict(values + FAST))
89