From 442f0911f295b6ba5321d11aa3c0939b6b27752a Mon Sep 17 00:00:00 2001
From: Vysheng <mail@vysheng.ru>
Date: Tue, 9 Sep 2014 15:34:59 +0400
Subject: [PATCH] Support for compilers without __builtin_bswap32

---
 config.h.in          |   3 +
 configure            | 141 ++++++++++++++++++++++++++++++++++++
 configure.ac         |   3 +
 crc32.c              |   9 +++
 m4-ax_gcc_builtin.m4 | 168 +++++++++++++++++++++++++++++++++++++++++++
 mtproto-client.c     |   9 +++
 6 files changed, 333 insertions(+)
 create mode 100644 m4-ax_gcc_builtin.m4

diff --git a/config.h.in b/config.h.in
index 9c1f275..2a24728 100644
--- a/config.h.in
+++ b/config.h.in
@@ -125,6 +125,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if the system has the `__builtin_bswap32' built-in function */
+#undef HAVE___BUILTIN_BSWAP32
+
 /* Define to the address where bug reports for this package should be sent. */
 #undef PACKAGE_BUGREPORT
 
diff --git a/configure b/configure
index 522bc71..dc5f1be 100755
--- a/configure
+++ b/configure
@@ -2533,6 +2533,102 @@ ac_config_headers="$ac_config_headers config.h"
 
 
 
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_gcc_builtin.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_GCC_BUILTIN(BUILTIN)
+#
+# DESCRIPTION
+#
+#   This macro checks if the compiler supports one of GCC's built-in
+#   functions; many other compilers also provide those same built-ins.
+#
+#   The BUILTIN parameter is the name of the built-in function.
+#
+#   If BUILTIN is supported define HAVE_<BUILTIN>. Keep in mind that since
+#   builtins usually start with two underscores they will be copied over
+#   into the HAVE_<BUILTIN> definition (e.g. HAVE___BUILTIN_EXPECT for
+#   __builtin_expect()).
+#
+#   The macro caches its result in the ax_cv_have_<BUILTIN> variable (e.g.
+#   ax_cv_have___builtin_expect).
+#
+#   The macro currently supports the following built-in functions:
+#
+#    __builtin_assume_aligned
+#    __builtin_bswap32
+#    __builtin_bswap64
+#    __builtin_choose_expr
+#    __builtin___clear_cache
+#    __builtin_clrsb
+#    __builtin_clrsbl
+#    __builtin_clrsbll
+#    __builtin_clz
+#    __builtin_clzl
+#    __builtin_clzll
+#    __builtin_complex
+#    __builtin_constant_p
+#    __builtin_ctz
+#    __builtin_ctzl
+#    __builtin_ctzll
+#    __builtin_expect
+#    __builtin_ffs
+#    __builtin_ffsl
+#    __builtin_ffsll
+#    __builtin_fpclassify
+#    __builtin_huge_val
+#    __builtin_huge_valf
+#    __builtin_huge_vall
+#    __builtin_inf
+#    __builtin_infd128
+#    __builtin_infd32
+#    __builtin_infd64
+#    __builtin_inff
+#    __builtin_infl
+#    __builtin_isinf_sign
+#    __builtin_nan
+#    __builtin_nand128
+#    __builtin_nand32
+#    __builtin_nand64
+#    __builtin_nanf
+#    __builtin_nanl
+#    __builtin_nans
+#    __builtin_nansf
+#    __builtin_nansl
+#    __builtin_object_size
+#    __builtin_parity
+#    __builtin_parityl
+#    __builtin_parityll
+#    __builtin_popcount
+#    __builtin_popcountl
+#    __builtin_popcountll
+#    __builtin_powi
+#    __builtin_powif
+#    __builtin_powil
+#    __builtin_prefetch
+#    __builtin_trap
+#    __builtin_types_compatible_p
+#    __builtin_unreachable
+#
+#   Unsuppored built-ins will be tested with an empty parameter set and the
+#   result of the check might be wrong or meaningless so use with care.
+#
+# LICENSE
+#
+#   Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 2
+
+
+
 
 # Checks for programs.
 ac_ext=c
@@ -6031,6 +6127,51 @@ done
 
 
 
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap32" >&5
+$as_echo_n "checking for __builtin_bswap32... " >&6; }
+if ${ax_cv_have___builtin_bswap32+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+            __builtin_bswap32(0)
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_have___builtin_bswap32=yes
+else
+  ax_cv_have___builtin_bswap32=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have___builtin_bswap32" >&5
+$as_echo "$ax_cv_have___builtin_bswap32" >&6; }
+
+    if test yes = $ax_cv_have___builtin_bswap32; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE___BUILTIN_BSWAP32 1
+_ACEOF
+
+fi
+
+
+
+
+
 ac_config_files="$ac_config_files Makefile"
 
 cat >confcache <<\_ACEOF
diff --git a/configure.ac b/configure.ac
index 753848c..2026f81 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,6 +6,7 @@ AC_CONFIG_HEADERS([config.h])
 m4_include([ax_lua.m4])
 m4_include([m4_ax_check_openssl.m4])
 m4_include([m4_ax_check_zlib.m4])
+m4_include([m4-ax_gcc_builtin.m4])
 
 # Checks for programs.
 AC_PROG_CC
@@ -113,6 +114,8 @@ AC_FUNC_MALLOC
 AC_FUNC_REALLOC
 AC_CHECK_FUNCS([alarm endpwent memset memmove mkdir select socket strdup strndup uname])
 
+AX_GCC_BUILTIN(__builtin_bswap32)
+
 AC_SUBST(EXTRA_LIBS)
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
diff --git a/crc32.c b/crc32.c
index fd62b20..285493b 100644
--- a/crc32.c
+++ b/crc32.c
@@ -26,6 +26,15 @@
 
 #include "crc32.h"
 
+#ifndef HAVE___BUILTIN_BSWAP32
+static inline unsigned __builtin_bswap32(unsigned x) {
+  return ((x << 24) & 0xff000000 ) |
+  ((x << 8) & 0x00ff0000 ) |
+  ((x >> 8) & 0x0000ff00 ) |
+  ((x >> 24) & 0x000000ff );
+}
+#endif
+
 unsigned int crc32_table[256] =
 {
   0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
diff --git a/m4-ax_gcc_builtin.m4 b/m4-ax_gcc_builtin.m4
new file mode 100644
index 0000000..b28a91b
--- /dev/null
+++ b/m4-ax_gcc_builtin.m4
@@ -0,0 +1,168 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_gcc_builtin.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_GCC_BUILTIN(BUILTIN)
+#
+# DESCRIPTION
+#
+#   This macro checks if the compiler supports one of GCC's built-in
+#   functions; many other compilers also provide those same built-ins.
+#
+#   The BUILTIN parameter is the name of the built-in function.
+#
+#   If BUILTIN is supported define HAVE_<BUILTIN>. Keep in mind that since
+#   builtins usually start with two underscores they will be copied over
+#   into the HAVE_<BUILTIN> definition (e.g. HAVE___BUILTIN_EXPECT for
+#   __builtin_expect()).
+#
+#   The macro caches its result in the ax_cv_have_<BUILTIN> variable (e.g.
+#   ax_cv_have___builtin_expect).
+#
+#   The macro currently supports the following built-in functions:
+#
+#    __builtin_assume_aligned
+#    __builtin_bswap32
+#    __builtin_bswap64
+#    __builtin_choose_expr
+#    __builtin___clear_cache
+#    __builtin_clrsb
+#    __builtin_clrsbl
+#    __builtin_clrsbll
+#    __builtin_clz
+#    __builtin_clzl
+#    __builtin_clzll
+#    __builtin_complex
+#    __builtin_constant_p
+#    __builtin_ctz
+#    __builtin_ctzl
+#    __builtin_ctzll
+#    __builtin_expect
+#    __builtin_ffs
+#    __builtin_ffsl
+#    __builtin_ffsll
+#    __builtin_fpclassify
+#    __builtin_huge_val
+#    __builtin_huge_valf
+#    __builtin_huge_vall
+#    __builtin_inf
+#    __builtin_infd128
+#    __builtin_infd32
+#    __builtin_infd64
+#    __builtin_inff
+#    __builtin_infl
+#    __builtin_isinf_sign
+#    __builtin_nan
+#    __builtin_nand128
+#    __builtin_nand32
+#    __builtin_nand64
+#    __builtin_nanf
+#    __builtin_nanl
+#    __builtin_nans
+#    __builtin_nansf
+#    __builtin_nansl
+#    __builtin_object_size
+#    __builtin_parity
+#    __builtin_parityl
+#    __builtin_parityll
+#    __builtin_popcount
+#    __builtin_popcountl
+#    __builtin_popcountll
+#    __builtin_powi
+#    __builtin_powif
+#    __builtin_powil
+#    __builtin_prefetch
+#    __builtin_trap
+#    __builtin_types_compatible_p
+#    __builtin_unreachable
+#
+#   Unsuppored built-ins will be tested with an empty parameter set and the
+#   result of the check might be wrong or meaningless so use with care.
+#
+# LICENSE
+#
+#   Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 2
+
+AC_DEFUN([AX_GCC_BUILTIN], [
+    AS_VAR_PUSHDEF([ac_var], [ax_cv_have_$1])
+
+    AC_CACHE_CHECK([for $1], [ac_var], [
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([], [
+            m4_case([$1],
+                [__builtin_assume_aligned], [$1("", 0)],
+                [__builtin_bswap32], [$1(0)],
+                [__builtin_bswap64], [$1(0)],
+                [__builtin_choose_expr], [$1(0, 0, 0)],
+                [__builtin___clear_cache], [$1("", "")],
+                [__builtin_clrsb], [$1(0)],
+                [__builtin_clrsbl], [$1(0)],
+                [__builtin_clrsbll], [$1(0)],
+                [__builtin_clz], [$1(0)],
+                [__builtin_clzl], [$1(0)],
+                [__builtin_clzll], [$1(0)],
+                [__builtin_complex], [$1(0.0, 0.0)],
+                [__builtin_constant_p], [$1(0)],
+                [__builtin_ctz], [$1(0)],
+                [__builtin_ctzl], [$1(0)],
+                [__builtin_ctzll], [$1(0)],
+                [__builtin_expect], [$1(0, 0)],
+                [__builtin_ffs], [$1(0)],
+                [__builtin_ffsl], [$1(0)],
+                [__builtin_ffsll], [$1(0)],
+                [__builtin_fpclassify], [$1(0, 1, 2, 3, 4, 0.0)],
+                [__builtin_huge_val], [$1()],
+                [__builtin_huge_valf], [$1()],
+                [__builtin_huge_vall], [$1()],
+                [__builtin_inf], [$1()],
+                [__builtin_infd128], [$1()],
+                [__builtin_infd32], [$1()],
+                [__builtin_infd64], [$1()],
+                [__builtin_inff], [$1()],
+                [__builtin_infl], [$1()],
+                [__builtin_isinf_sign], [$1(0.0)],
+                [__builtin_nan], [$1("")],
+                [__builtin_nand128], [$1("")],
+                [__builtin_nand32], [$1("")],
+                [__builtin_nand64], [$1("")],
+                [__builtin_nanf], [$1("")],
+                [__builtin_nanl], [$1("")],
+                [__builtin_nans], [$1("")],
+                [__builtin_nansf], [$1("")],
+                [__builtin_nansl], [$1("")],
+                [__builtin_object_size], [$1("", 0)],
+                [__builtin_parity], [$1(0)],
+                [__builtin_parityl], [$1(0)],
+                [__builtin_parityll], [$1(0)],
+                [__builtin_popcount], [$1(0)],
+                [__builtin_popcountl], [$1(0)],
+                [__builtin_popcountll], [$1(0)],
+                [__builtin_powi], [$1(0, 0)],
+                [__builtin_powif], [$1(0, 0)],
+                [__builtin_powil], [$1(0, 0)],
+                [__builtin_prefetch], [$1("")],
+                [__builtin_trap], [$1()],
+                [__builtin_types_compatible_p], [$1(int, int)],
+                [__builtin_unreachable], [$1()],
+                [m4_warn([syntax], [Unsupported built-in $1, the test may fail])
+                 $1()]
+            )
+            ])],
+            [AS_VAR_SET([ac_var], [yes])],
+            [AS_VAR_SET([ac_var], [no])])
+    ])
+
+    AS_IF([test yes = AS_VAR_GET([ac_var])],
+        [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1), 1,
+            [Define to 1 if the system has the `$1' built-in function])], [])
+
+    AS_VAR_POPDEF([ac_var])
+])
diff --git a/mtproto-client.c b/mtproto-client.c
index 4703ec6..e1e05ac 100644
--- a/mtproto-client.c
+++ b/mtproto-client.c
@@ -80,6 +80,15 @@
 #define MAX_NET_RES        (1L << 16)
 //extern int log_level;
 
+#ifndef HAVE___BUILTIN_BSWAP32
+static inline unsigned __builtin_bswap32(unsigned x) {
+  return ((x << 24) & 0xff000000 ) |
+  ((x << 8) & 0x00ff0000 ) |
+  ((x >> 8) & 0x0000ff00 ) |
+  ((x >> 24) & 0x000000ff );
+}
+#endif
+
 //int verbosity;
 static int auth_success;
 //static enum tgl_dc_state c_state;
-- 
2.21.0