diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/print.c | 47 |
2 files changed, 28 insertions, 21 deletions
diff --git a/src/lisp.h b/src/lisp.h index ca833476c03..61cc20e9d42 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -144,11 +144,13 @@ typedef intmax_t printmax_t; | |||
| 144 | typedef uintmax_t uprintmax_t; | 144 | typedef uintmax_t uprintmax_t; |
| 145 | # define pMd PRIdMAX | 145 | # define pMd PRIdMAX |
| 146 | # define pMu PRIuMAX | 146 | # define pMu PRIuMAX |
| 147 | # define pMx PRIxMAX | ||
| 147 | #else | 148 | #else |
| 148 | typedef EMACS_INT printmax_t; | 149 | typedef EMACS_INT printmax_t; |
| 149 | typedef EMACS_UINT uprintmax_t; | 150 | typedef EMACS_UINT uprintmax_t; |
| 150 | # define pMd pI"d" | 151 | # define pMd pI"d" |
| 151 | # define pMu pI"u" | 152 | # define pMu pI"u" |
| 153 | # define pMx pI"x" | ||
| 152 | #endif | 154 | #endif |
| 153 | 155 | ||
| 154 | /* Use pD to format ptrdiff_t values, which suffice for indexes into | 156 | /* Use pD to format ptrdiff_t values, which suffice for indexes into |
diff --git a/src/print.c b/src/print.c index 08c39d34664..406abbf4a3f 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -1361,6 +1361,19 @@ print_prune_string_charset (Lisp_Object string) | |||
| 1361 | return string; | 1361 | return string; |
| 1362 | } | 1362 | } |
| 1363 | 1363 | ||
| 1364 | #ifdef HAVE_MODULES | ||
| 1365 | /* Return a data pointer equal to FUNCPTR. */ | ||
| 1366 | |||
| 1367 | static void const * | ||
| 1368 | data_from_funcptr (void (*funcptr) (void)) | ||
| 1369 | { | ||
| 1370 | /* The module code, and the POSIX API for dynamic linking, already | ||
| 1371 | assume that function and data pointers are represented | ||
| 1372 | interchangeably, so it's OK to assume that here too. */ | ||
| 1373 | return (void const *) funcptr; | ||
| 1374 | } | ||
| 1375 | #endif | ||
| 1376 | |||
| 1364 | static bool | 1377 | static bool |
| 1365 | print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, | 1378 | print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, |
| 1366 | char *buf) | 1379 | char *buf) |
| @@ -1788,30 +1801,20 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, | |||
| 1788 | { | 1801 | { |
| 1789 | print_c_string ("#<module function ", printcharfun); | 1802 | print_c_string ("#<module function ", printcharfun); |
| 1790 | module_funcptr ptr = module_function_address (XMODULE_FUNCTION (obj)); | 1803 | module_funcptr ptr = module_function_address (XMODULE_FUNCTION (obj)); |
| 1791 | const char *file = NULL; | 1804 | char const *file; |
| 1792 | const char *symbol = NULL; | 1805 | char const *symbol; |
| 1793 | dynlib_addr (ptr, &file, &symbol); | 1806 | dynlib_addr (ptr, &file, &symbol); |
| 1794 | 1807 | ||
| 1795 | if (symbol == NULL) | 1808 | if (symbol == NULL) |
| 1796 | { | 1809 | { |
| 1797 | print_c_string ("at 0x", printcharfun); | 1810 | uintptr_t ui = (uintptr_t) data_from_funcptr (ptr); |
| 1798 | /* See https://stackoverflow.com/a/2741896 for how to | 1811 | |
| 1799 | portably print a function pointer. */ | 1812 | /* In theory this assignment could lose info on pre-C99 |
| 1800 | const unsigned char *p = (const unsigned char *) &ptr; | 1813 | hosts, but in practice it doesn't. */ |
| 1801 | for (size_t i = 0; i < sizeof ptr; ++i) | 1814 | uprintmax_t up = ui; |
| 1802 | { | 1815 | |
| 1803 | #ifdef WORDS_BIGENDIAN | 1816 | int len = sprintf (buf, "at 0x%"pMx, up); |
| 1804 | unsigned char b = p[i]; | 1817 | strout (buf, len, len, printcharfun); |
| 1805 | #else | ||
| 1806 | unsigned char b = p[sizeof ptr - i - 1]; | ||
| 1807 | #endif | ||
| 1808 | enum { digits = (CHAR_BIT + 4 - 1) / 4 }; | ||
| 1809 | char buffer[digits + 1]; | ||
| 1810 | int needed | ||
| 1811 | = snprintf (buffer, sizeof buffer, "%0*x", digits, b); | ||
| 1812 | eassert (needed == digits); | ||
| 1813 | print_c_string (buffer, printcharfun); | ||
| 1814 | } | ||
| 1815 | } | 1818 | } |
| 1816 | else | 1819 | else |
| 1817 | print_c_string (symbol, printcharfun); | 1820 | print_c_string (symbol, printcharfun); |
| @@ -1839,7 +1842,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 1839 | { | 1842 | { |
| 1840 | char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT), | 1843 | char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT), |
| 1841 | max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t), | 1844 | max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t), |
| 1842 | 40))]; | 1845 | max ((sizeof "at 0x" |
| 1846 | + (sizeof (uprintmax_t) * CHAR_BIT + 4 - 1) / 4), | ||
| 1847 | 40)))]; | ||
| 1843 | current_thread->stack_top = buf; | 1848 | current_thread->stack_top = buf; |
| 1844 | maybe_quit (); | 1849 | maybe_quit (); |
| 1845 | 1850 | ||