diff --git a/pd/src/m_pd.h b/pd/src/m_pd.h
index 63b93149e0282ea668c5123e700018265e13e41f..5f6f1e1e2f9e27c66ba2715bfc0d645aab55a506 100644
--- a/pd/src/m_pd.h
+++ b/pd/src/m_pd.h
@@ -13,7 +13,7 @@ extern "C" {
 #define PD_MAJOR_VERSION 0
 #define PD_MINOR_VERSION 42
 #define PD_BUGFIX_VERSION 7
-#define PD_TEST_VERSION "20140814"
+#define PD_TEST_VERSION "20140903"
 #define PDL2ORK
 
 /* old name for "MSW" flag -- we have to take it for the sake of many old
@@ -52,6 +52,12 @@ extern "C" {
 #define EXTERN_STRUCT extern struct
 #endif
 
+    /* Define some attributes, specific to the compiler */
+#if defined(__GNUC__)
+#define ATTRIBUTE_FORMAT_PRINTF(a, b) __attribute__ ((format (printf, a, b)))
+#else
+#define ATTRIBUTE_FORMAT_PRINTF(a, b)
+#endif
 
 #if !defined(_SIZE_T) && !defined(_SIZE_T_)
 #include <stddef.h>     /* just for size_t -- how lame! */
@@ -501,6 +507,8 @@ EXTERN void error(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
 EXTERN void verbose(int level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
 EXTERN void bug(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
 EXTERN void pd_error(void *object, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+EXTERN void logpost(const void *object, const int level, const char *fmt, ...)
+    ATTRIBUTE_FORMAT_PRINTF(3, 4);
 EXTERN void sys_logerror(const char *object, const char *s);
 EXTERN void sys_unixerror(const char *object);
 EXTERN void sys_ouch(void);
diff --git a/pd/src/s_print.c b/pd/src/s_print.c
index c262bd1439a9ec1e2b83fd4e6a5def69bf8250d9..8df706ae0bd6c5e472361de99efe1c17303f3bd2 100644
--- a/pd/src/s_print.c
+++ b/pd/src/s_print.c
@@ -9,6 +9,9 @@
 #include <string.h>
 #include <errno.h>
 #include "s_stuff.h"
+#ifdef _MSC_VER  /* This is only for Microsoft's compiler, not cygwin, e.g. */
+#define snprintf sprintf_s
+#endif
 
 t_printhook sys_printhook;
 int sys_printtostderr;
@@ -21,10 +24,10 @@ static char* strnescape(char *dest, const char *src, size_t len)
     for(; ptout < len; ptin++, ptout++)
     {
         int c = src[ptin];
-        if (c == '\\' || c == '{' || c == '}')
+        if (c == '\\' || c == '{' || c == '}' || c == ';')
             dest[ptout++] = '\\';
-            dest[ptout] = src[ptin];
-            if (c==0) break;
+        dest[ptout] = src[ptin];
+        if (c==0) break;
     }
 
     if(ptout < len)
@@ -65,6 +68,32 @@ static void doerror(const void *object, const char *s)
     }
 }
 
+static void dologpost(const void *object, const int level, const char *s)
+{
+    char upbuf[MAXPDSTRING];
+    upbuf[MAXPDSTRING-1]=0;
+
+    // what about sys_printhook_verbose ?
+    if (sys_printhook) 
+    {
+        snprintf(upbuf, MAXPDSTRING-1, "verbose(%d): %s", level, s);
+        (*sys_printhook)(upbuf);
+    }
+    else if (sys_printtostderr) 
+    {
+        fprintf(stderr, "verbose(%d): %s", level, s);
+    }
+    else
+    {
+        char obuf[MAXPDSTRING];
+        //sys_vgui("::pdwindow::logpost {%s} %d {%s}\n", 
+                 //strnpointerid(obuf, object, MAXPDSTRING), 
+                 //level, strnescape(upbuf, s, MAXPDSTRING));
+        sys_vgui("pdtk_post {%s}\n", 
+                 strnescape(upbuf, s, MAXPDSTRING));
+    }
+}
+
 static void dopost(const char *s)
 {
     if (sys_printhook)
@@ -93,6 +122,20 @@ static void dopost(const char *s)
     }
 }
 
+void logpost(const void *object, const int level, const char *fmt, ...)
+{
+    char buf[MAXPDSTRING];
+    va_list ap;
+    t_int arg[8];
+    int i;
+    va_start(ap, fmt);
+    vsnprintf(buf, MAXPDSTRING-1, fmt, ap);
+    va_end(ap);
+    strcat(buf, "\n");
+
+    dologpost(object, level, buf);
+}
+
 void post(const char *fmt, ...)
 {
     char buf[MAXPDSTRING];