[PATCH 0/8] Update Win32 port

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
22 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[PATCH 0/8] Update Win32 port

Ladislav Michl
Hi there,

this patches was initiated by Fabrizio Gennari at
https://savannah.nongnu.org/patch/index.php?8934
It aims to restore compilation for Windows host, so please
do test and report results.

There's (at least :)) one thing left: all programs needing
c99 snprintf should compile in common/snprintf.c directly,
otherwise we would need to make our (samba's) version of
snprintf part of gnokii API which does not sound as a bright
idea.

Oh, there's second thing: Implement common/winscript.c.
I'm not sure it is needed, I do not have time for that,
but if you do, ideas are inside that file.

Fabrizio Gennari (4):
  Use the native autoconf support for cross-compilation
  Use lower case for Win32 includes
  Remove some unnecessary #ifndef WIN32
  Update snprintf.c

Ladislav Michl (4):
  Test for number of mkdir() arguments
  Fix compat.c compilation with mingw32
  Use posix_spawn to run external scripts
  Refactor devices build

 ChangeLog                                     |  10 +
 common/Makefile.am                            |   8 +-
 common/cfgreader.c                            |  23 ---
 common/compat.c                               |  24 ++-
 common/device.c                               |  67 +-----
 common/devices/Makefile.am                    |  57 ++---
 common/devices/bluetooth.c                    |  31 ---
 common/devices/dku2libusb.c                   |  42 +---
 common/devices/irda.c                         |  27 ---
 common/devices/osxbluetooth.m                 |   8 +-
 common/devices/socketphonet.c                 |  38 +---
 common/devices/tcp.c                          |  53 +----
 common/devices/tekram.c                       |   1 -
 common/devices/unixbluetooth.c                |  19 +-
 common/devices/unixirda.c                     |  11 +-
 common/devices/winbluetooth.c                 |  16 +-
 common/devices/winirda.c                      |   7 +-
 common/posixscript.c                          | 102 +++++++++
 common/winscript.c                            |  36 ++++
 configure.ac                                  | 195 +++++++++---------
 gnokii/Makefile.am                            |  10 -
 gnokii/gnokii-calendar.c                      |   2 -
 gnokii/gnokii-monitor.c                       |   3 -
 include/compat.h                              |  15 +-
 .../devices/{unixbluetooth.h => bluetooth.h}  |  38 +++-
 include/devices/dku2libusb.h                  |  38 +++-
 include/devices/irda.h                        |  32 +++
 include/devices/socketphonet.h                |  32 +++
 include/devices/tcp.h                         |  33 +++
 include/devices/unixirda.h                    |  15 --
 include/gnokii-internal.h                     |  16 +-
 include/gnokii.h.in                           |   4 +-
 32 files changed, 525 insertions(+), 488 deletions(-)
 delete mode 100644 common/devices/bluetooth.c
 delete mode 100644 common/devices/irda.c
 create mode 100644 common/posixscript.c
 create mode 100644 common/winscript.c
 rename include/devices/{unixbluetooth.h => bluetooth.h} (52%)
 delete mode 100644 include/devices/unixirda.h

--
2.20.0.rc1


_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

[PATCH 1/8] Use the native autoconf support for cross-compilation

Ladislav Michl
From: Fabrizio Gennari <[hidden email]>

Remove homebrew --enable-win option and use the standard autoconf way
to cross-compile, that is using option --host.
---
 ChangeLog    |  3 ++
 configure.ac | 77 ++++++++++++++++++++--------------------------------
 2 files changed, 33 insertions(+), 47 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b2016d7f..d09275ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -114,6 +114,9 @@
  * pcsc driver updates
     o drop support for model=pcsc that was deprecated in libgnokii
       0.6.28 and renamed as model=APDU              (Daniele Forsi)
+ * build updates
+    o use the native Autoconf support for cross-compilation, that
+      is passing --host= to the configure script
 
 0.6.31
 ======
diff --git a/configure.ac b/configure.ac
index e6cefb54..379c7412 100644
--- a/configure.ac
+++ b/configure.ac
@@ -81,31 +81,23 @@ AC_SUBST(GETTEXT_PACKAGE)
 AM_GLIB_GNU_GETTEXT
 AM_ICONV
 
-dnl -----------------------------
-dnl Checks for FreeBSD Build
-dnl -----------------------------
-AC_MSG_CHECKING(if building on FreeBSD)
 
-if test `uname -s` = "FreeBSD" ; then
- AC_MSG_RESULT(yes)
+case x"$host_os" in
+ xfreebsd)
  CPPFLAGS="$CFLAGS -I/usr/local/include"
  LDFLAGS="$LDFLAGS -L/usr/local/lib"
-else
- AC_MSG_RESULT(no)
-fi
-
-dnl -----------------------------
-dnl Checks for NetBSD Build
-dnl -----------------------------
-AC_MSG_CHECKING(if building on NetBSD)
-
-if test `uname -s` = "NetBSD" ; then
-        AC_MSG_RESULT(yes)
+ ;;
+ xnetbsd*)
         CPPFLAGS="$CFLAGS -I/usr/pkg/include/"
         LDFLAGS="$LDFLAGS -L/usr/pkg/lib/"
-else
-        AC_MSG_RESULT(no)
-fi
+        ;;
+ xcygwin32|xcygwin|xmingw32|xmingw32msvc)
+  WIN32=1
+  ;;
+ xdarwin*)
+  FOR_MAC=1
+  ;;
+esac
 
 dnl ======================== Libtool versioning
 AC_LIBTOOL_WIN32_DLL
@@ -522,8 +514,9 @@ AC_ARG_ENABLE(bluetooth,
                             ),,
               [enable_bluetooth=yes])
 
+case "$host_os" in
+linux*)
 dnl ======================== Checks for Linux Bluetooth support
-if test `uname -s` = "Linux" ; then
  if test "$enable_bluetooth" = "yes" -a "$USE_BLUETOOTH" = "no"; then
  AC_MSG_NOTICE([checking for the Linux Bluetooth support])
  AC_CACHE_CHECK(for the struct sockaddr_rc in <bluetooth/rfcomm.h>, ac_cv_have_sockaddr_rc,
@@ -541,10 +534,9 @@ if test `uname -s` = "Linux" ; then
  AC_SUBST(BLUETOOTH_LIBS)
  fi
  fi
-fi
-
+ ;;
+darwin*)
 dnl ======================== Checks for MacOSX Bluetooth support
-if test `uname -s` = "Darwin" ; then
  if test "$enable_bluetooth" = "yes" -a "$USE_BLUETOOTH" = "no"; then
  AC_LANG_PUSH([Objective C])
  AC_CHECK_HEADERS(IOBluetooth/objc/IOBluetoothRFCOMMChannel.h)
@@ -569,11 +561,10 @@ if test `uname -s` = "Darwin" ; then
  AC_SUBST(BLUETOOTH_LIBS)
  fi
  fi
-fi
-AM_CONDITIONAL([FOR_MAC], [test x$ac_cv_have_iobluetooth = xyes])
+ ;;
 
 dnl ======================== Checks for FreeBSD/netgraph Bluetooth support
-if test `uname -s` = "FreeBSD" ; then
+freebsd)
  if test "$enable_bluetooth" = "yes" -a "$USE_BLUETOOTH" = "no"; then
  AC_MSG_NOTICE([checking for the FreeBSD/netgraph Bluetooth support])
  AC_CACHE_CHECK(for the struct sockaddr_rfcomm from <bluetooth.h>, ac_cv_have_sockaddr_rfcomm,
@@ -596,10 +587,10 @@ if test `uname -s` = "FreeBSD" ; then
  fi
  fi
  fi
-fi
+ ;;
 
 dnl ======================== Checks for NetBSD/netbt Bluetooth support
-if test `uname -s` = "NetBSD" ; then
+netbsd*)
  if test "$enable_bluetooth" = "yes" -a "$USE_BLUETOOTH" = "no"; then
  AC_MSG_NOTICE([checking for the NetBSD/netbt Bluetooth support])
  AC_CACHE_CHECK(for the struct sockaddr_bt from <bluetooth.h>, ac_cv_have_sockaddr_bt,
@@ -623,7 +614,8 @@ if test `uname -s` = "NetBSD" ; then
  fi
  fi
  fi
-fi
+ ;;
+esac
 
 dnl ======================== Checks for X base support
 
@@ -797,26 +789,17 @@ if test "$enable_libpcsclite" = "yes"; then
  fi
 fi
 
-AC_ARG_ENABLE(win,
-   [  --enable-win            if you want Windows support ],
-   [ if test x$enable_win32 = xyes; then
- AC_DEFINE(WIN32, 1, [Whether compiling on Windows])
- WIN32=1
- if test x$cross_compiling = xyes; then
- AC_DEFINE(WIN32_CROSS, 1, [Define if you cross compile Windows.])
- WIN32_CROSS=1
- win32="cross"
- else
- win32="yes"
+if test x"$host_os" = "xcygwin32" -o x"$host_os" = "xcygwin" -o x"$host_os" = "xmingw32" -o x"$host_os" = "xmingw32msvc"; then
+ AC_CHECK_HEADER(af_irda.h, [AC_DEFINE(HAVE_IRDA, 1, [Whether IrDA is available]) USE_IRDA="yes" LIBS="$LIBS -lwinmm"],, [#include <windows.h>])
+ AC_CHECK_HEADER(ws2bth.h, [AC_DEFINE(HAVE_BLUETOOTH, 1, [Whether Bluetooth is available]) USE_BLUETOOTH="yes"],, [#include <windows.h>])
+ if test x"$USE_IRDA" = "xyes" -o x"$USE_BLUETOOTH" = "xyes"; then
+  LIBS="$LIBS -lws2_32"
  fi
- AC_CHECK_HEADER(af_irda.h, [AC_DEFINE(HAVE_IRDA, 1, [Whether IrDA is available]) USE_IRDA="yes"])
-     else
- win32="no"
-     fi ],
-   [ win32="no"]
-)
+ WIN32=1
+fi
 
 AM_CONDITIONAL(WIN32, test "x$WIN32" = "x1")
+AM_CONDITIONAL([FOR_MAC], [test "x$FOR_MAC" = "x1"])
 
 AC_ARG_ENABLE(unix98test,
    [  --enable-unix98test     if you want to disable UNIX98 test and assume to
--
2.20.0.rc1


_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

[PATCH 2/8] Use lower case for Win32 includes

Ladislav Michl
In reply to this post by Ladislav Michl
From: Fabrizio Gennari <[hidden email]>

mingw32 provides lower case names for Win32 header files, use lower
case names in #include directives.
---
 ChangeLog                     | 4 ++++
 common/devices/winbluetooth.c | 6 +++---
 include/gnokii.h.in           | 4 ++--
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d09275ce..ed6d42ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -117,6 +117,10 @@
  * build updates
     o use the native Autoconf support for cross-compilation, that
       is passing --host= to the configure script
+ * win32 updates
+    o since Linux filesystems are case-sensitive, and MinGW-W64
+      provides lower case names for Win32 header files, use lower
+      case names in #include directives
 
 0.6.31
 ======
diff --git a/common/devices/winbluetooth.c b/common/devices/winbluetooth.c
index 832a46f9..a898e2e6 100644
--- a/common/devices/winbluetooth.c
+++ b/common/devices/winbluetooth.c
@@ -12,10 +12,10 @@
 
 #ifdef HAVE_BLUETOOTH
 
-#include <Winsock2.h>
+#include <winsock2.h>
 #include <mmsystem.h>
-#include <Ws2bth.h>
-#include <BluetoothAPIs.h>
+#include <ws2bth.h>
+#include <bluetoothapis.h>
 
 #include "compat.h"
 #include "gnokii.h"
diff --git a/include/gnokii.h.in b/include/gnokii.h.in
index b3253455..d407d53d 100644
--- a/include/gnokii.h.in
+++ b/include/gnokii.h.in
@@ -31,8 +31,8 @@ extern "C" {
 #elif defined(__svr4__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__MACH__)
 #  include <inttypes.h>
 #  include <sys/time.h>
-#elif defined(_MSC_VER) && defined(WIN32)
-#  include <Winsock.h> /* for struct timeval */
+#elif defined(WIN32)
+#  include <winsock.h> /* for struct timeval */
 typedef unsigned char uint8_t;
 #endif
 
--
2.20.0.rc1


_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

[PATCH 3/8] Remove some unnecessary #ifndef WIN32

Ladislav Michl
In reply to this post by Ladislav Michl
From: Fabrizio Gennari <[hidden email]>

This code works just fine under Windows, so compile
it here as well.
---
 gnokii/gnokii-calendar.c | 2 --
 gnokii/gnokii-monitor.c  | 3 ---
 2 files changed, 5 deletions(-)

diff --git a/gnokii/gnokii-calendar.c b/gnokii/gnokii-calendar.c
index e32bf769..10236bae 100644
--- a/gnokii/gnokii-calendar.c
+++ b/gnokii/gnokii-calendar.c
@@ -264,7 +264,6 @@ gn_error writecalendarnote(int argc, char *argv[], gn_data *data, struct gn_stat
  rewind(f);
  error = gn_ical2calnote(f, &calnote, i);
 
-#ifndef WIN32
  if (error == GN_ERR_NOTIMPLEMENTED) {
  switch (gn_vcal_file_event_read(optarg, &calnote, i)) {
  case 0:
@@ -275,7 +274,6 @@ gn_error writecalendarnote(int argc, char *argv[], gn_data *data, struct gn_stat
  break;
  }
  }
-#endif
  if (error != GN_ERR_NONE) {
  /* when reading until 'end' it's not an error if it tried to read a non existent note */
  if ((last_location == INT_MAX) && (error == GN_ERR_EMPTYLOCATION)) {
diff --git a/gnokii/gnokii-monitor.c b/gnokii/gnokii-monitor.c
index 7fde06c5..30aba457 100644
--- a/gnokii/gnokii-monitor.c
+++ b/gnokii/gnokii-monitor.c
@@ -109,8 +109,6 @@ static gn_error readcbmessage(gn_cb_message *message)
 
 static void displaycall(int call_id)
 {
-/* FIXME!!! */
-#ifndef WIN32
  gn_call *call;
  struct timeval now, delta;
  char *s;
@@ -148,7 +146,6 @@ static void displaycall(int call_id)
  fprintf(stdout, _("CALL%d: %s %s (%s) (callid: %d, duration: %d sec)\n"),
  call_id, s, call->remote_number, call->remote_name,
  call->call_id, (int)delta.tv_sec);
-#endif
 }
 
 /* Same code is for getnetworkinfo */
--
2.20.0.rc1


_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

[PATCH 4/8] Update snprintf.c

Ladislav Michl
In reply to this post by Ladislav Michl
From: Fabrizio Gennari <[hidden email]>

Update to the latest version from Samba's repository,
https://git.samba.org/?p=samba.git;a=blob;f=lib/replace/snprintf.c;hb=9f03cf91235641d017e31abc3856df994e6d1cf2
---

diff --git a/ChangeLog b/ChangeLog
index ed6d42ff..ad462734 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -121,6 +121,9 @@
     o since Linux filesystems are case-sensitive, and MinGW-W64
       provides lower case names for Win32 header files, use lower
       case names in #include directives
+    o update snprintf.c (replacement of snprintf for systems where
+      it is not C99-compatible, such as Win32) to the latest
+      version from Samba's repository
 
 0.6.31
 ======

diff --git a/common/snprintf.c b/common/snprintf.c
index b1222806..1f5f93e4 100644
--- a/common/snprintf.c
+++ b/common/snprintf.c
@@ -1,3 +1,7 @@
+/*
+ * NOTE: If you change this file, please merge it into rsync, samba, etc.
+ */
+
 /*
  * Copyright Patrick Powell 1995
  * This code is based on code written by Patrick Powell ([hidden email])
@@ -30,14 +34,14 @@
  *    probably requires libm on most operating systems.  Don't yet
  *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
  *    was pretty badly broken, it just wasn't being exercised in ways
- *    which showed it, so that's been fixed.  Also, formated the code
+ *    which showed it, so that's been fixed.  Also, formatted the code
  *    to mutt conventions, and removed dead code left over from the
  *    original.  Also, there is now a builtin-test, just compile with:
  *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
  *    and run snprintf for results.
- *
+ *
  *  Thomas Roessler <[hidden email]> 01/27/98 for mutt 0.89i
- *    The PGP code was using unsigned hexadecimal formats.
+ *    The PGP code was using unsigned hexadecimal formats.
  *    Unfortunately, unsigned formats simply didn't work.
  *
  *  Michael Elkins <[hidden email]> 03/05/98 for mutt 0.90.8
@@ -53,47 +57,76 @@
  *    got rid of fcvt code (twas buggy and made testing harder)
  *    added C99 semantics
  *
+ * date: 2002/12/19 19:56:31;  author: herb;  state: Exp;  lines: +2 -0
+ * actually print args for %g and %e
+ *
+ * date: 2002/06/03 13:37:52;  author: jmcd;  state: Exp;  lines: +8 -0
+ * Since includes.h isn't included here, VA_COPY has to be defined here.  I don't
+ * see any include file that is guaranteed to be here, so I'm defining it
+ * locally.  Fixes AIX and Solaris builds.
+ *
+ * date: 2002/06/03 03:07:24;  author: tridge;  state: Exp;  lines: +5 -13
+ * put the ifdef for HAVE_VA_COPY in one place rather than in lots of
+ * functions
+ *
+ * date: 2002/05/17 14:51:22;  author: jmcd;  state: Exp;  lines: +21 -4
+ * Fix usage of va_list passed as an arg.  Use __va_copy before using it
+ * when it exists.
+ *
+ * date: 2002/04/16 22:38:04;  author: idra;  state: Exp;  lines: +20 -14
+ * Fix incorrect zpadlen handling in fmtfp.
+ * Thanks to Ollie Oldham <[hidden email]> for spotting it.
+ * few mods to make it easier to compile the tests.
+ * addedd the "Ollie" test to the floating point ones.
+ *
+ * Martin Pool ([hidden email]) April 2003
+ *    Remove NO_CONFIG_H so that the test case can be built within a source
+ *    tree with less trouble.
+ *    Remove unnecessary SAFE_FREE() definition.
+ *
+ * Martin Pool ([hidden email]) May 2003
+ *    Put in a prototype for dummy_snprintf() to quiet compiler warnings.
+ *
+ *    Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even
+ *    if the C library has some snprintf functions already.
+ *
+ * Darren Tucker ([hidden email]) 2005
+ *    Fix bug allowing read overruns of the source string with "%.*s"
+ *    Usually harmless unless the read runs outside the process' allocation
+ *    (eg if your malloc does guard pages) in which case it will segfault.
+ *    From OpenSSH.  Also added test for same.
+ *
+ * Simo Sorce ([hidden email]) Jan 2006
+ *
+ *    Add support for position independent parameters
+ *    fix fmtstr now it conforms to sprintf wrt min.max
+ *
  **************************************************************/
 
-#ifndef NO_CONFIG_H /* for some tests */
-#  include "config.h"
-#endif
-
 #include "compat.h"
 
-#define snprintf __dummy_snprintf
-
-#if defined(WIN32) && !defined(CYGWIN)
-#  include <stdio.h>
-#  include <stddef.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#  include <string.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-#  include <strings.h>
-#endif
-#ifdef HAVE_CTYPE_H
-#  include <ctype.h>
-#endif
-#include <sys/types.h>
-#ifdef HAVE_STDARG_H
-#  include <stdarg.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif
+#ifdef TEST_SNPRINTF /* need math library headers for testing */
 
-#undef snprintf
+/* In test mode, we pretend that this system doesn't have any snprintf
+ * functions, regardless of what config.h says. */
+#  undef HAVE_SNPRINTF
+#  undef HAVE_VSNPRINTF
+#  undef HAVE_C99_VSNPRINTF
+#  undef HAVE_ASPRINTF
+#  undef HAVE_VASPRINTF
+#  include <math.h>
+#endif /* TEST_SNPRINTF */
 
 #if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF)
 /* only include stdio.h if we are not re-defining snprintf or vsnprintf */
-#  include <stdio.h>
-/* make the compiler happy with an empty file */
-void dummy_snprintf(void) {}
-#else
+#include <stdio.h>
+ /* make the compiler happy with an empty file */
+ void dummy_snprintf(void);
+ void dummy_snprintf(void) {}
+#endif /* HAVE_SNPRINTF, etc */
+
+/* yes this really must be a ||. Don't muck with this (tridge) */
+#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
 
 #ifdef HAVE_LONG_DOUBLE
 #define LDOUBLE long double
@@ -101,26 +134,22 @@ void dummy_snprintf(void) {}
 #define LDOUBLE double
 #endif
 
-#ifdef HAVE_LONG_LONG_INT
+#ifdef HAVE_LONG_LONG
 #define LLONG long long
 #else
 #define LLONG long
 #endif
 
-/* free memory if the pointer is valid and zero the pointer */
-#ifndef SAFE_FREE
-#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
+#ifndef VA_COPY
+#ifdef HAVE_VA_COPY
+#define VA_COPY(dest, src) va_copy(dest, src)
+#else
+#ifdef HAVE___VA_COPY
+#define VA_COPY(dest, src) __va_copy(dest, src)
+#else
+#define VA_COPY(dest, src) (dest) = (src)
+#endif
 #endif
-
-static size_t dopr(char *buffer, size_t maxlen, const char *format,
-   va_list args);
-static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
-    char *value, int flags, int min, int max);
-static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
-    long value, int base, int min, int max, int flags);
-static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
-   LDOUBLE fvalue, int min, int max, int flags);
-static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
 
 /*
  * dopr(): poor man's version of doprintf
@@ -146,66 +175,145 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
 #define DP_F_UNSIGNED (1 << 6)
 
 /* Conversion Flags */
-#define DP_C_SHORT   1
-#define DP_C_LONG    2
-#define DP_C_LDOUBLE 3
-#define DP_C_LLONG   4
+#define DP_C_CHAR    1
+#define DP_C_SHORT   2
+#define DP_C_LONG    3
+#define DP_C_LDOUBLE 4
+#define DP_C_LLONG   5
+#define DP_C_SIZET   6
+
+/* Chunk types */
+#define CNK_FMT_STR 0
+#define CNK_INT     1
+#define CNK_OCTAL   2
+#define CNK_UINT    3
+#define CNK_HEX     4
+#define CNK_FLOAT   5
+#define CNK_CHAR    6
+#define CNK_STRING  7
+#define CNK_PTR     8
+#define CNK_NUM     9
+#define CNK_PRCNT   10
 
 #define char_to_int(p) ((p)- '0')
 #ifndef MAX
 #define MAX(p,q) (((p) >= (q)) ? (p) : (q))
 #endif
 
-static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args)
-{
- char ch;
+struct pr_chunk {
+ int type; /* chunk type */
+ int num; /* parameter number */
+ int min;
+ int max;
+ int flags;
+ int cflags;
+ int start;
+ int len;
  LLONG value;
  LDOUBLE fvalue;
  char *strvalue;
- int min;
- int max;
+ void *pnum;
+ struct pr_chunk *min_star;
+ struct pr_chunk *max_star;
+ struct pr_chunk *next;
+};
+
+struct pr_chunk_x {
+ struct pr_chunk **chunks;
+ int num;
+};
+
+static int dopr(char *buffer, size_t maxlen, const char *format,
+   va_list args_in);
+static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
+    char *value, int flags, int min, int max);
+static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
+    LLONG value, int base, int min, int max, int flags);
+static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
+   LDOUBLE fvalue, int min, int max, int flags);
+static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
+static struct pr_chunk *new_chunk(void);
+static int add_cnk_list_entry(struct pr_chunk_x **list,
+ int max_num, struct pr_chunk *chunk);
+
+static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in)
+{
+ char ch;
  int state;
- int flags;
- int cflags;
+ int pflag;
+ int pnum;
+ int pfirst;
  size_t currlen;
-
+ va_list args;
+ const char *base;
+ struct pr_chunk *chunks = NULL;
+ struct pr_chunk *cnk = NULL;
+ struct pr_chunk_x *clist = NULL;
+ int max_pos;
+ int ret = -1;
+
+ VA_COPY(args, args_in);
+
  state = DP_S_DEFAULT;
- currlen = flags = cflags = min = 0;
- max = -1;
+ pfirst = 1;
+ pflag = 0;
+ pnum = 0;
+
+ max_pos = 0;
+ base = format;
  ch = *format++;
 
+ /* retrieve the string structure as chunks */
  while (state != DP_S_DONE) {
- if (ch == '\0')
+ if (ch == '\0')
  state = DP_S_DONE;
 
  switch(state) {
  case DP_S_DEFAULT:
- if (ch == '%')
+
+ if (cnk) {
+ cnk->next = new_chunk();
+ cnk = cnk->next;
+ } else {
+ cnk = new_chunk();
+ }
+ if (!cnk) goto done;
+ if (!chunks) chunks = cnk;
+
+ if (ch == '%') {
  state = DP_S_FLAGS;
- else
- dopr_outch (buffer, &currlen, maxlen, ch);
- ch = *format++;
+ ch = *format++;
+ } else {
+ cnk->type = CNK_FMT_STR;
+ cnk->start = format - base -1;
+ while ((ch != '\0') && (ch != '%')) ch = *format++;
+ cnk->len = format - base - cnk->start -1;
+ }
  break;
  case DP_S_FLAGS:
  switch (ch) {
  case '-':
- flags |= DP_F_MINUS;
+ cnk->flags |= DP_F_MINUS;
  ch = *format++;
  break;
  case '+':
- flags |= DP_F_PLUS;
+ cnk->flags |= DP_F_PLUS;
  ch = *format++;
  break;
  case ' ':
- flags |= DP_F_SPACE;
+ cnk->flags |= DP_F_SPACE;
  ch = *format++;
  break;
  case '#':
- flags |= DP_F_NUM;
+ cnk->flags |= DP_F_NUM;
  ch = *format++;
  break;
  case '0':
- flags |= DP_F_ZERO;
+ cnk->flags |= DP_F_ZERO;
+ ch = *format++;
+ break;
+ case 'I':
+ /* internationalization not supported yet */
  ch = *format++;
  break;
  default:
@@ -215,13 +323,51 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
  break;
  case DP_S_MIN:
  if (isdigit((unsigned char)ch)) {
- min = 10*min + char_to_int (ch);
+ cnk->min = 10 * cnk->min + char_to_int (ch);
+ ch = *format++;
+ } else if (ch == '$') {
+ if (!pfirst && !pflag) {
+ /* parameters must be all positioned or none */
+ goto done;
+ }
+ if (pfirst) {
+ pfirst = 0;
+ pflag = 1;
+ }
+ if (cnk->min == 0) /* what ?? */
+ goto done;
+ cnk->num = cnk->min;
+ cnk->min = 0;
  ch = *format++;
  } else if (ch == '*') {
- min = va_arg (args, int);
+ if (pfirst) pfirst = 0;
+ cnk->min_star = new_chunk();
+ if (!cnk->min_star) /* out of memory :-( */
+ goto done;
+ cnk->min_star->type = CNK_INT;
+ if (pflag) {
+ int num;
+ ch = *format++;
+ if (!isdigit((unsigned char)ch)) {
+ /* parameters must be all positioned or none */
+ goto done;
+ }
+ for (num = 0; isdigit((unsigned char)ch); ch = *format++) {
+ num = 10 * num + char_to_int(ch);
+ }
+ cnk->min_star->num = num;
+ if (ch != '$') /* what ?? */
+ goto done;
+ } else {
+ cnk->min_star->num = ++pnum;
+ }
+ max_pos = add_cnk_list_entry(&clist, max_pos, cnk->min_star);
+ if (max_pos == 0) /* out of memory :-( */
+ goto done;
  ch = *format++;
  state = DP_S_DOT;
  } else {
+ if (pfirst) pfirst = 0;
  state = DP_S_DOT;
  }
  break;
@@ -229,18 +375,51 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
  if (ch == '.') {
  state = DP_S_MAX;
  ch = *format++;
- } else {
+ } else {
  state = DP_S_MOD;
  }
  break;
  case DP_S_MAX:
  if (isdigit((unsigned char)ch)) {
- if (max < 0)
- max = 0;
- max = 10*max + char_to_int (ch);
+ if (cnk->max < 0)
+ cnk->max = 0;
+ cnk->max = 10 * cnk->max + char_to_int (ch);
+ ch = *format++;
+ } else if (ch == '$') {
+ if (!pfirst && !pflag) {
+ /* parameters must be all positioned or none */
+ goto done;
+ }
+ if (cnk->max <= 0) /* what ?? */
+ goto done;
+ cnk->num = cnk->max;
+ cnk->max = -1;
  ch = *format++;
  } else if (ch == '*') {
- max = va_arg (args, int);
+ cnk->max_star = new_chunk();
+ if (!cnk->max_star) /* out of memory :-( */
+ goto done;
+ cnk->max_star->type = CNK_INT;
+ if (pflag) {
+ int num;
+ ch = *format++;
+ if (!isdigit((unsigned char)ch)) {
+ /* parameters must be all positioned or none */
+ goto done;
+ }
+ for (num = 0; isdigit((unsigned char)ch); ch = *format++) {
+ num = 10 * num + char_to_int(ch);
+ }
+ cnk->max_star->num = num;
+ if (ch != '$') /* what ?? */
+ goto done;
+ } else {
+ cnk->max_star->num = ++pnum;
+ }
+ max_pos = add_cnk_list_entry(&clist, max_pos, cnk->max_star);
+ if (max_pos == 0) /* out of memory :-( */
+ goto done;
+
  ch = *format++;
  state = DP_S_MOD;
  } else {
@@ -250,19 +429,31 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
  case DP_S_MOD:
  switch (ch) {
  case 'h':
- cflags = DP_C_SHORT;
+ cnk->cflags = DP_C_SHORT;
  ch = *format++;
+ if (ch == 'h') {
+ cnk->cflags = DP_C_CHAR;
+ ch = *format++;
+ }
  break;
  case 'l':
- cflags = DP_C_LONG;
+ cnk->cflags = DP_C_LONG;
  ch = *format++;
  if (ch == 'l') { /* It's a long long */
- cflags = DP_C_LLONG;
+ cnk->cflags = DP_C_LLONG;
  ch = *format++;
  }
  break;
+ case 'j':
+ cnk->cflags = DP_C_LLONG;
+ ch = *format++;
+ break;
  case 'L':
- cflags = DP_C_LDOUBLE;
+ cnk->cflags = DP_C_LDOUBLE;
+ ch = *format++;
+ break;
+ case 'z':
+ cnk->cflags = DP_C_SIZET;
  ch = *format++;
  break;
  default:
@@ -271,131 +462,65 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
  state = DP_S_CONV;
  break;
  case DP_S_CONV:
+ if (cnk->num == 0) cnk->num = ++pnum;
+ max_pos = add_cnk_list_entry(&clist, max_pos, cnk);
+ if (max_pos == 0) /* out of memory :-( */
+ goto done;
+
  switch (ch) {
  case 'd':
  case 'i':
- if (cflags == DP_C_SHORT)
- value = va_arg (args, int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, long int);
- else if (cflags == DP_C_LLONG)
- value = va_arg (args, LLONG);
- else
- value = va_arg (args, int);
- fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+ cnk->type = CNK_INT;
  break;
  case 'o':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = va_arg (args, unsigned int);
- else if (cflags == DP_C_LONG)
- value = (long)va_arg (args, unsigned long int);
- else if (cflags == DP_C_LLONG)
- value = (long)va_arg (args, unsigned LLONG);
- else
- value = (long)va_arg (args, unsigned int);
- fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
+ cnk->type = CNK_OCTAL;
+ cnk->flags |= DP_F_UNSIGNED;
  break;
  case 'u':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = va_arg (args, unsigned int);
- else if (cflags == DP_C_LONG)
- value = (long)va_arg (args, unsigned long int);
- else if (cflags == DP_C_LLONG)
- value = (LLONG)va_arg (args, unsigned LLONG);
- else
- value = (long)va_arg (args, unsigned int);
- fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+ cnk->type = CNK_UINT;
+ cnk->flags |= DP_F_UNSIGNED;
  break;
  case 'X':
- flags |= DP_F_UP;
+ cnk->flags |= DP_F_UP;
  case 'x':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = va_arg (args, unsigned int);
- else if (cflags == DP_C_LONG)
- value = (long)va_arg (args, unsigned long int);
- else if (cflags == DP_C_LLONG)
- value = (LLONG)va_arg (args, unsigned LLONG);
- else
- value = (long)va_arg (args, unsigned int);
- fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
- break;
- case 'f':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- /* um, floating point? */
- fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
+ cnk->type = CNK_HEX;
+ cnk->flags |= DP_F_UNSIGNED;
  break;
+ case 'A':
+ /* hex float not supported yet */
  case 'E':
- flags |= DP_F_UP;
- case 'e':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- break;
  case 'G':
- flags |= DP_F_UP;
+ case 'F':
+ cnk->flags |= DP_F_UP;
+ case 'a':
+ /* hex float not supported yet */
+ case 'e':
+ case 'f':
  case 'g':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
+ cnk->type = CNK_FLOAT;
  break;
  case 'c':
- dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
+ cnk->type = CNK_CHAR;
  break;
  case 's':
- strvalue = va_arg (args, char *);
- if (!strvalue) strvalue = "(NULL)";
- if (max == -1) {
- max = strlen(strvalue);
- }
- if (min > 0 && max >= 0 && min > max) max = min;
- fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
+ cnk->type = CNK_STRING;
  break;
  case 'p':
- strvalue = va_arg (args, void *);
- fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
+ cnk->type = CNK_PTR;
+ cnk->flags |= DP_F_UNSIGNED;
  break;
  case 'n':
- if (cflags == DP_C_SHORT) {
- short int *num;
- num = va_arg (args, short int *);
- *num = currlen;
- } else if (cflags == DP_C_LONG) {
- long int *num;
- num = va_arg (args, long int *);
- *num = (long int)currlen;
- } else if (cflags == DP_C_LLONG) {
- LLONG *num;
- num = va_arg (args, LLONG *);
- *num = (LLONG)currlen;
- } else {
- int *num;
- num = va_arg (args, int *);
- *num = currlen;
- }
+ cnk->type = CNK_NUM;
  break;
  case '%':
- dopr_outch (buffer, &currlen, maxlen, ch);
- break;
- case 'w':
- /* not supported yet, treat as next char */
- ch = *format++;
+ cnk->type = CNK_PRCNT;
  break;
  default:
- /* Unknown, skip */
- break;
+ /* Unknown, bail out*/
+ goto done;
  }
  ch = *format++;
  state = DP_S_DEFAULT;
- flags = cflags = min = 0;
- max = -1;
  break;
  case DP_S_DONE:
  break;
@@ -404,14 +529,237 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
  break; /* some picky compilers need this */
  }
  }
+
+ /* retrieve the format arguments */
+ for (pnum = 0; pnum < max_pos; pnum++) {
+ int i;
+
+ if (clist[pnum].num == 0) {
+ /* ignoring a parameter should not be permitted
+ * all parameters must be matched at least once
+ * BUT seem some system ignore this rule ...
+ * at least my glibc based system does --SSS
+ */
+#ifdef DEBUG_SNPRINTF
+ printf("parameter at position %d not used\n", pnum+1);
+#endif
+ /* eat the parameter */
+ va_arg (args, int);
+ continue;
+ }
+ for (i = 1; i < clist[pnum].num; i++) {
+ if (clist[pnum].chunks[0]->type != clist[pnum].chunks[i]->type) {
+ /* nooo noo no!
+ * all the references to a parameter
+ * must be of the same type
+ */
+ goto done;
+ }
+ }
+ cnk = clist[pnum].chunks[0];
+ switch (cnk->type) {
+ case CNK_INT:
+ if (cnk->cflags == DP_C_SHORT)
+ cnk->value = va_arg (args, int);
+ else if (cnk->cflags == DP_C_LONG)
+ cnk->value = va_arg (args, long int);
+ else if (cnk->cflags == DP_C_LLONG)
+ cnk->value = va_arg (args, LLONG);
+ else if (cnk->cflags == DP_C_SIZET)
+ cnk->value = va_arg (args, ssize_t);
+ else
+ cnk->value = va_arg (args, int);
+
+ for (i = 1; i < clist[pnum].num; i++) {
+ clist[pnum].chunks[i]->value = cnk->value;
+ }
+ break;
+
+ case CNK_OCTAL:
+ case CNK_UINT:
+ case CNK_HEX:
+ if (cnk->cflags == DP_C_SHORT)
+ cnk->value = va_arg (args, unsigned int);
+ else if (cnk->cflags == DP_C_LONG)
+ cnk->value = (unsigned long int)va_arg (args, unsigned long int);
+ else if (cnk->cflags == DP_C_LLONG)
+ cnk->value = (LLONG)va_arg (args, unsigned LLONG);
+ else if (cnk->cflags == DP_C_SIZET)
+ cnk->value = (size_t)va_arg (args, size_t);
+ else
+ cnk->value = (unsigned int)va_arg (args, unsigned int);
+
+ for (i = 1; i < clist[pnum].num; i++) {
+ clist[pnum].chunks[i]->value = cnk->value;
+ }
+ break;
+
+ case CNK_FLOAT:
+ if (cnk->cflags == DP_C_LDOUBLE)
+ cnk->fvalue = va_arg (args, LDOUBLE);
+ else
+ cnk->fvalue = va_arg (args, double);
+
+ for (i = 1; i < clist[pnum].num; i++) {
+ clist[pnum].chunks[i]->fvalue = cnk->fvalue;
+ }
+ break;
+
+ case CNK_CHAR:
+ cnk->value = va_arg (args, int);
+
+ for (i = 1; i < clist[pnum].num; i++) {
+ clist[pnum].chunks[i]->value = cnk->value;
+ }
+ break;
+
+ case CNK_STRING:
+ cnk->strvalue = va_arg (args, char *);
+ if (!cnk->strvalue) cnk->strvalue = "(NULL)";
+
+ for (i = 1; i < clist[pnum].num; i++) {
+ clist[pnum].chunks[i]->strvalue = cnk->strvalue;
+ }
+ break;
+
+ case CNK_PTR:
+ cnk->strvalue = va_arg (args, void *);
+ for (i = 1; i < clist[pnum].num; i++) {
+ clist[pnum].chunks[i]->strvalue = cnk->strvalue;
+ }
+ break;
+
+ case CNK_NUM:
+ if (cnk->cflags == DP_C_CHAR)
+ cnk->pnum = va_arg (args, char *);
+ else if (cnk->cflags == DP_C_SHORT)
+ cnk->pnum = va_arg (args, short int *);
+ else if (cnk->cflags == DP_C_LONG)
+ cnk->pnum = va_arg (args, long int *);
+ else if (cnk->cflags == DP_C_LLONG)
+ cnk->pnum = va_arg (args, LLONG *);
+ else if (cnk->cflags == DP_C_SIZET)
+ cnk->pnum = va_arg (args, ssize_t *);
+ else
+ cnk->pnum = va_arg (args, int *);
+
+ for (i = 1; i < clist[pnum].num; i++) {
+ clist[pnum].chunks[i]->pnum = cnk->pnum;
+ }
+ break;
+
+ case CNK_PRCNT:
+ break;
+
+ default:
+ /* what ?? */
+ goto done;
+ }
+ }
+ /* print out the actual string from chunks */
+ currlen = 0;
+ cnk = chunks;
+ while (cnk) {
+ int len, min, max;
+
+ if (cnk->min_star) min = cnk->min_star->value;
+ else min = cnk->min;
+ if (cnk->max_star) max = cnk->max_star->value;
+ else max = cnk->max;
+
+ switch (cnk->type) {
+
+ case CNK_FMT_STR:
+ if (maxlen != 0 && maxlen > currlen) {
+ if (maxlen > (currlen + cnk->len)) len = cnk->len;
+ else len = maxlen - currlen;
+
+ memcpy(&(buffer[currlen]), &(base[cnk->start]), len);
+ }
+ currlen += cnk->len;
+
+ break;
+
+ case CNK_INT:
+ case CNK_UINT:
+ fmtint (buffer, &currlen, maxlen, cnk->value, 10, min, max, cnk->flags);
+ break;
+
+ case CNK_OCTAL:
+ fmtint (buffer, &currlen, maxlen, cnk->value, 8, min, max, cnk->flags);
+ break;
+
+ case CNK_HEX:
+ fmtint (buffer, &currlen, maxlen, cnk->value, 16, min, max, cnk->flags);
+ break;
+
+ case CNK_FLOAT:
+ fmtfp (buffer, &currlen, maxlen, cnk->fvalue, min, max, cnk->flags);
+ break;
+
+ case CNK_CHAR:
+ dopr_outch (buffer, &currlen, maxlen, cnk->value);
+ break;
+
+ case CNK_STRING:
+ if (max == -1) {
+ max = strlen(cnk->strvalue);
+ }
+ fmtstr (buffer, &currlen, maxlen, cnk->strvalue, cnk->flags, min, max);
+ break;
+
+ case CNK_PTR:
+ fmtint (buffer, &currlen, maxlen, (long)(cnk->strvalue), 16, min, max, cnk->flags);
+ break;
+
+ case CNK_NUM:
+ if (cnk->cflags == DP_C_CHAR)
+ *((char *)(cnk->pnum)) = (char)currlen;
+ else if (cnk->cflags == DP_C_SHORT)
+ *((short int *)(cnk->pnum)) = (short int)currlen;
+ else if (cnk->cflags == DP_C_LONG)
+ *((long int *)(cnk->pnum)) = (long int)currlen;
+ else if (cnk->cflags == DP_C_LLONG)
+ *((LLONG *)(cnk->pnum)) = (LLONG)currlen;
+ else if (cnk->cflags == DP_C_SIZET)
+ *((ssize_t *)(cnk->pnum)) = (ssize_t)currlen;
+ else
+ *((int *)(cnk->pnum)) = (int)currlen;
+ break;
+
+ case CNK_PRCNT:
+ dopr_outch (buffer, &currlen, maxlen, '%');
+ break;
+
+ default:
+ /* what ?? */
+ goto done;
+ }
+ cnk = cnk->next;
+ }
  if (maxlen != 0) {
- if (currlen < maxlen - 1)
+ if (currlen < maxlen - 1)
  buffer[currlen] = '\0';
- else if (maxlen > 0)
+ else if (maxlen > 0)
  buffer[maxlen - 1] = '\0';
  }
-
- return currlen;
+ ret = currlen;
+
+done:
+ va_end(args);
+
+ while (chunks) {
+ cnk = chunks->next;
+ free(chunks);
+ chunks = cnk;
+ }
+ if (clist) {
+ for (pnum = 0; pnum < max_pos; pnum++) {
+ if (clist[pnum].chunks) free(clist[pnum].chunks);
+ }
+ free(clist);
+ }
+ return ret;
 }
 
 static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
@@ -427,37 +775,35 @@ static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
  value = "<NULL>";
  }
 
- for (strln = 0; value[strln]; ++strln); /* strlen */
+ for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */
  padlen = min - strln;
- if (padlen < 0)
+ if (padlen < 0)
  padlen = 0;
- if (flags & DP_F_MINUS)
+ if (flags & DP_F_MINUS)
  padlen = -padlen; /* Left Justify */
 
- while ((padlen > 0) && (cnt < max)) {
+ while (padlen > 0) {
  dopr_outch (buffer, currlen, maxlen, ' ');
  --padlen;
- ++cnt;
  }
  while (*value && (cnt < max)) {
  dopr_outch (buffer, currlen, maxlen, *value++);
  ++cnt;
  }
- while ((padlen < 0) && (cnt < max)) {
+ while (padlen < 0) {
  dopr_outch (buffer, currlen, maxlen, ' ');
  ++padlen;
- ++cnt;
  }
 }
 
 /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
 
 static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
-    long value, int base, int min, int max, int flags)
+    LLONG value, int base, int min, int max, int flags)
 {
  int signvalue = 0;
- unsigned long uvalue;
- char convert[20];
+ unsigned LLONG uvalue;
+ char convert[22+1]; /* 64-bit value in octal: 22 digits + \0 */
  int place = 0;
  int spadlen = 0; /* amount to space pad */
  int zpadlen = 0; /* amount to zero pad */
@@ -479,7 +825,7 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
  signvalue = ' ';
  }
  }
-
+  
  if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
 
  do {
@@ -487,8 +833,8 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
  (caps? "0123456789ABCDEF":"0123456789abcdef")
  [uvalue % (unsigned)base  ];
  uvalue = (uvalue / (unsigned)base );
- } while(uvalue && (place < 20));
- if (place == 20) place--;
+ } while(uvalue && (place < sizeof(convert)));
+ if (place == sizeof(convert)) place--;
  convert[place] = 0;
 
  zpadlen = max - place;
@@ -499,7 +845,7 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
  zpadlen = MAX(zpadlen, spadlen);
  spadlen = 0;
  }
- if (flags & DP_F_MINUS)
+ if (flags & DP_F_MINUS)
  spadlen = -spadlen; /* Left Justifty */
 
 #ifdef DEBUG_SNPRINTF
@@ -514,7 +860,7 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
  }
 
  /* Sign */
- if (signvalue)
+ if (signvalue)
  dopr_outch (buffer, currlen, maxlen, signvalue);
 
  /* Zeros */
@@ -526,9 +872,9 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
  }
 
  /* Digits */
- while (place > 0)
+ while (place > 0)
  dopr_outch (buffer, currlen, maxlen, convert[--place]);
-
+  
  /* Left Justified spaces */
  while (spadlen < 0) {
  dopr_outch (buffer, currlen, maxlen, ' ');
@@ -554,7 +900,7 @@ static LDOUBLE POW10(int exp)
  result *= 10;
  exp--;
  }
-
+  
  return result;
 }
 
@@ -574,7 +920,7 @@ static LLONG ROUND(LDOUBLE value)
 static double my_modf(double x0, double *iptr)
 {
  int i;
- long l;
+ LLONG l=0;
  double x = x0;
  double f = 1.0;
 
@@ -598,7 +944,7 @@ static double my_modf(double x0, double *iptr)
  ret = my_modf(x0-l*f, &i2);
  (*iptr) = l*f + i2;
  return ret;
- }
+ }
 
  (*iptr) = l;
  return x - (*iptr);
@@ -615,14 +961,14 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
  int iplace = 0;
  int fplace = 0;
  int padlen = 0; /* amount to pad */
- int zpadlen = 0;
+ int zpadlen = 0;
  int caps = 0;
- int index;
+ int idx;
  double intpart;
  double fracpart;
  double temp;
-
- /*
+  
+ /*
  * AIX manpage says the default is 0, but Solaris says the default
  * is 6, and sprintf on AIX defaults to 6
  */
@@ -650,12 +996,12 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
  if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */
 #endif
 
- /*
- * Sorry, we only support 16 digits past the decimal because of our
+ /*
+ * Sorry, we only support 9 digits past the decimal because of our
  * conversion method
  */
- if (max > 16)
- max = 16;
+ if (max > 9)
+ max = 9;
 
  /* We "cheat" by converting the fractional part to integer by
  * multiplying by a factor of 10
@@ -674,14 +1020,13 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
 
  /* Convert integer part */
  do {
- temp = intpart;
- my_modf(intpart*0.1, &intpart);
- temp = temp*0.1;
- index = (int) ((temp -intpart +0.05)* 10.0);
- /* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
- /* printf ("%llf, %f, %x\n", temp, intpart, index); */
+ temp = intpart*0.1;
+ my_modf(temp, &intpart);
+ idx = (int) ((temp -intpart +0.05)* 10.0);
+ /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
+ /* printf ("%llf, %f, %x\n", temp, intpart, idx); */
  iconvert[iplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
+ (caps? "0123456789ABCDEF":"0123456789abcdef")[idx];
  } while (intpart && (iplace < 311));
  if (iplace == 311) iplace--;
  iconvert[iplace] = 0;
@@ -690,26 +1035,25 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
  if (fracpart)
  {
  do {
- temp = fracpart;
- my_modf(fracpart*0.1, &fracpart);
- temp = temp*0.1;
- index = (int) ((temp -fracpart +0.05)* 10.0);
- /* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
- /* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
+ temp = fracpart*0.1;
+ my_modf(temp, &fracpart);
+ idx = (int) ((temp -fracpart +0.05)* 10.0);
+ /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */
+ /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */
  fconvert[fplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
+ (caps? "0123456789ABCDEF":"0123456789abcdef")[idx];
  } while(fracpart && (fplace < 311));
  if (fplace == 311) fplace--;
  }
  fconvert[fplace] = 0;
-
+  
  /* -1 for decimal point, another -1 if we are printing a sign */
- padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
+ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
  zpadlen = max - fplace;
  if (zpadlen < 0) zpadlen = 0;
- if (padlen < 0)
+ if (padlen < 0)
  padlen = 0;
- if (flags & DP_F_MINUS)
+ if (flags & DP_F_MINUS)
  padlen = -padlen; /* Left Justifty */
 
  if ((flags & DP_F_ZERO) && (padlen > 0)) {
@@ -727,10 +1071,10 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
  dopr_outch (buffer, currlen, maxlen, ' ');
  --padlen;
  }
- if (signvalue)
+ if (signvalue)
  dopr_outch (buffer, currlen, maxlen, signvalue);
 
- while (iplace > 0)
+ while (iplace > 0)
  dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
 
 #ifdef DEBUG_SNPRINTF
@@ -744,14 +1088,14 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
  if (max > 0) {
  dopr_outch (buffer, currlen, maxlen, '.');
 
- while (fplace > 0)
+ while (zpadlen > 0) {
+ dopr_outch (buffer, currlen, maxlen, '0');
+ --zpadlen;
+ }
+
+ while (fplace > 0)
  dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
  }
-
- while (zpadlen > 0) {
- dopr_outch (buffer, currlen, maxlen, '0');
- --zpadlen;
- }
 
  while (padlen < 0) {
  dopr_outch (buffer, currlen, maxlen, ' ');
@@ -767,59 +1111,178 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
  (*currlen)++;
 }
 
-/* yes this really must be a ||. Don't muck with this (tridge) */
-#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
-int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
+static struct pr_chunk *new_chunk(void) {
+ struct pr_chunk *new_c = (struct pr_chunk *)malloc(sizeof(struct pr_chunk));
+
+ if (!new_c)
+ return NULL;
+
+ new_c->type = 0;
+ new_c->num = 0;
+ new_c->min = 0;
+ new_c->min_star = NULL;
+ new_c->max = -1;
+ new_c->max_star = NULL;
+ new_c->flags = 0;
+ new_c->cflags = 0;
+ new_c->start = 0;
+ new_c->len = 0;
+ new_c->value = 0;
+ new_c->fvalue = 0;
+ new_c->strvalue = NULL;
+ new_c->pnum = NULL;
+ new_c->next = NULL;
+
+ return new_c;
+}
+
+static int add_cnk_list_entry(struct pr_chunk_x **list,
+ int max_num, struct pr_chunk *chunk) {
+ struct pr_chunk_x *l;
+ struct pr_chunk **c;
+ int max;
+ int cnum;
+ int i, pos;
+
+ if (chunk->num > max_num) {
+ max = chunk->num;
+
+ if (*list == NULL) {
+ l = (struct pr_chunk_x *)malloc(sizeof(struct pr_chunk_x) * max);
+ pos = 0;
+ } else {
+ l = (struct pr_chunk_x *)realloc(*list, sizeof(struct pr_chunk_x) * max);
+ pos = max_num;
+ }
+ if (l == NULL) {
+ for (i = 0; i < max; i++) {
+ if ((*list)[i].chunks) free((*list)[i].chunks);
+ }
+ return 0;
+ }
+ for (i = pos; i < max; i++) {
+ l[i].chunks = NULL;
+ l[i].num = 0;
+ }
+ } else {
+ l = *list;
+ max = max_num;
+ }
+
+ i = chunk->num - 1;
+ cnum = l[i].num + 1;
+ if (l[i].chunks == NULL) {
+ c = (struct pr_chunk **)malloc(sizeof(struct pr_chunk *) * cnum);
+ } else {
+ c = (struct pr_chunk **)realloc(l[i].chunks, sizeof(struct pr_chunk *) * cnum);
+ }
+ if (c == NULL) {
+ for (i = 0; i < max; i++) {
+ if (l[i].chunks) free(l[i].chunks);
+ }
+ return 0;
+ }
+ c[l[i].num] = chunk;
+ l[i].chunks = c;
+ l[i].num = cnum;
+
+ *list = l;
+ return max;
+}
+
+ int rep_vsnprintf (char *str, size_t count, const char *fmt, va_list args)
 {
  return dopr(str, count, fmt, args);
 }
 #endif
 
-/* yes this really must be a ||. Don't muck wiith this (tridge)
+/* yes this really must be a ||. Don't muck with this (tridge)
  *
  * The logic for these two is that we need our own definition if the
  * OS *either* has no definition of *sprintf, or if it does have one
- * that doesn't work properly according to the autoconf test.  Perhaps
- * these should really be smb_snprintf to avoid conflicts with buggy
- * linkers? -- mbp
+ * that doesn't work properly according to the autoconf test.
  */
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_SNPRINTF)
-int snprintf(char *str,size_t count,const char *fmt,...)
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
+ int rep_snprintf(char *str,size_t count,const char *fmt,...)
 {
  size_t ret;
  va_list ap;
-
+    
  va_start(ap, fmt);
  ret = vsnprintf(str, count, fmt, ap);
  va_end(ap);
-#ifdef WIN32
- str[count-1] = 0;       /* Windows vsnprintf does NOT truncate str. We do it manually. */
+ return ret;
+}
 #endif
+
+#ifndef HAVE_C99_VSNPRINTF
+ int rep_printf(const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+ char *s;
+
+ s = NULL;
+ va_start(ap, fmt);
+ ret = vasprintf(&s, fmt, ap);
+ va_end(ap);
+
+ if (s) {
+ fwrite(s, 1, strlen(s), stdout);
+ }
+ free(s);
+
  return ret;
 }
 #endif
 
+#ifndef HAVE_C99_VSNPRINTF
+ int rep_fprintf(FILE *stream, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+ char *s;
+
+ s = NULL;
+ va_start(ap, fmt);
+ ret = vasprintf(&s, fmt, ap);
+ va_end(ap);
+
+ if (s) {
+ fwrite(s, 1, strlen(s), stream);
+ }
+ free(s);
+
+ return ret;
+}
 #endif
 
-#ifndef HAVE_VASPRINTF
-int vasprintf(char **ptr, const char *format, va_list ap)
+#endif
+
+#if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF)
+ int rep_vasprintf(char **ptr, const char *format, va_list ap)
 {
  int ret;
-
- ret = vsnprintf(NULL, 0, format, ap);
- if (ret <= 0) return ret;
+ va_list ap2;
+
+ VA_COPY(ap2, ap);
+ ret = vsnprintf(NULL, 0, format, ap2);
+ va_end(ap2);
+ if (ret < 0) return ret;
 
  (*ptr) = (char *)malloc(ret+1);
  if (!*ptr) return -1;
- ret = vsnprintf(*ptr, ret+1, format, ap);
+
+ VA_COPY(ap2, ap);
+ ret = vsnprintf(*ptr, ret+1, format, ap2);
+ va_end(ap2);
 
  return ret;
 }
 #endif
 
-
-#ifndef HAVE_ASPRINTF
-int asprintf(char **ptr, const char *format, ...)
+#if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF)
+ int rep_asprintf(char **ptr, const char *format, ...)
 {
  va_list ap;
  int ret;
@@ -833,28 +1296,16 @@ int asprintf(char **ptr, const char *format, ...)
 }
 #endif
 
-#ifndef HAVE_VSYSLOG
-#ifdef HAVE_SYSLOG
-void vsyslog (int facility_priority, char *format, va_list arglist)
-{
- char *msg = NULL;
- vasprintf(&msg, format, arglist);
- if (!msg)
- return;
- syslog(facility_priority, "%s", msg);
- SAFE_FREE(msg);
-}
-#endif /* HAVE_SYSLOG */
-#endif /* HAVE_VSYSLOG */
-
 #ifdef TEST_SNPRINTF
 
-int sprintf(char *str,const char *fmt,...);
+ int sprintf(char *str,const char *fmt,...);
+ int printf(const char *fmt,...);
 
-int main (void)
+ int main (void)
 {
  char buf1[1024];
  char buf2[1024];
+ char *buf3;
  char *fp_fmt[] = {
  "%1.1f",
  "%-1.5f",
@@ -870,11 +1321,13 @@ int main (void)
  "%3.2f",
  "%.0f",
  "%f",
- "-16.16f",
+ "%-8.8f",
+ "%-9.9f",
  NULL
  };
- double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
-     0.9996, 1.996, 4.136,  0};
+ double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996,
+     0.9996, 1.996, 4.136, 5.030201, 0.00205,
+     /* END LIST */ 0};
  char *int_fmt[] = {
  "%-1.5d",
  "%1.5d",
@@ -888,14 +1341,16 @@ int main (void)
  "%d",
  NULL
  };
- long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
+ long int_nums[] = { -1, 134, 91340, 341, 0203, 1234567890, 0};
  char *str_fmt[] = {
- "10.5s",
- "5.10s",
- "10.1s",
- "0.10s",
- "10.0s",
- "1.10s",
+ "%10.5s",
+ "%-10.5s",
+ "%5.10s",
+ "%-5.10s",
+ "%10.1s",
+ "%0.10s",
+ "%10.0s",
+ "%1.10s",
  "%s",
  "%.1s",
  "%.10s",
@@ -903,24 +1358,35 @@ int main (void)
  NULL
  };
  char *str_vals[] = {"hello", "a", "", "a longer string", NULL};
+#ifdef HAVE_LONG_LONG
+ char *ll_fmt[] = {
+ "%llu",
+ NULL
+ };
+ LLONG ll_nums[] = { 134, 91340, 341, 0203, 1234567890, 128006186140000000LL, 0};
+#endif
  int x, y;
  int fail = 0;
  int num = 0;
+ int l1, l2;
+ char *ss_fmt[] = {
+ "%zd",
+ "%zu",
+ NULL
+ };
+ size_t ss_nums[] = {134, 91340, 123456789, 0203, 1234567890, 0};
 
  printf ("Testing snprintf format codes against system sprintf...\n");
 
  for (x = 0; fp_fmt[x] ; x++) {
  for (y = 0; fp_nums[y] != 0 ; y++) {
- int l1 = snprintf(NULL, 0, fp_fmt[x], fp_nums[y]);
- int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
- sprintf (buf2, fp_fmt[x], fp_nums[y]);
- if (strcmp (buf1, buf2)) {
- printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n",
-       fp_fmt[x], buf1, buf2);
- fail++;
- }
- if (l1 != l2) {
- printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]);
+ buf1[0] = buf2[0] = '\0';
+ l1 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
+ l2 = sprintf (buf2, fp_fmt[x], fp_nums[y]);
+ buf1[1023] = buf2[1023] = '\0';
+ if (strcmp (buf1, buf2) || (l1 != l2)) {
+ printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
+       fp_fmt[x], l1, buf1, l2, buf2);
  fail++;
  }
  num++;
@@ -929,16 +1395,13 @@ int main (void)
 
  for (x = 0; int_fmt[x] ; x++) {
  for (y = 0; int_nums[y] != 0 ; y++) {
- int l1 = snprintf(NULL, 0, int_fmt[x], int_nums[y]);
- int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
- sprintf (buf2, int_fmt[x], int_nums[y]);
- if (strcmp (buf1, buf2)) {
- printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n",
-       int_fmt[x], buf1, buf2);
- fail++;
- }
- if (l1 != l2) {
- printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]);
+ buf1[0] = buf2[0] = '\0';
+ l1 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
+ l2 = sprintf (buf2, int_fmt[x], int_nums[y]);
+ buf1[1023] = buf2[1023] = '\0';
+ if (strcmp (buf1, buf2) || (l1 != l2)) {
+ printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
+       int_fmt[x], l1, buf1, l2, buf2);
  fail++;
  }
  num++;
@@ -947,30 +1410,117 @@ int main (void)
 
  for (x = 0; str_fmt[x] ; x++) {
  for (y = 0; str_vals[y] != 0 ; y++) {
- int l1 = snprintf(NULL, 0, str_fmt[x], str_vals[y]);
- int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]);
- sprintf (buf2, str_fmt[x], str_vals[y]);
- if (strcmp (buf1, buf2)) {
- printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n",
-       str_fmt[x], buf1, buf2);
+ buf1[0] = buf2[0] = '\0';
+ l1 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]);
+ l2 = sprintf (buf2, str_fmt[x], str_vals[y]);
+ buf1[1023] = buf2[1023] = '\0';
+ if (strcmp (buf1, buf2) || (l1 != l2)) {
+ printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
+       str_fmt[x], l1, buf1, l2, buf2);
  fail++;
  }
- if (l1 != l2) {
- printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]);
+ num++;
+ }
+ }
+
+#ifdef HAVE_LONG_LONG
+ for (x = 0; ll_fmt[x] ; x++) {
+ for (y = 0; ll_nums[y] != 0 ; y++) {
+ buf1[0] = buf2[0] = '\0';
+ l1 = snprintf(buf1, sizeof(buf1), ll_fmt[x], ll_nums[y]);
+ l2 = sprintf (buf2, ll_fmt[x], ll_nums[y]);
+ buf1[1023] = buf2[1023] = '\0';
+ if (strcmp (buf1, buf2) || (l1 != l2)) {
+ printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
+       ll_fmt[x], l1, buf1, l2, buf2);
  fail++;
  }
  num++;
  }
  }
+#endif
 
+#define BUFSZ 2048
+
+ buf1[0] = buf2[0] = '\0';
+ if ((buf3 = malloc(BUFSZ)) == NULL) {
+ fail++;
+ } else {
+ num++;
+ memset(buf3, 'a', BUFSZ);
+ snprintf(buf1, sizeof(buf1), "%.*s", 1, buf3);
+ buf1[1023] = '\0';
+ if (strcmp(buf1, "a") != 0) {
+ printf("length limit buf1 '%s' expected 'a'\n", buf1);
+ fail++;
+ }
+        }
+
+ buf1[0] = buf2[0] = '\0';
+ l1 = snprintf(buf1, sizeof(buf1), "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9);
+ l2 = sprintf(buf2, "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9);
+ buf1[1023] = buf2[1023] = '\0';
+ if (strcmp(buf1, buf2) || (l1 != l2)) {
+ printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
+ "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2);
+ fail++;
+ }
+
+ buf1[0] = buf2[0] = '\0';
+ l1 = snprintf(buf1, sizeof(buf1), "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9);
+ l2 = sprintf(buf2, "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9);
+ buf1[1023] = buf2[1023] = '\0';
+ if (strcmp(buf1, buf2)) {
+ printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
+ "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2);
+ fail++;
+ }
+
+ for (x = 0; ss_fmt[x] ; x++) {
+ for (y = 0; ss_nums[y] != 0 ; y++) {
+ buf1[0] = buf2[0] = '\0';
+ l1 = snprintf(buf1, sizeof(buf1), ss_fmt[x], ss_nums[y]);
+ l2 = sprintf (buf2, ss_fmt[x], ss_nums[y]);
+ buf1[1023] = buf2[1023] = '\0';
+ if (strcmp (buf1, buf2) || (l1 != l2)) {
+ printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
+       ss_fmt[x], l1, buf1, l2, buf2);
+ fail++;
+ }
+ num++;
+ }
+ }
+#if 0
+ buf1[0] = buf2[0] = '\0';
+ l1 = snprintf(buf1, sizeof(buf1), "%lld", (LLONG)1234567890);
+ l2 = sprintf(buf2, "%lld", (LLONG)1234567890);
+ buf1[1023] = buf2[1023] = '\0';
+ if (strcmp(buf1, buf2)) {
+ printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
+ "%lld", l1, buf1, l2, buf2);
+ fail++;
+ }
+
+ buf1[0] = buf2[0] = '\0';
+ l1 = snprintf(buf1, sizeof(buf1), "%Lf", (LDOUBLE)890.1234567890123);
+ l2 = sprintf(buf2, "%Lf", (LDOUBLE)890.1234567890123);
+ buf1[1023] = buf2[1023] = '\0';
+ if (strcmp(buf1, buf2)) {
+ printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
+ "%Lf", l1, buf1, l2, buf2);
+ fail++;
+ }
+#endif
  printf ("%d tests failed out of %d.\n", fail, num);
 
  printf("seeing how many digits we support\n");
  {
  double v0 = 0.12345678901234567890123456789012345678901;
  for (x=0; x<100; x++) {
- snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x));
- sprintf(buf2,                "%1.1f", v0*pow(10, x));
+ double p = pow(10, x);
+ double r = v0*p;
+ snprintf(buf1, sizeof(buf1), "%1.1f", r);
+ sprintf(buf2,                "%1.1f", r);
  if (strcmp(buf1, buf2)) {
  printf("we seem to support %d digits\n", x-1);
  break;
@@ -980,4 +1530,4 @@ int main (void)
 
  return 0;
 }
-#endif /* SNPRINTF_TEST */
+#endif /* TEST_SNPRINTF */

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

[PATCH 5/8] Test for number of mkdir() arguments

Ladislav Michl
In reply to this post by Ladislav Michl
Windows' mkdir() takes only 1 argument, so add a test for that.
---
 configure.ac     |  1 +
 include/compat.h | 15 ++++++++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 379c7412..cd2064dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -902,6 +902,7 @@ AC_PROG_GCC_TRADITIONAL
 AC_FUNC_MEMCMP
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
+AC_FUNC_MKDIR
 AC_CHECK_FUNCS(mktime timegm gettimeofday select poll wcrtomb)
 AC_CHECK_FUNCS(strchr strdup strndup strstr strtol strtok strsep)
 AC_CHECK_FUNCS(asprintf vasprintf snprintf vsnprintf getpass setenv)
diff --git a/include/compat.h b/include/compat.h
index 009f5f0e..8711c425 100644
--- a/include/compat.h
+++ b/include/compat.h
@@ -199,6 +199,20 @@ int vasprintf(char **ptr, const char *format, va_list ap);
 time_t timegm(struct tm *tm);
 #endif
 
+#if HAVE_MKDIR
+# if MKDIR_TAKES_ONE_ARG
+   /* Mingw32 */
+#  define mkdir(a,b) mkdir(a)
+# endif
+#else
+# if HAVE__MKDIR
+   /* plain Win32 */
+#  define mkdir(a,b) _mkdir(a)
+# else
+#  error "Don't know how to create a directory on this system."
+# endif
+#endif
+
 /*
  * The following code was taken from W. Richard Stevens'
  * "UNIX Network Programming", Volume 1, Second Edition.
@@ -219,7 +233,6 @@ time_t timegm(struct tm *tm);
 #ifdef WIN32
 #  ifdef _MSC_VER
 #    define inline __inline
-#    define mkdir(dirname, accessrights) _mkdir(dirname)
 #    define strcasecmp _stricmp
 #    define strncasecmp _strnicmp
 #    define __const const
--
2.20.0.rc1


_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

[PATCH 6/8] Fix compat.c compilation with mingw32

Ladislav Michl
In reply to this post by Ladislav Michl
Compilation fails with both HAVE_SETENV and WIN32 set.
---
 common/compat.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/common/compat.c b/common/compat.c
index a1e1a9b5..48a4637a 100644
--- a/common/compat.c
+++ b/common/compat.c
@@ -16,13 +16,10 @@
 #include "config.h"
 #include "compat.h"
 
+#ifndef HAVE_SETENV
+
 #ifdef WIN32
 #  include <windows.h>
-#  include <sys/timeb.h>
-#  include <time.h>
-#  define ftime _ftime
-#  define timeb _timeb
-
 int setenv(const char *name, const char *value, int overwrite)
 {
  return (int)SetEnvironmentVariable(name, value);
@@ -33,10 +30,7 @@ int unsetenv(const char *name)
  SetEnvironmentVariable(name, NULL);
  return 0;
 }
-
-#endif
-
-#ifndef HAVE_SETENV
+#else
 #  include <stdlib.h>
 /* Implemented according to http://www.greenend.org.uk/rjk/2008/putenv.html and Linux manpage */
 int setenv(const char *envname, const char *envvalue, int overwrite)
@@ -66,12 +60,21 @@ int unsetenv(const char *name)
 }
 #endif
 
+#endif
+
 #ifdef HAVE_SYS_TIME_H
 #  include <sys/time.h>
 #endif
 
 #ifndef HAVE_GETTIMEOFDAY
 
+#ifdef WIN32
+#  include <sys/timeb.h>
+#  include <time.h>
+#  define ftime _ftime
+#  define timeb _timeb
+#endif
+
 int gettimeofday(struct timeval *tv, void *tz)
 {
  struct timeb t;
@@ -89,7 +92,6 @@ int gettimeofday(struct timeval *tv, void *tz)
 #endif
 
 
-
 #ifndef HAVE_STRSEP
 
 /*
@@ -150,7 +152,7 @@ char *strsep(char **stringp, const char *delim)
  register const char *spanp;
  register int c, sc;
  char *tok;
-
+
  if ((s = *stringp) == NULL)
  return (NULL);
  for (tok = s;;) {
--
2.20.0.rc1


_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

[PATCH 7/8] Use posix_spawn to run external scripts

Ladislav Michl
In reply to this post by Ladislav Michl
posix_spawn specification dates back to last century and its
implementation is mature enough in all systems we do support.
Thus use it instead of current fork and exec in hope it will
save us some resources.
---
 common/Makefile.am        |   8 ++-
 common/cfgreader.c        |  23 ---------
 common/device.c           |  59 +---------------------
 common/posixscript.c      | 102 ++++++++++++++++++++++++++++++++++++++
 common/winscript.c        |  36 ++++++++++++++
 configure.ac              |   2 +
 include/gnokii-internal.h |  16 +++++-
 7 files changed, 163 insertions(+), 83 deletions(-)
 create mode 100644 common/posixscript.c
 create mode 100644 common/winscript.c

diff --git a/common/Makefile.am b/common/Makefile.am
index 597ba7dc..0933f100 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -2,10 +2,15 @@ DEFS = -DLOCALEDIR=\"$(localedir)\" -DCOMPILING_LIBGNOKII
 
 if WIN32
 DATA_DIR =
+DEVICE_SCRIPT = winscript.c
 else
 DATA_DIR = data
 endif
 
+if HAVE_POSIX_SPAWN
+DEVICE_SCRIPT = posixscript.c
+endif
+
 lib_LTLIBRARIES = libgnokii.la
 
 SUBDIRS = phones \
@@ -51,7 +56,8 @@ libgnokii_la_SOURCES = \
  snprintf.c \
  localcharset.c \
  map.c \
- gsm-auth.c
+ gsm-auth.c \
+ $(DEVICE_SCRIPT)
 
 libgnokii_la_LIBADD = \
  $(top_builddir)/common/phones/libPHONES.la \
diff --git a/common/cfgreader.c b/common/cfgreader.c
index abf2ae4e..ee1b4c3e 100644
--- a/common/cfgreader.c
+++ b/common/cfgreader.c
@@ -652,29 +652,6 @@ int cfg_section_exists(struct gn_cfg_header *cfg, const char *section)
  return false;
 }
 
-/*
- * Return all the entries of the given section.
- */
-void cfg_foreach(const char *section, cfg_foreach_func func)
-{
- struct gn_cfg_header *h;
- struct gn_cfg_entry *e;
- struct gn_cfg_header *cfg = gn_cfg_info;
-
- if ((cfg == NULL) || (section == NULL) || (func == NULL)) {
- return;
- }
-
- /* Search for section name */
- for (h = cfg; h != NULL; h = h->next) {
- if (strcmp(section, h->section) == 0) {
- /* Search for key within section */
- for (e = h->entries; e != NULL; e = e->next)
- (*func)(section, e->key, e->value);
- }
- }
-}
-
 /*  Set the value of a key in a config file.  Return the new value if
     the section/key can be found, else return NULL.  */
 char *cfg_set(struct gn_cfg_header *cfg, const char *section, const char *key,
diff --git a/common/device.c b/common/device.c
index 794106b7..3b4d2c3d 100644
--- a/common/device.c
+++ b/common/device.c
@@ -28,66 +28,11 @@
 #include "devices/dku2libusb.h"
 #include "devices/socketphonet.h"
 
-#include <errno.h>
-#include <sys/wait.h>
-
 GNOKII_API int device_getfd(struct gn_statemachine *state)
 {
  return state->device.fd;
 }
 
-/* Script handling: */
-static void device_script_cfgfunc(const char *section, const char *key, const char *value)
-{
- setenv(key, value, 1); /* errors ignored */
-}
-
-int device_script(int fd, const char *section, struct gn_statemachine *state)
-{
- pid_t pid;
- const char *scriptname;
- int status;
-
- if (!strcmp(section, "connect_script"))
- scriptname = state->config.connect_script;
- else
- scriptname = state->config.disconnect_script;
- if (scriptname[0] == '\0')
- return 0;
-
- errno = 0;
- switch ((pid = fork())) {
- case -1:
- fprintf(stderr, _("device_script(\"%s\"): fork() failure: %s!\n"), scriptname, strerror(errno));
- return -1;
-
- case 0: /* child */
- cfg_foreach(section, device_script_cfgfunc);
- errno = 0;
- if (dup2(fd, 0) != 0 || dup2(fd, 1) != 1 || close(fd)) {
- fprintf(stderr, _("device_script(\"%s\"): file descriptor preparation failure: %s\n"), scriptname, strerror(errno));
- _exit(-1);
- }
- /* FIXME: close all open descriptors - how to track them?
- */
- execl("/bin/sh", "sh", "-c", scriptname, NULL);
- fprintf(stderr, _("device_script(\"%s\"): script execution failure: %s\n"), scriptname, strerror(errno));
- _exit(-1);
- /* NOTREACHED */
-
- default:
- if (pid == waitpid(pid, &status, 0 /* options */) && WIFEXITED(status) && !WEXITSTATUS(status))
- return 0;
- fprintf(stderr, _("device_script(\"%s\"): child script execution failure: %s, exit code=%d\n"), scriptname,
- (WIFEXITED(status) ? _("normal exit") : _("abnormal exit")),
- (WIFEXITED(status) ? WEXITSTATUS(status) : -1));
- errno = EIO;
- return -1;
-
- }
- /* NOTREACHED */
-}
-
 int device_open(const char *file, int with_odd_parity, int with_async,
  int with_hw_handshake, gn_connection_type device_type,
  struct gn_statemachine *state)
@@ -132,7 +77,7 @@ int device_open(const char *file, int with_odd_parity, int with_async,
  /*
  * handle config file connect_script:
  */
- if (device_script(state->device.fd, "connect_script", state) == -1) {
+ if (device_script(state->device.fd, 1, state)) {
  dprintf("gnokii open device: connect_script failure\n");
  device_close(state);
  return 0;
@@ -148,7 +93,7 @@ void device_close(struct gn_statemachine *state)
  /*
  * handle config file disconnect_script:
  */
- if (device_script(state->device.fd, "disconnect_script", state) == -1)
+ if (device_script(state->device.fd, 0, state))
  dprintf("gnokii device close: disconnect_script failure\n");
 
  switch (state->device.type) {
diff --git a/common/posixscript.c b/common/posixscript.c
new file mode 100644
index 00000000..5079f898
--- /dev/null
+++ b/common/posixscript.c
@@ -0,0 +1,102 @@
+/*
+
+  G N O K I I
+
+  A Linux/Unix toolset and driver for the mobile phones.
+
+  This file is part of gnokii.
+
+  Copyright (C) 2018       Ladislav Michl
+
+*/
+
+#include "config.h"
+#include "compat.h"
+#include "misc.h"
+#include "gnokii.h"
+#include "gnokii-internal.h"
+
+#include <errno.h>
+#include <spawn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int device_script(int fd, int connect, struct gn_statemachine *state)
+{
+ const char *scriptname, *section;
+ char **envp, *env;
+ struct gn_cfg_entry *e;
+ struct gn_cfg_header *h;
+ posix_spawn_file_actions_t fa;
+ pid_t pid;
+ int cnt, ret, status;
+ size_t len;
+
+ if (connect) {
+ scriptname = state->config.connect_script;
+ section = "connect_script";
+ } else {
+ scriptname = state->config.disconnect_script;
+ section = "disconnect_script";
+ }
+ if (scriptname[0] == '\0')
+ return 0;
+
+ cnt = 0; len = 0; ret = -1;
+ h = gn_cfg_info;
+ cfg_foreach_entry(section, h, e) {
+ len += strlen(e->key);
+ len += strlen(e->value);
+ len += 1 + 1 + sizeof(char *);
+ cnt++;
+ }
+
+ env = malloc(len + sizeof(char *));
+ if (!env) {
+ fprintf(stderr, _("device_script(\"%s\"): out of memory\n"), scriptname);
+ goto out;
+ }
+
+ envp = &env;
+ env += sizeof(char *) * (cnt + 1);
+ h = gn_cfg_info;
+ cfg_foreach_entry(section, h, e) {
+ *envp++ = &env;
+ env += snprintf(env, "%s=%s", e->key, e->value);
+ env++;
+ }
+ envp = NULL;
+
+ if (posix_spawn_file_actions_init(&fa)) {
+ fprintf(stderr, _("device_script(\"%s\"): file descriptor preparation failure: %s\n"),
+ scriptname, strerror(errno));
+ goto out_free;
+ }
+ if (posix_spawn_file_actions_adddup2(&fa, fd, STDIN_FILENO) ||
+    posix_spawn_file_actions_adddup2(&fa, fd, STDOUT_FILENO) ||
+    posix_spawn_file_actions_addclose(&fa, fd)) {
+ fprintf(stderr, _("device_script(\"%s\"): file descriptor preparation failure: %s\n"),
+ scriptname, strerror(errno));
+ goto out_destroy;
+ }
+ if (posix_spawn(&pid, scriptname, &fa, NULL, NULL, envp)) {
+ fprintf(stderr, _("device_script(\"%s\"): script execution failure: %s\n"),
+ scriptname, strerror(errno));
+ goto out_destroy;
+ }
+
+ if (pid != waitpid(pid, &status, 0) && WIFEXITED(status) && !WEXITSTATUS(status)) {
+ fprintf(stderr, _("device_script(\"%s\"): child script execution failure: %s, exit code=%d\n"), scriptname,
+ (WIFEXITED(status) ? _("normal exit") : _("abnormal exit")),
+ (WIFEXITED(status) ? WEXITSTATUS(status) : -1));
+ } else {
+ ret = 0;
+ }
+
+out_destroy:
+ posix_spawn_file_actions_destroy(&fa);
+out_free:
+ free(envp);
+out:
+ return ret;
+}
diff --git a/common/winscript.c b/common/winscript.c
new file mode 100644
index 00000000..ea9abd2b
--- /dev/null
+++ b/common/winscript.c
@@ -0,0 +1,36 @@
+/*
+
+  G N O K I I
+
+  A Linux/Unix toolset and driver for the mobile phones.
+
+  This file is part of gnokii.
+
+  Copyright (C) 2018       Ladislav Michl
+
+*/
+
+int device_script(int fd, int connect, struct gn_statemachine *state)
+{
+ /* TODO: something like this...
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+ ULONG rc;
+
+ ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+ ZeroMemory(&si, sizeof(STARTUPINFO));
+
+ si.hStdOutput = fd;
+ si.hStdInput = fd;
+ si.dwFlags = STARTF_USESTDHANDLES;
+
+ if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0,  NULL, NULL, &siStartInfo, &piProcInfo))
+ return -1;
+
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ if(!GetExitCodeProcess(pi.hProcess, &rc))
+ rc = 0;
+ ...
+ */
+ return 0;
+}
diff --git a/configure.ac b/configure.ac
index cd2064dd..af2ce675 100644
--- a/configure.ac
+++ b/configure.ac
@@ -907,6 +907,8 @@ AC_CHECK_FUNCS(mktime timegm gettimeofday select poll wcrtomb)
 AC_CHECK_FUNCS(strchr strdup strndup strstr strtol strtok strsep)
 AC_CHECK_FUNCS(asprintf vasprintf snprintf vsnprintf getpass setenv)
 AC_CHECK_FUNCS(getaddrinfo)
+AC_CHECK_FUNCS(posix_spawn)
+AM_CONDITIONAL([HAVE_POSIX_SPAWN], [test "x$ac_cv_func_posix_spawn" = xyes])
 AC_CACHE_CHECK(for ISO C99 compliant snprintf,ac_cv_func_snprintf_c99,
  [AC_TRY_RUN([
 #include <stdio.h>
diff --git a/include/gnokii-internal.h b/include/gnokii-internal.h
index c4f6d625..9af2d8cc 100644
--- a/include/gnokii-internal.h
+++ b/include/gnokii-internal.h
@@ -20,6 +20,7 @@
 #ifndef _gnokii_internal_h
 #define _gnokii_internal_h
 
+#include "cfgreader.h"
 #include "compat.h"
 #include "misc.h"
 #if !defined(GNOKII_DEPRECATED)
@@ -154,8 +155,10 @@ int sms_nokia_text_encode(unsigned char *text, unsigned char *message, bool firs
 int sms_nokia_bitmap_encode(gn_bmp *bitmap, unsigned char *message, bool first);
 
 struct gn_cfg_header *cfg_file_read(const char *filename);
-typedef void (*cfg_foreach_func)(const char *section, const char *key, const char *value);
-void cfg_foreach(const char *section, cfg_foreach_func func);
+#define cfg_foreach_entry(section, header, entry) \
+ for (; header != NULL; header = header->next) \
+ if (strcmp(section, h->section) == 0) \
+ for (entry = h->entries; entry != NULL; entry = entry->next)
 char *cfg_set(struct gn_cfg_header *cfg, const char *section, const char *key, const char *value);
 int cfg_file_write(struct gn_cfg_header *cfg, const char *filename);
 /* Get some information about the given phone */
@@ -179,4 +182,13 @@ int strip_slashes(char *dest, const char *src, int maxlen, int len);
 /* authentication for at driver */
 gn_error do_auth(gn_auth_type auth_type, struct gn_statemachine *state);
 
+#if defined(HAVE_POSIX_SPAWN) || defined(WIN32)
+int device_script(int fd, int connect, struct gn_statemachine *state);
+#else
+static int device_script(int fd, int connect, struct gn_statemachine *state)
+{
+ return 0;
+}
+#endif
+
 #endif /* _gnokii_internal_h */
--
2.20.0.rc1


_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

[PATCH 8/8] Refactor devices build

Ladislav Michl
In reply to this post by Ladislav Michl
Remove #ifdefs from device drivers and compile them only when
selected. Once there, move device detection code in configure.ac
to live in one place.
---
 common/device.c                               |   8 +-
 common/devices/Makefile.am                    |  57 +++----
 common/devices/bluetooth.c                    |  31 ----
 common/devices/dku2libusb.c                   |  42 +----
 common/devices/irda.c                         |  27 ----
 common/devices/osxbluetooth.m                 |   8 +-
 common/devices/socketphonet.c                 |  38 +----
 common/devices/tcp.c                          |  53 +------
 common/devices/tekram.c                       |   1 -
 common/devices/unixbluetooth.c                |  19 +--
 common/devices/unixirda.c                     |  11 +-
 common/devices/winbluetooth.c                 |  10 +-
 common/devices/winirda.c                      |   7 +-
 configure.ac                                  | 147 ++++++++++--------
 gnokii/Makefile.am                            |  10 --
 .../devices/{unixbluetooth.h => bluetooth.h}  |  38 ++++-
 include/devices/dku2libusb.h                  |  38 ++++-
 include/devices/irda.h                        |  32 ++++
 include/devices/socketphonet.h                |  32 ++++
 include/devices/tcp.h                         |  33 ++++
 include/devices/unixirda.h                    |  15 --
 21 files changed, 305 insertions(+), 352 deletions(-)
 delete mode 100644 common/devices/bluetooth.c
 delete mode 100644 common/devices/irda.c
 rename include/devices/{unixbluetooth.h => bluetooth.h} (52%)
 delete mode 100644 include/devices/unixirda.h

diff --git a/common/device.c b/common/device.c
index 3b4d2c3d..eee21ecd 100644
--- a/common/device.c
+++ b/common/device.c
@@ -21,12 +21,12 @@
 #include "gnokii-internal.h"
 #include "device.h"
 #include "devices/irda.h"
-#include "devices/unixbluetooth.h"
-#include "devices/tcp.h"
-#include "devices/serial.h"
-#include "devices/tekram.h"
+#include "devices/bluetooth.h"
 #include "devices/dku2libusb.h"
+#include "devices/serial.h"
 #include "devices/socketphonet.h"
+#include "devices/tcp.h"
+#include "devices/tekram.h"
 
 GNOKII_API int device_getfd(struct gn_statemachine *state)
 {
diff --git a/common/devices/Makefile.am b/common/devices/Makefile.am
index 9beef37a..23127ec5 100644
--- a/common/devices/Makefile.am
+++ b/common/devices/Makefile.am
@@ -2,35 +2,39 @@ DEFS = -DCOMPILING_LIBGNOKII
 
 noinst_LTLIBRARIES = libDEVICES.la
 
-WIN32_FILES = \
- winserial.c \
- winirda.c \
- winbluetooth.c
-
-UNIX_FILES = \
- unixserial.c \
- unixirda.c \
- tcp.c \
- socketphonet.c
-
-if FOR_MAC
-UNIX_SPECIFIC_FILES = osxbluetooth.m
-else
-UNIX_SPECIFIC_FILES = unixbluetooth.c
+gnokii_devices = tekram.c
+if LIBUSB
+gnokii_devices += dku2libusb.c
+endif
+if !WIN32
+gnokii_devices += tcp.c
+endif
+if SOCKETPHONET
+gnokii_devices += socketphonet.c
+endif
+if OSXBLUETOOTH
+gnokii_devices += osxbluetooth.m
+endif
+if UNIXBLUETOOTH
+gnokii_devices += unixbluetooth.c
+endif
+if UNIXIRDA
+gnokii_devices += unixirda.c
+endif
+if !WIN32
+gnokii_devices += unixserial.c
+endif
+if WINBLUETOOTH
+gnokii_devices += winbluetooth.c
+endif
+if WINIRDA
+gnokii_devices += winirda.c
 endif
-
 if WIN32
-PLATFORM_FILES = $(WIN32_FILES)
-else
-PLATFORM_FILES = $(UNIX_FILES) $(UNIX_SPECIFIC_FILES)
+gnokii_devices += winserial.c
 endif
 
-libDEVICES_la_SOURCES = \
- $(PLATFORM_FILES) \
- tekram.c \
- irda.c \
- dku2libusb.c \
- bluetooth.c
+libDEVICES_la_SOURCES = $(gnokii_devices)
 
 libDEVICES_la_CFLAGS = \
  -I$(top_srcdir)/include
@@ -39,6 +43,3 @@ libDEVICES_la_LIBADD = \
  $(USB_LIBS) \
  $(BLUETOOTH_LIBS) \
  $(TCP_LIBS)
-
-EXTRA_DIST = $(WIN32_FILES) $(UNIX_FILES) $(UNIX_SPECIFIC_FILES)
-
diff --git a/common/devices/bluetooth.c b/common/devices/bluetooth.c
deleted file mode 100644
index dccf448b..00000000
--- a/common/devices/bluetooth.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-
-  G N O K I I
-
-  A Linux/Unix toolset and driver for the mobile phones.
-
-  This file is part of gnokii.
-
-  Copyright (C) 2002       Marcel Holtmann <[hidden email]>
-  Copyright (C) 2003       BORBELY Zoltan
-  Copyright (C) 2004       Pawel Kot, Phil Ashby
-
-  Fake definitions for the bluetooth handling functions.
-
-*/
-
-#include "config.h"
-#include "compat.h"
-#include "misc.h"
-#include "gnokii.h"
-#include "devices/unixbluetooth.h"
-
-#ifndef HAVE_BLUETOOTH
-
-int bluetooth_open(const char *addr, uint8_t channel, struct gn_statemachine *state) { return -1; }
-int bluetooth_close(int fd, struct gn_statemachine *state) { return -1; }
-int bluetooth_write(int fd, const __ptr_t bytes, int size, struct gn_statemachine *state) { return -1; }
-int bluetooth_read(int fd, __ptr_t bytes, int size, struct gn_statemachine *state) { return -1; }
-int bluetooth_select(int fd, struct timeval *timeout, struct gn_statemachine *state) { return -1; }
-
-#endif /* HAVE_BLUETOOTH */
diff --git a/common/devices/dku2libusb.c b/common/devices/dku2libusb.c
index f219c39b..77d2af54 100644
--- a/common/devices/dku2libusb.c
+++ b/common/devices/dku2libusb.c
@@ -14,46 +14,14 @@
 
 */
 
-#include "config.h"
-#include "compat.h"
-#include "misc.h"
-#include "gnokii.h"
-#include "devices/dku2libusb.h"
-
-#ifndef HAVE_LIBUSB
-int fbusdku2usb_open(struct gn_statemachine *state)
-{
- return -1;
-}
-
-int fbusdku2usb_close(struct gn_statemachine *state)
-{
- return -1;
-}
-
-int fbusdku2usb_write(const __ptr_t bytes, int size, struct gn_statemachine *state)
-{
- return -1;
-}
-
-int fbusdku2usb_read(__ptr_t bytes, int size, struct gn_statemachine *state)
-{
- return -1;
-}
-
-int fbusdku2usb_select(struct timeval *timeout, struct gn_statemachine *state)
-{
- return -1;
-}
-
-#else
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
 
+#include "devices/dku2libusb.h"
+
 #define DEVINSTANCE(s) (*((fbus_usb_interface **)(&(s)->device.device_instance)))
 
 /*
@@ -388,7 +356,7 @@ static int usbfbus_connect_request(struct gn_statemachine *state)
  return 1;
 
 err3:
- usb_release_interface(DEVINSTANCE(state)->interface->dev_data, DEVINSTANCE(state)->interface->data_interface);
+ usb_release_interface(DEVINSTANCE(state)->interface->dev_data, DEVINSTANCE(state)->interface->data_interface);
 err2:
  usb_release_interface(DEVINSTANCE(state)->interface->dev_data, DEVINSTANCE(state)->interface->control_interface);
 err1:
@@ -420,7 +388,7 @@ static int usbfbus_disconnect_request(struct gn_statemachine *state)
  ret = usb_close(DEVINSTANCE(state)->interface->dev_data);
  if (ret < 0)
  dprintf("Can't close data interface %d\n", ret);
- return ret;
+ return ret;
 }
 
 int fbusdku2usb_open(struct gn_statemachine *state)
@@ -459,5 +427,3 @@ int fbusdku2usb_select(struct timeval *timeout, struct gn_statemachine *state)
 {
  return 1;
 }
-
-#endif
diff --git a/common/devices/irda.c b/common/devices/irda.c
deleted file mode 100644
index 2674c2db..00000000
--- a/common/devices/irda.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *
- * G N O K I I
- *
- * A Linux/Unix toolset and driver for the mobile phones.
- *
- * Copyright (C) 1999-2000  Hugh Blemings & Pavel Janík ml.
- * Copyright (C) 2000-2001  Marcel Holtmann <[hidden email]>
- * Copyright (C) 2004       Phil Ashby
- *
- * Fake definitions for irda handling functions.
- */
-
-#include "config.h"
-#include "compat.h"
-#include "misc.h"
-#include "gnokii.h"
-
-#ifndef HAVE_IRDA
-
-int irda_open(struct gn_statemachine *state) { return -1; }
-int irda_close(int fd, struct gn_statemachine *state) { return -1; }
-int irda_write(int fd, const __ptr_t bytes, int size, struct gn_statemachine *state) { return -1; }
-int irda_read(int fd, __ptr_t bytes, int size, struct gn_statemachine *state) { return -1; }
-int irda_select(int fd, struct timeval *timeout, struct gn_statemachine *state) { return -1; }
-
-#endif /* HAVE_IRDA */
diff --git a/common/devices/osxbluetooth.m b/common/devices/osxbluetooth.m
index 6216cc5c..1fc11295 100644
--- a/common/devices/osxbluetooth.m
+++ b/common/devices/osxbluetooth.m
@@ -10,14 +10,10 @@
 
 */
 
-#include "config.h"
-
-#ifdef HAVE_BLUETOOTH_MACOSX
-
 #include <IOBluetooth/objc/IOBluetoothRFCOMMChannel.h>
 #include <IOBluetooth/objc/IOBluetoothDevice.h>
 
-#include "devices/unixbluetooth.h"
+#include "devices/bluetooth.h"
 
 static NSMutableDictionary *queues;
 static int next_fd = 1;
@@ -179,5 +175,3 @@ int bluetooth_close(int fd, struct gn_statemachine *state)
     [queues removeObjectForKey:@(fd)];
     return 1;
 }
-
-#endif
diff --git a/common/devices/socketphonet.c b/common/devices/socketphonet.c
index 12bed8b2..1e119939 100644
--- a/common/devices/socketphonet.c
+++ b/common/devices/socketphonet.c
@@ -15,49 +15,17 @@
 
 */
 
-#include "config.h"
-#include "compat.h" /* for __ptr_t definition */
-#include "gnokii.h"
-
-#ifndef HAVE_SOCKETPHONET
-
-int socketphonet_close(struct gn_statemachine *state)
-{
- return -1;
-}
-
-int socketphonet_open(const char *iface, int with_async, struct gn_statemachine *state)
-{
- return -1;
-}
-
-size_t socketphonet_read(int fd, __ptr_t buf, size_t nbytes, struct gn_statemachine *state)
-{
- return -1;
-}
-
-size_t socketphonet_write(int fd, const __ptr_t buf, size_t n, struct gn_statemachine *state)
-{
- return -1;
-}
-
-int socketphonet_select(int fd, struct timeval *timeout, struct gn_statemachine *state)
-{
- return -1;
-}
-
-#else
-
 /* System header files */
 #include <sys/socket.h>
 #include <linux/phonet.h>
 
 /* Various header files */
+#include "config.h"
 #include "compat.h"
 #include "links/fbus-common.h"
 #include "links/fbus-phonet.h"
-#include "device.h"
 #include "devices/serial.h"
+#include "devices/socketphonet.h"
 #include "gnokii-internal.h"
 
 static struct sockaddr_pn addr = { .spn_family = AF_PHONET, .spn_dev = FBUS_DEVICE_PHONE };
@@ -159,5 +127,3 @@ int socketphonet_select(int fd, struct timeval *timeout, struct gn_statemachine
 {
  return serial_select(fd, timeout, state);
 }
-
-#endif /* HAVE_SOCKETPHONET */
diff --git a/common/devices/tcp.c b/common/devices/tcp.c
index 619737aa..8a48d4e1 100644
--- a/common/devices/tcp.c
+++ b/common/devices/tcp.c
@@ -12,13 +12,6 @@
 
 */
 
-#include "config.h"
-#include "misc.h"
-#include "devices/tcp.h"
-#include "devices/serial.h"
-
-#ifndef WIN32
-
 #include <stdio.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -34,6 +27,12 @@
 #include <netdb.h>
 #include <termios.h>
 
+#include "config.h"
+#include "misc.h"
+#include "devices/tcp.h"
+#include "devices/serial.h"
+
+
 #ifdef HAVE_SYS_FILE_H
 #  include <sys/file.h>
 #endif
@@ -50,8 +49,6 @@
 #  define O_NONBLOCK  0
 #endif
 
-/* Open the serial port and store the settings. */
-
 static int tcp_open(const char *file)
 {
  int fd;
@@ -148,16 +145,12 @@ int tcp_close(int fd, struct gn_statemachine *state)
  return close(fd);
 }
 
-/* Open a device with standard options.
- * Use value (-1) for "with_hw_handshake" if its specification is required from the user
- */
 int tcp_opendevice(const char *file, int with_async, struct gn_statemachine *state)
 {
  int fd;
  int retcode;
 
  /* Open device */
-
  fd = tcp_open(file);
 
  if (fd < 0)
@@ -203,46 +196,12 @@ int tcp_select(int fd, struct timeval *timeout, struct gn_statemachine *state)
  return serial_select(fd, timeout, state);
 }
 
-
-/* Read from serial device. */
-
 size_t tcp_read(int fd, __ptr_t buf, size_t nbytes, struct gn_statemachine *state)
 {
  return read(fd, buf, nbytes);
 }
 
-/* Write to serial device. */
-
 size_t tcp_write(int fd, const __ptr_t buf, size_t n, struct gn_statemachine *state)
 {
  return write(fd, buf, n);
 }
-
-#else /* WIN32 */
-
-int tcp_close(int fd, struct gn_statemachine *state)
-{
- return -1;
-}
-
-int tcp_opendevice(const char *file, int with_async, struct gn_statemachine *state)
-{
- return -1;
-}
-
-size_t tcp_read(int fd, __ptr_t buf, size_t nbytes, struct gn_statemachine *state)
-{
- return -1;
-}
-
-size_t tcp_write(int fd, const __ptr_t buf, size_t n, struct gn_statemachine *state)
-{
- return -1;
-}
-
-int tcp_select(int fd, struct timeval *timeout, struct gn_statemachine *state)
-{
- return -1;
-}
-
-#endif /* WIN32 */
diff --git a/common/devices/tekram.c b/common/devices/tekram.c
index 51e5e8fb..bfb887ff 100644
--- a/common/devices/tekram.c
+++ b/common/devices/tekram.c
@@ -13,7 +13,6 @@
  */
 
 #include "config.h"
-
 #include "misc.h"
 #include "gnokii.h"
 
diff --git a/common/devices/unixbluetooth.c b/common/devices/unixbluetooth.c
index c9be96f9..2c195940 100644
--- a/common/devices/unixbluetooth.c
+++ b/common/devices/unixbluetooth.c
@@ -16,14 +16,6 @@
 
 */
 
-#include "config.h"
-#include "compat.h"
-#include "misc.h"
-#include "gnokii.h"
-#include "devices/unixbluetooth.h"
-
-#if defined(HAVE_BLUETOOTH_BLUEZ) || defined(HAVE_BLUETOOTH_NETGRAPH) || defined(HAVE_BLUETOOTH_NETBT)
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
@@ -32,6 +24,9 @@
 #include <sys/time.h>
 #include <sys/socket.h>
 
+#include "config.h"
+#include "devices/bluetooth.h"
+
 #ifdef HAVE_BLUETOOTH_NETGRAPH /* FreeBSD / netgraph */
 
 #include <bluetooth.h>
@@ -265,7 +260,7 @@ static int find_service_channel(bdaddr_t *adapter, bdaddr_t *device, int only_gn
  case SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET:
  if (channel == -1)
  break;
-
+
  SDP_GET8(type, start);
  switch (type) {
  case SDP_DATA_STR8:
@@ -303,7 +298,7 @@ static int find_service_channel(bdaddr_t *adapter, bdaddr_t *device, int only_gn
  break;
  }
  }
-
+
  if (strstr(name, "Nokia PC Suite") != NULL) {
  channel = -1;
  break;
@@ -509,7 +504,7 @@ int bluetooth_open(const char *addr, uint8_t channel, struct gn_statemachine *st
 
  dprintf("Using channel: %d\n", channel);
  raddr.rc_channel = channel;
-
+
  if (connect(fd, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) {
  perror(_("Can't connect"));
  close(fd);
@@ -549,5 +544,3 @@ int bluetooth_select(int fd, struct timeval *timeout, struct gn_statemachine *st
 
  return select(fd + 1, &readfds, NULL, NULL, timeout);
 }
-
-#endif /* HAVE_BLUETOOTH_BLUEZ || HAVE_BLUETOOTH_NETGRAPH || HAVE_BLUETOOTH_NETBT */
diff --git a/common/devices/unixirda.c b/common/devices/unixirda.c
index 96b9a58a..5292d203 100644
--- a/common/devices/unixirda.c
+++ b/common/devices/unixirda.c
@@ -13,12 +13,6 @@
  *
  */
 
-#include "config.h"
-#include "misc.h"
-#include "gnokii.h"
-#include "compat.h"
-
-#ifdef HAVE_IRDA
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -30,6 +24,9 @@
 #include <linux/types.h>
 #include <linux/irda.h>
 
+#include "config.h"
+#include "compat.h"
+#include "misc.h"
 #include "devices/irda.h"
 
 #ifndef AF_IRDA
@@ -178,5 +175,3 @@ int irda_select(int fd, struct timeval *timeout, struct gn_statemachine *state)
 
  return select(fd + 1, &readfds, NULL, NULL, timeout);
 }
-
-#endif /* HAVE_IRDA */
diff --git a/common/devices/winbluetooth.c b/common/devices/winbluetooth.c
index a898e2e6..7be40127 100644
--- a/common/devices/winbluetooth.c
+++ b/common/devices/winbluetooth.c
@@ -8,18 +8,14 @@
  *
  */
 
-#include "config.h"
-
-#ifdef HAVE_BLUETOOTH
-
 #include <winsock2.h>
 #include <mmsystem.h>
 #include <ws2bth.h>
 #include <bluetoothapis.h>
 
+#include "config.h"
 #include "compat.h"
-#include "gnokii.h"
-#include "misc.h"
+#include "devices/bluetooth.h"
 
 /* QTTY by Davide Libenzi ( Terminal interface to Symbian QConsole )
  * Copyright (C) 2004  Davide Libenzi
@@ -109,5 +105,3 @@ int bluetooth_select(int fd, struct timeval *timeout, struct gn_statemachine *st
 
  return select(0 /* ignored on Win32 */, &readfds, NULL, NULL, timeout);
 }
-
-#endif /* HAVE_BLUETOOTH */
diff --git a/common/devices/winirda.c b/common/devices/winirda.c
index 4bfed742..71018842 100644
--- a/common/devices/winirda.c
+++ b/common/devices/winirda.c
@@ -8,14 +8,11 @@
  *
  */
 
-#include "config.h"
-
-#ifdef HAVE_IRDA
-
 #define WIN32_LEAN_AND_MEAN
 #include <winsock.h>
 #include <mmsystem.h>
 
+#include "config.h"
 #include "compat.h"
 #include "misc.h"
 #include "devices/irda.h"
@@ -160,5 +157,3 @@ int irda_select(int fd, struct timeval *timeout, struct gn_statemachine *state)
 
  return select(0 /* ignored on Win32 */, &readfds, NULL, NULL, timeout);
 }
-
-#endif /* HAVE_IRDA */
diff --git a/configure.ac b/configure.ac
index af2ce675..b0736f6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -88,15 +88,9 @@ case x"$host_os" in
  LDFLAGS="$LDFLAGS -L/usr/local/lib"
  ;;
  xnetbsd*)
-        CPPFLAGS="$CFLAGS -I/usr/pkg/include/"
-        LDFLAGS="$LDFLAGS -L/usr/pkg/lib/"
-        ;;
- xcygwin32|xcygwin|xmingw32|xmingw32msvc)
-  WIN32=1
-  ;;
- xdarwin*)
-  FOR_MAC=1
-  ;;
+ CPPFLAGS="$CFLAGS -I/usr/pkg/include/"
+ LDFLAGS="$LDFLAGS -L/usr/pkg/lib/"
+ ;;
 esac
 
 dnl ======================== Libtool versioning
@@ -362,6 +356,17 @@ AC_ARG_WITH(readline,
 AC_SUBST(TERMLIBS)
 AC_SUBST(TERMLDFLAGS)
 
+dnl ======================== Defines location for gettext
+AC_ARG_WITH(gettext,
+ [  --with-gettext=DIR      specifies the base gettext],
+ [ if test x$withval = xyes; then
+ AC_MSG_WARN(Usage is: --with-gettext=DIR)
+  else
+ CFLAGS="$CFLAGS -I$withval"
+  fi
+ ]
+)
+
 dnl ======================== Check for libical
 AC_ARG_WITH(libical,
    [  --with-libical=DIR      specifies the base libical],
@@ -421,6 +426,15 @@ if test "$enable_libical" = "yes"; then
  CFLAGS="$OLD_CFLAGS"
 fi
 
+dnl ======================== Checks for gethostbyname support
+AC_CHECK_FUNC(gethostbyname, ,
+ AC_CHECK_LIB(nsl, gethostbyname, TCP_LIBS="-lnsl"
+     AC_SUBST(TCP_LIBS)))
+dnl Haiku requires -lnetwork for socket functions
+AC_CHECK_FUNC(gethostbyname, ,
+ AC_CHECK_LIB(network, gethostbyname, TCP_LIBS="-lnetwork"
+     AC_SUBST(TCP_LIBS)))
+
 dnl ======================== Check for libusb
 USE_LIBUSB="no"
 AC_ARG_ENABLE(libusb,
@@ -444,59 +458,25 @@ if test "$enable_libusb" = "yes"; then
  ]
  )
 fi
+AM_CONDITIONAL([LIBUSB], [test $USE_LIBUSB = yes])
 
-dnl ======================== Checks for Linux Phonet support
+dnl ======================== Phonet switch
 USE_SOCKETPHONET="no"
 AC_ARG_ENABLE(phonet,
               AC_HELP_STRING([--disable-phonet],
                              [disable phonet support (default is autodetected)]
                             ),,
               [enable_phonet=yes])
-if test "$enable_phonet" = "yes"; then
- AC_CHECK_HEADER(linux/phonet.h,
- [AC_DEFINE(HAVE_SOCKETPHONET, 1, [Whether Phonet is available])
- USE_SOCKETPHONET="yes"],,
- [#include <sys/socket.h>
- #include <linux/phonet.h>])
-fi
-
-dnl ======================== Checks for gethostbyname support
-AC_CHECK_FUNC(gethostbyname, ,
- AC_CHECK_LIB(nsl, gethostbyname, TCP_LIBS="-lnsl"
-     AC_SUBST(TCP_LIBS)))
-dnl Haiku requires -lnetwork for socket functions
-AC_CHECK_FUNC(gethostbyname, ,
- AC_CHECK_LIB(network, gethostbyname, TCP_LIBS="-lnetwork"
-     AC_SUBST(TCP_LIBS)))
 
-dnl ======================== Checks for Linux IrDA support
+dnl ======================== IrDA switch
 USE_IRDA="no"
 AC_ARG_ENABLE(irda,
               AC_HELP_STRING([--disable-irda],
                              [disable irda support (default is autodetected)]
                             ),,
               [enable_irda=yes])
-if test "$enable_irda" = "yes"; then
- AC_CHECK_HEADER(linux/irda.h,
- [AC_DEFINE(HAVE_IRDA, 1, [Whether IrDA is available])
- USE_IRDA="yes"],,
- [#include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <linux/types.h>])
-fi
 
-dnl ======================== Defines location for gettext
-AC_ARG_WITH(gettext,
- [  --with-gettext=DIR      specifies the base gettext],
- [ if test x$withval = xyes; then
- AC_MSG_WARN(Usage is: --with-gettext=DIR)
-  else
- CFLAGS="$CFLAGS -I$withval"
-  fi
- ]
-)
-
-dnl ======================== Checks for Bluetooth support
+dnl ======================== Bluetooth switch
 USE_BLUETOOTH="no"
 AC_ARG_WITH(bluetooth,
  [  --with-bluetooth=DIR    specifies the base libbluetooth],
@@ -516,8 +496,8 @@ AC_ARG_ENABLE(bluetooth,
 
 case "$host_os" in
 linux*)
-dnl ======================== Checks for Linux Bluetooth support
- if test "$enable_bluetooth" = "yes" -a "$USE_BLUETOOTH" = "no"; then
+dnl ======================== Checks for Linux devices
+ if test "$enable_bluetooth" = "yes"; then
  AC_MSG_NOTICE([checking for the Linux Bluetooth support])
  AC_CACHE_CHECK(for the struct sockaddr_rc in <bluetooth/rfcomm.h>, ac_cv_have_sockaddr_rc,
  [AC_TRY_COMPILE([#include <sys/socket.h>
@@ -530,14 +510,31 @@ dnl ======================== Checks for Linux Bluetooth support
  AC_DEFINE(HAVE_BLUETOOTH, 1, [Whether Bluetooth is available])
  AC_DEFINE(HAVE_BLUETOOTH_BLUEZ,[],[Compile on Linux])
  USE_BLUETOOTH="yes"
+ UNIX_BLUETOOTH="true"
  BLUETOOTH_LIBS="-lbluetooth"
  AC_SUBST(BLUETOOTH_LIBS)
  fi
  fi
+ if test "$enable_irda" = "yes"; then
+ AC_CHECK_HEADER(linux/irda.h,
+ [AC_DEFINE(HAVE_IRDA, 1, [Whether IrDA is available])
+ [USE_IRDA="yes" UNIX_IRDA="true"]],,
+ [#include <sys/socket.h>
+ #include <sys/ioctl.h>
+ #include <linux/types.h>])
+ fi
+ if test "$enable_phonet" = "yes"; then
+ AC_CHECK_HEADER(linux/phonet.h,
+ [AC_DEFINE(HAVE_SOCKETPHONET, 1, [Whether Phonet is available])
+ USE_SOCKETPHONET="yes"],,
+ [#include <sys/socket.h>
+ #include <linux/phonet.h>])
+ fi
  ;;
+
 darwin*)
 dnl ======================== Checks for MacOSX Bluetooth support
- if test "$enable_bluetooth" = "yes" -a "$USE_BLUETOOTH" = "no"; then
+ if test "$enable_bluetooth" = "yes"; then
  AC_LANG_PUSH([Objective C])
  AC_CHECK_HEADERS(IOBluetooth/objc/IOBluetoothRFCOMMChannel.h)
  AC_CHECK_HEADERS(IOBluetooth/objc/IOBluetoothDevice.h)
@@ -557,6 +554,7 @@ dnl ======================== Checks for MacOSX Bluetooth support
  AC_DEFINE(HAVE_BLUETOOTH, 1, [Whether Bluetooth is available])
  AC_DEFINE(HAVE_BLUETOOTH_MACOSX,[],[Compile on Darwin / Mac OSX])
  USE_BLUETOOTH="yes"
+ OSX_BLUETOOTH="true"
  BLUETOOTH_LIBS="$PTHREAD_LIBS -Wl,-framework,CoreFoundation -Wl,-framework,IOBluetooth -Wl,-framework,Foundation"
  AC_SUBST(BLUETOOTH_LIBS)
  fi
@@ -565,7 +563,7 @@ dnl ======================== Checks for MacOSX Bluetooth support
 
 dnl ======================== Checks for FreeBSD/netgraph Bluetooth support
 freebsd)
- if test "$enable_bluetooth" = "yes" -a "$USE_BLUETOOTH" = "no"; then
+ if test "$enable_bluetooth" = "yes"; then
  AC_MSG_NOTICE([checking for the FreeBSD/netgraph Bluetooth support])
  AC_CACHE_CHECK(for the struct sockaddr_rfcomm from <bluetooth.h>, ac_cv_have_sockaddr_rfcomm,
  [AC_TRY_COMPILE([#include <bluetooth.h>],
@@ -577,6 +575,7 @@ freebsd)
  AC_DEFINE(HAVE_BLUETOOTH, 1, [Whether Bluetooth is available])
  AC_DEFINE(HAVE_BLUETOOTH_NETGRAPH, [], [Compile on FreeBSD])
  USE_BLUETOOTH="yes"
+ UNIX_BLUETOOTH="true"
  AC_CHECK_LIB(bluetooth, bt_aton,
  [BLUETOOTH_LIBS="-lbluetooth" ac_cv_have_bt_lib=yes],
  ac_cv_have_bt_lib=no)
@@ -591,7 +590,7 @@ freebsd)
 
 dnl ======================== Checks for NetBSD/netbt Bluetooth support
 netbsd*)
- if test "$enable_bluetooth" = "yes" -a "$USE_BLUETOOTH" = "no"; then
+ if test "$enable_bluetooth" = "yes"; then
  AC_MSG_NOTICE([checking for the NetBSD/netbt Bluetooth support])
  AC_CACHE_CHECK(for the struct sockaddr_bt from <bluetooth.h>, ac_cv_have_sockaddr_bt,
  [AC_TRY_COMPILE([#include <bluetooth.h>],
@@ -603,6 +602,7 @@ netbsd*)
  AC_DEFINE(HAVE_BLUETOOTH, 1, [Whether Bluetooth is available])
  AC_DEFINE(HAVE_BLUETOOTH_NETBT, [], [Compile on NetBSD])
  USE_BLUETOOTH="yes"
+ UNIX_BLUETOOTH="true"
  CFLAGS="$CFLAGS -DCOMPAT_BLUEZ"
  AC_CHECK_LIB(bluetooth, bt_aton,
  [BLUETOOTH_LIBS="-lbluetooth" ac_cv_have_bt_lib=yes],
@@ -615,8 +615,39 @@ netbsd*)
  fi
  fi
  ;;
+
+dnl ======================== Checks for Windows devices
+cygwin32|cygwin|mingw32|mingw32msvc)
+ if test "$enable_bluetooth" = "yes"; then
+ AC_CHECK_HEADER(ws2bth.h,
+ [AC_DEFINE(HAVE_BLUETOOTH, 1, [Whether Bluetooth is available]) USE_BLUETOOTH="yes" WIN32_BLUETOOTH="true"],,
+ [#include <windows.h>])
+ fi
+ if test "$enable_irda" = "yes"; then
+ AC_CHECK_HEADER(af_irda.h,
+ [AC_DEFINE(HAVE_IRDA, 1, [Whether IrDA is available]) USE_IRDA="yes" WIN32_IRDA="true"],,
+ [#include <windows.h>])
+ fi
+ BLUETOOTH_LIBS=""
+ if test x"$USE_IRDA" = "xyes" -o x"$USE_BLUETOOTH" = "xyes"; then
+ BLUETOOTH_LIBS="-lws2_32"
+ fi
+ if test x"$USE_IRDA" = "xyes"; then
+ BLUETOOTH_LIBS="$BLUETOOTH_LIBS -lwinmm"
+ fi
+ AC_SUBST(BLUETOOTH_LIBS)
+ WIN32=1
+ ;;
 esac
 
+AM_CONDITIONAL([WIN32], test "x$WIN32" = "x1")
+AM_CONDITIONAL([SOCKETPHONET], [test "x$USE_SOCKETPHONET" = "xyes"])
+AM_CONDITIONAL([OSXBLUETOOTH], [test "x$OSX_BLUETOOTH" = "xtrue"])
+AM_CONDITIONAL([UNIXBLUETOOTH], [test "x$UNIX_BLUETOOTH" = "xtrue"])
+AM_CONDITIONAL([UNIXIRDA], [test "x$UNIX_IRDA" = "xtrue"])
+AM_CONDITIONAL([WINBLUETOOTH], [test "x$WIN32_BLUETOOTH" = "xtrue"])
+AM_CONDITIONAL([WINIRDA], [test "x$WIN32_IRDA" = "xtrue"])
+
 dnl ======================== Checks for X base support
 
 PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.0, found_gtk=yes, found_gtk=no)
@@ -789,18 +820,6 @@ if test "$enable_libpcsclite" = "yes"; then
  fi
 fi
 
-if test x"$host_os" = "xcygwin32" -o x"$host_os" = "xcygwin" -o x"$host_os" = "xmingw32" -o x"$host_os" = "xmingw32msvc"; then
- AC_CHECK_HEADER(af_irda.h, [AC_DEFINE(HAVE_IRDA, 1, [Whether IrDA is available]) USE_IRDA="yes" LIBS="$LIBS -lwinmm"],, [#include <windows.h>])
- AC_CHECK_HEADER(ws2bth.h, [AC_DEFINE(HAVE_BLUETOOTH, 1, [Whether Bluetooth is available]) USE_BLUETOOTH="yes"],, [#include <windows.h>])
- if test x"$USE_IRDA" = "xyes" -o x"$USE_BLUETOOTH" = "xyes"; then
-  LIBS="$LIBS -lws2_32"
- fi
- WIN32=1
-fi
-
-AM_CONDITIONAL(WIN32, test "x$WIN32" = "x1")
-AM_CONDITIONAL([FOR_MAC], [test "x$FOR_MAC" = "x1"])
-
 AC_ARG_ENABLE(unix98test,
    [  --enable-unix98test     if you want to disable UNIX98 test and assume to
                           use it; default is enabled],
diff --git a/gnokii/Makefile.am b/gnokii/Makefile.am
index e3d4d759..2acbed42 100644
--- a/gnokii/Makefile.am
+++ b/gnokii/Makefile.am
@@ -13,13 +13,3 @@ gnokii_CFLAGS = -I$(top_srcdir)/include
 # Compile getopt1.c and getopt.c unconditionally on all platforms, it
 # has its own magic for the platforms that already have it.
 gnokii_LDADD += $(top_builddir)/getopt/libgetopt.a
-
-#FIXME cross compiling
-#if WIN32_CROSS
-#PRGNAME=gnokii.exe
-#TARGET=-mconsole
-#AM_CFLAGS=-DGNOKIIDLL_IMPORTS
-#else
-PRGNAME=gnokii
-#endif
-
diff --git a/include/devices/unixbluetooth.h b/include/devices/bluetooth.h
similarity index 52%
rename from include/devices/unixbluetooth.h
rename to include/devices/bluetooth.h
index 81cad19b..1b0e9b3e 100644
--- a/include/devices/unixbluetooth.h
+++ b/include/devices/bluetooth.h
@@ -11,17 +11,49 @@
 
 */
 
-#ifndef _gnokii_unix_bluetooth_h
-#define _gnokii_unix_bluetooth_h
+#ifndef _gnokii_bluetooth_h
+#define _gnokii_bluetooth_h
 
 #include "compat.h"
+#include "config.h"
 #include "misc.h"
 #include "gnokii.h"
 
+#ifdef HAVE_BLUETOOTH
+
 int bluetooth_open(const char *addr, uint8_t channel, struct gn_statemachine *state);
 int bluetooth_close(int fd, struct gn_statemachine *state);
 int bluetooth_write(int fd, const __ptr_t bytes, int size, struct gn_statemachine *state);
 int bluetooth_read(int fd, __ptr_t bytes, int size, struct gn_statemachine *state);
 int bluetooth_select(int fd, struct timeval *timeout, struct gn_statemachine *state);
 
-#endif /* _gnokii_unix_bluetooth_h */
+#else
+
+int bluetooth_open(const char *addr, uint8_t channel, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int bluetooth_close(int fd, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int bluetooth_write(int fd, const __ptr_t bytes, int size, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int bluetooth_read(int fd, __ptr_t bytes, int size, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int bluetooth_select(int fd, struct timeval *timeout, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+#endif
+
+#endif /* _gnokii_bluetooth_h */
diff --git a/include/devices/dku2libusb.h b/include/devices/dku2libusb.h
index be4d4ba4..0987657e 100644
--- a/include/devices/dku2libusb.h
+++ b/include/devices/dku2libusb.h
@@ -16,16 +16,15 @@
 #ifndef _gnokii_dku2libusb_h
 #define _gnokii_dku2libusb_h
 
-#ifdef HAVE_LIBUSB
-#  include <usb.h>
-#endif
-
+#include "config.h"
 #include "compat.h"
 #include "misc.h"
 #include "gnokii.h"
 
 #ifdef HAVE_LIBUSB
 
+#include <usb.h>
+
 /* Information about a USB DKU2 FBUS interface present on the system */
 struct fbus_usb_interface_transport {
  struct fbus_usb_interface_transport *prev, *next; /* Next and previous interfaces in the list */
@@ -102,12 +101,39 @@ struct cdc_union_desc {
 #define USB_MAX_STRING_SIZE 256
 #define USB_FBUS_TIMEOUT 10000 /* 10 seconds */
 
-#endif
-
 int fbusdku2usb_open(struct gn_statemachine *state);
 int fbusdku2usb_close(struct gn_statemachine *state);
 int fbusdku2usb_write(const __ptr_t bytes, int size, struct gn_statemachine *state);
 int fbusdku2usb_read(__ptr_t bytes, int size, struct gn_statemachine *state);
 int fbusdku2usb_select(struct timeval *timeout, struct gn_statemachine *state);
 
+#else
+
+int fbusdku2usb_open(struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int fbusdku2usb_close(struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int fbusdku2usb_write(const __ptr_t bytes, int size, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int fbusdku2usb_read(__ptr_t bytes, int size, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int fbusdku2usb_select(struct timeval *timeout, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+#endif
+
 #endif /* _gnokii_dku2libusb_h */
diff --git a/include/devices/irda.h b/include/devices/irda.h
index 819dd257..82191b1f 100644
--- a/include/devices/irda.h
+++ b/include/devices/irda.h
@@ -12,12 +12,44 @@
 #ifndef __gnokii_irda_h_
 #define __gnokii_irda_h_
 
+#include "config.h"
 #include "gnokii.h"
 
+#ifdef HAVE_IRDA
+
 int irda_open(struct gn_statemachine *state);
 int irda_close(int fd, struct gn_statemachine *state);
 int irda_write(int fd, const __ptr_t bytes, int size, struct gn_statemachine *state);
 int irda_read(int fd, __ptr_t bytes, int size, struct gn_statemachine *state);
 int irda_select(int fd, struct timeval *timeout, struct gn_statemachine *state);
 
+#else
+
+int irda_open(struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int irda_close(int fd, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int irda_write(int fd, const __ptr_t bytes, int size, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int irda_read(int fd, __ptr_t bytes, int size, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int irda_select(int fd, struct timeval *timeout, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+#endif
+
 #endif /* __gnokii_irda_h_ */
diff --git a/include/devices/socketphonet.h b/include/devices/socketphonet.h
index 77550c6f..05a06f56 100644
--- a/include/devices/socketphonet.h
+++ b/include/devices/socketphonet.h
@@ -18,12 +18,44 @@
 #ifndef _gnokii_devices_linuxphonet_h
 #define _gnokii_devices_linuxphonet_h
 
+#include "config.h"
 #include "gnokii.h"
 
+#ifdef HAVE_SOCKETPHONET
+
 int socketphonet_close(struct gn_statemachine *state);
 int socketphonet_open(const char *iface, int with_async, struct gn_statemachine *state);
 size_t socketphonet_read(int fd, __ptr_t buf, size_t nbytes, struct gn_statemachine *state);
 size_t socketphonet_write(int fd, const __ptr_t buf, size_t n, struct gn_statemachine *state);
 int socketphonet_select(int fd, struct timeval *timeout, struct gn_statemachine *state);
 
+#else
+
+int socketphonet_close(struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int socketphonet_open(const char *iface, int with_async, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+size_t socketphonet_read(int fd, __ptr_t buf, size_t nbytes, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+size_t socketphonet_write(int fd, const __ptr_t buf, size_t n, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int socketphonet_select(int fd, struct timeval *timeout, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+#endif
+
 #endif /* _gnokii_devices_linuxphonet_h */
diff --git a/include/devices/tcp.h b/include/devices/tcp.h
index 0e3786e7..0ecf1d87 100644
--- a/include/devices/tcp.h
+++ b/include/devices/tcp.h
@@ -13,10 +13,13 @@
 #ifndef __devices_tcp_h
 #define __devices_tcp_h
 
+#include "config.h"
 #include "compat.h"
 #include "misc.h"
 #include "gnokii.h"
 
+#ifndef WIN32
+
 int tcp_opendevice(const char *file, int with_async, struct gn_statemachine *state);
 int tcp_close(int fd, struct gn_statemachine *state);
 
@@ -25,4 +28,34 @@ size_t tcp_write(int fd, const __ptr_t buf, size_t n, struct gn_statemachine *st
 
 int tcp_select(int fd, struct timeval *timeout, struct gn_statemachine *state);
 
+#else
+
+int tcp_opendevice(const char *file, int with_async, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int tcp_close(int fd, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+
+size_t tcp_read(int fd, __ptr_t buf, size_t nbytes, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+size_t tcp_write(int fd, const __ptr_t buf, size_t n, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+int tcp_select(int fd, struct timeval *timeout, struct gn_statemachine *state)
+{
+ return -1;
+}
+
+#endif
+
 #endif  /* __devices_tcp_h */
diff --git a/include/devices/unixirda.h b/include/devices/unixirda.h
deleted file mode 100644
index 19b07ef4..00000000
--- a/include/devices/unixirda.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- *
- * G N O K I I
- *
- * A Linux/Unix toolset and driver for the mobile phones.
- *
- * Copyright (C) 1999, 2000 Hugh Blemings & Pavel Janík ml.
- * Copyright (C) 2000-2001  Marcel Holtmann <[hidden email]>
- *
- */
-
-#ifndef __unix_irda_h_
-#define __unix_irda_h_
-
-#endif
--
2.20.0.rc1


_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/8] Use lower case for Win32 includes

Pawel Kot
In reply to this post by Ladislav Michl
Hi,

On Mon, Dec 3, 2018 at 12:42 PM Ladislav Michl <[hidden email]> wrote:
> diff --git a/include/gnokii.h.in b/include/gnokii.h.in
> index b3253455..d407d53d 100644
> --- a/include/gnokii.h.in
> +++ b/include/gnokii.h.in
> @@ -31,8 +31,8 @@ extern "C" {
[...]
> -#elif defined(_MSC_VER) && defined(WIN32)
[...]
> +#elif defined(WIN32)

So this one changes behaviour and is not explained. And not sure if correct. Care to give an explanation?

Cheers,
Paweł
--
Pawel Kot

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 3/8] Remove some unnecessary #ifndef WIN32

Pawel Kot
In reply to this post by Ladislav Michl
Hi,

On Mon, Dec 3, 2018 at 12:41 PM Ladislav Michl <[hidden email]> wrote:
> diff --git a/gnokii/gnokii-calendar.c b/gnokii/gnokii-calendar.c
> index e32bf769..10236bae 100644
> --- a/gnokii/gnokii-calendar.c
> +++ b/gnokii/gnokii-calendar.c
> @@ -264,7 +264,6 @@ gn_error writecalendarnote(int argc, char *argv[], gn_data *data, struct gn_stat
> -#ifndef WIN32
>                 if (error == GN_ERR_NOTIMPLEMENTED) {
>                         switch (gn_vcal_file_event_read(optarg, &calnote, i)) {

Probably excluding it for all WIN32 platforms is excessive, but gn_vcal_file_event_read() is generated by flex, which is missing on native Windows platforms. I'm fine with changing it but it will fail on Visual Studio platforms.

> diff --git a/gnokii/gnokii-monitor.c b/gnokii/gnokii-monitor.c
> index 7fde06c5..30aba457 100644
> --- a/gnokii/gnokii-monitor.c
> +++ b/gnokii/gnokii-monitor.c
> @@ -109,8 +109,6 @@ static gn_error readcbmessage(gn_cb_message *message)
>
>  static void displaycall(int call_id)
>  {
> -/* FIXME!!! */
> -#ifndef WIN32
[...]
>         struct timeval now, delta;
[...]
> -#endif

I believe it was due to some weirdness of struct timeval on Windows. Can you please tell on which compiling environments was it tested?

Cheers,
Paweł
--
Pawel Kot

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/8] Use posix_spawn to run external scripts

Pawel Kot
In reply to this post by Ladislav Michl
Hi,

On Mon, Dec 3, 2018 at 12:54 PM Ladislav Michl <[hidden email]> wrote:
>
> posix_spawn specification dates back to last century and its
> implementation is mature enough in all systems we do support.
> Thus use it instead of current fork and exec in hope it will
> save us some resources.

There is more than this in this patch. Would you mind in splitting it into two or more parts? A large portion of the patch is related to reorganizing the code. Two examples below.

Cheers,
Paweł

> diff --git a/include/gnokii-internal.h b/include/gnokii-internal.h
> index c4f6d625..9af2d8cc 100644
> --- a/include/gnokii-internal.h
> +++ b/include/gnokii-internal.h
> @@ -20,6 +20,7 @@
>  #ifndef _gnokii_internal_h
>  #define _gnokii_internal_h
>
> +#include "cfgreader.h"

I think I was trying to avoid that for a long time. Not sure now about the reasoning.

> -typedef void (*cfg_foreach_func)(const char *section, const char *key, const char *value);
> -void cfg_foreach(const char *section, cfg_foreach_func func);
> +#define cfg_foreach_entry(section, header, entry) \
> +       for (; header != NULL; header = header->next) \
> +               if (strcmp(section, h->section) == 0) \
> +                       for (entry = h->entries; entry != NULL; entry = entry->next)

Why that?

Cheers
Paweł
--
Pawel Kot

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/8] Use posix_spawn to run external scripts

Ladislav Michl
On Mon, Dec 03, 2018 at 06:28:56PM +0300, Pawel Kot wrote:

> Hi,
>
> On Mon, Dec 3, 2018 at 12:54 PM Ladislav Michl <[hidden email]> wrote:
> >
> > posix_spawn specification dates back to last century and its
> > implementation is mature enough in all systems we do support.
> > Thus use it instead of current fork and exec in hope it will
> > save us some resources.
>
> There is more than this in this patch. Would you mind in splitting it into
> two or more parts?

Sure, no problem. I read above you are fine with that approach in general.

> A large portion of the patch is related to reorganizing
> the code. Two examples below.
>
> Cheers,
> Paweł
>
> > diff --git a/include/gnokii-internal.h b/include/gnokii-internal.h
> > index c4f6d625..9af2d8cc 100644
> > --- a/include/gnokii-internal.h
> > +++ b/include/gnokii-internal.h
> > @@ -20,6 +20,7 @@
> >  #ifndef _gnokii_internal_h
> >  #define _gnokii_internal_h
> >
> > +#include "cfgreader.h"
>
> I think I was trying to avoid that for a long time. Not sure now about the
> reasoning.

I saw something like that in one of your commit logs... and therefore
will avoid that in next version.

However it would be nice if someone could actually give pachset a try.
Preferably on non linux platforms.

> > -typedef void (*cfg_foreach_func)(const char *section, const char *key,
> const char *value);
> > -void cfg_foreach(const char *section, cfg_foreach_func func);
> > +#define cfg_foreach_entry(section, header, entry) \
> > +       for (; header != NULL; header = header->next) \
> > +               if (strcmp(section, h->section) == 0) \
> > +                       for (entry = h->entries; entry != NULL; entry =
> entry->next)
>
> Why that?

If that question leads to opencoding that single macro use, I'm fine
with that.

> Cheers
> Paweł

Best regards,
        ladis

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 3/8] Remove some unnecessary #ifndef WIN32

Ladislav Michl
In reply to this post by Pawel Kot
Hi Paweł,

On Mon, Dec 03, 2018 at 06:15:07PM +0300, Pawel Kot wrote:

> Hi,
>
> On Mon, Dec 3, 2018 at 12:41 PM Ladislav Michl <[hidden email]> wrote:
> > diff --git a/gnokii/gnokii-calendar.c b/gnokii/gnokii-calendar.c
> > index e32bf769..10236bae 100644
> > --- a/gnokii/gnokii-calendar.c
> > +++ b/gnokii/gnokii-calendar.c
> > @@ -264,7 +264,6 @@ gn_error writecalendarnote(int argc, char *argv[],
> gn_data *data, struct gn_stat
> > -#ifndef WIN32
> >                 if (error == GN_ERR_NOTIMPLEMENTED) {
> >                         switch (gn_vcal_file_event_read(optarg, &calnote,
> i)) {
>
> Probably excluding it for all WIN32 platforms is excessive, but
> gn_vcal_file_event_read() is generated by flex, which is missing on native
> Windows platforms. I'm fine with changing it but it will fail on Visual
> Studio platforms.

Which leads to a question whenever flex output should be part of source
tarball. Developers working on git version should be smart enough to setup
their envinroment properly.

> > diff --git a/gnokii/gnokii-monitor.c b/gnokii/gnokii-monitor.c
> > index 7fde06c5..30aba457 100644
> > --- a/gnokii/gnokii-monitor.c
> > +++ b/gnokii/gnokii-monitor.c
> > @@ -109,8 +109,6 @@ static gn_error readcbmessage(gn_cb_message *message)
> >
> >  static void displaycall(int call_id)
> >  {
> > -/* FIXME!!! */
> > -#ifndef WIN32
> [...]
> >         struct timeval now, delta;
> [...]
> > -#endif
>
> I believe it was due to some weirdness of struct timeval on Windows. Can
> you please tell on which compiling environments was it tested?

Please note that commit messages on Fabrizio's patches are based on his
comments here: https://savannah.nongnu.org/patch/?8934
Original patches explain even less. I suggest leaving this one out for
now. It is not a real showstopper.

Regards,
        ladis

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/8] Use lower case for Win32 includes

Ladislav Michl
In reply to this post by Pawel Kot
On Mon, Dec 03, 2018 at 06:10:26PM +0300, Pawel Kot wrote:

> Hi,
>
> On Mon, Dec 3, 2018 at 12:42 PM Ladislav Michl <[hidden email]> wrote:
> > diff --git a/include/gnokii.h.in b/include/gnokii.h.in
> > index b3253455..d407d53d 100644
> > --- a/include/gnokii.h.in
> > +++ b/include/gnokii.h.in
> > @@ -31,8 +31,8 @@ extern "C" {
> [...]
> > -#elif defined(_MSC_VER) && defined(WIN32)
> [...]
> > +#elif defined(WIN32)
>
> So this one changes behaviour and is not explained. And not sure if
> correct. Care to give an explanation?

I'll leave an explanation to the patch author and meanwhile offer
updated patch :) Change in include/gnokii.h.in is now no-op, it could
be as well left out, I kept it for consistency with other windows
include names.

---8<---

From: Fabrizio Gennari <[hidden email]>
Subject: [PATCH v2] Use lower case for Win32 includes

mingw32 provides lower case names for Win32 header files, use lower
case names in #include directives.

diff --git a/ChangeLog b/ChangeLog
index d09275ce..ed6d42ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -117,6 +117,10 @@
  * build updates
     o use the native Autoconf support for cross-compilation, that
       is passing --host= to the configure script
+ * win32 updates
+    o since Linux filesystems are case-sensitive, and MinGW-W64
+      provides lower case names for Win32 header files, use lower
+      case names in #include directives
 
 0.6.31
 ======
diff --git a/common/devices/winbluetooth.c b/common/devices/winbluetooth.c
index 832a46f9..a898e2e6 100644
--- a/common/devices/winbluetooth.c
+++ b/common/devices/winbluetooth.c
@@ -12,10 +12,10 @@
 
 #ifdef HAVE_BLUETOOTH
 
-#include <Winsock2.h>
+#include <winsock2.h>
 #include <mmsystem.h>
-#include <Ws2bth.h>
-#include <BluetoothAPIs.h>
+#include <ws2bth.h>
+#include <bluetoothapis.h>
 
 #include "compat.h"
 #include "gnokii.h"
diff --git a/include/gnokii.h.in b/include/gnokii.h.in
index b3253455..b1bb0c5c 100644
--- a/include/gnokii.h.in
+++ b/include/gnokii.h.in
@@ -32,7 +32,7 @@ extern "C" {
 #  include <inttypes.h>
 #  include <sys/time.h>
 #elif defined(_MSC_VER) && defined(WIN32)
-#  include <Winsock.h> /* for struct timeval */
+#  include <winsock.h> /* for struct timeval */
 typedef unsigned char uint8_t;
 #endif
 

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/8] Use posix_spawn to run external scripts

Pawel Kot
In reply to this post by Ladislav Michl
Hi,

On Mon, Dec 3, 2018 at 7:50 PM Ladislav Michl <[hidden email]> wrote:
> Sure, no problem. I read above you are fine with that approach in general.

Yes, overall it seems fine to me.

> However it would be nice if someone could actually give pachset a try.
> Preferably on non linux platforms.

I will on Windows and OS X once I'm done with travelling.

> > > -typedef void (*cfg_foreach_func)(const char *section, const char *key,
> > const char *value);
> > > -void cfg_foreach(const char *section, cfg_foreach_func func);
> > > +#define cfg_foreach_entry(section, header, entry) \
> > > +       for (; header != NULL; header = header->next) \
> > > +               if (strcmp(section, h->section) == 0) \
> > > +                       for (entry = h->entries; entry != NULL; entry =
> > entry->next)
> >
> > Why that?
>
> If that question leads to opencoding that single macro use, I'm fine
> with that.

Yes, that's what I've meant. Sorry for not being clear.

Cheers,
Paweł
--
Pawel Kot

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 3/8] Remove some unnecessary #ifndef WIN32

Pawel Kot
In reply to this post by Ladislav Michl
Hi,

On Mon, Dec 3, 2018 at 7:49 PM Ladislav Michl <[hidden email]> wrote:

>
> Hi Paweł,
>
> On Mon, Dec 03, 2018 at 06:15:07PM +0300, Pawel Kot wrote:
> > Hi,
> >
> > On Mon, Dec 3, 2018 at 12:41 PM Ladislav Michl <[hidden email]> wrote:
> > > diff --git a/gnokii/gnokii-calendar.c b/gnokii/gnokii-calendar.c
> > > index e32bf769..10236bae 100644
> > > --- a/gnokii/gnokii-calendar.c
> > > +++ b/gnokii/gnokii-calendar.c
> > > @@ -264,7 +264,6 @@ gn_error writecalendarnote(int argc, char *argv[],
> > gn_data *data, struct gn_stat
> > > -#ifndef WIN32
> > >                 if (error == GN_ERR_NOTIMPLEMENTED) {
> > >                         switch (gn_vcal_file_event_read(optarg, &calnote,
> > i)) {
> >
> > Probably excluding it for all WIN32 platforms is excessive, but
> > gn_vcal_file_event_read() is generated by flex, which is missing on native
> > Windows platforms. I'm fine with changing it but it will fail on Visual
> > Studio platforms.
>
> Which leads to a question whenever flex output should be part of source
> tarball. Developers working on git version should be smart enough to setup
> their envinroment properly.

Yes, we had this discussion some time ago. The conclusion was that in git tree we do not keep it, but we put it into a source tarball. Still, I'm not sure if it would compile under Windows.

Cheers,
Paweł
--
Pawel Kot

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 5/8] Test for number of mkdir() arguments

Ladislav Michl
In reply to this post by Ladislav Michl
Paweł,

there's an issue with changes like that one bellow.
Currently each file including compat.h have to include
config.h before on its own. That does not sound too
convenient and is quite error prone as I just found
testing mkdir patch on more configurations.

So what about this change:

diff --git a/include/compat.h b/include/compat.h
index 8711c425..60974344 100644
--- a/include/compat.h
+++ b/include/compat.h
@@ -18,6 +18,17 @@
 #ifndef _gnokii_compat_h
 #define _gnokii_compat_h
 
+#if defined(HAVE_CONFIG_H)
+#  include "config.h"
+
+#elif defined(WIN32) && defined(_MSC_VER)
+#  include "windows-config.h"
+
+#else
+#  error "compat.h requires config.h"
+
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>

Perhaps ommiting windows-config.h part in the first round.
Then we could delete config.h include from each file which
also include compat.h. That is... almost each file.

Objections?


On Mon, Dec 03, 2018 at 10:42:06AM +0100, Ladislav Michl wrote:

> Windows' mkdir() takes only 1 argument, so add a test for that.
> ---
>  configure.ac     |  1 +
>  include/compat.h | 15 ++++++++++++++-
>  2 files changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/configure.ac b/configure.ac
> index 379c7412..cd2064dd 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -902,6 +902,7 @@ AC_PROG_GCC_TRADITIONAL
>  AC_FUNC_MEMCMP
>  AC_TYPE_SIGNAL
>  AC_FUNC_STRFTIME
> +AC_FUNC_MKDIR
>  AC_CHECK_FUNCS(mktime timegm gettimeofday select poll wcrtomb)
>  AC_CHECK_FUNCS(strchr strdup strndup strstr strtol strtok strsep)
>  AC_CHECK_FUNCS(asprintf vasprintf snprintf vsnprintf getpass setenv)
> diff --git a/include/compat.h b/include/compat.h
> index 009f5f0e..8711c425 100644
> --- a/include/compat.h
> +++ b/include/compat.h
> @@ -199,6 +199,20 @@ int vasprintf(char **ptr, const char *format, va_list ap);
>  time_t timegm(struct tm *tm);
>  #endif
>  
> +#if HAVE_MKDIR
> +# if MKDIR_TAKES_ONE_ARG
> +   /* Mingw32 */
> +#  define mkdir(a,b) mkdir(a)
> +# endif
> +#else
> +# if HAVE__MKDIR
> +   /* plain Win32 */
> +#  define mkdir(a,b) _mkdir(a)
> +# else
> +#  error "Don't know how to create a directory on this system."
> +# endif
> +#endif
> +
>  /*
>   * The following code was taken from W. Richard Stevens'
>   * "UNIX Network Programming", Volume 1, Second Edition.
> @@ -219,7 +233,6 @@ time_t timegm(struct tm *tm);
>  #ifdef WIN32
>  #  ifdef _MSC_VER
>  #    define inline __inline
> -#    define mkdir(dirname, accessrights) _mkdir(dirname)
>  #    define strcasecmp _stricmp
>  #    define strncasecmp _strnicmp
>  #    define __const const
> --
> 2.20.0.rc1
>
>
> _______________________________________________
> gnokii-users mailing list
> [hidden email]
> https://lists.nongnu.org/mailman/listinfo/gnokii-users

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 5/8] Test for number of mkdir() arguments

Pawel Kot
Hi Ladis,

On Mon, Dec 3, 2018 at 11:28 PM Ladislav Michl <[hidden email]> wrote:
> there's an issue with changes like that one bellow.
> Currently each file including compat.h have to include
> config.h before on its own. That does not sound too
> convenient and is quite error prone as I just found
> testing mkdir patch on more configurations.

I remeber it being discussed. Still not quite sure why we did it that way.
I believe #include "config.h" from compat.h should be safe. Even without removing all others. I believe that whenever you need something from "config.h" you should explicitly include it.

Cheers,
Paweł

> So what about this change:
>
> diff --git a/include/compat.h b/include/compat.h
> index 8711c425..60974344 100644
> --- a/include/compat.h
> +++ b/include/compat.h
> @@ -18,6 +18,17 @@
>  #ifndef        _gnokii_compat_h
>  #define        _gnokii_compat_h
>
> +#if defined(HAVE_CONFIG_H)
> +#  include "config.h"
> +
> +#elif defined(WIN32) && defined(_MSC_VER)
> +#  include "windows-config.h"
> +
> +#else
> +#  error "compat.h requires config.h"
> +
> +#endif
> +
>  #include <stdlib.h>
>  #include <stdio.h>
>
> Perhaps ommiting windows-config.h part in the first round.
> Then we could delete config.h include from each file which
> also include compat.h. That is... almost each file.
>
> Objections?
>
>
> On Mon, Dec 03, 2018 at 10:42:06AM +0100, Ladislav Michl wrote:
> > Windows' mkdir() takes only 1 argument, so add a test for that.
> > ---
> >  configure.ac     |  1 +
> >  include/compat.h | 15 ++++++++++++++-
> >  2 files changed, 15 insertions(+), 1 deletion(-)
> >
> > diff --git a/configure.ac b/configure.ac
> > index 379c7412..cd2064dd 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -902,6 +902,7 @@ AC_PROG_GCC_TRADITIONAL
> >  AC_FUNC_MEMCMP
> >  AC_TYPE_SIGNAL
> >  AC_FUNC_STRFTIME
> > +AC_FUNC_MKDIR
> >  AC_CHECK_FUNCS(mktime timegm gettimeofday select poll wcrtomb)
> >  AC_CHECK_FUNCS(strchr strdup strndup strstr strtol strtok strsep)
> >  AC_CHECK_FUNCS(asprintf vasprintf snprintf vsnprintf getpass setenv)
> > diff --git a/include/compat.h b/include/compat.h
> > index 009f5f0e..8711c425 100644
> > --- a/include/compat.h
> > +++ b/include/compat.h
> > @@ -199,6 +199,20 @@ int vasprintf(char **ptr, const char *format, va_list ap);
> >  time_t timegm(struct tm *tm);
> >  #endif
> >
> > +#if HAVE_MKDIR
> > +# if MKDIR_TAKES_ONE_ARG
> > +   /* Mingw32 */
> > +#  define mkdir(a,b) mkdir(a)
> > +# endif
> > +#else
> > +# if HAVE__MKDIR
> > +   /* plain Win32 */
> > +#  define mkdir(a,b) _mkdir(a)
> > +# else
> > +#  error "Don't know how to create a directory on this system."
> > +# endif
> > +#endif
> > +
> >  /*
> >   * The following code was taken from W. Richard Stevens'
> >   * "UNIX Network Programming", Volume 1, Second Edition.
> > @@ -219,7 +233,6 @@ time_t timegm(struct tm *tm);
> >  #ifdef WIN32
> >  #  ifdef _MSC_VER
> >  #    define inline __inline
> > -#    define mkdir(dirname, accessrights) _mkdir(dirname)
> >  #    define strcasecmp _stricmp
> >  #    define strncasecmp _strnicmp
> >  #    define __const const
> > --
> > 2.20.0.rc1
> >
> >
> > _______________________________________________
> > gnokii-users mailing list
> > [hidden email]
> > https://lists.nongnu.org/mailman/listinfo/gnokii-users
>
> _______________________________________________
> gnokii-users mailing list
> [hidden email]
> https://lists.nongnu.org/mailman/listinfo/gnokii-users



--
Pawel Kot

_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/8] Use lower case for Win32 includes

Fabrizio Gennari
In reply to this post by Pawel Kot


Il 03-12-18 16:10, Pawel Kot ha scritto:
Hi,

On Mon, Dec 3, 2018 at 12:42 PM Ladislav Michl <[hidden email]> wrote:
> diff --git a/include/gnokii.h.in b/include/gnokii.h.in
> index b3253455..d407d53d 100644
> --- a/include/gnokii.h.in
> +++ b/include/gnokii.h.in
> @@ -31,8 +31,8 @@ extern "C" {
[...]
> -#elif defined(_MSC_VER) && defined(WIN32)
[...]
> +#elif defined(WIN32)

So this one changes behaviour and is not explained. And not sure if correct. Care to give an explanation?

This fixes a compilation error on MinGW32 about struct timeval not being defined

i686-w64-mingw32-gcc -DHAVE_CONFIG_H -I. -I../include    -I../include -g -O2 -Wall -Wno-pointer-sign -fvisibility=hidden -fno-strict-aliasing  -MT dump_vcard-dump-vcard.o -MD -MP -MF .deps/dump_vcard-dump-vcard.Tpo -c -o dump_vcard-dump-vcard.o `test -f 'dump-vcard.c' || echo './'`dump-vcard.c
In file included from ../include/gnokii.h:63:0,
                 from dump-vcard.c:4:
../include/gnokii/common.h:775:17: error: field ‘last’ has incomplete type
  struct timeval last;
                 ^~~~
In file included from ../include/gnokii/data.h:22:0,
                 from ../include/gnokii.h:64,
                 from dump-vcard.c:4:
../include/gnokii/call.h:70:17: error: field ‘start_time’ has incomplete type
  struct timeval start_time;
                 ^~~~~~~~~~
../include/gnokii/call.h:71:17: error: field ‘answer_time’ has incomplete type
  struct timeval answer_time;
                 ^~~~~~~~~~~


_______________________________________________
gnokii-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/gnokii-users
12