commit 2b3065f0afa0ef7019735845083395221fe26add (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Sat Mar 11 10:25:05 2017 +0200 Avoid aborts/assertion violations due to 'vim-empty-lines-mode' * src/xdisp.c (handle_single_display_spec): If position to be restored after processing the display property comes from an overlay, protect against that overlay's end point being outside of the narrowed region. Reported by Filipe Silva in http://lists.gnu.org/archive/html/emacs-devel/2017-03/msg00176.html. diff --git a/src/xdisp.c b/src/xdisp.c index 1e7cb4ec66..7ff37a6fb4 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4999,6 +4999,14 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, { ptrdiff_t ovendpos = OVERLAY_POSITION (OVERLAY_END (overlay)); + /* Some borderly-sane Lisp might call us with the current + buffer narrowed so that overlay-end is outside the + POINT_MIN..POINT_MAX region, which will then cause + various assertion violations and crashes down the road, + starting with pop_it when it will attempt to use POSITION + set below. Prevent that. */ + ovendpos = clip_to_bounds (BEGV, ovendpos, ZV); + if (ovendpos > CHARPOS (*position)) SET_TEXT_POS (*position, ovendpos, CHAR_TO_BYTE (ovendpos)); } commit 996fcc74a431e6db819dae1cfbc90ffdc15a222f Author: Glenn Morris Date: Fri Mar 10 15:39:52 2017 -0500 ; * doc/lispref/processes.texi: Restore deleted FIXME comment. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 8bfb56bd96..630853384e 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -3337,6 +3337,10 @@ dotted notation. @node Bindat Examples @subsection Examples of Byte Unpacking and Packing +@c FIXME? This seems a very long example for something that is not used +@c very often. As of 25.2, gdb-mi.el is the only user of bindat.el in Emacs. +@c Maybe one or both of these examples should just be moved to the +@c commentary of bindat.el. Here are two complete examples that use bindat.el. The first shows simple byte packing: commit b2f20aa60b1997aa85949c529c2981bb978510a6 Author: Glenn Morris Date: Fri Mar 10 15:14:33 2017 -0500 Small improvement for epa-display-error (bug#24553) * lisp/epa.el (epa-display-error): Report the actual program in use. diff --git a/lisp/epa.el b/lisp/epa.el index 4378c09738..52963b6d3c 100644 --- a/lisp/epa.el +++ b/lisp/epa.el @@ -628,7 +628,7 @@ If SECRET is non-nil, list secret keys instead of public keys." (`import-keys "Error while importing keys with \"%s\":") (`export-keys "Error while exporting keys with \"%s\":") (_ "Error while executing \"%s\":\n\n")) - epg-gpg-program) + (epg-context-program context)) "\n\n" (epg-context-error-output context))) (epa-info-mode) commit ec168376d1d961be9adceaafcbff04d5b2b0a492 Author: Paul Eggert Date: Fri Mar 10 09:30:30 2017 -0800 Tweak X toolkit code to pacify modern GCC * lwlib/lwlib-Xaw.c, lwlib/lwlib-Xm.c, lwlib/lwlib.c: Don’t include , since this code now calls emacs_abort rather than abort. * lwlib/lwlib-Xaw.c (make_dialog, xaw_generic_callback) (wm_delete_window): * lwlib/lwlib-Xm.c (make_menu_in_widget, do_call): * lwlib/lwlib.c (instantiate_widget_instance, lw_make_widget): * lwlib/xlwmenu.c (abort_gracefully, draw_separator) (separator_height, XlwMenuInitialize): Use emacs_abort, not abort. Without this change, some calls to ‘abort’ were invalid, as stdlib.h was not always included. * src/widget.c (resources, emacsFrameClassRec): * src/xfns.c (x_window) [USE_X_TOOLKIT]: * src/xmenu.c (create_and_show_popup_menu) [USE_X_TOOLKIT]: * src/xterm.c (emacs_options) [USE_X_TOOLKIT}: (x_term_init) [USE_X_TOOLKIT]: Cast string constants to char * to pacify --enable-gcc-warnings. diff --git a/lwlib/lwlib-Xaw.c b/lwlib/lwlib-Xaw.c index af57a7fe91..ec33e78829 100644 --- a/lwlib/lwlib-Xaw.c +++ b/lwlib/lwlib-Xaw.c @@ -21,7 +21,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include #include @@ -516,10 +515,10 @@ make_dialog (char* name, XtTranslations button_override; #endif - if (! pop_up_p) abort (); /* not implemented */ - if (text_input_slot) abort (); /* not implemented */ - if (radio_box) abort (); /* not implemented */ - if (list) abort (); /* not implemented */ + if (! pop_up_p) emacs_abort (); /* not implemented */ + if (text_input_slot) emacs_abort (); /* not implemented */ + if (radio_box) emacs_abort (); /* not implemented */ + if (list) emacs_abort (); /* not implemented */ if (! actions_initted) { @@ -764,7 +763,7 @@ xaw_generic_callback (Widget widget, XtPointer closure, XtPointer call_data) break; val = val->next; } - if (! val) abort (); + if (! val) emacs_abort (); user_data = val->call_data; } @@ -790,11 +789,11 @@ wm_delete_window (Widget w, shell = w; if (! XtIsSubclass (shell, shellWidgetClass)) - abort (); + emacs_abort (); XtVaGetValues (shell, XtNnumChildren, &nkids, NULL); XtVaGetValues (shell, XtNchildren, &kids, NULL); if (!kids || !*kids) - abort (); + emacs_abort (); for (i = 0; i < nkids; i++) { widget = kids[i]; @@ -804,11 +803,11 @@ wm_delete_window (Widget w, if (! widget) return; id = lw_get_widget_id (widget); - if (! id) abort (); + if (! id) emacs_abort (); { widget_info *info = lw_get_widget_info (id); - if (! info) abort (); + if (! info) emacs_abort (); if (info->selection_cb) info->selection_cb (widget, id, (XtPointer) -1); } diff --git a/lwlib/lwlib-Xm.c b/lwlib/lwlib-Xm.c index 6e1e0d6921..b18429067d 100644 --- a/lwlib/lwlib-Xm.c +++ b/lwlib/lwlib-Xm.c @@ -22,7 +22,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include #include @@ -504,14 +503,14 @@ make_menu_in_widget (widget_instance* instance, /* WIDGET should be a RowColumn. */ if (!XmIsRowColumn (widget)) - abort (); + emacs_abort (); /* Determine whether WIDGET is a menu bar. */ type = -1; XtSetArg (al[0], XmNrowColumnType, &type); XtGetValues (widget, al, 1); if (type != XmMENU_BAR && type != XmMENU_PULLDOWN && type != XmMENU_POPUP) - abort (); + emacs_abort (); menubar_p = type == XmMENU_BAR; /* Add a callback to popups and pulldowns that is called when @@ -528,7 +527,7 @@ make_menu_in_widget (widget_instance* instance, /* Check that those are all we have (the caller should have deleted the rest). */ if (old_num_children != keep_first_children) - abort (); + emacs_abort (); /* Create the rest. */ for (child_index = keep_first_children; cur; child_index++, cur = cur->next) @@ -677,7 +676,7 @@ update_one_menu_entry (widget_instance* instance, if (strcmp (XtName (widget_list[i]), XtName (widget)) == 0) break; if (i == old_num_children) - abort (); + emacs_abort (); if (XmIsCascadeButton (widget_list[i])) { menu = XmCreatePulldownMenu (parent, XtName(widget), NULL, 0); @@ -1829,7 +1828,7 @@ do_call (Widget widget, break; default: - abort (); + emacs_abort (); } } diff --git a/lwlib/lwlib.c b/lwlib/lwlib.c index 18a46109eb..fffb17f7c3 100644 --- a/lwlib/lwlib.c +++ b/lwlib/lwlib.c @@ -26,7 +26,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include "lwlib-int.h" #include "lwlib-utils.h" #include @@ -721,13 +720,13 @@ instantiate_widget_instance (widget_instance *instance) { printf ("No creation function for widget type %s\n", instance->info->type); - abort (); + emacs_abort (); } instance->widget = (*function) (instance); if (!instance->widget) - abort (); + emacs_abort (); /* XtRealizeWidget (instance->widget);*/ } @@ -772,7 +771,7 @@ lw_make_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p) initialize_widget_instance (instance); } if (!instance->widget) - abort (); + emacs_abort (); return instance->widget; } diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index 11be340725..1ce4aead93 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c @@ -267,7 +267,7 @@ abort_gracefully (Widget w) if (XtIsShell (XtParent (w))) XtRemoveGrab (w); ungrab_all (w, CurrentTime); - abort (); + emacs_abort (); } static void @@ -897,7 +897,7 @@ draw_separator (XlwMenuWidget mw, break; default: - abort (); + emacs_abort (); } } @@ -933,7 +933,7 @@ separator_height (enum menu_separator separator) return 5; default: - abort (); + emacs_abort (); } } @@ -1900,7 +1900,7 @@ XlwMenuInitialize (Widget request, Widget w, ArgList args, Cardinal *num_args) if (!mw->menu.font) { fprintf (stderr, "Menu font fixed not found, can't continue.\n"); - abort (); + emacs_abort (); } } } diff --git a/src/widget.c b/src/widget.c index 96555ed2ac..d7ec702851 100644 --- a/src/widget.c +++ b/src/widget.c @@ -57,31 +57,34 @@ static XtGeometryResult EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry #define offset(field) offsetof (EmacsFrameRec, emacs_frame.field) static XtResource resources[] = { - {XtNgeometry, XtCGeometry, XtRString, sizeof (String), + {(char *) XtNgeometry, (char *) XtCGeometry, XtRString, sizeof (String), offset (geometry), XtRString, (XtPointer) 0}, {XtNiconic, XtCIconic, XtRBoolean, sizeof (Boolean), offset (iconic), XtRImmediate, (XtPointer) False}, - {XtNemacsFrame, XtCEmacsFrame, XtRPointer, sizeof (XtPointer), + {(char *) XtNemacsFrame, (char *) XtCEmacsFrame, + XtRPointer, sizeof (XtPointer), offset (frame), XtRImmediate, 0}, - {XtNminibuffer, XtCMinibuffer, XtRInt, sizeof (int), + {(char *) XtNminibuffer, (char *) XtCMinibuffer, XtRInt, sizeof (int), offset (minibuffer), XtRImmediate, (XtPointer)0}, - {XtNunsplittable, XtCUnsplittable, XtRBoolean, sizeof (Boolean), + {(char *) XtNunsplittable, (char *) XtCUnsplittable, + XtRBoolean, sizeof (Boolean), offset (unsplittable), XtRImmediate, (XtPointer)0}, - {XtNinternalBorderWidth, XtCInternalBorderWidth, XtRInt, sizeof (int), + {(char *) XtNinternalBorderWidth, (char *) XtCInternalBorderWidth, + XtRInt, sizeof (int), offset (internal_border_width), XtRImmediate, (XtPointer)4}, - {XtNinterline, XtCInterline, XtRInt, sizeof (int), + {(char *) XtNinterline, (char *) XtCInterline, XtRInt, sizeof (int), offset (interline), XtRImmediate, (XtPointer)0}, - {XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel), - offset (foreground_pixel), XtRString, "XtDefaultForeground"}, - {XtNcursorColor, XtCForeground, XtRPixel, sizeof (Pixel), - offset (cursor_color), XtRString, "XtDefaultForeground"}, - {XtNbarCursor, XtCBarCursor, XtRBoolean, sizeof (Boolean), + {(char *) XtNforeground, (char *) XtCForeground, XtRPixel, sizeof (Pixel), + offset (foreground_pixel), XtRString, (char *) "XtDefaultForeground"}, + {(char *) XtNcursorColor, (char *) XtCForeground, XtRPixel, sizeof (Pixel), + offset (cursor_color), XtRString, (char *) "XtDefaultForeground"}, + {(char *) XtNbarCursor, (char *) XtCBarCursor, XtRBoolean, sizeof (Boolean), offset (bar_cursor), XtRImmediate, (XtPointer)0}, - {XtNvisualBell, XtCVisualBell, XtRBoolean, sizeof (Boolean), + {(char *) XtNvisualBell, (char *) XtCVisualBell, XtRBoolean, sizeof (Boolean), offset (visual_bell), XtRImmediate, (XtPointer)0}, - {XtNbellVolume, XtCBellVolume, XtRInt, sizeof (int), + {(char *) XtNbellVolume, (char *) XtCBellVolume, XtRInt, sizeof (int), offset (bell_volume), XtRImmediate, (XtPointer)0}, }; @@ -106,7 +109,7 @@ emacsFrameTranslations [] = "\ static EmacsFrameClassRec emacsFrameClassRec = { { /* core fields */ /* superclass */ &widgetClassRec, - /* class_name */ "EmacsFrame", + /* class_name */ (char *) "EmacsFrame", /* widget_size */ sizeof (EmacsFrameRec), /* class_initialize */ 0, /* class_part_initialize */ 0, diff --git a/src/xfns.c b/src/xfns.c index 97aa923da0..d3e0839d8a 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -2640,10 +2640,10 @@ x_window (struct frame *f, long window_prompting) ac = 0; XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++; - XtSetArg (al[ac], XtNshowGrip, 0); ac++; - XtSetArg (al[ac], XtNallowResize, 1); ac++; - XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++; - XtSetArg (al[ac], XtNemacsFrame, f); ac++; + XtSetArg (al[ac], (char *) XtNshowGrip, 0); ac++; + XtSetArg (al[ac], (char *) XtNallowResize, 1); ac++; + XtSetArg (al[ac], (char *) XtNresizeToPreferred, 1); ac++; + XtSetArg (al[ac], (char *) XtNemacsFrame, f); ac++; XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++; XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++; XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++; diff --git a/src/xmenu.c b/src/xmenu.c index e1f71a2490..249cd6903f 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1366,7 +1366,7 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, event->button = i; /* Don't allow any geometry request from the user. */ - XtSetArg (av[ac], XtNgeometry, 0); ac++; + XtSetArg (av[ac], (char *) XtNgeometry, 0); ac++; XtSetValues (menu, av, ac); /* Display the menu. */ diff --git a/src/xterm.c b/src/xterm.c index 28faea14a3..7856793f8d 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -11671,20 +11671,21 @@ x_check_font (struct frame *f, struct font *font) #ifdef USE_X_TOOLKIT static XrmOptionDescRec emacs_options[] = { - {"-geometry", ".geometry", XrmoptionSepArg, NULL}, - {"-iconic", ".iconic", XrmoptionNoArg, (XtPointer) "yes"}, - - {"-internal-border-width", "*EmacsScreen.internalBorderWidth", - XrmoptionSepArg, NULL}, - {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL}, - - {"-T", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL}, - {"-wn", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL}, - {"-title", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL}, - {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL}, - {"-in", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL}, - {"-mc", "*pointerColor", XrmoptionSepArg, (XtPointer) NULL}, - {"-cr", "*cursorColor", XrmoptionSepArg, (XtPointer) NULL} + {(char *) "-geometry", (char *) ".geometry", XrmoptionSepArg, NULL}, + {(char *) "-iconic", (char *) ".iconic", XrmoptionNoArg, (XtPointer) "yes"}, + + {(char *) "-internal-border-width", + (char *) "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL}, + {(char *) "-ib", (char *) "*EmacsScreen.internalBorderWidth", + XrmoptionSepArg, NULL}, + {(char *) "-T", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL}, + {(char *) "-wn", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL}, + {(char *) "-title", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL}, + {(char *) "-iconname", (char *) "*EmacsShell.iconName", + XrmoptionSepArg, NULL}, + {(char *) "-in", (char *) "*EmacsShell.iconName", XrmoptionSepArg, NULL}, + {(char *) "-mc", (char *) "*pointerColor", XrmoptionSepArg, NULL}, + {(char *) "-cr", (char *) "*cursorColor", XrmoptionSepArg, NULL} }; /* Whether atimer for Xt timeouts is activated or not. */ @@ -12002,11 +12003,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) int argc = 0; char *argv[3]; - argv[0] = ""; + argv[0] = (char *) ""; argc = 1; if (xrm_option) { - argv[argc++] = "-xrm"; + argv[argc++] = (char *) "-xrm"; argv[argc++] = xrm_option; } turn_on_atimers (false); @@ -12384,7 +12385,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) dpy = dpyinfo->display; d.addr = (XPointer)&dpy; d.size = sizeof (Display *); - fr.addr = XtDefaultFont; + fr.addr = (char *) XtDefaultFont; fr.size = sizeof (XtDefaultFont); to.size = sizeof (Font *); to.addr = (XPointer)&font; commit 817c4d1a3055a12ab2f1a6a06479b5eb4d66286b Author: Michael Albinus Date: Fri Mar 10 16:13:39 2017 +0100 * doc/misc/tramp.texi (Android shell setup): Require adb program diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index fab2b532d6..dd52a87a1a 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -1891,9 +1891,10 @@ where @samp{192.168.0.1} is the remote host IP address @section Android shell setup hints @cindex android shell setup -@value{tramp} uses the @option{adb} method to access Android -devices. Android devices provide a restricted shell access through an -USB connection. The local host must have the Android SDK installed. +@value{tramp} uses the @option{adb} method to access Android devices. +Android devices provide a restricted shell access through an USB +connection. The local host must have the @command{adb} program +installed. Applications such as @code{SSHDroid} that run @command{sshd} process on the Android device can accept any @option{ssh}-based methods commit 7e434ed2ebc4f9fddd6f7d34e7a9907729fd3bcf Author: Michael Albinus Date: Fri Mar 10 14:34:23 2017 +0100 Adapt tramp-tests.el * test/lisp/net/tramp-tests.el (tramp-test06-directory-file-name) (tramp-test24-file-name-completion): Call `tramp-completion-mode-p' with argument. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 0c3068aeb0..a854f4e87d 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -732,7 +732,8 @@ This checks also `file-name-as-directory', `file-name-directory', (should (string-equal (file-name-as-directory file) - (if (tramp-completion-mode-p) file (concat file "./")))) + (if (tramp-completion-mode-p (tramp-dissect-file-name file)) + file (concat file "./")))) (should (string-equal (file-name-directory file) file)) (should (string-equal (file-name-nondirectory file) "")))))))) @@ -1515,7 +1516,9 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (progn ;; Method and host name in completion mode. This kind ;; of completion does not work on MS Windows. - (when (and (tramp-completion-mode-p) + (when (and (tramp-completion-mode-p + (tramp-dissect-file-name + tramp-test-temporary-file-directory)) (not (memq system-type '(cygwin windows-nt)))) (unless (zerop (length method)) (should commit ae6b2b8918007c8694563dd8ba14207a560d72c1 Author: Thien-Thi Nguyen Date: Fri Mar 10 13:25:41 2017 +0100 [doc] Replace bindat example: s/fortune cookie/rfc868 payload/ * doc/lispref/processes.texi (Bindat Examples): Mention two examples in intro blurb; rewrite first example. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 58e04a311a..8bfb56bd96 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -3337,91 +3337,31 @@ dotted notation. @node Bindat Examples @subsection Examples of Byte Unpacking and Packing -@c FIXME? This seems a very long example for something that is not used -@c very often. As of 24.1, gdb-mi.el is the only user of bindat.el in Emacs. -@c Maybe one or both of these examples should just be moved to the -@c commentary of bindat.el. - Here is a complete example of byte unpacking and packing: + Here are two complete examples that use bindat.el. +The first shows simple byte packing: @lisp (require 'bindat) -(defvar fcookie-index-spec - '((:version u32) - (:count u32) - (:longest u32) - (:shortest u32) - (:flags u32) - (:delim u8) - (:ignored fill 3) - (:offset repeat (:count) (:foo u32))) - "Description of a fortune cookie index file's contents.") - -(defun fcookie (cookies &optional index) - "Display a random fortune cookie from file COOKIES. -Optional second arg INDEX specifies the associated index -filename, by default \"COOKIES.dat\". Display cookie text -in buffer \"*Fortune Cookie: BASENAME*\", where BASENAME -is COOKIES without the directory part." - (interactive "fCookies file: ") - (let* ((info (with-temp-buffer - (insert-file-contents-literally - (or index (concat cookies ".dat"))) - (bindat-unpack fcookie-index-spec - (buffer-string)))) - (sel (random (bindat-get-field info :count))) - (beg (cdar (bindat-get-field info :offset sel))) - (end (or (cdar (bindat-get-field info - :offset (1+ sel))) - (nth 7 (file-attributes cookies))))) - (switch-to-buffer - (get-buffer-create - (format "*Fortune Cookie: %s*" - (file-name-nondirectory cookies)))) - (erase-buffer) - (insert-file-contents-literally - cookies nil beg (- end 3)))) - -(defun fcookie-create-index (cookies &optional index delim) - "Scan file COOKIES, and write out its index file. -Optional arg INDEX specifies the index filename, which by -default is \"COOKIES.dat\". Optional arg DELIM specifies the -unibyte character that, when found on a line of its own in -COOKIES, indicates the border between entries." - (interactive "fCookies file: ") - (setq delim (or delim ?%)) - (let ((delim-line (format "\n%c\n" delim)) - (count 0) - (max 0) - min p q len offsets) - (unless (= 3 (string-bytes delim-line)) - (error "Delimiter cannot be represented in one byte")) - (with-temp-buffer - (insert-file-contents-literally cookies) - (while (and (setq p (point)) - (search-forward delim-line (point-max) t) - (setq len (- (point) 3 p))) - (setq count (1+ count) - max (max max len) - min (min (or min max) len) - offsets (cons (1- p) offsets)))) - (with-temp-buffer - (set-buffer-multibyte nil) - (insert - (bindat-pack - fcookie-index-spec - `((:version . 2) - (:count . ,count) - (:longest . ,max) - (:shortest . ,min) - (:flags . 0) - (:delim . ,delim) - (:offset . ,(mapcar (lambda (o) - (list (cons :foo o))) - (nreverse offsets)))))) - (let ((coding-system-for-write 'raw-text-unix)) - (write-file (or index (concat cookies ".dat"))))))) +(defun rfc868-payload () + (bindat-pack + '((now-hi u16) + (now-lo u16)) + ;; Emacs uses Unix epoch, while RFC868 epoch + ;; is 1900-01-01 00:00:00, which is 2208988800 + ;; (or #x83aa7e80) seconds more. + (let ((now (time-add nil '(#x83aa #x7e80)))) + `((now-hi . ,(car now)) + (now-lo . ,(cadr now)))))) + +(let ((s (rfc868-payload))) + (list (multibyte-string-p s) + (mapconcat (lambda (byte) + (format "%02x" byte)) + s " ") + (current-time-string))) + @result{} (nil "dc 6d 17 01" "Fri Mar 10 13:13:53 2017") @end lisp The following is an example of defining and unpacking a complex