1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-12 09:00:40 -08:00

Merge branch 'master' into feature/igc

This commit is contained in:
Pip Cet 2025-05-01 12:59:07 +00:00
commit fc555a3772
330 changed files with 10080 additions and 5191 deletions

View file

@ -241,6 +241,8 @@ formatting them:
there will be no individual ChangeLog entries beyond the one in the there will be no individual ChangeLog entries beyond the one in the
summary line. summary line.
- If the commit message is a single-line, it should end with a period.
- If the commit has more than one author, the commit message should - If the commit has more than one author, the commit message should
contain separate lines to mention the other authors, like the contain separate lines to mention the other authors, like the
following: following:

View file

@ -245,9 +245,6 @@ Sean Whitton
============================================================================== ==============================================================================
2. Areas that someone is willing to maintain, although he would not 2. Areas that someone is willing to maintain, although he would not
necessarily mind if someone else was the official maintainer. necessarily mind if someone else was the official maintainer.
This list also includes people who are in the process of handing over
maintainership to someone listed above, but who want to continue to be
CC'd as though they were still the primary maintainer, in the meantime.
============================================================================== ==============================================================================
Eli Zaretskii Eli Zaretskii
@ -342,7 +339,6 @@ Tassilo Horn
Dmitry Gutov Dmitry Gutov
lisp/whitespace.el lisp/whitespace.el
lisp/vc/*
Vibhav Pant Vibhav Pant
lisp/net/browse-url.el lisp/net/browse-url.el

View file

@ -0,0 +1,14 @@
diff --git a/lib/getloadavg.c b/lib/getloadavg.c
index 9da41c16c02..1cb1c01097d 100644
--- a/lib/getloadavg.c
+++ b/lib/getloadavg.c
@@ -499,7 +499,8 @@ getloadavg (double loadavg[], int nelem)
}
# endif
-# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__)
+# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__) \
+ && (!defined __ANDROID__ || __ANDROID_API__ >= 13)
/* Linux without glibc, Android, Cygwin */
# define LDAV_DONE
# undef LOAD_AVE_TYPE

View file

@ -58,7 +58,7 @@ GNULIB_MODULES='
AVOIDED_MODULES=' AVOIDED_MODULES='
access btowc chmod close crypto/af_alg dup fchdir fstat gnulib-i18n access btowc chmod close crypto/af_alg dup fchdir fstat gnulib-i18n
iswblank iswctype iswdigit iswxdigit langinfo-h libgmp-mpq iswblank iswctype iswdigit iswxdigit langinfo-h libgmp-mpq
localename-unsafe-limited lock locale-h localename-unsafe-limited lock
mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo
openat-die opendir pthread-h raise openat-die opendir pthread-h raise
save-cwd select setenv sigprocmask stat stdarg-h save-cwd select setenv sigprocmask stat stdarg-h
@ -80,6 +80,10 @@ case $src in
*) src=$src/ ;; *) src=$src/ ;;
esac esac
GNULIB_TOOL_FLAGS="$GNULIB_TOOL_FLAGS
--local-dir="$src"admin/gnulib-patches
"
# Gnulib's source directory. # Gnulib's source directory.
gnulib_srcdir=${1-$src../gnulib} gnulib_srcdir=${1-$src../gnulib}

View file

@ -91,7 +91,7 @@ emba.gnu.org:5050, is not accessible publicly. Instead, the container
images must be build locally. Change the current directory to a images must be build locally. Change the current directory to a
recent Emacs branch (not a worktree), and apply the command recent Emacs branch (not a worktree), and apply the command
docker build --target emacs-inotify --tag emacs-inotify \ docker buildx build --target emacs-inotify --tag emacs-inotify \
-f test/infra/Dockerfile.emba . -f test/infra/Dockerfile.emba .
This creates the Debian-based image emacs-inotify, based on the This creates the Debian-based image emacs-inotify, based on the

View file

@ -59,8 +59,11 @@ case "${lang}" in
sourcedir="tree-sitter-typescript/tsx/src" sourcedir="tree-sitter-typescript/tsx/src"
grammardir="tree-sitter-typescript/tsx" grammardir="tree-sitter-typescript/tsx"
;; ;;
"toml")
org="tree-sitter-grammars"
;;
"yaml") "yaml")
org="ikatyang" org="tree-sitter-grammars"
;; ;;
esac esac

View file

@ -72,6 +72,9 @@ Section
# add registry key to enable uninstall from control panel # add registry key to enable uninstall from control panel
WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "GNU Emacs ${VERSION_BRANCH}" WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "GNU Emacs ${VERSION_BRANCH}"
WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$\"$UninstallerPath$\""
WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${VERSION_BRANCH}"
WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "Free Software Foundation, Inc."
WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$UninstallerPath$\"" WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$UninstallerPath$\""
;Create shortcuts ;Create shortcuts

View file

@ -72,31 +72,33 @@
;;; Query validation ;;; Query validation
(defvar treesit-admin--builtin-language-sources (defvar treesit-admin--builtin-language-sources
'((c "https://github.com/tree-sitter/tree-sitter-c") '((c "https://github.com/tree-sitter/tree-sitter-c" "v0.23.4")
(cpp "https://github.com/tree-sitter/tree-sitter-cpp") (cpp "https://github.com/tree-sitter/tree-sitter-cpp" "v0.23.4")
(cmake "https://github.com/uyha/tree-sitter-cmake") (cmake "https://github.com/uyha/tree-sitter-cmake" "v0.5.0")
(dockerfile "https://github.com/camdencheek/tree-sitter-dockerfile") (dockerfile "https://github.com/camdencheek/tree-sitter-dockerfile" "v0.2.0")
(go "https://github.com/tree-sitter/tree-sitter-go") (go "https://github.com/tree-sitter/tree-sitter-go" "v0.23.4")
(ruby "https://github.com/tree-sitter/tree-sitter-ruby") (ruby "https://github.com/tree-sitter/tree-sitter-ruby" "v0.23.1")
(javascript "https://github.com/tree-sitter/tree-sitter-javascript") (javascript "https://github.com/tree-sitter/tree-sitter-javascript" "v0.23.1")
(typescript "https://github.com/tree-sitter/tree-sitter-typescript" (typescript "https://github.com/tree-sitter/tree-sitter-typescript"
nil "typescript/src") "v0.23.2" "typescript/src")
(tsx "https://github.com/tree-sitter/tree-sitter-typescript" (tsx "https://github.com/tree-sitter/tree-sitter-typescript"
nil "tsx/src") "v0.23.2" "tsx/src")
(json "https://github.com/tree-sitter/tree-sitter-json") (json "https://github.com/tree-sitter/tree-sitter-json" "v0.24.8")
(rust "https://github.com/tree-sitter/tree-sitter-rust") (rust "https://github.com/tree-sitter/tree-sitter-rust" "v0.23.2")
(php "https://github.com/tree-sitter/tree-sitter-php" (php "https://github.com/tree-sitter/tree-sitter-php"
nil "php/src") "v0.23.11" "php/src")
(css "https://github.com/tree-sitter/tree-sitter-css") (css "https://github.com/tree-sitter/tree-sitter-css" "v0.23.1")
(phpdoc "https://github.com/claytonrcarter/tree-sitter-phpdoc") (phpdoc "https://github.com/claytonrcarter/tree-sitter-phpdoc")
(doxygen "https://github.com/tree-sitter-grammars/tree-sitter-doxygen") (doxygen "https://github.com/tree-sitter-grammars/tree-sitter-doxygen" "v1.1.0")
(lua "https://github.com/tree-sitter-grammars/tree-sitter-lua") (lua "https://github.com/tree-sitter-grammars/tree-sitter-lua" "v0.3.0")
(python "https://github.com/tree-sitter/tree-sitter-python") (python "https://github.com/tree-sitter/tree-sitter-python" "v0.23.6")
(html "https://github.com/tree-sitter/tree-sitter-html") (html "https://github.com/tree-sitter/tree-sitter-html" "v0.23.2")
(elixir "https://github.com/elixir-lang/tree-sitter-elixir") (elixir "https://github.com/elixir-lang/tree-sitter-elixir" "v0.3.3")
(heex "https://github.com/phoenixframework/tree-sitter-heex") (heex "https://github.com/phoenixframework/tree-sitter-heex" "v0.7.0")
(java "https://github.com/tree-sitter/tree-sitter-java") (java "https://github.com/tree-sitter/tree-sitter-java" "v0.23.5")
(jsdoc "https://github.com/tree-sitter/tree-sitter-jsdoc")) (jsdoc "https://github.com/tree-sitter/tree-sitter-jsdoc" "v0.23.2")
(toml "https://github.com/tree-sitter-grammars/tree-sitter-toml" "v0.7.0")
(yaml "https://github.com/tree-sitter-grammars/tree-sitter-yaml" "v0.7.0"))
"A list of sources for the builtin modes. "A list of sources for the builtin modes.
The source information are in the format of The source information are in the format of
`treesit-language-source-alist'. This is for development only.") `treesit-language-source-alist'. This is for development only.")
@ -154,9 +156,7 @@ queries that has problems with latest grammar."
(unless (memq language (alist-get mode mode-language-alist)) (unless (memq language (alist-get mode mode-language-alist))
(push language (alist-get mode mode-language-alist))) (push language (alist-get mode mode-language-alist)))
;; Validate query. ;; Validate query.
(when (not (ignore-errors (unless (treesit-query-valid-p language query)
(treesit-query-compile language query t)
t))
(push (list mode language feature) invalid-feature-list) (push (list mode language feature) invalid-feature-list)
(setq all-queries-valid nil)))) (setq all-queries-valid nil))))
(when all-queries-valid (when all-queries-valid
@ -259,9 +259,7 @@ Return non-nil if all queries are valid, nil otherwise."
(language (treesit-query-language query))) (language (treesit-query-language query)))
;; Validate query. ;; Validate query.
(when (and (eq lang language) (when (and (eq lang language)
(not (ignore-errors (not (treesit-query-valid-p language query)))
(treesit-query-compile language query t)
t)))
(setq all-queries-valid nil)))) (setq all-queries-valid nil))))
all-queries-valid)) all-queries-valid))

View file

@ -1866,6 +1866,7 @@ AS_IF([test $gl_gcc_warnings = no],
gl_WARN_ADD([$w]) gl_WARN_ADD([$w])
done done
gl_WARN_ADD([-Wredundant-decls]) # Prefer this, as we don't use Bison. gl_WARN_ADD([-Wredundant-decls]) # Prefer this, as we don't use Bison.
gl_WARN_ADD([-Wtrailing-whitespace]) # This project's coding style
gl_WARN_ADD([-Wno-missing-field-initializers]) # We need this one gl_WARN_ADD([-Wno-missing-field-initializers]) # We need this one
gl_WARN_ADD([-Wno-override-init]) # More trouble than it is worth gl_WARN_ADD([-Wno-override-init]) # More trouble than it is worth
gl_WARN_ADD([-Wno-sign-compare]) # Too many warnings for now gl_WARN_ADD([-Wno-sign-compare]) # Too many warnings for now
@ -2239,7 +2240,7 @@ AC_CACHE_CHECK([for flags to work around GCC bug 58416],
[AC_LANG_DEFINES_PROVIDED [AC_LANG_DEFINES_PROVIDED
[/* Work around GCC bug with double in unions on x86, [/* Work around GCC bug with double in unions on x86,
where the generated insns copy non-floating-point data where the generated insns copy non-floating-point data
via fldl/fstpl instruction pairs. This can misbehave via fldl/fstpl instruction pairs. This can misbehave if
the data's bit pattern looks like a NaN. See, e.g.: the data's bit pattern looks like a NaN. See, e.g.:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58416#c10 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58416#c10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71460 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71460

View file

@ -674,6 +674,9 @@ Run the SDB debugger.
using the minibuffer. The minibuffer's initial contents contain the using the minibuffer. The minibuffer's initial contents contain the
standard executable name and options for the debugger, and sometimes standard executable name and options for the debugger, and sometimes
also a guess for the name of the executable file you want to debug. also a guess for the name of the executable file you want to debug.
For @code{pdb}, @code{perldb}, and @code{guiler}, if the current buffer
visits a file, pressing @kbd{M-n} (@code{next-history-element})
in the prompt suggests a full command line including that file name.
Shell wildcards and variables are not allowed in this command line. Shell wildcards and variables are not allowed in this command line.
Emacs assumes that the first command argument which does not start Emacs assumes that the first command argument which does not start
with a @samp{-} is the executable file name. with a @samp{-} is the executable file name.

View file

@ -2165,6 +2165,10 @@ You can similarly enter the Shift, Control, and Meta modifiers by
using @kbd{C-x @@ S}, @kbd{C-x @@ c}, and @kbd{C-x @@ m}, respectively, using @kbd{C-x @@ S}, @kbd{C-x @@ c}, and @kbd{C-x @@ m}, respectively,
although this is rarely needed. although this is rarely needed.
On graphical terminals, you can enable the Modifier Bar mode, which
allows simulating the missing modifier keys by clicking a tool-bar
button. @xref{Tool Bars}.
@node Function Keys @node Function Keys
@subsection Rebinding Function Keys @subsection Rebinding Function Keys
@ -2965,9 +2969,19 @@ Emacs will set @code{user-emacs-directory} to the directory it decides
to use. This directory is subsequently used to look for your other to use. This directory is subsequently used to look for your other
user-specific Emacs files, such as @code{custom-file} (@pxref{Saving user-specific Emacs files, such as @code{custom-file} (@pxref{Saving
Customizations}), the saved desktop (@pxref{Saving Emacs Sessions}) and Customizations}), the saved desktop (@pxref{Saving Emacs Sessions}) and
others. The @code{--init-directory} command-line option (@pxref{Initial others. It is also used to compute the value of the
Options}) overrides the value of @code{user-emacs-directory} determined @code{native-comp-eln-load-path} (@pxref{Lisp Libraries}), which is
as side effect of the search for your user init file described above. where Emacs looks for natively-compiled Lisp code and where it deposits
the newly-compiled Lisp code produced by asynchronous compilation of
packages your init files and the subsequent Emacs session load. The
@code{--init-directory} command-line option (@pxref{Initial Options})
overrides the value of @code{user-emacs-directory} determined as side
effect of the search for your user init file described above.
Since @code{user-emacs-directory}, once determined by Emacs, is used by
the rest of the startup code to locate other files and directories, we
do not recommend changing its value in your init files, as that could
disrupt or break the correct startup of your Emacs sessions.
Although this is backward-compatible with older Emacs versions, modern Although this is backward-compatible with older Emacs versions, modern
POSIX platforms prefer putting your initialization files under POSIX platforms prefer putting your initialization files under

View file

@ -1811,6 +1811,21 @@ formats by setting each of the variables @code{eol-mnemonic-unix},
@code{eol-mnemonic-dos}, @code{eol-mnemonic-mac}, and @code{eol-mnemonic-dos}, @code{eol-mnemonic-mac}, and
@code{eol-mnemonic-undecided} to the strings you prefer. @code{eol-mnemonic-undecided} to the strings you prefer.
@vindex mode-line-compact
@vindex mode-line-collapse-minor-modes
Some modes put a lot of data in the mode line, pushing elements at the
end of the mode line off to the right. Emacs can ``compress'' the mode
line if the @code{mode-line-compact} variable is non-@code{nil} by
turning stretches of spaces into a single space. If this variable is
@code{long}, this is only done when the mode line is wider than the
currently selected window. (This computation is approximate, based on
the number of characters, and not their displayed width.) This variable
can be buffer-local to only compress mode-lines in certain buffers. To
further ``compress'' the mode line, you may customize the
@code{mode-line-collapse-minor-modes} option to a non-@code{nil} value,
and Emacs will hide some minor mode indicators on the mode line by
collapsing them into a single clickable button.
@node Text Display @node Text Display
@section How Text Is Displayed @section How Text Is Displayed
@cindex characters (in text) @cindex characters (in text)

View file

@ -1093,7 +1093,7 @@ type @kbd{M-x normal-mode} to re-read them.
Here is another example, with the time stamp inserted into Here is another example, with the time stamp inserted into
the last paragraph of an HTML document. the last paragraph of an HTML document.
Since this template is at the end of the document, not in the first Since this template is at the end of the document, not in the first
eight lines, @code{time-stamp-format} starts with @code{-10/} to tell eight lines, @code{time-stamp-pattern} starts with @code{-10/} to tell
@code{time-stamp} to look at the last 10 lines. @code{time-stamp} to look at the last 10 lines.
The @code{%%} asks for the default format The @code{%%} asks for the default format
(specified by @code{time-stamp-format}). (specified by @code{time-stamp-format}).
@ -2529,7 +2529,7 @@ select a group of images to copy somewhere else). The @kbd{m}
(@code{image-mode-mark-file}) command will mark the current file in (@code{image-mode-mark-file}) command will mark the current file in
any Dired buffer(s) that display the current file's directory. If no any Dired buffer(s) that display the current file's directory. If no
such buffer is open, the directory is opened in a new buffer. To such buffer is open, the directory is opened in a new buffer. To
unmark files, use the @kbd{u} (@code{image-mode-mark-file}) command. unmark files, use the @kbd{u} (@code{image-mode-unmark-file}) command.
Finally, if you just want to copy the current buffers file name to the Finally, if you just want to copy the current buffers file name to the
kill ring, you can use the @kbd{w} kill ring, you can use the @kbd{w}
(@code{image-mode-copy-file-name-as-kill}) command. (@code{image-mode-copy-file-name-as-kill}) command.

View file

@ -1346,15 +1346,18 @@ displayed by moving the mouse pointer to the top of the screen.
@cindex displaying modifier keys in the tool bar @cindex displaying modifier keys in the tool bar
@cindex mode, Modifier Bar @cindex mode, Modifier Bar
@cindex Modifier Bar @cindex Modifier Bar
Keyboards often lack one or more of the modifier keys that Emacs Keyboards often lack one or more of the modifier keys (@pxref{Modifier
might want to use, making it difficult or impossible to input key Keys}) that Emacs users might want to use, making it difficult or
sequences that contain them. Emacs can optionally display a list of impossible to input key sequences with these modifiers. For example,
buttons that act as substitutes for modifier keys within the tool bar; many keyboards lack the Hyper and Super modifiers, and smartphones
these buttons are also referred to as the ``modifier bar''. Clicking usually also lack Ctrl and Alt modifiers. Emacs can optionally display
an icon within the modifier bar will cause a modifier key to be a tool bar of buttons that can substitute the modifier keys; this
applied to the next keyboard event that is read. The modifier bar is additional tool bar is known as the @dfn{modifier bar}. Clicking a
displayed when the global minor mode @code{modifier-bar-mode} is button within the modifier bar will cause the modifier key shown on the
enabled; to do so, type @kbd{M-x modifier-bar-mode}. button to be applied to the next keyboard event that Emacs reads. The
modifier bar is displayed when the global minor mode
@code{modifier-bar-mode} is enabled; to do so, type @kbd{M-x
modifier-bar-mode}.
@node Tab Bars @node Tab Bars
@section Tab Bars @section Tab Bars

View file

@ -472,9 +472,9 @@ C-x C-k b 4
will bind the last keyboard macro to the key sequence @kbd{C-x C-k 4}. will bind the last keyboard macro to the key sequence @kbd{C-x C-k 4}.
@findex insert-kbd-macro @findex insert-kbd-macro
Once a macro has a command name, you can save its definition in a file. You can save a macro's definition in a file. Then it can be used in
Then it can be used in another editing session. First, visit the file another editing session. First, visit the file you want to save the
you want to save the definition in. Then use this command: definition in. Then use this command:
@example @example
M-x insert-kbd-macro @key{RET} @var{macroname} @key{RET} M-x insert-kbd-macro @key{RET} @var{macroname} @key{RET}
@ -494,6 +494,9 @@ additional Lisp code to record the keys (if any) that you have bound
to @var{macroname}, so that the macro will be reassigned the same keys to @var{macroname}, so that the macro will be reassigned the same keys
when you load the file. when you load the file.
If you do not give @code{insert-kbd-macro} a macro name, it will
insert Lisp code to restore the @code{last-kdb-macro}.
@node Edit Keyboard Macro @node Edit Keyboard Macro
@section Editing a Keyboard Macro @section Editing a Keyboard Macro

View file

@ -190,8 +190,8 @@ which it refers to as @dfn{back ends}:
@item @item
Git is a decentralized version control system originally invented by Git is a decentralized version control system originally invented by
Linus Torvalds to support development of Linux (his kernel). VC Linus Torvalds to support development of Linux (his kernel). VC
supports many common Git operations, but others, such as repository supports all the common Git operations, but notably, Git rebases other
syncing, must be done from the command line. than simply to edit a commit message must be done from the command line.
@cindex CVS @cindex CVS
@item @item
@ -235,8 +235,7 @@ everything you can do with RCS can be done through VC.
@cindex Mercurial @cindex Mercurial
@item @item
Mercurial (hg) is a decentralized version control system broadly Mercurial (hg) is a decentralized version control system broadly
resembling Git. VC supports most Mercurial commands, with the resembling Git. VC supports most Mercurial commands.
exception of repository sync operations.
@cindex bzr @cindex bzr
@cindex Bazaar @cindex Bazaar
@ -1783,20 +1782,18 @@ more programs. Files that belong to a project are typically stored in
a hierarchy of directories; the top-level directory of the hierarchy a hierarchy of directories; the top-level directory of the hierarchy
is known as the @dfn{project root}. is known as the @dfn{project root}.
@cindex project back-end @cindex project backend
Whether a given directory is a root of some project is determined by Whether a given directory is a root of some project is determined by
the project-specific infrastructure, known as @dfn{project back-end}. the project-specific infrastructure, known as @dfn{project backend}.
Emacs currently supports two such back-ends: VC-aware (@pxref{Version Emacs currently supports two such backends: VC-aware (@pxref{Version
Control}), whereby a VCS repository is considered a project; and EDE Control}), whereby a VCS repository is considered a project; and EDE
(@pxref{EDE}). This is expected to be extended in the future to (@pxref{EDE}). This is expected to be extended in the future to
support additional types of projects. support additional types of projects.
Which files do or don't belong to a project is also determined by Which files do or don't belong to a project is also determined by
the project back-end. For example, the VC-aware back-end doesn't the project backend. For example, the VC-aware backend doesn't
consider ``ignored'' files (@pxref{VC Ignore}) to be part of the consider ``ignored'' files (@pxref{VC Ignore}) to be part of the
project. Also, the VC-aware Project back-end considers ``untracked'' project. See its entry below for description and related options.
files by default. That behavior is controllable with the variable
@code{project-vc-include-untracked}.
@cindex current project name on mode line @cindex current project name on mode line
@defopt project-mode-line @defopt project-mode-line
@ -1811,6 +1808,7 @@ The default value is @code{nil}.
* Project Buffer Commands:: Commands for handling project buffers. * Project Buffer Commands:: Commands for handling project buffers.
* Switching Projects:: Switching between projects. * Switching Projects:: Switching between projects.
* Managing Projects:: Managing the project list file. * Managing Projects:: Managing the project list file.
* VC-Aware Project Backend:: Default project backend.
@end menu @end menu
@node Project File Commands @node Project File Commands
@ -2050,6 +2048,50 @@ matched against the project root, and the predicate should take the
project object as the only argument and return non-@code{nil} if the project object as the only argument and return non-@code{nil} if the
project should @emph{not} be saved to @code{project-list-file}. project should @emph{not} be saved to @code{project-list-file}.
@cindex VC-aware project backend
@cindex project backend, VC-aware
@node VC-Aware Project Backend
This backend is part of Emacs and is enabled by default. (Other
backends may need installation of add-on packages and their proper
configuration.)
It determines the contents of the project based on the VCS repository's
configuration (if any), excluding the ``ignored'' files from the output.
It has some performance optimizations for listing the files with some of
the popular VCS systems (currently Git and Mercurial).
@defopt project-vc-include-untracked
By default, files which are neither registered with nor ignored by the
VCS are considered part of the project. Customize this variable to nil
to change that.
@end defopt
@defopt project-vc-ignores
Using this variable you can add more ignore patterns to the project, to
exclude more files from the project's file listing. The value is a list
of glob strings. They can match both regular files and directories. To
anchor an entry to the project root, start it with @code{./}. To match
directories only, end it with @code{/}.
@end defopt
@defopt project-vc-name
This variable allows you to change the automatically detected name of
the project to a string of your choice. By default the name is the base
name of its root directory.
@end defopt
@defopt project-vc-extra-root-markers
This variable allows you to set up detection of non-VC projects in this
backend, and also to have some subdirectories detected as separate
projects. The value is a list.
Each element is either a base file name or a glob pattern for such.
Example values: @file{.dir-locals.el}, @file{package.json},
@file{requirements.txt}, @file{*.gemspec}.
@end defopt
@node Change Log @node Change Log
@section Change Logs @section Change Logs

View file

@ -2924,11 +2924,15 @@ can use @kbd{M-x desktop-read} to restore a previously-saved desktop
if the current Emacs session didn't load any desktop yet. if the current Emacs session didn't load any desktop yet.
@vindex desktop-restore-frames @vindex desktop-restore-frames
By default, the desktop tries to save and restore the frame and By default, the desktop tries to save and restore the frame and window
window configuration. To disable this, set configuration.@footnote{
@code{desktop-restore-frames} to @code{nil}. (See that variable's Except on Android, where this option defaults to @code{nil} because the
documentation for some related options that you can customize to window manager (@pxref{Android Windowing}) is too prohibitive, and
fine-tune this behavior.) doesn't allow restoring frame configurations.}
To disable or enable this, set @code{desktop-restore-frames} to
@code{nil} or any non-@code{nil} value respectively. (See that
variable's documentation for some related options that you can customize
to fine-tune this behavior.)
@vindex frameset-filter-alist @vindex frameset-filter-alist
When the desktop restores the frame and window configuration, it When the desktop restores the frame and window configuration, it
@ -2968,8 +2972,8 @@ invoking @kbd{M-x desktop-read} next. The @code{desktop-clear}
command kills all buffers except for internal ones, and clears the command kills all buffers except for internal ones, and clears the
global variables listed in @code{desktop-globals-to-clear}. If you global variables listed in @code{desktop-globals-to-clear}. If you
want it to preserve certain buffers, customize the variable want it to preserve certain buffers, customize the variable
@code{desktop-clear-preserve-buffers-regexp}, whose value is a regular @code{desktop-clear-preserve-buffers}, whose value is a list of regular
expression matching the names of buffers not to kill. expressions matching the names of buffers not to kill.
@vindex desktop-globals-to-save @vindex desktop-globals-to-save
If you want to save minibuffer history from one session to If you want to save minibuffer history from one session to

View file

@ -654,7 +654,13 @@ maintainer, you can use the command @code{package-report-bug} to
report a bug via Email. This report will include all the user options report a bug via Email. This report will include all the user options
that you have customized. If you have made a change you wish to share that you have customized. If you have made a change you wish to share
with the maintainers, first commit your changes then use the command with the maintainers, first commit your changes then use the command
@code{package-vc-prepare-patch} to share it. @xref{Preparing Patches}. @code{package-vc-prepare-patch} to share it.
@iftex
@xref{Preparing Patches,,,emacs-xtra, Specialized Emacs Features}.
@end iftex
@ifnottex
@xref{Preparing Patches}.
@end ifnottex
@findex package-vc-install-from-checkout @findex package-vc-install-from-checkout
@findex package-vc-rebuild @findex package-vc-rebuild

View file

@ -958,11 +958,11 @@ argument specifies the number of levels to go down.
@node Matching @node Matching
@subsection Matching Parentheses @subsection Matching Parentheses
@cindex matching parentheses @cindex matching, parentheses and other paired delimiters
@cindex parentheses, displaying matches @cindex parentheses, displaying matches
Emacs has a number of @dfn{parenthesis matching} features, which Emacs has a number of @dfn{parenthesis matching} features, which make
make it easy to see how and whether parentheses (or other delimiters) it easy to see how and whether parentheses (or other paired delimiters)
match up. match up.
Whenever you type a self-inserting character that is a closing Whenever you type a self-inserting character that is a closing
@ -1063,16 +1063,17 @@ nonblank line.
@findex electric-pair-mode @findex electric-pair-mode
Electric Pair mode, a global minor mode, provides a way to easily Electric Pair mode, a global minor mode, provides a way to easily
insert matching delimiters: parentheses, braces, brackets, etc. insert matching delimiters: parentheses, braces, brackets, etc.
Whenever you insert an opening delimiter, the matching closing Whenever you insert an opening delimiter, the matching closing delimiter
delimiter is automatically inserted as well, leaving point between the is automatically inserted as well, leaving point between the two.
two. Conversely, when you insert a closing delimiter over an existing However, if you insert a closing delimiter where one already exists
one, no insertion takes places, and that position is simply skipped (probably a mistake, since typing the opening delimiter inserted the
over. If the region is active (@pxref{Mark}), insertion of a closing one for you), Emacs simply moves point to after the closing
delimiter operates on the region: the characters in the region are delimiter, skipping the insertion. If the region is active
enclosed in a pair of matching delimiters, leaving point after the (@pxref{Mark}), insertion of a delimiter operates on the region: the
delimiter you typed. If you provide a prefix argument when inserting characters in the region are enclosed in a pair of matching delimiters,
a delimiter, the numeric value of that prefix argument specifies the leaving point after the delimiter you typed. If you provide a prefix
number of pairs to insert. argument when inserting a delimiter, the numeric value of that prefix
argument specifies the number of pairs to insert.
These variables control additional features of Electric Pair mode: These variables control additional features of Electric Pair mode:

View file

@ -341,7 +341,7 @@ down-casing.
@kindex M-s M-. @kindex M-s M-.
@findex isearch-forward-thing-at-point @findex isearch-forward-thing-at-point
To begin a new incremental search with the text near point yanked To begin a new incremental search with the text near point yanked
into the initial search string, type @kbd{M-s M-.} that runs the into the initial search string, type @kbd{M-s M-.}, which runs the
command @code{isearch-forward-thing-at-point}. If the region was command @code{isearch-forward-thing-at-point}. If the region was
active, then it yanks the text from the region into the search string. active, then it yanks the text from the region into the search string.
Otherwise, it tries to yank a URL, a symbol or an expression found Otherwise, it tries to yank a URL, a symbol or an expression found

View file

@ -312,7 +312,14 @@ If you expect to contribute patches on a regular basis, you can set
the user option @code{vc-default-patch-addressee} to the address(es) the user option @code{vc-default-patch-addressee} to the address(es)
you wish to use. This will be used as the default value when invoking you wish to use. This will be used as the default value when invoking
@code{vc-prepare-patch}. Project maintainers may consider setting @code{vc-prepare-patch}. Project maintainers may consider setting
this as a directory local variable (@pxref{Directory Variables}). this as a directory local variable
@iftex
(@pxref{Directory Variables,,Per-Directory Local Variables,
emacs, the Emacs Manual}).
@end iftex
@ifnottex
(@pxref{Directory Variables}).
@end ifnottex
@node Customizing VC @node Customizing VC
@subsection Customizing VC @subsection Customizing VC

View file

@ -940,21 +940,21 @@ same time, and then press and release @kbd{t}.)
Also, I often refer to one of Emacs's standard commands by listing the Also, I often refer to one of Emacs's standard commands by listing the
keys which you press to invoke the command and then giving the name of keys which you press to invoke the command and then giving the name of
the command in parentheses, like this: @kbd{M-C-\} the command in parentheses, like this: @kbd{C-M-\}
(@code{indent-region}). What this means is that the (@code{indent-region}). What this means is that the
@code{indent-region} command is customarily invoked by typing @code{indent-region} command is customarily invoked by typing
@kbd{M-C-\}. (You can, if you wish, change the keys that are typed to @kbd{C-M-\}. (You can, if you wish, change the keys that are typed to
invoke the command; this is called @dfn{rebinding}. @xref{Keymaps, , invoke the command; this is called @dfn{rebinding}. @xref{Keymaps, ,
Keymaps}.) The abbreviation @kbd{M-C-\} means that you type your Keymaps}.) The abbreviation @kbd{C-M-\} means that you type your
@key{META} key, @key{CTRL} key and @kbd{\} key all at the same time. @key{CTRL} key, @key{META} key, and @kbd{\} key all at the same time.
(On many modern keyboards the @key{META} key is labeled (On many modern keyboards the @key{META} key is labeled
@key{ALT}.) @key{ALT}.)
Sometimes a combination like this is called a keychord, since it is Sometimes a combination like this is called a keychord, since it is
similar to the way you play a chord on a piano. If your keyboard does similar to the way you play a chord on a piano. If your keyboard does
not have a @key{META} key, the @key{ESC} key prefix is used in place not have a @key{META} key, the @key{ESC} key prefix is used in place
of it. In this case, @kbd{M-C-\} means that you press and release your of it. In this case, @kbd{C-M-\} means that you press and release your
@key{ESC} key and then type the @key{CTRL} key and the @kbd{\} key at @key{ESC} key and then type the @key{CTRL} key and the @kbd{\} key at
the same time. But usually @kbd{M-C-\} means press the @key{CTRL} key the same time. But usually @kbd{C-M-\} means press the @key{CTRL} key
along with the key that is labeled @key{ALT} and, at the same time, along with the key that is labeled @key{ALT} and, at the same time,
press the @kbd{\} key. press the @kbd{\} key.
@ -962,7 +962,7 @@ In addition to typing a lone keychord, you can prefix what you type
with @kbd{C-u}, which is called the @dfn{universal argument}. The with @kbd{C-u}, which is called the @dfn{universal argument}. The
@kbd{C-u} keychord passes an argument to the subsequent command. @kbd{C-u} keychord passes an argument to the subsequent command.
Thus, to indent a region of plain text by 6 spaces, mark the region, Thus, to indent a region of plain text by 6 spaces, mark the region,
and then type @w{@kbd{C-u 6 M-C-\}}. (If you do not specify a number, and then type @w{@kbd{C-u 6 C-M-\}}. (If you do not specify a number,
Emacs either passes the number 4 to the command or otherwise runs the Emacs either passes the number 4 to the command or otherwise runs the
command differently than it would otherwise.) @xref{Arguments, , command differently than it would otherwise.) @xref{Arguments, ,
Numeric Arguments, emacs, The GNU Emacs Manual}. Numeric Arguments, emacs, The GNU Emacs Manual}.
@ -1258,7 +1258,7 @@ Interaction mode or Emacs Lisp mode, you have available to you several
commands to format the Lisp expression so it is easy to read. For commands to format the Lisp expression so it is easy to read. For
example, pressing the @key{TAB} key automatically indents the line the example, pressing the @key{TAB} key automatically indents the line the
cursor is on by the right amount. A command to properly indent the cursor is on by the right amount. A command to properly indent the
code in a region is customarily bound to @kbd{M-C-\}. Indentation is code in a region is customarily bound to @kbd{C-M-\}. Indentation is
designed so that you can see which elements of a list belong to which designed so that you can see which elements of a list belong to which
list---elements of a sub-list are indented more than the elements of list---elements of a sub-list are indented more than the elements of
the enclosing list. the enclosing list.

View file

@ -404,8 +404,10 @@ elapsed since the time the first message was emitted.
@defvar inhibit-message @defvar inhibit-message
When this variable is non-@code{nil}, @code{message} and related functions When this variable is non-@code{nil}, @code{message} and related functions
will not display any messages in the Echo Area. Echo-area messages will not display any messages in the Echo Area, and will also not clear
are still logged in the @file{*Messages*} buffer, though. previous echo-area messages when @code{message} is called with a
@code{nil} or an empty argument. Echo-area messages are still logged in
the @file{*Messages*} buffer, though.
@end defvar @end defvar
@defmac with-temp-message message &rest body @defmac with-temp-message message &rest body
@ -4122,6 +4124,14 @@ available, since it also checks whether the coding system for the text
terminal can encode the character (@pxref{Terminal I/O Encoding}). terminal can encode the character (@pxref{Terminal I/O Encoding}).
@end defun @end defun
@defun char-displayable-on-frame-p char frame
This function behaves like @code{char-displayable-p} does (relative to
@var{frame}), but in the graphical case, it does not perform the final
check of whether the underlying text terminal can encode the character.
It thus provides a displayability check for @var{char} more specific to
@var{frame}.
@end defun
@node Low-Level Font @node Low-Level Font
@subsection Low-Level Font Representation @subsection Low-Level Font Representation
@cindex font property @cindex font property
@ -5607,12 +5617,20 @@ instead of the text that has the display specification.
@item (slice @var{x} @var{y} @var{width} @var{height}) @item (slice @var{x} @var{y} @var{width} @var{height})
This specification together with @code{image} specifies a @dfn{slice} This specification together with @code{image} specifies a @dfn{slice}
(a partial area) of the image to display. The elements @var{y} and (a partial area) of the image to display. More precisely, the
@var{x} specify the top left corner of the slice, within the image; specification should have the following form:
@var{width} and @var{height} specify the width and height of the
slice. Integers are numbers of pixels. A floating-point number @lisp
in the range 0.0--1.0 stands for that fraction of the width or height ((slice @var{x} @var{y} @var{width} @var{height}) @var{image-desc})
of the entire image. @end lisp
@noindent
where @var{image-desc} is an image descriptor described above. The
elements @var{x} and @var{y} specify the top left corner of the slice,
within the image; @var{width} and @var{height} specify the width and
height of the slice. Integers are numbers of pixels. A floating-point
number in the range 0.0--1.0 stands for that fraction of the width or
height of the entire image.
@item ((margin nil) @var{string}) @item ((margin nil) @var{string})
A display specification of this form means to display @var{string} A display specification of this form means to display @var{string}

View file

@ -2839,8 +2839,11 @@ than deleted.
@end deffn @end deffn
The following function checks whether a frame can be safely deleted. It The following function checks whether a frame can be safely deleted. It
is useful to avoid that a subsequent call of @code{delete-frame} throws is useful for avoiding the situation whereby a subsequent call of
an error. @code{delete-frame} fails to delete its argument @var{frame} and/or
signals an error. To that end, your Lisp program should call
@code{delete-frame} only if the following function returns
non-@code{nil}.
@defun frame-deletable-p &optional frame @defun frame-deletable-p &optional frame
This function returns non-@code{nil} if the frame specified by This function returns non-@code{nil} if the frame specified by

View file

@ -1510,9 +1510,6 @@ You can thus get the full benefit of adaptive filling
(see the variable `adaptive-fill-mode'). (see the variable `adaptive-fill-mode').
\\@{text-mode-map@} \\@{text-mode-map@}
Turning on Text mode runs the normal hook `text-mode-hook'." Turning on Text mode runs the normal hook `text-mode-hook'."
@end group
@group
(setq-local text-mode-variant t)
(setq-local require-final-newline mode-require-final-newline)) (setq-local require-final-newline mode-require-final-newline))
@end group @end group
@end smallexample @end smallexample
@ -2152,17 +2149,6 @@ windows, you can say something like:
@end lisp @end lisp
@end defun @end defun
@vindex mode-line-compact
Some modes put a lot of data in the mode line, pushing elements at
the end of the mode line off to the right. Emacs can ``compress'' the
mode line if the @code{mode-line-compact} variable is non-@code{nil}
by turning stretches of spaces into a single space. If this variable
is @code{long}, this is only done when the mode line is wider than the
currently selected window. (This computation is approximate, based on
the number of characters, and not their displayed width.) This
variable can be buffer-local to only compress mode-lines in certain
buffers.
@node Mode Line Data @node Mode Line Data
@subsection The Data Structure of the Mode Line @subsection The Data Structure of the Mode Line
@cindex mode line construct @cindex mode line construct

View file

@ -1953,14 +1953,18 @@ This is a synonym for @samp{%H:%M:%S}.
This stands for the numeric day of week (1--7). Monday is day 1. This stands for the numeric day of week (1--7). Monday is day 1.
@item %U @item %U
This stands for the week of the year (01--52), assuming that weeks This stands for the week of the year (01--52), assuming that weeks
start on Sunday. start on Sunday. If January 1 is not a Sunday, the first partial week
is week zero.
@item %V @item %V
This stands for the week of the year according to ISO 8601. This stands for the week of the year according to ISO 8601. Note that,
unlike @samp{%U} and @samp{%W}, the week according to ISO 8601 does
@emph{not} roll over to 1 on January 1, but keeps its last number.
@item %w @item %w
This stands for the numeric day of week (0--6). Sunday is day 0. This stands for the numeric day of week (0--6). Sunday is day 0.
@item %W @item %W
This stands for the week of the year (01--52), assuming that weeks This stands for the week of the year (01--52), assuming that weeks start
start on Monday. on Monday. If January 1 is not a Monday, the first partial week is week
zero.
@item %x @item %x
This has a locale-specific meaning. In the default locale (named This has a locale-specific meaning. In the default locale (named
@samp{C}), it is equivalent to @samp{%D}. @samp{C}), it is equivalent to @samp{%D}.

View file

@ -1814,12 +1814,12 @@ ranges for each parser are correct before using parsers in a buffer, and
call @code{treesit-language-at} to figure out the language responsible call @code{treesit-language-at} to figure out the language responsible
for the text at some position. These two functions don't work by for the text at some position. These two functions don't work by
themselves; they need major modes to set @code{treesit-range-settings} themselves; they need major modes to set @code{treesit-range-settings}
and @code{treesit-language-at-point-function}, which do the actual work. and optionally @code{treesit-language-at-point-function}, which do the actual work.
These functions and variables are explained in more detail towards the These functions and variables are explained in more detail towards the
end of the section. end of the section.
In short, multi-language major modes should set In short, multi-language major modes should set
@code{treesit-primary-parser}, @code{treesit-range-settings}, and @code{treesit-primary-parser}, @code{treesit-range-settings}, and optionally
@code{treesit-language-at-point-function} before calling @code{treesit-language-at-point-function} before calling
@code{treesit-major-mode-setup}. @code{treesit-major-mode-setup}.
@ -1921,9 +1921,9 @@ This function returns the language of the text at buffer position
@var{pos}. Under the hood it calls @var{pos}. Under the hood it calls
@code{treesit-language-at-point-function} and returns its return @code{treesit-language-at-point-function} and returns its return
value. If @code{treesit-language-at-point-function} is @code{nil}, value. If @code{treesit-language-at-point-function} is @code{nil},
this function returns the language of the first parser in the returned this function returns the language of the deepest parser by embed level
value of @code{treesit-parser-list}. If there is no parser in the among parsers returned by @code{treesit-parsers-at}. If there is no
buffer, it returns @code{nil}. parser at that buffer position, it returns @code{nil}.
@end defun @end defun
@heading Supporting multiple languages in major modes @heading Supporting multiple languages in major modes
@ -2011,7 +2011,7 @@ directly translate into operations shown above.
@end group @end group
@group @group
;; Major modes with multiple languages should always set ;; Major modes with multiple languages can optionally set
;; `treesit-language-at-point-function' (which see). ;; `treesit-language-at-point-function' (which see).
(setq treesit-language-at-point-function (setq treesit-language-at-point-function
(lambda (pos) (lambda (pos)
@ -2094,17 +2094,45 @@ language of the buffer text at @var{pos}. This variable is used by
@code{treesit-language-at}. @code{treesit-language-at}.
@end defvar @end defvar
@defun treesit-local-parsers-at &optional pos language @defun treesit-parsers-at &optional pos language with-host only
This function returns all parsers at @var{pos} in the current buffer.
@var{pos} defaults to point. The returned parsers are sorted by the
decreasing embed level.
If @var{language} is non-@code{nil}, return parsers only for that
language.
If @var{with-host} is non-@code{nil}, return a list of
@w{@code{(@var{parser} . @var{host-parser})}} where @var{host-parser}
is the host parser which created the @var{parser}.
If @var{only} is non-@code{nil}, return all parsers including the
primary parser.
The argument @var{only} can be a list of symbols that specify what
parsers to include in the return value.
If @var{only} contains the symbol @code{local}, include local parsers.
Local parsers are those which only parse a limited region marked by an
overlay with a non-@code{nil} @code{treesit-parser-local-p} property.
If @var{only} contains the symbol @code{global}, include non-local parsers
excluding the primary parser.
If @var{only} contains the symbol `primary', include the primary parser.
@end defun
@defun treesit-local-parsers-at &optional pos language with-host
This function returns all the local parsers at @var{pos} in the This function returns all the local parsers at @var{pos} in the
current buffer. @var{pos} defaults to point. current buffer. @var{pos} defaults to point.
Local parsers are those which only parse a limited region marked by an Local parsers are those which only parse a limited region marked by an
overlay with a non-@code{nil} @code{treesit-parser} property. If overlay with a non-@code{nil} @code{treesit-parser-local-p} property.
@var{language} is non-@code{nil}, only return parsers for that If @var{language} is non-@code{nil}, only return parsers for that
language. language.
@end defun @end defun
@defun treesit-local-parsers-on &optional beg end language @defun treesit-local-parsers-on &optional beg end language with-host
This function is the same as @code{treesit-local-parsers-at}, but it This function is the same as @code{treesit-local-parsers-at}, but it
returns the local parsers in the range between @var{beg} and @var{end} returns the local parsers in the range between @var{beg} and @var{end}
instead of at point. instead of at point.

View file

@ -1932,7 +1932,7 @@ they default to the whole buffer.
This function adjusts the indentation at the beginning of the current This function adjusts the indentation at the beginning of the current
line to the value specified by the variable @code{left-margin}. (That line to the value specified by the variable @code{left-margin}. (That
may involve either inserting or deleting whitespace.) This function may involve either inserting or deleting whitespace.) This function
is value of @code{indent-line-function} in Paragraph-Indent Text mode. is the value of @code{indent-line-function} in Paragraph-Indent Text mode.
@end defun @end defun
@defopt left-margin @defopt left-margin
@ -5366,11 +5366,17 @@ available in this Emacs session.
When SQLite support is available, the following functions can be used. When SQLite support is available, the following functions can be used.
@cindex database object @cindex database object
@defun sqlite-open &optional file @defun sqlite-open &optional file readonly disable-uri
This function opens @var{file} as an SQLite database file. If This function opens @var{file} as an SQLite database file. If
@var{file} doesn't exist, a new database will be created and stored in @var{file} doesn't exist, a new database will be created and stored in
that file. If @var{file} is omitted or @code{nil}, a new in-memory that file. If @var{file} is omitted or @code{nil}, a new in-memory
database is created instead. database is created instead. Second optional argument @var{readonly},
if non-@code{nil}, means open the database only for reading; the
database must already exist in that case. By default, @var{file} can be
a @file{file://} URI as well as a file name; in the unusual case that
you have a local file whose name begins with @file{file:}, specify a
non-@code{nil} value for the third optional argument @var{disable-uri}
to disable the automatic recognition and processing of URIs.
The return value is a @dfn{database object} that can be used as the The return value is a @dfn{database object} that can be used as the
argument to most of the subsequent functions described below. argument to most of the subsequent functions described below.

View file

@ -73,18 +73,13 @@ not meant to be used by other packages.
Occasionally, for a command name intended for users to use, it is more Occasionally, for a command name intended for users to use, it is more
convenient if some words come before the package's name prefix. For convenient if some words come before the package's name prefix. For
example, it is our convention to have commands that list objects named example, it is our convention to have commands that list objects named
as @samp{list-@var{something}}, e.g., a package called @samp{frob} as @samp{list-@var{something}}, e.g., a package called @samp{frob} could
could have a command @samp{list-frobs}, when its other global symbols have a command @samp{list-frobs}, when its other global symbols begin
begin with @samp{frob-}. Also, constructs that define functions, with @samp{frob-}. Also, constructs that define functions, variables,
variables, etc., work better if they start with @samp{define-}, so put etc., may work better if they start with @samp{define-}, so it's okay to
the name prefix later on in the name. put the name prefix later on in the name. Outside of these
well-established cases, however, err on the side of prepending your name
This recommendation applies even to names for traditional Lisp prefix.
primitives that are not primitives in Emacs Lisp---such as
@code{copy-list}. Believe it or not, there is more than one plausible
way to define @code{copy-list}. Play it safe; append your name prefix
to produce a name like @code{foo-copy-list} or @code{mylib-copy-list}
instead.
If you write a function that you think ought to be added to Emacs under If you write a function that you think ought to be added to Emacs under
a certain name, such as @code{twiddle-files}, don't call it by that name a certain name, such as @code{twiddle-files}, don't call it by that name

View file

@ -2256,7 +2256,7 @@ unless stated otherwise.
counterclockwise. counterclockwise.
@cindex rotate window layout @cindex rotate window layout
@deffn Command rotate-window-layout-clockwise &optional window @deffn Command window-layout-rotate-clockwise &optional window
This command rotates the window layout clockwise by 90 degrees. Imagine This command rotates the window layout clockwise by 90 degrees. Imagine
a layout with three live windows @var{A}, @var{B} and @var{C} as a layout with three live windows @var{A}, @var{B} and @var{C} as
depicted on the left below. Then this command will produce the layout depicted on the left below. Then this command will produce the layout
@ -2276,8 +2276,8 @@ on the right.
@end smallexample @end smallexample
@end deffn @end deffn
@deffn Command rotate-window-layout-counterclockwise &optional window @deffn Command window-layout-rotate-anticlockwise &optional window
This is like @code{rotate-window-layout-clockwise} but rotates the This is like @code{window-layout-rotate-clockwise} but rotates the
layout in the opposite direction as demonstrated in the example below. layout in the opposite direction as demonstrated in the example below.
@smallexample @smallexample
@ -2298,7 +2298,7 @@ The next two commands @sc{flip} the window layout---rotate it around an
imaginary horizontal or vertical axis. imaginary horizontal or vertical axis.
@cindex flip window layout @cindex flip window layout
@deffn Command flip-window-layout-vertically &optional window @deffn Command window-layout-flip-topdown &optional window
This command flips windows such that windows on the bottom become This command flips windows such that windows on the bottom become
windows on the top and vice-versa as in the example below. windows on the top and vice-versa as in the example below.
@ -2316,7 +2316,7 @@ windows on the top and vice-versa as in the example below.
@end smallexample @end smallexample
@end deffn @end deffn
@deffn Command flip-window-layout-horizontally &optional window @deffn Command window-layout-flip-leftright &optional window
This command rearranges window in a way that the windows on the right This command rearranges window in a way that the windows on the right
become the window on the left, and vice-versa. become the window on the left, and vice-versa.
@ -2338,7 +2338,7 @@ The next command can be used for @sc{transposing} windows---changing
horizontal splits to vertical ones and vice-versa. horizontal splits to vertical ones and vice-versa.
@cindex transposing windows @cindex transposing windows
@deffn Command transpose-window-layout &optional window @deffn Command window-layout-transpose &optional window
This command reorganizes windows such that every horizontal split This command reorganizes windows such that every horizontal split
becomes a vertical split and vice versa. becomes a vertical split and vice versa.

View file

@ -353,6 +353,7 @@ not bundled with Emacs. @xref{Other useful ports}.
@section What is my init file? @section What is my init file?
@cindex .emacs @cindex .emacs
@cindex init file @cindex init file
@cindex early init file
When Emacs starts up, it attempts to load and execute the contents of When Emacs starts up, it attempts to load and execute the contents of
a file commonly called @file{.emacs} (though it may have other names, a file commonly called @file{.emacs} (though it may have other names,
@ -362,22 +363,31 @@ code to your .emacs, or you can use the Customization interface
accessible from the @emph{Options} menu. If the file does not exist, accessible from the @emph{Options} menu. If the file does not exist,
Emacs will start with the default settings. Emacs will start with the default settings.
In addition, Emacs 27 and later attempts to load and execute the
contents of the @file{early-init.el} file. As its name suggests, this
file, if it exists, is loaded and executed early on during the Emacs
startup sequence, before @code{.emacs}, and is intended to contain the
few initializations which must be performed before @file{.emacs} is
looked up and loaded.
@node Location of init file @node Location of init file
@section Where do I put my init file? @section Where do I put my init file?
@cindex HOME directory @cindex HOME directory
@cindex .emacs.d @cindex .emacs.d
@cindex _emacs @cindex _emacs
@cindex init.el @cindex init.el
@cindex early-init.el
@cindex registry, setting the HOME directory in @cindex registry, setting the HOME directory in
On Windows, the @file{.emacs} file may be called @file{_emacs} for On Windows, the @file{.emacs} init file may be called @file{_emacs} for
backward compatibility with DOS and FAT filesystems where filenames backward compatibility with DOS and FAT filesystems where filenames
could not start with a dot. Some users prefer to continue using such could not start with a dot. Some users prefer to continue using such
a name due to historical problems various Windows tools had in the a name due to historical problems various Windows tools had in the
past with file names that begin with a dot. The init file may also be past with file names that begin with a dot. The init file may also be
called @file{.emacs.d/init.el}. Many of the other files that are called @file{.emacs.d/init.el}. The @file{early-init.el} file and many
created by Lisp packages are stored in the @file{.emacs.d} directory of the other files that are created by Lisp packages are stored in the
too, which keeps all your Emacs related files in one place. @file{.emacs.d} directory too, which keeps all your Emacs related files
in one place.
All the files mentioned above should go in your @env{HOME} directory. All the files mentioned above should go in your @env{HOME} directory.
The @env{HOME} directory is determined by following the steps below: The @env{HOME} directory is determined by following the steps below:
@ -2157,7 +2167,7 @@ MSYS2 is an independent rewrite of MSYS, based on modern Cygwin and
MinGW-w64 with the aim of better interoperability with native Windows MinGW-w64 with the aim of better interoperability with native Windows
software. It plays the same role MSYS does in MinGW. Being a software. It plays the same role MSYS does in MinGW. Being a
distribution, MSYS2 provides tools to build software as well as more distribution, MSYS2 provides tools to build software as well as more
than 2.600 precompiled packages ready for use. than 2600 precompiled packages ready for use.
@node EZWinPorts @node EZWinPorts
@section EZWinPorts @section EZWinPorts

View file

@ -134,11 +134,11 @@ package @file{pp.el}):
;; (pp-to-string '('a 'b)) ; same as above ;; (pp-to-string '('a 'b)) ; same as above
@end lisp @end lisp
The code contained in these comments can be evaluated from time to The Lisp forms contained in these comments can be evaluated from time to
time to compare the output with the expected output. ERT formalizes time, e.g. with @kbd{C-x C-e}, to compare the output with the expected
this and introduces a common convention, which simplifies Emacs output. ERT formalizes this and introduces a common convention, which
development, since programmers no longer have to manually find and simplifies Emacs development, since programmers no longer have to
evaluate such comments. manually find and evaluate such comments.
An ERT test definition equivalent to the above comments is this: An ERT test definition equivalent to the above comments is this:

View file

@ -62,7 +62,7 @@ To learn about using Flymake, @pxref{Using Flymake}.
When the Emacs LSP support mode Eglot is enabled, Flymake will use that When the Emacs LSP support mode Eglot is enabled, Flymake will use that
as an additional back-end. @xref{Eglot Features,,, eglot, Eglot: The as an additional back-end. @xref{Eglot Features,,, eglot, Eglot: The
Emacs LSP Client}. Flymake is also designed to be easily extended to Emacs LSP Client}. Flymake is also designed to be easily extended to
support new backends via an Elisp interface. @xref{Extending Flymake}. support new backends via an Elisp interface. @xref{Flymake API}.
@ifnottex @ifnottex
@insertcopying @insertcopying
@ -70,7 +70,7 @@ support new backends via an Elisp interface. @xref{Extending Flymake}.
@menu @menu
* Using Flymake:: * Using Flymake::
* Extending Flymake:: * Flymake API::
* The legacy Proc backend:: * The legacy Proc backend::
* GNU Free Documentation License:: * GNU Free Documentation License::
* Index:: * Index::
@ -178,6 +178,10 @@ listing includes the type of the diagnostic, its line and column in
the file, as well as the diagnostic message. You may sort the listing the file, as well as the diagnostic message. You may sort the listing
by each of these columns. by each of these columns.
When invoked on a diagnostic (either via the keyboard or a mouse click)
the command @code{flymake-show-buffer-diagnostics} attempts to reveal
said diagnostic in the listing.
@node Mode line status @node Mode line status
@section Mode line status @section Mode line status
@cindex flymake mode line @cindex flymake mode line
@ -210,7 +214,7 @@ investigate and remedy the situation (@pxref{Troubleshooting}).
@item @code{?} @item @code{?}
@tab There are no applicable Flymake backends for this buffer, thus Flymake @tab There are no applicable Flymake backends for this buffer, thus Flymake
cannot annotate it. To fix this, a user may look to extending Flymake cannot annotate it. To fix this, a user may look to extending Flymake
and add a new backend (@pxref{Extending Flymake}). and add a new backend (@pxref{Flymake API}).
@end multitable @end multitable
@ -313,6 +317,9 @@ The indicator type which Flymake should use to indicate lines with
errors or warnings. errors or warnings.
Depending on your preference, this can either use @code{fringes} or Depending on your preference, this can either use @code{fringes} or
@code{margins} for indicating errors. @code{margins} for indicating errors.
If set to @code{fringes} (the default), it will automatically fall back
to using margins in windows or frames without fringes, such as text
terminals.
@item flymake-error-bitmap @item flymake-error-bitmap
A bitmap used in the fringe to mark lines for which an error has A bitmap used in the fringe to mark lines for which an error has
@ -344,9 +351,14 @@ If non-@code{nil}, moving to errors with @code{flymake-goto-next-error} and
@item flymake-show-diagnostics-at-end-of-line @item flymake-show-diagnostics-at-end-of-line
If non-@code{nil}, show summarized descriptions of diagnostics at the If non-@code{nil}, show summarized descriptions of diagnostics at the
end of the line. Depending on your preference, this can either be end of the line. Depending on your preference, this can either be
distracting and easily confused with actual code, or a significant distracting and easily confused with actual code, or a significant early
early aid that relieves you from moving around or reaching for the aid that relieves you from moving around or reaching for the mouse to
mouse to consult an error message. consult an error message. This value may also be set to @code{fancy},
which will attempt to layout diagnostics below the affected line using
unicode graphics to point to diagnostic locus.
@item flymake-diagnostic-format-alist
Control which parts of a diagnostic to show in various situations.
@item flymake-error-eol @item flymake-error-eol
A custom face for summarizing diagnostic error messages. A custom face for summarizing diagnostic error messages.
@ -358,19 +370,23 @@ A custom face for summarizing diagnostic warning messages.
A custom face for summarizing diagnostic notes. A custom face for summarizing diagnostic notes.
@end vtable @end vtable
@node Extending Flymake @node Flymake API, The legacy Proc backend, Using Flymake, Top
@chapter Extending Flymake @chapter Flymake API
@cindex extending flymake @cindex extending flymake
Flymake can primarily be extended in one of two ways: Flymake's API supports the following use cases:
@enumerate @enumerate
@item @item
By changing the look and feel of the annotations produced by the Changing the look and feel of the annotations produced by the
different backends. @xref{Flymake error types}. different backends. @xref{Flymake error types}.
@item @item
By adding a new buffer-checking backend. @xref{Backend functions}. Adding a new buffer-checking backend. @xref{Backend functions}.
@item
Writing extension to and process Flymake's output. @xref{Inspecting
diagnostics}.
@end enumerate @end enumerate
The following sections discuss each approach in detail. The following sections discuss each approach in detail.
@ -378,6 +394,7 @@ The following sections discuss each approach in detail.
@menu @menu
* Flymake error types:: * Flymake error types::
* Backend functions:: * Backend functions::
* Inspecting diagnostics::
@end menu @end menu
@node Flymake error types @node Flymake error types
@ -670,37 +687,19 @@ reports targeting other parts of the buffer remain valid.
Before delivering them to Flymake, backends create diagnostic objects Before delivering them to Flymake, backends create diagnostic objects
by calling the function @code{flymake-make-diagnostic}. by calling the function @code{flymake-make-diagnostic}.
@deffn Function flymake-make-diagnostic locus beg end type text &optional data @deffn Function flymake-make-diagnostic locus beg end type info &optional data
Make a Flymake diagnostic for the region of text in @var{locus}'s Make a Flymake diagnostic for the region of text in @var{locus}'s
delimited by @var{beg} and @var{end}. @var{type} is a diagnostic delimited by @var{beg} and @var{end}. @var{type} is a diagnostic symbol
symbol (@pxref{Flymake error types}), and @var{text} is a description (@pxref{Flymake error types}). @var{text} can be a string or a list
of the problem detected in this region. Most commonly @var{locus} is (@var{origin} @var{code} @var{message}) appropriately categorizing and
the buffer object designating for the current buffer being describing the diagnostic. Most commonly, @var{locus} is the buffer
syntax-checked. However, it may be a string naming a file relative object designating for the current buffer being syntax-checked.
to the current working directory. @xref{Foreign and list-only However, it may be a string naming a file relative to the current
diagnostics}, for when this may be useful. Depending on the type of working directory. @xref{Foreign and list-only diagnostics}, for when
@var{locus}, @var{beg} and @var{end} are both either buffer positions this may be useful. Depending on the type of @var{locus}, @var{beg} and
or conses (@var{line} . @var{col}) which specify the line and column @var{end} are both either buffer positions or conses (@var{line}
of the diagnostic's start and end positions, respectively. . @var{col}) which specify the line and column of the diagnostic's start
@end deffn and end positions, respectively.
@cindex access diagnostic object
These objects' properties can be accessed with the functions
@code{flymake-diagnostic-backend}, @code{flymake-diagnostic-buffer},
@code{flymake-diagnostic-text}, @code{flymake-diagnostic-beg},
@code{flymake-diagnostic-end}, @code{flymake-diagnostic-type} and
@code{flymake-diagnostic-data}.
Additionally, the function @code{flymake-diagnostics} will collect
such objects in the region you specify.
@cindex collect diagnostic objects
@deffn Function flymake-diagnostics beg end
Get a list of Flymake diagnostics in the region determined by
@var{beg} and @var{end}. If neither @var{beg} or @var{end} is
supplied, use the whole buffer, otherwise if @var{beg} is
non-@code{nil} and @var{end} is @code{nil}, consider only diagnostics
at @var{beg}.
@end deffn @end deffn
@cindex buffer position from line and column number @cindex buffer position from line and column number
@ -859,7 +858,7 @@ Binding,,, elisp, The Emacs Lisp Reference Manual}) to be active.
;; ;;
(cl-loop (cl-loop
while (search-forward-regexp while (search-forward-regexp
"^\\(?:.*.rb\\|-\\):\\([0-9]+\\): \\(.*\\)$" "^\\(?:.*\\.rb\\|-\\):\\([0-9]+\\): \\(.*\\)$"
nil t) nil t)
for msg = (match-string 2) for msg = (match-string 2)
for (beg . end) = (flymake-diag-region for (beg . end) = (flymake-diag-region
@ -897,6 +896,32 @@ Binding,,, elisp, The Emacs Lisp Reference Manual}) to be active.
@end group @end group
@end example @end example
@node Inspecting diagnostics
@section Inspecting diagnostics
When Flymake has called on the backend and collected its diagnostics, it
will annotate the buffer with it. After this happens, Elisp programs
may call @code{flymake-diagnostics} to collect such objects in a
specified region.
@cindex collect diagnostic objects
@deffn Function flymake-diagnostics beg end
Get a list of Flymake diagnostics in the region determined by
@var{beg} and @var{end}. If neither @var{beg} or @var{end} is
supplied, use the whole buffer, otherwise if @var{beg} is
non-@code{nil} and @var{end} is @code{nil}, consider only diagnostics
at @var{beg}.
@end deffn
@cindex access diagnostic object
A diagnostic object's properties can be accessed with the functions
@code{flymake-diagnostic-backend}, @code{flymake-diagnostic-buffer},
@code{flymake-diagnostic-origin}, @code{flymake-diagnostic-code}
@code{flymake-diagnostic-message}, @code{flymake-diagnostic-beg},
@code{flymake-diagnostic-end}, @code{flymake-diagnostic-type} and
@code{flymake-diagnostic-data}. @code{flymake-diagnostic-text} will
compose the diagnostic's origin, code and message in a single string.
@node The legacy Proc backend @node The legacy Proc backend
@chapter The legacy ``Proc'' backend @chapter The legacy ``Proc'' backend
@cindex legacy proc backend @cindex legacy proc backend

View file

@ -4,9 +4,9 @@
#+language: en #+language: en
#+options: ':t toc:nil author:t email:t num:t #+options: ':t toc:nil author:t email:t num:t
#+startup: content #+startup: content
#+macro: stable-version 4.6.0 #+macro: stable-version 4.7.0
#+macro: release-date 2024-10-27 #+macro: release-date 2025-04-17
#+macro: development-version 4.7.0-dev #+macro: development-version 4.8.0-dev
#+macro: file @@texinfo:@file{@@$1@@texinfo:}@@ #+macro: file @@texinfo:@file{@@$1@@texinfo:}@@
#+macro: space @@texinfo:@: @@ #+macro: space @@texinfo:@: @@
#+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@ #+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@
@ -88,7 +88,7 @@ The Modus themes consist of eight themes, divided into four subgroups.
are variants of the two main themes. They slightly tone down the are variants of the two main themes. They slightly tone down the
intensity of the background and provide a bit more color variety. intensity of the background and provide a bit more color variety.
~modus-operandi-tinted~ has a set of base tones that are shades of ~modus-operandi-tinted~ has a set of base tones that are shades of
light ocher (earthly colors), while ~modus-vivendi-tinted~ gives a light ochre (earthly colors), while ~modus-vivendi-tinted~ gives a
night sky impression. night sky impression.
- Deuteranopia themes :: ~modus-operandi-deuteranopia~ and its - Deuteranopia themes :: ~modus-operandi-deuteranopia~ and its
@ -1309,37 +1309,32 @@ Examples demonstrating how to use the aforementioned:
#+findex: modus-themes-list-colors #+findex: modus-themes-list-colors
The command ~modus-themes-list-colors~ uses minibuffer completion to The command ~modus-themes-list-colors~ uses minibuffer completion to
select an item from the Modus themes and then produces a buffer with select an item from the Modus themes and then produces a buffer with
previews of its color palette entries. The buffer has a naming scheme previews of all of its color palette entries.
that reflects the given choice, like =modus-operandi-list-colors= for
the ~modus-operandi~ theme.
#+findex: modus-themes-list-colors-current #+findex: modus-themes-list-colors-current
The command ~modus-themes-list-colors-current~ skips the minibuffer The command ~modus-themes-list-colors-current~ skips the minibuffer
selection process and just produces a preview for the current Modus selection process to produce a preview for the current Modus theme.
theme.
When called with a prefix argument (=C-u= with the default key When called with a prefix argument (=C-u= with the default key
bindings), these commands will show a preview of the palette's bindings), these commands will show a preview of the palette's
semantic color mappings instead of the named colors. In this context, semantic color mappings instead of the full palette ([[#h:34c7a691-19bb-4037-8d2f-67a07edab150][Option for palette overrides]]).
"named colors" are entries that associate a symbol to a string color
value, such as =(blue-warmer "#354fcf")=. Whereas "semantic color
mappings" associate a named color to a symbol, like =(string
blue-warmer)=, thus making the theme render all string constructs in
the =blue-warmer= color value ([[#h:34c7a691-19bb-4037-8d2f-67a07edab150][Option for palette overrides]]).
#+findex: modus-themes-preview-colors #+findex: modus-themes-preview-colors
#+findex: modus-themes-preview-colors-current #+findex: modus-themes-preview-colors-current
Aliases for those commands are ~modus-themes-preview-colors~ and Aliases for these commands are ~modus-themes-preview-colors~ and
~modus-themes-preview-colors-current~. ~modus-themes-preview-colors-current~.
Each row shows a foreground and background coloration using the Each row includes a foreground and background rendition of the given
underlying value it references. For example a line with =#a60000= (a color value. For example a line with =#a60000= (a shade of red) will
shade of red) will show red text followed by a stripe with that same show a column with a red background combined with a suitable
color as a backdrop. foreground followed by another column with a red foreground against
the current theme's background. The intent is to illustrate which
values are suitable as a background or foreground.
The name of the buffer describes the given Modus theme and what the The name of the buffer describes the given Modus theme and what the
contents are, such as =*modus-operandi-list-colors*= for named colors contents are, such as =*modus-operandi-list-all*= for the entirety of
and ==*modus-operandi-list-mappings*= for the semantic color mappings. the palette (named colors as well as semantic color mappings) and
==*modus-operandi-list-mappings*= for the mappings only.
* Use colors from the Modus themes palette * Use colors from the Modus themes palette
:PROPERTIES: :PROPERTIES:
@ -1361,7 +1356,7 @@ value in some other application.
:END: :END:
#+findex: modus-themes-get-color-value #+findex: modus-themes-get-color-value
The function ~modus-themes-get-color-value~ can be called from Lisp to The fuction ~modus-themes-get-color-value~ can be called from Lisp to
return the value of a color from the active Modus theme palette. It return the value of a color from the active Modus theme palette. It
takea a =COLOR= argument and an optional =OVERRIDES=. It also accepts takea a =COLOR= argument and an optional =OVERRIDES=. It also accepts
a third =THEME= argument, to get the color from the given theme. a third =THEME= argument, to get the color from the given theme.
@ -2367,7 +2362,7 @@ until version 4.3.0.
;; was the default in versions of the Modus themes before 4.4.0 ;; was the default in versions of the Modus themes before 4.4.0
(setq modus-themes-common-palette-overrides (setq modus-themes-common-palette-overrides
'((bg-prose-block-contents unspecified) '((bg-prose-block-contents unspecified)
(bg-prose-block-delimiter unspecified) (bg-prose-block-delimiter unspeficied)
(fg-prose-block-delimiter fg-dim))) (fg-prose-block-delimiter fg-dim)))
#+end_src #+end_src
@ -2941,7 +2936,7 @@ Reload the theme for changes to take effect.
:CUSTOM_ID: h:a5140c9c-18b2-45db-8021-38d0b5074116 :CUSTOM_ID: h:a5140c9c-18b2-45db-8021-38d0b5074116
:END: :END:
By default, the background of the ~region~ face extends from the By the default, the background of the ~region~ face extends from the
end of the line to the edge of the window. To limit it to the end of end of the line to the edge of the window. To limit it to the end of
the line, we need to override the face's =:extend= attribute. Adding the line, we need to override the face's =:extend= attribute. Adding
this to the Emacs configuration file will suffice: this to the Emacs configuration file will suffice:
@ -3365,7 +3360,7 @@ specification of that variable looks like this:
With the exception of ~org-verbatim~ and ~org-code~ faces, everything else With the exception of ~org-verbatim~ and ~org-code~ faces, everything else
uses the corresponding type of emphasis: a bold typographic weight, or uses the corresponding type of emphasis: a bold typographic weight, or
italicized, underlined, and struck through text. italicised, underlined, and struck through text.
The best way for users to add some extra attributes, such as a The best way for users to add some extra attributes, such as a
foreground color, is to define their own faces and assign them to the foreground color, is to define their own faces and assign them to the
@ -3985,13 +3980,13 @@ styles to use. The following is but a basic attempt to get started.
(modus-themes-with-colors (modus-themes-with-colors
(custom-set-faces (custom-set-faces
;; FIXME: What is a "region cursor" and should it differ from the position highlights below? ;; FIXME: What is a "region cursor" and should it differ from the position highlights below?
`(meow-region-cursor-1 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-0))) `(meow-region-cursor-1 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))
`(meow-region-cursor-2 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-1))) `(meow-region-cursor-2 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))
`(meow-region-cursor-3 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-2))) `(meow-region-cursor-3 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))
`(meow-position-highlight-number-1 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-0))) `(meow-position-highlight-number-1 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))
`(meow-position-highlight-number-2 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-1))) `(meow-position-highlight-number-2 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))
`(meow-position-highlight-number-3 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-2)))))) `(meow-position-highlight-number-3 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))))))
(add-hook 'enable-theme-functions #'my-modus-themes-custom-faces) (add-hook 'enable-theme-functions #'my-modus-themes-custom-faces)
#+end_src #+end_src
@ -4049,45 +4044,6 @@ the theme level. Users can try this instead:
[[#h:d87673fe-2ce1-4c80-a4b8-be36ca9f2d24][Using a hook at the post-load-theme phase]]. [[#h:d87673fe-2ce1-4c80-a4b8-be36ca9f2d24][Using a hook at the post-load-theme phase]].
** DIY Add support for howm
:PROPERTIES:
:CUSTOM_ID: h:7ea8fa66-1cd8-47b0-92b4-9998a3068f85
:END:
The ~howm~ package is a note-taking solution for Emacs. Users can add
support for its faces with something like the following.
#+begin_src emacs-lisp
(defun my-modus-themes-custom-faces (&rest _)
(modus-themes-with-colors
(custom-set-faces
`(action-lock-face ((,c :inherit button)))
`(howm-mode-keyword-face (( )))
`(howm-mode-ref-face ((,c :inherit link)))
`(howm-mode-title-face ((,c :inherit modus-themes-heading-0)))
`(howm-mode-wiki-face ((,c :inherit link)))
`(howm-reminder-deadline-face ((,c :foreground ,date-deadline)))
`(howm-reminder-late-deadline-face ((,c :inherit bold :foreground ,date-deadline)))
`(howm-reminder-defer-face ((,c :foreground ,date-scheduled)))
`(howm-reminder-scheduled-face ((,c :foreground ,date-scheduled)))
`(howm-reminder-done-face ((,c :foreground ,prose-done)))
`(howm-reminder-todo-face ((,c :foreground ,prose-todo)))
`(howm-reminder-normal-face ((,c :foreground ,date-common)))
`(howm-reminder-today-face ((,c :inherit bold :foreground ,date-common)))
`(howm-reminder-tomorrow-face ((,c :inherit bold :foreground ,date-scheduled)))
`(howm-simulate-todo-mode-line-face ((,c :inherit bold)))
`(howm-view-empty-face (( )))
`(howm-view-hilit-face ((,c :inherit match)))
`(howm-view-name-face ((,c :inherit bold)))
`(iigrep-counts-face1 ((,c :foreground ,rainbow-1)))
`(iigrep-counts-face2 ((,c :foreground ,rainbow-2)))
`(iigrep-counts-face3 ((,c :foreground ,rainbow-3)))
`(iigrep-counts-face4 ((,c :foreground ,rainbow-4)))
`(iigrep-counts-face5 ((,c :foreground ,rainbow-5))))))
(add-hook 'enable-theme-functions #'my-modus-themes-custom-faces)
#+end_src
** DIY Use a hook at the post-load-theme phase ** DIY Use a hook at the post-load-theme phase
:PROPERTIES: :PROPERTIES:
:CUSTOM_ID: h:d87673fe-2ce1-4c80-a4b8-be36ca9f2d24 :CUSTOM_ID: h:d87673fe-2ce1-4c80-a4b8-be36ca9f2d24
@ -4207,6 +4163,7 @@ project. The idea is to offer an overview of the known status of all
affected face groups. The items with an appended asterisk =*= tend to affected face groups. The items with an appended asterisk =*= tend to
have lots of extensions, so the "full support" may not be 100% true… have lots of extensions, so the "full support" may not be 100% true…
+ abbrev
+ ace-window + ace-window
+ agda2-mode + agda2-mode
+ all-the-icons + all-the-icons
@ -4314,6 +4271,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ hl-fill-column + hl-fill-column
+ hl-line-mode + hl-line-mode
+ hl-todo + hl-todo
+ howm
+ hydra + hydra
+ ibuffer + ibuffer
+ icomplete + icomplete
@ -4420,6 +4378,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ sly + sly
+ smart-mode-line + smart-mode-line
+ smerge + smerge
+ spacious-padding
+ speedbar + speedbar
+ spell-fu + spell-fu
+ stripes + stripes
@ -4435,8 +4394,10 @@ have lots of extensions, so the "full support" may not be 100% true…
+ terraform-mode + terraform-mode
+ term + term
+ textsec + textsec
+ tldr
+ transient (pop-up windows such as Magit's) + transient (pop-up windows such as Magit's)
+ trashed + trashed
+ treemacs
+ tree-sitter + tree-sitter
+ tty-menu + tty-menu
+ tuareg + tuareg
@ -5407,7 +5368,7 @@ more effective than trying to do the same with either red or blue (the
latter is the least effective in that regard). latter is the least effective in that regard).
When we need to work with several colors, it is always better to have When we need to work with several colors, it is always better to have
sufficient maneuvering space, especially since we cannot pick arbitrary sufficient manoeuvring space, especially since we cannot pick arbitrary
colors but only those that satisfy the accessibility objectives of the colors but only those that satisfy the accessibility objectives of the
themes. themes.
@ -5513,7 +5474,7 @@ it is already understood that one must follow the indicator or headline
to view its contents and (ii) underlining everything would make the to view its contents and (ii) underlining everything would make the
interface virtually unusable. interface virtually unusable.
Again, one must exercise judgment in order to avoid discrimination, Again, one must exercise judgement in order to avoid discrimination,
where "discrimination" refers to: where "discrimination" refers to:
+ The treatment of substantially different magnitudes as if they were of + The treatment of substantially different magnitudes as if they were of
@ -5587,7 +5548,7 @@ the themes, which is partially fleshed out in this manual.
With regard to the artistic aspect (where "art" qua skill may amount to With regard to the artistic aspect (where "art" qua skill may amount to
an imprecise science), there is no hard-and-fast rule in effect as it an imprecise science), there is no hard-and-fast rule in effect as it
requires one to exercise discretion and make decisions based on requires one to exercize discretion and make decisions based on
context-dependent information or constraints. As is true with most context-dependent information or constraints. As is true with most
things in life, when in doubt, do not cling on to the letter of the law things in life, when in doubt, do not cling on to the letter of the law
but try to understand its spirit. but try to understand its spirit.
@ -5736,14 +5697,14 @@ The Modus themes are a collective effort. Every bit of work matters.
Contovounesios, Björn Lindström, Carlo Zancanaro, Christian Tietze, Contovounesios, Björn Lindström, Carlo Zancanaro, Christian Tietze,
Daniel Mendler, David Edmondson, Eli Zaretskii, Fritz Grabo, Gautier Daniel Mendler, David Edmondson, Eli Zaretskii, Fritz Grabo, Gautier
Ponsinet, Illia Ostapyshyn, Jared Finder, Kévin Le Gouguec, Koen van Ponsinet, Illia Ostapyshyn, Jared Finder, Kévin Le Gouguec, Koen van
Greevenbroek, Kostadin Ninev, Madhavan Krishnan, Manuel Giraud, Greevenbroek, Kostadin Ninev, Leilei332, Madhavan Krishnan, Manuel
Markus Beppler, Matthew Stevenson, Mauro Aranda, Nacho Barrientos, Giraud, Markus Beppler, Matthew Stevenson, Mauro Aranda, Nacho
Niall Dooley, Nicolas De Jaeghere, Paul David, Pavel Novichkov, Barrientos, Niall Dooley, Nicolas De Jaeghere, Paul David, Pavel
Philip Kaludercic, Pierre Téchoueyres, Rudolf Adamkovič, Sergey Novichkov, Philip Kaludercic, Pierre Téchoueyres, Rahul M.
Nichiporchik, Shreyas Ragavan, Stefan Kangas, Stephen Berman, {{{space()}}} Juliato, Rudolf Adamkovič, Sergey Nichiporchik,
Stephen Gildea, Steve Downey, Thanos Apollo, Tomasz Hołubowicz, Shreyas Ragavan, Stefan Kangas, Stephen Berman, Stephen Gildea,
Utkarsh Singh, Vincent Murphy, Xinglu Chen, Yuanchen Xie, fluentpwn, Steve Downey, Thanos Apollo, Tomasz Hołubowicz, Utkarsh Singh,
okamsn. Vincent Murphy, Xinglu Chen, Yuanchen Xie, fluentpwn, okamsn.
+ Ideas and user feedback :: Aaron Jensen, Adam Porter, Adam Spiers, + Ideas and user feedback :: Aaron Jensen, Adam Porter, Adam Spiers,
Adrian Manea, Aleksei Pirogov, Alex Griffin, Alex Koen, Alex Adrian Manea, Aleksei Pirogov, Alex Griffin, Alex Koen, Alex
@ -5779,7 +5740,8 @@ The Modus themes are a collective effort. Every bit of work matters.
Eugene, Fourchaux, Fredrik, Moesasji, Nick, Summer Emacs, TheBlob42, Eugene, Fourchaux, Fredrik, Moesasji, Nick, Summer Emacs, TheBlob42,
TitusMu, Trey, ZharMeny, bepolymathe, bit9tream, bangedorrunt, TitusMu, Trey, ZharMeny, bepolymathe, bit9tream, bangedorrunt,
derek-upham, doolio, fleimgruber, gitrj95, iSeeU, jixiuf, ltmsyvag, derek-upham, doolio, fleimgruber, gitrj95, iSeeU, jixiuf, ltmsyvag,
okamsn, pRot0ta1p, shipmints, soaringbird, tumashu, wakamenod. okamsn, pedro-nonfree, pRot0ta1p, shipmints, soaringbird, tumashu,
wakamenod.
+ Packaging :: Basil L.{{{space()}}} Contovounesios, Eli Zaretskii, + Packaging :: Basil L.{{{space()}}} Contovounesios, Eli Zaretskii,
Glenn Morris, Mauro Aranda, Richard Stallman, Stefan Kangas (core Glenn Morris, Mauro Aranda, Richard Stallman, Stefan Kangas (core
@ -5812,7 +5774,7 @@ All errors are my own.
Version 1.3, 3 November 2008 Version 1.3, 3 November 2008
Copyright (C) 2000-2002, 2007-2008, 2025 Free Software Foundation, Inc. Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
<https://fsf.org/> <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.

View file

@ -3,7 +3,7 @@
% Load plain if necessary, i.e., if running under initex. % Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
% %
\def\texinfoversion{2025-01-31.21} \def\texinfoversion{2025-03-22.08}
% %
% Copyright 1985, 1986, 1988, 1990-2025 Free Software Foundation, Inc. % Copyright 1985, 1986, 1988, 1990-2025 Free Software Foundation, Inc.
% %
@ -287,7 +287,6 @@
% Avoid "undefined control sequence" errors. % Avoid "undefined control sequence" errors.
\def\currentchapterdefs{} \def\currentchapterdefs{}
\def\currentsectiondefs{} \def\currentsectiondefs{}
\def\currentsection{}
\def\prevchapterdefs{} \def\prevchapterdefs{}
\def\prevsectiondefs{} \def\prevsectiondefs{}
\def\currentcolordefs{} \def\currentcolordefs{}
@ -980,18 +979,51 @@ where each line of input produces a line of output.}
\newif\ifpdf \newif\ifpdf
\newif\ifpdfmakepagedest \newif\ifpdfmakepagedest
% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
% can be set). So we test for \relax and 0 as well as being undefined.
\ifx\pdfoutput\thisisundefined
\else
\ifx\pdfoutput\relax
\else
\ifcase\pdfoutput
\else
\pdftrue
\fi
\fi
\fi
\newif\ifxetex
\ifx\XeTeXrevision\thisisundefined\else
\xetextrue
\fi
\newif\ifluatex \newif\ifluatex
\ifx\luatexversion\thisisundefined\else \ifx\luatexversion\thisisundefined\else
\luatextrue \luatextrue
\ifnum\luatexversion>84
\pdftrue
\fi
\fi \fi
\newif\ifpdforxetex
\ifpdf
\pdforxetextrue
\fi
\ifxetex
\pdforxetextrue
\fi
% Whether to use non-ASCII bytes in internal link targets. Presently this
% is almost always on.
\newif\iftxiuseunicodedestname
\txiuseunicodedestnametrue
% %
% For LuaTeX % For LuaTeX
% %
\newif\iftxiuseunicodedestname
\txiuseunicodedestnamefalse % For pdfTeX etc.
\ifluatex \ifluatex
% Use Unicode destination names % Use Unicode destination names
\txiuseunicodedestnametrue \txiuseunicodedestnametrue
@ -1045,7 +1077,7 @@ where each line of input produces a line of output.}
% %
\endgroup \endgroup
\def\pdfescapestring#1{\directlua{PDFescstr('\luaescapestring{#1}')}} \def\pdfescapestring#1{\directlua{PDFescstr('\luaescapestring{#1}')}}
\ifnum\luatexversion>84 \ifpdf
% For LuaTeX >= 0.85 % For LuaTeX >= 0.85
\def\pdfdest{\pdfextension dest} \def\pdfdest{\pdfextension dest}
\let\pdfoutput\outputmode \let\pdfoutput\outputmode
@ -1068,33 +1100,6 @@ where each line of input produces a line of output.}
\fi \fi
\fi \fi
% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
% can be set). So we test for \relax and 0 as well as being undefined.
\ifx\pdfoutput\thisisundefined
\else
\ifx\pdfoutput\relax
\else
\ifcase\pdfoutput
\else
\pdftrue
\fi
\fi
\fi
\newif\ifxetex
\ifx\XeTeXrevision\thisisundefined\else
\xetextrue
\fi
\newif\ifpdforxetex
\pdforxetexfalse
\ifpdf
\pdforxetextrue
\fi
\ifxetex
\pdforxetextrue
\fi
% Output page labels information. % Output page labels information.
% See PDF reference v.1.7 p.594, section 8.3.1. % See PDF reference v.1.7 p.594, section 8.3.1.
@ -1388,9 +1393,6 @@ output) for that.)}
\safewhatsit{\pdfdest name{\pdfdestname} xyz}% \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
} }
% %
% used to mark target names; must be expandable.
\def\pdfmkpgn#1{#1}
%
% Adding outlines to PDF; macros for calculating structure of outlines % Adding outlines to PDF; macros for calculating structure of outlines
% come from Petr Olsak % come from Petr Olsak
\def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
@ -1416,7 +1418,7 @@ output) for that.)}
\def\pdfdestname{#4}% \def\pdfdestname{#4}%
\fi \fi
% %
\pdfoutline goto name{\pdfmkpgn{\pdfdestname}}#2{\pdfoutlinetext}% \pdfoutline goto name{\pdfdestname}#2{\pdfoutlinetext}%
} }
% %
\def\pdfmakeoutlines{% \def\pdfmakeoutlines{%
@ -1427,15 +1429,18 @@ output) for that.)}
\def\thischapnum{##2}% \def\thischapnum{##2}%
\def\thissecnum{0}% \def\thissecnum{0}%
\def\thissubsecnum{0}% \def\thissubsecnum{0}%
\def\indexlastsec{chap\thischapnum}%
}% }%
\def\numsecentry##1##2##3##4{% \def\numsecentry##1##2##3##4{%
\advancenumber{chap\thischapnum}% \advancenumber{chap\thischapnum}%
\def\thissecnum{##2}% \def\thissecnum{##2}%
\def\thissubsecnum{0}% \def\thissubsecnum{0}%
\def\indexlastsec{sec\thissecnum}%
}% }%
\def\numsubsecentry##1##2##3##4{% \def\numsubsecentry##1##2##3##4{%
\advancenumber{sec\thissecnum}% \advancenumber{sec\thissecnum}%
\def\thissubsecnum{##2}% \def\thissubsecnum{##2}%
\def\indexlastsec{subsec\thissecnum}%
}% }%
\def\numsubsubsecentry##1##2##3##4{% \def\numsubsubsecentry##1##2##3##4{%
\advancenumber{subsec\thissubsecnum}% \advancenumber{subsec\thissubsecnum}%
@ -1443,7 +1448,13 @@ output) for that.)}
\def\thischapnum{0}% \def\thischapnum{0}%
\def\thissecnum{0}% \def\thissecnum{0}%
\def\thissubsecnum{0}% \def\thissubsecnum{0}%
\let\indexlastsec\empty
% %
% Index initials are subsidiary to whatever sectioning command just
% occurred, usually @appendix or @chapter but occasionally a lower level.
\def\idxinitialentry##1##2##3##4{%
\expandafter\advancenumber\expandafter{\indexlastsec}%
}%
% use \def rather than \let here because we redefine \chapentry et % use \def rather than \let here because we redefine \chapentry et
% al. a second time, below. % al. a second time, below.
\def\appentry{\numchapentry}% \def\appentry{\numchapentry}%
@ -1455,9 +1466,6 @@ output) for that.)}
\def\unnsubsecentry{\numsubsecentry}% \def\unnsubsecentry{\numsubsecentry}%
\def\unnsubsubsecentry{\numsubsubsecentry}% \def\unnsubsubsecentry{\numsubsubsecentry}%
% %
% Treat index initials like @section. Note that this is the wrong
% level if the index is not at the level of @appendix or @chapter.
\def\idxinitialentry{\numsecentry}%
\readdatafile{toc}% \readdatafile{toc}%
% %
% Read toc second time, this time actually producing the outlines. % Read toc second time, this time actually producing the outlines.
@ -1482,18 +1490,6 @@ output) for that.)}
\def\idxinitialentry##1##2##3##4{% \def\idxinitialentry##1##2##3##4{%
\dopdfoutline{##1}{}{idx.##1.##2}{##4}}% \dopdfoutline{##1}{}{idx.##1.##2}{##4}}%
% %
% PDF outlines are displayed using system fonts, instead of
% document fonts. Therefore we cannot use special characters,
% since the encoding is unknown. For example, the eogonek from
% Latin 2 (0xea) gets translated to a | character. Info from
% Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
%
% TODO this right, we have to translate 8-bit characters to
% their "best" equivalent, based on the @documentencoding. Too
% much work for too little return. Just use the ASCII equivalents
% we use for the index sort strings.
%
\indexnofonts
\ifnodeseen\else \dopdfoutlinecontents \fi % for @contents at beginning \ifnodeseen\else \dopdfoutlinecontents \fi % for @contents at beginning
\setupdatafile \setupdatafile
% We can have normal brace characters in the PDF outlines, unlike % We can have normal brace characters in the PDF outlines, unlike
@ -1501,9 +1497,9 @@ output) for that.)}
\def\{{\lbracecharliteral}% \def\{{\lbracecharliteral}%
\def\}{\rbracecharliteral}% \def\}{\rbracecharliteral}%
\catcode`\\=\active \otherbackslash \catcode`\\=\active \otherbackslash
\input \tocreadfilename \input \tocreadfilename\relax
\ifnodeseen \dopdfoutlinecontents \fi % for @contents at end
\endgroup \endgroup
\ifnodeseen \dopdfoutlinecontents \fi % for @contents at end
} }
\def\dopdfoutlinecontents{% \def\dopdfoutlinecontents{%
\expandafter\dopdfoutline\expandafter{\putwordTOC}{}{txi.CONTENTS}{}% \expandafter\dopdfoutline\expandafter{\putwordTOC}{}{txi.CONTENTS}{}%
@ -1541,7 +1537,7 @@ output) for that.)}
% %
\def\pdflink#1{\pdflinkpage{#1}{#1}}% \def\pdflink#1{\pdflinkpage{#1}{#1}}%
\def\pdflinkpage#1#2{% \def\pdflinkpage#1#2{%
\startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} \startlink attr{/Border [0 0 0]} goto name{#1}
\setcolor{\linkcolor}#2\endlink} \setcolor{\linkcolor}#2\endlink}
\else \else
% non-pdf mode % non-pdf mode
@ -1644,18 +1640,20 @@ output) for that.)}
% horizontal space being required in the PDF viewer. % horizontal space being required in the PDF viewer.
\def\partentry##1##2##3##4{}% ignore parts in the outlines \def\partentry##1##2##3##4{}% ignore parts in the outlines
\def\numchapentry##1##2##3##4{% \def\numchapentry##1##2##3##4{%
\dopdfoutline{##2 ##1}{1}{##3}{##4}}% \dopdfoutline{##2 ##1}{1}{##3}{##4}%
\def\indexseclevel{2}}%
\def\numsecentry##1##2##3##4{% \def\numsecentry##1##2##3##4{%
\dopdfoutline{##1}{2}{##3}{##4}}% \dopdfoutline{##1}{2}{##3}{##4}%
\def\indexseclevel{3}}%
\def\numsubsecentry##1##2##3##4{% \def\numsubsecentry##1##2##3##4{%
\dopdfoutline{##1}{3}{##3}{##4}}% \dopdfoutline{##1}{3}{##3}{##4}%
\def\indexseclevel{4}}%
\def\numsubsubsecentry##1##2##3##4{% \def\numsubsubsecentry##1##2##3##4{%
\dopdfoutline{##1}{4}{##3}{##4}}% \dopdfoutline{##1}{4}{##3}{##4}%
\def\indexseclevel{5}}%
% %
% Note this is at the wrong level unless the index is in an @appendix
% or @chapter.
\def\idxinitialentry##1##2##3##4{% \def\idxinitialentry##1##2##3##4{%
\dopdfoutline{##1}{2}{idx.##1.##2}{##4}}% \dopdfoutline{##1}{\indexseclevel}{idx.##1.##2}{##4}}%
% %
\let\appentry\numchapentry% \let\appentry\numchapentry%
\let\appsecentry\numsecentry% \let\appsecentry\numsecentry%
@ -1680,7 +1678,9 @@ output) for that.)}
\def\{{\lbracecharliteral}% \def\{{\lbracecharliteral}%
\def\}{\rbracecharliteral}% \def\}{\rbracecharliteral}%
\catcode`\\=\active \otherbackslash \catcode`\\=\active \otherbackslash
\xetexpreauxfile
\input \tocreadfilename\relax \input \tocreadfilename\relax
\xetexpostauxfile
\ifnodeseen \dopdfoutlinecontents \fi % for @contents at end \ifnodeseen \dopdfoutlinecontents \fi % for @contents at end
\endgroup \endgroup
} }
@ -5177,8 +5177,8 @@ $$%
% %
\uccode`\1=`\{ \uppercase{\def\{{1}}% \uccode`\1=`\{ \uppercase{\def\{{1}}%
\uccode`\1=`\} \uppercase{\def\}{1}}% \uccode`\1=`\} \uppercase{\def\}{1}}%
\let\lbracechar\{% \def\lbracechar##1{\{}%
\let\rbracechar\}% \def\rbracechar##1{\}}%
% %
% %
% We need to get rid of all macros, leaving only the arguments (if present). % We need to get rid of all macros, leaving only the arguments (if present).
@ -5523,6 +5523,8 @@ $$%
\tolerance = 9500 \tolerance = 9500
\plainfrenchspacing \plainfrenchspacing
\everypar = {}% don't want the \kern\-parindent from indentation suppression. \everypar = {}% don't want the \kern\-parindent from indentation suppression.
\let\entry\indexentry
\ifxetex\xetexpreauxfile\fi
% %
% See comment in \requireopenindexfile. % See comment in \requireopenindexfile.
\def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi \def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi
@ -5548,6 +5550,7 @@ $$%
\fi \fi
\fi \fi
\closein 1 \closein 1
\ifxetex\xetexpostauxfile\fi
\endgroup} \endgroup}
% Checked in @bye % Checked in @bye
@ -5583,7 +5586,9 @@ might help (with 'rm \jobname.?? \jobname.??s')%
}% }%
\else \else
\begindoublecolumns \begindoublecolumns
\ifxetex\xetexpreauxfile\fi
\input \jobname.\indexname s \input \jobname.\indexname s
\ifxetex\xetexpostauxfile\fi
\enddoublecolumns \enddoublecolumns
\fi \fi
}{% }{%
@ -5594,11 +5599,39 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% should work because we (hopefully) don't otherwise use @ in index files. % should work because we (hopefully) don't otherwise use @ in index files.
%\catcode`\@=12\relax %\catcode`\@=12\relax
\catcode`\@=0\relax \catcode`\@=0\relax
\ifxetex\xetexpreauxfile\fi
\input \jobname.\indexname s \input \jobname.\indexname s
\ifxetex\xetexpostauxfile\fi
\enddoublecolumns \enddoublecolumns
}% }%
} }
\def\indexentry#1#2{%
\let\entrypagetarget\empty
\ifpdforxetex
% only link the index text to the page if no comma appears in the
% list of pages, i.e. there is only one page
\checkpagelistcomma{#2}\pagelistcomma
\expandafter\ifcase\pagelistcomma
\def\entrypagetarget{#2}%
\fi
\fi%
\entryinternal{#1}{#2}%
}
\def\checkpagelistcomma#1#2{%
\checkpagelistcommaxx#2#1,\finish
}
\def\checkpagelistcommaxx#1#2,#3\finish{%
\def\tmp{#3}%
\ifx\tmp\empty
\def#1{0\relax}
\else
\def#1{1\relax}
\fi
}
% These macros are used by the sorted index file itself. % These macros are used by the sorted index file itself.
% Change them to control the appearance of the index. % Change them to control the appearance of the index.
@ -5673,18 +5706,14 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\def\doindexinitialentry#1{% \def\doindexinitialentry#1{%
\ifpdforxetex \ifpdforxetex
\global\advance\idxinitialno by 1 \global\advance\idxinitialno by 1
\def\indexlbrace{\{} \def\indexlbrace{\{}%
\def\indexrbrace{\}} \def\indexrbrace{\}}%
\def\indexbackslash{\realbackslash} \def\indexbackslash{\realbackslash}%
\def\indexatchar{\@} \def\indexatchar{\@}%
\writetocentry{idxinitial}{\asis #1}{IDX\the\idxinitialno}% \writetocentry{idxinitial}{\asis #1}{IDX\the\idxinitialno}%
% The @asis removes a pair of braces around e.g. {@indexatchar} that % The @asis removes a pair of braces around e.g. {@indexatchar} that
% are output by texindex. % are output by texindex.
% %
\vbox to 0pt{}%
% This vbox fixes the \pdfdest location for double column formatting.
% Without it, the \pdfdest is output above topskip glue at the top
% of a column as this glue is not added until the first box.
\pdfmkdest{idx.\asis #1.IDX\the\idxinitialno}% \pdfmkdest{idx.\asis #1.IDX\the\idxinitialno}%
\fi \fi
} }
@ -5704,16 +5733,18 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\newdimen\entrycontskip \newdimen\entrycontskip
\entrycontskip=1em \entrycontskip=1em
% for PDF output, whether to make the text of the entry a link to the page % for PDF output, whether to make the text of the entry a link to the section.
% number. set for @contents and @shortcontents where there is only one % set for @contents and @shortcontents.
% page number.
\newif\iflinkentrytext \newif\iflinkentrytext
% \entry typesets a paragraph consisting of the text (#1), dot leaders, and % \entryinternal typesets a paragraph consisting of the text (#1), dot
% then page number (#2) flushed to the right margin. It is used for index % leaders, and then page number (#2) flushed to the right margin. It is
% and table of contents entries. The paragraph is indented by \leftskip. % used for index and table of contents entries. The paragraph is indented
% If \tocnodetarget is set, link text to the referenced node. % by \leftskip.
\def\entry{% % For PDF output, if \linkentrytexttrue and \tocnodetarget is set, link text
% to the referenced node. Else if \entrypagetarget is set, link text to the
% page.
\def\entryinternal{%
\begingroup \begingroup
% %
% Start a new paragraph if necessary, so our assignments below can't % Start a new paragraph if necessary, so our assignments below can't
@ -5761,7 +5792,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\endlink \endlink
\fi \fi
\else \else
\unhbox\boxA \ifx\entrypagetarget\empty
\unhbox\boxA
\else
\pdflinkpage{\entrypagetarget}{\unhbox\boxA}%
\fi
\fi \fi
\else \else
\unhbox\boxA \unhbox\boxA
@ -6433,6 +6468,10 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} \parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
\suppressfirstparagraphindent} \suppressfirstparagraphindent}
% @xrefname - give text with printed name for linking to node and allow
% referencing node, but do not print any heading.
\parseargdef\xrefname{\donoderef{Yomitfromtoc}{#1}}%
% These macros generate a chapter, section, etc. heading only % These macros generate a chapter, section, etc. heading only
% (including whitespace, linebreaking, etc. around it), % (including whitespace, linebreaking, etc. around it),
% given all the information in convenient, parsed form. % given all the information in convenient, parsed form.
@ -6554,11 +6593,6 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\chapfonts \rm \chapfonts \rm
\let\footnote=\errfootnoteheading % give better error message \let\footnote=\errfootnoteheading % give better error message
% %
% Have to define \currentsection before calling \donoderef, because the
% xref code eventually uses it. On the other hand, it has to be called
% after \pchapsepmacro, or the headline will change too soon.
\gdef\currentsection{#1}%
%
% Only insert the separating space if we have a chapter/appendix % Only insert the separating space if we have a chapter/appendix
% number, and don't print the unnumbered ``number''. % number, and don't print the unnumbered ``number''.
\ifx\temptype\Ynothingkeyword \ifx\temptype\Ynothingkeyword
@ -6585,7 +6619,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% been typeset. If the destination for the pdf outline is after the % been typeset. If the destination for the pdf outline is after the
% text, then jumping from the outline may wind up with the text not % text, then jumping from the outline may wind up with the text not
% being visible, for instance under high magnification. % being visible, for instance under high magnification.
\donoderef{#2}% \donoderef{#2}{#1}%
% %
% Typeset the actual heading. % Typeset the actual heading.
\nobreak % Avoid page breaks at the interline glue. \nobreak % Avoid page breaks at the interline glue.
@ -6701,21 +6735,17 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\ifx\temptype\Ynothingkeyword \ifx\temptype\Ynothingkeyword
\setbox0 = \hbox{}% \setbox0 = \hbox{}%
\def\toctype{unn}% \def\toctype{unn}%
\gdef\currentsection{#1}%
\else\ifx\temptype\Yomitfromtockeyword \else\ifx\temptype\Yomitfromtockeyword
% for @headings -- no section number, don't include in toc, % for @headings -- no section number, don't include in toc.
% and don't redefine \currentsection.
\setbox0 = \hbox{}% \setbox0 = \hbox{}%
\def\toctype{omit}% \def\toctype{omit}%
\let\sectionlevel=\empty \let\sectionlevel=\empty
\else\ifx\temptype\Yappendixkeyword \else\ifx\temptype\Yappendixkeyword
\setbox0 = \hbox{#4\enspace}% \setbox0 = \hbox{#4\enspace}%
\def\toctype{app}% \def\toctype{app}%
\gdef\currentsection{#1}%
\else \else
\setbox0 = \hbox{#4\enspace}% \setbox0 = \hbox{#4\enspace}%
\def\toctype{num}% \def\toctype{num}%
\gdef\currentsection{#1}%
\fi\fi\fi \fi\fi\fi
% %
% Write the toc entry (before \donoderef). See comments in \chapmacro. % Write the toc entry (before \donoderef). See comments in \chapmacro.
@ -6723,7 +6753,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% %
% Write the node reference (= pdf destination for pdftex). % Write the node reference (= pdf destination for pdftex).
% Again, see comments in \chapmacro. % Again, see comments in \chapmacro.
\donoderef{#3}% \donoderef{#3}{#1}%
% %
% Interline glue will be inserted when the vbox is completed. % Interline glue will be inserted when the vbox is completed.
% That glue will be a valid breakpoint for the page, since it'll be % That glue will be a valid breakpoint for the page, since it'll be
@ -6955,6 +6985,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% %
\def\contents{% \def\contents{%
\startcontents{\putwordTOC}{\contentsmkdest}% \startcontents{\putwordTOC}{\contentsmkdest}%
\ifxetex\xetexpreauxfile\fi
\openin 1 \tocreadfilename\space \openin 1 \tocreadfilename\space
\ifeof 1 \else \ifeof 1 \else
\findsecnowidths \findsecnowidths
@ -6966,6 +6997,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\pdfmakeoutlines \pdfmakeoutlines
\fi \fi
\closein 1 \closein 1
\ifxetex\xetexpostauxfile\fi
\endgroup \endgroup
\contentsendroman \contentsendroman
} }
@ -6999,11 +7031,13 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\let\numsubsubsecentry = \numsecentry \let\numsubsubsecentry = \numsecentry
\let\appsubsubsecentry = \numsecentry \let\appsubsubsecentry = \numsecentry
\let\unnsubsubsecentry = \numsecentry \let\unnsubsubsecentry = \numsecentry
\ifxetex\xetexpreauxfile\fi
\openin 1 \tocreadfilename\space \openin 1 \tocreadfilename\space
\ifeof 1 \else \ifeof 1 \else
\readtocfile \readtocfile
\fi \fi
\closein 1 \closein 1
\ifxetex\xetexpostauxfile\fi
\vfill \eject \vfill \eject
\contentsalignmacro % in case @setchapternewpage odd is in effect \contentsalignmacro % in case @setchapternewpage odd is in effect
\endgroup \endgroup
@ -7167,6 +7201,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\extrasecnoskip=0pt \extrasecnoskip=0pt
\let\tocnodetarget\empty \let\tocnodetarget\empty
\let\entrypagetarget\empty
% \tocentry{TITLE}{SEC NO}{NODE}{PAGE} % \tocentry{TITLE}{SEC NO}{NODE}{PAGE}
% %
@ -7174,7 +7209,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\def\tocnodetarget{#3}% \def\tocnodetarget{#3}%
\def\secno{#2}% \def\secno{#2}%
\ifx\empty\secno \ifx\empty\secno
\entry{#1}{#4}% \entryinternal{#1}{#4}%
\else \else
\ifdim 0pt=\secnowidth \ifdim 0pt=\secnowidth
\setbox0=\hbox{#2\hskip\labelspace\hskip\extrasecnoskip}% \setbox0=\hbox{#2\hskip\labelspace\hskip\extrasecnoskip}%
@ -7185,7 +7220,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
#2\hskip\labelspace\hskip\extrasecnoskip\hfill}% #2\hskip\labelspace\hskip\extrasecnoskip\hfill}%
\fi \fi
\entrycontskip=\wd0 \entrycontskip=\wd0
\entry{\box0 #1}{#4}% \entryinternal{\box0 #1}{#4}%
\fi \fi
} }
\newdimen\labelspace \newdimen\labelspace
@ -8170,18 +8205,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
} }
\fi \fi
\let\E=\expandafter
% Used at the time of macro expansion. % Used at the time of macro expansion.
% Argument is macro body with arguments substituted % Argument is macro body with arguments substituted
\def\scanmacro#1{% \def\scanmacro#1{%
\newlinechar`\^^M \newlinechar`\^^M
% expand the expansion of \eatleadingcr twice to maybe remove a leading \def\xeatspaces##1{\eatleadingcrthen\eatspaces{##1}}%
% newline (and \else and \fi tokens), then call \eatspaces on the result.
\def\xeatspaces##1{%
\E\E\E\E\E\E\E\eatspaces\E\E\E\E\E\E\E{\eatleadingcr##1%
}}%
\def\xempty##1{}%
% %
% Process the macro body under the current catcode regime. % Process the macro body under the current catcode regime.
\scantokens{#1@comment}% \scantokens{#1@comment}%
@ -8234,10 +8262,12 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\unbrace{\gdef\trim@@@ #1 } #2@{#1} \unbrace{\gdef\trim@@@ #1 } #2@{#1}
} }
{\catcode`\^^M=\other% % Trim a single leading ^^M off a string, then call #1
\gdef\eatleadingcr#1{\if\noexpand#1\noexpand^^M\else\E#1\fi}}% {\catcode`\^^M=\active \catcode`\Q=3%
% Warning: this won't work for a delimited argument \gdef\eatleadingcrthen #1#2{\eatlcra #1Q#2Q^^MQ}%
% or for an empty argument \gdef\eatlcra #1#2Q^^M{\eatlcrb #1#2Q}%
\gdef\eatlcrb #1Q#2Q#3Q{#1{#2}}%
}
% Trim a single trailing ^^M off a string. % Trim a single trailing ^^M off a string.
{\catcode`\^^M=\other \catcode`\Q=3% {\catcode`\^^M=\other \catcode`\Q=3%
@ -8373,6 +8403,10 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% <parameter list> is #, then the preceding argument is delimited by % <parameter list> is #, then the preceding argument is delimited by
% an opening brace, and that opening brace is not consumed. % an opening brace, and that opening brace is not consumed.
% Make @ a letter, so that we can make private-to-Texinfo macro names.
\edef\texiatcatcode{\the\catcode`\@}
\catcode `@=11\relax
% Parse the optional {params} list to @macro or @rmacro. % Parse the optional {params} list to @macro or @rmacro.
% Set \paramno to the number of arguments, % Set \paramno to the number of arguments,
% and \paramlist to a parameter text for the macro (e.g. #1,#2,#3 for a % and \paramlist to a parameter text for the macro (e.g. #1,#2,#3 for a
@ -8385,14 +8419,13 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% That gets used by \mbodybackslash (above). % That gets used by \mbodybackslash (above).
% %
% If there are 10 or more arguments, a different technique is used: see % If there are 10 or more arguments, a different technique is used: see
% \parsemmanyargdef. % \parsemmanyargdef@@.
% %
\def\parsemargdef#1;{% \def\parsemargdef#1;{%
\paramno=0\def\paramlist{}% \paramno=0\def\paramlist{}%
\let\hash\relax \let\hash\relax
% \hash is redefined to `#' later to get it into definitions % \hash is redefined to `#' later to get it into definitions
\let\xeatspaces\relax \let\xeatspaces\relax
\let\xempty\relax
\parsemargdefxxx#1,;,% \parsemargdefxxx#1,;,%
\ifnum\paramno<10\relax\else \ifnum\paramno<10\relax\else
\paramno0\relax \paramno0\relax
@ -8404,11 +8437,9 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\else \let\next=\parsemargdefxxx \else \let\next=\parsemargdefxxx
\advance\paramno by 1 \advance\paramno by 1
\expandafter\edef\csname macarg.\eatspaces{#1}\endcsname \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
{\xeatspaces{\hash\the\paramno\noexpand\xempty{}}}% {\xeatspaces{\hash\the\paramno}}%
\edef\paramlist{\paramlist\hash\the\paramno,}% \edef\paramlist{\paramlist\hash\the\paramno,}%
\fi\next} \fi\next}
% the \xempty{} is to give \eatleadingcr an argument in the case of an
% empty macro argument.
% \parsemacbody, \parsermacbody % \parsemacbody, \parsermacbody
% %
@ -8419,14 +8450,12 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% body to be transformed. % body to be transformed.
% Set \macrobody to the body of the macro, and call \macrodef. % Set \macrobody to the body of the macro, and call \macrodef.
% %
\catcode `\@\texiatcatcode
{\catcode`\ =\other\long\gdef\parsemacbody#1@end macro{% {\catcode`\ =\other\long\gdef\parsemacbody#1@end macro{%
\xdef\macrobody{\eatcr{#1}}\endgroup\macrodef}}% \xdef\macrobody{\eatcr{#1}}\endgroup\macrodef}}%
{\catcode`\ =\other\long\gdef\parsermacbody#1@end rmacro{% {\catcode`\ =\other\long\gdef\parsermacbody#1@end rmacro{%
\xdef\macrobody{\eatcr{#1}}\endgroup\macrodef}}% \xdef\macrobody{\eatcr{#1}}\endgroup\macrodef}}%
\catcode `\@=11\relax
% Make @ a letter, so that we can make private-to-Texinfo macro names.
\edef\texiatcatcode{\the\catcode`\@}
\catcode `@=11\relax
%%%%%%%%%%%%%% Code for > 10 arguments only %%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%% Code for > 10 arguments only %%%%%%%%%%%%%%%%%%
@ -8687,15 +8716,13 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\noexpand\expandafter \noexpand\expandafter
\expandafter\noexpand\csname\the\macname @@\endcsname}% \expandafter\noexpand\csname\the\macname @@\endcsname}%
\expandafter\xdef\csname\the\macname @@\endcsname##1{% \expandafter\xdef\csname\the\macname @@\endcsname##1{%
\noexpand\passargtomacro \noexpand\passargtomacro
\expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}%
\expandafter\xdef\csname\the\macname @@@\endcsname##1{% \expandafter\xdef\csname\the\macname @@@\endcsname##1{%
\expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}%
\expandafter\expandafter \expandaftergroup{\expandafter\xdef\csname\the\macname @@@@\endcsname}%
\expandafter\xdef \paramlist{%
\expandafter\expandafter \endgroup\noexpand\scanmacro{\macrobody}}%
\csname\the\macname @@@@\endcsname\paramlist{%
\endgroup\noexpand\scanmacro{\macrobody}}%
\else % 10 or more: \else % 10 or more:
\expandafter\xdef\csname\the\macname\endcsname{% \expandafter\xdef\csname\the\macname\endcsname{%
\noexpand\getargvals@{\the\macname}{\argl}% \noexpand\getargvals@{\the\macname}{\argl}%
@ -8707,6 +8734,16 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\catcode `\@\texiatcatcode\relax % end private-to-Texinfo catcodes \catcode `\@\texiatcatcode\relax % end private-to-Texinfo catcodes
% utility definition to avoid excessive use of \expandafter. call
% as \expandaftergroup{CONTENT}\WORD to expand \WORD exactly once and remove
% braces around CONTENT.
\def\expandaftergroup#1#2{%
\expandafter\expandaftergroupx\expandafter{#2}{#1}%
}
\def\expandaftergroupx#1#2{%
#2#1%
}
\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
@ -8876,9 +8913,8 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\expandafter\noexpand \expandafter\noexpand
\csname\the\macname @@@\endcsname##1\noexpand\endlinemacro \csname\the\macname @@@\endcsname##1\noexpand\endlinemacro
} }
\expandafter\expandafter \expandaftergroup{\expandafter\xdef\csname\the\macname @@@\endcsname}%
\expandafter\xdef \paramlist{%
\expandafter\expandafter\csname\the\macname @@@\endcsname\paramlist{%
\newlinechar=13 % split \macrobody into lines \newlinechar=13 % split \macrobody into lines
\noexpand\scantokens{\macrobody}% \noexpand\scantokens{\macrobody}%
} }
@ -8953,11 +8989,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\let\lastnode=\empty \let\lastnode=\empty
% Write a cross-reference definition for the current node. #1 is the % Write a cross-reference definition for the current node. #1 is the
% type (Ynumbered, Yappendix, Ynothing). % type (Ynumbered, Yappendix, Ynothing). #2 is the section title.
% %
\def\donoderef#1{% \def\donoderef#1#2{%
\ifx\lastnode\empty\else \ifx\lastnode\empty\else
\setref{\lastnode}{#1}% \setref{\lastnode}{#1}{#2}%
\global\let\lastnode=\empty \global\let\lastnode=\empty
\setnodeseenonce \setnodeseenonce
\fi \fi
@ -8978,21 +9014,28 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% %
\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} \def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} \def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} \def\anchor#1{%
\savesf \setref{#1}{Yanchor}{#1}\restoresf \ignorespaces
}
% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an % @namedanchor{NAME, XREFNAME} -- define xref target at arbitrary point
% anchor), which consists of three parts: % with label text for cross-references to it.
% 1) NAME-title - the current sectioning name taken from \currentsection, \def\namedanchor#1{\donamedanchor#1\finish}%
% or the anchor name. \def\donamedanchor#1,#2\finish{%
% 2) NAME-snt - section number and type, passed as the SNT arg, or \savesf \setref{#1}{Yanchor}{\ignorespaces #2\unskip}\restoresf \ignorespaces
% empty for anchors. }
% \setref{NAME}{SNT}{TITLE} defines a cross-reference point NAME (a node
% or an anchor), which consists of three parts:
% 1) NAME-title - the current sectioning name
% 2) NAME-snt - section number and type, passed as the SNT arg.
% 3) NAME-pg - the page number. % 3) NAME-pg - the page number.
% %
% This is called from \donoderef, \anchor, and \dofloat. In the case of % This is called from \donoderef, \anchor, and \dofloat. In the case of
% floats, there is an additional part, which is not written here: % floats, there is an additional part, which is not written here:
% 4) NAME-lof - the text as it should appear in a @listoffloats. % 4) NAME-lof - the text as it should appear in a @listoffloats.
% %
\def\setref#1#2{% \def\setref#1#2#3{%
\pdfmkdest{#1}% \pdfmkdest{#1}%
\iflinks \iflinks
{% {%
@ -9004,7 +9047,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
##1}{##2}}% these are parameters of \writexrdef ##1}{##2}}% these are parameters of \writexrdef
}% }%
\toks0 = \expandafter{\currentsection}% \toks0 = {#3}%
\immediate \writexrdef{title}{\the\toks0 }% \immediate \writexrdef{title}{\the\toks0 }%
\immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
\safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout
@ -9058,15 +9101,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\setbox\infofilenamebox = \hbox{\infofilename\unskip}% \setbox\infofilenamebox = \hbox{\infofilename\unskip}%
% %
\startxreflink{#1}{#4}% \startxreflink{#1}{#4}%
{% \getrefx{#1-title}\Xthisreftitle
% Have to otherify everything special to allow the \csname to
% include an _ in the xref name, etc.
\indexnofonts
\turnoffactive
\def\value##1{##1}%
\expandafter\global\expandafter\let\expandafter\Xthisreftitle
\csname XR#1-title\endcsname
}%
% %
% Float references are printed completely differently: "Figure 1.2" % Float references are printed completely differently: "Figure 1.2"
% instead of "[somenode], p.3". \iffloat distinguishes them by % instead of "[somenode], p.3". \iffloat distinguishes them by
@ -9099,21 +9134,23 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% Cross-manual reference with a printed manual name. % Cross-manual reference with a printed manual name.
% %
\crossmanualxref{\cite{\printedmanual\unskip}}% \crossmanualxref{\cite{\printedmanual\unskip}}%
%
\else\ifdim \wd\infofilenamebox > 0pt \else\ifdim \wd\infofilenamebox > 0pt
% Cross-manual reference with only an info filename (arg 4), no % Cross-manual reference with only an info filename (arg 4), no
% printed manual name (arg 5). This is essentially the same as % printed manual name (arg 5). This is essentially the same as
% the case above; we output the filename, since we have nothing else. % the case above; we output the filename, since we have nothing else.
% %
\crossmanualxref{\code{\infofilename\unskip}}% \crossmanualxref{\code{\infofilename\unskip}}%
%
\else \else
% Reference within this manual. % Reference within this manual.
% %
% Only output a following space if the -snt ref is nonempty, as the ref % Only output a following space if the -snt ref is nonempty, as is
% will be empty for @unnumbered and @anchor. % the case for @unnumbered and @anchor.
\setbox2 = \hbox{\ignorespaces \refx{#1-snt}}% \getrefx{#1-snt}\tmp
\ifdim \wd2 > 0pt \refx{#1-snt}\space\fi \ifx\tmp\empty\else
\ifx\tmp\Yanchor\else
\tmp\space
\fi
\fi
% %
% output the `[mynode]' via the macro below so it can be overridden. % output the `[mynode]' via the macro below so it can be overridden.
\xrefprintnodename\printedrefname \xrefprintnodename\printedrefname
@ -9169,7 +9206,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\else \else
% Otherwise just copy the Info node name. % Otherwise just copy the Info node name.
\def\printedrefname{\ignorespaces #1}% \def\printedrefname{\ignorespaces #1}%
\fi% \fi
\fi \fi
\fi \fi
\fi \fi
@ -9201,7 +9238,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\ifnum\filenamelength>0 \ifnum\filenamelength>0
goto file{\the\filename.pdf} name{\pdfdestname}% goto file{\the\filename.pdf} name{\pdfdestname}%
\else \else
goto name{\pdfmkpgn{\pdfdestname}}% goto name{\pdfdestname}%
\fi \fi
\else % XeTeX \else % XeTeX
\ifnum\filenamelength>0 \ifnum\filenamelength>0
@ -9281,6 +9318,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% %
\def\Ynothing{} \def\Ynothing{}
\def\Yomitfromtoc{} \def\Yomitfromtoc{}
\def\Yanchor{\isanchor} \let\isanchor\relax
\def\Ynumbered{% \def\Ynumbered{%
\ifnum\secno=0 \ifnum\secno=0
\putwordChapter@tie \the\chapno \putwordChapter@tie \the\chapno
@ -9307,14 +9345,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% \refx{NAME} - reference a cross-reference string named NAME. % \refx{NAME} - reference a cross-reference string named NAME.
\def\refx#1{% \def\refx#1{%
\requireauxfile \getrefx{#1}\thisrefX
{%
\indexnofonts
\turnoffactive
\def\value##1{##1}%
\expandafter\global\expandafter\let\expandafter\thisrefX
\csname XR#1\endcsname
}%
\ifx\thisrefX\relax \ifx\thisrefX\relax
% If not defined, say something at least. % If not defined, say something at least.
\angleleft un\-de\-fined\angleright \angleleft un\-de\-fined\angleright
@ -9335,6 +9366,17 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\fi \fi
} }
% Set #2 to xref string #1
\def\getrefx#1#2{%
\requireauxfile
{%
\indexnofonts
\turnoffactive
\def\value##1{##1}%
\expandafter\global\expandafter\let\expandafter#2\csname XR#1\endcsname
}%
}
% This is the macro invoked by entries in the aux file. Define a control % This is the macro invoked by entries in the aux file. Define a control
% sequence for a cross-reference target (we prepend XR to the control sequence % sequence for a cross-reference target (we prepend XR to the control sequence
% name to avoid collisions). The value is the page number. If this is a float % name to avoid collisions). The value is the page number. If this is a float
@ -9399,12 +9441,14 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% Read the last existing aux file, if any. No error if none exists. % Read the last existing aux file, if any. No error if none exists.
% %
\def\tryauxfile{% \def\tryauxfile{%
\ifxetex\xetexpreauxfile\fi
\openin 1 \jobname.aux \openin 1 \jobname.aux
\ifeof 1 \else \ifeof 1 \else
\readdatafile{aux}% \readdatafile{aux}%
\global\havexrefstrue \global\havexrefstrue
\fi \fi
\closein 1 \closein 1
\ifxetex\xetexpostauxfile\fi
} }
\def\setupdatafile{% \def\setupdatafile{%
@ -9790,14 +9834,15 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\global\advance\floatno by 1 \global\advance\floatno by 1
% %
{% {%
% This magic value for \currentsection is output by \setref as the % This magic value for the third argument of \setref is output as
% XREFLABEL-title value. \xrefX uses it to distinguish float % the XREFLABEL-title value. \xrefX uses it to distinguish float
% labels (which have a completely different output format) from % labels (which have a completely different output format) from
% node and anchor labels. And \xrdef uses it to construct the % node and anchor labels. And \xrdef uses it to construct the
% lists of floats. % lists of floats.
% %
\edef\currentsection{\floatmagic=\safefloattype}% \edef\tmp{\noexpand\setref{\floatlabel}{Yfloat}%
\setref{\floatlabel}{Yfloat}% {\floatmagic=\safefloattype}}%
\tmp
}% }%
\fi \fi
% %
@ -9919,7 +9964,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% #1 is the control sequence we are passed; we expand into a conditional % #1 is the control sequence we are passed; we expand into a conditional
% which is true if #1 represents a float ref. That is, the magic % which is true if #1 represents a float ref. That is, the magic
% \currentsection value which we \setref above. % value which we passed to \setref above.
% %
\def\iffloat#1{\expandafter\doiffloat#1==\finish} \def\iffloat#1{\expandafter\doiffloat#1==\finish}
% %
@ -9976,6 +10021,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\toksA = \expandafter{\csname XR#1-lof\endcsname}% \toksA = \expandafter{\csname XR#1-lof\endcsname}%
% %
% use the same \entry macro we use to generate the TOC and index. % use the same \entry macro we use to generate the TOC and index.
\let\entry\entryinternal
\edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
\writeentry \writeentry
}} }}
@ -10071,17 +10117,24 @@ directory should work if nowhere else does.}
\fi \fi
\fi \fi
\let\xetexpreauxfile\relax
\let\xetexpostauxfile\relax
% Set I/O by bytes instead of UTF-8 sequence for XeTeX and LuaTex % Set I/O by bytes instead of UTF-8 sequence for XeTeX and LuaTex
% for non-UTF-8 (byte-wise) encodings. % for non-UTF-8 (byte-wise) encodings.
% %
\def\setbytewiseio{% \def\setbytewiseio{%
\ifxetex \ifxetex
\XeTeXdefaultencoding "bytes" % For subsequent files to be read % For document root file
\XeTeXinputencoding "bytes" % For document root file \XeTeXinputencoding "bytes"
% Unfortunately, there seems to be no corresponding XeTeX command for %
% output encoding. This is a problem for auxiliary index and TOC files. % Setting for subsequent files to be read with @include.
% The only solution would be perhaps to write out @U{...} sequences in \XeTeXdefaultencoding "bytes"
% place of non-ASCII characters. %
% Use UTF-8 for reading auxiliary index and TOC files, which are
% always output in UTF-8 with XeTeX.
\def\xetexpreauxfile{\XeTeXdefaultencoding "UTF-8"}%
\def\xetexpostauxfile{\XeTeXdefaultencoding "bytes"}%
\fi \fi
\ifluatex \ifluatex
@ -10713,12 +10766,12 @@ directory should work if nowhere else does.}
% Suppress ligature creation from adjacent characters. % Suppress ligature creation from adjacent characters.
\ifluatex \ifluatex
\def\nolig{{}}
\else
% Braces do not suppress ligature creation in LuaTeX, e.g. in of{}fice % Braces do not suppress ligature creation in LuaTeX, e.g. in of{}fice
% to suppress the "ff" ligature. Using a kern appears to be the only % to suppress the "ff" ligature. Using a kern appears to be the only
% workaround. % workaround.
\def\nolig{\kern0pt{}} \def\nolig{\kern0pt{}}
\else
\def\nolig{{}}
\fi \fi
% https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_M % https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_M

View file

@ -6769,6 +6769,15 @@ the following settings are required:
@end group @end group
@end lisp @end lisp
@vindex warning-suppress-types
@value{tramp} warnings are displayed in the @file{*Warnings*} buffer,
which pops up. If you don't want to see this buffer for every
@value{tramp} warning, set @code{warning-suppress-types}:
@lisp
(setq warning-suppress-types '((tramp)))
@end lisp
If @code{tramp-verbose} is greater than or equal to 10, Lisp If @code{tramp-verbose} is greater than or equal to 10, Lisp
backtraces are also added to the @value{tramp} debug buffer in case of backtraces are also added to the @value{tramp} debug buffer in case of
errors. errors.

View file

@ -1471,7 +1471,7 @@ faces. Example:
(use-package example (use-package example
:custom-face :custom-face
(example-1-face ((t (:foreground "LightPink")))) (example-1-face ((t (:foreground "LightPink"))))
(example-2-face ((t (:foreground "LightGreen"))) face-defspec-spec)) (example-2-face ((t (:foreground "LightGreen")))))
@end group @end group
@group @group
@ -1486,6 +1486,11 @@ faces. Example:
@end group @end group
@end lisp @end lisp
Similarly to @code{:custom} (@pxref{User options}), this allows
configuring customizable faces outside of Customize (@pxref{Saving
Customizations,,, emacs, GNU Emacs Manual}). Using both systems to
configure the same face can lead to confusing results.
@node Hiding minor modes @node Hiding minor modes
@section Hiding minor modes with diminish and delight @section Hiding minor modes with diminish and delight
@cindex hiding minor modes @cindex hiding minor modes

View file

@ -19,11 +19,11 @@ such as --prefix):
./configure --enable-checking='yes,glyphs' --enable-check-lisp-object-type \ ./configure --enable-checking='yes,glyphs' --enable-check-lisp-object-type \
CFLAGS='-O0 -g3' CFLAGS='-O0 -g3'
The -O0 flag is important, as debugging optimized code can be hard. The -O0 flag is important, as debugging optimized code can be hard, even
If the problem happens only with optimized code, you may need to in the case that the -Og compiler option is used.[1] If the problem
enable optimizations. If that happens, try using -Og first instead of happens only with optimized code, you may need to enable optimizations.
-O2, as -Og disables some optimizations that make debugging some code If that happens, try using -Og first instead of -O2, as -Og disables
exceptionally hard. some optimizations that make debugging some code exceptionally hard.
Older versions of GCC may need more than just the -g3 flag. For more, Older versions of GCC may need more than just the -g3 flag. For more,
search for "analyze failed assertions" below. search for "analyze failed assertions" below.
@ -38,6 +38,9 @@ this below under "Debugging Emacs redisplay problems".
Emacs needs not be installed to be debugged, you can debug the binary Emacs needs not be installed to be debugged, you can debug the binary
created in the 'src' directory. created in the 'src' directory.
[1] gcc's -Og has some known problems and limitations, documented here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78685
*** Configuring GDB *** Configuring GDB
To start GDB to debug Emacs, you can simply type "gdb ./emacs RET" at To start GDB to debug Emacs, you can simply type "gdb ./emacs RET" at

View file

@ -47,6 +47,13 @@ The composition of Eglot's mode line can be fully customized by adding
or removing symbols and strings from the customizable variable or removing symbols and strings from the customizable variable
'eglot-mode-line-format' 'eglot-mode-line-format'
** Improved diagnostic-reporting performance and bugfixes (bug#77588)
Eglot remembers the LSP document version to which diagonstics reported
by the LSP server pertain. This helps in skipping useless or harmful
updates, avoiding flakiness with code actions and flickering overlays
when the buffer is changed.
* Changes in Eglot 1.18 (20/1/2025) * Changes in Eglot 1.18 (20/1/2025)

738
etc/NEWS

File diff suppressed because it is too large Load diff

View file

@ -37,15 +37,50 @@
<url type="contribute">https://www.gnu.org/software/emacs/manual/html_node/emacs/Contributing.html</url> <url type="contribute">https://www.gnu.org/software/emacs/manual/html_node/emacs/Contributing.html</url>
<launchable type="desktop-id">emacs.desktop</launchable> <launchable type="desktop-id">emacs.desktop</launchable>
<launchable type="service">emacs.service</launchable> <launchable type="service">emacs.service</launchable>
<recommends>
<control>keyboard</control>
<!-- 80×24 at 6×13 per character -->
<display_length side="longest">480</display_length>
<display_length side="shortest">312</display_length>
</recommends>
<supports>
<control>console</control>
<control>pointing</control>
<control>touch</control>
<internet/>
</supports>
<project_group>GNU</project_group> <project_group>GNU</project_group>
<project_license>GPL-3.0+ and GFDL-1.3+</project_license> <project_license>GPL-3.0+ and GFDL-1.3+</project_license>
<developer_name>Free Software Foundation</developer_name> <developer_name>Free Software Foundation</developer_name>
<screenshots> <screenshots>
<screenshot type="default"> <screenshot type="default">
<image type="source" width="632" height="354">https://www.gnu.org/software/emacs/images/appdata-26.png</image> <image type="source" width="1024" height="576">https://www.gnu.org/software/emacs/images/appdata-26.png</image>
<caption>Editing a Lisp program whilst viewing the Emacs manual.</caption> <caption>Editing a Lisp program, whilst viewing the manual</caption>
</screenshot> </screenshot>
</screenshots> </screenshots>
<!-- https://hughsie.github.io/oars/generate.html -->
<content_rating type="oars-1.1">
<!-- M-x doctor -->
<content_attribute id="violence-fantasy">moderate</content_attribute>
<content_attribute id="violence-sexual">intense</content_attribute>
<content_attribute id="drugs-alcohol">mild</content_attribute>
<content_attribute id="drugs-narcotics">mild</content_attribute>
<content_attribute id="sex-themes">moderate</content_attribute>
<content_attribute id="language-profanity">intense</content_attribute>
<!-- etc/JOKES -->
<content_attribute id="language-humor">mild</content_attribute>
<content_attribute id="sex-nudity">mild</content_attribute>
<!-- Gnus, rirc, etc. -->
<content_attribute id="social-chat">intense</content_attribute>
<!-- M-x report-emacs-bug -->
<content_attribute id="social-info">intense</content_attribute>
</content_rating>
<update_contact>emacs-devel_AT_gnu.org</update_contact> <update_contact>emacs-devel_AT_gnu.org</update_contact>
<branding> <branding>
<color type="primary" scheme_preference="light">#7f5ab6</color> <color type="primary" scheme_preference="light">#7f5ab6</color>

View file

@ -1,6 +1,6 @@
;;; modus-operandi-deuteranopia-theme.el --- Deuteranopia-optimized theme with a white background -*- lexical-binding:t -*- ;;; modus-operandi-deuteranopia-theme.el --- Deuteranopia-optimized theme with a white background -*- lexical-binding:t -*-
;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com> ;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com> ;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
@ -167,15 +167,11 @@ standard)."
(bg-completion "#c0deff") (bg-completion "#c0deff")
(bg-hover "#b2e4dc") (bg-hover "#b2e4dc")
(bg-hover-secondary "#f5d0a0") (bg-hover-secondary "#e5d7a0")
(bg-hl-line "#dae5ec") (bg-hl-line "#dae5ec")
(bg-region "#bdbdbd") (bg-region "#bdbdbd")
(fg-region "#000000") (fg-region "#000000")
(bg-char-0 "#7feaff")
(bg-char-1 "#ffaaff")
(bg-char-2 "#dff000")
(bg-mode-line-active "#d0d6ff") (bg-mode-line-active "#d0d6ff")
(fg-mode-line-active "#0f0f0f") (fg-mode-line-active "#0f0f0f")
(border-mode-line-active "#4f4f74") (border-mode-line-active "#4f4f74")
@ -216,13 +212,6 @@ standard)."
(bg-diff-context "#f3f3f3") (bg-diff-context "#f3f3f3")
;;; Paren match
(bg-paren-match "#5fcfff")
(fg-paren-match fg-main)
(bg-paren-expression "#efd3f5")
(underline-paren-match unspecified)
;;; Mappings ;;; Mappings
;;;; General mappings ;;;; General mappings
@ -257,17 +246,17 @@ standard)."
;;;; Code mappings ;;;; Code mappings
(bracket fg-main) (bracket fg-main)
(builtin magenta-warmer) (builtin yellow)
(comment yellow-cooler) (comment yellow-cooler)
(constant blue-cooler) (constant blue-faint)
(delimiter fg-main) (delimiter fg-main)
(docmarkup magenta-faint) (docmarkup magenta-faint)
(docstring green-faint) (docstring green-faint)
(fnname magenta) (fnname yellow-warmer)
(keyword magenta-cooler) (keyword blue-cooler)
(number fg-main) (number fg-main)
(operator fg-main) (operator fg-main)
(preprocessor red-cooler) (preprocessor magenta-cooler)
(punctuation fg-main) (punctuation fg-main)
(rx-backslash blue-cooler) (rx-backslash blue-cooler)
(rx-construct yellow-cooler) (rx-construct yellow-cooler)
@ -275,12 +264,19 @@ standard)."
(type cyan-cooler) (type cyan-cooler)
(variable cyan) (variable cyan)
;;;; Paren match
(bg-paren-match bg-cyan-subtle)
(fg-paren-match fg-main)
(underline-paren-match unspecified)
(bg-paren-expression bg-yellow-nuanced)
;;;; Accent mappings ;;;; Accent mappings
(accent-0 blue) (accent-0 blue-warmer)
(accent-1 yellow-warmer) (accent-1 yellow-warmer)
(accent-2 cyan) (accent-2 cyan)
(accent-3 magenta-cooler) (accent-3 yellow-cooler)
;;;; Button mappings ;;;; Button mappings
@ -291,10 +287,10 @@ standard)."
;;;; Completion mappings ;;;; Completion mappings
(fg-completion-match-0 blue) (fg-completion-match-0 blue-warmer)
(fg-completion-match-1 yellow-warmer) (fg-completion-match-1 yellow-warmer)
(fg-completion-match-2 cyan) (fg-completion-match-2 cyan)
(fg-completion-match-3 magenta-cooler) (fg-completion-match-3 yellow-cooler)
(bg-completion-match-0 unspecified) (bg-completion-match-0 unspecified)
(bg-completion-match-1 unspecified) (bg-completion-match-1 unspecified)
(bg-completion-match-2 unspecified) (bg-completion-match-2 unspecified)
@ -313,7 +309,7 @@ standard)."
(date-scheduled yellow-cooler) (date-scheduled yellow-cooler)
(date-scheduled-subtle yellow-faint) (date-scheduled-subtle yellow-faint)
(date-weekday cyan) (date-weekday cyan)
(date-weekend magenta) (date-weekend blue-cooler)
;;;; Line number mappings ;;;; Line number mappings
@ -374,7 +370,7 @@ standard)."
(fg-prose-macro magenta-cooler) (fg-prose-macro magenta-cooler)
(bg-prose-verbatim unspecified) (bg-prose-verbatim unspecified)
(fg-prose-verbatim magenta-warmer) (fg-prose-verbatim yellow)
(prose-done blue) (prose-done blue)
(prose-todo yellow-warmer) (prose-todo yellow-warmer)
@ -385,7 +381,7 @@ standard)."
(prose-table fg-alt) (prose-table fg-alt)
(prose-table-formula yellow-warmer) (prose-table-formula yellow-warmer)
(prose-tag magenta-faint) (prose-tag fg-alt)
;;;; Rainbow mappings ;;;; Rainbow mappings
@ -403,7 +399,7 @@ standard)."
(bg-search-current bg-yellow-intense) (bg-search-current bg-yellow-intense)
(bg-search-lazy bg-blue-intense) (bg-search-lazy bg-blue-intense)
(bg-search-replace bg-magenta-intense) (bg-search-replace bg-yellow-intense)
(bg-search-rx-group-0 bg-cyan-intense) (bg-search-rx-group-0 bg-cyan-intense)
(bg-search-rx-group-1 bg-magenta-intense) (bg-search-rx-group-1 bg-magenta-intense)
@ -463,11 +459,11 @@ standard)."
(fg-heading-0 cyan-cooler) (fg-heading-0 cyan-cooler)
(fg-heading-1 fg-main) (fg-heading-1 fg-main)
(fg-heading-2 yellow-faint) (fg-heading-2 yellow-faint)
(fg-heading-3 fg-alt) (fg-heading-3 blue-faint)
(fg-heading-4 magenta) (fg-heading-4 green-faint)
(fg-heading-5 green-faint) (fg-heading-5 magenta-cooler)
(fg-heading-6 red-faint) (fg-heading-6 yellow-cooler)
(fg-heading-7 cyan-warmer) (fg-heading-7 cyan)
(fg-heading-8 fg-dim) (fg-heading-8 fg-dim)
(bg-heading-0 unspecified) (bg-heading-0 unspecified)

View file

@ -1,6 +1,6 @@
;;; modus-operandi-theme.el --- Elegant, highly legible theme with a white background -*- lexical-binding:t -*- ;;; modus-operandi-theme.el --- Elegant, highly legible theme with a white background -*- lexical-binding:t -*-
;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com> ;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com> ;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
@ -170,10 +170,6 @@ which corresponds to a minimum contrast in relative luminance of
(bg-region "#bdbdbd") (bg-region "#bdbdbd")
(fg-region "#000000") (fg-region "#000000")
(bg-char-0 "#7feaff")
(bg-char-1 "#ffaaff")
(bg-char-2 "#dff000")
(bg-mode-line-active "#c8c8c8") (bg-mode-line-active "#c8c8c8")
(fg-mode-line-active "#000000") (fg-mode-line-active "#000000")
(border-mode-line-active "#5a5a5a") (border-mode-line-active "#5a5a5a")
@ -214,13 +210,6 @@ which corresponds to a minimum contrast in relative luminance of
(bg-diff-context "#f3f3f3") (bg-diff-context "#f3f3f3")
;;; Paren match
(bg-paren-match "#5fcfff")
(fg-paren-match fg-main)
(bg-paren-expression "#efd3f5")
(underline-paren-match unspecified)
;;; Mappings ;;; Mappings
;;;; General mappings ;;;; General mappings
@ -273,6 +262,13 @@ which corresponds to a minimum contrast in relative luminance of
(type cyan-cooler) (type cyan-cooler)
(variable cyan) (variable cyan)
;;;; Paren match
(bg-paren-match bg-cyan-subtle)
(fg-paren-match fg-main)
(underline-paren-match unspecified)
(bg-paren-expression bg-yellow-nuanced)
;;;; Accent mappings ;;;; Accent mappings
(accent-0 blue) (accent-0 blue)

View file

@ -1,6 +1,6 @@
;;; modus-operandi-tinted-theme.el --- Elegant, highly legible theme with a light ocher background -*- lexical-binding:t -*- ;;; modus-operandi-tinted-theme.el --- Elegant, highly legible theme with a light ochre background -*- lexical-binding:t -*-
;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com> ;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com> ;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
@ -44,7 +44,7 @@
;;;###theme-autoload ;;;###theme-autoload
(deftheme modus-operandi-tinted (deftheme modus-operandi-tinted
"Elegant, highly legible theme with a light ocher background. "Elegant, highly legible theme with a light ochre background.
Conforms with the highest legibility standard for color contrast Conforms with the highest legibility standard for color contrast
between background and foreground in any given piece of text, between background and foreground in any given piece of text,
which corresponds to a minimum contrast in relative luminance of which corresponds to a minimum contrast in relative luminance of
@ -73,18 +73,18 @@ which corresponds to a minimum contrast in relative luminance of
(red-cooler "#a0132f") (red-cooler "#a0132f")
(red-faint "#7f0000") (red-faint "#7f0000")
(red-intense "#d00000") (red-intense "#d00000")
(green "#006800") (green "#006300")
(green-warmer "#316500") (green-warmer "#306010")
(green-cooler "#00663f") (green-cooler "#00603f")
(green-faint "#2a5045") (green-faint "#2a5045")
(green-intense "#008900") (green-intense "#008900")
(yellow "#6f5500") (yellow "#6d5000")
(yellow-warmer "#884900") (yellow-warmer "#894000")
(yellow-cooler "#7a4f2f") (yellow-cooler "#602938")
(yellow-faint "#624416") (yellow-faint "#574316")
(yellow-intense "#808000") (yellow-intense "#808000")
(blue "#0031a9") (blue "#0031a9")
(blue-warmer "#3548cf") (blue-warmer "#3546c2")
(blue-cooler "#0000b0") (blue-cooler "#0000b0")
(blue-faint "#003497") (blue-faint "#003497")
(blue-intense "#0000ff") (blue-intense "#0000ff")
@ -93,10 +93,10 @@ which corresponds to a minimum contrast in relative luminance of
(magenta-cooler "#531ab6") (magenta-cooler "#531ab6")
(magenta-faint "#7c318f") (magenta-faint "#7c318f")
(magenta-intense "#dd22dd") (magenta-intense "#dd22dd")
(cyan "#005e8b") (cyan "#00598b")
(cyan-warmer "#3f578f") (cyan-warmer "#32548f")
(cyan-cooler "#005f5f") (cyan-cooler "#005f5f")
(cyan-faint "#005077") (cyan-faint "#304463")
(cyan-intense "#008899") (cyan-intense "#008899")
;;; Uncommon accent foregrounds ;;; Uncommon accent foregrounds
@ -165,15 +165,11 @@ which corresponds to a minimum contrast in relative luminance of
(bg-completion "#f0c1cf") (bg-completion "#f0c1cf")
(bg-hover "#b2e4dc") (bg-hover "#b2e4dc")
(bg-hover-secondary "#f5d0a0") (bg-hover-secondary "#dfe09f")
(bg-hl-line "#f1d5d0") (bg-hl-line "#f1d5d0")
(bg-region "#c2bcb5") (bg-region "#c2bcb5")
(fg-region "#000000") (fg-region "#000000")
(bg-char-0 "#7feaff")
(bg-char-1 "#ffaaff")
(bg-char-2 "#dff000")
(bg-mode-line-active "#cab9b2") (bg-mode-line-active "#cab9b2")
(fg-mode-line-active "#000000") (fg-mode-line-active "#000000")
(border-mode-line-active "#545454") (border-mode-line-active "#545454")
@ -214,13 +210,6 @@ which corresponds to a minimum contrast in relative luminance of
(bg-diff-context "#efe9df") (bg-diff-context "#efe9df")
;;; Paren match
(bg-paren-match "#7fdfcf")
(fg-paren-match fg-main)
(bg-paren-expression "#efd3f5")
(underline-paren-match unspecified)
;;; Mappings ;;; Mappings
;;;; General mappings ;;;; General mappings
@ -230,11 +219,11 @@ which corresponds to a minimum contrast in relative luminance of
(keybind red) (keybind red)
(name magenta) (name magenta)
(identifier yellow-cooler) (identifier yellow-faint)
(err red) (err red)
(warning yellow-warmer) (warning yellow)
(info cyan-cooler) (info green)
(underline-err red-intense) (underline-err red-intense)
(underline-warning yellow-intense) (underline-warning yellow-intense)
@ -255,30 +244,37 @@ which corresponds to a minimum contrast in relative luminance of
;;;; Code mappings ;;;; Code mappings
(bracket fg-main) (bracket fg-main)
(builtin magenta-warmer) (builtin magenta)
(comment red-faint) (comment red-faint)
(constant blue-cooler) (constant magenta-cooler)
(delimiter fg-main) (delimiter fg-main)
(docmarkup magenta-faint) (docmarkup magenta-faint)
(docstring green-faint) (docstring cyan-faint)
(fnname magenta) (fnname yellow-cooler)
(keyword magenta-cooler) (keyword blue)
(number fg-main) (number fg-main)
(operator fg-main) (operator fg-main)
(preprocessor red-cooler) (preprocessor yellow-warmer)
(punctuation fg-main) (punctuation fg-main)
(rx-backslash magenta) (rx-backslash magenta-warmer)
(rx-construct green-cooler) (rx-construct magenta-cooler)
(string blue-warmer) (string cyan)
(type cyan-cooler) (type green-warmer)
(variable cyan) (variable green-cooler)
;;;; Paren match
(bg-paren-match bg-cyan-subtle)
(fg-paren-match fg-main)
(underline-paren-match unspecified)
(bg-paren-expression bg-yellow-nuanced)
;;;; Accent mappings ;;;; Accent mappings
(accent-0 blue) (accent-0 red-cooler)
(accent-1 magenta-warmer) (accent-1 cyan)
(accent-2 cyan) (accent-2 magenta-cooler)
(accent-3 red) (accent-3 yellow-warmer)
;;;; Button mappings ;;;; Button mappings
@ -336,14 +332,14 @@ which corresponds to a minimum contrast in relative luminance of
;;;; Mail mappings ;;;; Mail mappings
(mail-cite-0 blue-faint) (mail-cite-0 cyan-cooler)
(mail-cite-1 yellow-warmer) (mail-cite-1 yellow)
(mail-cite-2 cyan-cooler) (mail-cite-2 green-warmer)
(mail-cite-3 red-cooler) (mail-cite-3 red-cooler)
(mail-part cyan) (mail-part magenta-cooler)
(mail-recipient magenta-cooler) (mail-recipient blue-warmer)
(mail-subject magenta-warmer) (mail-subject magenta-warmer)
(mail-other magenta-faint) (mail-other magenta)
;;;; Mark mappings ;;;; Mark mappings
@ -356,7 +352,7 @@ which corresponds to a minimum contrast in relative luminance of
;;;; Prompt mappings ;;;; Prompt mappings
(fg-prompt cyan-cooler) (fg-prompt green-cooler)
(bg-prompt unspecified) (bg-prompt unspecified)
;;;; Prose mappings ;;;; Prose mappings
@ -366,13 +362,13 @@ which corresponds to a minimum contrast in relative luminance of
(bg-prose-block-contents bg-dim) (bg-prose-block-contents bg-dim)
(bg-prose-code unspecified) (bg-prose-code unspecified)
(fg-prose-code cyan-cooler) (fg-prose-code green-cooler)
(bg-prose-macro unspecified) (bg-prose-macro unspecified)
(fg-prose-macro magenta-cooler) (fg-prose-macro blue-cooler)
(bg-prose-verbatim unspecified) (bg-prose-verbatim unspecified)
(fg-prose-verbatim magenta-warmer) (fg-prose-verbatim yellow-warmer)
(prose-done green) (prose-done green)
(prose-todo red) (prose-todo red)
@ -458,7 +454,7 @@ which corresponds to a minimum contrast in relative luminance of
;;;; Heading mappings ;;;; Heading mappings
(fg-heading-0 cyan-cooler) (fg-heading-0 green-cooler)
(fg-heading-1 fg-main) (fg-heading-1 fg-main)
(fg-heading-2 yellow-faint) (fg-heading-2 yellow-faint)
(fg-heading-3 fg-alt) (fg-heading-3 fg-alt)

View file

@ -1,6 +1,6 @@
;;; modus-operandi-tritanopia-theme.el --- Tritanopia-optimized theme with a white background -*- lexical-binding:t -*- ;;; modus-operandi-tritanopia-theme.el --- Tritanopia-optimized theme with a white background -*- lexical-binding:t -*-
;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com> ;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com> ;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
@ -63,7 +63,7 @@ standard)."
(bg-dim "#f2f2f2") (bg-dim "#f2f2f2")
(fg-main "#000000") (fg-main "#000000")
(fg-dim "#595959") (fg-dim "#595959")
(fg-alt "#193668") (fg-alt "#024960")
(bg-active "#c4c4c4") (bg-active "#c4c4c4")
(bg-inactive "#e0e0e0") (bg-inactive "#e0e0e0")
(border "#9f9f9f") (border "#9f9f9f")
@ -167,15 +167,11 @@ standard)."
(bg-completion "#afdfef") (bg-completion "#afdfef")
(bg-hover "#ffafbc") (bg-hover "#ffafbc")
(bg-hover-secondary "#9fdfff") (bg-hover-secondary "#abdfdd")
(bg-hl-line "#dfeaec") (bg-hl-line "#dfeaec")
(bg-region "#bdbdbd") (bg-region "#bdbdbd")
(fg-region "#000000") (fg-region "#000000")
(bg-char-0 "#ff908f")
(bg-char-1 "#bfbfff")
(bg-char-2 "#5fcfdf")
(bg-mode-line-active "#afe0f2") (bg-mode-line-active "#afe0f2")
(fg-mode-line-active "#0f0f0f") (fg-mode-line-active "#0f0f0f")
(border-mode-line-active "#2f4f44") (border-mode-line-active "#2f4f44")
@ -216,13 +212,6 @@ standard)."
(bg-diff-context "#f3f3f3") (bg-diff-context "#f3f3f3")
;;; Paren match
(bg-paren-match "#5fcfff")
(fg-paren-match fg-main)
(bg-paren-expression "#efd3f5")
(underline-paren-match unspecified)
;;; Mappings ;;; Mappings
;;;; General mappings ;;;; General mappings
@ -275,6 +264,13 @@ standard)."
(type blue-warmer) (type blue-warmer)
(variable cyan-cooler) (variable cyan-cooler)
;;;; Paren match
(bg-paren-match bg-cyan-subtle)
(fg-paren-match fg-main)
(underline-paren-match unspecified)
(bg-paren-expression bg-red-nuanced)
;;;; Accent mappings ;;;; Accent mappings
(accent-0 cyan) (accent-0 cyan)
@ -385,7 +381,7 @@ standard)."
(prose-table fg-alt) (prose-table fg-alt)
(prose-table-formula red-cooler) (prose-table-formula red-cooler)
(prose-tag magenta-faint) (prose-tag fg-alt)
;;;; Rainbow mappings ;;;; Rainbow mappings

View file

@ -1,12 +1,12 @@
;;; modus-themes.el --- Elegant, highly legible and customizable themes -*- lexical-binding:t -*- ;;; modus-themes.el --- Elegant, highly legible and customizable themes -*- lexical-binding:t -*-
;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com> ;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com> ;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
;; URL: https://github.com/protesilaos/modus-themes ;; URL: https://github.com/protesilaos/modus-themes
;; Version: 4.6.0 ;; Version: 4.7.0
;; Package-Requires: ((emacs "27.1")) ;; Package-Requires: ((emacs "28.1"))
;; Keywords: faces, theme, accessibility ;; Keywords: faces, theme, accessibility
;; This file is part of GNU Emacs. ;; This file is part of GNU Emacs.
@ -309,11 +309,12 @@ If the value is nil or otherwise does not specify two valid Modus
themes, the command `modus-themes-toggle' reverts to selecting a themes, the command `modus-themes-toggle' reverts to selecting a
theme from the list of available Modus themes. In effect, it is theme from the list of available Modus themes. In effect, it is
the same as using the command `modus-themes-select'." the same as using the command `modus-themes-select'."
:type `(choice :type (let ((themes (mapcar (lambda (theme) (list 'const theme)) modus-themes-items)))
(const :tag "No toggle" nil) `(choice
(list :tag "Pick two themes to toggle between" (const :tag "No toggle" nil)
(choice :tag "Theme one of two" ,@(mapcar (lambda (theme) (list 'const theme)) modus-themes-items)) (list :tag "Pick two themes to toggle between"
(choice :tag "Theme two of two" ,@(mapcar (lambda (theme) (list 'const theme)) modus-themes-items)))) (choice :tag "Theme one of two" ,@themes)
(choice :tag "Theme two of two" ,@themes))))
:package-version '(modus-themes . "4.0.0") :package-version '(modus-themes . "4.0.0")
:version "30.1" :version "30.1"
:group 'modus-themes) :group 'modus-themes)
@ -327,7 +328,8 @@ the same as using the command `modus-themes-select'."
:version "31.1" :version "31.1"
:group 'modus-themes) :group 'modus-themes)
(defvaralias 'modus-themes-post-load-hook 'modus-themes-after-load-theme-hook) (defvaralias 'modus-themes-post-load-hook 'modus-themes-after-load-theme-hook
"Alias for `modus-themes-after-load-theme-hook'.")
(defcustom modus-themes-after-load-theme-hook nil (defcustom modus-themes-after-load-theme-hook nil
"Hook that runs after loading a Modus theme. "Hook that runs after loading a Modus theme.
@ -1153,7 +1155,7 @@ This function is used in the macros `modus-themes-theme',
(eq value 'unspecified)) (eq value 'unspecified))
value) value)
((and (symbolp value) ((and (symbolp value)
(memq value (mapcar #'car palette))) value)
(modus-themes--retrieve-palette-value value palette)) (modus-themes--retrieve-palette-value value palette))
(t (t
'unspecified)))) 'unspecified))))
@ -1209,15 +1211,15 @@ symbol, which is safe when used as a face attribute's value."
"Render `modus-themes--list-known-themes' as completion with theme category." "Render `modus-themes--list-known-themes' as completion with theme category."
(modus-themes--completion-table 'theme (modus-themes--list-known-themes))) (modus-themes--completion-table 'theme (modus-themes--list-known-themes)))
(defun modus-themes--select-prompt () (defun modus-themes--select-prompt (&optional prompt)
"Minibuffer prompt to select a Modus theme." "Minibuffer prompt to select a Modus theme.
With optional PROMPT string, use it. Else use a generic prompt."
(let ((completion-extra-properties `(:annotation-function ,#'modus-themes--annotate-theme))) (let ((completion-extra-properties `(:annotation-function ,#'modus-themes--annotate-theme)))
(intern (intern
(completing-read (completing-read
"Select Modus theme: " (or prompt "Select Modus theme: ")
(modus-themes--completion-table-candidates) (modus-themes--completion-table-candidates)
nil t nil nil t nil 'modus-themes--select-theme-history))))
'modus-themes--select-theme-history))))
;;;###autoload ;;;###autoload
(defun modus-themes-select (theme) (defun modus-themes-select (theme)
@ -1231,13 +1233,13 @@ Disable other themes per `modus-themes-disable-other-themes'."
(defun modus-themes--toggle-theme-p () (defun modus-themes--toggle-theme-p ()
"Return non-nil if `modus-themes-to-toggle' are valid." "Return non-nil if `modus-themes-to-toggle' are valid."
(mapc (condition-case nil
(lambda (theme) (dolist (theme modus-themes-to-toggle)
(if (or (memq theme modus-themes-items) (or (memq theme modus-themes-items)
(memq theme (modus-themes--list-known-themes))) (memq theme (modus-themes--list-known-themes))
theme (error "`%s' is not part of `modus-themes-items'" theme)))
(user-error "`%s' is not part of `modus-themes-items'" theme))) (error nil)
modus-themes-to-toggle)) (:success modus-themes-to-toggle)))
;;;###autoload ;;;###autoload
(defun modus-themes-toggle () (defun modus-themes-toggle ()
@ -1294,87 +1296,88 @@ the list becomes the last. Do not modify THEMES in the process."
;;;;; Preview a theme palette ;;;;; Preview a theme palette
(defun modus-themes--list-colors-render (buffer theme &optional mappings &rest _) (defun modus-themes--list-colors-get-mappings (palette)
"Render colors in BUFFER from THEME for `modus-themes-list-colors'. "Get the semantic palette entries in PALETTE.
Optional MAPPINGS changes the output to only list the semantic PALETTE is the value of a variable like `modus-operandi-palette'."
color mappings of the palette, instead of its named colors." (seq-remove
(lambda (cell)
(stringp (cadr cell)))
palette))
(defun modus-themes--list-colors-tabulated (theme &optional mappings)
"Return a data structure of THEME palette or MAPPINGS for tabulated list."
(let* ((current-palette (modus-themes--palette-value theme mappings)) (let* ((current-palette (modus-themes--palette-value theme mappings))
(palette (if mappings (palette (if mappings
(seq-remove (lambda (cell) (modus-themes--list-colors-get-mappings current-palette)
(stringp (cadr cell))) current-palette)))
current-palette) (mapcar (lambda (cell)
current-palette)) (pcase-let* ((`(,name ,value) cell)
(current-buffer buffer) (name-string (format "%s" name))
(current-theme theme)) (value-string (format "%s" value))
(with-help-window buffer (value-string-padded (string-pad value-string 30))
(with-current-buffer standard-output (color (modus-themes-get-color-value name mappings theme))) ; resolve a semantic mapping
(erase-buffer) (list name
(when (<= (display-color-cells) 256) (vector
(insert (concat "Your display terminal may not render all color previews!\n" (if (and (symbolp value)
"It seems to only support <= 256 colors.\n\n")) (not (eq value 'unspecified)))
(put-text-property (point-min) (point) 'face 'warning)) "Yes"
;; We need this to properly render the first line. "")
(insert " ") name-string
(dolist (cell palette) (propertize value-string 'face `( :foreground ,color))
(let* ((name (car cell)) (propertize value-string-padded 'face (list :background color
(color (modus-themes-get-color-value name mappings theme)) :foreground (if (string= color "unspecified")
(pad (make-string 10 ?\s)) (readable-foreground-color (modus-themes-get-color-value 'bg-main nil theme))
(fg (if (eq color 'unspecified) (readable-foreground-color color))))))))
(progn palette)))
(readable-foreground-color (modus-themes-get-color-value 'bg-main nil theme))
(setq pad (make-string 6 ?\s)))
(readable-foreground-color color))))
(let ((old-point (point)))
(insert (format "%s %s" color pad))
(put-text-property old-point (point) 'face `( :foreground ,color)))
(let ((old-point (point)))
(insert (format " %s %s %s\n" color pad name))
(put-text-property old-point (point)
'face `( :background ,color
:foreground ,fg
:extend t)))
;; We need this to properly render the last line.
(insert " ")))
(setq-local revert-buffer-function
(lambda (_ignore-auto _noconfirm)
(modus-themes--list-colors-render current-buffer current-theme mappings)))))))
(defvar modus-themes--list-colors-prompt-history '() (defvar modus-themes-current-preview nil)
"Minibuffer history for `modus-themes--list-colors-prompt'.") (defvar modus-themes-current-preview-show-mappings nil)
(defun modus-themes--list-colors-prompt () (defun modus-themes--set-tabulated-entries ()
"Prompt for Modus theme. "Set the value of `tabulated-list-entries' with palette entries."
Helper function for `modus-themes-list-colors'." (setq-local tabulated-list-entries
(let ((def (format "%s" (modus-themes--current-theme))) (modus-themes--list-colors-tabulated modus-themes-current-preview modus-themes-current-preview-show-mappings)))
(completion-extra-properties `(:annotation-function ,#'modus-themes--annotate-theme)))
(completing-read
(format "Use palette from theme [%s]: " def)
(modus-themes--completion-table-candidates)
nil t nil
'modus-themes--list-colors-prompt-history def)))
(defun modus-themes-list-colors (theme &optional mappings) (defun modus-themes-list-colors (theme &optional mappings)
"Preview named colors of the Modus THEME of choice. "Preview the palette of the Modus THEME of choice.
With optional prefix argument for MAPPINGS preview the semantic With optional prefix argument for MAPPINGS preview only the semantic
color mappings instead of the named colors." color mappings instead of the complete palette."
(interactive (list (intern (modus-themes--list-colors-prompt)) current-prefix-arg)) (interactive
(modus-themes--list-colors-render (let ((prompt (if current-prefix-arg
(format (if mappings "*%s-list-mappings*" "*%s-list-colors*") theme) "Preview palette mappings of THEME: "
theme "Preview palette of THEME: ")))
mappings)) (list
(modus-themes--select-prompt prompt)
current-prefix-arg)))
(let ((buffer (get-buffer-create (format (if mappings "*%s-list-mappings*" "*%s-list-all*") theme))))
(with-current-buffer buffer
(let ((modus-themes-current-preview theme)
(modus-themes-current-preview-show-mappings mappings))
(modus-themes-preview-mode)))
(pop-to-buffer buffer)))
(defalias 'modus-themes-preview-colors 'modus-themes-list-colors (defalias 'modus-themes-preview-colors 'modus-themes-list-colors
"Alias of `modus-themes-list-colors'.") "Alias for `modus-themes-list-colors'.")
(defun modus-themes-list-colors-current (&optional mappings) (defun modus-themes-list-colors-current (&optional mappings)
"Call `modus-themes-list-colors' for the current Modus theme. "Like `modus-themes-list-colors' with optional MAPPINGS for the current theme."
Optional prefix argument MAPPINGS has the same meaning as for
`modus-themes-list-colors'."
(interactive "P") (interactive "P")
(modus-themes-list-colors (modus-themes--current-theme) mappings)) (modus-themes-list-colors (modus-themes--current-theme) mappings))
(defalias 'modus-themes-preview-colors-current 'modus-themes-list-colors-current (defalias 'modus-themes-preview-colors-current 'modus-themes-list-colors-current
"Alias of `modus-themes-list-colors-current'.") "Alias for `modus-themes-list-colors-current'.")
(define-derived-mode modus-themes-preview-mode tabulated-list-mode "Modus palette"
"Major mode to display a Modus themes palette."
:interactive nil
(setq-local tabulated-list-format
[("Mapping?" 10 t)
("Symbol name" 30 t)
("As foreground" 30 t)
("As background" 0 t)])
(modus-themes--set-tabulated-entries)
(tabulated-list-init-header)
(tabulated-list-print))
@ -1449,7 +1452,7 @@ color that is combined with FG-FOR-BG."
:foreground fg :foreground fg
:weight :weight
;; If we have `bold' specifically, we inherit the face of ;; If we have `bold' specifically, we inherit the face of
;; the same name. This allows the user to customize that ;; the same name. This allows the user to customise that
;; face, such as to change its font family. ;; face, such as to change its font family.
(if (and weight (not (eq weight 'bold))) (if (and weight (not (eq weight 'bold)))
weight weight
@ -1670,6 +1673,7 @@ FG and BG are the main colors."
`(tool-bar ((,c :background ,bg-dim :foreground ,fg-main))) `(tool-bar ((,c :background ,bg-dim :foreground ,fg-main)))
`(vertical-border ((,c :foreground ,border))) `(vertical-border ((,c :foreground ,border)))
;;;;; basic and/or ungrouped styles ;;;;; basic and/or ungrouped styles
`(abbrev-table-name ((,c :inherit bold)))
`(appt-notification ((,c :inherit bold :foreground ,modeline-err))) `(appt-notification ((,c :inherit bold :foreground ,modeline-err)))
`(blink-matching-paren-offscreen ((,c :background ,bg-paren-match))) `(blink-matching-paren-offscreen ((,c :background ,bg-paren-match)))
`(bold ((,c :weight bold))) `(bold ((,c :weight bold)))
@ -1720,6 +1724,25 @@ FG and BG are the main colors."
`(link ((,c :inherit button))) `(link ((,c :inherit button)))
`(link-visited ((,c :background ,bg-link-visited :foreground ,fg-link-visited :underline ,underline-link-visited))) `(link-visited ((,c :background ,bg-link-visited :foreground ,fg-link-visited :underline ,underline-link-visited)))
`(tooltip ((,c :background ,bg-active :foreground ,fg-main))) `(tooltip ((,c :background ,bg-active :foreground ,fg-main)))
;;;;; adoc-mode
`(adoc-code-face ((,c :inherit font-lock-constant-face)))
`(adoc-command-face ((,c :inherit modus-themes-prose-macro)))
`(adoc-complex-replacement-face ((,c :background ,bg-magenta-subtle :foreground ,magenta)))
`(adoc-emphasis-face ((t (:inherit bold))))
`(adoc-gen-face ((,c :foreground ,blue)))
`(adoc-meta-face ((,c :inherit modus-themes-fixed-pitch :foreground ,prose-metadata)))
`(adoc-meta-hide-face ((,c :inherit modus-themes-fixed-pitch :foreground ,prose-metadata)))
`(adoc-replacement-face ((,c :inherit font-lock-escape-face)))
`(adoc-secondary-text-face ((,c :inherit modus-themes-fixed-pitch :foreground ,prose-metadata-value)))
`(adoc-table-face ((,c :inherit modus-themes-fixed-pitch :foreground ,prose-table)))
`(adoc-title-0-face ((,c :inherit modus-themes-heading-0)))
`(adoc-title-1-face ((,c :inherit modus-themes-heading-1)))
`(adoc-title-2-face ((,c :inherit modus-themes-heading-2)))
`(adoc-title-3-face ((,c :inherit modus-themes-heading-3)))
`(adoc-title-4-face ((,c :inherit modus-themes-heading-4)))
`(adoc-title-5-face ((,c :inherit modus-themes-heading-5)))
`(adoc-typewriter-face ((,c :inherit modus-themes-prose-verbatim)))
`(adoc-verbatim-face ((,c :inherit modus-themes-prose-verbatim)))
;;;;; agda2-mode ;;;;; agda2-mode
`(agda2-highlight-bound-variable-face ((,c :inherit font-lock-variable-name-face))) `(agda2-highlight-bound-variable-face ((,c :inherit font-lock-variable-name-face)))
`(agda2-highlight-catchall-clause-face ((,c :background ,bg-inactive))) `(agda2-highlight-catchall-clause-face ((,c :background ,bg-inactive)))
@ -1849,13 +1872,14 @@ FG and BG are the main colors."
`(TeX-error-description-warning ((,c :inherit warning))) `(TeX-error-description-warning ((,c :inherit warning)))
;;;;; auto-dim-other-buffers ;;;;; auto-dim-other-buffers
`(auto-dim-other-buffers-face ((,c :background ,bg-inactive))) `(auto-dim-other-buffers-face ((,c :background ,bg-inactive)))
`(auto-dim-other-buffers-hide-face ((,c :foreground ,bg-inactive :background ,bg-inactive)))
;;;;; avy ;;;;; avy
`(avy-background-face ((,c :background ,bg-dim :foreground ,fg-dim :extend t))) `(avy-background-face ((,c :background ,bg-dim :foreground ,fg-dim :extend t)))
`(avy-goto-char-timer-face ((,c :inherit bold :background ,bg-active))) `(avy-goto-char-timer-face ((,c :inherit (bold modus-themes-search-lazy modus-themes-reset-soft))))
`(avy-lead-face ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-0))) `(avy-lead-face ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))
`(avy-lead-face-0 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-1))) `(avy-lead-face-0 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))
`(avy-lead-face-1 ((,c :inherit modus-themes-reset-soft :background ,bg-inactive))) `(avy-lead-face-1 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))
`(avy-lead-face-2 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-2))) `(avy-lead-face-2 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))
;;;;; aw (ace-window) ;;;;; aw (ace-window)
`(aw-background-face ((,c :foreground "gray50"))) `(aw-background-face ((,c :foreground "gray50")))
`(aw-key-face ((,c :inherit modus-themes-key-binding))) `(aw-key-face ((,c :inherit modus-themes-key-binding)))
@ -2028,8 +2052,8 @@ FG and BG are the main colors."
;;;;; corfu-candidate-overlay ;;;;; corfu-candidate-overlay
`(corfu-candidate-overlay-face ((t :inherit shadow))) `(corfu-candidate-overlay-face ((t :inherit shadow)))
;;;;; corfu-quick ;;;;; corfu-quick
`(corfu-quick1 ((,c :inherit bold :background ,bg-char-0))) `(corfu-quick1 ((,c :inherit (bold modus-themes-search-current))))
`(corfu-quick2 ((,c :inherit bold :background ,bg-char-1))) `(corfu-quick2 ((,c :inherit (bold modus-themes-search-current))))
;;;;; counsel ;;;;; counsel
`(counsel-active-mode ((,c :foreground ,keyword))) `(counsel-active-mode ((,c :foreground ,keyword)))
`(counsel-application-name ((,c :foreground ,name))) `(counsel-application-name ((,c :foreground ,name)))
@ -2518,10 +2542,10 @@ FG and BG are the main colors."
`(geiser-font-lock-xref-link ((,c :inherit button))) `(geiser-font-lock-xref-link ((,c :inherit button)))
;;;;; git-commit ;;;;; git-commit
`(git-commit-comment-action ((,c :inherit font-lock-comment-face))) `(git-commit-comment-action ((,c :inherit font-lock-comment-face)))
`(git-commit-comment-branch-local ((,c :inherit font-lock-comment-face :foreground ,accent-0))) `(git-commit-comment-branch-local ((,c :inherit (bold font-lock-comment-face) :foreground ,accent-0)))
`(git-commit-comment-branch-remote ((,c :inherit font-lock-comment-face :foreground ,accent-1))) `(git-commit-comment-branch-remote ((,c :inherit (bold font-lock-comment-face) :foreground ,accent-1)))
`(git-commit-comment-heading ((,c :inherit (bold font-lock-comment-face)))) `(git-commit-comment-heading ((,c :inherit (bold font-lock-comment-face))))
`(git-commit-comment-file ((,c :inherit font-lock-comment-face :foreground ,name))) `(git-commit-comment-file ((,c :inherit font-lock-comment-face :foreground ,accent-2))) ; like `magit-filename'
`(git-commit-keyword ((,c :foreground ,keyword))) `(git-commit-keyword ((,c :foreground ,keyword)))
`(git-commit-nonempty-second-line ((,c :inherit error))) `(git-commit-nonempty-second-line ((,c :inherit error)))
`(git-commit-overlong-summary ((,c :inherit warning))) `(git-commit-overlong-summary ((,c :inherit warning)))
@ -2682,6 +2706,30 @@ FG and BG are the main colors."
`(hl-fill-column-face ((,c :background ,bg-active))) `(hl-fill-column-face ((,c :background ,bg-active)))
;;;;; hl-todo ;;;;; hl-todo
`(hl-todo ((,c :inherit (bold font-lock-comment-face) :foreground ,err))) `(hl-todo ((,c :inherit (bold font-lock-comment-face) :foreground ,err)))
;;;;; howm
`(action-lock-face ((,c :inherit button)))
`(howm-mode-keyword-face (( )))
`(howm-mode-ref-face ((,c :inherit link)))
`(howm-mode-title-face ((,c :inherit modus-themes-heading-0)))
`(howm-mode-wiki-face ((,c :inherit link)))
`(howm-reminder-deadline-face ((,c :foreground ,date-deadline)))
`(howm-reminder-late-deadline-face ((,c :inherit bold :foreground ,date-deadline)))
`(howm-reminder-defer-face ((,c :foreground ,date-scheduled)))
`(howm-reminder-scheduled-face ((,c :foreground ,date-scheduled)))
`(howm-reminder-done-face ((,c :foreground ,prose-done)))
`(howm-reminder-todo-face ((,c :foreground ,prose-todo)))
`(howm-reminder-normal-face ((,c :foreground ,date-common)))
`(howm-reminder-today-face ((,c :inherit bold :foreground ,date-common)))
`(howm-reminder-tomorrow-face ((,c :inherit bold :foreground ,date-scheduled)))
`(howm-simulate-todo-mode-line-face ((,c :inherit bold)))
`(howm-view-empty-face (( )))
`(howm-view-hilit-face ((,c :inherit match)))
`(howm-view-name-face ((,c :inherit bold)))
`(iigrep-counts-face1 ((,c :foreground ,rainbow-1)))
`(iigrep-counts-face2 ((,c :foreground ,rainbow-2)))
`(iigrep-counts-face3 ((,c :foreground ,rainbow-3)))
`(iigrep-counts-face4 ((,c :foreground ,rainbow-4)))
`(iigrep-counts-face5 ((,c :foreground ,rainbow-5)))
;;;;; hydra ;;;;; hydra
`(hydra-face-amaranth ((,c :inherit bold :foreground ,yellow-warmer))) `(hydra-face-amaranth ((,c :inherit bold :foreground ,yellow-warmer)))
`(hydra-face-blue ((,c :inherit bold :foreground ,blue))) `(hydra-face-blue ((,c :inherit bold :foreground ,blue)))
@ -2695,14 +2743,16 @@ FG and BG are the main colors."
`(ibut-face ((,c :inherit button :background ,bg-link-symbolic :foreground ,fg-link-symbolic :underline ,underline-link-symbolic))) `(ibut-face ((,c :inherit button :background ,bg-link-symbolic :foreground ,fg-link-symbolic :underline ,underline-link-symbolic)))
;;;;; icomplete ;;;;; icomplete
`(icomplete-first-match ((,c :inherit modus-themes-completion-match-0))) `(icomplete-first-match ((,c :inherit modus-themes-completion-match-0)))
`(icomplete-vertical-selected-prefix-indicator-face ((,c :inherit bold :foreground ,keybind)))
`(icomplete-vertical-unselected-prefix-indicator-face ((,c :inherit shadow)))
`(icomplete-selected-match ((,c :inherit modus-themes-completion-selected))) `(icomplete-selected-match ((,c :inherit modus-themes-completion-selected)))
;;;;; ido-mode ;;;;; ido-mode
`(ido-first-match ((,c :inherit modus-themes-completion-match-0))) `(ido-first-match ((,c :inherit modus-themes-completion-match-0)))
`(ido-incomplete-regexp ((,c :inherit error))) `(ido-incomplete-regexp ((,c :inherit error)))
`(ido-indicator ((,c :inherit bold))) `(ido-indicator ((,c :inherit bold)))
`(ido-only-match ((,c :inherit ido-first-match))) `(ido-only-match ((,c :inherit ido-first-match)))
`(ido-subdir ((,c :foreground ,accent-0))) `(ido-subdir ((,c :foreground ,keyword)))
`(ido-virtual ((,c :foreground ,accent-1))) `(ido-virtual ((,c :foreground ,warning)))
;;;;; iedit ;;;;; iedit
`(iedit-occurrence ((,c :inherit modus-themes-search-lazy))) `(iedit-occurrence ((,c :inherit modus-themes-search-lazy)))
`(iedit-read-only-occurrence ((,c :inherit modus-themes-search-current))) `(iedit-read-only-occurrence ((,c :inherit modus-themes-search-current)))
@ -2803,19 +2853,19 @@ FG and BG are the main colors."
`(ivy-minibuffer-match-face-4 ((,c :inherit modus-themes-completion-match-2))) `(ivy-minibuffer-match-face-4 ((,c :inherit modus-themes-completion-match-2)))
`(ivy-remote ((,c :inherit italic))) `(ivy-remote ((,c :inherit italic)))
`(ivy-separator ((,c :inherit shadow))) `(ivy-separator ((,c :inherit shadow)))
`(ivy-subdir ((,c :foreground ,accent-0))) `(ivy-subdir ((,c :foreground ,keyword)))
`(ivy-virtual ((,c :foreground ,accent-1))) `(ivy-virtual ((,c :foreground ,warning)))
;;;;; ivy-posframe ;;;;; ivy-posframe
`(ivy-posframe-border ((,c :background ,border))) `(ivy-posframe-border ((,c :background ,border)))
`(ivy-posframe-cursor ((,c :background ,fg-main :foreground ,bg-main))) `(ivy-posframe-cursor ((,c :background ,fg-main :foreground ,bg-main)))
;;;;; jabber ;;;;; jabber
`(jabber-activity-face ((,c :foreground ,modeline-info))) `(jabber-activity-face ((,c :foreground ,modeline-info)))
`(jabber-roster-user-away ((,c :foreground ,red-faint))) `(jabber-roster-user-away ((,c :foreground ,red-faint)))
`(jabber-roster-user-xa ((,c :foreground ,magenta :slant italic))) `(jabber-roster-user-xa ((,c :foreground ,magenta :italic t)))
`(jabber-roster-user-dnd ((,c :foreground ,red :weight bold))) `(jabber-roster-user-dnd ((,c :foreground ,red :bold t)))
`(jabber-roster-user-chatty ((,c :foreground ,cyan-intense))) `(jabber-roster-user-chatty ((,c :foreground ,cyan-intense)))
`(jabber-roster-user-error ((,c :inherit error))) `(jabber-roster-user-error ((,c :inherit error)))
`(jabber-roster-user-offline ((,c :foreground ,fg-dim :slant italic))) `(jabber-roster-user-offline ((,c :foreground ,fg-dim :italic t)))
`(jabber-roster-user-online ((,c :foreground ,cyan :weight bold))) `(jabber-roster-user-online ((,c :foreground ,cyan :weight bold)))
`(jabber-chat-prompt-foreign ((,c :foreground ,red :weight bold))) `(jabber-chat-prompt-foreign ((,c :foreground ,red :weight bold)))
`(jabber-chat-prompt-system ((,c :foreground ,green))) `(jabber-chat-prompt-system ((,c :foreground ,green)))
@ -3326,7 +3376,7 @@ FG and BG are the main colors."
`(org-clock-overlay ((,c :inherit secondary-selection))) `(org-clock-overlay ((,c :inherit secondary-selection)))
`(org-code ((,c :inherit modus-themes-prose-code))) `(org-code ((,c :inherit modus-themes-prose-code)))
`(org-column ((,c :inherit default :background ,bg-dim))) `(org-column ((,c :inherit default :background ,bg-dim)))
`(org-column-title ((,c :inherit (bold default) :underline t :background ,bg-dim))) `(org-column-title ((,c :inherit (modus-themes-fixed-pitch bold default) :underline t :background ,bg-dim)))
`(org-date ((,c :inherit modus-themes-fixed-pitch :foreground ,date-common))) `(org-date ((,c :inherit modus-themes-fixed-pitch :foreground ,date-common)))
`(org-date-selected ((,c :foreground ,date-common :inverse-video t))) `(org-date-selected ((,c :foreground ,date-common :inverse-video t)))
;; NOTE 2024-03-17: Normally we do not want to add this padding ;; NOTE 2024-03-17: Normally we do not want to add this padding
@ -3706,6 +3756,9 @@ FG and BG are the main colors."
`(smerge-refined-changed (())) `(smerge-refined-changed (()))
`(smerge-refined-removed ((,c :inherit diff-refine-removed))) `(smerge-refined-removed ((,c :inherit diff-refine-removed)))
`(smerge-upper ((,c :inherit diff-removed))) `(smerge-upper ((,c :inherit diff-removed)))
;;;;; spacious-padding
`(spacious-padding-subtle-mode-line-active ((,c :foreground ,accent-0)))
`(spacious-padding-subtle-mode-line-inactive ((,c :foreground ,border)))
;;;;; speedbar ;;;;; speedbar
`(speedbar-button-face ((,c :inherit button))) `(speedbar-button-face ((,c :inherit button)))
`(speedbar-directory-face ((,c :inherit bold :foreground ,accent-0))) `(speedbar-directory-face ((,c :inherit bold :foreground ,accent-0)))
@ -3812,6 +3865,13 @@ FG and BG are the main colors."
`(term-underline ((,c :underline t))) `(term-underline ((,c :underline t)))
;;;;; textsec ;;;;; textsec
`(textsec-suspicious (( ))) `(textsec-suspicious (( )))
;;;;; tldr
`(tldr-code-block (( )))
`(tldr-command-argument ((,c :inherit font-lock-string-face)))
`(tldr-command-itself ((,c :inherit font-lock-builtin-face)))
`(tldr-description ((,c :inherit font-lock-doc-face)))
`(tldr-introduction ((,c :inherit font-lock-comment-face)))
`(tldr-title ((,c :inherit bold)))
;;;;; transient ;;;;; transient
`(transient-active-infix ((,c :inherit highlight))) `(transient-active-infix ((,c :inherit highlight)))
`(transient-amaranth ((,c :inherit bold :foreground ,yellow-warmer))) `(transient-amaranth ((,c :inherit bold :foreground ,yellow-warmer)))
@ -3834,7 +3894,9 @@ FG and BG are the main colors."
`(transient-key ((,c :inherit modus-themes-key-binding))) `(transient-key ((,c :inherit modus-themes-key-binding)))
`(transient-key-exit ((,c :inherit modus-themes-key-binding))) `(transient-key-exit ((,c :inherit modus-themes-key-binding)))
`(transient-key-noop ((,c :inherit (shadow modus-themes-key-binding)))) `(transient-key-noop ((,c :inherit (shadow modus-themes-key-binding))))
`(transient-key-recurse ((,c :inherit modus-themes-key-binding)))
`(transient-key-return ((,c :inherit modus-themes-key-binding))) `(transient-key-return ((,c :inherit modus-themes-key-binding)))
`(transient-key-stack ((,c :inherit modus-themes-key-binding)))
`(transient-key-stay ((,c :inherit modus-themes-key-binding))) `(transient-key-stay ((,c :inherit modus-themes-key-binding)))
`(transient-mismatched-key ((,c :underline t))) `(transient-mismatched-key ((,c :underline t)))
`(transient-nonstandard-key ((,c :underline t))) `(transient-nonstandard-key ((,c :underline t)))
@ -3851,6 +3913,39 @@ FG and BG are the main colors."
`(trashed-mark ((,c :inherit bold))) `(trashed-mark ((,c :inherit bold)))
`(trashed-marked ((,c :inherit modus-themes-mark-alt))) `(trashed-marked ((,c :inherit modus-themes-mark-alt)))
`(trashed-restored ((,c :inherit modus-themes-mark-sel))) `(trashed-restored ((,c :inherit modus-themes-mark-sel)))
;;;;; treemacs
`(treemacs-async-loading-face ((,c :foreground ,fg-main)))
`(treemacs-directory-face ((,c :foreground ,accent-0)))
`(treemacs-directory-collapsed-face ((,c :foreground ,accent-0)))
`(treemacs-file-face ((,c :foreground ,fg-main)))
`(treemacs-fringe-indicator-face ((,c :foreground ,fg-main)))
`(treemacs-git-added-face ((,c :inherit success)))
`(treemacs-git-commit-diff-face ((,c :foreground ,err)))
`(treemacs-git-conflict-face ((,c :inherit error)))
`(treemacs-git-ignored-face ((,c :inherit shadow)))
`(treemacs-git-modified-face ((,c :inherit warning)))
`(treemacs-git-renamed-face ((,c :inherit italic)))
`(treemacs-git-unmodified-face ((,c :foreground ,fg-main)))
`(treemacs-git-untracked-face ((,c :inherit success)))
`(treemacs-header-button-face ((,c :foreground ,fg-main)))
`(treemacs-help-column-face ((,c :inherit modus-themes-bold :foreground ,keyword)))
`(treemacs-help-title-face ((,c :foreground ,fg-main)))
`(treemacs-hl-line-face ((,c :background ,bg-hl-line :extend t)))
`(treemacs-marked-file-face ((,c :inherit modus-themes-mark-alt)))
`(treemacs-nerd-icons-face ((,c :foreground ,accent-0)))
`(treemacs-on-failure-pulse-face ((,c :foreground ,fg-main)))
`(treemacs-on-success-pulse-face ((,c :foreground ,fg-main)))
`(treemacs-peek-mode-indicator-face ((,c :foreground ,fg-main)))
`(treemacs-remote-face ((,c :foreground ,fg-main)))
`(treemacs-root-face ((,c :foreground ,accent-0)))
`(treemacs-root-remote-disconnected-face ((,c :inherit warning)))
`(treemacs-root-remote-unreadable-face ((,c :inherit warning)))
`(treemacs-root-unreadable-face ((,c :inherit error)))
`(treemacs-tags-face ((,c :foreground ,fg-main)))
`(treemacs-term-node-face ((,c :inherit modus-themes-bold :foreground ,keyword)))
`(treemacs-window-background-face ((,c :background ,bg-main)))
`(treemacs-nerd-icons-root-face ((,c :foreground ,accent-0)))
`(treemacs-nerd-icons-file-face ((,c :foreground ,accent-0)))
;;;;; tree-sitter ;;;;; tree-sitter
`(tree-sitter-hl-face:attribute ((,c :inherit font-lock-variable-name-face))) `(tree-sitter-hl-face:attribute ((,c :inherit font-lock-variable-name-face)))
`(tree-sitter-hl-face:constant.builtin ((,c :inherit tree-sitter-hl-face:constant))) `(tree-sitter-hl-face:constant.builtin ((,c :inherit tree-sitter-hl-face:constant)))
@ -3930,8 +4025,8 @@ FG and BG are the main colors."
;;;;; vertico ;;;;; vertico
`(vertico-current ((,c :inherit modus-themes-completion-selected))) `(vertico-current ((,c :inherit modus-themes-completion-selected)))
;;;;; vertico-quick ;;;;; vertico-quick
`(vertico-quick1 ((,c :inherit bold :background ,bg-char-0))) `(vertico-quick1 ((,c :inherit (bold modus-themes-search-current))))
`(vertico-quick2 ((,c :inherit bold :background ,bg-char-1))) `(vertico-quick2 ((,c :inherit (bold modus-themes-search-current))))
;;;;; vimish-fold ;;;;; vimish-fold
`(vimish-fold-fringe ((,c :foreground ,cyan))) `(vimish-fold-fringe ((,c :foreground ,cyan)))
`(vimish-fold-mouse-face ((,c :inherit modus-themes-intense-blue))) `(vimish-fold-mouse-face ((,c :inherit modus-themes-intense-blue)))
@ -3956,20 +4051,24 @@ FG and BG are the main colors."
`(vr/match-1 ((,c :inherit modus-themes-search-lazy))) `(vr/match-1 ((,c :inherit modus-themes-search-lazy)))
`(vr/match-separator-face ((,c :inherit bold :background ,bg-active))) `(vr/match-separator-face ((,c :inherit bold :background ,bg-active)))
;;;;; vterm ;;;;; vterm
;; NOTE 2023-08-10: `vterm-color-black' and `vterm-color-white'
;; use the "bright" semantic color mappings to make sure they are
;; distinct from `vterm-color-default'.
`(vterm-color-black ((,c :background ,bg-term-black :foreground ,fg-term-black))) `(vterm-color-black ((,c :background ,bg-term-black :foreground ,fg-term-black)))
`(vterm-color-blue ((,c :background ,bg-term-blue :foreground ,fg-term-blue))) `(vterm-color-bright-black ((,c :background ,bg-term-black-bright :foreground ,fg-term-black-bright)))
`(vterm-color-cyan ((,c :background ,bg-term-cyan :foreground ,fg-term-cyan)))
`(vterm-color-default ((,c :background ,bg-main :foreground ,fg-main)))
`(vterm-color-green ((,c :background ,bg-term-green :foreground ,fg-term-green)))
`(vterm-color-inverse-video ((,c :background ,bg-main :inverse-video t)))
`(vterm-color-magenta ((,c :background ,bg-term-magenta :foreground ,fg-term-magenta)))
`(vterm-color-red ((,c :background ,bg-term-red :foreground ,fg-term-red))) `(vterm-color-red ((,c :background ,bg-term-red :foreground ,fg-term-red)))
`(vterm-color-underline ((,c :underline t))) `(vterm-color-bright-red ((,c :background ,bg-term-red-bright :foreground ,fg-term-red-bright)))
`(vterm-color-white ((,c :background ,bg-term-white :foreground ,fg-term-white))) `(vterm-color-green ((,c :background ,bg-term-green :foreground ,fg-term-green)))
`(vterm-color-bright-green ((,c :background ,bg-term-green-bright :foreground ,fg-term-green-bright)))
`(vterm-color-yellow ((,c :background ,bg-term-yellow :foreground ,fg-term-yellow))) `(vterm-color-yellow ((,c :background ,bg-term-yellow :foreground ,fg-term-yellow)))
`(vterm-color-bright-yellow ((,c :background ,bg-term-yellow-bright :foreground ,fg-term-yellow-bright)))
`(vterm-color-blue ((,c :background ,bg-term-blue :foreground ,fg-term-blue)))
`(vterm-color-bright-blue ((,c :background ,bg-term-blue-bright :foreground ,fg-term-blue-bright)))
`(vterm-color-magenta ((,c :background ,bg-term-magenta :foreground ,fg-term-magenta)))
`(vterm-color-bright-magenta ((,c :background ,bg-term-magenta-bright :foreground ,fg-term-magenta-bright)))
`(vterm-color-cyan ((,c :background ,bg-term-cyan :foreground ,fg-term-cyan)))
`(vterm-color-bright-cyan ((,c :background ,bg-term-cyan-bright :foreground ,fg-term-cyan-bright)))
`(vterm-color-white ((,c :background ,bg-term-white :foreground ,fg-term-white)))
`(vterm-color-bright-white ((,c :background ,bg-term-white-bright :foreground ,fg-term-white-bright)))
`(vterm-color-inverse-video ((,c :background ,bg-main :inverse-video t)))
`(vterm-color-underline ((,c :underline t)))
;;;;; vundo ;;;;; vundo
`(vundo-default ((,c :inherit shadow))) `(vundo-default ((,c :inherit shadow)))
`(vundo-highlight ((,c :inherit (bold vundo-node) :foreground ,red))) `(vundo-highlight ((,c :inherit (bold vundo-node) :foreground ,red)))

View file

@ -1,6 +1,6 @@
;;; modus-vivendi-deuteranopia-theme.el --- Deuteranopia-optimized theme with a black background -*- lexical-binding:t -*- ;;; modus-vivendi-deuteranopia-theme.el --- Deuteranopia-optimized theme with a black background -*- lexical-binding:t -*-
;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com> ;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com> ;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
@ -167,15 +167,11 @@ standard)."
(bg-completion "#2f447f") (bg-completion "#2f447f")
(bg-hover "#45605e") (bg-hover "#45605e")
(bg-hover-secondary "#654a39") (bg-hover-secondary "#604c30")
(bg-hl-line "#2f3849") (bg-hl-line "#2f3849")
(bg-region "#5a5a5a") (bg-region "#5a5a5a")
(fg-region "#ffffff") (fg-region "#ffffff")
(bg-char-0 "#0050af")
(bg-char-1 "#7f1f7f")
(bg-char-2 "#625a00")
(bg-mode-line-active "#2a2a6a") (bg-mode-line-active "#2a2a6a")
(fg-mode-line-active "#f0f0f0") (fg-mode-line-active "#f0f0f0")
(border-mode-line-active "#8080a7") (border-mode-line-active "#8080a7")
@ -216,13 +212,6 @@ standard)."
(bg-diff-context "#1a1a1a") (bg-diff-context "#1a1a1a")
;;; Paren match
(bg-paren-match "#2f7f9f")
(fg-paren-match fg-main)
(bg-paren-expression "#453040")
(underline-paren-match unspecified)
;;; Mappings ;;; Mappings
;;;; General mappings ;;;; General mappings
@ -257,17 +246,17 @@ standard)."
;;;; Code mappings ;;;; Code mappings
(bracket fg-main) (bracket fg-main)
(builtin magenta-warmer) (builtin yellow)
(comment yellow-cooler) (comment yellow-cooler)
(constant blue-cooler) (constant blue-faint)
(delimiter fg-main) (delimiter fg-main)
(docmarkup magenta-faint) (docmarkup magenta-faint)
(docstring cyan-faint) (docstring cyan-faint)
(fnname magenta) (fnname yellow-warmer)
(keyword magenta-cooler) (keyword blue-cooler)
(number fg-main) (number fg-main)
(operator fg-main) (operator fg-main)
(preprocessor red-cooler) (preprocessor magenta-cooler)
(punctuation fg-main) (punctuation fg-main)
(rx-backslash blue-cooler) (rx-backslash blue-cooler)
(rx-construct yellow-cooler) (rx-construct yellow-cooler)
@ -275,12 +264,19 @@ standard)."
(type cyan-cooler) (type cyan-cooler)
(variable cyan) (variable cyan)
;;;; Paren match
(bg-paren-match bg-cyan-subtle)
(fg-paren-match fg-main)
(underline-paren-match unspecified)
(bg-paren-expression bg-yellow-nuanced)
;;;; Accent mappings ;;;; Accent mappings
(accent-0 blue-cooler) (accent-0 blue-warmer)
(accent-1 yellow) (accent-1 yellow)
(accent-2 cyan-cooler) (accent-2 cyan-cooler)
(accent-3 magenta-warmer) (accent-3 yellow-cooler)
;;;; Button mappings ;;;; Button mappings
@ -294,7 +290,7 @@ standard)."
(fg-completion-match-0 blue-cooler) (fg-completion-match-0 blue-cooler)
(fg-completion-match-1 yellow) (fg-completion-match-1 yellow)
(fg-completion-match-2 cyan-cooler) (fg-completion-match-2 cyan-cooler)
(fg-completion-match-3 magenta-warmer) (fg-completion-match-3 yellow-cooler)
(bg-completion-match-0 unspecified) (bg-completion-match-0 unspecified)
(bg-completion-match-1 unspecified) (bg-completion-match-1 unspecified)
(bg-completion-match-2 unspecified) (bg-completion-match-2 unspecified)
@ -313,7 +309,7 @@ standard)."
(date-scheduled yellow-cooler) (date-scheduled yellow-cooler)
(date-scheduled-subtle yellow-faint) (date-scheduled-subtle yellow-faint)
(date-weekday cyan) (date-weekday cyan)
(date-weekend magenta) (date-weekend magenta-cooler)
;;;; Line number mappings ;;;; Line number mappings
@ -374,7 +370,7 @@ standard)."
(fg-prose-macro magenta-cooler) (fg-prose-macro magenta-cooler)
(bg-prose-verbatim unspecified) (bg-prose-verbatim unspecified)
(fg-prose-verbatim magenta-warmer) (fg-prose-verbatim yellow)
(prose-done blue) (prose-done blue)
(prose-todo yellow-warmer) (prose-todo yellow-warmer)
@ -385,7 +381,7 @@ standard)."
(prose-table fg-alt) (prose-table fg-alt)
(prose-table-formula yellow-warmer) (prose-table-formula yellow-warmer)
(prose-tag magenta-faint) (prose-tag fg-alt)
;;;; Rainbow mappings ;;;; Rainbow mappings
@ -403,7 +399,7 @@ standard)."
(bg-search-current bg-yellow-intense) (bg-search-current bg-yellow-intense)
(bg-search-lazy bg-blue-intense) (bg-search-lazy bg-blue-intense)
(bg-search-replace bg-magenta-intense) (bg-search-replace bg-yellow-intense)
(bg-search-rx-group-0 bg-cyan-intense) (bg-search-rx-group-0 bg-cyan-intense)
(bg-search-rx-group-1 bg-magenta-intense) (bg-search-rx-group-1 bg-magenta-intense)
@ -464,10 +460,10 @@ standard)."
(fg-heading-1 fg-main) (fg-heading-1 fg-main)
(fg-heading-2 yellow-faint) (fg-heading-2 yellow-faint)
(fg-heading-3 blue-faint) (fg-heading-3 blue-faint)
(fg-heading-4 magenta) (fg-heading-4 green-faint)
(fg-heading-5 green-faint) (fg-heading-5 magenta-cooler)
(fg-heading-6 red-faint) (fg-heading-6 yellow-cooler)
(fg-heading-7 cyan-faint) (fg-heading-7 cyan)
(fg-heading-8 fg-dim) (fg-heading-8 fg-dim)
(bg-heading-0 unspecified) (bg-heading-0 unspecified)

View file

@ -1,6 +1,6 @@
;;; modus-vivendi-theme.el --- Elegant, highly legible theme with a black background -*- lexical-binding:t -*- ;;; modus-vivendi-theme.el --- Elegant, highly legible theme with a black background -*- lexical-binding:t -*-
;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com> ;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com> ;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
@ -170,10 +170,6 @@ which corresponds to a minimum contrast in relative luminance of
(bg-region "#5a5a5a") (bg-region "#5a5a5a")
(fg-region "#ffffff") (fg-region "#ffffff")
(bg-char-0 "#0050af")
(bg-char-1 "#7f1f7f")
(bg-char-2 "#625a00")
(bg-mode-line-active "#505050") (bg-mode-line-active "#505050")
(fg-mode-line-active "#ffffff") (fg-mode-line-active "#ffffff")
(border-mode-line-active "#959595") (border-mode-line-active "#959595")
@ -214,13 +210,6 @@ which corresponds to a minimum contrast in relative luminance of
(bg-diff-context "#1a1a1a") (bg-diff-context "#1a1a1a")
;;; Paren match
(bg-paren-match "#2f7f9f")
(fg-paren-match fg-main)
(bg-paren-expression "#453040")
(underline-paren-match unspecified)
;;; Mappings ;;; Mappings
;;;; General mappings ;;;; General mappings
@ -273,6 +262,13 @@ which corresponds to a minimum contrast in relative luminance of
(type cyan-cooler) (type cyan-cooler)
(variable cyan) (variable cyan)
;;;; Paren match
(bg-paren-match bg-cyan-subtle)
(fg-paren-match fg-main)
(underline-paren-match unspecified)
(bg-paren-expression bg-yellow-nuanced)
;;;; Accent mappings ;;;; Accent mappings
(accent-0 blue-cooler) (accent-0 blue-cooler)

View file

@ -1,6 +1,6 @@
;;; modus-vivendi-tinted-theme.el --- Elegant, highly legible theme with a night sky background -*- lexical-binding:t -*- ;;; modus-vivendi-tinted-theme.el --- Elegant, highly legible theme with a night sky background -*- lexical-binding:t -*-
;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com> ;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com> ;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
@ -71,11 +71,11 @@ which corresponds to a minimum contrast in relative luminance of
(red "#ff5f59") (red "#ff5f59")
(red-warmer "#ff6b55") (red-warmer "#ff6b55")
(red-cooler "#ff7f86") (red-cooler "#ff7f86")
(red-faint "#ff9f80") (red-faint "#ef8386")
(red-intense "#ff5f5f") (red-intense "#ff5f5f")
(green "#44bc44") (green "#44bc44")
(green-warmer "#70b900") (green-warmer "#75c13e")
(green-cooler "#00c06f") (green-cooler "#11c777")
(green-faint "#88ca9f") (green-faint "#88ca9f")
(green-intense "#44df44") (green-intense "#44df44")
(yellow "#d0bc00") (yellow "#d0bc00")
@ -165,15 +165,11 @@ which corresponds to a minimum contrast in relative luminance of
(bg-completion "#483d8a") (bg-completion "#483d8a")
(bg-hover "#45605e") (bg-hover "#45605e")
(bg-hover-secondary "#654a39") (bg-hover-secondary "#64404f")
(bg-hl-line "#303a6f") (bg-hl-line "#303a6f")
(bg-region "#555a66") (bg-region "#555a66")
(fg-region "#ffffff") (fg-region "#ffffff")
(bg-char-0 "#0050af")
(bg-char-1 "#7f1f7f")
(bg-char-2 "#625a00")
(bg-mode-line-active "#484d67") (bg-mode-line-active "#484d67")
(fg-mode-line-active "#ffffff") (fg-mode-line-active "#ffffff")
(border-mode-line-active "#979797") (border-mode-line-active "#979797")
@ -214,13 +210,6 @@ which corresponds to a minimum contrast in relative luminance of
(bg-diff-context "#1a1f30") (bg-diff-context "#1a1f30")
;;; Paren match
(bg-paren-match "#5f789f")
(fg-paren-match fg-main)
(bg-paren-expression "#453040")
(underline-paren-match unspecified)
;;; Mappings ;;; Mappings
;;;; General mappings ;;;; General mappings
@ -233,8 +222,8 @@ which corresponds to a minimum contrast in relative luminance of
(identifier yellow-faint) (identifier yellow-faint)
(err red) (err red)
(warning yellow-warmer) (warning yellow)
(info cyan-cooler) (info green-cooler)
(underline-err red-intense) (underline-err red-intense)
(underline-warning yellow) (underline-warning yellow)
@ -255,30 +244,37 @@ which corresponds to a minimum contrast in relative luminance of
;;;; Code mappings ;;;; Code mappings
(bracket fg-main) (bracket fg-main)
(builtin magenta-warmer) (builtin magenta)
(comment red-faint) (comment red-faint)
(constant blue-cooler) (constant magenta-cooler)
(delimiter fg-main) (delimiter fg-main)
(docmarkup magenta-faint) (docmarkup magenta-faint)
(docstring cyan-faint) (docstring cyan-faint)
(fnname magenta) (fnname magenta-warmer)
(keyword magenta-cooler) (keyword blue-warmer)
(number fg-main) (number fg-main)
(operator fg-main) (operator fg-main)
(preprocessor red-cooler) (preprocessor red-cooler)
(punctuation fg-main) (punctuation fg-main)
(rx-backslash magenta) (rx-backslash magenta-warmer)
(rx-construct green-cooler) (rx-construct magenta-cooler)
(string blue-warmer) (string blue)
(type cyan-cooler) (type green-cooler)
(variable cyan) (variable cyan-warmer)
;;;; Paren match
(bg-paren-match bg-cyan-subtle)
(fg-paren-match fg-main)
(underline-paren-match unspecified)
(bg-paren-expression bg-yellow-nuanced)
;;;; Accent mappings ;;;; Accent mappings
(accent-0 blue-cooler) (accent-0 magenta-cooler)
(accent-1 magenta-warmer) (accent-1 cyan)
(accent-2 cyan-cooler) (accent-2 magenta-warmer)
(accent-3 yellow) (accent-3 yellow-warmer)
;;;; Button mappings ;;;; Button mappings
@ -336,14 +332,14 @@ which corresponds to a minimum contrast in relative luminance of
;;;; Mail mappings ;;;; Mail mappings
(mail-cite-0 blue-warmer) (mail-cite-0 blue)
(mail-cite-1 yellow-cooler) (mail-cite-1 yellow-cooler)
(mail-cite-2 cyan-cooler) (mail-cite-2 cyan-cooler)
(mail-cite-3 red-cooler) (mail-cite-3 red-cooler)
(mail-part blue) (mail-part magenta-cooler)
(mail-recipient magenta-cooler) (mail-recipient blue-warmer)
(mail-subject magenta-warmer) (mail-subject magenta-warmer)
(mail-other magenta-faint) (mail-other magenta)
;;;; Mark mappings ;;;; Mark mappings
@ -356,7 +352,7 @@ which corresponds to a minimum contrast in relative luminance of
;;;; Prompt mappings ;;;; Prompt mappings
(fg-prompt cyan-cooler) (fg-prompt cyan-warmer)
(bg-prompt unspecified) (bg-prompt unspecified)
;;;; Prose mappings ;;;; Prose mappings

View file

@ -1,6 +1,6 @@
;;; modus-vivendi-tritanopia-theme.el --- Tritanopia-optimized theme with a black background -*- lexical-binding:t -*- ;;; modus-vivendi-tritanopia-theme.el --- Tritanopia-optimized theme with a black background -*- lexical-binding:t -*-
;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Copyright (C) 2019-2025 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com> ;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com> ;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
@ -63,7 +63,7 @@ standard)."
(bg-dim "#1e1e1e") (bg-dim "#1e1e1e")
(fg-main "#ffffff") (fg-main "#ffffff")
(fg-dim "#989898") (fg-dim "#989898")
(fg-alt "#c6daff") (fg-alt "#a0d7f2")
(bg-active "#535353") (bg-active "#535353")
(bg-inactive "#303030") (bg-inactive "#303030")
(border "#646464") (border "#646464")
@ -167,15 +167,11 @@ standard)."
(bg-completion "#004253") (bg-completion "#004253")
(bg-hover "#8e3e3b") (bg-hover "#8e3e3b")
(bg-hover-secondary "#00405f") (bg-hover-secondary "#204853")
(bg-hl-line "#2f3849") (bg-hl-line "#2f3849")
(bg-region "#5a5a5a") (bg-region "#5a5a5a")
(fg-region "#ffffff") (fg-region "#ffffff")
(bg-char-0 "#922a00")
(bg-char-1 "#00709f")
(bg-char-2 "#5f3faf")
(bg-mode-line-active "#003c52") (bg-mode-line-active "#003c52")
(fg-mode-line-active "#f0f0f0") (fg-mode-line-active "#f0f0f0")
(border-mode-line-active "#5f8fb4") (border-mode-line-active "#5f8fb4")
@ -216,13 +212,6 @@ standard)."
(bg-diff-context "#1a1a1a") (bg-diff-context "#1a1a1a")
;;; Paren match
(bg-paren-match "#2f7f9f")
(fg-paren-match fg-main)
(bg-paren-expression "#453040")
(underline-paren-match unspecified)
;;; Mappings ;;; Mappings
;;;; General mappings ;;;; General mappings
@ -275,6 +264,13 @@ standard)."
(type blue-warmer) (type blue-warmer)
(variable cyan-cooler) (variable cyan-cooler)
;;;; Paren match
(bg-paren-match bg-cyan-subtle)
(fg-paren-match fg-main)
(underline-paren-match unspecified)
(bg-paren-expression bg-red-nuanced)
;;;; Accent mappings ;;;; Accent mappings
(accent-0 cyan) (accent-0 cyan)
@ -385,7 +381,7 @@ standard)."
(prose-table fg-alt) (prose-table fg-alt)
(prose-table-formula red-cooler) (prose-table-formula red-cooler)
(prose-tag magenta-faint) (prose-tag fg-alt)
;;;; Rainbow mappings ;;;; Rainbow mappings

View file

@ -18,6 +18,7 @@ dnl You should have received a copy of the GNU General Public License
dnl along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. dnl along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
define(`SYSCALL_open', `ifelse(`@MIPS_N32@',`yes',`6002',`4005')') define(`SYSCALL_open', `ifelse(`@MIPS_N32@',`yes',`6002',`4005')')
dnl define(`SYSCALL_openat', `ifelse(`@MIPS_N32@',`yes',`6251',`4288')')
define(`SYSCALL_close', `ifelse(`@MIPS_N32@',`yes',`6003',`4006')') define(`SYSCALL_close', `ifelse(`@MIPS_N32@',`yes',`6003',`4006')')
define(`SYSCALL_mmap', `ifelse(`@MIPS_N32@',`yes',`6009',`4090')') define(`SYSCALL_mmap', `ifelse(`@MIPS_N32@',`yes',`6009',`4090')')
define(`SYSCALL_nanosleep', `ifelse(`@MIPS_N32@',`yes',`6034',`4166')') define(`SYSCALL_nanosleep', `ifelse(`@MIPS_N32@',`yes',`6034',`4166')')
@ -34,9 +35,14 @@ define(`SYSCALL', `ifelse(`@MIPS_N32@',`yes',` move $a4, $1
sw $4, 28($sp)')') sw $4, 28($sp)')')
define(`RESTORE', `ifelse(`@MIPS_N32@',`yes',` nop',` addi $sp, 32')') define(`RESTORE', `ifelse(`@MIPS_N32@',`yes',` nop',` addi $sp, 32')')
define(`FP', `ifelse(`@MIPS_N32@',`yes',`$s8',`$fp')')
dnl For mips64. Some assemblers don't want to assemble `daddi'. dnl For mips64. Some assemblers don't want to assemble `daddi'.
define(`DADDI2', `ifelse(`@DADDI_BROKEN@',`yes',` li $at, $2 define(`DADDI2', `ifelse(`@DADDI_BROKEN@',`yes',`.set noat
dadd $1, $1, $at',` daddi $1, $2')') li $at, $2
define(`DADDI3', `ifelse(`@DADDI_BROKEN@',`yes',` li $at, $3 dadd $1, $1, $at
dadd $1, $2, $at',` daddi $1, $2, $3')') .set at',` daddi $1, $2')')
define(`DADDI3', `ifelse(`@DADDI_BROKEN@',`yes',`.set noat
li $at, $3
dadd $1, $2, $at
.set at',` daddi $1, $2, $3')')

View file

@ -213,11 +213,11 @@ AC_CACHE_CHECK([whether MIPS NABI calling convention is used],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sgidefs.h> #include <sgidefs.h>
]], [[ ]], [[
#ifndef __mips64__ #if !defined __mips64__ && !defined __LP64__
#if _MIPS_SIM == _ABIO32 #if _MIPS_SIM == _ABIO32
OABI in use. OABI in use.
#endif /* _MIPS_SIM == _ABIO32 */ #endif /* _MIPS_SIM == _ABIO32 */
#endif /* !__mips64__ */ #endif /* !__mips64__ && !defined __LP64__ */
]])], [exec_cv_mips_nabi=yes], ]])], [exec_cv_mips_nabi=yes],
[exec_cv_mips_nabi=no])]) [exec_cv_mips_nabi=no])])
@ -455,12 +455,12 @@ AS_CASE([$host], [x86_64-*linux*],
.section text .section text
.global __start .global __start
__start: __start:
li $t0, 0 li \$t0, 0
li $t1, 0 li \$t1, 0
daddi $t0, $t1, 1 daddi \$t0, \$t1, 1
daddi $t0, $t1, -1 daddi \$t0, \$t1, -1
daddi $t0, -1 daddi \$t0, -1
daddi $t0, 1 daddi \$t0, 1
_ACEOF _ACEOF
$AS $ASFLAGS conftest.s -o conftest.$OBJEXT \ $AS $ASFLAGS conftest.s -o conftest.$OBJEXT \
@ -470,7 +470,8 @@ _ACEOF
AS_IF([test "x$exec_cv_as_daddi" != "xyes"], AS_IF([test "x$exec_cv_as_daddi" != "xyes"],
[DADDI_BROKEN=yes]) [DADDI_BROKEN=yes])
exec_CHECK_LINUX_CLONE3 exec_CHECK_LINUX_CLONE3
exec_CHECK_MIPS_NABI AC_DEFINE([MIPS_NABI], [1],
[Define to 1 if MIPS NABI calling convention is being used.])
LOADERFLAGS="$LOADERFLAGS $LDPREFIX-Ttext=0x3e00000000" LOADERFLAGS="$LOADERFLAGS $LDPREFIX-Ttext=0x3e00000000"
is_mips=yes is_mips=yes
exec_loader=loader-mips64el.s], [*], exec_loader=loader-mips64el.s], [*],

View file

@ -231,10 +231,10 @@ struct exec_jump_command
/* The value of AT_BASE inside the aux vector. */ /* The value of AT_BASE inside the aux vector. */
USER_WORD at_base; USER_WORD at_base;
#if defined __mips__ && !defined MIPS_NABI #if defined __mips__ && !defined __LP64__
/* The FPU mode to apply. */ /* The FPU mode to apply. Not used when !MIPS_NABI. */
USER_WORD fpu_mode; USER_WORD fpu_mode;
#endif /* defined __mips__ && !defined MIPS_NABI */ #endif /* defined __mips__ && !defined __LP64__ */
}; };
@ -831,7 +831,7 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
assert (new3 == new + effective_size); assert (new3 == new + effective_size);
/* And that it is properly aligned. */ /* And that it is properly aligned. */
assert (!(new3 & (sizeof new3 - 2))); assert (!(new3 & (sizeof new3 - 1)));
/* Now modify the system call argument to point to new + /* Now modify the system call argument to point to new +
text_size. */ text_size. */
@ -916,7 +916,9 @@ exec_0 (char *name, struct exec_tracee *tracee,
program_header program; program_header program;
USER_WORD entry, program_entry, offset; USER_WORD entry, program_entry, offset;
USER_WORD header_offset; USER_WORD header_offset;
USER_WORD name_len, aligned_len;
struct exec_jump_command jump; struct exec_jump_command jump;
/* This also encompasses !__LP64__. */
#if defined __mips__ && !defined MIPS_NABI #if defined __mips__ && !defined MIPS_NABI
int fpu_mode; int fpu_mode;
#endif /* defined __mips__ && !defined MIPS_NABI */ #endif /* defined __mips__ && !defined MIPS_NABI */
@ -1129,7 +1131,9 @@ exec_0 (char *name, struct exec_tracee *tracee,
fpu_mode = FP_FRE; fpu_mode = FP_FRE;
jump.fpu_mode = fpu_mode; jump.fpu_mode = fpu_mode;
#endif /* defined __mips__ && !defined MIPS_NABI */ #elif defined __mips__ && !defined __LP64__
jump.fpu_mode = 0;
#endif /* defined __mips__ && defined MIPS_NABI && !defined __LP64__ */
/* The offset used for at_phdr should be that of the first /* The offset used for at_phdr should be that of the first
mapping. */ mapping. */
@ -1146,6 +1150,23 @@ exec_0 (char *name, struct exec_tracee *tracee,
sizeof jump); sizeof jump);
loader_area_used += sizeof jump; loader_area_used += sizeof jump;
/* Copy the length of NAME and NAME itself to the loader area. */
name_len = strlen (name);
aligned_len = ((name_len + 1 + sizeof name_len - 1)
& -sizeof name_len);
if (sizeof loader_area - loader_area_used
< aligned_len + sizeof name_len)
goto fail1;
memcpy (loader_area + loader_area_used, &name_len, sizeof name_len);
loader_area_used += sizeof name_len;
memcpy (loader_area + loader_area_used, name, name_len + 1);
loader_area_used += name_len + 1;
/* Properly align the loader area. */
offset = aligned_len - (name_len + 1);
while (offset--)
loader_area[loader_area_used++] = '\0';
/* Close the file descriptor and return the number of bytes /* Close the file descriptor and return the number of bytes
used. */ used. */

View file

@ -152,6 +152,10 @@ struct exec_tracee
completion. */ completion. */
USER_WORD sp; USER_WORD sp;
/* ID of the system call that is pending completion. This value is
not available as the call number is overwritten on success. */
USER_WORD callno;
/* Name of the executable being run. */ /* Name of the executable being run. */
char *exec_file; char *exec_file;

View file

@ -22,68 +22,68 @@
.section .text .section .text
.global _start .global _start
_start: _start:
//mov x8, 101 // SYS_nanosleep // mov x8, 101 // SYS_nanosleep
//adr x0, timespec // req // adr x0, timespec // req
//mov x1, #0 // rem // mov x1, #0 // rem
//svc #0 // syscall // svc #0 // syscall
mov x20, sp // x20 = sp mov x20, sp // x20 = sp
ldr x10, [x20] // x10 = original SP ldr x10, [x20] // x10 = original SP
add x20, x20, #16 // x20 = start of load area add x20, x20, #16 // x20 = start of load area
mov x28, #-1 // x28 = secondary fd mov x28, #-1 // x28 = secondary fd
.next_action: next_action:
ldr x11, [x20] // action number ldr x11, [x20] // action number
and x12, x11, #-17 // actual action number and x12, x11, #-17 // actual action number
cbz x12, .open_file // open file? cbz x12, open_file // open file?
cmp x12, #3 // jump? cmp x12, #3 // jump?
beq .rest_of_exec beq rest_of_exec
cmp x12, #4 // anonymous mmap? cmp x12, #4 // anonymous mmap?
beq .do_mmap_anon beq do_mmap_anon
.do_mmap: do_mmap:
ldr x0, [x20, 8] // vm_address ldr x0, [x20, 8] // vm_address
ldr x1, [x20, 32] // length ldr x1, [x20, 32] // length
ldr x2, [x20, 24] // protection ldr x2, [x20, 24] // protection
ldr x3, [x20, 40] // flags ldr x3, [x20, 40] // flags
tst x11, #16 // primary fd? tst x11, #16 // primary fd?
mov x4, x29 // primary fd mov x4, x29 // primary fd
beq .do_mmap_1 beq do_mmap_1
mov x4, x28 // secondary fd mov x4, x28 // secondary fd
.do_mmap_1: do_mmap_1:
mov x8, #222 // SYS_mmap mov x8, #222 // SYS_mmap
ldr x5, [x20, 16] // file_offset ldr x5, [x20, 16] // file_offset
svc #0 // syscall svc #0 // syscall
ldr x9, [x20, 8] // length ldr x9, [x20, 8] // length
cmp x0, x9 // mmap result cmp x0, x9 // mmap result
bne .perror // print error bne perror // print error
ldr x3, [x20, 48] // clear ldr x3, [x20, 48] // clear
add x1, x1, x0 // x1 = vm_address + end add x1, x1, x0 // x1 = vm_address + end
sub x3, x1, x3 // x3 = x1 - clear sub x3, x1, x3 // x3 = x1 - clear
mov x0, #0 // x0 = 0 mov x0, #0 // x0 = 0
.fill64: fill64:
sub x2, x1, x3 // x2 = x1 - x3 sub x2, x1, x3 // x2 = x1 - x3
cmp x2, #63 // x2 >= 64? cmp x2, #63 // x2 >= 64?
ble .fillb // start filling bytes ble fillb // start filling bytes
stp x0, x0, [x3] // x3[0] = 0, x3[1] = 0 stp x0, x0, [x3] // x3[0] = 0, x3[1] = 0
stp x0, x0, [x3, 16] // x3[2] = 0, x3[3] = 0 stp x0, x0, [x3, 16] // x3[2] = 0, x3[3] = 0
stp x0, x0, [x3, 32] // x3[4] = 0, x3[5] = 0 stp x0, x0, [x3, 32] // x3[4] = 0, x3[5] = 0
stp x0, x0, [x3, 48] // x3[6] = 0, x3[7] = 0 stp x0, x0, [x3, 48] // x3[6] = 0, x3[7] = 0
add x3, x3, #64 // x3 += 8 add x3, x3, #64 // x3 += 8
b .fill64 b fill64
.fillb: fillb:
cmp x1, x3 // x1 == x3? cmp x1, x3 // x1 == x3?
beq .continue // done beq continue // done
strb w0, [x3], #1 // ((char *) x3)++ = 0 strb w0, [x3], #1 // ((char *) x3)++ = 0
b .fillb b fillb
.continue: continue:
add x20, x20, #56 // next action add x20, x20, #56 // next action
b .next_action b next_action
.do_mmap_anon: do_mmap_anon:
ldr x0, [x20, 8] // vm_address ldr x0, [x20, 8] // vm_address
ldr x1, [x20, 32] // length ldr x1, [x20, 32] // length
ldr x2, [x20, 24] // protection ldr x2, [x20, 24] // protection
ldr x3, [x20, 40] // flags ldr x3, [x20, 40] // flags
mov x4, #-1 // fd mov x4, #-1 // fd
b .do_mmap_1 b do_mmap_1
.open_file: open_file:
mov x8, #56 // SYS_openat mov x8, #56 // SYS_openat
mov x0, #-100 // AT_FDCWD mov x0, #-100 // AT_FDCWD
add x1, x20, #8 // file name add x1, x20, #8 // file name
@ -91,19 +91,19 @@ _start:
mov x3, #0 // mode mov x3, #0 // mode
svc #0 // syscall svc #0 // syscall
cmp x0, #-1 // rc < 0? cmp x0, #-1 // rc < 0?
ble .perror ble perror
mov x19, x1 // x19 == x1 mov x19, x1 // x19 == x1
.nextc: nextc:
ldrb w2, [x1], #1 // b = *x1++ ldrb w2, [x1], #1 // b = *x1++
cmp w2, #47 // dir separator? cmp w2, #47 // dir separator?
bne .nextc1 // not dir separator bne nextc1 // not dir separator
mov x19, x1 // x19 = char past separator mov x19, x1 // x19 = char past separator
.nextc1: nextc1:
cbnz w2, .nextc // b? cbnz w2, nextc // b?
add x1, x1, #7 // round up x1 add x1, x1, #7 // round up x1
and x20, x1, #-8 // mask for round, set x20 and x20, x1, #-8 // mask for round, set x20
tst x11, #16 // primary fd? tst x11, #16 // primary fd?
bne .secondary // secondary fd bne secondary // secondary fd
mov x29, x0 // primary fd mov x29, x0 // primary fd
mov x8, #167 // SYS_prctl mov x8, #167 // SYS_prctl
mov x0, #15 // PR_SET_NAME mov x0, #15 // PR_SET_NAME
@ -113,75 +113,117 @@ _start:
mov x4, #0 // arg4 mov x4, #0 // arg4
mov x5, #0 // arg5 mov x5, #0 // arg5
svc #0 // syscall svc #0 // syscall
b .next_action // next action b next_action // next action
.secondary: secondary:
mov x28, x0 // secondary fd mov x28, x0 // secondary fd
b .next_action // next action. b next_action // next action.
.perror: perror:
mov x8, #93 // SYS_exit mov x8, #93 // SYS_exit
mvn x0, x0 // x1 = ~x0 mvn x0, x0 // x1 = ~x0
add x0, x0, 1 // x1 += 1 add x0, x0, 1 // x1 += 1
svc #0 // exit svc #0 // exit
.rest_of_exec: rest_of_exec:
mov x7, x20 // x7 = x20 mov x7, x20 // x7 = x20
mov x20, x10 // x20 = x10 mov x8, x10 // x8 = x10
ldr x9, [x20] // argc ldr x9, [x8], #16 // (void *) x8 += 2
add x9, x9, #2 // x9 += 2
lsl x9, x9, #3 // argc * 8 lsl x9, x9, #3 // argc * 8
add x20, x20, x9 // now past argv add x8, x8, x9 // now past argv
.skipenv: skip_environ:
ldr x9, [x20], #8 // x9 = *envp++ ldr x9, [x8], #8 // x9 = *envp++
cbnz x9, .skipenv // x9? cbnz x9, skip_environ // x9?
.one_auxv: // Skip the auxiliary vector.
ldr x9, [x20], #16 // x9 = *sp, sp += 2 1: ldp x11, x12, [x8], #16 // a_type, a_un.a_val
cbz x9, .cleanup // !x9? cbnz x11, 1b // a_type != NULL
cmp x9, #3 // is AT_PHDR? // Prepare sufficient space at x20 for the file name string.
beq .replace_phdr // replace // Load the aforesaid string, and its length.
cmp x9, #4 // is AT_PHENT? ldr x6, [x7, 56] // string length
beq .replace_phent // replace add x6, x6, 1
cmp x9, #5 // is AT_PHNUM? add x5, x7, 64 // string pointer
beq .replace_phnum // replace sub x4, x10, x8 // number of elements to copy
cmp x9, #9 // is AT_ENTRY? sub x7, x8, x6 // AT_EXECFN location
beq .replace_entry // replace and x7, x7, -8 // align value
cmp x9, #7 // is AT_BASE? add x4, x7, x4 // destination argc
beq .replace_base // replace and x4, x4, -16 // align destination argc
b .one_auxv // next auxv // Load values that must be preserved into registers x14-x19.
.replace_phdr: // x14 = cmd->entry
ldr x9, [x7, 40] // at_phdr // x15 = cmd->at_entry
str x9, [x20, -8] // store value // x16 = cmd->at_phent
b .one_auxv // x17 = cmd->at_phnum
.replace_phent: // x18 = cmd->at_phdr
ldr x9, [x7, 24] // at_phent // x19 = cmd->at_base
str x9, [x20, -8] // store value ldp x14, x15, [x20, 8]
b .one_auxv ldp x16, x17, [x20, 24]
.replace_phnum: ldp x18, x19, [x20, 40]
ldr x9, [x7, 32] // at_phnum // Move the string to a safe location, if necessary.
str x9, [x20, -8] // store value sub x3, x4, x5 // distance from dest to string
b .one_auxv cmp x3, x6 // distance > length
.replace_entry: bge copy_env_and_args // not necessary
ldr x9, [x7, 16] // at_entry mov x2, x5 // src
str x9, [x20, -8] // store value sub x5, x4, x6 // backup string
b .one_auxv mov x1, x5 // dst
.replace_base: add x9, x2, x6 // src end
ldr x9, [x7, 48] // at_base cmp x2, x9
str x9, [x20, -8] // store value bcs copy_env_and_args
b .one_auxv 1: ldrb w3, [x2], #1
.cleanup: strb w3, [x1], #1
cmp x28, #-1 // is secondary fd set? cmp x2, x9
bne .cleanup1 // not set blo 1b
copy_env_and_args:
// Copy argc and the environment array.
mov x8, x10
mov x10, x4
1: ldr x9, [x8], #8 // envp
str x9, [x4], #8
cbnz x9, 1b
1: ldr x9, [x8], #8 // environ
str x9, [x4], #8
cbnz x9, 1b
copy_auxv:
ldp x11, x12, [x8], #16 // a_type, a_un.a_val
stp x11, x12, [x4], #16 // write value
cbz x11, cleanup // AT_NULL
cmp x11, #3 // AT_PHDR
csel x12, x18, x12, eq
cmp x11, #4 // AT_PHENT
csel x12, x16, x12, eq
cmp x11, #5 // AT_PHNUM
csel x12, x17, x12, eq
cmp x11, #9 // AT_ENTRY
csel x12, x15, x12, eq
cmp x11, #7 // AT_BASE
csel x12, x19, x12, eq
cmp x11, #31 // AT_EXECFN
csel x12, x7, x12, eq
str x12, [x4, -8] // replace value
b copy_auxv
cleanup:
// Copy the filename.
add x9, x5, x6 // end
cmp x5, x9
bcs 2f
1: ldrb w3, [x5], #1
strb w3, [x7], #1
cmp x5, x9
blo 1b
// Close file descriptors.
2: cmp x28, #-1 // is secondary fd set?
beq cleanup1 // not set
mov x8, #57 // SYS_close mov x8, #57 // SYS_close
mov x0, x28 // secondary fd mov x0, x28 // secondary fd
svc #0 // syscall svc #0 // syscall
.cleanup1: cleanup1:
mov x8, #57 // SYS_close mov x8, #57 // SYS_close
mov x0, x29 // primary fd mov x0, x29 // primary fd
svc #0 // syscall svc #0 // syscall
.enter: enter:
mov sp, x10 // restore original SP mov sp, x10 // restore original SP
mov x0, #0 // clear rtld_fini mov x0, #0 // clear rtld_fini
ldr x1, [x7, 8] // branch to code br x14
br x1
timespec: // timespec:
.quad 10 // .quad 10
.quad 10 // .quad 10
// Local Variables:
// asm-comment-char: ?/
// End:

View file

@ -18,23 +18,23 @@
.section .text .section .text
.global _start .global _start
_start: _start:
@mov r7, #162 @ SYS_nanosleep @@ mov r7, #162 @ SYS_nanosleep
@adr r0, timespec @ req @@ adr r0, timespec @ req
@mov r1, #0 @ rem @@ mov r1, #0 @ rem
@swi #0 @ syscall @@ swi #0 @ syscall
mov r8, sp @ r8 = sp mov r8, sp @ r8 = sp
ldr r9, [r8], #8 @ r9 = original sp, r8 += 8 ldr r9, [r8], #8 @ r9 = original sp, r8 += 8
mov r14, #-1 @ r14 = secondary fd mov r14, #-1 @ r14 = secondary fd
.next_action: next_action:
ldr r11, [r8] @ r11 = action number ldr r11, [r8] @ r11 = action number
and r12, r11, #-17 @ actual action number and r12, r11, #-17 @ actual action number
cmp r12, #0 @ open file? cmp r12, #0 @ open file?
beq .open_file @ open file. beq open_file @ open file.
cmp r12, #3 @ jump? cmp r12, #3 @ jump?
beq .rest_of_exec @ jump to code. beq rest_of_exec @ jump to code.
cmp r12, #4 @ anonymous mmap? cmp r12, #4 @ anonymous mmap?
beq .do_mmap_anon @ anonymous mmap. beq do_mmap_anon @ anonymous mmap.
.do_mmap: do_mmap:
add r6, r8, #4 @ r6 = r8 + 4 add r6, r8, #4 @ r6 = r8 + 4
ldm r6!, {r0, r5} @ vm_address, file_offset ldm r6!, {r0, r5} @ vm_address, file_offset
ldm r6!, {r1, r2} @ protection, length ldm r6!, {r1, r2} @ protection, length
@ -45,28 +45,28 @@ _start:
ldm r6!, {r3, r12} @ flags, clear ldm r6!, {r3, r12} @ flags, clear
tst r11, #16 @ primary fd? tst r11, #16 @ primary fd?
mov r4, r10 @ primary fd mov r4, r10 @ primary fd
beq .do_mmap_1 beq do_mmap_1
mov r4, r14 @ secondary fd mov r4, r14 @ secondary fd
.do_mmap_1: do_mmap_1:
mov r7, #192 @ SYS_mmap2 mov r7, #192 @ SYS_mmap2
swi #0 @ syscall swi #0 @ syscall
ldr r2, [r8, #4] @ vm_address ldr r2, [r8, #4] @ vm_address
cmp r2, r0 @ rc == vm_address? cmp r2, r0 @ rc == vm_address?
bne .perror bne perror
add r0, r1, r2 @ r0 = length + vm_address add r0, r1, r2 @ r0 = length + vm_address
sub r3, r0, r12 @ r3 = r0 - clear sub r3, r0, r12 @ r3 = r0 - clear
mov r1, #0 @ r1 = 0 mov r1, #0 @ r1 = 0
.align: align:
cmp r0, r3 @ r0 == r3? cmp r0, r3 @ r0 == r3?
beq .continue @ continue beq continue @ continue
tst r3, #3 @ r3 & 3? tst r3, #3 @ r3 & 3?
bne .fill32 @ fill aligned bne fill32 @ fill aligned
strb r1, [r3], #1 @ fill byte strb r1, [r3], #1 @ fill byte
b .align @ align again b align @ align again
.fill32: fill32:
sub r2, r0, r3 @ r2 = r0 - r3 sub r2, r0, r3 @ r2 = r0 - r3
cmp r2, #31 @ r2 >= 32? cmp r2, #31 @ r2 >= 32?
ble .fillb @ start filling bytes ble fillb @ start filling bytes
str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0
str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0
str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0
@ -75,16 +75,16 @@ _start:
str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0
str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0
str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0
b .fill32 b fill32
.fillb: fillb:
cmp r0, r3 @ r0 == r3 cmp r0, r3 @ r0 == r3
beq .continue @ done beq continue @ done
strb r1, [r3], #1 @ ((char *) r3)++ = 0 strb r1, [r3], #1 @ ((char *) r3)++ = 0
b .fillb b fillb
.continue: continue:
add r8, r8, #28 @ next action add r8, r8, #28 @ next action
b .next_action b next_action
.do_mmap_anon: do_mmap_anon:
add r6, r8, #4 @ r6 = r8 + 4 add r6, r8, #4 @ r6 = r8 + 4
ldm r6!, {r0, r5} @ vm_address, file_offset ldm r6!, {r0, r5} @ vm_address, file_offset
ldm r6!, {r1, r2} @ protection, length ldm r6!, {r1, r2} @ protection, length
@ -94,29 +94,29 @@ _start:
mov r2, r3 @ swap mov r2, r3 @ swap
ldm r6!, {r3, r12} @ flags, clear ldm r6!, {r3, r12} @ flags, clear
mov r4, #-1 @ fd mov r4, #-1 @ fd
b .do_mmap_1 b do_mmap_1
.open_file: open_file:
mov r7, #5 @ SYS_open mov r7, #5 @ SYS_open
add r0, r8, #4 @ file name add r0, r8, #4 @ file name
mov r1, #0 @ O_RDONLY mov r1, #0 @ O_RDONLY
mov r2, #0 @ mode mov r2, #0 @ mode
swi #0 @ syscall swi #0 @ syscall
cmp r0, #-1 @ r0 <= -1? cmp r0, #-1 @ r0 <= -1?
ble .perror ble perror
add r8, r8, #4 @ r8 = start of string add r8, r8, #4 @ r8 = start of string
mov r1, r8 @ r1 = r8 mov r1, r8 @ r1 = r8
.nextc: nextc:
ldrb r2, [r8], #1 @ b = *r0++ ldrb r2, [r8], #1 @ b = *r0++
cmp r2, #47 @ dir separator? cmp r2, #47 @ dir separator?
bne .nextc1 @ not dir separator bne nextc1 @ not dir separator
mov r1, r8 @ r1 = char past separator mov r1, r8 @ r1 = char past separator
.nextc1: nextc1:
cmp r2, #0 @ b? cmp r2, #0 @ b?
bne .nextc @ next character bne nextc @ next character
add r8, r8, #3 @ round up r8 add r8, r8, #3 @ round up r8
and r8, r8, #-4 @ mask for round, set r8 and r8, r8, #-4 @ mask for round, set r8
tst r11, #16 @ primary fd? tst r11, #16 @ primary fd?
bne .secondary @ secondary fd bne secondary @ secondary fd
mov r10, r0 @ primary fd mov r10, r0 @ primary fd
mov r7, #172 @ SYS_prctl mov r7, #172 @ SYS_prctl
mov r0, #15 @ PR_SET_NAME, r1 = name mov r0, #15 @ PR_SET_NAME, r1 = name
@ -125,79 +125,139 @@ _start:
mov r4, #0 @ arg4 mov r4, #0 @ arg4
mov r5, #0 @ arg5 mov r5, #0 @ arg5
swi #0 @ syscall swi #0 @ syscall
b .next_action @ next action b next_action @ next action
.secondary: secondary:
mov r14, r0 @ secondary fd mov r14, r0 @ secondary fd
b .next_action @ next action b next_action @ next action
.perror: perror:
mov r7, #1 @ SYS_exit mov r7, #1 @ SYS_exit
mvn r0, r0 @ r0 = ~r0 mvn r0, r0 @ r0 = ~r0
add r0, r0, #1 @ r0 += 1 add r0, r0, #1 @ r0 += 1
swi #0 swi #0
.rest_of_exec: rest_of_exec: @ r8 points to seven ints + string
mov r7, r9 @ r7 = original SP mov r7, r9 @ r7 = original SP
ldr r6, [r7] @ argc ldr r6, [r7], #8 @ argc & terminator
add r6, r6, #2 @ argc + 2
lsl r6, r6, #2 @ argc *= 4 lsl r6, r6, #2 @ argc *= 4
add r7, r7, r6 @ now past argv add r7, r7, r6 @ now past argv
.skipenv: ldr r6, [r8, #28] @ length of string
ldr r6, [r7], #4 @ r6 = *r7++ add r6, r6, #1
cmp r6, #0 @ r6? skip_environ:
bne .skipenv @ r6? 1: ldr r1, [r7], #4 @ r1 = *r7++
.one_auxv: tst r1, r1 @ r1
ldr r6, [r7], #8 @ r6 = *r7, r7 += 2 bne 1b @ r1
cmp r6, #0 @ !r6? 1: ldm r7!, {r0, r1} @ a_type, a_un.a_val
beq .cleanup @ r6? tst r0, r0
cmp r6, #3 @ is AT_PHDR? bne 1b @ a_type -> 1b
beq .replace_phdr @ replace @@ Establish the number of bytes in the argument, environment,
cmp r6, #4 @ is AT_PHENT? @@ and auxiliary vectors to be moved.
beq .replace_phent @ replace sub r5, r7, r9 @ r5 = bytes in vectors
cmp r6, #5 @ is AT_PHNUM? @@ Expand r7 with sufficient space for the filename and align
beq .replace_phnum @ replace @@ it.
cmp r6, #9 @ is AT_ENTRY? sub r4, r7, r5
beq .replace_entry @ replace and r4, r4, #-8 @ r4 = address of AT_EXECFN
cmp r6, #7 @ is AT_BASE? sub r3, r4, r5 @ r4 - number of bytes in vectors
beq .replace_base @ replace and r3, r3, #-16 @ r3 = position of new argc
b .one_auxv @ next auxv @@ Reserve an area that is guaranteed not to be clobbered into
.replace_phdr: @@ which to copy the command and file name.
ldr r6, [r8, #20] @ at_phdr mov r2, r3
str r6, [r7, #-4] @ store value cmp r2, r8
b .one_auxv blo 1f
.replace_phent: mov r2, r8
ldr r6, [r8, #12] @ at_phent 1: sub r2, r2, #24 @ space for data
str r6, [r7, #-4] @ store value @@ [r2, #0] = entry
b .one_auxv @@ [r2, #4] = at_entry
.replace_phnum: @@ [r2, #8] = at_phent
ldr r6, [r8, #16] @ at_phnum @@ [r2, #12] = at_phnum
str r6, [r7, #-4] @ store value @@ [r2, #16] = at_phdr
b .one_auxv @@ [r2, #20] = at_base
.replace_entry: add r7, r8, #4 @ &cmd->entry
ldr r6, [r8, #8] @ at_entry ldm r7!, {r0, r1}
str r6, [r7, #-4] @ store value stm r2!, {r0, r1}
b .one_auxv ldm r7!, {r0, r1}
.replace_base: stm r2!, {r0, r1}
ldr r6, [r8, #24] @ at_base ldm r7!, {r0, r1}
str r6, [r7, #-4] @ store value stm r2!, {r0, r1}
b .one_auxv sub r2, r2, #24
.cleanup: sub r0, r2, r6 @ r0 = copy of AT_EXECFN
add r1, r8, #32 @ src
add r5, r1, r6 @ src end
cmp r1, r5
bcs copy_env_and_args
1: ldrb r7, [r1], #1
strb r7, [r0], #1
cmp r1, r5
blo 1b
copy_env_and_args:
mov r5, r3
1: ldr r0, [r9], #4 @ argc and arguments
str r0, [r5], #4 @ *dst = ...
tst r0, r0
bne 1b
1: ldr r0, [r9], #4 @ environment string
str r0, [r5], #4 @ *dst = ...
tst r0, r0
bne 1b
copy_auxv:
ldm r9!, {r0, r1} @ a_type, a_un.a_val
tst r0, r0 @ AT_NULL
beq 8f
cmp r0, #3 @ AT_PHDR
beq 2f
cmp r0, #4 @ AT_PHENT
beq 3f
cmp r0, #5 @ AT_PHNUM
beq 4f
cmp r0, #9 @ AT_ENTRY
beq 5f
cmp r0, #7 @ AT_BASE
beq 6f
cmp r0, #31 @ AT_EXECFN
beq 7f
1: stm r5!, {r0, r1}
b copy_auxv
2: ldr r1, [r2, #16]
b 1b
3: ldr r1, [r2, #8]
b 1b
4: ldr r1, [r2, #12]
b 1b
5: ldr r1, [r2, #4]
b 1b
6: ldr r1, [r2, #20]
b 1b
7: mov r1, r4
b 1b
8:
stm r5!, {r0, r1}
cleanup:
@@ Copy the filename.
sub r0, r2, r6 @ src
add r1, r0, r6 @ src end
cmp r0, r1
bcs 2f
1: ldrb r5, [r0], #1
strb r5, [r4], #1 @ *dst++
cmp r0, r1
blo 1b
2: mov r9, r3 @ replace original SP
cmp r14, #-1 @ secondary fd set? cmp r14, #-1 @ secondary fd set?
bne .cleanup1 @ not set beq cleanup1 @ not set
mov r7, #6 @ SYS_close mov r7, #6 @ SYS_close
mov r0, r14 @ secondary fd mov r0, r14 @ secondary fd
swi #0 @ syscall swi #0 @ syscall
.cleanup1: cleanup1:
mov r7, #6 @ SYS_close mov r7, #6 @ SYS_close
mov r0, r10 @ primary fd mov r0, r10 @ primary fd
swi #0 @ syscall swi #0 @ syscall
.enter: enter:
mov sp, r9 @ restore original SP mov sp, r9 @ restore original SP
mov r0, #0 @ clear rtld_fini mov r0, #0 @ clear rtld_fini
ldr r1, [r8, #4] @ branch to code ldr r1, [r2] @ branch to code
bx r1 bx r1
timespec: @@ timespec:
.long 10 @@ .long 10
.long 10 @@ .long 10
@ Local Variables: @ Local Variables:
@ asm-comment-char: ?@ @ asm-comment-char: ?@

View file

@ -17,32 +17,38 @@
include(`config-mips.m4') include(`config-mips.m4')
/* These "registers" alias a4-a7 and caution must be exercised not
to overwrite them when issuing system calls. */
define(`T4', `$a4')
define(`T5', `$a5')
define(`T6', `$a6')
define(`T7', `$a7')
.set noreorder # delay slots managed by hand .set noreorder # delay slots managed by hand
.set noat # no assembler macros
.section .text .section .text
.global __start .global __start
__start: __start:
dnl li $v0, 5034 # SYS_nanosleep ## li $v0, 5034 # SYS_nanosleep
dnl dla $a0, .timespec # rqtp ## dla $a0, timespec # rqtp
dnl li $a1, 0 # rmtp ## li $a1, 0 # rmtp
dnl syscall # syscall ## syscall # syscall
ld $s2, ($sp) # original stack pointer ld $s6, ($sp) # original stack pointer
DADDI3( $s0, $sp, 16) # start of load area DADDI3( $s0, $sp, 16) # start of load area
DADDI2( $sp, -16) # primary fd, secondary fd DADDI2( $sp, -16) # primary fd, secondary fd
li $t0, -1 # secondary fd li $t0, -1 # secondary fd
sd $t0, 8($sp) # initialize secondary fd sd $t0, 8($sp) # initialize secondary fd
.next_action: next_action:
ld $s1, ($s0) # action number ld $s1, ($s0) # action number
andi $t0, $s1, 15 # t0 = action number & 15 andi $t0, $s1, 15 # t0 = action number & 15
beqz $t0, .open_file # open file? beqz $t0, open_file # open file?
nop # delay slot nop # delay slot
DADDI2( $t0, -3) # t0 -= 3 DADDI2( $t0, -3) # t0 -= 3
beqz $t0, .rest_of_exec # jump to code beqz $t0, rest_of_exec # jump to code
nop # delay slot nop # delay slot
li $t1, 1 li $t1, 1
beq $t0, $t1, .do_mmap_anon # anonymous mmap? beq $t0, $t1, do_mmap_anon # anonymous mmap?
nop # delay slot nop # delay slot
.do_mmap: do_mmap:
ld $t0, 8($s0) # vm address ld $t0, 8($s0) # vm address
ld $t1, 16($s0) # file_offset ld $t1, 16($s0) # file_offset
ld $t2, 24($s0) # protection ld $t2, 24($s0) # protection
@ -50,10 +56,10 @@ dnl syscall # syscall
ld $v0, 40($s0) # flags ld $v0, 40($s0) # flags
ld $v1, ($sp) # primary fd ld $v1, ($sp) # primary fd
andi $s3, $s1, 16 # s1 & 16? andi $s3, $s1, 16 # s1 & 16?
beqz $s3, .do_mmap_1 # secondary fd? beqz $s3, do_mmap_1 # secondary fd?
nop # delay slot nop # delay slot
ld $v1, 8($sp) # secondary fd ld $v1, 8($sp) # secondary fd
.do_mmap_1: do_mmap_1:
move $a0, $t0 # syscall arg move $a0, $t0 # syscall arg
move $a1, $t3 # syscall arg move $a1, $t3 # syscall arg
move $a2, $t2 # syscall arg move $a2, $t2 # syscall arg
@ -62,21 +68,21 @@ dnl syscall # syscall
move $a5, $t1 # syscall arg move $a5, $t1 # syscall arg
li $v0, 5009 # SYS_mmap li $v0, 5009 # SYS_mmap
syscall # syscall syscall # syscall
bne $a3, $zero, .perror # perror? bne $a3, $zero, perror # perror?
nop # delay slot nop # delay slot
ld $t1, 48($s0) # clear ld $t1, 48($s0) # clear
dadd $t0, $a0, $a1 # t0 = end of mapping dadd $t0, $a0, $a1 # t0 = end of mapping
dsub $t1, $t0, $t1 # t1 = t0 - clear dsub $t1, $t0, $t1 # t1 = t0 - clear
.align: align:
beq $t0, $t1, .continue # already finished beq $t0, $t1, continue # already finished
nop # delay slot nop # delay slot
andi $t2, $t1, 7 # t1 & 7? andi $t2, $t1, 7 # t1 & 7?
bnez $t2, .filld # start filling longs bnez $t2, filld # start filling longs
nop # delay slot nop # delay slot
.filld: filld:
dsub $t2, $t0, $t1 # t2 = t0 - t1 dsub $t2, $t0, $t1 # t2 = t0 - t1
sltiu $t2, $t2, 64 # t2 < 64? sltiu $t2, $t2, 64 # t2 < 64?
bne $t2, $zero, .fillb # fill bytes bne $t2, $zero, fillb # fill bytes
nop # delay slot nop # delay slot
sd $zero, ($t1) # zero doubleword sd $zero, ($t1) # zero doubleword
DADDI2( $t1, 8) # next doubleword DADDI2( $t1, 8) # next doubleword
@ -94,140 +100,258 @@ dnl syscall # syscall
DADDI2( $t1, 8) # next doubleword DADDI2( $t1, 8) # next doubleword
sd $zero, ($t1) # zero doubleword sd $zero, ($t1) # zero doubleword
DADDI2( $t1, 8) # next doubleword DADDI2( $t1, 8) # next doubleword
j .filld # fill either doubleword or byte j filld # fill either doubleword or byte
nop # delay slot nop # delay slot
.fillb: fillb:
beq $t0, $t1, .continue # already finished? beq $t0, $t1, continue # already finished?
nop # delay slot nop # delay slot
sb $zero, ($t1) # clear byte sb $zero, ($t1) # clear byte
DADDI2( $t1, 1) # t1++ DADDI2( $t1, 1) # t1++
.continue: continue:
DADDI2( $s0, 56) # s0 = next action DADDI2( $s0, 56) # s0 = next action
j .next_action # next action j next_action # next action
nop # delay slot nop # delay slot
.do_mmap_anon: do_mmap_anon:
ld $t0, 8($s0) # vm address ld $t0, 8($s0) # vm address
ld $t1, 16($s0) # file_offset ld $t1, 16($s0) # file_offset
ld $t2, 24($s0) # protection ld $t2, 24($s0) # protection
ld $t3, 32($s0) # length ld $t3, 32($s0) # length
ld $v0, 40($s0) # flags ld $v0, 40($s0) # flags
li $v1, -1 # fd dli $v1, -1 # fd
j .do_mmap_1 # do mmap j do_mmap_1 # do mmap
nop # branch delay slot nop # branch delay slot
.open_file: open_file:
li $v0, 5002 # SYS_open dli $v0, 5002 # SYS_open
DADDI3( $a0, $s0, 8) # start of name DADDI3( $a0, $s0, 8) # start of name
move $a1, $zero # flags = O_RDONLY move $a1, $zero # flags = O_RDONLY
move $a2, $zero # mode = 0 move $a2, $zero # mode = 0
syscall # syscall syscall # syscall
bne $a3, $zero, .perror # perror bne $a3, $zero, perror # perror
nop # delay slot nop # delay slot
DADDI2( $s0, 8) # start of string DADDI2( $s0, 8) # start of string
move $t3, $s0 # t3 = s0 move $t3, $s0 # t3 = s0
.nextc: nextc:
lb $t0, ($s0) # load byte lb $t0, ($s0) # load byte
DADDI2( $s0, 1) # s0++ DADDI2( $s0, 1) # s0++
li $t1, 47 # directory separator `/' dli $t1, 47 # directory separator `/'
bne $t0, $t1, .nextc1 # is separator char? bne $t0, $t1, nextc1 # is separator char?
nop # delay slot nop # delay slot
move $t3, $s0 # t3 = char past separator move $t3, $s0 # t3 = char past separator
.nextc1: nextc1:
bnez $t0, .nextc # next character? bnez $t0, nextc # next character?
nop # delay slot nop # delay slot
DADDI2( $s0, 7) # adjust for round DADDI2( $s0, 7) # adjust for round
li $t2, -8 # t2 = -8 dli $t2, -8 # t2 = -8
and $s0, $s0, $t2 # mask for round and $s0, $s0, $t2 # mask for round
andi $t0, $s1, 16 # t1 = s1 & 16 andi $t0, $s1, 16 # t1 = s1 & 16
move $t1, $sp # address of primary fd move $t1, $sp # address of primary fd
beqz $t0, .primary # primary fd? beqz $t0, primary # primary fd?
nop # delay slot nop # delay slot
DADDI2( $t1, 8) # address of secondary fd DADDI2( $t1, 8) # address of secondary fd
sd $v0, ($t1) # store fd sd $v0, ($t1) # store fd
j .next_action # next action j next_action # next action
nop # delay slot nop # delay slot
.primary: primary:
sd $v0, ($t1) # store fd sd $v0, ($t1) # store fd
li $v0, 5153 # SYS_prctl dli $v0, 5153 # SYS_prctl
li $a0, 15 # PR_SET_NAME dli $a0, 15 # PR_SET_NAME
move $a1, $t3 # char past separator move $a1, $t3 # char past separator
move $a2, $zero # a2 move $a2, $zero # a2
move $a3, $zero # a3 move $a3, $zero # a3
move $a4, $zero # a4 move $a4, $zero # a4
move $a5, $zero # a5 move $a5, $zero # a5
syscall # syscall syscall # syscall
j .next_action # next action j next_action # next action
nop # delay slot nop # delay slot
.perror: perror:
move $a0, $v0 # errno move $a0, $v0 # errno
li $v0, 5058 # SYS_exit dli $v0, 5058 # SYS_exit
syscall # syscall syscall # syscall
.rest_of_exec: rest_of_exec:
move $s1, $s2 # original SP move $s1, $s6 # original SP
ld $t0, ($s1) # argc ld $t0, ($s1) # argc
dsll $t0, $t0, 3 # argc *= 8 dsll $t0, $t0, 3 # argc *= 8
DADDI2( $t0, 16) # argc += 16 DADDI2( $t0, 16) # argc += 16
dadd $s1, $s1, $t0 # s1 = start of envp dadd $s1, $s1, $t0 # s1 = start of envp
.skipenv: skip_environ:
ld $t0, ($s1) # t0 = *s1 /* Locate the auxiliary vector. */
DADDI2( $s1, 8) # s1++ li $t8, 8 # DADDI2 isn't appropriate in delay slots.
bne $t0, $zero, .skipenv # skip again 1: ld $t0, ($s1) # t0 = *s1
nop # delay slot bnez $t0, 1b # skip environment entry
dla $t3, .auxvtab # address of auxv table dadd $s1, $s1, $t8 # s1++
.one_auxv: move $s2, $s1 # s2 = end of environment
ld $t0, ($s1) # t0 = auxv type li $t8, 16
li $t1, 10 # t1 = 10 1: ld $t0, ($s1) # t0 = s1->a_type
beqz $t0, .finish # is AT_IGNORE? bnez $t0, 1b # skip auxiliary vector entry
nop # delay slot dadd $s1, $s1, $t8 # (Elf64_auxv_t *) s1++
sltu $t1, $t0, $t1 # t1 = t0 < num offsets /* Decide how many bytes must be copied and where to
beqz $t1, .next # next auxv save the file name. Move the stack pointer to a safe
nop # delay slot position below any data that must be preserved. */
dsll $t1, $t0, 2 # t1 = t0 * 4 ld $t1, 56($s0) # length of string
dadd $t1, $t3, $t1 # t1 = .auxvtab + t1 DADDI2( $t1, 1)
lw $t2, ($t1) # t2 = *t1 DADDI3( $t2, $s0, 64) # pointer to string
beqz $t2, .next # skip auxv dsub $t3, $s1, $s6 # number of bytes in vectors
nop # delay slot dsub $t0, $s1, $t1 # position of string
dadd $t2, $s0, $t2 # t2 = s0 + t2 and $t0, $t0, -16 # align value
ld $t2, ($t2) # t2 = *t2 dsub $t3, $t0, $t3 # position of argc
sd $t2, 8($s1) # set auxv value and $t3, $t3, -16 # align value
.next: /* Move the stack pointer and save required information.
DADDI2( $s1, 16) # next auxv 8($fp) = secondary/interpreter fd.
j .one_auxv # next auxv 0($fp) = primary/executable fd.
nop # delay slot -8($fp) = cmd->entry
.finish: -16($fp) = cmd->at_entry
ld $t0, 8($sp) # secondary fd -24($fp) = cmd->at_phent
-32($fp) = cmd->at_phnum
-40($fp) = cmd->at_phdr
-48($fp) = cmd->at_base
$sp = copy of string. */
move T4, $sp # current sp
dsub T5, $t3, $sp # new argc - current sp
li $t8, -16
blt T5, 16, 1f # more than two slots apart
dadd $sp, $t3, $t8 # $sp = two slots below new argc
j 2f # skip copying fds
move $sp, T4 # retain current sp
1: ld T5, (T4) # old primary fd
ld T5, ($sp) # save the same
ld T5, 8(T4) # old interpreter fd
sd T5, 8($sp) # save the same
2: move $fp, $sp # set base pointer
DADDI2( $sp, -48) # command data
ld T5, 8($s0) # entry
ld T6, 16($s0) # at_entry
ld T7, 24($s0) # at_phent
ld $t8, 32($s0) # at_phnum
sd T5, -8($fp) # save entry
ld T5, 40($s0) # at_phdr
sd T6, -16($fp) # save at_entry
ld T6, 48($s0) # at_base
sd T7, -24($fp) # save at_phent
sd $t8, -32($fp) # save at_phnum
sd T5, -40($fp) # save at_phdr
sd T6, -48($fp) # save at_base
dsub $sp, $sp, $t1 # space for string
/* Save the input string. */
dadd T5, $t2, $t1 # end of source ($t2)
move T6, $sp # dst
move $s0, $t1 # $s0 = length of string
/* src = $t2, dst = T6 */
bgeu $t2, T5, 2f # there already?
nop
1: lb $t1, ($t2) # $t1 = *$t2
DADDI2( $t2, 1) # $t2++
DADDI2( T6, 1) # $t6++
bltu $t2, T5, 1b
sb $t1, -1(T6) # *(T6 - 1) = $t1
2: move $s3, $sp # copy of string
and $sp, $sp, -16 # align stack
copy_env_and_args:
/* Copy argc, argv, and the environment array.
T4 = destination, T5 = src, $s2 = src_end */
move T4, $t3 # destination of argc
move T5, $s6 # original SP
bgeu T5, $s2, 2f # there already?
nop
1: ld $t1, (T5) # $t1 = *src
DADDI2( T5, 8) # src++
DADDI2( T4, 8) # dst++
bltu T5, $s2, 1b # src < src_end
sd $t1, -8(T4) # *(dst - 8) = $t1
copy_auxv:
/* T4 = destination, T5 = first auxval. */
2: ld $t1, (T5) # a_type
ld $t2, 8(T5) # a_un.a_val
DADDI2( T4, 16) # (Elf64_auxv_t *) dst++
DADDI2( T5, 16) # (Elf64_auxv_t *) src
beqz $t1, 8f # AT_NULL
li T6, 3
beq $t1, T6, 1f # AT_PHDR
li T6, 4
beq $t1, T6, 2f # AT_PHENT
li T6, 5
beq $t1, T6, 3f # AT_PHNUM
li T6, 9
beq $t1, T6, 4f # AT_ENTRY
li T6, 7
beq $t1, T6, 5f # AT_BASE
li T6, 31
beq $t1, T6, 6f # AT_EXECFN
nop
b 7f
nop
1: b 7f
ld $t2, -40($fp)
2: b 7f
ld $t2, -24($fp)
3: b 7f
ld $t2, -32($fp)
4: b 7f
ld $t2, -16($fp)
5: b 7f
ld $t2, -48($fp)
6: b 7f
move $t2, $t0
7: sd $t1, -16(T4) # dst->a_type
j copy_auxv
sd $t2, -8(T4) # dst->a_un.a_val
/* Copy the final element. */
8: sd $t1, -16(T4) # dst->a_type
sd $t2, -8(T4) # dst->a_un.a_val
finish:
/* Copy the string to its position in auxv
(src = $s3, dst = $t0). */
dadd $t1, $s3, $s0 # src end
bgeu $s3, $t1, 2f # there already?
nop
1: lb $t2, ($s3) # c = *src
DADDI2( $s3, 1) # src++
DADDI2( $t0, 1) # dst++
bltu $s3, $t1, 1b
sb $t2, -1($t0) # *(dst - 1) = c
/* Save variables. */
2: move $s6, $t3 # new stack pointer
ld $t0, 8($fp) # secondary fd
li $t1, -1 # t1 = -1 li $t1, -1 # t1 = -1
ld $s1, ($sp) # s1 = primary fd ld $s1, ($fp) # s1 = primary fd
beq $t0, $t2, finish1 # secondary fd set?
li $v0, 5003 # SYS_close li $v0, 5003 # SYS_close
beq $t0, $t2, .finish1 # secondary fd set?
nop # delay slot
move $a0, $t0 # secondary fd move $a0, $t0 # secondary fd
syscall # syscall syscall # syscall
li $v0, 5003 # SYS_close li $v0, 5003 # SYS_close
.finish1: finish1:
move $a0, $s1 # primary fd move $a0, $s1 # primary fd
syscall # syscall syscall # syscall
.jump: jump:
move $v0, $zero # rtld_fini move $v0, $zero # rtld_fini
ld $t0, 8($s0) # entry ld $t9, -8($fp) # entry
move $sp, $s2 # restore stack pointer, delay slot move $sp, $s6 # restore stack pointer, delay slot
jr $t0 # enter /* Clear at least one page's worth of stack. glibc on mipsel
copies certain fields from the stack to the `link_map'
structure representing ld.so, which are not subsequently
replaced if otherwise than zero.
XXX: report this glibc bug? */
DADDI3( $v0, $sp, -4096)
and $v0, $v0, -4095
1: sd $zero, ($v0) # copy 32 byte blocks
sd $zero, 8($v0)
sd $zero, 16($v0)
sd $zero, 24($v0)
DADDI2( $v0, 32)
dsub $t0, $sp, $v0 # remainder
bge $t0, 32, 1b # test remainder
nop # copy 4 byte blocks
beqz $t0, 2f
nop
1: DADDI2( $v0, 4)
bltu $v0, $sp, 1b
sw $zero, -4($v0)
2: jr $t9 # enter
nop # delay slot nop # delay slot
.auxvtab: ## timespec:
.long 0 # 0 ## .quad 10
.long 0 # 1 ## .quad 10
.long 0 # 2
.long 40 # 3 AT_PHDR
.long 24 # 4 AT_PHENT
.long 32 # 5 AT_PHNUM
.long 0 # 6
.long 48 # 7 AT_BASE
.long 0 # 8
.long 16 # 9 AT_ENTRY
.timespec:
.quad 10
.quad 10
# Local Variables: # Local Variables:
# asm-comment-char: ?# # asm-comment-char: ?#

View file

@ -17,32 +17,32 @@
include(`config-mips.m4') include(`config-mips.m4')
# Make sure not to use t4 through t7, in order to maintain portability ## Beware: $t0-$t4 alias the syscall (and function, but they are not
# with N32 ABI systems. ## material in this context) argument registers on N32 systems, and
## mustn't be relied upon to hold arguments to `SYSCALL'.
.set noreorder # delay slots managed by hand .set noreorder # delay slots managed by hand
.section .text .section .text
.global __start .global __start
__start: __start:
dnl li $v0, SYSCALL_nanosleep # SYS_nanosleep ## li $v0, SYSCALL_nanosleep # SYS_nanosleep
dnl la $a0, .timespec # rqtp ## la $a0, timespec # rqtp
dnl li $a1, 0 # rmtp ## li $a1, 0 # rmtp
dnl syscall # syscall ## syscall # syscall
lw $s6, ($sp) # original stack pointer lw $s6, ($sp) # original stack pointer
addi $s0, $sp, 8 # start of load area addi $s0, $sp, 8 # start of load area
addi $sp, -8 # primary fd, secondary fd addi $sp, -8 # primary fd, secondary fd
li $t0, -1 # secondary fd li $t0, -1 # secondary fd
sw $t0, 4($sp) # initialize secondary fd sw $t0, 4($sp) # initialize secondary fd
.next_action: next_action:
lw $s2, ($s0) # action number lw $s2, ($s0) # action number
nop # delay slot
andi $t0, $s2, 15 # t0 = s2 & 15 andi $t0, $s2, 15 # t0 = s2 & 15
beqz $t0, .open_file # open file? beqz $t0, open_file # open file?
li $t1, 3 # t1 = 3, delay slot li $t1, 3 # t1 = 3, delay slot
beq $t0, $t1, .rest_of_exec # jump to code beq $t0, $t1, rest_of_exec # jump to code
li $t1, 4 # t1 = 4, delay slot li $t1, 4 # t1 = 4, delay slot
beq $t0, $t1, .do_mmap_anon # anonymous mmap beq $t0, $t1, do_mmap_anon # anonymous mmap
.do_mmap: do_mmap:
lw $a0, 4($s0) # vm_address, delay slot lw $a0, 4($s0) # vm_address, delay slot
lw $v1, 8($s0) # file_offset lw $v1, 8($s0) # file_offset
lw $a2, 12($s0) # protection lw $a2, 12($s0) # protection
@ -50,33 +50,33 @@ dnl syscall # syscall
lw $a3, 20($s0) # flags lw $a3, 20($s0) # flags
lw $v0, ($sp) # primary fd lw $v0, ($sp) # primary fd
andi $t1, $s2, 16 # t1 = s2 & 16 andi $t1, $s2, 16 # t1 = s2 & 16
beqz $t1, .do_mmap_1 # secondary fd? beqz $t1, do_mmap_1 # secondary fd?
nop # delay slot nop # delay slot
lw $v0, 4($sp) # secondary fd lw $v0, 4($sp) # secondary fd
nop # delay slot nop # delay slot
.do_mmap_1: do_mmap_1:
SYSCALL(`$v0',`$v1',`$zero',`$zero') # syscall args SYSCALL(`$v0',`$v1',`$zero',`$zero') # syscall args
li $v0, SYSCALL_mmap # SYS_mmap li $v0, SYSCALL_mmap # SYS_mmap
syscall # syscall syscall # syscall
bne $a3, $zero, .perror # perror bnez $a3, perror # perror
RESTORE() # delay slot, restore sp RESTORE() # delay slot, restore sp
lw $s5, 24($s0) # clear lw $s5, 24($s0) # clear
add $t0, $a0, $a1 # t0 = length + vm_address, delay slot add $t0, $a0, $a1 # t0 = length + vm_address, delay slot
sub $t1, $t0, $s5 # t1 = t0 - clear sub $t1, $t0, $s5 # t1 = t0 - clear
.align: align:
beq $t0, $t1, .continue # already finished? beq $t0, $t1, continue # already finished?
nop # delay slot nop # delay slot
andi $t2, $t1, 3 # t1 & 3? andi $t2, $t1, 3 # t1 & 3?
bnez $t2, .fillw # start filling longs bnez $t2, fillw # start filling longs
nop # delay slot nop # delay slot
sb $zero, ($t1) # clear byte sb $zero, ($t1) # clear byte
addi $t1, $t1, 1 # t1++ addi $t1, $t1, 1 # t1++
j .align # continue j align # continue
nop # delay slot nop # delay slot
.fillw: fillw:
sub $t2, $t0, $t1 # t2 = t0 - t1 sub $t2, $t0, $t1 # t2 = t0 - t1
sltiu $t2, $t2, 32 # r2 < 32? sltiu $t2, $t2, 32 # r2 < 32?
bne $t2, $zero, .fillb # fill bytes bne $t2, $zero, fillb # fill bytes
nop # delay slot nop # delay slot
sw $zero, ($t1) # zero word sw $zero, ($t1) # zero word
addi $t1, $t1, 4 # next word addi $t1, $t1, 4 # next word
@ -94,53 +94,52 @@ RESTORE() # delay slot, restore sp
addi $t1, $t1, 4 # next word addi $t1, $t1, 4 # next word
sw $zero, ($t1) # zero word sw $zero, ($t1) # zero word
addi $t1, $t1, 4 # next word addi $t1, $t1, 4 # next word
j .fillw # fill either word or byte j fillw # fill either word or byte
nop # delay slot nop # delay slot
.fillb: fillb:
beq $t0, $t1, .continue # already finished? beq $t0, $t1, continue # already finished?
nop # delay slot nop # delay slot
sb $zero, ($t1) # clear byte sb $zero, ($t1) # clear byte
addi $t1, $t1, 1 # t1++ addi $t1, $t1, 1 # t1++
.continue: continue:
addi $s0, $s0, 28 # s0 = next action addi $s0, $s0, 28 # s0 = next action
j .next_action # next action j next_action # next action
nop # delay slot nop # delay slot
.do_mmap_anon: do_mmap_anon:
lw $v1, 8($s0) # file_offset lw $v1, 8($s0) # file_offset
lw $a2, 12($s0) # protection lw $a2, 12($s0) # protection
lw $a1, 16($s0) # length lw $a1, 16($s0) # length
lw $a3, 20($s0) # flags lw $a3, 20($s0) # flags
li $t4, -1 # fd j do_mmap_1 # do mmap
j .do_mmap_1 # do mmap li $v0, -1 # fd, delay slot
nop # delay slot open_file:
.open_file:
li $v0, SYSCALL_open # SYS_open li $v0, SYSCALL_open # SYS_open
addi $a0, $s0, 4 # start of name addi $a0, $s0, 4 # start of name
move $a1, $zero # flags = O_RDONLY move $a1, $zero # flags = O_RDONLY
move $a2, $zero # mode = 0 move $a2, $zero # mode = 0
syscall # syscall syscall # syscall
bne $a3, $zero, .perror # perror bne $a3, $zero, perror # perror
addi $s0, $s0, 4 # start of string, delay slot addi $s0, $s0, 4 # start of string, delay slot
move $t3, $s0 # t3 = char past separator move $t3, $s0 # t3 = char past separator
.nextc: nextc:
lb $t0, ($s0) # load byte lb $t0, ($s0) # load byte
addi $s0, $s0, 1 # s0++ addi $s0, $s0, 1 # s0++
li $t1, 47 # directory separator `/' li $t1, 47 # directory separator `/'
bne $t0, $t1, .nextc1 # is separator char? bne $t0, $t1, nextc1 # is separator char?
nop # delay slot nop # delay slot
move $t3, $s0 # t3 = char past separator move $t3, $s0 # t3 = char past separator
.nextc1: nextc1:
bnez $t0, .nextc # next character? bnez $t0, nextc # next character?
nop # delay slot nop # delay slot
addi $s0, $s0, 3 # adjust for round addi $s0, $s0, 3 # adjust for round
li $t2, -4 # t2 = -4 li $t2, -4 # t2 = -4
and $s0, $s0, $t2 # mask for round and $s0, $s0, $t2 # mask for round
andi $t0, $s2, 16 # t1 = s2 & 16 andi $t0, $s2, 16 # t1 = s2 & 16
beqz $t0, .primary # primary fd? beqz $t0, primary # primary fd?
move $t0, $sp # address of primary fd, delay slot move $t0, $sp # address of primary fd, delay slot
addi $t0, $t0, 4 # address of secondary fd addi $t0, $t0, 4 # address of secondary fd
j .next_action # next action j next_action # next action
.primary: primary:
sw $v0, ($t0) # store fd, delay slot sw $v0, ($t0) # store fd, delay slot
li $v0, SYSCALL_prctl # SYS_prctl li $v0, SYSCALL_prctl # SYS_prctl
li $a0, 15 # PR_SET_NAME li $a0, 15 # PR_SET_NAME
@ -150,86 +149,208 @@ RESTORE() # delay slot, restore sp
SYSCALL(`$a2',`$a2',`$a2',`$a2') # syscall args SYSCALL(`$a2',`$a2',`$a2',`$a2') # syscall args
syscall # syscall syscall # syscall
RESTORE() # restore sp RESTORE() # restore sp
j .next_action # next action j next_action # next action
nop # delay slot nop # delay slot
.perror: perror:
move $a0, $v0 # errno move $a0, $v0 # errno
li $v0, SYSCALL_exit # SYS_exit li $v0, SYSCALL_exit # SYS_exit
syscall # syscall syscall # syscall
.rest_of_exec: rest_of_exec:
move $s1, $s6 # s1 = original SP move $s1, $s6 # s1 = original SP
lw $t0, ($s1) # argc lw $t0, ($s1) # argc
nop # delay slot
sll $t0, $t0, 2 # argc *= 4 sll $t0, $t0, 2 # argc *= 4
addi $t0, $t0, 8 # argc += 8 addi $t0, $t0, 8 # argc += 8
add $s1, $s1, $t0 # s1 = start of envp add $s1, $s1, $t0 # s1 = start of envp
.skipenv: skip_environ:
lw $t0, ($s1) # t0 = *s1 /* Locate the auxiliary vector. */
1: lw $t0, ($s1) # t0 = *s1
bnez $t0, 1b # skip environment entry
addi $s1, $s1, 4 # s1++ addi $s1, $s1, 4 # s1++
bne $t0, $zero, .skipenv # skip again move $s2, $s1 # $s2 = end of environment
nop # delay slot 1: lw $t0, ($s1) # t0 = *s1
la $s2, .auxvtab # address of auxv table bnez $t0, 1b # skip auxiliary vector entry
.one_auxv: addi $s1, $s1, 8 # (Elf32_auxv_t *) s1++
lw $t0, ($s1) # t0 = auxv type /* Decide how many bytes must be copied and where to
li $t1, 10 # t1 = 10, delay slot save the file name. Move the stack pointer to a safe
beqz $t0, .finish # is AT_IGNORE? position below any data that must be preserved. */
sltu $t1, $t0, $t1 # t1 = t0 < num offsets, delay slot lw $t1, 32($s0) # length of string
beq $t1, $zero, .next # next auxv addi $t1, $t1, 1
sll $t1, $t0, 2 # t1 = t0 * 4, delay slot addi $t2, $s0, 36 # pointer to string
add $t1, $s2, $t1 # t1 = .auxvtab + t1 sub $t3, $s1, $s6 # number of bytes in vectors
lw $t2, ($t1) # t2 = *t1 sub $t0, $s1, $t1 # position of string
nop # delay slot and $t0, $t0, -16 # align value
beqz $t2, .next # skip auxv sub $t3, $t0, $t3 # position of argc
add $t2, $s0, $t2 # t2 = s0 + t2 and $t3, $t3, -16 # align value
lw $t2, ($t2) # t2 = *t2 /* Move the stack pointer and save required information.
nop # delay slot 4(FP) = secondary/interpreter fd.
sw $t2, 4($s1) # set auxv value 0(FP) = primary/executable fd.
.next: -4(FP) = cmd->entry
addi $s1, $s1, 8 # next auxv -8(FP) = cmd->at_entry
j .one_auxv # next auxv -12(FP) = cmd->at_phent
nop # delay slot -16(FP) = cmd->at_phnum
.finish: -20(FP) = cmd->at_phdr
lw $t0, 4($sp) # secondary fd -24(FP) = cmd->at_base
lw $s1, ($sp) # primary fd, delay slot, preserved -28(FP) = cmd->fpu_mode (only significant when N32)
$sp = copy of string. */
move $t4, $sp # current sp
sub $t5, $t3, $sp # new argc - current sp
blt $t5, 8, 1f # more than two slots apart
addi $sp, $t3, -8 # $sp = two slots below new argc
j 2f # skip copying fds
move $sp, $t4 # retain current sp
1: lw $t5, ($t4) # old primary fd
sw $t5, ($sp) # save the same
lw $t5, 4($t4) # old interpreter fd
sw $t5, 4($sp) # save the same
2: move FP, $sp # set base pointer
addi $sp, $sp, -28 # command data
lw $t5, 4($s0) # entry
lw $t6, 8($s0) # at_entry
sw $t5, -4(FP) # save entry
sw $t6, -8(FP) # save at_entry
lw $t5, 12($s0) # at_phent
lw $t6, 16($s0) # at_phnum
sw $t5, -12(FP) # save at_phent
sw $t6, -16(FP) # save at_phnum
lw $t5, 20($s0) # at_phdr
lw $t6, 24($s0) # at_base
sw $t5, -20(FP) # save at_phdr
sw $t6, -24(FP) # save at_base
lw $t5, 28($s0) # fpu_mode
sw $t5, -28(FP) # save fpu_mode
sub $sp, $sp, $t1 # space for string
/* Save the input string. */
add $t5, $t2, $t1 # end of source ($t2)
move $t6, $sp # dst
move $s0, $t1 # $s0 = length of string
/* src = $t2, dst = $t6 */
bgeu $t2, $t5, 2f # there already?
nop
1: lb $t1, ($t2) # $t1 = *$t2
addi $t2, $t2, 1 # $t2++
addi $t6, $t6, 1 # $t6++
bltu $t2, $t5, 1b
sb $t1, -1($t6) # *($t6 - 1) = $t1
2: move $s3, $sp # copy of string
and $sp, $sp, -16 # align stack
copy_env_and_args:
/* Copy argc, argv, and the environment array.
$t4 = destination, $t5 = src, $s2 = src_end */
move $t4, $t3 # destination of argc
move $t5, $s6 # original SP
bgeu $t5, $s2, 2f # there already?
nop
1: lw $t1, ($t5) # $t1 = *src
addi $t5, $t5, 4 # src++
addi $t4, $t4, 4 # dst++
bltu $t5, $s2, 1b # src < src_end
sw $t1, -4($t4) # *(dst - 4) = $t1
copy_auxv:
/* $t4 = destination, $t5 = first auxval. */
2: lw $t1, ($t5) # a_type
lw $t2, 4($t5) # a_un.a_val
addi $t4, $t4, 8 # (Elf32_auxv_t *) dst++
addi $t5, $t5, 8 # (Elf32_auxv_t *) src++
beqz $t1, 8f # AT_NULL
li $t6, 3
beq $t1, $t6, 1f # AT_PHDR
li $t6, 4
beq $t1, $t6, 2f # AT_PHENT
li $t6, 5
beq $t1, $t6, 3f # AT_PHNUM
li $t6, 9
beq $t1, $t6, 4f # AT_ENTRY
li $t6, 7
beq $t1, $t6, 5f # AT_BASE
li $t6, 31
beq $t1, $t6, 6f # AT_EXECFN
nop
b 7f
nop
1: b 7f
lw $t2, -20(FP)
2: b 7f
lw $t2, -12(FP)
3: b 7f
lw $t2, -16(FP)
4: b 7f
lw $t2, -8(FP)
5: b 7f
lw $t2, -24(FP)
6: b 7f
move $t2, $t0
7: sw $t1, -8($t4) # dst->a_type
j copy_auxv
sw $t2, -4($t4) # dst->a_un.a_val
/* Copy the final element. */
8: sw $t1, -8($t4) # dst->a_type
sw $t2, -4($t4) # dst->a_un.a_val
finish:
/* Copy the string to its position in auxv
(src = $s3, dst = $t0). */
add $t1, $s3, $s0 # src end
bgeu $s3, $t1, 2f # there already?
nop
1: lb $t2, ($s3) # c = *src
addi $s3, $s3, 1 # *src++
addi $t0, $t0, 1 # dst++
bltu $s3, $t1, 1b
sb $t2, -1($t0) # *(dst - 1) = c
/* Save variables. */
2: move $s6, $t3 # new stack pointer
lw $t4, 4(FP) # secondary fd
lw $s1, (FP) # primary fd, delay slot, preserved
li $t2, -1 # immediate -1 li $t2, -1 # immediate -1
beq $t0, $t2, .finish1 # secondary fd set? beq $t4, $t2, finish1 # secondary fd set?
li $v0, SYSCALL_close # SYS_close, delay slot li $v0, SYSCALL_close # SYS_close, delay slot
move $a0, $t0 # fd move $a0, $t4 # fd
syscall # syscall syscall # syscall
li $v0, SYSCALL_close # SYS_close li $v0, SYSCALL_close # SYS_close
.finish1: finish1:
move $a0, $s1 # primary fd move $a0, $s1 # primary fd
syscall # syscall syscall # syscall
li $v0, SYSCALL_prctl # SYS_prctl li $v0, SYSCALL_prctl # SYS_prctl
li $a0, 45 # PR_SET_FP_MODE li $a0, 45 # PR_SET_FP_MODE
lw $a1, 28($s0) # fpu_mode lw $a1, -28(FP) # fpu_mode
move $a2, $zero # arg3 move $a2, $zero # arg3
move $a3, $zero # arg4 move $a3, $zero # arg4
SYSCALL(`$a2',`$a2',`$a2',`$a2') # syscall args SYSCALL(`$a2',`$a2',`$a2',`$a2') # syscall args
syscall # syscall syscall # syscall
RESTORE() # restore sp RESTORE() # restore sp
.jump: jump:
move $v0, $zero # rtld_fini move $v0, $zero # rtld_fini
lw $t0, 4($s0) # entry lw $t9, -4(FP) # entry
move $sp, $s6 # restore stack pointer, delay slot move $sp, $s6 # restore stack pointer, delay slot
jr $t0 # enter /* Clear at least one page's worth of stack. glibc on mipsel
copies certain fields from the stack to the `link_map'
structure representing ld.so, which are not subsequently
replaced if otherwise than zero.
XXX: report this glibc bug? */
addi $v0, $sp, -4096
and $v0, $v0, -4095
1: sw $zero, ($v0) # copy 32 byte blocks
sw $zero, 4($v0)
sw $zero, 8($v0)
sw $zero, 12($v0)
sw $zero, 16($v0)
sw $zero, 20($v0)
sw $zero, 24($v0)
sw $zero, 28($v0)
addi $v0, $v0, 32
sub $t0, $sp, $v0 # remainder
bge $t0, 32, 1b # test remainder
nop # copy 4 byte blocks
beqz $t0, 2f
1: addi $v0, $v0, 4
bltu $v0, $sp, 1b
sw $zero, -4($v0)
2: jr $t9 # enter
nop # delay slot nop # delay slot
.auxvtab: ## timespec:
.long 0 # 0 ## .long 10
.long 0 # 1 ## .long 10
.long 0 # 2
.long 20 # 3 AT_PHDR
.long 12 # 4 AT_PHENT
.long 16 # 5 AT_PHNUM
.long 0 # 6
.long 24 # 7 AT_BASE
.long 0 # 8
.long 8 # 9 AT_ENTRY
.timespec:
.long 10
.long 10
# Local Variables: # Local Variables:
# asm-comment-char: ?# # asm-comment-char: ?#

View file

@ -15,26 +15,29 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. # along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
/* Sorry! This program is a hopeless shambles in consequence of
being hastily written in under twenty minutes with minimal testing. */
.section .text .section .text
.global _start .global _start
_start: _start:
# movl $162, %eax # SYS_nanosleep ## movl $162, %eax # SYS_nanosleep
# leal timespec, %ebx ## leal timespec, %ebx
# xorl %ecx, %ecx ## xorl %ecx, %ecx
# int $0x80 ## int $0x80
leal 8(%esp), %ebp # ebp = start of load area leal 8(%esp), %ebp # ebp = start of load area
subl $8, %esp # (%esp) = primary fd, 4(%esp) = secondary fd subl $8, %esp # (%esp) = primary fd, 4(%esp) = secondary fd
movl $-1, 4(%esp) movl $-1, 4(%esp)
.next_action: next_action:
movl (%ebp), %edx # edx = action number movl (%ebp), %edx # edx = action number
andl $-17, %edx andl $-17, %edx
cmpl $0, %edx # open file? cmpl $0, %edx # open file?
je .open_file je open_file
cmpl $3, %edx # jump? cmpl $3, %edx # jump?
je .rest_of_exec je rest_of_exec
cmpl $4, %edx # anonymous mmap? cmpl $4, %edx # anonymous mmap?
je .do_mmap_anon je do_mmap_anon
.do_mmap: do_mmap:
subl $24, %esp subl $24, %esp
movl $90, %eax # SYS_old_mmap movl $90, %eax # SYS_old_mmap
movl %esp, %ebx movl %esp, %ebx
@ -52,27 +55,27 @@ _start:
movl %ecx, 16(%esp) # fd movl %ecx, 16(%esp) # fd
movl 8(%ebp), %ecx # offset movl 8(%ebp), %ecx # offset
movl %ecx, 20(%esp) movl %ecx, 20(%esp)
.do_mmap_1: do_mmap_1:
int $0x80 int $0x80
addl $24, %esp # restore esp addl $24, %esp # restore esp
cmpl $-1, %eax # mmap failed? cmpl $-1, %eax # mmap failed?
je .perror je perror
movl 24(%ebp), %ecx # clear movl 24(%ebp), %ecx # clear
testl %ecx, %ecx testl %ecx, %ecx
jz .continue jz continue
movl 4(%ebp), %esi # start of mapping movl 4(%ebp), %esi # start of mapping
addl 16(%ebp), %esi # end of mapping addl 16(%ebp), %esi # end of mapping
subl %ecx, %esi # start of clear area subl %ecx, %esi # start of clear area
.again: again:
testl %ecx, %ecx testl %ecx, %ecx
jz .continue jz continue
subl $1, %ecx subl $1, %ecx
movb $0, (%esi, %ecx, 1) movb $0, (%esi, %ecx, 1)
jmp .again jmp again
.continue: continue:
leal 28(%ebp), %ebp leal 28(%ebp), %ebp
jmp .next_action jmp next_action
.do_mmap_anon: do_mmap_anon:
subl $24, %esp subl $24, %esp
movl $90, %eax # SYS_old_mmap movl $90, %eax # SYS_old_mmap
movl %esp, %ebx movl %esp, %ebx
@ -87,8 +90,8 @@ _start:
movl $-1, 16(%esp) # fd movl $-1, 16(%esp) # fd
movl 8(%ebp), %ecx # offset movl 8(%ebp), %ecx # offset
movl %ecx, 20(%esp) movl %ecx, 20(%esp)
jmp .do_mmap_1 jmp do_mmap_1
.open_file: open_file:
movl $5, %eax # SYS_open movl $5, %eax # SYS_open
leal 4(%ebp), %ebx # ebx = %esp + 8 leal 4(%ebp), %ebx # ebx = %esp + 8
pushl %ebx pushl %ebx
@ -96,27 +99,27 @@ _start:
xorl %edx, %edx # mode = 0 xorl %edx, %edx # mode = 0
int $0x80 int $0x80
cmpl $-1, %eax # open failed? cmpl $-1, %eax # open failed?
jle .perror jle perror
movl %ebp, %esi # (esi) = original action number movl %ebp, %esi # (esi) = original action number
popl %ebp # ebp = start of string popl %ebp # ebp = start of string
movl %ebp, %ecx # char past separator movl %ebp, %ecx # char past separator
decl %ebp decl %ebp
.nextc: nextc:
incl %ebp incl %ebp
movb (%ebp), %dl # dl = *ebp movb (%ebp), %dl # dl = *ebp
cmpb $47, %dl # dl == '\?'? cmpb $47, %dl # dl == '\?'?
jne .nextc1 jne nextc1
leal 1(%ebp), %ecx # ecx = char past separator leal 1(%ebp), %ecx # ecx = char past separator
.nextc1: nextc1:
cmpb $0, %dl # dl == 0? cmpb $0, %dl # dl == 0?
jne .nextc jne nextc
addl $4, %ebp # adjust past ebp prior to rounding addl $4, %ebp # adjust past ebp prior to rounding
andl $-4, %ebp # round ebp up to the next long andl $-4, %ebp # round ebp up to the next long
testl $16, (%esi) # original action number & 16? testl $16, (%esi) # original action number & 16?
jz .primary jz primary
movl %eax, 4(%esp) # secondary fd = eax movl %eax, 4(%esp) # secondary fd = eax
jmp .next_action jmp next_action
.primary: primary:
pushl %ebp pushl %ebp
xorl %esi, %esi # arg3 xorl %esi, %esi # arg3
movl %eax, 4(%esp) # primary fd = eax movl %eax, 4(%esp) # primary fd = eax
@ -127,74 +130,168 @@ _start:
xorl %ebp, %ebp # arg5 xorl %ebp, %ebp # arg5
int $0x80 # syscall int $0x80 # syscall
popl %ebp popl %ebp
jmp .next_action jmp next_action
.perror: perror:
movl %eax, %ebx movl %eax, %ebx
negl %ebx negl %ebx
movl $1, %eax movl $1, %eax
int $0x80 int $0x80
.rest_of_exec: rest_of_exec:
movl 8(%esp), %ecx # ecx = original stack pointer movl 8(%esp), %ecx # ecx = original stack pointer
movl (%ecx), %esi # esi = argc movl (%ecx), %esi # esi = argc
leal 8(%ecx, %esi, 4), %ecx # ecx = start of environ leal 8(%ecx, %esi, 4), %ecx # ecx = start of environ
.skip_environ: movl (%esp), %eax # %eax = primary fd
movl 4(%esp), %edi # %edi = secondary fd
skip_environ:
movl (%ecx), %esi # envp[N] movl (%ecx), %esi # envp[N]
addl $4, %ecx addl $4, %ecx
testl %esi, %esi # envp[n] ? testl %esi, %esi # envp[n] ?
jnz .skip_environ # otherwise, esi is now at the start of auxv jnz skip_environ # otherwise, ecx is now at the end of auxv
.one_auxv: 1: testl $-1, (%ecx) # auxv type
movl (%ecx), %esi # auxv type
leal 8(%ecx), %ecx # skip to next auxv leal 8(%ecx), %ecx # skip to next auxv
testl %esi, %esi # is 0? jnz 1b # otherwise copy auxv
jz .cleanup movl %ecx, %edx # end of auxv
cmpl $3, %esi # is AT_PHDR /* Prepare sufficient space for the new executable name at the
je .replace_phdr start of the auxiliary vector. */
cmpl $4, %esi # is AT_PHENT? 1: leal 32(%ebp), %esi # file name
je .replace_phent /* 28(%ebp) = file name length. */
cmpl $5, %esi # is AT_PHNUM? subl 28(%ebp), %ecx # destination of file name
je .replace_phnum decl %ecx
cmpl $9, %esi # is AT_ENTRY? /* This is still 16 bytes on i386--see arch_align_stack:
je .replace_entry https://android.googlesource.com/kernel/goldfish/+/refs/heads
cmpl $7, %esi # is AT_BASE /android-goldfish-3.10/arch/x86/kernel/process.c#446. */
je .replace_base andl $-16, %ecx # align stack
jmp .one_auxv /* Prepare to store the auxiliary, environment, and argument
.replace_phdr: vectors. */
movl 20(%ebp), %esi subl 8(%esp), %edx # end of auxv to start of stack
negl %edx
andl $-16, %edx # align value
movl %ecx, (%ebp) # temporarily save ecx
addl %edx, %ecx # %ecx = new position of argc
/* Allocate a temporary stack away from any crucial data in which
to store parameters and temporaries. */
cmpl %ecx, %ebp # select position of temporary stack
movl %ecx, %ebx # ebx = temporary stack
jge 1f # %ebx = MIN (%ecx, %edx)
movl %ebp, %ebx # ebx = temporary stack
1: movl (%ebp), %edx # edx = destination of file name
movl %edx, -4(%ebx) # -4(%ebx) = destination of file name
movl 28(%ebp), %edx # file name length
movl %edx, -8(%ebx) # -8(%ebx) = file name length
movl %ecx, -12(%ebx) # -12(%ebx) = new position of argc
movl %esi, -16(%ebx) # -16(%ebx) = file name
movl 8(%esp), %edx # %edx = initial stack pointer
leal -16(%ebx), %esp # switch to temporary stack
/* Push parameters of `struct exec_jump_command'. */
push %edx # initial stack pointer -20(%ebx)
push 4(%ebp) # entry -24(%ebx)
push 8(%ebp) # at_entry -28(%ebx)
push 12(%ebp) # at_phent -32(%ebx)
push 16(%ebp) # at_phnum -36(%ebx)
push 20(%ebp) # at_phdr -40(%ebx)
push 24(%ebp) # at_base -44(%ebx)
/* Push primary and secondary fds. */
push %eax # primary fd -48(%ebx)
push %edi # secondary fd -52(%ebx)
/* Swap %ebp with %ebx. */
push %ebp
push %ebx
pop %ebp
pop %ebx # ebx is the exec_jump_command
/* Save the string lest it should be overwritten while
the environment is moved. */
movl -8(%ebp), %ecx
subl $4, %esp # -56(%ebp)
subl %ecx, %esp
leal -1(%esp), %edi
movl %edi, -56(%ebp) # copy of string
incl %ecx
movl %edi, %esp
cld
rep movsb # complete copy
andl $-4, %esp # align stack
movl -12(%ebp), %ecx
/* Begin moving the argument vectors and environment from
the original SP to the adjusted one. */
1: movl (%edx), %eax # argc and values
movl %eax, (%ecx)
leal 4(%ecx), %ecx
leal 4(%edx), %edx
testl %eax, %eax
jnz 1b
1: movl (%edx), %eax # envp
movl %eax, (%ecx)
leal 4(%ecx), %ecx
leal 4(%edx), %edx
testl %eax, %eax
jnz 1b
copy_auxv:
movl (%edx), %eax # a_type
movl 4(%edx), %esi # a_un.a_val
testl %eax, %eax
leal 8(%edx), %edx
movl %eax, (%ecx) # copy auxv type
leal 8(%ecx), %ecx
jz cleanup # AT_NULL
cmpl $3, %eax # AT_PHDR
jz 1f
cmpl $4, %eax # AT_PHENT
jz 2f
cmpl $5, %eax # AT_PHNUM
jz 3f
cmpl $9, %eax # AT_ENTRY
jz 4f
cmpl $7, %eax # AT_BASE
jz 5f
cmpl $31, %eax # AT_EXECFN
jz 6f
movl %esi, -4(%ecx) movl %esi, -4(%ecx)
jmp .one_auxv jmp copy_auxv
.replace_phent: 1: movl -40(%ebp), %esi
movl 12(%ebp), %esi
movl %esi, -4(%ecx) movl %esi, -4(%ecx)
jmp .one_auxv jmp copy_auxv
.replace_phnum: 2: movl -32(%ebp), %esi
movl 16(%ebp), %esi
movl %esi, -4(%ecx) movl %esi, -4(%ecx)
jmp .one_auxv jmp copy_auxv
.replace_entry: 3: movl -36(%ebp), %esi
movl 8(%ebp), %esi
movl %esi, -4(%ecx) movl %esi, -4(%ecx)
jmp .one_auxv jmp copy_auxv
.replace_base: 4: movl -28(%ebp), %esi
movl 24(%ebp), %esi
movl %esi, -4(%ecx) movl %esi, -4(%ecx)
jmp .one_auxv jmp copy_auxv
.cleanup: 5: movl -44(%ebp), %esi
movl %esi, -4(%ecx)
jmp copy_auxv
6: movl -4(%ebp), %esi # Note: the filename is yet to be copied.
movl %esi, -4(%ecx)
jmp copy_auxv
cleanup:
movl $0, -4(%ecx) # AT_NULL value
/* Copy data for AT_EXECFN to the destination address. */
movl -4(%ebp), %edi
movl -56(%ebp), %esi
movl -8(%ebp), %ecx
incl %ecx
rep movsb
movl $6, %eax # SYS_close movl $6, %eax # SYS_close
cmpl $-1, 4(%esp) # see if interpreter fd is set cmpl $-1, -52(%ebp) # see if interpreter fd is set
je .cleanup_1 je cleanup_1
movl 4(%esp), %ebx movl -52(%ebp), %ebx
int $0x80 int $0x80
movl $6, %eax # SYS_close movl $6, %eax # SYS_close
.cleanup_1: cleanup_1:
movl (%esp), %ebx movl -48(%ebp), %ebx
int $0x80 int $0x80
.enter: enter:
pushl $0 pushl $0
popfl # restore floating point state popfl # restore floating point state
movl 8(%esp), %esp # restore initial stack pointer movl -12(%ebp), %esp # restore initial stack pointer
xorl %edx, %edx # clear rtld_fini xorl %edx, %edx # clear rtld_fini
jmpl *4(%ebp) # entry jmpl *-24(%ebp) # entry
## timespec:
## .long 10
## .long 10
timespec: # Local Variables:
.long 10 # asm-comment-char: ?#
.long 10 # End:

View file

@ -25,17 +25,17 @@ _start:
popq %r13 # original SP popq %r13 # original SP
popq %r15 # size of load area. popq %r15 # size of load area.
movq $-1, %r12 # r12 is the interpreter fd movq $-1, %r12 # r12 is the interpreter fd
.next_action: next_action:
movq (%rsp), %r14 # action number movq (%rsp), %r14 # action number
movq %r14, %r15 # original action number movq %r14, %r15 # original action number
andq $-17, %r14 andq $-17, %r14
cmpq $0, %r14 # open file? cmpq $0, %r14 # open file?
je .open_file je open_file
cmpq $3, %r14 # jump? cmpq $3, %r14 # jump?
je .rest_of_exec je rest_of_exec
cmpq $4, %r14 # anonymous mmap? cmpq $4, %r14 # anonymous mmap?
je .do_mmap_anon je do_mmap_anon
.do_mmap: do_mmap:
movq $9, %rax # SYS_mmap movq $9, %rax # SYS_mmap
movq 8(%rsp), %rdi # address movq 8(%rsp), %rdi # address
movq 16(%rsp), %r9 # offset movq 16(%rsp), %r9 # offset
@ -46,26 +46,26 @@ _start:
testq $16, %r15 testq $16, %r15
movq %r12, %r8 movq %r12, %r8
cmovzq %rbx, %r8 cmovzq %rbx, %r8
.do_mmap_1: do_mmap_1:
syscall syscall
cmpq $-1, %rax # mmap failed cmpq $-1, %rax # mmap failed
je .perror je perror
movq 48(%rsp), %r9 # clear movq 48(%rsp), %r9 # clear
testq %r9, %r9 testq %r9, %r9
jz .continue jz continue
movq 8(%rsp), %r10 # start of mapping movq 8(%rsp), %r10 # start of mapping
addq 32(%rsp), %r10 # end of mapping addq 32(%rsp), %r10 # end of mapping
subq %r9, %r10 # start of clear area subq %r9, %r10 # start of clear area
.again: again:
testq %r9, %r9 testq %r9, %r9
jz .continue jz continue
subq $1, %r9 subq $1, %r9
movb $0, (%r10, %r9, 1) movb $0, (%r10, %r9, 1)
jmp .again jmp again
.continue: continue:
leaq 56(%rsp), %rsp leaq 56(%rsp), %rsp
jmp .next_action jmp next_action
.do_mmap_anon: do_mmap_anon:
movq $9, %rax # SYS_mmap movq $9, %rax # SYS_mmap
movq 8(%rsp), %rdi # address movq 8(%rsp), %rdi # address
movq 16(%rsp), %r9 # offset movq 16(%rsp), %r9 # offset
@ -73,35 +73,35 @@ _start:
movq 32(%rsp), %rsi # length movq 32(%rsp), %rsi # length
movq 40(%rsp), %r10 # flags movq 40(%rsp), %r10 # flags
movq $-1, %r8 # -1 movq $-1, %r8 # -1
jmp .do_mmap_1 jmp do_mmap_1
.open_file: open_file:
movq $2, %rax # SYS_open movq $2, %rax # SYS_open
leaq 8(%rsp), %rdi # rdi = %rsp + 8 leaq 8(%rsp), %rdi # rdi = %rsp + 8
xorq %rsi, %rsi # flags = O_RDONLY xorq %rsi, %rsi # flags = O_RDONLY
xorq %rdx, %rdx # mode = 0 xorq %rdx, %rdx # mode = 0
syscall syscall
cmpq $-1, %rax # open failed cmpq $-1, %rax # open failed
jle .perror jle perror
movq %rdi, %rsp # rsp = start of string movq %rdi, %rsp # rsp = start of string
subq $1, %rsp subq $1, %rsp
movq %rsp, %r14 # r14 = start of string movq %rsp, %r14 # r14 = start of string
.nextc: nextc:
addq $1, %rsp addq $1, %rsp
movb (%rsp), %dil # rdi = *rsp movb (%rsp), %dil # rdi = *rsp
cmpb $47, %dil # *rsp == '/'? cmpb $47, %dil # *rsp == '/'?
jne .nextc1 jne nextc1
movq %rsp, %r14 # r14 = rsp movq %rsp, %r14 # r14 = rsp
addq $1, %r14 # r14 = char past separator addq $1, %r14 # r14 = char past separator
.nextc1: nextc1:
cmpb $0, %dil # *rsp == 0? cmpb $0, %dil # *rsp == 0?
jne .nextc jne nextc
addq $8, %rsp # adjust past rsp prior to rounding addq $8, %rsp # adjust past rsp prior to rounding
andq $-8, %rsp # round rsp up to the next quad andq $-8, %rsp # round rsp up to the next quad
testq $16, %r15 # r15 & 16? testq $16, %r15 # r15 & 16?
jz .primary jz primary
movq %rax, %r12 # otherwise, move fd to r12 movq %rax, %r12 # otherwise, move fd to r12
jmp .next_action jmp next_action
.primary: primary:
movq %rax, %rbx # if not, move fd to rbx movq %rax, %rbx # if not, move fd to rbx
movq $157, %rax # SYS_prctl movq $157, %rax # SYS_prctl
movq $15, %rdi # PR_SET_NAME movq $15, %rdi # PR_SET_NAME
@ -111,82 +111,159 @@ _start:
xorq %r8, %r8 # arg4 xorq %r8, %r8 # arg4
xorq %r9, %r9 # arg5 xorq %r9, %r9 # arg5
syscall syscall
jmp .next_action jmp next_action
.perror: perror:
movq %rax, %r12 # error code movq %rax, %r12 # error code
negq %r12 negq %r12
movq $1, %rax # SYS_write movq $1, %rax # SYS_write
movq $1, %rdi # stdout movq $1, %rdi # stdout
leaq error(%rip), %rsi # buffer leaq error(%rip), %rsi # buffer
movq $23, %rdx # count movq $24, %rdx # count
syscall syscall
movq $60, %rax # SYS_exit movq $60, %rax # SYS_exit
movq %r12, %rdi # code movq %r12, %rdi # code
syscall syscall
.rest_of_exec: # rsp now points to six quads: rest_of_exec: # rsp now points to seven quads + string:
movq %rsp, %r8 # now, they are r8 movq %rsp, %r8 # now, they are r8
movq %r13, %rsp # restore SP movq %r13, %rsp # restore SP
popq %r10 # argc popq %r10 # argc
leaq 8(%rsp,%r10,8), %rsp # now at start of environ leaq 8(%rsp,%r10,8), %rsp # now at start of environ
.skip_environ: skip_environ:
popq %r10 # envp[N] popq %rcx # envp[N]
testq %r10, %r10 # envp[n]? testq %rcx, %rcx # envp[n]?
jnz .skip_environ # otherwise, rsp is now at the start of auxv jnz skip_environ # otherwise, rsp is now at the end of auxv
.one_auxv: movq %rsp, %r11 # start of auxv
popq %rcx # auxv type 1: testq $-1, (%r11) # NULL?
addq $8, %rsp # skip value leaq 16(%r11), %r11 # next entry
testq %rcx, %rcx # is 0? jnz 1b # otherwise copy auxv
jz .cleanup /* Prepare sufficient space for the new executable name at the
cmpq $3, %rcx # is AT_PHDR? start of the auxiliary vector. */
je .replace_phdr 1: leaq 64(%r8), %rsi # file name
cmpq $4, %rcx # is AT_PHENT? movq 56(%r8), %r9 # name length
je .replace_phent leaq -1(%r11), %r14
cmpq $5, %rcx # is AT_PHNUM? subq %r9, %r14 # destination of file name
je .replace_phnum andq $-16, %r14 # align destination
cmpq $9, %rcx # is AT_ENTRY? /* Prepare to copy argv, environ and auxv. */
je .replace_entry 1: subq %r13, %r11 # size required
cmpq $7, %rcx # is AT_BASE? addq $15, %r11 # align size
je .replace_base andq $-16, %r11
jmp .one_auxv negq %r11 # subtract
.replace_phdr: leaq -56(%r14,%r11,1), %r11 # %r11 = destination - struct exec_jump_command
movq 40(%r8), %r9 /* Move the file name out of the way. */
movq %r9, -8(%rsp) # set at_phdr leaq 9(%rsi,%r9,1), %r10 # end of name + 8
jmp .one_auxv cmpq %r10, %r11 # end of name >= struct exec_jump_command - 8
.replace_phent: jae 1f # save exec command
movq 24(%r8), %r9 xorq %r10, %r10
movq %r9, -8(%rsp) # set at_phent subq %r9, %r10
jmp .one_auxv leaq -9(%r11,%r10,1), %rdi # position of new name
.replace_phnum: movq %rdi, %r10
movq 32(%r8), %r9 cld
movq %r9, -8(%rsp) # set at_phnum leaq 1(%r9), %rcx # length (including termination)
jmp .one_auxv rep movsb # copy file name
.replace_entry: movq %r10, %rsi # file name
movq 16(%r8), %r9 /* Preserve jump command. */
movq %r9, -8(%rsp) # set at_entry 1: cmpq %r8, %r11 # decide copy direction
jmp .one_auxv jb 1f # copy forward
.replace_base: movq 48(%r8), %rax
movq 48(%r8), %r9 movq %rax, 48(%r11) # %r11->at_base
movq %r9, -8(%rsp) # set at_base movq 40(%r8), %rax
jmp .one_auxv movq %rax, 40(%r11) # %r11->at_phdr
.cleanup: movq 32(%r8), %rax
movq %rax, 32(%r11) # %r11->at_phnum
movq 24(%r8), %rax
movq %rax, 24(%r11) # %r11->at_phent
movq 16(%r8), %rax
movq %rax, 16(%r11) # %r11->at_entry
movq 8(%r8), %rax
movq %rax, 8(%r11) # %r11->entry
movq (%r8), %rax
movq %rax, (%r11) # %r11->command
movq %r14, -8(%r11) # destination of file name
jmp copy_env_and_args
1: movq %r14, -8(%r11) # destination of file name
movq (%r8), %rax
movq %rax, (%r11) # %r11->command
movq 8(%r8), %rax
movq %rax, 8(%r11) # %r11->entry
movq 16(%r8), %rax
movq %rax, 16(%r11) # %r11->at_entry
movq 24(%r8), %rax
movq %rax, 24(%r11) # %r11->at_phent
movq 32(%r8), %rax
movq %rax, 32(%r11) # %r11->at_phnum
movq 40(%r8), %rax
movq %rax, 40(%r11) # %r11->at_phdr
movq 48(%r8), %rax
movq %rax, 48(%r11) # %r11->at_base
copy_env_and_args:
/* Copy argv and environ to their new positions. */
leaq 8(%r13), %r10 # src
leaq 64(%r11), %rdi # dest
movq (%r13), %rcx # argc
movq %rcx, -8(%rdi) # copy argc
1: movq (%r10), %rcx
movq %rcx, (%rdi)
testq %rcx, %rcx
leaq 8(%r10), %r10 # src++
leaq 8(%rdi), %rdi # dst++
jnz 1b
1: movq (%r10), %rcx
movq %rcx, (%rdi)
testq %rcx, %rcx
leaq 8(%r10), %r10 # src++
leaq 8(%rdi), %rdi # dst++
jnz 1b
copy_auxv:
movq (%r10), %rcx # a_type
movq 8(%r10), %rdx # a_un.a_val
addq $16, %r10 # next entry
movq %rcx, (%rdi)
jrcxz cleanup # AT_NULL
cmpq $3, %rcx # AT_PHDR
cmoveq 40(%r11), %rdx # %r11->at_phdr
cmpq $4, %rcx # AT_PHENT
cmoveq 24(%r11), %rdx # %r11->at_phent
cmpq $5, %rcx # AT_PHNUM
cmoveq 32(%r11), %rdx # %r11->at_phnum
cmpq $9, %rcx # AT_ENTRY
cmoveq 16(%r11), %rdx # %r11->at_entry
cmpq $7, %rcx # AT_BASE
cmoveq 48(%r11), %rdx # %r11->at_base
cmpq $31, %rcx # AT_EXECFN
jne 1f
movq -8(%r11), %rdx # string
1: movq %rdx, 8(%rdi) # AT_NULL value
addq $16, %rdi # next entry
jmp copy_auxv
cleanup:
/* Copy the filename. */
movq -8(%r11), %rdi # destination of file name
leaq 1(%r9), %rcx # length (including termination)
rep movsb
movq %rdx, 8(%rdi) # AT_NULL value
leaq 56(%r11), %r13 # restore original stack pointer
movq $3, %rax # SYS_close movq $3, %rax # SYS_close
cmpq $-1, %r12 # see if interpreter fd is set cmpq $-1, %r12 # see if interpreter fd is set
je .cleanup_1 je cleanup_1
movq %r12, %rdi movq %r12, %rdi
syscall syscall
movq $3, %rax # SYS_close movq $3, %rax # SYS_close
.cleanup_1: cleanup_1:
movq %rbx, %rdi movq %rbx, %rdi
syscall syscall
.enter: /* Enter the program. */
pushq $0 pushq $0
popfq # clear FP state popfq # clear FP state
movq %r13, %rsp # restore SP movq %r13, %rsp # restore SP
xorq %rdx, %rdx # clear rtld_fini xorq %rdx, %rdx # clear rtld_fini
jmpq *8(%r8) # entry jmpq *-48(%rsp) # entry
error: error:
.ascii "_start: internal error." .ascii "_start: internal error.\n"
timespec: #timespec:
.quad 10 # .quad 10
.quad 10 # .quad 10
# Local Variables:
# asm-comment-char: ?#
# End:

View file

@ -909,6 +909,18 @@ finish_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
tracee->pid, 0, 0)) tracee->pid, 0, 0))
goto error; goto error;
/* Enable this block to debug the executable loader. */
#if 0
{
int rc, wstatus;
again1:
rc = waitpid (tracee->pid, &wstatus, __WALL);
if (rc == -1 && errno == EINTR)
goto again1;
ptrace (PTRACE_DETACH, tracee->pid, 0, 0);
}
#endif /* 0 */
error: error:
free (tracee->exec_data); free (tracee->exec_data);
tracee->exec_data = NULL; tracee->exec_data = NULL;
@ -1234,7 +1246,11 @@ process_system_call (struct exec_tracee *tracee)
set, this must be exec, whatever the value of SYSCALL_NUM_REG, set, this must be exec, whatever the value of SYSCALL_NUM_REG,
which is erased when exec loads another image. */ which is erased when exec loads another image. */
callno = (!tracee->exec_data ? regs.SYSCALL_NUM_REG : EXEC_SYSCALL); callno = (!tracee->exec_data
? (!tracee->waiting_for_syscall
? regs.SYSCALL_NUM_REG : tracee->callno)
: EXEC_SYSCALL);
tracee->callno = callno;
switch (callno) switch (callno)
{ {
case EXEC_SYSCALL: case EXEC_SYSCALL:
@ -1641,6 +1657,11 @@ seccomp_system_call (struct exec_tracee *tracee)
/* Now dispatch based on the system call. */ /* Now dispatch based on the system call. */
callno = regs.SYSCALL_NUM_REG; callno = regs.SYSCALL_NUM_REG;
/* Record the call number, which may be required if one of the
following handlers should arrange for process_system_call to
intercede after the system call completes. */
tracee->callno = callno;
switch (callno) switch (callno)
{ {
case EXEC_SYSCALL: case EXEC_SYSCALL:
@ -1703,7 +1724,7 @@ seccomp_system_call (struct exec_tracee *tracee)
if (rc < 0) if (rc < 0)
return; return;
tracee->waiting_for_syscall = !tracee->waiting_for_syscall; tracee->waiting_for_syscall = true;
break; break;
default: default:
@ -2021,6 +2042,7 @@ after_fork (pid_t pid)
return 1; return 1;
tracee->pid = pid; tracee->pid = pid;
tracee->callno = 0;
tracee->next = tracing_processes; tracee->next = tracing_processes;
tracee->waiting_for_syscall = false; tracee->waiting_for_syscall = false;
tracee->new_child = false; tracee->new_child = false;

4
java/README.res Normal file
View file

@ -0,0 +1,4 @@
* The wrench icon that is superimposed on Emacs's own icon in
res/drawable/emacs_wrench.png was released into the Public Domain by the
Tango Desktop Project.
<https://web.archive.org/web/20230207074050/https://tango.freedesktop.org/Tango_Desktop_Project>

View file

@ -196,6 +196,10 @@ public final class EmacsNative
/* Send an ANDROID_NOTIFICATION_ACTION event. */ /* Send an ANDROID_NOTIFICATION_ACTION event. */
public static native void sendNotificationAction (String tag, String action); public static native void sendNotificationAction (String tag, String action);
/* Send an ANDROID_CONFIGURATION_CHANGED event. */
public static native void sendConfigurationChanged (float dpiX, float dpiY,
float dpiScaled);
/* Return the file name associated with the specified file /* Return the file name associated with the specified file
descriptor, or NULL if there is none. */ descriptor, or NULL if there is none. */
public static native byte[] getProcName (int fd); public static native byte[] getProcName (int fd);

View file

@ -29,6 +29,7 @@ import android.graphics.Rect;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
@ -103,6 +104,8 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver
public public
Sdk7FontEntity (Sdk7Typeface typeface) Sdk7FontEntity (Sdk7Typeface typeface)
{ {
DisplayMetrics metrics;
foundry = "Google"; foundry = "Google";
family = typeface.familyName; family = typeface.familyName;
adstyle = null; adstyle = null;
@ -110,7 +113,8 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver
slant = typeface.slant; slant = typeface.slant;
spacing = typeface.spacing; spacing = typeface.spacing;
width = typeface.width; width = typeface.width;
dpi = Math.round (EmacsService.SERVICE.metrics.scaledDensity * 160f); metrics = EmacsService.SERVICE.getResources ().getDisplayMetrics ();
dpi = Math.round (metrics.scaledDensity * 160f);
this.typeface = typeface; this.typeface = typeface;
} }
@ -127,6 +131,7 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver
{ {
float totalWidth; float totalWidth;
String testWidth, testString; String testWidth, testString;
DisplayMetrics metrics;
this.typeface = typeface; this.typeface = typeface;
this.pixelSize = pixelSize; this.pixelSize = pixelSize;
@ -137,7 +142,8 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver
slant = typeface.slant; slant = typeface.slant;
spacing = typeface.spacing; spacing = typeface.spacing;
width = typeface.width; width = typeface.width;
dpi = Math.round (EmacsService.SERVICE.metrics.scaledDensity * 160f); metrics = EmacsService.SERVICE.getResources ().getDisplayMetrics ();
dpi = Math.round (metrics.scaledDensity * 160f);
/* Compute the ascent and descent. */ /* Compute the ascent and descent. */
typeface.typefacePaint.setTextSize (pixelSize); typeface.typefacePaint.setTextSize (pixelSize);

View file

@ -123,9 +123,6 @@ public final class EmacsService extends Service
public static final int IC_MODE_TEXT = 2; public static final int IC_MODE_TEXT = 2;
public static final int IC_MODE_PASSWORD = 3; public static final int IC_MODE_PASSWORD = 3;
/* Display metrics used by font backends. */
public DisplayMetrics metrics;
/* Flag that says whether or not to print verbose debugging /* Flag that says whether or not to print verbose debugging
information when responding to an input method. */ information when responding to an input method. */
public static final boolean DEBUG_IC = false; public static final boolean DEBUG_IC = false;
@ -149,8 +146,9 @@ public final class EmacsService extends Service
thread. */ thread. */
private Thread mainThread; private Thread mainThread;
/* "Resources" object required by GContext bookkeeping. */ /* The display's horizontal and vertical density and that which is
public static Resources resources; consulted for font scaling. */
private double dpiX, dpiY, dpiScaled;
static static
{ {
@ -236,10 +234,12 @@ public final class EmacsService extends Service
final AssetManager manager; final AssetManager manager;
Context app_context; Context app_context;
final String filesDir, libDir, cacheDir, classPath; final String filesDir, libDir, cacheDir, classPath;
final double pixelDensityX; final float pixelDensityX;
final double pixelDensityY; final float pixelDensityY;
final double scaledDensity; final float scaledDensity;
double tempScaledDensity; float tempScaledDensity;
Resources resources;
DisplayMetrics metrics;
super.onCreate (); super.onCreate ();
@ -265,13 +265,18 @@ public final class EmacsService extends Service
corresponds to 1 pixel, not 72 or 96 as used elsewhere. This corresponds to 1 pixel, not 72 or 96 as used elsewhere. This
difference is codified in PT_PER_INCH defined in font.h. */ difference is codified in PT_PER_INCH defined in font.h. */
if (tempScaledDensity < 160) if (tempScaledDensity < 160.0f)
tempScaledDensity = 160; tempScaledDensity = 160.0f;
/* scaledDensity is const as required to refer to it from within /* scaledDensity is const as required to refer to it from within
the nested function below. */ the nested function below. */
scaledDensity = tempScaledDensity; scaledDensity = tempScaledDensity;
/* Save these fields for future reference. */
dpiX = pixelDensityX;
dpiY = pixelDensityY;
dpiScaled = scaledDensity;
/* Remove all tasks from previous Emacs sessions but the task /* Remove all tasks from previous Emacs sessions but the task
created by the system at startup. */ created by the system at startup. */
EmacsWindowManager.MANAGER.removeOldTasks (this); EmacsWindowManager.MANAGER.removeOldTasks (this);
@ -304,9 +309,8 @@ public final class EmacsService extends Service
run () run ()
{ {
EmacsNative.setEmacsParams (manager, filesDir, libDir, EmacsNative.setEmacsParams (manager, filesDir, libDir,
cacheDir, (float) pixelDensityX, cacheDir, pixelDensityX,
(float) pixelDensityY, pixelDensityY, scaledDensity,
(float) scaledDensity,
classPath, EmacsService.this, classPath, EmacsService.this,
Build.VERSION.SDK_INT); Build.VERSION.SDK_INT);
} }
@ -344,6 +348,40 @@ public final class EmacsService extends Service
super.onLowMemory (); super.onLowMemory ();
} }
@Override
public void
onConfigurationChanged (Configuration newConfig)
{
DisplayMetrics metrics;
float pixelDensityX, pixelDensityY, scaledDensity;
metrics = getResources ().getDisplayMetrics ();
/* The display configuration may have been altered. Retrieve the
revised display density and deliver an event if so. */
pixelDensityX = metrics.xdpi;
pixelDensityY = metrics.ydpi;
scaledDensity = ((getScaledDensity (metrics)
/ metrics.density) * pixelDensityX);
/* A density below 160 probably indicates a system bug. See
onCreate for more commentary. */
if (scaledDensity < 160.0f)
scaledDensity = 160.0f;
if (pixelDensityX != dpiX || pixelDensityY != dpiY
|| scaledDensity != dpiScaled)
{
dpiX = pixelDensityX;
dpiY = pixelDensityY;
dpiScaled = scaledDensity;
EmacsNative.sendConfigurationChanged (pixelDensityX, pixelDensityY,
scaledDensity);
}
super.onConfigurationChanged (newConfig);
}
/* Functions from here on must only be called from the Emacs /* Functions from here on must only be called from the Emacs

View file

@ -1715,8 +1715,13 @@ set_socket (bool no_exit_if_error)
} }
#ifdef HAVE_NTGUI #ifdef HAVE_NTGUI
FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */ typedef void (* VOIDFNPTR) (void);
FARPROC get_wc; /* Pointer to RealGetWindowClassA. */ typedef BOOL (WINAPI *AllowSetForegroundWindow_proc) (DWORD);
/* Pointer to AllowSetForegroundWindow. */
static AllowSetForegroundWindow_proc set_fg;
typedef UINT (WINAPI *RealGetWindowClassA_proc) (HWND, LPSTR, UINT);
/* Pointer to RealGetWindowClassA. */
static RealGetWindowClassA_proc get_wc;
void w32_set_user_model_id (void); void w32_set_user_model_id (void);
@ -1794,8 +1799,8 @@ w32_give_focus (void)
emacsclient can allow Emacs to grab the focus by calling the function emacsclient can allow Emacs to grab the focus by calling the function
AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and
NT) lack this function, so we have to check its availability. */ NT) lack this function, so we have to check its availability. */
if ((set_fg = GetProcAddress (user32, "AllowSetForegroundWindow")) if ((set_fg = (AllowSetForegroundWindow_proc) (VOIDFNPTR) GetProcAddress (user32, "AllowSetForegroundWindow"))
&& (get_wc = GetProcAddress (user32, "RealGetWindowClassA"))) && (get_wc = (RealGetWindowClassA_proc) (VOIDFNPTR) GetProcAddress (user32, "RealGetWindowClassA")))
EnumWindows (w32_find_emacs_process, (LPARAM) 0); EnumWindows (w32_find_emacs_process, (LPARAM) 0);
} }
#endif /* HAVE_NTGUI */ #endif /* HAVE_NTGUI */

View file

@ -42,6 +42,7 @@ variants of those files that can be used to sandbox Emacs before
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <asm/termbits.h> /* mandatory accordingly to latest ioctl_tty(2) */
#include <time.h> #include <time.h>
#include <asm/prctl.h> #include <asm/prctl.h>
@ -64,6 +65,11 @@ variants of those files that can be used to sandbox Emacs before
#define ARCH_CET_STATUS 0x3001 #define ARCH_CET_STATUS 0x3001
#endif #endif
/* https://github.com/torvalds/linux/commit/9651fcedf7b92d3f7f1ab179e8ab55b85ee10fc1 */
#ifndef MAP_DROPPABLE
#define MAP_DROPPABLE 0x08
#endif
static ATTRIBUTE_FORMAT_PRINTF (2, 3) _Noreturn void static ATTRIBUTE_FORMAT_PRINTF (2, 3) _Noreturn void
fail (int error, const char *format, ...) fail (int error, const char *format, ...)
{ {
@ -187,7 +193,7 @@ main (int argc, char **argv)
some versions of the dynamic loader still use it. Also some versions of the dynamic loader still use it. Also
allow allocating thread stacks. */ allow allocating thread stacks. */
SCMP_A3_32 (SCMP_CMP_MASKED_EQ, SCMP_A3_32 (SCMP_CMP_MASKED_EQ,
~(MAP_SHARED | MAP_PRIVATE | MAP_FILE ~(MAP_SHARED | MAP_PRIVATE | MAP_FILE | MAP_DROPPABLE
| MAP_ANONYMOUS | MAP_FIXED | MAP_DENYWRITE | MAP_ANONYMOUS | MAP_FIXED | MAP_DENYWRITE
| MAP_STACK | MAP_NORESERVE), | MAP_STACK | MAP_NORESERVE),
0)); 0));
@ -274,6 +280,11 @@ main (int argc, char **argv)
SCMP_A0_32 (SCMP_CMP_EQ, STDIN_FILENO), SCMP_A0_32 (SCMP_CMP_EQ, STDIN_FILENO),
SCMP_A1_32 (SCMP_CMP_EQ, TIOCGPGRP)); SCMP_A1_32 (SCMP_CMP_EQ, TIOCGPGRP));
/* Allow `tcgetattr' call of glibc on physical terminal devices. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (ioctl),
SCMP_A0_32 (SCMP_CMP_EQ, STDERR_FILENO),
SCMP_A1_32 (SCMP_CMP_EQ, TCGETS));
/* Allow reading (but not setting) file flags. */ /* Allow reading (but not setting) file flags. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (fcntl), RULE (SCMP_ACT_ALLOW, SCMP_SYS (fcntl),
SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL)); SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL));

View file

@ -31,7 +31,7 @@
# include <string.h> # include <string.h>
#endif #endif
#if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ #if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
@ -45,7 +45,7 @@ acl_extended_nontrivial (acl_t acl)
return (acl_entries (acl) > 0); return (acl_entries (acl) > 0);
} }
# else /* Linux, FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */ # else /* Linux, FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */
/* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS. /* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
Return 1 if the given ACL is non-trivial. Return 1 if the given ACL is non-trivial.
@ -59,7 +59,7 @@ acl_access_nontrivial (acl_t acl)
at least, allowing us to write at least, allowing us to write
return (3 < acl_entries (acl)); return (3 < acl_entries (acl));
but the following code is more robust. */ but the following code is more robust. */
# if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, Cygwin >= 2.5 */ # if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */
acl_entry_t ace; acl_entry_t ace;
int got_one; int got_one;
@ -548,7 +548,7 @@ void
free_permission_context (struct permission_context *ctx) free_permission_context (struct permission_context *ctx)
{ {
#if USE_ACL #if USE_ACL
# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ # if HAVE_ACL_GET_FILE /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
if (ctx->acl) if (ctx->acl)
acl_free (ctx->acl); acl_free (ctx->acl);
# if !HAVE_ACL_TYPE_EXTENDED # if !HAVE_ACL_TYPE_EXTENDED

View file

@ -52,10 +52,7 @@ extern int aclsort (int, int, struct acl *);
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <stdint.h>
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
#ifndef HAVE_FCHMOD #ifndef HAVE_FCHMOD
# define HAVE_FCHMOD false # define HAVE_FCHMOD false
@ -121,8 +118,13 @@ rpl_acl_set_fd (int fd, acl_t acl)
# endif # endif
/* Linux-specific */ /* Linux-specific */
/* Cygwin >= 2.5 implements this function, but it returns 1 for all /* Cygwin >= 2.5 implements acl_extended_file(), but it returns 1 for nearly all
directories, thus is unusable. */ directories for reasons explained in
<https://sourceware.org/pipermail/cygwin/2025-March/257762.html> —, thus is
unusable. For the user, 'ls' should not print a '+' sign, indicating the
presence of an ACL, for 99,9% of the files; this would not be useful.
Therefore, on Cygwin, we ignore the acl_extended_file function and instead
use our own acl_access_nontrivial function. */
# if !defined HAVE_ACL_EXTENDED_FILE || defined __CYGWIN__ # if !defined HAVE_ACL_EXTENDED_FILE || defined __CYGWIN__
# undef HAVE_ACL_EXTENDED_FILE # undef HAVE_ACL_EXTENDED_FILE
# define HAVE_ACL_EXTENDED_FILE false # define HAVE_ACL_EXTENDED_FILE false

View file

@ -22,7 +22,7 @@
#include "acl-internal.h" #include "acl-internal.h"
/* This file assumes POSIX-draft like ACLs /* This file assumes POSIX-draft like ACLs
(Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5). */ (Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5). */
/* Return the number of entries in ACL. /* Return the number of entries in ACL.
Return -1 and set errno upon failure to determine it. */ Return -1 and set errno upon failure to determine it. */
@ -34,7 +34,7 @@ acl_entries (acl_t acl)
if (acl != NULL) if (acl != NULL)
{ {
#if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, Mac OS X, Cygwin >= 2.5 */ #if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, Cygwin >= 2.5 */
# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
/* acl_get_entry returns 0 when it successfully fetches an entry, /* acl_get_entry returns 0 when it successfully fetches an entry,
and -1/EINVAL at the end. */ and -1/EINVAL at the end. */
@ -45,7 +45,7 @@ acl_entries (acl_t acl)
got_one >= 0; got_one >= 0;
got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace)) got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
count++; count++;
# else /* Linux, FreeBSD, Cygwin >= 2.5 */ # else /* Linux, FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */
/* acl_get_entry returns 1 when it successfully fetches an entry, /* acl_get_entry returns 1 when it successfully fetches an entry,
and 0 at the end. */ and 0 at the end. */
acl_entry_t ace; acl_entry_t ace;

View file

@ -22,8 +22,12 @@
#endif #endif
@PRAGMA_COLUMNS@ @PRAGMA_COLUMNS@
#if defined __need_system_fcntl_h #if defined __need_system_fcntl_h || defined _@GUARD_PREFIX@_ALREADY_INCLUDING_FCNTL_H
/* Special invocation convention. */ /* Special invocation convention:
- On Haiku we have a sequence of nested includes
<fcntl.h> -> <unistd.h> -> <fcntl.h>
In this situation, GNULIB_defined_O_NONBLOCK gets defined before the
system's definition of O_NONBLOCK is processed. */
/* Needed before <sys/stat.h>. /* Needed before <sys/stat.h>.
May also define off_t to a 64-bit type on native Windows. */ May also define off_t to a 64-bit type on native Windows. */
@ -50,6 +54,8 @@
#ifndef _@GUARD_PREFIX@_FCNTL_H #ifndef _@GUARD_PREFIX@_FCNTL_H
#define _@GUARD_PREFIX@_ALREADY_INCLUDING_FCNTL_H
/* Needed before <sys/stat.h>. /* Needed before <sys/stat.h>.
May also define off_t to a 64-bit type on native Windows. May also define off_t to a 64-bit type on native Windows.
Also defines off64_t on macOS, NetBSD, OpenBSD, MSVC, Cygwin, Haiku. */ Also defines off64_t on macOS, NetBSD, OpenBSD, MSVC, Cygwin, Haiku. */
@ -72,6 +78,8 @@
# include <io.h> # include <io.h>
#endif #endif
#undef _@GUARD_PREFIX@_ALREADY_INCLUDING_FCNTL_H
#ifndef _@GUARD_PREFIX@_FCNTL_H #ifndef _@GUARD_PREFIX@_FCNTL_H
#define _@GUARD_PREFIX@_FCNTL_H #define _@GUARD_PREFIX@_FCNTL_H

View file

@ -50,7 +50,6 @@ static char const UNKNOWN_SECURITY_CONTEXT[] = "?";
# include <selinux/selinux.h> # include <selinux/selinux.h>
# endif # endif
# include <stdckdint.h> # include <stdckdint.h>
# include <stdint.h>
# include <string.h> # include <string.h>
# include <arpa/inet.h> # include <arpa/inet.h>
# include <sys/xattr.h> # include <sys/xattr.h>
@ -363,6 +362,29 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes)
} }
#endif #endif
#if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FD \
&& !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED \
&& !HAVE_ACL_GET_LINK_NP)
# include <fcntl.h>
# ifdef O_PATH
/* Like acl_get_file, but do not follow symbolic links. */
static acl_t
acl_get_link_np (char const *name, acl_type_t type)
{
int fd = open (name, O_PATH | O_NOFOLLOW);
if (fd < 0)
return NULL;
acl_t r = acl_get_fd (fd);
int err = errno;
close (fd);
errno = err;
return r;
}
# define HAVE_ACL_GET_LINK_NP 1
# endif
#endif
/* Return 1 if NAME has a nontrivial access control list, /* Return 1 if NAME has a nontrivial access control list,
0 if ACLs are not supported, or if NAME has no or only a base ACL, 0 if ACLs are not supported, or if NAME has no or only a base ACL,
and -1 (setting errno) on error. Note callers can determine and -1 (setting errno) on error. Note callers can determine
@ -468,7 +490,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
ret = -1; ret = -1;
# else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ # else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */
acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file; acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file;
# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10 */ # if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */
if (! (flags & ACL_SYMLINK_FOLLOW)) if (! (flags & ACL_SYMLINK_FOLLOW))
acl_get_file_or_link = acl_get_link_np; acl_get_file_or_link = acl_get_link_np;
# endif # endif

View file

@ -26,7 +26,7 @@
/* This file is not used on systems that already have the __fpending function, /* This file is not used on systems that already have the __fpending function,
namely glibc >= 2.2, Solaris >= 7, UnixWare >= 7.1.4.MP4, Cygwin >= 1.7.34, namely glibc >= 2.2, Solaris >= 7, UnixWare >= 7.1.4.MP4, Cygwin >= 1.7.34,
Android API >= 23. */ Android API >= 23, musl libc, Haiku >= hrev58760. */
/* Return the number of pending (aka buffered, unflushed) /* Return the number of pending (aka buffered, unflushed)
bytes on the stream, FP, that is open for writing. */ bytes on the stream, FP, that is open for writing. */

View file

@ -47,8 +47,6 @@
N_NAME_POINTER The nlist n_name element is a pointer, N_NAME_POINTER The nlist n_name element is a pointer,
not an array. not an array.
HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'. HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'.
LINUX_LDAV_FILE [__linux__, __ANDROID__, __CYGWIN__]: File
containing load averages.
Specific system predefines this file uses, aside from setting Specific system predefines this file uses, aside from setting
default values if not emacs: default values if not emacs:
@ -65,8 +63,7 @@
UMAX4_3 UMAX4_3
VMS VMS
_WIN32 Native Windows (possibly also defined on Cygwin) _WIN32 Native Windows (possibly also defined on Cygwin)
__linux__, __ANDROID__ Linux: assumes /proc file system mounted. __linux__, __ANDROID__ Linux: assumes sysinfo() call.
Support from Michael K. Johnson.
__CYGWIN__ Cygwin emulates linux /proc/loadavg. __CYGWIN__ Cygwin emulates linux /proc/loadavg.
__NetBSD__ NetBSD: assumes /kern file system mounted. __NetBSD__ NetBSD: assumes /kern file system mounted.
@ -108,10 +105,10 @@
# endif # endif
/* Same issues as for NeXT apply to the HURD-based GNU system. */ /* Same issues as for NeXT apply to the HURD-based GNU system. */
# ifdef __GNU__ # if defined __gnu_hurd__ || defined NeXT
# undef BSD # undef BSD
# undef FSCALE # undef FSCALE
# endif /* __GNU__ */ # endif /* __gnu_hurd__ || NeXT */
/* Set values that are different from the defaults, which are /* Set values that are different from the defaults, which are
set a little farther down with #ifndef. */ set a little farther down with #ifndef. */
@ -312,8 +309,7 @@
# endif # endif
# endif # endif
# if defined (__GNU__) && !defined (NeXT) # if defined __gnu_hurd__ && !defined NeXT
/* Note that NeXT Openstep defines __GNU__ even though it should not. */
/* GNU system acts much like NeXT, for load average purposes, /* GNU system acts much like NeXT, for load average purposes,
but not exactly. */ but not exactly. */
# define NeXT # define NeXT
@ -358,6 +354,11 @@
# include <sys/dg_sys_info.h> # include <sys/dg_sys_info.h>
# endif # endif
# if defined __linux__ || defined __ANDROID__
# include <sys/param.h>
# include <sys/sysinfo.h>
# endif
# if (defined __linux__ || defined __ANDROID__ \ # if (defined __linux__ || defined __ANDROID__ \
|| defined __CYGWIN__ || defined SUNOS_5 \ || defined __CYGWIN__ || defined SUNOS_5 \
|| (defined LOAD_AVE_TYPE && ! defined __VMS)) || (defined LOAD_AVE_TYPE && ! defined __VMS))
@ -498,20 +499,33 @@ getloadavg (double loadavg[], int nelem)
} }
# endif # endif
# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__ || defined __CYGWIN__) # if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__) \
&& (!defined __ANDROID__ || __ANDROID_API__ >= 13)
/* Linux without glibc, Android, Cygwin */ /* Linux without glibc, Android, Cygwin */
# define LDAV_DONE # define LDAV_DONE
# undef LOAD_AVE_TYPE # undef LOAD_AVE_TYPE
# ifndef LINUX_LDAV_FILE {
# define LINUX_LDAV_FILE "/proc/loadavg" struct sysinfo info;
# endif if (sysinfo (&info) < 0)
return -1;
loadavg[0] = info.loads[0] / (double)(1U << SI_LOAD_SHIFT);
loadavg[1] = info.loads[1] / (double)(1U << SI_LOAD_SHIFT);
loadavg[2] = info.loads[2] / (double)(1U << SI_LOAD_SHIFT);
elem = 3;
}
# endif /* __linux__ || __ANDROID__ */
# if !defined (LDAV_DONE) && defined __CYGWIN__
/* Cygwin */
# define LDAV_DONE
# undef LOAD_AVE_TYPE
char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")];
char const *ptr = ldavgbuf; char const *ptr = ldavgbuf;
int fd, count, saved_errno; int fd, count, saved_errno;
fd = open (LINUX_LDAV_FILE, O_RDONLY | O_CLOEXEC); fd = open ("/proc/loadavg", O_RDONLY | O_CLOEXEC);
if (fd == -1) if (fd == -1)
return -1; return -1;
count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); count = read (fd, ldavgbuf, sizeof ldavgbuf - 1);
@ -554,7 +568,7 @@ getloadavg (double loadavg[], int nelem)
return elem; return elem;
# endif /* __linux__ || __ANDROID__ || __CYGWIN__ */ # endif /* __CYGWIN__ */
# if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */ # if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */
# define LDAV_DONE # define LDAV_DONE

View file

@ -38,11 +38,9 @@
# endif # endif
# undef getopt_long # undef getopt_long
# undef getopt_long_only # undef getopt_long_only
# undef option
# undef _getopt_internal # undef _getopt_internal
# define getopt_long __GETOPT_ID (getopt_long) # define getopt_long __GETOPT_ID (getopt_long)
# define getopt_long_only __GETOPT_ID (getopt_long_only) # define getopt_long_only __GETOPT_ID (getopt_long_only)
# define option __GETOPT_ID (option)
# define _getopt_internal __GETOPT_ID (getopt_internal) # define _getopt_internal __GETOPT_ID (getopt_internal)
/* The system's getopt.h may have already included getopt-ext.h to /* The system's getopt.h may have already included getopt-ext.h to

View file

@ -30,7 +30,12 @@
<getopt.h>; our definitions will be present soon enough. */ <getopt.h>; our definitions will be present soon enough. */
#if @HAVE_GETOPT_H@ #if @HAVE_GETOPT_H@
# define _GL_SYSTEM_GETOPT # define _GL_SYSTEM_GETOPT
/* Rename the system's 'struct option' to 'struct sys_option',
so that we don't have to rename ours to 'struct rpl_option'
(which would cause significant trouble in C++ mode). */
# define option sys_option
# @INCLUDE_NEXT@ @NEXT_GETOPT_H@ # @INCLUDE_NEXT@ @NEXT_GETOPT_H@
# undef option
# undef _GL_SYSTEM_GETOPT # undef _GL_SYSTEM_GETOPT
#endif #endif

View file

@ -22,6 +22,7 @@
# Generated by gnulib-tool. # Generated by gnulib-tool.
# Reproduce by: # Reproduce by:
# gnulib-tool --import \ # gnulib-tool --import \
# --local-dir=./admin/gnulib-patches \
# --lib=libgnu \ # --lib=libgnu \
# --source-base=lib \ # --source-base=lib \
# --m4-base=m4 \ # --m4-base=m4 \
@ -49,6 +50,7 @@
# --avoid=iswxdigit \ # --avoid=iswxdigit \
# --avoid=langinfo-h \ # --avoid=langinfo-h \
# --avoid=libgmp-mpq \ # --avoid=libgmp-mpq \
# --avoid=locale-h \
# --avoid=localename-unsafe-limited \ # --avoid=localename-unsafe-limited \
# --avoid=lock \ # --avoid=lock \
# --avoid=mbrtowc \ # --avoid=mbrtowc \
@ -624,6 +626,7 @@ GL_GNULIB_STRCHRNUL = @GL_GNULIB_STRCHRNUL@
GL_GNULIB_STRDUP = @GL_GNULIB_STRDUP@ GL_GNULIB_STRDUP = @GL_GNULIB_STRDUP@
GL_GNULIB_STRERROR = @GL_GNULIB_STRERROR@ GL_GNULIB_STRERROR = @GL_GNULIB_STRERROR@
GL_GNULIB_STRERRORNAME_NP = @GL_GNULIB_STRERRORNAME_NP@ GL_GNULIB_STRERRORNAME_NP = @GL_GNULIB_STRERRORNAME_NP@
GL_GNULIB_STRERROR_L = @GL_GNULIB_STRERROR_L@
GL_GNULIB_STRERROR_R = @GL_GNULIB_STRERROR_R@ GL_GNULIB_STRERROR_R = @GL_GNULIB_STRERROR_R@
GL_GNULIB_STRFTIME = @GL_GNULIB_STRFTIME@ GL_GNULIB_STRFTIME = @GL_GNULIB_STRFTIME@
GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@ GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@
@ -916,6 +919,7 @@ HAVE_STR2SIG = @HAVE_STR2SIG@
HAVE_STRCASESTR = @HAVE_STRCASESTR@ HAVE_STRCASESTR = @HAVE_STRCASESTR@
HAVE_STRCHRNUL = @HAVE_STRCHRNUL@ HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
HAVE_STRERRORNAME_NP = @HAVE_STRERRORNAME_NP@ HAVE_STRERRORNAME_NP = @HAVE_STRERRORNAME_NP@
HAVE_STRERROR_L = @HAVE_STRERROR_L@
HAVE_STRPBRK = @HAVE_STRPBRK@ HAVE_STRPBRK = @HAVE_STRPBRK@
HAVE_STRPTIME = @HAVE_STRPTIME@ HAVE_STRPTIME = @HAVE_STRPTIME@
HAVE_STRSEP = @HAVE_STRSEP@ HAVE_STRSEP = @HAVE_STRSEP@
@ -1213,6 +1217,7 @@ REPLACE_GETENTROPY = @REPLACE_GETENTROPY@
REPLACE_GETGROUPS = @REPLACE_GETGROUPS@ REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
REPLACE_GETLINE = @REPLACE_GETLINE@ REPLACE_GETLINE = @REPLACE_GETLINE@
REPLACE_GETLOADAVG = @REPLACE_GETLOADAVG@ REPLACE_GETLOADAVG = @REPLACE_GETLOADAVG@
REPLACE_GETLOGIN = @REPLACE_GETLOGIN@
REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@ REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@ REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
REPLACE_GETPASS = @REPLACE_GETPASS@ REPLACE_GETPASS = @REPLACE_GETPASS@
@ -1307,6 +1312,7 @@ REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@
REPLACE_STRDUP = @REPLACE_STRDUP@ REPLACE_STRDUP = @REPLACE_STRDUP@
REPLACE_STRERROR = @REPLACE_STRERROR@ REPLACE_STRERROR = @REPLACE_STRERROR@
REPLACE_STRERRORNAME_NP = @REPLACE_STRERRORNAME_NP@ REPLACE_STRERRORNAME_NP = @REPLACE_STRERRORNAME_NP@
REPLACE_STRERROR_L = @REPLACE_STRERROR_L@
REPLACE_STRERROR_R = @REPLACE_STRERROR_R@ REPLACE_STRERROR_R = @REPLACE_STRERROR_R@
REPLACE_STRFTIME = @REPLACE_STRFTIME@ REPLACE_STRFTIME = @REPLACE_STRFTIME@
REPLACE_STRNCAT = @REPLACE_STRNCAT@ REPLACE_STRNCAT = @REPLACE_STRNCAT@
@ -1543,6 +1549,7 @@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@ srcdir = @srcdir@
standardlisppath = @standardlisppath@ standardlisppath = @standardlisppath@
sysconfdir = @sysconfdir@ sysconfdir = @sysconfdir@
systemduserunitdir = @systemduserunitdir@
target_alias = @target_alias@ target_alias = @target_alias@
version = @version@ version = @version@
with_mailutils = @with_mailutils@ with_mailutils = @with_mailutils@
@ -1715,13 +1722,25 @@ libgnu_a_SOURCES += c-ctype.h c-ctype.c
endif endif
## end gnulib module c-ctype ## end gnulib module c-ctype
## begin gnulib module c-strcase ## begin gnulib module c-strcasecmp
ifeq (,$(OMIT_GNULIB_MODULE_c-strcase)) ifeq (,$(OMIT_GNULIB_MODULE_c-strcasecmp))
libgnu_a_SOURCES += c-strcase.h c-strcasecmp.c c-strncasecmp.c libgnu_a_SOURCES += c-strcasecmp.c
EXTRA_DIST += c-strcase.h
endif endif
## end gnulib module c-strcase ## end gnulib module c-strcasecmp
## begin gnulib module c-strncasecmp
ifeq (,$(OMIT_GNULIB_MODULE_c-strncasecmp))
libgnu_a_SOURCES += c-strncasecmp.c
EXTRA_DIST += c-strcase.h
endif
## end gnulib module c-strncasecmp
## begin gnulib module canonicalize-lgpl ## begin gnulib module canonicalize-lgpl
ifeq (,$(OMIT_GNULIB_MODULE_canonicalize-lgpl)) ifeq (,$(OMIT_GNULIB_MODULE_canonicalize-lgpl))
@ -3681,6 +3700,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's/@''GNULIB_STR_STARTSWITH''@/$(GL_GNULIB_STR_STARTSWITH)/g' \ -e 's/@''GNULIB_STR_STARTSWITH''@/$(GL_GNULIB_STR_STARTSWITH)/g' \
-e 's/@''GNULIB_STRERROR''@/$(GL_GNULIB_STRERROR)/g' \ -e 's/@''GNULIB_STRERROR''@/$(GL_GNULIB_STRERROR)/g' \
-e 's/@''GNULIB_STRERROR_R''@/$(GL_GNULIB_STRERROR_R)/g' \ -e 's/@''GNULIB_STRERROR_R''@/$(GL_GNULIB_STRERROR_R)/g' \
-e 's/@''GNULIB_STRERROR_L''@/$(GL_GNULIB_STRERROR_L)/g' \
-e 's/@''GNULIB_STRERRORNAME_NP''@/$(GL_GNULIB_STRERRORNAME_NP)/g' \ -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GL_GNULIB_STRERRORNAME_NP)/g' \
-e 's/@''GNULIB_SIGABBREV_NP''@/$(GL_GNULIB_SIGABBREV_NP)/g' \ -e 's/@''GNULIB_SIGABBREV_NP''@/$(GL_GNULIB_SIGABBREV_NP)/g' \
-e 's/@''GNULIB_SIGDESCR_NP''@/$(GL_GNULIB_SIGDESCR_NP)/g' \ -e 's/@''GNULIB_SIGDESCR_NP''@/$(GL_GNULIB_SIGDESCR_NP)/g' \
@ -3711,6 +3731,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \
-e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \
-e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \ -e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \
-e 's|@''HAVE_STRERROR_L''@|$(HAVE_STRERROR_L)|g' \
-e 's|@''HAVE_STRERRORNAME_NP''@|$(HAVE_STRERRORNAME_NP)|g' \ -e 's|@''HAVE_STRERRORNAME_NP''@|$(HAVE_STRERRORNAME_NP)|g' \
-e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \ -e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \
-e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \ -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \
@ -3734,6 +3755,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \ -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \
-e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \
-e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \
-e 's|@''REPLACE_STRERROR_L''@|$(REPLACE_STRERROR_L)|g' \
-e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \ -e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \
-e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \
-e 's|@''REPLACE_STRVERSCMP''@|$(REPLACE_STRVERSCMP)|g' \ -e 's|@''REPLACE_STRVERSCMP''@|$(REPLACE_STRVERSCMP)|g' \
@ -4328,6 +4350,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \
-e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \ -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \
-e 's|@''REPLACE_GETENTROPY''@|$(REPLACE_GETENTROPY)|g' \ -e 's|@''REPLACE_GETENTROPY''@|$(REPLACE_GETENTROPY)|g' \
-e 's|@''REPLACE_GETLOGIN''@|$(REPLACE_GETLOGIN)|g' \
-e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \
-e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \
-e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \

View file

@ -39,7 +39,7 @@
then 'switch (INT_PROMOTE (E))' pacifies gcc -Wswitch-enum if some then 'switch (INT_PROMOTE (E))' pacifies gcc -Wswitch-enum if some
enum values are deliberately omitted from the switch's cases. enum values are deliberately omitted from the switch's cases.
Here, unary + is safer than a cast or inline function, as unary + Here, unary + is safer than a cast or inline function, as unary +
does only integer promotions. */ does only integer promotions and is disallowed on pointers. */
#define INT_PROMOTE(e) (+ (e)) #define INT_PROMOTE(e) (+ (e))

View file

@ -398,20 +398,16 @@ parse_omp_threads (char const* threads)
/* Convert it from positive decimal to 'unsigned long'. */ /* Convert it from positive decimal to 'unsigned long'. */
if (c_isdigit (*threads)) if (c_isdigit (*threads))
{ {
char *endptr = NULL; char *endptr;
unsigned long int value = strtoul (threads, &endptr, 10); unsigned long int value = strtoul (threads, &endptr, 10);
while (*endptr != '\0' && c_isspace (*endptr))
if (endptr != NULL) endptr++;
{ if (*endptr == '\0')
while (*endptr != '\0' && c_isspace (*endptr)) return value;
endptr++; /* Also accept the first value in a nesting level,
if (*endptr == '\0') since we can't determine the nesting level from env vars. */
return value; else if (*endptr == ',')
/* Also accept the first value in a nesting level, return value;
since we can't determine the nesting level from env vars. */
else if (*endptr == ',')
return value;
}
} }
return ret; return ret;
@ -438,6 +434,9 @@ num_processors (enum nproc_query query)
query = NPROC_CURRENT; query = NPROC_CURRENT;
} }
/* Here query is one of NPROC_ALL, NPROC_CURRENT. */ /* Here query is one of NPROC_ALL, NPROC_CURRENT. */
if (omp_env_limit == 1)
/* No need to even call num_processors_ignoring_omp (query). */
return 1;
{ {
unsigned long nprocs = num_processors_ignoring_omp (query); unsigned long nprocs = num_processors_ignoring_omp (query);
return MIN (nprocs, omp_env_limit); return MIN (nprocs, omp_env_limit);

View file

@ -45,7 +45,7 @@
# include <utmp.h> # include <utmp.h>
#endif #endif
/* Needed for BOOT_TIME and USER_PROCESS. */ /* Needed for BOOT_TIME, USER_PROCESS, LOGIN_PROCESS. */
#if HAVE_UTMPX_H #if HAVE_UTMPX_H
# if defined _THREAD_SAFE && defined UTMP_DATA_INIT # if defined _THREAD_SAFE && defined UTMP_DATA_INIT
/* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE
@ -74,7 +74,8 @@ struct gl_utmp
struct timespec ut_ts; /* time */ struct timespec ut_ts; /* time */
pid_t ut_pid; /* process ID of ? */ pid_t ut_pid; /* process ID of ? */
pid_t ut_session; /* process ID of session leader */ pid_t ut_session; /* process ID of session leader */
short ut_type; /* BOOT_TIME, USER_PROCESS, or other */ short ut_type; /* BOOT_TIME, USER_PROCESS, LOGIN_PROCESS,
or other */
struct { int e_termination; int e_exit; } ut_exit; struct { int e_termination; int e_exit; } ut_exit;
}; };
@ -257,19 +258,21 @@ struct utmpx32
# define WTMP_FILE "/etc/wtmp" # define WTMP_FILE "/etc/wtmp"
#endif #endif
/* In early versions of Android, <utmp.h> did not define BOOT_TIME, only /* In early versions of Android, <utmp.h> did not define BOOT_TIME or
USER_PROCESS. We need to use the value that is defined in newer versions LOGIN_PROCESS, only USER_PROCESS. We need to use the value that is defined
of Android. */ in newer versions of Android. */
#if defined __ANDROID__ && !defined BOOT_TIME #if defined __ANDROID__ && !defined BOOT_TIME
# define BOOT_TIME 2 # define BOOT_TIME 2
# define LOGIN_PROCESS 6
#endif #endif
/* Some platforms, such as OpenBSD, don't have an ut_type field and don't have /* Some platforms, such as OpenBSD, don't have an ut_type field and don't have
the BOOT_TIME and USER_PROCESS macros. But we want to support them in the BOOT_TIME, USER_PROCESS, and LOGIN_PROCESS macros. But we want to
'struct gl_utmp'. */ support them in 'struct gl_utmp'. */
#if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE) #if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE)
# define BOOT_TIME 2 # define BOOT_TIME 2
# define USER_PROCESS 0 # define USER_PROCESS 0
# define LOGIN_PROCESS 6
#endif #endif
/* Macros that test (UT)->ut_type. */ /* Macros that test (UT)->ut_type. */
@ -283,6 +286,11 @@ struct utmpx32
#else #else
# define UT_TYPE_USER_PROCESS(UT) 0 # define UT_TYPE_USER_PROCESS(UT) 0
#endif #endif
#ifdef LOGIN_PROCESS
# define UT_TYPE_LOGIN_PROCESS(UT) ((UT)->ut_type == LOGIN_PROCESS)
#else
# define UT_TYPE_LOGIN_PROCESS(UT) 0
#endif
/* Determines whether an entry *UT corresponds to a user process. */ /* Determines whether an entry *UT corresponds to a user process. */
#define IS_USER_PROCESS(UT) \ #define IS_USER_PROCESS(UT) \

View file

@ -831,7 +831,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
if (table_size > pat_len) if (table_size > pat_len)
break; break;
dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size); dfa->state_table = calloc (table_size, sizeof (struct re_state_table_entry));
dfa->state_hash_mask = table_size - 1; dfa->state_hash_mask = table_size - 1;
dfa->mb_cur_max = MB_CUR_MAX; dfa->mb_cur_max = MB_CUR_MAX;
@ -862,7 +862,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
{ {
int i, j, ch; int i, j, ch;
dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); dfa->sb_char = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t));
if (__glibc_unlikely (dfa->sb_char == NULL)) if (__glibc_unlikely (dfa->sb_char == NULL))
return REG_ESPACE; return REG_ESPACE;
@ -3055,8 +3055,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
_NL_COLLATE_SYMB_EXTRAMB); _NL_COLLATE_SYMB_EXTRAMB);
} }
#endif #endif
sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); sbcset = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t));
mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); mbcset = (re_charset_t *) calloc (1, sizeof (re_charset_t));
if (__glibc_unlikely (sbcset == NULL || mbcset == NULL)) if (__glibc_unlikely (sbcset == NULL || mbcset == NULL))
{ {
re_free (sbcset); re_free (sbcset);
@ -3548,13 +3548,13 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
reg_errcode_t ret; reg_errcode_t ret;
bin_tree_t *tree; bin_tree_t *tree;
sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); sbcset = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t));
if (__glibc_unlikely (sbcset == NULL)) if (__glibc_unlikely (sbcset == NULL))
{ {
*err = REG_ESPACE; *err = REG_ESPACE;
return NULL; return NULL;
} }
mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); mbcset = (re_charset_t *) calloc (1, sizeof (re_charset_t));
if (__glibc_unlikely (mbcset == NULL)) if (__glibc_unlikely (mbcset == NULL))
{ {
re_free (sbcset); re_free (sbcset);

View file

@ -66,15 +66,14 @@ typedef unsigned long int active_reg_t;
/* The following bits are used to determine the regexp syntax we /* The following bits are used to determine the regexp syntax we
recognize. The set/not-set meanings are chosen so that Emacs syntax recognize. The set/not-set meanings are chosen so that Emacs syntax
remains the value 0. The bits are given in alphabetical order, and is the value 0 for Emacs 20 (2000) and earlier, and the value
the definitions shifted by one from the previous bit; thus, when we RE_SYNTAX_EMACS for Emacs 21 (2001) and later. */
add or remove a bit, only one other definition need change. */
typedef unsigned long int reg_syntax_t; typedef unsigned long int reg_syntax_t;
#ifdef __USE_GNU #ifdef __USE_GNU
/* If this bit is not set, then \ inside a bracket expression is literal. /* If this bit is not set, then \ inside a bracket expression is literal.
If set, then such a \ quotes the following character. */ If set, then such a \ quotes the following character. */
# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) # define RE_BACKSLASH_ESCAPE_IN_LISTS 1ul
/* If this bit is not set, then + and ? are operators, and \+ and \? are /* If this bit is not set, then + and ? are operators, and \+ and \? are
literals. literals.
@ -215,7 +214,8 @@ extern reg_syntax_t re_syntax_options;
(The [[[ comments delimit what gets put into the Texinfo file, so (The [[[ comments delimit what gets put into the Texinfo file, so
don't delete them!) */ don't delete them!) */
/* [[[begin syntaxes]]] */ /* [[[begin syntaxes]]] */
# define RE_SYNTAX_EMACS 0 # define RE_SYNTAX_EMACS \
(RE_CHAR_CLASSES | RE_INTERVALS)
# define RE_SYNTAX_AWK \ # define RE_SYNTAX_AWK \
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
@ -522,20 +522,6 @@ typedef struct
/* Declarations for routines. */ /* Declarations for routines. */
#ifndef _REGEX_NELTS
# if (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \
&& !defined __STDC_NO_VLA__)
# define _REGEX_NELTS(n) n
# else
# define _REGEX_NELTS(n)
# endif
#endif
#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wvla"
#endif
#ifndef _Attr_access_ #ifndef _Attr_access_
# ifdef __attr_access # ifdef __attr_access
# define _Attr_access_(arg) __attr_access (arg) # define _Attr_access_(arg) __attr_access (arg)
@ -682,8 +668,7 @@ extern int regcomp (regex_t *_Restrict_ __preg,
extern int regexec (const regex_t *_Restrict_ __preg, extern int regexec (const regex_t *_Restrict_ __preg,
const char *_Restrict_ __String, size_t __nmatch, const char *_Restrict_ __String, size_t __nmatch,
regmatch_t __pmatch[_Restrict_arr_ regmatch_t __pmatch[_Restrict_arr_],
_REGEX_NELTS (__nmatch)],
int __eflags); int __eflags);
extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
@ -692,10 +677,6 @@ extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
extern void regfree (regex_t *__preg); extern void regfree (regex_t *__preg);
#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
# pragma GCC diagnostic pop
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* C++ */ #endif /* C++ */

View file

@ -1595,7 +1595,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
reg_errcode_t err; reg_errcode_t err;
re_dfastate_t *newstate; re_dfastate_t *newstate;
newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); newstate = (re_dfastate_t *) calloc (1, sizeof (re_dfastate_t));
if (__glibc_unlikely (newstate == NULL)) if (__glibc_unlikely (newstate == NULL))
return NULL; return NULL;
err = re_node_set_init_copy (&newstate->nodes, nodes); err = re_node_set_init_copy (&newstate->nodes, nodes);
@ -1643,7 +1643,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
reg_errcode_t err; reg_errcode_t err;
re_dfastate_t *newstate; re_dfastate_t *newstate;
newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); newstate = (re_dfastate_t *) calloc (1, sizeof (re_dfastate_t));
if (__glibc_unlikely (newstate == NULL)) if (__glibc_unlikely (newstate == NULL))
return NULL; return NULL;
err = re_node_set_init_copy (&newstate->nodes, nodes); err = re_node_set_init_copy (&newstate->nodes, nodes);

View file

@ -185,7 +185,7 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len);
int int
regexec (const regex_t *__restrict preg, const char *__restrict string, regexec (const regex_t *__restrict preg, const char *__restrict string,
size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) size_t nmatch, regmatch_t pmatch[], int eflags)
{ {
reg_errcode_t err; reg_errcode_t err;
Idx start, length; Idx start, length;
@ -229,7 +229,7 @@ int
attribute_compat_text_section attribute_compat_text_section
__compat_regexec (const regex_t *__restrict preg, __compat_regexec (const regex_t *__restrict preg,
const char *__restrict string, size_t nmatch, const char *__restrict string, size_t nmatch,
regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) regmatch_t pmatch[], int eflags)
{ {
return regexec (preg, string, nmatch, pmatch, return regexec (preg, string, nmatch, pmatch,
eflags & (REG_NOTBOL | REG_NOTEOL)); eflags & (REG_NOTBOL | REG_NOTEOL));
@ -2721,8 +2721,8 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx)
continue; /* No. */ continue; /* No. */
if (sub_top->path == NULL) if (sub_top->path == NULL)
{ {
sub_top->path = calloc (sizeof (state_array_t), sub_top->path = calloc (sl_str - sub_top->str_idx + 1,
sl_str - sub_top->str_idx + 1); sizeof (state_array_t));
if (sub_top->path == NULL) if (sub_top->path == NULL)
return REG_ESPACE; return REG_ESPACE;
} }
@ -3266,7 +3266,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
if (ndests == 0) if (ndests == 0)
{ {
state->trtable = (re_dfastate_t **) state->trtable = (re_dfastate_t **)
calloc (sizeof (re_dfastate_t *), SBC_MAX); calloc (SBC_MAX, sizeof (re_dfastate_t *));
if (__glibc_unlikely (state->trtable == NULL)) if (__glibc_unlikely (state->trtable == NULL))
return false; return false;
return true; return true;
@ -3338,7 +3338,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
discern by looking at the character code: allocate a discern by looking at the character code: allocate a
256-entry transition table. */ 256-entry transition table. */
trtable = state->trtable = trtable = state->trtable =
(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); (re_dfastate_t **) calloc (SBC_MAX, sizeof (re_dfastate_t *));
if (__glibc_unlikely (trtable == NULL)) if (__glibc_unlikely (trtable == NULL))
goto out_free; goto out_free;
@ -3369,7 +3369,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
transition tables, one starting at trtable[0] and one transition tables, one starting at trtable[0] and one
starting at trtable[SBC_MAX]. */ starting at trtable[SBC_MAX]. */
trtable = state->word_trtable = trtable = state->word_trtable =
(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX); (re_dfastate_t **) calloc (2 * SBC_MAX, sizeof (re_dfastate_t *));
if (__glibc_unlikely (trtable == NULL)) if (__glibc_unlikely (trtable == NULL))
goto out_free; goto out_free;

View file

@ -30,6 +30,49 @@
# endif # endif
#endif #endif
/* Haiku stdio implementation. */
#if defined __HAIKU__
# include <stdint.h>
/* This FILE structure was made into an incomplete type in 2025.
See <https://cgit.haiku-os.org/haiku/tree/src/system/libroot/posix/glibc/libio/libio.h>. */
# define fp_ ((struct { int _flags; \
char *_IO_read_ptr; \
char *_IO_read_end; \
char *_IO_read_base; \
char *_IO_write_base; \
char *_IO_write_ptr; \
char *_IO_write_end; \
char *_IO_buf_base; \
char *_IO_buf_end; \
char *_IO_save_base; \
char *_IO_backup_base; \
char *_IO_save_end; \
void *_markers; \
void *_chain; \
int _fileno; \
int _flags2; \
off_t _old_offset; \
unsigned short _cur_column; \
signed char _vtable_offset; \
char _shortbuf[1]; \
void *_lock; \
int64_t _offset; \
/* More fields, not relevant here. */ \
} *) fp)
# if !defined _IO_UNBUFFERED
# define _IO_UNBUFFERED 0x2
# endif
# if !defined _IO_EOF_SEEN
# define _IO_EOF_SEEN 0x10
# endif
# if !defined _IO_IN_BACKUP
# define _IO_IN_BACKUP 0x100
# endif
# if !defined _IO_LINE_BUF
# define _IO_LINE_BUF 0x200
# endif
#endif
/* BSD stdio derived implementations. */ /* BSD stdio derived implementations. */
#if defined __NetBSD__ /* NetBSD */ #if defined __NetBSD__ /* NetBSD */

View file

@ -63,7 +63,7 @@
#include <stddef.h> #include <stddef.h>
/* MirBSD 10 defines WEXITSTATUS in <sys/wait.h>, not in <stdlib.h>. /* MirBSD 10 defines WEXITSTATUS in <sys/wait.h>, not in <stdlib.h>.
glibc 2.40 defines WCOREDUMP in <sys/wait.h>, not in <stdlib.h>. */ glibc 2.41 defines WCOREDUMP in <sys/wait.h>, not in <stdlib.h>. */
#if @GNULIB_SYSTEM_POSIX@ && !(defined WEXITSTATUS && defined WCOREDUMP) #if @GNULIB_SYSTEM_POSIX@ && !(defined WEXITSTATUS && defined WCOREDUMP)
# include <sys/wait.h> # include <sys/wait.h>
#endif #endif
@ -120,14 +120,14 @@ struct random_data
# include <unistd.h> # include <unistd.h>
#endif #endif
#if ((@GNULIB_STRTOL@ && @REPLACE_STRTOL@) || (@GNULIB_STRTOLL@ && @REPLACE_STRTOLL@) || (@GNULIB_STRTOUL@ && @REPLACE_STRTOUL@) || (@GNULIB_STRTOULL@ && @REPLACE_STRTOULL@)) && defined __cplusplus && !defined GNULIB_NAMESPACE && defined __GNUG__ && !defined __clang__ && defined __sun #if ((@GNULIB_STRTOL@ && @REPLACE_STRTOL@) || (@GNULIB_STRTOLL@ && @REPLACE_STRTOLL@) || (@GNULIB_STRTOUL@ && @REPLACE_STRTOUL@) || (@GNULIB_STRTOULL@ && @REPLACE_STRTOULL@)) && defined __cplusplus && !defined GNULIB_NAMESPACE && defined __GNUG__ && !defined __clang__ && (defined __sun || defined _AIX)
/* When strtol, strtoll, strtoul, or strtoull is going to be defined as a macro /* When strtol, strtoll, strtoul, or strtoull is going to be defined as a macro
below, this may cause compilation errors later in the libstdc++ header files below, this may cause compilation errors later in the libstdc++ header files
(that are part of GCC), such as: (that are part of GCC), such as:
error: 'rpl_strtol' is not a member of 'std' error: 'rpl_strtol' is not a member of 'std'
To avoid this, include the relevant header files here, before these symbols To avoid this, include the relevant header files here, before these symbols
get defined as macros. But do so only on Solaris 11 (where it is needed), get defined as macros. But do so only on Solaris 11 and AIX (where it is
not on mingw (where it would cause other compilation errors). */ needed), not on mingw (where it would cause other compilation errors). */
# include <string> # include <string>
#endif #endif
@ -1473,11 +1473,17 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - "
# if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ # if @REPLACE_REALLOC_FOR_REALLOC_POSIX@
# if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ == 2 # if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ == 2
# define _GL_INLINE_RPL_REALLOC 1 # define _GL_INLINE_RPL_REALLOC 1
# ifdef __cplusplus
extern "C" {
# endif
_GL_REALLOC_INLINE void * _GL_REALLOC_INLINE void *
rpl_realloc (void *ptr, size_t size) rpl_realloc (void *ptr, size_t size)
{ {
return realloc (ptr, size ? size : 1); return realloc (ptr, size ? size : 1);
} }
# ifdef __cplusplus
}
# endif
# endif # endif
# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ # if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
|| _GL_USE_STDLIB_ALLOC) || _GL_USE_STDLIB_ALLOC)

View file

@ -54,6 +54,11 @@
/* NetBSD 5.0 mis-defines NULL. */ /* NetBSD 5.0 mis-defines NULL. */
#include <stddef.h> #include <stddef.h>
#if @GNULIB_STRERROR_L@
/* Get locale_t. */
# include <locale.h>
#endif
/* MirBSD defines mbslen as a macro. */ /* MirBSD defines mbslen as a macro. */
#if @GNULIB_MBSLEN@ && defined __MirBSD__ #if @GNULIB_MBSLEN@ && defined __MirBSD__
# include <wchar.h> # include <wchar.h>
@ -429,7 +434,9 @@ _GL_FUNCDECL_SYS (memset_explicit, void *,
# endif # endif
_GL_CXXALIAS_SYS (memset_explicit, void *, (void *__dest, int __c, size_t __n)); _GL_CXXALIAS_SYS (memset_explicit, void *, (void *__dest, int __c, size_t __n));
# endif # endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (memset_explicit); _GL_CXXALIASWARN (memset_explicit);
# endif
#elif defined GNULIB_POSIXCHECK #elif defined GNULIB_POSIXCHECK
# undef memset_explicit # undef memset_explicit
# if HAVE_RAW_DECL_MEMSET_EXPLICIT # if HAVE_RAW_DECL_MEMSET_EXPLICIT
@ -1178,6 +1185,33 @@ _GL_CXXALIASWARN (mbsrchr);
_GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) _GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle)
_GL_ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE
_GL_ARG_NONNULL ((1, 2)); _GL_ARG_NONNULL ((1, 2));
# ifndef _GL_NO_CONST_GENERICS
/* Don't silently convert a 'const char *' to a 'char *'. Programmers want
compiler warnings for 'const' related mistakes. */
# ifdef __cplusplus
extern "C++" { /* needed for AIX */
template <typename T>
T * mbsstr_template (T* haystack, const char *needle);
template <>
inline char * mbsstr_template (char *haystack, const char *needle)
{ return mbsstr (haystack, needle); }
template <>
inline const char * mbsstr_template (const char *haystack, const char *needle)
{ return mbsstr (haystack, needle); }
}
# undef mbsstr
# define mbsstr mbsstr_template
# elif !defined mbsstr
# if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
|| defined __ICC || defined __TINYC__ \
|| (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
# define mbsstr(h,n) \
_Generic ((h), \
char const *: (char const *) mbsstr ((h), (n)), \
default : mbsstr ((h), (n)))
# endif
# endif
# endif
#endif #endif
#if @GNULIB_MBSCASECMP@ #if @GNULIB_MBSCASECMP@
@ -1219,6 +1253,33 @@ _GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n)
_GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix)
_GL_ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE
_GL_ARG_NONNULL ((1, 2)); _GL_ARG_NONNULL ((1, 2));
# ifndef _GL_NO_CONST_GENERICS
/* Don't silently convert a 'const char *' to a 'char *'. Programmers want
compiler warnings for 'const' related mistakes. */
# ifdef __cplusplus
extern "C++" { /* needed for AIX */
template <typename T>
T * mbspcasecmp_template (T* string, const char *prefix);
template <>
inline char * mbspcasecmp_template (char *string, const char *prefix)
{ return mbspcasecmp (string, prefix); }
template <>
inline const char * mbspcasecmp_template (const char *string, const char *prefix)
{ return mbspcasecmp (string, prefix); }
}
# undef mbspcasecmp
# define mbspcasecmp mbspcasecmp_template
# elif !defined mbspcasecmp
# if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
|| defined __ICC || defined __TINYC__ \
|| (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
# define mbspcasecmp(s,p) \
_Generic ((s), \
char const *: (char const *) mbspcasecmp ((s), (p)), \
default : mbspcasecmp ((s), (p)))
# endif
# endif
# endif
#endif #endif
#if @GNULIB_MBSCASESTR@ #if @GNULIB_MBSCASESTR@
@ -1230,6 +1291,33 @@ _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix)
_GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) _GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle)
_GL_ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE
_GL_ARG_NONNULL ((1, 2)); _GL_ARG_NONNULL ((1, 2));
# ifndef _GL_NO_CONST_GENERICS
/* Don't silently convert a 'const char *' to a 'char *'. Programmers want
compiler warnings for 'const' related mistakes. */
# ifdef __cplusplus
extern "C++" { /* needed for AIX */
template <typename T>
T * mbscasestr_template (T* haystack, const char *needle);
template <>
inline char * mbscasestr_template (char *haystack, const char *needle)
{ return mbscasestr (haystack, needle); }
template <>
inline const char * mbscasestr_template (const char *haystack, const char *needle)
{ return mbscasestr (haystack, needle); }
}
# undef mbscasestr
# define mbscasestr mbscasestr_template
# elif !defined mbscasestr
# if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
|| defined __ICC || defined __TINYC__ \
|| (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
# define mbscasestr(h,n) \
_Generic ((h), \
char const *: (char const *) mbscasestr ((h), (n)), \
default : mbscasestr ((h), (n)))
# endif
# endif
# endif
#endif #endif
#if @GNULIB_MBSCSPN@ #if @GNULIB_MBSCSPN@
@ -1388,6 +1476,44 @@ _GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - "
# endif # endif
#endif #endif
/* Map any int, typically from errno, into an error message.
With locale_t argument. */
#if @GNULIB_STRERROR_L@
# if @REPLACE_STRERROR_L@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef strerror_l
# define strerror_l rpl_strerror_l
# endif
_GL_FUNCDECL_RPL (strerror_l, char *, (int errnum, locale_t locale),
_GL_ARG_NONNULL ((2)));
_GL_CXXALIAS_RPL (strerror_l, char *, (int errnum, locale_t locale));
# else
# if !@HAVE_STRERROR_L@
_GL_FUNCDECL_SYS (strerror_l, char *, (int errnum, locale_t locale),
_GL_ARG_NONNULL ((2)));
# endif
_GL_CXXALIAS_SYS (strerror_l, char *, (int errnum, locale_t locale));
# endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (strerror_l);
# endif
#elif defined GNULIB_POSIXCHECK
# undef strerror_l
# if HAVE_RAW_DECL_STRERROR_L
_GL_WARN_ON_USE (strerror_l, "strerror_l is unportable - "
"use gnulib module strerror_l for portability");
# endif
#endif
/* Map any int, typically from errno, into an error message. Multithread-safe,
with locale_t argument.
Not portable! Only provided by gnulib. */
#if @GNULIB_STRERROR_L@
_GL_FUNCDECL_SYS (strerror_l_r, int,
(int errnum, char *buf, size_t buflen, locale_t locale),
_GL_ARG_NONNULL ((2, 4)));
#endif
/* Return the name of the system error code ERRNUM. */ /* Return the name of the system error code ERRNUM. */
#if @GNULIB_STRERRORNAME_NP@ #if @GNULIB_STRERRORNAME_NP@
# if @REPLACE_STRERRORNAME_NP@ # if @REPLACE_STRERRORNAME_NP@
@ -1403,7 +1529,9 @@ _GL_FUNCDECL_SYS (strerrorname_np, const char *, (int errnum), );
# endif # endif
_GL_CXXALIAS_SYS (strerrorname_np, const char *, (int errnum)); _GL_CXXALIAS_SYS (strerrorname_np, const char *, (int errnum));
# endif # endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (strerrorname_np); _GL_CXXALIASWARN (strerrorname_np);
# endif
#elif defined GNULIB_POSIXCHECK #elif defined GNULIB_POSIXCHECK
# undef strerrorname_np # undef strerrorname_np
# if HAVE_RAW_DECL_STRERRORNAME_NP # if HAVE_RAW_DECL_STRERRORNAME_NP

View file

@ -186,7 +186,9 @@ _GL_FUNCDECL_SYS (timespec_getres, int, (struct timespec *ts, int base),
# endif # endif
_GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base)); _GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base));
# endif # endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (timespec_getres); _GL_CXXALIASWARN (timespec_getres);
# endif
# elif defined GNULIB_POSIXCHECK # elif defined GNULIB_POSIXCHECK
# undef timespec_getres # undef timespec_getres
# if HAVE_RAW_DECL_TIMESPEC_GETRES # if HAVE_RAW_DECL_TIMESPEC_GETRES

View file

@ -95,12 +95,15 @@
# include <stdio.h> # include <stdio.h>
#endif #endif
/* FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, Solaris 11.4, and glibc 2.41
do not define O_CLOEXEC in <unistd.h>. */
/* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in /* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in
<unistd.h>. */ <unistd.h>. */
/* But avoid namespace pollution on glibc systems. */ /* But avoid namespace pollution on glibc systems. */
#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \ #if ! defined O_CLOEXEC \
&& (defined __CYGWIN__ || defined __ANDROID__) \ || ((@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \
&& ! defined __GLIBC__ && (defined __CYGWIN__ || defined __ANDROID__) \
&& ! defined __GLIBC__)
# include <fcntl.h> # include <fcntl.h>
#endif #endif
@ -463,7 +466,9 @@ _GL_CXXALIAS_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos,
int ofd, off_t *opos, int ofd, off_t *opos,
size_t len, unsigned flags)); size_t len, unsigned flags));
# endif # endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (copy_file_range); _GL_CXXALIASWARN (copy_file_range);
# endif
#elif defined GNULIB_POSIXCHECK #elif defined GNULIB_POSIXCHECK
# undef copy_file_range # undef copy_file_range
# if HAVE_RAW_DECL_COPY_FILE_RANGE # if HAVE_RAW_DECL_COPY_FILE_RANGE
@ -1362,11 +1367,21 @@ _GL_WARN_ON_USE (gethostname, "gethostname is unportable - "
${LOGNAME-$USER} on Unix platforms, ${LOGNAME-$USER} on Unix platforms,
$USERNAME on native Windows platforms. $USERNAME on native Windows platforms.
*/ */
# if !@HAVE_DECL_GETLOGIN@ # if @REPLACE_GETLOGIN@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define getlogin rpl_getlogin
# endif
_GL_FUNCDECL_RPL (getlogin, char *, (void), );
_GL_CXXALIAS_RPL (getlogin, char *, (void));
# else
# if !@HAVE_DECL_GETLOGIN@
_GL_FUNCDECL_SYS (getlogin, char *, (void), ); _GL_FUNCDECL_SYS (getlogin, char *, (void), );
# endif # endif
_GL_CXXALIAS_SYS (getlogin, char *, (void)); _GL_CXXALIAS_SYS (getlogin, char *, (void));
# endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (getlogin); _GL_CXXALIASWARN (getlogin);
# endif
#elif defined GNULIB_POSIXCHECK #elif defined GNULIB_POSIXCHECK
# undef getlogin # undef getlogin
# if HAVE_RAW_DECL_GETLOGIN # if HAVE_RAW_DECL_GETLOGIN
@ -2405,7 +2420,7 @@ _GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - "
#if @GNULIB_USLEEP@ #if @GNULIB_USLEEP@
/* Pause the execution of the current thread for N microseconds. /* Pause the execution of the current thread for N microseconds.
Returns 0 on completion, or -1 on range error. Returns 0 on completion, or -1 on range error.
See the POSIX:2001 specification See the POSIX.1-2004 specification
<https://pubs.opengroup.org/onlinepubs/009695399/functions/usleep.html>. */ <https://pubs.opengroup.org/onlinepubs/009695399/functions/usleep.html>. */
# if @REPLACE_USLEEP@ # if @REPLACE_USLEEP@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)

View file

@ -25,7 +25,7 @@
#include <time.h> #include <time.h>
#if HAVE_UTIMENS || HAVE_LUTIMENS #if HAVE_UTIMENS || HAVE_LUTIMENS
# include <sys/time.h> # include <sys/stat.h>
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -136,8 +136,9 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
} }
# endif # endif
# endif # endif
# if defined __APPLE__ && defined __MACH__ # if (defined __APPLE__ && defined __MACH__) || defined __gnu_hurd__
/* macOS 10.13 does not reject invalid tv_nsec values either. */ /* macOS 10.13 and GNU Hurd do not reject invalid tv_nsec values
either. */
if (times if (times
&& ((times[0].tv_nsec != UTIME_OMIT && ((times[0].tv_nsec != UTIME_OMIT
&& times[0].tv_nsec != UTIME_NOW && times[0].tv_nsec != UTIME_NOW
@ -151,6 +152,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
# if defined __APPLE__ && defined __MACH__
size_t len = strlen (file); size_t len = strlen (file);
if (len > 0 && file[len - 1] == '/') if (len > 0 && file[len - 1] == '/')
{ {
@ -163,6 +165,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
return -1; return -1;
} }
} }
# endif
# endif # endif
result = utimensat (fd, file, times, flag); result = utimensat (fd, file, times, flag);
/* Linux kernel 2.6.25 has a bug where it returns EINVAL for /* Linux kernel 2.6.25 has a bug where it returns EINVAL for

View file

@ -157,9 +157,10 @@
#define _GL_CONCAT0(x, y) x##y #define _GL_CONCAT0(x, y) x##y
/* _GL_COUNTER is an integer, preferably one that changes each time we /* _GL_COUNTER is an integer, preferably one that changes each time we
use it. Use __COUNTER__ if it works, falling back on __LINE__ use it. Use __COUNTER__ if it works (it does so with most compilers,
otherwise. __LINE__ isn't perfect, but it's better than a see <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3457.htm>),
constant. */ falling back on __LINE__ otherwise. __LINE__ isn't perfect, but it's
better than a constant. */
#if defined __COUNTER__ && __COUNTER__ != __COUNTER__ #if defined __COUNTER__ && __COUNTER__ != __COUNTER__
# define _GL_COUNTER __COUNTER__ # define _GL_COUNTER __COUNTER__
#else #else

View file

@ -42,7 +42,7 @@
(defcustom abbrev-file-name (defcustom abbrev-file-name
(locate-user-emacs-file "abbrev_defs" ".abbrev_defs") (locate-user-emacs-file "abbrev_defs" ".abbrev_defs")
"Default name of file from which to read and where to save abbrevs." "Default name of file from which to read and where to save abbrevs."
:initialize 'custom-initialize-delay :initialize #'custom-initialize-delay
:type 'file) :type 'file)
(defcustom only-global-abbrevs nil (defcustom only-global-abbrevs nil
@ -62,7 +62,7 @@ be replaced by its expansion."
;; defining it again. ;; defining it again.
:variable abbrev-mode) :variable abbrev-mode)
(put 'abbrev-mode 'safe-local-variable 'booleanp) (put 'abbrev-mode 'safe-local-variable #'booleanp)
(define-obsolete-variable-alias 'edit-abbrevs-map (define-obsolete-variable-alias 'edit-abbrevs-map
@ -225,7 +225,8 @@ about loading the abbrevs."
(list (list
(read-file-name (format-prompt "Read abbrev file" abbrev-file-name) (read-file-name (format-prompt "Read abbrev file" abbrev-file-name)
nil abbrev-file-name t))) nil abbrev-file-name t)))
(load (or file abbrev-file-name) nil quietly) (let ((warning-inhibit-types '((files missing-lexbind-cookie))))
(load (or file abbrev-file-name) nil quietly))
(setq abbrevs-changed nil)) (setq abbrevs-changed nil))
(defun quietly-read-abbrev-file (&optional file) (defun quietly-read-abbrev-file (&optional file)
@ -270,7 +271,8 @@ abbrevs have been saved."
(when (unencodable-char-position (point-min) (point-max) 'utf-8) (when (unencodable-char-position (point-min) (point-max) 'utf-8)
(setq coding-system-for-write 'utf-8-emacs)) (setq coding-system-for-write 'utf-8-emacs))
(goto-char (point-min)) (goto-char (point-min))
(insert (format ";;-*-coding: %s;-*-\n" coding-system-for-write)) (insert (format ";; -*- coding: %S; lexical-binding: t -*-\n"
coding-system-for-write))
(write-region nil nil file nil (and (not verbose) 0))))) (write-region nil nil file nil (and (not verbose) 0)))))
(defun abbrev-edit-save-to-file (file) (defun abbrev-edit-save-to-file (file)
@ -494,13 +496,13 @@ A prefix argument means don't query; expand all abbrevs."
(set sym nil) ; Make sure it won't be confused for an abbrev. (set sym nil) ; Make sure it won't be confused for an abbrev.
(put sym prop val))) (put sym prop val)))
(defalias 'abbrev-get 'get (defalias 'abbrev-get #'get
"Get the property PROP of abbrev ABBREV "Get the property PROP of abbrev ABBREV
See `define-abbrev' for the effect of some special properties. See `define-abbrev' for the effect of some special properties.
\(fn ABBREV PROP)") \(fn ABBREV PROP)")
(defalias 'abbrev-put 'put (defalias 'abbrev-put #'put
"Set the property PROP of abbrev ABBREV to value VAL. "Set the property PROP of abbrev ABBREV to value VAL.
See `define-abbrev' for the effect of some special properties. See `define-abbrev' for the effect of some special properties.
@ -573,8 +575,7 @@ This causes `save-some-buffers' to offer to save the abbrevs.")
(defcustom abbrev-all-caps nil (defcustom abbrev-all-caps nil
"Non-nil means expand multi-word abbrevs in all caps if the abbrev was so." "Non-nil means expand multi-word abbrevs in all caps if the abbrev was so."
:type 'boolean :type 'boolean)
:group 'abbrev-mode)
(defvar abbrev-start-location nil (defvar abbrev-start-location nil
"Buffer position for `expand-abbrev' to use as the start of the abbrev. "Buffer position for `expand-abbrev' to use as the start of the abbrev.
@ -691,7 +692,7 @@ current (if global is nil) or standard syntax table."
(cl-pushnew (aref abbrev (match-beginning 0)) badchars) (cl-pushnew (aref abbrev (match-beginning 0)) badchars)
(setq pos (1+ pos))) (setq pos (1+ pos)))
(error "Some abbrev characters (%s) are not word constituents %s" (error "Some abbrev characters (%s) are not word constituents %s"
(apply 'string (nreverse badchars)) (apply #'string (nreverse badchars))
(if global "in the standard syntax" "in this mode")))))) (if global "in the standard syntax" "in this mode"))))))
(defun define-global-abbrev (abbrev expansion) (defun define-global-abbrev (abbrev expansion)
@ -1096,8 +1097,7 @@ This differs from ordinary undo in that other editing done since then
is not undone." is not undone."
(interactive) (interactive)
(save-excursion (save-excursion
(unless (or (< last-abbrev-location (point-min)) (when (<= (point-min) last-abbrev-location (point-max))
(> last-abbrev-location (point-max)))
(goto-char last-abbrev-location) (goto-char last-abbrev-location)
(when (stringp last-abbrev-text) (when (stringp last-abbrev-text)
;; This isn't correct if last-abbrev's hook was used ;; This isn't correct if last-abbrev's hook was used
@ -1106,9 +1106,9 @@ is not undone."
(unless (stringp val) (unless (stringp val)
(error "Value of abbrev-symbol must be a string")) (error "Value of abbrev-symbol must be a string"))
;; Don't inherit properties here; just copy from old contents. ;; Don't inherit properties here; just copy from old contents.
(insert last-abbrev-text) (replace-region-contents (point) (+ (point) (length val))
;; Delete after inserting, to better preserve markers. last-abbrev-text 0)
(delete-region (point) (+ (point) (length val))) (goto-char (+ (point) (length last-abbrev-text)))
(setq last-abbrev-text nil)))))) (setq last-abbrev-text nil))))))
(defun abbrev--write (sym) (defun abbrev--write (sym)
@ -1158,21 +1158,21 @@ a call to `define-abbrev-table' that, when evaluated, will define
the abbrev table NAME exactly as it is currently defined. the abbrev table NAME exactly as it is currently defined.
Abbrevs marked as \"system abbrevs\" are ignored." Abbrevs marked as \"system abbrevs\" are ignored."
(let ((symbols (abbrev--table-symbols name readable))) (let ((symbols (abbrev--table-symbols name readable)))
(setq symbols (sort symbols 'string-lessp)) (setq symbols (sort symbols #'string-lessp))
(let ((standard-output (current-buffer))) (let ((standard-output (current-buffer)))
(if readable (if readable
(progn (progn
(insert "(") (insert "(")
(prin1 name) (prin1 name)
(insert ")\n\n") (insert ")\n\n")
(mapc 'abbrev--describe symbols) (mapc #'abbrev--describe symbols)
(insert "\n\n")) (insert "\n\n"))
(insert "(define-abbrev-table '") (insert "(define-abbrev-table '")
(prin1 name) (prin1 name)
(if (null symbols) (if (null symbols)
(insert " '())\n\n") (insert " '())\n\n")
(insert "\n '(\n") (insert "\n '(\n")
(mapc 'abbrev--write symbols) (mapc #'abbrev--write symbols)
(insert " ))\n\n"))) (insert " ))\n\n")))
nil))) nil)))
@ -1215,7 +1215,7 @@ Properties with special meaning:
;; There is really no docstring, instead the docstring arg ;; There is really no docstring, instead the docstring arg
;; is a property name. ;; is a property name.
(push docstring props) (setq docstring nil)) (push docstring props) (setq docstring nil))
(eval `(defvar ,tablename nil ,@(if docstring (list docstring)))) (defvar-1 tablename nil docstring)
(let ((table (if (boundp tablename) (symbol-value tablename)))) (let ((table (if (boundp tablename) (symbol-value tablename))))
(unless table (unless table
(setq table (make-abbrev-table)) (setq table (make-abbrev-table))
@ -1229,7 +1229,7 @@ Properties with special meaning:
(unless (cdr props) (error "Missing value for property %S" (car props))) (unless (cdr props) (error "Missing value for property %S" (car props)))
(abbrev-table-put table (pop props) (pop props))) (abbrev-table-put table (pop props) (pop props)))
(dolist (elt definitions) (dolist (elt definitions)
(apply 'define-abbrev table elt)))) (apply #'define-abbrev table elt))))
(defun abbrev-table-menu (table &optional prompt sortfun) (defun abbrev-table-menu (table &optional prompt sortfun)
"Return a menu that shows all abbrevs in TABLE. "Return a menu that shows all abbrevs in TABLE.

View file

@ -792,7 +792,15 @@ archive.
;; The funny [] here make it unlikely that the .elc file will be treated ;; The funny [] here make it unlikely that the .elc file will be treated
;; as an archive by other software. ;; as an archive by other software.
(let (case-fold-search) (let (case-fold-search)
(cond ((looking-at "\\(PK00\\)?[P]K\003\004") 'zip) ;; See APPNOTE.txt (version 6.3.10) from PKWARE for the zip
;; file signatures:
;; - PK\003\004 == 0x04034b50: local file header signature
;; (section 4.3.7)
;; - PK\007\010 == 0x08074b50 (followed by local header):
;; spanned/split archive signature (section 8.5.3)
;; - PK00 == 0x30304b50 (followed by local header): temporary
;; spanned/split archive signature (section 8.5.4)
(cond ((looking-at "\\(?:PK\007\010\\|PK00\\)?[P]K\003\004") 'zip)
((looking-at "..-l[hz][0-9ds]-") 'lzh) ((looking-at "..-l[hz][0-9ds]-") 'lzh)
((looking-at "....................[\334]\247\304\375") 'zoo) ((looking-at "....................[\334]\247\304\375") 'zoo)
((and (looking-at "\C-z") ; signature too simple, IMHO ((and (looking-at "\C-z") ; signature too simple, IMHO

View file

@ -149,7 +149,6 @@ HOSTS can be a string or a list of strings."
(defvar auth-source-pass-backend (defvar auth-source-pass-backend
(auth-source-backend (auth-source-backend
(when (<= emacs-major-version 25) "password-store")
:source "." ;; not used :source "." ;; not used
:type 'password-store :type 'password-store
:search-function #'auth-source-pass-search) :search-function #'auth-source-pass-search)

View file

@ -708,7 +708,11 @@ must call it to obtain the actual value."
(condition-case nil (condition-case nil
(unless (auth-source-search-collection (unless (auth-source-search-collection
(plist-get spec key) (plist-get spec key)
(slot-value backend key)) (slot-value
backend
(if (keywordp key)
(intern-soft (substring (symbol-name key) 1))
key)))
(setq filtered-backends (delq backend filtered-backends)) (setq filtered-backends (delq backend filtered-backends))
(cl-return)) (cl-return))
(invalid-slot-name nil)))) (invalid-slot-name nil))))
@ -2391,21 +2395,21 @@ See `auth-source-search' for details on SPEC."
:version "28.1") :version "28.1")
(defvar authinfo--keywords (defvar authinfo--keywords
'(("^#.*" . font-lock-comment-face) '(("^#.*" (0 'font-lock-comment-face))
("^\\(machine\\)[ \t]+\\([^ \t\n]+\\)" ("^\\(machine\\)[ \t]+\\([^ \t\n]+\\)"
(1 font-lock-variable-name-face) (1 'font-lock-variable-name-face)
(2 font-lock-builtin-face)) (2 'font-lock-builtin-face))
("\\(login\\)[ \t]+\\([^ \t\n]+\\)" ("\\(login\\)[ \t]+\\([^ \t\n]+\\)"
(1 font-lock-comment-delimiter-face) (1 'font-lock-comment-delimiter-face)
(2 font-lock-keyword-face)) (2 'font-lock-keyword-face))
("\\(password\\)[ \t]+\\([^ \t\n]+\\)" ("\\(password\\)[ \t]+\\([^ \t\n]+\\)"
(1 font-lock-comment-delimiter-face) (1 'font-lock-comment-delimiter-face)
(2 font-lock-doc-face)) (2 'font-lock-doc-face))
("\\(port\\)[ \t]+\\([^ \t\n]+\\)" ("\\(port\\)[ \t]+\\([^ \t\n]+\\)"
(1 font-lock-comment-delimiter-face) (1 'font-lock-comment-delimiter-face)
(2 font-lock-type-face)) (2 'font-lock-type-face))
("\\([^ \t\n]+\\)[, \t]+\\([^ \t\n]+\\)" ("\\([^ \t\n]+\\)[, \t]+\\([^ \t\n]+\\)"
(1 font-lock-constant-face) (1 'font-lock-constant-face)
(2 nil)))) (2 nil))))
;;;###autoload ;;;###autoload

View file

@ -429,6 +429,145 @@ a menu, so this function is not useful for non-menu keymaps."
(bindings--menu-item-string (cdr-safe b)))))) (bindings--menu-item-string (cdr-safe b))))))
(nconc (make-sparse-keymap prompt) bindings))) (nconc (make-sparse-keymap prompt) bindings)))
(defcustom mode-line-collapse-minor-modes nil
"Minor modes for which mode line lighters are hidden.
Hidden lighters are collapsed into one, which latter is customizable
using the option `mode-line-collapse-minor-modes-to'.
The value could be a list (MODES ...) which means to collapse lighters
only for MODES, or a list (not MODES ...) which means to collapse all
lighters for minor modes not in MODES. Other non-nil values make all
lighters hidden."
:type '(choice (const :tag "No modes" nil)
(repeat :tag "Modes" symbol)
(cons :tag "All modes except"
(const not) (repeat symbol))
(const :tag "All modes" t))
:group 'mode-line
:version "31.1")
(defcustom mode-line-collapse-minor-modes-to
(if (char-displayable-p ?…) "" " ...")
"Lighter for collapsed minor modes.
This is effective only when `mode-line-collapse-minor-modes' is non-nil."
:type 'string
:initialize #'custom-initialize-delay
:group 'mode-line
:version "31.1")
(defcustom mode-line-modes-delimiters '("(" . ")")
"Strings placed around the modes displayed in the mode line.
These elements are placed around `mode-name' and `mode-line-modes'."
:type '(choice (const :tag "No delimiters")
(cons (string :tag "Left delimiter")
(string :tag "Right delimiter")))
:group 'mode-line
:version "31.1")
(defvar mode-line-minor-modes '(:eval (mode-line--minor-modes))
"Mode line construct for minor mode lighters.")
;;;###autoload
(put 'mode-line-minor-modes 'risky-local-variable t)
(defun mode-line--make-lighter-menu (alist)
"Return a menu keymap for minor mode lighters in ALIST.
ALIST should be in the same format as `minor-mode-alist'.
Return nil if no lighters in ALIST should be visible, for example, there
are no active minor modes or non-empty lighters."
(let ((menu (make-sparse-keymap "Minor Modes"))
(empty t))
(dolist (item alist)
(when-let* ((variable (car item))
((and (boundp variable)
(symbol-value variable)))
(lighter (format-mode-line `("" ,@(cdr-safe item))))
((not (string= lighter "")))
(toggle (or (get variable :minor-mode-function) variable))
;; Follow the format in `mouse-minor-mode-menu'
(name (format "%s - %s" lighter
(capitalize
(string-replace
"-" " " (symbol-name toggle))))))
(when (eq ? (aref name 0))
(setq name (substring name 1)))
(let* ((map (cdr-safe (assq variable minor-mode-map-alist)))
(mm-menu (and (keymapp map)
(keymap-lookup map "<menu-bar>"))))
(setq mm-menu
(cond (mm-menu (mouse-menu-non-singleton mm-menu))
((fboundp toggle)
(define-keymap :name name
"<help>" (list 'menu-item
"Help for minor mode"
(lambda () (interactive)
(describe-function toggle)))
"<turn-off>" (list 'menu-item
"Turn off minor mode"
toggle)))
;; No menu and not a minor mode function, so just
;; display the label without a sub-menu.
(t nil)))
(keymap-set menu (format "<%s>" toggle)
(list 'menu-item name mm-menu))
(setq empty nil))))
(and (not empty) menu)))
(defun mode-line--minor-modes ()
"Compute mode line constructs for minor mode lighters."
(let (visible hidden)
(cond
((not mode-line-collapse-minor-modes)
(setq visible minor-mode-alist
hidden nil))
((eq 'not (car-safe mode-line-collapse-minor-modes))
(let ((modes (cdr mode-line-collapse-minor-modes)))
(dolist (item minor-mode-alist)
(if (memq (car item) modes)
(push item visible)
(push item hidden)))
(setq visible (nreverse visible)
hidden (nreverse hidden))))
((listp mode-line-collapse-minor-modes)
(let ((modes mode-line-collapse-minor-modes))
(dolist (item minor-mode-alist)
(if (memq (car item) modes)
(push item hidden)
(push item visible)))
(setq visible (nreverse visible)
hidden (nreverse hidden))))
(t (setq visible nil
hidden minor-mode-alist)))
(list ""
`(:propertize ("" ,visible)
mouse-face mode-line-highlight
help-echo "Minor mode\n\
mouse-1: Display minor mode menu\n\
mouse-2: Show help for minor mode\n\
mouse-3: Toggle minor modes"
local-map ,mode-line-minor-mode-keymap)
(unless (string= "" (format-mode-line `("" ,hidden)))
(let* ((menu
;; FIXME: This is to defer the computation of the
;; menu, but may not play well with touchscreen.
(lambda (e)
(interactive "@e")
(if-let* ((m (mode-line--make-lighter-menu hidden)))
(popup-menu m e)
(message "No menu available"))))
(keymap
(define-keymap
:parent mode-line-minor-mode-keymap
"<mode-line> <down-mouse-1>" menu
"<mode-line> <mouse-2>" #'describe-mode)))
`(:propertize mode-line-collapse-minor-modes-to
mouse-face mode-line-highlight
help-echo "Hidden minor modes\n\
mouse-1: Display hidden minor modes\n\
mouse-2: Show help for enabled minor modes\n\
mouse-3: Toggle minor modes"
local-map ,keymap))))))
(defvar mode-line-major-mode-keymap (defvar mode-line-major-mode-keymap
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map [mode-line down-mouse-1] (define-key map [mode-line down-mouse-1]
@ -457,7 +596,7 @@ Keymap to display on minor modes.")
(let ((recursive-edit-help-echo (let ((recursive-edit-help-echo
"Recursive edit, type C-M-c to get out")) "Recursive edit, type C-M-c to get out"))
(list (propertize "%[" 'help-echo recursive-edit-help-echo) (list (propertize "%[" 'help-echo recursive-edit-help-echo)
"(" '(:eval (car mode-line-modes-delimiters))
`(:propertize ("" mode-name) `(:propertize ("" mode-name)
help-echo "Major mode\n\ help-echo "Major mode\n\
mouse-1: Display major mode menu\n\ mouse-1: Display major mode menu\n\
@ -466,18 +605,12 @@ mouse-3: Toggle minor modes"
mouse-face mode-line-highlight mouse-face mode-line-highlight
local-map ,mode-line-major-mode-keymap) local-map ,mode-line-major-mode-keymap)
'("" mode-line-process) '("" mode-line-process)
`(:propertize ("" minor-mode-alist)
mouse-face mode-line-highlight
help-echo "Minor mode\n\
mouse-1: Display minor mode menu\n\
mouse-2: Show help for minor mode\n\
mouse-3: Toggle minor modes"
local-map ,mode-line-minor-mode-keymap)
(propertize "%n" 'help-echo "mouse-2: Remove narrowing from buffer" (propertize "%n" 'help-echo "mouse-2: Remove narrowing from buffer"
'mouse-face 'mode-line-highlight 'mouse-face 'mode-line-highlight
'local-map (make-mode-line-mouse-map 'local-map (make-mode-line-mouse-map
'mouse-2 #'mode-line-widen)) 'mouse-2 #'mode-line-widen))
")" '("" mode-line-minor-modes)
'(:eval (cdr mode-line-modes-delimiters))
(propertize "%]" 'help-echo recursive-edit-help-echo) (propertize "%]" 'help-echo recursive-edit-help-echo)
" ")) " "))
"Mode line construct for displaying major and minor modes.") "Mode line construct for displaying major and minor modes.")

View file

@ -290,22 +290,16 @@
(goto-char (point-max)) (goto-char (point-max))
(insert "\n\n") (insert "\n\n")
(forward-char -1)) (forward-char -1))
(save-excursion
(goto-char (point-max))
(skip-chars-backward " \n\t ")
(when (bobp)
(insert ";;; -*- mode: emacs-lisp; lexical-binding:t -*-\n")))
(insert ";;; Mode settings stored by Calc on " (current-time-string) "\n") (insert ";;; Mode settings stored by Calc on " (current-time-string) "\n")
(let ((list calc-mode-var-list)) (pcase-dolist (`(,v ,def) calc-mode-var-list)
(while list (let* ((val (pop vals)))
(let* ((v (car (car list))) (or (equal val def)
(def (nth 1 (car list))) (pp `(setq ,v ,(macroexp-quote val)) (current-buffer)))))
(val (car vals)))
(or (equal val def)
(progn
(insert "(setq " (symbol-name v) " ")
(if (and (or (listp val)
(symbolp val))
(not (memq val '(nil t))))
(insert "'"))
(insert (prin1-to-string val) ")\n"))))
(setq list (cdr list)
vals (cdr vals))))
(run-hooks 'calc-mode-save-hook) (run-hooks 'calc-mode-save-hook)
(insert ";;; End of mode settings\n") (insert ";;; End of mode settings\n")
(save-buffer) (save-buffer)
@ -332,7 +326,8 @@
(equal user-init-file calc-settings-file) (equal user-init-file calc-settings-file)
(> arg 0)) (> arg 0))
(< arg 0) (< arg 0)
(load name t) (let ((warning-inhibit-types '((files missing-lexbind-cookie))))
(load name t))
(message "New file"))))) (message "New file")))))
(defun math-get-modes-vec () (defun math-get-modes-vec ()

View file

@ -167,14 +167,7 @@
(interactive "p") (interactive "p")
(calc-with-trail-buffer (calc-with-trail-buffer
(let ((buffer-read-only nil)) (let ((buffer-read-only nil))
(save-restriction (kill-line n))
(narrow-to-region ; don't delete "Emacs Trail" header
(save-excursion
(goto-char (point-min))
(forward-line 1)
(point))
(point-max))
(kill-line n)))
(calc-trail-here))) (calc-trail-here)))
(provide 'calc-trail) (provide 'calc-trail)

View file

@ -1347,7 +1347,8 @@ Notations: 3.14e6 3.14 * 10^6
(equal calc-settings-file user-init-file) (equal calc-settings-file user-init-file)
(progn (progn
(setq calc-loaded-settings-file t) (setq calc-loaded-settings-file t)
(load (file-name-sans-extension calc-settings-file) t))) ; t = missing-ok (let ((warning-inhibit-types '((files missing-lexbind-cookie))))
(load (file-name-sans-extension calc-settings-file) t)))) ; t = missing-ok
(let ((p command-line-args)) (let ((p command-line-args))
(while p (while p
(and (equal (car p) "-f") (and (equal (car p) "-f")

Some files were not shown because too many files have changed in this diff Show more