I wrote:
> Matteo Beccati <p...@beccati.com> writes:
>> On 26/05/2014 19:31, Andres Freund wrote:
>>> On 2014-05-26 13:25:49 -0400, Tom Lane wrote:
>>>> Matteo Beccati <p...@beccati.com> writes:
>>>>> * Restored --with-ossp-uuid. Configure tries ossp support first, then
>>>>> falls back to Linux and BSD variants

>>> Imo should be the other way round.

>> My goal was to avoid changing the underlying implementation if someone
>> has the ossp library installed. Tom is suggesting to split the configure
>> switch in two, so I guess that would allow the most flexibility.

> Yeah: if we have two configure switches then we can avoid having to decide
> which library takes precedence.  But the main reason for that is we have
> a general policy that what you get from a given configure switch should be
> predictable, rather than depending on what is or is not installed.  (If we
> were sure these libraries were 100% interchangeable then maybe one switch
> would be OK, but I'm not too sure about that, yet.)

Some research uncovered the fact that the e2fsprogs UUID library (ie the
"Linux" one) is available for FreeBSD too:
http://www.freshports.org/misc/e2fsprogs-libuuid/

This means that if we want to give users control over which implementation
gets selected, we actually need *three* configure switches.  In the
attached revision of Matteo's patch, I called them --with-ossp-uuid
(the existing switch name), --with-linux-uuid, and --with-bsd-uuid.
I'm not necessarily wedded to the latter two names; in particular it seems
unfortunate that the right one to use on OS X is --with-linux-uuid.
But I think --with-e2fsprogs-uuid is right out, so it's not clear what
would be better.

I've verified functionality of this patch on these scenarios:

(1) --with-ossp-uuid on RHEL6, using uuid-1.6.1-10.el6.x86_64
(2) --with-linux-uuid on RHEL6, using libuuid-2.17.2-12.14.el6_5.x86_64
(3) --with-linux-uuid on OS X 10.9.3, Intel
(4) --with-linux-uuid on OS X 10.4.11, PPC (hence, bigendian)

I do not have a machine on which to try --with-bsd-uuid, so it's
possible I broke that portion of Matteo's patch.  Would someone try
that case on a FreeBSD box?

Other than retesting that case, I think this is ready to go except that
it lacks documentation updates.

                        regards, tom lane

diff --git a/configure b/configure
index 17f3f26..a4ba3f3 100755
*** a/configure
--- b/configure
*************** acx_pthread_config
*** 657,663 ****
  have_win32_dbghelp
  HAVE_IPV6
  LIBOBJS
! OSSP_UUID_LIBS
  ZIC
  python_enable_shared
  python_additional_libs
--- 657,663 ----
  have_win32_dbghelp
  HAVE_IPV6
  LIBOBJS
! UUID_LIBS
  ZIC
  python_enable_shared
  python_additional_libs
*************** with_system_tzdata
*** 705,711 ****
  with_libxslt
  with_libxml
  XML2_CONFIG
! with_ossp_uuid
  with_selinux
  with_openssl
  krb_srvtab
--- 705,712 ----
  with_libxslt
  with_libxml
  XML2_CONFIG
! UUID_EXTRA_OBJS
! with_uuid
  with_selinux
  with_openssl
  krb_srvtab
*************** with_openssl
*** 826,831 ****
--- 827,834 ----
  with_selinux
  with_readline
  with_libedit_preferred
+ with_bsd_uuid
+ with_linux_uuid
  with_ossp_uuid
  with_libxml
  with_libxslt
*************** Optional Packages:
*** 1512,1518 ****
    --without-readline      do not use GNU Readline nor BSD Libedit for editing
    --with-libedit-preferred
                            prefer BSD Libedit over GNU Readline
!   --with-ossp-uuid        build contrib/uuid-ossp, requires OSSP UUID library
    --with-libxml           build with XML support
    --with-libxslt          use XSLT support when building contrib/xml2
    --with-system-tzdata=DIR
--- 1515,1524 ----
    --without-readline      do not use GNU Readline nor BSD Libedit for editing
    --with-libedit-preferred
                            prefer BSD Libedit over GNU Readline
!   --with-bsd-uuid         build contrib/uuid-ossp, using BSD UUID library
!   --with-linux-uuid       build contrib/uuid-ossp, using Linux/OSX UUID
!                           library
!   --with-ossp-uuid        build contrib/uuid-ossp, using OSSP UUID library
    --with-libxml           build with XML support
    --with-libxslt          use XSLT support when building contrib/xml2
    --with-system-tzdata=DIR
*************** fi
*** 1737,1742 ****
--- 1743,1815 ----
  
  } # ac_fn_c_try_cpp
  
+ # ac_fn_c_check_func LINENO FUNC VAR
+ # ----------------------------------
+ # Tests whether FUNC exists, setting the cache variable VAR accordingly
+ ac_fn_c_check_func ()
+ {
+   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+ $as_echo_n "checking for $2... " >&6; }
+ if eval \${$3+:} false; then :
+   $as_echo_n "(cached) " >&6
+ else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ /* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+ #define $2 innocuous_$2
+ 
+ /* System header to define __stub macros and hopefully few prototypes,
+     which can conflict with char $2 (); below.
+     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+     <limits.h> exists even on freestanding compilers.  */
+ 
+ #ifdef __STDC__
+ # include <limits.h>
+ #else
+ # include <assert.h>
+ #endif
+ 
+ #undef $2
+ 
+ /* Override any GCC internal prototype to avoid an error.
+    Use char because int might match the return type of a GCC
+    builtin and then its argument prototype would still apply.  */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ char $2 ();
+ /* The GNU C library defines this for functions which it implements
+     to always fail with ENOSYS.  Some functions are actually named
+     something starting with __ and the normal name is an alias.  */
+ #if defined __stub_$2 || defined __stub___$2
+ choke me
+ #endif
+ 
+ int
+ main ()
+ {
+ return $2 ();
+   ;
+   return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+   eval "$3=yes"
+ else
+   eval "$3=no"
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+ fi
+ eval ac_res=\$$3
+ 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+ $as_echo "$ac_res" >&6; }
+   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ 
+ } # ac_fn_c_check_func
+ 
  # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
  # -------------------------------------------------------
  # Tests whether HEADER exists, giving a warning if it cannot be compiled using
*************** rm -f conftest.val
*** 2195,2267 ****
  
  } # ac_fn_c_compute_int
  
- # ac_fn_c_check_func LINENO FUNC VAR
- # ----------------------------------
- # Tests whether FUNC exists, setting the cache variable VAR accordingly
- ac_fn_c_check_func ()
- {
-   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
- $as_echo_n "checking for $2... " >&6; }
- if eval \${$3+:} false; then :
-   $as_echo_n "(cached) " >&6
- else
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
- /* end confdefs.h.  */
- /* Define $2 to an innocuous variant, in case <limits.h> declares $2.
-    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
- #define $2 innocuous_$2
- 
- /* System header to define __stub macros and hopefully few prototypes,
-     which can conflict with char $2 (); below.
-     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-     <limits.h> exists even on freestanding compilers.  */
- 
- #ifdef __STDC__
- # include <limits.h>
- #else
- # include <assert.h>
- #endif
- 
- #undef $2
- 
- /* Override any GCC internal prototype to avoid an error.
-    Use char because int might match the return type of a GCC
-    builtin and then its argument prototype would still apply.  */
- #ifdef __cplusplus
- extern "C"
- #endif
- char $2 ();
- /* The GNU C library defines this for functions which it implements
-     to always fail with ENOSYS.  Some functions are actually named
-     something starting with __ and the normal name is an alias.  */
- #if defined __stub_$2 || defined __stub___$2
- choke me
- #endif
- 
- int
- main ()
- {
- return $2 ();
-   ;
-   return 0;
- }
- _ACEOF
- if ac_fn_c_try_link "$LINENO"; then :
-   eval "$3=yes"
- else
-   eval "$3=no"
- fi
- rm -f core conftest.err conftest.$ac_objext \
-     conftest$ac_exeext conftest.$ac_ext
- fi
- eval ac_res=\$$3
- 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
- $as_echo "$ac_res" >&6; }
-   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- 
- } # ac_fn_c_check_func
- 
  # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
  # ---------------------------------------------
  # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
--- 2268,2273 ----
*************** fi
*** 5614,5624 ****
  
  
  #
! # OSSP UUID library
  #
  
  
  
  # Check whether --with-ossp-uuid was given.
  if test "${with_ossp_uuid+set}" = set; then :
    withval=$with_ossp_uuid;
--- 5620,5685 ----
  
  
  #
! # UUID library
! #
! # There are at least three UUID libraries in common use: the FreeBSD library,
! # the "Linux" one (originally part of e2fsprogs, now part of util-linux-ng),
! # and the OSSP library (previously the only one supported by Postgres).
! # More than one of these might be present on a given platform,
! # so we make the user say which one she wants.
! # Note: Mac OS X has a version of the "Linux" library.
  #
  
  
  
+ # Check whether --with-bsd-uuid was given.
+ if test "${with_bsd_uuid+set}" = set; then :
+   withval=$with_bsd_uuid;
+   case $withval in
+     yes)
+       :
+       ;;
+     no)
+       :
+       ;;
+     *)
+       as_fn_error $? "no argument expected for --with-bsd-uuid option" "$LINENO" 5
+       ;;
+   esac
+ 
+ else
+   with_bsd_uuid=no
+ 
+ fi
+ 
+ 
+ 
+ 
+ 
+ # Check whether --with-linux-uuid was given.
+ if test "${with_linux_uuid+set}" = set; then :
+   withval=$with_linux_uuid;
+   case $withval in
+     yes)
+       :
+       ;;
+     no)
+       :
+       ;;
+     *)
+       as_fn_error $? "no argument expected for --with-linux-uuid option" "$LINENO" 5
+       ;;
+   esac
+ 
+ else
+   with_linux_uuid=no
+ 
+ fi
+ 
+ 
+ 
+ 
+ 
  # Check whether --with-ossp-uuid was given.
  if test "${with_ossp_uuid+set}" = set; then :
    withval=$with_ossp_uuid;
*************** fi
*** 5641,5646 ****
--- 5702,5737 ----
  
  
  
+ if test "$with_bsd_uuid" = yes ; then
+   if test "$with_linux_uuid" = yes -o "$with_ossp_uuid" = yes ; then
+     as_fn_error $? "Please select only one UUID library" "$LINENO" 5
+   fi
+ 
+ $as_echo "#define HAVE_UUID_BSD 1" >>confdefs.h
+ 
+   UUID_EXTRA_OBJS="md5.o sha1.o"
+   with_uuid=yes
+ elif test "$with_linux_uuid" = yes ; then
+   if test "$with_ossp_uuid" = yes ; then
+     as_fn_error $? "Please select only one UUID library" "$LINENO" 5
+   fi
+ 
+ $as_echo "#define HAVE_UUID_LINUX 1" >>confdefs.h
+ 
+   UUID_EXTRA_OBJS="md5.o sha1.o"
+   with_uuid=yes
+ elif test "$with_ossp_uuid" = yes ; then
+ 
+ $as_echo "#define HAVE_UUID_OSSP 1" >>confdefs.h
+ 
+   UUID_EXTRA_OBJS=""
+   with_uuid=yes
+ else
+   UUID_EXTRA_OBJS=""
+   with_uuid=no
+ fi
+ 
+ 
  
  
  #
*************** fi
*** 8775,8781 ****
  fi
  
  # for contrib/uuid-ossp
! if test "$with_ossp_uuid" = yes ; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -lossp-uuid" >&5
  $as_echo_n "checking for uuid_export in -lossp-uuid... " >&6; }
  if ${ac_cv_lib_ossp_uuid_uuid_export+:} false; then :
--- 8866,8931 ----
  fi
  
  # for contrib/uuid-ossp
! if test "$with_bsd_uuid" = yes ; then
!   # On BSD, the UUID functions are in libc
!   ac_fn_c_check_func "$LINENO" "uuid_to_string" "ac_cv_func_uuid_to_string"
! if test "x$ac_cv_func_uuid_to_string" = xyes; then :
!   UUID_LIBS=""
! else
!   as_fn_error $? "BSD UUID functions are not present" "$LINENO" 5
! fi
! 
! elif test "$with_linux_uuid" = yes ; then
!   # On OS/X, the UUID functions are in libc
!   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate in -luuid" >&5
! $as_echo_n "checking for uuid_generate in -luuid... " >&6; }
! if ${ac_cv_lib_uuid_uuid_generate+:} false; then :
!   $as_echo_n "(cached) " >&6
! else
!   ac_check_lib_save_LIBS=$LIBS
! LIBS="-luuid  $LIBS"
! cat confdefs.h - <<_ACEOF >conftest.$ac_ext
! /* end confdefs.h.  */
! 
! /* Override any GCC internal prototype to avoid an error.
!    Use char because int might match the return type of a GCC
!    builtin and then its argument prototype would still apply.  */
! #ifdef __cplusplus
! extern "C"
! #endif
! char uuid_generate ();
! int
! main ()
! {
! return uuid_generate ();
!   ;
!   return 0;
! }
! _ACEOF
! if ac_fn_c_try_link "$LINENO"; then :
!   ac_cv_lib_uuid_uuid_generate=yes
! else
!   ac_cv_lib_uuid_uuid_generate=no
! fi
! rm -f core conftest.err conftest.$ac_objext \
!     conftest$ac_exeext conftest.$ac_ext
! LIBS=$ac_check_lib_save_LIBS
! fi
! { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate" >&5
! $as_echo "$ac_cv_lib_uuid_uuid_generate" >&6; }
! if test "x$ac_cv_lib_uuid_uuid_generate" = xyes; then :
!   UUID_LIBS="-luuid"
! else
!   ac_fn_c_check_func "$LINENO" "uuid_generate" "ac_cv_func_uuid_generate"
! if test "x$ac_cv_func_uuid_generate" = xyes; then :
!   UUID_LIBS=""
! else
!   as_fn_error $? "library 'uuid' is required for Linux/OSX UUID" "$LINENO" 5
! fi
! 
! fi
! 
! elif test "$with_ossp_uuid" = yes ; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -lossp-uuid" >&5
  $as_echo_n "checking for uuid_export in -lossp-uuid... " >&6; }
  if ${ac_cv_lib_ossp_uuid_uuid_export+:} false; then :
*************** fi
*** 8813,8819 ****
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ossp_uuid_uuid_export" >&5
  $as_echo "$ac_cv_lib_ossp_uuid_uuid_export" >&6; }
  if test "x$ac_cv_lib_ossp_uuid_uuid_export" = xyes; then :
!   OSSP_UUID_LIBS="-lossp-uuid"
  else
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -luuid" >&5
  $as_echo_n "checking for uuid_export in -luuid... " >&6; }
--- 8963,8969 ----
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ossp_uuid_uuid_export" >&5
  $as_echo "$ac_cv_lib_ossp_uuid_uuid_export" >&6; }
  if test "x$ac_cv_lib_ossp_uuid_uuid_export" = xyes; then :
!   UUID_LIBS="-lossp-uuid"
  else
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -luuid" >&5
  $as_echo_n "checking for uuid_export in -luuid... " >&6; }
*************** fi
*** 8852,8860 ****
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_export" >&5
  $as_echo "$ac_cv_lib_uuid_uuid_export" >&6; }
  if test "x$ac_cv_lib_uuid_uuid_export" = xyes; then :
!   OSSP_UUID_LIBS="-luuid"
  else
!   as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP-UUID" "$LINENO" 5
  fi
  
  fi
--- 9002,9010 ----
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_export" >&5
  $as_echo "$ac_cv_lib_uuid_uuid_export" >&6; }
  if test "x$ac_cv_lib_uuid_uuid_export" = xyes; then :
!   UUID_LIBS="-luuid"
  else
!   as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP UUID" "$LINENO" 5
  fi
  
  fi
*************** fi
*** 9398,9404 ****
  fi
  
  # for contrib/uuid-ossp
! if test "$with_ossp_uuid" = yes ; then
    for ac_header in ossp/uuid.h
  do :
    ac_fn_c_check_header_mongrel "$LINENO" "ossp/uuid.h" "ac_cv_header_ossp_uuid_h" "$ac_includes_default"
--- 9548,9633 ----
  fi
  
  # for contrib/uuid-ossp
! if test "$with_bsd_uuid" = yes ; then
!   for ac_header in uuid.h
! do :
!   ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
! if test "x$ac_cv_header_uuid_h" = xyes; then :
!   cat >>confdefs.h <<_ACEOF
! #define HAVE_UUID_H 1
! _ACEOF
!  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
! /* end confdefs.h.  */
! #include <uuid.h>
! 
! _ACEOF
! if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
!   $EGREP "uuid_to_string" >/dev/null 2>&1; then :
! 
! else
!   as_fn_error $? "header file <uuid.h> does not match BSD UUID library" "$LINENO" 5
! fi
! rm -f conftest*
! 
! else
!   as_fn_error $? "header file <uuid.h> is required for BSD UUID" "$LINENO" 5
! fi
! 
! done
! 
! elif test "$with_linux_uuid" = yes ; then
!   for ac_header in uuid/uuid.h
! do :
!   ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default"
! if test "x$ac_cv_header_uuid_uuid_h" = xyes; then :
!   cat >>confdefs.h <<_ACEOF
! #define HAVE_UUID_UUID_H 1
! _ACEOF
!  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
! /* end confdefs.h.  */
! #include <uuid/uuid.h>
! 
! _ACEOF
! if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
!   $EGREP "uuid_generate" >/dev/null 2>&1; then :
! 
! else
!   as_fn_error $? "header file <uuid/uuid.h> does not match Linux/OSX UUID library" "$LINENO" 5
! fi
! rm -f conftest*
! 
! else
!   for ac_header in uuid.h
! do :
!   ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
! if test "x$ac_cv_header_uuid_h" = xyes; then :
!   cat >>confdefs.h <<_ACEOF
! #define HAVE_UUID_H 1
! _ACEOF
!  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
! /* end confdefs.h.  */
! #include <uuid.h>
! 
! _ACEOF
! if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
!   $EGREP "uuid_generate" >/dev/null 2>&1; then :
! 
! else
!   as_fn_error $? "header file <uuid.h> does not match Linux/OSX UUID library" "$LINENO" 5
! fi
! rm -f conftest*
! 
! else
!   as_fn_error $? "header file <uuid/uuid.h> or <uuid.h> is required for Linux/OSX UUID" "$LINENO" 5
! fi
! 
! done
! 
! fi
! 
! done
! 
! elif test "$with_ossp_uuid" = yes ; then
    for ac_header in ossp/uuid.h
  do :
    ac_fn_c_check_header_mongrel "$LINENO" "ossp/uuid.h" "ac_cv_header_ossp_uuid_h" "$ac_includes_default"
*************** if test "x$ac_cv_header_ossp_uuid_h" = x
*** 9406,9424 ****
    cat >>confdefs.h <<_ACEOF
  #define HAVE_OSSP_UUID_H 1
  _ACEOF
  
  else
  
!     for ac_header in uuid.h
  do :
    ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
  if test "x$ac_cv_header_uuid_h" = xyes; then :
    cat >>confdefs.h <<_ACEOF
  #define HAVE_UUID_H 1
  _ACEOF
  
  else
!   as_fn_error $? "header file <ossp/uuid.h> or <uuid.h> is required for OSSP-UUID" "$LINENO" 5
  fi
  
  done
--- 9635,9676 ----
    cat >>confdefs.h <<_ACEOF
  #define HAVE_OSSP_UUID_H 1
  _ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ #include <ossp/uuid.h>
+ 
+ _ACEOF
+ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+   $EGREP "uuid_export" >/dev/null 2>&1; then :
  
  else
+   as_fn_error $? "header file <ossp/uuid.h> does not match OSSP UUID library" "$LINENO" 5
+ fi
+ rm -f conftest*
  
! else
!   for ac_header in uuid.h
  do :
    ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
  if test "x$ac_cv_header_uuid_h" = xyes; then :
    cat >>confdefs.h <<_ACEOF
  #define HAVE_UUID_H 1
  _ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ #include <uuid.h>
+ 
+ _ACEOF
+ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+   $EGREP "uuid_export" >/dev/null 2>&1; then :
  
  else
!   as_fn_error $? "header file <uuid.h> does not match OSSP UUID library" "$LINENO" 5
! fi
! rm -f conftest*
! 
! else
!   as_fn_error $? "header file <ossp/uuid.h> or <uuid.h> is required for OSSP UUID" "$LINENO" 5
  fi
  
  done
diff --git a/configure.in b/configure.in
index b94db35..aea362d 100644
*** a/configure.in
--- b/configure.in
*************** PGAC_ARG_BOOL(with, libedit-preferred, n
*** 694,703 ****
  
  
  #
! # OSSP UUID library
  #
! PGAC_ARG_BOOL(with, ossp-uuid, no, [build contrib/uuid-ossp, requires OSSP UUID library])
! AC_SUBST(with_ossp_uuid)
  
  
  #
--- 694,736 ----
  
  
  #
! # UUID library
  #
! # There are at least three UUID libraries in common use: the FreeBSD library,
! # the "Linux" one (originally part of e2fsprogs, now part of util-linux-ng),
! # and the OSSP library (previously the only one supported by Postgres).
! # More than one of these might be present on a given platform,
! # so we make the user say which one she wants.
! # Note: Mac OS X has a version of the "Linux" library.
! #
! PGAC_ARG_BOOL(with, bsd-uuid, no, [build contrib/uuid-ossp, using BSD UUID library])
! PGAC_ARG_BOOL(with, linux-uuid, no, [build contrib/uuid-ossp, using Linux/OSX UUID library])
! PGAC_ARG_BOOL(with, ossp-uuid, no, [build contrib/uuid-ossp, using OSSP UUID library])
! 
! if test "$with_bsd_uuid" = yes ; then
!   if test "$with_linux_uuid" = yes -o "$with_ossp_uuid" = yes ; then
!     AC_MSG_ERROR([Please select only one UUID library])
!   fi
!   AC_DEFINE([HAVE_UUID_BSD], 1, [Define to 1 if you have BSD UUID support.])
!   UUID_EXTRA_OBJS="md5.o sha1.o"
!   with_uuid=yes
! elif test "$with_linux_uuid" = yes ; then
!   if test "$with_ossp_uuid" = yes ; then
!     AC_MSG_ERROR([Please select only one UUID library])
!   fi
!   AC_DEFINE([HAVE_UUID_LINUX], 1, [Define to 1 if you have Linux/OSX UUID support.])
!   UUID_EXTRA_OBJS="md5.o sha1.o"
!   with_uuid=yes
! elif test "$with_ossp_uuid" = yes ; then
!   AC_DEFINE([HAVE_UUID_OSSP], 1, [Define to 1 if you have OSSP UUID support.])
!   UUID_EXTRA_OBJS=""
!   with_uuid=yes
! else
!   UUID_EXTRA_OBJS=""
!   with_uuid=no
! fi
! AC_SUBST(with_uuid)
! AC_SUBST(UUID_EXTRA_OBJS)
  
  
  #
*************** if test "$with_selinux" = yes; then
*** 948,961 ****
  fi
  
  # for contrib/uuid-ossp
! if test "$with_ossp_uuid" = yes ; then
    AC_CHECK_LIB(ossp-uuid, uuid_export,
!     [OSSP_UUID_LIBS="-lossp-uuid"],
      [AC_CHECK_LIB(uuid, uuid_export,
!       [OSSP_UUID_LIBS="-luuid"],
!       [AC_MSG_ERROR([library 'ossp-uuid' or 'uuid' is required for OSSP-UUID])])])
  fi
! AC_SUBST(OSSP_UUID_LIBS)
  
  
  ##
--- 981,1006 ----
  fi
  
  # for contrib/uuid-ossp
! if test "$with_bsd_uuid" = yes ; then
!   # On BSD, the UUID functions are in libc
!   AC_CHECK_FUNC(uuid_to_string,
!     [UUID_LIBS=""],
!     [AC_MSG_ERROR([BSD UUID functions are not present])])
! elif test "$with_linux_uuid" = yes ; then
!   # On OS/X, the UUID functions are in libc
!   AC_CHECK_LIB(uuid, uuid_generate,
!     [UUID_LIBS="-luuid"],
!     [AC_CHECK_FUNC(uuid_generate,
!       [UUID_LIBS=""],
!       [AC_MSG_ERROR([library 'uuid' is required for Linux/OSX UUID])])])
! elif test "$with_ossp_uuid" = yes ; then
    AC_CHECK_LIB(ossp-uuid, uuid_export,
!     [UUID_LIBS="-lossp-uuid"],
      [AC_CHECK_LIB(uuid, uuid_export,
!       [UUID_LIBS="-luuid"],
!       [AC_MSG_ERROR([library 'ossp-uuid' or 'uuid' is required for OSSP UUID])])])
  fi
! AC_SUBST(UUID_LIBS)
  
  
  ##
*************** if test "$with_bonjour" = yes ; then
*** 1075,1084 ****
  fi
  
  # for contrib/uuid-ossp
! if test "$with_ossp_uuid" = yes ; then
!   AC_CHECK_HEADERS(ossp/uuid.h, [], [
!     AC_CHECK_HEADERS(uuid.h, [],
!       [AC_MSG_ERROR([header file <ossp/uuid.h> or <uuid.h> is required for OSSP-UUID])])])
  fi
  
  if test "$PORTNAME" = "win32" ; then
--- 1120,1146 ----
  fi
  
  # for contrib/uuid-ossp
! if test "$with_bsd_uuid" = yes ; then
!   AC_CHECK_HEADERS(uuid.h,
!     [AC_EGREP_HEADER([uuid_to_string], uuid.h, [],
!       [AC_MSG_ERROR([header file <uuid.h> does not match BSD UUID library])])],
!     [AC_MSG_ERROR([header file <uuid.h> is required for BSD UUID])])
! elif test "$with_linux_uuid" = yes ; then
!   AC_CHECK_HEADERS(uuid/uuid.h,
!     [AC_EGREP_HEADER([uuid_generate], uuid/uuid.h, [],
!       [AC_MSG_ERROR([header file <uuid/uuid.h> does not match Linux/OSX UUID library])])],
!     [AC_CHECK_HEADERS(uuid.h,
!       [AC_EGREP_HEADER([uuid_generate], uuid.h, [],
!         [AC_MSG_ERROR([header file <uuid.h> does not match Linux/OSX UUID library])])],
!       [AC_MSG_ERROR([header file <uuid/uuid.h> or <uuid.h> is required for Linux/OSX UUID])])])
! elif test "$with_ossp_uuid" = yes ; then
!   AC_CHECK_HEADERS(ossp/uuid.h,
!     [AC_EGREP_HEADER([uuid_export], ossp/uuid.h, [],
!       [AC_MSG_ERROR([header file <ossp/uuid.h> does not match OSSP UUID library])])],
!     [AC_CHECK_HEADERS(uuid.h,
!       [AC_EGREP_HEADER([uuid_export], uuid.h, [],
!         [AC_MSG_ERROR([header file <uuid.h> does not match OSSP UUID library])])],
!       [AC_MSG_ERROR([header file <ossp/uuid.h> or <uuid.h> is required for OSSP UUID])])])
  fi
  
  if test "$PORTNAME" = "win32" ; then
diff --git a/contrib/Makefile b/contrib/Makefile
index 8dc40f7..7681924 100644
*** a/contrib/Makefile
--- b/contrib/Makefile
*************** else
*** 64,70 ****
  ALWAYS_SUBDIRS += sslinfo
  endif
  
! ifeq ($(with_ossp_uuid),yes)
  SUBDIRS += uuid-ossp
  else
  ALWAYS_SUBDIRS += uuid-ossp
--- 64,70 ----
  ALWAYS_SUBDIRS += sslinfo
  endif
  
! ifeq ($(with_uuid),yes)
  SUBDIRS += uuid-ossp
  else
  ALWAYS_SUBDIRS += uuid-ossp
diff --git a/contrib/uuid-ossp/.gitignore b/contrib/uuid-ossp/.gitignore
index ...6c989c7 .
*** a/contrib/uuid-ossp/.gitignore
--- b/contrib/uuid-ossp/.gitignore
***************
*** 0 ****
--- 1,6 ----
+ /md5.c
+ /sha1.c
+ # Generated subdirectories
+ /log/
+ /results/
+ /tmp_check/
diff --git a/contrib/uuid-ossp/Makefile b/contrib/uuid-ossp/Makefile
index 9b2d2e3..335cc7e 100644
*** a/contrib/uuid-ossp/Makefile
--- b/contrib/uuid-ossp/Makefile
***************
*** 1,12 ****
  # contrib/uuid-ossp/Makefile
  
  MODULE_big = uuid-ossp
! OBJS = uuid-ossp.o
  
  EXTENSION = uuid-ossp
  DATA = uuid-ossp--1.0.sql uuid-ossp--unpackaged--1.0.sql
  
! SHLIB_LINK += $(OSSP_UUID_LIBS)
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 1,21 ----
  # contrib/uuid-ossp/Makefile
  
  MODULE_big = uuid-ossp
! OBJS = uuid-ossp.o $(UUID_EXTRA_OBJS)
  
  EXTENSION = uuid-ossp
  DATA = uuid-ossp--1.0.sql uuid-ossp--unpackaged--1.0.sql
  
! REGRESS = uuid_ossp
! 
! SHLIB_LINK += $(UUID_LIBS)
! 
! # We copy some needed files verbatim from pgcrypto
! pgcrypto_src = $(top_srcdir)/contrib/pgcrypto
! 
! PG_CPPFLAGS = -I$(pgcrypto_src)
! 
! EXTRA_CLEAN = md5.c sha1.c
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*************** top_builddir = ../..
*** 18,20 ****
--- 27,32 ----
  include $(top_builddir)/src/Makefile.global
  include $(top_srcdir)/contrib/contrib-global.mk
  endif
+ 
+ md5.c sha1.c: % : $(pgcrypto_src)/%
+ 	rm -f $@ && $(LN_S) $< .
diff --git a/contrib/uuid-ossp/expected/uuid_ossp.out b/contrib/uuid-ossp/expected/uuid_ossp.out
index ...f393e86 .
*** a/contrib/uuid-ossp/expected/uuid_ossp.out
--- b/contrib/uuid-ossp/expected/uuid_ossp.out
***************
*** 0 ****
--- 1,79 ----
+ CREATE EXTENSION "uuid-ossp";
+ SELECT uuid_nil();
+                uuid_nil               
+ --------------------------------------
+  00000000-0000-0000-0000-000000000000
+ (1 row)
+ 
+ SELECT uuid_ns_dns();
+              uuid_ns_dns              
+ --------------------------------------
+  6ba7b810-9dad-11d1-80b4-00c04fd430c8
+ (1 row)
+ 
+ SELECT uuid_ns_url();
+              uuid_ns_url              
+ --------------------------------------
+  6ba7b811-9dad-11d1-80b4-00c04fd430c8
+ (1 row)
+ 
+ SELECT uuid_ns_oid();
+              uuid_ns_oid              
+ --------------------------------------
+  6ba7b812-9dad-11d1-80b4-00c04fd430c8
+ (1 row)
+ 
+ SELECT uuid_ns_x500();
+              uuid_ns_x500             
+ --------------------------------------
+  6ba7b814-9dad-11d1-80b4-00c04fd430c8
+ (1 row)
+ 
+ SELECT uuid_generate_v1() < uuid_generate_v1();
+  ?column? 
+ ----------
+  t
+ (1 row)
+ 
+ SELECT uuid_generate_v1() < uuid_generate_v1mc();
+  ?column? 
+ ----------
+  t
+ (1 row)
+ 
+ SELECT substr(uuid_generate_v1()::text, 25) = substr(uuid_generate_v1()::text, 25);
+  ?column? 
+ ----------
+  t
+ (1 row)
+ 
+ SELECT substr(uuid_generate_v1()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+  ?column? 
+ ----------
+  t
+ (1 row)
+ 
+ SELECT substr(uuid_generate_v1mc()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+  ?column? 
+ ----------
+  t
+ (1 row)
+ 
+ SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com');
+            uuid_generate_v3           
+ --------------------------------------
+  3d813cbb-47fb-32ba-91df-831e1593ac29
+ (1 row)
+ 
+ SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com');
+            uuid_generate_v5           
+ --------------------------------------
+  21f7f8de-8051-5b89-8680-0195ef798b6a
+ (1 row)
+ 
+ SELECT uuid_generate_v4()::text ~ '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$';
+  ?column? 
+ ----------
+  t
+ (1 row)
+ 
diff --git a/contrib/uuid-ossp/sql/uuid_ossp.sql b/contrib/uuid-ossp/sql/uuid_ossp.sql
index ...8f22417 .
*** a/contrib/uuid-ossp/sql/uuid_ossp.sql
--- b/contrib/uuid-ossp/sql/uuid_ossp.sql
***************
*** 0 ****
--- 1,19 ----
+ CREATE EXTENSION "uuid-ossp";
+ 
+ SELECT uuid_nil();
+ SELECT uuid_ns_dns();
+ SELECT uuid_ns_url();
+ SELECT uuid_ns_oid();
+ SELECT uuid_ns_x500();
+ 
+ SELECT uuid_generate_v1() < uuid_generate_v1();
+ SELECT uuid_generate_v1() < uuid_generate_v1mc();
+ 
+ SELECT substr(uuid_generate_v1()::text, 25) = substr(uuid_generate_v1()::text, 25);
+ SELECT substr(uuid_generate_v1()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+ SELECT substr(uuid_generate_v1mc()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+ 
+ SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com');
+ SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com');
+ 
+ SELECT uuid_generate_v4()::text ~ '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$';
diff --git a/contrib/uuid-ossp/uuid-ossp.c b/contrib/uuid-ossp/uuid-ossp.c
index 8f99084..bc29ade 100644
*** a/contrib/uuid-ossp/uuid-ossp.c
--- b/contrib/uuid-ossp/uuid-ossp.c
***************
*** 1,40 ****
  /*-------------------------------------------------------------------------
   *
!  * UUID generation functions using the OSSP UUID library
   *
   * Copyright (c) 2007-2014, PostgreSQL Global Development Group
   *
   * contrib/uuid-ossp/uuid-ossp.c
   *
   *-------------------------------------------------------------------------
   */
  
  #include "postgres.h"
  #include "fmgr.h"
  #include "utils/builtins.h"
  #include "utils/uuid.h"
  
  /*
!  * There's some confusion over the location of the uuid.h header file.
!  * On Debian, it's installed as ossp/uuid.h, while on Fedora, or if you
!  * install ossp-uuid from a tarball, it's installed as uuid.h. Don't know
!  * what other systems do.
   */
! #ifdef HAVE_OSSP_UUID_H
! #include <ossp/uuid.h>
! #else
  #ifdef HAVE_UUID_H
  #include <uuid.h>
- #else
- #error OSSP uuid.h not found
  #endif
  #endif
  
! /* better both be 16 */
! #if (UUID_LEN != UUID_LEN_BIN)
  #error UUID length mismatch
  #endif
  
  
  PG_MODULE_MAGIC;
  
--- 1,113 ----
  /*-------------------------------------------------------------------------
   *
!  * UUID generation functions using the BSD, Linux or OSSP UUID library
   *
   * Copyright (c) 2007-2014, PostgreSQL Global Development Group
   *
+  * Some parts are Copyright (c) 2009 Andrew Gierth
+  *
   * contrib/uuid-ossp/uuid-ossp.c
   *
   *-------------------------------------------------------------------------
   */
  
  #include "postgres.h"
+ 
  #include "fmgr.h"
  #include "utils/builtins.h"
  #include "utils/uuid.h"
  
  /*
!  * It's possible that there's more than one uuid.h header file present.
!  * We expect configure to set the HAVE_ symbol for only the one we want.
!  *
!  * BSD includes a uuid_hash() function that conflicts with the one in
!  * builtins.h; we #define it out of the way.
   */
! #define uuid_hash bsd_uuid_hash
! 
  #ifdef HAVE_UUID_H
  #include <uuid.h>
  #endif
+ #ifdef HAVE_OSSP_UUID_H
+ #include <ossp/uuid.h>
+ #endif
+ #ifdef HAVE_UUID_UUID_H
+ #include <uuid/uuid.h>
+ #endif
+ 
+ #undef uuid_hash
+ 
+ /*
+  * Some BSD variants offer md5 and sha1 implementations but Linux does not,
+  * so we use a copy of the ones from pgcrypto.  Not needed with OSSP, though.
+  */
+ #ifndef HAVE_UUID_OSSP
+ #include "md5.h"
+ #include "sha1.h"
  #endif
  
! 
! /* Check our UUID length against OSSP's; better both be 16 */
! #if defined(HAVE_UUID_OSSP) && (UUID_LEN != UUID_LEN_BIN)
  #error UUID length mismatch
  #endif
  
+ /* Define some constants like OSSP's, to make the code more readable */
+ #ifndef HAVE_UUID_OSSP
+ #define UUID_MAKE_MC 0
+ #define UUID_MAKE_V1 1
+ #define UUID_MAKE_V2 2
+ #define UUID_MAKE_V3 3
+ #define UUID_MAKE_V4 4
+ #define UUID_MAKE_V5 5
+ #endif
+ 
+ /*
+  * A DCE 1.1 compatible source representation of UUIDs, derived from
+  * the BSD implementation.  BSD already has this; OSSP doesn't need it.
+  */
+ #ifdef HAVE_UUID_LINUX
+ typedef struct
+ {
+ 	uint32_t	time_low;
+ 	uint16_t	time_mid;
+ 	uint16_t	time_hi_and_version;
+ 	uint8_t		clock_seq_hi_and_reserved;
+ 	uint8_t		clock_seq_low;
+ 	uint8_t		node[6];
+ } dce_uuid_t;
+ #else
+ #define dce_uuid_t uuid_t
+ #endif
+ 
+ /* If not OSSP, we need some endianness-manipulation macros */
+ #ifndef HAVE_UUID_OSSP
+ 
+ #define UUID_TO_NETWORK(uu) \
+ do { \
+ 	uu.time_low = htonl(uu.time_low); \
+ 	uu.time_mid = htons(uu.time_mid); \
+ 	uu.time_hi_and_version = htons(uu.time_hi_and_version); \
+ } while (0)
+ 
+ #define UUID_TO_LOCAL(uu) \
+ do { \
+ 	uu.time_low = ntohl(uu.time_low); \
+ 	uu.time_mid = ntohs(uu.time_mid); \
+ 	uu.time_hi_and_version = ntohs(uu.time_hi_and_version); \
+ } while (0)
+ 
+ #define UUID_V3_OR_V5(uu, v) \
+ do { \
+ 	uu.time_hi_and_version &= 0x0FFF; \
+ 	uu.time_hi_and_version |= (v << 12); \
+ 	uu.clock_seq_hi_and_reserved &= 0x3F; \
+ 	uu.clock_seq_hi_and_reserved |= 0x80; \
+ } while(0)
+ 
+ #endif   /* !HAVE_UUID_OSSP */
+ 
  
  PG_MODULE_MAGIC;
  
*************** PG_FUNCTION_INFO_V1(uuid_generate_v3);
*** 51,56 ****
--- 124,131 ----
  PG_FUNCTION_INFO_V1(uuid_generate_v4);
  PG_FUNCTION_INFO_V1(uuid_generate_v5);
  
+ #ifdef HAVE_UUID_OSSP
+ 
  static void
  pguuid_complain(uuid_rc_t rc)
  {
*************** special_uuid_value(const char *name)
*** 114,213 ****
  	return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
  }
  
  
  Datum
  uuid_nil(PG_FUNCTION_ARGS)
  {
  	return special_uuid_value("nil");
  }
  
  
  Datum
  uuid_ns_dns(PG_FUNCTION_ARGS)
  {
  	return special_uuid_value("ns:DNS");
  }
  
  
  Datum
  uuid_ns_url(PG_FUNCTION_ARGS)
  {
  	return special_uuid_value("ns:URL");
  }
  
  
  Datum
  uuid_ns_oid(PG_FUNCTION_ARGS)
  {
  	return special_uuid_value("ns:OID");
  }
  
  
  Datum
  uuid_ns_x500(PG_FUNCTION_ARGS)
  {
  	return special_uuid_value("ns:X500");
! }
! 
! 
! static Datum
! uuid_generate_internal(int mode, const uuid_t *ns, const char *name)
! {
! 	uuid_t	   *uuid;
! 	char	   *str;
! 	uuid_rc_t	rc;
! 
! 	rc = uuid_create(&uuid);
! 	if (rc != UUID_RC_OK)
! 		pguuid_complain(rc);
! 	rc = uuid_make(uuid, mode, ns, name);
! 	if (rc != UUID_RC_OK)
! 		pguuid_complain(rc);
! 	str = uuid_to_string(uuid);
! 	rc = uuid_destroy(uuid);
! 	if (rc != UUID_RC_OK)
! 		pguuid_complain(rc);
! 
! 	return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
  }
  
  
  Datum
  uuid_generate_v1(PG_FUNCTION_ARGS)
  {
! 	return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL);
  }
  
  
  Datum
  uuid_generate_v1mc(PG_FUNCTION_ARGS)
  {
! 	return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL, NULL);
! }
! 
! 
! static Datum
! uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name)
! {
! 	uuid_t	   *ns_uuid;
! 	Datum		result;
! 	uuid_rc_t	rc;
! 
! 	rc = uuid_create(&ns_uuid);
! 	if (rc != UUID_RC_OK)
! 		pguuid_complain(rc);
! 	string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, UUIDPGetDatum(ns))),
! 				   ns_uuid);
  
! 	result = uuid_generate_internal(mode,
! 									ns_uuid,
! 									text_to_cstring(name));
  
! 	rc = uuid_destroy(ns_uuid);
! 	if (rc != UUID_RC_OK)
! 		pguuid_complain(rc);
  
! 	return result;
  }
  
  
--- 189,478 ----
  	return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
  }
  
+ /* len is unused with OSSP, but we want to have the same number of args */
+ static Datum
+ uuid_generate_internal(int mode, const uuid_t *ns, const char *name, int len)
+ {
+ 	uuid_t	   *uuid;
+ 	char	   *str;
+ 	uuid_rc_t	rc;
+ 
+ 	rc = uuid_create(&uuid);
+ 	if (rc != UUID_RC_OK)
+ 		pguuid_complain(rc);
+ 	rc = uuid_make(uuid, mode, ns, name);
+ 	if (rc != UUID_RC_OK)
+ 		pguuid_complain(rc);
+ 	str = uuid_to_string(uuid);
+ 	rc = uuid_destroy(uuid);
+ 	if (rc != UUID_RC_OK)
+ 		pguuid_complain(rc);
+ 
+ 	return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
+ }
+ 
+ 
+ static Datum
+ uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name)
+ {
+ 	uuid_t	   *ns_uuid;
+ 	Datum		result;
+ 	uuid_rc_t	rc;
+ 
+ 	rc = uuid_create(&ns_uuid);
+ 	if (rc != UUID_RC_OK)
+ 		pguuid_complain(rc);
+ 	string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, UUIDPGetDatum(ns))),
+ 				   ns_uuid);
+ 
+ 	result = uuid_generate_internal(mode,
+ 									ns_uuid,
+ 									text_to_cstring(name),
+ 									0);
+ 
+ 	rc = uuid_destroy(ns_uuid);
+ 	if (rc != UUID_RC_OK)
+ 		pguuid_complain(rc);
+ 
+ 	return result;
+ }
+ 
+ #else							/* !HAVE_UUID_OSSP */
+ 
+ static Datum
+ uuid_generate_internal(int v, unsigned char *ns, char *ptr, int len)
+ {
+ 	char		strbuf[40];
+ 
+ 	switch (v)
+ 	{
+ 		case 0:			/* constant-value uuids */
+ 			strlcpy(strbuf, ptr, 37);
+ 			break;
+ 
+ 		case 1:			/* time/node-based uuids */
+ 			{
+ #ifdef HAVE_UUID_LINUX
+ 				uuid_t		uu;
+ 
+ 				uuid_generate_time(uu);
+ 				uuid_unparse(uu, strbuf);
+ 
+ 				/*
+ 				 * PTR, if set, replaces the trailing characters of the uuid;
+ 				 * this is to support v1mc, where a random multicast MAC is
+ 				 * used instead of the physical one
+ 				 */
+ 				if (ptr && len <= 36)
+ 					strcpy(strbuf + (36 - len), ptr);
+ #else							/* BSD */
+ 				uuid_t		uu;
+ 				uint32_t	status = uuid_s_ok;
+ 				char	   *str = NULL;
+ 
+ 				uuid_create(&uu, &status);
+ 
+ 				if (status == uuid_s_ok)
+ 				{
+ 					uuid_to_string(&uu, &str, &status);
+ 					if (status == uuid_s_ok)
+ 					{
+ 						strlcpy(strbuf, str, 37);
+ 
+ 						/*
+ 						 * PTR, if set, replaces the trailing characters of
+ 						 * the uuid; this is to support v1mc, where a random
+ 						 * multicast MAC is used instead of the physical one
+ 						 */
+ 						if (ptr && len <= 36)
+ 							strcpy(strbuf + (36 - len), ptr);
+ 					}
+ 					if (str)
+ 						free(str);
+ 				}
+ 
+ 				if (status != uuid_s_ok)
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
+ 							 errmsg("uuid library failure: %d",
+ 									(int) status)));
+ #endif
+ 				break;
+ 			}
+ 
+ 		case 3:			/* namespace-based MD5 uuids */
+ 		case 5:			/* namespace-based SHA1 uuids */
+ 			{
+ 				dce_uuid_t	uu;
+ #ifdef HAVE_UUID_BSD
+ 				uint32_t	status = uuid_s_ok;
+ 				char	   *str = NULL;
+ #endif
+ 
+ 				if (v == 3)
+ 				{
+ 					MD5_CTX		ctx;
+ 
+ 					MD5Init(&ctx);
+ 					MD5Update(&ctx, ns, sizeof(uu));
+ 					MD5Update(&ctx, (unsigned char *) ptr, len);
+ 					MD5Final((unsigned char *) &uu, &ctx);
+ 				}
+ 				else
+ 				{
+ 					SHA1_CTX	ctx;
+ 
+ 					SHA1Init(&ctx);
+ 					SHA1Update(&ctx, ns, sizeof(uu));
+ 					SHA1Update(&ctx, (unsigned char *) ptr, len);
+ 					SHA1Final((unsigned char *) &uu, &ctx);
+ 				}
+ 
+ 				/* the calculated hash is using local order */
+ 				UUID_TO_NETWORK(uu);
+ 				UUID_V3_OR_V5(uu, v);
+ 
+ #ifdef HAVE_UUID_LINUX
+ 				/* uuid_unparse expects local order */
+ 				UUID_TO_LOCAL(uu);
+ 				uuid_unparse((unsigned char *) &uu, strbuf);
+ #else							/* BSD */
+ 				uuid_to_string(&uu, &str, &status);
+ 
+ 				if (status == uuid_s_ok)
+ 					strlcpy(strbuf, str, 37);
+ 
+ 				if (str)
+ 					free(str);
+ 
+ 				if (status != uuid_s_ok)
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
+ 							 errmsg("uuid library failure: %d",
+ 									(int) status)));
+ #endif
+ 				break;
+ 			}
+ 
+ 		case 4:			/* random uuid */
+ 		default:
+ 			{
+ #ifdef HAVE_UUID_LINUX
+ 				uuid_t		uu;
+ 
+ 				uuid_generate_random(uu);
+ 				uuid_unparse(uu, strbuf);
+ #else							/* BSD */
+ 				snprintf(strbuf, sizeof(strbuf),
+ 						 "%08lx-%04x-%04x-%04x-%04x%08lx",
+ 						 (unsigned long) arc4random(),
+ 						 (unsigned) (arc4random() & 0xffff),
+ 						 (unsigned) ((arc4random() & 0xfff) | 0x4000),
+ 						 (unsigned) ((arc4random() & 0x3fff) | 0x8000),
+ 						 (unsigned) (arc4random() & 0xffff),
+ 						 (unsigned long) arc4random());
+ #endif
+ 				break;
+ 			}
+ 	}
+ 
+ 	return DirectFunctionCall1(uuid_in, CStringGetDatum(strbuf));
+ }
+ 
+ #endif   /* HAVE_UUID_OSSP */
+ 
  
  Datum
  uuid_nil(PG_FUNCTION_ARGS)
  {
+ #ifdef HAVE_UUID_OSSP
  	return special_uuid_value("nil");
+ #else
+ 	return uuid_generate_internal(0, NULL,
+ 								  "00000000-0000-0000-0000-000000000000", 36);
+ #endif
  }
  
  
  Datum
  uuid_ns_dns(PG_FUNCTION_ARGS)
  {
+ #ifdef HAVE_UUID_OSSP
  	return special_uuid_value("ns:DNS");
+ #else
+ 	return uuid_generate_internal(0, NULL,
+ 								  "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 36);
+ #endif
  }
  
  
  Datum
  uuid_ns_url(PG_FUNCTION_ARGS)
  {
+ #ifdef HAVE_UUID_OSSP
  	return special_uuid_value("ns:URL");
+ #else
+ 	return uuid_generate_internal(0, NULL,
+ 								  "6ba7b811-9dad-11d1-80b4-00c04fd430c8", 36);
+ #endif
  }
  
  
  Datum
  uuid_ns_oid(PG_FUNCTION_ARGS)
  {
+ #ifdef HAVE_UUID_OSSP
  	return special_uuid_value("ns:OID");
+ #else
+ 	return uuid_generate_internal(0, NULL,
+ 								  "6ba7b812-9dad-11d1-80b4-00c04fd430c8", 36);
+ #endif
  }
  
  
  Datum
  uuid_ns_x500(PG_FUNCTION_ARGS)
  {
+ #ifdef HAVE_UUID_OSSP
  	return special_uuid_value("ns:X500");
! #else
! 	return uuid_generate_internal(0, NULL,
! 								  "6ba7b814-9dad-11d1-80b4-00c04fd430c8", 36);
! #endif
  }
  
  
  Datum
  uuid_generate_v1(PG_FUNCTION_ARGS)
  {
! 	return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL, 0);
  }
  
  
  Datum
  uuid_generate_v1mc(PG_FUNCTION_ARGS)
  {
! #ifdef HAVE_UUID_OSSP
! 	char	   *buf = NULL;
! #elif defined(HAVE_UUID_LINUX)
! 	char		strbuf[40];
! 	char	   *buf;
! 	uuid_t		uu;
  
! 	uuid_generate_random(uu);
! 	uuid_unparse(uu, strbuf);
! 	buf = strbuf + 24;
! #else							/* BSD */
! 	char		buf[16];
  
! 	/* set IEEE802 multicast and local-admin bits */
! 	snprintf(buf, sizeof(buf), "-%04x%08lx",
! 			 (unsigned) ((arc4random() & 0xffff) | 0x0300),
! 			 (unsigned long) arc4random());
! #endif
  
! 	return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL,
! 								  buf, buf ? 13 : 0);
  }
  
  
*************** uuid_generate_v3(PG_FUNCTION_ARGS)
*** 217,230 ****
  	pg_uuid_t  *ns = PG_GETARG_UUID_P(0);
  	text	   *name = PG_GETARG_TEXT_P(1);
  
  	return uuid_generate_v35_internal(UUID_MAKE_V3, ns, name);
  }
  
  
  Datum
  uuid_generate_v4(PG_FUNCTION_ARGS)
  {
! 	return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL);
  }
  
  
--- 482,500 ----
  	pg_uuid_t  *ns = PG_GETARG_UUID_P(0);
  	text	   *name = PG_GETARG_TEXT_P(1);
  
+ #ifdef HAVE_UUID_OSSP
  	return uuid_generate_v35_internal(UUID_MAKE_V3, ns, name);
+ #else
+ 	return uuid_generate_internal(UUID_MAKE_V3, (unsigned char *) ns,
+ 								  VARDATA(name), VARSIZE(name) - VARHDRSZ);
+ #endif
  }
  
  
  Datum
  uuid_generate_v4(PG_FUNCTION_ARGS)
  {
! 	return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL, 0);
  }
  
  
*************** uuid_generate_v5(PG_FUNCTION_ARGS)
*** 234,238 ****
--- 504,513 ----
  	pg_uuid_t  *ns = PG_GETARG_UUID_P(0);
  	text	   *name = PG_GETARG_TEXT_P(1);
  
+ #ifdef HAVE_UUID_OSSP
  	return uuid_generate_v35_internal(UUID_MAKE_V5, ns, name);
+ #else
+ 	return uuid_generate_internal(UUID_MAKE_V5, (unsigned char *) ns,
+ 								  VARDATA(name), VARSIZE(name) - VARHDRSZ);
+ #endif
  }
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 4b31c0a..14119a1 100644
*** a/src/Makefile.global.in
--- b/src/Makefile.global.in
*************** with_perl	= @with_perl@
*** 163,173 ****
  with_python	= @with_python@
  with_tcl	= @with_tcl@
  with_openssl	= @with_openssl@
- with_ossp_uuid	= @with_ossp_uuid@
  with_selinux	= @with_selinux@
  with_libxml	= @with_libxml@
  with_libxslt	= @with_libxslt@
  with_system_tzdata = @with_system_tzdata@
  with_zlib	= @with_zlib@
  enable_rpath	= @enable_rpath@
  enable_nls	= @enable_nls@
--- 163,173 ----
  with_python	= @with_python@
  with_tcl	= @with_tcl@
  with_openssl	= @with_openssl@
  with_selinux	= @with_selinux@
  with_libxml	= @with_libxml@
  with_libxslt	= @with_libxslt@
  with_system_tzdata = @with_system_tzdata@
+ with_uuid	= @with_uuid@
  with_zlib	= @with_zlib@
  enable_rpath	= @enable_rpath@
  enable_nls	= @enable_nls@
*************** DLLWRAP = @DLLWRAP@
*** 240,246 ****
  LIBS = @LIBS@
  LDAP_LIBS_FE = @LDAP_LIBS_FE@
  LDAP_LIBS_BE = @LDAP_LIBS_BE@
! OSSP_UUID_LIBS = @OSSP_UUID_LIBS@
  LD = @LD@
  with_gnu_ld = @with_gnu_ld@
  ld_R_works = @ld_R_works@
--- 240,247 ----
  LIBS = @LIBS@
  LDAP_LIBS_FE = @LDAP_LIBS_FE@
  LDAP_LIBS_BE = @LDAP_LIBS_BE@
! UUID_LIBS = @UUID_LIBS@
! UUID_EXTRA_OBJS = @UUID_EXTRA_OBJS@
  LD = @LD@
  with_gnu_ld = @with_gnu_ld@
  ld_R_works = @ld_R_works@
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index db930f5..b5317d6 100644
*** a/src/include/pg_config.h.in
--- b/src/include/pg_config.h.in
***************
*** 602,610 ****
--- 602,622 ----
  /* Define to 1 if you have the <utime.h> header file. */
  #undef HAVE_UTIME_H
  
+ /* Define to 1 if you have BSD UUID support. */
+ #undef HAVE_UUID_BSD
+ 
  /* Define to 1 if you have the <uuid.h> header file. */
  #undef HAVE_UUID_H
  
+ /* Define to 1 if you have Linux/OSX UUID support. */
+ #undef HAVE_UUID_LINUX
+ 
+ /* Define to 1 if you have OSSP UUID support. */
+ #undef HAVE_UUID_OSSP
+ 
+ /* Define to 1 if you have the <uuid/uuid.h> header file. */
+ #undef HAVE_UUID_UUID_H
+ 
  /* Define to 1 if you have the `vsnprintf' function. */
  #undef HAVE_VSNPRINTF
  
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to