Skip to content

Commit dfb866d

Browse files
author
Victor Stinner
committed
Enhance Py_ARRAY_LENGTH(): fail at build time if the argument is not an array
Move other various macros to pymcacro.h Thanks Rusty Russell for having written these amazing C macros!
1 parent 2bdc7f5 commit dfb866d

File tree

5 files changed

+65
-19
lines changed

5 files changed

+65
-19
lines changed

Include/Python.h

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <assert.h>
4949

5050
#include "pyport.h"
51+
#include "pymacro.h"
5152

5253
#include "pyatomic.h"
5354

@@ -126,24 +127,6 @@
126127
#include "pystrcmp.h"
127128
#include "dtoa.h"
128129
#include "fileutils.h"
129-
130-
/* Argument must be a char or an int in [-128, 127] or [0, 255]. */
131-
#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff))
132-
133130
#include "pyfpe.h"
134131

135-
/* Define macros for inline documentation. */
136-
#define PyDoc_VAR(name) static char name[]
137-
#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
138-
#ifdef WITH_DOC_STRINGS
139-
#define PyDoc_STR(str) str
140-
#else
141-
#define PyDoc_STR(str) ""
142-
#endif
143-
144-
#define Py_ARRAY_LENGTH(array) (sizeof(array) / sizeof((array)[0]))
145-
146-
#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x))
147-
#define Py_MAX(x, y) (((x) > (y)) ? (x) : (y))
148-
149132
#endif /* !Py_PYTHON_H */

Include/pymacro.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#ifndef Py_PYMACRO_H
2+
#define Py_PYMACRO_H
3+
4+
#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x))
5+
#define Py_MAX(x, y) (((x) > (y)) ? (x) : (y))
6+
7+
/* Argument must be a char or an int in [-128, 127] or [0, 255]. */
8+
#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff))
9+
10+
11+
/* Assert a build-time dependency, as an expression.
12+
13+
Your compile will fail if the condition isn't true, or can't be evaluated
14+
by the compiler. This can be used in an expression: its value is 0.
15+
16+
Example:
17+
18+
#define foo_to_char(foo) \
19+
((char *)(foo) \
20+
+ Py_BUILD_ASSERT(offsetof(struct foo, string) == 0))
21+
22+
Written by Rusty Russell, public domain. */
23+
#define Py_BUILD_ASSERT(cond) \
24+
(sizeof(char [1 - 2*!(cond)]) - 1)
25+
26+
#if defined(__GNUC__)
27+
/* Two gcc extensions.
28+
&a[0] degrades to a pointer: a different type from an array */
29+
#define _Py_ARRAY_LENGTH_CHECK(array) \
30+
Py_BUILD_ASSERT(!__builtin_types_compatible_p(typeof(array), \
31+
typeof(&(array)[0])))
32+
#else
33+
#define _Py_ARRAY_LENGTH_CHECK(array) 0
34+
#endif
35+
36+
37+
/* Get the number of elements in a visible array
38+
39+
This does not work on pointers, or arrays declared as [], or function
40+
parameters. With correct compiler support, such usage will cause a build
41+
error (see Py_BUILD_ASSERT).
42+
43+
Written by Rusty Russell, public domain. */
44+
#define Py_ARRAY_LENGTH(array) \
45+
(sizeof(array) / sizeof((array)[0]) + _Py_ARRAY_LENGTH_CHECK(array))
46+
47+
48+
/* Define macros for inline documentation. */
49+
#define PyDoc_VAR(name) static char name[]
50+
#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
51+
#ifdef WITH_DOC_STRINGS
52+
#define PyDoc_STR(str) str
53+
#else
54+
#define PyDoc_STR(str) ""
55+
#endif
56+
57+
#endif /* Py_PYMACRO_H */

Makefile.pre.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
493493
-install_name $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \
494494
-compatibility_version $(VERSION) \
495495
-current_version $(VERSION) \
496-
-framework CoreFoundation $(LIBS);
496+
-framework CoreFoundation $(LIBS);
497497
$(INSTALL) -d -m $(DIRMODE) \
498498
$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/English.lproj
499499
$(INSTALL_DATA) $(RESSRCDIR)/Info.plist \
@@ -718,6 +718,7 @@ PYTHON_HEADERS= \
718718
Include/pyfpe.h \
719719
Include/pymath.h \
720720
Include/pygetopt.h \
721+
Include/pymacro.h \
721722
Include/pymem.h \
722723
Include/pyport.h \
723724
Include/pystate.h \

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ Rauli Ruohonen
825825
Jeff Rush
826826
Sam Rushing
827827
Mark Russell
828+
Rusty Russell
828829
Nick Russo
829830
Patrick Sabin
830831
Sébastien Sablé

PCbuild/pythoncore.vcproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,10 @@
886886
RelativePath="..\Include\pytime.h"
887887
>
888888
</File>
889+
<File
890+
RelativePath="..\Include\pymacro.h"
891+
>
892+
</File>
889893
<File
890894
RelativePath="..\Include\pymem.h"
891895
>

0 commit comments

Comments
 (0)