Subject: bug#6668: 23.1.90; desktop-read and/or hack-local-variables fails to load local variables from DOS formatted files

From: Brent Goodrick <[email-masked]>
Date: Mon, 19 Jul 2010 08:40:22 -0700

This bug report will be sent to the Free Software Foundation,
not to your local site managers!
Please write in English if possible, because the Emacs maintainers
usually do not have translators to read other languages for them.

Your bug report will be posted to the [email-masked] mailing list,
and to the gnu.emacs.bug news group.

Please describe exactly what actions triggered the bug
and the precise symptoms of the bug.  If you can, give
a recipe starting from `emacs -Q':

The desktop-read function (actually hack-local-variables) gives a
false error when the local variables in a buffer that is being read
have CR codes as a part of the line terminators.

This is all I have in my .emacs in order to reproduce this bug:

--- cut here ---
;; this file is in -*-emacs-lisp-*-

(progn
  (let (
	;; Keep the desktop filename separate, as now I'm using the same
	;; Emacs fileset for all platforms, including Windows. If we do not
	;; do this, then we get errors when trying to find files from
	;; Windows that are referenced in the desktop file:
	(my-desktop-base-file-name (or
				    (getenv "EMACS_DESKTOP_FILE") ;; <-- for debugging
				    (error "You did not export the EMACS_DESKTOP_FILE env var!"))))
    ;; Avoid the prompt about the desktop being locked. At some point in the new Emacs (22.2.1 on Debian), it began prompting
    ;; me for it being locked. I don't understand that silliness.
    (setq desktop-load-locked-desktop t)
    (desktop-save-mode 1)
    (setq desktop-base-file-name my-desktop-base-file-name)
    (desktop-read)))
--- cut here ---

For the purpose of reproducing this bug, EMACS_DESKTOP_FILE contains
"/home/brentg/.emacs.desktop.bad2" and it contains:

--- cut here ---
;; -*- mode: emacs-lisp; coding: emacs-mule; -*-
;; --------------------------------------------------------------------------
;; Desktop File for Emacs
;; --------------------------------------------------------------------------
;; Created Mon Jul 19 07:54:58 2010
;; Desktop file format version 206
;; Emacs version 23.1.90.1

;; Global section:
(setq desktop-missing-file-warning nil)
(setq tags-file-name nil)
(setq tags-table-list nil)
(setq search-ring nil)
(setq regexp-search-ring nil)
(setq register-alist nil)
(setq file-name-history '("~/perltest.pm"))

;; Buffer section -- buffers listed in same order as in buffer list:
(desktop-create-buffer 206
  "/home/brentg/perltest.pm"
  "perltest.pm"
  'perl-mode
  nil
  245
  '(1 nil)
  t
  nil
  '((indent-tabs-mode) (buffer-file-coding-system . undecided-unix) (fill-column . 130)))
--- cut here ---

The perltest.pm file contains the following text, and has DOS line
terminators (CR+LF, not just LF):

--- cut here ---
package perltest;

1;  # so the require or use succeeds  

### Local Variables: ***
### mode: perl ***
### indent-tabs-mode:nil ***
### sh-indent-after-open:+ ***
### sh-indent-after-if:0 ***
### sh-indent-comment:t ***
### End: ***
--- cut here ---

This works (executing a shell script that sets PATH and invokes my
locally compiled Emacs from CVS source and enables XFT):

brentg@hungover:~$ EMACS_DESKTOP_FILE=~/.emacs.desktop.bad2 emacsxft -Q
+ /home/brentg/install/Linux.x86_64/bin/emacs -Q -debug-init

This does not:

brentg@hungover:~$ EMACS_DESKTOP_FILE=~/.emacs.desktop.bad2 emacsxft 
+ /home/brentg/install/Linux.x86_64/bin/emacs -debug-init

The error stack trace on the latter command is (control codes squashed
into literal escape sequences for the email report):

Debugger entered--Lisp error: (error "Local variables entry is missing the suffix")
  signal(error ("Local variables entry is missing the suffix"))
  error("Local variables entry is missing the suffix")
  hack-local-variables()
  normal-mode(t)
  after-find-file(nil t)
  find-file-noselect-1(#<buffer perltest.pm> "~/perltest.pm" nil nil "/mnt/sdb1/home/brentg/perltest.pm" (32524636 2065))
  find-file-noselect("/home/brentg/perltest.pm")
  desktop-restore-file-buffer("/home/brentg/perltest.pm" "perltest.pm" nil)
  #[nil "\010	\236A\206\010\000\305\n\013\f#\207" [desktop-buffer-major-mode desktop-buffer-mode-handlers desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc desktop-restore-file-buffer] 4]()
  desktop-create-buffer(206 "/home/brentg/perltest.pm" "perltest.pm" perl-mode nil 245 (1 nil) t nil ((indent-tabs-mode) (buffer-file-coding-system . undecided-unix) (fill-column . 130)))
  eval-buffer(#<buffer  *load*<2>> nil "/home/brentg/.emacs.desktop.bad2" nil t)  ; Reading at buffer position 843
  load-with-code-conversion("/home/brentg/.emacs.desktop.bad2" "/home/brentg/.emacs.desktop.bad2" t t)
  load("/home/brentg/.emacs.desktop.bad2" t t t)
  desktop-read()
  (let ((my-desktop-base-file-name ...)) (setq desktop-load-locked-desktop t) (desktop-save-mode 1) (setq desktop-base-file-name my-desktop-base-file-name) (desktop-read))
  (progn (let (...) (setq desktop-load-locked-desktop t) (desktop-save-mode 1) (setq desktop-base-file-name my-desktop-base-file-name) (desktop-read)))
  eval-buffer(#<buffer  *load*> nil "/home/brentg/.emacs" nil t)  ; Reading at buffer position 807
  load-with-code-conversion("/home/brentg/.emacs" "/home/brentg/.emacs" t t)
  load("~/.emacs" t t)
  #[nil "\010\205\264\000	\306=\203\021\000\307\010\310Q\2027\000	\311=\2033\000\312\307\313\314#\203#\000\315\2027\000\312\307\313\316#\203/\000\317\2027\000\315\2027\000\307\010\320Q\032\321\023\322\n\321\211#\210\013\321=\203_\000\323\324\325\307\010\326Q!\"\034\322\f\321\211#\210\013\321=\203^\000\n\023)\013\203\244\000\327\013!\330\232\203\244\000\331\013!\211\035\332P\036\"\333\016\"!\203\200\000\016\"\202\213\000\333\015!\203\212\000\015\202\213\000\313\211\025\203\243\000\334\015\013\"\203\241\000\335\336\015\013#\210\337\340!\210\015\023*\016#?\205\263\000\313\036$\322\341\321\211#))\207" [init-file-user system-type user-init-file-1 user-init-file otherfile source ms-dos "~" "/_emacs" windows-nt directory-files nil "^\\.emacs\\(\\.elc?\\)?$" "~/.emacs" "^_emacs\\(\\.elc?\\)?$" "~/_emacs" "/.emacs" t load expand-file-name "init" file-name-as-directory "/.emacs.d" file-name-extension "elc" file-name-sans-extension ".el" file-exists-p file-newer-than-file-p message "Warning: %s is newer than %s" sit-for 1 "default" alt inhibit-default-init inhibit-startup-screen] 7]()
  command-line()
  normal-top-level()

Notice the (buffer-file-coding-system . undecided-unix) in the desktop
save file, even though the file is in DOS formatted mode
originally. If I use (buffer-file-coding-system . undecided-dos) in
the desktop file instead, it works.  I believe the quick workaround
for this is to just delete the desktop file and reload (this started
being a problem after I recently updated my Emacs from CVS and rebuilt
from scratch at Sun Jul 4 17:07:52 PDT 2010). I know I had invoked and
saved that desktop several times between then and now, and so I don't
know why the desktop would have been has a buffer-file-coding-system
of "undecided-unix". Perhaps the original file from which I created
perltest.pm started out as undecided-unix, but then switched to
undecided-dos in between sessions???

Since this does not occur under -q or -Q conditions, I cannot
determine exactly how the perltest.pm buffer is left in a state where
the CR codes are in the buffer during Emacs init.  But I believe one
aspect of the problem is that `hack-local-variables' is tripping up on
the CR codes as left in the suffix local variable, and should
not.

Below is how I hacked around it to confirm it.

--- cut here ---
;; Originally taken from
;; /mnt/sdb1/home/brentg/install/Linux.x86_64/share/emacs/23.1.90/lisp/files.el.gz
;; and hacked to avoid the (error "Local variables entry is missing the
;; suffix") error. See HACK below:
(defun hack-local-variables (&optional mode-only)
  "Parse and put into effect this buffer's local variables spec.
If MODE-ONLY is non-nil, all we do is check whether the major mode
is specified, returning t if it is specified."
  (let ((enable-local-variables
	 (and local-enable-local-variables enable-local-variables))
	result)
    (unless mode-only
      (setq file-local-variables-alist nil)
      (report-errors "Directory-local variables error: %s"
	(hack-dir-local-variables)))
    (when (or mode-only enable-local-variables)
      (setq result (hack-local-variables-prop-line mode-only))
      ;; Look for "Local variables:" line in last page.
      (save-excursion
	(goto-char (point-max))
	(search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
			 'move)
	(when (let ((case-fold-search t))
		(search-forward "Local Variables:" nil t))
	  (skip-chars-forward " \t")
	  ;; suffix is what comes after "local variables:" in its line.
	  ;; prefix is what comes before "local variables:" in its line.
	  (let ((suffix
		 (concat
		  (regexp-quote (buffer-substring (point)
						  (line-end-position)))
		  "$"))
		(prefix
		 (concat "^" (regexp-quote
			      (buffer-substring (line-beginning-position)
						(match-beginning 0)))))
		beg)
	    (forward-line 1)
	    (let ((startpos (point))
		  endpos
		  (thisbuf (current-buffer)))
	      (save-excursion
		(unless (let ((case-fold-search t))
			  (re-search-forward
			   (concat prefix "[ \t]*End:[ \t]*" suffix)
			   nil t))
		  ;; This used to be an error, but really all it means is
		  ;; that this may simply not be a local-variables section,
		  ;; so just ignore it.
		  (message "Local variables list is not properly terminated"))
		(beginning-of-line)
		(setq endpos (point)))
	      (with-temp-buffer
		(insert-buffer-substring thisbuf startpos endpos)
		(goto-char (point-min))
		;; HACK: Do not replace the CR codes in the buffer since it
		;; may be a DOS formatted buffer and the above retrieval of
		;; the suffix includes the CR code, which will cause the
		;; (error "Local variables entry is missing the suffix") error
		;; to occur, which is a false failure. therefore, I commented
		;; out the following call to `subst-char-in-region' as the
		;; lame hackaround for the bug report:
		;; (subst-char-in-region (point) (point-max) ?\^m ?\n)
		(while (not (eobp))
		  ;; Discard the prefix.
		  (if (looking-at prefix)
		      (delete-region (point) (match-end 0))
		    (error "Local variables entry is missing the prefix"))
		  (end-of-line)
		  ;; Discard the suffix.
		  (if (looking-back suffix)
		      (delete-region (match-beginning 0) (point))
		    (error "Local variables entry is missing the suffix"))
		  (forward-line 1))
		(goto-char (point-min))
		(while (not (eobp))
		  ;; Find the variable name; strip whitespace.
		  (skip-chars-forward " \t")
		  (setq beg (point))
		  (skip-chars-forward "^:\n")
		  (if (eolp) (error "Missing colon in local variables entry"))
		  (skip-chars-backward " \t")
		  (let* ((str (buffer-substring beg (point)))
			 (var (let ((read-circle nil))
				(read str)))
			 val)
		    ;; Read the variable value.
		    (skip-chars-forward "^:")
		    (forward-char 1)
		    (let ((read-circle nil))
		      (setq val (read (current-buffer))))
		    (if mode-only
			(if (eq var 'mode)
			    (setq result t))
		      (unless (eq var 'coding)
			(condition-case nil
			    (push (cons (if (eq var 'eval)
					    'eval
					  (indirect-variable var))
					val) result)
			  (error nil)))))
		  (forward-line 1))))))))
    ;; Now we've read all the local variables.
    ;; If MODE-ONLY is non-nil, return whether the mode was specified.
    (cond (mode-only result)
	  ;; Otherwise, set the variables.
	  (enable-local-variables
	   (hack-local-variables-filter result nil)
	   (when file-local-variables-alist
	     ;; Any 'evals must run in the Right sequence.
	     (setq file-local-variables-alist
		   (nreverse file-local-variables-alist))
	     (run-hooks 'before-hack-local-variables-hook)
	     (dolist (elt file-local-variables-alist)
	       (hack-one-local-variable (car elt) (cdr elt))))
	   (run-hooks 'hack-local-variables-hook)))))
--- cut here ---

Maybe the correct fix involves insuring that the suffix has all CR
codes cleaned out similarly to how subst-char-in-region is used. That
way, it doesn't matter whether or not the CR codes are in the buffer.

Emacs doesn't crash, just errors out upon init.

Thanks!
bg

If Emacs crashed, and you have the Emacs process in the gdb debugger,
please include the output from the following gdb commands:
    `bt full' and `xbacktrace'.
For information about debugging Emacs, please read the file
/home/brentg/install/Linux.x86_64/share/emacs/23.1.90/etc/DEBUG.

In GNU Emacs 23.1.90.1 (x86_64-unknown-linux-gnu, GTK+ Version 2.18.6)
 of 2010-07-04 on hungover
Windowing system distributor `The X.Org Foundation', version 11.0.10707000
configured using `configure  '--with-x-toolkit' '--with-xft' '--prefix=/home/brentg/install/Linux.x86_64''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: nil
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t

Major mode: Emacs-Lisp

Minor modes in effect:
  desktop-save-mode: t
  erc-ring-mode: t
  erc-services-mode: t
  erc-networks-mode: t
  display-time-mode: t
  shell-dirtrack-mode: t
  iswitchb-mode: t
  delete-selection-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  global-auto-composition-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: 1
  transient-mark-mode: t
  abbrev-mode: t

Recent input:
C-p C-p C-p C-p C-p C-p C-p C-p C-n C-n C-n C-n C-n 
C-n C-n C-n C-n C-n C-a C-n C-n C-n C-n C-n C-n C-n 
C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n 
C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n 
C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n 
C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n 
C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n M-p M-p C-p 
C-p C-p C-p C-p C-p C-M-SPC C-z C-c C-g C-g M-> M-P 
C-SPC M-b C-v SPC SPC - l SPC ~ / . e m <tab> M-b M-b 
M-b M-b M-b M-f SPC - q <return> C-l M-P M-b M-b M-b 
M-b M-b C-M-SPC C-M-SPC <backspace> C-d C-d C-k C-k 
<backspace> <return> <help-echo> M-x C-g C-x C-b C-n 
C-n C-n d x C-n d d d d d d d d d d d d d d d x C-p 
<return> C-n C-n C-n C-n C-n C-n C-n C-M-SPC C-w <tab> 
M-( e r r o r SPC M-" Y o u SPC d i d SPC n o t SPC 
s p e c i f i y <backspace> <backspace> y SPC C-p M-b 
C-M-SPC C-z C-n C-f C-f C-f C-f C-f C-f C-f C-f C-f 
C-f C-f C-f C-f C-b C-b C-M-SPC e x p o r t SPC C-v 
SPC e n v SPC v a r b M-b M-b M-b t h e SPC C-a C-e 
C-b C-b C-b C-b C-b C-b C-b C-f <backspace> ! C-d C-a 
C-x C-s M-x r e p p p p o r t <C-backspace> r e p o 
r t - b <tab> <tab> e <tab> <tab> <return>

Recent messages:

Pushed a window configuration.
Mark set [4 times]
Saving file /home/brentg/.emacs...
Wrote /home/brentg/.emacs
Making completion list... [2 times]

Load-path shadows:
/home/brentg/emacs_lisp_imported/slime/tree-widget hides /home/brentg/install/Linux.x86_64/share/emacs/23.1.90/lisp/tree-widget
/home/brentg/emacs_lisp_imported/remember/remember hides /home/brentg/install/Linux.x86_64/share/emacs/23.1.90/lisp/textmodes/remember
/home/brentg/emacs_lisp_imported/css-mode/css-mode hides /home/brentg/install/Linux.x86_64/share/emacs/23.1.90/lisp/textmodes/css-mode

Features:
(shadow mailalias vm-pgg vm-reply pgg pgg-parse pgg-def vm-rfaddons
gnus-group gnus-undo nnmail mail-source gnus-start gnus-spec gnus-int
gnus-range message ecomplete mml mml-sec password-cache mm-decode
mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 qp ietf-drums
gmm-utils mailheader canlock sha1 hex-util hashcash gnus-win bbdb-vm
vm-autoload bbdb-snarf mail-extr rfc822 bbdb-com vm-menu vm-window
vm-toolbar vm-folder vm-undo vm-summary vm-mouse vm-page vm-motion
vm-minibuf vm-misc emacsbug ediff-vers ansi-color dabbrev
multi-isearch bg-emacs bg-desktop-setup vc-git desktop
bg-customizations bg-x-setup bg-init-program-setup bg-cmake-setup
cmake-mode bg-quack-setup quack bg-qmake-setup bg-allout-setup
bg-gimp-mode-setup eldoc cmuscheme scheme gimp-mode scheme-complete
snippet autoinsert bg-edebug-setup edebug bg-lisppaste-setup
bg-instrument-util bg-calc-setup calc-ext calc calc-loaddefs calc-macs
bg-sudo-setup sudo bg-crontab-util bg-reminder bg-wikipedia-mode-setup
wikipedia-mode bg-outline-magic-mode-setup outline-magic noutline
outline bg-emacs-lisp-mode-setup find-func bg-lisp-setup slime
tree-widget hyperspec hideshow bg-css-mode-setup bg-gnuserv-setup
gnuserv bg-compressed-files-setup bg-search-replace-util
bg-apropos-mode-setup apropos bg-search-tcl bg-man-setup bg-env-setup
man assoc bg-visual-basic-mode-setup bg-regr-util bg-help-mode-setup
help-mode bg-diag bg-password-hiding-setup bg-browser-setup
bg-x-windows-util bg-perl-setup gud bg-perl-util bg-rectangle-setup
bg-picture-mode-setup bg-xml-setup nxml-mode nxml-outln nxml-rap
nxml-util nxml-glyph nxml-enc xmltok boxquote bg-iswitchb-setup
bg-outline-setup allout bg-autosave-setup bg-planner-setup
bg-planner-indexing bg-planner-yank-link bg-planner-yank-link-man
bg-planner-yank-link-file bg-planner-yank-link-info bg-web-util mm-url
url url-proxy url-privacy url-expand url-methods url-history
url-cookie url-util url-parse url-vars mailcap
bg-planner-yank-link-w3m bg-planner-yank-link-base bg-planner-elisp
bg-remember-mode-setup remember-planner remember bg-bbdb-setup
bbdb-autoloads bbdb bg-planner-note-util bg-elisp-unit-test-util
bg-planner-util bg-narrowing-setup bg-muse-hacks image-file
planner-lisp planner-publish muse-xml planner cal-menu calendar
cal-loaddefs sort muse-colors bg-muse-setup bg-planner-abbrevs-setup
muse-html muse-xml-common cus-edit cus-start cus-load muse-publish
muse-project muse-protocols muse-regexps muse muse-nested-tags
muse-mode bg-planner-vars timeclock bg-scrolling-setup bg-irc-setup
erc-ring erc-join erc-services erc-networks erc-dcc erc-fill erc-stamp
erc-goodies erc erc-backend erc-compat format-spec bg-ediff-setup
bg-info-setup bg-local-key-mappings bg-global-key-mappings
bg-rx-interactive bg-grep-setup bg-grep-group grep-group grep
bg-color-moccur-setup color-moccur bg-occur-mode-setup
bg-find-file-setup bg-bookmark-definitions bookmark pp
bg-tabstop-definitions bg-mail-setup vm-w3m vm-mime vm-pine vm-macro
vm-message vm vm-autoloads vm-vars vm-version bg-encryption-setup dgpg
generic epa-file epa derived epg epg-config bg-w3m-setup edmacro
kmacro bg-w3m-hacks w3m browse-url doc-view jka-compr image-mode
timezone w3m-hist w3m-fb w3m-ems w3m-ccl ccl w3m-favicon w3m-image
w3m-proc w3m-util supercite regi smtpmail sendmail bg-gnus-definitions
imap gnus gnus-ems nnheader gnus-util netrc mail-utils mm-util
mail-prsvr wid-edit bg-octave-setup bg-scm-setup bg-vc-util vc
vc-dispatcher pcvs pcvs-parse pcvs-info pcvs-defs bg-git-setup git
log-edit easy-mmode pcvs-util add-log ewoc bg-tcl-mode-setup
bg-compile-setup bg-grep-compilation-util bg-python-mode-setup
python-21 python bg-buffer-menu-setup bg-makefile-mode-setup
bg-shell-script-mode-setup sh-script executable bg-sticky-windows
bg-dbx bg-gdb-mode-setup bg-gdb bg-gdb-util bg-javascript-setup js
byte-opt bytecomp byte-compile json etags imenu newcomment
bg-java-setup bg-calendar-setup bg-minibuffer-setup bg-abbrev-setup
bg-precision-util bg-shell-util bg-background time-date mailabbrev
uniquify ibuffer bg-frame-definitions bg-vc-mode-setup
bg-dired-extensions bg-pdf-setup dired-aux dired bg-forms-mode-setup
forms-mode forms bg-defaults-definitions time bg-isearch-setup advice
advice-preload bg-display-setup bg-cc-mode-setup bg-cxx-nav
bg-run-immediate bg-window-config-helper bg-id-utils-setup idutils
compile info bg-info-util bg-symbol-stack bg-cxx-util
bg-cxx-scan-debug-mode-base bg-basic-regexps-and-chars bg-p4-setup
bg-p4-completion bg-p4-resolve bg-set-util bg-ediff-sparse-mode
bg-ediff-sparse-mode-base bg-p4-manual-apply-mode
bg-p4-manual-apply-mode-base bg-p4-base bg-det-setup bg-rx-extra
bg-shell-mode-setup bg-rlogin-setup rlogin shell comint ring
bg-open-file-at-point bg-boilers bg-boiler-commands rx help-fns
bg-p4-scan-mode bg-p4-scan-mode-base view bg-button-mode-util
bg-p4-basic-button bg-p4-util cc-mode cc-fonts easymenu cc-menus
cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs regexp-opt
bg-elisp-debug-util elp bg-utility iswitchb bg-file-cleanup bg-os-util
bg-linux-utility help-macro cl cl-19 ediff-merg ediff-diff ediff-wind
ediff-help ediff-util ediff-mult ediff-init ediff perl-mode mouse-sel
thingatpt rect bg-delete-selection-mode-setup delsel
bg-coding-system-setup lisppaste-autoloads xml-rpc-autoloads package
reporter tooltip ediff-hook vc-hooks lisp-float-type mwheel x-win
x-dnd font-setting tool-bar dnd fontset image fringe lisp-mode
register page menu-bar rfn-eshadow timer select scroll-bar mldrag
mouse jit-lock font-lock syntax facemenu font-core frame cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese case-table epa-hook jka-cmpr-hook help simple abbrev
loaddefs button minibuffer faces cus-face files text-properties
overlay md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote make-network-process dbusbind
system-font-setting font-render-setting gtk x-toolkit x multi-tty
emacs)