* mu4e-proc, mu-cmd-server: update server output
protocol - this unbreaks running mu server on non-utf8 locales - should also be a bit faster - configure.ac: bump version
This commit is contained in:
@ -14,7 +14,7 @@
|
|||||||
## along with this program; if not, write to the Free Software Foundation,
|
## along with this program; if not, write to the Free Software Foundation,
|
||||||
## Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
## Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
AC_INIT([mu],[0.9.8.4-dev2],[http://code.google.com/p/mu0/issues/list],[mu])
|
AC_INIT([mu],[0.9.8.4-dev3],[http://code.google.com/p/mu0/issues/list],[mu])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_SRCDIR([src/mu.cc])
|
AC_CONFIG_SRCDIR([src/mu.cc])
|
||||||
# libtoolize wants to put some stuff in here; if you have an old
|
# libtoolize wants to put some stuff in here; if you have an old
|
||||||
|
|||||||
@ -34,9 +34,23 @@
|
|||||||
(defvar mu4e~proc-buf nil "Buffer for results data.")
|
(defvar mu4e~proc-buf nil "Buffer for results data.")
|
||||||
(defconst mu4e~proc-name "*mu4e-proc*" "Name of the server process, buffer.")
|
(defconst mu4e~proc-name "*mu4e-proc*" "Name of the server process, buffer.")
|
||||||
(defvar mu4e~proc-process nil "The mu-server process")
|
(defvar mu4e~proc-process nil "The mu-server process")
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
|
;; dealing with the length cookie that precedes expressions
|
||||||
|
(defconst mu4e~cookie-pre "\376"
|
||||||
|
"Each expression we get from the backend (mu server) starts with
|
||||||
|
a length cookie:
|
||||||
|
<`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>.")
|
||||||
|
(defconst mu4e~cookie-post "\377"
|
||||||
|
"Each expression we get from the backend (mu server) starts with
|
||||||
|
a length cookie:
|
||||||
|
<`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>.")
|
||||||
|
(defconst mu4e~cookie-matcher-rx
|
||||||
|
(concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)" mu4e~cookie-post)
|
||||||
|
"Regular expression matching the length cookie. Match 1 will be
|
||||||
|
the length (in hex).")
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e~proc-start ()
|
(defun mu4e~proc-start ()
|
||||||
"Start the mu server process."
|
"Start the mu server process."
|
||||||
@ -78,16 +92,20 @@
|
|||||||
|
|
||||||
|
|
||||||
(defun mu4e~proc-eat-sexp-from-buf ()
|
(defun mu4e~proc-eat-sexp-from-buf ()
|
||||||
"'Eat' the next s-expression from `mu4e~proc-buf'. `mu4e~proc-buf gets its
|
"'Eat' the next s-expression from `mu4e~proc-buf'. Note: this is a string,
|
||||||
contents from the mu-servers in the following form:
|
not an emacs-buffer. `mu4e~proc-buf gets its contents from the
|
||||||
\376<len-of-sexp>\376<sexp>
|
mu-servers in the following form:
|
||||||
Function returns this sexp, or nil if there was none. `mu4e~proc-buf' is
|
<`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>
|
||||||
updated as well, with all processed sexp data removed."
|
|
||||||
|
Function returns this sexp, or nil if there was
|
||||||
|
none. `mu4e~proc-buf' is updated as well, with all processed sexp
|
||||||
|
data removed."
|
||||||
(when mu4e~proc-buf
|
(when mu4e~proc-buf
|
||||||
;; TODO: maybe try a non-regexp solution?
|
;; mu4e~cookie-matcher-rx:
|
||||||
(let* ((b (string-match "\376\\([0-9]+\\)\376" mu4e~proc-buf))
|
;; (concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)]" mu4e~cookie-post)
|
||||||
|
(let* ((b (string-match mu4e~cookie-matcher-rx mu4e~proc-buf))
|
||||||
(sexp-len
|
(sexp-len
|
||||||
(when b (string-to-number (match-string 1 mu4e~proc-buf)))))
|
(when b (string-to-number (match-string 1 mu4e~proc-buf) 16))))
|
||||||
;; does mu4e~proc-buf contain the full sexp?
|
;; does mu4e~proc-buf contain the full sexp?
|
||||||
(when (and b (>= (length mu4e~proc-buf) (+ sexp-len (match-end 0))))
|
(when (and b (>= (length mu4e~proc-buf) (+ sexp-len (match-end 0))))
|
||||||
;; clear-up start
|
;; clear-up start
|
||||||
@ -96,7 +114,7 @@ updated as well, with all processed sexp data removed."
|
|||||||
;; is the sexp, and convert that to utf-8, before we interpret it.
|
;; is the sexp, and convert that to utf-8, before we interpret it.
|
||||||
(let ((objcons
|
(let ((objcons
|
||||||
(ignore-errors ;; note: this may fail if we killed the process
|
(ignore-errors ;; note: this may fail if we killed the process
|
||||||
;; in the middle
|
;; in the middle
|
||||||
(read-from-string
|
(read-from-string
|
||||||
(decode-coding-string (substring mu4e~proc-buf 0 sexp-len) 'utf-8)))))
|
(decode-coding-string (substring mu4e~proc-buf 0 sexp-len) 'utf-8)))))
|
||||||
(when objcons
|
(when objcons
|
||||||
|
|||||||
@ -82,17 +82,26 @@ install_sig_handler (void)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Markers for/after the lenght cookie that precedes the expression we
|
||||||
|
* write to output. We use octal 376, 377 (ie, 0xfe, 0xff) as they
|
||||||
|
* will never occur in utf8 */
|
||||||
|
|
||||||
|
|
||||||
/* BOX - beginning-of-expression */
|
#define COOKIE_PRE '\376'
|
||||||
#define BOX "\376"
|
#define COOKIE_POST '\377'
|
||||||
|
|
||||||
static void G_GNUC_PRINTF(1, 2)
|
static void G_GNUC_PRINTF(1, 2)
|
||||||
print_expr (const char* frm, ...)
|
print_expr (const char* frm, ...)
|
||||||
{
|
{
|
||||||
char *expr;
|
char *expr;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
size_t exprlen;
|
size_t exprlen, lenlen;
|
||||||
|
char cookie[16];
|
||||||
|
static int outfd = 0;
|
||||||
|
|
||||||
|
if (outfd == 0)
|
||||||
|
outfd = fileno (stdout);
|
||||||
|
|
||||||
expr = NULL;
|
expr = NULL;
|
||||||
|
|
||||||
@ -100,8 +109,16 @@ print_expr (const char* frm, ...)
|
|||||||
exprlen = g_vasprintf (&expr, frm, ap);
|
exprlen = g_vasprintf (&expr, frm, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
g_print (BOX "%u" BOX "%s\n", (unsigned)exprlen + 1,
|
/* this cookie tells the frontend where to expect the next
|
||||||
expr);
|
* expression */
|
||||||
|
|
||||||
|
cookie[0] = COOKIE_PRE;
|
||||||
|
lenlen = sprintf(cookie + 1, "%x", exprlen + 1); /* + 1 for \n */
|
||||||
|
cookie[lenlen + 1] = COOKIE_POST;
|
||||||
|
|
||||||
|
write (outfd, cookie, lenlen + 2); /* + 2 for the 2 BOX */
|
||||||
|
write (outfd, expr, exprlen);
|
||||||
|
write (outfd, "\n", 1);
|
||||||
|
|
||||||
g_free (expr);
|
g_free (expr);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user